diff --git a/.editorconfig b/.editorconfig index 8bbc2b52..6cfef2fc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,5 @@ [*] indent_size = 4 indent_style = spaces +[*.yml] +indent_size = 2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..fd9b922e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: Project CI + +on: + pull_request: + branches: [main] + push: + branches: [main] + workflow_dispatch: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [24.x] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Cache NPM Deps + id: cache-npm + uses: actions/cache@v3 + with: + path: node_modules/ + key: npm-${{ hashFiles('package-lock.json') }} + + - name: Install NPM Deps + if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} + run: npm ci + + - name: Lint + run: npm run lint \ No newline at end of file diff --git a/daggerheart.mjs b/daggerheart.mjs index 399e6873..e25f1b09 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -361,7 +361,7 @@ Hooks.on(CONFIG.DH.HOOKS.hooksConfig.groupRollStart, async data => { const updateActorsRangeDependentEffects = async token => { if (!token) return; - + const rangeMeasurement = game.settings.get( CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..ce2bb86f --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,14 @@ +import globals from 'globals'; +import { defineConfig } from 'eslint/config'; +import prettier from 'eslint-plugin-prettier'; + +export default defineConfig([ + { files: ['**/*.{js,mjs,cjs}'], languageOptions: { globals: globals.browser } }, + { plugins: { prettier } }, + { + files: ['**/*.{js,mjs,cjs}'], + rules: { + 'prettier/prettier': 'error' + } + } +]); diff --git a/lang/en.json b/lang/en.json index 3d225a82..fe8205b8 100755 --- a/lang/en.json +++ b/lang/en.json @@ -118,7 +118,9 @@ "deleteTriggerTitle": "Delete Trigger", "deleteTriggerContent": "Are you sure you want to delete the {trigger} trigger?", "advantageState": "Advantage State", - "damageOnSave": "Damage on Save" + "damageOnSave": "Damage on Save", + "useDefaultItemValues": "Use default Item values", + "itemDamageIsUsed": "Item Damage Is Used" }, "RollField": { "diceRolling": { @@ -133,7 +135,7 @@ "attackModifier": "Attack Modifier", "attackName": "Attack Name", "criticalThreshold": "Critical Threshold", - "includeBase": { "label": "Include Item Damage" }, + "includeBase": { "label": "Use Item Damage" }, "groupAttack": { "label": "Group Attack" }, "multiplier": "Multiplier", "saveHint": "Set a default Trait to enable Reaction Roll. It can be changed later in Reaction Roll Dialog.", @@ -3239,6 +3241,7 @@ "Tooltip": { "disableEffect": "Disable Effect", "enableEffect": "Enable Effect", + "edit": "Edit", "openItemWorld": "Open Item World", "openActorWorld": "Open Actor World", "sendToChat": "Send to Chat", diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 3475dee7..989e4625 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -259,8 +259,9 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV const resetValue = increasing ? 0 : feature.system.resource.max - ? Roll.replaceFormulaData(feature.system.resource.max, this.actor) + ? new Roll(Roll.replaceFormulaData(feature.system.resource.max, this.actor)).evaluateSync().total : 0; + await feature.update({ 'system.resource.value': resetValue }); } diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index d5adb79c..f991187f 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -28,10 +28,8 @@ export default class DHActionConfig extends DHActionBaseConfig { game.system.api.data.activeEffects.BaseEffect.getDefaultObject({ transfer: false }) ]); - if (areaIndex !== undefined) - data.area[areaIndex].effects.push(created[0]._id); - else - data.effects.push({ _id: created[0]._id }); + if (areaIndex !== undefined) data.area[areaIndex].effects.push(created[0]._id); + else data.effects.push({ _id: created[0]._id }); this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); this.action.item.effects.get(created[0]._id).sheet.render(true); } @@ -57,14 +55,14 @@ export default class DHActionConfig extends DHActionBaseConfig { static removeEffect(event, button) { if (!this.action.effects) return; - const { areaIndex, index } = button.dataset; - let effectId = null; + const { areaIndex, index } = button.dataset; + let effectId = null; if (areaIndex !== undefined) { effectId = this.action.area[areaIndex].effects[index]; const data = this.action.toObject(); data.area[areaIndex].effects.splice(index, 1); this.constructor.updateForm.call(this, null, null, { object: foundry.utils.flattenObject(data) }); - } else { + } else { effectId = this.action.effects[index]._id; this.constructor.removeElement.call(this, event, button); } diff --git a/module/applications/sheets-configs/action-settings-config.mjs b/module/applications/sheets-configs/action-settings-config.mjs index 5ec9fb5f..fd62f621 100644 --- a/module/applications/sheets-configs/action-settings-config.mjs +++ b/module/applications/sheets-configs/action-settings-config.mjs @@ -40,10 +40,8 @@ export default class DHActionSettingsConfig extends DHActionBaseConfig { this.sheetUpdate(data, effectData); this.effects = [...this.effects, effectData]; - if(areaIndex !== undefined) - data.area[areaIndex].effects.push(effectData.id); - else - data.effects.push({ _id: effectData.id }); + if (areaIndex !== undefined) data.area[areaIndex].effects.push(effectData.id); + else data.effects.push({ _id: effectData.id }); this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); } @@ -62,7 +60,6 @@ export default class DHActionSettingsConfig extends DHActionBaseConfig { this.constructor.removeElement.call(this, event, button); } - this.sheetUpdate( this.action.toObject(), this.effects.find(x => x.id === effectId), diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index f2686fdd..c59dd64e 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -12,8 +12,6 @@ export default class CharacterSheet extends DHBaseActorSheet { static DEFAULT_OPTIONS = { classes: ['character'], position: { width: 850, height: 800 }, - /* Foundry adds disabled to all buttons and inputs if editPermission is missing. This is not desired. */ - editPermission: CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER, actions: { toggleVault: CharacterSheet.#toggleVault, rollAttribute: CharacterSheet.#rollAttribute, @@ -68,7 +66,7 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - handler: CharacterSheet.#getEquipamentContextOptions, + handler: CharacterSheet.#getEquipmentContextOptions, selector: '[data-item-uuid][data-type="armor"], [data-item-uuid][data-type="weapon"]', options: { parentClassHooks: false, @@ -170,6 +168,16 @@ export default class CharacterSheet extends DHBaseActorSheet { return applicationOptions; } + /** @inheritdoc */ + _toggleDisabled(disabled) { + // Overriden to only disable text inputs by default. + // Everything else is done by checking @root.editable in the sheet + const form = this.form; + for (const input of form.querySelectorAll('input:not([type=search]), .editor.prosemirror')) { + input.disabled = disabled; + } + } + /** @inheritDoc */ async _onRender(context, options) { await super._onRender(context, options); @@ -315,11 +323,11 @@ export default class CharacterSheet extends DHBaseActorSheet { /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ const options = [ { - name: 'toLoadout', + label: 'toLoadout', icon: 'fa-solid fa-arrow-up', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && doc.system.inVault; + return doc?.isOwner && doc.system.inVault; }, callback: async target => { const doc = await getDocFromElement(target); @@ -329,11 +337,11 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - name: 'recall', + label: 'recall', icon: 'fa-solid fa-bolt-lightning', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && doc.system.inVault; + return doc?.isOwner && doc.system.inVault; }, callback: async (target, event) => { const doc = await getDocFromElement(target); @@ -368,17 +376,17 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - name: 'toVault', + label: 'toVault', icon: 'fa-solid fa-arrow-down', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && !doc.system.inVault; + return doc?.isOwner && !doc.system.inVault; }, callback: async target => (await getDocFromElement(target)).update({ 'system.inVault': true }) } ].map(option => ({ ...option, - name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, + label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, icon: `` })); @@ -391,29 +399,29 @@ export default class CharacterSheet extends DHBaseActorSheet { * @this {CharacterSheet} * @protected */ - static #getEquipamentContextOptions() { + static #getEquipmentContextOptions() { const options = [ { - name: 'equip', + label: 'equip', icon: 'fa-solid fa-hands', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && !doc.system.equipped; + return doc.isOwner && doc && !doc.system.equipped; }, callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target) }, { - name: 'unequip', + label: 'unequip', icon: 'fa-solid fa-hands', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && doc.system.equipped; + return doc.isOwner && doc && doc.system.equipped; }, callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target) } ].map(option => ({ ...option, - name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, + label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, icon: `` })); diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index e93ce774..5faa5d5c 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -418,18 +418,18 @@ export default function DHApplicationMixin(Base) { /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ const options = [ { - name: 'disableEffect', + label: 'disableEffect', icon: 'fa-solid fa-lightbulb', - condition: element => { + visible: element => { const target = element.closest('[data-item-uuid]'); return !target.dataset.disabled && target.dataset.itemType !== 'beastform'; }, callback: async target => (await getDocFromElement(target)).update({ disabled: true }) }, { - name: 'enableEffect', + label: 'enableEffect', icon: 'fa-regular fa-lightbulb', - condition: element => { + visible: element => { const target = element.closest('[data-item-uuid]'); return target.dataset.disabled && target.dataset.itemType !== 'beastform'; }, @@ -437,7 +437,7 @@ export default function DHApplicationMixin(Base) { } ].map(option => ({ ...option, - name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, + label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, icon: `` })); @@ -468,14 +468,14 @@ export default function DHApplicationMixin(Base) { _getContextMenuCommonOptions({ usable = false, toChat = false, deletable = true }) { const options = [ { - name: 'CONTROLS.CommonEdit', + label: 'CONTROLS.CommonEdit', icon: 'fa-solid fa-pen-to-square', - condition: target => { + visible: target => { const { dataset } = target.closest('[data-item-uuid]'); const doc = getDocFromElementSync(target); return ( (!dataset.noCompendiumEdit && !doc) || - (doc && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection)) + (doc?.isOwner && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection)) ); }, callback: async target => (await getDocFromElement(target)).sheet.render({ force: true }) @@ -484,14 +484,14 @@ export default function DHApplicationMixin(Base) { if (usable) { options.unshift({ - name: 'DAGGERHEART.GENERAL.damage', + label: 'DAGGERHEART.GENERAL.damage', icon: 'fa-solid fa-explosion', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return ( + const hasDamage = !foundry.utils.isEmpty(doc?.system?.attack?.damage.parts) || - !foundry.utils.isEmpty(doc?.damage?.parts) - ); + !foundry.utils.isEmpty(doc?.damage?.parts); + return doc?.isOwner && hasDamage; }, callback: async (target, event) => { const doc = await getDocFromElement(target), @@ -507,11 +507,11 @@ export default function DHApplicationMixin(Base) { }); options.unshift({ - name: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', + label: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', icon: 'fa-solid fa-burst', - condition: target => { + visible: target => { const doc = getDocFromElementSync(target); - return doc && !(doc.type === 'domainCard' && doc.system.inVault); + return doc?.isOwner && !(doc.type === 'domainCard' && doc.system.inVault); }, callback: async (target, event) => (await getDocFromElement(target)).use(event) }); @@ -519,18 +519,19 @@ export default function DHApplicationMixin(Base) { if (toChat) options.push({ - name: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', + label: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', icon: 'fa-solid fa-message', callback: async target => (await getDocFromElement(target)).toChat(this.document.uuid) }); if (deletable) options.push({ - name: 'CONTROLS.CommonDelete', + label: 'CONTROLS.CommonDelete', icon: 'fa-solid fa-trash', - condition: element => { + visible: element => { const target = element.closest('[data-item-uuid]'); - return target.dataset.itemType !== 'beastform'; + const doc = getDocFromElementSync(target); + return doc?.isOwner && target.dataset.itemType !== 'beastform'; }, callback: async (target, event) => { const doc = await getDocFromElement(target); diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index 6ff98ca7..7f9028d5 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -31,7 +31,7 @@ export default class FeatureSheet extends DHBaseItemSheet { labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } }; -//Might be wrong location but testing out if here is okay. + //Might be wrong location but testing out if here is okay. /**@override */ async _prepareContext(options) { const context = await super._prepareContext(options); diff --git a/module/applications/sidebar/tabs/actorDirectory.mjs b/module/applications/sidebar/tabs/actorDirectory.mjs index 1306de61..89da1426 100644 --- a/module/applications/sidebar/tabs/actorDirectory.mjs +++ b/module/applications/sidebar/tabs/actorDirectory.mjs @@ -48,9 +48,9 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs. const options = super._getEntryContextOptions(); options.push( { - name: 'DAGGERHEART.UI.Sidebar.actorDirectory.duplicateToNewTier', + label: 'DAGGERHEART.UI.Sidebar.actorDirectory.duplicateToNewTier', icon: ``, - condition: li => { + visible: li => { const actor = game.actors.get(li.dataset.entryId); return actor?.type === 'adversary' && actor.system.type !== 'social'; }, @@ -92,9 +92,9 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs. } }, { - name: 'DAGGERHEART.UI.Sidebar.actorDirectory.activateParty', + label: 'DAGGERHEART.UI.Sidebar.actorDirectory.activateParty', icon: ``, - condition: li => { + visible: li => { const actor = game.actors.get(li.dataset.entryId); return actor && actor.type === 'party' && !actor.system.active; }, diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 59939963..34b25591 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -103,23 +103,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo _getEntryContextOptions() { return [ ...super._getEntryContextOptions(), - // { - // name: 'Reroll', - // icon: '', - // condition: li => { - // const message = game.messages.get(li.dataset.messageId); - - // return (game.user.isGM || message.isAuthor) && message.rolls.length > 0; - // }, - // callback: li => { - // const message = game.messages.get(li.dataset.messageId); - // new game.system.api.applications.dialogs.RerollDialog(message).render({ force: true }); - // } - // }, { - name: game.i18n.localize('DAGGERHEART.UI.ChatLog.rerollDamage'), + label: 'DAGGERHEART.UI.ChatLog.rerollDamage', icon: '', - condition: li => { + visible: li => { const message = game.messages.get(li.dataset.messageId); const hasRolledDamage = message.system.hasDamage ? Object.keys(message.system.damage).length > 0 diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index 1043e128..fb19a17e 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -84,15 +84,15 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C _getCombatContextOptions() { return [ { - name: 'COMBAT.ClearMovementHistories', + label: 'COMBAT.ClearMovementHistories', icon: '', - condition: () => game.user.isGM && this.viewed?.combatants.size > 0, + visible: () => game.user.isGM && this.viewed?.combatants.size > 0, callback: () => this.viewed.clearMovementHistories() }, { - name: 'COMBAT.Delete', + label: 'COMBAT.Delete', icon: '', - condition: () => game.user.isGM && !!this.viewed, + visible: () => game.user.isGM && !!this.viewed, callback: () => this.viewed.endCombat() } ]; diff --git a/module/canvas/placeables/regionLayer.mjs b/module/canvas/placeables/regionLayer.mjs index 44a5e630..56f3084b 100644 --- a/module/canvas/placeables/regionLayer.mjs +++ b/module/canvas/placeables/regionLayer.mjs @@ -100,7 +100,11 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { const { line, rectangle, inFront, cone } = CONFIG.DH.GENERAL.templateTypes; const usedAngle = - type === cone.id ? (angle ?? CONFIG.MeasuredTemplate.defaults.angle) : type === inFront.id ? '180' : undefined; + type === cone.id + ? (angle ?? CONFIG.MeasuredTemplate.defaults.angle) + : type === inFront.id + ? '180' + : undefined; const { grid, distance } = CONFIG.Scene.documentClass.schema.fields.grid.fields; const sceneGridSize = canvas.scene?.grid.size ?? grid.size.initial; @@ -109,7 +113,8 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { const rangeNumber = Number(range); const settings = canvas.scene?.rangeSettings; - const baseDistance = (!Number.isNaN(rangeNumber) ? rangeNumber : (settings ? settings[range] : 0)) * dimensionConstant; + const baseDistance = + (!Number.isNaN(rangeNumber) ? rangeNumber : settings ? settings[range] : 0) * dimensionConstant; const length = baseDistance; const radius = length; diff --git a/module/config/actionConfig.mjs b/module/config/actionConfig.mjs index 38e85805..a6c04e18 100644 --- a/module/config/actionConfig.mjs +++ b/module/config/actionConfig.mjs @@ -121,4 +121,4 @@ export const areaTypes = { id: 'placed', label: 'Placed Area' } -}; \ No newline at end of file +}; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index e7b2614d..6fc85ec5 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -1124,4 +1124,4 @@ export const simpleDispositions = { id: 1, label: 'TOKEN.DISPOSITION.FRIENDLY' } -}; \ No newline at end of file +}; diff --git a/module/config/itemBrowserConfig.mjs b/module/config/itemBrowserConfig.mjs index f20e56d0..5c0a219b 100644 --- a/module/config/itemBrowserConfig.mjs +++ b/module/config/itemBrowserConfig.mjs @@ -75,12 +75,17 @@ export const typeConfig = { { key: 'type', label: 'DAGGERHEART.GENERAL.type', - format: type => type ? `TYPES.Item.${type}` : '-' + format: type => (type ? `TYPES.Item.${type}` : '-') }, { key: 'system.secondary', label: 'DAGGERHEART.UI.ItemBrowser.subtype', - format: isSecondary => (isSecondary ? 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon.short' : isSecondary === false ? 'DAGGERHEART.ITEMS.Weapon.primaryWeapon.short' : '-') + format: isSecondary => + isSecondary + ? 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon.short' + : isSecondary === false + ? 'DAGGERHEART.ITEMS.Weapon.primaryWeapon.short' + : '-' }, { key: 'system.tier', @@ -260,12 +265,12 @@ export const typeConfig = { { key: 'system.type', label: 'DAGGERHEART.GENERAL.type', - format: type => type ? `DAGGERHEART.CONFIG.DomainCardTypes.${type}` : '-' + format: type => (type ? `DAGGERHEART.CONFIG.DomainCardTypes.${type}` : '-') }, { key: 'system.domain', label: 'DAGGERHEART.GENERAL.Domain.single', - format: domain => domain ? CONFIG.DH.DOMAIN.allDomains()[domain].label : '-' + format: domain => (domain ? CONFIG.DH.DOMAIN.allDomains()[domain].label : '-') }, { key: 'system.level', diff --git a/module/config/settingsConfig.mjs b/module/config/settingsConfig.mjs index 6dae29aa..50841084 100644 --- a/module/config/settingsConfig.mjs +++ b/module/config/settingsConfig.mjs @@ -42,7 +42,7 @@ export const gameSettings = { SpotlightRequestQueue: 'SpotlightRequestQueue', CompendiumBrowserSettings: 'CompendiumBrowserSettings', SpotlightTracker: 'SpotlightTracker', - ActiveParty: 'ActiveParty', + ActiveParty: 'ActiveParty' }; export const actionAutomationChoices = { diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index 5e93d70b..f54ea282 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -13,7 +13,7 @@ export default class DHAttackAction extends DHDamageAction { if (!!this.item?.system?.attack) { if (this.damage.includeBase) { const baseDamage = this.getParentDamage(); - this.damage.parts.unshift(new DHDamageData(baseDamage)); + this.damage.parts.hitPoints = new DHDamageData(baseDamage); } if (this.roll.useDefault) { this.roll.trait = this.item.system.attack.roll.trait; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 6e3f6d1c..631a1211 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -110,6 +110,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel return this._id; } + /** Returns true if the current user is the owner of the containing item */ + get isOwner() { + return this.item?.isOwner ?? true; + } + /** * Return Item the action is attached too. */ @@ -143,6 +148,12 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel : null; } + /** Returns true if the action is usable */ + get usable() { + const actor = this.actor; + return this.isOwner && actor?.type === 'character'; + } + static getRollType(parent) { return 'trait'; } diff --git a/module/data/activeEffect/baseEffect.mjs b/module/data/activeEffect/baseEffect.mjs index 46de63b0..4037ca0e 100644 --- a/module/data/activeEffect/baseEffect.mjs +++ b/module/data/activeEffect/baseEffect.mjs @@ -94,9 +94,12 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel { }, { nullable: true, initial: null } ), - targetDispositions: new fields.SetField(new fields.NumberField({ - choices: CONFIG.DH.GENERAL.simpleDispositions, - }), { label: 'Affected Dispositions' }), + targetDispositions: new fields.SetField( + new fields.NumberField({ + choices: CONFIG.DH.GENERAL.simpleDispositions + }), + { label: 'Affected Dispositions' } + ) }; } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index bf3d7bb8..1bb3560f 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -20,7 +20,7 @@ export default class DhCharacter extends DhCreature { settingSheet: DHCharacterSettings, isNPC: false, hasInventory: true, - quantifiable: ["loot", "consumable"] + quantifiable: ['loot', 'consumable'] }); } @@ -302,7 +302,7 @@ export default class DhCharacter extends DhCreature { choices: CONFIG.DH.GENERAL.dieFaces, initial: null, label: 'DAGGERHEART.ACTORS.Character.defaultDisadvantageDice' - }), + }) }) }) }; @@ -449,7 +449,7 @@ export default class DhCharacter extends DhCreature { /* All items are valid on characters */ isItemValid() { - return true; + return true; } /** @inheritDoc */ diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index a1fa1429..538031fb 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -78,7 +78,7 @@ export default class DhCompanion extends DhCreature { choices: CONFIG.DH.GENERAL.dieFaces, initial: null, label: 'DAGGERHEART.ACTORS.Character.defaultDisadvantageDice' - }), + }) }) }), attack: new ActionField({ diff --git a/module/data/actor/party.mjs b/module/data/actor/party.mjs index 6ccf8852..93596cda 100644 --- a/module/data/actor/party.mjs +++ b/module/data/actor/party.mjs @@ -9,7 +9,7 @@ export default class DhParty extends BaseDataActor { static get metadata() { return foundry.utils.mergeObject(super.metadata, { hasInventory: true, - quantifiable: ["weapon", "armor", "loot", "consumable"] + quantifiable: ['weapon', 'armor', 'loot', 'consumable'] }); } diff --git a/module/data/chat-message/abilityUse.mjs b/module/data/chat-message/abilityUse.mjs index 3c209355..f5986d0f 100644 --- a/module/data/chat-message/abilityUse.mjs +++ b/module/data/chat-message/abilityUse.mjs @@ -11,7 +11,7 @@ export default class DHAbilityUse extends foundry.abstract.TypeDataModel { actor: new fields.StringField(), item: new fields.StringField(), action: new fields.StringField() - }), + }) }; } diff --git a/module/data/fields/action/areaField.mjs b/module/data/fields/action/areaField.mjs index 28db74fe..a45af8dc 100644 --- a/module/data/fields/action/areaField.mjs +++ b/module/data/fields/action/areaField.mjs @@ -33,8 +33,8 @@ export default class AreaField extends fields.ArrayField { initial: CONFIG.DH.GENERAL.range.veryClose.id, label: 'DAGGERHEART.ACTIONS.Config.area.size' }), - effects: new fields.ArrayField(new fields.DocumentIdField()), + effects: new fields.ArrayField(new fields.DocumentIdField()) }); super(element, options, context); } -} \ No newline at end of file +} diff --git a/module/data/fields/action/summonField.mjs b/module/data/fields/action/summonField.mjs index 914a1d69..ec7881f7 100644 --- a/module/data/fields/action/summonField.mjs +++ b/module/data/fields/action/summonField.mjs @@ -40,9 +40,7 @@ export default class DHSummonField extends fields.ArrayField { const roll = new Roll(itemAbleRollParse(summon.count, this.actor, this.item)); await roll.evaluate(); const count = roll.total; - if (!roll.isDeterministic && game.modules.get('dice-so-nice')?.active) - rolls.push(roll); - + if (!roll.isDeterministic && game.modules.get('dice-so-nice')?.active) rolls.push(roll); const actor = await DHSummonField.getWorldActor(await foundry.utils.fromUuid(summon.actorUUID)); /* Extending summon data in memory so it's available in actionField.toChat. Think it's harmless, but ugly. Could maybe find a better way. */ diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index d4698d4a..7bdd75f8 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -287,7 +287,7 @@ export function ActionMixin(Base) { source: { actor: this.actor.uuid, item: this.item.id, - action: this.id, + action: this.id }, itemOrigin: this.item, description: this.description || (this.item instanceof Item ? this.item.system.description : '') diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 72718c5e..cc198dc4 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -108,6 +108,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { } get actionsList() { + // No actions on non-characters + if (this.actor && this.actor.type !== 'character') return []; return this.actions; } diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 9335037c..75e6dc8e 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -99,7 +99,9 @@ export default class DHWeapon extends AttachableItem { /* -------------------------------------------- */ get actionsList() { - return [this.attack, ...this.actions]; + // No actions on non-characters + if (this.actor && this.actor.type !== 'character') return []; + return [this.attack, ...super.actionsList]; } get customActions() { diff --git a/module/data/regionBehavior/_module.mjs b/module/data/regionBehavior/_module.mjs index 7a8893de..d0c8172d 100644 --- a/module/data/regionBehavior/_module.mjs +++ b/module/data/regionBehavior/_module.mjs @@ -1 +1 @@ -export { default as applyActiveEffect } from './applyActiveEffect.mjs'; \ No newline at end of file +export { default as applyActiveEffect } from './applyActiveEffect.mjs'; diff --git a/module/data/regionBehavior/applyActiveEffect.mjs b/module/data/regionBehavior/applyActiveEffect.mjs index 4be262c2..51406cfa 100644 --- a/module/data/regionBehavior/applyActiveEffect.mjs +++ b/module/data/regionBehavior/applyActiveEffect.mjs @@ -1,38 +1,40 @@ export default class DhApplyActiveEffect extends CONFIG.RegionBehavior.dataModels.applyActiveEffect { static async #getApplicableEffects(token) { const effects = await Promise.all(this.effects.map(foundry.utils.fromUuid)); - return effects.filter(effect => !effect.system.targetDispositions.size || effect.system.targetDispositions.has(token.disposition)); + return effects.filter( + effect => !effect.system.targetDispositions.size || effect.system.targetDispositions.has(token.disposition) + ); } static async #onTokenEnter(event) { - if ( !event.user.isSelf ) return; - const {token, movement} = event.data; + if (!event.user.isSelf) return; + const { token, movement } = event.data; const actor = token.actor; - if ( !actor ) return; + if (!actor) return; const resumeMovement = movement ? token.pauseMovement() : undefined; const effects = await DhApplyActiveEffect.#getApplicableEffects.bind(this)(event.data.token); const toCreate = []; - for ( const effect of effects ) { - const data = effect.toObject(); - delete data._id; - if ( effect.compendium ) { - data._stats.duplicateSource = null; - data._stats.compendiumSource = effect.uuid; - } else { - data._stats.duplicateSource = effect.uuid; - data._stats.compendiumSource = null; + for (const effect of effects) { + const data = effect.toObject(); + delete data._id; + if (effect.compendium) { + data._stats.duplicateSource = null; + data._stats.compendiumSource = effect.uuid; + } else { + data._stats.duplicateSource = effect.uuid; + data._stats.compendiumSource = null; + } + data._stats.exportSource = null; + data.origin = this.parent.uuid; + toCreate.push(data); } - data._stats.exportSource = null; - data.origin = this.parent.uuid; - toCreate.push(data); - } - if ( toCreate.length ) await actor.createEmbeddedDocuments("ActiveEffect", toCreate); + if (toCreate.length) await actor.createEmbeddedDocuments('ActiveEffect', toCreate); await resumeMovement?.(); } - /** @override */ - static events = { - ...CONFIG.RegionBehavior.dataModels.applyActiveEffect.events, - [CONST.REGION_EVENTS.TOKEN_ENTER]: this.#onTokenEnter, - }; -} \ No newline at end of file + /** @override */ + static events = { + ...CONFIG.RegionBehavior.dataModels.applyActiveEffect.events, + [CONST.REGION_EVENTS.TOKEN_ENTER]: this.#onTokenEnter + }; +} diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 2448a16d..5e03a680 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -11,7 +11,9 @@ export default class DualityRoll extends D20Roll { this.rallyChoices = this.setRallyChoices(); this.guaranteedCritical = options.guaranteedCritical; - const advantageFaces = data.rules?.roll?.defaultAdvantageDice ? Number.parseInt(data.rules.roll.defaultAdvantageDice) : 6 + const advantageFaces = data.rules?.roll?.defaultAdvantageDice + ? Number.parseInt(data.rules.roll.defaultAdvantageDice) + : 6; this.advantageFaces = Number.isNaN(advantageFaces) ? 6 : advantageFaces; } diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 8ec7a751..227e2613 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -200,7 +200,6 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { static effectSafeEval(expression) { let result; try { - // eslint-disable-next-line no-new-func const evl = new Function('sandbox', `with (sandbox) { return ${expression}}`); result = evl(Roll.MATH_PROXY); } catch (err) { diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 4e20db0e..db249033 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -602,7 +602,7 @@ export default class DhpActor extends Actor { rollData.system = this.system.getRollData(); rollData.prof = this.system.proficiency ?? 1; rollData.cast = this.system.spellcastModifier ?? 1; - + return rollData; } diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 4839e433..6f3080f4 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -137,7 +137,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { element.addEventListener('click', this.onApplyEffect.bind(this)) ); - html.querySelectorAll('.action-areas').forEach(element => + html.querySelectorAll('.action-areas').forEach(element => element.addEventListener('click', this.onCreateAreas.bind(this)) ); @@ -254,9 +254,9 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { } async onCreateAreas(event) { - const createArea = async (selectedArea) => { + const createArea = async selectedArea => { const effects = selectedArea.effects.map(effect => this.system.action.item.effects.get(effect).uuid); - const { shape: type, size: range } = selectedArea; + const { shape: type, size: range } = selectedArea; const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range }); await canvas.regions.placeRegion( @@ -264,13 +264,15 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { name: selectedArea.name, shapes: [shapeData], restriction: { enabled: false, type: 'move', priority: 0 }, - behaviors: [{ - name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'), - type: 'applyActiveEffect', - system: { - effects: effects + behaviors: [ + { + name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'), + type: 'applyActiveEffect', + system: { + effects: effects + } } - }], + ], displayMeasurements: true, locked: false, ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE }, @@ -278,18 +280,17 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { }, { create: true } ); - } + }; - if (this.system.action.area.length === 1) - createArea(this.system.action.area[0]); - else if(this.system.action.area.length > 1) { - /* Pop a selection. Possibly a context menu? */ + if (this.system.action.area.length === 1) createArea(this.system.action.area[0]); + else if (this.system.action.area.length > 1) { + /* Pop a selection. Possibly a context menu? */ new foundry.applications.ux.ContextMenu.implementation( event.target, '.action-areas', this.system.action.area.map((area, index) => ({ name: area.name, - callback: () => createArea(this.system.action.area[index]), + callback: () => createArea(this.system.action.area[index]) })), { jQuery: false, diff --git a/module/documents/collections/actorCollection.mjs b/module/documents/collections/actorCollection.mjs index 8df407e6..115dd694 100644 --- a/module/documents/collections/actorCollection.mjs +++ b/module/documents/collections/actorCollection.mjs @@ -3,7 +3,7 @@ export default class DhActorCollection extends foundry.documents.collections.Act get party() { const id = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.ActiveParty); const actor = game.actors.get(id); - return actor?.type === "party" ? actor : null; + return actor?.type === 'party' ? actor : null; } /** Ensure companions are initialized after all other subtypes. */ diff --git a/module/documents/item.mjs b/module/documents/item.mjs index a8b41b05..8ece56fa 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -76,6 +76,13 @@ export default class DHItem extends foundry.documents.Item { return this.system.metadata.isInventoryItem ?? false; } + /** Returns true if the item can be used */ + get usable() { + const actor = this.actor; + const actionsList = this.system.actionsList; + return this.isOwner && actor?.type === 'character' && (actionsList?.size || actionsList?.length); + } + /** @inheritdoc */ static async createDialog(data = {}, createOptions = {}, options = {}) { const { folders, types, template, context = {}, ...dialogOptions } = options; diff --git a/module/enrichers/TemplateEnricher.mjs b/module/enrichers/TemplateEnricher.mjs index 1480b8d0..8db3ec14 100644 --- a/module/enrichers/TemplateEnricher.mjs +++ b/module/enrichers/TemplateEnricher.mjs @@ -61,7 +61,7 @@ export const renderMeasuredTemplate = async event => { type, angle, range, - direction, + direction }); await canvas.regions.placeRegion( @@ -77,4 +77,4 @@ export const renderMeasuredTemplate = async event => { }, { create: true } ); -}; \ No newline at end of file +}; diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 80e8df92..7f30d970 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -16,7 +16,7 @@ export default class RegisterHandlebarsHelpers { empty: this.empty, pluralize: this.pluralize, positive: this.positive, - isNullish: this.isNullish, + isNullish: this.isNullish }); } static add(a, b) { diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index 69bd1730..41cab011 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -56,10 +56,10 @@ export const registerKeyBindings = () => { game.keybindings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.keybindings.partySheet, { name: _loc('DAGGERHEART.SETTINGS.Keybindings.partySheet.name'), hint: _loc('DAGGERHEART.SETTINGS.Keybindings.partySheet.hint'), - editable: [{ key: "KeyP" }], + editable: [{ key: 'KeyP' }], onDown: () => { const controlled = canvas.ready ? canvas.tokens.controlled : []; - const selectedParty = controlled.find((c) => c.actor?.type === 'party')?.actor; + const selectedParty = controlled.find(c => c.actor?.type === 'party')?.actor; const party = selectedParty ?? game.actors.party; if (!party) return; @@ -215,6 +215,6 @@ const registerNonConfigSettings = () => { scope: 'world', config: false, type: String, - default: null, + default: null }); }; diff --git a/package-lock.json b/package-lock.json index 864d027c..b8fef1cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,9 @@ "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "concurrently": "^8.2.2", + "eslint": "^10.2.1", + "eslint-plugin-prettier": "^5.5.5", + "globals": "^17.5.0", "husky": "^9.1.5", "lint-staged": "^15.2.10", "postcss": "^8.4.32", @@ -32,6 +35,152 @@ "node": ">=6.9.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", + "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, "node_modules/@foundryvtt/foundryvtt-cli": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-1.1.0.tgz", @@ -72,12 +221,91 @@ "node": ">=10.13.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "25.0.8", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz", @@ -415,11 +643,25 @@ "node": ">=10.13.0" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -458,6 +700,46 @@ "node": ">=12" } }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -1417,6 +1699,13 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -1622,6 +1911,190 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.1.tgz", + "integrity": "sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz", + "integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.1", + "synckit": "^0.11.12" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", @@ -1631,12 +2104,76 @@ "node": ">=6" } }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -1694,11 +2231,32 @@ "node": ">=0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-levenshtein": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", @@ -1723,6 +2281,19 @@ "reusify": "^1.0.4" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1734,6 +2305,23 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/findup-sync": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", @@ -1771,6 +2359,27 @@ "node": ">= 10.13.0" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -2033,6 +2642,19 @@ "which": "bin/which" } }, + "node_modules/globals": { + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", + "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glogg": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", @@ -2381,6 +3003,16 @@ } ] }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -2423,6 +3055,16 @@ "node": ">=8" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2769,6 +3411,37 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/last-run": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", @@ -2832,6 +3505,20 @@ "node": ">=12" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -2932,6 +3619,22 @@ "lie": "3.1.1" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -3202,6 +3905,13 @@ "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==", "dev": true }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/nedb-promises": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.2.3.tgz", @@ -3370,6 +4080,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/optionator/node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -3379,6 +4114,38 @@ "node": ">=4" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", @@ -3442,6 +4209,16 @@ "node": ">=0.10.0" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4140,6 +4917,16 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/prettier": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", @@ -4155,6 +4942,19 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/promise.series": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz", @@ -4181,6 +4981,16 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4950,6 +5760,22 @@ "node": ">= 10" } }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", @@ -5010,6 +5836,19 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -5070,6 +5909,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -5222,6 +6071,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", @@ -5313,6 +6172,19 @@ "engines": { "node": ">=12" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 183d2de2..28c83549 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,18 @@ "pullYMLtoLDB": "node ./tools/pullYMLtoLDB.mjs", "pullYMLtoLDBBuild": "node ./tools/pullYMLtoLDB.mjs --build", "createSymlink": "node ./tools/create-symlink.mjs", - "setup:dev": "node ./tools/dev-setup.mjs" + "setup:dev": "node ./tools/dev-setup.mjs", + "lint": "eslint", + "lint:fix": "eslint --fix" }, "devDependencies": { "@foundryvtt/foundryvtt-cli": "^1.0.2", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "concurrently": "^8.2.2", + "eslint": "^10.2.1", + "eslint-plugin-prettier": "^5.5.5", + "globals": "^17.5.0", "husky": "^9.1.5", "lint-staged": "^15.2.10", "postcss": "^8.4.32", diff --git a/styles/less/sheets/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less index ee6580fd..68792c99 100644 --- a/styles/less/sheets/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -11,21 +11,6 @@ padding-bottom: 0; overflow-x: auto; - &.viewMode { - button:not(.btn-toggle-view), - input:not(.search), - .controls, - .character-sidebar-sheet, - .img-portait, - .name-row, - .hope-section, - .downtime-section, - .character-traits, - .card-list { - pointer-events: none; - } - } - .character-sidebar-sheet { grid-row: 1 / span 2; grid-column: 1; diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index e7027163..b159a8e8 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -316,9 +316,9 @@ border-radius: 3px; background: light-dark(@dark-blue, @golden); clip-path: none; - cursor: pointer; display: flex; align-items: center; + justify-content: center; gap: 4px; border: 1px solid transparent; transition: all 0.3s ease; diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 192c5be5..454d0413 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -21,7 +21,7 @@ {{!-- Handlebars uses Symbol.Iterator to produce index|key. This isn't compatible with our parts object, so we instead use applyTo, which is the same value --}} - {{#each source.parts as |dmg|}} + {{#each source.parts as |dmg key|}}