@archivist-gg/dnd5e 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/SRD.md +37 -0
  3. package/README.md +65 -0
  4. package/dist/armor/armor.codec.d.ts +10 -0
  5. package/dist/armor/armor.codec.js +8 -0
  6. package/dist/armor/armor.entity-type.d.ts +2 -0
  7. package/dist/armor/armor.parser.d.ts +3 -0
  8. package/dist/armor/armor.parser.js +7 -0
  9. package/dist/armor/armor.schema.d.ts +25 -0
  10. package/dist/armor/armor.schema.js +6 -0
  11. package/dist/armor/armor.types.d.ts +26 -0
  12. package/dist/armor/armor.types.js +0 -0
  13. package/dist/background/background.codec.d.ts +9 -0
  14. package/dist/background/background.codec.js +11 -0
  15. package/dist/background/background.entity-type.d.ts +2 -0
  16. package/dist/background/background.parser.d.ts +3 -0
  17. package/dist/background/background.parser.js +10 -0
  18. package/dist/background/background.schema.d.ts +74 -0
  19. package/dist/background/background.schema.js +9 -0
  20. package/dist/background/background.types.d.ts +52 -0
  21. package/dist/background/background.types.js +0 -0
  22. package/dist/chunk-24GFQU7T.js +18 -0
  23. package/dist/chunk-3DZ74AKK.js +28 -0
  24. package/dist/chunk-3TM34RSJ.js +23 -0
  25. package/dist/chunk-3TRGRSCH.js +8 -0
  26. package/dist/chunk-4C2KOKLF.js +185 -0
  27. package/dist/chunk-4F6AIZ36.js +19 -0
  28. package/dist/chunk-4SSDYJS2.js +86 -0
  29. package/dist/chunk-4TIJKN6O.js +37 -0
  30. package/dist/chunk-537BHVSH.js +18 -0
  31. package/dist/chunk-5INR4NSL.js +18 -0
  32. package/dist/chunk-5XUXXAQJ.js +30 -0
  33. package/dist/chunk-656QCX4U.js +22 -0
  34. package/dist/chunk-66XXW2Z2.js +133 -0
  35. package/dist/chunk-6NK2MUD3.js +114 -0
  36. package/dist/chunk-6PXE7T7C.js +79 -0
  37. package/dist/chunk-7P65Q426.js +158 -0
  38. package/dist/chunk-A7T5L7SS.js +83 -0
  39. package/dist/chunk-AFKTJXRA.js +39 -0
  40. package/dist/chunk-B7UXKNLD.js +46 -0
  41. package/dist/chunk-BAXWWGFJ.js +45 -0
  42. package/dist/chunk-BH6AMZVY.js +25 -0
  43. package/dist/chunk-CDW7R2QT.js +62 -0
  44. package/dist/chunk-DABBCYTT.js +68 -0
  45. package/dist/chunk-DC74TZNA.js +46 -0
  46. package/dist/chunk-DNAJRMNN.js +68 -0
  47. package/dist/chunk-DRNZJNJP.js +19 -0
  48. package/dist/chunk-FEOB24KP.js +18 -0
  49. package/dist/chunk-FFULAF2P.js +63 -0
  50. package/dist/chunk-FUK7QSN5.js +19 -0
  51. package/dist/chunk-GIOH5JB5.js +19 -0
  52. package/dist/chunk-GJOI2GHP.js +25 -0
  53. package/dist/chunk-GZ46OVGZ.js +31 -0
  54. package/dist/chunk-HCP3GMHS.js +44 -0
  55. package/dist/chunk-IDTDACM6.js +19 -0
  56. package/dist/chunk-IKSMX4TN.js +0 -0
  57. package/dist/chunk-IXZXFFFW.js +269 -0
  58. package/dist/chunk-J2RYSZMQ.js +16 -0
  59. package/dist/chunk-JEYQU3JT.js +36 -0
  60. package/dist/chunk-LSLSG67V.js +31 -0
  61. package/dist/chunk-LWFTHJIE.js +24 -0
  62. package/dist/chunk-MDEJHMKK.js +52 -0
  63. package/dist/chunk-N2JE7BWL.js +81 -0
  64. package/dist/chunk-NAEPSZAM.js +88 -0
  65. package/dist/chunk-NXR3BD2V.js +90 -0
  66. package/dist/chunk-PKC77VZP.js +18 -0
  67. package/dist/chunk-PMADYMUI.js +19 -0
  68. package/dist/chunk-PTXBIDG7.js +63 -0
  69. package/dist/chunk-PZOWBI3B.js +49 -0
  70. package/dist/chunk-QQ5W2AZP.js +515 -0
  71. package/dist/chunk-QS5L5YTJ.js +24 -0
  72. package/dist/chunk-QYZV2MQA.js +97 -0
  73. package/dist/chunk-R2ZV233X.js +233 -0
  74. package/dist/chunk-RAWJTA45.js +271 -0
  75. package/dist/chunk-RSDRMH54.js +18 -0
  76. package/dist/chunk-RVYYKYFL.js +18 -0
  77. package/dist/chunk-SSXBYF3P.js +18 -0
  78. package/dist/chunk-TJCNX6UZ.js +521 -0
  79. package/dist/chunk-TZK36BU7.js +38 -0
  80. package/dist/chunk-UC4FE5X3.js +65 -0
  81. package/dist/chunk-WP2CX2JO.js +235 -0
  82. package/dist/chunk-WYGD2UGN.js +14 -0
  83. package/dist/chunk-XJNECUPT.js +31 -0
  84. package/dist/chunk-XURS6Q6Q.js +127 -0
  85. package/dist/chunk-Y4I74YEG.js +33 -0
  86. package/dist/chunk-Z4TL2V7S.js +18 -0
  87. package/dist/chunk-Z6GXV2GO.js +121 -0
  88. package/dist/chunk-ZLG6FQFB.js +237 -0
  89. package/dist/chunk-ZMR77DDL.js +18 -0
  90. package/dist/class/class.codec.d.ts +10 -0
  91. package/dist/class/class.codec.js +15 -0
  92. package/dist/class/class.entity-type.d.ts +2 -0
  93. package/dist/class/class.parser.d.ts +3 -0
  94. package/dist/class/class.parser.js +14 -0
  95. package/dist/class/class.schema.d.ts +202 -0
  96. package/dist/class/class.schema.js +13 -0
  97. package/dist/class/class.slug.d.ts +11 -0
  98. package/dist/class/class.slug.js +8 -0
  99. package/dist/class/class.types.d.ts +74 -0
  100. package/dist/class/class.types.js +0 -0
  101. package/dist/data-srd/index.generated.d.ts +7 -0
  102. package/dist/data-srd/index.generated.js +146 -0
  103. package/dist/dnd/constants.d.ts +16 -0
  104. package/dist/dnd/constants.js +36 -0
  105. package/dist/dnd/formula-tags.d.ts +16 -0
  106. package/dist/dnd/formula-tags.js +119 -0
  107. package/dist/dnd/math.d.ts +24 -0
  108. package/dist/dnd/math.js +35 -0
  109. package/dist/dnd/prose-tags.d.ts +16 -0
  110. package/dist/dnd/prose-tags.js +18 -0
  111. package/dist/dnd/resource-die.d.ts +6 -0
  112. package/dist/dnd/resource-die.js +17 -0
  113. package/dist/dnd/resource-formula.d.ts +41 -0
  114. package/dist/dnd/resource-formula.js +159 -0
  115. package/dist/dnd/srd-tag-converter.d.ts +44 -0
  116. package/dist/dnd/srd-tag-converter.js +12 -0
  117. package/dist/dnd/tag-grammar.d.ts +19 -0
  118. package/dist/dnd/tag-grammar.js +12 -0
  119. package/dist/encounter/encounter.ai-schema.d.ts +29 -0
  120. package/dist/encounter/encounter.ai-schema.js +8 -0
  121. package/dist/encounter/encounter.entity-type.d.ts +2 -0
  122. package/dist/encounter/encounter.generatable.d.ts +2 -0
  123. package/dist/entities/base-item-resolver.d.ts +21 -0
  124. package/dist/entities/base-item-resolver.js +9 -0
  125. package/dist/entities/slug.d.ts +5 -0
  126. package/dist/entities/slug.js +6 -0
  127. package/dist/feat/feat.codec.d.ts +9 -0
  128. package/dist/feat/feat.codec.js +10 -0
  129. package/dist/feat/feat.entity-type.d.ts +2 -0
  130. package/dist/feat/feat.parser.d.ts +3 -0
  131. package/dist/feat/feat.parser.js +9 -0
  132. package/dist/feat/feat.schema.d.ts +194 -0
  133. package/dist/feat/feat.schema.js +8 -0
  134. package/dist/feat/feat.types.d.ts +42 -0
  135. package/dist/feat/feat.types.js +0 -0
  136. package/dist/index.d.ts +12 -0
  137. package/dist/index.js +139149 -0
  138. package/dist/inline-tag-parser.d.ts +11 -0
  139. package/dist/inline-tag-parser.js +6 -0
  140. package/dist/item/item.actions-map.d.ts +41 -0
  141. package/dist/item/item.actions-map.js +85 -0
  142. package/dist/item/item.ai-schema.d.ts +35 -0
  143. package/dist/item/item.ai-schema.js +6 -0
  144. package/dist/item/item.attunement.d.ts +18 -0
  145. package/dist/item/item.attunement.js +12 -0
  146. package/dist/item/item.bonuses.d.ts +2 -0
  147. package/dist/item/item.bonuses.js +7 -0
  148. package/dist/item/item.codec.d.ts +3 -0
  149. package/dist/item/item.codec.js +8 -0
  150. package/dist/item/item.conditions.d.ts +10 -0
  151. package/dist/item/item.conditions.js +8 -0
  152. package/dist/item/item.conditions.types.d.ts +28 -0
  153. package/dist/item/item.conditions.types.js +0 -0
  154. package/dist/item/item.enrichment.d.ts +4 -0
  155. package/dist/item/item.enrichment.js +9 -0
  156. package/dist/item/item.entity-type.d.ts +2 -0
  157. package/dist/item/item.generatable.d.ts +2 -0
  158. package/dist/item/item.parser.d.ts +3 -0
  159. package/dist/item/item.parser.js +7 -0
  160. package/dist/item/item.schema.d.ts +174 -0
  161. package/dist/item/item.schema.js +8 -0
  162. package/dist/item/item.types.d.ts +108 -0
  163. package/dist/item/item.types.js +0 -0
  164. package/dist/monster/monster.ai-schema.d.ts +67 -0
  165. package/dist/monster/monster.ai-schema.js +6 -0
  166. package/dist/monster/monster.codec.d.ts +13 -0
  167. package/dist/monster/monster.enrichment.d.ts +10 -0
  168. package/dist/monster/monster.enrichment.js +19 -0
  169. package/dist/monster/monster.entity-type.d.ts +2 -0
  170. package/dist/monster/monster.generatable.d.ts +2 -0
  171. package/dist/monster/monster.parser.d.ts +3 -0
  172. package/dist/monster/monster.parser.js +6 -0
  173. package/dist/monster/monster.resolve.d.ts +10 -0
  174. package/dist/monster/monster.types.d.ts +29 -0
  175. package/dist/monster/monster.types.js +1 -0
  176. package/dist/npc/npc.ai-schema.d.ts +6 -0
  177. package/dist/npc/npc.entity-type.d.ts +2 -0
  178. package/dist/npc/npc.generatable.d.ts +2 -0
  179. package/dist/optional-feature/optional-feature.codec.d.ts +14 -0
  180. package/dist/optional-feature/optional-feature.codec.js +11 -0
  181. package/dist/optional-feature/optional-feature.entity-type.d.ts +2 -0
  182. package/dist/optional-feature/optional-feature.parser.d.ts +3 -0
  183. package/dist/optional-feature/optional-feature.parser.js +10 -0
  184. package/dist/optional-feature/optional-feature.schema.d.ts +236 -0
  185. package/dist/optional-feature/optional-feature.schema.js +9 -0
  186. package/dist/pack.d.ts +11 -0
  187. package/dist/pc/conditions.constants.d.ts +3 -0
  188. package/dist/pc/conditions.constants.js +8 -0
  189. package/dist/pc/decision-recognizer.d.ts +4 -0
  190. package/dist/pc/decision-recognizer.js +8 -0
  191. package/dist/pc/pc.conditions.d.ts +3 -0
  192. package/dist/pc/pc.conditions.js +6 -0
  193. package/dist/pc/pc.decision-engine.d.ts +97 -0
  194. package/dist/pc/pc.decision-engine.js +19 -0
  195. package/dist/pc/pc.equipment.d.ts +12 -0
  196. package/dist/pc/pc.equipment.js +15 -0
  197. package/dist/pc/pc.feature-effects.d.ts +95 -0
  198. package/dist/pc/pc.feature-effects.js +9 -0
  199. package/dist/pc/pc.formula-context.d.ts +4 -0
  200. package/dist/pc/pc.formula-context.js +11 -0
  201. package/dist/pc/pc.parser.d.ts +3 -0
  202. package/dist/pc/pc.parser.js +41 -0
  203. package/dist/pc/pc.pools.d.ts +12 -0
  204. package/dist/pc/pc.pools.js +15 -0
  205. package/dist/pc/pc.proficiencies.d.ts +8 -0
  206. package/dist/pc/pc.proficiencies.js +47 -0
  207. package/dist/pc/pc.proficiency-query.d.ts +11 -0
  208. package/dist/pc/pc.proficiency-query.js +17 -0
  209. package/dist/pc/pc.recalc.d.ts +105 -0
  210. package/dist/pc/pc.recalc.js +662 -0
  211. package/dist/pc/pc.resolver.d.ts +34 -0
  212. package/dist/pc/pc.resolver.js +267 -0
  213. package/dist/pc/pc.resource-seed.d.ts +10 -0
  214. package/dist/pc/pc.resource-seed.js +40 -0
  215. package/dist/pc/pc.rest.d.ts +23 -0
  216. package/dist/pc/pc.rest.js +128 -0
  217. package/dist/pc/pc.schema.d.ts +294 -0
  218. package/dist/pc/pc.schema.js +7 -0
  219. package/dist/pc/pc.slotting.d.ts +22 -0
  220. package/dist/pc/pc.slotting.js +20 -0
  221. package/dist/pc/pc.spellcasting.d.ts +56 -0
  222. package/dist/pc/pc.spellcasting.js +16 -0
  223. package/dist/pc/pc.table-column.d.ts +12 -0
  224. package/dist/pc/pc.table-column.js +8 -0
  225. package/dist/pc/pc.types.d.ts +514 -0
  226. package/dist/pc/pc.types.js +0 -0
  227. package/dist/race/race.codec.d.ts +9 -0
  228. package/dist/race/race.codec.js +13 -0
  229. package/dist/race/race.entity-type.d.ts +2 -0
  230. package/dist/race/race.parser.d.ts +3 -0
  231. package/dist/race/race.parser.js +12 -0
  232. package/dist/race/race.schema.d.ts +67 -0
  233. package/dist/race/race.schema.js +11 -0
  234. package/dist/race/race.types.d.ts +44 -0
  235. package/dist/race/race.types.js +0 -0
  236. package/dist/schemas/attack-schema.d.ts +38 -0
  237. package/dist/schemas/choice-schema.d.ts +5 -0
  238. package/dist/schemas/choice-schema.js +7 -0
  239. package/dist/schemas/duration-schema.d.ts +13 -0
  240. package/dist/schemas/duration-schema.js +6 -0
  241. package/dist/schemas/equipment-grant-schema.d.ts +6 -0
  242. package/dist/schemas/equipment-grant-schema.js +12 -0
  243. package/dist/schemas/feature-effect-schema.d.ts +131 -0
  244. package/dist/schemas/feature-effect-schema.js +6 -0
  245. package/dist/schemas/feature-schema.d.ts +2 -0
  246. package/dist/schemas/feature-schema.js +10 -0
  247. package/dist/schemas/index.d.ts +6 -0
  248. package/dist/schemas/resource-schema.d.ts +95 -0
  249. package/dist/schemas/resource-schema.js +12 -0
  250. package/dist/schemas/selection-pool-schema.d.ts +34 -0
  251. package/dist/schemas/selection-pool-schema.js +10 -0
  252. package/dist/spell/spell.access.d.ts +15 -0
  253. package/dist/spell/spell.access.js +25 -0
  254. package/dist/spell/spell.ai-schema.d.ts +24 -0
  255. package/dist/spell/spell.ai-schema.js +6 -0
  256. package/dist/spell/spell.codec.d.ts +3 -0
  257. package/dist/spell/spell.codec.js +8 -0
  258. package/dist/spell/spell.enrichment.d.ts +2 -0
  259. package/dist/spell/spell.enrichment.js +9 -0
  260. package/dist/spell/spell.entity-type.d.ts +2 -0
  261. package/dist/spell/spell.filter.d.ts +15 -0
  262. package/dist/spell/spell.filter.js +87 -0
  263. package/dist/spell/spell.generatable.d.ts +2 -0
  264. package/dist/spell/spell.parser.d.ts +3 -0
  265. package/dist/spell/spell.parser.js +7 -0
  266. package/dist/spell/spell.scaling.d.ts +14 -0
  267. package/dist/spell/spell.scaling.js +28 -0
  268. package/dist/spell/spell.schema.d.ts +31 -0
  269. package/dist/spell/spell.schema.js +6 -0
  270. package/dist/spell/spell.types.d.ts +25 -0
  271. package/dist/spell/spell.types.js +0 -0
  272. package/dist/srd-store.d.ts +53 -0
  273. package/dist/subclass/subclass.codec.d.ts +11 -0
  274. package/dist/subclass/subclass.codec.js +14 -0
  275. package/dist/subclass/subclass.entity-type.d.ts +2 -0
  276. package/dist/subclass/subclass.parser.d.ts +3 -0
  277. package/dist/subclass/subclass.parser.js +13 -0
  278. package/dist/subclass/subclass.schema.d.ts +118 -0
  279. package/dist/subclass/subclass.schema.js +12 -0
  280. package/dist/subclass/subclass.types.d.ts +20 -0
  281. package/dist/subclass/subclass.types.js +0 -0
  282. package/dist/types/abilities.d.ts +8 -0
  283. package/dist/types/abilities.js +0 -0
  284. package/dist/types/ac.d.ts +5 -0
  285. package/dist/types/attack.d.ts +22 -0
  286. package/dist/types/attack.js +0 -0
  287. package/dist/types/casting-option.d.ts +14 -0
  288. package/dist/types/casting-option.js +0 -0
  289. package/dist/types/choice.d.ts +66 -0
  290. package/dist/types/choice.js +6 -0
  291. package/dist/types/edition.d.ts +4 -0
  292. package/dist/types/edition.js +0 -0
  293. package/dist/types/equipment-grant.d.ts +41 -0
  294. package/dist/types/equipment-grant.js +0 -0
  295. package/dist/types/feature-effect.d.ts +79 -0
  296. package/dist/types/feature-effect.js +0 -0
  297. package/dist/types/feature.d.ts +41 -0
  298. package/dist/types/feature.js +0 -0
  299. package/dist/types/formula-context.d.ts +7 -0
  300. package/dist/types/formula-context.js +0 -0
  301. package/dist/types/hp.d.ts +4 -0
  302. package/dist/types/index.d.ts +10 -0
  303. package/dist/types/item-conditions.types.d.ts +63 -0
  304. package/dist/types/item-conditions.types.js +0 -0
  305. package/dist/types/optional-feature.types.d.ts +60 -0
  306. package/dist/types/optional-feature.types.js +0 -0
  307. package/dist/types/resource.d.ts +44 -0
  308. package/dist/types/resource.js +0 -0
  309. package/dist/types/selection-pool.d.ts +37 -0
  310. package/dist/types/selection-pool.js +0 -0
  311. package/dist/types/speed.d.ts +8 -0
  312. package/dist/weapon/weapon.codec.d.ts +12 -0
  313. package/dist/weapon/weapon.codec.js +8 -0
  314. package/dist/weapon/weapon.entity-type.d.ts +2 -0
  315. package/dist/weapon/weapon.parser.d.ts +3 -0
  316. package/dist/weapon/weapon.parser.js +7 -0
  317. package/dist/weapon/weapon.schema.d.ts +34 -0
  318. package/dist/weapon/weapon.schema.js +6 -0
  319. package/dist/weapon/weapon.types.d.ts +36 -0
  320. package/dist/weapon/weapon.types.js +0 -0
  321. package/package.json +32 -0
  322. package/src/data-srd/ATTRIBUTION.md +2 -0
@@ -0,0 +1,521 @@
1
+ import {
2
+ ALL_SKILL_SLUGS
3
+ } from "./chunk-BH6AMZVY.js";
4
+ import {
5
+ recognizeDecision
6
+ } from "./chunk-JEYQU3JT.js";
7
+ import {
8
+ ABILITY_KEYS
9
+ } from "./chunk-WP2CX2JO.js";
10
+
11
+ // src/pc/pc.decision-engine.ts
12
+ var warnedDegradedEquipment = /* @__PURE__ */ new Set();
13
+ function wikilinkTailSlug(link) {
14
+ var _a;
15
+ const inner = link.replace(/^\[\[/, "").replace(/\]\]$/, "");
16
+ const tail = (_a = inner.split("/").pop()) != null ? _a : inner;
17
+ return tail.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
18
+ }
19
+ function bareEntitySlug(slug) {
20
+ if (!slug) return "";
21
+ const i = slug.indexOf("_");
22
+ return i === -1 ? slug : slug.slice(i + 1);
23
+ }
24
+ function matchesFilter(e, where, ownerBare) {
25
+ var _a, _b, _c;
26
+ const d = e.data;
27
+ if (where.feature_type && d.feature_type !== where.feature_type) return false;
28
+ if (where.category && d.category !== where.category) return false;
29
+ if (where.weapon_category) {
30
+ const cat = ((_a = d.category) != null ? _a : "").toLowerCase();
31
+ if (!cat.startsWith(`${where.weapon_category}-`) && cat !== where.weapon_category) return false;
32
+ }
33
+ if (where.armor_category) {
34
+ if (((_b = d.category) != null ? _b : "").toLowerCase() !== where.armor_category) return false;
35
+ }
36
+ if (where.parent_class === "self") {
37
+ if (!d.parent_class || wikilinkTailSlug(d.parent_class) !== ownerBare) return false;
38
+ }
39
+ if (where.available_to === "self") {
40
+ const list = (_c = d.available_to) != null ? _c : [];
41
+ if (!list.some((l) => wikilinkTailSlug(l) === ownerBare)) return false;
42
+ }
43
+ return true;
44
+ }
45
+ var __matchesFilterForTest = matchesFilter;
46
+ function categoryToEntitySelect(category, id) {
47
+ const c = category.toLowerCase();
48
+ if (c === "shield") {
49
+ return { kind: "select-entity", id, label: "Choose a shield", count: 1, entity_type: "armor", where: { armor_category: "shield" } };
50
+ }
51
+ if (c.includes("armor")) {
52
+ const klass = c.includes("light") ? "light" : c.includes("medium") ? "medium" : c.includes("heavy") ? "heavy" : null;
53
+ return klass ? { kind: "select-entity", id, label: `Choose ${klass} armor`, count: 1, entity_type: "armor", where: { armor_category: klass } } : { kind: "select-entity", id, label: "Choose armor", count: 1, entity_type: "armor" };
54
+ }
55
+ const wc = c.includes("martial") ? "martial" : "simple";
56
+ return { kind: "select-entity", id, label: `Choose a ${c.replace(/-/g, " ")}`, count: 1, entity_type: "weapon", where: { weapon_category: wc } };
57
+ }
58
+ function enumerateOptions(choice, ctx, ownerBare) {
59
+ var _a, _b;
60
+ switch (choice.kind) {
61
+ case "select-inline":
62
+ return choice.options.map((o) => ({ value: o.value, label: o.label, description: o.description }));
63
+ case "select-entity": {
64
+ if (choice.from) {
65
+ const byBare = /* @__PURE__ */ new Map();
66
+ for (const e of ctx.registry.search("", choice.entity_type, Number.POSITIVE_INFINITY)) {
67
+ byBare.set(bareEntitySlug(e.slug), e);
68
+ }
69
+ return choice.from.map((slug) => {
70
+ var _a2;
71
+ const e = (_a2 = ctx.registry.getByTypeAndSlug(choice.entity_type, slug)) != null ? _a2 : byBare.get(slug);
72
+ return e ? { value: e.slug, label: e.name, entity: e } : { value: slug, label: slug, missing: true };
73
+ });
74
+ }
75
+ const all = ctx.registry.search("", choice.entity_type, Number.POSITIVE_INFINITY);
76
+ const filtered = choice.where ? all.filter((e) => matchesFilter(e, choice.where, ownerBare)) : all;
77
+ return filtered.map((e) => ({ value: e.slug, label: e.name, entity: e }));
78
+ }
79
+ case "select-proficiency": {
80
+ const pool = (_a = choice.from) != null ? _a : choice.domain === "skill" ? [...ALL_SKILL_SLUGS] : [];
81
+ return pool.map((v) => ({ value: v, label: v.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()) }));
82
+ }
83
+ case "ability-points": {
84
+ const pool = (_b = choice.pool) != null ? _b : ["str", "dex", "con", "int", "wis", "cha"];
85
+ return pool.map((a) => ({ value: a, label: a.toUpperCase() }));
86
+ }
87
+ }
88
+ }
89
+ function selectionCount(choice, selected) {
90
+ if (selected === void 0) return 0;
91
+ if (choice.kind === "ability-points") {
92
+ if (typeof selected !== "object" || Array.isArray(selected)) return 0;
93
+ return Object.values(selected).reduce((s, v) => s + (typeof v === "number" ? v : 0), 0);
94
+ }
95
+ if (Array.isArray(selected)) return selected.length;
96
+ return typeof selected === "string" && selected.length > 0 ? 1 : 0;
97
+ }
98
+ function requiredCount(choice) {
99
+ var _a;
100
+ if (choice.kind === "ability-points") return choice.points;
101
+ if (choice.kind === "select-proficiency") return choice.count;
102
+ return (_a = choice.count) != null ? _a : 1;
103
+ }
104
+ function statusOf(choice, selected) {
105
+ const n = selectionCount(choice, selected);
106
+ const need = requiredCount(choice);
107
+ if (n === 0) return "unresolved";
108
+ return n >= need ? "resolved" : "partial";
109
+ }
110
+ function resolveEntityRef(ctx, entityType, value) {
111
+ if (typeof value !== "string" || value.length === 0) return void 0;
112
+ const raw = value.replace(/^\[\[/, "").replace(/\]\]$/, "");
113
+ const direct = ctx.registry.getByTypeAndSlug(entityType, raw);
114
+ if (direct) return direct;
115
+ for (const e of ctx.registry.search("", entityType, Number.POSITIVE_INFINITY)) {
116
+ if (e.slug === raw || bareEntitySlug(e.slug) === raw) return e;
117
+ }
118
+ return void 0;
119
+ }
120
+ function buildItem(choice, source, level, featureName, readValue, ctx, ownerBare, opts) {
121
+ var _a, _b, _c, _d;
122
+ const keyPrefix = (_a = opts == null ? void 0 : opts.keyPrefix) != null ? _a : "";
123
+ const expandFeatChildren = (_b = opts == null ? void 0 : opts.expandFeatChildren) != null ? _b : true;
124
+ const key = keyPrefix + choice.id;
125
+ const selected = readValue(key);
126
+ const item = {
127
+ key,
128
+ source,
129
+ level,
130
+ featureName,
131
+ choice,
132
+ description: opts == null ? void 0 : opts.description,
133
+ options: enumerateOptions(choice, ctx, ownerBare),
134
+ selected,
135
+ status: statusOf(choice, selected)
136
+ };
137
+ if (choice.kind === "select-inline" && typeof selected === "string") {
138
+ const branch = choice.options.find((o) => o.value === selected);
139
+ if ((_c = branch == null ? void 0 : branch.choices) == null ? void 0 : _c.length) {
140
+ item.children = branch.choices.map((c) => buildItem(c, source, level, featureName, readValue, ctx, ownerBare, { keyPrefix, expandFeatChildren }));
141
+ if (item.status === "resolved" && item.children.some((c) => c.status !== "resolved")) {
142
+ item.status = "partial";
143
+ }
144
+ }
145
+ }
146
+ if (choice.kind === "select-entity" && choice.entity_type === "feat" && expandFeatChildren && typeof selected === "string") {
147
+ const entity = resolveEntityRef(ctx, "feat", selected);
148
+ const rawChoices = (_d = entity == null ? void 0 : entity.data) == null ? void 0 : _d.choices;
149
+ const featChoices = Array.isArray(rawChoices) ? rawChoices : [];
150
+ if (featChoices.length) {
151
+ const childPrefix = `${keyPrefix}feat:`;
152
+ item.children = featChoices.map((c) => buildItem(
153
+ c,
154
+ source,
155
+ level,
156
+ featureName,
157
+ readValue,
158
+ ctx,
159
+ ownerBare,
160
+ { keyPrefix: childPrefix, expandFeatChildren: false }
161
+ ));
162
+ if (item.status === "resolved" && item.children.some((c) => c.status !== "resolved")) {
163
+ item.status = "partial";
164
+ }
165
+ }
166
+ }
167
+ return item;
168
+ }
169
+ function buildSubclassItem(choice, source, level, featureName, c, ctx, ownerBare, description) {
170
+ const selected = c.subclass ? c.subclass.slug : void 0;
171
+ return {
172
+ key: "subclass",
173
+ source,
174
+ level,
175
+ featureName,
176
+ description,
177
+ choice,
178
+ options: enumerateOptions(choice, ctx, ownerBare),
179
+ selected,
180
+ status: selected ? "resolved" : "unresolved"
181
+ };
182
+ }
183
+ function collectChosenProficiencies(resolved) {
184
+ var _a, _b;
185
+ const out = { skills: [], expertise: [], languages: [], tools: [] };
186
+ const apply = (choice, selected) => {
187
+ if (choice.kind !== "select-proficiency") return;
188
+ const vals = Array.isArray(selected) ? selected : typeof selected === "string" ? [selected] : [];
189
+ const pool = choice.from;
190
+ const valid = pool ? vals.filter((v) => pool.includes(v)) : vals;
191
+ const bucket = choice.domain === "skill" ? choice.expertise ? out.expertise : out.skills : choice.domain === "language" ? out.languages : choice.domain === "tool" ? out.tools : null;
192
+ if (bucket) {
193
+ for (const v of valid) if (!bucket.includes(v)) bucket.push(v);
194
+ }
195
+ };
196
+ const walk = (choices, read) => {
197
+ for (const ch of choices != null ? choices : []) {
198
+ apply(ch, read(ch.id));
199
+ if (ch.kind === "select-inline") {
200
+ const sel = read(ch.id);
201
+ const branch = typeof sel === "string" ? ch.options.find((o) => o.value === sel) : void 0;
202
+ if (branch == null ? void 0 : branch.choices) walk(branch.choices, read);
203
+ }
204
+ }
205
+ };
206
+ resolved.classes.forEach((c, i) => {
207
+ var _a2, _b2;
208
+ if (!c.entity) return;
209
+ const entity = c.entity;
210
+ const readAt = (lvl) => (id) => {
211
+ var _a3;
212
+ return (_a3 = c.choices[lvl]) == null ? void 0 : _a3[id];
213
+ };
214
+ if (i === 0 && ((_b2 = (_a2 = entity.skill_choices) == null ? void 0 : _a2.from) == null ? void 0 : _b2.length)) {
215
+ apply({
216
+ kind: "select-proficiency",
217
+ id: "skills",
218
+ count: entity.skill_choices.count,
219
+ domain: "skill",
220
+ from: entity.skill_choices.from
221
+ }, readAt(1)("skills"));
222
+ }
223
+ for (const rf of resolved.features) {
224
+ if (rf.source.kind !== "class" && rf.source.kind !== "subclass") continue;
225
+ const belongs = rf.source.kind === "class" ? rf.source.slug === entity.slug : c.subclass != null && rf.source.slug === c.subclass.slug;
226
+ if (!belongs) continue;
227
+ walk(rf.feature.choices, readAt(rf.source.level));
228
+ }
229
+ });
230
+ const oc = (_a = resolved.definition.origin_choices) != null ? _a : {};
231
+ const originRead = (ns) => (id) => oc[`${ns}:${id}`];
232
+ if (resolved.race) {
233
+ walk(resolved.race.choices, originRead("race"));
234
+ for (const t of (_b = resolved.race.traits) != null ? _b : []) walk(t.choices, originRead("race"));
235
+ }
236
+ if (resolved.background) {
237
+ walk(resolved.background.choices, originRead("background"));
238
+ if (resolved.background.feature) {
239
+ walk(resolved.background.feature.choices, originRead("background"));
240
+ }
241
+ }
242
+ return out;
243
+ }
244
+ function collectChosenAbilityPoints(resolved) {
245
+ var _a, _b, _c;
246
+ const oc = (_a = resolved.definition.origin_choices) != null ? _a : {};
247
+ const out = { race: {}, background: {} };
248
+ const fold = (ns, choices) => {
249
+ var _a2;
250
+ for (const ch of choices != null ? choices : []) {
251
+ if (ch.kind !== "ability-points") continue;
252
+ const raw = oc[`${ns}:${ch.id}`];
253
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
254
+ let left = ch.points;
255
+ for (const ab of ABILITY_KEYS) {
256
+ if (ch.pool && !ch.pool.includes(ab)) continue;
257
+ const v = raw[ab];
258
+ if (typeof v !== "number" || v <= 0 || left <= 0) continue;
259
+ const take = Math.min(v, ch.max_per, left);
260
+ out[ns][ab] = ((_a2 = out[ns][ab]) != null ? _a2 : 0) + take;
261
+ left -= take;
262
+ }
263
+ }
264
+ };
265
+ const race = resolved.race;
266
+ if (race) {
267
+ fold("race", race.choices);
268
+ for (const t of (_b = race.traits) != null ? _b : []) fold("race", t.choices);
269
+ }
270
+ const bg = resolved.background;
271
+ if (bg) {
272
+ fold("background", bg.choices);
273
+ fold("background", (_c = bg.feature) == null ? void 0 : _c.choices);
274
+ }
275
+ return out;
276
+ }
277
+ function buildDecisionLedger(resolved, ctx) {
278
+ var _a, _b, _c, _d;
279
+ const classes = [];
280
+ resolved.classes.forEach((c, classIndex) => {
281
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
282
+ if (!c.entity) return;
283
+ const entity = c.entity;
284
+ const ownerBare = bareEntitySlug(entity.slug);
285
+ const byLevel = /* @__PURE__ */ new Map();
286
+ const push = (lvl, item) => {
287
+ var _a3;
288
+ const arr = (_a3 = byLevel.get(lvl)) != null ? _a3 : [];
289
+ arr.push(item);
290
+ byLevel.set(lvl, arr);
291
+ };
292
+ const readAt = (lvl) => (id) => {
293
+ var _a3;
294
+ return (_a3 = c.choices[lvl]) == null ? void 0 : _a3[id];
295
+ };
296
+ if (classIndex === 0 && ((_b2 = (_a2 = entity.skill_choices) == null ? void 0 : _a2.from) == null ? void 0 : _b2.length)) {
297
+ const skillChoice = {
298
+ kind: "select-proficiency",
299
+ id: "skills",
300
+ label: "Skill Proficiencies",
301
+ count: entity.skill_choices.count,
302
+ domain: "skill",
303
+ from: entity.skill_choices.from
304
+ };
305
+ push(1, buildItem(
306
+ skillChoice,
307
+ { kind: "class", slug: entity.slug, level: 1 },
308
+ 1,
309
+ "Proficiencies",
310
+ readAt(1),
311
+ ctx,
312
+ ownerBare
313
+ ));
314
+ }
315
+ if (classIndex === 0) {
316
+ ((_c2 = entity.starting_equipment) != null ? _c2 : []).forEach((eq, i) => {
317
+ var _a3;
318
+ if (eq.kind !== "choice") return;
319
+ const options = (_a3 = eq.options) != null ? _a3 : [];
320
+ let degraded = false;
321
+ const ch = {
322
+ kind: "select-inline",
323
+ id: `equipment-${i}`,
324
+ label: "Starting Equipment",
325
+ count: 1,
326
+ options: options.map((opt, j) => {
327
+ var _a4;
328
+ const label = typeof opt === "string" ? opt : (_a4 = opt == null ? void 0 : opt.label) != null ? _a4 : "";
329
+ const grants = opt && typeof opt === "object" && Array.isArray(opt.grants) ? opt.grants : [];
330
+ if (typeof opt === "string" || !(opt && typeof opt === "object" && Array.isArray(opt.grants))) {
331
+ degraded = true;
332
+ }
333
+ return {
334
+ value: `option-${j}`,
335
+ label,
336
+ choices: grants.flatMap((g, k) => g && typeof g === "object" && "category" in g && g.category ? [categoryToEntitySelect(g.category, `equipment-${i}-opt-${j}-cat-${k}`)] : [])
337
+ };
338
+ })
339
+ };
340
+ if (degraded && !warnedDegradedEquipment.has(entity.slug)) {
341
+ warnedDegradedEquipment.add(entity.slug);
342
+ console.warn(
343
+ `[archivist] Starting equipment for "${entity.slug}" is in an outdated/unstructured format; its nested picks and seeding are skipped. Re-sync the compendium (delete _compendium.md and reload) to fix.`
344
+ );
345
+ }
346
+ push(1, buildItem(
347
+ ch,
348
+ { kind: "class", slug: entity.slug, level: 1 },
349
+ 1,
350
+ "Starting Equipment",
351
+ readAt(1),
352
+ ctx,
353
+ ownerBare
354
+ ));
355
+ });
356
+ }
357
+ let sawAuthoredSubclass = false;
358
+ for (const rf of resolved.features) {
359
+ const src = rf.source;
360
+ if (src.kind !== "class" && src.kind !== "subclass") continue;
361
+ const belongs = src.kind === "class" ? src.slug === entity.slug : c.subclass != null && src.slug === c.subclass.slug;
362
+ if (!belongs) continue;
363
+ const lvl = src.level;
364
+ let choices = rf.feature.choices;
365
+ if (!(choices == null ? void 0 : choices.length)) {
366
+ const recognized = recognizeDecision(rf.feature);
367
+ if (recognized === "informational") {
368
+ push(lvl, {
369
+ key: (_d2 = rf.feature.id) != null ? _d2 : rf.feature.name,
370
+ source: src,
371
+ level: lvl,
372
+ featureName: rf.feature.name,
373
+ description: (_f = rf.feature.description) != null ? _f : (_e = rf.feature.entries) == null ? void 0 : _e.join("\n\n"),
374
+ choice: { kind: "select-inline", id: (_g = rf.feature.id) != null ? _g : rf.feature.name, options: [{ value: "_", label: "_" }] },
375
+ options: [],
376
+ selected: void 0,
377
+ status: "informational"
378
+ });
379
+ continue;
380
+ }
381
+ choices = recognized != null ? recognized : void 0;
382
+ }
383
+ if (!(choices == null ? void 0 : choices.length)) {
384
+ if (rf.feature.description || ((_h = rf.feature.entries) == null ? void 0 : _h.length)) {
385
+ push(lvl, {
386
+ key: (_i = rf.feature.id) != null ? _i : rf.feature.name,
387
+ source: src,
388
+ level: lvl,
389
+ featureName: rf.feature.name,
390
+ description: (_k = rf.feature.description) != null ? _k : (_j = rf.feature.entries) == null ? void 0 : _j.join("\n\n"),
391
+ choice: { kind: "select-inline", id: (_l = rf.feature.id) != null ? _l : rf.feature.name, options: [{ value: "_", label: "_" }] },
392
+ options: [],
393
+ selected: void 0,
394
+ status: "informational"
395
+ });
396
+ }
397
+ continue;
398
+ }
399
+ for (const ch of choices) {
400
+ if (ch.kind === "select-entity" && ch.entity_type === "subclass") {
401
+ sawAuthoredSubclass = true;
402
+ push(lvl, buildSubclassItem(ch, src, lvl, rf.feature.name, c, ctx, ownerBare, rf.feature.description));
403
+ continue;
404
+ }
405
+ push(lvl, buildItem(
406
+ ch,
407
+ src,
408
+ lvl,
409
+ rf.feature.name,
410
+ readAt(lvl),
411
+ ctx,
412
+ ownerBare,
413
+ { description: rf.feature.description }
414
+ ));
415
+ }
416
+ }
417
+ const subclassLevel = (_m = entity.subclass_level) != null ? _m : null;
418
+ if (subclassLevel != null && subclassLevel <= c.level && !sawAuthoredSubclass) {
419
+ const featureName = (_n = entity.subclass_feature_name) != null ? _n : "Subclass";
420
+ const synthChoice = {
421
+ kind: "select-entity",
422
+ id: "subclass",
423
+ label: featureName,
424
+ count: 1,
425
+ entity_type: "subclass",
426
+ where: { parent_class: "self" }
427
+ };
428
+ push(subclassLevel, buildSubclassItem(
429
+ synthChoice,
430
+ { kind: "class", slug: entity.slug, level: subclassLevel },
431
+ subclassLevel,
432
+ featureName,
433
+ c,
434
+ ctx,
435
+ ownerBare
436
+ ));
437
+ }
438
+ for (const pool of resolved.pools) {
439
+ if (pool.classIndex !== classIndex || pool.count < 1) continue;
440
+ const synth = {
441
+ kind: "select-entity",
442
+ id: pool.id,
443
+ label: pool.label,
444
+ count: pool.count,
445
+ entity_type: "optional-feature",
446
+ from: pool.available.map((e) => e.slug)
447
+ };
448
+ push(pool.anchorLevel, buildItem(
449
+ synth,
450
+ { kind: "class", slug: entity.slug, level: pool.anchorLevel },
451
+ pool.anchorLevel,
452
+ pool.label,
453
+ readAt(pool.anchorLevel),
454
+ ctx,
455
+ ownerBare
456
+ ));
457
+ }
458
+ const levels = [...byLevel.entries()].sort(([a], [b]) => a - b).map(([level, items]) => ({ level, items }));
459
+ classes.push({ classIndex, levels });
460
+ });
461
+ const origin = [];
462
+ const oc = (_a = resolved.definition.origin_choices) != null ? _a : {};
463
+ const originRead = (ns) => (id) => oc[`${ns}:${id}`];
464
+ const pushOrigin = (choices, ns, source, featureName, ownerBare, description) => {
465
+ for (const ch of choices != null ? choices : []) {
466
+ origin.push(buildItem(ch, source, 0, featureName, originRead(ns), ctx, ownerBare, { description }));
467
+ }
468
+ };
469
+ if (resolved.race) {
470
+ const bare = bareEntitySlug(resolved.race.slug);
471
+ pushOrigin(
472
+ resolved.race.choices,
473
+ "race",
474
+ { kind: "race", slug: resolved.race.slug },
475
+ (_b = resolved.race.name) != null ? _b : "Race",
476
+ bare,
477
+ resolved.race.description
478
+ );
479
+ for (const t of (_c = resolved.race.traits) != null ? _c : []) {
480
+ pushOrigin(
481
+ t.choices,
482
+ "race",
483
+ { kind: "race", slug: resolved.race.slug },
484
+ t.name,
485
+ bare,
486
+ t.description
487
+ );
488
+ }
489
+ }
490
+ if (resolved.background) {
491
+ const bare = bareEntitySlug(resolved.background.slug);
492
+ pushOrigin(
493
+ resolved.background.choices,
494
+ "background",
495
+ { kind: "background", slug: resolved.background.slug },
496
+ (_d = resolved.background.name) != null ? _d : "Background",
497
+ bare,
498
+ resolved.background.description
499
+ );
500
+ if (resolved.background.feature) {
501
+ pushOrigin(
502
+ resolved.background.feature.choices,
503
+ "background",
504
+ { kind: "background", slug: resolved.background.slug },
505
+ resolved.background.feature.name,
506
+ bare,
507
+ resolved.background.feature.description
508
+ );
509
+ }
510
+ }
511
+ return { classes, origin };
512
+ }
513
+
514
+ export {
515
+ wikilinkTailSlug,
516
+ bareEntitySlug,
517
+ __matchesFilterForTest,
518
+ collectChosenProficiencies,
519
+ collectChosenAbilityPoints,
520
+ buildDecisionLedger
521
+ };
@@ -0,0 +1,38 @@
1
+ // src/pc/conditions.constants.ts
2
+ var CONDITION_SLUGS = [
3
+ "blinded",
4
+ "charmed",
5
+ "deafened",
6
+ "frightened",
7
+ "grappled",
8
+ "incapacitated",
9
+ "invisible",
10
+ "paralyzed",
11
+ "petrified",
12
+ "poisoned",
13
+ "prone",
14
+ "restrained",
15
+ "stunned",
16
+ "unconscious"
17
+ ];
18
+ var CONDITION_DISPLAY_NAMES = {
19
+ blinded: "Blinded",
20
+ charmed: "Charmed",
21
+ deafened: "Deafened",
22
+ frightened: "Frightened",
23
+ grappled: "Grappled",
24
+ incapacitated: "Incapacitated",
25
+ invisible: "Invisible",
26
+ paralyzed: "Paralyzed",
27
+ petrified: "Petrified",
28
+ poisoned: "Poisoned",
29
+ prone: "Prone",
30
+ restrained: "Restrained",
31
+ stunned: "Stunned",
32
+ unconscious: "Unconscious"
33
+ };
34
+
35
+ export {
36
+ CONDITION_SLUGS,
37
+ CONDITION_DISPLAY_NAMES
38
+ };
@@ -0,0 +1,65 @@
1
+ import {
2
+ resolveBaseItem
3
+ } from "./chunk-DC74TZNA.js";
4
+
5
+ // src/pc/pc.slotting.ts
6
+ function isItemEntity(e) {
7
+ return !!e && typeof e === "object" && "rarity" in e;
8
+ }
9
+ function isWeaponEntity(e) {
10
+ if (!e || typeof e !== "object") return false;
11
+ if (!("damage" in e) || !("category" in e)) return false;
12
+ const cat = e.category;
13
+ return typeof cat === "string" && /melee|ranged/.test(cat);
14
+ }
15
+ function isArmorEntity(e) {
16
+ return !!e && typeof e === "object" && "ac" in e && "category" in e && !("damage" in e);
17
+ }
18
+ function resolveEntityForEntry(item, registry) {
19
+ const found = resolveBaseItem(item, registry);
20
+ if (!found) return { entity: null, entityType: null };
21
+ return {
22
+ entity: found.data,
23
+ entityType: found.entityType
24
+ };
25
+ }
26
+ function isShieldArmor(armor) {
27
+ var _a, _b;
28
+ if (armor.category === "shield") return true;
29
+ const slug = ((_a = armor.slug) != null ? _a : "").toLowerCase();
30
+ if (slug === "shield" || slug.endsWith("_shield") || slug.endsWith("-shield")) return true;
31
+ return ((_b = armor.name) != null ? _b : "").trim().toLowerCase() === "shield";
32
+ }
33
+ function effectiveArmor(entity, registry) {
34
+ if (isArmorEntity(entity)) return entity;
35
+ if (isItemEntity(entity) && typeof entity.base_item === "string") {
36
+ const base = resolveBaseItem(entity.base_item, registry);
37
+ if ((base == null ? void 0 : base.entityType) === "armor") return base.data;
38
+ }
39
+ return null;
40
+ }
41
+ function defaultSlotForType(entityType, entity, registry) {
42
+ if (entityType === "weapon") return "mainhand";
43
+ if (entityType === "armor") {
44
+ return isArmorEntity(entity) && isShieldArmor(entity) ? "shield" : "armor";
45
+ }
46
+ if (entityType === "item" && isItemEntity(entity) && typeof entity.base_item === "string") {
47
+ const base = resolveBaseItem(entity.base_item, registry);
48
+ if ((base == null ? void 0 : base.entityType) === "weapon") return "mainhand";
49
+ if ((base == null ? void 0 : base.entityType) === "armor") {
50
+ const armorData = base.data;
51
+ return isShieldArmor(armorData) ? "shield" : "armor";
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+
57
+ export {
58
+ isItemEntity,
59
+ isWeaponEntity,
60
+ isArmorEntity,
61
+ resolveEntityForEntry,
62
+ isShieldArmor,
63
+ effectiveArmor,
64
+ defaultSlotForType
65
+ };