@archivist-gg/dnd5e 0.3.19 → 0.3.26
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.
- package/LICENSE +48 -21
- package/README.md +26 -48
- package/dist/armor/armor.codec.d.ts +0 -7
- package/dist/armor/armor.codec.js +1 -9
- package/dist/armor/armor.parser.js +1 -8
- package/dist/armor/armor.schema.js +1 -7
- package/dist/armor/armor.types.d.ts +0 -3
- package/dist/background/background.codec.d.ts +0 -6
- package/dist/background/background.codec.js +1 -12
- package/dist/background/background.parser.js +1 -11
- package/dist/background/background.schema.js +1 -12
- package/dist/background/background.types.d.ts +0 -5
- package/dist/chunk-2EOGK6R6.js +1 -0
- package/dist/chunk-2HRRH3WL.js +1 -0
- package/dist/chunk-2NUDWOFG.js +1 -0
- package/dist/chunk-3LWOVRLA.js +1 -0
- package/dist/chunk-3QQOATV3.js +1 -0
- package/dist/chunk-4E2GIWJE.js +1 -0
- package/dist/chunk-4GN3GYMP.js +1 -0
- package/dist/chunk-4IAMSRHD.js +1 -0
- package/dist/chunk-4JEF3CET.js +1 -0
- package/dist/chunk-4KVVAENP.js +1 -0
- package/dist/chunk-4SYAKWY4.js +1 -0
- package/dist/chunk-56JK6VCL.js +1 -0
- package/dist/chunk-5XDCM6YK.js +1 -0
- package/dist/chunk-63YJPWTM.js +1 -0
- package/dist/chunk-6R46KYGU.js +1 -0
- package/dist/chunk-6W253VHH.js +1 -0
- package/dist/chunk-72PRMZRD.js +1 -0
- package/dist/chunk-757KM22B.js +1 -0
- package/dist/chunk-7EL3GWWJ.js +1 -0
- package/dist/chunk-7FPQJDFD.js +1 -0
- package/dist/chunk-AINRPPLH.js +1 -0
- package/dist/chunk-BC52J4LA.js +1 -0
- package/dist/chunk-BCXGB4HP.js +1 -0
- package/dist/chunk-BREHZNTL.js +1 -0
- package/dist/chunk-BZ6BGGZS.js +1 -0
- package/dist/chunk-CAPYNIGK.js +1 -0
- package/dist/chunk-CCAVZANF.js +1 -0
- package/dist/chunk-CCFIINBA.js +1 -0
- package/dist/chunk-CEHL7PPC.js +1 -0
- package/dist/chunk-CMIEZQL4.js +1 -0
- package/dist/chunk-CNMHADNV.js +1 -0
- package/dist/chunk-CSTAQQGX.js +1 -0
- package/dist/chunk-DTB7YBMZ.js +1 -0
- package/dist/chunk-DVUXUIPV.js +1 -0
- package/dist/chunk-DZITM5AG.js +1 -0
- package/dist/chunk-E3MS4M3N.js +1 -0
- package/dist/chunk-E7KFJLDR.js +1 -0
- package/dist/chunk-EAARMPCW.js +1 -0
- package/dist/chunk-EPA24PVZ.js +1 -0
- package/dist/chunk-ETDMOGFO.js +1 -0
- package/dist/chunk-EVT7MGAC.js +1 -0
- package/dist/chunk-FOLHTMSC.js +1 -0
- package/dist/chunk-GCYUCIDN.js +1 -0
- package/dist/chunk-GD7WRCNH.js +1 -0
- package/dist/chunk-GGQDQSIF.js +1 -0
- package/dist/chunk-GIQLIBC7.js +1 -0
- package/dist/chunk-HX7WBOKR.js +1 -0
- package/dist/chunk-I26FHSI6.js +1 -0
- package/dist/chunk-IHPLT2ZT.js +1 -0
- package/dist/chunk-J3RP5C7L.js +1 -0
- package/dist/chunk-J5GL6FLP.js +1 -0
- package/dist/chunk-JXDX2DKF.js +1 -0
- package/dist/chunk-KEXSF3CH.js +1 -0
- package/dist/chunk-KM75CC6Q.js +1 -0
- package/dist/chunk-L2DXF7YS.js +1 -0
- package/dist/chunk-LHH5XSEA.js +1 -0
- package/dist/chunk-LJNT3PJP.js +1 -0
- package/dist/chunk-LR6UMA5V.js +1 -0
- package/dist/chunk-M6RPOLKS.js +1 -0
- package/dist/chunk-MGGKZGLG.js +1 -0
- package/dist/chunk-NEMX7QGG.js +1 -0
- package/dist/chunk-NIWLD33X.js +1 -0
- package/dist/chunk-NU2Z7MTS.js +1 -0
- package/dist/chunk-NYPH7RQN.js +1 -0
- package/dist/chunk-NYTR6NJS.js +1 -0
- package/dist/chunk-O2QZ73GA.js +1 -0
- package/dist/chunk-O776WL7O.js +1 -0
- package/dist/chunk-ONCXJMJM.js +1 -0
- package/dist/chunk-OTRH62HY.js +1 -0
- package/dist/chunk-PFQPP77Q.js +1 -0
- package/dist/chunk-PKIMOVQG.js +1 -0
- package/dist/chunk-PZ3ZZ5H5.js +1 -0
- package/dist/chunk-PZ4L2EEG.js +1 -0
- package/dist/chunk-QMEKQTUT.js +1 -0
- package/dist/chunk-QVWT67WA.js +1 -0
- package/dist/chunk-RE5Z5RNK.js +1 -0
- package/dist/chunk-RHIEOYDX.js +1 -0
- package/dist/chunk-RQZCGXUZ.js +1 -0
- package/dist/chunk-S5UCI27C.js +1 -0
- package/dist/chunk-SEOASDO4.js +1 -0
- package/dist/chunk-SFK57JAA.js +1 -0
- package/dist/chunk-SU4MEZ5P.js +1 -0
- package/dist/chunk-T55DELVL.js +1 -0
- package/dist/chunk-TKIEPC6F.js +1 -0
- package/dist/chunk-UBUKCRZ3.js +1 -0
- package/dist/chunk-VA3ZWV7C.js +1 -0
- package/dist/chunk-VIP3FH2O.js +1 -0
- package/dist/chunk-VTQ4RWEG.js +1 -0
- package/dist/chunk-VVJXZZ4Z.js +1 -0
- package/dist/chunk-WAUNLUFQ.js +1 -0
- package/dist/chunk-X22SISGM.js +1 -0
- package/dist/chunk-XKJXT2PN.js +1 -0
- package/dist/chunk-XPF53K54.js +1 -0
- package/dist/chunk-YGH7S5ZF.js +1 -0
- package/dist/chunk-ZE46ADXS.js +1 -0
- package/dist/chunk-ZI3FEUX3.js +1 -0
- package/dist/chunk-ZS5BMNXC.js +1 -0
- package/dist/chunk-ZVL5FXXO.js +1 -0
- package/dist/class/class.codec.d.ts +0 -7
- package/dist/class/class.codec.js +1 -18
- package/dist/class/class.parser.js +1 -17
- package/dist/class/class.schema.d.ts +4 -3
- package/dist/class/class.schema.js +1 -15
- package/dist/class/class.slug.d.ts +0 -11
- package/dist/class/class.slug.js +1 -8
- package/dist/class/class.standard-array.d.ts +0 -7
- package/dist/class/class.standard-array.js +1 -20
- package/dist/class/class.types.d.ts +0 -20
- package/dist/condition/condition.codec.d.ts +0 -6
- package/dist/condition/condition.parser.d.ts +0 -10
- package/dist/condition/condition.parser.js +1 -7
- package/dist/condition/condition.schema.d.ts +0 -16
- package/dist/condition/condition.types.d.ts +0 -3
- package/dist/data-srd/index.generated.js +1 -146
- package/dist/dnd/amount-text.d.ts +3 -30
- package/dist/dnd/amount-text.js +1 -15
- package/dist/dnd/constants.d.ts +0 -18
- package/dist/dnd/constants.js +1 -42
- package/dist/dnd/formula-tags.d.ts +0 -2
- package/dist/dnd/formula-tags.js +1 -119
- package/dist/dnd/math.d.ts +0 -26
- package/dist/dnd/math.js +1 -45
- package/dist/dnd/prose-tags.d.ts +1 -15
- package/dist/dnd/prose-tags.js +1 -18
- package/dist/dnd/resource-die.d.ts +0 -4
- package/dist/dnd/resource-die.js +1 -17
- package/dist/dnd/resource-formula.d.ts +0 -43
- package/dist/dnd/resource-formula.js +1 -14
- package/dist/dnd/resource-words.d.ts +0 -2
- package/dist/dnd/resource-words.js +1 -30
- package/dist/dnd/srd-tag-converter.d.ts +0 -21
- package/dist/dnd/srd-tag-converter.js +1 -12
- package/dist/dnd/tag-grammar.js +1 -12
- package/dist/dnd/warn-once.js +1 -8
- package/dist/encounter/encounter.ai-schema.js +1 -8
- package/dist/entities/base-item-resolver.d.ts +0 -26
- package/dist/entities/base-item-resolver.js +1 -11
- package/dist/entities/registry-revision.d.ts +0 -15
- package/dist/entities/registry-revision.js +1 -10
- package/dist/entities/slug.d.ts +1 -31
- package/dist/entities/slug.js +1 -12
- package/dist/entities/wikilink-display.d.ts +0 -2
- package/dist/entities/wikilink-display.js +1 -10
- package/dist/feat/feat.category-codes.d.ts +1 -26
- package/dist/feat/feat.category-codes.js +1 -14
- package/dist/feat/feat.codec.d.ts +0 -6
- package/dist/feat/feat.codec.js +1 -12
- package/dist/feat/feat.parser.js +1 -11
- package/dist/feat/feat.schema.d.ts +46 -4
- package/dist/feat/feat.schema.js +1 -10
- package/dist/feat/feat.types.d.ts +0 -6
- package/dist/index.js +45 -141495
- package/dist/inline-tag-parser.js +1 -6
- package/dist/item/item.actions-map.d.ts +4 -63
- package/dist/item/item.actions-map.js +1 -10
- package/dist/item/item.ai-schema.js +1 -6
- package/dist/item/item.attunement.d.ts +0 -14
- package/dist/item/item.attunement.js +1 -6
- package/dist/item/item.bonuses.js +1 -10
- package/dist/item/item.codec.js +1 -9
- package/dist/item/item.conditions.d.ts +0 -7
- package/dist/item/item.conditions.js +1 -11
- package/dist/item/item.conditions.types.d.ts +0 -2
- package/dist/item/item.cost.js +1 -29
- package/dist/item/item.enrichment.js +1 -9
- package/dist/item/item.icon.d.ts +0 -8
- package/dist/item/item.icon.js +1 -211
- package/dist/item/item.parser.js +1 -8
- package/dist/item/item.schema.d.ts +5 -0
- package/dist/item/item.schema.js +1 -11
- package/dist/item/item.types.d.ts +5 -28
- package/dist/monster/monster.ai-schema.js +1 -6
- package/dist/monster/monster.codec.d.ts +0 -10
- package/dist/monster/monster.enrichment.js +1 -19
- package/dist/monster/monster.format.d.ts +0 -69
- package/dist/monster/monster.format.js +1 -78
- package/dist/monster/monster.parser.d.ts +0 -4
- package/dist/monster/monster.parser.js +1 -15
- package/dist/monster/monster.resolve.d.ts +0 -4
- package/dist/monster/monster.schema.d.ts +0 -9
- package/dist/monster/monster.schema.js +1 -34
- package/dist/monster/monster.types.d.ts +0 -3
- package/dist/monster/monster.types.js +1 -1
- package/dist/optional-feature/optional-feature.codec.d.ts +0 -11
- package/dist/optional-feature/optional-feature.codec.js +1 -13
- package/dist/optional-feature/optional-feature.parser.js +1 -12
- package/dist/optional-feature/optional-feature.schema.d.ts +44 -3
- package/dist/optional-feature/optional-feature.schema.js +1 -15
- package/dist/pack.d.ts +0 -9
- package/dist/pc/conditions.constants.js +1 -6
- package/dist/pc/decision-recognizer.js +1 -8
- package/dist/pc/pc.additional-spells.d.ts +0 -24
- package/dist/pc/pc.additional-spells.js +1 -26
- package/dist/pc/pc.amount-bindings.d.ts +3 -28
- package/dist/pc/pc.amount-bindings.js +1 -28
- package/dist/pc/pc.asi-flatten.d.ts +0 -59
- package/dist/pc/pc.asi-flatten.js +1 -16
- package/dist/pc/pc.conditions.d.ts +1 -0
- package/dist/pc/pc.conditions.js +1 -6
- package/dist/pc/pc.containment.d.ts +0 -5
- package/dist/pc/pc.containment.js +1 -24
- package/dist/pc/pc.decision-engine.d.ts +6 -145
- package/dist/pc/pc.decision-engine.js +1 -55
- package/dist/pc/pc.defense-normalize.d.ts +0 -10
- package/dist/pc/pc.defense-normalize.js +1 -6
- package/dist/pc/pc.entry-overrides.d.ts +19 -58
- package/dist/pc/pc.entry-overrides.js +1 -41
- package/dist/pc/pc.equipment.d.ts +2 -22
- package/dist/pc/pc.equipment.js +1 -34
- package/dist/pc/pc.feature-effects.d.ts +27 -281
- package/dist/pc/pc.feature-effects.js +1 -39
- package/dist/pc/pc.formula-context.js +1 -11
- package/dist/pc/pc.infusions.d.ts +0 -65
- package/dist/pc/pc.infusions.js +1 -65
- package/dist/pc/pc.item-effects.d.ts +19 -0
- package/dist/pc/pc.item-effects.js +1 -0
- package/dist/pc/pc.member-choices.d.ts +3 -66
- package/dist/pc/pc.member-choices.js +1 -39
- package/dist/pc/pc.parser.js +1 -58
- package/dist/pc/pc.pools.d.ts +7 -10
- package/dist/pc/pc.pools.js +1 -27
- package/dist/pc/pc.proficiencies.d.ts +0 -40
- package/dist/pc/pc.proficiencies.js +1 -156
- package/dist/pc/pc.proficiency-grants.d.ts +3 -27
- package/dist/pc/pc.proficiency-normalize.d.ts +0 -35
- package/dist/pc/pc.proficiency-normalize.js +1 -18
- package/dist/pc/pc.proficiency-query.d.ts +0 -13
- package/dist/pc/pc.proficiency-query.js +1 -27
- package/dist/pc/pc.recalc.d.ts +8 -131
- package/dist/pc/pc.recalc.js +1 -1042
- package/dist/pc/pc.resolver.d.ts +9 -107
- package/dist/pc/pc.resolver.js +1 -60
- package/dist/pc/pc.resource-seed.d.ts +0 -8
- package/dist/pc/pc.resource-seed.js +1 -42
- package/dist/pc/pc.resources.d.ts +1 -59
- package/dist/pc/pc.resources.js +1 -23
- package/dist/pc/pc.rest.d.ts +1 -20
- package/dist/pc/pc.rest.js +1 -231
- package/dist/pc/pc.schema.d.ts +20 -2
- package/dist/pc/pc.schema.js +1 -9
- package/dist/pc/pc.slotting.d.ts +0 -29
- package/dist/pc/pc.slotting.js +1 -28
- package/dist/pc/pc.speeds.d.ts +36 -0
- package/dist/pc/pc.spell-scope.d.ts +0 -16
- package/dist/pc/pc.spellcasting.d.ts +0 -70
- package/dist/pc/pc.spellcasting.js +1 -28
- package/dist/pc/pc.table-column.d.ts +3 -22
- package/dist/pc/pc.table-column.js +1 -18
- package/dist/pc/pc.tool-picks.d.ts +0 -27
- package/dist/pc/pc.tool-picks.js +1 -18
- package/dist/pc/pc.types.d.ts +59 -374
- package/dist/pc/pc.weapon-grant.d.ts +0 -6
- package/dist/pc/pool-layout.d.ts +0 -39
- package/dist/pc/pool-layout.js +1 -18
- package/dist/pc/resource-equivalents.d.ts +2 -40
- package/dist/pc/roll-scope.js +1 -8
- package/dist/pc/roll-tag-labels.d.ts +0 -32
- package/dist/pc/roll-tag-labels.js +1 -17
- package/dist/pc/spell-source.d.ts +0 -11
- package/dist/pc/spell-source.js +1 -8
- package/dist/race/race.codec.d.ts +0 -6
- package/dist/race/race.codec.js +1 -15
- package/dist/race/race.parser.js +1 -14
- package/dist/race/race.schema.d.ts +0 -8
- package/dist/race/race.schema.js +1 -14
- package/dist/race/race.structural.d.ts +0 -6
- package/dist/race/race.structural.js +1 -6
- package/dist/race/race.types.d.ts +0 -8
- package/dist/schemas/attack-schema.d.ts +5 -0
- package/dist/schemas/caster-type-schema.d.ts +1 -6
- package/dist/schemas/caster-type-schema.js +1 -6
- package/dist/schemas/choice-schema.js +1 -7
- package/dist/schemas/duration-schema.d.ts +0 -2
- package/dist/schemas/duration-schema.js +1 -6
- package/dist/schemas/entity-extras-schema.d.ts +0 -30
- package/dist/schemas/entity-extras-schema.js +1 -10
- package/dist/schemas/equipment-grant-schema.d.ts +0 -2
- package/dist/schemas/equipment-grant-schema.js +1 -12
- package/dist/schemas/feature-alias.d.ts +0 -27
- package/dist/schemas/feature-effect-schema.d.ts +44 -3
- package/dist/schemas/feature-effect-schema.js +1 -6
- package/dist/schemas/feature-schema.d.ts +0 -6
- package/dist/schemas/feature-schema.js +1 -12
- package/dist/schemas/resource-schema.d.ts +1 -34
- package/dist/schemas/resource-schema.js +1 -12
- package/dist/schemas/selection-pool-schema.js +1 -10
- package/dist/spell/casting-time.d.ts +0 -15
- package/dist/spell/casting-time.js +1 -6
- package/dist/spell/spell.access.d.ts +0 -6
- package/dist/spell/spell.access.js +1 -45
- package/dist/spell/spell.ai-schema.js +1 -6
- package/dist/spell/spell.codec.js +1 -9
- package/dist/spell/spell.enrichment.js +1 -9
- package/dist/spell/spell.filter.d.ts +0 -5
- package/dist/spell/spell.filter.js +1 -75
- package/dist/spell/spell.parser.d.ts +0 -31
- package/dist/spell/spell.parser.js +1 -16
- package/dist/spell/spell.scaling.d.ts +0 -46
- package/dist/spell/spell.scaling.js +1 -79
- package/dist/spell/spell.schema.js +1 -7
- package/dist/spell/spell.types.d.ts +0 -7
- package/dist/srd/retired-items.d.ts +0 -4
- package/dist/srd/retired-items.js +1 -11
- package/dist/srd-store.d.ts +0 -33
- package/dist/subclass/subclass.codec.d.ts +0 -8
- package/dist/subclass/subclass.codec.js +1 -17
- package/dist/subclass/subclass.parser.js +1 -16
- package/dist/subclass/subclass.schema.d.ts +2 -1
- package/dist/subclass/subclass.schema.js +1 -14
- package/dist/subclass/subclass.types.d.ts +0 -3
- package/dist/types/attack.d.ts +2 -0
- package/dist/types/casting-option.d.ts +0 -4
- package/dist/types/choice.d.ts +1 -72
- package/dist/types/choice.js +1 -24
- package/dist/types/edition.d.ts +0 -3
- package/dist/types/equipment-grant.d.ts +1 -27
- package/dist/types/equipment-grant.js +1 -12
- package/dist/types/feature-effect.d.ts +11 -23
- package/dist/types/feature.d.ts +0 -22
- package/dist/types/optional-feature.types.d.ts +1 -31
- package/dist/types/resource.d.ts +1 -21
- package/dist/types/selection-pool.d.ts +0 -24
- package/dist/weapon/weapon-mastery.d.ts +0 -1
- package/dist/weapon/weapon.classify.d.ts +0 -11
- package/dist/weapon/weapon.classify.js +1 -7
- package/dist/weapon/weapon.codec.d.ts +0 -9
- package/dist/weapon/weapon.codec.js +1 -9
- package/dist/weapon/weapon.parser.js +1 -8
- package/dist/weapon/weapon.schema.js +1 -7
- package/dist/weapon/weapon.types.d.ts +0 -3
- package/package.json +3 -3
- package/src/data-srd/ATTRIBUTION.md +1 -1
- package/dist/chunk-2FRUSVZS.js +0 -489
- package/dist/chunk-2LULMQTF.js +0 -14
- package/dist/chunk-3LWMFYKS.js +0 -57
- package/dist/chunk-3SFGWFVQ.js +0 -19
- package/dist/chunk-3SIUAFDQ.js +0 -18
- package/dist/chunk-3TM34RSJ.js +0 -23
- package/dist/chunk-4J6DS3EJ.js +0 -30
- package/dist/chunk-4U55VNC7.js +0 -22
- package/dist/chunk-5GKJAUMX.js +0 -59
- package/dist/chunk-5JXFJ5AU.js +0 -26
- package/dist/chunk-64VNLMSG.js +0 -375
- package/dist/chunk-656QCX4U.js +0 -22
- package/dist/chunk-6GNXYAYP.js +0 -25
- package/dist/chunk-6PXTNCBP.js +0 -133
- package/dist/chunk-6X2NV665.js +0 -33
- package/dist/chunk-7Q2VPKCD.js +0 -181
- package/dist/chunk-7XJHI5H5.js +0 -709
- package/dist/chunk-A54HHCWW.js +0 -67
- package/dist/chunk-B2QHP6UF.js +0 -159
- package/dist/chunk-B3DP42OM.js +0 -55
- package/dist/chunk-BJGOSM76.js +0 -18
- package/dist/chunk-BJWSOQUC.js +0 -133
- package/dist/chunk-CJYCVNW2.js +0 -7
- package/dist/chunk-CM5CWO4K.js +0 -735
- package/dist/chunk-DEEHHLAP.js +0 -271
- package/dist/chunk-DPUJDOKV.js +0 -365
- package/dist/chunk-EJD47JHL.js +0 -1838
- package/dist/chunk-EJP263OP.js +0 -186
- package/dist/chunk-EVMUJYUD.js +0 -195
- package/dist/chunk-EYX4JMAU.js +0 -101
- package/dist/chunk-FC4IGH5Y.js +0 -18
- package/dist/chunk-FJYBLXV7.js +0 -89
- package/dist/chunk-FMUD3LDV.js +0 -19
- package/dist/chunk-FMYWORTP.js +0 -93
- package/dist/chunk-FVXLP7P3.js +0 -18
- package/dist/chunk-G6MHJDVT.js +0 -41
- package/dist/chunk-GVWEFECG.js +0 -18
- package/dist/chunk-HHBD4SQ6.js +0 -24
- package/dist/chunk-HS6FIOLP.js +0 -52
- package/dist/chunk-HY2SRSVM.js +0 -23
- package/dist/chunk-IHE6KVC3.js +0 -13
- package/dist/chunk-IN4M4X7P.js +0 -34
- package/dist/chunk-IUAAXXNO.js +0 -58
- package/dist/chunk-JXWNXIIZ.js +0 -219
- package/dist/chunk-K5NJBTE2.js +0 -18
- package/dist/chunk-KR6JF3BF.js +0 -14
- package/dist/chunk-KSTV7J2U.js +0 -112
- package/dist/chunk-KU3YLF6D.js +0 -106
- package/dist/chunk-LBEXLN6I.js +0 -91
- package/dist/chunk-LHZXYFBU.js +0 -94
- package/dist/chunk-LICYHPI3.js +0 -237
- package/dist/chunk-LNT64X7C.js +0 -81
- package/dist/chunk-LSLSG67V.js +0 -31
- package/dist/chunk-LVQLWRCU.js +0 -15
- package/dist/chunk-MYY2C5MB.js +0 -233
- package/dist/chunk-NKZMQV2C.js +0 -19
- package/dist/chunk-NTU2DXNG.js +0 -355
- package/dist/chunk-NXUY5XQN.js +0 -1062
- package/dist/chunk-NZO7M5GV.js +0 -18
- package/dist/chunk-OOL4KMG2.js +0 -71
- package/dist/chunk-OOSRUJBI.js +0 -19
- package/dist/chunk-PDJSUH24.js +0 -110
- package/dist/chunk-PTXBIDG7.js +0 -63
- package/dist/chunk-PVCEA4HZ.js +0 -6
- package/dist/chunk-QA3YCOML.js +0 -101
- package/dist/chunk-QFWQKS3M.js +0 -110
- package/dist/chunk-QS5L5YTJ.js +0 -24
- package/dist/chunk-QYZV2MQA.js +0 -97
- package/dist/chunk-RD2MID3M.js +0 -292
- package/dist/chunk-S3YUXDSC.js +0 -278
- package/dist/chunk-S7REMWW4.js +0 -21
- package/dist/chunk-TOM66P2P.js +0 -38
- package/dist/chunk-TRBGC4ZG.js +0 -112
- package/dist/chunk-UA5KS2PL.js +0 -26
- package/dist/chunk-UJCK5IW4.js +0 -187
- package/dist/chunk-UNYR5GLI.js +0 -23
- package/dist/chunk-UZXG6QSY.js +0 -58
- package/dist/chunk-VN5DLURA.js +0 -158
- package/dist/chunk-VP5TIXDK.js +0 -178
- package/dist/chunk-VPYBK2MG.js +0 -18
- package/dist/chunk-VTTA2ALZ.js +0 -16
- package/dist/chunk-W6GC6OKK.js +0 -16
- package/dist/chunk-WELIKLZF.js +0 -256
- package/dist/chunk-WOHX7YTH.js +0 -165
- package/dist/chunk-WSVMLNTO.js +0 -31
- package/dist/chunk-WYGD2UGN.js +0 -14
- package/dist/chunk-XCFC7LGF.js +0 -122
- package/dist/chunk-XJ2F2WO6.js +0 -8
- package/dist/chunk-XTEFPUSN.js +0 -23
- package/dist/chunk-YBLDE5CG.js +0 -42
- package/dist/chunk-YDGMBMYI.js +0 -25
- package/dist/chunk-YHYTW5QA.js +0 -20
- package/dist/chunk-ZCTUYGNV.js +0 -26
- package/dist/chunk-ZDAEGJH4.js +0 -102
- package/dist/chunk-ZJXSXVFP.js +0 -58
- package/dist/chunk-ZOWKWMD2.js +0 -18
- package/dist/chunk-ZUQW5VBZ.js +0 -89
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-NIWLD33X.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{featEntitySchema}from"./chunk-GIQLIBC7.js";import{parseYaml}from"@archivist-gg/core";function parseFeat(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=featEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`feat schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseFeat};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readTableColumn}from"./chunk-CSTAQQGX.js";import{bareSlug,baseClassName}from"./chunk-CAPYNIGK.js";import{abilityModifier}from"./chunk-7FPQJDFD.js";function hasPreparedColumn(table){return Object.values(table).some(row=>PREPARED_COLUMNS.some(k=>{var _a;return((_a=row==null?void 0:row.columns)==null?void 0:_a[k])!==void 0}))}function resolveSpellcasting(rc){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p;const sub=(_b=(_a=rc.subclass)==null?void 0:_a.spellcasting)!=null?_b:null;const cls=(_d=(_c=rc.entity)==null?void 0:_c.spellcasting)!=null?_d:null;const casterType=(_f=(_e=sub==null?void 0:sub.caster_type)!=null?_e:cls==null?void 0:cls.caster_type)!=null?_f:null;const ability=(_h=(_g=sub==null?void 0:sub.ability)!=null?_g:cls==null?void 0:cls.ability)!=null?_h:null;if(!casterType||!ability)return null;const table=(_l=(_k=(sub==null?void 0:sub.caster_type)?(_i=rc.subclass)==null?void 0:_i.table:void 0)!=null?_k:(_j=rc.entity)==null?void 0:_j.table)!=null?_l:{};const preparation=(_n=(_m=sub==null?void 0:sub.preparation)!=null?_m:cls==null?void 0:cls.preparation)!=null?_n:hasPreparedColumn(table)?"prepared":"known";const spellList=(_p=(_o=sub==null?void 0:sub.spell_list)!=null?_o:cls==null?void 0:cls.spell_list)!=null?_p:null;return{ability,casterType,preparation,spellList,table}}function effectiveSpellcastingAbility(classSlug,dataAbility,overrides){var _a,_b;return(_b=(_a=overrides.spellcasting_ability_by_class)==null?void 0:_a[classSlug])!=null?_b:dataAbility}function normalizeKnownSpell(entry){var _a,_b;if(typeof entry==="string"){return{slug:bareSlug(entry),classSlug:null,source:"class",preparedFlag:void 0,alwaysPrepared:false}}return{slug:bareSlug(entry.spell),classSlug:entry.class?bareSlug(entry.class):null,source:(_a=entry.source)!=null?_a:"class",preparedFlag:entry.prepared,alwaysPrepared:(_b=entry.always_prepared)!=null?_b:false}}function firstListedCasterClass(spellClasses,casterClassSlugs){var _a;if(!Array.isArray(spellClasses)||spellClasses.length===0)return null;const listed=new Set(spellClasses.map(c=>baseClassName(String(c))));return(_a=casterClassSlugs.find(slug=>listed.has(baseClassName(slug))))!=null?_a:null}var LISTED_CLASS_NAMES=new WeakMap;var NO_NAMES=new Set;function listedSpellClassNames(registry,compendium){var _a;const count=registry.count();let cached=LISTED_CLASS_NAMES.get(registry);if(!cached||cached.count!==count){const byCompendium=new Map;for(const e of registry.search("","spell",Number.POSITIVE_INFINITY)){const classes=e.data.classes;if(!Array.isArray(classes))continue;let names=byCompendium.get(e.compendium);if(!names)byCompendium.set(e.compendium,names=new Set);for(const c of classes)names.add(baseClassName(String(c)))}cached={count,byCompendium};LISTED_CLASS_NAMES.set(registry,cached)}return(_a=cached.byCompendium.get(compendium))!=null?_a:NO_NAMES}function attributeUnclassedSpell(spellClasses,casters,registry){var _a;const first=casters[0];if(!first)return null;const listed=firstListedCasterClass(spellClasses,casters.map(c=>c.classSlug));if(listed==null||listed===first.classSlug)return first.classSlug;if(first.spellList==null)return first.classSlug;const compendium=(_a=registry.getByTypeAndSlug("class",first.classSlug))==null?void 0:_a.compendium;if(compendium==null||!listedSpellClassNames(registry,compendium).has(baseClassName(first.classSlug)))return first.classSlug;return listed}var FULL_CASTER_SLOTS=[[2,0,0,0,0,0,0,0,0],[3,0,0,0,0,0,0,0,0],[4,2,0,0,0,0,0,0,0],[4,3,0,0,0,0,0,0,0],[4,3,2,0,0,0,0,0,0],[4,3,3,0,0,0,0,0,0],[4,3,3,1,0,0,0,0,0],[4,3,3,2,0,0,0,0,0],[4,3,3,3,1,0,0,0,0],[4,3,3,3,2,0,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,1],[4,3,3,3,3,1,1,1,1],[4,3,3,3,3,2,1,1,1],[4,3,3,3,3,2,2,1,1]];var HALF_CASTER_SLOTS=[[0,0,0,0,0],[2,0,0,0,0],[3,0,0,0,0],[3,0,0,0,0],[4,2,0,0,0],[4,2,0,0,0],[4,3,0,0,0],[4,3,0,0,0],[4,3,2,0,0],[4,3,2,0,0],[4,3,3,0,0],[4,3,3,0,0],[4,3,3,1,0],[4,3,3,1,0],[4,3,3,2,0],[4,3,3,2,0],[4,3,3,3,1],[4,3,3,3,1],[4,3,3,3,2],[4,3,3,3,2]];var THIRD_CASTER_SLOTS=[[0,0,0,0],[0,0,0,0],[2,0,0,0],[3,0,0,0],[3,0,0,0],[3,0,0,0],[4,2,0,0],[4,2,0,0],[4,2,0,0],[4,3,0,0],[4,3,0,0],[4,3,0,0],[4,3,2,0],[4,3,2,0],[4,3,2,0],[4,3,3,0],[4,3,3,0],[4,3,3,0],[4,3,3,1],[4,3,3,1]];var PACT_MAGIC=[{level:1,total:1},{level:1,total:2},{level:2,total:2},{level:2,total:2},{level:3,total:2},{level:3,total:2},{level:4,total:2},{level:4,total:2},{level:5,total:2},{level:5,total:2},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:4},{level:5,total:4},{level:5,total:4},{level:5,total:4}];var HALF_UP_CASTER_SLOTS=HALF_CASTER_SLOTS.map(row=>[...row]);HALF_UP_CASTER_SLOTS[0]=[2,0,0,0,0];function slotTableFor(caster){switch(caster){case"full":return FULL_CASTER_SLOTS;case"half":return HALF_CASTER_SLOTS;case"third":return THIRD_CASTER_SLOTS;case"half-up":return HALF_UP_CASTER_SLOTS;default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function rowToRecord(row){const out={};row.forEach((n,i)=>{if(n>0)out[i+1]=n});return out}function deriveSpellSlots(classes){let fullLevels=0,halfLevels=0,thirdLevels=0,halfUpLevels=0,warlockLevel=0;const regular=[];for(const c of classes){if(c.casterType==="pact"){warlockLevel+=c.level;continue}regular.push({caster:c.casterType,level:c.level});switch(c.casterType){case"full":fullLevels+=c.level;break;case"half":halfLevels+=c.level;break;case"third":thirdLevels+=c.level;break;case"half-up":halfUpLevels+=c.level;break;default:{const _n=c.casterType;throw new Error(`unknown caster type ${String(_n)}`)}}}let standard={};if(regular.length===1){const only=regular[0];const table=slotTableFor(only.caster);const idx=only.level-1;if(idx>=0&&idx<table.length)standard=rowToRecord(table[idx])}else if(regular.length>=2){const cl=fullLevels+Math.floor(halfLevels/2)+Math.floor(thirdLevels/3)+Math.ceil(halfUpLevels/2);if(cl>=1&&cl<=FULL_CASTER_SLOTS.length)standard=rowToRecord(FULL_CASTER_SLOTS[cl-1])}const pact=warlockLevel>=1&&warlockLevel<=PACT_MAGIC.length?PACT_MAGIC[warlockLevel-1]:null;return{standard,pact}}var PREPARED_COLUMNS=["Prepared Spells","Spells Prepared"];function preparedLevelTerm(caster,level){switch(caster){case"full":case"pact":return level;case"half":case"half-up":return Math.floor(level/2);case"third":return Math.floor(level/3);default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function computeSpellLimits(inputs){const out=[];for(const i of inputs){const p=i.profile;const cantripsKnown=readTableColumn(p.table,i.level,["Cantrips Known","Cantrips"]);const mod=abilityModifier(i.abilityScore);let preparedOrKnown;if(p.preparation==="prepared"){const fromTable=readTableColumn(p.table,i.level,PREPARED_COLUMNS);preparedOrKnown=fromTable!==null?fromTable:Math.max(1,mod+preparedLevelTerm(p.casterType,i.level))}else{preparedOrKnown=readTableColumn(p.table,i.level,["Spells Known","Prepared Spells"])}out.push({classSlug:i.classSlug,kind:p.preparation,cantripsKnown,preparedOrKnown})}return out}export{resolveSpellcasting,effectiveSpellcastingAbility,normalizeKnownSpell,listedSpellClassNames,attributeUnclassedSpell,slotTableFor,deriveSpellSlots,PREPARED_COLUMNS,preparedLevelTerm,computeSpellLimits};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseCastingTime}from"./chunk-CMIEZQL4.js";import{readTableColumn}from"./chunk-CSTAQQGX.js";import{derivePoolLayout}from"./chunk-O776WL7O.js";import{findItemAction,isReadOnceItem,resolveItemAction}from"./chunk-DVUXUIPV.js";import{requiresAttunement}from"./chunk-YGH7S5ZF.js";import{defaultSlotForType,effectiveArmor,isItemEntity,isShieldArmor,resolveEntityForEntry,slotAcTerms}from"./chunk-4IAMSRHD.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{keptSlugFor,resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bucketOf,memoByRevision}from"./chunk-QMEKQTUT.js";import{bareEntitySlug,slugify,twinKey,wikilinkTailSlug}from"./chunk-63YJPWTM.js";import{parseInlineTag}from"./chunk-BREHZNTL.js";import{isCanonicalDamageType}from"./chunk-7FPQJDFD.js";function equivalentResourceIds(id,index){var _a,_b,_c;const out=[];const add=other=>{if(other!==id&&index.has(other)&&!out.includes(other))out.push(other)};for(const other of(_b=(_a=index.get(id))==null?void 0:_a.equivalentIds)!=null?_b:[])add(other);for(const res of index.values())if((_c=res.equivalentIds)==null?void 0:_c.includes(id))add(res.id);return out}function ownedByClass(res,rc){var _a,_b;const s=(_a=res==null?void 0:res.owner)==null?void 0:_a.source;if(!s)return false;if(s.kind==="class")return s.slug===((_b=rc.entity)==null?void 0:_b.slug);if(s.kind==="subclass")return!!rc.subclass&&s.slug===rc.subclass.slug;return false}function payingResourceId(id,index,owner){const candidates=[id,...equivalentResourceIds(id,index)].filter(c=>index.has(c));if(candidates.length===0)return void 0;if(owner){const own=candidates.find(c=>ownedByClass(index.get(c),owner));if(own)return own}return candidates[0]}function classOfSource(source,classes){var _a,_b;if(source.kind==="class")return(_a=classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))!=null?_a:null;if(source.kind==="subclass")return(_b=classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))!=null?_b:null;return null}function bindFeatureConsumers(features,index,classes){return features.map(rf=>{const consumes=rf.feature.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return rf;const payer=payingResourceId(id,index,classOfSource(rf.source,classes));if(payer===void 0||payer===id)return rf;return{...rf,feature:{...rf.feature,consumes:{...consumes,resource:payer}}}})}var SORTED_OPTIONAL_FEATURES=new WeakMap;function sortedOptionalFeatures(registry){return memoByRevision(SORTED_OPTIONAL_FEATURES,registry,()=>bucketOf(registry,"optional-feature").slice().sort((a,b)=>a.name.localeCompare(b.name)||a.slug.localeCompare(b.slug)))}var SRD_OWNER_PREFIXES=new Set(["srd-5e","srd-2024"]);function levelPrereqMax(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="level").reduce((m,p)=>Math.max(m,p.min),0)}function namedRefKey(name){return name?slugify(name.replace(/\s*\([^)]*\)\s*$/,"")):""}function levelPrereqRefsMet(d,rc){var _a,_b;for(const p of(_a=d.prerequisites)!=null?_a:[]){if(p.kind!=="level")continue;if(p.class&&namedRefKey(p.class.name)!==namedRefKey((_b=rc.entity)==null?void 0:_b.name))return false;if(p.subclass){const sub=rc.subclass;const own=[sub==null?void 0:sub.short_name,sub==null?void 0:sub.name].map(namedRefKey).filter(k=>k!=="");if(!own.includes(namedRefKey(p.subclass.name)))return false}}return true}function optionalFeaturePrereqKeys(d){var _a;return((_a=d.prerequisites)!=null?_a:[]).filter(p=>p.kind==="optionalfeature").map(p=>twinKey(wikilinkTailSlug(p.optionalfeature)))}function withOptionalFeaturePrereqsMet(offered,selected,grants){let open=offered;for(;;){const openSlugs=new Set(open.map(e=>e.slug));const held=new Set([...grants,...selected.filter(e=>openSlugs.has(e.slug))].map(e=>twinKey(e.slug)));const next=open.filter(e=>optionalFeaturePrereqKeys(e.entity).every(k=>held.has(k)));if(next.length===open.length)return next;open=next}}function poolAnchorLevel(entity,pool){let anchorLevel=1;let columnSeen=false;for(let l=1;l<=20;l++){const c=readTableColumn(entity.table,l,[pool.count.column]);if(c!=null)columnSeen=true;if(c!=null&&c>=1){anchorLevel=l;break}}return{anchorLevel,columnSeen}}function resolvePool(rc,classIndex,pool,registry,index,edition){var _a,_b,_c,_d,_e,_f,_g,_h,_i;const entity=rc.entity;const level=rc.level;const ownerBare=bareEntitySlug(entity.slug);const ownerPrefix=entity.slug.split("_")[0];const ownEdition=SRD_OWNER_PREFIXES.has(ownerPrefix)?entity.edition:void 0;const col=pool.count.column;const count=(_a=readTableColumn(entity.table,level,[col]))!=null?_a:0;const{anchorLevel,columnSeen}=poolAnchorLevel(entity,pool);if(!columnSeen){warnOnce(`pool-column:${pool.id}`,`Archivist: pool "${pool.id}" declares count column "${col}", which "${entity.slug}"'s class table carries at no level; the pool resolves count 0 at anchor level 1`)}const ft=pool.source.where.feature_type;const all=sortedOptionalFeatures(registry);const entryOf=(slug,entity2,compendium)=>({slug,entity:entity2,...compendium?{compendium}:{},key:slug,param:null,itemBound:isItemBound(entity2)});const byBare=new Map;const candidates=new Map;for(const e of all){const d=e.data;const entry=entryOf(e.slug,d,e.compendium);const bare=bareEntitySlug(e.slug);byBare.set(bare,entry);if(d.feature_type!==ft)continue;if(!((_b=d.available_to)!=null?_b:[]).some(l=>wikilinkTailSlug(l)===ownerBare))continue;if(levelPrereqMax(d)>level)continue;if(!levelPrereqRefsMet(d,rc))continue;if(ownEdition&&d.edition&&d.edition!==ownEdition)continue;const key=twinKey(e.slug);const group=candidates.get(key);if(group)group.push(entry);else candidates.set(key,[entry])}const collapsed=[];for(const group of candidates.values()){if(group.length===1){collapsed.push(group[0]);continue}const bare=bareEntitySlug(group[0].slug);const owned=group.find(e=>e.slug.split("_")[0]===ownerPrefix);if(!owned){warnOnce(`pool-collapse:${bare}`,`Archivist: pool "${pool.id}" holds ${group.length} cross-edition entries for "${bare}" and none shares the owner's compendium prefix "${ownerPrefix}"; keeping "${group[0].slug}"`)}collapsed.push(owned!=null?owned:group[0])}const grantDecls=[...(_d=(_c=rc.entity)==null?void 0:_c.pool_grants)!=null?_d:[],...(_f=(_e=rc.subclass)==null?void 0:_e.pool_grants)!=null?_f:[]];const grantsRaw=grantDecls.filter(g=>g.pool===pool.id).flatMap(g=>g.grants).filter(g=>g.at_level<=level).map(g=>byBare.get(wikilinkTailSlug(g.feature))).filter(e=>e!=null);const grantedBare=new Set;const grants=grantsRaw.filter(e=>{const key=bareEntitySlug(e.slug);if(grantedBare.has(key))return false;grantedBare.add(key);return true});const offered=collapsed.filter(e=>!grantedBare.has(bareEntitySlug(e.slug)));const bySlugAvailable=new Map(offered.map(e=>[e.slug,e]));const byTwinAvailable=new Map(offered.map(e=>[twinKey(e.slug),e]));const resolveStored=s=>{const exact=bySlugAvailable.get(s);if(exact)return exact;const survivor=byTwinAvailable.get(twinKey(s));if(survivor)return survivor;const full=registry.getByTypeAndSlug("optional-feature",s);if(full)return entryOf(full.slug,full.data,full.compendium);return byBare.get(bareEntitySlug(s))};const raw=(_g=rc.choices[anchorLevel])==null?void 0:_g[pool.id];const selectedSlugs=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];const selected=[];const seenKeys=new Set;for(const s of selectedSlugs){const{slugPart,param}=parsePickKey(s);const entry=resolveStored(slugPart);if(!entry)continue;const repeatable=entry.entity.repeatable===true;if(!repeatable&¶m!==null){warnOnce(`pick-param:${pool.id}:${s}`,`Archivist: pool "${pool.id}" pick "${s}" names a parameter, but "${entry.slug}" is not repeatable; the parameter is ignored`)}const nkey=repeatable?normalizedPickKey(s,true):twinKey(entry.slug);if(grantedBare.has(bareEntitySlug(entry.slug))||seenKeys.has(nkey))continue;seenKeys.add(nkey);selected.push({...entry,key:repeatable||param!==null?s:entry.slug,param:repeatable?param:null,...repeatable?{option:resolveCopyOption(entry.entity,param,{classLevel:level,registry,edition})}:{}})}const available=withOptionalFeaturePrereqsMet(offered,selected,grants);const members=[...available,...grants];const layout=derivePoolLayout(members);const votes=new Map;for(const e of members){const id=(_h=e.entity.consumes)==null?void 0:_h.resource;const payer=id?payingResourceId(id,index,rc):void 0;if(!payer)continue;votes.set(payer,((_i=votes.get(payer))!=null?_i:0)+1)}let resource;let bestN=0;for(const[id,n]of votes)if(n>bestN){resource=id;bestN=n}const bind=poolRebinder(rc,pool.id,resource,index);return{id:pool.id,label:pool.label,classIndex,count,anchorLevel,selected:selected.map(bind),available:available.map(bind),grants:grants.map(bind),...layout?{layout}:{},...resource?{resource}:{},...pool.count.label?{countLabel:pool.count.label}:{},...pool.active?{active:pool.active}:{},...pool.head_resource?{headResource:pool.head_resource}:{}}}function poolRebinder(rc,poolId,vote,index){const declared=declaredResourceIds(rc);const copies=new Map;return e=>{const consumes=e.entity.consumes;const id=consumes==null?void 0:consumes.resource;if(!consumes||typeof id!=="string"||id.length===0)return e;const payer=payingResourceId(id,index,rc);if(payer===id)return e;const target=payer!=null?payer:vote!==void 0&&!declared.has(id)?vote:void 0;if(target===void 0)return e;const done=copies.get(e.key);if(done)return done;if(payer===void 0){warnOnce(`pool-rebind:${poolId}:${id}`,`Archivist: pool "${poolId}" members consume "${id}", which this character does not own; bound to the pool's resource "${target}"`)}const copy={...e,entity:{...e.entity,consumes:{...consumes,resource:target}}};copies.set(e.key,copy);return copy}}function declaredResourceIds(rc){var _a;const out=new Set;const add=list=>{for(const r of list!=null?list:[])if(typeof(r==null?void 0:r.id)==="string")out.add(r.id)};for(const owner of[rc.entity,rc.subclass]){if(!owner)continue;add(owner.resources);for(const features of Object.values((_a=owner.features_by_level)!=null?_a:{}))for(const f of features!=null?features:[])add(f.resources)}return out}function resolveAllPools(resolved,registry,index){const out=[];resolved.classes.forEach((rc,classIndex)=>{var _a,_b,_c,_d;if(!rc.entity)return;const decls=[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]];const seen=new Set;for(const pool of decls){if(seen.has(pool.id))continue;seen.add(pool.id);out.push(resolvePool(rc,classIndex,pool,registry,index,(_d=resolved.definition)==null?void 0:_d.edition))}});return out}function strandedPicks(pool){const inAvailable=new Set(pool.available.map(e=>e.slug));return pool.selected.filter(e=>!inAvailable.has(e.slug))}function heldPicks(pool){var _a;const selected=(_a=pool.selected)!=null?_a:[];if(!pool.available)return[...selected];const inAvailable=new Set(pool.available.map(e=>e.slug));return selected.filter(e=>inAvailable.has(e.slug))}function withoutStrandedSites(sites,classes,registry,edition){if(sites.length===0)return sites;const strandedKeys=new Map;const keysOf=(classIndex,poolId)=>{var _a,_b,_c;const at=`${classIndex}:${poolId}`;let keys=strandedKeys.get(at);if(keys)return keys;const rc=classes[classIndex];const decl=(rc==null?void 0:rc.entity)?[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]].find(p=>p.id===poolId):void 0;keys=new Set(rc&&decl?strandedPicks(resolvePool(rc,classIndex,decl,registry,new Map,edition)).map(e=>twinKey(e.slug)):[]);strandedKeys.set(at,keys);return keys};return sites.filter(site=>!keysOf(site.classIndex,site.poolId).has(twinKey(site.memberSlug)))}function poolCountLabel(pool){var _a;return(_a=pool.countLabel)!=null?_a:"Known"}function poolActiveWords(pool){var _a,_b,_c;const a=pool.active;if(!a)return null;return{column:a.column,label:a.label,verb:a.verb,counterLabel:(_a=a.counter_label)!=null?_a:a.label,createLabel:(_b=a.create_label)!=null?_b:"Created",createVerb:(_c=a.create_verb)!=null?_c:"Create"}}function parsePickKey(stored){const i=stored.indexOf("#");return i===-1?{slugPart:stored,param:null}:{slugPart:stored.slice(0,i),param:stored.slice(i+1)}}function normalizedPickKey(stored,repeatable){const{slugPart,param}=parsePickKey(stored);return repeatable?`${bareEntitySlug(slugPart)}#${param!=null?param:""}`:bareEntitySlug(slugPart)}function markerKey(by){const{slugPart,param}=parsePickKey(by);return param===null?bareEntitySlug(slugPart):`${bareEntitySlug(slugPart)}#${param}`}function isItemBound(note){var _a;return!!note.infuse||note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))}var SRD_BOOKS=new Set(["SRD 2024","SRD 5e"]);var lc=v=>String(v!=null?v:"").trim().toLowerCase();var linkSlug=link=>link.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0];var itemsOf=registry=>registry.search("","item",Number.POSITIVE_INFINITY);function matchesFilter(data,f){var _a;const type=lc(data.type);if(!f.rarity.map(lc).includes(lc(data.rarity)))return false;if(f.types&&!f.types.map(lc).includes(type))return false;if((_a=f.exclude_types)==null?void 0:_a.map(lc).includes(type))return false;return!(f.cursed===false&&data.cursed===true)}function rowMatches(row,it){const c=row.creates;if(c.item)return lc(it.name)===lc(row.name)||it.slug===linkSlug(c.item);if(c.variant)return c.variant.candidates.some(l=>bareEntitySlug(linkSlug(l))===bareEntitySlug(it.slug));return!!c.filter&&matchesFilter(it.data,c.filter)}function buildItemIndex(items){const lcType=[],lcRarity=[];const byLcName=new Map,bySlug=new Map,byBare=new Map;const push=(m,k,i)=>{const l=m.get(k);if(l)l.push(i);else m.set(k,[i])};items.forEach((it,i)=>{const data=it.data;lcType.push(lc(data.type));lcRarity.push(lc(data.rarity));push(byLcName,lc(it.name),i);if(!bySlug.has(it.slug))bySlug.set(it.slug,i);push(byBare,bareEntitySlug(it.slug),i)});return{items,lcType,lcRarity,byLcName,bySlug,byBare}}var ITEM_INDEX=new WeakMap;var itemIndexOf=registry=>memoByRevision(ITEM_INDEX,registry,()=>buildItemIndex(itemsOf(registry)));var inBucketOrder=(ix,hits)=>[...hits].sort((a,b)=>a-b).map(i=>ix.items[i]);function rowInstalledIn(row,ix){var _a,_b,_c;const c=row.creates;if(c.item){const hits=new Set((_a=ix.byLcName.get(lc(row.name)))!=null?_a:[]);const own=ix.bySlug.get(linkSlug(c.item));if(own!==void 0)hits.add(own);return inBucketOrder(ix,hits)}if(c.variant){const hits=new Set;for(const l of c.variant.candidates)for(const i of(_b=ix.byBare.get(bareEntitySlug(linkSlug(l))))!=null?_b:[])hits.add(i);return inBucketOrder(ix,hits)}const f=c.filter;if(!f)return[];const rarities=new Set(f.rarity.map(lc));const types=f.types?new Set(f.types.map(lc)):null;const excluded=new Set(((_c=f.exclude_types)!=null?_c:[]).map(lc));return ix.items.filter((it,i)=>rarities.has(ix.lcRarity[i])&&(!types||types.has(ix.lcType[i]))&&!excluded.has(ix.lcType[i])&&!(f.cursed===false&&it.data.cursed===true))}var rowInstalled=(row,registry)=>rowInstalledIn(row,itemIndexOf(registry));function candidateOrder(edition){return(a,b)=>{const ea=edition&&lc(a.data.edition)===edition?0:1;const eb=edition&&lc(b.data.edition)===edition?0:1;if(ea!==eb)return ea-eb;const sa=SRD_BOOKS.has(a.compendium)?0:1,sb=SRD_BOOKS.has(b.compendium)?0:1;if(sa!==sb)return sa-sb;return a.slug<b.slug?-1:a.slug>b.slug?1:0}}function optionCandidates(row,registry,opts={}){return candidatesFrom(rowInstalled(row,registry),registry,opts)}function candidatesFrom(installed,registry,opts){var _a,_b;const visible=(_a=opts.isEntityVisible)!=null?_a:(()=>true);const excluded=((_b=opts.exclude)!=null?_b:[]).map(s=>{var _a2;return registry.getByTypeAndSlug("item",(_a2=keptSlugFor(s))!=null?_a2:s)}).filter(e=>!!e);const exNames=new Set(excluded.map(e=>lc(e.name))),exBares=new Set(excluded.map(e=>bareEntitySlug(e.slug)));const seen=new Set,out=[];for(const e of installed.filter(visible).sort(candidateOrder(opts.edition))){const bare=bareEntitySlug(e.slug);if(seen.has(bare))continue;seen.add(bare);if(exNames.has(lc(e.name))||exBares.has(bare))continue;out.push(e.slug)}return out}function resolveOptionRows(note,registry,opts={}){var _a;const ix=itemIndexOf(registry);return((_a=note.options)!=null?_a:[]).map(row=>{var _a2;const rowItems=rowInstalledIn(row,ix);const candidates=candidatesFrom(rowItems,registry,opts);const anyVisible=candidates.length>0||candidatesFrom(rowItems,registry,{...opts,exclude:[]}).length>0;const installed=rowItems.length>0;return{key:row.key,name:row.name,minLevel:row.min_level,...row.attunement!==void 0?{attunement:row.attunement}:{},arm:row.creates.item?"item":row.creates.variant?"variant":"filter",candidates,availability:anyVisible?"installed":installed?"hidden-only":"not-installed",...rowItemWords(row,candidates[0]?ix.items[(_a2=ix.bySlug.get(candidates[0]))!=null?_a2:-1]:rowItems[0])}})}function rowItemWords(row,item){var _a,_b,_c,_d;const f=row.creates.filter;if(f)return{type:((_a=f.types)==null?void 0:_a[0])?lc(f.types[0]):null,rarity:f.rarity[0]?lc(f.rarity[0]):null,charges:null};const data=(_b=item==null?void 0:item.data)!=null?_b:{};const max=(_c=data.charges)==null?void 0:_c.max;return{type:lc(data.type)||null,rarity:lc(data.rarity)||null,charges:typeof max==="number"&&max>0?{max,...typeof((_d=data.charges)==null?void 0:_d.recharge)==="string"?{recharge:data.charges.recharge}:{}}:null}}function resolveCopyOption(note,param,ctx){var _a,_b,_c;const rows=(_a=note.options)!=null?_a:[];if(param===null||param==="")return{row:null,status:"needs-choice"};if(note.item_choice==="create"){const row=rows.find(r=>r.key===param);if(!row)return{row:null,status:"invalid"};const installed=rowInstalled(row,ctx.registry).sort(candidateOrder(ctx.edition));if(installed.length===0)return{row,status:"not-installed"};const own=row.creates.item?linkSlug(row.creates.item):void 0;const item=row.creates.item?((_b=installed.find(e=>e.slug===own))!=null?_b:installed[0]).slug:void 0;return{row,...item?{item}:{},status:row.min_level<=ctx.classLevel?"ok":"level"}}const slug=(_c=keptSlugFor(param))!=null?_c:param;const it=ctx.registry.getByTypeAndSlug("item",slug);if(!it)return{row:null,item:slug,status:"not-installed"};const matching=rows.filter(r=>rowMatches(r,it)).sort((a,b)=>a.min_level-b.min_level);if(matching.length===0)return{row:null,item:slug,status:"invalid"};return{row:matching[0],item:slug,status:matching[0].min_level<=ctx.classLevel?"ok":"level"}}var MUNDANE=new Set(["","none","mundane"]);var isMagic=data=>{const r=data==null?void 0:data.rarity;return typeof r==="string"&&!MUNDANE.has(r.trim().toLowerCase())};var plainText=item=>item.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|").pop().split("/").pop();function scaledInfuseItem(infuse,classLevel){var _a,_b;let item={...(_a=infuse.item)!=null?_a:{}};const rows=[...(_b=infuse.scales_at)!=null?_b:[]].sort((a,b)=>a.level-b.level);for(const row of rows)if(row.level<=classLevel)item={...item,...row.item};return item}function wrapInfused(entry,note,classLevel,registry){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k;const infuse=note.infuse;const item=scaledInfuseItem(infuse,classLevel);const resist=[...(_a=item.resist)!=null?_a:[],...((_b=infuse.choice)==null?void 0:_b.kind)==="damage-type"&&((_c=entry.infusion)==null?void 0:_c.choice)?[entry.infusion.choice]:[]];const overlay={...item.bonuses?{bonuses:item.bonuses}:{},resist,...item.charges?{charges:item.charges}:{},...item.action?{action:item.action}:{},...item.range?{range:item.range}:{},...infuse.attunement?{attunement:{required:true}}:{}};const base=resolveBaseItem(entry.item,registry);const data=(_d=base==null?void 0:base.data)!=null?_d:null;if(base&&isMagic(data)){const b=data;const bonuses={...(_e=b.bonuses)!=null?_e:{}};for(const[k,v]of Object.entries((_f=item.bonuses)!=null?_f:{}))if(typeof v==="number")bonuses[k]=(typeof bonuses[k]==="number"?bonuses[k]:0)+v;return{entity:{...b,bonuses,resist:[...new Set([...(_g=b.resist)!=null?_g:[],...resist])],attunement:{required:requiresAttunement(b)||!!infuse.attunement}},magicBase:true}}const rarity=(_h=infuse.rarity)!=null?_h:"unknown";if(!base){const text=plainText(entry.item);return{entity:{slug:`infused:${slugify(text)}`,name:text,type:"wondrous item",rarity,...overlay,description:""},magicBase:false}}const name=String((_i=data==null?void 0:data.name)!=null?_i:base.name),description=String((_j=data==null?void 0:data.description)!=null?_j:"");const slotted=base.entityType==="armor"||base.entityType==="weapon"?base:typeof(data==null?void 0:data.base_item)==="string"?resolveBaseItem(data.base_item,registry):null;if(slotted&&(slotted.entityType==="armor"||slotted.entityType==="weapon")){const type=slotted.entityType==="weapon"?"weapon":isShieldArmor(slotted.data)?"shield":"armor";return{entity:{slug:base.slug,name,type,rarity,base_item:`[[${slotted.slug}]]`,...overlay,description},magicBase:false}}return{entity:{slug:base.slug,name,type:String((_k=data==null?void 0:data.type)!=null?_k:"adventuring gear"),rarity,...overlay,description},magicBase:false}}function resolveEntryEntity(entry,index,registry,infusions){const view=!infusions?void 0:"views"in infusions?infusions.views.get(index):infusions.index===index?infusions:void 0;if(view)return{entity:view.entity,entityType:view.entityType};return resolveEntityForEntry(entry.item,registry)}function buildInfusionContext(character,resolved,registry){var _a,_b,_c,_d,_e;const equipment=(_a=character.equipment)!=null?_a:[];const pools=((_b=resolved.pools)!=null?_b:[]).filter(p=>!!p.active||p.selected.some(e=>e.itemBound));if(pools.length===0&&!equipment.some(e=>!!e.infusion))return void 0;const owners=new Map;for(const pool of pools)for(const entry of pool.selected)if(entry.itemBound)owners.set(normalizedPickKey(entry.key,entry.entity.repeatable===true),{pool,entry});const views=new Map,flags=[];const newest=new Map;equipment.forEach((e,i)=>{if(!e.infusion)return;const k=markerKey(e.infusion.by);const j=newest.get(k);if(j===void 0||equipment[j].infusion.seq<e.infusion.seq)newest.set(k,i)});equipment.forEach((e,i)=>{var _a2,_b2,_c2;const m=e.infusion;if(!m)return;const owner=owners.get(markerKey(m.by));const nullView=()=>{var _a3,_b3,_c3,_d2,_e2;return{index:i,kind:m.kind,entity:null,entityType:null,key:m.by,seq:m.seq,poolId:(_a3=owner==null?void 0:owner.pool.id)!=null?_a3:"",classIndex:(_b3=owner==null?void 0:owner.pool.classIndex)!=null?_b3:-1,noteSlug:(_c3=owner==null?void 0:owner.entry.slug)!=null?_c3:"",noteName:(_d2=owner==null?void 0:owner.entry.entity.name)!=null?_d2:"",sourceLabel:(_e2=owner==null?void 0:owner.entry.entity.name)!=null?_e2:""}};if(!owner){flags.push({index:i,reason:"orphan"});if(m.kind==="created")views.set(i,nullView());return}if(newest.get(markerKey(m.by))!==i){flags.push({index:i,reason:"duplicate"});if(m.kind==="created")views.set(i,nullView());return}if(((_a2=e.qty)!=null?_a2:1)>1)flags.push({index:i,reason:"stack"});const classLevel=(_c2=(_b2=resolved.classes[owner.pool.classIndex])==null?void 0:_b2.level)!=null?_c2:0;const base={index:i,kind:m.kind,key:m.by,seq:m.seq,poolId:owner.pool.id,classIndex:owner.pool.classIndex,noteSlug:owner.entry.slug,noteName:owner.entry.entity.name,sourceLabel:owner.entry.entity.name};if(m.kind==="created"){const own=resolveEntityForEntry(e.item,registry);const it=resolveBaseItem(e.item,registry);const opt=owner.entry.option;const fits=!!it&&!!(opt==null?void 0:opt.row)&&(opt.item===it.slug||rowMatches(opt.row,it));if(!fits)flags.push({index:i,reason:"mismatch"});views.set(i,{...base,entity:own.entity,entityType:own.entityType});return}if(!owner.entry.entity.infuse){flags.push({index:i,reason:"orphan"});return}const w=wrapInfused(e,owner.entry.entity,classLevel,registry);if(w.magicBase)flags.push({index:i,reason:"magic-base"});views.set(i,{...base,entity:w.entity,entityType:"item"})});const counters=new Map;for(const pool of pools){const words=poolActiveWords(pool);if(!words)continue;const rc=resolved.classes[pool.classIndex];const max=(_e=readTableColumn((_c=rc==null?void 0:rc.entity)==null?void 0:_c.table,(_d=rc==null?void 0:rc.level)!=null?_d:0,[words.column]))!=null?_e:0;const used=[...views.values()].filter(v=>v.poolId===pool.id&&v.entity!==null).length;counters.set(pool.id,{label:words.counterLabel,used,max,over:used>max})}return{views,counters,flags}}function entryCharges(entry,view,registry){return effectiveItemCharges(entry,registry,view)}function withEntryCharges(entry,view,current,registry){var _a,_b,_c,_d,_e,_f;const overlayMax=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(overlayMax!==void 0&&entry.infusion)return{...entry,infusion:{...entry.infusion,charges:{current:Math.max(0,Math.min(current,overlayMax))}}};const max=(_e=(_d=(_b=(_a=entry.state)==null?void 0:_a.charges)==null?void 0:_b.max)!=null?_d:(_c=effectiveItemCharges(entry,registry,view))==null?void 0:_c.max)!=null?_e:Math.max(0,current);return{...entry,state:{...(_f=entry.state)!=null?_f:{},charges:{current:Math.max(0,Math.min(current,max)),max}}}}function isMarkedEntry(entry){return!!entry.infusion}function splitOne(equipment,index){var _a,_b;const src=equipment[index];if(!src||((_a=src.qty)!=null?_a:1)<=1)return[...equipment];const one={item:src.item,qty:1,...src.in!==void 0?{in:src.in}:{},...src.overrides?{overrides:src.overrides}:{}};return[...equipment.slice(0,index),{...src,qty:((_b=src.qty)!=null?_b:1)-1},one,...equipment.slice(index+1)]}var refuse=reason=>({ok:false,reason});function endInfusion(equipment,index,registry){const entry=equipment[index];if(!(entry==null?void 0:entry.infusion))return{equipment:[...equipment],ended:[]};const{kind,by}=entry.infusion;if(kind==="infused"){const{infusion:_m,...rest}=entry;const keep=requiresAttunement(resolveEntryEntity(rest,index,registry).entity);const next=keep?rest:(({attuned:_a,...r})=>r)(rest);return{equipment:equipment.map((e,i)=>i===index?next:e),ended:[{index,key:by,kind,item:entry.item}]}}const moved=equipment.map((e,i)=>{if(i===index||entry.id===void 0||e.in!==entry.id)return e;if(entry.in===void 0){const{in:_in,...r}=e;return r}return{...e,in:entry.in}});return{equipment:moved.filter((_,i)=>i!==index),ended:[{index:-1,key:by,kind,item:entry.item}]}}var pickKeyOf=e=>normalizedPickKey(e.key,e.entity.repeatable===true);var nextSeq=equipment=>equipment.reduce((m,e)=>{var _a,_b;return Math.max(m,(_b=(_a=e.infusion)==null?void 0:_a.seq)!=null?_b:0)},0)+1;function ownedPick(resolved,key){var _a,_b;const k=markerKey(key);for(const pool of(_a=resolved.pools)!=null?_a:[]){const entry=pool.selected.find(e=>e.itemBound&&pickKeyOf(e)===k);if(entry)return{pool,entry,stranded:strandedPicks(pool).includes(entry)||((_b=entry.option)==null?void 0:_b.status)==="level"}}return null}var wordsOf=(...texts)=>texts.map(lc).join(" ").split(/[^a-z]+/).filter(w=>w!=="");function shapeOf(found,text,registry){var _a,_b,_c;if(!found)return{kind:"gear",words:wordsOf(text)};const data=(_a=found.data)!=null?_a:{};const words=wordsOf((_b=data.name)!=null?_b:text,data.type);const slotted=found.entityType==="armor"||found.entityType==="weapon"?found:typeof data.base_item==="string"?resolveBaseItem(data.base_item,registry):null;if((slotted==null?void 0:slotted.entityType)==="armor"){const armor=slotted.data;return{kind:isShieldArmor(armor)?"shield":"armor",words,category:lc(armor.category)}}if((slotted==null?void 0:slotted.entityType)==="weapon"){const w=slotted.data;return{kind:"weapon",words,category:lc(w.category),properties:((_c=w.properties)!=null?_c:[]).filter(p=>typeof p==="string").map(lc)}}return{kind:"gear",words}}function admits(t,s){var _a,_b,_c,_d;if(t.kind!==s.kind)return false;if(((_a=t.category)==null?void 0:_a.length)&&!t.category.map(lc).includes(((_b=s.category)!=null?_b:"").split("-")[0]))return false;if(t.property&&!((_c=s.properties)!=null?_c:[]).includes(lc(t.property)))return false;if(((_d=t.name_any)==null?void 0:_d.length)&&!t.name_any.some(n=>{const w=wordsOf(n);return w.length>0&&w.every(x=>s.words.includes(x))}))return false;return true}function targetVerdict(entry,infuse,registry){const found=resolveBaseItem(entry.item,registry);if(!infuse.targets.some(t=>admits(t,shapeOf(found,plainText(entry.item),registry))))return"target-kind";return found&&isMagic(found.data)?"magic-base":"ok"}function newObjectEntry(name,infuse,registry,visible){const want=lc(name);const found=[];for(const type of["armor","weapon","item"]){for(const e of registry.search(name,type,Number.POSITIVE_INFINITY)){if(lc(e.name)===want&&!isMagic(e.data)&&visible(e)&&infuse.targets.some(t=>admits(t,shapeOf(e,e.name,registry))))found.push(e)}}const first=found.sort(candidateOrder(void 0))[0];return first?{item:`[[${first.slug}]]`,qty:1}:{item:name,qty:1}}function endBySeqs(equipment,seqs,registry){let eq=[...equipment];let slots=eq.map((_,i)=>i);const rows=[];for(const{seq,by}of seqs){const i=eq.findIndex(e=>{var _a;return((_a=e.infusion)==null?void 0:_a.seq)===seq&&e.infusion.by===by});if(i===-1)continue;const w=endInfusion(eq,i,registry);for(const row of w.ended)rows.push({row,slot:slots[i]});if(eq[i].infusion.kind==="created")slots=slots.filter((_,j)=>j!==i);eq=w.equipment}return{equipment:eq,ended:rows.map(({row,slot})=>row.kind==="infused"?{...row,index:slots.indexOf(slot)}:row)}}function displaced(equipment,resolved,pool,key){var _a;const k=markerKey(key);const out=equipment.filter(e=>!!e.infusion&&markerKey(e.infusion.by)===k).map(e=>({seq:e.infusion.seq,by:e.infusion.by}));const counter=(_a=resolved.infusions)==null?void 0:_a.counters.get(pool.id);if(!counter)return out;const live=[...resolved.infusions.views.values()].filter(v=>v.poolId===pool.id&&v.classIndex===pool.classIndex&&v.entity!==null&&markerKey(v.key)!==k).sort((a,b)=>a.seq-b.seq);let used=live.length;for(const v of live){if(used+1<=counter.max)break;out.push({seq:v.seq,by:v.key});used--}return out}function infuseEntry(character,resolved,registry,req){var _a,_b,_c,_d,_e,_f,_g;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const infuse=owned.entry.entity.infuse;if(!infuse)return refuse("not-infusing");if(owned.stranded)return refuse("stranded");const wantsChoice=((_a=infuse.choice)==null?void 0:_a.kind)==="damage-type";const choice=lc(req.choice);if(wantsChoice&&choice==="")return refuse("choice-required");if(wantsChoice&&!isCanonicalDamageType(choice))return refuse("bad-choice");if(wantsChoice&&((_b=infuse.choice)==null?void 0:_b.options)&&!infuse.choice.options.some(o=>lc(o)===choice))return refuse("bad-choice");const equipment=(_c=character.equipment)!=null?_c:[];const charges=scaledInfuseItem(infuse,(_e=(_d=resolved.classes[owned.pool.classIndex])==null?void 0:_d.level)!=null?_e:0).charges;const marker={kind:"infused",by:owned.entry.key,seq:nextSeq(equipment),...wantsChoice?{choice}:{},...charges?{charges:{current:charges.max}}:{}};let placed;if(typeof req.target==="number"){const target=equipment[req.target];if(!target)return refuse("no-target");if(target.infusion)return refuse("marked");const verdict=targetVerdict(target,infuse,registry);if(verdict!=="ok")return refuse(verdict);const split=((_f=target.qty)!=null?_f:1)>1;placed=split?splitOne(equipment,req.target):[...equipment];const i=split?req.target+1:req.target;placed[i]={...placed[i],infusion:marker}}else{const name=req.target.newObject.trim();if(name==="")return refuse("no-target");placed=[...equipment,{...newObjectEntry(name,infuse,registry,(_g=req.isEntityVisible)!=null?_g:(()=>true)),infusion:marker}]}return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function createEntry(character,resolved,registry,req){var _a,_b;const owned=ownedPick(resolved,req.key);if(!owned)return refuse("not-owned");const note=owned.entry.entity;if(!(note.repeatable===true&&!!((_a=note.options)==null?void 0:_a.some(r=>!!r.creates))))return refuse("not-creating");if(owned.stranded)return refuse("stranded");const opt=owned.entry.option;if(!(opt==null?void 0:opt.row)||opt.status!=="ok")return refuse("invalid-item");const it=registry.getByTypeAndSlug("item",linkSlug(req.item.trim()));if(!it||!(opt.item===it.slug||rowMatches(opt.row,it)))return refuse("invalid-item");const equipment=(_b=character.equipment)!=null?_b:[];const placed=[...equipment,{item:`[[${it.slug}]]`,qty:1,infusion:{kind:"created",by:owned.entry.key,seq:nextSeq(equipment)}}];return{ok:true,...endBySeqs(placed,displaced(equipment,resolved,owned.pool,owned.entry.key),registry)}}function markersWhere(equipment,pick){const out=[];equipment.forEach((e,index)=>{const m=e.infusion;if(m&&pick(m))out.push({index,key:m.by,kind:m.kind,item:e.item,seq:m.seq,by:m.by})});return out}var asRows=list=>list.map(({index,key,kind,item})=>({index,key,kind,item}));var storedKeys=v=>typeof v==="string"?[v]:Array.isArray(v)?v:[];function choiceEnds(character,resolved,req){var _a,_b,_c,_d,_e,_f;const pool=((_a=resolved.pools)!=null?_a:[]).find(p=>p.classIndex===req.classIndex&&p.id===req.choiceKey);if(!pool||!(pool.active||pool.selected.some(e=>e.itemBound)))return[];const choices=(_c=(_b=character.class[req.classIndex])==null?void 0:_b.choices)!=null?_c:{};const kept=new Set(req.next.map(markerKey));for(const lvl of Object.keys(choices))if(Number(lvl)!==req.level)for(const s of storedKeys((_d=choices[Number(lvl)])==null?void 0:_d[req.choiceKey]))kept.add(markerKey(s));const removed=new Set(storedKeys((_e=choices[req.level])==null?void 0:_e[req.choiceKey]).map(markerKey).filter(k=>!kept.has(k)));return markersWhere((_f=character.equipment)!=null?_f:[],m=>removed.has(markerKey(m.by)))}function infusionsEndedByChoice(character,resolved,_registry,req){return asRows(choiceEnds(character,resolved,req))}function reconcileChoiceEdit(character,resolved,registry,req){var _a;const list=choiceEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function classEnds(character,resolved,req){var _a,_b,_c,_d,_e;let pools=((_a=resolved.pools)!=null?_a:[]).filter(p=>p.classIndex===req.classIndex);if(!("remove"in req)){const old=(_c=(_b=resolved.classes[req.classIndex])==null?void 0:_b.subclass)!=null?_c:null;if(!old||req.subclass!==null&&bareEntitySlug(linkSlug(req.subclass.trim()))===bareEntitySlug(old.slug))return[];const ids=new Set(((_d=old.selection_pools)!=null?_d:[]).map(p=>p.id));pools=pools.filter(p=>ids.has(p.id))}const owned=new Set;for(const pool of pools)for(const e of pool.selected)if(e.itemBound)owned.add(pickKeyOf(e));return markersWhere((_e=character.equipment)!=null?_e:[],m=>owned.has(markerKey(m.by)))}function infusionsEndedByClassEdit(character,resolved,_registry,req){return asRows(classEnds(character,resolved,req))}function reconcileClassEdit(character,resolved,registry,req){var _a;const list=classEnds(character,resolved,req);return list.length===0?null:endBySeqs((_a=character.equipment)!=null?_a:[],list,registry)}function eligibleTargets(character,resolved,registry,key){var _a,_b;const infuse=(_a=ownedPick(resolved,key))==null?void 0:_a.entry.entity.infuse;if(!infuse)return[];const out=[];((_b=character.equipment)!=null?_b:[]).forEach((e,index)=>{var _a2;if(!e.infusion&&targetVerdict(e,infuse,registry)==="ok")out.push({index,stack:((_a2=e.qty)!=null?_a2:1)>1})});return out}var WEAPON_DEFAULT_ACTION_COST="action";var linkOf=item=>{var _a,_b;return(_b=(_a=item.match(/^\[\[(.+)\]\]$/))==null?void 0:_a[1])!=null?_b:null};var ruleOf=(entry,registry,view)=>resolveEntryEntity(entry,view?view.index:-1,registry,view!=null?view:null);function isWeaponLikeEntry(entry,registry,view){if(!registry)return false;const r=ruleOf(entry,registry,view);return defaultSlotForType(r.entityType,r.entity,registry)==="mainhand"}function itemsRowBranch(entry,registry,view){var _a,_b;const link=linkOf(entry.item);if(!link||!registry)return false;const t=view?view.entityType:(_b=(_a=registry.getBySlug(link))==null?void 0:_a.entityType)!=null?_b:null;return t!=="weapon"&&t!=="armor"&&!isWeaponLikeEntry(entry,registry,view)}function customizableOverrideKeys(entry,registry){const consumed=isConsumedOnUse(entry,registry);const keys=new Set(consumed?["name"]:["name","charges","recovery"]);if(!registry)return keys;const r=ruleOf(entry,registry);const slot=defaultSlotForType(r.entityType,r.entity,registry);const weaponLike=slot==="mainhand";const itemsRow=itemsRowBranch(entry,registry);if(weaponLike){keys.add("bonus");keys.add("damage_bonus");keys.add("extra_damage")}if(slot==="armor"||slot==="shield")keys.add("ac_bonus");if(weaponLike||itemsRow)keys.add("action");if(itemsRow)keys.add("range");const link=linkOf(entry.item);if(r.entityType==="item"&&!consumed&&!(link&&isReadOnceItem(link)))keys.add("resist");return keys}function defaultActionCost(entry,registry,view){var _a,_b,_c,_d,_e;if(isWeaponLikeEntry(entry,registry,view))return WEAPON_DEFAULT_ACTION_COST;const link=linkOf(entry.item);if(!link||!registry||!itemsRowBranch(entry,registry,view))return null;const withoutOverrides={...entry,overrides:void 0};const type=view?(_a=view.entity)==null?void 0:_a.type:(_c=(_b=registry.getBySlug(link))==null?void 0:_b.data)==null?void 0:_c.type;return(_e=(_d=resolveItemAction(link,withoutOverrides,type,{view,spellCost:scrollSpellCost(entry,registry)}))==null?void 0:_d.cost)!=null?_e:null}var SPELL_COST={action:"action",bonus:"bonus-action",reaction:"reaction"};function scrollSpellCost(entry,registry){var _a,_b,_c,_d,_e;const ref=(_a=entry.overrides)==null?void 0:_a.spell;if(!ref||!registry)return void 0;const castingTime=(_d=(_c=registry.getByTypeAndSlug("spell",(_b=linkOf(ref))!=null?_b:ref))==null?void 0:_c.data)==null?void 0:_d.casting_time;const kind=typeof castingTime==="string"?(_e=parseCastingTime(castingTime))==null?void 0:_e.kind:void 0;return kind?SPELL_COST[kind]:void 0}var chargesOf=e=>e==null?void 0:e.charges;function itemChargesMax(entity){const c=chargesOf(entity);if(typeof c==="number")return c>0?c:void 0;const m=c==null?void 0:c.max;return typeof m==="number"&&m>0?m:void 0}var RESET_OF=r=>{const s=String(r!=null?r:"").toLowerCase();return s.includes("dawn")?"dawn":s.includes("short")?"short":s.includes("long")?"long":"special"};function rechargeAmount(c){var _a,_b;const raw=[c.recharge_amount,c.dice].find(v=>typeof v==="string"&&v.trim()!=="");if(!raw)return"1";const bare=raw.trim().replace(/^`+|`+$/g,"");return((_b=(_a=parseInlineTag(bare))==null?void 0:_a.content)!=null?_b:bare).replace(/\s+/g,"")}var recoveryOf=(c,needRecharge)=>!c||typeof c==="number"||needRecharge&&(typeof c.recharge!=="string"||c.recharge.trim()==="")?void 0:{amount:rechargeAmount(c),reset:RESET_OF(c.recharge)};function effectiveItemRecovery(entry,registry,view){var _a,_b;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;if((view==null?void 0:view.kind)==="infused"&&itemChargesMax(view.entity)!==void 0)return recoveryOf(chargesOf(view.entity),false);if((_a=entry.state)==null?void 0:_a.recovery)return entry.state.recovery;const own=registry?recoveryOf(chargesOf(ruleOf(entry,registry,view).entity),true):void 0;if(own)return own;const link=linkOf(entry.item);return link?(_b=findItemAction(link))==null?void 0:_b.recovery:void 0}function isConsumedOnUse(entry,registry,view){var _a;const link=linkOf(entry.item);if(!link)return false;if((_a=findItemAction(link))==null?void 0:_a.consumed)return true;const entity=entityOf(entry,registry,view);return(entity==null?void 0:entity.type)==="potion"||isScrollEntity(entity)}function isScrollEntity(entity){if(!entity||typeof entity!=="object")return false;return entity.type==="scroll"||isCastableScroll(entity)}function isCastableScroll(entity){return settableSpellLevel(entity)!==null&&!storesSpell(entity)}function settableSpellLevel(entity){if(!entity||typeof entity!=="object")return null;const level=entity.scroll_level;return typeof level==="number"?level:null}function storesSpell(entity){if(settableSpellLevel(entity)===null)return false;const e=entity;if(e.type==="scroll")return false;return itemChargesMax(entity)!==void 0||typeof e.spell_charge_cost==="number"}function storedSpellNumbers(entity){if(!storesSpell(entity))return null;const e=entity;const text=[e.description,...Array.isArray(e.entries)?e.entries:[]].filter(t=>typeof t==="string").join("\n");const fromText=re=>{const m=re.exec(text);return m?parseInt(m[1],10):void 0};const saveDC=typeof e.spell_save_dc==="number"?e.spell_save_dc:fromText(/\bsav(?:e|ing throw) DC (?:is|of) (\d+)/i);const attackBonus=typeof e.spell_attack_bonus==="number"?e.spell_attack_bonus:fromText(/\battack bonus (?:is|of) \+?(-?\d+)/i);if(saveDC===void 0&&attackBonus===void 0)return null;return{...saveDC!==void 0?{saveDC}:{},...attackBonus!==void 0?{attackBonus}:{}}}function itemSpellUse(entry,registry,view){const entity=entityOf(entry,registry,view);if(settableSpellLevel(entity)===null)return null;if(isConsumedOnUse(entry,registry,view))return{kind:"consume"};const declared=entity.spell_charge_cost;const cost=typeof declared==="number"&&Number.isInteger(declared)&&declared>=0?declared:1;const charges=effectiveItemCharges(entry,registry,view);if(cost===0||!charges)return{kind:"at-will"};return{kind:"charges",cost,charges:{current:charges.current,max:charges.max}}}function entityOf(entry,registry,view){if(!registry||!linkOf(entry.item))return null;return ruleOf(entry,registry,view).entity}function effectiveItemCharges(entry,registry,view){var _a,_b,_c,_d,_e,_f;if(isConsumedOnUse(entry,registry,view))return void 0;if(view&&view.entity===null)return void 0;const infused=(view==null?void 0:view.kind)==="infused"?itemChargesMax(view.entity):void 0;if(infused!==void 0)return{current:Math.max(0,Math.min((_c=(_b=(_a=entry.infusion)==null?void 0:_a.charges)==null?void 0:_b.current)!=null?_c:infused,infused)),max:infused};const stored=(_d=entry.state)==null?void 0:_d.charges;if(stored)return stored;const own=registry?itemChargesMax(ruleOf(entry,registry,view).entity):void 0;if(own!==void 0)return{current:own,max:own};const link=linkOf(entry.item);const max=link?(_f=(_e=findItemAction(link))==null?void 0:_e.max_charges)!=null?_f:0:0;return max>0?{current:max,max}:void 0}function effectiveItemArmorClass(entry,registry,view){var _a;if(!registry)return null;const{entity}=ruleOf(entry,registry,view);const armor=effectiveArmor(entity,registry);if(!armor)return null;const shield=isShieldArmor(armor);const bonus=isItemEntity(entity)&&typeof((_a=entity.bonuses)==null?void 0:_a.ac)==="number"?entity.bonuses.ac:0;const terms=slotAcTerms(armor,entry);return{value:terms.armor+terms.override+bonus,shield,addDex:!shield&&armor.ac.add_dex===true}}export{WEAPON_DEFAULT_ACTION_COST,isWeaponLikeEntry,customizableOverrideKeys,defaultActionCost,scrollSpellCost,itemChargesMax,effectiveItemRecovery,isConsumedOnUse,isScrollEntity,isCastableScroll,settableSpellLevel,storesSpell,storedSpellNumbers,itemSpellUse,effectiveItemCharges,effectiveItemArmorClass,poolCountLabel,poolActiveWords,parsePickKey,normalizedPickKey,markerKey,isItemBound,optionCandidates,resolveOptionRows,resolveCopyOption,scaledInfuseItem,resolveEntryEntity,buildInfusionContext,entryCharges,withEntryCharges,isMarkedEntry,splitOne,endInfusion,infuseEntry,createEntry,infusionsEndedByChoice,reconcileChoiceEdit,infusionsEndedByClassEdit,reconcileClassEdit,eligibleTargets,bindFeatureConsumers,levelPrereqMax,levelPrereqRefsMet,poolAnchorLevel,resolvePool,resolveAllPools,strandedPicks,heldPicks,withoutStrandedSites};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var SPELL_SOURCE={class:{ownAbility:false,section:"spellbook",freeCastWhenNoSlot:false,showInPrepare:true,countsAsGranted:false},feat:{ownAbility:true,section:"spellbook",freeCastWhenNoSlot:true,showInPrepare:true,countsAsGranted:true},item:{ownAbility:false,section:"consumable",freeCastWhenNoSlot:false,showInPrepare:false,countsAsGranted:true},race:{ownAbility:true,section:"spellbook",freeCastWhenNoSlot:true,showInPrepare:true,countsAsGranted:true},domain:{ownAbility:false,section:"spellbook",freeCastWhenNoSlot:false,showInPrepare:true,countsAsGranted:false}};var spellSource=s=>SPELL_SOURCE[s.source];export{SPELL_SOURCE,spellSource};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{slugify}from"./chunk-63YJPWTM.js";var retired_items_2014_default=[{retired_slug:"srd-5e_item_adamantine-breastplate",retired_name:"Adamantine Breastplate",retired_path:"SRD 5e/Magic Items/Adamantine Breastplate.md",kept_slug:"srd-5e_item_adamantine-armor-breastplate",kept_name:"Adamantine Armor (Breastplate)"},{retired_slug:"srd-5e_item_adamantine-chain-mail",retired_name:"Adamantine Chain Mail",retired_path:"SRD 5e/Magic Items/Adamantine Chain Mail.md",kept_slug:"srd-5e_item_adamantine-armor-chain-mail",kept_name:"Adamantine Armor (Chain-Mail)"},{retired_slug:"srd-5e_item_adamantine-chain-shirt",retired_name:"Adamantine Chain Shirt",retired_path:"SRD 5e/Magic Items/Adamantine Chain Shirt.md",kept_slug:"srd-5e_item_adamantine-armor-chain-shirt",kept_name:"Adamantine Armor (Chain-Shirt)"},{retired_slug:"srd-5e_item_adamantine-half-plate-armor",retired_name:"Adamantine Half Plate Armor",retired_path:"SRD 5e/Magic Items/Adamantine Half Plate Armor.md",kept_slug:"srd-5e_item_adamantine-armor-half-plate",kept_name:"Adamantine Armor (Half-Plate)"},{retired_slug:"srd-5e_item_adamantine-plate-armor",retired_name:"Adamantine Plate Armor",retired_path:"SRD 5e/Magic Items/Adamantine Plate Armor.md",kept_slug:"srd-5e_item_adamantine-armor-plate",kept_name:"Adamantine Armor (Plate)"},{retired_slug:"srd-5e_item_adamantine-ring-mail",retired_name:"Adamantine Ring Mail",retired_path:"SRD 5e/Magic Items/Adamantine Ring Mail.md",kept_slug:"srd-5e_item_adamantine-armor-ring-mail",kept_name:"Adamantine Armor (Ring-Mail)"},{retired_slug:"srd-5e_item_adamantine-scale-mail",retired_name:"Adamantine Scale Mail",retired_path:"SRD 5e/Magic Items/Adamantine Scale Mail.md",kept_slug:"srd-5e_item_adamantine-armor-scale-mail",kept_name:"Adamantine Armor (Scale-Mail)"},{retired_slug:"srd-5e_item_adamantine-splint-armor",retired_name:"Adamantine Splint Armor",retired_path:"SRD 5e/Magic Items/Adamantine Splint Armor.md",kept_slug:"srd-5e_item_adamantine-armor-splint",kept_name:"Adamantine Armor (Splint)"},{retired_slug:"srd-5e_item_greatsword-sword-of-life-stealing",retired_name:"Greatsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-greatsword",kept_name:"Sword of Life Stealing (Greatsword)"},{retired_slug:"srd-5e_item_greatsword-sword-of-sharpness",retired_name:"Greatsword, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-greatsword",kept_name:"Sword of Sharpness (Greatsword)"},{retired_slug:"srd-5e_item_greatsword-sword-of-wounding",retired_name:"Greatsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-greatsword",kept_name:"Sword of Wounding (Greatsword)"},{retired_slug:"srd-5e_item_hand-crossbow-1",retired_name:"Hand Crossbow +1",retired_path:"SRD 5e/Magic Items/Hand Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-hand-1",kept_name:"Crossbow-Hand (+1)"},{retired_slug:"srd-5e_item_hand-crossbow-2",retired_name:"Hand Crossbow +2",retired_path:"SRD 5e/Magic Items/Hand Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-hand-2",kept_name:"Crossbow-Hand (+2)"},{retired_slug:"srd-5e_item_hand-crossbow-3",retired_name:"Hand Crossbow +3",retired_path:"SRD 5e/Magic Items/Hand Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-hand-3",kept_name:"Crossbow-Hand (+3)"},{retired_slug:"srd-5e_item_heavy-crossbow-1",retired_name:"Heavy Crossbow +1",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-heavy-1",kept_name:"Crossbow-Heavy (+1)"},{retired_slug:"srd-5e_item_heavy-crossbow-2",retired_name:"Heavy Crossbow +2",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-heavy-2",kept_name:"Crossbow-Heavy (+2)"},{retired_slug:"srd-5e_item_heavy-crossbow-3",retired_name:"Heavy Crossbow +3",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-heavy-3",kept_name:"Crossbow-Heavy (+3)"},{retired_slug:"srd-5e_item_light-crossbow-1",retired_name:"Light Crossbow +1",retired_path:"SRD 5e/Magic Items/Light Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-light-1",kept_name:"Crossbow-Light (+1)"},{retired_slug:"srd-5e_item_light-crossbow-2",retired_name:"Light Crossbow +2",retired_path:"SRD 5e/Magic Items/Light Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-light-2",kept_name:"Crossbow-Light (+2)"},{retired_slug:"srd-5e_item_light-crossbow-3",retired_name:"Light Crossbow +3",retired_path:"SRD 5e/Magic Items/Light Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-light-3",kept_name:"Crossbow-Light (+3)"},{retired_slug:"srd-5e_item_longsword-sword-of-life-stealing",retired_name:"Longsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-longsword",kept_name:"Sword of Life Stealing (Longsword)"},{retired_slug:"srd-5e_item_longsword-sword-of-sharpness",retired_name:"Longsword, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-longsword",kept_name:"Sword of Sharpness (Longsword)"},{retired_slug:"srd-5e_item_longsword-sword-of-wounding",retired_name:"Longsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-longsword",kept_name:"Sword of Wounding (Longsword)"},{retired_slug:"srd-5e_item_mithral-breastplate",retired_name:"Mithral Breastplate",retired_path:"SRD 5e/Magic Items/Mithral Breastplate.md",kept_slug:"srd-5e_item_mithral-armor-breastplate",kept_name:"Mithral Armor (Breastplate)"},{retired_slug:"srd-5e_item_mithral-chain-mail",retired_name:"Mithral Chain Mail",retired_path:"SRD 5e/Magic Items/Mithral Chain Mail.md",kept_slug:"srd-5e_item_mithral-armor-chain-mail",kept_name:"Mithral Armor (Chain-Mail)"},{retired_slug:"srd-5e_item_mithral-chain-shirt",retired_name:"Mithral Chain Shirt",retired_path:"SRD 5e/Magic Items/Mithral Chain Shirt.md",kept_slug:"srd-5e_item_mithral-armor-chain-shirt",kept_name:"Mithral Armor (Chain-Shirt)"},{retired_slug:"srd-5e_item_mithral-half-plate-armor",retired_name:"Mithral Half Plate Armor",retired_path:"SRD 5e/Magic Items/Mithral Half Plate Armor.md",kept_slug:"srd-5e_item_mithral-armor-half-plate",kept_name:"Mithral Armor (Half-Plate)"},{retired_slug:"srd-5e_item_mithral-plate-armor",retired_name:"Mithral Plate Armor",retired_path:"SRD 5e/Magic Items/Mithral Plate Armor.md",kept_slug:"srd-5e_item_mithral-armor-plate",kept_name:"Mithral Armor (Plate)"},{retired_slug:"srd-5e_item_mithral-ring-mail",retired_name:"Mithral Ring Mail",retired_path:"SRD 5e/Magic Items/Mithral Ring Mail.md",kept_slug:"srd-5e_item_mithral-armor-ring-mail",kept_name:"Mithral Armor (Ring-Mail)"},{retired_slug:"srd-5e_item_mithral-scale-mail",retired_name:"Mithral Scale Mail",retired_path:"SRD 5e/Magic Items/Mithral Scale Mail.md",kept_slug:"srd-5e_item_mithral-armor-scale-mail",kept_name:"Mithral Armor (Scale-Mail)"},{retired_slug:"srd-5e_item_mithral-splint-armor",retired_name:"Mithral Splint Armor",retired_path:"SRD 5e/Magic Items/Mithral Splint Armor.md",kept_slug:"srd-5e_item_mithral-armor-splint",kept_name:"Mithral Armor (Splint)"},{retired_slug:"srd-5e_item_rapier-sword-of-life-stealing",retired_name:"Rapier, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Rapier, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-rapier",kept_name:"Sword of Life Stealing (Rapier)"},{retired_slug:"srd-5e_item_rapier-sword-of-wounding",retired_name:"Rapier, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Rapier, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-rapier",kept_name:"Sword of Wounding (Rapier)"},{retired_slug:"srd-5e_item_scimitar-sword-of-sharpness",retired_name:"Scimitar, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Scimitar, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-scimitar",kept_name:"Sword of Sharpness (Scimitar)"},{retired_slug:"srd-5e_item_shortsword-sword-of-life-stealing",retired_name:"Shortsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Shortsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-shortsword",kept_name:"Sword of Life Stealing (Shortsword)"},{retired_slug:"srd-5e_item_shortsword-sword-of-wounding",retired_name:"Shortsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Shortsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-shortsword",kept_name:"Sword of Wounding (Shortsword)"},{retired_slug:"srd-5e_item_vicious-battleaxe",retired_name:"Vicious Battleaxe",retired_path:"SRD 5e/Magic Items/Vicious Battleaxe.md",kept_slug:"srd-5e_item_vicious-weapon-battleaxe",kept_name:"Vicious Weapon (Battleaxe)"},{retired_slug:"srd-5e_item_vicious-blowgun",retired_name:"Vicious Blowgun",retired_path:"SRD 5e/Magic Items/Vicious Blowgun.md",kept_slug:"srd-5e_item_vicious-weapon-blowgun",kept_name:"Vicious Weapon (Blowgun)"},{retired_slug:"srd-5e_item_vicious-club",retired_name:"Vicious Club",retired_path:"SRD 5e/Magic Items/Vicious Club.md",kept_slug:"srd-5e_item_vicious-weapon-club",kept_name:"Vicious Weapon (Club)"},{retired_slug:"srd-5e_item_vicious-dagger",retired_name:"Vicious Dagger",retired_path:"SRD 5e/Magic Items/Vicious Dagger.md",kept_slug:"srd-5e_item_vicious-weapon-dagger",kept_name:"Vicious Weapon (Dagger)"},{retired_slug:"srd-5e_item_vicious-dart",retired_name:"Vicious Dart",retired_path:"SRD 5e/Magic Items/Vicious Dart.md",kept_slug:"srd-5e_item_vicious-weapon-dart",kept_name:"Vicious Weapon (Dart)"},{retired_slug:"srd-5e_item_vicious-flail",retired_name:"Vicious Flail",retired_path:"SRD 5e/Magic Items/Vicious Flail.md",kept_slug:"srd-5e_item_vicious-weapon-flail",kept_name:"Vicious Weapon (Flail)"},{retired_slug:"srd-5e_item_vicious-glaive",retired_name:"Vicious Glaive",retired_path:"SRD 5e/Magic Items/Vicious Glaive.md",kept_slug:"srd-5e_item_vicious-weapon-glaive",kept_name:"Vicious Weapon (Glaive)"},{retired_slug:"srd-5e_item_vicious-greataxe",retired_name:"Vicious Greataxe",retired_path:"SRD 5e/Magic Items/Vicious Greataxe.md",kept_slug:"srd-5e_item_vicious-weapon-greataxe",kept_name:"Vicious Weapon (Greataxe)"},{retired_slug:"srd-5e_item_vicious-greatclub",retired_name:"Vicious Greatclub",retired_path:"SRD 5e/Magic Items/Vicious Greatclub.md",kept_slug:"srd-5e_item_vicious-weapon-greatclub",kept_name:"Vicious Weapon (Greatclub)"},{retired_slug:"srd-5e_item_vicious-greatsword",retired_name:"Vicious Greatsword",retired_path:"SRD 5e/Magic Items/Vicious Greatsword.md",kept_slug:"srd-5e_item_vicious-weapon-greatsword",kept_name:"Vicious Weapon (Greatsword)"},{retired_slug:"srd-5e_item_vicious-halberd",retired_name:"Vicious Halberd",retired_path:"SRD 5e/Magic Items/Vicious Halberd.md",kept_slug:"srd-5e_item_vicious-weapon-halberd",kept_name:"Vicious Weapon (Halberd)"},{retired_slug:"srd-5e_item_vicious-hand-crossbow",retired_name:"Vicious Hand Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Hand Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-hand",kept_name:"Vicious Weapon (Crossbow-Hand)"},{retired_slug:"srd-5e_item_vicious-handaxe",retired_name:"Vicious Handaxe",retired_path:"SRD 5e/Magic Items/Vicious Handaxe.md",kept_slug:"srd-5e_item_vicious-weapon-handaxe",kept_name:"Vicious Weapon (Handaxe)"},{retired_slug:"srd-5e_item_vicious-heavy-crossbow",retired_name:"Vicious Heavy Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Heavy Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-heavy",kept_name:"Vicious Weapon (Crossbow-Heavy)"},{retired_slug:"srd-5e_item_vicious-javelin",retired_name:"Vicious Javelin",retired_path:"SRD 5e/Magic Items/Vicious Javelin.md",kept_slug:"srd-5e_item_vicious-weapon-javelin",kept_name:"Vicious Weapon (Javelin)"},{retired_slug:"srd-5e_item_vicious-lance",retired_name:"Vicious Lance",retired_path:"SRD 5e/Magic Items/Vicious Lance.md",kept_slug:"srd-5e_item_vicious-weapon-lance",kept_name:"Vicious Weapon (Lance)"},{retired_slug:"srd-5e_item_vicious-light-crossbow",retired_name:"Vicious Light Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Light Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-light",kept_name:"Vicious Weapon (Crossbow-Light)"},{retired_slug:"srd-5e_item_vicious-light-hammer",retired_name:"Vicious Light Hammer",retired_path:"SRD 5e/Magic Items/Vicious Light Hammer.md",kept_slug:"srd-5e_item_vicious-weapon-light-hammer",kept_name:"Vicious Weapon (Light-Hammer)"},{retired_slug:"srd-5e_item_vicious-longbow",retired_name:"Vicious Longbow",retired_path:"SRD 5e/Magic Items/Vicious Longbow.md",kept_slug:"srd-5e_item_vicious-weapon-longbow",kept_name:"Vicious Weapon (Longbow)"},{retired_slug:"srd-5e_item_vicious-longsword",retired_name:"Vicious Longsword",retired_path:"SRD 5e/Magic Items/Vicious Longsword.md",kept_slug:"srd-5e_item_vicious-weapon-longsword",kept_name:"Vicious Weapon (Longsword)"},{retired_slug:"srd-5e_item_vicious-mace",retired_name:"Vicious Mace",retired_path:"SRD 5e/Magic Items/Vicious Mace.md",kept_slug:"srd-5e_item_vicious-weapon-mace",kept_name:"Vicious Weapon (Mace)"},{retired_slug:"srd-5e_item_vicious-maul",retired_name:"Vicious Maul",retired_path:"SRD 5e/Magic Items/Vicious Maul.md",kept_slug:"srd-5e_item_vicious-weapon-maul",kept_name:"Vicious Weapon (Maul)"},{retired_slug:"srd-5e_item_vicious-morningstar",retired_name:"Vicious Morningstar",retired_path:"SRD 5e/Magic Items/Vicious Morningstar.md",kept_slug:"srd-5e_item_vicious-weapon-morningstar",kept_name:"Vicious Weapon (Morningstar)"},{retired_slug:"srd-5e_item_vicious-net",retired_name:"Vicious Net",retired_path:"SRD 5e/Magic Items/Vicious Net.md",kept_slug:"srd-5e_item_vicious-weapon-net",kept_name:"Vicious Weapon (Net)"},{retired_slug:"srd-5e_item_vicious-pike",retired_name:"Vicious Pike",retired_path:"SRD 5e/Magic Items/Vicious Pike.md",kept_slug:"srd-5e_item_vicious-weapon-pike",kept_name:"Vicious Weapon (Pike)"},{retired_slug:"srd-5e_item_vicious-quarterstaff",retired_name:"Vicious Quarterstaff",retired_path:"SRD 5e/Magic Items/Vicious Quarterstaff.md",kept_slug:"srd-5e_item_vicious-weapon-quarterstaff",kept_name:"Vicious Weapon (Quarterstaff)"},{retired_slug:"srd-5e_item_vicious-rapier",retired_name:"Vicious Rapier",retired_path:"SRD 5e/Magic Items/Vicious Rapier.md",kept_slug:"srd-5e_item_vicious-weapon-rapier",kept_name:"Vicious Weapon (Rapier)"},{retired_slug:"srd-5e_item_vicious-scimitar",retired_name:"Vicious Scimitar",retired_path:"SRD 5e/Magic Items/Vicious Scimitar.md",kept_slug:"srd-5e_item_vicious-weapon-scimitar",kept_name:"Vicious Weapon (Scimitar)"},{retired_slug:"srd-5e_item_vicious-shortbow",retired_name:"Vicious Shortbow",retired_path:"SRD 5e/Magic Items/Vicious Shortbow.md",kept_slug:"srd-5e_item_vicious-weapon-shortbow",kept_name:"Vicious Weapon (Shortbow)"},{retired_slug:"srd-5e_item_vicious-shortsword",retired_name:"Vicious Shortsword",retired_path:"SRD 5e/Magic Items/Vicious Shortsword.md",kept_slug:"srd-5e_item_vicious-weapon-shortsword",kept_name:"Vicious Weapon (Shortsword)"},{retired_slug:"srd-5e_item_vicious-sickle",retired_name:"Vicious Sickle",retired_path:"SRD 5e/Magic Items/Vicious Sickle.md",kept_slug:"srd-5e_item_vicious-weapon-sickle",kept_name:"Vicious Weapon (Sickle)"},{retired_slug:"srd-5e_item_vicious-sling",retired_name:"Vicious Sling",retired_path:"SRD 5e/Magic Items/Vicious Sling.md",kept_slug:"srd-5e_item_vicious-weapon-sling",kept_name:"Vicious Weapon (Sling)"},{retired_slug:"srd-5e_item_vicious-spear",retired_name:"Vicious Spear",retired_path:"SRD 5e/Magic Items/Vicious Spear.md",kept_slug:"srd-5e_item_vicious-weapon-spear",kept_name:"Vicious Weapon (Spear)"},{retired_slug:"srd-5e_item_vicious-trident",retired_name:"Vicious Trident",retired_path:"SRD 5e/Magic Items/Vicious Trident.md",kept_slug:"srd-5e_item_vicious-weapon-trident",kept_name:"Vicious Weapon (Trident)"},{retired_slug:"srd-5e_item_vicious-war-pick",retired_name:"Vicious War Pick",retired_path:"SRD 5e/Magic Items/Vicious War Pick.md",kept_slug:"srd-5e_item_vicious-weapon-war-pick",kept_name:"Vicious Weapon (War-Pick)"},{retired_slug:"srd-5e_item_vicious-warhammer",retired_name:"Vicious Warhammer",retired_path:"SRD 5e/Magic Items/Vicious Warhammer.md",kept_slug:"srd-5e_item_vicious-weapon-warhammer",kept_name:"Vicious Weapon (Warhammer)"},{retired_slug:"srd-5e_item_vicious-whip",retired_name:"Vicious Whip",retired_path:"SRD 5e/Magic Items/Vicious Whip.md",kept_slug:"srd-5e_item_vicious-weapon-whip",kept_name:"Vicious Weapon (Whip)"}];var retired_items_2024_default=[{retired_slug:"srd-2024_item_adamantine-breastplate",retired_name:"Adamantine Breastplate",retired_path:"SRD 2024/Magic Items/Adamantine Breastplate.md",kept_slug:"srd-2024_item_adamantine-armor-breastplate",kept_name:"Adamantine Armor (Breastplate)"},{retired_slug:"srd-2024_item_adamantine-chain-mail",retired_name:"Adamantine Chain Mail",retired_path:"SRD 2024/Magic Items/Adamantine Chain Mail.md",kept_slug:"srd-2024_item_adamantine-armor-chain-mail",kept_name:"Adamantine Armor (Chain Mail)"},{retired_slug:"srd-2024_item_adamantine-chain-shirt",retired_name:"Adamantine Chain Shirt",retired_path:"SRD 2024/Magic Items/Adamantine Chain Shirt.md",kept_slug:"srd-2024_item_adamantine-armor-chain-shirt",kept_name:"Adamantine Armor (Chain Shirt)"},{retired_slug:"srd-2024_item_adamantine-half-plate-armor",retired_name:"Adamantine Half Plate Armor",retired_path:"SRD 2024/Magic Items/Adamantine Half Plate Armor.md",kept_slug:"srd-2024_item_adamantine-armor-half-plate",kept_name:"Adamantine Armor (Half Plate)"},{retired_slug:"srd-2024_item_adamantine-plate-armor",retired_name:"Adamantine Plate Armor",retired_path:"SRD 2024/Magic Items/Adamantine Plate Armor.md",kept_slug:"srd-2024_item_adamantine-armor-plate",kept_name:"Adamantine Armor (Plate)"},{retired_slug:"srd-2024_item_adamantine-ring-mail",retired_name:"Adamantine Ring Mail",retired_path:"SRD 2024/Magic Items/Adamantine Ring Mail.md",kept_slug:"srd-2024_item_adamantine-armor-ring-mail",kept_name:"Adamantine Armor (Ring Mail)"},{retired_slug:"srd-2024_item_adamantine-scale-mail",retired_name:"Adamantine Scale Mail",retired_path:"SRD 2024/Magic Items/Adamantine Scale Mail.md",kept_slug:"srd-2024_item_adamantine-armor-scale-mail",kept_name:"Adamantine Armor (Scale Mail)"},{retired_slug:"srd-2024_item_adamantine-splint-armor",retired_name:"Adamantine Splint Armor",retired_path:"SRD 2024/Magic Items/Adamantine Splint Armor.md",kept_slug:"srd-2024_item_adamantine-armor-splint",kept_name:"Adamantine Armor (Splint)"},{retired_slug:"srd-2024_item_dwarven-half-plate-armor",retired_name:"Dwarven Half Plate Armor",retired_path:"SRD 2024/Magic Items/Dwarven Half Plate Armor.md",kept_slug:"srd-2024_item_dwarven-half-plate",kept_name:"Dwarven Half Plate"},{retired_slug:"srd-2024_item_dwarven-plate-armor",retired_name:"Dwarven Plate Armor",retired_path:"SRD 2024/Magic Items/Dwarven Plate Armor.md",kept_slug:"srd-2024_item_dwarven-plate",kept_name:"Dwarven Plate"},{retired_slug:"srd-2024_item_half-plate-armor-plate-armor-of-etherealness",retired_name:"Half Plate Armor, Plate Armor of Etherealness (*)",retired_path:"SRD 2024/Magic Items/Half Plate Armor, Plate Armor of Etherealness (_).md",kept_slug:"srd-2024_item_half-plate-armor-of-etherealness",kept_name:"Half Plate Armor of Etherealness"},{retired_slug:"srd-2024_item_mithral-breastplate",retired_name:"Mithral Breastplate",retired_path:"SRD 2024/Magic Items/Mithral Breastplate.md",kept_slug:"srd-2024_item_mithral-armor-breastplate",kept_name:"Mithral Armor (Breastplate)"},{retired_slug:"srd-2024_item_mithral-chain-mail",retired_name:"Mithral Chain Mail",retired_path:"SRD 2024/Magic Items/Mithral Chain Mail.md",kept_slug:"srd-2024_item_mithral-armor-chain-mail",kept_name:"Mithral Armor (Chain Mail)"},{retired_slug:"srd-2024_item_mithral-chain-shirt",retired_name:"Mithral Chain Shirt",retired_path:"SRD 2024/Magic Items/Mithral Chain Shirt.md",kept_slug:"srd-2024_item_mithral-armor-chain-shirt",kept_name:"Mithral Armor (Chain Shirt)"},{retired_slug:"srd-2024_item_mithral-half-plate-armor",retired_name:"Mithral Half Plate Armor",retired_path:"SRD 2024/Magic Items/Mithral Half Plate Armor.md",kept_slug:"srd-2024_item_mithral-armor-half-plate",kept_name:"Mithral Armor (Half Plate)"},{retired_slug:"srd-2024_item_mithral-plate-armor",retired_name:"Mithral Plate Armor",retired_path:"SRD 2024/Magic Items/Mithral Plate Armor.md",kept_slug:"srd-2024_item_mithral-armor-plate",kept_name:"Mithral Armor (Plate)"},{retired_slug:"srd-2024_item_mithral-ring-mail",retired_name:"Mithral Ring Mail",retired_path:"SRD 2024/Magic Items/Mithral Ring Mail.md",kept_slug:"srd-2024_item_mithral-armor-ring-mail",kept_name:"Mithral Armor (Ring Mail)"},{retired_slug:"srd-2024_item_mithral-scale-mail",retired_name:"Mithral Scale Mail",retired_path:"SRD 2024/Magic Items/Mithral Scale Mail.md",kept_slug:"srd-2024_item_mithral-armor-scale-mail",kept_name:"Mithral Armor (Scale Mail)"},{retired_slug:"srd-2024_item_mithral-splint-armor",retired_name:"Mithral Splint Armor",retired_path:"SRD 2024/Magic Items/Mithral Splint Armor.md",kept_slug:"srd-2024_item_mithral-armor-splint",kept_name:"Mithral Armor (Splint)"},{retired_slug:"srd-2024_item_plate-armor-plate-armor-of-etherealness",retired_name:"Plate Armor, Plate Armor of Etherealness (*)",retired_path:"SRD 2024/Magic Items/Plate Armor, Plate Armor of Etherealness (_).md",kept_slug:"srd-2024_item_plate-armor-of-etherealness",kept_name:"Plate Armor of Etherealness"}];function unwrapWikilink(input){const m=/^\[\[([^\]]+)\]\]$/.exec(input.trim());if(!m)return null;const inner=m[1];const pipe=inner.indexOf("|");return pipe===-1?inner:inner.slice(0,pipe)}var FOLDER_TO_TYPE={Weapons:"weapon",Armor:"armor","Magic Items":"item"};function vaultPathToSlug(target){const segments=target.split("/").map(s=>s.trim()).filter(s=>s.length>0);if(segments.length===0)return"";if(segments.length===1){return slugify(segments[0])}const compendiumName=segments[0];const typeFolder=segments[segments.length-2];const basename=segments[segments.length-1];const prefix=slugify(compendiumName);const nameSlug=slugify(basename);if(!prefix||!nameSlug)return nameSlug;const type=FOLDER_TO_TYPE[typeFolder];return type?`${prefix}_${type}_${nameSlug}`:`${prefix}_${nameSlug}`}function resolveBaseItem(baseItem,registry){var _a,_b;if(typeof baseItem!=="string"||baseItem.length===0)return null;const target=(_a=unwrapWikilink(baseItem))!=null?_a:baseItem.trim();if(target.length===0)return null;if(!target.includes("/")){const direct=registry.getBySlug(target);if(direct)return direct}const slug=vaultPathToSlug(target);if(!slug)return null;const found=registry.getBySlug(slug);if(found)return found;const kept=keptSlugForLink(target);return kept===void 0?null:(_b=registry.getBySlug(kept))!=null?_b:null}function resolveBaseItemOfType(baseItem,entityType,registry){const found=resolveBaseItem(baseItem,registry);return found&&found.entityType===entityType?found:null}var RETIRED_ITEMS=Object.freeze([...retired_items_2014_default,...retired_items_2024_default]);var KEPT_BY_RETIRED=new Map(RETIRED_ITEMS.map(r=>[r.retired_slug,r.kept_slug]));function keptSlugFor(slug){return KEPT_BY_RETIRED.get(slug)}function keptSlugForLink(target){const t=target.trim();if(t.length===0)return void 0;return keptSlugFor(t.includes("/")?vaultPathToSlug(t):t)}export{RETIRED_ITEMS,keptSlugFor,keptSlugForLink,vaultPathToSlug,resolveBaseItem,resolveBaseItemOfType};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function registryRevision(registry){const r=registry==null?void 0:registry.revision;return typeof r==="number"?r:void 0}function memoByRevision(cache,registry,compute){const revision=registryRevision(registry);if(revision===void 0)return compute();const hit=cache.get(registry);if(hit&&hit.revision===revision)return hit.value;const value=compute();cache.set(registry,{revision,value});return value}var BUCKETS=new WeakMap;function bucketOf(registry,type){const byType=memoByRevision(BUCKETS,registry,()=>new Map);let bucket=byType.get(type);if(!bucket){bucket=registry.search("",type,Number.POSITIVE_INFINITY);byType.set(type,bucket)}return bucket}export{registryRevision,memoByRevision,bucketOf};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{bareEntitySlug}from"./chunk-63YJPWTM.js";import{ABILITY_KEYS}from"./chunk-EVT7MGAC.js";function flattenAsiOrFeat(choice){var _a;if(choice.kind!=="select-inline"||choice.id!=="asi-or-feat")return choice;const featBranches=choice.options.filter(o=>{var _a2;return((_a2=o.choices)!=null?_a2:[]).some(c=>c.kind==="select-entity"&&c.entity_type==="feat")});if(featBranches.length!==1)return choice;const inner=(_a=featBranches[0].choices)!=null?_a:[];if(inner.length!==1)return choice;const only=inner[0];if(only.kind!=="select-entity"||only.entity_type!=="feat")return choice;return only}var ASI_FEAT_BARE="ability-score-improvement";function legacyAsiBranch(block){if(!block||typeof block!=="object")return null;const b=block;if(typeof b.feat==="string")return null;const asi=b.asi;if(!asi||typeof asi!=="object"||Array.isArray(asi))return null;const out={};let any=false;for(const ab of ABILITY_KEYS){const v=asi[ab];if(typeof v==="number"){out[ab]=v;any=true}}return any?out:null}function convertibleLegacyAsi(block){const alloc=legacyAsiBranch(block);if(!alloc)return null;const branch=block["asi-or-feat"];return branch===void 0||branch==="asi"?alloc:null}function resolveLegacyAsiFeat(registry,classEntity){if(!classEntity)return null;const prefix=classEntity.slug.split("_")[0];const ranked=[];for(const e of registry.search("","feat",Number.POSITIVE_INFINITY)){if(bareEntitySlug(e.slug)!==ASI_FEAT_BARE)continue;const data=e.data;const choices=Array.isArray(data==null?void 0:data.choices)?data.choices:[];const points=choices.find(c=>(c==null?void 0:c.kind)==="ability-points"&&typeof c.id==="string");if(!points)continue;ranked.push({slug:e.slug,childId:points.id,prefixHit:e.slug.split("_")[0]===prefix,editionHit:classEntity.edition!==void 0&&(data==null?void 0:data.edition)===classEntity.edition})}ranked.sort((a,b)=>Number(b.prefixHit)-Number(a.prefixHit)||Number(b.editionHit)-Number(a.editionHit)||(a.slug<b.slug?-1:a.slug>b.slug?1:0));return ranked.length?{slug:ranked[0].slug,childId:ranked[0].childId}:null}function migrateLegacyAsiLevel(block,key,value,registry,classEntity){if(key!=="feat"&&!key.startsWith("feat:"))return null;const alloc=convertibleLegacyAsi(block);if(!alloc)return null;const asi=resolveLegacyAsiFeat(registry,classEntity);if(!asi)return null;const childKey=`feat:${asi.childId}`;const isSwitch=key==="feat"&&value!==asi.slug;const out={};for(const[k,v]of Object.entries(block)){if(k==="asi-or-feat"||k==="asi"||k===childKey)continue;out[k]=v}out.feat=asi.slug;if(!isSwitch)out[childKey]=alloc;return out}export{flattenAsiOrFeat,legacyAsiBranch,convertibleLegacyAsi,resolveLegacyAsiFeat,migrateLegacyAsiLevel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var acSchema=z.object({base:z.number().int(),flat:z.number().int().default(0),add_dex:z.boolean().default(false),dex_max:z.number().int().nonnegative().optional(),add_con:z.boolean().default(false),add_wis:z.boolean().default(false),description:z.string().optional()});var armorEntitySchema=z.object({name:z.string().min(1),slug:z.string().min(1),category:z.string(),ac:acSchema,strength_requirement:z.number().int().optional(),stealth_disadvantage:z.boolean().optional(),weight:z.union([z.number(),z.string()]).optional(),cost:z.string().optional(),rarity:z.string().optional(),source:z.string().optional(),page:z.number().int().optional(),edition:z.string().optional(),entries:z.array(z.unknown()).optional(),rendering_hint:z.string().optional(),icon:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),image:imageField,raw:z.record(z.string(),z.unknown()).optional()}).loose();export{armorEntitySchema};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseSubclass}from"./chunk-ETDMOGFO.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{ALL_TOOLS,ARTISANS_TOOLS,GAMING_SETS,MUSICAL_INSTRUMENTS}from"./chunk-4JEF3CET.js";import{toProfSlug}from"./chunk-VTQ4RWEG.js";var TOOL_CATEGORIES={"musical-instrument":{pool:MUSICAL_INSTRUMENTS,itemType:"instrument",label:"a musical instrument"},"artisan's-tools":{pool:ARTISANS_TOOLS,itemType:"artisan's tools",label:"artisan's tools"},"gaming-set":{pool:GAMING_SETS,itemType:"gaming set",label:"a gaming set"}};function categoryWords(token){return token.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase().replace(/['’ʼ]/g,"").split(/[\s_-]+/).filter(Boolean).map(w=>w.length>3&&w.endsWith("s")&&!w.endsWith("ss")?w.slice(0,-1):w)}var CATEGORY_BY_WORDS=new Map([["musical instrument","musical-instrument"],["artisan tool","artisan's-tools"],["gaming set","gaming-set"]]);function toolCategoriesOf(token){const parts=[[]];for(const w of categoryWords(token)){if(w==="or")parts.push([]);else parts[parts.length-1].push(w)}const out=[];for(const p of parts){const c=CATEGORY_BY_WORDS.get(p.filter(w=>w!=="any"&&w!=="one").join(" "));if(!c)return void 0;if(!out.includes(c))out.push(c)}return out}function expandToolPool(from){const out=[];const seen=new Set;const add=v=>{const k=toProfSlug(v);if(seen.has(k))return;seen.add(k);out.push(v)};for(const v of from){const cats=toolCategoriesOf(v);if(cats)for(const c of cats)for(const t of TOOL_CATEGORIES[c].pool)add(t);else add(v)}return out}var EMPTY={decisions:[],grants:[]};var poolOf=from=>Array.isArray(from)?from.filter(v=>typeof v==="string"&&v.length>0):typeof from==="string"&&from.length>0?[from]:[];var countOf=count=>{const n=Number(count!=null?count:1);return Number.isFinite(n)&&n>0?Math.floor(n):1};var KNOWN_TOOLS=new Set(ALL_TOOLS.map(toProfSlug));var namesToolsOutright=from=>from.every(v=>!toolCategoriesOf(v)&&KNOWN_TOOLS.has(toProfSlug(v)));var authorsToolPick=choices=>Array.isArray(choices)&&choices.some(c=>!!c&&typeof c==="object"&&c.kind==="select-proficiency"&&c.domain==="tool");function toolPick(count,from,id,allowDecision){const authored=poolOf(from);const pool=expandToolPool(authored);const n=countOf(count);if(pool.length===0)return EMPTY;if(n>=pool.length&&namesToolsOutright(authored))return{decisions:[],grants:pool};if(!allowDecision)return EMPTY;return{decisions:[{kind:"select-proficiency",id,count:n,domain:"tool",from:pool}],grants:[]}}function classToolPicks(entity){var _a;const tools=(_a=entity==null?void 0:entity.proficiencies)==null?void 0:_a.tools;const choice=tools==null?void 0:tools.choice;if(!choice||typeof choice!=="object")return EMPTY;return toolPick(choice.count,choice.from,"tool",!authorsToolPick(entity==null?void 0:entity.choices))}function backgroundToolPicks(bg){const entries=Array.isArray(bg==null?void 0:bg.tool_proficiencies)?bg.tool_proficiencies:[];const allowDecision=!authorsToolPick(bg==null?void 0:bg.choices);const out={decisions:[],grants:[]};for(const e of entries){if(!e||typeof e!=="object"||e.kind!=="choice")continue;const id=out.decisions.length===0?"tool":`tool-${out.decisions.length+1}`;const r=toolPick(e.count,e.from,id,allowDecision);out.decisions.push(...r.decisions);out.grants.push(...r.grants)}return out}export{TOOL_CATEGORIES,categoryWords,toolCategoriesOf,expandToolPool,classToolPicks,backgroundToolPicks};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function aliasFeatureActionCost(f){if(f.action===void 0&&typeof f.action_cost==="string")f.action=f.action_cost}function aliasFeatureListActionCost(list){if(Array.isArray(list)){for(const f of list)if(f&&typeof f==="object")aliasFeatureActionCost(f)}}function aliasFeaturesByLevelActionCost(byLevel){if(byLevel&&typeof byLevel==="object")for(const list of Object.values(byLevel))aliasFeatureListActionCost(list)}function withResolvedActionCost(f){return f.action===void 0&&typeof f.action_cost==="string"?{...f,action:f.action_cost}:f}export{aliasFeatureListActionCost,aliasFeaturesByLevelActionCost,withResolvedActionCost};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{bareEntitySlug}from"./chunk-63YJPWTM.js";var PURE_RANGED_THROWN_SLUGS=new Set(["dart","net"]);function classifyWeaponRange(weapon){const has=p=>weapon.properties.some(x=>x===p);const isCatRanged=/ranged/.test(weapon.category);const pureRanged=isCatRanged&&(has("ammunition")||has("loading")||PURE_RANGED_THROWN_SLUGS.has(bareEntitySlug(weapon.slug)));if(pureRanged){return{melee:null,ranged:weapon.range?{normal:weapon.range.normal,long:weapon.range.long,thrown:false}:null}}return{melee:{reach:5+(has("reach")?5:0)},ranged:weapon.range?{normal:weapon.range.normal,long:weapon.range.long,thrown:true}:null}}export{classifyWeaponRange};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{optionalFeatureEntitySchema}from"./chunk-NYPH7RQN.js";import{parseYaml}from"@archivist-gg/core";function parseOptionalFeature(source){const raw=parseYaml(source,["name","slug","feature_type"]);if(!raw.success)return raw;const result=optionalFeatureEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`optional-feature schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseOptionalFeature};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"zod";var itemInputSchema=z.object({name:z.string().describe("Item name"),type:z.enum(["weapon","armor","potion","ring","rod","scroll","staff","wand","wondrous item","shield"]),rarity:z.enum(["common","uncommon","rare","very rare","legendary","artifact"]),entries:z.array(z.string()).optional().describe("Item description and properties. Use inline formula tags for attack rolls, damage, and save DCs: `atk:ABILITY` for attack bonus, `damage:DICE+ABILITY` for damage (e.g. `damage:2d6`), `dc:ABILITY` for save DCs. Valid abilities: STR, DEX, CON, INT, WIS, CHA."),weight:z.number().optional(),value:z.number().optional(),attunement:z.union([z.boolean(),z.string()]).optional(),properties:z.array(z.string()).optional(),damage:z.string().optional(),damage_type:z.string().optional(),ac:z.number().optional(),charges:z.number().optional(),recharge:z.string().optional(),curse:z.boolean().optional()});export{itemInputSchema};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{classifyWeaponRange}from"./chunk-SEOASDO4.js";var PROPERTY_KEY={"2h":"two_handed","two-handed":"two_handed","two handed":"two_handed",h:"heavy",l:"light",f:"finesse",t:"thrown",v:"versatile",r:"reach",a:"ammunition",ld:"loading",s:"special"};var propertyKey=word=>{var _a;const w=word.trim().toLowerCase();return(_a=PROPERTY_KEY[w])!=null?_a:w.replace(/[\s-]+/g,"_")};var GRANT_RE=new RegExp("^(?:all\\s+)?(?:(melee|ranged)\\s+)?(simple|martial)(?:\\s+(melee|ranged))?\\s+weapons?\\s+(?:that|which)\\s+(have|has|don'?t\\s+have|do\\s+not\\s+have|doesn'?t\\s+have|does\\s+not\\s+have)\\s+the\\s+(.+?)\\s+propert(?:y|ies)\\.?$","i");function parseQualifiedWeaponGrant(text){var _a,_b;const m=GRANT_RE.exec(text.replace(/’/g,"'").trim().replace(/\s+/g," "));if(!m)return null;const range=(_b=(_a=m[1])!=null?_a:m[3])==null?void 0:_b.toLowerCase();const properties=m[5].split(/\s*,\s*|\s+or\s+|\s+and\s+/i).map(w=>w.trim()).filter(Boolean).map(propertyKey);if(properties.length===0)return null;return{category:m[2].toLowerCase(),...range?{range}:{},properties,without:/n'?t|not/i.test(m[4])}}function qualifiedGrantCovers(text,weapon){const g=parseQualifiedWeaponGrant(text);if(!g||typeof weapon.category!=="string")return false;if(!new RegExp(`^${g.category}\\b`).test(weapon.category))return false;if(g.range){const melee=classifyWeaponRange(weapon).melee!==null;if(g.range==="melee"!==melee)return false}const has=g.properties.some(p=>weapon.properties.some(x=>x===p));return g.without?!has:has}export{qualifiedGrantCovers};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"zod";var equipmentGrantSchema=z.union([z.object({item:z.string().min(1),qty:z.number().int().positive().optional(),contains_value:z.number().int().nonnegative().optional(),display_name:z.string().min(1).optional(),worth_value:z.number().int().nonnegative().optional()}).strict(),z.object({category:z.string().min(1),qty:z.number().int().positive().optional(),display_name:z.string().min(1).optional()}).strict(),z.object({gold:z.number().int().positive()}).strict()]);var equipmentOptionSchema=z.object({label:z.string().min(1),grants:z.array(equipmentGrantSchema)}).strict();var startingEquipmentEntrySchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("choice"),options:z.array(equipmentOptionSchema).nonempty()}).strict(),z.object({kind:z.literal("fixed"),label:z.string().min(1).optional(),grants:z.array(equipmentGrantSchema)}).strict(),z.object({kind:z.literal("gold"),amount:z.number().int().positive()}).strict()]);var startingGoldSchema=z.object({fixed:z.number().int().nonnegative().optional(),dice:z.string().min(1).optional(),multiplier:z.number().int().positive().optional()}).strict();export{equipmentGrantSchema,equipmentOptionSchema,startingEquipmentEntrySchema,startingGoldSchema};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var RACE_STRUCTURAL_PSEUDO=new Set(["size","speed","darkvision"]);export{RACE_STRUCTURAL_PSEUDO};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var ZERO_EFFECTS={speed_multiplier:1,speed_reduction_ft:0,speed_floor_zero:false,hp_max_multiplier:1,d20_test_penalty:0,exhaustion_level:0,attack_disadvantage:false,attack_advantage:false,attack_advantage_against:false,ability_check_disadvantage:false,save_disadvantage_dex:false,save_autofail_str:false,save_autofail_dex:false,saves_disadvantage_all:false,actions_disabled:false,reactions_disabled:false,sources:[]};var CONDITION_EFFECTS_2014={blinded:{attack_disadvantage:true,attack_advantage_against:true},charmed:{},deafened:{},frightened:{attack_disadvantage:true,ability_check_disadvantage:true},grappled:{speed_floor_zero:true},incapacitated:{actions_disabled:true,reactions_disabled:true},invisible:{attack_advantage:true},paralyzed:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},petrified:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},poisoned:{attack_disadvantage:true,ability_check_disadvantage:true},prone:{attack_disadvantage:true},restrained:{speed_floor_zero:true,attack_disadvantage:true,attack_advantage_against:true,save_disadvantage_dex:true},stunned:{save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},unconscious:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true}};var CONDITION_EFFECTS_2024={...CONDITION_EFFECTS_2014,grappled:{speed_floor_zero:true,attack_disadvantage:true}};var EXHAUSTION_EFFECTS_2014={0:{},1:{ability_check_disadvantage:true},2:{ability_check_disadvantage:true,speed_multiplier:.5},3:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true},4:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5},5:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5,speed_floor_zero:true},6:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5,speed_floor_zero:true}};function exhaustionEffects2024(level){if(level<=0)return{};return{d20_test_penalty:-2*level,speed_reduction_ft:5*level}}var CONDITION_TOOLTIPS_2014={blinded:["Auto-fail any check requiring sight."],charmed:["Can't attack the charmer or target them with harmful effects.","Charmer has advantage on social checks against you."],deafened:["Auto-fail any check requiring hearing."],frightened:["Disadvantage on attacks/checks while source in line of sight.","Can't willingly move closer to source."],grappled:["Speed = 0. Ends if grappler is incapacitated or you're moved out of reach."],incapacitated:["Can't take actions or reactions."],invisible:["Heavily obscured for hiding.","Your attacks have advantage; attacks against you have disadvantage.","Detectable by noise/tracks."],paralyzed:["Incapacitated. Speed 0.","Auto-fail STR/DEX saves.","Attacks against have advantage; melee within 5 ft. auto-crit."],petrified:["Incapacitated. Speed 0.","Resist all damage. Immune to poison/disease.","Auto-fail STR/DEX saves."],poisoned:["Disadvantage on attack rolls and ability checks."],prone:["Attacks against within 5 ft. have advantage; beyond 5 ft. have disadvantage.","Your attacks have disadvantage."],restrained:["Speed 0. Disadvantage on attacks and DEX saves.","Attacks against have advantage."],stunned:["Incapacitated. Auto-fail STR/DEX saves.","Attacks against have advantage."],unconscious:["Incapacitated, prone, dropped held items. Speed 0.","Auto-fail STR/DEX saves.","Attacks against have advantage; melee within 5 ft. auto-crit."]};var CONDITION_TOOLTIPS_2024={...CONDITION_TOOLTIPS_2014,grappled:["Speed = 0. Disadvantage on attack rolls against creatures other than the grappler.","Ends if grappler is incapacitated or you're moved out of reach."]};function computeConditionEffects(state,edition,_scores){var _a,_b;const out={...ZERO_EFFECTS,sources:[]};const conditionTable=edition==="2024"?CONDITION_EFFECTS_2024:CONDITION_EFFECTS_2014;const tooltipTable=edition==="2024"?CONDITION_TOOLTIPS_2024:CONDITION_TOOLTIPS_2014;const sortedConditions=[...new Set(state.conditions)].sort();for(const slug of sortedConditions){const partial=conditionTable[slug];if(!partial)continue;mergePartial(out,partial);out.sources.push({condition:slug,effects:(_a=tooltipTable[slug])!=null?_a:[]})}const exhLevel=clamp((_b=state.exhaustion)!=null?_b:0,0,6);out.exhaustion_level=exhLevel;if(exhLevel>0){const exhPartial=edition==="2024"?exhaustionEffects2024(exhLevel):EXHAUSTION_EFFECTS_2014[exhLevel];mergePartial(out,exhPartial);out.sources.push({condition:"exhaustion",level:exhLevel,effects:exhaustionTooltip(exhLevel,edition)})}return out}function speedConditionNames(state,edition){var _a;const table=edition==="2024"?CONDITION_EFFECTS_2024:CONDITION_EFFECTS_2014;const moves=p=>{var _a2,_b;return!!p&&(p.speed_floor_zero===true||((_a2=p.speed_multiplier)!=null?_a2:1)!==1||((_b=p.speed_reduction_ft)!=null?_b:0)!==0)};const names=[...new Set(state.conditions)].sort().filter(slug=>moves(table[slug])).map(slug=>slug.charAt(0).toUpperCase()+slug.slice(1));const exh=clamp((_a=state.exhaustion)!=null?_a:0,0,6);const exhPartial=exh>0?edition==="2024"?exhaustionEffects2024(exh):EXHAUSTION_EFFECTS_2014[exh]:void 0;if(moves(exhPartial))names.push(`Exhaustion ${exh}`);return names}function mergePartial(out,partial){for(const k of Object.keys(partial)){const v=partial[k];if(typeof v==="boolean"){out[k]=out[k]||v}else if(typeof v==="number"){if(k==="speed_multiplier"||k==="hp_max_multiplier"){out[k]=Math.min(out[k],v)}else{out[k]=out[k]+v}}}}function clamp(n,lo,hi){return Math.max(lo,Math.min(hi,Math.floor(n)))}function exhaustionTooltip(level,edition){if(edition==="2024"){return[`\u2212${2*level} on all d20 tests (attacks, saves, ability checks).`,`Speed reduced by ${5*level} ft.`,level>=6?"Death.":`Long rest reduces by 1 level.`]}const lines=[];if(level>=1)lines.push("Disadvantage on ability checks.");if(level>=2)lines.push("Speed halved.");if(level>=3)lines.push("Disadvantage on attack rolls and saving throws.");if(level>=4)lines.push("Hit point maximum halved.");if(level>=5)lines.push("Speed reduced to 0.");if(level>=6)lines.push("Death.");return lines}export{computeConditionEffects,speedConditionNames};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{evaluateMaxFormula,isValidMaxFormula}from"./chunk-EAARMPCW.js";var ABILITY_WORD={strength:"str",dexterity:"dex",constitution:"con",intelligence:"int",wisdom:"wis",charisma:"cha",str:"str",dex:"dex",con:"con",int:"int",wis:"wis",cha:"cha"};var ABILITY_RE="(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)";var SRD_CLASSES=["Barbarian","Bard","Cleric","Druid","Fighter","Monk","Paladin","Ranger","Rogue","Sorcerer","Warlock","Wizard"];function classAlternation(ownClass,classNames=[]){const extra=[];for(const name of[ownClass,...classNames]){const own=name==null?void 0:name.trim();if(!own)continue;if([...SRD_CLASSES,...extra].some(c=>c.toLowerCase()===own.toLowerCase()))continue;extra.push(own)}return`(${[...SRD_CLASSES,...extra.map(c=>c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))].join("|")})`}var TOKEN_ALIAS={prof_bonus:"prof",proficiency_bonus:"prof",spellcasting_mod:"spell_mod",spell_save_dc:"spell_dc"};var IDENT_LABEL={level:"level",class_level:"class level",prof:"PB",str_mod:"STR mod",dex_mod:"DEX mod",con_mod:"CON mod",int_mod:"INT mod",wis_mod:"WIS mod",cha_mod:"CHA mod",spell_mod:"spellcasting mod",spell_dc:"spell save DC"};var abilityToken=word=>`{${ABILITY_WORD[word.toLowerCase()]}_mod}`;var PHRASE_TABLES=new Map;function phraseTable(ownClass,classNames){const CLASS_RE=classAlternation(ownClass,classNames);const hit=PHRASE_TABLES.get(CLASS_RE);if(hit)return hit;const table=[[/\b(?:your|the)\s+(?:[a-z]+\s+)?spell save DC(?:\s+from this class's Spellcasting feature)?/gi,"{spell_dc}"],[new RegExp(`\\b8 plus your ${ABILITY_RE} modifier and (?:your )?Proficiency Bonus`,"gi"),(_m,a)=>`8 + ${abilityToken(a)} + {prof}`],[/\b(?:your\s+)?spellcasting ability modifier\b/gi,"{spell_mod}"],[/\b(?:your\s+)?spellcasting modifier\b/gi,"{spell_mod}"],[/\b(?:your\s+)?spell(?:casting)? mod\b/gi,"{spell_mod}"],[new RegExp(`\\b(?:your\\s+)?${ABILITY_RE} modifier\\b`,"gi"),(_m,a)=>abilityToken(a)],[/\b(STR|DEX|CON|INT|WIS|CHA) mod(?:ifier)?\b/g,(_m,a)=>abilityToken(a)],[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? up\\))`,"gi"),"ceil({class_level} / 2)"],[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? down\\))?`,"gi"),"floor({class_level} / 2)"],[/\bhalf your level in this class(?:\s*\(round(?:ed)? up\))/gi,"ceil({class_level} / 2)"],[/\bhalf your level in this class(?:\s*\(round(?:ed)? down\))?/gi,"floor({class_level} / 2)"],[new RegExp(`\\byour ${CLASS_RE} level\\b`,"gi"),"{class_level}"],[/\byour level in this class\b/gi,"{class_level}"],[/\byour (?:character )?level\b/gi,"{level}"],[/\b(?:your\s+)?proficiency bonus\b/gi,"{prof}"],[/\bPB\b/g,"{prof}"]];PHRASE_TABLES.set(CLASS_RE,table);return table}function normalizeAmountPhrases(text,ownClass,classNames){let out=text;for(const[re,to]of phraseTable(ownClass,classNames))out=out.replace(re,to);if(out===text)return text;out=out.replace(/\s+plus\s+/gi," + ").replace(/\s+minus\s+/gi," - ").replace(/\btwice (\{[a-z_]+\})/gi,"2 * $1");return out}var TRAILING_MIN=/\s*\(minimum(?: bonus)? of \+?(\d+)[^)]*\)\s*$/i;var DICE=/^\d*d\d+$/i;function tidySigns(s){return s.replace(/\+\s*-\s*/g,"- ").replace(/-\s*-\s*/g,"+ ")}function foldDice(expr){const parts=expr.replace(/\s+/g,"").match(/[+-]?[^+-]+/g);if(!parts)return null;const dice=[];let sum=0;for(const raw of parts){const sign=raw.startsWith("-")?-1:1;const body=raw.replace(/^[+-]/,"");if(DICE.test(body)){if(sign<0)return null;dice.push(body.toLowerCase());continue}if(!isValidMaxFormula(body))return null;sum+=sign*evaluateMaxFormula(body,ZERO_BINDINGS)}if(dice.length===0)return null;const n=Math.trunc(sum);return`${dice.join("+")}${n>0?`+${n}`:n<0?`${n}`:""}`}var ZERO_BINDINGS={level:0,class_level:0,prof:0,str_mod:0,dex_mod:0,con_mod:0,int_mod:0,wis_mod:0,cha_mod:0,columns:{}};function resolveAmountText(text,b){const normalized=normalizeAmountPhrases(text,b.class_name,b.class_names);if(!normalized.includes("{"))return text;const values=b;let unbound=false;const substitute=numeric2=>normalized.replace(/\{([a-z_]+)\}/g,(_m,raw)=>{var _a,_b;const id=(_a=TOKEN_ALIAS[raw])!=null?_a:raw;const v=values[id];if(typeof v!=="number"||!Number.isFinite(v)){unbound=true;return(_b=IDENT_LABEL[id])!=null?_b:raw}return numeric2&&v<0?`(0 - ${-v})`:String(v)});const display=tidySigns(substitute(false));if(unbound)return text.includes("{")?display:text;const min=TRAILING_MIN.exec(display);const minText=min?display.slice(min.index):"";const numeric=substitute(true);const numericCore=numeric.replace(TRAILING_MIN,"");if(isValidMaxFormula(numericCore)){const v=evaluateMaxFormula(numericCore,ZERO_BINDINGS);return String(Math.trunc(min?Math.max(Number(min[1]),v):v))}const roll=foldDice(min?display.slice(0,min.index):display);if(roll)return`${roll}${minText}`;if(/\b(?:floor|ceil|max|min)\(/.test(display))return text;return display}function addToRoll(roll,amounts){var _a;if(!amounts.length)return roll;const text=tidySigns([roll,...amounts].join(" + "));return(_a=foldDice(text))!=null?_a:text}function diceRollOf(resolved){var _a,_b;return(_b=(_a=diceRollPrefix(resolved))==null?void 0:_a.notation)!=null?_b:null}function diceRollPrefix(text){const m=/^(\d*d\d+(?:\s*[+-]\s*\d+)*)(?=\s|$)/i.exec(text);return m?{raw:m[1],notation:m[1].replace(/\s+/g,"")}:null}export{normalizeAmountPhrases,resolveAmountText,addToRoll,diceRollOf,diceRollPrefix};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var normKey=s=>s.toLowerCase().replace(/[^a-z0-9]+/g," ").trim().split(/\s+/).filter(Boolean).map(w=>w.endsWith("s")?w.slice(0,-1):w).sort().join(" ");var toProfSlug=s=>s.toLowerCase().replace(/’/g,"'").trim().replace(/\s+/g,"-");var humanizeProficiency=s=>s.replace(/-/g," ").replace(/(^|\s)\w/g,c=>c.toUpperCase());var proficiencyLabel=raw=>{const text=raw.replace(/’/g,"'").trim().replace(/\s+/g," ");if(!/\s/.test(text)||text===text.toLowerCase())return humanizeProficiency(toProfSlug(raw));return text.charAt(0).toUpperCase()+text.slice(1)};var weaponProfKey=raw=>{const key=normKey(raw);const bare=key.split(" ").filter(w=>w!=="weapon").join(" ");return bare==="simple"||bare==="martial"?bare:key};var armorProfKey=raw=>normKey(raw).split(" ").filter(w=>w!=="armor").join(" ");var proficiencyKey=(kind,raw)=>kind==="weapons"?weaponProfKey(raw):kind==="armor"?armorProfKey(raw):toProfSlug(raw);export{normKey,toProfSlug,humanizeProficiency,proficiencyLabel,weaponProfKey,armorProfKey,proficiencyKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{backgroundEntitySchema}from"./chunk-L2DXF7YS.js";import{parseYaml}from"@archivist-gg/core";function parseBackground(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=backgroundEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`background schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseBackground};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{heldPicks,parsePickKey,poolAnchorLevel}from"./chunk-PKIMOVQG.js";import{featProgressionCategory}from"./chunk-3QQOATV3.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{bucketOf}from"./chunk-QMEKQTUT.js";import{bareEntitySlug,twinKey,wikilinkTailSlug}from"./chunk-63YJPWTM.js";var OPTIONAL_FEATURE_TYPE_CODE={"MV:B":"maneuver",MV:"maneuver",EI:"invocation",MM:"metamagic","FS:F":"fighting_style"};function spellFilter(choose,edition){const where={edition};for(const part of choose.split("|")){const[rawKey,rawValue=""]=part.split("=");const key=rawKey.trim().toLowerCase();const value=rawValue.trim();if(key==="level"){const n=Number(value.split(";")[0]);if(!Number.isInteger(n))return null;where.level=n}else if(key==="class")where.list=value.toLowerCase();else if(key==="components & miscellaneous"&&/ritual/i.test(value))where.ritual=true}return where}function isTargetChoice(ch){return ch.kind==="select-entity"&&ch.target===true}var PACT_WEAPON_CHOICE_ID="pact-weapon";function pactWeaponPick(sites){for(const site of sites){for(const ch of site.choices){if(ch.kind!=="select-entity"||ch.id!==PACT_WEAPON_CHOICE_ID)continue;const v=site.read(ch.id);const first=Array.isArray(v)?v.find(x=>typeof x==="string"&&x.trim()!==""):v;if(typeof first!=="string"||!first.trim())continue;return first.trim().replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].trim()}}return void 0}function classPactWeaponPick(character,classes){var _a,_b,_c,_d,_e,_f,_g;const inBlock=(choices,block)=>{for(const ch of choices!=null?choices:[]){if(ch.kind==="select-inline"){const sel=block[ch.id];const branch=typeof sel==="string"?ch.options.find(o=>o.value===sel):void 0;const hit=inBlock(branch==null?void 0:branch.choices,block);if(hit)return hit}else if(ch.kind==="select-entity"&&ch.id===PACT_WEAPON_CHOICE_ID){const hit=pactWeaponPick([{choices:[ch],read:id=>block[id]}]);if(hit)return hit}}return void 0};for(let i=0;i<classes.length;i++){const entity=(_a=classes[i])==null?void 0:_a.entity;const entry=character.class[i];if(!entity||!entry)continue;for(const[lvl,raw]of Object.entries((_b=entry.choices)!=null?_b:{})){const block=raw!=null?raw:{};const features=[...(_d=((_c=entity.features_by_level)!=null?_c:{})[Number(lvl)])!=null?_d:[],...(_g=((_f=(_e=classes[i].subclass)==null?void 0:_e.features_by_level)!=null?_f:{})[Number(lvl)])!=null?_g:[]];for(const f of features){const hit=inBlock(f.choices,block);if(hit)return hit}}}return void 0}function progressionCount(p){var _a;if(Array.isArray(p))return 0;return(_a=p["*"])!=null?_a:Math.max(0,...Object.values(p))}function spellChoices(entity,used){var _a,_b;const out=[];for(const block of(_a=entity.additional_spells)!=null?_a:[]){for(const bucket of["known","prepared"]){const byLevel=block[bucket];if(!byLevel||typeof byLevel!=="object")continue;for(const rows of Object.values(byLevel)){for(const row of Array.isArray(rows)?rows:[]){const r=row;if(typeof r.choose!=="string")continue;const where=spellFilter(r.choose,entity.edition);if(!where)continue;const base=where.ritual?"rituals":where.level===0?"cantrips":`spells-${(_b=where.level)!=null?_b:"any"}`;const label=where.ritual?"Rituals":where.level===0?"Cantrips":`Level ${where.level} spells`;let id=base;for(let i=2;used.has(id);i++)id=`${base}-${i}`;used.add(id);out.push({kind:"select-entity",id,label,count:typeof r.count==="number"?r.count:1,entity_type:"spell",where})}}}}return out}function memberChoices(entity){var _a,_b,_c,_d,_e,_f;if(!entity)return[];if((_a=entity.choices)==null?void 0:_a.length)return entity.choices;const out=[];const used=new Set;for(const fp of(_b=entity.feat_progression)!=null?_b:[]){const category=featProgressionCategory(fp.category);const count=progressionCount(fp.progression);if(!category||count<1)continue;const id=used.has("feat")?`feat-${used.size}`:"feat";used.add(id);out.push({kind:"select-entity",id,label:fp.name,count,entity_type:"feat",where:{category,edition:entity.edition}})}for(const op of(_c=entity.optionalfeature_progression)!=null?_c:[]){const codes=(_e=(_d=op.feature_type)!=null?_d:op.featureType)!=null?_e:[];const featureType=codes.map(c=>OPTIONAL_FEATURE_TYPE_CODE[c]).find(t=>!!t);const count=progressionCount(op.progression);if(!featureType||count<1){if(!featureType)warnOnce(`member-of-code:${entity.slug}`,`Archivist: "${entity.slug}" asks for optional features of type ${codes.join(", ")}, which this engine does not map; no pick is offered`);continue}const id=op.name.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"option";used.add(id);out.push({kind:"select-entity",id,label:op.name,count,entity_type:"optional-feature",where:{feature_type:featureType,edition:entity.edition}})}out.push(...spellChoices(entity,used));for(const pre of(_f=entity.prerequisites)!=null?_f:[]){if(pre.kind!=="spell-choose")continue;const where=spellFilter(pre.choose,entity.edition);if(!where||used.has("cantrip"))continue;used.add("cantrip");out.push({kind:"select-entity",id:"cantrip",label:where.level===0?"Cantrip":"Spell",count:1,entity_type:"spell",where,target:true})}return out}function memberSpellTargets(member,read){var _a;const refs=[];const open=[];for(const ch of memberChoices(member)){if(ch.kind!=="select-entity"||!isTargetChoice(ch)||ch.entity_type!=="spell")continue;const v=read(ch.id);const picked=(Array.isArray(v)?v:[v]).filter(x=>typeof x==="string"&&x.trim()!=="");if(picked.length)refs.push(...picked);else if(ch.where)open.push(ch.where)}for(const pre of(_a=member.prerequisites)!=null?_a:[])if(pre.kind==="spell-known")refs.push(pre.spell);return refs.length||open.length?{refs,open}:null}function spellMatchesFilter(d,where){var _a,_b;if(where.list&&!((_a=d.classes)!=null?_a:[]).includes(where.list))return false;if(where.level!==void 0&&((_b=d.level)!=null?_b:0)!==where.level)return false;if(where.edition&&d.edition!==where.edition)return false;if(where.ritual&&d.ritual!==true)return false;return true}function spellsReached(targets,spells){if(!targets)return[];const hit=new Set;for(const ref of targets.refs){const full=stripRef(ref);const exact=spells.filter(s=>s.slug===full);const bare=wikilinkTailSlug(ref);for(const s of exact.length?exact:spells.filter(s2=>bareEntitySlug(s2.slug)===bare))hit.add(s.slug)}for(const where of targets.open){const legal=new Set(spells.filter(s=>{var _a;return spellMatchesFilter(s.entity,where)&&!!((_a=s.entity.damage_roll)==null?void 0:_a.trim())}).map(s=>s.slug));if(legal.size===1)hit.add([...legal][0])}return[...new Set(spells.map(s=>s.slug))].filter(slug=>hit.has(slug))}function siteOf(classIndex,level,poolId,pickKey,member,memberSlug,block){const choices=memberChoices(member);if(!choices.length)return null;const prefix=`${poolId}:${pickKey}:`;return{classIndex,level,poolId,pickKey,member,memberSlug,choices,prefix,block,read:id=>block[`${prefix}${id}`]}}function poolMemberSites(classes,registry){const out=[];let byBare=null;let all=null;const lookup=(s,ownerPrefix)=>{all!=null?all:all=bucketOf(registry,"optional-feature");const bare=bareEntitySlug(s);const twin=twinKey(s);const owned=all.find(e=>twinKey(e.slug)===twin&&e.slug.split("_")[0]===ownerPrefix);if(owned)return owned;const direct=registry.getByTypeAndSlug("optional-feature",s);if(direct)return direct;byBare!=null?byBare:byBare=new Map(all.map(e=>[bareEntitySlug(e.slug),e]));return byBare.get(bare)};classes.forEach((rc,classIndex)=>{var _a,_b,_c,_d,_e;if(!rc.entity)return;const seen=new Set;for(const pool of[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]]){if(seen.has(pool.id))continue;seen.add(pool.id);const{anchorLevel}=poolAnchorLevel(rc.entity,pool);const block=(_e=(_d=rc.choices)==null?void 0:_d[anchorLevel])!=null?_e:{};const raw=block[pool.id];const picks=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];for(const s of picks){if(typeof s!=="string")continue;const{slugPart,param}=parsePickKey(s);const reg=lookup(slugPart,rc.entity.slug.split("_")[0]);if(!reg)continue;const member=reg.data;const key=member.repeatable===true||param!==null?s:reg.slug;const site=siteOf(classIndex,anchorLevel,pool.id,key,member,reg.slug,block);if(site)out.push(site)}}});return out}function poolMemberSitesOf(resolved){var _a,_b,_c,_d,_e;const out=[];for(const pool of(_a=resolved.pools)!=null?_a:[]){const block=(_e=(_d=(_c=(_b=resolved.classes)==null?void 0:_b[pool.classIndex])==null?void 0:_c.choices)==null?void 0:_d[pool.anchorLevel])!=null?_e:{};for(const e of heldPicks(pool)){const site=siteOf(pool.classIndex,pool.anchorLevel,pool.id,e.key,e.entity,e.slug,block);if(site)out.push(site)}}return out}var stripRef=ref=>ref.replace(/^\[\[/,"").replace(/\]\]$/,"");function featPickSites(classEntries,memberSites,classSlugOf){const out=[];(classEntries!=null?classEntries:[]).forEach((c,classIndex)=>{var _a;for(const[lvl,choiceBlock]of Object.entries((_a=c.choices)!=null?_a:{})){const block=choiceBlock;const feat=block==null?void 0:block.feat;if(!block||typeof feat!=="string")continue;const slug=stripRef(feat);if(!slug)continue;const level=/^\d+$/.test(lvl)?Number(lvl):null;const cls=classSlugOf(classIndex);out.push({slug,classIndex,level,via:cls&&level!==null?{kind:"class",slug:cls,level}:null,read:id=>block[`feat:${id}`]})}});for(const site of memberSites){for(const ch of site.choices){if(ch.kind!=="select-entity"||ch.entity_type!=="feat"||ch.target===true)continue;const v=site.read(ch.id);for(const ref of Array.isArray(v)?v:typeof v==="string"?[v]:[]){if(typeof ref!=="string")continue;const slug=stripRef(ref);if(!slug)continue;const cls=classSlugOf(site.classIndex);out.push({slug,classIndex:site.classIndex,level:site.level,via:cls?{kind:"pool",slug:site.memberSlug,name:site.member.name,classSlug:cls,level:site.level}:null,read:id=>site.block[`${site.prefix}feat:${id}`]})}}}return out}function raceFeatSites(race,originChoices){var _a;if(!race)return[];const oc=originChoices!=null?originChoices:{};const out=[];for(const list of[race.choices,...((_a=race.traits)!=null?_a:[]).map(t=>t==null?void 0:t.choices)]){for(const ch of Array.isArray(list)?list:[]){if((ch==null?void 0:ch.kind)!=="select-entity"||ch.entity_type!=="feat")continue;const v=oc[`race:${ch.id}`];for(const ref of Array.isArray(v)?v:typeof v==="string"?[v]:[]){const slug=typeof ref==="string"?stripRef(ref):"";if(slug)out.push({slug,via:{kind:"race",slug:race.slug},read:id=>oc[`race:feat:${id}`]})}}}return out}function featOfSite(site,feats){var _a;return(_a=feats.find(f=>f.slug===site.slug))!=null?_a:feats.find(f=>bareEntitySlug(f.slug)===bareEntitySlug(site.slug))}function nestedPickKeysToPrune(block,key,next){const prev=block==null?void 0:block[key];if(!block||!Array.isArray(prev))return[];const keep=new Set(next);const gone=prev.filter(k=>typeof k==="string"&&!keep.has(k));if(!gone.length)return[];return Object.keys(block).filter(k=>gone.some(g=>k.startsWith(`${key}:${g}:`)))}export{isTargetChoice,PACT_WEAPON_CHOICE_ID,pactWeaponPick,classPactWeaponPick,memberChoices,memberSpellTargets,spellsReached,poolMemberSites,poolMemberSitesOf,featPickSites,raceFeatSites,featOfSite,nestedPickKeysToPrune};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"zod";var casterTypeEnum=z.enum(["full","half","third","pact","half-up"]);export{casterTypeEnum};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseSpell}from"./chunk-4KVVAENP.js";import yaml from"js-yaml";var spellCodec={parse(doc){return parseSpell(doc.body)},serialize(spell){const{material:_material,...doc}=spell;return yaml.dump(doc,{lineWidth:-1,sortKeys:false})}};export{spellCodec};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{aliasFeaturesByLevelActionCost}from"./chunk-S5UCI27C.js";import{classEntitySchema}from"./chunk-DTB7YBMZ.js";import{parseYaml}from"@archivist-gg/core";function parseClass(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;aliasFeaturesByLevelActionCost(raw.data.features_by_level);const result=classEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`class schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseClass};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function requiresAttunement(entity){if(!entity||!("attunement"in entity))return false;const a=entity.attunement;if(a===true)return true;if(typeof a==="string")return a.length>0;if(typeof a==="object"&&a!==null)return a.required===true;return false}export{requiresAttunement};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"zod";var durationSchema=z.union([z.literal("instantaneous"),z.literal("until-dispelled"),z.object({amount:z.number().int().positive(),unit:z.enum(["round","minute","hour","day"])}).strict()]);export{durationSchema};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{STATIC_FALLBACK_CONTEXT,convertDescToTags}from"./chunk-MGGKZGLG.js";function enrichItem(raw){var _a,_b,_c;const enriched={...raw,source:(_a=raw.source)!=null?_a:"Homebrew",attunement:(_b=raw.attunement)!=null?_b:false,curse:(_c=raw.curse)!=null?_c:false};if(Array.isArray(enriched.entries)){enriched.entries=enriched.entries.map(e=>convertDescToTags(e,STATIC_FALLBACK_CONTEXT))}return enriched}export{enrichItem};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{MONSTER_KNOWN_KEYS,monsterSchema}from"./chunk-HX7WBOKR.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","heavy","pact-weapon"]);var speedGateEnum=z.enum(["heavy-armor","armor","shield"]);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().optional(),equal_to:z.literal("walk").optional(),set:z.boolean().optional(),scales_at:z.array(z.object({level:z.number().int().min(1).max(20),value:z.number().int()})).optional(),inactive_while:z.union([speedGateEnum,z.array(speedGateEnum).nonempty()]).optional(),condition:conditionField,subject:subjectField}).refine(e=>e.value===void 0!==(e.equal_to===void 0),{path:["value"],message:"speed-bonus takes exactly one of `value` (feet) or `equal_to: walk`"}).refine(e=>e.equal_to===void 0||e.mode!=="walk"&&e.set===void 0&&e.scales_at===void 0,{path:["equal_to"],message:"`equal_to: walk` grants a mode other than walk, never with `set` or `scales_at`"}),z.object({kind:z.literal("speed-rule"),flag:z.enum(["ignore-armor-strength"]),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};
|
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
import type { DocCodec } from "@archivist-gg/core";
|
|
2
2
|
import type { ClassEntity } from "./class.types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Normalizing codec (0c.1a). `parse` delegates to `parseClass`, which validates
|
|
5
|
-
* against `classEntitySchema`. `class.types` is this entity's dnd5e home for
|
|
6
|
-
* `SpellcastingConfig`/`ClassEntity` (consumed by PC + all subclass files).
|
|
7
|
-
* `serialize` stays `yaml.dump` (the edit-save path uses obsidian's separate
|
|
8
|
-
* serializer; gate (d) verifies `yaml.dump` round-trips through `parseClass`).
|
|
9
|
-
*/
|
|
10
3
|
export declare const classCodec: DocCodec<ClassEntity>;
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
classCodec
|
|
3
|
-
} from "../chunk-GVWEFECG.js";
|
|
4
|
-
import "../chunk-XTEFPUSN.js";
|
|
5
|
-
import "../chunk-4U55VNC7.js";
|
|
6
|
-
import "../chunk-UJCK5IW4.js";
|
|
7
|
-
import "../chunk-G6MHJDVT.js";
|
|
8
|
-
import "../chunk-CJYCVNW2.js";
|
|
9
|
-
import "../chunk-B2QHP6UF.js";
|
|
10
|
-
import "../chunk-WYGD2UGN.js";
|
|
11
|
-
import "../chunk-ZJXSXVFP.js";
|
|
12
|
-
import "../chunk-IN4M4X7P.js";
|
|
13
|
-
import "../chunk-OOL4KMG2.js";
|
|
14
|
-
import "../chunk-JXWNXIIZ.js";
|
|
15
|
-
import "../chunk-UA5KS2PL.js";
|
|
16
|
-
export {
|
|
17
|
-
classCodec
|
|
18
|
-
};
|
|
1
|
+
import{classCodec}from"../chunk-EPA24PVZ.js";import"../chunk-XPF53K54.js";import"../chunk-S5UCI27C.js";import"../chunk-DTB7YBMZ.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-NIWLD33X.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-LHH5XSEA.js";import"../chunk-ZVL5FXXO.js";import"../chunk-I26FHSI6.js";export{classCodec};
|
|
@@ -1,17 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
parseClass
|
|
3
|
-
} from "../chunk-XTEFPUSN.js";
|
|
4
|
-
import "../chunk-4U55VNC7.js";
|
|
5
|
-
import "../chunk-UJCK5IW4.js";
|
|
6
|
-
import "../chunk-G6MHJDVT.js";
|
|
7
|
-
import "../chunk-CJYCVNW2.js";
|
|
8
|
-
import "../chunk-B2QHP6UF.js";
|
|
9
|
-
import "../chunk-WYGD2UGN.js";
|
|
10
|
-
import "../chunk-ZJXSXVFP.js";
|
|
11
|
-
import "../chunk-IN4M4X7P.js";
|
|
12
|
-
import "../chunk-OOL4KMG2.js";
|
|
13
|
-
import "../chunk-JXWNXIIZ.js";
|
|
14
|
-
import "../chunk-UA5KS2PL.js";
|
|
15
|
-
export {
|
|
16
|
-
parseClass
|
|
17
|
-
};
|
|
1
|
+
import{parseClass}from"../chunk-XPF53K54.js";import"../chunk-S5UCI27C.js";import"../chunk-DTB7YBMZ.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-NIWLD33X.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-LHH5XSEA.js";import"../chunk-ZVL5FXXO.js";import"../chunk-I26FHSI6.js";export{parseClass};
|
|
@@ -40,10 +40,10 @@ export declare const classEntitySchema: z.ZodObject<{
|
|
|
40
40
|
}>>;
|
|
41
41
|
proficiencies: z.ZodObject<{
|
|
42
42
|
armor: z.ZodArray<z.ZodEnum<{
|
|
43
|
-
light: "light";
|
|
44
|
-
medium: "medium";
|
|
45
43
|
heavy: "heavy";
|
|
46
44
|
shield: "shield";
|
|
45
|
+
light: "light";
|
|
46
|
+
medium: "medium";
|
|
47
47
|
}>>;
|
|
48
48
|
weapons: z.ZodObject<{
|
|
49
49
|
fixed: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -99,7 +99,7 @@ export declare const classEntitySchema: z.ZodObject<{
|
|
|
99
99
|
full: "full";
|
|
100
100
|
pact: "pact";
|
|
101
101
|
third: "third";
|
|
102
|
-
|
|
102
|
+
"half-up": "half-up";
|
|
103
103
|
}>;
|
|
104
104
|
ability: z.ZodEnum<{
|
|
105
105
|
str: "str";
|
|
@@ -159,6 +159,7 @@ export declare const classEntitySchema: z.ZodObject<{
|
|
|
159
159
|
band: "band";
|
|
160
160
|
tab: "tab";
|
|
161
161
|
}>>;
|
|
162
|
+
equivalent_ids: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
162
163
|
recovery: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
163
164
|
id: z.ZodString;
|
|
164
165
|
name: z.ZodString;
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
classEntitySchema
|
|
3
|
-
} from "../chunk-UJCK5IW4.js";
|
|
4
|
-
import "../chunk-G6MHJDVT.js";
|
|
5
|
-
import "../chunk-CJYCVNW2.js";
|
|
6
|
-
import "../chunk-B2QHP6UF.js";
|
|
7
|
-
import "../chunk-WYGD2UGN.js";
|
|
8
|
-
import "../chunk-ZJXSXVFP.js";
|
|
9
|
-
import "../chunk-IN4M4X7P.js";
|
|
10
|
-
import "../chunk-OOL4KMG2.js";
|
|
11
|
-
import "../chunk-JXWNXIIZ.js";
|
|
12
|
-
import "../chunk-UA5KS2PL.js";
|
|
13
|
-
export {
|
|
14
|
-
classEntitySchema
|
|
15
|
-
};
|
|
1
|
+
import{classEntitySchema}from"../chunk-DTB7YBMZ.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-NIWLD33X.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-LHH5XSEA.js";import"../chunk-ZVL5FXXO.js";import"../chunk-I26FHSI6.js";export{classEntitySchema};
|
|
@@ -1,13 +1,2 @@
|
|
|
1
1
|
export declare function bareSlug(ref: string): string;
|
|
2
|
-
/**
|
|
3
|
-
* Bare class name for profile / spell-`classes` lookups.
|
|
4
|
-
*
|
|
5
|
-
* Compendium-qualified slugs are `<compendium>_<type>_<name>` (3-part, e.g.
|
|
6
|
-
* `srd-2024_class_wizard`) or the legacy `<compendium>_<name>` (2-part, e.g.
|
|
7
|
-
* `srd-5e_wizard`); compendium/type segments are hyphen-cased, so `_` only ever
|
|
8
|
-
* separates the structural parts from the entity name. Strip that prefix to get
|
|
9
|
-
* the canonical class key (`wizard`). Name-slugs never contain `_`, so a 3-part
|
|
10
|
-
* slug's name is `parts.slice(2).join("_")`. Hand-written/test slugs without a
|
|
11
|
-
* `_` pass through unchanged (`wizard` → `wizard`).
|
|
12
|
-
*/
|
|
13
2
|
export declare function baseClassName(ref: string): string;
|
package/dist/class/class.slug.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* D2b-A (A-1, user pick A) · the class's recommended Standard Array, which the Builder's Abilities step suggests.
|
|
3
|
-
*/
|
|
4
1
|
import type { Ability } from "@archivist-gg/dnd5e/types/choice";
|
|
5
2
|
import type { ClassEntity } from "./class.types.js";
|
|
6
|
-
/** Structural subset of the registry this reads. */
|
|
7
3
|
export interface StandardArrayRegistry {
|
|
8
4
|
search(query: string, entityType: string, limit: number): Array<{
|
|
9
5
|
slug: string;
|
|
10
6
|
data: Record<string, unknown>;
|
|
11
7
|
}>;
|
|
12
8
|
}
|
|
13
|
-
/** The class's own `standard_array`; else, for a 2024 class that carries none (a book class imported before the table
|
|
14
|
-
* was data), the table of its 2024 twin in the registry (the same bare slug, e.g. the SRD 2024 Fighter for the PHB
|
|
15
|
-
* 2024 Fighter). Null for a 2014 class and for a class with no 2024 twin (homebrew): the Builder then suggests nothing. */
|
|
16
9
|
export declare function standardArrayFor(entity: Pick<ClassEntity, "slug" | "edition" | "standard_array">, registry: StandardArrayRegistry | null | undefined): Record<Ability, number> | null;
|
|
@@ -1,20 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
bareEntitySlug
|
|
3
|
-
} from "../chunk-ZCTUYGNV.js";
|
|
4
|
-
|
|
5
|
-
// src/class/class.standard-array.ts
|
|
6
|
-
var isArray = (v) => !!v && typeof v === "object" && ["str", "dex", "con", "int", "wis", "cha"].every((k) => typeof v[k] === "number");
|
|
7
|
-
function standardArrayFor(entity, registry) {
|
|
8
|
-
if (isArray(entity.standard_array)) return entity.standard_array;
|
|
9
|
-
if (entity.edition !== "2024" || !registry) return null;
|
|
10
|
-
const bare = bareEntitySlug(entity.slug);
|
|
11
|
-
for (const e of registry.search("", "class", Number.POSITIVE_INFINITY)) {
|
|
12
|
-
if (e.slug === entity.slug || bareEntitySlug(e.slug) !== bare) continue;
|
|
13
|
-
const d = e.data;
|
|
14
|
-
if (d.edition === "2024" && isArray(d.standard_array)) return d.standard_array;
|
|
15
|
-
}
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
export {
|
|
19
|
-
standardArrayFor
|
|
20
|
-
};
|
|
1
|
+
import{bareEntitySlug}from"../chunk-63YJPWTM.js";var isArray=v=>!!v&&typeof v==="object"&&["str","dex","con","int","wis","cha"].every(k=>typeof v[k]==="number");function standardArrayFor(entity,registry){if(isArray(entity.standard_array))return entity.standard_array;if(entity.edition!=="2024"||!registry)return null;const bare=bareEntitySlug(entity.slug);for(const e of registry.search("","class",Number.POSITIVE_INFINITY)){if(e.slug===entity.slug||bareEntitySlug(e.slug)!==bare)continue;const d=e.data;if(d.edition==="2024"&&isArray(d.standard_array))return d.standard_array}return null}export{standardArrayFor};
|