@archivist-gg/dnd5e 0.3.17 → 0.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/LICENSE +48 -21
  2. package/README.md +26 -48
  3. package/dist/armor/armor.codec.d.ts +0 -7
  4. package/dist/armor/armor.codec.js +1 -9
  5. package/dist/armor/armor.parser.js +1 -8
  6. package/dist/armor/armor.schema.js +1 -7
  7. package/dist/armor/armor.types.d.ts +0 -3
  8. package/dist/background/background.codec.d.ts +0 -6
  9. package/dist/background/background.codec.js +1 -12
  10. package/dist/background/background.parser.js +1 -11
  11. package/dist/background/background.schema.js +1 -12
  12. package/dist/background/background.types.d.ts +0 -5
  13. package/dist/chunk-2EOGK6R6.js +1 -0
  14. package/dist/chunk-2HRRH3WL.js +1 -0
  15. package/dist/chunk-2LCGKNVM.js +1 -0
  16. package/dist/chunk-2NUDWOFG.js +1 -0
  17. package/dist/chunk-334WLI7V.js +1 -0
  18. package/dist/chunk-3LWOVRLA.js +1 -0
  19. package/dist/chunk-3QQOATV3.js +1 -0
  20. package/dist/chunk-4E2GIWJE.js +1 -0
  21. package/dist/chunk-4GN3GYMP.js +1 -0
  22. package/dist/chunk-4IAMSRHD.js +1 -0
  23. package/dist/chunk-4JEF3CET.js +1 -0
  24. package/dist/chunk-4KVVAENP.js +1 -0
  25. package/dist/chunk-56JK6VCL.js +1 -0
  26. package/dist/chunk-5FEXHY4U.js +1 -0
  27. package/dist/chunk-63YJPWTM.js +1 -0
  28. package/dist/chunk-6ASJ3MVB.js +1 -0
  29. package/dist/chunk-6IC53O3Q.js +1 -0
  30. package/dist/chunk-6LCNV26D.js +1 -0
  31. package/dist/chunk-6W253VHH.js +1 -0
  32. package/dist/chunk-7AKJBRBD.js +1 -0
  33. package/dist/chunk-7EL3GWWJ.js +1 -0
  34. package/dist/chunk-7FPQJDFD.js +1 -0
  35. package/dist/chunk-7J5BNH2D.js +1 -0
  36. package/dist/chunk-7LPKI27J.js +1 -0
  37. package/dist/chunk-7UPYRKMF.js +1 -0
  38. package/dist/chunk-A7H6LX47.js +1 -0
  39. package/dist/chunk-AINRPPLH.js +1 -0
  40. package/dist/chunk-BC52J4LA.js +1 -0
  41. package/dist/chunk-BCXGB4HP.js +1 -0
  42. package/dist/chunk-BGX36NPE.js +1 -0
  43. package/dist/chunk-BPKG6RZ7.js +1 -0
  44. package/dist/chunk-BREHZNTL.js +1 -0
  45. package/dist/chunk-BZ6BGGZS.js +1 -0
  46. package/dist/chunk-CAPYNIGK.js +1 -0
  47. package/dist/chunk-CCFIINBA.js +1 -0
  48. package/dist/chunk-CMIEZQL4.js +1 -0
  49. package/dist/chunk-DVUXUIPV.js +1 -0
  50. package/dist/chunk-DY6FVAGA.js +1 -0
  51. package/dist/chunk-DZITM5AG.js +1 -0
  52. package/dist/chunk-DZKSXSJF.js +1 -0
  53. package/dist/chunk-EAARMPCW.js +1 -0
  54. package/dist/chunk-EVT7MGAC.js +1 -0
  55. package/dist/chunk-FOLHTMSC.js +1 -0
  56. package/dist/chunk-GCYUCIDN.js +1 -0
  57. package/dist/chunk-GIOV6JW7.js +1 -0
  58. package/dist/chunk-HCK6IUB3.js +1 -0
  59. package/dist/chunk-HR5MKCP2.js +1 -0
  60. package/dist/chunk-I26FHSI6.js +1 -0
  61. package/dist/chunk-I4O2FIDT.js +1 -0
  62. package/dist/chunk-IGVRLGLM.js +1 -0
  63. package/dist/chunk-IHPLT2ZT.js +1 -0
  64. package/dist/chunk-IOCJIWCV.js +1 -0
  65. package/dist/chunk-JXDX2DKF.js +1 -0
  66. package/dist/chunk-KBFSJ5WE.js +1 -0
  67. package/dist/chunk-KM75CC6Q.js +1 -0
  68. package/dist/chunk-KZDDFG4O.js +1 -0
  69. package/dist/chunk-LJNT3PJP.js +1 -0
  70. package/dist/chunk-LR6UMA5V.js +1 -0
  71. package/dist/chunk-M6RPOLKS.js +1 -0
  72. package/dist/chunk-MC6PLWRZ.js +1 -0
  73. package/dist/chunk-MGGKZGLG.js +1 -0
  74. package/dist/chunk-N3RYJ7RE.js +1 -0
  75. package/dist/chunk-NEMX7QGG.js +1 -0
  76. package/dist/chunk-NI364WV7.js +1 -0
  77. package/dist/chunk-O2QZ73GA.js +1 -0
  78. package/dist/chunk-O776WL7O.js +1 -0
  79. package/dist/chunk-OTFNINUY.js +1 -0
  80. package/dist/chunk-PQAVMK3T.js +1 -0
  81. package/dist/chunk-PZ3ZZ5H5.js +1 -0
  82. package/dist/chunk-PZ4L2EEG.js +1 -0
  83. package/dist/chunk-PZUPZBTN.js +1 -0
  84. package/dist/chunk-QBA757AU.js +1 -0
  85. package/dist/chunk-QFIGPOFW.js +1 -0
  86. package/dist/chunk-QMEKQTUT.js +1 -0
  87. package/dist/chunk-QVWT67WA.js +1 -0
  88. package/dist/chunk-RDXQAZBA.js +1 -0
  89. package/dist/chunk-RE5Z5RNK.js +1 -0
  90. package/dist/chunk-RL4VY2AL.js +1 -0
  91. package/dist/chunk-RQGTBHJW.js +1 -0
  92. package/dist/chunk-RQZCGXUZ.js +1 -0
  93. package/dist/chunk-S5UCI27C.js +1 -0
  94. package/dist/chunk-SEOASDO4.js +1 -0
  95. package/dist/chunk-SU4MEZ5P.js +1 -0
  96. package/dist/chunk-T55DELVL.js +1 -0
  97. package/dist/chunk-TKIEPC6F.js +1 -0
  98. package/dist/chunk-TLXFGGWH.js +1 -0
  99. package/dist/chunk-UBUKCRZ3.js +1 -0
  100. package/dist/chunk-V6NQ547U.js +1 -0
  101. package/dist/chunk-VA3ZWV7C.js +1 -0
  102. package/dist/chunk-VIP3FH2O.js +1 -0
  103. package/dist/chunk-VTQ4RWEG.js +1 -0
  104. package/dist/chunk-WUHTSLG4.js +1 -0
  105. package/dist/chunk-X22SISGM.js +1 -0
  106. package/dist/chunk-XKJXT2PN.js +1 -0
  107. package/dist/chunk-XQMKH4R4.js +1 -0
  108. package/dist/chunk-YGH7S5ZF.js +1 -0
  109. package/dist/chunk-ZE46ADXS.js +1 -0
  110. package/dist/chunk-ZI3FEUX3.js +1 -0
  111. package/dist/class/class.codec.d.ts +0 -7
  112. package/dist/class/class.codec.js +1 -18
  113. package/dist/class/class.parser.js +1 -17
  114. package/dist/class/class.schema.d.ts +2 -1
  115. package/dist/class/class.schema.js +1 -15
  116. package/dist/class/class.slug.d.ts +0 -11
  117. package/dist/class/class.slug.js +1 -8
  118. package/dist/class/class.standard-array.d.ts +0 -7
  119. package/dist/class/class.standard-array.js +1 -20
  120. package/dist/class/class.types.d.ts +0 -20
  121. package/dist/condition/condition.codec.d.ts +0 -6
  122. package/dist/condition/condition.parser.d.ts +0 -10
  123. package/dist/condition/condition.parser.js +1 -7
  124. package/dist/condition/condition.schema.d.ts +0 -16
  125. package/dist/condition/condition.types.d.ts +0 -3
  126. package/dist/data-srd/index.generated.js +1 -146
  127. package/dist/dnd/amount-text.d.ts +4 -27
  128. package/dist/dnd/amount-text.js +1 -13
  129. package/dist/dnd/constants.d.ts +0 -18
  130. package/dist/dnd/constants.js +1 -42
  131. package/dist/dnd/formula-tags.d.ts +0 -2
  132. package/dist/dnd/formula-tags.js +1 -119
  133. package/dist/dnd/math.d.ts +0 -26
  134. package/dist/dnd/math.js +1 -45
  135. package/dist/dnd/prose-tags.d.ts +1 -15
  136. package/dist/dnd/prose-tags.js +1 -18
  137. package/dist/dnd/resource-die.d.ts +0 -4
  138. package/dist/dnd/resource-die.js +1 -17
  139. package/dist/dnd/resource-formula.d.ts +0 -43
  140. package/dist/dnd/resource-formula.js +1 -14
  141. package/dist/dnd/resource-words.d.ts +0 -2
  142. package/dist/dnd/resource-words.js +1 -30
  143. package/dist/dnd/srd-tag-converter.d.ts +0 -21
  144. package/dist/dnd/srd-tag-converter.js +1 -12
  145. package/dist/dnd/tag-grammar.js +1 -12
  146. package/dist/dnd/warn-once.js +1 -8
  147. package/dist/encounter/encounter.ai-schema.js +1 -8
  148. package/dist/entities/base-item-resolver.d.ts +0 -26
  149. package/dist/entities/base-item-resolver.js +1 -11
  150. package/dist/entities/registry-revision.d.ts +10 -0
  151. package/dist/entities/registry-revision.js +1 -0
  152. package/dist/entities/slug.d.ts +1 -31
  153. package/dist/entities/slug.js +1 -12
  154. package/dist/entities/wikilink-display.d.ts +0 -2
  155. package/dist/entities/wikilink-display.js +1 -10
  156. package/dist/feat/feat.category-codes.d.ts +1 -26
  157. package/dist/feat/feat.category-codes.js +1 -14
  158. package/dist/feat/feat.codec.d.ts +0 -6
  159. package/dist/feat/feat.codec.js +1 -12
  160. package/dist/feat/feat.parser.js +1 -11
  161. package/dist/feat/feat.schema.d.ts +31 -1
  162. package/dist/feat/feat.schema.js +1 -10
  163. package/dist/feat/feat.types.d.ts +0 -6
  164. package/dist/index.js +45 -138113
  165. package/dist/inline-tag-parser.js +1 -6
  166. package/dist/item/item.actions-map.d.ts +4 -63
  167. package/dist/item/item.actions-map.js +1 -10
  168. package/dist/item/item.ai-schema.js +1 -6
  169. package/dist/item/item.attunement.d.ts +0 -14
  170. package/dist/item/item.attunement.js +1 -6
  171. package/dist/item/item.bonuses.js +1 -10
  172. package/dist/item/item.codec.js +1 -9
  173. package/dist/item/item.conditions.d.ts +0 -7
  174. package/dist/item/item.conditions.js +1 -11
  175. package/dist/item/item.conditions.types.d.ts +0 -2
  176. package/dist/item/item.cost.js +1 -29
  177. package/dist/item/item.enrichment.js +1 -9
  178. package/dist/item/item.icon.d.ts +0 -8
  179. package/dist/item/item.icon.js +1 -211
  180. package/dist/item/item.parser.js +1 -8
  181. package/dist/item/item.schema.d.ts +2 -0
  182. package/dist/item/item.schema.js +1 -11
  183. package/dist/item/item.types.d.ts +2 -28
  184. package/dist/monster/monster.ai-schema.js +1 -6
  185. package/dist/monster/monster.codec.d.ts +0 -10
  186. package/dist/monster/monster.enrichment.js +1 -19
  187. package/dist/monster/monster.format.d.ts +0 -69
  188. package/dist/monster/monster.format.js +1 -78
  189. package/dist/monster/monster.parser.d.ts +0 -4
  190. package/dist/monster/monster.parser.js +1 -15
  191. package/dist/monster/monster.resolve.d.ts +0 -4
  192. package/dist/monster/monster.schema.d.ts +0 -9
  193. package/dist/monster/monster.schema.js +1 -34
  194. package/dist/monster/monster.types.d.ts +0 -3
  195. package/dist/monster/monster.types.js +1 -1
  196. package/dist/optional-feature/optional-feature.codec.d.ts +0 -11
  197. package/dist/optional-feature/optional-feature.codec.js +1 -13
  198. package/dist/optional-feature/optional-feature.parser.js +1 -12
  199. package/dist/optional-feature/optional-feature.schema.d.ts +30 -1
  200. package/dist/optional-feature/optional-feature.schema.js +1 -15
  201. package/dist/pack.d.ts +0 -9
  202. package/dist/pc/conditions.constants.js +1 -6
  203. package/dist/pc/decision-recognizer.js +1 -8
  204. package/dist/pc/pc.additional-spells.d.ts +4 -14
  205. package/dist/pc/pc.additional-spells.js +1 -23
  206. package/dist/pc/pc.amount-bindings.d.ts +4 -20
  207. package/dist/pc/pc.amount-bindings.js +1 -23
  208. package/dist/pc/pc.asi-flatten.d.ts +0 -59
  209. package/dist/pc/pc.asi-flatten.js +1 -16
  210. package/dist/pc/pc.conditions.d.ts +1 -0
  211. package/dist/pc/pc.conditions.js +1 -6
  212. package/dist/pc/pc.containment.d.ts +0 -5
  213. package/dist/pc/pc.containment.js +1 -24
  214. package/dist/pc/pc.decision-engine.d.ts +4 -141
  215. package/dist/pc/pc.decision-engine.js +1 -52
  216. package/dist/pc/pc.defense-normalize.d.ts +0 -10
  217. package/dist/pc/pc.defense-normalize.js +1 -6
  218. package/dist/pc/pc.entry-overrides.d.ts +0 -58
  219. package/dist/pc/pc.entry-overrides.js +1 -40
  220. package/dist/pc/pc.equipment.d.ts +2 -22
  221. package/dist/pc/pc.equipment.js +1 -33
  222. package/dist/pc/pc.feature-effects.d.ts +23 -275
  223. package/dist/pc/pc.feature-effects.js +1 -26
  224. package/dist/pc/pc.formula-context.js +1 -11
  225. package/dist/pc/pc.infusions.d.ts +0 -65
  226. package/dist/pc/pc.infusions.js +1 -64
  227. package/dist/pc/pc.item-effects.d.ts +18 -0
  228. package/dist/pc/pc.member-choices.d.ts +18 -49
  229. package/dist/pc/pc.member-choices.js +1 -32
  230. package/dist/pc/pc.parser.js +1 -58
  231. package/dist/pc/pc.pools.d.ts +7 -10
  232. package/dist/pc/pc.pools.js +1 -26
  233. package/dist/pc/pc.proficiencies.d.ts +7 -33
  234. package/dist/pc/pc.proficiencies.js +1 -107
  235. package/dist/pc/pc.proficiency-grants.d.ts +0 -26
  236. package/dist/pc/pc.proficiency-normalize.d.ts +4 -25
  237. package/dist/pc/pc.proficiency-normalize.js +1 -12
  238. package/dist/pc/pc.proficiency-query.d.ts +0 -13
  239. package/dist/pc/pc.proficiency-query.js +1 -27
  240. package/dist/pc/pc.recalc.d.ts +7 -131
  241. package/dist/pc/pc.recalc.js +1 -946
  242. package/dist/pc/pc.resolver.d.ts +0 -104
  243. package/dist/pc/pc.resolver.js +1 -59
  244. package/dist/pc/pc.resource-seed.d.ts +0 -8
  245. package/dist/pc/pc.resource-seed.js +1 -42
  246. package/dist/pc/pc.resources.d.ts +1 -59
  247. package/dist/pc/pc.resources.js +1 -23
  248. package/dist/pc/pc.rest.d.ts +1 -20
  249. package/dist/pc/pc.rest.js +1 -230
  250. package/dist/pc/pc.schema.d.ts +19 -2
  251. package/dist/pc/pc.schema.js +1 -9
  252. package/dist/pc/pc.slotting.d.ts +0 -29
  253. package/dist/pc/pc.slotting.js +1 -28
  254. package/dist/pc/pc.speeds.d.ts +19 -0
  255. package/dist/pc/pc.spell-scope.d.ts +6 -0
  256. package/dist/pc/pc.spellcasting.d.ts +0 -70
  257. package/dist/pc/pc.spellcasting.js +1 -28
  258. package/dist/pc/pc.table-column.d.ts +0 -22
  259. package/dist/pc/pc.table-column.js +1 -18
  260. package/dist/pc/pc.tool-picks.d.ts +0 -27
  261. package/dist/pc/pc.tool-picks.js +1 -18
  262. package/dist/pc/pc.types.d.ts +85 -344
  263. package/dist/pc/pc.weapon-grant.d.ts +0 -6
  264. package/dist/pc/pool-layout.d.ts +0 -39
  265. package/dist/pc/pool-layout.js +1 -18
  266. package/dist/pc/resource-equivalents.d.ts +2 -40
  267. package/dist/pc/roll-scope.js +1 -8
  268. package/dist/pc/roll-tag-labels.d.ts +0 -32
  269. package/dist/pc/roll-tag-labels.js +1 -17
  270. package/dist/pc/spell-source.d.ts +0 -11
  271. package/dist/pc/spell-source.js +1 -8
  272. package/dist/race/race.codec.d.ts +0 -6
  273. package/dist/race/race.codec.js +1 -15
  274. package/dist/race/race.parser.js +1 -14
  275. package/dist/race/race.schema.d.ts +0 -8
  276. package/dist/race/race.schema.js +1 -14
  277. package/dist/race/race.structural.d.ts +0 -6
  278. package/dist/race/race.structural.js +1 -6
  279. package/dist/race/race.types.d.ts +0 -8
  280. package/dist/schemas/attack-schema.d.ts +5 -0
  281. package/dist/schemas/caster-type-schema.d.ts +1 -6
  282. package/dist/schemas/caster-type-schema.js +1 -6
  283. package/dist/schemas/choice-schema.js +1 -7
  284. package/dist/schemas/duration-schema.d.ts +0 -2
  285. package/dist/schemas/duration-schema.js +1 -6
  286. package/dist/schemas/entity-extras-schema.d.ts +0 -30
  287. package/dist/schemas/entity-extras-schema.js +1 -10
  288. package/dist/schemas/equipment-grant-schema.d.ts +0 -2
  289. package/dist/schemas/equipment-grant-schema.js +1 -12
  290. package/dist/schemas/feature-alias.d.ts +0 -27
  291. package/dist/schemas/feature-effect-schema.d.ts +30 -1
  292. package/dist/schemas/feature-effect-schema.js +1 -6
  293. package/dist/schemas/feature-schema.d.ts +0 -6
  294. package/dist/schemas/feature-schema.js +1 -12
  295. package/dist/schemas/resource-schema.d.ts +1 -34
  296. package/dist/schemas/resource-schema.js +1 -12
  297. package/dist/schemas/selection-pool-schema.js +1 -10
  298. package/dist/spell/casting-time.d.ts +0 -15
  299. package/dist/spell/casting-time.js +1 -6
  300. package/dist/spell/spell.access.d.ts +0 -6
  301. package/dist/spell/spell.access.js +1 -45
  302. package/dist/spell/spell.ai-schema.js +1 -6
  303. package/dist/spell/spell.codec.js +1 -9
  304. package/dist/spell/spell.enrichment.js +1 -9
  305. package/dist/spell/spell.filter.d.ts +0 -5
  306. package/dist/spell/spell.filter.js +1 -75
  307. package/dist/spell/spell.parser.d.ts +0 -31
  308. package/dist/spell/spell.parser.js +1 -16
  309. package/dist/spell/spell.scaling.d.ts +0 -46
  310. package/dist/spell/spell.scaling.js +1 -79
  311. package/dist/spell/spell.schema.js +1 -7
  312. package/dist/spell/spell.types.d.ts +0 -7
  313. package/dist/srd/retired-items.d.ts +0 -4
  314. package/dist/srd/retired-items.js +1 -11
  315. package/dist/srd-store.d.ts +0 -33
  316. package/dist/subclass/subclass.codec.d.ts +0 -8
  317. package/dist/subclass/subclass.codec.js +1 -17
  318. package/dist/subclass/subclass.parser.js +1 -16
  319. package/dist/subclass/subclass.schema.d.ts +2 -1
  320. package/dist/subclass/subclass.schema.js +1 -14
  321. package/dist/subclass/subclass.types.d.ts +0 -3
  322. package/dist/types/attack.d.ts +2 -0
  323. package/dist/types/casting-option.d.ts +0 -4
  324. package/dist/types/choice.d.ts +1 -72
  325. package/dist/types/choice.js +1 -24
  326. package/dist/types/edition.d.ts +0 -3
  327. package/dist/types/equipment-grant.d.ts +1 -27
  328. package/dist/types/equipment-grant.js +1 -12
  329. package/dist/types/feature-effect.d.ts +14 -14
  330. package/dist/types/feature.d.ts +0 -22
  331. package/dist/types/optional-feature.types.d.ts +1 -31
  332. package/dist/types/resource.d.ts +1 -21
  333. package/dist/types/selection-pool.d.ts +0 -24
  334. package/dist/weapon/weapon-mastery.d.ts +0 -1
  335. package/dist/weapon/weapon.classify.d.ts +0 -11
  336. package/dist/weapon/weapon.classify.js +1 -7
  337. package/dist/weapon/weapon.codec.d.ts +0 -9
  338. package/dist/weapon/weapon.codec.js +1 -9
  339. package/dist/weapon/weapon.parser.js +1 -8
  340. package/dist/weapon/weapon.schema.js +1 -7
  341. package/dist/weapon/weapon.types.d.ts +0 -3
  342. package/package.json +3 -3
  343. package/src/data-srd/ATTRIBUTION.md +1 -1
  344. package/dist/chunk-2FRUSVZS.js +0 -489
  345. package/dist/chunk-2JSQE3DD.js +0 -206
  346. package/dist/chunk-2LULMQTF.js +0 -14
  347. package/dist/chunk-2UDSN6VW.js +0 -18
  348. package/dist/chunk-3LWMFYKS.js +0 -57
  349. package/dist/chunk-3MGQFFNE.js +0 -110
  350. package/dist/chunk-3TM34RSJ.js +0 -23
  351. package/dist/chunk-3VZZDKRA.js +0 -1014
  352. package/dist/chunk-4U55VNC7.js +0 -22
  353. package/dist/chunk-5GKJAUMX.js +0 -59
  354. package/dist/chunk-5MXFW4O3.js +0 -71
  355. package/dist/chunk-656QCX4U.js +0 -22
  356. package/dist/chunk-6EI737IO.js +0 -19
  357. package/dist/chunk-6GNXYAYP.js +0 -25
  358. package/dist/chunk-6PXTNCBP.js +0 -133
  359. package/dist/chunk-6X2NV665.js +0 -33
  360. package/dist/chunk-7ATNGKBS.js +0 -178
  361. package/dist/chunk-7Q2VPKCD.js +0 -181
  362. package/dist/chunk-7QN7XSAK.js +0 -19
  363. package/dist/chunk-A54HHCWW.js +0 -67
  364. package/dist/chunk-AZRGFUSR.js +0 -18
  365. package/dist/chunk-B3DP42OM.js +0 -55
  366. package/dist/chunk-CJYCVNW2.js +0 -7
  367. package/dist/chunk-CM5CWO4K.js +0 -735
  368. package/dist/chunk-DEEHHLAP.js +0 -271
  369. package/dist/chunk-DOXSFYLH.js +0 -158
  370. package/dist/chunk-DPUJDOKV.js +0 -365
  371. package/dist/chunk-EJP263OP.js +0 -186
  372. package/dist/chunk-EVMUJYUD.js +0 -195
  373. package/dist/chunk-EYX4JMAU.js +0 -101
  374. package/dist/chunk-FANQVQ3D.js +0 -89
  375. package/dist/chunk-FC4IGH5Y.js +0 -18
  376. package/dist/chunk-G6MHJDVT.js +0 -41
  377. package/dist/chunk-G6PBI2BU.js +0 -18
  378. package/dist/chunk-H5PTKYXL.js +0 -101
  379. package/dist/chunk-HHBD4SQ6.js +0 -24
  380. package/dist/chunk-HS6FIOLP.js +0 -52
  381. package/dist/chunk-HTYMW5CH.js +0 -228
  382. package/dist/chunk-IHE6KVC3.js +0 -13
  383. package/dist/chunk-IN4M4X7P.js +0 -34
  384. package/dist/chunk-IUAAXXNO.js +0 -58
  385. package/dist/chunk-JCMUVZIK.js +0 -133
  386. package/dist/chunk-JSM6JFZR.js +0 -709
  387. package/dist/chunk-K5NJBTE2.js +0 -18
  388. package/dist/chunk-KR6JF3BF.js +0 -14
  389. package/dist/chunk-KSTV7J2U.js +0 -112
  390. package/dist/chunk-KU3YLF6D.js +0 -106
  391. package/dist/chunk-LBEXLN6I.js +0 -91
  392. package/dist/chunk-LF5AGJA4.js +0 -81
  393. package/dist/chunk-LHZXYFBU.js +0 -94
  394. package/dist/chunk-LSLSG67V.js +0 -31
  395. package/dist/chunk-LVQLWRCU.js +0 -15
  396. package/dist/chunk-MBX25B6D.js +0 -18
  397. package/dist/chunk-MYY2C5MB.js +0 -233
  398. package/dist/chunk-OFCSP6MT.js +0 -23
  399. package/dist/chunk-ONTGZR5T.js +0 -1806
  400. package/dist/chunk-OOSRUJBI.js +0 -19
  401. package/dist/chunk-PDJSUH24.js +0 -110
  402. package/dist/chunk-PKX6TGRE.js +0 -93
  403. package/dist/chunk-PQZ4LM4Z.js +0 -19
  404. package/dist/chunk-PTXBIDG7.js +0 -63
  405. package/dist/chunk-PVCEA4HZ.js +0 -6
  406. package/dist/chunk-PXVNAY7T.js +0 -84
  407. package/dist/chunk-QH36K2PU.js +0 -158
  408. package/dist/chunk-QS5L5YTJ.js +0 -24
  409. package/dist/chunk-QYZV2MQA.js +0 -97
  410. package/dist/chunk-QZSWN2KT.js +0 -18
  411. package/dist/chunk-RLGQ5PZZ.js +0 -16
  412. package/dist/chunk-RYLXAYIQ.js +0 -18
  413. package/dist/chunk-S3YUXDSC.js +0 -278
  414. package/dist/chunk-S7REMWW4.js +0 -21
  415. package/dist/chunk-T6QIF5XR.js +0 -348
  416. package/dist/chunk-TOM66P2P.js +0 -38
  417. package/dist/chunk-TULQ4FFX.js +0 -353
  418. package/dist/chunk-UA5KS2PL.js +0 -26
  419. package/dist/chunk-UUBJCNQU.js +0 -187
  420. package/dist/chunk-UZXG6QSY.js +0 -58
  421. package/dist/chunk-VPYBK2MG.js +0 -18
  422. package/dist/chunk-VRV3NNTA.js +0 -161
  423. package/dist/chunk-VTTA2ALZ.js +0 -16
  424. package/dist/chunk-W6GC6OKK.js +0 -16
  425. package/dist/chunk-WELIKLZF.js +0 -256
  426. package/dist/chunk-WSVMLNTO.js +0 -31
  427. package/dist/chunk-WYGD2UGN.js +0 -14
  428. package/dist/chunk-XCFC7LGF.js +0 -122
  429. package/dist/chunk-XJ2F2WO6.js +0 -8
  430. package/dist/chunk-Y5VVP73C.js +0 -23
  431. package/dist/chunk-YBLDE5CG.js +0 -42
  432. package/dist/chunk-YD2VAHA6.js +0 -159
  433. package/dist/chunk-YDGMBMYI.js +0 -25
  434. package/dist/chunk-YHYTW5QA.js +0 -20
  435. package/dist/chunk-YKL6SHRJ.js +0 -23
  436. package/dist/chunk-ZCTUYGNV.js +0 -26
  437. package/dist/chunk-ZDAEGJH4.js +0 -102
  438. package/dist/chunk-ZJXSXVFP.js +0 -58
  439. package/dist/chunk-ZUQW5VBZ.js +0 -89
package/LICENSE CHANGED
@@ -1,21 +1,48 @@
1
- MIT License
2
-
3
- Copyright (c) 2025-2026 Archivist
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ @archivist-gg/dnd5e Freeware Licence
2
+
3
+ Copyright (c) 2025-2026 Shinoobi. All rights reserved.
4
+
5
+ This licence applies to the @archivist-gg/dnd5e package as published to the npm registry:
6
+ its dist folder and the documentation that comes with it, from version 0.3.24 on ("the
7
+ Software"). Versions released before 0.3.24 stay under the licence they were released with
8
+ (0.3.19 and earlier: the MIT License for the code).
9
+
10
+ 1. What you may do
11
+
12
+ You may download, install and use the Software free of charge, for any lawful purpose, on
13
+ as many devices as you like. You may keep backup copies for your own use.
14
+
15
+ 2. What you may not do
16
+
17
+ Unless the copyright holder has given you written permission, you may not:
18
+
19
+ (a) modify, adapt or translate the Software, or build other works on it;
20
+ (b) sell, rent, lease or sublicense the Software, or charge anyone for it;
21
+ (c) redistribute, publish or host copies of the Software, on their own or as part of
22
+ anything else. Point people to the official download instead.
23
+
24
+ 3. Third-party material
25
+
26
+ The Software contains content from the System Reference Document 5.1 and 5.2 by Wizards of
27
+ the Coast LLC, licensed under the Creative Commons Attribution 4.0 International License
28
+ (CC-BY-4.0); see LICENSES/SRD.md for the attribution. The libraries the package depends on
29
+ (@archivist-gg/core, js-yaml, zod) are installed separately, under their own licences. That
30
+ material stays under its own licence. Nothing in this licence limits the rights that licence
31
+ gives you, and where the two differ for that material, its own licence applies.
32
+
33
+ 4. No warranty
34
+
35
+ The Software is provided "as is", without warranty of any kind, express or implied,
36
+ including the warranties of merchantability, fitness for a particular purpose and
37
+ non-infringement.
38
+
39
+ 5. Limitation of liability
40
+
41
+ In no event shall the copyright holder be liable for any claim, damages or other liability,
42
+ whether in an action of contract, tort or otherwise, arising from, out of or in connection
43
+ with the Software or its use.
44
+
45
+ 6. End of this permission
46
+
47
+ This permission ends automatically if you break these terms. When it ends, you must stop
48
+ using the Software and delete your copies.
package/README.md CHANGED
@@ -1,65 +1,43 @@
1
1
  # @archivist-gg/dnd5e
2
2
 
3
- The D&D 5e (2014 & 2024) rules pack for Archivist: parsers, schemas, codecs, and
4
- types for every entity type, the dice/formula/tag machinery, the player-character
5
- engine, and the bundled SRD content. Built on [`@archivist-gg/core`](https://github.com/archivist-gg/archivist-core).
3
+ The D&D 5e (2014 and 2024) rules pack of Archivist, the D&D toolkit for Obsidian: parsers,
4
+ schemas, codecs and types for every entity type, the dice, formula and tag machinery, the
5
+ player-character engine, and the bundled SRD content. Built on `@archivist-gg/core`.
6
6
 
7
7
  ## What's inside
8
8
 
9
- - **Entity types** — armor, background, class, subclass, race, feat,
10
- optional-feature, item, weapon, monster, npc, and spell. Each has a parser, a
11
- [zod](https://zod.dev) schema, a codec, and TypeScript types, exposed as
12
- `@archivist-gg/dnd5e/<entity>/*` subpath exports.
13
- - **Rules engine** (`dnd/*`) — ability math, proficiency/XP, the formula and
14
- inline-tag grammar, resource dice, and SRD tag conversion.
15
- - **Player characters** (`pc/*`) — parse → resolve → recalc a character into
16
- derived stats (AC, saves, skills, attacks, spellcasting, resources, rest), plus
17
- the decision engine, equipment/slotting, and conditions.
18
- - **SRD data** — System Reference Document 5.1 and 5.2 as `.md` sources plus
19
- canonical/runtime JSON, loadable through `srd-store`.
9
+ - **Entity types**: armor, background, class, subclass, race, feat, optional-feature, item,
10
+ weapon, monster, npc and spell. Each has a parser, a [zod](https://zod.dev) schema, a codec and
11
+ TypeScript types, exposed as `@archivist-gg/dnd5e/<entity>/*` subpath exports.
12
+ - **Rules engine** (`dnd/*`): ability math, proficiency and XP, the formula and inline-tag
13
+ grammar, resource dice, and brace-tag conversion.
14
+ - **Player characters** (`pc/*`): parse, resolve and recalc a character into derived stats (AC,
15
+ saves, skills, speeds, attacks, spellcasting, resources, rests), plus the decision engine,
16
+ equipment and slotting, item benefits and conditions.
17
+ - **SRD data**: the System Reference Document 5.1 and 5.2, loadable through `srd-store`.
20
18
 
21
- Common entry points are re-exported from the package root; everything else is
22
- available via subpath exports.
19
+ Common entry points are re-exported from the package root; everything else is available through
20
+ subpath exports.
23
21
 
24
- ## Usage
22
+ ## Install
25
23
 
26
- Distributed as TypeScript source (no build step). It depends on `@archivist-gg/core`
27
- via a sibling path dependency, so clone both repos side by side:
28
-
29
- ```
30
- archivist-core/
31
- archivist-dnd5e/
32
- ```
33
-
34
- ```jsonc
35
- // package.json
36
- "dependencies": {
37
- "@archivist-gg/core": "file:../archivist-core",
38
- "@archivist-gg/dnd5e": "file:../archivist-dnd5e"
39
- }
24
+ ```sh
25
+ npm install @archivist-gg/dnd5e
40
26
  ```
41
27
 
42
- Running `npm install` in `archivist-dnd5e` then resolves the sibling.
28
+ It brings `@archivist-gg/core`, `js-yaml` and `zod` with it.
43
29
 
44
30
  ```ts
45
31
  import { parseMonster, dnd5ePack } from "@archivist-gg/dnd5e";
46
32
  import { parsePC } from "@archivist-gg/dnd5e/pc/pc.parser";
47
33
  ```
48
34
 
49
- ## Scripts
50
-
51
- - `npm run typecheck` — type-check the pack and its tools.
52
- - `npm test` — run the test suite with vitest (regenerates the SRD md-index first).
53
- - `npm run generate` — regenerate `src/data-srd/index.generated.ts` from the `.md` sources.
54
- - `npm run build:srd-canonical[:refresh]` — dev tool that rebuilds the canonical SRD
55
- JSON from an external 5etools structured-rules dump (`STRUCTURED_RULES_PATH`). Not
56
- part of the test gate; the committed `src/srd/data/{canonical,runtime}` JSON is the
57
- consumer contract.
58
-
59
- ## License
35
+ ## Licence
60
36
 
61
- - **Code:** MIT — see [LICENSE](./LICENSE).
62
- - **Bundled SRD data** (`src/srd/data/`, `src/data-srd/`): System Reference Document
63
- 5.1 and 5.2 by Wizards of the Coast LLC, licensed under
64
- [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). See
65
- [LICENSES/SRD.md](./LICENSES/SRD.md).
37
+ - **The package:** from version 0.3.24 on, freeware: copyright Shinoobi, all rights reserved, free
38
+ to download and use, but you may not modify, sell or redistribute it. See [LICENSE](./LICENSE).
39
+ Versions up to 0.3.19 were published under the MIT License. The source code is not public.
40
+ - **The bundled SRD data:** System Reference Document 5.1 and 5.2 by Wizards of the Coast LLC,
41
+ licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). The
42
+ package's licence does not restrict it. See [LICENSES/SRD.md](./LICENSES/SRD.md) for the
43
+ attribution.
@@ -1,10 +1,3 @@
1
1
  import type { DocCodec } from "@archivist-gg/core";
2
2
  import type { ArmorEntity } from "./armor.types.js";
3
- /**
4
- * Normalizing codec (0c.1a). `parse` delegates to `parseArmor`, which validates
5
- * against `armorEntitySchema` (injecting the `ac.flat`/`ac.add_con`/`ac.add_wis`
6
- * defaults) and captures any unknown top-level keys into `entity.raw`.
7
- * `serialize` stays `yaml.dump` (the edit-save path uses obsidian's separate
8
- * serializer; gate (d) verifies `yaml.dump` round-trips through `parseArmor`).
9
- */
10
3
  export declare const armorCodec: DocCodec<ArmorEntity>;
@@ -1,9 +1 @@
1
- import {
2
- armorCodec
3
- } from "../chunk-FC4IGH5Y.js";
4
- import "../chunk-UZXG6QSY.js";
5
- import "../chunk-HS6FIOLP.js";
6
- import "../chunk-UA5KS2PL.js";
7
- export {
8
- armorCodec
9
- };
1
+ import{armorCodec}from"../chunk-AINRPPLH.js";import"../chunk-O2QZ73GA.js";import"../chunk-RE5Z5RNK.js";import"../chunk-I26FHSI6.js";export{armorCodec};
@@ -1,8 +1 @@
1
- import {
2
- parseArmor
3
- } from "../chunk-UZXG6QSY.js";
4
- import "../chunk-HS6FIOLP.js";
5
- import "../chunk-UA5KS2PL.js";
6
- export {
7
- parseArmor
8
- };
1
+ import{parseArmor}from"../chunk-O2QZ73GA.js";import"../chunk-RE5Z5RNK.js";import"../chunk-I26FHSI6.js";export{parseArmor};
@@ -1,7 +1 @@
1
- import {
2
- armorEntitySchema
3
- } from "../chunk-HS6FIOLP.js";
4
- import "../chunk-UA5KS2PL.js";
5
- export {
6
- armorEntitySchema
7
- };
1
+ import{armorEntitySchema}from"../chunk-RE5Z5RNK.js";import"../chunk-I26FHSI6.js";export{armorEntitySchema};
@@ -24,13 +24,10 @@ export interface ArmorEntity {
24
24
  page?: number;
25
25
  edition?: "2014" | "2024" | string;
26
26
  entries?: unknown[];
27
- /** Carried as the empty string on every converter armor carrier today (27). */
28
27
  rendering_hint?: string;
29
- /** The icon key (I3): a key of the renderer's icon set or a Lucide name. */
30
28
  icon?: string;
31
29
  has_fluff?: boolean;
32
30
  has_fluff_images?: boolean;
33
- /** One wikilink, or an array for >= 2 fluff images (images-ON emit). */
34
31
  image?: z.infer<typeof imageField>;
35
32
  raw?: Record<string, unknown>;
36
33
  }
@@ -1,9 +1,3 @@
1
1
  import type { DocCodec } from "@archivist-gg/core";
2
2
  import type { BackgroundEntity } from "./background.types.js";
3
- /**
4
- * Normalizing codec (0c.1a). `parse` delegates to `parseBackground`, which seeds
5
- * the `edition: "2014"` default and validates against `backgroundEntitySchema`.
6
- * `serialize` stays `yaml.dump` (the edit-save path uses obsidian's separate
7
- * serializer; gate (d) verifies `yaml.dump` round-trips through `parseBackground`).
8
- */
9
3
  export declare const backgroundCodec: DocCodec<BackgroundEntity>;
@@ -1,12 +1 @@
1
- import {
2
- backgroundCodec
3
- } from "../chunk-2UDSN6VW.js";
4
- import "../chunk-6EI737IO.js";
5
- import "../chunk-3MGQFFNE.js";
6
- import "../chunk-IN4M4X7P.js";
7
- import "../chunk-5MXFW4O3.js";
8
- import "../chunk-2JSQE3DD.js";
9
- import "../chunk-UA5KS2PL.js";
10
- export {
11
- backgroundCodec
12
- };
1
+ import{backgroundCodec}from"../chunk-WUHTSLG4.js";import"../chunk-KZDDFG4O.js";import"../chunk-N3RYJ7RE.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{backgroundCodec};
@@ -1,11 +1 @@
1
- import {
2
- parseBackground
3
- } from "../chunk-6EI737IO.js";
4
- import "../chunk-3MGQFFNE.js";
5
- import "../chunk-IN4M4X7P.js";
6
- import "../chunk-5MXFW4O3.js";
7
- import "../chunk-2JSQE3DD.js";
8
- import "../chunk-UA5KS2PL.js";
9
- export {
10
- parseBackground
11
- };
1
+ import{parseBackground}from"../chunk-KZDDFG4O.js";import"../chunk-N3RYJ7RE.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{parseBackground};
@@ -1,12 +1 @@
1
- import {
2
- backgroundEntitySchema,
3
- langProfSchema
4
- } from "../chunk-3MGQFFNE.js";
5
- import "../chunk-IN4M4X7P.js";
6
- import "../chunk-5MXFW4O3.js";
7
- import "../chunk-2JSQE3DD.js";
8
- import "../chunk-UA5KS2PL.js";
9
- export {
10
- backgroundEntitySchema,
11
- langProfSchema
12
- };
1
+ import{backgroundEntitySchema,langProfSchema}from"../chunk-N3RYJ7RE.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{backgroundEntitySchema,langProfSchema};
@@ -50,11 +50,8 @@ export interface BackgroundEntity {
50
50
  origin_feat: string | null;
51
51
  suggested_characteristics: SuggestedCharacteristics | null;
52
52
  choices?: Choice[];
53
- /** Converter/bundle extras declared by background.schema.ts §2.6; all optional, none read today. */
54
53
  rendering_hint?: string;
55
54
  has_fluff_images?: boolean;
56
- /** 88 roll tables over 67 docs; `roll` is a STRING on every row ("1", "2-3"). Render is G3b's
57
- * (the 2026-09-02 G3 split; G3a renders no background tables). */
58
55
  tables?: Array<{
59
56
  name: string;
60
57
  dice: string;
@@ -64,11 +61,9 @@ export interface BackgroundEntity {
64
61
  }>;
65
62
  }>;
66
63
  additional_spells?: AdditionalSpellsEntry[];
67
- /** The kind is CLOSED at the converter's only push site (background-mapper.ts). */
68
64
  prerequisites?: Array<{
69
65
  kind: "campaign";
70
66
  slug: string;
71
67
  }>;
72
- /** One wikilink, or an array of them for the multi-fluff-image emit. */
73
68
  image?: string | string[];
74
69
  }
@@ -0,0 +1 @@
1
+ function isCategoryGrant(g){return!!g&&typeof g==="object"&&typeof g.category==="string"&&g.category.length>0}var equipmentCategoryKey=(i,j,k)=>`equipment-${i}-opt-${j}-cat-${k}`;var equipmentCategoryKeys=(grants,i,j)=>grants.flatMap((g,k)=>isCategoryGrant(g)?[equipmentCategoryKey(i,j,k)]:[]);var isStartingEquipmentKey=key=>key.startsWith("equipment-");export{isCategoryGrant,equipmentCategoryKey,equipmentCategoryKeys,isStartingEquipmentKey};
@@ -0,0 +1 @@
1
+ var TAG_TYPE_ALIASES={atk:"atk",attack:"atk",dmg:"dmg",damage:"dmg",dc:"dc",dice:"dice"};function normalizeTagType(input){var _a;const lower=input.toLowerCase().trim();return(_a=TAG_TYPE_ALIASES[lower])!=null?_a:null}var ABILITY_RE=/^(str|dex|con|int|wis|cha)$/i;var PB_RE=/^pb$/i;var DICE_RE=/^(\d+)d(\d+)$/;var LITERAL_RE=/^([+-]?\d+)$/;var SLUG_RE=/^\[\[([^[\]]+)\]\]$/;function parseTagTerms(content){const out={pbTerm:false,literalTerms:[],diceTerms:[],slugTerms:[]};const trimmed=content.trim();if(trimmed.length===0)return{error:"empty content"};const tokens=[];let i=0;const advancePastTerm=start=>{let j=start;while(j<trimmed.length&&trimmed[j]!=="+"&&trimmed[j]!=="-"){if(trimmed[j]==="["&&trimmed[j+1]==="["){const close=trimmed.indexOf("]]",j+2);if(close===-1)return trimmed.length;j=close+2;continue}j++}return j};while(i<trimmed.length){if(trimmed[i]==="+"||trimmed[i]==="-"){const j=advancePastTerm(i+1);tokens.push(trimmed.slice(i,j));i=j}else{const j=advancePastTerm(i);tokens.push(trimmed.slice(i,j));i=j}}for(let raw of tokens){raw=raw.trim();if(raw.length===0)return{error:"empty term"};let signed=raw;let body=raw;if(raw[0]==="+"||raw[0]==="-"){body=raw.slice(1).trim()}else{signed="+"+raw}if(DICE_RE.test(body)){const m=body.match(DICE_RE);out.diceTerms.push({count:Number.parseInt(m[1],10),sides:Number.parseInt(m[2],10)});continue}if(ABILITY_RE.test(body)){if(out.abilityTerm)return{error:`multiple ability terms (${out.abilityTerm}, ${body.toLowerCase()})`};out.abilityTerm=body.toLowerCase();continue}if(PB_RE.test(body)){if(out.pbTerm)return{error:"duplicate PB term"};out.pbTerm=true;continue}const slugMatch=body.match(SLUG_RE);if(slugMatch){out.slugTerms.push(slugMatch[1]);continue}if(LITERAL_RE.test(signed)){out.literalTerms.push(Number.parseInt(signed,10));continue}return{error:`unrecognized term: ${raw}`}}return out}export{normalizeTagType,parseTagTerms};
@@ -0,0 +1 @@
1
+ import{parseFeat}from"./chunk-IOCJIWCV.js";import yaml from"js-yaml";var featCodec={parse(doc){return parseFeat(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{featCodec};
@@ -0,0 +1 @@
1
+ import{STATIC_FALLBACK_CONTEXT,convertDescToTags}from"./chunk-MGGKZGLG.js";function enrichSpell(raw){var _a,_b,_c,_d;const duration=raw.duration;const concentration=(_b=raw.concentration)!=null?_b:(_a=duration==null?void 0:duration.toLowerCase().includes("concentration"))!=null?_a:false;const classes=((_c=raw.classes)==null?void 0:_c.length)?raw.classes:["Wizard","Sorcerer"];const enriched={...raw,concentration,ritual:(_d=raw.ritual)!=null?_d:false,classes};if(typeof enriched.description==="string"){enriched.description=convertDescToTags(enriched.description,STATIC_FALLBACK_CONTEXT)}if(Array.isArray(enriched.at_higher_levels)){enriched.at_higher_levels=enriched.at_higher_levels.map(p=>convertDescToTags(p,STATIC_FALLBACK_CONTEXT))}return enriched}export{enrichSpell};
@@ -0,0 +1 @@
1
+ import{actionCostEnum,resourceSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}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 categoryEnum=z.enum(["origin","general","fighting-style","epic-boon"]);var prerequisiteSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("ability"),ability:abilityEnum,min:z.number().int().positive()}),z.object({kind:z.literal("level"),min:z.number().int().positive()}),z.object({kind:z.literal("spellcaster")}),z.object({kind:z.literal("proficiency"),proficiency_type:z.enum(["armor","weapon","tool","skill","saving-throw"]),value:z.string().min(1)}),z.object({kind:z.literal("race"),slug:z.string().min(1)}),z.object({kind:z.literal("class"),slug:z.string().min(1)}),z.object({kind:z.literal("feat"),slug:z.string().min(1)}),z.object({kind:z.literal("campaign"),slug:z.string().min(1)}),z.object({kind:z.literal("exclusive-feat-category"),slug:z.string().min(1)}),z.object({kind:z.literal("feature"),slug:z.string().min(1)}),z.object({kind:z.literal("other"),detail:z.string().min(1)}),z.object({kind:z.literal("feat-category"),slug:z.string().min(1)}),z.object({kind:z.literal("background"),slug:z.string().min(1)})]);var featEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),category:categoryEnum,description:z.string(),prerequisites:z.array(prerequisiteSchema),benefits:z.array(z.string()),effects:z.array(featureEffectSchema),grants_asi:z.object({amount:z.number().int().positive(),pool:z.array(abilityEnum).optional()}).nullable(),repeatable:z.boolean(),choices:z.array(choiceSchema),rendering_hint:z.string().optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),trait_tags:z.unknown().optional(),optionalfeature_progression:z.array(progressionSchema).optional(),resources:z.array(resourceSchema).optional(),action_cost:actionCostEnum.optional(),image:imageField});export{featEntitySchema};
@@ -0,0 +1 @@
1
+ var DECISION_SIGNAL=[/\bchoose (one|two|three|a|an)\b/i,/\bof your choice\b/i,/\byour choice of\b/i];var ASI_FEAT={kind:"select-entity",id:"feat",entity_type:"feat",count:1};var TABLE={"ability-score-improvement":[ASI_FEAT],"expertise":[{kind:"select-proficiency",id:"expertise",count:2,domain:"skill",from_proficient:true,expertise:true}],"fighting-style":[{kind:"select-entity",id:"fighting-style",count:1,entity_type:"optional-feature",where:{feature_type:"fighting_style",available_to:"self"}}]};function recognizeDecision(feature){var _a,_b;const slug=((_a=feature.id)!=null?_a:feature.name).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-|-$)/g,"");if(TABLE[slug])return TABLE[slug];const desc=(_b=feature.description)!=null?_b:"";return DECISION_SIGNAL.some(re=>re.test(desc))?"informational":null}export{DECISION_SIGNAL,recognizeDecision};
@@ -0,0 +1 @@
1
+ var FEAT_CATEGORY_CODE_LABELS={D:"Dragonmark",G:"General",O:"Origin",FS:"Fighting Style",EB:"Epic Boon",DG:"Dark Gift","FS:P":"Fighting Style","FS:R":"Fighting Style"};function featCategoryLabel(code){var _a;return(_a=FEAT_CATEGORY_CODE_LABELS[code])!=null?_a:code}var FEAT_PROGRESSION_CATEGORY={FS:"fighting-style","FS:P":"fighting-style","FS:R":"fighting-style",EB:"epic-boon",O:"origin",G:"general"};function featCategoryOf(value){const v=value.trim();if(Object.prototype.hasOwnProperty.call(FEAT_PROGRESSION_CATEGORY,v))return FEAT_PROGRESSION_CATEGORY[v];const upper=v.toUpperCase();if(Object.prototype.hasOwnProperty.call(FEAT_PROGRESSION_CATEGORY,upper))return FEAT_PROGRESSION_CATEGORY[upper];return v.toLowerCase()}var FEATURE_TYPE_FOR_CATEGORY={"fighting-style":"fighting_style"};function featProgressionCategory(codes){for(const code of codes!=null?codes:[]){if(Object.prototype.hasOwnProperty.call(FEAT_PROGRESSION_CATEGORY,code)){return FEAT_PROGRESSION_CATEGORY[code]}}return void 0}export{FEAT_CATEGORY_CODE_LABELS,featCategoryLabel,FEAT_PROGRESSION_CATEGORY,featCategoryOf,FEATURE_TYPE_FOR_CATEGORY,featProgressionCategory};
@@ -0,0 +1 @@
1
+ import{resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bareEntitySlug,slugify,wikilinkTailSlug}from"./chunk-63YJPWTM.js";function nonEmptyRef(v){return typeof v==="string"&&v.length>0?v:null}function isContainerItem(entity){if(!entity||typeof entity!=="object")return false;const c=entity.container;if(!c||typeof c!=="object")return false;const container=c;if(typeof container.holds_items==="boolean")return container.holds_items;if(typeof container.capacity_weight==="number"&&container.capacity_weight>0)return true;const cap=container.capacity;if(!cap||typeof cap!=="object")return false;const k=cap;if(Array.isArray(k.weight)&&k.weight.length>0)return true;if(Array.isArray(k.item)&&k.item.length>0)return true;return k.weightless===true}function idOwners(equipment){const ownerOfId=new Map;const duplicateIds=[];equipment.forEach((entry,i)=>{const id=nonEmptyRef(entry.id);if(id===null)return;if(ownerOfId.has(id))duplicateIds.push(i);else ownerOfId.set(id,i)});return{ownerOfId,duplicateIds}}function entityOfEntry(entry,registry){var _a,_b;if(!registry)return null;return(_b=(_a=resolveBaseItem(entry.item,registry))==null?void 0:_a.data)!=null?_b:null}function resolveContainment(equipment,registry){const n=equipment.length;const{ownerOfId,duplicateIds}=idOwners(equipment);const entities=equipment.map(entry=>entityOfEntry(entry,registry));const isContainer=entities.map(entity=>isContainerItem(entity));const parentOf=new Array(n).fill(null);const broken=[];const closesCycle=(child,owner)=>{for(let cur=owner;cur!==null;cur=parentOf[cur])if(cur===child)return true;return false};for(let i=0;i<n;i++){const target=nonEmptyRef(equipment[i].in);if(target===null)continue;const owner=ownerOfId.get(target);let reason=null;if(equipment[i].equipped===true)reason="equipped";else if(owner===void 0)reason="missing";else if(owner===i)reason="self";else if(entities[owner]===null)reason="unresolved";else if(!isContainer[owner])reason="not-container";else if(closesCycle(i,owner))reason="cycle";if(reason!==null){broken.push({index:i,reason});continue}parentOf[i]=owner}const childrenOf=Array.from({length:n},()=>[]);parentOf.forEach((p,i)=>{if(p!==null)childrenOf[p].push(i)});return{parentOf,childrenOf,isContainer,ownerOfId,duplicateIds,broken}}function mintBase(entry,registry){var _a,_b,_c;const found=registry?resolveBaseItem(entry.item,registry):null;const byName=found?slugify((_a=found.name)!=null?_a:""):"";if(byName)return byName;const inner=(_c=(_b=/^\[\[(.+?)\]\]$/.exec(entry.item.trim()))==null?void 0:_b[1])!=null?_c:entry.item.trim();const ref=inner.split("|")[0].trim();const byRef=ref.includes("/")?wikilinkTailSlug(ref):slugify(bareEntitySlug(ref));return byRef||"item"}function ensureEntryId(equipment,index,registry){const{ownerOfId}=idOwners(equipment);const own=nonEmptyRef(equipment[index].id);if(own!==null&&ownerOfId.get(own)===index)return own;const taken=new Set;for(const entry of equipment){const a=nonEmptyRef(entry.id);if(a!==null)taken.add(a);const b=nonEmptyRef(entry.in);if(b!==null)taken.add(b)}const base=mintBase(equipment[index],registry);let id=base;for(let k=2;taken.has(id);k++)id=`${base}-${k}`;equipment[index].id=id;return id}function canMoveInto(equipment,index,target,registry){var _a;const inRange=i=>Number.isInteger(i)&&i>=0&&i<equipment.length;if(!inRange(index)||target!==null&&!inRange(target))return{ok:false,reason:"out-of-range"};if(target===null)return{ok:true};if(equipment[index].equipped===true)return{ok:false,reason:"equipped"};if(target===index)return{ok:false,reason:"self"};const view=resolveContainment(equipment,registry);const unresolvedLink=new Set(view.broken.filter(b=>b.reason==="unresolved").map(b=>b.index));const seen=new Set;for(let cur=target;cur!==null&&!seen.has(cur);){if(cur===index)return{ok:false,reason:"descendant"};seen.add(cur);const up=view.parentOf[cur];if(up!==null){cur=up;continue}if(unresolvedLink.has(cur)){const raw=nonEmptyRef(equipment[cur].in);cur=raw===null?null:(_a=view.ownerOfId.get(raw))!=null?_a:null;continue}cur=null}const entity=entityOfEntry(equipment[target],registry);if(entity===null)return{ok:false,reason:"unresolved"};if(!isContainerItem(entity))return{ok:false,reason:"not-container"};return{ok:true}}function moveInto(equipment,index,target,registry){const check=canMoveInto(equipment,index,target,registry);if(!check.ok)return check;const entry=equipment[index];if(target===null){const had=entry.in!==void 0;delete entry.in;return{ok:true,changed:had}}const wasHonoured=resolveContainment(equipment,registry).parentOf[index]===target;const idBefore=equipment[target].id;const id=ensureEntryId(equipment,target,registry);entry.in=id;return{ok:true,changed:idBefore!==id||!wasHonoured}}function repairContainment(equipment,registry){if(!registry)return 0;let removed=0;for(const entry of equipment){if(entry.id===""){delete entry.id;removed++}if(entry.in===""){delete entry.in;removed++}}const view=resolveContainment(equipment,registry);for(const b of view.broken){if(b.reason==="unresolved")continue;delete equipment[b.index].in;removed++}for(const i of view.duplicateIds){delete equipment[i].id;removed++}return removed}export{nonEmptyRef,isContainerItem,idOwners,entityOfEntry,resolveContainment,ensureEntryId,canMoveInto,moveInto,repairContainment};
@@ -0,0 +1 @@
1
+ import{parseWeapon}from"./chunk-BZ6BGGZS.js";import yaml from"js-yaml";var weaponCodec={parse(doc){return parseWeapon(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{weaponCodec};
@@ -0,0 +1 @@
1
+ import{resolveBaseItem}from"./chunk-PZ4L2EEG.js";function isItemEntity(e){return!!e&&typeof e==="object"&&"rarity"in e}function isWeaponEntity(e){if(!e||typeof e!=="object")return false;if(!("damage"in e)||!("category"in e))return false;const cat=e.category;return typeof cat==="string"&&/melee|ranged/.test(cat)}function isArmorEntity(e){return!!e&&typeof e==="object"&&"ac"in e&&"category"in e&&!("damage"in e)}function resolveEntityForEntry(item,registry){const found=resolveBaseItem(item,registry);if(!found)return{entity:null,entityType:null};return{entity:found.data,entityType:found.entityType}}function isShieldArmor(armor){var _a,_b;if(armor.category==="shield")return true;const slug=((_a=armor.slug)!=null?_a:"").toLowerCase();if(slug==="shield"||slug.endsWith("_shield")||slug.endsWith("-shield"))return true;return((_b=armor.name)!=null?_b:"").trim().toLowerCase()==="shield"}function effectiveArmor(entity,registry){if(isArmorEntity(entity))return entity;if(isItemEntity(entity)&&typeof entity.base_item==="string"){const base=resolveBaseItem(entity.base_item,registry);if((base==null?void 0:base.entityType)==="armor")return base.data}return null}function effectiveWeapon(entity,registry){if(isWeaponEntity(entity))return entity;if(isItemEntity(entity)&&typeof entity.base_item==="string"){const base=resolveBaseItem(entity.base_item,registry);if((base==null?void 0:base.entityType)==="weapon"&&isWeaponEntity(base.data))return base.data}return null}function isTwoHandedWeapon(entity,registry){if(!entity||typeof entity!=="object")return false;const own=entity.properties;if(Array.isArray(own)&&own.length>0)return own.some(p=>p==="two_handed");if(!registry)return false;const weapon=effectiveWeapon(entity,registry);return!!weapon&&Array.isArray(weapon.properties)&&weapon.properties.some(p=>p==="two_handed")}function armorAcTerm(armor){var _a;return armor.ac.base+((_a=armor.ac.flat)!=null?_a:0)}function slotAcTerms(armor,entry){var _a;const bonus=(_a=entry==null?void 0:entry.overrides)==null?void 0:_a.ac_bonus;return{armor:armor?armorAcTerm(armor):null,override:typeof bonus==="number"?bonus:0}}function defaultSlotForType(entityType,entity,registry){if(entityType==="weapon")return"mainhand";if(entityType==="armor"){return isArmorEntity(entity)&&isShieldArmor(entity)?"shield":"armor"}if(entityType==="item"&&isItemEntity(entity)&&typeof entity.base_item==="string"){const base=resolveBaseItem(entity.base_item,registry);if((base==null?void 0:base.entityType)==="weapon")return"mainhand";if((base==null?void 0:base.entityType)==="armor"){const armorData=base.data;return isShieldArmor(armorData)?"shield":"armor"}}return null}export{isItemEntity,isWeaponEntity,isArmorEntity,resolveEntityForEntry,isShieldArmor,effectiveArmor,effectiveWeapon,isTwoHandedWeapon,armorAcTerm,slotAcTerms,defaultSlotForType};
@@ -0,0 +1 @@
1
+ var ALL_SKILL_SLUGS=["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"];var STANDARD_LANGUAGES=["common","dwarvish","elvish","giant","gnomish","goblin","halfling","orc"];var EXOTIC_LANGUAGES=["abyssal","celestial","deep-speech","draconic","infernal","primordial","sylvan","undercommon"];var SECRET_LANGUAGES=["druidic","thieves'-cant"];var ALL_LANGUAGES=[...STANDARD_LANGUAGES,...EXOTIC_LANGUAGES,...SECRET_LANGUAGES];var ARTISANS_TOOLS=["alchemist's-supplies","brewer's-supplies","calligrapher's-supplies","carpenter's-tools","cartographer's-tools","cobbler's-tools","cook's-utensils","glassblower's-tools","jeweler's-tools","leatherworker's-tools","mason's-tools","painter's-supplies","potter's-tools","smith's-tools","tinker's-tools","weaver's-tools","woodcarver's-tools"];var MUSICAL_INSTRUMENTS=["bagpipes","drum","dulcimer","flute","horn","lute","lyre","pan-flute","shawm","viol"];var GAMING_SETS=["dice-set","playing-cards"];var OTHER_TOOLS=["disguise-kit","forgery-kit","herbalism-kit","navigator's-tools","poisoner's-kit","thieves'-tools"];var ALL_TOOLS=[...ARTISANS_TOOLS,...MUSICAL_INSTRUMENTS,...GAMING_SETS,...OTHER_TOOLS];export{ALL_SKILL_SLUGS,STANDARD_LANGUAGES,EXOTIC_LANGUAGES,SECRET_LANGUAGES,ALL_LANGUAGES,ARTISANS_TOOLS,MUSICAL_INSTRUMENTS,GAMING_SETS,OTHER_TOOLS,ALL_TOOLS};
@@ -0,0 +1 @@
1
+ import{spellEntitySchema}from"./chunk-7EL3GWWJ.js";import{parseYaml,toStringSafe}from"@archivist-gg/core";var KNOWN_KEYS=new Set(["name","level","school","casting_time","range","components","duration","concentration","ritual","classes","description","at_higher_levels","damage","damage_roll","saving_throw","casting_options","rendering_hint","misc_tags","area_tags","condition_inflict","affects_creature_type","spell_attack","ability_check","damage_resist","damage_immune","condition_immune","damage_vulnerable","has_fluff","image","has_fluff_images","slug","edition","source"]);var DURATION_END_WORDS={dispel:"dispelled",trigger:"triggered"};function normalizeSpellComponents(value){if(typeof value==="string")return value;if(value==null||typeof value!=="object"||Array.isArray(value))return toStringSafe(value);const c=value;const parts=[];if(c.v===true)parts.push("V");if(c.s===true)parts.push("S");if(typeof c.m==="string")parts.push(`M (${c.m})`);else if(c.m===true)parts.push("M");else if(c.m!=null&&typeof c.m==="object"){const text=c.m.text;parts.push(typeof text==="string"?`M (${text})`:"M")}if(c.r===true)parts.push("R");return parts.join(", ")}function spellMaterialOf(value){if(value==null||typeof value!=="object"||Array.isArray(value))return void 0;const m=value.m;if(m==null||typeof m!=="object"||Array.isArray(m))return void 0;const{text,cost,consume}=m;if(typeof text!=="string")return void 0;return{text,...typeof cost==="number"?{cost}:{},...typeof consume==="boolean"||typeof consume==="string"?{consume}:{}}}function normalizeSpellDurationEntry(entry){if(entry==null||typeof entry!=="object")return toStringSafe(entry);const e=entry;if(e.type==="permanent"&&Array.isArray(e.ends)){return"until "+e.ends.map(w=>{var _a;return(_a=DURATION_END_WORDS[String(w)])!=null?_a:String(w)}).join(" or ")}if(e.type==="timed"&&e.duration!=null){const unit=e.duration.type;const amount=e.duration.amount;if(typeof unit==="string"&&typeof amount==="number"){const prefix=e.duration.up_to===true?"up to ":"";return`${prefix}${amount} ${unit}${amount>1?"s":""}`}}return toStringSafe(entry)}function normalizeSpellDuration(value){if(typeof value==="string")return value;if(!Array.isArray(value))return toStringSafe(value);return value.map(entry=>normalizeSpellDurationEntry(entry)).join("; ")}function mirrorSpellShapes(entity){const material=spellMaterialOf(entity.components);return{...entity,...entity.components!=null?{components:normalizeSpellComponents(entity.components)}:{},...material?{material}:{},...entity.duration!=null?{duration:normalizeSpellDuration(entity.duration)}:{}}}function parseSpell(source){const result=parseYaml(source,["name"]);if(!result.success)return result;const meta={};if(typeof result.data.source==="string")meta.source=result.data.source;if(typeof result.data.edition==="string")meta.edition=result.data.edition;const filtered={};for(const[k,v]of Object.entries(result.data)){if(k==="slug"||k==="edition"||k==="source")continue;if(!KNOWN_KEYS.has(k)){return{success:false,error:`Unknown spell field: ${k}`}}filtered[k]=v}const parsed=spellEntitySchema.safeParse(filtered);if(!parsed.success){return{success:false,error:`spell schema validation failed: ${parsed.error.message}`}}const raw=parsed.data;const spell={name:raw.name};if(raw.level!=null)spell.level=raw.level;if(raw.school!=null)spell.school=toStringSafe(raw.school);if(raw.casting_time!=null)spell.casting_time=toStringSafe(raw.casting_time);if(raw.range!=null)spell.range=toStringSafe(raw.range);if(raw.components!=null)spell.components=normalizeSpellComponents(raw.components);if(raw.duration!=null)spell.duration=normalizeSpellDuration(raw.duration);const material=spellMaterialOf(raw.components);if(material)spell.material=material;if(raw.concentration!=null)spell.concentration=Boolean(raw.concentration);if(raw.ritual!=null)spell.ritual=Boolean(raw.ritual);if(raw.classes)spell.classes=raw.classes.map(String);if(raw.description)spell.description=raw.description;if(raw.at_higher_levels)spell.at_higher_levels=raw.at_higher_levels.map(String);if(raw.damage)spell.damage={types:raw.damage.types.map(String)};if(raw.damage_roll!=null)spell.damage_roll=raw.damage_roll;if(raw.saving_throw)spell.saving_throw={ability:raw.saving_throw.ability};if(raw.casting_options){spell.casting_options=raw.casting_options.map(opt=>{const co={type:opt.type};if(opt.damage_roll!==void 0)co.damage_roll=opt.damage_roll;if(opt.target_count!==void 0)co.target_count=opt.target_count;if(opt.duration!==void 0)co.duration=opt.duration;if(opt.range!==void 0)co.range=opt.range;if(opt.concentration!==void 0)co.concentration=opt.concentration;if(opt.shape_size!==void 0)co.shape_size=opt.shape_size;if(opt.desc!==void 0)co.desc=opt.desc;return co})}if(raw.rendering_hint!=null)spell.rendering_hint=raw.rendering_hint;if(raw.misc_tags!=null)spell.misc_tags=raw.misc_tags;if(raw.area_tags!=null)spell.area_tags=raw.area_tags;if(raw.condition_inflict!=null)spell.condition_inflict=raw.condition_inflict;if(raw.affects_creature_type!=null)spell.affects_creature_type=raw.affects_creature_type;if(raw.spell_attack!=null)spell.spell_attack=raw.spell_attack;if(raw.ability_check!=null)spell.ability_check=raw.ability_check;if(raw.damage_resist!=null)spell.damage_resist=raw.damage_resist;if(raw.damage_immune!=null)spell.damage_immune=raw.damage_immune;if(raw.condition_immune!=null)spell.condition_immune=raw.condition_immune;if(raw.damage_vulnerable!=null)spell.damage_vulnerable=raw.damage_vulnerable;if(raw.has_fluff!=null)spell.has_fluff=raw.has_fluff;if(raw.image!=null)spell.image=raw.image;if(raw.has_fluff_images!=null)spell.has_fluff_images=raw.has_fluff_images;if(meta.source)spell.source=meta.source;if(meta.edition)spell.edition=meta.edition;return{success:true,data:spell}}export{normalizeSpellComponents,spellMaterialOf,normalizeSpellDuration,mirrorSpellShapes,parseSpell};
@@ -0,0 +1 @@
1
+ import{isTwoHandedWeapon}from"./chunk-4IAMSRHD.js";function unwrapSlug(maybeWiki){if(!maybeWiki)return"";const m=/^\[\[([^\]]+)\]\]$/.exec(maybeWiki);return(m?m[1]:maybeWiki).toLowerCase()}function evaluateCondition(cond,ctx){var _a;switch(cond.kind){case"no_armor":return ctx.derived.equippedSlots.armor===void 0?"true":"false";case"no_shield":return ctx.derived.equippedSlots.shield===void 0?"true":"false";case"wielding_two_handed":return isTwoHandedWeapon((_a=ctx.derived.equippedSlots.mainhand)==null?void 0:_a.entity,ctx.registry)?"true":"false";case"is_class":{const target=cond.value.toLowerCase();return ctx.classList.some(c=>unwrapSlug(c.name)===target)?"true":"false"}case"is_race":return unwrapSlug(ctx.race)===cond.value.toLowerCase()?"true":"false";case"is_subclass":return ctx.subclasses.some(s=>s.toLowerCase()===cond.value.toLowerCase())?"true":"false";case"vs_creature_type":case"vs_attack_type":case"on_attack_type":case"with_weapon_property":case"vs_spell_save":case"lighting":case"underwater":case"movement_state":case"has_condition":case"is_concentrating":case"bloodied":return"informational";case"raw":return"informational";case"any_of":{let sawInformational=false;for(const branch of cond.conditions){const o=evaluateCondition(branch,ctx);if(o==="true")return"true";if(o==="informational")sawInformational=true}return sawInformational?"informational":"false"}}}function evaluateConditions(conds,ctx){let sawInformational=false;for(const c of conds){const o=evaluateCondition(c,ctx);if(o==="false")return"false";if(o==="informational")sawInformational=true}return sawInformational?"informational":"true"}export{evaluateCondition,evaluateConditions};
@@ -0,0 +1 @@
1
+ import{CONDITION_SLUGS}from"./chunk-KM75CC6Q.js";import{z}from"zod";var conditionSlugEnum=z.enum(CONDITION_SLUGS);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 proficiencyTri=z.enum(["none","proficient","expertise"]);var slotEnum=z.enum(["mainhand","offhand","armor","shield"]);var equipmentEntryOverridesSchema=z.object({name:z.string().optional(),bonus:z.number().int().optional(),damage_bonus:z.number().int().optional(),extra_damage:z.string().optional(),ac_bonus:z.number().int().optional(),action:z.enum(["action","bonus-action","reaction","free","special"]).optional(),range:z.string().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(),spell:z.string().optional(),spell_ability:abilityEnum.optional()}).strict();var equipmentEntryStateSchema=z.object({charges:z.object({current:z.number().int().nonnegative(),max:z.number().int().nonnegative()}).optional(),recovery:z.object({amount:z.string(),reset:z.enum(["dawn","short","long","special"])}).optional(),depletion_risk:z.object({trigger:z.string(),roll:z.string(),threshold:z.number().int(),effect:z.string()}).optional()}).strict();var entryRefField=z.preprocess(v=>typeof v==="number"?String(v):typeof v==="string"&&v.length>0?v:void 0,z.string().optional());var infusionMarkerSchema=z.object({kind:z.enum(["infused","created"]),by:z.string().min(1),seq:z.number().int().min(1),choice:z.string().min(1).optional(),charges:z.object({current:z.number().int().nonnegative()}).optional()});var equipmentEntrySchema=z.object({item:z.string().min(1),equipped:z.boolean().optional(),attuned:z.boolean().optional(),qty:z.number().int().positive().optional(),notes:z.string().optional(),slot:slotEnum.nullable().optional(),overrides:equipmentEntryOverridesSchema.optional(),state:equipmentEntryStateSchema.optional(),granted_by:z.string().optional(),id:entryRefField,in:entryRefField,infusion:infusionMarkerSchema.optional()});var characterOverridesShape=z.object({scores:z.partialRecord(abilityEnum,z.number().int()).optional(),saves:z.partialRecord(abilityEnum,z.object({bonus:z.number().int().optional(),proficient:z.boolean().optional()})).optional(),skills:z.partialRecord(skillEnum,z.object({bonus:z.number().int(),proficiency:proficiencyTri.optional()})).optional(),passives:z.object({perception:z.number().int().optional(),investigation:z.number().int().optional(),insight:z.number().int().optional()}).partial().optional(),hp:z.object({max:z.number().int().positive().optional(),rolled:z.number().int().positive().optional(),modifier:z.number().int().optional()}).optional(),ac:z.number().int().optional(),speed:z.number().int().optional(),initiative:z.number().int().optional(),spellcasting_ability_by_class:z.record(z.string(),abilityEnum).optional(),spellcasting_ability:abilityEnum.optional(),spell_slots:z.record(z.coerce.number().int(),z.number().int().nonnegative()).optional(),attunement_limit:z.number().int().nonnegative().optional(),languages:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),tools:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional(),proficiency:z.record(z.string(),proficiencyTri).optional()}).optional(),weapons:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),armor:z.object({add:z.array(z.string()).optional(),remove:z.array(z.string()).optional()}).optional(),defenses:z.object({resistances:z.object({remove:z.array(z.string()).optional()}).optional(),immunities:z.object({remove:z.array(z.string()).optional()}).optional(),vulnerabilities:z.object({remove:z.array(z.string()).optional()}).optional(),condition_immunities:z.object({remove:z.array(z.string()).optional()}).optional()}).optional()});var characterOverridesSchema=characterOverridesShape.default({});var characterStateSchema=z.object({hp:z.object({current:z.number().int(),max:z.number().int(),temp:z.number().int().nonnegative()}),hit_dice:z.record(z.string(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots:z.record(z.coerce.number().int(),z.object({used:z.number().int().nonnegative(),total:z.number().int().nonnegative()})).default({}),spell_slots_pact:z.object({level:z.number().int().nonnegative(),used:z.number().int().nonnegative(),total:z.number().int().nonnegative()}).optional(),concentration:z.string().nullable().default(null),conditions:z.array(conditionSlugEnum).default([]),exhaustion:z.number().int().min(0).max(6).default(0),death_saves:z.object({successes:z.number().int().min(0).max(3),failures:z.number().int().min(0).max(3)}).optional(),inspiration:z.number().int().nonnegative().default(0),currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),feature_uses:z.record(z.string(),z.object({used:z.number().int().nonnegative(),max:z.number().int().nonnegative()})).default({}),feature_rolls:z.record(z.string(),z.array(z.number().int().refine(n=>n!==0&&Math.abs(n)<=999,"banked rolls are nonzero, |value| 1..999"))).default({}),active_buffs:z.array(z.string()).optional(),attuned_items:z.array(z.string()).optional()});var choiceValueSchema=z.union([z.string(),z.array(z.string()),z.record(z.string(),z.unknown())]).catch(ctx=>ctx.value);var classEntrySchema=z.object({name:z.string().min(1),level:z.number().int().min(1).max(20),subclass:z.string().nullable().default(null),choices:z.record(z.coerce.number().int(),z.record(z.string(),choiceValueSchema).catch(ctx=>ctx.value)).default({})});var spellOverrideSchema=z.object({slug:z.string().min(1),overrides:z.record(z.string(),z.unknown()).default({})});var knownSpellObjectSchema=z.object({spell:z.string().min(1),class:z.string().optional(),source:z.enum(["class","feat","item","race","domain"]).optional(),prepared:z.boolean().optional(),always_prepared:z.boolean().optional()}).strict();var knownSpellEntrySchema=z.union([z.string().min(1),knownSpellObjectSchema]);var sheetViewFilterSchema=z.object({show:z.array(z.string().min(1)).optional(),hide:z.array(z.string().min(1)).optional()});var sheetPoolViewSchema=z.object({show:z.enum(["known","granted","not-known"]).optional().catch(void 0),off:z.record(z.string(),z.array(z.string())).optional(),folded:z.array(z.string().min(1)).optional()});var sheetStateSchema=z.object({layout:z.object({saves:z.enum(["section"]).optional().catch(void 0),body:z.enum(["wide"]).optional().catch(void 0)}).optional(),favorites:z.array(z.string().min(1)).optional(),filters:z.object({actions:sheetViewFilterSchema.optional(),passive:sheetViewFilterSchema.optional()}).optional(),pools:z.record(z.string(),sheetPoolViewSchema).optional()});var characterSchema=z.object({name:z.string().min(1),edition:z.enum(["2014","2024"]),builder:z.boolean().optional(),alignment:z.string().optional(),age:z.string().optional(),race:z.string().nullable().default(null),subrace:z.string().nullable().default(null),background:z.string().nullable().default(null),class:z.array(classEntrySchema).default([]),origin_choices:z.record(z.string(),choiceValueSchema).default({}),abilities:z.object({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}),ability_method:z.enum(["standard-array","point-buy","archivist-point-buy","rolled","manual"]),builder_rolls:z.array(z.number().int()).optional(),builder_equipment_mode:z.enum(["starting","gold","empty"]).optional(),skills:z.object({proficient:z.array(skillEnum).default([]),expertise:z.array(skillEnum).default([])}).default({proficient:[],expertise:[]}),spells:z.object({known:z.array(knownSpellEntrySchema).default([]),overrides:z.array(spellOverrideSchema).default([]),view:z.enum(["by-level","table"]).optional()}).default({known:[],overrides:[]}),equipment:z.array(equipmentEntrySchema).default([]),overrides:characterOverridesSchema,currency:z.object({cp:z.number().int().nonnegative(),sp:z.number().int().nonnegative(),ep:z.number().int().nonnegative(),gp:z.number().int().nonnegative(),pp:z.number().int().nonnegative()}).optional(),additional_features:z.array(z.string().min(1)).default([]),notes:z.string().optional(),defenses:z.object({resistances:z.array(z.string()).default([]),immunities:z.array(z.string()).default([]),vulnerabilities:z.array(z.string()).default([]),condition_immunities:z.array(z.string()).default([])}).partial().optional(),sheet:sheetStateSchema.optional(),state:characterStateSchema});export{characterOverridesShape,characterSchema};
@@ -0,0 +1 @@
1
+ function slugify(name){return name.toLowerCase().replace(/[^a-z0-9\s-]/g,"").replace(/[\s]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function bareEntitySlug(slug){if(!slug)return"";const p=slug.split("_");return p.length>=3?p.slice(2).join("_"):p[p.length-1]}var STORED_SLUG=/^[a-z0-9-]+(?:_[a-z0-9-]+)+$/;function isStoredSlug(tail){return STORED_SLUG.test(tail)}function wikilinkTailSlug(link){var _a;const inner=link.replace(/^\[\[/,"").replace(/\]\]$/,"");const tail=((_a=inner.split("/").pop())!=null?_a:inner).trim();return isStoredSlug(tail)?bareEntitySlug(tail):slugify(tail)}function twinKey(slug){return bareEntitySlug(slug).replace(/-/g,"")}export{slugify,bareEntitySlug,isStoredSlug,wikilinkTailSlug,twinKey};
@@ -0,0 +1 @@
1
+ import{MONSTER_KNOWN_KEYS,monsterSchema}from"./chunk-QFIGPOFW.js";import{parseYaml}from"@archivist-gg/core";var VALID_RECHARGE_TYPES=new Set(["recharge_on_roll","per_day","per_short_rest","per_long_rest"]);var NUMERIC_STRING=/^[+-]?\d+(\.\d+)?$/;var FEATURE_ARRAYS=["traits","actions","reactions","legendary_actions","bonus_actions","mythic"];var SPEED_MODES=["walk","fly","swim","climb","burrow"];var ABILITY_KEYS=["str","dex","con","int","wis","cha"];var NULL_KEPT=new Set(["senses","languages","group"]);function isRecord(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function coerceNumeric(obj,key){const v=obj[key];if(typeof v==="string"&&NUMERIC_STRING.test(v.trim()))obj[key]=Number(v)}function scrubNulls(v,top){if(Array.isArray(v)){for(let i=v.length-1;i>=0;i--){if(v[i]===null)v.splice(i,1);else scrubNulls(v[i],false)}return}if(!isRecord(v))return;for(const[k,x]of Object.entries(v)){if(x===null){if(!(top&&NULL_KEPT.has(k)))delete v[k]}else scrubNulls(x,false)}}function scrubNonFinite(v){if(Array.isArray(v)){for(const x of v)scrubNonFinite(x);return}if(!isRecord(v))return;for(const[k,x]of Object.entries(v)){if(typeof x==="number"&&!Number.isFinite(x))delete v[k];else scrubNonFinite(x)}}function migrateLegacy(raw){scrubNulls(raw,true);if(raw.legendary_actions!=null&&!Array.isArray(raw.legendary_actions)&&typeof raw.legendary_actions!=="object"){if(raw.legendary_action_uses==null)raw.legendary_action_uses=Number(raw.legendary_actions);delete raw.legendary_actions}if(!Array.isArray(raw.legendary_actions)&&Array.isArray(raw.legendary))raw.legendary_actions=raw.legendary;delete raw.legendary;if(typeof raw.ac==="number")raw.ac=[{ac:raw.ac}];if(Array.isArray(raw.ac))raw.ac=raw.ac.map(e=>typeof e==="number"?{ac:e}:e);if(typeof raw.hp==="number")raw.hp={average:raw.hp};if(typeof raw.cr==="number")raw.cr=String(raw.cr);for(const k of["passive_perception","legendary_action_uses","legendary_resistance","columns","initiative"])coerceNumeric(raw,k);if(isRecord(raw.initiative))coerceNumeric(raw.initiative,"proficiency");for(const k of["saves","skills"]){const o=raw[k];if(isRecord(o))for(const m of Object.keys(o))coerceNumeric(o,m)}if(isRecord(raw.hp))coerceNumeric(raw.hp,"average");if(Array.isArray(raw.ac)){for(const e of raw.ac)if(isRecord(e))coerceNumeric(e,"ac")}if(isRecord(raw.abilities))for(const k of ABILITY_KEYS)coerceNumeric(raw.abilities,k);if(isRecord(raw.speed))for(const k of SPEED_MODES){coerceNumeric(raw.speed,k);const v=raw.speed[k];if(isRecord(v))coerceNumeric(v,"number")}scrubNonFinite(raw);if(isRecord(raw.abilities)){for(const k of ABILITY_KEYS)if(raw.abilities[k]==null)raw.abilities[k]=10}if(typeof raw.senses==="string")raw.senses=[raw.senses];if(typeof raw.languages==="string")raw.languages=[raw.languages];for(const k of FEATURE_ARRAYS){const arr=raw[k];if(!Array.isArray(arr))continue;for(const f of arr){if(!isRecord(f))continue;if(typeof f.desc==="string"&&f.description===void 0&&!Array.isArray(f.entries)){f.description=f.desc;delete f.desc}const r=f.recharge;if(r!==void 0&&!(isRecord(r)&&typeof r.param==="number"&&VALID_RECHARGE_TYPES.has(r.type)))delete f.recharge}}}function parseMonster(source){var _a,_b;const result=parseYaml(source,["name"]);if(!result.success)return result;const raw=result.data;migrateLegacy(raw);const parsed=monsterSchema.safeParse(raw);if(!parsed.success){return{success:false,error:`monster schema validation failed: ${parsed.error.message}`}}const monster=parsed.data;const extras={};for(const[k,v]of Object.entries(raw))if(!MONSTER_KNOWN_KEYS.has(k))extras[k]=v;if(Object.keys(extras).length>0)monster.raw={...(_a=monster.raw)!=null?_a:{},...extras};if(!monster.legendary_resistance&&monster.traits){const lrIndex=monster.traits.findIndex(t=>{var _a2;return/^Legendary Resistance\s*\(/i.test((_a2=t.name)!=null?_a2:"")});if(lrIndex!==-1){const match=(_b=monster.traits[lrIndex].name)==null?void 0:_b.match(/\((\d+)\/Day\)/i);if(match){monster.legendary_resistance=parseInt(match[1],10);monster.traits.splice(lrIndex,1)}}}return{success:true,data:monster}}export{migrateLegacy,parseMonster};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var subjectField=z.string().min(1).optional();var conditionField=z.string().optional();var weaponScopeEnum=z.enum(["weapon","melee","ranged","unarmed","finesse","thrown","pact-weapon"]);var spellScopeSchema=z.object({list:z.string().min(1).optional(),level:z.number().int().min(0).max(9).optional(),school:z.string().min(1).optional(),damage_types:z.array(z.string().min(1)).min(1).optional(),damage_type_pick:z.string().min(1).optional(),spells:z.array(z.string().min(1)).min(1).optional(),once:z.boolean().optional()}).strict();var featureEffectSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("initiative-bonus"),value:z.number().int().optional(),amount:z.string().min(1).optional(),condition:conditionField,subject:subjectField}).refine(e=>e.value===void 0!==(e.amount===void 0),{path:["value"],message:"initiative-bonus takes exactly one of `value` (a number) or `amount` (a formula)"}),z.object({kind:z.literal("skill-bonus"),skills:z.array(z.string().min(1)).nonempty(),ability:abilityEnum,minimum:z.number().int().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("save-bonus"),ability:abilityEnum,minimum:z.number().int().optional(),saves:z.array(abilityEnum).nonempty().optional(),inactive_while:z.enum(["incapacitated","unconscious"]).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("half-proficiency"),skills:z.array(z.string().min(1)).nonempty().optional(),round:z.enum(["down","up"]).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("immune-condition"),condition:z.string().min(1),while:z.string().optional(),subject:subjectField}),z.object({kind:z.literal("resistance"),damage_type:z.string().min(1),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("hp-per-level-bonus"),value:z.number().int(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("speed-bonus"),mode:z.enum(["walk","fly","swim","climb","burrow"]),value:z.number().int(),set:z.boolean().optional(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),value:z.number().int()})).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("attunement-limit"),value:z.number().int().positive(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),value:z.number().int().positive()})).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("sense"),type:z.enum(["darkvision","blindsight","tremorsense","truesight"]),range:z.number().int().nonnegative(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("apply-condition"),condition:z.string().min(1),duration:z.string().optional(),ends_on:z.array(z.string()).optional(),save_repeat:z.object({ability:z.string().min(1),timing:z.string().min(1)}).optional(),subject:subjectField}),z.object({kind:z.literal("damage-bonus"),damage_type:z.string().min(1),amount:z.string().min(1),applies_to:z.union([z.enum(["spell","all"]),weaponScopeEnum,z.array(weaponScopeEnum).min(1)]).optional(),spell_scope:spellScopeSchema.optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("proficiency"),proficiency_type:z.enum(["skill","tool","language","saving-throw","armor","weapon"]),value:z.string().min(1),expertise:z.boolean().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("ac-bonus"),value:z.number().int(),requires_armor:z.boolean().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("unarmored-ac"),abilities:z.array(abilityEnum),base:z.number().int().optional(),allow_shield:z.boolean().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("unarmed-strike"),dice:z.union([z.string().regex(/^\d+d\d+$/i),z.object({column:z.string().min(1)})]).optional(),abilities:z.array(abilityEnum).nonempty().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("weapon-ability"),ability:z.union([abilityEnum,z.literal("spellcasting")]),weapons:z.union([z.literal("chosen"),z.string(),z.array(z.string())]).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("roll-modifier"),mode:z.enum(["advantage","disadvantage","reroll","add-d4"]),roll:z.enum(["ability-check","saving-throw","attack","any"]),scope:z.string().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("extra-attack"),count:z.number().int().positive(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),count:z.number().int().positive()})).optional(),applies_to:z.union([weaponScopeEnum,z.array(weaponScopeEnum).min(1)]).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("crit-range"),min_roll:z.number().int().min(2).max(20),applies_to:z.enum(["weapon","spell","all"]).optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("reroll-damage"),max_reroll:z.number().int().positive(),applies_to:z.enum(["weapon","spell","all"]).optional(),once_per_die:z.boolean().optional(),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("attack-rule"),flag:z.enum(["no-ranged-in-melee-disadvantage"]),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("immunity"),damage_type:z.string().min(1),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("vulnerability"),damage_type:z.string().min(1),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("temp-hp"),amount:z.string().min(1),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("heal"),amount:z.string().min(1),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("ability-score-increase"),abilities:z.union([z.literal("chosen"),z.array(abilityEnum).min(1)]),amount:z.number().int().positive(),choose:z.number().int().positive().nullable(),max:z.number().int().positive().nullable(),condition:conditionField,subject:subjectField}).refine(e=>e.abilities==="chosen"===(e.choose!==null),{path:["choose"],message:'choose is required IFF abilities is "chosen": a fixed LIST is its own count'}),z.object({kind:z.literal("extra-action"),count:z.number().int().positive(),action_type:z.enum(["action","bonus-action","reaction"]),condition:conditionField,subject:subjectField}),z.object({kind:z.literal("save-outcome"),ability:z.union([abilityEnum,z.literal("any")]),on_success:z.enum(["none","half","full"]),on_failure:z.enum(["none","half","full"]),applies_to:z.string().nullable(),condition:conditionField,subject:subjectField})]);export{featureEffectSchema};
@@ -0,0 +1 @@
1
+ import{featureSchema}from"./chunk-V6NQ547U.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 sizeEnum=z.enum(["tiny","small","medium","large","huge"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var speedSchema=z.object({walk:z.number().int().nonnegative().optional(),fly:z.number().int().nonnegative().optional(),swim:z.number().int().nonnegative().optional(),climb:z.number().int().nonnegative().optional(),burrow:z.number().int().nonnegative().optional(),hover:z.boolean().optional()});var visionSchema=z.object({darkvision:z.number().int().nonnegative().optional(),blindsight:z.number().int().nonnegative().optional(),tremorsense:z.number().int().nonnegative().optional(),truesight:z.number().int().nonnegative().optional()});var fixedAsiSchema=z.object({ability:abilityEnum,amount:z.number().int()});var choiceAsiSchema=z.object({choose:z.number().int().positive(),pool:z.array(abilityEnum).nonempty(),amount:z.number().int()});var asiSchema=z.union([fixedAsiSchema,choiceAsiSchema]);var languagesSchema=z.object({fixed:z.array(z.string()),choice:z.object({count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])}).optional()});var raceEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),size:sizeEnum,speed:speedSchema,ability_score_increases:z.array(asiSchema),age:z.string(),alignment:z.string(),vision:visionSchema,languages:languagesSchema,variant_label:z.string().min(1),traits:z.array(featureSchema),choices:z.array(choiceSchema).optional(),subspecies_of:z.string().regex(wikilinkRegex).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),creature_type:z.array(z.string().min(1)).optional(),creature_type_tags:z.array(z.string().min(1)).optional(),additional_spells:z.union([z.array(additionalSpellsEntrySchema),additionalSpellsEntrySchema]).optional(),trait_tags:z.unknown().optional(),lineage:z.unknown().optional(),height_and_weight:z.unknown().optional(),sound_clip:z.unknown().optional(),image:imageField});export{fixedAsiSchema,raceEntitySchema};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var abilitiesSchema=z.object({str:z.number().min(1).max(30),dex:z.number().min(1).max(30),con:z.number().min(1).max(30),int:z.number().min(1).max(30),wis:z.number().min(1).max(30),cha:z.number().min(1).max(30)});var acSchema=z.object({ac:z.number(),from:z.array(z.string()).optional(),condition:z.string().optional()});var hpSchema=z.object({average:z.number(),formula:z.string()});var speedSchema=z.object({walk:z.number().optional(),fly:z.number().optional(),swim:z.number().optional(),climb:z.number().optional(),burrow:z.number().optional()});var featureSchema=z.object({name:z.string(),entries:z.array(z.string().describe("Inline tag forms: `atk:ABILITY` for non-proficient attacks (ability mod alone), `atk:ABILITY+PB` for proficient attacks (ability mod + proficiency), `atk:+N` for literal attack bonuses, `dmg:DICE+ABILITY` for damage rolls (PB never added to damage), `dc:ABILITY` for save DCs (proficiency always included implicitly)."))});var monsterInputSchema=z.object({name:z.string().describe("Monster name"),size:z.enum(["Tiny","Small","Medium","Large","Huge","Gargantuan"]),type:z.string().describe("Creature type (e.g., aberration, beast, dragon)"),subtype:z.string().optional(),alignment:z.string(),cr:z.string().describe('Challenge rating (e.g., "0", "1/8", "1/4", "1/2", "1" through "30")'),abilities:abilitiesSchema,ac:z.array(acSchema),hp:hpSchema,speed:speedSchema,saves:z.record(z.string(),z.number()).optional(),skills:z.record(z.string(),z.number()).optional(),damage_vulnerabilities:z.array(z.string()).optional(),damage_resistances:z.array(z.string()).optional(),damage_immunities:z.array(z.string()).optional(),condition_immunities:z.array(z.string()).optional(),senses:z.array(z.string()).optional(),passive_perception:z.number().optional(),languages:z.array(z.string()).optional(),traits:z.array(featureSchema).optional(),actions:z.array(featureSchema).optional(),reactions:z.array(featureSchema).optional(),legendary_actions:z.array(featureSchema).optional(),legendary_action_uses:z.number().optional(),legendary_resistance:z.number().optional()});export{monsterInputSchema};
@@ -0,0 +1 @@
1
+ import{parseSubclass}from"./chunk-TLXFGGWH.js";import yaml from"js-yaml";var subclassCodec={parse(doc){return parseSubclass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{subclassCodec};
@@ -0,0 +1 @@
1
+ import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var castingOptionSchema=z.object({type:z.string(),damage_roll:z.string().optional(),target_count:z.number().optional(),duration:z.string().optional(),range:z.number().optional(),concentration:z.boolean().optional(),shape_size:z.number().optional(),desc:z.string().optional()});var spellMaterialSchema=z.union([z.boolean(),z.string(),z.strictObject({text:z.string(),cost:z.number().optional(),consume:z.union([z.boolean(),z.string()]).optional()})]);var spellComponentsObjectSchema=z.strictObject({v:z.boolean().optional(),s:z.boolean().optional(),m:spellMaterialSchema.optional(),r:z.boolean().optional()});var spellDurationEntrySchema=z.discriminatedUnion("type",[z.strictObject({type:z.literal("permanent"),ends:z.array(z.enum(["dispel","trigger"])).nonempty()}),z.strictObject({type:z.literal("timed"),duration:z.strictObject({type:z.enum(["minute","hour"]),amount:z.number().int().positive(),up_to:z.boolean().optional()})})]);var spellEntitySchema=z.object({name:z.string().min(1),level:z.number().int().min(0).optional(),school:z.string().optional(),casting_time:z.string().optional(),range:z.string().optional(),components:z.union([z.string(),spellComponentsObjectSchema]).optional(),duration:z.union([z.string(),z.array(spellDurationEntrySchema).nonempty()]).optional(),concentration:z.boolean().optional(),ritual:z.boolean().optional(),classes:z.array(z.string()).optional(),description:z.string().optional(),at_higher_levels:z.array(z.string()).optional(),damage:z.object({types:z.array(z.string())}).optional(),damage_roll:z.string().optional(),saving_throw:z.object({ability:z.string()}).optional(),casting_options:z.array(castingOptionSchema).optional(),rendering_hint:z.string().optional(),misc_tags:z.array(z.string()).optional(),area_tags:z.array(z.string()).optional(),condition_inflict:z.array(z.string()).optional(),affects_creature_type:z.array(z.string()).optional(),spell_attack:z.enum(["melee","ranged"]).optional(),ability_check:z.array(z.string()).optional(),damage_resist:z.array(z.string()).optional(),damage_immune:z.array(z.string()).optional(),condition_immune:z.array(z.string()).optional(),damage_vulnerable:z.array(z.string()).optional(),has_fluff:z.boolean().optional(),image:imageField,has_fluff_images:z.boolean().optional()}).strict();export{spellEntitySchema};
@@ -0,0 +1 @@
1
+ import{ABILITY_KEYS,CR_PROFICIENCY,CR_XP,DAMAGE_TYPES,SIZE_HIT_DICE}from"./chunk-EVT7MGAC.js";function abilityModifier(score){return Math.floor((score-10)/2)}function formatModifier(mod){return mod>=0?`+${mod}`:`${mod}`}function proficiencyBonusFromCR(cr){var _a;return(_a=CR_PROFICIENCY[cr])!=null?_a:2}function proficiencyFromLevel(level){if(level<5)return 2;if(level<9)return 3;if(level<13)return 4;if(level<17)return 5;return 6}function crToXP(cr){var _a;return(_a=CR_XP[cr])!=null?_a:0}function hitDiceSizeFromCreatureSize(size){var _a;return(_a=SIZE_HIT_DICE[size.toLowerCase()])!=null?_a:8}function hpFromHitDice(hitDiceCount,hitDiceSize,conMod){const avg=Math.floor(hitDiceCount*(hitDiceSize+1)/2+hitDiceCount*conMod);return Math.max(1,avg)}function parseHitDiceFormula(formula){const match=formula.match(/^(\d+)d(\d+)/i);if(!match)return null;return{count:parseInt(match[1],10),size:parseInt(match[2],10)}}function savingThrow(abilityScore,isProficient,profBonus){return abilityModifier(abilityScore)+(isProficient?profBonus:0)}function skillBonus(abilityScore,proficiency,profBonus){const mod=abilityModifier(abilityScore);if(proficiency==="expertise")return mod+profBonus*2;if(proficiency==="proficient")return mod+profBonus;return mod}function passive(abilityScore,proficiency,profBonus){return 10+skillBonus(abilityScore,proficiency,profBonus)}function passivePerception(wisScore,perceptionProf,profBonus){return passive(wisScore,perceptionProf,profBonus)}function attackBonus(abilityScore,profBonus){return abilityModifier(abilityScore)+profBonus}function saveDC(abilityScore,profBonus){return 8+profBonus+abilityModifier(abilityScore)}function abilityNameToKey(name){const lower=name.toLowerCase();if(ABILITY_KEYS.includes(lower)){return lower}return null}var CANONICAL_DAMAGE_TYPES=new Set(DAMAGE_TYPES.map(t=>t.toLowerCase()));function isCanonicalDamageType(type){return CANONICAL_DAMAGE_TYPES.has(type.trim().toLowerCase())}var CHOSEN_DAMAGE_TYPE="chosen";var CHOSEN_DAMAGE_TYPE_NOTE="damage type of your choice";function isChosenDamageType(type){return type!==void 0&&type.trim().toLowerCase()===CHOSEN_DAMAGE_TYPE}function isRenderableDamageText(text){var _a;const m=/^(?:\d*d\d+(?:\s*[+-]\s*\d+)?|[+-]?\d+)(?:\s+(.*))?$/i.exec(text.trim());if(!m)return false;const type=((_a=m[1])!=null?_a:"").trim();return type===""||isCanonicalDamageType(type)}export{abilityModifier,formatModifier,proficiencyBonusFromCR,proficiencyFromLevel,crToXP,hitDiceSizeFromCreatureSize,hpFromHitDice,parseHitDiceFormula,savingThrow,skillBonus,passive,passivePerception,attackBonus,saveDC,abilityNameToKey,isCanonicalDamageType,CHOSEN_DAMAGE_TYPE,CHOSEN_DAMAGE_TYPE_NOTE,isChosenDamageType,isRenderableDamageText};
@@ -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{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var editionEnum=z.enum(["2014","2024"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var spellcastingSchema=z.object({caster_type:casterTypeEnum.optional(),ability:abilityEnum,preparation:z.enum(["known","prepared"]).optional(),spell_list:z.string().min(1).optional()});var subclassTableRowSchema=z.object({columns:z.record(z.string(),z.union([z.string(),z.number()])).optional()});var subclassEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),parent_class:z.string().regex(wikilinkRegex,"parent_class must be a wikilink like [[rogue]]"),edition:editionEnum,source:z.string().min(1),description:z.string(),spellcasting:spellcastingSchema.nullable().optional(),table:z.record(z.string(),subclassTableRowSchema).optional(),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(),short_name:z.string().min(1).optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),fluff:z.unknown().optional(),table_col_labels:z.array(z.string().min(1)).optional(),cantrip_progression:z.array(z.number()).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(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{subclassEntitySchema};
@@ -0,0 +1 @@
1
+ import{itemEntitySchema}from"./chunk-RL4VY2AL.js";import{parseYaml}from"@archivist-gg/core";var KNOWN_KEYS=new Set(["name","slug","type","rarity","base_item","bonuses","resist","immune","vulnerable","condition_immune","charges","attached_spells","attunement","grants","container","light","cursed","sentient","focus","tier","tattoo","damage","weapon_category","armor_category","weight","cost","source","page","edition","description","entries","effects","damage_riders","raw","scroll_level","unidentified","masked_category","modify_speed","rendering_hint","icon","has_fluff","has_fluff_images","image","speed_on_use","mastery","damage_dice","damage_type","properties","recharge","curse"]);function migrateAttunement(raw){const legacy=raw.requires_attunement;if(raw.attunement===void 0&&typeof legacy==="boolean"){raw.attunement={required:legacy}}if(legacy!==void 0){delete raw.requires_attunement}const v=raw.attunement;if(v===void 0||v===null)return;if(typeof v==="object"&&!Array.isArray(v))return;if(typeof v==="boolean"){raw.attunement={required:v}}else if(typeof v==="string"){raw.attunement={required:true,restriction:v}}}function parseItem(source){var _a;const raw=parseYaml(source,["name"]);if(!raw.success)return raw;migrateAttunement(raw.data);const result=itemEntitySchema.safeParse(raw.data);if(!result.success){return{success:false,error:`item 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{parseItem};