From cbd4f13bf8c54cce78995f75637f3d93523dd26c Mon Sep 17 00:00:00 2001
From: Jan Weigmann
Date: Mon, 21 Oct 2024 09:50:46 +0200
Subject: [PATCH] 6.1.4
---
README.md | 3 ++-
bundle/modules/dsa5.js | 26 +++++++++++++-------------
modules/actor/actor-dsa5.js | 33 ++++++++++++++++++++++-----------
modules/system/opposed-dsa5.js | 8 ++++++--
system.json | 4 ++--
5 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
index 3ef82505..35eaa0d7 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
+![Version](https://img.shields.io/github/v/tag/Plushtoast/dsa5-foundryVTT?label=Version&style=flat-square&color=2577a1) ![Foundry Core Compatible Version](https://img.shields.io/badge/dynamic/json.svg?url=https%3A%2F%2Fraw.githubusercontent.com%2FPlushtoast%2Fdsa5-foundryVTT%2Ffoundry12%2Fsystem.json&label=Foundry%20Core%20Compatible%20Version&query=$.compatibility.verified&style=flat-square&color=ff6400)
+
# Official Das Schwarze Auge/The Dark Eye system for Foundry
![](https://repository-images.githubusercontent.com/311655339/4d523800-55a9-11eb-9e2e-6bbc2b71d8a4)
## Current Version and Compatibility:
-6.0.x - FoundryVTT 12.+
This system is intended for usage with [Foundry Virtual Tabletop](https://foundryvtt.com/) to play "Das Schwarze Auge" 5th edition.
If you want to learn more checkout the [German](https://ulisses-spiele.de/virtual-tabletop-dsa-vtt/) or [English](https://ulisses-us.com/ulisses-virtual-tabletops/virtual-tabletop-dsa-vtt/) VTT Page by Ulisses Spiele.
diff --git a/bundle/modules/dsa5.js b/bundle/modules/dsa5.js
index fc6ef19d..98848b6c 100644
--- a/bundle/modules/dsa5.js
+++ b/bundle/modules/dsa5.js
@@ -24,13 +24,13 @@ var tr=Object.defineProperty;var u=(o,e)=>tr(o,"name",{value:e,configurable:!0})
- `;e.find(".dpsSelector").remove(),e.find('.tab[data-tab="grid"]').append(s)});var{mergeObject:tc}=foundry.utils,ia=class o extends Dialog{static{u(this,"AddTargetDialog")}static async getDialog(e){let t=Array.from(game.user.targets).map(i=>i.id),a=[],s=canvas.scene?canvas.scene.tokens.get(e.token)?.object:void 0;return game.combat&&game.combat.combatants.forEach(i=>{if(i.visible){if(i.isSelected=t.includes(i.token.id),s&&i.token){let n=canvas.scene.tokens.get(i.token.id).object;i.distance=ne.rangeFinder(s,n),i.distance.distanceSum=Number(i.distance.distanceSum.toFixed(1))}a.push(i)}}),new o({title:game.i18n.localize("DIALOG.addTarget"),content:await renderTemplate("systems/dsa5/templates/dialog/addTarget-dialog.html",{selectables:a}),buttons:{}})}activateListeners(e){super.activateListeners(e);let t=e.find(".combatant");t.dblclick(a=>this.setTargets(a,!0)),t.click(a=>this.setTargets(a)),t.hover(this._onCombatantHoverIn.bind(this),this._onCombatantHoverOut.bind(this)),t.mousedown(a=>this._onRightClick(a))}_onCombatantHoverOut(e){this._getCombatApp()._onCombatantHoverOut(e)}_onCombatantHoverIn(e){this._getCombatApp()._onCombatantHoverIn(e)}_onRightClick(e){if(e.button==2){let t=game.combat.combatants.get(e.currentTarget.dataset.combatantId);if(t.token)return canvas.animatePan({x:t.token.x,y:t.token.y})}}_getCombatApp(){return game.combats.apps[0]}async setTargets(e,t=!1){let a=e.originalEvent.shiftKey;a||$(e.currentTarget).closest(".directory").find(".combatant").removeClass("selectedTarget"),$(e.currentTarget).addClass("selectedTarget");let s=e.currentTarget.dataset.combatantId;game.combat.combatants.get(s).token.object.setTarget(!0,{user:game.user,releaseOthers:!a,groupSelection:!0}),t&&this.close()}},pt=class o extends foundry.applications.api.HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2){static{u(this,"SelectUserDialog")}static DEFAULT_OPTIONS={window:{title:"DIALOG.setTargetToUser"}};static PARTS={main:{template:"systems/dsa5/templates/dialog/selectForUserDialog.html"}};static async getDialog(){return new o}async _prepareContext(e){let t=await super._prepareContext(e);return t.users=game.users.filter(a=>a.active&&!a.isGM),t}static registerButtons(){Hooks.on("getSceneControlButtons",e=>{if(!game.user.isGM)return;let t={name:"targetUser",title:"CONTROLS.targetForUser",icon:"fa fa-bullseye",button:!0,onClick:u(async()=>{(await o.getDialog()).render(!0)},"onClick")};e[0].tools.splice(2,0,t)})}_onRender(e,t){super._onRender(t),$(this.element).find(".combatant").on("click",s=>this.setTargetToUser(s))}setTargetToUser(e){let t=Array.from(game.user.targets).map(i=>i.id),a=e.currentTarget.dataset.userId;game.users.get(a).updateTokenTargets(t),game.socket.emit("userActivity",a,{targets:t}),this.close()}},ft=class o extends foundry.applications.api.DialogV2{static{u(this,"UserMultipickDialog")}static async getDialog(e){let t=game.users.filter(a=>a.active&&!a.isGM);new o({window:{title:"SHEET.PostItem"},content:await renderTemplate("systems/dsa5/templates/dialog/usermultipickdialog.html",{users:t}),buttons:[{action:"done",icon:"fa fa-check",label:"yes",default:!0,callback:u((a,s,i)=>{this.postContent(s.form.elements,e)},"callback")},{action:"cancel",icon:"fas fa-times",label:"cancel"}]}).render(!0)}static async postContent(e,t){let a=g.chatDataSetup(t);if(!e.sel_all.checked){let s=[];for(let i of Object.keys(e))e[i].checked&&i!="sel_all"&&s.push(e[i].value);a.whisper=s}ChatMessage.create(a)}_onRender(e,t){super._onRender(t);let a=$(this.element);a.find('[name="sel_all"]').on("change",s=>{a.find(".usersel").prop("disabled",s.currentTarget.checked).prop("checked",s.currentTarget.checked)})}};var de=class o extends Dialog{static{u(this,"DialogShared")}static roman=[""," I"," II"," III"," IV"," V"," VI"," VII"," VIII"," IX"," X"];recallSettings(e,t,a,s){return this.recallData=game.dsa5.memory.recall(e,t,a),this.dialogData={mode:a,speaker:e,source:t,renderData:s},this}async _render(e,t){await super._render(e,t),await this.prepareFormRecall($(this._element))}setRollButtonWarning(){return this.dialogData.mode=="attack"?` ${game.i18n.localize("DIALOG.noTarget")}`:""}setMultipleTargetsWarning(){return this.dialogData.mode=="attack"?` ${game.i18n.localize("DIALOG.multipleTarget")}`:""}renderRollValueDie(e=1){if(this.dialogData.rollValue&&this.dialogData.mode!="damage"){let t=this.dialogData.mode=="attack"||this.dialogData.counterAttack?"die-mu":"die-in",a=this.dialogData.modifier||0;return`${Math.clamp(Math.round((this.dialogData.rollValue+a)*e),1,20)}`}else return""}async updateRollButton(e,t=1){let a=this.renderRollValueDie(t)+game.i18n.localize("Roll");e.length>0?e.length>1&&(a+=this.setMultipleTargetsWarning()):a+=this.setRollButtonWarning(),$(this._element).find(".dialog-buttons .rollButton").html(a)}async updateTargets(e,t){let a=await renderTemplate("systems/dsa5/templates/dialog/parts/targets.html",{targets:t});e.find(".targets").html(a),this.updateRollButton(t)}removeTarget(e){let t=e.currentTarget.dataset.id;$(e.currentTarget).remove();let a=[];game.user.targets.forEach(s=>{t!=s.id&&a.push(s.id)}),game.user.updateTokenTargets(a)}calculateProbability(e,t,a,s){if(g.moduleEnabled("dsa5-core")){let i=game.settings.get("dsa5-core","showProbability");if(i==1||i==2&&game.user.isGM){let n=[];for(let r=0;r<6;r++){let l=1+r,c=game.dsa5.apps.DSACharacterCalculator.rollSuccessCalculation(e,t,a,l,s);if(c>1)c=`${c}`.padStart(2,"0"),n.push(`${game.i18n.localize("CHARAbbrev.QS")} ${l}: ${c}%`);else break}$(this.element).find(".nonOpposedButton,.rollButton").attr("data-tooltip",n.join(" "))}}}readTargets(){let e=[];return game.user.targets.forEach(t=>{t.actor&&e.push({name:t.actor.name,img:t.actor.img,id:t.id})}),e}compareTargets(e,t){let a=this.readTargets();return JSON.stringify(t)!=JSON.stringify(a)&&(t=a,this.updateTargets(e,t)),t}activateListeners(e){super.activateListeners(e),e.find(".quantity-click").mousedown(t=>N.quantityClick(t)),e.find(".modifiers option").mousedown(t=>(t.preventDefault(),$(t.currentTarget).prop("selected",!$(t.currentTarget).prop("selected")),!1)),e.on("click",".rollTarget",t=>this.removeTarget(t)),e.on("click",".addTarget",t=>this.addTarget(t))}async addTarget(e){(await ia.getDialog(this.dialogData.speaker)).render(!0)}async prepareFormRecall(e){if(this.recallData)for(let t in this.recallData)if(t=="specAbs")for(let a of this.recallData[t]){let s=e.find(`.specAbs[data-id="${a.id}"]`);s.addClass("active").attr("data-step",a.step),s.find(".step").text(o.roman[a.step])}else{let a=e.find(`[name="${t}"]`);if(Array.isArray(this.recallData[t])){let s=a.find("option");for(let i of s){let n=this.recallData[t].find(r=>r.name==$(i).text().trim());n&&(i.selected=n.selected)}}else a.attr("type")=="checkbox"?a[0].checked=this.recallData[t]:a.val(this.recallData[t])}}};var{mergeObject:kn,duplicate:ps}=foundry.utils,Se=class o extends de{static{u(this,"DSA5SpellDialog")}static rollChanges=["defenseMalus"];static rollModifiers={forceSpell:{mod:1},reduceCostSpell:{mod:-1},increaseRangeSpell:{mod:-1},increaseCastingTime:{mod:1},decreaseCastingTime:{mod:-1},removeGesture:{mod:-2},removeFormula:{mod:-2},extensionModifier:{mod:0}};static get defaultOptions(){let e=super.defaultOptions;return kn(e,{width:700,resizable:!0}),e}static bigTimes=[5,30,120,480,960,1920];async prepareFormRecall(e){await super.prepareFormRecall(e),e.find(".spellModifier").trigger("change")}static getRollButtons(e,t,a,s){let i=ae.getRollButtons(e,t,a,s);if(["spell","liturgy"].includes(e.source.type)){let n=Number(e.source.system.castingTime.value),r=e.source.system.castingTime.progress,l=e.source.system.castingTime.modified;if(n&&e.extra.speaker.token!="emptyActor"){let c=l>0?` (${r}/${l})`:"";kn(i,{reloadButton:{label:`${game.i18n.localize("SPELL.reload")}${c}`,callback:u(async m=>{let d=await g.getSpeaker(e.extra.speaker),p={_id:e.source._id,"system.castingTime.progress":r+1};l==0&&(l=Number(m.find(".castingTime").text())-1,p["system.castingTime.modified"]=l),await d.updateEmbeddedDocuments("Item",[p]);let f=game.i18n.format("SPELL.isReloading",{actor:d.token?.name||d.prototypeToken.name,item:e.source.name,status:`${r+1}/${l}`});await ChatMessage.create(g.chatDataSetup(f))},"callback")}})}}return i}async applyTransformations(e,t){let a=t.find('[name="situationalModifiers"]');a.find('option[data-extension="1"]').remove();let s=[],i=Object.keys(o.rollModifiers).map(r=>`${r}.mod`);this.dialogData.renderData.rollModifiersPrepared=ps(this.dialogData.renderData.rollModifiers);for(let r of t.find(".specAbs.active")){let l=await fromUuid(r.dataset.uuid);if(l)for(let c of l.effects)for(let m of c.changes)if(o.rollChanges.includes(m.key)){let d=l.name.split(" - "),p=game.i18n.localize(`MODS.${m.key}`);d=`${d[1]||d[0]}`;let f=`${p}: ${m.value} ${game.i18n.localize("spellextension")}: ${d}`;s.push(``)}else m.key=="macro.transform"?await g.callItemTransformationMacro(m.value,e,c):i.includes(m.key)?c.apply(this.dialogData.renderData.rollModifiersPrepared,m):c.apply(e,m)}let n=this.dialogData.renderData.rollModifiersPrepared.extensionModifier.mod;if(n){let r=game.i18n.localize("ABBR.modifiers"),l=game.i18n.localize("spellextension"),c=`${r}: ${n} ${l}`;s.push(``)}a.append(s.join(""))}static setData(e,t,a){let s=ps(o.rollModifiers),i=`${t}RollModifiers`;if(e.system[i])for(let n of Object.keys(e.system[i]))s[n].mod+=Number(e.system[i][n]?.mod??0);return s}async recalcSpellModifiers(e,t){let a=e,s=ps(this.dialogData.source);N.ensureNumber(s);let i=a.find(".castingTime"),n=a.find(".aspcost"),r=a.find(".reach"),l=a.find(".maintainCost"),c=a.find(".ritual").length>0;await this.applyTransformations(s,a);let m=a.find(".maxMods");if(a.find(".spellModifier:checked").length>Number(m.text())){t&&(t.currentTarget.checked=!1),m.addClass("emphasize"),setTimeout(function(){m.removeClass("emphasize")},600);return}for(let I of Object.keys(this.dialogData.renderData.rollModifiersPrepared)){let A=this.dialogData.renderData.rollModifiersPrepared[I].mod;e.find(`.${I}Label`).text(`(${A})`),e.find(`#${I}`).val(A)}let d=e.find(".canChangeCastingTime");s.system.canChangeCastingTime.value=="true"?d.is(":empty")&&(d.html(await renderTemplate("systems/dsa5/templates/dialog/parts/canChangeCastingTime.html",{rollModifiers:this.dialogData.renderData.rollModifiers})),this.setPosition({height:"auto"})):d.is(":empty")||(d.html(""),this.setPosition({height:"auto"}));let p=s.system.AsPCost.value,f=s.system.range.value,h=s.system.castingTime.value,y=p,k=s.system.maintainCost.value;a.find(".variableBaseCost")[s.system.variableBaseCost=="true"?"show":"hide"]();let D=0;a.find(".spellModifier[data-cost]:checked").each(function(I,A){if(y=y*(A.value<0?.5:2),k!=""&&k!=null){let j=String(k).split(" ");j[0]=Math.max(Number(j[0])*(A.value<0?.5:2)),k=j.join(" ")}D+=Number(A.value)}),y<1?t&&(t.currentTarget.checked=!1):(n.text(y),l.text(k),n.attr("data-mod",D)),D=0,y=h,a.find(".spellModifier[data-castingTime]:checked").each(function(I,A){if(c){let j=o.bigTimes.indexOf(Number(y));if(j!=null){let S=j+(A.value>0?1:-1);S=0?y=o.bigTimes[S]:ui.notifications.error("DSAError.CastingTimeLimit",{localize:!0})}else ui.notifications.error("DSAError.TimeCannotBeParsed",{localize:!0})}else y=y*(A.value>0?2:.5);D+=Number(A.value)}),y<1?t&&(t.currentTarget.checked=!1):(i.text(y),i.attr("data-mod",D)),D=0;let v=game.i18n.localize("ReverseSpellRanges."+f);r.text(f),a.find(".spellModifier[data-reach]:checked").each(function(I,A){if(v=="self")A.checked=!1;else if(v=="touch")r.text("4 "+game.i18n.localize("step")),D+=Number(A.value);else{let j=f.split(" ");v=Number(j[0]),isNaN(v)?(t&&(t.currentTarget.checked=!1),ui.notifications.error("DSAError.RangeCannotBeParsed",{localize:!0})):(r.text(v*2+" "+game.i18n.localize("step")),D+=Number(A.value))}}),r.attr("data-mod",D),e.find(".reloadButton").prop("disabled",Number(e.find(".castingTime").text())<2),this.calculateProbability()}async calculateProbability(){let e=g.getSpeaker(this.dialogData.speaker),t=new FormDataExtended(this.element.find("form")[0]).object;t.situationalModifiers=O._parseModifiers(this._element);let a=this.dialogData.source.system.talentValue.value+t.fw+await R._situationalModifiers(t,"FW"),s=await R._situationalModifiers(t)+$(this.element).find("input.spellModifier:checked").map((i,n)=>Number(n.value)).get().reduce((i,n)=>i+n,0)+$(this.element).find("[name=maintainedSpells]")[0].value*-1;super.calculateProbability(e,this.dialogData.source,s,a)}activateListeners(e){super.activateListeners(e),e.find(".reloadButton").prop("disabled",Number(e.find(".castingTime").text())<2),e.find(".specAbs").mousedown(s=>{$(s.currentTarget).toggleClass("active"),this.recalcSpellModifiers(e)}),e.find(".variableBaseCost").change(s=>{let i=$(s.currentTarget).parents(".skill-test"),n=i.find(".aspcost").attr("data-base"),r=$(s.currentTarget).val();i.find(".aspcost").attr("data-base",r),i.find(".aspcost").text(Number(i.find(".aspcost").text())*r/n)}),e.on("change",".spellModifier",s=>this.recalcSpellModifiers(e,s)),e.on("change","input,select",()=>this.calculateProbability()),e.on("mousedown",".quantity-click",()=>this.calculateProbability());let t=this.readTargets();t.length==0&&this.setRollButtonWarning();let a=this;this.checkTargets=setInterval(function(){t=a.compareTargets(e,t)},500)}};var{getProperty:yr,hasProperty:br}=foundry.utils,K=class o{static{u(this,"DSA5SoundEffect")}static sounds;static triedInit=!1;static prepareSoundEffects(){o.soundPaths={money:[],armor:[],meleeweapon:[],rangeweapon:[],default:[]},game.modules.get("gAudioBundle-3")&&(o.soundPaths.money.push("modules/gAudioBundle-3/src/Mint Coins And Money/Coin_Slide_Carpet.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_Drop_Carpet_06.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_Bottlecaps_Drop.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_In_Sack_Held_By_Drawstring_06.ogg","modules/gAudioBundle-3/src/Money/Money_Coins_Handle.ogg"),o.soundPaths.meleeweapon.push("modules/gAudioBundle-3/src/Medieval Armor And Impacts/Weapon_Impact_Parry_01.ogg")),game.modules.get("gAudioBundle-2")&&(o.soundPaths.meleeweapon.push("modules/gAudioBundle-2/src/Gore/Melee_Sword_Attack_04.ogg"),o.soundPaths.armor.push("modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Foley_Soldier_Gear_Equipment_Metal_Cloth_Heavy_Movement_Light_08.ogg"),o.soundPaths.default.push("modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Foley_Sports_Bag_Grab_Pickup_Catch_04.ogg","modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Footstep_Ice_Crunchy_Run_01.ogg","modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Footstep_Ice_Crunchy_Run_02.ogg")),game.modules.get("gAudioBundle-4")&&o.soundPaths.rangeweapon.push("modules/gAudioBundle-4/src/Super Heroes Sound Design/Hawk's_Arrow_Flies_Bow_And_Arrow_Shoot_2.ogg"),Hooks.call("setDefaultDSASounds",o.soundPaths)}static async playEffect(e,t,a,s=void 0,i=!1){let n=await this.getSound(e,t,a);if(n)try{s?(game.socket.emit("system.dsa5",{type:"playWhisperSound",payload:{whisper:s,soundPath:n}}),i||foundry.audio.AudioHelper.play({src:n,volume:.8,loop:!1},!1)):foundry.audio.AudioHelper.play({src:n,volume:.8,loop:!1},!0)}catch{console.warn(`Could not play item sound effect ${n}`)}}static async loadSoundConfig(){let e=game.settings.get("dsa5","soundConfig");if(e)try{let a=await(await fetch(e)).json();this.sounds=a,console.log("DSA5 | Sound Config Loaded")}catch(t){console.warn(t)}}static successLevelToString(e){switch(e){case-1:return["fail"];case-2:return["botch","fail"];case 1:return["success"];case 2:return["crit","success"];default:return[]}}static async getSound(e,t,a){if(!this.sounds&&!this.triedInit&&(await this.loadSoundConfig(),this.triedInit=!0),!this.sounds)return;let s=this.successLevelToString(a),i=[],n;switch(t.type){case"meleeweapon":case"rangeweapon":i=[...s.map(r=>`${t.type}.manual.${t.name}.${e}_${r}`),`${t.type}.manual.${t.name}.${e}`,`${t.type}.manual.${t.name}.default.${e}`,`${t.type}.manual.${t.name}.default`,...s.map(r=>`${t.type}.${t.system.combatskill.value}.${e}_${r}`),`${t.type}.${t.system.combatskill.value}.${e}`,...s.map(r=>`${t.type}.${t.system.combatskill.value}.default_${r}`),`${t.type}.${t.system.combatskill.value}.default`];break;case"skill":i=[...s.map(r=>`${t.type}.${t.name}.${e}_${r}`),`${t.type}.${t.name}.${e}`,...s.map(r=>`${t.type}.${t.name}.default_${r}`),`${t.type}.${t.name}.default`];break;case"liturgy":case"spell":case"ceremony":case"ritual":i=[...s.map(r=>`${t.type}.${t.name}.${e}_${r}`),`${t.type}.${t.name}.${e}`,...s.map(r=>`${t.type}.${t.name}.default_${r}`),`${t.type}.${t.name}.default`];break}i.push(...s.map(r=>`${t.type}.default_${r}`),`${t.type}.default`);for(let r of i)if(br(this.sounds,r)&&(n=yr(this.sounds,r),n&&(typeof n=="string"||n instanceof String)))break;return n}static async playMoneySound(e=!1){let t=o.soundPaths.money,a=t[Math.floor(Math.random()*t.length)];await this.playSoundPath(a,e)}static async playEquipmentWearStatusChange(e,t=!1){let a=o.soundPaths[e.type]||o.soundPaths.default;if(a.length>0){let s=a[Math.floor(Math.random()*a.length)];await this.playSoundPath(s,t,.5)}}static async playSoundPath(e,t=!1,a=.8){if(game.settings.get("dsa5","inventorySound"))try{foundry.audio.AudioHelper.play({src:e,volume:a,loop:!1},t)}catch{console.warn(`Could not play item sound effect ${e}`)}}};var{duplicate:wn}=foundry.utils,J=class o{static{u(this,"OnUseEffect")}constructor(e){this.item=e}async callMacro(e,t,a={}){let i=await game.packs.get(e)?.getDocuments({name:t});if(!i||!i.length){for(let r of game.packs.filter(l=>l.documentName=="Macro"&&/\(internal\)/.test(l.metadata.label)))if(i=await r.getDocuments({name:t}),i.length)break}let n={};if(i.length){let r=Object.getPrototypeOf(async function(){}).constructor;try{a.result=n;let l=new r("args","actor","item",i[0].command);n.ret=await l.call(this,a,this.item.actor,this.item)}catch{try{let c=new r("args","actor","item",`
+ `;e.find(".dpsSelector").remove(),e.find('.tab[data-tab="grid"]').append(s)});var{mergeObject:tc}=foundry.utils,ia=class o extends Dialog{static{u(this,"AddTargetDialog")}static async getDialog(e){let t=Array.from(game.user.targets).map(i=>i.id),a=[],s=canvas.scene?canvas.scene.tokens.get(e.token)?.object:void 0;return game.combat&&game.combat.combatants.forEach(i=>{if(i.visible){if(i.isSelected=t.includes(i.token.id),s&&i.token){let n=canvas.scene.tokens.get(i.token.id).object;i.distance=ne.rangeFinder(s,n),i.distance.distanceSum=Number(i.distance.distanceSum.toFixed(1))}a.push(i)}}),new o({title:game.i18n.localize("DIALOG.addTarget"),content:await renderTemplate("systems/dsa5/templates/dialog/addTarget-dialog.html",{selectables:a}),buttons:{}})}activateListeners(e){super.activateListeners(e);let t=e.find(".combatant");t.dblclick(a=>this.setTargets(a,!0)),t.click(a=>this.setTargets(a)),t.hover(this._onCombatantHoverIn.bind(this),this._onCombatantHoverOut.bind(this)),t.mousedown(a=>this._onRightClick(a))}_onCombatantHoverOut(e){this._getCombatApp()._onCombatantHoverOut(e)}_onCombatantHoverIn(e){this._getCombatApp()._onCombatantHoverIn(e)}_onRightClick(e){if(e.button==2){let t=game.combat.combatants.get(e.currentTarget.dataset.combatantId);if(t.token)return canvas.animatePan({x:t.token.x,y:t.token.y})}}_getCombatApp(){return game.combats.apps[0]}async setTargets(e,t=!1){let a=e.originalEvent.shiftKey;a||$(e.currentTarget).closest(".directory").find(".combatant").removeClass("selectedTarget"),$(e.currentTarget).addClass("selectedTarget");let s=e.currentTarget.dataset.combatantId;game.combat.combatants.get(s).token.object.setTarget(!0,{user:game.user,releaseOthers:!a,groupSelection:!0}),t&&this.close()}},pt=class o extends foundry.applications.api.HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2){static{u(this,"SelectUserDialog")}static DEFAULT_OPTIONS={window:{title:"DIALOG.setTargetToUser"}};static PARTS={main:{template:"systems/dsa5/templates/dialog/selectForUserDialog.html"}};static async getDialog(){return new o}async _prepareContext(e){let t=await super._prepareContext(e);return t.users=game.users.filter(a=>a.active&&!a.isGM),t}static registerButtons(){Hooks.on("getSceneControlButtons",e=>{if(!game.user.isGM)return;let t={name:"targetUser",title:"CONTROLS.targetForUser",icon:"fa fa-bullseye",button:!0,onClick:u(async()=>{(await o.getDialog()).render(!0)},"onClick")};e[0].tools.splice(2,0,t)})}_onRender(e,t){super._onRender(t),$(this.element).find(".combatant").on("click",s=>this.setTargetToUser(s))}setTargetToUser(e){let t=Array.from(game.user.targets).map(i=>i.id),a=e.currentTarget.dataset.userId;game.users.get(a).updateTokenTargets(t),game.socket.emit("userActivity",a,{targets:t}),this.close()}},ft=class o extends foundry.applications.api.DialogV2{static{u(this,"UserMultipickDialog")}static async getDialog(e){let t=game.users.filter(a=>a.active&&!a.isGM);new o({window:{title:"SHEET.PostItem"},content:await renderTemplate("systems/dsa5/templates/dialog/usermultipickdialog.html",{users:t}),buttons:[{action:"done",icon:"fa fa-check",label:"yes",default:!0,callback:u((a,s,i)=>{this.postContent(s.form.elements,e)},"callback")},{action:"cancel",icon:"fas fa-times",label:"cancel"}]}).render(!0)}static async postContent(e,t){let a=g.chatDataSetup(t);if(!e.sel_all.checked){let s=[];for(let i of Object.keys(e))e[i].checked&&i!="sel_all"&&s.push(e[i].value);a.whisper=s}ChatMessage.create(a)}_onRender(e,t){super._onRender(t);let a=$(this.element);a.find('[name="sel_all"]').on("change",s=>{a.find(".usersel").prop("disabled",s.currentTarget.checked).prop("checked",s.currentTarget.checked)})}};var de=class o extends Dialog{static{u(this,"DialogShared")}static roman=[""," I"," II"," III"," IV"," V"," VI"," VII"," VIII"," IX"," X"];recallSettings(e,t,a,s){return this.recallData=game.dsa5.memory.recall(e,t,a),this.dialogData={mode:a,speaker:e,source:t,renderData:s},this}async _render(e,t){await super._render(e,t),await this.prepareFormRecall($(this._element))}setRollButtonWarning(){return this.dialogData.mode=="attack"?` ${game.i18n.localize("DIALOG.noTarget")}`:""}setMultipleTargetsWarning(){return this.dialogData.mode=="attack"?` ${game.i18n.localize("DIALOG.multipleTarget")}`:""}renderRollValueDie(e=1){if(this.dialogData.rollValue&&this.dialogData.mode!="damage"){let t=this.dialogData.mode=="attack"||this.dialogData.counterAttack?"die-mu":"die-in",a=this.dialogData.modifier||0;return`${Math.clamp(Math.round((this.dialogData.rollValue+a)*e),1,20)}`}else return""}async updateRollButton(e,t=1){let a=this.renderRollValueDie(t)+game.i18n.localize("Roll");e.length>0?e.length>1&&(a+=this.setMultipleTargetsWarning()):a+=this.setRollButtonWarning(),$(this._element).find(".dialog-buttons .rollButton").html(a)}async updateTargets(e,t){let a=await renderTemplate("systems/dsa5/templates/dialog/parts/targets.html",{targets:t});e.find(".targets").html(a),this.updateRollButton(t)}removeTarget(e){let t=e.currentTarget.dataset.id;$(e.currentTarget).remove();let a=[];game.user.targets.forEach(s=>{t!=s.id&&a.push(s.id)}),game.user.updateTokenTargets(a)}calculateProbability(e,t,a,s){if(g.moduleEnabled("dsa5-core")){let i=game.settings.get("dsa5-core","showProbability");if(i==1||i==2&&game.user.isGM){let n=[];for(let r=0;r<6;r++){let l=1+r,c=game.dsa5.apps.DSACharacterCalculator.rollSuccessCalculation(e,t,a,l,s);if(c>1)c=`${c}`.padStart(2,"0"),n.push(`${game.i18n.localize("CHARAbbrev.QS")} ${l}: ${c}%`);else break}$(this.element).find(".nonOpposedButton,.rollButton").attr("data-tooltip",n.join(" "))}}}readTargets(){let e=[];return game.user.targets.forEach(t=>{t.actor&&e.push({name:t.actor.name,img:t.actor.img,id:t.id})}),e}compareTargets(e,t){let a=this.readTargets();return JSON.stringify(t)!=JSON.stringify(a)&&(t=a,this.updateTargets(e,t)),t}activateListeners(e){super.activateListeners(e),e.find(".quantity-click").mousedown(t=>N.quantityClick(t)),e.find(".modifiers option").mousedown(t=>(t.preventDefault(),$(t.currentTarget).prop("selected",!$(t.currentTarget).prop("selected")),!1)),e.on("click",".rollTarget",t=>this.removeTarget(t)),e.on("click",".addTarget",t=>this.addTarget(t))}async addTarget(e){(await ia.getDialog(this.dialogData.speaker)).render(!0)}async prepareFormRecall(e){if(this.recallData)for(let t in this.recallData)if(t=="specAbs")for(let a of this.recallData[t]){let s=e.find(`.specAbs[data-id="${a.id}"]`);s.addClass("active").attr("data-step",a.step),s.find(".step").text(o.roman[a.step])}else{let a=e.find(`[name="${t}"]`);if(Array.isArray(this.recallData[t])){let s=a.find("option");for(let i of s){let n=this.recallData[t].find(r=>r.name==$(i).text().trim());n&&(i.selected=n.selected)}}else a.attr("type")=="checkbox"?a[0].checked=this.recallData[t]:a.val(this.recallData[t])}}};var{mergeObject:kn,duplicate:ps}=foundry.utils,Se=class o extends de{static{u(this,"DSA5SpellDialog")}static rollChanges=["defenseMalus"];static rollModifiers={forceSpell:{mod:1},reduceCostSpell:{mod:-1},increaseRangeSpell:{mod:-1},increaseCastingTime:{mod:1},decreaseCastingTime:{mod:-1},removeGesture:{mod:-2},removeFormula:{mod:-2},extensionModifier:{mod:0}};static get defaultOptions(){let e=super.defaultOptions;return kn(e,{width:700,resizable:!0}),e}static bigTimes=[5,30,120,480,960,1920];async prepareFormRecall(e){await super.prepareFormRecall(e),e.find(".spellModifier").trigger("change")}static getRollButtons(e,t,a,s){let i=ae.getRollButtons(e,t,a,s);if(["spell","liturgy"].includes(e.source.type)){let n=Number(e.source.system.castingTime.value),r=e.source.system.castingTime.progress,l=e.source.system.castingTime.modified;if(n&&e.extra.speaker.token!="emptyActor"){let c=l>0?` (${r}/${l})`:"";kn(i,{reloadButton:{label:`${game.i18n.localize("SPELL.reload")}${c}`,callback:u(async m=>{let d=await g.getSpeaker(e.extra.speaker),p={_id:e.source._id,"system.castingTime.progress":r+1};l==0&&(l=Number(m.find(".castingTime").text())-1,p["system.castingTime.modified"]=l),await d.updateEmbeddedDocuments("Item",[p]);let f=game.i18n.format("SPELL.isReloading",{actor:d.token?.name||d.prototypeToken.name,item:e.source.name,status:`${r+1}/${l}`});await ChatMessage.create(g.chatDataSetup(f))},"callback")}})}}return i}async applyTransformations(e,t){let a=t.find('[name="situationalModifiers"]');a.find('option[data-extension="1"]').remove();let s=[],i=Object.keys(o.rollModifiers).map(r=>`${r}.mod`);this.dialogData.renderData.rollModifiersPrepared=ps(this.dialogData.renderData.rollModifiers);for(let r of t.find(".specAbs.active")){let l=await fromUuid(r.dataset.uuid);if(l)for(let c of l.effects)for(let m of c.changes)if(o.rollChanges.includes(m.key)){let d=l.name.split(" - "),p=game.i18n.localize(`MODS.${m.key}`);d=`${d[1]||d[0]}`;let f=`${p}: ${m.value} ${game.i18n.localize("spellextension")}: ${d}`;s.push(``)}else m.key=="macro.transform"?await g.callItemTransformationMacro(m.value,e,c):i.includes(m.key)?c.apply(this.dialogData.renderData.rollModifiersPrepared,m):c.apply(e,m)}let n=this.dialogData.renderData.rollModifiersPrepared.extensionModifier.mod;if(n){let r=game.i18n.localize("ABBR.modifiers"),l=game.i18n.localize("spellextension"),c=`${r}: ${n} ${l}`;s.push(``)}a.append(s.join(""))}static setData(e,t,a){let s=ps(o.rollModifiers),i=`${t}RollModifiers`;if(e.system[i])for(let n of Object.keys(e.system[i]))s[n].mod+=Number(e.system[i][n]?.mod??0);return s}async recalcSpellModifiers(e,t){let a=e,s=ps(this.dialogData.source);N.ensureNumber(s);let i=a.find(".castingTime"),n=a.find(".aspcost"),r=a.find(".reach"),l=a.find(".maintainCost"),c=a.find(".ritual").length>0;await this.applyTransformations(s,a);let m=a.find(".maxMods");if(a.find(".spellModifier:checked").length>Number(m.text())){t&&(t.currentTarget.checked=!1),m.addClass("emphasize"),setTimeout(function(){m.removeClass("emphasize")},600);return}for(let I of Object.keys(this.dialogData.renderData.rollModifiersPrepared)){let S=this.dialogData.renderData.rollModifiersPrepared[I].mod;e.find(`.${I}Label`).text(`(${S})`),e.find(`#${I}`).val(S)}let d=e.find(".canChangeCastingTime");s.system.canChangeCastingTime.value=="true"?d.is(":empty")&&(d.html(await renderTemplate("systems/dsa5/templates/dialog/parts/canChangeCastingTime.html",{rollModifiers:this.dialogData.renderData.rollModifiers})),this.setPosition({height:"auto"})):d.is(":empty")||(d.html(""),this.setPosition({height:"auto"}));let p=s.system.AsPCost.value,f=s.system.range.value,h=s.system.castingTime.value,y=p,k=s.system.maintainCost.value;a.find(".variableBaseCost")[s.system.variableBaseCost=="true"?"show":"hide"]();let C=0;a.find(".spellModifier[data-cost]:checked").each(function(I,S){if(y=y*(S.value<0?.5:2),k!=""&&k!=null){let j=String(k).split(" ");j[0]=Math.max(Number(j[0])*(S.value<0?.5:2)),k=j.join(" ")}C+=Number(S.value)}),y<1?t&&(t.currentTarget.checked=!1):(n.text(y),l.text(k),n.attr("data-mod",C)),C=0,y=h,a.find(".spellModifier[data-castingTime]:checked").each(function(I,S){if(c){let j=o.bigTimes.indexOf(Number(y));if(j!=null){let A=j+(S.value>0?1:-1);A=0?y=o.bigTimes[A]:ui.notifications.error("DSAError.CastingTimeLimit",{localize:!0})}else ui.notifications.error("DSAError.TimeCannotBeParsed",{localize:!0})}else y=y*(S.value>0?2:.5);C+=Number(S.value)}),y<1?t&&(t.currentTarget.checked=!1):(i.text(y),i.attr("data-mod",C)),C=0;let v=game.i18n.localize("ReverseSpellRanges."+f);r.text(f),a.find(".spellModifier[data-reach]:checked").each(function(I,S){if(v=="self")S.checked=!1;else if(v=="touch")r.text("4 "+game.i18n.localize("step")),C+=Number(S.value);else{let j=f.split(" ");v=Number(j[0]),isNaN(v)?(t&&(t.currentTarget.checked=!1),ui.notifications.error("DSAError.RangeCannotBeParsed",{localize:!0})):(r.text(v*2+" "+game.i18n.localize("step")),C+=Number(S.value))}}),r.attr("data-mod",C),e.find(".reloadButton").prop("disabled",Number(e.find(".castingTime").text())<2),this.calculateProbability()}async calculateProbability(){let e=g.getSpeaker(this.dialogData.speaker),t=new FormDataExtended(this.element.find("form")[0]).object;t.situationalModifiers=O._parseModifiers(this._element);let a=this.dialogData.source.system.talentValue.value+t.fw+await R._situationalModifiers(t,"FW"),s=await R._situationalModifiers(t)+$(this.element).find("input.spellModifier:checked").map((i,n)=>Number(n.value)).get().reduce((i,n)=>i+n,0)+$(this.element).find("[name=maintainedSpells]")[0].value*-1;super.calculateProbability(e,this.dialogData.source,s,a)}activateListeners(e){super.activateListeners(e),e.find(".reloadButton").prop("disabled",Number(e.find(".castingTime").text())<2),e.find(".specAbs").mousedown(s=>{$(s.currentTarget).toggleClass("active"),this.recalcSpellModifiers(e)}),e.find(".variableBaseCost").change(s=>{let i=$(s.currentTarget).parents(".skill-test"),n=i.find(".aspcost").attr("data-base"),r=$(s.currentTarget).val();i.find(".aspcost").attr("data-base",r),i.find(".aspcost").text(Number(i.find(".aspcost").text())*r/n)}),e.on("change",".spellModifier",s=>this.recalcSpellModifiers(e,s)),e.on("change","input,select",()=>this.calculateProbability()),e.on("mousedown",".quantity-click",()=>this.calculateProbability());let t=this.readTargets();t.length==0&&this.setRollButtonWarning();let a=this;this.checkTargets=setInterval(function(){t=a.compareTargets(e,t)},500)}};var{getProperty:yr,hasProperty:br}=foundry.utils,K=class o{static{u(this,"DSA5SoundEffect")}static sounds;static triedInit=!1;static prepareSoundEffects(){o.soundPaths={money:[],armor:[],meleeweapon:[],rangeweapon:[],default:[]},game.modules.get("gAudioBundle-3")&&(o.soundPaths.money.push("modules/gAudioBundle-3/src/Mint Coins And Money/Coin_Slide_Carpet.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_Drop_Carpet_06.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_Bottlecaps_Drop.ogg","modules/gAudioBundle-3/src/Mint Coins And Money/Coins_In_Sack_Held_By_Drawstring_06.ogg","modules/gAudioBundle-3/src/Money/Money_Coins_Handle.ogg"),o.soundPaths.meleeweapon.push("modules/gAudioBundle-3/src/Medieval Armor And Impacts/Weapon_Impact_Parry_01.ogg")),game.modules.get("gAudioBundle-2")&&(o.soundPaths.meleeweapon.push("modules/gAudioBundle-2/src/Gore/Melee_Sword_Attack_04.ogg"),o.soundPaths.armor.push("modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Foley_Soldier_Gear_Equipment_Metal_Cloth_Heavy_Movement_Light_08.ogg"),o.soundPaths.default.push("modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Foley_Sports_Bag_Grab_Pickup_Catch_04.ogg","modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Footstep_Ice_Crunchy_Run_01.ogg","modules/gAudioBundle-2/src/Footsteps/Footstep And Foley Sounds/Footstep_Ice_Crunchy_Run_02.ogg")),game.modules.get("gAudioBundle-4")&&o.soundPaths.rangeweapon.push("modules/gAudioBundle-4/src/Super Heroes Sound Design/Hawk's_Arrow_Flies_Bow_And_Arrow_Shoot_2.ogg"),Hooks.call("setDefaultDSASounds",o.soundPaths)}static async playEffect(e,t,a,s=void 0,i=!1){let n=await this.getSound(e,t,a);if(n)try{s?(game.socket.emit("system.dsa5",{type:"playWhisperSound",payload:{whisper:s,soundPath:n}}),i||foundry.audio.AudioHelper.play({src:n,volume:.8,loop:!1},!1)):foundry.audio.AudioHelper.play({src:n,volume:.8,loop:!1},!0)}catch{console.warn(`Could not play item sound effect ${n}`)}}static async loadSoundConfig(){let e=game.settings.get("dsa5","soundConfig");if(e)try{let a=await(await fetch(e)).json();this.sounds=a,console.log("DSA5 | Sound Config Loaded")}catch(t){console.warn(t)}}static successLevelToString(e){switch(e){case-1:return["fail"];case-2:return["botch","fail"];case 1:return["success"];case 2:return["crit","success"];default:return[]}}static async getSound(e,t,a){if(!this.sounds&&!this.triedInit&&(await this.loadSoundConfig(),this.triedInit=!0),!this.sounds)return;let s=this.successLevelToString(a),i=[],n;switch(t.type){case"meleeweapon":case"rangeweapon":i=[...s.map(r=>`${t.type}.manual.${t.name}.${e}_${r}`),`${t.type}.manual.${t.name}.${e}`,`${t.type}.manual.${t.name}.default.${e}`,`${t.type}.manual.${t.name}.default`,...s.map(r=>`${t.type}.${t.system.combatskill.value}.${e}_${r}`),`${t.type}.${t.system.combatskill.value}.${e}`,...s.map(r=>`${t.type}.${t.system.combatskill.value}.default_${r}`),`${t.type}.${t.system.combatskill.value}.default`];break;case"skill":i=[...s.map(r=>`${t.type}.${t.name}.${e}_${r}`),`${t.type}.${t.name}.${e}`,...s.map(r=>`${t.type}.${t.name}.default_${r}`),`${t.type}.${t.name}.default`];break;case"liturgy":case"spell":case"ceremony":case"ritual":i=[...s.map(r=>`${t.type}.${t.name}.${e}_${r}`),`${t.type}.${t.name}.${e}`,...s.map(r=>`${t.type}.${t.name}.default_${r}`),`${t.type}.${t.name}.default`];break}i.push(...s.map(r=>`${t.type}.default_${r}`),`${t.type}.default`);for(let r of i)if(br(this.sounds,r)&&(n=yr(this.sounds,r),n&&(typeof n=="string"||n instanceof String)))break;return n}static async playMoneySound(e=!1){let t=o.soundPaths.money,a=t[Math.floor(Math.random()*t.length)];await this.playSoundPath(a,e)}static async playEquipmentWearStatusChange(e,t=!1){let a=o.soundPaths[e.type]||o.soundPaths.default;if(a.length>0){let s=a[Math.floor(Math.random()*a.length)];await this.playSoundPath(s,t,.5)}}static async playSoundPath(e,t=!1,a=.8){if(game.settings.get("dsa5","inventorySound"))try{foundry.audio.AudioHelper.play({src:e,volume:a,loop:!1},t)}catch{console.warn(`Could not play item sound effect ${e}`)}}};var{duplicate:wn}=foundry.utils,J=class o{static{u(this,"OnUseEffect")}constructor(e){this.item=e}async callMacro(e,t,a={}){let i=await game.packs.get(e)?.getDocuments({name:t});if(!i||!i.length){for(let r of game.packs.filter(l=>l.documentName=="Macro"&&/\(internal\)/.test(l.metadata.label)))if(i=await r.getDocuments({name:t}),i.length)break}let n={};if(i.length){let r=Object.getPrototypeOf(async function(){}).constructor;try{a.result=n;let l=new r("args","actor","item",i[0].command);n.ret=await l.call(this,a,this.item.actor,this.item)}catch{try{let c=new r("args","actor","item",`
const that = this;
${i[0].command.replace(/(?=[ |(|{]+)?this\./g,"that.")}
- `);n.ret=await c.call(this,a,this.item.actor)}catch(c){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(c),n.error=!0}}}else ui.notifications.error(game.i18n.format("DSAError.macroNotFound",{name:t}));return n}async executeOnUseEffect(){if(!this.item.actor)return;if(!game.user.can("MACRO_SCRIPT"))return ui.notifications.warn("You are not allowed to use JavaScript macros.");let e=o.getOnUseEffect(this.item);try{let t=Object.getPrototypeOf(async function(){}).constructor;await new t("item","actor",e).call(this,this.item,this.item.actor)}catch(t){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(t),console.warn(t.stack)}}static getOnUseEffect(e){return e.getFlag("dsa5","onUseEffect")}async automatedAnimation(e,t={}){g.moduleEnabled("autoanimations")&&console.warn("Animations for on use effects not enabled yet")}static effectBaseDummy(e,t,a){return{name:e,icon:"icons/svg/aura.svg",changes:t,duration:a,flags:{dsa5:{value:null,description:e}}}}effectDummy(e,t,a){return o.effectBaseDummy(e,t,a)}async socketedConditionAddActor(e,t){if(game.user.isGM){let a=typeof t=="string";a&&(t=wn(CONFIG.statusEffects.find(i=>i.id==t)),t.name=game.i18n.localize(t.name));let s=[];for(let i of e)a?await i.addCondition(t,1,!1,!1):await i.addCondition(t),s.push(i.name);await this.createInfoMessage(t,s)}else{let a={id:this.item.uuid,data:t,actors:e.map(s=>s.id)};game.socket.emit("system.dsa5",{type:"socketedConditionAddActor",payload:a})}}async createInfoMessage(e,t,a=!0){if(t.length){let s=a?"ActiveEffects.appliedEffect":"ActiveEffects.removedEffect",i=game.i18n.format(s,{source:e.name,target:t.join(", ")});await ChatMessage.create(g.chatDataSetup(i))}}async socketedRemoveCondition(e,t,a=1){if(game.user.isGM){let s=[];for(let n of e){let r=canvas.tokens.get(n);r.actor&&(await r.actor.removeCondition(t,a,!1),s.push(r.name))}let i=CONFIG.statusEffects.find(n=>n.id==t);i.name=game.i18n.localize(i.name),await this.createInfoMessage(i,s,!1)}else{let s={id:this.item.uuid,coreId:t,targets:e};game.socket.emit("system.dsa5",{type:"socketedRemoveCondition",payload:s})}}async socketedActorTransformation(e,t){if(game.user.isGM)for(let a of e){let s=canvas.tokens.get(a);s.actor&&await s.actor.update(t)}else{let a={id:this.item.uuid,targets:e,update:t};game.socket.emit("system.dsa5",{type:"socketedActorTransformation",payload:a})}}async socketedConditionAdd(e,t){if(game.user.isGM){let a=typeof t=="string";a&&(t=wn(CONFIG.statusEffects.find(i=>i.id==t)),t.name=game.i18n.localize(t.name));let s=[];for(let i of e){let n=canvas.tokens.get(i);n.actor&&(a?await n.actor.addCondition(t,1,!1,!1):await n.actor.addCondition(t),s.push(n.name))}await this.createInfoMessage(t,s)}else{let a={id:this.item.uuid,data:t,targets:e};game.socket.emit("system.dsa5",{type:"socketedConditionAdd",payload:a})}}};var pe=class o{static{u(this,"DSATriggers")}static EVENTS={ARMOR_TRANSFORMATION:4,DAMAGE_TRANSFORMATION:5,POST_ROLL:6,POST_OPPOSED:7};static async postOpposed(e){let t=g.getSpeaker(e.attacker.speaker);t&&await this.runMacro(t,e.attacker.testResult,o.EVENTS.POST_OPPOSED,e)}static async postRoll(e){let t=g.getSpeaker(e.testData.speaker);t&&await this.runMacro(t,e.testData,o.EVENTS.POST_ROLL,e)}static async callMacro(e,t,a,s={}){return await new J(e).callMacro(t,a,s)}static async runMacro(e,t,a,s){if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else for(let[i,n]of Object.entries(e.dsatriggers[a])){let r=e.items.get(i),l=r.effects.get(n),c=l.getFlag("dsa5","args3");try{let m=Object.getPrototypeOf(async function(){}).constructor;return await new m("actor","testData","type","data","source","ef",c).call(this,e,t,a,s,r,l)}catch(m){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(m)}}}};var{mergeObject:gt,getProperty:X,duplicate:na,setProperty:vn}=foundry.utils;function Tn(o,e={}){g.moduleEnabled("autoanimations")&&console.warn("Animations for on use effects not enabled yet")}u(Tn,"automatedAnimation");function kr(o,e,t){return J.effectBaseDummy(o,e,t)}u(kr,"effectDummy");async function fs(o,e,t,a,s,i={}){let n={};if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else{let l=await game.packs.get(o)?.getDocuments({name:e});if(!l||!l.length){for(let c of game.packs.filter(m=>m.documentName=="Macro"&&/\(internal\)/.test(m.metadata.label)))if(l=await c.getDocuments({name:e}),l.length)break}if(l.length){let c=Object.getPrototypeOf(async function(){}).constructor,m=new c("actor","item","qs","automatedAnimation","args",l[0].command);try{i.result=n;let d=gt({automatedAnimation:Tn,effectDummy:kr},this);await m.call(d,t,a,s,Tn,i)}catch(d){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(d),n.error=!0}}else ui.notifications.error(game.i18n.format("DSAError.macroNotFound",{name:e}))}return n}u(fs,"callMacro");Hooks.once("i18nInit",()=>{Z.effectDurationRegexes=[{regEx:new RegExp(game.i18n.localize("DSAREGEX.combatRounds"),"i"),seconds:5},{regEx:new RegExp(game.i18n.localize("DSAREGEX.minutes"),"i"),seconds:60},{regEx:new RegExp(game.i18n.localize("DSAREGEX.hours"),"i"),seconds:3600},{regEx:new RegExp(game.i18n.localize("DSAREGEX.days"),"i"),seconds:3600*24},{regEx:new RegExp(game.i18n.localize("DSAREGEX.weeks"),"i"),seconds:3600*24*7},{regEx:new RegExp(game.i18n.localize("DSAREGEX.months"),"i"),seconds:3600*24*30},{regEx:new RegExp(game.i18n.localize("DSAREGEX.years"),"i"),seconds:3600*24*350}]});var Z=class o extends ActiveEffectConfig{static{u(this,"DSAActiveEffectConfig")}static AdvantageRuleItems=new Set(["armor","meleeweapon","rangeweapon"]);static get defaultOptions(){return gt(super.defaultOptions,{resizable:!0})}static async callMacro(e,t,a,s,i,n={}){return await fs(e,t,a,s,i,n)}static async startDelayedEffect(e,t){t.update({"system.delayed":!1,duration:e,"flags.dsa5.-=onDelayed":null})}static onDelayedEffect(e,t){let a=!0;if(t.system.delayed){let s=t.system?.originalDuration||{seconds:"",rounds:""};if(gt(s,{startRound:game.combat?.round,startTurn:game.combat?.turn,startTime:game.time.worldTime}),!s.rounds&&s.seconds&&(s.rounds=Number(s.seconds)/5),(t.changes.length||t.statuses.size)&&(this.startDelayedEffect(s,t),a=!1),t.system.macroEffect){let i=t.system.initialTestData,n=game.actors.get(t.system.sourceActor),r=t.system.source,l=na(t.system.macroEffect);delete l.flags.dsa5?.onDelayed,l.system.delayed=!1,l.duration=s,this.applyAdvancedFunction(e,[l],r,i,n)}}return a}static async onEffectRemove(e,t){let a=X(t,"flags.dsa5.onRemove");if(a)if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else try{let s=Object.getPrototypeOf(async function(){}).constructor;await new s("effect","actor",a).call(this,t,e)}catch(s){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(s),console.warn(s.stack)}}async checkTimesUpInstalled(){let e=g.moduleEnabled("times-up");return!e&&game.user.isGM&&ui.notifications.warn("DSAError.shouldTimesUp",{localize:!0}),e}async _render(e=!1,t={}){await super._render(e,t);let a=0,s=X(this.object,"parent.type"),i=["meleeweapon","rangeweapon"].includes(s)||s=="trait"&&["meleeAttack","rangeAttack"].includes(X(this.object,"parent.system.traitType.value")),n={hasSpellEffects:i||["spell","liturgy","ritual","skill","ceremony","consumable","poison","disease","ammunition"].includes(s)||["specialability"].includes(s)&&X(this.object,"parent.system.category.value")=="Combat",hasDamageTransformation:["ammunition","meleeweapon","rangeweapon"].includes(s),hasTriggerEffects:["specialability"].includes(s),hasSuccessEffects:["poison","disease"].includes(s)},r=[];if((n.hasSpellEffects||n.hasDamageTransformation||n.hasTriggerEffects)&&r.push({name:"ActiveEffects.advancedFunctions.none",index:0}),n.hasSpellEffects)for(let y of["systemEffect","macro","creature"])r.push({name:`ActiveEffects.advancedFunctions.${y}`,index:a+=1});n.hasDamageTransformation&&r.push({name:"ActiveEffects.advancedFunctions.armorPostprocess",index:pe.EVENTS.ARMOR_TRANSFORMATION},{name:"ActiveEffects.advancedFunctions.damagePostprocess",index:pe.EVENTS.DAMAGE_TRANSFORMATION}),n.hasTriggerEffects&&r.push({name:"ActiveEffects.advancedFunctions.postRoll",index:pe.EVENTS.POST_ROLL},{name:"ActiveEffects.advancedFunctions.postOpposed",index:pe.EVENTS.POST_OPPOSED});let l={systemEffects:this.getStatusEffects(),canEditMacros:game.user.isGM||game.settings.get("dsa5","playerCanEditSpellMacro")},c=["players","player","playergm","gm"].reduce((y,k)=>(y[k]=game.i18n.localize(`ActiveEffects.messageReceivers.${k}`),y),{}),m={1:"ActiveEffects.onSuccess",2:"ActiveEffects.onFailure"},d=o.AdvantageRuleItems.has(s),p=[2,6,7],f=$(this._element);f.find(".tabs").append(`${game.i18n.localize("advanced")}`);let h=await renderTemplate("systems/dsa5/templates/status/advanced_effect.html",{effect:this.object,advancedFunctions:r,effectConfigs:n,macroIndexes:p,messageReceivers:c,canWeaponAdvantages:d,equipmentAdvantageOptions:{1:game.i18n.localize(`AdvantageRuleItems.${s}.1`),2:game.i18n.localize(`AdvantageRuleItems.${s}.2`)},applySuccessConditions:m,config:l,isWeapon:i,dispositions:Object.entries(CONST.TOKEN_DISPOSITIONS).reduce((y,k)=>(y[k[1]]=`TOKEN.DISPOSITION.${k[0]}`,y),{2:game.i18n.localize("all")})});f.find('.tab[data-tab="effects"]').after($(h)),f.find(".advancedSelector").on("change",y=>{let k=this.object;k.flags.dsa5.advancedFunction=$(y.currentTarget).val(),renderTemplate("systems/dsa5/templates/status/advanced_functions.html",{effect:k,config:l,macroIndexes:p}).then(D=>{f.find(".advancedFunctions").html(D)})}),f.find(".auraSelector").on("change",y=>{f.find(".auraDetails").toggleClass("dsahidden",!y.currentTarget.checked),f.find(".auraBox").toggleClass("groupbox",y.currentTarget.checked)}),this.object.statuses.size&&game.i18n.has(this.object.description)&&f.find('[data-tab="details"] .editor').replaceWith(`
${game.i18n.localize(this.object.description)}
`),this.checkTimesUpInstalled()}getStatusEffects(){return CONFIG.statusEffects.map(e=>({id:e.id,name:game.i18n.localize(e.name)})).sort((e,t)=>e.name.localeCompare(t.name))}static applyRollTransformation(e,t,a){let s="",i=t.origin;for(let n of i.effects)try{if(Number(X(n,"flags.dsa5.advancedFunction"))==a)if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else try{let r=Object.getPrototypeOf(function(){}).constructor;new r("ef","callMacro","actor","msg","source","options",X(n,"flags.dsa5.args3")).call(this,n,fs,e,s,i,t)}catch(r){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(r),console.warn(r.stack)}}catch(r){console.warn("Unable to apply advanced effect",r,n)}return t.origin=i,{msg:s,options:t}}static async applyAdvancedFunction(e,t,a,s,i,n=!0){let r="",l=[],c=!1,m=[],d=new Set;for(let p of t){p.origin&&delete p.origin;let f=Number(X(p,"flags.dsa5.specStep"))||0;try{let h=Number(X(p,"flags.dsa5.advancedFunction")),y=Math.min(s.qualityStep||0,6),k=X(p,"flags.dsa5.resistRoll"),D=X(p,"flags.dsa5.isAura");if(D){let v=`${X(p,"flags.dsa5.auraRadius")||1}`.replace(/q(l|s)/i,y),I=(await new Roll(v).evaluate()).total;vn(p,"flags.dsa5.auraRadius",I)}if(k&&!n){let v=k.split(" "),I=`${v.pop()}`;l.push({skill:v.join(" "),mod:Math.round(Roll.safeEval(`${I}`.replace(/q(l|s)/i,y).replaceAll("step",f)))||0,effect:p,target:e,token:e.token?.id})}else{c=!0,d.has(p.name)||d.add(p.name);let v=X(p,"flags.dsa5.onDelayed"),I={duration:{seconds:v},system:{delayed:!0,originalDuration:p.duration}},A=p.changes&&p.changes.length>0||D&&!h;if(h)switch(h){case 1:{let S=`${X(p,"flags.dsa5.args1")}`||"1";/,/.test(S)?S=Number(S.split(",")[y-1]):S=Number(S.replace(game.i18n.localize("CHARAbbrev.QS"),y));let M=X(p,"flags.dsa5.args0"),T=game.i18n.localize(`CONDITION.${M}`),L={name:`${a.name} (${T})`,duration:p.duration};v&>(L,I),await e.addTimedCondition(M,S,!1,!1,L)}break;case 2:if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else if(v){let S=na(p);S.changes=[],A=!0,gt(p,{system:{macroEffect:S,sourceActor:i?.id,source:a,initialTestData:{qualityStep:s.qualityStep}}})}else try{let S=Object.getPrototypeOf(async function(){}).constructor;await new S("effect","actor","callMacro","msg","source","actor","sourceActor","testData","qs",X(p,"flags.dsa5.args3")).call(this,p,e,fs,r,a,e,i,s,y)}catch(S){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(S),console.warn(S.stack)}break;case 3:let j=(X(p,"flags.dsa5.args4")||"").split(",").map(S=>`@Compendium[${S.trim().replace(/(@Compendium\[|\])/)}]`).join(" ");r+=`
`).join("")),new foundry.applications.api.DialogV2({window:{title:r.name},content:h,buttons:[{action:"yes",icon:"fa fa-check",label:"HELP.pay",default:!0,callback:u(async()=>{if(await m.applyMana(Number(Fe(r,"flags.dsa5.maintain")),Fe(r,"flags.dsa5.payType"))){let k={startTime:game.time.worldTime};game.combat&&(k.startRound=game.combat.round,k.startTurn=game.combat.turn),m.updateEmbeddedDocuments("ActiveEffect",[{_id:r._id,duration:k}])}},"callback")},{action:"delete",icon:"fas fa-trash",label:"delete",callback:u((y,k,D)=>{for(let v of k.form.elements)v.classList.contains("effectRemoveSelector")&&d.push(v.value);m.deleteEmbeddedDocuments("ActiveEffect",d,{noHook:!0})},"callback")}]}).render(!0),!1}}),Hooks.on("updateActor",(r,l)=>{!game.user.isGM&&r.limited&&wr(l,"system.merchant.hidePlayer")&&ui.sidebar.render(!0)}),Hooks.on("deleteActiveEffect",(r,l)=>{if(!g.isActiveGM()||l.noHook)return;let c=r.parent;e(r,l),c&&c.documentName=="Actor"&&(r.statuses.has("bloodrush")?c.addCondition("stunned",2,!1,!1):(r.statuses.has("dead")||r.statuses.has("defeated"))&&game.combat&&c.markDead(!1),Z.onEffectRemove(c,r))}),Hooks.on("preDeleteActiveEffect",(r,l,c)=>{if(!g.isActiveGM()||l.noHook)return;let m=r.parent;if(m&&m.documentName=="Actor"&&(Z.onDelayedEffect(m,r)===!1||Hooks.call("deleteActorActiveEffect",m,r)===!1))return!1}),Hooks.on("dropActorSheetData",(r,l,c)=>{switch(c.data?.type){case"condition":return r.addCondition(c.data.payload.id,1,!1,!1),!1;case"lookup":return l._handleLookup(c.data),!1;case"fullpack":return l._addFullPack(c.data),!1}}),Hooks.on("createActiveEffect",(r,l,c)=>{g.isActiveGM()&&(o(r),t(r))}),Hooks.on("deleteActiveEffect",(r,l,c)=>{g.isActiveGM()&&o(r)}),Hooks.on("updateActiveEffect",(r,l,c)=>{g.isActiveGM()&&(o(r),a(r))});function o(r){if(game.combat&&r.changes.some(l=>/(system\.status\.initiative|system\.characteristics.mu|system\.characteristics\.ge)/.test(l.key))){let l=r.parent.id,c=game.combat.combatants.find(m=>m.actor.id==l);c&&c.recalcInitiative()}}u(o,"checkIniChange");let e=u(async(r,l)=>{if(!r.parent)return;let c=Fe(r,"flags.dsa5.removeMessage");if(!(game.settings.get("dsa5","notifyOnFadingEffects")&&r.parent.documentName=="Actor"||c))return;let m=[];switch(c){case"player":m=game.users.filter(d=>!d.isGM&&r.parent.testUserPermission(d,"OWNER"));break;case"playergm":m=game.users.filter(d=>r.parent.testUserPermission(d,"OWNER"));break;case"players":m=void 0;break;default:m=game.users.filter(d=>d.isGM)}m=m?.map(d=>d.id),ChatMessage.create(g.chatDataSetup(game.i18n.format("CHATNOTIFICATION.fadingEffect",{effect:r.name,actor:r.parent.link}),void 0,void 0,m))},"notifyFadingEffect"),t=u(async r=>{let l=r.parent;l&&(await a(r,{},l),(r.statuses.has("dead")||r.statuses.has("defeated"))&&game.combat&&await l.markDead(!0),r.statuses.has("unconscious")&&await l.addCondition("prone"))},"createEffects"),a=u(async(r,l={},c)=>{if(c||(c=r.parent),!c||c.documentName!="Actor")return;let m=/^system\.condition\./;for(let d of r.changes||[])m.test(d.key)&&d.mode==2&&(l[d.key.split(".")[2]]=Number(d.value));for(let d of Object.keys(l))if(c.system.condition[d]>=4&&(d=="inpain"?await c.initResistPainRoll(r):["encumbered","stunned","feared","confused","trance"].includes(d)?await c.addCondition("incapacitated"):d=="paralysed"?await c.addCondition("rooted"):["drunken","exhaustion"].includes(d)&&(await c.addCondition("stunned"),await c.removeCondition(d))),(Number(l.inpain)||0)>0&&!c.hasCondition("bloodrush")&&c.system.condition.inpain>0&&P.hasVantage(c,game.i18n.localize("LocalizedIDs.frenzy"))){await c.addCondition("bloodrush");let p=g.replaceConditions(`${game.i18n.format("CHATNOTIFICATION.gainsBloodrush",{character:""+c.name+""})}`);ChatMessage.create(g.chatDataSetup(p))}},"countableDependentEffects"),s=u(async(r,l)=>{(game.dsa5.apps.AskForNameDialog||hs).getDialog(r,l)},"askForName"),i=u(async r=>{if(g.isActiveGM()&&game.settings.get("dsa5","randomWeaponSelection")&&r.actor.type!="character"){let l=[],c=[],m=[];for(let p of r.actor.items)p.type=="meleeweapon"&&p.system.worn.value?N.isShield(p)?c.push(p):l.push(p):p.type=="rangeweapon"&&p.system.worn.value&&m.push(p);let d=[];if(l.length){let p=l[Math.floor(Math.random()*l.length)],f=p._id,h;!N.regex2h.test(p.name)&&c.length&&(h=c[Math.floor(Math.random()*c.length)]._id);for(let y of l)y._id!=f&&d.push({_id:y._id,system:{worn:{value:!1}}});for(let y of c)y._id!=h&&d.push({_id:y._id,system:{worn:{value:!1}}})}if(m.length){let p=m[Math.floor(Math.random()*m.length)]._id;for(let f of m)f._id!=p&&d.push({_id:f._id,system:{worn:{value:!1}}})}d.length&&r.actor.updateEmbeddedDocuments("Item",d)}},"randomWeaponSelection"),n=u(async(r,l)=>{if(!g.isActiveGM())return;let c=r.actor;if(c.hasPlayerOwner)return;let m=Number(game.settings.get("dsa5","obfuscateTokenNames"));if(m==0||Fe(c,"merchant.merchantType")=="loot")return;let d=canvas.scene.tokens.filter(f=>f.actor&&f.actor.id===c.id),p=game.i18n.localize("unknown");if([2,4].includes(m)){if(!(r.id||r._id))return;s(r,m);return}if(d.length>0&&m<3){let f=d.length;for(let h of d){let y=h.name.match(/\d+$/);y&&Number(y[0])>f&&(f=Number(y[0]))}p=`${d[0].name.replace(/ \d{1,}$/,"")} ${f+1}`}l.name=p},"obfuscateName");Hooks.on("updateToken",(r,l,c)=>{if(!r.rendered)return;let m={center:r.object.center,elevation:r.elevation};H.updateTokenHook(r,l,c);let d=c.animation?.name||r.object?.animationName;(r.object?.animationContexts.get(d)?.promise||Promise.resolve()).then(()=>{r.object?.drawAuras(),game.dsa5.apps.LightDialog&&game.dsa5.apps.LightDialog.onTokenMove(r,l,c,m)})}),Hooks.on("preDeleteToken",r=>{_e.onDeleteToken(r)}),Hooks.on("deleteToken",r=>{H.deleteTokenHook(r),Ve.hide(r)}),Hooks.on("canvasReady",r=>{for(let l of r.scene.tokens)l.object?.drawAuras()}),Hooks.on("preCreateToken",(r,l,c,m)=>{let d=r.actor;if(!d)return;let p={};Fe(d,"system.merchant.merchantType")=="loot"?It(p,{displayBars:0}):Fe(d,"system.config.autoBar")&&(It(p,{bar1:{attribute:"status.wounds"}}),d.system.isMage?It(p,{bar2:{attribute:"status.astralenergy"}}):d.system.isPriest?It(p,{bar2:{attribute:"status.karmaenergy"}}):It(p,{bar2:{attribute:"tbd"}})),Fe(d,"system.config.autoSize")&&g.calcTokenSize(d,p),n(r,p),r.updateSource(p)}),Hooks.on("createToken",(r,l,c)=>{l.noHook||(n(r,{}),i(r),H.createTokenHook(r,l,c),r.object?.drawAuras())}),Hooks.on("hoverToken",(r,l)=>{game.settings.get("dsa5","showWeaponsOnHover")&&(l?Ve.show(r):Ve.hide(r))})}u(ys,"default");var Ve=class{static{u(this,"TokenHoverHud")}static show(e){if(!game.combat||canvas.hud?.token?.rendered)return;let t=e.actor.items.filter(a=>a.type=="meleeweapon"||a.type=="rangeweapon"?a.system.worn.value:!1);if(t.length){let a=t.map(i=>``).join(" "),s=$(`
`;return ChatMessage.create(g.chatDataSetup(a,"roll")),!1}return t}static async handlePayAction(e,t,a,s=void 0){if(game.user.isGM&&!s){ui.notifications.info("PAYMENT.onlyActors",{localize:!0});return}s?K.playMoneySound(!0):s=game.user.character;let i=!1;s&&t?i=await o.payMoney(s,a):s&&!t?i=await o.getMoney(s,a):ui.notifications.info("PAYMENT.onlyActors",{localize:!0}),i&&e&&(e.fadeOut(),game.socket.emit("system.dsa5",{type:"updateMsg",payload:{id:e.closest(".message").attr("data-message-id"),updateData:{[`flags.dsa5.userHidden.${game.user.id}`]:!0}}}))}static async _moneyToCoins(e,t=void 0){let a=(t||(await g.allMoneyItems()).filter(n=>n.system.subcategory!=1)).sort((n,r)=>r.system.price.value-n.system.price.value),s=[],i=e;for(let n of a){let r=Math.floor(i/n.system.price.value);s.push({name:n.name,amount:r,img:n.img}),i-=r*n.system.price.value}return i>.001&&(s[s.length-1].amount+=1),s}static _parseMoneyString(e){let t=e.replace(",",".").match(/\d{1,}(\.\d{1,3}|,\d{1,3})?/);return t?Number(t[0]):!1}static _actorsMoney(e){let t=e.items.filter(a=>a.type=="money"&&a.system.subcategory!=1);return{money:t,sum:t.reduce((a,s)=>a+Number(s.system.quantity.value)*Number(s.system.price.value),0)}}static async _replaceMoney(e){let t=o._actorsMoney(e),a=await g.allMoneyItems();await e.deleteEmbeddedDocuments("Item",t.money.map(s=>s.id),{render:!1}),await e.createEmbeddedDocuments("Item",a,{render:!1}),await o._updateMoney(e,o._actorsMoney(e).money,t.sum)}static async _updateMoney(e,t,a,s=!0){let i=await o._moneyToCoins(a,t),n=[];for(let r of t){let l=i.find(c=>c.name==r.name);l!=null&&n.push({_id:r.id,"system.quantity.value":l.amount})}await e.updateEmbeddedDocuments("Item",n,{render:s})}static async _moneyToString(e){let t=await o._moneyToCoins(e),a=[];for(let s of t)s.amount>0&&a.push(`${s.amount} `);return a.join(", ")}static async chatListeners(e){e.on("click",".payButton",t=>{let a=$(t.currentTarget);o.handlePayAction(a,Number(a.attr("data-pay"))!=1,a.attr("data-amount")),K.playMoneySound()})}};var{getProperty:Cn,setProperty:ks,getType:Sr}=foundry.utils,Me=class o extends ActiveEffect{static{u(this,"DSAActiveEffect")}static itemChangeRegex=/^@/;static deprecatedDataRegex=/^data\./;apply(e,t){if(o.itemChangeRegex.test(t.key)){let a=this._getModifiedItems(e,t);for(let s of a.items){let i=foundry.utils.flattenObject(s.overrides||{});i[a.key]=Number.isNumeric(s.value)?Number(a.value):a.value;let n={...t,key:a.key,value:a.value};super.apply(s,n),s.overrides=foundry.utils.expandObject(i)}}else{if(t.key.startsWith("data.")){let a=game.i18n.format("DSAError.ActiveEffectDataChange",{name:e.name});console.error(a),t.key=t.key.replace(o.deprecatedDataRegex,"system.")}return super.apply(e,t)}}static realyRealyEnabled(e){return!(e.disabled||!e.transfer||e.system.delayed||!game.settings.get("dsa5","enableWeaponAdvantages")&&e.system.equipmentAdvantage)}static async _onCreateOperation(e,t,a){for(let s of e)s.parent.documentName=="Actor"&&await O.postUpdateConditions(s.parent);return super._onCreateOperation(e,t,a)}static async _onUpdateOperation(e,t,a){for(let s of e)s.parent.documentName=="Actor"&&await O.postUpdateConditions(s.parent);return super._onUpdateOperation(e,t,a)}static async _onDeleteOperation(e,t,a){for(let s of e)s.parent.documentName=="Actor"&&await O.postUpdateConditions(s.parent);return super._onDeleteOperation(e,t,a)}isVisibleEffect(){return!this.disabled&&!this.notApplicable&&(game.user.isGM||!this.getFlag("dsa5","hidePlayers"))&&!this.getFlag("dsa5","hideOnToken")}_displayScrollingStatus(e){let t=["dead"];(game.user.isGM||this.target?.testUserPermission(game.user,"OBSERVER")||!game.settings.get("dsa5","hideEffects")?this.isVisibleEffect():t.some(i=>this.statuses.has(i)))&&super._displayScrollingStatus(e)}_getModifiedItems(e,t){let a=t.key.split("."),s=a.shift();s=s.replace("@","").toLowerCase();let i=a.shift(),n=a.join("."),r=t.value;return{items:i=="self"?[this.parent]:e?.items?.filter(c=>c.type==s&&(c.name==i||c.id==i))||[],key:n,value:r}}async _preUpdate(e,t,a){await super._preUpdate(e,t,a),this._clearModifiedItems()}_clearModifiedItems(){if(this.parent instanceof CONFIG.Actor.documentClass){for(let e of this.changes)if(o.itemChangeRegex.test(e.key)){let t=this._getModifiedItems(this.parent,e);for(let a of t.items){let s=foundry.utils.flattenObject(a.overrides||{}),i=t.key;delete s[i];let n=Cn(a._source,i);ks(a,i,n),a.overrides=foundry.utils.expandObject(s),a.sheet?.rendered&&a.sheet.render(!0)}}}}async _preDelete(e,t){super._preDelete(e,t),this._clearModifiedItems()}},Ar=u((o,e)=>{let t=Cn(o,e.key)||null;t==null&&/^system\.(vulnerabilities|resistances)/.test(e.key)&&(t=[],ks(o,e.key,t));let a=Sr(t),s=null;switch(a){case"Array":let i=[],n=e.effect.name;for(let r of`${e.value}`.split(/[;,]+/)){let l=r.split(" "),c=l.pop(),m=l.join(" ");i.push({source:n,value:c,target:m,item:e.effect.parent?.name})}s=t.concat(i)}return s!==null&&ks(o,e.key,s),s},"applyCustomEffect");Hooks.on("applyActiveEffect",(o,e)=>Ar(o,e));var{getProperty:se,mergeObject:ue,duplicate:He}=foundry.utils,C=class o extends Item{static{u(this,"Itemdsa5")}static DEFAULT_ICON="systems/dsa5/icons/blank.webp";static defaultImages={advantage:"systems/dsa5/icons/categories/Vorteil.webp",disadvantage:"systems/dsa5/icons/categories/Nachteil.webp",armor:"systems/dsa5/icons/categories/Armor.webp",meleeweapon:"systems/dsa5/icons/categories/Meleeweapon.webp",rangeweapon:"systems/dsa5/icons/categories/Rangeweapon.webp",equipment:"systems/dsa5/icons/categories/Equipment.webp",consumable:"systems/dsa5/icons/categories/consumable.webp",liturgy:"systems/dsa5/icons/categories/Liturgy.webp",spell:"systems/dsa5/icons/categories/Spell.webp",ammunition:"systems/dsa5/icons/categories/Munition.webp",career:"systems/dsa5/icons/categories/Career.webp",magictrick:"systems/dsa5/icons/categories/Spelltrick.webp",blessing:"systems/dsa5/icons/categories/Blessing.webp",combatskill:"systems/dsa5/icons/categories/Combat_Skill.webp",skill:"systems/dsa5/icons/categories/Skill.webp",Geweihte:"systems/dsa5/icons/categories/Geweihte.webp",Weltliche:"systems/dsa5/icons/categories/Weltliche.webp",Zauberer:"systems/dsa5/icons/categories/Zauberer.webp",ritual:"systems/dsa5/icons/categories/ritual.webp",ceremony:"systems/dsa5/icons/categories/ceremony.webp",abilityclerical:"systems/dsa5/icons/categories/ability_clerical.webp",abilityCombat:"systems/dsa5/icons/categories/ability_combat.webp",abilityfatePoints:"systems/dsa5/icons/categories/ability_fate_points.webp",abilitygeneral:"systems/dsa5/icons/categories/ability_general.webp",specialability:"systems/dsa5/icons/categories/ability_general.webp",abilitymagical:"systems/dsa5/icons/categories/ability_magical.webp",abilitylanguage:"systems/dsa5/icons/categories/Ability_Language.webp",abilitystaff:"systems/dsa5/icons/categories/ability_staff.webp",abilityceremonial:"systems/dsa5/icons/categories/ability_ceremonial.webp",abilityanimal:"systems/dsa5/icons/categories/ability_animal.webp",trait:"systems/dsa5/icons/categories/trait.webp",Tiere:"systems/dsa5/icons/categories/Tiere.webp",aggregatedTest:"systems/dsa5/icons/categories/aggregated_test.webp",poison:"systems/dsa5/icons/categories/poison.webp",disease:"systems/dsa5/icons/categories/disease.webp",spellextension:"systems/dsa5/icons/categories/Spellextension.webp",species:"icons/environment/people/group.webp",application:"systems/dsa5/icons/categories/Skill.webp",trick:"systems/dsa5/icons/categories/Tiere.webp",disadvantageanimal:"systems/dsa5/icons/categories/NachteilAnimal.webp",advantageanimal:"systems/dsa5/icons/categories/VorteilAnimal.webp",diseaseanimal:"systems/dsa5/icons/categories/diseaseAnimal.webp",effectwrapper:"icons/svg/aura.svg",liturgyTalisman:"systems/dsa5/icons/categories/LiturgieTalisman.webp",plant:"systems/dsa5/icons/categories/plant.webp",magicalsign:"systems/dsa5/icons/categories/magicalsign.webp",abilitypact:"systems/dsa5/icons/categories/ability_pact.webp",demonmark:"systems/dsa5/icons/categories/ability_pact.webp",patron:"systems/dsa5/icons/categories/ability_pact.webp",information:"systems/dsa5/icons/categories/DSA-Auge.webp",essence:"systems/dsa5/icons/categories/wesenszug.webp",imprint:"systems/dsa5/icons/categories/praegung.webp",book:"systems/dsa5/icons/backgrounds/library.webp",trap:"systems/dsa5/icons/categories/trap.webp"};static defaultIcon(e){(!e.img||e.img=="")&&(e.type in this.defaultImages?e.img=this.defaultImages[e.type]:e.type.startsWith("ability")?e.img=this.defaultImages.specialability:e.img=o.DEFAULT_ICON)}static async create(e,t){if(Array.isArray(e))for(let a of e)this.defaultIcon(a);else this.defaultIcon(e);return await super.create(e,t)}static getSpecAbModifiers(e,t){let a=[];for(let s of e.find(".specAbs")){let i=Number($(s).attr("data-step"));if(i>0){let n=t=="attack"?$(s).attr("data-atbonus"):$(s).attr("data-pabonus"),r=n.split(",").reduce((l,c)=>l+Number(c),0);a.push({name:$(s).find("a").text(),value:isNaN(r)?Number(n.replace("*","")):Number(r)*i,damageBonus:$(s).attr("data-tpbonus"),dmmalus:$(s).attr("data-dmmalus")*i,step:i,specAbId:$(s).attr("data-id"),type:/^\*/.test(n)?"*":void 0})}}return a}async _buildEmbedHTML(e,t={}){let a=`systems/dsa5/templates/items/browse/${this.type}.html`,s=await renderTemplate(a,{document:this,isGM:game.user.isGM,...await this.sheet.getData(),...t});return $(s)[0]}static setupSubClasses(){game.dsa5.config.ItemSubclasses={ritual:Hs,spell:Et,liturgy:oa,ceremony:Os,advantage:la,disadvantage:la,aggregatedTest:Ds,trait:Vs,blessing:$s,magictrick:ra,specialability:Bs,disease:Rs,poison:_s,armor:Es,money:Cs,rangeweapon:Fs,meleeweapon:Ls,ammunition:Ms,equipment:Ps,combatskill:xs,skill:Gs,application:js,consumable:zs,spellextension:Ws,species:qs,effectwrapper:Is,plant:ws,magicalsign:vs,patron:As,demonmark:Ts,information:Ns,book:Us,trap:Ss}}static buildSpeaker(e,t){return{token:t,actor:e?.id,scene:canvas.scene?.id}}static parseValueType(e,t){let a="";return/^\*/.test(t)&&(a="*",t=t.substring(1).replace(",",".")),{name:e,value:Number(t),type:a}}async addCondition(e,t=1,a=!1,s=!0){return await z.addCondition(this,e,t,a,s)}async removeCondition(e,t=1,a=!0,s=!1){return z.removeCondition(this,e,t,a,s)}hasCondition(e){return z.hasCondition(this,e)}static getMiracleModifiers(e,t,a,s){let i=new RegExp(`${game.i18n.localize("combatskill")} `,"gi"),n=(se(e,"system.happyTalents.value")||"").split(/;|,/).map(l=>l.replace(i,"").trim()),r=[];if(n.includes(t.name)){let l=e.system.status.karmaenergy.value,c=se(e,`system.miracle.${s}`)||0;if(l<4)return[];r.push({name:game.i18n.localize("LocalizedIDs.miracle"),value:2+c,type:a,selected:!1});let m=game.i18n.localize("LocalizedIDs.miracleMight");l>=6&&F.hasAbility(e,m)&&r.push({name:m,value:3+c,type:a,selected:!1})}return r}static getSkZkModifier(e,t){let a=[],s=[],i=["spell","liturgy","ceremony","ritual"].includes(t.type)&&t.system.effectFormula.value.trim()=="";game.user.targets.size&&game.user.targets.forEach(n=>{if(n.actor){let r=0;i&&(r=x.detectCreatureType(n.actor).reduce((d,p)=>d+p.spellResistanceModifier(n.actor),0));let l=se(n.actor,`system.status.soulpower.${t.type}resist`)||0,c=se(n.actor,`system.status.toughness.${t.type}resist`)||0;a.push((n.actor.system.status.soulpower.max+l)*-1-r),s.push((n.actor.system.status.toughness.max+c)*-1-r)}}),ue(e,{SKModifier:a.length>0?Math.min(...a):0,ZKModifier:s.length>0?Math.min(...s):0})}static async _onCreateOperation(e,t,a){for(let s of e)s.actor&&await O.postUpdateConditions(s.actor);return super._onCreateOperation(e,t,a)}static async _onUpdateOperation(e,t,a){for(let s of e)s.actor&&await O.postUpdateConditions(s.actor);return super._onUpdateOperation(e,t,a)}static async _onDeleteOperation(e,t,a){for(let s of e)s.actor&&await O.postUpdateConditions(s.actor);return super._onDeleteOperation(e,t,a)}static parseEffect(e,t){let a={},s=new RegExp(game.i18n.localize("CHARAbbrev.GS"),"gi");for(let i of e.split(/,|;/).map(n=>n.trim())){let n=i.replace(/(\s+)/g," ").trim().split(" ");if(n[0]=n[0].replace(s,t.system.status.speed.max),n.length==2&&(!isNaN(n[0])||/(=)?[+-]\d([+-]\d)?/.test(n[0])||/(=)?\d[dDwW]\d/.test(n[0])||/=\d+/.test(n[0])||/\*\d(\.\d)*/.test(n[0]))){let r=n[1].toLowerCase();a[r]==null&&(a[r]=[]),a[r].push(n[0])}}return a}static getDefenseMalus(e,t){let a=!1;if(t.flags.oppose){let s=game.messages.get(t.flags.oppose.messageId),i=s.flags.data.preData;a=!(se(i,"source.type")=="meleeweapon"||se(i,"source.system.traitType.value")=="meleeAttack");let n=/ \[(-)?\d{1,}\]/;for(let r of i.situationalModifiers)r.dmmalus!=null&&r.dmmalus!=0?e.push({name:`${game.i18n.localize("MODS.defenseMalus")} - ${r.name.replace(n,"")}`,value:r.dmmalus,selected:!0}):r.type=="defenseMalus"&&r.value!=0&&e.push({name:r.name.replace(n,""),value:r.value,selected:!0});s.flags.data.postData.halfDefense&&e.push({name:`${game.i18n.localize("MODS.defenseMalus")} - ${game.i18n.localize("halfDefenseShort")}`,value:.5,type:"*",selected:!0})}return a}static changeChars(e,t,a,s){e.system.characteristic1.value=t,e.system.characteristic2.value=a,e.system.characteristic3.value=s}static specAbsDataset(e,t,a,s="effect.value"){let i=a=="parry",n=i?["pa"]:["at","tp","dm"],r=n.reduce((m,d)=>(m[d]=game.i18n.localize(`LocalizedAbilityModifiers.${d}`),m),{}),l=[],c=i?(m,d)=>m.pa!=0:(m,d)=>m.at!=0||m.tp!=0||m.dm!=0||d.effects.size>0;for(let m of e){let d=o.parseEffect(se(m.system,s),t),p=["","2","3"].filter(h=>se(m,`system.effect.value${h}`)).length,f=n.reduce((h,y)=>(h[y]=d[r[y]]||[0],h),{});if(c(f,m)){let h=game.i18n.localize(b.combatSkillSubCategories[m.system.category.sub]);l.push({name:m.name,atbonus:f.at||[0],pabonus:f.pa||[0],tpbonus:f.tp||[0],dmmalus:f.dm||[0],steps:m.system.step.value,category:{id:m.system.category.sub,css:`ab_${m.system.category.sub}`,name:h},id:m.id,actor:t.id,variantCount:p})}}return l}static buildCombatSpecAbs(e,t,a,s,i){let n=u(()=>!0,"searchFilter");a&&(a.push(game.i18n.localize("LocalizedIDs.all")),a=a.map(f=>f.toLowerCase()),n=u((f,h)=>f.system.list.value.split(/;|,/).map(y=>y.trim().toLowerCase()).some(y=>h.includes(y.replace(/ \([a-zA-Z äüöÄÖÜ]*\)/,""))),"searchFilter"));let r=game.combat?.isBrawling?()=>!0:f=>Number(f.system.category.sub)!=5,l=new Set([]),c=new Set([]),m={};for(let f of i.effects||[])if(Me.realyRealyEnabled(f)){for(let h of f.changes)if(h.key.startsWith("self.maneuver.")){let y=g.parseAbilityString(h.value);if(/-$/.test(y.name))c.add(y.name.replace(/-$/,"").trim());else if(/\+$/.test(y.name))l.add(y.name.replace(/\+$/,"").trim());else{let k=h.key.split(".")[2];m[y.name]||(m[y.name]={}),m[y.name][k]||(m[y.name][k]=0),m[y.name][k]+=y.step}}}let d=e.items.filter(f=>f.type=="specialability"&&t.includes(f.system.category.value)&&f.system.effect.value!=""&&(n(f,a)||l.has(f.name))&&r(f)&&!c.has(f.name)),p=this.specAbsDataset(d,e,s);for(let f of p)if(m[f.name])for(let h of Object.keys(m[f.name]))f[h].push(m[f.name][h]);return p}static getCombatSkillModifier(e,t,a){if(t.type=="trait")return;let s=e.items.find(i=>i.type=="combatskill"&&i.name==t.system.combatskill.value);for(let i of s.effects)for(let n of i.changes)switch(n.key){case"system.rangeStats.defenseMalus":case"system.meleeStats.defenseMalus":a.push({name:`${s.name} - ${game.i18n.localize("MODS.defenseMalus")}`,value:n.value*-1,type:"defenseMalus",selected:!0});break}}static attackStatEffect(e,t){t!=0&&(t=isNaN(t)?t:Number(t),e.push({name:game.i18n.localize("statuseffects"),value:t,selected:!0}))}static getTargetSizeAndModifier(e,t,a){let s="average";return game.user.targets.forEach(i=>{if(i.actor){let n=se(i.actor,"system.status.size.value");n&&(s=n),x.addCreatureTypeModifiers(i.actor,t,a,e),this.checkDuplicatus(e,i.actor,a)}}),s}static checkDuplicatus(e,t,a){let s=se(t,"system.extra.duplicatus"),i=x.detectCreatureType(e).some(n=>n.spellImmunities.includes("Illusion"));s&&a.push({name:`Duplicatus - ${game.i18n.localize("doppelganger")}`,value:s,selected:!i,type:"effect",source:"Duplicatus"})}static prepareRangeAttack(e,t,a,s,i,n,r=void 0){e.push(...P.getVantageAsModifier(t,game.i18n.localize("LocalizedIDs.restrictedSenseSight"),-2)),this.getCombatSkillModifier(t,s,e);let l=this.getTargetSizeAndModifier(t,s,e),c=Number(t.system.rangeStats.defenseMalus)*-1;c!=0&&e.push({name:`${game.i18n.localize("statuseffects")} - ${game.i18n.localize("MODS.defenseMalus")}`,value:c,type:"defenseMalus",selected:!0});let m=new Set(["short","medium","long","rangesense","extreme"]);m.delete(P.hasVantage(t,game.i18n.localize("LocalizedIDs.senseOfRange"))?"long":"rangesense"),F.hasAbility(t,game.i18n.localize("LocalizedIDs.extremeShot"))||m.delete("extreme");let d=F.hasAbility(t,game.i18n.localize("LocalizedIDs.drivingArcher")),p=F.hasAbility(t,game.i18n.localize("LocalizedIDs.mountedArcher")),f;p&&H.isRiding(t)?f=He(b.mountedRangeOptionsSpecAb):d?f=He(b.drivingArcherOptions):f=He(b.mountedRangeOptions);let h={};for(let y of Object.keys(f))h[`${game.i18n.localize("mountedRangeOptions."+y)} (${f[y]})`]=f[y];this.swarmModifiers(t,"attack",e),ue(a,{rangeOptions:m,rangeDistance:Array.from(m)[ne.distanceModifier(game.canvas.tokens.get(i),s,r)],visionOptions:b.rangeVision,mountedOptions:h,shooterMovementOptions:b.shooterMovementOptions,targetMovementOptions:b.targetMomevementOptions,targetSize:l,combatSpecAbs:n})}static swarmModifiers(e,t,a){e.system.swarm?.count>1&&(t=="attack"?a.push({name:`${game.i18n.localize("swarm.name")} - ${game.i18n.localize("MODS.defenseMalus")}`,value:e.system.swarm.parry,type:"defenseMalus",selected:!0},{name:`${game.i18n.localize("swarm.name")} - ${game.i18n.localize("CHARAbbrev.AT")}`,value:e.system.swarm.attack,selected:!0},{name:`${game.i18n.localize("swarm.name")} - ${game.i18n.localize("CHARAbbrev.damage")}`,value:e.system.swarm.damage,type:"dmg",selected:!0}):a.push({name:`${game.i18n.localize("swarm.name")} - ${game.i18n.localize("CHARAbbrev.PA")}`,value:e.system.swarm.parry,selected:!0}))}static prepareMeleeAttack(e,t,a,s,i,n){let r="short";game.user.targets.forEach(m=>{if(m.actor){for(let d of m.actor.items)if((d.type=="meleeweapon"&&d.system.worn.value||d.type=="trait"&&d.system.traitType.value=="meleeAttack"&&d.system.pa)&&(b.meleeRangesArray.indexOf(d.system.reach.value)>b.meleeRangesArray.indexOf(r)&&(r=d.system.reach.value),r=="long"))break}});let l=this.getTargetSizeAndModifier(t,s,e);this.getCombatSkillModifier(t,s,e);let c=Number(t.system.meleeStats.defenseMalus)*-1;c!=0&&e.push({name:`${game.i18n.localize("statuseffects")} - ${game.i18n.localize("MODS.defenseMalus")}`,value:c,type:"defenseMalus",selected:!0}),this.swarmModifiers(t,"attack",e),ue(a,{visionOptions:b.meleeRangeVision(a.mode),weaponSizes:b.meleeRanges,melee:!0,showAttack:!0,targetWeaponSize:r,combatSpecAbs:i,meleeSizeOptions:b.meleeSizeCategories,targetSize:l,constricted:t.hasCondition("constricted"),wrongHandDisabled:n,offHand:!n&&se(s,"system.worn.offHand")})}static prepareMeleeParry(e,t,a,s,i,n){let r=o.getDefenseMalus(e,t);this.swarmModifiers(t,"parry",e),ue(a,{visionOptions:b.meleeRangeVision(a.mode),showDefense:!0,isRangeDefense:r,wrongHandDisabled:n&&se(s,"system.worn.offHand"),offHand:!n&&se(s,"system.worn.offHand")&&!N.isShield(s),melee:!0,combatSpecAbs:i,constricted:t.hasCondition("constricted")})}static _chatLineHelper(e,t){return`${game.i18n.localize(e)}: ${t||"-"}`}static setupDialog(e,t,a,s,i){return null}setupEffect(e,t={},a){return o.getSubClass(this.type).setupDialog(e,t,this,this.parent,a)}static checkEquality(e,t){return t.type==e.type&&e.name==t.name&&e.system.description?.value==t.system.description?.value}static async combineItem(e,t,a,s=!0){return e=He(e),e.system.quantity.value+=t.system.quantity.value,await a.updateEmbeddedDocuments("Item",[e],{render:s})}static areEquals(e,t){return e.type!=t.type||e.id==t.id?!1:o.getSubClass(e.type).checkEquality(e,t)}static async stackItems(e,t,a,s=!0){return await o.getSubClass(e.type).combineItem(e,t,a,s)}_setupCardOptions(e,t,a){let s=ChatMessage.getSpeaker();return{speaker:{alias:s.alias,scene:s.scene},flags:{img:s.token?canvas.tokens.get(s.token).document.img:this.img},title:t,template:e}}async itemTest({testData:e,cardOptions:t},a={}){e=await R.rollDices(e,t);let s=await R.rollTest(e);if(s.postFunction="itemTest",game.user.targets.size){t.isOpposedTest=e.opposable;let i=` - ${game.i18n.localize("Opposed")}`;t.isOpposedTest&&t.title.match(i+"$")!=i&&(t.title+=i)}return a.suppressMessage||R.renderRollCard(t,s,a.rerenderMessage),{result:s,cardOptions:t}}static chatData(e,t){return[]}static getSubClass(e){return game.dsa5.config.ItemSubclasses[e]||o}async postItem(){o.getSubClass(this.type)._postItem(this)}static async _postItem(e){let t=He(e),a=se(t,"system.obfuscation.details"),s=se(t,"system.obfuscation.description");if(ue(t,{properties:a?[]:o.getSubClass(e.type).chatData(He(t.system),e.name),descriptionObfuscated:s}),t.hasPrice="price"in t.system&&!a,t.hasPrice){let r=t.system.price.value;t.system.QL&&(r=o.getSubClass(t.type).consumablePrice(t));let l=await Q._moneyToString(r);t.properties.push(`${game.i18n.localize("price")}: ${l}`)}e.pack&&(t.itemLink=e.link),t.img.includes("/blank.webp")&&(t.img=null);let i=await renderTemplate("systems/dsa5/templates/chat/post-item.html",t),n=g.chatDataSetup(i);ChatMessage.create(n)}},ws=class extends C{static{u(this,"PlantItemDSA5")}static chatData(e,t){return[this._chatLineHelper("effect",e.effect),this._chatLineHelper("PLANT.recipes",e.recipes),this._chatLineHelper("PLANT.usages",e.usages)]}},vs=class extends C{static{u(this,"MagicalSignItemDSA5")}static chatData(e,t){let a=[this._chatLineHelper("AsPCost",e.asp)];return e.category==2&&a.push(this._chatLineHelper("feature",e.feature)),a}},Ts=class extends C{static{u(this,"DemonmarkItemDSA5")}static chatData(e,t){return[this._chatLineHelper("attributes",e.attribute),this._chatLineHelper("skills",e.skills),this._chatLineHelper("domains",e.domain)]}},Ss=class extends C{static{u(this,"TrapItemDSA5")}static chatData(e,t){return[]}},As=class extends C{static{u(this,"PatronItemDSA5")}static chatData(e,t){return[this._chatLineHelper("skills",e.talents),this._chatLineHelper("culture",e.culture),this._chatLineHelper("Category",game.i18n.localize(`PATRON.${e.category}`))]}},Cs=class extends C{static{u(this,"MoneyItemDSA5")}static checkEquality(e,t){return t.type==e.type&&game.i18n.localize(e.name)==game.i18n.localize(t.name)&&e.system.description?.value==t.system.description?.value}},Ds=class extends C{static{u(this,"AggregatedTestItemDSA5")}static async _postItem(e){let t="",a=game.i18n.localize("Ongoing");e.system.cummulatedQS.value>=10?(a=game.i18n.localize("Success"),t=`${await TextEditor.enrichHTML(e.system.partsuccess,{secrets:this.isOwner,async:!0})}${await TextEditor.enrichHTML(e.system.success,{secrets:this.isOwner,async:!0})}`):e.system.cummulatedQS.value>=6?(a=game.i18n.localize("PartSuccess"),t=`${await TextEditor.enrichHTML(e.system.partsuccess,{secrets:this.isOwner,async:!0})}`):e.system.allowedTestCount.value-e.system.usedTestCount.value<=0&&(a=game.i18n.localize("Failure"));let s=[this._chatLineHelper("cummulatedQS",`${e.system.cummulatedQS.value} / 10`),this._chatLineHelper("interval",e.system.interval.value),this._chatLineHelper("probes",`${e.system.usedTestCount.value} / ${e.system.allowedTestCount.value}`),this._chatLineHelper("result",a),t],i=se(e,"system.obfuscation.description"),n=await renderTemplate("systems/dsa5/templates/chat/aggregatedTestResult.html",{descriptionObfuscated:i,item:e,properties:s}),r=g.chatDataSetup(n);ChatMessage.create(r)}},Ms=class extends C{static{u(this,"AmmunitionItemDSA5")}static chatData(e,t){return[this._chatLineHelper("ammunitiongroup",game.i18n.localize(e.ammunitiongroup.value))]}},Is=class extends C{static{u(this,"EffectWrapperItemDSA5")}},Es=class extends C{static{u(this,"ArmorItemDSA5")}static chatData(e,t){let a=[this._chatLineHelper("protection",e.protection.value),this._chatLineHelper("encumbrance",e.encumbrance.value)];return e.effect.value!=""&&a.push(this._chatLineHelper("effect",e.effect.value)),a}},ra=class extends C{static{u(this,"CantripItemDSA5")}static chatData(e,t){return[this._chatLineHelper("duration",e.duration.value),this._chatLineHelper("targetCategory",e.targetCategory.value),this._chatLineHelper("feature",e.feature.value)]}},$s=class extends ra{static{u(this,"BlessingItemDSA5")}},Et=class o extends C{static{u(this,"SpellItemDSA5")}static chatData(e,t){return[this._chatLineHelper("castingTime",e.castingTime.value),this._chatLineHelper("AsPCost",e.AsPCost.value),this._chatLineHelper("distribution",e.distribution.value),this._chatLineHelper("duration",e.duration.value),this._chatLineHelper("reach",e.range.value),this._chatLineHelper("targetCategory",e.targetCategory.value),this._chatLineHelper("effect",g.replaceConditions(g.replaceDies(e.effect.value)))]}static async getCallbackData(e,t,a){e.testDifficulty=0,e.situationalModifiers=O._parseModifiers(t);let s=new FormDataExtended(t.find("form")[0]).object;e.calculatedSpellModifiers={castingTime:t.find(".castingTime").text(),cost:t.find(".aspcost").text(),reach:t.find(".reach").text(),maintainCost:t.find(".maintainCost").text()},e.situationalModifiers.push({name:game.i18n.localize("removeGesture"),value:Number(s.removeGesture)||0},{name:game.i18n.localize("removeFormula"),value:Number(s.removeFormula)||0},{name:game.i18n.localize("castingTime"),value:t.find(".castingTime").data("mod")},{name:game.i18n.localize("cost"),value:t.find(".aspcost").data("mod")},{name:game.i18n.localize("reach"),value:t.find(".reach").data("mod")},{name:game.i18n.localize("zkModifier"),value:s.zkModifier||0},{name:game.i18n.localize("skModifier"),value:s.skModifier||0},{name:game.i18n.localize("maintainedSpells"),value:s.maintainedSpells*-1}),e.extensions=o.getSpecAbModifiers(t),e.advancedModifiers={chars:[0,1,2].map(i=>s[`ch${i}`]),fws:s.fw,qls:s.qs},C.changeChars(e.source,...[0,1,2].map(i=>s[`characteristics${i}`])),await this.applyExtensions(e.source,e.extensions,a)}static async applyExtensions(e,t,a){N.ensureNumber(e);let s=Object.keys(Se.rollModifiers).map(i=>`${i}.mod`);for(let i of t){let n=fromUuidSync(i.uuid);if(n)for(let r of n.effects)for(let l of r.changes)Se.rollChanges.includes(l.key)||s.includes(l.key)||(l.key=="macro.transform"?await g.callItemTransformationMacro(l.value,e,r):r.apply(e,l))}}static getSpecAbModifiers(e){let t=[];for(let a of e.find(".specAbs.active"))t.push({name:a.dataset.name,title:a.dataset.tooltip,uuid:a.dataset.uuid});return t}static attackSpellMalus(e){let t=[];return e.system.effectFormula.value&&t.push({name:game.i18n.localize("MODS.defenseMalus"),value:-4,type:"defenseMalus",selected:!0,source:e.name}),t}static getPropertyModifiers(e,t){let a=["ceremony","liturgy"].includes(t.type),s=(se(t,"system.feature")||"").replace(/\(a-z äöü-\)/gi,"").split(",").map(c=>c.trim()),i=[],n=a?"KaPCost":"AsPCost",r=["FP","step","QL","TPM","FW",n];for(let c of r){let m=c=="step"?"":c,d=se(e.system.skillModifiers,`feature.${c}`);i.push(...d.filter(p=>s.includes(p.target)).map(p=>({name:p.source,value:p.value,type:m,source:p.source})))}let l=se(e.system.skillModifiers,`conditional.${n}`);return i.push(...l.map(c=>({name:c.target,value:c.value,source:c.source,type:n}))),i}static foreignSpellModifier(e,t,a,s){if(game.settings.get("dsa5","enableForeignSpellModifer")&&["npc","character"].includes(e.type)&&["spell","ritual"].includes(t.type)){let i=t.system.distribution.value.split(",").map(l=>l.trim().toLowerCase()),n=new RegExp(`(${game.i18n.localize("tradition")}|\\)|\\()`,"g"),r=e.system.tradition.magical.replace(n,"").split(",").map(l=>l.trim().toLowerCase());r.push(game.i18n.localize("general").toLowerCase()),s.isForeign=!i.some(l=>r.includes(l)),s.isForeign&&a.push({name:game.i18n.localize("DSASETTINGS.enableForeignSpellModifer"),value:-2,selected:!0})}}static getSituationalModifiers(e,t,a,s){e.push(...te.getTalentBonus(t,s.name,["advantage","disadvantage","specialability","equipment"]),...P.getVantageAsModifier(t,game.i18n.localize("LocalizedIDs.magicalAttunement"),1,!0),...P.getVantageAsModifier(t,game.i18n.localize("LocalizedIDs.magicalRestriction"),-1,!0),...P.getVantageAsModifier(t,game.i18n.localize("LocalizedIDs.boundToArtifact"),-1,!0),...this.getPropertyModifiers(t,s),...this.attackSpellMalus(s)),this.foreignSpellModifier(t,s,e,a),game.user.targets.size&&game.user.targets.forEach(i=>{i.actor&&(x.addCreatureTypeModifiers(i.actor,s,e,t),this.checkDuplicatus(t,i.actor,e))}),e.push(...t.getSkillModifier(s.name,s.type));for(let i of t.system.skillModifiers.global)e.push({name:i.source,value:i.value});this.getSkZkModifier(a,s)}static setupDialog(e,t,a,s,i){let n="spell";["ceremony","liturgy"].includes(a.type)&&(n="liturgy");let r=`${a.name} ${game.i18n.localize(`${a.type}Test`)}${t.subtitle||""}`,l={opposable:a.system.effectFormula.value.length>0,source:a,extra:{actor:s.toObject(!1),options:t,speaker:C.buildSpeaker(s,i)},advancedModifiers:{chars:[0,0,0],fws:0,qls:0},calculatedSpellModifiers:{castingTime:0,cost:0,reach:0,maintainCost:0}},c={rollMode:t.rollMode,spellCost:a.system.AsPCost.value,maintainCost:a.system.maintainCost.value,spellCastingTime:a.system.castingTime.value,spellReach:a.system.range.value,canChangeCost:a.system.canChangeCost.value=="true",canChangeRange:a.system.canChangeRange.value=="true",canChangeCastingTime:a.system.canChangeCastingTime.value=="true",hasSKModifier:a.system.resistanceModifier.value=="SK",hasZKModifier:a.system.resistanceModifier.value=="ZK",maxMods:Math.floor(Number(a.system.talentValue.value)/4),extensions:this.prepareExtensions(s,a),variableBaseCost:a.system.variableBaseCost=="true",characteristics:[1,2,3].map(f=>a.system[`characteristic${f}`].value)},m=s?z.getRollModifiers(s,a):[];this.getSituationalModifiers(m,s,c,a),c.situationalModifiers=m;let d={title:r,template:`systems/dsa5/templates/dialog/${n}-enhanced-dialog.html`,data:c,callback:u(async(f,h={})=>(p.rollMode=f.find('[name="rollMode"]:checked').val(),await this.getCallbackData(l,f,s),ue(l.extra.options,h),{testData:l,cardOptions:p}),"callback")},p=s._setupCardOptions("systems/dsa5/templates/chat/roll/spell-card.html",r,i);return R.setupDialog({dialogOptions:d,testData:l,cardOptions:p})}static prepareExtensions(e,t){return e.items.filter(a=>a.type=="spellextension"&&a.system.source==t.name&&a.system.category==t.type).map(a=>(a.shortName=a.name.split(" - ").length>1?a.name.split(" - ")[1]:a.name,a.descr=$(a.system.description.value).text()||"",a))}},oa=class extends Et{static{u(this,"LiturgyItemDSA5")}static chatData(e,t){return[this._chatLineHelper("castingTime",e.castingTime.value),this._chatLineHelper("KaPCost",e.AsPCost.value),this._chatLineHelper("distribution",e.distribution.value),this._chatLineHelper("duration",e.duration.value),this._chatLineHelper("reach",e.range.value),this._chatLineHelper("targetCategory",e.targetCategory.value),this._chatLineHelper("effect",g.replaceConditions(g.replaceDies(e.effect.value)))]}},Os=class extends oa{static{u(this,"CeremonyItemDSA5")}static getCallbackData(e,t,a){super.getCallbackData(e,t,a),e.situationalModifiers.push({name:game.i18n.localize("CEREMONYMODIFIER.artefact"),value:t.find('[name="artefactUsage"]').is(":checked")?1:0},{name:game.i18n.localize("place"),value:t.find('[name="placeModifier"]').val()},{name:game.i18n.localize("time"),value:t.find('[name="timeModifier"]').val()})}static getSituationalModifiers(e,t,a,s){super.getSituationalModifiers(e,t,a,s),ue(a,{isCeremony:!0,locationModifiers:b.ceremonyLocationModifiers,timeModifiers:b.ceremonyTimeModifiers})}},xs=class extends C{static{u(this,"CombatskillDSA5")}static chatData(e,t){return[this._chatLineHelper("Description",game.i18n.localize(`Combatskilldescr.${t}`))]}static setupDialog(e,t,a,s,i){let n=t.mode,r=a.name+" "+game.i18n.localize(n+"test"),l={opposable:!0,source:a,mode:n,extra:{actor:s.toObject(!1),options:t,speaker:C.buildSpeaker(s,i)}},c={title:r,template:"systems/dsa5/templates/dialog/combatskill-dialog.html",data:{rollMode:t.rollMode},callback:u((d,p={})=>(m.rollMode=d.find('[name="rollMode"]:checked').val(),l.situationalModifiers=O._parseModifiers(d),ue(l.extra.options,p),{testData:l,cardOptions:m}),"callback")},m=s._setupCardOptions("systems/dsa5/templates/chat/roll/combatskill-card.html",r,i);return R.setupDialog({dialogOptions:c,testData:l,cardOptions:m})}},zs=class extends C{static{u(this,"ConsumableItemDSA")}static chatData(e,t){return[this._chatLineHelper("qualityStep",e.QL),this._chatLineHelper("effect",g.replaceDies(e.QLList.split(`
+ `);n.ret=await c.call(this,a,this.item.actor)}catch(c){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(c),n.error=!0}}}else ui.notifications.error(game.i18n.format("DSAError.macroNotFound",{name:t}));return n}async executeOnUseEffect(){if(!this.item.actor)return;if(!game.user.can("MACRO_SCRIPT"))return ui.notifications.warn("You are not allowed to use JavaScript macros.");let e=o.getOnUseEffect(this.item);try{let t=Object.getPrototypeOf(async function(){}).constructor;await new t("item","actor",e).call(this,this.item,this.item.actor)}catch(t){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(t),console.warn(t.stack)}}static getOnUseEffect(e){return e.getFlag("dsa5","onUseEffect")}async automatedAnimation(e,t={}){g.moduleEnabled("autoanimations")&&console.warn("Animations for on use effects not enabled yet")}static effectBaseDummy(e,t,a){return{name:e,icon:"icons/svg/aura.svg",changes:t,duration:a,flags:{dsa5:{value:null,description:e}}}}effectDummy(e,t,a){return o.effectBaseDummy(e,t,a)}async socketedConditionAddActor(e,t){if(game.user.isGM){let a=typeof t=="string";a&&(t=wn(CONFIG.statusEffects.find(i=>i.id==t)),t.name=game.i18n.localize(t.name));let s=[];for(let i of e)a?await i.addCondition(t,1,!1,!1):await i.addCondition(t),s.push(i.name);await this.createInfoMessage(t,s)}else{let a={id:this.item.uuid,data:t,actors:e.map(s=>s.id)};game.socket.emit("system.dsa5",{type:"socketedConditionAddActor",payload:a})}}async createInfoMessage(e,t,a=!0){if(t.length){let s=a?"ActiveEffects.appliedEffect":"ActiveEffects.removedEffect",i=game.i18n.format(s,{source:e.name,target:t.join(", ")});await ChatMessage.create(g.chatDataSetup(i))}}async socketedRemoveCondition(e,t,a=1){if(game.user.isGM){let s=[];for(let n of e){let r=canvas.tokens.get(n);r.actor&&(await r.actor.removeCondition(t,a,!1),s.push(r.name))}let i=CONFIG.statusEffects.find(n=>n.id==t);i.name=game.i18n.localize(i.name),await this.createInfoMessage(i,s,!1)}else{let s={id:this.item.uuid,coreId:t,targets:e};game.socket.emit("system.dsa5",{type:"socketedRemoveCondition",payload:s})}}async socketedActorTransformation(e,t){if(game.user.isGM)for(let a of e){let s=canvas.tokens.get(a);s.actor&&await s.actor.update(t)}else{let a={id:this.item.uuid,targets:e,update:t};game.socket.emit("system.dsa5",{type:"socketedActorTransformation",payload:a})}}async socketedConditionAdd(e,t){if(game.user.isGM){let a=typeof t=="string";a&&(t=wn(CONFIG.statusEffects.find(i=>i.id==t)),t.name=game.i18n.localize(t.name));let s=[];for(let i of e){let n=canvas.tokens.get(i);n.actor&&(a?await n.actor.addCondition(t,1,!1,!1):await n.actor.addCondition(t),s.push(n.name))}await this.createInfoMessage(t,s)}else{let a={id:this.item.uuid,data:t,targets:e};game.socket.emit("system.dsa5",{type:"socketedConditionAdd",payload:a})}}};var pe=class o{static{u(this,"DSATriggers")}static EVENTS={ARMOR_TRANSFORMATION:4,DAMAGE_TRANSFORMATION:5,POST_ROLL:6,POST_OPPOSED:7};static async postOpposed(e){let t=g.getSpeaker(e.attacker.speaker);t&&await this.runMacro(t,e.attacker.testResult,o.EVENTS.POST_OPPOSED,e)}static async postRoll(e){let t=g.getSpeaker(e.testData.speaker);t&&await this.runMacro(t,e.testData,o.EVENTS.POST_ROLL,e)}static async callMacro(e,t,a,s={}){return await new J(e).callMacro(t,a,s)}static async runMacro(e,t,a,s){if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else for(let[i,n]of Object.entries(e.dsatriggers[a])){let r=e.items.get(i),l=r.effects.get(n),c=l.getFlag("dsa5","args3");try{let m=Object.getPrototypeOf(async function(){}).constructor;return await new m("actor","testData","type","data","source","ef",c).call(this,e,t,a,s,r,l)}catch(m){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(m)}}}};var{mergeObject:gt,getProperty:X,duplicate:na,setProperty:vn}=foundry.utils;function Tn(o,e={}){g.moduleEnabled("autoanimations")&&console.warn("Animations for on use effects not enabled yet")}u(Tn,"automatedAnimation");function kr(o,e,t){return J.effectBaseDummy(o,e,t)}u(kr,"effectDummy");async function fs(o,e,t,a,s,i={}){let n={};if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else{let l=await game.packs.get(o)?.getDocuments({name:e});if(!l||!l.length){for(let c of game.packs.filter(m=>m.documentName=="Macro"&&/\(internal\)/.test(m.metadata.label)))if(l=await c.getDocuments({name:e}),l.length)break}if(l.length){let c=Object.getPrototypeOf(async function(){}).constructor,m=new c("actor","item","qs","automatedAnimation","args",l[0].command);try{i.result=n;let d=gt({automatedAnimation:Tn,effectDummy:kr},this);await m.call(d,t,a,s,Tn,i)}catch(d){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(d),n.error=!0}}else ui.notifications.error(game.i18n.format("DSAError.macroNotFound",{name:e}))}return n}u(fs,"callMacro");Hooks.once("i18nInit",()=>{Z.effectDurationRegexes=[{regEx:new RegExp(game.i18n.localize("DSAREGEX.combatRounds"),"i"),seconds:5},{regEx:new RegExp(game.i18n.localize("DSAREGEX.minutes"),"i"),seconds:60},{regEx:new RegExp(game.i18n.localize("DSAREGEX.hours"),"i"),seconds:3600},{regEx:new RegExp(game.i18n.localize("DSAREGEX.days"),"i"),seconds:3600*24},{regEx:new RegExp(game.i18n.localize("DSAREGEX.weeks"),"i"),seconds:3600*24*7},{regEx:new RegExp(game.i18n.localize("DSAREGEX.months"),"i"),seconds:3600*24*30},{regEx:new RegExp(game.i18n.localize("DSAREGEX.years"),"i"),seconds:3600*24*350}]});var Z=class o extends ActiveEffectConfig{static{u(this,"DSAActiveEffectConfig")}static AdvantageRuleItems=new Set(["armor","meleeweapon","rangeweapon"]);static get defaultOptions(){return gt(super.defaultOptions,{resizable:!0})}static async callMacro(e,t,a,s,i,n={}){return await fs(e,t,a,s,i,n)}static async startDelayedEffect(e,t){t.update({"system.delayed":!1,duration:e,"flags.dsa5.-=onDelayed":null})}static onDelayedEffect(e,t){let a=!0;if(t.system.delayed){let s=t.system?.originalDuration||{seconds:"",rounds:""};if(gt(s,{startRound:game.combat?.round,startTurn:game.combat?.turn,startTime:game.time.worldTime}),!s.rounds&&s.seconds&&(s.rounds=Number(s.seconds)/5),(t.changes.length||t.statuses.size)&&(this.startDelayedEffect(s,t),a=!1),t.system.macroEffect){let i=t.system.initialTestData,n=game.actors.get(t.system.sourceActor),r=t.system.source,l=na(t.system.macroEffect);delete l.flags.dsa5?.onDelayed,l.system.delayed=!1,l.duration=s,this.applyAdvancedFunction(e,[l],r,i,n)}}return a}static async onEffectRemove(e,t){let a=X(t,"flags.dsa5.onRemove");if(a)if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else try{let s=Object.getPrototypeOf(async function(){}).constructor;await new s("effect","actor",a).call(this,t,e)}catch(s){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(s),console.warn(s.stack)}}async checkTimesUpInstalled(){let e=g.moduleEnabled("times-up");return!e&&game.user.isGM&&ui.notifications.warn("DSAError.shouldTimesUp",{localize:!0}),e}async _render(e=!1,t={}){await super._render(e,t);let a=0,s=X(this.object,"parent.type"),i=["meleeweapon","rangeweapon"].includes(s)||s=="trait"&&["meleeAttack","rangeAttack"].includes(X(this.object,"parent.system.traitType.value")),n={hasSpellEffects:i||["spell","liturgy","ritual","skill","ceremony","consumable","poison","disease","ammunition"].includes(s)||["specialability"].includes(s)&&X(this.object,"parent.system.category.value")=="Combat",hasDamageTransformation:["ammunition","meleeweapon","rangeweapon"].includes(s),hasTriggerEffects:["specialability"].includes(s),hasSuccessEffects:["poison","disease"].includes(s)},r=[];if((n.hasSpellEffects||n.hasDamageTransformation||n.hasTriggerEffects)&&r.push({name:"ActiveEffects.advancedFunctions.none",index:0}),n.hasSpellEffects)for(let y of["systemEffect","macro","creature"])r.push({name:`ActiveEffects.advancedFunctions.${y}`,index:a+=1});n.hasDamageTransformation&&r.push({name:"ActiveEffects.advancedFunctions.armorPostprocess",index:pe.EVENTS.ARMOR_TRANSFORMATION},{name:"ActiveEffects.advancedFunctions.damagePostprocess",index:pe.EVENTS.DAMAGE_TRANSFORMATION}),n.hasTriggerEffects&&r.push({name:"ActiveEffects.advancedFunctions.postRoll",index:pe.EVENTS.POST_ROLL},{name:"ActiveEffects.advancedFunctions.postOpposed",index:pe.EVENTS.POST_OPPOSED});let l={systemEffects:this.getStatusEffects(),canEditMacros:game.user.isGM||game.settings.get("dsa5","playerCanEditSpellMacro")},c=["players","player","playergm","gm"].reduce((y,k)=>(y[k]=game.i18n.localize(`ActiveEffects.messageReceivers.${k}`),y),{}),m={1:"ActiveEffects.onSuccess",2:"ActiveEffects.onFailure"},d=o.AdvantageRuleItems.has(s),p=[2,6,7],f=$(this._element);f.find(".tabs").append(`${game.i18n.localize("advanced")}`);let h=await renderTemplate("systems/dsa5/templates/status/advanced_effect.html",{effect:this.object,advancedFunctions:r,effectConfigs:n,macroIndexes:p,messageReceivers:c,canWeaponAdvantages:d,equipmentAdvantageOptions:{1:game.i18n.localize(`AdvantageRuleItems.${s}.1`),2:game.i18n.localize(`AdvantageRuleItems.${s}.2`)},applySuccessConditions:m,config:l,isWeapon:i,dispositions:Object.entries(CONST.TOKEN_DISPOSITIONS).reduce((y,k)=>(y[k[1]]=`TOKEN.DISPOSITION.${k[0]}`,y),{2:game.i18n.localize("all")})});f.find('.tab[data-tab="effects"]').after($(h)),f.find(".advancedSelector").on("change",y=>{let k=this.object;k.flags.dsa5.advancedFunction=$(y.currentTarget).val(),renderTemplate("systems/dsa5/templates/status/advanced_functions.html",{effect:k,config:l,macroIndexes:p}).then(C=>{f.find(".advancedFunctions").html(C)})}),f.find(".auraSelector").on("change",y=>{f.find(".auraDetails").toggleClass("dsahidden",!y.currentTarget.checked),f.find(".auraBox").toggleClass("groupbox",y.currentTarget.checked)}),this.object.statuses.size&&game.i18n.has(this.object.description)&&f.find('[data-tab="details"] .editor').replaceWith(`
${game.i18n.localize(this.object.description)}
`),this.checkTimesUpInstalled()}getStatusEffects(){return CONFIG.statusEffects.map(e=>({id:e.id,name:game.i18n.localize(e.name)})).sort((e,t)=>e.name.localeCompare(t.name))}static applyRollTransformation(e,t,a){let s="",i=t.origin;for(let n of i.effects)try{if(Number(X(n,"flags.dsa5.advancedFunction"))==a)if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else try{let r=Object.getPrototypeOf(function(){}).constructor;new r("ef","callMacro","actor","msg","source","options",X(n,"flags.dsa5.args3")).call(this,n,fs,e,s,i,t)}catch(r){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(r),console.warn(r.stack)}}catch(r){console.warn("Unable to apply advanced effect",r,n)}return t.origin=i,{msg:s,options:t}}static async applyAdvancedFunction(e,t,a,s,i,n=!0){let r="",l=[],c=!1,m=[],d=new Set;for(let p of t){p.origin&&delete p.origin;let f=Number(X(p,"flags.dsa5.specStep"))||0;try{let h=Number(X(p,"flags.dsa5.advancedFunction")),y=Math.min(s.qualityStep||0,6),k=X(p,"flags.dsa5.resistRoll"),C=X(p,"flags.dsa5.isAura");if(C){let v=`${X(p,"flags.dsa5.auraRadius")||1}`.replace(/q(l|s)/i,y),I=(await new Roll(v).evaluate()).total;vn(p,"flags.dsa5.auraRadius",I)}if(k&&!n){let v=k.split(" "),I=`${v.pop()}`;l.push({skill:v.join(" "),mod:Math.round(Roll.safeEval(`${I}`.replace(/q(l|s)/i,y).replaceAll("step",f)))||0,effect:p,target:e,token:e.token?.id})}else{c=!0,d.has(p.name)||d.add(p.name);let v=X(p,"flags.dsa5.onDelayed"),I={duration:{seconds:v},system:{delayed:!0,originalDuration:p.duration}},S=p.changes&&p.changes.length>0||C&&!h;if(h)switch(h){case 1:{let A=`${X(p,"flags.dsa5.args1")}`||"1";/,/.test(A)?A=Number(A.split(",")[y-1]):A=Number(A.replace(game.i18n.localize("CHARAbbrev.QS"),y));let M=X(p,"flags.dsa5.args0"),T=game.i18n.localize(`CONDITION.${M}`),L={name:`${a.name} (${T})`,duration:p.duration};v&>(L,I),await e.addTimedCondition(M,A,!1,!1,L)}break;case 2:if(!game.user.can("MACRO_SCRIPT"))ui.notifications.warn("You are not allowed to use JavaScript macros.");else if(v){let A=na(p);A.changes=[],S=!0,gt(p,{system:{macroEffect:A,sourceActor:i?.id,source:a,initialTestData:{qualityStep:s.qualityStep}}})}else try{let A=Object.getPrototypeOf(async function(){}).constructor;await new A("effect","actor","callMacro","msg","source","actor","sourceActor","testData","qs",X(p,"flags.dsa5.args3")).call(this,p,e,fs,r,a,e,i,s,y)}catch(A){ui.notifications.error("There was an error in your macro syntax. See the console (F12) for details"),console.error(A),console.warn(A.stack)}break;case 3:let j=(X(p,"flags.dsa5.args4")||"").split(",").map(A=>`@Compendium[${A.trim().replace(/(@Compendium\[|\])/)}]`).join(" ");r+=`
`).join("")),new foundry.applications.api.DialogV2({window:{title:r.name},content:h,buttons:[{action:"yes",icon:"fa fa-check",label:"HELP.pay",default:!0,callback:u(async()=>{if(await m.applyMana(Number(Fe(r,"flags.dsa5.maintain")),Fe(r,"flags.dsa5.payType"))){let k={startTime:game.time.worldTime};game.combat&&(k.startRound=game.combat.round,k.startTurn=game.combat.turn),m.updateEmbeddedDocuments("ActiveEffect",[{_id:r._id,duration:k}])}},"callback")},{action:"delete",icon:"fas fa-trash",label:"delete",callback:u((y,k,C)=>{for(let v of k.form.elements)v.classList.contains("effectRemoveSelector")&&d.push(v.value);m.deleteEmbeddedDocuments("ActiveEffect",d,{noHook:!0})},"callback")}]}).render(!0),!1}}),Hooks.on("updateActor",(r,l)=>{!game.user.isGM&&r.limited&&wr(l,"system.merchant.hidePlayer")&&ui.sidebar.render(!0)}),Hooks.on("deleteActiveEffect",(r,l)=>{if(!g.isActiveGM()||l.noHook)return;let c=r.parent;e(r,l),c&&c.documentName=="Actor"&&(r.statuses.has("bloodrush")?c.addCondition("stunned",2,!1,!1):(r.statuses.has("dead")||r.statuses.has("defeated"))&&game.combat&&c.markDead(!1),Z.onEffectRemove(c,r))}),Hooks.on("preDeleteActiveEffect",(r,l,c)=>{if(!g.isActiveGM()||l.noHook)return;let m=r.parent;if(m&&m.documentName=="Actor"&&(Z.onDelayedEffect(m,r)===!1||Hooks.call("deleteActorActiveEffect",m,r)===!1))return!1}),Hooks.on("dropActorSheetData",(r,l,c)=>{switch(c.data?.type){case"condition":return r.addCondition(c.data.payload.id,1,!1,!1),!1;case"lookup":return l._handleLookup(c.data),!1;case"fullpack":return l._addFullPack(c.data),!1}}),Hooks.on("createActiveEffect",(r,l,c)=>{g.isActiveGM()&&(o(r),t(r))}),Hooks.on("deleteActiveEffect",(r,l,c)=>{g.isActiveGM()&&o(r)}),Hooks.on("updateActiveEffect",(r,l,c)=>{g.isActiveGM()&&(o(r),a(r))});function o(r){if(game.combat&&r.changes.some(l=>/(system\.status\.initiative|system\.characteristics.mu|system\.characteristics\.ge)/.test(l.key))){let l=r.parent.id,c=game.combat.combatants.find(m=>m.actor.id==l);c&&c.recalcInitiative()}}u(o,"checkIniChange");let e=u(async(r,l)=>{if(!r.parent)return;let c=Fe(r,"flags.dsa5.removeMessage");if(!(game.settings.get("dsa5","notifyOnFadingEffects")&&r.parent.documentName=="Actor"||c))return;let m=[];switch(c){case"player":m=game.users.filter(d=>!d.isGM&&r.parent.testUserPermission(d,"OWNER"));break;case"playergm":m=game.users.filter(d=>r.parent.testUserPermission(d,"OWNER"));break;case"players":m=void 0;break;default:m=game.users.filter(d=>d.isGM)}m=m?.map(d=>d.id),ChatMessage.create(g.chatDataSetup(game.i18n.format("CHATNOTIFICATION.fadingEffect",{effect:r.name,actor:r.parent.link}),void 0,void 0,m))},"notifyFadingEffect"),t=u(async r=>{let l=r.parent;l&&(await a(r,{},l),(r.statuses.has("dead")||r.statuses.has("defeated"))&&game.combat&&await l.markDead(!0),r.statuses.has("unconscious")&&await l.addCondition("prone"))},"createEffects"),a=u(async(r,l={},c)=>{if(c||(c=r.parent),!c||c.documentName!="Actor")return;let m=/^system\.condition\./;for(let d of r.changes||[])m.test(d.key)&&d.mode==2&&(l[d.key.split(".")[2]]=Number(d.value));for(let d of Object.keys(l))if(c.system.condition[d]>=4&&(d=="inpain"?await c.initResistPainRoll(r):["encumbered","stunned","feared","confused","trance"].includes(d)?await c.addCondition("incapacitated"):d=="paralysed"?await c.addCondition("rooted"):["drunken","exhaustion"].includes(d)&&(await c.addCondition("stunned"),await c.removeCondition(d))),(Number(l.inpain)||0)>0&&!c.hasCondition("bloodrush")&&c.system.condition.inpain>0&&P.hasVantage(c,game.i18n.localize("LocalizedIDs.frenzy"))){await c.addCondition("bloodrush");let p=g.replaceConditions(`${game.i18n.format("CHATNOTIFICATION.gainsBloodrush",{character:""+c.name+""})}`);ChatMessage.create(g.chatDataSetup(p))}},"countableDependentEffects"),s=u(async(r,l)=>{(game.dsa5.apps.AskForNameDialog||hs).getDialog(r,l)},"askForName"),i=u(async r=>{if(g.isActiveGM()&&game.settings.get("dsa5","randomWeaponSelection")&&r.actor.type!="character"){let l=[],c=[],m=[];for(let p of r.actor.items)p.type=="meleeweapon"&&p.system.worn.value?N.isShield(p)?c.push(p):l.push(p):p.type=="rangeweapon"&&p.system.worn.value&&m.push(p);let d=[];if(l.length){let p=l[Math.floor(Math.random()*l.length)],f=p._id,h;!N.regex2h.test(p.name)&&c.length&&(h=c[Math.floor(Math.random()*c.length)]._id);for(let y of l)y._id!=f&&d.push({_id:y._id,system:{worn:{value:!1}}});for(let y of c)y._id!=h&&d.push({_id:y._id,system:{worn:{value:!1}}})}if(m.length){let p=m[Math.floor(Math.random()*m.length)]._id;for(let f of m)f._id!=p&&d.push({_id:f._id,system:{worn:{value:!1}}})}d.length&&r.actor.updateEmbeddedDocuments("Item",d)}},"randomWeaponSelection"),n=u(async(r,l)=>{if(!g.isActiveGM())return;let c=r.actor;if(c.hasPlayerOwner)return;let m=Number(game.settings.get("dsa5","obfuscateTokenNames"));if(m==0||Fe(c,"merchant.merchantType")=="loot")return;let d=canvas.scene.tokens.filter(f=>f.actor&&f.actor.id===c.id),p=game.i18n.localize("unknown");if([2,4].includes(m)){if(!(r.id||r._id))return;s(r,m);return}if(d.length>0&&m<3){let f=d.length;for(let h of d){let y=h.name.match(/\d+$/);y&&Number(y[0])>f&&(f=Number(y[0]))}p=`${d[0].name.replace(/ \d{1,}$/,"")} ${f+1}`}l.name=p},"obfuscateName");Hooks.on("updateToken",(r,l,c)=>{if(!r.rendered)return;let m={center:r.object.center,elevation:r.elevation};H.updateTokenHook(r,l,c);let d=c.animation?.name||r.object?.animationName;(r.object?.animationContexts.get(d)?.promise||Promise.resolve()).then(()=>{r.object?.drawAuras(),game.dsa5.apps.LightDialog&&game.dsa5.apps.LightDialog.onTokenMove(r,l,c,m)})}),Hooks.on("preDeleteToken",r=>{_e.onDeleteToken(r)}),Hooks.on("deleteToken",r=>{H.deleteTokenHook(r),Ve.hide(r)}),Hooks.on("canvasReady",r=>{for(let l of r.scene.tokens)l.object?.drawAuras()}),Hooks.on("preCreateToken",(r,l,c,m)=>{let d=r.actor;if(!d)return;let p={};Fe(d,"system.merchant.merchantType")=="loot"?It(p,{displayBars:0}):Fe(d,"system.config.autoBar")&&(It(p,{bar1:{attribute:"status.wounds"}}),d.system.isMage?It(p,{bar2:{attribute:"status.astralenergy"}}):d.system.isPriest?It(p,{bar2:{attribute:"status.karmaenergy"}}):It(p,{bar2:{attribute:"tbd"}})),Fe(d,"system.config.autoSize")&&g.calcTokenSize(d,p),n(r,p),r.updateSource(p)}),Hooks.on("createToken",(r,l,c)=>{l.noHook||(n(r,{}),i(r),H.createTokenHook(r,l,c),r.object?.drawAuras())}),Hooks.on("hoverToken",(r,l)=>{game.settings.get("dsa5","showWeaponsOnHover")&&(l?Ve.show(r):Ve.hide(r))})}u(ys,"default");var Ve=class{static{u(this,"TokenHoverHud")}static show(e){if(!game.combat||canvas.hud?.token?.rendered)return;let t=e.actor.items.filter(a=>a.type=="meleeweapon"||a.type=="rangeweapon"?a.system.worn.value:!1);if(t.length){let a=t.map(i=>``).join(" "),s=$(`
0&&(o.description=`${game.i18n.localize("Failure")}, ${game.i18n.localize("CHATNOTIFICATION.duplicatus")}`,o.successLevel=0)}}static async _rollConfirm(){return await new Roll("1d20").evaluate()}static async _rollSingleD20(o,e,t,a,s,i="",n=1){let r="";e=Math.round((e+a)*n);let l=o.total??o._total,c=game.dsa5.apps.DiceSoNiceCustomization.getAttributeConfiguration(t),m=e-l>=0,d=[{char:t,res:l,suc:m,tar:e}],p=m?1:-1,f=20,h=1,y={meleeweapon:"meleeStats",rangeweapon:"rangeStats"}[s.source.type];y&&(f=Math.min(s.extra.actor.system[y].botch,s.source.system.botch),h=Math.max(s.extra.actor.system[y].crit,s.source.system.crit)),N.improvisedWeapon.test(s.source.name)&&(F.hasAbility(s.extra.actor,game.i18n.localize("LocalizedIDs.improvisedWeaponMaster"))||(f=Math.min(19,f)),this._appendSituationalModifiers(s,`${game.i18n.localize("CHAR.ATTACK")} - ${game.i18n.localize("WEAPON.improvised")}`,2,"defenseMalus")),s.situationalModifiers.find(v=>v.name==game.i18n.localize("MODS.opportunityAttack")&&v.value!=0)&&(f=50,h=-50);let k=l<=h,C=l>=f;if(k||C){if(r=game.i18n.localize(k?"CriticalSuccess":"CriticalFailure"),p=k?3:-3,!game.settings.get("dsa5","noConfirmationRoll")){let v=await _DiceDSA5.manualRolls(await _DiceDSA5._rollConfirm(),"confirmationRoll",s.extra.options),I=$e(s.source,`system.${k?"critConfirm":"botchConfirm"}`)||0,S=e-Math.clamp(v.total+I,1,20);if(P.hasVantage(s.extra.actor,`${game.i18n.localize("LocalizedIDs.weaponAptitude")} (${i})`)&&!(S>=0)){let A=v.total;v=await _DiceDSA5.manualRolls(await _DiceDSA5._rollConfirm(),"LocalizedIDs.weaponAptitude",s.extra.options),S=e-Math.clamp(v.total+I,1,20),r+=`, ${game.i18n.format("usedWeaponExpertise",{a:A,b:v.total})}`}this._addRollDiceSoNice(s,v,c);let j=S>=0;C&&(j=!j),d.push({char:t,res:Math.clamp(v.total+I,1,20),suc:j,tar:e}),r=`${game.i18n.localize(j?"confirmed":"unconfirmed")} ${r}`,j?p=k?3:-3:p=k?2:-2}}else r=game.i18n.localize(m?"Success":"Failure");return{successLevel:p,characteristics:d,description:r,preData:s,modifiers:a,extra:{attackFromBehind:s.extra.attackFromBehind}}}static async rollFallingDamage(o){let e=o.roll,t=[];for(let s of e.terms[0].results)t.push({char:"damage",res:s.result,suc:!1});return{rollType:"fallingDamage",preData:o,modifiers:await this._situationalModifiers(o),extra:{},damage:Math.max(0,e.total),formula:e.formula,characteristics:t}}static async rollRegeneration(o){let e=await this._situationalModifiers(o),t=o.roll,a=[],s={rollType:"regenerate",preData:o,modifiers:e,extra:{}},i=[];o.regenerateLeP&&i.push("LeP"),o.extra.actor.system.isMage&&o.regenerateAsP&&i.push("AsP"),o.extra.actor.system.isPriest&&o.regenerateKaP&&i.push("KaP");let n=0;if(o.extra.actor.effects.some(l=>l.statuses.includes("sick"))){this._appendSituationalModifiers(o,game.i18n.localize("CONDITION.sick"),"*0");for(let l of i)a.push({char:l,res:0,die:"d6"}),s[l]=0,n+=2}else for(let l of i)this._appendSituationalModifiers(o,game.i18n.localize(`LocalizedIDs.regeneration${l}`),P.vantageStep(o.extra.actor,game.i18n.localize(`LocalizedIDs.regeneration${l}`)),l),this._appendSituationalModifiers(o,game.i18n.localize(`LocalizedIDs.weakRegeneration${l}`),P.vantageStep(o.extra.actor,game.i18n.localize(`LocalizedIDs.weakRegeneration${l}`))*-1,l),this._appendSituationalModifiers(o,game.i18n.localize(`LocalizedIDs.advancedRegeneration${l}`),F.abilityStep(o.extra.actor,game.i18n.localize(`LocalizedIDs.advancedRegeneration${l}`)),l),this._appendSituationalModifiers(o,`${game.i18n.localize(`CHARAbbrev.${l}`)} ${game.i18n.localize("Modifier")}`,o[`${l}Modifier`],l),this._appendSituationalModifiers(o,`${game.i18n.localize(`CHARAbbrev.${l}`)} ${game.i18n.localize("regenerate")}`,o[`regeneration${l}`],l),a.push({char:l,res:t.terms[n].results[0].result,die:"d6"}),s[l]=Math.round(Math.max(0,Number(t.terms[n].results[0].result)+Number(e)+await this._situationalModifiers(o,l))*Number(o.regenerationFactor)),n+=2;return s.characteristics=a,s}static async rollStatus(o){let e=o.roll||await new Roll("1d20").evaluate(),t=await this._rollSingleD20(e,o.source.system.max,o.extra.statusId,await this._situationalModifiers(o),o,"",this._situationalMultipliers(o));t.rollType="dodge";let a=o.extra.statusId=="dodge";return a&&t.successLevel==3?await B.tableEnabledFor("criticalMeleeDefense")?t.description+=B.rollCritBotchButton("criticalMeleeDefense",!1,o,o):t.description+=B.defaultParryCrit():a&&t.successLevel==-3&&(await B.tableEnabledFor("Defense")?t.description+=B.rollCritBotchButton("Defense",!0,o,o):t.description+=await B.defaultBotch()),t}static async rollAttribute(o){let e=o.roll?o.roll:await new Roll("1d20").evaluate();this._appendSituationalModifiers(o,game.i18n.localize("Difficulty"),o.testDifficulty);let t=await this._rollSingleD20(e,o.source.system.value,o.extra.characteristicId,await this._situationalModifiers(o),o,"",this._situationalMultipliers(o));return t.rollType="attribute",t}static async damageFormula(o){let e;if(o.source.type=="meleeweapon"){let t=O._calculateCombatSkillValues(o.extra.actor.items.find(a=>a.type=="combatskill"&&a.name==o.source.system.combatskill.value),o.extra.actor.system);e=O._prepareMeleeWeapon(o.source,[t],o.extra.actor)}else if(o.source.type=="rangeweapon"){let t=O._calculateCombatSkillValues(o.extra.actor.items.find(a=>a.type=="combatskill"&&a.name==o.source.system.combatskill.value),o.extra.actor.system);e=O._prepareRangeWeapon(o.source,[],[t],o.extra.actor)}else e=o.source.system;return this.replaceDieLocalization(o.source.system.damage.value)+`+${e.extraDamage||0}`}static async rollDamage(o){let e=await this._situationalModifiers(o),t=[],a=o.roll,s=a.total+e;for(let i of a.terms)if(i instanceof foundry.dice.terms.Die||i.class=="Die")for(let n of i.results)t.push({char:o.mode,res:n.result,die:"d"+i.faces});return{rollType:"damage",damage:s,characteristics:t,preData:o,modifiers:e,extra:{}}}static async _situationalModifiers(o,e=""){let t=0;for(let a of o.situationalModifiers){if(a.value==null)continue;let s=Number(a.value)||await this._stringToRoll(a.value);t+=a.type==e||e==""&&a.type==null?s:0}return t}static _situationalPartCheckModifiers(o){return o.situationalModifiers.reduce(function(e,t){if(t.type=="TPM"){let a=t.value.split("|");return a.length!=3||(e[0]=e[0]+Number(a[0]),e[1]=e[1]+Number(a[1]),e[2]=e[2]+Number(a[2])),e}else return e},[0,0,0])}static _situationalMultipliers(o){return o.situationalModifiers.reduce(function(e,t){return e*(t.type=="*"&&Number(`${t.value}`.replace(/,/,"."))||1)},1)}static _appendSituationalModifiers(o,e,t,a=""){let s=o.situationalModifiers.find(i=>i.name==e);s?s.value=t:o.situationalModifiers.push({name:e,value:t,type:a})}static async rollCombatTrait(o){let e=o.roll||await new Roll("1d20").evaluate(),t=o.source,a=t.system.traitType.value=="meleeAttack",s=o.mode=="attack";if(a){let l={system:{combatskill:{value:"-"},reach:{value:t.system.reach.value}}};this._appendSituationalModifiers(o,game.i18n.localize("opposingWeaponSize"),this._compareWeaponReach(l,o))}let i=await this._rollSingleD20(e,Number(s?t.system.at.value:t.system.pa),o.mode,await this._situationalModifiers(o),o,"",this._situationalMultipliers(o));await this.getDuplicatusRoll(i,o);let n=i.successLevel>0;await this.detailedWeaponResult(i,o,t),s&&n&&await _DiceDSA5.evaluateDamage(o,i,t,!a,i.doubleDamage),i.rollType="weapon";let r=_DiceDSA5.parseEffect(t);return r&&(i.parsedEffect=r),i}static async _stringToRoll(o,e){let t=[],a=/\d{1}[dDwW]\d/g,s=`${o}`;s.replace(a,function(r){t.push(new Roll(_DiceDSA5.replaceDieLocalization(r),e.extra.actor.system).evaluate())});let i=await Promise.all(t),n=s.replace(a,()=>{let r=i.shift();return e&&_DiceDSA5._addRollDiceSoNice(e,r,game.dsa5.apps.DiceSoNiceCustomization.getAttributeConfiguration("ch")),r.total});return await Roll.safeEval(n)}static replaceDieLocalization(o){return o.replace(/[Ww](?=\d)/g,"d")}static async evaluateDamage(o,e,t,a,s){let i=this.replaceDieLocalization(t.system.damage.value),n=[],r=t.dmgMultipliers||[],l=r.map(y=>`${y.name} *${y.val}`),c=[],m=0;for(let y of o.situationalModifiers){let k=0;if(y.armorPen&&c.push(y.armorPen),y.damageBonus){if(/^\*/.test(y.damageBonus)){r.push({name:y.name,val:Number(y.damageBonus.replace("*",""))});continue}let C=/^=/.test(y.damageBonus),v=`${y.damageBonus}`.replace(/^=/,""),I=await _DiceDSA5._stringToRoll(v,o);if(k=I*(y.step||1),C){i=this.replaceDieLocalization(v),n.push({name:y.name,roll:I});continue}else y.damageBonus=I,m+=k}}let d=o.damageRoll||await _DiceDSA5.manualRolls(await new Roll(i,o.extra.actor.system).evaluate(),"CHAR.DAMAGE",o.extra.options),p=d.total,f=0;for(let y of d.terms)if(y instanceof foundry.dice.terms.Die||y.class=="Die")for(let k of y.results)f+=Number(k.result),e.characteristics.push({char:"damage",res:k.result,die:"d"+y.faces});let h=p-f;if(n.length>0)l.push(n[0].name+" "+p);else{p+=m,l.push(game.i18n.localize("Roll")+" "+f),h!=0&&l.push(game.i18n.localize("weaponModifier")+" "+h),o.situationalModifiers.reduce((I,S)=>{if(S.damageBonus){let j=/^\*/.test(S.damageBonus)?S.damageBonus:Number(S.damageBonus)*(S.step||1);l.push(`${S.name} ${j}`)}},l),o.situationalModifiers.find(I=>I.name.indexOf(game.i18n.localize("CONDITION.bloodrush"))>-1)&&(p+=2,l.push(game.i18n.localize("CONDITION.bloodrush")+" 2")),t.extraDamage&&(p=Number(t.extraDamage)+Number(p),l.push(game.i18n.localize("damageThreshold")+" "+t.extraDamage));let y=o.extra.actor.system[a?"rangeStats":"meleeStats"].damage,k=await _DiceDSA5._stringToRoll(y,o);k!=0&&(p+=k,l.push(game.i18n.localize("statuseffects")+" "+k));let C=$e(t,"system.combatskill.value"),v=o.extra.actor.system.skillModifiers.combat.damage.reduce((I,S)=>(S.target==C&&(I+=Number(S.value)),I),0);v&&(p=p+v,l.push(`${game.i18n.localize("TYPES.Item.combatskill")} (${game.i18n.localize("CHARAbbrev.damage")}) ${v}`))}s&&(p=p*s,l.push(game.i18n.format("doubleDamage",{x:s})));for(let y of r)p=p*y.val;e.armorPen=c,e.damagedescription=l.join(", "),e.damage=Math.round(p),e.damageRoll=xr(d)}static async rollWeapon(o){let e=o.roll||await new Roll("1d20").evaluate(),t,a=o.source,s=a.system.combatskill.value,i=O._calculateCombatSkillValues(o.extra.actor.items.find(c=>c.type=="combatskill"&&c.name==s),o.extra.actor.system,{step:await this._situationalModifiers(o,"step"),[o.mode]:await this._situationalModifiers(o,o.mode)}),n=a.type=="meleeweapon";n?(t=O._prepareMeleeWeapon(a,[i],o.extra.actor),o.mode=="attack"&&this._appendSituationalModifiers(o,game.i18n.localize("opposingWeaponSize"),this._compareWeaponReach(t,o))):t=O._prepareRangeWeapon(a,[],[i],o.extra.actor);let r=await this._rollSingleD20(e,t[o.mode],o.mode,await this._situationalModifiers(o),o,s,this._situationalMultipliers(o));await this.getDuplicatusRoll(r,o),await this.detailedWeaponResult(r,o,a),o.mode=="attack"&&r.successLevel>0&&!o.extra.counterAttack&&await _DiceDSA5.evaluateDamage(o,r,t,!n,r.doubleDamage),o.extra.counterAttack&&(g.getSpeaker(o.extra.speaker).addCondition("stunned"),r.description+=", "+g.replaceConditions(game.i18n.localize("stunnedByCounterAttack"))),r.rollType="weapon";let l=_DiceDSA5.parseEffect(t);return l&&(r.parsedEffect=l),r}static _weaponBotchCritEffect(o,e,t){let a=[];for(let s of o.effects)for(let i of s.changes)if(i.key==e){if(i.value=="description")a.push(s.description);else if(/^condition /.test(i.value)){let n=i.value.replace(/^condition /,"").split(" "),r=Number(n[1])||1,l=game.i18n.localize(`CONDITION.${n[0]}`),c=g.replaceConditions(game.i18n.format("CHATNOTIFICATION.suffersCondition",{actor:t.name,condition:l,count:r}));a.push(`
${c}
`)}}return a.join(" ")}static async detailedWeaponResult(o,e,t){let a=e.mode=="attack"&&!e.extra.counterAttack,s=t.type=="meleeweapon"||$e(t,"system.traitType.value")=="meleeAttack";switch(o.successLevel){case 3:a?(await B.tableEnabledFor("criticalAttack")?o.description+=B.rollCritBotchButton("criticalAttack",!1,e):(o.description+=B.defaultAttackCrit(!0),o.doubleDamage=2),o.halfDefense=!0):e.isRangeDefense&&await B.tableEnabledFor("criticalRangeDefense")?o.description+=B.rollCritBotchButton("criticalRangeDefense",!1,e):await B.tableEnabledFor("criticalMeleeDefense")?o.description+=B.rollCritBotchButton("criticalMeleeDefense",!1,e):o.description+=B.defaultParryCrit(),o.description+=this._weaponBotchCritEffect(t,"self.criteffect",e.extra.actor);break;case-3:let i=$e(t,"system.combatskill.value")==game.i18n.localize("LocalizedIDs.wrestle")||t.type=="trait";a&&s&&await B.tableEnabledFor("Melee")?o.description+=B.rollCritBotchButton("Melee",i,e):a&&await B.tableEnabledFor("Range")?o.description+=B.rollCritBotchButton("Range",!1,e):!a&&await B.tableEnabledFor("Defense")?o.description+=B.rollCritBotchButton("Defense",i,e):o.description+=await B.defaultBotch(),o.description+=this._weaponBotchCritEffect(t,"self.botcheffect",e.extra.actor);break;case 2:a&&(o.description+=B.defaultAttackCrit(!1),o.halfDefense=!0);break;case-2:break}}static async _addRollDiceSoNice(o,e,t){if(o.rollMode){for(let a=0;a{new ae({title:game.i18n.localize(t.cheat?"DIALOG.cheat":"DSASETTINGS.allowPhysicalDice"),content:r,default:"ok",buttons:{ok:{icon:'',label:game.i18n.localize("yes"),callback:u(m=>l([!0,m]),"callback")},cancel:{icon:'',label:game.i18n.localize("cancel"),callback:u(()=>l([!1,0]),"callback")}}}).render(!0)}),s){let l=[];i.find(".dieInput").each(function(c){let m=Number($(this).val());m>0&&l.push({val:m,index:c}),c++}),o.editRollAtIndex(l)}}return o}static parseEffect(o){let e=o.system.effect?o.system.effect.value:void 0,t=[];if(e){let s=/^[a-z]+\|[öäüÖÄÜa-zA-z ]+$/;for(let i of e.split(";"))if(s.test(i.trim())){let n=i.split("|").map(r=>r.trim());if(n[0]=="condition"){let r=CONFIG.statusEffects.find(l=>l.id==n[1]);t.push(`${game.i18n.localize(r.name)}
`)}else t.push(`${game.i18n.localize(n[0])}: ${n[1]}`)}}let a=$e(o,"flags.dsa5.poison");return a&&t.push(`${game.i18n.localize("TYPES.Item.poison")}: ${a.name}`),t.join(", ")}static async calculateEnergyCost(o,e,t){let a=[],s,i,n,r;if(e.successLevel<0){let l=["traditionWitch","traditionFjarning","braniborian"].map(m=>game.i18n.localize(`LocalizedIDs.${m}`)),c=t.extra.actor.items.some(m=>m.type=="specialability"&&l.includes(m.name))?3:2;e.preData.calculatedSpellModifiers.finalcost=Math.round(e.preData.calculatedSpellModifiers.finalcost/c)}if(o?(r="KaPCost",s=game.i18n.localize("LocalizedIDs.weakKarmicBody"),i=game.i18n.localize(`LocalizedIDs.${e.successLevel>0?"mightyKarmaControl":"karmaControl"}`),n={val:"kapModifier",name:"KaP"}):(r="AsPCost",s=game.i18n.localize("LocalizedIDs.weakAstralBody"),i=game.i18n.localize(`LocalizedIDs.${e.successLevel>0?"energyControl":"smallEnergyControl"}`),n={val:"aspModifier",name:"AsP"}),a.push({name:s,value:P.vantageStep(t.extra.actor,s)},{name:i,value:F.abilityStep(t.extra.actor,i)*-1},{name:`${game.i18n.localize("statuseffects")} (${game.i18n.localize("CHARAbbrev."+n.name)})`,value:t.extra.actor.system[n.val]+await this._situationalModifiers(t,r)}),a=a.filter(l=>l.value!=0),e.preData.calculatedSpellModifiers.description=a.map(l=>`${l.name} ${l.value}`).join(`
`),e.preData.calculatedSpellModifiers.finalcost=Math.max(1,Number(e.preData.calculatedSpellModifiers.finalcost)+a.reduce((l,c)=>l+c.value,0)),e.successLevel>0&&e.preData.calculatedSpellModifiers.maintainCost!=0){let l=e.preData.calculatedSpellModifiers.maintainCost.split(" ");l[0]=Math.round(Number(l[0])),e.preData.calculatedSpellModifiers.finalcost+=l[0],e.preData.calculatedSpellModifiers.maintainCost=l.join(" ")}}static async rollSpell(o){let e=await this._rollThreeD20(o),t=["ceremony","liturgy"].includes(o.source.type);if(e.rollType=o.source.type,e.preData.calculatedSpellModifiers.finalcost=e.preData.calculatedSpellModifiers.cost,e.successLevel>=2){let a=(await new Roll("1d6").evaluate()).total;e.description=e.description+", "+game.i18n.localize("additionalFPs")+" "+a,e.result+=a,e.qualityStep=Math.min(game.settings.get("dsa5","capQSat"),Math.ceil(e.result/3)),e.preData.calculatedSpellModifiers.finalcost=Math.round(e.preData.calculatedSpellModifiers.cost/2)}else e.successLevel<=-2&&(e.description+=B.rollCritBotchButton(t?"Liturgy":"Spell",!1,o));if(e.successLevel>0&&o.source.system.effectFormula.value!=""){let a=_DiceDSA5.replaceDieLocalization(o.source.system.effectFormula.value.replaceAll(game.i18n.localize("CHARAbbrev.QS"),e.qualityStep)),s=[];for(let l of o.situationalModifiers)l.armorPen&&s.push(l.armorPen);/(,|;)/.test(a)&&(a=a.split(/[,;]/)[e.qualityStep-1]);let i=o.damageRoll?o.damageRoll:await _DiceDSA5.manualRolls(await new Roll(a,o.extra.actor.system).evaluate(),"CHAR.DAMAGE",o.extra.options);this._addRollDiceSoNice(o,i,game.dsa5.apps.DiceSoNiceCustomization.getAttributeConfiguration("damage")),e.calculatedEffectFormula=a;for(let l of i.terms)if(l instanceof foundry.dice.terms.Die||l.class=="Die")for(let c of l.results)e.characteristics.push({char:"effect",res:c.result,die:"d"+l.faces});let n=[],r=await _DiceDSA5._stringToRoll(o.extra.actor.system[t?"liturgyStats":"spellStats"].damage,o);r!=0&&n.push(game.i18n.localize("statuseffects")+" "+r),e.armorPen=s,e.damageRoll=i,e.damage=i.total+r,e.damagedescription=n.join(`
-`)}await this.calculateEnergyCost(t,e,o),await this.getDuplicatusRoll(e,o);for(let a of["minorFairies","minorSpirits"]){let s=game.i18n.localize("CONDITION."+a);P.hasVantage(o.extra.actor,s)&&!o.extra.actor.effects.find(i=>i.name==s)&&(await new Roll("1d20").evaluate()).total<=e.preData.calculatedSpellModifiers.finalcost&&(e.description+=", "+game.i18n.format("minorghostsappear",{creature:s}),g.getSpeaker(o.extra.speaker).addCondition(a))}return e}static async _rollThreeD20(o){let e=o.roll?o.roll instanceof Roll?o.roll:Roll.fromData(o.roll):await new Roll("1d20+1d20+1d20").evaluate(),t=[],a=0;this._appendSituationalModifiers(o,game.i18n.localize("Difficulty"),o.testDifficulty);let s=await this._situationalModifiers(o),i=Number(o.source.system.talentValue.value)+o.advancedModifiers.fws+await this._situationalModifiers(o,"FW"),n=this._situationalPartCheckModifiers(o,"TPM"),r=[1,2,3].map(f=>o.extra.actor.system.characteristics[o.source.system[`characteristic${f}`].value].value+s+o.advancedModifiers.chars[f-1]+n[f-1]),l=[0,1,2].map(f=>e.terms[f*2].results[0].result-r[f]);if(o.routine)i=Math.round(i/2);else for(let f of l)f>0&&(i-=f);let c=o.extra.actor.system.skillModifiers.crit,m=o.extra.actor.system.skillModifiers.botch;if(["spell","ritual"].includes(o.source.type)&&P.hasVantage(o.extra.actor,game.i18n.localize("LocalizedIDs.wildMagic"))&&(m=19),o.source.type=="skill"&&P.hasVantage(o.extra.actor,`${game.i18n.localize("LocalizedIDs.incompetent")} (${o.source.name})`)){let f=await new Roll("1d20").evaluate(),h=l.reduce((k,D,v,I)=>D0&&(i+=await this._situationalModifiers(o,"FP"),p=Math.max(1,(i==0?1:i>0?Math.ceil(i/3):0)+(o.qualityStep!=null?Number(o.qualityStep):0))+(o.advancedModifiers.qls||0)+await this._situationalModifiers(o,"QL")),p=Math.min(game.settings.get("dsa5","capQSat"),p),p({char:o.source.system[`characteristic${f+1}`].value,res:e.terms[f*2].results[0].result,suc:l[f]<=0,tar:r[f]})),qualityStep:p,description:t,preData:o,successLevel:a,modifiers:s,extra:{}}}static async rollTalent(o){let e=await this._rollThreeD20(o);return e.rollType="talent",e}static get3D20SuccessLevel(o,e,t=20,a=1){let s=o.terms.filter(n=>n.results&&n.results[0].result<=a).length,i=o.terms.filter(n=>n.results&&n.results[0].result>=t).length;return s>=2?s:i>=2?i*-1:e>=0?1:-1}static getSuccessDescription(o){return game.i18n.localize(["AstoundingFailure","CriticalFailure","Failure","","Success","CriticalSuccess","AstoundingSuccess"][o+3])}static async rollItem(o){let e=o.roll||await new Roll("1d20+1d20+1d20").evaluate(),t=[],a=await this._situationalModifiers(o),s=Number(o.source.system.step.value),i=[1,2,3].map(m=>10+Number(o.source.system.step.value)+a),n=[0,1,2].map(m=>e.terms[m*2].results[0].result-i[m]);for(let m of n)m>0&&(s-=m);let l=_DiceDSA5.get3D20SuccessLevel(e,s,20);t.push(_DiceDSA5.getSuccessDescription(l)),t=t.join(", ");let c={result:s,characteristics:[0,1,2].map(m=>({char:o.source.type,res:e.terms[m*2].results[0].result,suc:n[m]<=0,tar:i[m]})),qualityStep:Math.min(game.settings.get("dsa5","capQSat"),(s==0?1:s>0?Math.ceil(s/3):0)+(o.qualityStep!=null?Number(o.qualityStep):0)),description:t,preData:o,successLevel:l,modifiers:a,extra:{}};switch(o.source.type){case"poison":let m=o.source.system.duration.value.split(" / ").map(h=>h.trim()),d=o.source.system.effect.value.split(" / ").map(h=>h.trim());c.duration=m.length>1?c.successLevel>0?m[0]:m[1]:m[0],c.effect=d.length>1?c.successLevel>0?d[0]:d[1]:d[0];break;case"disease":let p=o.source.system.damage.value.split(" / ").map(h=>h.trim()),f=o.source.system.duration.value.split(" / ").map(h=>h.trim());c.damageeffect=p.length>1?c.successLevel>0?p[0]:p[1]:p[0],c.duration=f.length>1?c.successLevel>0?f[0]:f[1]:f[0];break}return c}static async updateDefenseCount(o){game.combat&&!o.fateUsed&&await game.combat.updateDefenseCount(o.extra.speaker)}static _compareWeaponReach(o,e){let t=e.situationalModifiers.find(i=>i.name==game.i18n.localize("LocalizedIDs.circumvent")),a=b.meleeRangesArray.indexOf(o.system.reach.value),s=b.meleeRangesArray.indexOf(e.opposingWeaponSize);return t&&s>a&&(t.value=Math.min(t.step,s-a)*2),Math.min(0,a-s)*2}static async showDiceSoNice(o,e){if(g.moduleEnabled("dice-so-nice")&&game.dice3d){let t=null,a=!1;switch(e){case"blindroll":a=!0,t=game.users.filter(i=>i.isGM).map(i=>i.id);break;case"gmroll":t=game.users.filter(i=>i.isGM).map(i=>i.id);break;case"selfroll":t=[];break}let s=game.dice3d.showForRoll(o,game.user,!0,t,a);game.settings.get("dice-so-nice","immediatelyDisplayChatMessages")||await s}}static addApplyEffectData(o){let e=o.preData.source;if(o.successLevel>0){if(["meleeweapon","rangeweapon"].includes(e.type)||e.type=="trait"&&["rangeAttack","meleeAttack"].includes(e.system.traitType.value)){if(e.effects.some(a=>!$e(a,"flags.dsa5.applyToOwner")))return!0}else if(["spell","liturgy","ritual","ceremony","trait","skill"].includes(e.type)&&e.effects.length>0)return!0}if(["disease","poison"].includes(e.type)){let a=o.successLevel>0?1:2;return e.effects.filter(s=>$e(s,"flags.dsa5.successEffect")==a||!$e(s,"flags.dsa5.successEffect")).length>0}let t=o.preData.situationalModifiers.filter(a=>a.specAbId).map(a=>a.specAbId);if(t.length>0){let a=o.preData.extra.actor.items.filter(s=>t.includes(s._id));for(let s of a)if(s.effects.length>0)return!0}return!1}static async renderRollCard(chatOptions,testData,rerenderMessage){let applyEffect=this.addApplyEffectData(testData),immuneTo=x.checkImmunity(testData),preData=On(testData.preData),hideDamage=rerenderMessage?rerenderMessage.flags.data.hideDamage:preData.mode=="attack";await pe.postRoll({testData,preData}),Hooks.call("postProcessDSARoll",chatOptions,testData,rerenderMessage,hideDamage),await g.callAsyncHooks("postProcessDSARoll",[testData]),delete preData.extra.actor,delete testData.actor,delete testData.preData;let hasAreaTemplate=testData.successLevel>0&&preData.source.system.target&&preData.source.system.target.type in game.dsa5.config.areaTargetTypes,chatData={title:chatOptions.title,immuneTo,testData,hideData:game.user.isGM,preData,hideDamage,modifierList:preData.situationalModifiers.filter(o=>o.value!=0),applyEffect,hasAreaTemplate,showDamageToGear:await W.showDamageToGear(preData,testData)};if(preData.advancedModifiers&&(preData.advancedModifiers.chars.some(o=>o!=0)&&chatData.modifierList.push({name:game.i18n.localize("MODS.partChecks"),value:preData.advancedModifiers.chars}),preData.advancedModifiers.fws!=0&&chatData.modifierList.push({name:game.i18n.localize("MODS.FW"),value:preData.advancedModifiers.fws}),preData.advancedModifiers.qls!=0&&chatData.modifierList.push({name:game.i18n.localize("MODS.QS"),value:preData.advancedModifiers.qls})),["gmroll","blindroll"].includes(chatOptions.rollMode)&&(chatOptions.whisper=game.users.filter(o=>o.isGM).map(o=>o.id)),chatOptions.rollMode==="blindroll"?chatOptions.blind=!0:chatOptions.rollMode==="selfroll"&&(chatOptions.whisper=[game.user.id]),K.playEffect(preData.mode,preData.source,testData.successLevel,chatOptions.whisper,chatOptions.blind),oe(chatOptions,{flags:{data:{preData,postData:testData,template:chatOptions.template,rollMode:chatOptions.rollMode,isOpposedTest:chatOptions.isOpposedTest,title:chatOptions.title,hideData:chatData.hideData,hideDamage:chatData.hideDamage,isDSARoll:!0}}}),rerenderMessage){let postFunction=$e(rerenderMessage,"flags.data.preData.extra.options.postFunction");postFunction&&(testData.messageId=rerenderMessage.id,await eval(postFunction.functionName)(postFunction,{result:testData,chatData},preData.source));let html=await renderTemplate(chatOptions.template,chatData),actor=ChatMessage.getSpeakerActor(rerenderMessage.speaker)||game.users.get(rerenderMessage.author)?.character,rollData=actor?actor.getRollData():{},enriched=await TextEditor.enrichHTML(html,{rollData,async:!0});chatOptions.content=enriched;let newMsg=await rerenderMessage.update({content:chatOptions.content,flags:{data:chatOptions.flags.data}});return ui.chat.updateMessage(newMsg),newMsg}else return chatOptions.content=await renderTemplate(chatOptions.template,chatData),await ChatMessage.create(chatOptions)}static async _itemRoll(o){let e=$(o.currentTarget),t=e.parents(".message").attr("data-message-id"),a=game.messages.get(t),s=a.speaker,i=e.attr("data-type"),n=e.attr("data-name"),r=g.getSpeaker(s);if(r){let l=r.items.find(c=>c.name==n&&c.type==i);if(l){let c=new C(l.toObject()),m=e.attr("data-removecharge")?e.attr("data-removecharge")=="true":!1;if(m&&c.system.quantity.value<1){ui.notifications.error("DSAError.NotEnoughCharges",{localize:!0});return}c.setupEffect().then(async d=>{await c.itemTest(d),m&&await l.update({"system.quantity.value":l.system.quantity.value-1})})}else ui.notifications.error(game.i18n.format("DSAError.notFound",{category:i,name:n}))}}static async _rollEdit(o){let e=$(o.currentTarget),t=e.parents(".message").attr("data-message-id"),a=game.messages.get(t),s=a.flags.data,i=s.preData;i.extra.actor=g.getSpeaker(i.extra.speaker)?.toObject(!1),i.extra.options.cheat&&delete i.extra.options.cheat;let n;switch(e.attr("data-edit-type")){case"roll":n=e.attr("data-edit-id");let l=Number(e.val());if(i.roll.terms.length>n*2){let m=Roll.fromData(i.roll);m.editRollAtIndex([{index:n,val:l}]),i.roll=m}else{let m=Roll.fromData(s.postData.damageRoll);n=n-i.roll.terms.filter(d=>d.results).length,m.editRollAtIndex([{index:n,val:l}]),i.damageRoll=m}break;case"mod":n=i.situationalModifiers.findIndex(m=>m.name==game.i18n.localize("chatEdit")),n>0&&i.situationalModifiers.splice(n,1);let c={name:game.i18n.localize("chatEdit"),value:Number(e.val())-await this._situationalModifiers(i)};i.situationalModifiers.push(c);break}s.postData.damageRoll&&!i.damageRoll&&(i.damageRoll=s.postData.damageRoll);let r={template:s.template,rollMode:s.rollMode,title:s.title,speaker:a.speaker,user:a.author.id};["gmroll","blindroll"].includes(r.rollMode)&&(r.whisper=game.users.filter(l=>l.isGM).map(l=>l.id)),r.rollMode==="blindroll"&&(r.blind=!0),["poison","disease"].includes(i.source.type)?new C(i.source)[`${s.postData.postFunction}`]({testData:i,cardOptions:r},{rerenderMessage:a}):g.getSpeaker(a.speaker)[`${s.postData.postFunction}`]({testData:i,cardOptions:r},{rerenderMessage:a})}static async gearDamaged(o){let e=o.currentTarget.dataset.uuid.split(";");if(e.length>1){let t=await Promise.all(e.map(a=>fromUuid(a)));zt.showDialog(t)}else W.breakingTest(await fromUuid(e[0]))}static showCurrentTargets(o){let e=[],t;if(o.currentTarget.dataset.target=="target"){t="TT.applyEffectTargets";for(let s of game.user.targets)e.push(s.document.texture.src)}else{t="TT.applyEffectCaster";let s=game.messages.get($(o.currentTarget).parents(".message").attr("data-message-id")),i=g.getSpeaker(s.flags.data.preData.extra.speaker);i&&e.push(i.token?i.token.texture.src:i.prototypeToken.texture.src)}let a=e.length?e.map(s=>``).join(""):` ${game.i18n.localize("DIALOG.noTarget")}`;o.currentTarget.dataset.tooltip=`
${game.i18n.localize(t)}
${a}
`}static async rollResistPain(o){let e=o.currentTarget.dataset,t={token:e.token,actor:e.actor,scene:canvas.id},a=g.getSpeaker(t);a&&a.finishResistPainRoll()}static async wrapLock(o,e){let t=$(o.currentTarget);t.hasClass("locked")||(t.addClass("locked"),t.prepend(''),await e(o,t),setTimeout(()=>{t.removeClass("locked"),t.find("i").remove()},2e3))}static async chatListeners(o){o.on("click",".expand-mods",e=>{e.preventDefault();let t=$(e.currentTarget);t.find("i").toggleClass("fa-minus fa-plus"),t.siblings("ul,div").fadeToggle()}),o.on("click",".edit-toggle",e=>{e.preventDefault(),$(e.currentTarget).parents(".chat-card").find(".display-toggle").toggle()}),o.on("click",".botch-roll",e=>B.showBotchCard(e.currentTarget.dataset)),o.on("click",".roll-item",e=>_DiceDSA5._itemRoll(e)),o.on("click",".gearDamaged",async e=>_DiceDSA5.gearDamaged(e)),o.on("click",".applyDamage",async e=>wt($(e.currentTarget).closest(".message"),e.currentTarget.dataset.mode)),o.on("change",".roll-edit",e=>_DiceDSA5._rollEdit(e)),o.on("click",".applyEffect",async e=>{_DiceDSA5.wrapLock(e,async(t,a)=>{let s=a.parents(".message").attr("data-message-id"),i=t.currentTarget.dataset.target;await Z.applyEffect(s,i)})}),o.on("mouseenter",".applyEffect",e=>_DiceDSA5.showCurrentTargets(e)),o.on("click",".applyTableEffect",async e=>{_DiceDSA5.wrapLock(e,async(t,a)=>{let s=a.parents(".message").attr("data-message-id"),i=t.currentTarget.dataset.target;await Nt.applyEffect(s,i)})}),o.on("click",".placeTemplate",async e=>Le.placeTemplateFromChat(e)),o.on("click",".message-delete",e=>{let t=game.messages.get($(e.currentTarget).parents(".message").attr("data-message-id"));if(!t.flags.unopposeData)return;let s=canvas.tokens.get(t.flags.unopposeData.targetSpeaker.token);ee.clearOpposed(s.actor)}),o.on("click",".resistEffect",e=>Z.resistEffect(e)),o.on("click",".resistPain",e=>_DiceDSA5.rollResistPain(e)),ie.chatListeners(o)}};var{getProperty:U,mergeObject:we,duplicate:Ke,hasProperty:zr,setProperty:Nr,expandObject:Rr}=foundry.utils,O=class o extends Actor{static{u(this,"Actordsa5")}static DEFAULT_ICON="icons/svg/mystery-man-black.svg";static selfRegex=/^self\./;static skipAlternateWeaponKeys=new Set([["flags","system.description"]]);static async create(e,t){if(e instanceof Array||e.items)return await super.create(e,t);let a=await g.allSkills()||[],s=await g.allCombatSkills()||[],i=await g.allMoneyItems()||[];return e.items=[...a,...s,...i],e.type!="character"&&(e.system={status:{fatePoints:{current:0,value:0}}}),e.type!="creature"&&[void 0,0].includes(U(e,"system.status.wounds.value"))&&we(e,{system:{status:{wounds:{value:16}}}}),await super.create(e,t)}_getArmorCompensation(e,t,a){let s=F.abilityStep(e,game.i18n.localize("LocalizedIDs.inuredToEncumbrance")),i=t.reduce((n,r)=>n+=Number(r.system.encumbrance.value),0);if(s>i){let n=[game.i18n.localize("CHARAbbrev.GS"),game.i18n.localize("CHARAbbrev.INI")];for(let r of n)a[r]&&(a[r]=a[r].filter(l=>l.type!="armor"))}}_getItemModifiers(){let e=[],t={};for(let a of this.items.filter(s=>["meleeweapon","rangeweapon","armor","equipment"].includes(s.type)&&U(s,"system.worn.value")||["advantage","specialability","disadvantage"].includes(s.type)))this._buildGearAndAbilityModifiers(t,a),a.type=="armor"&&e.push(a);this._getArmorCompensation(this,e,t),this._applyModiferTransformations(t)}prepareDerivedData(){let e=this.system;try{this._getItemModifiers();for(let p of Object.values(e.characteristics))p.value=p.initial+p.advances+(p.modifier||0)+p.gearmodifier;e.totalWeight=0;let t=[],a=game.i18n.localize("LocalizedIDs.familiar"),s=game.i18n.localize("LocalizedIDs.companion"),i=game.settings.get("dsa5","moneyHasWeight"),n=new Map,r=this.items.filter(p=>p.type=="equipment"&&p.system.equipmentType.value=="bags");for(let p of r)n.set(p.id,[]);this.system.moneyWeight=0;for(let p of this.items)if(i&&p.type=="money")p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=Number(p.system.preparedWeight),this.system.moneyWeight+=Number(p.system.preparedWeight);else if(b.equipmentCategories.has(p.type)){let f=U(p,"system.parent_id");if(f&&f!=p._id&&n.has(f)){n.get(f).push(p);continue}p.type=="armor"?(p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=parseFloat((p.system.weight.value*(p.system.worn.value?Math.max(0,p.system.quantity.value-1):p.system.quantity.value)).toFixed(3)),p.system.worn.value&&t.push(p)):(p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=Number(p.system.preparedWeight))}else switch(p.type){case"trait":p.name==a?e.isFamiliar=!0:p.name==s&&(e.isPet=!0);break;case"spell":case"ritual":case"magictrick":e.isMage=!0;break;case"liturgy":case"ceremony":case"blessing":e.isPriest=!0;break;case"specialability":b.sortedSpecs.magical.has(p.system.category.value)?e.isMage=!0:b.sortedSpecs.clerical.has(p.system.category.value)&&(e.isPriest=!0);break}e.isMage||=e.isFamiliar;for(let p of r){let f=U(p,"system.parent_id");(!f||!n.has(f))&&(e.totalWeight+=this._calcBagweight(p,n,!0))}e.canAdvance=this.isOwner&&(this.type=="character"||e.isFamiliar||e.isPet),this.canAdvance=e.canAdvance,e.carrycapacity=e.characteristics.kk.value*2+e.carryModifier,e.canAdvance&&(e.details.experience.current=e.details.experience.total-e.details.experience.spent,e.details.experience.description=g.experienceDescription(e.details.experience.total)),(this.type=="character"||this.type=="npc")&&(e.status.wounds.current=e.status.wounds.initial+e.characteristics.ko.value*2,e.status.soulpower.value=(e.status.soulpower.initial||0)+Math.round((e.characteristics.mu.value+e.characteristics.kl.value+e.characteristics.in.value)/6),e.status.toughness.value=(e.status.toughness.initial||0)+Math.round((e.characteristics.ko.value+e.characteristics.ko.value+e.characteristics.kk.value)/6),e.status.wounds.min=-1*e.characteristics.ko.value),e.status.fatePoints.max=Number(e.status.fatePoints.current)+Number(e.status.fatePoints.modifier)+e.status.fatePoints.gearmodifier,this.type=="creature"&&(e.status.wounds.current=e.status.wounds.initial,e.status.astralenergy.current=e.status.astralenergy.initial,e.status.karmaenergy.current=e.status.karmaenergy.initial),e.status.wounds.max=Math.round((e.status.wounds.current+e.status.wounds.modifier+e.status.wounds.advances)*e.status.wounds.multiplier+e.status.wounds.gearmodifier),e.status.regeneration.LePmax=e.status.regeneration.LePTemp+e.status.regeneration.LePMod+e.status.regeneration.LePgearmodifier,e.status.regeneration.KaPmax=e.status.regeneration.KaPTemp+e.status.regeneration.KaPMod+e.status.regeneration.KaPgearmodifier,e.status.regeneration.AsPmax=e.status.regeneration.AsPTemp+e.status.regeneration.AsPMod+e.status.regeneration.AsPgearmodifier;let l=e.guidevalue;e.status.astralenergy.rebuy||=0,e.status.karmaenergy.rebuy||=0,e.status.astralenergy.permanentLoss||=0,e.status.karmaenergy.permanentLoss||=0,e.status.astralenergy.permanentLossSum=e.status.astralenergy.permanentLoss-e.status.astralenergy.rebuy+e.status.astralenergy.permanentGear,e.status.karmaenergy.permanentLossSum=e.status.karmaenergy.permanentLoss-e.status.karmaenergy.rebuy+e.status.karmaenergy.permanentGear,(e.isFamiliar||l&&this.type!="creature")&&(e.status.astralenergy.current=e.status.astralenergy.initial,e.status.karmaenergy.current=e.status.karmaenergy.initial,e.characteristics[l.magical]&&(e.status.astralenergy.current+=Math.round(e.characteristics[l.magical].value*e.energyfactor.magical)),e.characteristics[l.clerical]&&(e.status.karmaenergy.current+=Math.round(e.characteristics[l.clerical].value*e.energyfactor.clerical))),e.status.astralenergy.max=e.status.astralenergy.current+e.status.astralenergy.modifier+e.status.astralenergy.advances+e.status.astralenergy.gearmodifier-e.status.astralenergy.permanentLossSum,e.status.karmaenergy.max=e.status.karmaenergy.current+e.status.karmaenergy.modifier+e.status.karmaenergy.advances+e.status.karmaenergy.gearmodifier-e.status.karmaenergy.permanentLossSum,e.status.soulpower.max=e.status.soulpower.value+e.status.soulpower.modifier+e.status.soulpower.gearmodifier,e.status.toughness.max=e.status.toughness.value+e.status.toughness.modifier+e.status.toughness.gearmodifier,e.status.dodge.value=Math.round(e.characteristics.ge.value/2)+e.status.dodge.gearmodifier;let c=this.calcEncumbrance(e),m=H.isRiding(this)?H.getHorse(this):void 0;this.calcInitiative(e,c,m),e.status.dodge.max=Number(e.status.dodge.value)+Number(e.status.dodge.modifier)+Number(game.settings.get("dsa5","higherDefense"))/2,e.armorEncumbrance=this.getArmorEncumbrance(this,t),this.prepareSwarm(e),this.effectivePain(e);let d=this.statuses.has("fixated");this.calcSpeed(e,d,m),d&&(e.status.dodge.max=Math.max(0,e.status.dodge.max-4))}catch(t){console.error(`Something went wrong with preparing actor data ${this.name}: `+t+t.stack),ui.notifications.error(game.i18n.format("DSAError.PreparationError",{name:this.name})+t+t.stack)}}static async deferredEffectAddition(e,t,a){let i=(t.effects.find(r=>r.statuses.has(e))?.flags.dsa5.auto||0)!=a,n=`changing${e}`;t[n]=i,i&&await t.addCondition(e,a,!0,!0).then(()=>t[n]=void 0)}static async postUpdateConditions(e){if(!g.isActiveGM())return;let t=e.system,a=e.isMerchant();if(!he.hasTrait(e,game.i18n.localize("LocalizedIDs.painImmunity"))){let n=e.woundPain(t);await this.deferredEffectAddition("inpain",e,n)}let s=t.armorEncumbrance;(e.type!="creature"||e.canAdvance)&&!a&&(s+=Math.max(0,Math.ceil((t.totalWeight-t.carrycapacity-4)/4))),await this.deferredEffectAddition("encumbered",e,s);let i=e.woundPain(t,"temporaryLeP");await this.deferredEffectAddition("stunned",e,i),P.hasVantage(e,game.i18n.localize("LocalizedIDs.blind"))&&await e.addCondition("blind"),P.hasVantage(e,game.i18n.localize("LocalizedIDs.mute"))&&await e.addCondition("mute"),P.hasVantage(e,game.i18n.localize("LocalizedIDs.deaf"))&&await e.addCondition("deaf"),a&&await e.prepareMerchant()}static async _onCreateOperation(e,t,a){for(let s of e)await o.postUpdateConditions(s);return super._onCreateOperation(e,t,a)}static async _onUpdateOperation(e,t,a){for(let s of e)await o.postUpdateConditions(s);return super._onUpdateOperation(e,t,a)}prepareSwarm(e){let t=Number(e.swarm.count)||1;if(t<2)return;e.swarm.maxwounds=e.status.wounds.max,e.status.wounds.max*=t;let a=Math.min(Math.ceil(e.status.wounds.value/e.swarm.maxwounds),t),s=Number(e.swarm.gg)||1;e.swarm.attack+=Math.min(10,Math.floor(a/s)),e.swarm.parry+=-1,e.swarm.effectiveCount=a,e.swarm.damage=Math.min(5,Math.floor(a/s))}effectivePain(e){let t=e.condition.inpain||0;t<4&&(t-=P.vantageStep(this,game.i18n.localize("LocalizedIDs.ruggedFighter"))+P.vantageStep(this,game.i18n.localize("LocalizedIDs.ruggedAnimal"))+(F.hasAbility(this,game.i18n.localize("LocalizedIDs.traditionKor"))?1:0)),t>0&&(t+=P.vantageStep(this,game.i18n.localize("LocalizedIDs.sensitiveToPain"))+P.vantageStep(this,game.i18n.localize("LocalizedIDs.fragileAnimal"))),t=Math.clamp(t,0,4),e.condition.inpain=t}woundPain(e,t="wounds"){let a=0;return e.status[t].max>0&&(this.type!="creature"||e.status[t].max>=20?(a=Math.floor((1-e.status[t].value/e.status[t].max)*4),e.status[t].value<=5&&(a=4)):a=Math.floor(5-5*e.status[t].value/e.status[t].max)),Math.clamp(a,0,4)}calcSpeed(e,t,a){if(a){if(e.status.speed.max=a.system.status.speed.max,!e.status.speed.max){let s=a.system;a.calcSpeed(s,a.hasCondition("fixated"))}e.status.speed.max=a.system.status.speed.max}else{e.status.speed.max=e.status.speed.initial+(e.status.speed.modifier||0)+(e.status.speed.gearmodifier||0),e.status.speed.max=Math.round(Math.max(0,e.status.speed.max-Math.min(4,this.calcEncumbrance(e)))*e.status.speed.multiplier),this.hasCondition("bloodrush")||(e.status.speed.max=Math.max(0,e.status.speed.max-(e.condition?.inpain||0)));let s=this.hasCondition("paralysed");s&&(e.status.speed.max=Math.round(e.status.speed.max*(1-s.flags.dsa5.value*.25))),t||this.hasCondition("rooted")||this.hasCondition("incapacitated")?e.status.speed.max=0:this.hasCondition("prone")&&(e.status.speed.max=Math.min(1,e.status.speed.max)),H.updateRiderSpeed(this,e.status.speed.max)}}calcEncumbrance(e){return Math.clamp(e.condition?.encumbered||0,0,4)}calcInitiative(e,t,a){if(this.type=="character"||this.type=="npc"?e.status.initiative.value=Math.round((e.characteristics.mu.value+e.characteristics.ge.value)/2)+(e.status.initiative.modifier||0):e.status.initiative.value=e.status.initiative.current+(e.status.initiative.modifier||0),a){if(e.status.initiative.value=a.system.status.initiative.value,!e.status.initiative.value){let s=a.system;a.calcInitiative(s,a.calcEncumbrance(s)),e.status.initiative.value=s.status.initiative.value}}else{e.status.initiative.value+=(e.status.initiative.gearmodifier||0)-Math.min(4,t);let s=Number((.01*e.status.initiative.value).toFixed(2));e.status.initiative.value*=e.status.initiative.multiplier||1,e.status.initiative.value=Math.round(e.status.initiative.value)+s}}get creatureType(){return x.creatureTypeName(this)}async prepareMerchant(){if(U(this,"system.merchant.merchantType")=="loot"){if(U(this,"system.merchant.locked")&&!this.hasCondition("locked"))await this.addCondition(o.lockedCondition());else if(!U(this,"system.merchant.locked")){let e=this.effects.find(t=>t.statuses.has("locked"));e&&await this.deleteEmbeddedDocuments("ActiveEffect",[e.id])}}}static lockedCondition(){return{id:"locked",name:game.i18n.localize("MERCHANT.locked"),img:"icons/svg/padlock.svg",flags:{dsa5:{noEffect:!0,hidePlayers:!0,description:game.i18n.localize("MERCHANT.locked")}}}}applyActiveEffects(){let e={};this.statuses??=new Set;let t=new Map;for(let c of Object.values(CONFIG.specialStatusEffects))t.set(c,this.statuses.has(c));this.statuses.clear();let a=[],s=1;for(let c of this.effects){if(c.disabled||c.system.delayed)continue;if(U(c,"flags.dsa5.isAura")){this.auras.push(c.uuid);continue}s=1;let m=c.getFlag("dsa5","value");m&&(s=Number(m));for(let d=0;d(p=foundry.utils.duplicate(p),p.effect=c,p.priority=p.priority?p.priority:p.mode*10,p)));for(let d of c.statuses)this.statuses.add(d)}let i=!0,n=this.items.filter(c=>["rangeweapon","meleeweapon","equipment","armor"].includes(c.type)&&c.system.isArtifact&&(c.system.worn.value||c.type=="equipment"&&!c.system.worn.wearable)).map(c=>c.system.artifact),r=!game.settings.get("dsa5","enableWeaponAdvantages");this.dsatriggers={6:{},7:{}};for(let c of this.items)for(let m of c.effects){if(m.disabled||!m.transfer||m.system.delayed)continue;switch(i=!0,c.type){case"meleeweapon":case"rangeweapon":if(r&&m.system.equipmentAdvantage)continue;i=c.system.worn.value&&m.getFlag("dsa5","applyToOwner");break;case"armor":if(r&&m.system.equipmentAdvantage)continue;i=c.system.worn.value;break;case"equipment":i=!c.system.worn.wearable||c.system.worn.wearable&&c.system.worn.value;break;case"trait":i=!["meleeAttack","rangeAttack"].includes(c.system.traitType.value)||m.getFlag("dsa5","applyToOwner"),s=Number(U(c.system,"step.value"))||1;break;case"ammunition":case"plant":case"consumable":case"combatskill":case"magicsign":case"poison":case"spell":case"liturgy":case"ceremony":case"ritual":case"skill":case"spellextension":i=!1;break;case"specialability":switch(c.system.category.value){case"Combat":i=[2,3].includes(Number(c.system.category.sub));break;case"staff":i=c.system.permanentEffects||n.includes(c.system.artifact);break;default:i=!0}s=Number(c.system.step.value)||1;break;case"advantage":case"disadvantage":s=Number(c.system.step.value)||1;break}let d=U(m,"flags.dsa5.advancedFunction");if(Object.prototype.hasOwnProperty.call(this.dsatriggers,d)&&(this.dsatriggers[d][c.id]=m.id),m.notApplicable=!i,i&&U(m,"flags.dsa5.isAura")){this.auras.push(m.uuid);continue}if(i){for(let p=0;p(f=foundry.utils.duplicate(f),f.effect=m,f.priority=f.priority?f.priority:f.mode*10,f)));for(let p of m.statuses)this.statuses.add(p)}}a.sort((c,m)=>c.priority-m.priority);for(let c of a){if(!c.key||o.selfRegex.test(c.key))continue;let m=c.effect.apply(this,c);Object.assign(e,m)}this.overrides=Rr(e);let l;for(let[c,m]of t){let d=this.statuses.has(c);if(d!==m){l??=this.getActiveTokens();for(let p of l)p._onApplyStatusEffect(c,d)}}}_setOnUseEffect(e){U(e,"flags.dsa5.onUseEffect")&&(e.OnUseEffect=!0)}_setAEPayments(e){if(e.OnUseEffect)return;Number(U(e,"system.AsPCost"))&&(e.AEpayable=!0)}prepareBaseData(){let e=this.system;this.auras=[],we(e,{itemModifiers:{},condition:{},swarm:{attack:0,parry:0,damage:0},creatureType:this.creatureType,skillModifiers:{FP:[],step:[],QL:[],TPM:[],FW:[],botch:20,crit:1,global:[],conditional:{AsPCost:[],KaPCost:[]},combat:{step:[],parry:[],attack:[],damage:[]},feature:{FP:[],step:[],QL:[],TPM:[],FW:[],KaPCost:[],AsPCost:[]},...["liturgy","ceremony","ritual","spell","skill"].reduce((t,a)=>(t[a]={FP:[],step:[],QL:[],TPM:[],FW:[]},t),{})},status:{initiative:{multiplier:1},astralenergy:{permanentGear:0},karmaenergy:{permanentGear:0},wounds:{multiplier:1},speed:{multiplier:1},regeneration:{LePgearmodifier:0,KaPgearmodifier:0,AsPgearmodifier:0}},repeatingEffects:{startOfRound:{wounds:[],karmaenergy:[],astralenergy:[]}},temperature:{heatProtection:0,coldProtection:0},totalArmor:0,spellArmor:0,liturgyArmor:0,carryModifier:0,aspModifier:0,kapModifier:0,immunities:[],thresholds:{effects:[]},creatureBonus:[],miracle:{attack:0,parry:0},spellStats:{damage:"0"},liturgyStats:{damage:"0"},meleeStats:{parry:0,attack:0,damage:"0",defenseMalus:0,botch:20,crit:1},rangeStats:{attack:0,damage:"0",defenseMalus:0,botch:20,crit:1}});for(let t of b.gearModifyableCalculatedAttributes)e.status[t]&&(e.status[t].gearmodifier=0);for(let t of Object.values(e.characteristics))t.gearmodifier=0}getSkillModifier(e,t){let a=[],s=["FP","step","QL","TPM","FW"];for(let i of s){let n=i=="step"?"":i;a.push(...this.system.skillModifiers[i].filter(r=>r.target==e).map(r=>({name:r.source,value:r.value,source:r.item,type:n}))),this.system.skillModifiers[t]&&a.push(...this.system.skillModifiers[t][i].map(r=>({name:r.target||r.source,value:r.value,source:r.source,type:n})))}return a}getCombatEffectSkillModifier(e,t){let a=[],s=["step",t];for(let i of s)a.push(...this.system.skillModifiers.combat[i].filter(n=>n.target==e).map(n=>({name:`${n.target||n.source} - ${game.i18n.localize(`CHAR.${i.toUpperCase()}`)}`,value:n.value,source:n.source,type:i,selected:!0})));return a}prepareSheet(e){let t={system:{characteristics:{}}};if(we(t,this.prepareItems(e)),t.canAdvance){let a=["wounds","astralenergy","karmaenergy"],s=this.system.isFamiliar||this.system.isPet,i=s?"C":"D";for(let n of a)we(t.system,{status:{[n]:{cost:game.i18n.format("advancementCost",{cost:g._calculateAdvCost(this.system.status[n].advances,"D")}),refund:game.i18n.format("refundCost",{cost:g._calculateAdvCost(this.system.status[n].advances,"D",0)})}}});i=s?"C":"E";for(let[n,r]of Object.entries(this.system.characteristics))t.system.characteristics[n]={cost:game.i18n.format("advancementCost",{cost:g._calculateAdvCost(r.initial+r.advances,i)}),refund:game.i18n.format("refundCost",{cost:g._calculateAdvCost(r.initial+r.advances,i,0)})}}return t}static canAdvance(e){return e.canAdvance}static armorOpposedTransformation(e,t,a){if(a.origin){let s=U(a.origin,"system.combatskill.value");t=t.map(i=>{let n=we(Ke(a),{armor:Ke(i)});if(s){s+=" ";for(let r of n.armor.effects)if(Me.realyRealyEnabled(r)){for(let l of r.changes)if(l.key=="self.armorVulnerability"){let c=l.value.split(/[,;]/),m;if(a.defenderTest.attackFromBehind&&(m=c.find(d=>d.trim().startsWith("attackFromBehind "))),m||(m=c.find(d=>d.trim().startsWith(s))),m){let d=Number(m.match(/[-+]?\d+/)[0])||0;for(let p of["head","rightleg","leftleg","rightarm","leftarm","value"])n.armor.system.protection[p]&&(n.armor.system.protection[p]=Math.max(0,n.armor.system.protection[p]+d))}else if(m=c.find(d=>d.trim().startsWith("randomArmor ")),m){let d=m.split(" ")[1].split("|"),p=d[Math.floor(Math.random()*d.length)];for(let f of["head","rightleg","leftleg","rightarm","leftarm","value"])n.armor.system.protection[f]&&(n.armor.system.protection[f]=p)}}}}return Z.applyRollTransformation(e,n,pe.EVENTS.ARMOR_TRANSFORMATION).options.armor})}return t}static armorValue(e,t={}){let a=this.armorOpposedTransformation(e,e.items.filter(n=>n.type=="armor"&&n.system.worn.value==!0),t),s=a.reduce((n,r)=>n+W.armorWearModifier(r,r.system.protection.value),0),i=e.items.reduce((n,r)=>n+(r.type=="trait"&&r.system.traitType.value=="armor"?Number(r.system.at.value):0),0);return{wornArmor:a,armor:s+i+(e.system.totalArmor||0)}}static _calculateCombatSkillValues(e,t,{step:a,parry:s,attack:i}={step:0,parry:0,attack:0}){let n=e.system.talentValue.value+a;if(e.system.weapontype.value=="melee"){let r=e.system.guidevalue.value.split("/").map(m=>Number(t.characteristics[m].initial)+Number(t.characteristics[m].modifier)+Number(t.characteristics[m].advances)+Number(t.characteristics[m].gearmodifier)),l=Math.max(...r),c=t.characteristics.mu.initial+t.characteristics.mu.modifier+t.characteristics.mu.advances+t.characteristics.mu.gearmodifier;e.system.parry.value=Math.ceil(n/2)+Math.max(0,Math.floor((l-8)/3))+Number(game.settings.get("dsa5","higherDefense"))+s,e.system.attack.value=n+Math.max(0,Math.floor((c-8)/3))+i}else{let r=t.characteristics.ff.initial+t.characteristics.ff.modifier+t.characteristics.ff.advances+t.characteristics.ff.gearmodifier;e.system.parry.value=0,e.system.attack.value=n+Math.max(0,Math.floor((r-8)/3))+i}return e.cost=game.i18n.format("advancementCost",{cost:g._calculateAdvCost(e.system.talentValue.value,e.system.StF.value)}),e}drawAuras(e=!1){for(let t of this.getActiveTokens())t.drawAuras(e)}_onCreateDescendantDocuments(...e){super._onCreateDescendantDocuments(...e),this.drawAuras()}_onUpdateDescendantDocuments(...e){super._onUpdateDescendantDocuments(...e);let t=e[1]=="effects"&&e[3].some(a=>["flags.dsa5.auraRadius","flags.dsa5.borderColor","flags.dsa5.disposition","flags.dsa5.fillColor","flags.dsa5.borderThickness"].some(s=>zr(a,s)));this.drawAuras(t)}_onDeleteDescendantDocuments(...e){super._onCreateDescendantDocuments(...e),this.drawAuras()}_perpareItemAdvancementCost(e){let t=this.system.isPet||this.system.isFamiliar?"C":e.system.StF.value;return e.cost=game.i18n.format("advancementCost",{cost:g._calculateAdvCost(e.system.talentValue.value,t)}),e.refund=game.i18n.format("refundCost",{cost:g._calculateAdvCost(e.system.talentValue.value,t,0)}),e}async modifyTokenAttribute(e,t,a=!1,s=!0){let i=foundry.utils.getProperty(this.system,e),n;return s?(a&&(t=Math.clamp(i.min||0,Number(i.value)+t,i.max)),n={[`system.${e}.value`]:t}):(a&&(t=Number(i)+t),n={[`system.${e}`]:t}),Hooks.call("modifyTokenAttribute",{attribute:e,value:t,isDelta:a,isBar:s},n)!==!1?this.update(n):this}schipshtml(){let e=[];for(let t=1;t<=Number(this.system.status.fatePoints.max);t++)e.push({value:t,cssClass:t<=Number(this.system.status.fatePoints.value)?"fullSchip":"emptySchip"});return e}prepareItems(e){let t=this.toObject(!1),a=[],s=[],i=[],n=[],r=[],l=[],c=[],m=[],d=[],p=[],f=Object.fromEntries(Object.keys(b.specialAbilityCategories).map(w=>[w,[]])),h=Object.fromEntries(Object.keys(b.traitCategories).map(w=>[w,[]])),y=[],k=[],D=[],v=[],I={hasSpells:this.system.isMage,hasPrayers:this.system.isPriest,liturgy:[],spell:[],ritual:[],ceremony:[],blessing:[],magictrick:[],magicalsign:[]},A={spell:{},ritual:{},ceremony:{},liturgy:{}},j=this.hasPlayerOwner?N.getGroupSchips():[],S=this.schipshtml(),M={meleeweapons:{items:[],show:!1,dataType:"meleeweapon"},rangeweapons:{items:[],show:!1,dataType:"rangeweapon"},armor:{items:[],show:!1,dataType:"armor"},ammunition:{items:[],show:!1,dataType:"ammunition"},plant:{items:[],show:!1,dataType:"plant"},poison:{items:[],show:!1,dataType:"poison"},book:{items:[],show:!1,dataType:"book"}};for(let w in b.equipmentTypes)M[w]={items:[],show:!1,dataType:w};M.misc.show=!0;let T={coins:[],total:0,show:!0};t.items=t.items.sort((w,G)=>w.name.localeCompare(G.name));let L=t.system.totalArmor||0,q={body:[],social:[],knowledge:[],trade:[],nature:[]},ve=new Map;for(let w of t.items.filter(G=>G.type=="equipment"&&G.system.equipmentType.value=="bags"))ve.set(w._id,[]);let Te=new Map,qe=[],St=!1,lt=t.items.some(w=>!["skill","combatskill","money"].includes(w.type)),ct=H.getHorse(this,!0);for(let w of t.items)try{let G=U(w,"system.parent_id");if(w.type=="ammunition"&&qe.push(o._prepareitemStructure(w)),G&&G!=w._id&&ve.has(G)){ve.get(G).push(w);continue}switch(e.details&&e.details.includes(w._id)&&(w.detailed="shown"),w.system.isArtifact&&(w.volume=b.traditionArtifacts[w.system.artifact]||0,w.volumeFinal=0,v.push(w)),w.type){case"skill":q[w.system.group.value].push(this._perpareItemAdvancementCost(w));break;case"information":m.push(w);break;case"aggregatedTest":n.push(w);break;case"spellextension":A[w.system.category][w.system.source]?A[w.system.category][w.system.source].push(w.name):A[w.system.category][w.system.source]=[w.name];break;case"ritual":case"spell":case"liturgy":case"ceremony":I[w.type].push(o.buildSpellChargeProgress(this._perpareItemAdvancementCost(w)));break;case"magicalsign":case"magictrick":case"blessing":I[w.type].push(w);break;case"trait":switch(w.system.traitType.value){case"rangeAttack":w=o._prepareRangeTrait(w,this.system);break;case"meleeAttack":w=o._prepareMeleetrait(w,this.system);break;case"armor":L+=Number(w.system.at.value);break}h[w.system.traitType.value].push(w),St=!0;break;case"combatskill":a.push(o._calculateCombatSkillValues(w,this.system));break;case"ammunition":M.ammunition.items.push(o.prepareMag(w)),M.ammunition.show=!0;break;case"meleeweapon":w.toggleValue=w.system.worn.value||!1,w.toggle=!0,this._setOnUseEffect(w),M.meleeweapons.items.push(o._prepareitemStructure(w)),M.meleeweapons.show=!0,w.toggleValue&&c.push(w);break;case"rangeweapon":w.toggleValue=w.system.worn.value||!1,w.toggle=!0,this._setOnUseEffect(w),M.rangeweapons.items.push(o._prepareitemStructure(w)),M.rangeweapons.show=!0;break;case"armor":if(w.toggleValue=w.system.worn.value||!1,M.armor.items.push(o._prepareitemStructure(w)),M.armor.show=!0,w.toggle=!0,this._setOnUseEffect(w),w.system.worn.value){for(let De in w.system.protection){let dt=w.system.protection[De];w.system.protection[De]=W.armorWearModifier(w,dt)}L+=Number(w.system.protection.value),y.push(w)}break;case"book":case"poison":case"plant":M[w.type].items.push(w),M[w.type].show=!0;break;case"consumable":M[w.system.equipmentType.value].items.push(o._prepareConsumable(w)),M[w.system.equipmentType.value].show=!0;break;case"equipment":w.toggle=U(w,"system.worn.wearable")||!1,w.toggle&&(w.toggleValue=w.system.worn.value||!1),this._setOnUseEffect(w),M[w.system.equipmentType.value].items.push(o._prepareitemStructure(w)),M[w.system.equipmentType.value].show=!0;break;case"money":T.coins.push(w),T.total+=w.system.quantity.value*w.system.price.value;break;case"advantage":this._setOnUseEffect(w),s.push(w);break;case"disadvantage":this._setOnUseEffect(w),i.push(w);break;case"specialability":this._setOnUseEffect(w),this._setAEPayments(w),f[w.system.category.value].push(w);break;case"disease":r.push(w);break;case"patron":f.magical.push(w);break;case"demonmark":l.push(w);break;case"essence":d.push(w);break;case"imprint":p.push(w);break;case"application":Te.has(w.system.skill)?Te.get(w.system.skill).push(w):Te.set(w.system.skill,[w]);break}}catch(G){this._itemPreparationError(w,G)}for(let w of M.bags.items)this._setBagContent(w,ve);for(let[w,G]of Object.entries(A))for(let[De,dt]of Object.entries(G)){let mn=I[w].find(er=>er.name==De);mn?mn.extensions=dt.join(", "):ui.notifications.warn(game.i18n.format("DSAError.noSpellForExtension",{name:De,category:g.categoryLocalization(w),extension:dt.join(",")}))}for(let w of M.rangeweapons.items)try{w.system.worn.value&&k.push(o._prepareRangeWeapon(w,qe,a,this))}catch(G){this._itemPreparationError(w,G)}for(let w of c)try{D.push(o._prepareMeleeWeapon(w,a,t,c.filter(G=>G._id!=w._id&&!N.isYieldedTwohanded(G))))}catch(G){this._itemPreparationError(w,G)}for(let w of Object.values(q))for(let G of w)G.applications=Te.get(G.name)||[];T.coins=T.coins.sort((w,G)=>w.system.price.value>G.system.price.value?-1:1),f.magical.push(...f.pact),f.clerical.push(...f.ceremonial);for(let w of f.staff){let G=v.find(De=>De.system.artifact==w.system.artifact);if(G){G.abilities==null&&(G.abilities=[]),G.abilities.push(w);let De=Number(w.system.volume)||0,dt=De>0?"volumeFinal":"volume";G[dt]+=Math.abs(De)*Number(w.system.step.value)}else f.magical.push(w)}let Zt=Ke(b.characteristics);Zt["-"]="-";let At=a.find(w=>w.name==game.i18n.localize("LocalizedIDs.wrestle"));return{totalWeight:parseFloat(this.system.totalWeight?.toFixed(3)),traditionArtifacts:v,armorSum:L,sortedSpecs:b.sortedSpecs,spellArmor:t.system.spellArmor||0,liturgyArmor:t.system.liturgyArmor||0,money:T,brawling:{attack:At?.system.attack.value||0,parry:At?.system.parry.value||0},encumbrance:this.system.condition?.encumbered||0,carrycapacity:this.system.carrycapacity,isSwarm:this.isSwarm(),canSwarm:!this.prototypeToken.actorLink,wornRangedWeapons:k,wornMeleeWeapons:D,moneyWeight:this.system.moneyWeight,horseActor:ct,advantages:s,hasAnyItem:lt,disadvantages:i,specAbs:f,information:m,aggregatedtests:n,wornArmor:y,essence:d,imprint:p,inventory:M,hasTrait:St,demonmarks:l,diseases:r,canBuild:game.dsa5.sheets.DSACharBuilder&&!t.system.details.species?.value,itemModifiers:this.system.itemModifiers,languagePoints:t.system.freeLanguagePoints?.value?`(${t.system.freeLanguagePoints?.used}/${t.system.freeLanguagePoints?.value})`:"",schips:S,groupschips:j,guidevalues:Zt,magic:I,traits:h,combatskills:a,canAdvance:this.canAdvance,sheetLocked:t.system.sheetLocked.value,bodyAttrs:["ff","ge","ko","kk"],mentalAttrs:["mu","kl","in","ch"],allSkillsLeft:{body:q.body,social:q.social,nature:q.nature},allSkillsRight:{knowledge:q.knowledge,trade:q.trade}}}isSwarm(){return this.system.swarm.count>1&&!this.prototypeToken.actorLink}getArmorEncumbrance(e,t){let a=t.reduce((i,n)=>(n.system.calculatedEncumbrance=Number(n.system.encumbrance.value)+W.armorEncumbranceModifier(n),n.system.damageToolTip=W.damageTooltip(n),i+=n.system.calculatedEncumbrance),0),s=H.isRiding(this)?-1:0;return Math.max(0,a-F.abilityStep(e,game.i18n.localize("LocalizedIDs.inuredToEncumbrance"))+s)}_calcBagweight(e,t,a=!0){let s=0;if(t.has(e._id)){let i=0;!e.system.worn.value&&a&&(s-=e.system.preparedWeight);for(let n of t.get(e._id))n.system.preparedWeight=Number(parseFloat((n.system.weight.value*n.system.quantity.value).toFixed(3))),t.has(n._id)?i+=this._calcBagweight(n,t,!1):i+=n.system.preparedWeight;a?e.system.worn.value&&(s+=i):s+=i+e.system.preparedWeight,e.system.bagweight=`${i.toFixed(3)}/${e.system.capacity}`}return s}_setBagContent(e,t){if(t.has(e._id)){e.children=[];for(let a of t.get(e._id))e.children.push(o._prepareitemStructure(o._prepareConsumable(a))),t.has(a._id)&&this._setBagContent(a,t)}}isMerchant(){return["merchant","loot"].includes(U(this,"system.merchant.merchantType"))}_itemPreparationError(e,t){console.error("Something went wrong with preparing item "+e.name+": "+t),console.warn(t),console.warn(e),ui.notifications.error("Something went wrong with preparing item "+e.name+": "+t)}_applyModiferTransformations(e){this.system.itemModifiers={};for(let t of Object.keys(e)){let a=game.dsa5.config.knownShortcuts[t.toLowerCase()];if(a){let s=e[t].reduce((i,n)=>i=i+n.value,0);this.system[a[0]][a[1]][a[2]]+=s,this.system.itemModifiers[t]={value:s,sources:e[t].map(i=>i.source)}}}}_buildGearAndAbilityModifiers(e,t){let a=U(t,"system.effect.value");if(a)for(let s of`${a}`.split(/,|;/).map(i=>i.trim())){let i=s.replace(/(\s+)/g," ").trim().split(" ");if(i.length==2&&!isNaN(i[0])){let n={value:Number(i[0])*(t.system.step&&Number(t.system.step.value)||1),source:t.name,type:t.type};e[i[1]]==null?e[i[1]]=[n]:e[i[1]].push(n)}}}async _updateAPs(e,t={},a={}){if(o.canAdvance(this))if(!isNaN(e)&&e!=null){let s=Number(e);t["system.details.experience.spent"]=Number(this.system.details.experience.spent)+s,await this.update(t,a);let i=game.i18n.format(s>0?"advancementCost":"refundCost",{cost:Math.abs(s)});ge(i)}else ui.notifications.error("DSAError.APUpdateError",{localize:!0})}async checkEnoughXP(e){if(!o.canAdvance(this)||isNaN(e)||e==null||Number(this.system.details.experience.total)-Number(this.system.details.experience.spent)>=e)return!0;if(Number(this.system.details.experience.total)==0){let t=await renderTemplate("systems/dsa5/templates/dialog/parts/expChoices.html",{entries:b.startXP}),a=0,s=!1;try{[s,a]=await foundry.applications.api.DialogV2.wait({window:{title:"DSAError.NotEnoughXP"},content:t,buttons:[{action:"yes",icon:"fa fa-check",label:"yes",default:!0,callback:u((i,n,r)=>[!0,Number(n.form.elements.APsel.value)],"callback")},{action:"cancel",icon:"fas fa-times",label:"cancel",callback:u(()=>[!1,0],"callback")}]})}catch{}if(s)return await this.update({"system.details.experience.total":a}),!0}return ui.notifications.error("DSAError.NotEnoughXP",{localize:!0}),!1}setupWeapon(e,t,a,s){return a.mode=t,C.getSubClass(e.type).setupDialog(null,a,e,this,s)}throwMelee(e,t){let a=game.i18n.localize("LocalizedIDs.Throwing Weapons"),s=game.i18n.localize(`LocalizedCTs.${e.system.combatskill.value}`),i=["Daggers","Fencing Weapons","Impact Weapons","Swords","Polearms"].includes(s)&&F.hasAbility(this,game.i18n.localize("LocalizedIDs.weaponThrow")),n=e.name+" ("+a+")",r=new C({name:n,type:"rangeweapon",system:{combatskill:{value:a},reach:{value:b.meleeAsRangeReach[s]},effect:{attributes:e.system.effect.attributes},damage:{value:e.system.damage.value},quantity:{value:1}}}),l={situationalModifiers:[{name:n,value:i?-4:-8,selected:!0}]};this.setupWeapon(r,"attack",l,t).then(async c=>{i||(c.testData.source.dmgMultipliers||=[],c.testData.source.dmgMultipliers.push({name:"LocalizedIDs.Throwing Weapons",val:"0.5"})),await this.basicTest(c)})}setupWeaponless(e,t={},a){let s=[];F.hasAbility(this,game.i18n.localize("LocalizedIDs.mightyAstralBody"))&&s.push(game.i18n.localize("magical")),F.hasAbility(this,game.i18n.localize("LocalizedIDs.mightyKarmalBody"))&&s.push(game.i18n.localize("blessed"));let i=b.defaultWeapon({name:game.i18n.localize(`${e}Weaponless`),system:{combatskill:{value:game.i18n.localize("LocalizedIDs.wrestle")},effect:{attributes:s.join(", ")}}});return t.mode=e,C.getSubClass(i.type).setupDialog(null,t,i,this,a)}setupSpell(e,t={},a){return this.setupSkill(e,t,a)}setupSkill(e,t={},a){return C.getSubClass(e.type).setupDialog(null,t,e,this,a)}tokenScrollingText(e){let t=this.isToken?[this.token?.object]:this.getActiveTokens(!0);for(let a of t){if(!a)continue;let s=0;for(let i of e)canvas.interface.createScrollingText(a.center,i.value,{anchor:s,direction:i.value>0?2:1,fontSize:game.settings.get("dsa5","scrollingFontsize"),stroke:i.stroke,strokeThickness:1,jitter:.25,duration:1e3}),s+=1}}_containsChangedAttribute(e,t){let a=U(e,t);return[null,void 0].includes(a)||a===U(this,t)?!1:a}async _preUpdate(e,t,a){let s={wounds:9109504,astralenergy:723929,karmaenergy:303670};game.combat?.isBrawling&&(s.temporaryLeP=16525967);let i=[];for(let l of Object.keys(s)){let c=this._containsChangedAttribute(e,`system.status.${l}.value`);c!==!1&&i.push({value:c-this.system.status[l].value,stroke:s[l]})}i.length&&this.tokenScrollingText(i);let n=this._containsChangedAttribute(e,"system.swarm.count");if(n!==!1&&!t.skipSwarmUpdate){let l=U(e,"system.status.wounds.value")||this.system.status.wounds.value,c=n-(this.system.swarm.count||1),m=this.system.swarm.maxwounds||this.system.status.wounds.max;Nr(e,"system.status.wounds.value",Math.max(0,l+c*m))}let r=this._containsChangedAttribute(e,"system.details.experience.total");if(r!==!1){let l=this.system.details.experience.total;_.track(this,{type:"sum",previous:l,next:r},r-l)}return super._preUpdate(e,t,a)}async applyDamage(e,t={}){let a=await new Roll(`${e}`).evaluate(),s=a.total;if(game.combat?.isBrawling){let i=Math.min(this.system.status.temporaryLeP.max,this.system.status.temporaryLeP.value-s);await this.update({"system.status.temporaryLeP.value":i})}else{let i=Math.min(this.system.status.wounds.max,this.system.status.wounds.value-s);await this.update({"system.status.wounds.value":i})}if(t.msg){let i=await a.render();ChatMessage.create(g.chatDataSetup(`
${game.i18n.format(t.msg,{name:this.name})}
${i}`))}}async applyRegeneration(e,t,a){let s={"system.status.wounds.value":Math.min(this.system.status.wounds.max,this.system.status.wounds.value+(e||0)),"system.status.karmaenergy.value":Math.min(this.system.status.karmaenergy.max,this.system.status.karmaenergy.value+(a||0)),"system.status.astralenergy.value":Math.min(this.system.status.astralenergy.max,this.system.status.astralenergy.value+(t||0))};await this.update(s)}async applyMana(e,t){let a=t=="AsP"?"astralenergy":"karmaenergy",s=(await new Roll(`${e}`).evaluate()).total,i=Math.min(this.system.status[a].max,this.system.status[a].value-s);return i>=0?(await this.update({[`system.status.${a}.value`]:i}),!0):(ui.notifications.error(`DSAError.NotEnough${t}`,{localize:!0}),!1)}preparePostRollAction(e){let t=e.flags.data,a={flags:{img:e.flags.img},rollMode:t.rollMode,speaker:e.speaker,template:t.template,title:t.title,user:e.author};return t.attackerMessage&&(a.attackerMessage=t.attackerMessage),t.defenderMessage&&(a.defenderMessage=t.defenderMessage),t.unopposedStartMessage&&(a.unopposedStartMessage=t.unopposedStartMessage),a}resetTargetAndMessage(e,t){e.originalTargets?.size&&(game.user.targets=e.originalTargets,game.user.targets.user=game.user),!e.defenderMessage&&e.startMessagesList&&(t.startMessagesList=e.startMessagesList)}async fatererollDamage(e,t,a,s,i,n){t.fatePointDamageRerollUsed=!0,this.resetTargetAndMessage(i,t);let r=i.postData.damageRoll,l=await R.manualRolls(await new Roll(r.formula||r._formula).evaluate(),"CHATCONTEXT.rerollDamage");for(let c=0;c${game.i18n.localize("CHATFATE.fatepointUsed")}
- ${game.i18n.format("CHATFATE.isTalented",{character:""+this.name+""})} `;let n=await renderTemplate("systems/dsa5/templates/dialog/isTalentedReroll-dialog.html",{testData:a,postData:i.postData});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:n,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async r=>{let l=r.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(l.length>0){let c=[];for(let p of l){let f=a.roll.terms[p*2];c.push(f.number+"d"+f.faces+"["+f.options.colorset+"]")}c=await R.manualRolls(await new Roll(c.join("+")).evaluate(),"CHATCONTEXT.talentedReroll"),await R.showDiceSoNice(c,a.rollMode);let m=0,d=[];for(let p of l){let f=a.source.system[`characteristic${p+1}`],h=f?game.i18n.localize(`CHARAbbrev.${f.value.toUpperCase()}`)+" - ":"";d.push(`${h}${a.roll.terms[p*2].results[0].result}/${c.terms[m*2].results[0].result}`),a.roll.terms[p*2].results[0].result=Math.min(c.terms[m*2].results[0].result,a.roll.terms[p*2].results[0].result),m+=1}e+=`${game.i18n.localize("Roll")}: ${d.join(", ")}`,ChatMessage.create(g.chatDataSetup(e)),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.talentedRerollUsed":!0})}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}async fatereroll(e,t,a,s,i,n){t.fatePointDamageRerollUsed=!0,this.resetTargetAndMessage(i,t);let r=await renderTemplate("systems/dsa5/templates/dialog/fateReroll-dialog.html",{testData:a,postData:i.postData,singleDie:i.postData.characteristics.length==1});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:r,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async l=>{let c=l.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(c.length>0){let m=[];for(let k of c){let D=a.roll.terms[k*2];m.push(D.number+"d"+D.faces+"["+D.options.colorset+"]")}m=await R.manualRolls(await new Roll(m.join("+")).evaluate(),"CHATCONTEXT.Reroll"),await R.showDiceSoNice(m,a.rollMode);let d=0,p=[],f=g.getSpeaker(a.extra.speaker),h=game.i18n.localize("LocalizedIDs.traditionPhex"),y=f.items.some(k=>k.type=="specialability"&&k.name==h);for(let k of c){let D=a.source.system[`characteristic${k+1}`],v=D?`${game.i18n.localize(`CHARAbbrev.${D.value.toUpperCase()}`)} - `:"";p.push(`${v}${a.roll.terms[k*2].results[0].result}/${m.terms[d*2].results[0].result}`),y?a.roll.terms[k*2].results[0].result=Math.min(m.terms[d*2].results[0].result,a.roll.terms[k*2].results[0].result):a.roll.terms[k*2].results[0].result=m.terms[d*2].results[0].result,d+=1}e+=` ${game.i18n.localize("Roll")}: ${p.join(", ")}`,ChatMessage.create(g.chatDataSetup(e)),a.fateUsed=!0,this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fatePointRerollUsed":!0}),await this.reduceSchips(n)}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}async fateaddQS(e,t,a,s,i,n){ChatMessage.create(g.chatDataSetup(e)),game.user.targets.forEach(r=>r.setTarget(!1,{user:game.user,releaseOthers:!1,groupSelection:!0})),t.fatePointAddQSUsed=!0,a.qualityStep=1,this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fatePointAddQSUsed":!0}),await this.reduceSchips(n)}async fateImprove(e,t,a,s,i,n){ChatMessage.create(g.chatDataSetup(e)),this.resetTargetAndMessage(i,t);let r=s.flags.data.preData.source.type;if(["spell","liturgy","ceremony","ritual","skill"].includes(r)){let l=await renderTemplate("systems/dsa5/templates/dialog/fateImprove-dialog.html",{testData:a,postData:i.postData});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:l,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async c=>{let m=[0,0,0],d=c.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(d.length==1){m[d]=2;let p={name:game.i18n.localize("CHATCONTEXT.improveFate"),value:m.join("|"),type:"roll"};a.roll.terms[d*2].results[0].result=Math.max(1,a.roll.terms[d*2].results[0].result-2),a.situationalModifiers.push(p),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fateImproved":!0}),await this.reduceSchips(n)}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}else{let l={name:game.i18n.localize("CHATCONTEXT.improveFate"),value:2,type:"roll"};a.situationalModifiers.push(l),a.roll.terms[0].results[0].result=Math.max(1,a.roll.terms[0].results[0].result-2),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fateImproved":!0}),await this.reduceSchips(n)}}async reduceSchips(e){e==0?await this.update({"system.status.fatePoints.value":this.system.status.fatePoints.value-1}):await o.reduceGroupSchip()}static async reduceGroupSchip(){if(game.user.isGM){let e=game.settings.get("dsa5","groupschips").split("/").map(t=>Number(t));e[0]=e[0]-1,await game.settings.set("dsa5","groupschips",e.join("/"))}else game.socket.emit("system.dsa5",{type:"reduceGroupSchip",payload:{}})}async useFateOnRoll(e,t,a){if(t=="isTalented"||g.fateAvailable(this,a==1)){let s=e.flags.data,i=this.preparePostRollAction(e),n,r;a==0?(n=this.system.status.fatePoints.value-1,r="PointsRemaining"):(n=game.settings.get("dsa5","groupschips").split("/")[0],r="GroupPointsRemaining");let l=`
`}static async rollResistPain(o){let e=o.currentTarget.dataset,t={token:e.token,actor:e.actor,scene:canvas.id},a=g.getSpeaker(t);a&&a.finishResistPainRoll()}static async wrapLock(o,e){let t=$(o.currentTarget);t.hasClass("locked")||(t.addClass("locked"),t.prepend(''),await e(o,t),setTimeout(()=>{t.removeClass("locked"),t.find("i").remove()},2e3))}static async chatListeners(o){o.on("click",".expand-mods",e=>{e.preventDefault();let t=$(e.currentTarget);t.find("i").toggleClass("fa-minus fa-plus"),t.siblings("ul,div").fadeToggle()}),o.on("click",".edit-toggle",e=>{e.preventDefault(),$(e.currentTarget).parents(".chat-card").find(".display-toggle").toggle()}),o.on("click",".botch-roll",e=>B.showBotchCard(e.currentTarget.dataset)),o.on("click",".roll-item",e=>_DiceDSA5._itemRoll(e)),o.on("click",".gearDamaged",async e=>_DiceDSA5.gearDamaged(e)),o.on("click",".applyDamage",async e=>wt($(e.currentTarget).closest(".message"),e.currentTarget.dataset.mode)),o.on("change",".roll-edit",e=>_DiceDSA5._rollEdit(e)),o.on("click",".applyEffect",async e=>{_DiceDSA5.wrapLock(e,async(t,a)=>{let s=a.parents(".message").attr("data-message-id"),i=t.currentTarget.dataset.target;await Z.applyEffect(s,i)})}),o.on("mouseenter",".applyEffect",e=>_DiceDSA5.showCurrentTargets(e)),o.on("click",".applyTableEffect",async e=>{_DiceDSA5.wrapLock(e,async(t,a)=>{let s=a.parents(".message").attr("data-message-id"),i=t.currentTarget.dataset.target;await Nt.applyEffect(s,i)})}),o.on("click",".placeTemplate",async e=>Le.placeTemplateFromChat(e)),o.on("click",".message-delete",e=>{let t=game.messages.get($(e.currentTarget).parents(".message").attr("data-message-id"));if(!t.flags.unopposeData)return;let s=canvas.tokens.get(t.flags.unopposeData.targetSpeaker.token);ee.clearOpposed(s.actor)}),o.on("click",".resistEffect",e=>Z.resistEffect(e)),o.on("click",".resistPain",e=>_DiceDSA5.rollResistPain(e)),ie.chatListeners(o)}};var{getProperty:U,mergeObject:we,duplicate:Ke,hasProperty:zr,setProperty:Nr,expandObject:Rr}=foundry.utils,O=class o extends Actor{static{u(this,"Actordsa5")}static DEFAULT_ICON="icons/svg/mystery-man-black.svg";static selfRegex=/^self\./;static skipAlternateWeaponKeys=new Set([["flags","system.description"]]);static async create(e,t){if(e instanceof Array||e.items)return await super.create(e,t);let a=await g.allSkills()||[],s=await g.allCombatSkills()||[],i=await g.allMoneyItems()||[];return e.items=[...a,...s,...i],e.type!="character"&&(e.system={status:{fatePoints:{current:0,value:0}}}),e.type!="creature"&&[void 0,0].includes(U(e,"system.status.wounds.value"))&&we(e,{system:{status:{wounds:{value:16}}}}),await super.create(e,t)}_getArmorCompensation(e,t,a){let s=F.abilityStep(e,game.i18n.localize("LocalizedIDs.inuredToEncumbrance")),i=t.reduce((n,r)=>n+=Number(r.system.encumbrance.value),0);if(s>i){let n=[game.i18n.localize("CHARAbbrev.GS"),game.i18n.localize("CHARAbbrev.INI")];for(let r of n)a[r]&&(a[r]=a[r].filter(l=>l.type!="armor"))}}_getItemModifiers(){let e=[],t={};for(let a of this.items.filter(s=>["meleeweapon","rangeweapon","armor","equipment"].includes(s.type)&&U(s,"system.worn.value")||["advantage","specialability","disadvantage"].includes(s.type)))this._buildGearAndAbilityModifiers(t,a),a.type=="armor"&&e.push(a);this._getArmorCompensation(this,e,t),this._applyModiferTransformations(t)}prepareDerivedData(){let e=this.system;try{this._getItemModifiers();for(let p of Object.values(e.characteristics))p.value=p.initial+p.advances+(p.modifier||0)+p.gearmodifier;e.totalWeight=0;let t=[],a=game.i18n.localize("LocalizedIDs.familiar"),s=game.i18n.localize("LocalizedIDs.companion"),i=game.settings.get("dsa5","moneyHasWeight"),n=new Map,r=this.items.filter(p=>p.type=="equipment"&&p.system.equipmentType.value=="bags");for(let p of r)n.set(p.id,[]);this.system.moneyWeight=0;for(let p of this.items)if(i&&p.type=="money")p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=Number(p.system.preparedWeight),this.system.moneyWeight+=Number(p.system.preparedWeight);else if(b.equipmentCategories.has(p.type)){let f=U(p,"system.parent_id");if(f&&f!=p._id&&n.has(f)){n.get(f).push(p);continue}p.type=="armor"?(p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=parseFloat((p.system.weight.value*(p.system.worn.value?Math.max(0,p.system.quantity.value-1):p.system.quantity.value)).toFixed(3)),p.system.worn.value&&t.push(p)):(p.system.preparedWeight=parseFloat((p.system.weight.value*p.system.quantity.value).toFixed(3)),e.totalWeight+=Number(p.system.preparedWeight))}else switch(p.type){case"trait":p.name==a?e.isFamiliar=!0:p.name==s&&(e.isPet=!0);break;case"spell":case"ritual":case"magictrick":e.isMage=!0;break;case"liturgy":case"ceremony":case"blessing":e.isPriest=!0;break;case"specialability":b.sortedSpecs.magical.has(p.system.category.value)?e.isMage=!0:b.sortedSpecs.clerical.has(p.system.category.value)&&(e.isPriest=!0);break}e.isMage||=e.isFamiliar;for(let p of r){let f=U(p,"system.parent_id");(!f||!n.has(f))&&(e.totalWeight+=this._calcBagweight(p,n,!0))}e.canAdvance=this.isOwner&&(this.type=="character"||e.isFamiliar||e.isPet),this.canAdvance=e.canAdvance,e.carrycapacity=e.characteristics.kk.value*2+e.carryModifier,e.canAdvance&&(e.details.experience.current=e.details.experience.total-e.details.experience.spent,e.details.experience.description=g.experienceDescription(e.details.experience.total)),(this.type=="character"||this.type=="npc")&&(e.status.wounds.current=e.status.wounds.initial+e.characteristics.ko.value*2,e.status.soulpower.value=(e.status.soulpower.initial||0)+Math.round((e.characteristics.mu.value+e.characteristics.kl.value+e.characteristics.in.value)/6),e.status.toughness.value=(e.status.toughness.initial||0)+Math.round((e.characteristics.ko.value+e.characteristics.ko.value+e.characteristics.kk.value)/6),e.status.wounds.min=-1*e.characteristics.ko.value),e.status.fatePoints.max=Number(e.status.fatePoints.current)+Number(e.status.fatePoints.modifier)+e.status.fatePoints.gearmodifier,this.type=="creature"&&(e.status.wounds.current=e.status.wounds.initial,e.status.astralenergy.current=e.status.astralenergy.initial,e.status.karmaenergy.current=e.status.karmaenergy.initial),e.status.wounds.max=Math.round((e.status.wounds.current+e.status.wounds.modifier+e.status.wounds.advances)*e.status.wounds.multiplier+e.status.wounds.gearmodifier),e.status.regeneration.LePmax=e.status.regeneration.LePTemp+e.status.regeneration.LePMod+e.status.regeneration.LePgearmodifier,e.status.regeneration.KaPmax=e.status.regeneration.KaPTemp+e.status.regeneration.KaPMod+e.status.regeneration.KaPgearmodifier,e.status.regeneration.AsPmax=e.status.regeneration.AsPTemp+e.status.regeneration.AsPMod+e.status.regeneration.AsPgearmodifier;let l=e.guidevalue;e.status.astralenergy.rebuy||=0,e.status.karmaenergy.rebuy||=0,e.status.astralenergy.permanentLoss||=0,e.status.karmaenergy.permanentLoss||=0,e.status.astralenergy.permanentLossSum=e.status.astralenergy.permanentLoss-e.status.astralenergy.rebuy+e.status.astralenergy.permanentGear,e.status.karmaenergy.permanentLossSum=e.status.karmaenergy.permanentLoss-e.status.karmaenergy.rebuy+e.status.karmaenergy.permanentGear,(e.isFamiliar||l&&this.type!="creature")&&(e.status.astralenergy.current=e.status.astralenergy.initial,e.status.karmaenergy.current=e.status.karmaenergy.initial,e.characteristics[l.magical]&&(e.status.astralenergy.current+=Math.round(e.characteristics[l.magical].value*e.energyfactor.magical)),e.characteristics[l.clerical]&&(e.status.karmaenergy.current+=Math.round(e.characteristics[l.clerical].value*e.energyfactor.clerical))),e.status.astralenergy.max=e.status.astralenergy.current+e.status.astralenergy.modifier+e.status.astralenergy.advances+e.status.astralenergy.gearmodifier-e.status.astralenergy.permanentLossSum,e.status.karmaenergy.max=e.status.karmaenergy.current+e.status.karmaenergy.modifier+e.status.karmaenergy.advances+e.status.karmaenergy.gearmodifier-e.status.karmaenergy.permanentLossSum,e.status.soulpower.max=e.status.soulpower.value+e.status.soulpower.modifier+e.status.soulpower.gearmodifier,e.status.toughness.max=e.status.toughness.value+e.status.toughness.modifier+e.status.toughness.gearmodifier,e.status.dodge.value=Math.round(e.characteristics.ge.value/2)+e.status.dodge.gearmodifier;let c=this.calcEncumbrance(e),m=H.isRiding(this)?H.getHorse(this):void 0;this.calcInitiative(e,c,m),e.status.dodge.max=Number(e.status.dodge.value)+Number(e.status.dodge.modifier)+Number(game.settings.get("dsa5","higherDefense"))/2,e.armorEncumbrance=this.getArmorEncumbrance(this,t),this.prepareSwarm(e),this.effectivePain(e);let d=this.statuses.has("fixated");this.calcSpeed(e,d,m),d&&(e.status.dodge.max=Math.max(0,e.status.dodge.max-4))}catch(t){console.error(`Something went wrong with preparing actor data ${this.name}: `+t+t.stack),ui.notifications.error(game.i18n.format("DSAError.PreparationError",{name:this.name})+t+t.stack)}}static async deferredEffectAddition(e,t,a){let i=(t.effects.find(r=>r.statuses.has(e))?.flags.dsa5.auto||0)!=a,n=`changing${e}`;t[n]=i,i&&await t.addCondition(e,a,!0,!0).then(()=>t[n]=void 0)}static async postUpdateConditions(e){if(!g.isActiveGM())return;let t=e.system,a=e.isMerchant();if(!he.hasTrait(e,game.i18n.localize("LocalizedIDs.painImmunity"))){let n=e.woundPain(t);await this.deferredEffectAddition("inpain",e,n)}let s=t.armorEncumbrance;(e.type!="creature"||e.canAdvance)&&!a&&(s+=Math.max(0,Math.ceil((t.totalWeight-t.carrycapacity-4)/4))),await this.deferredEffectAddition("encumbered",e,s);let i=e.woundPain(t,"temporaryLeP");await this.deferredEffectAddition("stunned",e,i),P.hasVantage(e,game.i18n.localize("LocalizedIDs.blind"))&&await e.addCondition("blind"),P.hasVantage(e,game.i18n.localize("LocalizedIDs.mute"))&&await e.addCondition("mute"),P.hasVantage(e,game.i18n.localize("LocalizedIDs.deaf"))&&await e.addCondition("deaf"),a&&await e.prepareMerchant()}static async _onCreateOperation(e,t,a){for(let s of e)await o.postUpdateConditions(s);return super._onCreateOperation(e,t,a)}static async _onUpdateOperation(e,t,a){for(let s of e)await o.postUpdateConditions(s);return super._onUpdateOperation(e,t,a)}prepareSwarm(e){let t=Number(e.swarm.count)||1;if(t<2)return;e.swarm.maxwounds=e.status.wounds.max,e.status.wounds.max*=t;let a=Math.min(Math.ceil(e.status.wounds.value/e.swarm.maxwounds),t),s=Number(e.swarm.gg)||1;e.swarm.attack+=Math.min(10,Math.floor(a/s)),e.swarm.parry+=-1,e.swarm.effectiveCount=a,e.swarm.damage=Math.min(5,Math.floor(a/s))}effectivePain(e){let t=e.condition.inpain||0;t<4&&(t-=P.vantageStep(this,game.i18n.localize("LocalizedIDs.ruggedFighter"))+P.vantageStep(this,game.i18n.localize("LocalizedIDs.ruggedAnimal"))+(F.hasAbility(this,game.i18n.localize("LocalizedIDs.traditionKor"))?1:0)),t>0&&(t+=P.vantageStep(this,game.i18n.localize("LocalizedIDs.sensitiveToPain"))+P.vantageStep(this,game.i18n.localize("LocalizedIDs.fragileAnimal"))),t=Math.clamp(t,0,4),e.condition.inpain=t}woundPain(e,t="wounds"){let a=0;return e.status[t].max>0&&(this.type!="creature"||e.status[t].max>=20?(a=Math.floor((1-e.status[t].value/e.status[t].max)*4),e.status[t].value<=5&&(a=4)):a=Math.floor(5-5*e.status[t].value/e.status[t].max)),Math.clamp(a,0,4)}calcSpeed(e,t,a){if(a){if(e.status.speed.max=a.system.status.speed.max,!e.status.speed.max){let s=a.system;a.calcSpeed(s,a.hasCondition("fixated"))}e.status.speed.max=a.system.status.speed.max}else{e.status.speed.max=e.status.speed.initial+(e.status.speed.modifier||0)+(e.status.speed.gearmodifier||0),e.status.speed.max=Math.round(Math.max(0,e.status.speed.max-Math.min(4,this.calcEncumbrance(e)))*e.status.speed.multiplier),this.hasCondition("bloodrush")||(e.status.speed.max=Math.max(0,e.status.speed.max-(e.condition?.inpain||0)));let s=this.hasCondition("paralysed");s&&(e.status.speed.max=Math.round(e.status.speed.max*(1-s.flags.dsa5.value*.25))),t||this.hasCondition("rooted")||this.hasCondition("incapacitated")?e.status.speed.max=0:this.hasCondition("prone")&&(e.status.speed.max=Math.min(1,e.status.speed.max)),H.updateRiderSpeed(this,e.status.speed.max)}}calcEncumbrance(e){return Math.clamp(e.condition?.encumbered||0,0,4)}calcInitiative(e,t,a){if(this.type=="character"||this.type=="npc"?e.status.initiative.value=Math.round((e.characteristics.mu.value+e.characteristics.ge.value)/2)+(e.status.initiative.modifier||0):e.status.initiative.value=e.status.initiative.current+(e.status.initiative.modifier||0),a){if(e.status.initiative.value=a.system.status.initiative.value,!e.status.initiative.value){let s=a.system;a.calcInitiative(s,a.calcEncumbrance(s)),e.status.initiative.value=s.status.initiative.value}}else{e.status.initiative.value+=(e.status.initiative.gearmodifier||0)-Math.min(4,t);let s=Number((.01*e.status.initiative.value).toFixed(2));e.status.initiative.value*=e.status.initiative.multiplier||1,e.status.initiative.value=Math.round(e.status.initiative.value)+s}}get creatureType(){return x.creatureTypeName(this)}async prepareMerchant(){if(U(this,"system.merchant.merchantType")=="loot"){if(U(this,"system.merchant.locked")&&!this.hasCondition("locked"))await this.addCondition(o.lockedCondition());else if(!U(this,"system.merchant.locked")){let e=this.effects.find(t=>t.statuses.has("locked"));e&&await this.deleteEmbeddedDocuments("ActiveEffect",[e.id])}}}static lockedCondition(){return{id:"locked",name:game.i18n.localize("MERCHANT.locked"),img:"icons/svg/padlock.svg",flags:{dsa5:{noEffect:!0,hidePlayers:!0,description:game.i18n.localize("MERCHANT.locked")}}}}applyActiveEffects(){let e={};this.statuses??=new Set;let t=new Map;for(let c of Object.values(CONFIG.specialStatusEffects))t.set(c,this.statuses.has(c));this.statuses.clear();let a=[],s=1;for(let c of this.effects){if(c.disabled||c.system.delayed)continue;if(U(c,"flags.dsa5.isAura")){this.auras.push(c.uuid);continue}s=1;let m=c.getFlag("dsa5","value");m&&(s=Number(m));for(let d=0;d(p=foundry.utils.duplicate(p),p.effect=c,p.priority=p.priority?p.priority:p.mode*10,p)));for(let d of c.statuses)this.statuses.add(d)}let i=!0,n=this.items.filter(c=>["rangeweapon","meleeweapon","equipment","armor"].includes(c.type)&&c.system.isArtifact&&(c.system.worn.value||c.type=="equipment"&&!c.system.worn.wearable)).map(c=>c.system.artifact),r=!game.settings.get("dsa5","enableWeaponAdvantages");this.dsatriggers={6:{},7:{}};for(let c of this.items)for(let m of c.effects){if(m.disabled||!m.transfer||m.system.delayed)continue;switch(i=!0,c.type){case"meleeweapon":case"rangeweapon":if(r&&m.system.equipmentAdvantage)continue;i=c.system.worn.value&&m.getFlag("dsa5","applyToOwner");break;case"armor":if(r&&m.system.equipmentAdvantage)continue;i=c.system.worn.value;break;case"equipment":i=!c.system.worn.wearable||c.system.worn.wearable&&c.system.worn.value;break;case"trait":i=!["meleeAttack","rangeAttack"].includes(c.system.traitType.value)||m.getFlag("dsa5","applyToOwner"),s=Number(U(c.system,"step.value"))||1;break;case"ammunition":case"plant":case"consumable":case"combatskill":case"magicsign":case"poison":case"spell":case"liturgy":case"ceremony":case"ritual":case"skill":case"spellextension":i=!1;break;case"specialability":switch(c.system.category.value){case"Combat":i=[2,3].includes(Number(c.system.category.sub));break;case"staff":i=c.system.permanentEffects||n.includes(c.system.artifact);break;default:i=!0}s=Number(c.system.step.value)||1;break;case"advantage":case"disadvantage":s=Number(c.system.step.value)||1;break}let d=U(m,"flags.dsa5.advancedFunction");if(Object.prototype.hasOwnProperty.call(this.dsatriggers,d)&&(this.dsatriggers[d][c.id]=m.id),m.notApplicable=!i,i&&U(m,"flags.dsa5.isAura")){this.auras.push(m.uuid);continue}if(i){for(let p=0;p(f=foundry.utils.duplicate(f),f.effect=m,f.priority=f.priority?f.priority:f.mode*10,f)));for(let p of m.statuses)this.statuses.add(p)}}a.sort((c,m)=>c.priority-m.priority);for(let c of a){if(!c.key||o.selfRegex.test(c.key))continue;let m=c.effect.apply(this,c);Object.assign(e,m)}this.overrides=Rr(e);let l;for(let[c,m]of t){let d=this.statuses.has(c);if(d!==m){l??=this.getActiveTokens();for(let p of l)p._onApplyStatusEffect(c,d)}}}_setOnUseEffect(e){U(e,"flags.dsa5.onUseEffect")&&(e.OnUseEffect=!0)}_setAEPayments(e){if(e.OnUseEffect)return;Number(U(e,"system.AsPCost"))&&(e.AEpayable=!0)}prepareBaseData(){let e=this.system;this.auras=[],we(e,{itemModifiers:{},condition:{},swarm:{attack:0,parry:0,damage:0},creatureType:this.creatureType,skillModifiers:{FP:[],step:[],QL:[],TPM:[],FW:[],botch:20,crit:1,global:[],conditional:{AsPCost:[],KaPCost:[]},combat:{step:[],parry:[],attack:[],damage:[]},feature:{FP:[],step:[],QL:[],TPM:[],FW:[],KaPCost:[],AsPCost:[]},...["liturgy","ceremony","ritual","spell","skill"].reduce((t,a)=>(t[a]={FP:[],step:[],QL:[],TPM:[],FW:[]},t),{})},status:{initiative:{multiplier:1},astralenergy:{permanentGear:0},karmaenergy:{permanentGear:0},wounds:{multiplier:1},speed:{multiplier:1},regeneration:{LePgearmodifier:0,KaPgearmodifier:0,AsPgearmodifier:0}},repeatingEffects:{startOfRound:{wounds:[],karmaenergy:[],astralenergy:[]}},temperature:{heatProtection:0,coldProtection:0},totalArmor:0,spellArmor:0,liturgyArmor:0,carryModifier:0,aspModifier:0,kapModifier:0,immunities:[],thresholds:{effects:[]},creatureBonus:[],miracle:{attack:0,parry:0},spellStats:{damage:"0"},liturgyStats:{damage:"0"},meleeStats:{parry:0,attack:0,damage:"0",defenseMalus:0,botch:20,crit:1},rangeStats:{attack:0,damage:"0",defenseMalus:0,botch:20,crit:1}});for(let t of b.gearModifyableCalculatedAttributes)e.status[t]&&(e.status[t].gearmodifier=0);for(let t of Object.values(e.characteristics))t.gearmodifier=0}getSkillModifier(e,t){let a=[],s=["FP","step","QL","TPM","FW"];for(let i of s){let n=i=="step"?"":i;a.push(...this.system.skillModifiers[i].filter(r=>r.target==e).map(r=>({name:r.source,value:r.value,source:r.item,type:n}))),this.system.skillModifiers[t]&&a.push(...this.system.skillModifiers[t][i].map(r=>({name:r.target||r.source,value:r.value,source:r.source,type:n})))}return a}getCombatEffectSkillModifier(e,t){let a=[],s=["step",t];for(let i of s)a.push(...this.system.skillModifiers.combat[i].filter(n=>n.target==e).map(n=>({name:`${n.target||n.source} - ${game.i18n.localize(`CHAR.${i.toUpperCase()}`)}`,value:n.value,source:n.source,type:i,selected:!0})));return a}prepareSheet(e){let t={system:{characteristics:{}}};if(we(t,this.prepareItems(e)),t.canAdvance){let a=["wounds","astralenergy","karmaenergy"],s=this.system.isFamiliar||this.system.isPet,i=s?"C":"D";for(let n of a)we(t.system,{status:{[n]:{cost:game.i18n.format("advancementCost",{cost:g._calculateAdvCost(this.system.status[n].advances,"D")}),refund:game.i18n.format("refundCost",{cost:g._calculateAdvCost(this.system.status[n].advances,"D",0)})}}});i=s?"C":"E";for(let[n,r]of Object.entries(this.system.characteristics))t.system.characteristics[n]={cost:game.i18n.format("advancementCost",{cost:g._calculateAdvCost(r.initial+r.advances,i)}),refund:game.i18n.format("refundCost",{cost:g._calculateAdvCost(r.initial+r.advances,i,0)})}}return t}static canAdvance(e){return e.canAdvance}static armorOpposedTransformation(e,t,a){if(a.origin){let s=U(a.origin,"system.combatskill.value");t=t.map(i=>{let n=we(Ke(a),{armor:Ke(i)});if(s){s+=" ";for(let r of n.armor.effects)if(Me.realyRealyEnabled(r)){for(let l of r.changes)if(l.key=="self.armorVulnerability"){let c=l.value.split(/[,;]/),m;if(a.defenderTest.attackFromBehind&&(m=c.find(d=>d.trim().startsWith("attackFromBehind "))),m||(m=c.find(d=>d.trim().startsWith(s))),m){let d=Number(m.match(/[-+]?\d+/)[0])||0;for(let p of["head","rightleg","leftleg","rightarm","leftarm","value"])n.armor.system.protection[p]&&(n.armor.system.protection[p]=Math.max(0,n.armor.system.protection[p]+d))}else if(m=c.find(d=>d.trim().startsWith("randomArmor ")),m){let d=m.split(" ")[1].split("|"),p=d[Math.floor(Math.random()*d.length)];for(let f of["head","rightleg","leftleg","rightarm","leftarm","value"])n.armor.system.protection[f]&&(n.armor.system.protection[f]=p)}}}}return Z.applyRollTransformation(e,n,pe.EVENTS.ARMOR_TRANSFORMATION).options.armor})}return t}static armorValue(e,t={}){let a=this.armorOpposedTransformation(e,e.items.filter(n=>n.type=="armor"&&n.system.worn.value==!0),t),s=a.reduce((n,r)=>n+W.armorWearModifier(r,r.system.protection.value),0),i=e.items.reduce((n,r)=>n+(r.type=="trait"&&r.system.traitType.value=="armor"?Number(r.system.at.value):0),0);return{wornArmor:a,armor:s+i+(e.system.totalArmor||0)}}static _calculateCombatSkillValues(e,t,{step:a,parry:s,attack:i}={step:0,parry:0,attack:0}){let n=e.system.talentValue.value+a;if(e.system.weapontype.value=="melee"){let r=e.system.guidevalue.value.split("/").map(m=>Number(t.characteristics[m].initial)+Number(t.characteristics[m].modifier)+Number(t.characteristics[m].advances)+Number(t.characteristics[m].gearmodifier)),l=Math.max(...r),c=t.characteristics.mu.initial+t.characteristics.mu.modifier+t.characteristics.mu.advances+t.characteristics.mu.gearmodifier;e.system.parry.value=Math.ceil(n/2)+Math.max(0,Math.floor((l-8)/3))+Number(game.settings.get("dsa5","higherDefense"))+s,e.system.attack.value=n+Math.max(0,Math.floor((c-8)/3))+i}else{let r=t.characteristics.ff.initial+t.characteristics.ff.modifier+t.characteristics.ff.advances+t.characteristics.ff.gearmodifier;e.system.parry.value=0,e.system.attack.value=n+Math.max(0,Math.floor((r-8)/3))+i}return e.cost=game.i18n.format("advancementCost",{cost:g._calculateAdvCost(e.system.talentValue.value,e.system.StF.value)}),e}drawAuras(e=!1){for(let t of this.getActiveTokens())t.drawAuras(e)}_onCreateDescendantDocuments(...e){super._onCreateDescendantDocuments(...e),this.drawAuras()}_onUpdateDescendantDocuments(...e){super._onUpdateDescendantDocuments(...e);let t=e[1]=="effects"&&e[3].some(a=>["flags.dsa5.auraRadius","flags.dsa5.borderColor","flags.dsa5.disposition","flags.dsa5.fillColor","flags.dsa5.borderThickness"].some(s=>zr(a,s)));this.drawAuras(t)}_onDeleteDescendantDocuments(...e){super._onCreateDescendantDocuments(...e),this.drawAuras()}_perpareItemAdvancementCost(e){let t=this.system.isPet||this.system.isFamiliar?"C":e.system.StF.value;return e.cost=game.i18n.format("advancementCost",{cost:g._calculateAdvCost(e.system.talentValue.value,t)}),e.refund=game.i18n.format("refundCost",{cost:g._calculateAdvCost(e.system.talentValue.value,t,0)}),e}async modifyTokenAttribute(e,t,a=!1,s=!0){let i=foundry.utils.getProperty(this.system,e),n;return s?(a&&(t=Math.clamp(i.min||0,Number(i.value)+t,i.max)),n={[`system.${e}.value`]:t}):(a&&(t=Number(i)+t),n={[`system.${e}`]:t}),Hooks.call("modifyTokenAttribute",{attribute:e,value:t,isDelta:a,isBar:s},n)!==!1?this.update(n):this}schipshtml(){let e=[];for(let t=1;t<=Number(this.system.status.fatePoints.max);t++)e.push({value:t,cssClass:t<=Number(this.system.status.fatePoints.value)?"fullSchip":"emptySchip"});return e}prepareItems(e){let t=this.toObject(!1),a=[],s=[],i=[],n=[],r=[],l=[],c=[],m=[],d=[],p=[],f=Object.fromEntries(Object.keys(b.specialAbilityCategories).map(w=>[w,[]])),h=Object.fromEntries(Object.keys(b.traitCategories).map(w=>[w,[]])),y=[],k=[],C=[],v=[],I={hasSpells:this.system.isMage,hasPrayers:this.system.isPriest,liturgy:[],spell:[],ritual:[],ceremony:[],blessing:[],magictrick:[],magicalsign:[]},S={spell:{},ritual:{},ceremony:{},liturgy:{}},j=this.hasPlayerOwner?N.getGroupSchips():[],A=this.schipshtml(),M={meleeweapons:{items:[],show:!1,dataType:"meleeweapon"},rangeweapons:{items:[],show:!1,dataType:"rangeweapon"},armor:{items:[],show:!1,dataType:"armor"},ammunition:{items:[],show:!1,dataType:"ammunition"},plant:{items:[],show:!1,dataType:"plant"},poison:{items:[],show:!1,dataType:"poison"},book:{items:[],show:!1,dataType:"book"}};for(let w in b.equipmentTypes)M[w]={items:[],show:!1,dataType:w};M.misc.show=!0;let T={coins:[],total:0,show:!0};t.items=t.items.sort((w,G)=>w.name.localeCompare(G.name));let L=t.system.totalArmor||0,q={body:[],social:[],knowledge:[],trade:[],nature:[]},ve=new Map;for(let w of t.items.filter(G=>G.type=="equipment"&&G.system.equipmentType.value=="bags"))ve.set(w._id,[]);let Te=new Map,qe=[],St=!1,lt=t.items.some(w=>!["skill","combatskill","money"].includes(w.type)),ct=H.getHorse(this,!0);for(let w of t.items)try{let G=U(w,"system.parent_id");if(w.type=="ammunition"&&qe.push(o._prepareitemStructure(w)),G&&G!=w._id&&ve.has(G)){ve.get(G).push(w);continue}switch(e.details&&e.details.includes(w._id)&&(w.detailed="shown"),w.system.isArtifact&&(w.volume=b.traditionArtifacts[w.system.artifact]||0,w.volumeFinal=0,v.push(w)),w.type){case"skill":q[w.system.group.value].push(this._perpareItemAdvancementCost(w));break;case"information":m.push(w);break;case"aggregatedTest":n.push(w);break;case"spellextension":S[w.system.category][w.system.source]?S[w.system.category][w.system.source].push(w.name):S[w.system.category][w.system.source]=[w.name];break;case"ritual":case"spell":case"liturgy":case"ceremony":I[w.type].push(o.buildSpellChargeProgress(this._perpareItemAdvancementCost(w)));break;case"magicalsign":case"magictrick":case"blessing":I[w.type].push(w);break;case"trait":switch(w.system.traitType.value){case"rangeAttack":w=o._prepareRangeTrait(w,this.system);break;case"meleeAttack":w=o._prepareMeleetrait(w,this.system);break;case"armor":L+=Number(w.system.at.value);break}h[w.system.traitType.value].push(w),St=!0;break;case"combatskill":a.push(o._calculateCombatSkillValues(w,this.system));break;case"ammunition":M.ammunition.items.push(o.prepareMag(w)),M.ammunition.show=!0;break;case"meleeweapon":w.toggleValue=w.system.worn.value||!1,w.toggle=!0,this._setOnUseEffect(w),M.meleeweapons.items.push(o._prepareitemStructure(w)),M.meleeweapons.show=!0,w.toggleValue&&c.push(w);break;case"rangeweapon":w.toggleValue=w.system.worn.value||!1,w.toggle=!0,this._setOnUseEffect(w),M.rangeweapons.items.push(o._prepareitemStructure(w)),M.rangeweapons.show=!0;break;case"armor":if(w.toggleValue=w.system.worn.value||!1,M.armor.items.push(o._prepareitemStructure(w)),M.armor.show=!0,w.toggle=!0,this._setOnUseEffect(w),w.system.worn.value){for(let De in w.system.protection){let dt=w.system.protection[De];w.system.protection[De]=W.armorWearModifier(w,dt)}L+=Number(w.system.protection.value),y.push(w)}break;case"book":case"poison":case"plant":M[w.type].items.push(w),M[w.type].show=!0;break;case"consumable":M[w.system.equipmentType.value].items.push(o._prepareConsumable(w)),M[w.system.equipmentType.value].show=!0;break;case"equipment":w.toggle=U(w,"system.worn.wearable")||!1,w.toggle&&(w.toggleValue=w.system.worn.value||!1),this._setOnUseEffect(w),M[w.system.equipmentType.value].items.push(o._prepareitemStructure(w)),M[w.system.equipmentType.value].show=!0;break;case"money":T.coins.push(w),T.total+=w.system.quantity.value*w.system.price.value;break;case"advantage":this._setOnUseEffect(w),s.push(w);break;case"disadvantage":this._setOnUseEffect(w),i.push(w);break;case"specialability":this._setOnUseEffect(w),this._setAEPayments(w),f[w.system.category.value].push(w);break;case"disease":r.push(w);break;case"patron":f.magical.push(w);break;case"demonmark":l.push(w);break;case"essence":d.push(w);break;case"imprint":p.push(w);break;case"application":Te.has(w.system.skill)?Te.get(w.system.skill).push(w):Te.set(w.system.skill,[w]);break}}catch(G){this._itemPreparationError(w,G)}for(let w of M.bags.items)this._setBagContent(w,ve);for(let[w,G]of Object.entries(S))for(let[De,dt]of Object.entries(G)){let mn=I[w].find(er=>er.name==De);mn?mn.extensions=dt.join(", "):ui.notifications.warn(game.i18n.format("DSAError.noSpellForExtension",{name:De,category:g.categoryLocalization(w),extension:dt.join(",")}))}for(let w of M.rangeweapons.items)try{w.system.worn.value&&k.push(o._prepareRangeWeapon(w,qe,a,this))}catch(G){this._itemPreparationError(w,G)}for(let w of c)try{C.push(o._prepareMeleeWeapon(w,a,t,c.filter(G=>G._id!=w._id&&!N.isYieldedTwohanded(G))))}catch(G){this._itemPreparationError(w,G)}for(let w of Object.values(q))for(let G of w)G.applications=Te.get(G.name)||[];T.coins=T.coins.sort((w,G)=>w.system.price.value>G.system.price.value?-1:1),f.magical.push(...f.pact),f.clerical.push(...f.ceremonial);for(let w of f.staff){let G=v.find(De=>De.system.artifact==w.system.artifact);if(G){G.abilities==null&&(G.abilities=[]),G.abilities.push(w);let De=Number(w.system.volume)||0,dt=De>0?"volumeFinal":"volume";G[dt]+=Math.abs(De)*Number(w.system.step.value)}else f.magical.push(w)}let Zt=Ke(b.characteristics);Zt["-"]="-";let At=a.find(w=>w.name==game.i18n.localize("LocalizedIDs.wrestle"));return{totalWeight:parseFloat(this.system.totalWeight?.toFixed(3)),traditionArtifacts:v,armorSum:L,sortedSpecs:b.sortedSpecs,spellArmor:t.system.spellArmor||0,liturgyArmor:t.system.liturgyArmor||0,money:T,brawling:{attack:At?.system.attack.value||0,parry:At?.system.parry.value||0},encumbrance:this.system.condition?.encumbered||0,carrycapacity:this.system.carrycapacity,isSwarm:this.isSwarm(),canSwarm:!this.prototypeToken.actorLink,wornRangedWeapons:k,wornMeleeWeapons:C,moneyWeight:this.system.moneyWeight,horseActor:ct,advantages:s,hasAnyItem:lt,disadvantages:i,specAbs:f,information:m,aggregatedtests:n,wornArmor:y,essence:d,imprint:p,inventory:M,hasTrait:St,demonmarks:l,diseases:r,canBuild:game.dsa5.sheets.DSACharBuilder&&!t.system.details.species?.value,itemModifiers:this.system.itemModifiers,languagePoints:t.system.freeLanguagePoints?.value?`(${t.system.freeLanguagePoints?.used}/${t.system.freeLanguagePoints?.value})`:"",schips:A,groupschips:j,guidevalues:Zt,magic:I,traits:h,combatskills:a,canAdvance:this.canAdvance,sheetLocked:t.system.sheetLocked.value,bodyAttrs:["ff","ge","ko","kk"],mentalAttrs:["mu","kl","in","ch"],allSkillsLeft:{body:q.body,social:q.social,nature:q.nature},allSkillsRight:{knowledge:q.knowledge,trade:q.trade}}}isSwarm(){return this.system.swarm.count>1&&!this.prototypeToken.actorLink}getArmorEncumbrance(e,t){let a=t.reduce((i,n)=>(n.system.calculatedEncumbrance=Number(n.system.encumbrance.value)+W.armorEncumbranceModifier(n),n.system.damageToolTip=W.damageTooltip(n),i+=n.system.calculatedEncumbrance),0),s=H.isRiding(this)?-1:0;return Math.max(0,a-F.abilityStep(e,game.i18n.localize("LocalizedIDs.inuredToEncumbrance"))+s)}_calcBagweight(e,t,a=!0){let s=0;if(t.has(e._id)){let i=0;!e.system.worn.value&&a&&(s-=e.system.preparedWeight);for(let n of t.get(e._id))n.system.preparedWeight=Number(parseFloat((n.system.weight.value*n.system.quantity.value).toFixed(3))),t.has(n._id)?i+=this._calcBagweight(n,t,!1):i+=n.system.preparedWeight;a?e.system.worn.value&&(s+=i):s+=i+e.system.preparedWeight,e.system.bagweight=`${i.toFixed(3)}/${e.system.capacity}`}return s}_setBagContent(e,t){if(t.has(e._id)){e.children=[];for(let a of t.get(e._id))e.children.push(o._prepareitemStructure(o._prepareConsumable(a))),t.has(a._id)&&this._setBagContent(a,t)}}isMerchant(){return["merchant","loot"].includes(U(this,"system.merchant.merchantType"))}_itemPreparationError(e,t){console.error("Something went wrong with preparing item "+e.name+": "+t),console.warn(t),console.warn(e),ui.notifications.error("Something went wrong with preparing item "+e.name+": "+t)}_applyModiferTransformations(e){this.system.itemModifiers={};for(let t of Object.keys(e)){let a=game.dsa5.config.knownShortcuts[t.toLowerCase()];if(a){let s=e[t].reduce((i,n)=>i=i+n.value,0);this.system[a[0]][a[1]][a[2]]+=s,this.system.itemModifiers[t]={value:s,sources:e[t].map(i=>i.source)}}}}_buildGearAndAbilityModifiers(e,t){let a=U(t,"system.effect.value");if(a)for(let s of`${a}`.split(/,|;/).map(i=>i.trim())){let i=s.replace(/(\s+)/g," ").trim().split(" ");if(i.length==2&&!isNaN(i[0])){let n={value:Number(i[0])*(t.system.step&&Number(t.system.step.value)||1),source:t.name,type:t.type};e[i[1]]==null?e[i[1]]=[n]:e[i[1]].push(n)}}}async _updateAPs(e,t={},a={}){if(o.canAdvance(this))if(!isNaN(e)&&e!=null){let s=Number(e);t["system.details.experience.spent"]=Number(this.system.details.experience.spent)+s,await this.update(t,a);let i=game.i18n.format(s>0?"advancementCost":"refundCost",{cost:Math.abs(s)});ge(i)}else ui.notifications.error("DSAError.APUpdateError",{localize:!0})}async checkEnoughXP(e){if(!o.canAdvance(this)||isNaN(e)||e==null||Number(this.system.details.experience.total)-Number(this.system.details.experience.spent)>=e)return!0;if(Number(this.system.details.experience.total)==0){let t=await renderTemplate("systems/dsa5/templates/dialog/parts/expChoices.html",{entries:b.startXP}),a=0,s=!1;try{[s,a]=await foundry.applications.api.DialogV2.wait({window:{title:"DSAError.NotEnoughXP"},content:t,buttons:[{action:"yes",icon:"fa fa-check",label:"yes",default:!0,callback:u((i,n,r)=>[!0,Number(n.form.elements.APsel.value)],"callback")},{action:"cancel",icon:"fas fa-times",label:"cancel",callback:u(()=>[!1,0],"callback")}]})}catch{}if(s)return await this.update({"system.details.experience.total":a}),!0}return ui.notifications.error("DSAError.NotEnoughXP",{localize:!0}),!1}setupWeapon(e,t,a,s){return a.mode=t,D.getSubClass(e.type).setupDialog(null,a,e,this,s)}throwMelee(e,t){let a=game.i18n.localize("LocalizedIDs.Throwing Weapons"),s=game.i18n.localize(`LocalizedCTs.${e.system.combatskill.value}`),i=["Daggers","Fencing Weapons","Impact Weapons","Swords","Polearms"].includes(s)&&F.hasAbility(this,game.i18n.localize("LocalizedIDs.weaponThrow")),n=e.name+" ("+a+")",r=new D({name:n,type:"rangeweapon",system:{combatskill:{value:a},reach:{value:b.meleeAsRangeReach[s]},effect:{attributes:e.system.effect.attributes},damage:{value:e.system.damage.value},quantity:{value:1}}}),l={situationalModifiers:[{name:n,value:i?-4:-8,selected:!0}]};this.setupWeapon(r,"attack",l,t).then(async c=>{i||(c.testData.source.dmgMultipliers||=[],c.testData.source.dmgMultipliers.push({name:"LocalizedIDs.Throwing Weapons",val:"0.5"})),await this.basicTest(c)})}setupWeaponless(e,t={},a){let s=[];F.hasAbility(this,game.i18n.localize("LocalizedIDs.mightyAstralBody"))&&s.push(game.i18n.localize("magical")),F.hasAbility(this,game.i18n.localize("LocalizedIDs.mightyKarmalBody"))&&s.push(game.i18n.localize("blessed"));let i=b.defaultWeapon({name:game.i18n.localize(`${e}Weaponless`),system:{combatskill:{value:game.i18n.localize("LocalizedIDs.wrestle")},effect:{attributes:s.join(", ")}}});return t.mode=e,D.getSubClass(i.type).setupDialog(null,t,i,this,a)}setupSpell(e,t={},a){return this.setupSkill(e,t,a)}setupSkill(e,t={},a){return D.getSubClass(e.type).setupDialog(null,t,e,this,a)}tokenScrollingText(e){let t=this.isToken?[this.token?.object]:this.getActiveTokens(!0);for(let a of t){if(!a)continue;let s=0;for(let i of e)canvas.interface.createScrollingText(a.center,i.value,{anchor:s,direction:i.value>0?2:1,fontSize:game.settings.get("dsa5","scrollingFontsize"),stroke:i.stroke,strokeThickness:1,jitter:.25,duration:1e3}),s+=1}}_containsChangedAttribute(e,t){let a=U(e,t);return[null,void 0].includes(a)||a===U(this,t)?!1:a}async _preUpdate(e,t,a){let s={wounds:9109504,astralenergy:723929,karmaenergy:303670};game.combat?.isBrawling&&(s.temporaryLeP=16525967);let i=[];for(let l of Object.keys(s)){let c=this._containsChangedAttribute(e,`system.status.${l}.value`);c!==!1&&i.push({value:c-this.system.status[l].value,stroke:s[l]})}i.length&&this.tokenScrollingText(i);let n=this._containsChangedAttribute(e,"system.swarm.count");if(n!==!1&&!t.skipSwarmUpdate){let l=U(e,"system.status.wounds.value")||this.system.status.wounds.value,c=n-(this.system.swarm.count||1),m=this.system.swarm.maxwounds||this.system.status.wounds.max;Nr(e,"system.status.wounds.value",Math.max(0,l+c*m))}let r=this._containsChangedAttribute(e,"system.details.experience.total");if(r!==!1){let l=this.system.details.experience.total;_.track(this,{type:"sum",previous:l,next:r},r-l)}return super._preUpdate(e,t,a)}async applyDamage(e,t={}){let a=await new Roll(`${e}`).evaluate(),s=a.total;if(game.combat?.isBrawling){let i=Math.min(this.system.status.temporaryLeP.max,this.system.status.temporaryLeP.value-s);await this.update({"system.status.temporaryLeP.value":i})}else{let i=Math.min(this.system.status.wounds.max,this.system.status.wounds.value-s);await this.update({"system.status.wounds.value":i})}if(t.msg){let i=await a.render();ChatMessage.create(g.chatDataSetup(`
${game.i18n.format(t.msg,{name:this.name})}
${i}`))}}async applyRegeneration(e,t,a){let s={"system.status.wounds.value":Math.min(this.system.status.wounds.max,this.system.status.wounds.value+(e||0)),"system.status.karmaenergy.value":Math.min(this.system.status.karmaenergy.max,this.system.status.karmaenergy.value+(a||0)),"system.status.astralenergy.value":Math.min(this.system.status.astralenergy.max,this.system.status.astralenergy.value+(t||0))};await this.update(s)}async applyMana(e,t){let a=t=="AsP"?"astralenergy":"karmaenergy",s=(await new Roll(`${e}`).evaluate()).total,i=Math.min(this.system.status[a].max,this.system.status[a].value-s);return i>=0?(await this.update({[`system.status.${a}.value`]:i}),!0):(ui.notifications.error(`DSAError.NotEnough${t}`,{localize:!0}),!1)}preparePostRollAction(e){let t=e.flags.data,a={flags:{img:e.flags.img},rollMode:t.rollMode,speaker:e.speaker,template:t.template,title:t.title,user:e.author};return t.attackerMessage&&(a.attackerMessage=t.attackerMessage),t.defenderMessage&&(a.defenderMessage=t.defenderMessage),t.unopposedStartMessage&&(a.unopposedStartMessage=t.unopposedStartMessage),a}resetTargetAndMessage(e,t){e.originalTargets?.size&&(game.user.targets=e.originalTargets,game.user.targets.user=game.user),!e.defenderMessage&&e.startMessagesList&&(t.startMessagesList=e.startMessagesList)}async fatererollDamage(e,t,a,s,i,n){t.fatePointDamageRerollUsed=!0,this.resetTargetAndMessage(i,t);let r=i.postData.damageRoll,l=await R.manualRolls(await new Roll(r.formula||r._formula).evaluate(),"CHATCONTEXT.rerollDamage");for(let c=0;c${game.i18n.localize("CHATFATE.fatepointUsed")}
+ ${game.i18n.format("CHATFATE.isTalented",{character:""+this.name+""})} `;let n=await renderTemplate("systems/dsa5/templates/dialog/isTalentedReroll-dialog.html",{testData:a,postData:i.postData});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:n,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async r=>{let l=r.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(l.length>0){let c=[];for(let f of l){let h=a.roll.terms[f*2];c.push(h.number+"d"+h.faces+"["+h.options.colorset+"]")}c=await R.manualRolls(await new Roll(c.join("+")).evaluate(),"CHATCONTEXT.talentedReroll"),await R.showDiceSoNice(c,a.rollMode);let m=0,d=[],p=[];a.roll=Roll.fromData(a.roll);for(let f of l){let h=a.source.system[`characteristic${f+1}`],y=h?game.i18n.localize(`CHARAbbrev.${h.value.toUpperCase()}`)+" - ":"",k=c.terms[m*2].results[0].result;d.push(`${y}${a.roll.terms[f*2].results[0].result}/${k}`),k=Math.min(k,a.roll.terms[f*2].results[0].result),p.push({index:f,val:k}),m+=1}a.roll.editRollAtIndex(p),e+=`${game.i18n.localize("Roll")}: ${d.join(", ")}`,ChatMessage.create(g.chatDataSetup(e)),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.talentedRerollUsed":!0})}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}async fatereroll(e,t,a,s,i,n){t.fatePointDamageRerollUsed=!0,this.resetTargetAndMessage(i,t);let r=await renderTemplate("systems/dsa5/templates/dialog/fateReroll-dialog.html",{testData:a,postData:i.postData,singleDie:i.postData.characteristics.length==1});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:r,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async l=>{let c=l.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(c.length>0){let m=[];for(let C of c){let v=a.roll.terms[C*2];m.push(v.number+"d"+v.faces+"["+v.options.colorset+"]")}m=await R.manualRolls(await new Roll(m.join("+")).evaluate(),"CHATCONTEXT.Reroll"),await R.showDiceSoNice(m,a.rollMode);let d=0,p=[],f=g.getSpeaker(a.extra.speaker),h=game.i18n.localize("LocalizedIDs.traditionPhex"),y=f.items.some(C=>C.type=="specialability"&&C.name==h);a.roll=Roll.fromData(a.roll);let k=[];for(let C of c){let v=a.source.system[`characteristic${C+1}`],I=v?`${game.i18n.localize(`CHARAbbrev.${v.value.toUpperCase()}`)} - `:"",S=m.terms[d*2].results[0].result;p.push(`${I}${a.roll.terms[C*2].results[0].result}/${S}`),y&&(S=Math.min(S,a.roll.terms[C*2].results[0].result)),k.push({index:C,val:S}),d+=1}a.roll.editRollAtIndex(k),e+=` ${game.i18n.localize("Roll")}: ${p.join(", ")}`,ChatMessage.create(g.chatDataSetup(e)),a.fateUsed=!0,this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fatePointRerollUsed":!0}),await this.reduceSchips(n)}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}async fateaddQS(e,t,a,s,i,n){ChatMessage.create(g.chatDataSetup(e)),game.user.targets.forEach(r=>r.setTarget(!1,{user:game.user,releaseOthers:!1,groupSelection:!0})),t.fatePointAddQSUsed=!0,a.qualityStep=1,this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fatePointAddQSUsed":!0}),await this.reduceSchips(n)}async fateImprove(e,t,a,s,i,n){ChatMessage.create(g.chatDataSetup(e)),this.resetTargetAndMessage(i,t);let r=s.flags.data.preData.source.type;if(["spell","liturgy","ceremony","ritual","skill"].includes(r)){let l=await renderTemplate("systems/dsa5/templates/dialog/fateImprove-dialog.html",{testData:a,postData:i.postData});new ae({title:game.i18n.localize("CHATFATE.selectDice"),content:l,buttons:{Yes:{icon:'',label:game.i18n.localize("Ok"),callback:u(async c=>{let m=[0,0,0],d=c.find(".dieSelected").map(function(){return Number($(this).attr("data-index"))}).get();if(d.length==1){m[d]=2;let p={name:game.i18n.localize("CHATCONTEXT.improveFate"),value:m.join("|"),type:"roll"};a.roll=Roll.fromData(a.roll),a.roll.editRollAtIndex([{index:d,val:Math.max(1,a.roll.terms[d*2].results[0].result-2)}]),a.situationalModifiers.push(p),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fateImproved":!0}),await this.reduceSchips(n)}},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}},default:"Yes"}).render(!0)}else{let l={name:game.i18n.localize("CHATCONTEXT.improveFate"),value:2,type:"roll"};a.situationalModifiers.push(l),a.roll=Roll.fromData(a.roll),a.roll.editRollAtIndex([{index:0,val:Math.max(1,a.roll.terms[0].results[0].result-2)}]),this[`${i.postData.postFunction}`]({testData:a,cardOptions:t},{rerenderMessage:s}),await s.update({"flags.data.fateImproved":!0}),await this.reduceSchips(n)}}async reduceSchips(e){e==0?await this.update({"system.status.fatePoints.value":this.system.status.fatePoints.value-1}):await o.reduceGroupSchip()}static async reduceGroupSchip(){if(game.user.isGM){let e=game.settings.get("dsa5","groupschips").split("/").map(t=>Number(t));e[0]=e[0]-1,await game.settings.set("dsa5","groupschips",e.join("/"))}else game.socket.emit("system.dsa5",{type:"reduceGroupSchip",payload:{}})}async useFateOnRoll(e,t,a){if(t=="isTalented"||g.fateAvailable(this,a==1)){let s=e.flags.data,i=this.preparePostRollAction(e),n,r;a==0?(n=this.system.status.fatePoints.value-1,r="PointsRemaining"):(n=game.settings.get("dsa5","groupschips").split("/")[0],r="GroupPointsRemaining");let l=`
`,buttons:[{action:"ok",default:!0,icon:"fas fa-check",label:"Ok",callback:u(()=>!1,"callback")},{action:"cancel",icon:"fas fa-close",label:"Cancel",callback:u(()=>!0,"callback")}]})}catch{}return a}async updateSkill(e,t,a=1,s=!0){let i=[];for(let n of e){let r=g.parseAbilityString(n.trim()),l=this.actor.items.find(c=>c.type==t&&c.name==r.name);l?i.push({_id:l.id,"system.talentValue.value":Math.max(0,a*r.step+(s?Number(l.system.talentValue.value):0))}):(console.warn(`Could not find ${t} ${n}`),this.errors.push(`${g.categoryLocalization(t)}: ${n}`))}await this.actor.updateEmbeddedDocuments("Item",i,{render:!1})}async getData(e){let t=await super.getData(e);return await game.dsa5.itemLibrary.buildEquipmentIndex(),t}_validateInput(e,t=this){let a=/^exclusive_/;for(let s of e.find(".tab")){let i=$(s),n=new Set;for(let r of i.find(".exclusive"))n.add(r.className.split(/\s+/).filter(l=>a.test(l))[0]);for(let r of n){let l=i.find(".allowedCount_"+r.split("_")[1]),c=Number(l.attr("data-count"));if(i.find(`.${r}:checked`).length!=c)return this._showInputValidation(l,i,t),!1}}return!0}_showInputValidation(e,t,a){ui.notifications.error("DSAError.MissingChoices",{localize:!0});let s=e.closest(".tab").attr("data-tab");a.activateTab(s),o.flashElem(t.find(`.tabs a[data-tab='${s}']`)),o.flashElem(e.closest("div"))}activateListeners(e){super.activateListeners(e),me(e),e.find("button.ok").click(()=>{this.updating||(this.updating=!0,this.updateCharacter($(this._element)).then(()=>this.updating=!1))}),e.find("button.cancel").click(()=>{this.close()});let t=u(s=>{s.stopPropagation();let i=s.currentTarget.dataset.type,n=s.currentTarget.dataset.uuid;!n||!i||s.originalEvent.dataTransfer.setData("text/plain",JSON.stringify({type:i,uuid:n}))},"itemDragStart"),a=e.find(".show-item");a.click(async s=>{let i=s.currentTarget.dataset.uuid;(await fromUuid(i)).sheet.render(!0)}),a.attr("draggable",!0).on("dragstart",s=>t(s)),e.on("click",".searchableAbility a",s=>mt(s)),e.find(".exclusive").change(s=>{let i=$(s.currentTarget).closest(".tab"),n=$(s.currentTarget).attr("data-sel"),r=i.find(`.allowedCount_${n}`),l=Number(r.attr("data-count"));if(i.find(`.exclusive_${n}:checked`).length>l){s.currentTarget.checked=!1,o.flashElem(r);return}})}static flashElem(e,t="emphasize"){e.addClass(t),setTimeout(function(){e.removeClass(t)},600)}finalizeUpdate(){this.errors.length==0?this.close():$(this._element).find(".dialog-buttons").html(`
`,buttons:[{action:"ok",default:!0,icon:"fas fa-check",label:"Ok",callback:u(()=>!1,"callback")},{action:"cancel",icon:"fas fa-close",label:"Cancel",callback:u(()=>!0,"callback")}]})}catch{}return a}async updateSkill(e,t,a=1,s=!0){let i=[];for(let n of e){let r=g.parseAbilityString(n.trim()),l=this.actor.items.find(c=>c.type==t&&c.name==r.name);l?i.push({_id:l.id,"system.talentValue.value":Math.max(0,a*r.step+(s?Number(l.system.talentValue.value):0))}):(console.warn(`Could not find ${t} ${n}`),this.errors.push(`${g.categoryLocalization(t)}: ${n}`))}await this.actor.updateEmbeddedDocuments("Item",i,{render:!1})}async getData(e){let t=await super.getData(e);return await game.dsa5.itemLibrary.buildEquipmentIndex(),t}_validateInput(e,t=this){let a=/^exclusive_/;for(let s of e.find(".tab")){let i=$(s),n=new Set;for(let r of i.find(".exclusive"))n.add(r.className.split(/\s+/).filter(l=>a.test(l))[0]);for(let r of n){let l=i.find(".allowedCount_"+r.split("_")[1]),c=Number(l.attr("data-count"));if(i.find(`.${r}:checked`).length!=c)return this._showInputValidation(l,i,t),!1}}return!0}_showInputValidation(e,t,a){ui.notifications.error("DSAError.MissingChoices",{localize:!0});let s=e.closest(".tab").attr("data-tab");a.activateTab(s),o.flashElem(t.find(`.tabs a[data-tab='${s}']`)),o.flashElem(e.closest("div"))}activateListeners(e){super.activateListeners(e),me(e),e.find("button.ok").click(()=>{this.updating||(this.updating=!0,this.updateCharacter($(this._element)).then(()=>this.updating=!1))}),e.find("button.cancel").click(()=>{this.close()});let t=u(s=>{s.stopPropagation();let i=s.currentTarget.dataset.type,n=s.currentTarget.dataset.uuid;!n||!i||s.originalEvent.dataTransfer.setData("text/plain",JSON.stringify({type:i,uuid:n}))},"itemDragStart"),a=e.find(".show-item");a.click(async s=>{let i=s.currentTarget.dataset.uuid;(await fromUuid(i)).sheet.render(!0)}),a.attr("draggable",!0).on("dragstart",s=>t(s)),e.on("click",".searchableAbility a",s=>mt(s)),e.find(".exclusive").change(s=>{let i=$(s.currentTarget).closest(".tab"),n=$(s.currentTarget).attr("data-sel"),r=i.find(`.allowedCount_${n}`),l=Number(r.attr("data-count"));if(i.find(`.exclusive_${n}:checked`).length>l){s.currentTarget.checked=!1,o.flashElem(r);return}})}static flashElem(e,t="emphasize"){e.addClass(t),setTimeout(function(){e.removeClass(t)},600)}finalizeUpdate(){this.errors.length==0?this.close():$(this._element).find(".dialog-buttons").html(`
`)),this.rendered&&this.render(!0)}},"callback");this.buildDialog(game.i18n.localize("MASTER.awardXP"),s,i)}getNames(e){return e.map(t=>t.name).join(", ")}buildDialog(e,t,a){new de({title:e,content:t,default:"Yes",buttons:{Yes:{icon:'',label:game.i18n.localize("yes"),callback:u(s=>{a(s)},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}}}).render(!0)}_canDragDrop(e){return!0}async _onDrop(e){let t;try{t=JSON.parse(e.dataTransfer.getData("text/plain")),t=await Actor.implementation.fromDropData(t)}catch{return!1}if(t.documentName=="Actor"){let a=game.settings.get("dsa5","trackedActors");a=a.actors||[],a.indexOf(t.id)==-1&&!t.pack&&(a.push(t.id),await this.setTrackedHeros(a),this.render(!0));let s=$(e.target).closest(".isFolder"),i=Pe(game.settings.get("dsa5","masterSettings"));s.length?i.folders=i.folders.map(n=>(n.content=n.content.filter(r=>r!=t.id),n.id==s[0].dataset.id&&n.content.push(t.id),n)):i.folders=i.folders?.map(n=>(n.content=n.content.filter(r=>r!=t.id),n))||[],await game.settings.set("dsa5","masterSettings",i),this.render(!0)}}selectedIDs(){let e=[],t=this.getSelectedActors();for(let[a,s]of Object.entries(t))s&&game.actors.has(a)&&e.push(a);return e.length?e:game.settings.get("dsa5","trackedActors").actors||[]}async doGroupCheck(e=0){let[t,a]=this.lastSkill.split("|");if(a!="skill")return;let s=await renderTemplate("systems/dsa5/templates/dialog/master-dialog-award.html",{amount:e,text:game.i18n.localize(game.i18n.format("MASTER.doGroupCheck",{skill:t}))}),i=u(n=>{let r=Number(n.find(".input-text").val()),[l,c]=this.lastSkill.split("|");c=="skill"&&ie.showGCMessage(l,r)},"callback");this.buildDialog(game.i18n.localize("HELP.groupcheck"),s,i)}async rollRequest(e=0){let[t,a]=this.lastSkill.split("|"),s=["attribute","skill","regeneration"];if(!s.includes(a))return;let i=await renderTemplate("systems/dsa5/templates/dialog/master-dialog-award.html",{amount:e,text:game.i18n.localize(game.i18n.format("MASTER.doRequestRoll",{skill:t}))}),n=u(r=>{let l=Number(r.find(".input-text").val()),[c,m]=this.lastSkill.split("|");s.includes(m)&&ie.showRQMessage(c,l)},"callback");this.buildDialog(game.i18n.localize("HELP.request"),i,n)}rollAbility(e){let[t,a]=this.lastSkill.split("|");switch(a){case"skill":this.rollSkill(e,t);break;case"attribute":this.rollAttribute(e,t);break;case"regeneration":this.rollRegeneration(e);break}}rollRegeneration(e){let t=game.actors.filter(a=>e.includes(a.id));for(let a of t)a.setupRegeneration("regenerate",{rollMode:"blindroll",subtitle:` (${a.name})`},void 0).then(s=>{a.basicTest(s)})}rollAttribute(e,t){let a=game.actors.filter(i=>e.includes(i.id)),s=Object.keys(game.dsa5.config.characteristics).find(i=>game.i18n.localize(game.dsa5.config.characteristics[i])==t);for(let i of a)i.setupCharacteristic(s,{rollMode:"blindroll",subtitle:` (${i.name})`},void 0).then(n=>{i.basicTest(n)})}rollSkill(e,t){let a=game.actors.filter(s=>e.includes(s.id));for(let s of a){let i=s.items.find(n=>n.name==t&&n.type=="skill");s.setupSkill(i,{rollMode:"blindroll",subtitle:` (${s.name})`},void 0).then(n=>{s.basicTest(n)})}}getID(e){return $(e.currentTarget).closest(".hero").attr("data-id")}static get defaultOptions(){let e=super.defaultOptions;return e.tabs=[{navSelector:".tabs",contentSelector:".content",initial:"main"}],Sa(e,{classes:e.classes.concat(["dsa5","largeDialog","masterMenu","sheet"]),width:470,height:740,title:game.i18n.localize("gmMenu"),dragDrop:[{dragSelector:null,dropSelector:null}]}),e.template="systems/dsa5/templates/system/mastermenu.html",e.resizable=!0,e}async getTrackedHeros(){let e=game.settings.get("dsa5","trackedActors"),t=[];return e.actors&&e.actors.length>0?t=game.actors.filter(a=>e.actors.includes(a.id)).sort((a,s)=>e.actors.indexOf(a.id)-e.actors.indexOf(s.id)):(t=game.actors.filter(a=>a.hasPlayerOwner),await this.setTrackedHeros(t.map(a=>a.id))),t}async getData(e){let t=await super.getData(e),a=await this.getTrackedHeros(),s=N.getGroupSchips(),i=game.settings.get("dsa5","sightOptions").split("|"),n=/ \[[a-zA-Zäöü\d-]+\]/,r=[1,2,3,4].map(p=>({label:game.i18n.localize(`VisionDisruption.step${p}`).replace(n,""),value:i[p-1]}));t.sceneConfig={sceneAutomationEnabled:game.settings.get("dsa5","sightAutomationEnabled"),enableDPS:game.settings.get("dsa5","enableDPS"),lightSightCompensationEnabled:game.settings.get("dsa5","lightSightCompensationEnabled"),visions:r,darkness:canvas.scene?.environment.darknessLevel||0},this.heros=a;let l=this.getSelectedActors(),c=Pe(game.settings.get("dsa5","masterSettings")),m=[],d=(c.folders||[]).map(p=>(p.contents=[],p.content=new Set(p.content),p));for(let p of a){let f=Fo(p),h=[],y=[],k=[];for(let v of f.items)switch(v.type){case"disadvantage":h.push({name:v.name,uuid:v.uuid});break;case"advantage":y.push({name:v.name,uuid:v.uuid});break;case"money":k.push(v);break}Sa(f,{id:p.id,uuid:p.uuid,selected:l[p.id],schips:p.schipshtml(),purse:k.sort((v,I)=>I.system.price.value-v.system.price.value).map(v=>`${v.system.quantity.value}`).join(" - "),advantages:y,disadvantages:h,system:{status:{wounds:{max:p.system.status.wounds.max},astralenergy:{max:p.system.status.astralenergy.max},karmaenergy:{max:p.system.status.karmaenergy.max}},isMage:p.system.isMage,isPriest:p.system.isPriest}});let D=!1;for(let v of d)if(v.content.has(p.id)){v.contents.push(f),D=!0;break}D||m.push(f)}if(!this.abilities){let p=await g.allSkillsList();this.abilities=p.map(f=>({name:f,type:"skill"})).concat(Object.values(game.dsa5.config.characteristics).map(f=>({name:game.i18n.localize(f),type:"attribute"})).concat({name:game.i18n.localize("regenerate"),type:"regeneration"})).map(f=>(f.key=`${f.name}|${f.type}`,f))}return Sa(t,{hasHeros:a.length>0,heros:m,folders:d,abilities:this.abilities,groupschips:s,masterSettings:c,lastSkill:this.lastSkill,randomCreation:this.randomCreation.map(p=>p.template),lightButton:game.dsa5.apps.LightDialog?await game.dsa5.apps.LightDialog.getButtonHTML():""}),t}registerRandomCreation(e){this.randomCreation.push(e)}},Aa=class extends FormApplication{static{u(this,"GlobalModAddition")}constructor(e){super(),this.mod_id=e}static get defaultOptions(){let e=super.defaultOptions;return e.template="systems/dsa5/templates/system/global-mod-addition.html",e.title=game.i18n.localize("MASTER.addGlobalMod"),e.width=400,e.resizable=!0,e}activateListeners(e){super.activateListeners(e),e.find(".addGlobalMod").click(t=>this.addGlobalMod(t))}async getData(e){let t=await super.getData(e);return this.mod_id?t.config=Pe(game.settings.get("dsa5","masterSettings").globalMods[this.mod_id]):t.config={value:0,victim:{npc:!0,player:!0}},t.categories=["skill","spell","meleeweapon","rangeweapon","ritual","ceremony","liturgy","trait"],t}async addGlobalMod(e){e.preventDefault();let t=Pe(game.settings.get("dsa5","masterSettings")),a=Pe(new FormDataExtended($(this._element).find("form")[0]).object);a.enabled=!0,a.name&&(this.mod_id?t.globalMods[this.mod_id]=a:Sa(t,{globalMods:{[Xn()]:a}}),await game.settings.set("dsa5","masterSettings",t),game.dsa5.apps.gameMasterMenu.render(),this.close())}};var qt=class extends Be(Ne){static{u(this,"CreatureMerchantSheetDSA5")}static get merchantTemplate(){return"systems/dsa5/templates/actors/merchant/creature-merchant-sheet.html"}};var Wt=class extends Be(Ce){static{u(this,"CharacterMerchantSheetDSA5")}static get merchantTemplate(){return"systems/dsa5/templates/actors/merchant/character-merchant-sheet.html"}};var{mergeObject:Ho}=foundry.utils,Ut=class extends JournalSheet{static{u(this,"DSAJournalSheet")}static get defaultOptions(){let e=super.defaultOptions;return Ho(e,{classes:e.classes.concat(["dsa5","dsajournal"])}),e}};function Zn(){let o=ActorDelta._onUpdateOperation;ActorDelta._onUpdateOperation=async(t,a,s)=>{for(let i of t)await O.postUpdateConditions(i.syntheticActor);return o(t,a,s)};let e=ActorDelta._onCreateOperation;ActorDelta._onCreateOperation=async(t,a,s)=>{for(let i of t)await O.postUpdateConditions(i.syntheticActor);return e(t,a,s)}}u(Zn,"setActorDelta");var{mergeObject:jo}=foundry.utils;function sn(){Mi(),Ei(),ys(),$i(),Oi(),_i(),$n(),ji(),Gi(),Ui(),Hi(),Ia(),Ki(),Ji(),Zn()}u(sn,"default");Hooks.once("init",()=>{loadTemplates(["systems/dsa5/templates/actors/actor-main.html","systems/dsa5/templates/actors/actor-talents.html","systems/dsa5/templates/items/item-description.html","systems/dsa5/templates/dialog/default-dialog.html","systems/dsa5/templates/dialog/parts/targets.html","systems/dsa5/templates/dialog/enhanced-default-dialog.html","systems/dsa5/templates/dialog/default-combat-dialog.html","systems/dsa5/templates/chat/roll/test-card.html","systems/dsa5/templates/items/item-equipment.html","systems/dsa5/templates/items/item-enchantment.html","systems/dsa5/templates/actors/actor-combat.html","systems/dsa5/templates/actors/actor-equipment.html","systems/dsa5/templates/actors/actor-notes.html","systems/dsa5/templates/dialog/parts/spellmodifiers.html","systems/dsa5/templates/dialog/parts/canChangeCastingTime.html","systems/dsa5/templates/actors/parts/schipspart.html","systems/dsa5/templates/chat/post-item.html","systems/dsa5/templates/items/item-stat.html","systems/dsa5/templates/items/item-extension.html","systems/dsa5/templates/actors/creature/creature-main.html","systems/dsa5/templates/actors/creature/creature-loot.html","systems/dsa5/templates/actors/creature/creature-notes.html","systems/dsa5/templates/actors/creature/creature-magic.html","systems/dsa5/templates/system/masterHeros.html","systems/dsa5/templates/actors/creature/creature-religion.html","systems/dsa5/templates/actors/parts/characteristics-large.html","systems/dsa5/templates/actors/parts/gearSearch.html","systems/dsa5/templates/actors/parts/magicalSigns.html","systems/dsa5/templates/actors/parts/containerContent.html","systems/dsa5/templates/actors/npc/npc-main.html","systems/dsa5/templates/actors/character/actor-magic.html","systems/dsa5/templates/actors/character/actor-religion.html","systems/dsa5/templates/actors/character/actor-aggregatedtests.html","systems/dsa5/templates/actors/parts/creature-derived-attributes-small.html","systems/dsa5/templates/actors/parts/creature-derived-attributes-large.html","systems/dsa5/templates/actors/parts/status_effects.html","systems/dsa5/templates/actors/parts/purse.html","systems/dsa5/templates/actors/parts/combat_weapon.hbs","systems/dsa5/templates/actors/parts/combat_rangeweapon.hbs","systems/dsa5/templates/actors/parts/horse.html","systems/dsa5/templates/actors/parts/healthbar.html","systems/dsa5/templates/actors/merchant/merchant-commerce.html","systems/dsa5/templates/items/item-header.html","systems/dsa5/templates/items/item-effects.html","systems/dsa5/templates/items/item-aoe.html","systems/dsa5/templates/items/traditionArtifact.html","systems/dsa5/templates/status/advanced_functions.html","systems/dsa5/templates/actors/parts/information.html","systems/dsa5/templates/actors/parts/personaltrait.html","systems/dsa5/templates/actors/parts/combatskills.html","systems/dsa5/templates/actors/parts/attributes.html","systems/dsa5/templates/actors/parts/swarm.html","systems/dsa5/templates/actors/parts/carryandpurse.html","systems/dsa5/templates/actors/parts/specialabilities.html","systems/dsa5/templates/actors/parts/experienceBox.html","systems/dsa5/templates/actors/parts/temperature.html","systems/dsa5/templates/actors/parts/temperatureSmall.html","systems/dsa5/templates/actors/parts/spells.html","systems/dsa5/templates/dialog/parts/expChoices.html","systems/dsa5/templates/actors/parts/liturgies.html","systems/dsa5/templates/items/browse/actor.html","systems/dsa5/templates/items/browse/garadan.html","systems/dsa5/templates/items/browse/culture.html","systems/dsa5/templates/items/browse/species.html","systems/dsa5/templates/items/browse/career.html","systems/dsa5/templates/items/meleeweapon-attack-part.hbs","systems/dsa5/templates/items/rangeweapon-attack-part.hbs","systems/dsa5/templates/actors/parts/specblock.html"]),Actors.unregisterSheet("core",ActorSheet),Actors.registerSheet("dsa5",Ce,{types:["character"],makeDefault:!0}),Actors.registerSheet("dsa5",Ne,{types:["creature"],makeDefault:!0}),Actors.registerSheet("dsa5",Re,{types:["npc"],makeDefault:!0}),Actors.registerSheet("dsa5",Ie,{types:["npc"]}),Actors.registerSheet("dsa5",qt,{types:["creature"]}),Actors.registerSheet("dsa5",Wt,{types:["character"]}),DocumentSheetConfig.registerSheet(ActiveEffect,"dsa5",Z,{makeDefault:!0}),Journal.registerSheet("dsa5",Ut,{makeDefault:!0}),Y.setupSheets(),Hooks.call("registerDSAstyle",b.styles),Kn(),ne.initDoorMinDistance(),jo(CONFIG.JournalEntry.noteIcons,b.noteIcons),K.prepareSoundEffects();let o=game.settings.get("dsa5","globalStyle");b.styles[o]||(o=Object.keys(b.styles)[0]),$("body").addClass(o)});Hooks.once("setup",()=>{if(!["de","en"].includes(game.i18n.lang))console.warn(`DSA5 - ${game.i18n.lang} is not a supported language. Falling back to default language.`),Go();else{let o=game.settings.get("dsa5","forceLanguage");["de","en"].includes(o)&&game.i18n.lang!=o&&Bo(o)}Gt.initHook(),Yi(),Bt.registerButtons(),pt.registerButtons(),CONFIG.Canvas.lightAnimations.daylight={label:"LIGHT.daylight",illuminationShader:an},P.setupFunctions(),F.setupFunctions()});Hooks.once("i18nInit",()=>{qo()});var tn=class extends foundry.applications.api.DialogV2{static{u(this,"ForbiddenLanguageDialog")}async close(e={}){if(["de","en"].includes(game.i18n.lang))return super.close(e)}},Go=u(()=>{new tn({window:{title:"language"},content:"
Your foundry language is not supported by this system. Due to technical reasons your foundry language setting has to be switched to either english or german.
`)),this.rendered&&this.render(!0)}},"callback");this.buildDialog(game.i18n.localize("MASTER.awardXP"),s,i)}getNames(e){return e.map(t=>t.name).join(", ")}buildDialog(e,t,a){new de({title:e,content:t,default:"Yes",buttons:{Yes:{icon:'',label:game.i18n.localize("yes"),callback:u(s=>{a(s)},"callback")},cancel:{icon:'',label:game.i18n.localize("cancel")}}}).render(!0)}_canDragDrop(e){return!0}async _onDrop(e){let t;try{t=JSON.parse(e.dataTransfer.getData("text/plain")),t=await Actor.implementation.fromDropData(t)}catch{return!1}if(t.documentName=="Actor"){let a=game.settings.get("dsa5","trackedActors");a=a.actors||[],a.indexOf(t.id)==-1&&!t.pack&&(a.push(t.id),await this.setTrackedHeros(a),this.render(!0));let s=$(e.target).closest(".isFolder"),i=Pe(game.settings.get("dsa5","masterSettings"));s.length?i.folders=i.folders.map(n=>(n.content=n.content.filter(r=>r!=t.id),n.id==s[0].dataset.id&&n.content.push(t.id),n)):i.folders=i.folders?.map(n=>(n.content=n.content.filter(r=>r!=t.id),n))||[],await game.settings.set("dsa5","masterSettings",i),this.render(!0)}}selectedIDs(){let e=[],t=this.getSelectedActors();for(let[a,s]of Object.entries(t))s&&game.actors.has(a)&&e.push(a);return e.length?e:game.settings.get("dsa5","trackedActors").actors||[]}async doGroupCheck(e=0){let[t,a]=this.lastSkill.split("|");if(a!="skill")return;let s=await renderTemplate("systems/dsa5/templates/dialog/master-dialog-award.html",{amount:e,text:game.i18n.localize(game.i18n.format("MASTER.doGroupCheck",{skill:t}))}),i=u(n=>{let r=Number(n.find(".input-text").val()),[l,c]=this.lastSkill.split("|");c=="skill"&&ie.showGCMessage(l,r)},"callback");this.buildDialog(game.i18n.localize("HELP.groupcheck"),s,i)}async rollRequest(e=0){let[t,a]=this.lastSkill.split("|"),s=["attribute","skill","regeneration"];if(!s.includes(a))return;let i=await renderTemplate("systems/dsa5/templates/dialog/master-dialog-award.html",{amount:e,text:game.i18n.localize(game.i18n.format("MASTER.doRequestRoll",{skill:t}))}),n=u(r=>{let l=Number(r.find(".input-text").val()),[c,m]=this.lastSkill.split("|");s.includes(m)&&ie.showRQMessage(c,l)},"callback");this.buildDialog(game.i18n.localize("HELP.request"),i,n)}rollAbility(e){let[t,a]=this.lastSkill.split("|");switch(a){case"skill":this.rollSkill(e,t);break;case"attribute":this.rollAttribute(e,t);break;case"regeneration":this.rollRegeneration(e);break}}rollRegeneration(e){let t=game.actors.filter(a=>e.includes(a.id));for(let a of t)a.setupRegeneration("regenerate",{rollMode:"blindroll",subtitle:` (${a.name})`},void 0).then(s=>{a.basicTest(s)})}rollAttribute(e,t){let a=game.actors.filter(i=>e.includes(i.id)),s=Object.keys(game.dsa5.config.characteristics).find(i=>game.i18n.localize(game.dsa5.config.characteristics[i])==t);for(let i of a)i.setupCharacteristic(s,{rollMode:"blindroll",subtitle:` (${i.name})`},void 0).then(n=>{i.basicTest(n)})}rollSkill(e,t){let a=game.actors.filter(s=>e.includes(s.id));for(let s of a){let i=s.items.find(n=>n.name==t&&n.type=="skill");s.setupSkill(i,{rollMode:"blindroll",subtitle:` (${s.name})`},void 0).then(n=>{s.basicTest(n)})}}getID(e){return $(e.currentTarget).closest(".hero").attr("data-id")}static get defaultOptions(){let e=super.defaultOptions;return e.tabs=[{navSelector:".tabs",contentSelector:".content",initial:"main"}],Sa(e,{classes:e.classes.concat(["dsa5","largeDialog","masterMenu","sheet"]),width:470,height:740,title:game.i18n.localize("gmMenu"),dragDrop:[{dragSelector:null,dropSelector:null}]}),e.template="systems/dsa5/templates/system/mastermenu.html",e.resizable=!0,e}async getTrackedHeros(){let e=game.settings.get("dsa5","trackedActors"),t=[];return e.actors&&e.actors.length>0?t=game.actors.filter(a=>e.actors.includes(a.id)).sort((a,s)=>e.actors.indexOf(a.id)-e.actors.indexOf(s.id)):(t=game.actors.filter(a=>a.hasPlayerOwner),await this.setTrackedHeros(t.map(a=>a.id))),t}async getData(e){let t=await super.getData(e),a=await this.getTrackedHeros(),s=N.getGroupSchips(),i=game.settings.get("dsa5","sightOptions").split("|"),n=/ \[[a-zA-Zäöü\d-]+\]/,r=[1,2,3,4].map(p=>({label:game.i18n.localize(`VisionDisruption.step${p}`).replace(n,""),value:i[p-1]}));t.sceneConfig={sceneAutomationEnabled:game.settings.get("dsa5","sightAutomationEnabled"),enableDPS:game.settings.get("dsa5","enableDPS"),lightSightCompensationEnabled:game.settings.get("dsa5","lightSightCompensationEnabled"),visions:r,darkness:canvas.scene?.environment.darknessLevel||0},this.heros=a;let l=this.getSelectedActors(),c=Pe(game.settings.get("dsa5","masterSettings")),m=[],d=(c.folders||[]).map(p=>(p.contents=[],p.content=new Set(p.content),p));for(let p of a){let f=Fo(p),h=[],y=[],k=[];for(let v of f.items)switch(v.type){case"disadvantage":h.push({name:v.name,uuid:v.uuid});break;case"advantage":y.push({name:v.name,uuid:v.uuid});break;case"money":k.push(v);break}Sa(f,{id:p.id,uuid:p.uuid,selected:l[p.id],schips:p.schipshtml(),purse:k.sort((v,I)=>I.system.price.value-v.system.price.value).map(v=>`${v.system.quantity.value}`).join(" - "),advantages:y,disadvantages:h,system:{status:{wounds:{max:p.system.status.wounds.max},astralenergy:{max:p.system.status.astralenergy.max},karmaenergy:{max:p.system.status.karmaenergy.max}},isMage:p.system.isMage,isPriest:p.system.isPriest}});let C=!1;for(let v of d)if(v.content.has(p.id)){v.contents.push(f),C=!0;break}C||m.push(f)}if(!this.abilities){let p=await g.allSkillsList();this.abilities=p.map(f=>({name:f,type:"skill"})).concat(Object.values(game.dsa5.config.characteristics).map(f=>({name:game.i18n.localize(f),type:"attribute"})).concat({name:game.i18n.localize("regenerate"),type:"regeneration"})).map(f=>(f.key=`${f.name}|${f.type}`,f))}return Sa(t,{hasHeros:a.length>0,heros:m,folders:d,abilities:this.abilities,groupschips:s,masterSettings:c,lastSkill:this.lastSkill,randomCreation:this.randomCreation.map(p=>p.template),lightButton:game.dsa5.apps.LightDialog?await game.dsa5.apps.LightDialog.getButtonHTML():""}),t}registerRandomCreation(e){this.randomCreation.push(e)}},Aa=class extends FormApplication{static{u(this,"GlobalModAddition")}constructor(e){super(),this.mod_id=e}static get defaultOptions(){let e=super.defaultOptions;return e.template="systems/dsa5/templates/system/global-mod-addition.html",e.title=game.i18n.localize("MASTER.addGlobalMod"),e.width=400,e.resizable=!0,e}activateListeners(e){super.activateListeners(e),e.find(".addGlobalMod").click(t=>this.addGlobalMod(t))}async getData(e){let t=await super.getData(e);return this.mod_id?t.config=Pe(game.settings.get("dsa5","masterSettings").globalMods[this.mod_id]):t.config={value:0,victim:{npc:!0,player:!0}},t.categories=["skill","spell","meleeweapon","rangeweapon","ritual","ceremony","liturgy","trait"],t}async addGlobalMod(e){e.preventDefault();let t=Pe(game.settings.get("dsa5","masterSettings")),a=Pe(new FormDataExtended($(this._element).find("form")[0]).object);a.enabled=!0,a.name&&(this.mod_id?t.globalMods[this.mod_id]=a:Sa(t,{globalMods:{[Xn()]:a}}),await game.settings.set("dsa5","masterSettings",t),game.dsa5.apps.gameMasterMenu.render(),this.close())}};var qt=class extends Be(Ne){static{u(this,"CreatureMerchantSheetDSA5")}static get merchantTemplate(){return"systems/dsa5/templates/actors/merchant/creature-merchant-sheet.html"}};var Wt=class extends Be(Ce){static{u(this,"CharacterMerchantSheetDSA5")}static get merchantTemplate(){return"systems/dsa5/templates/actors/merchant/character-merchant-sheet.html"}};var{mergeObject:Ho}=foundry.utils,Ut=class extends JournalSheet{static{u(this,"DSAJournalSheet")}static get defaultOptions(){let e=super.defaultOptions;return Ho(e,{classes:e.classes.concat(["dsa5","dsajournal"])}),e}};function Zn(){let o=ActorDelta._onUpdateOperation;ActorDelta._onUpdateOperation=async(t,a,s)=>{for(let i of t)await O.postUpdateConditions(i.syntheticActor);return o(t,a,s)};let e=ActorDelta._onCreateOperation;ActorDelta._onCreateOperation=async(t,a,s)=>{for(let i of t)await O.postUpdateConditions(i.syntheticActor);return e(t,a,s)}}u(Zn,"setActorDelta");var{mergeObject:jo}=foundry.utils;function sn(){Mi(),Ei(),ys(),$i(),Oi(),_i(),$n(),ji(),Gi(),Ui(),Hi(),Ia(),Ki(),Ji(),Zn()}u(sn,"default");Hooks.once("init",()=>{loadTemplates(["systems/dsa5/templates/actors/actor-main.html","systems/dsa5/templates/actors/actor-talents.html","systems/dsa5/templates/items/item-description.html","systems/dsa5/templates/dialog/default-dialog.html","systems/dsa5/templates/dialog/parts/targets.html","systems/dsa5/templates/dialog/enhanced-default-dialog.html","systems/dsa5/templates/dialog/default-combat-dialog.html","systems/dsa5/templates/chat/roll/test-card.html","systems/dsa5/templates/items/item-equipment.html","systems/dsa5/templates/items/item-enchantment.html","systems/dsa5/templates/actors/actor-combat.html","systems/dsa5/templates/actors/actor-equipment.html","systems/dsa5/templates/actors/actor-notes.html","systems/dsa5/templates/dialog/parts/spellmodifiers.html","systems/dsa5/templates/dialog/parts/canChangeCastingTime.html","systems/dsa5/templates/actors/parts/schipspart.html","systems/dsa5/templates/chat/post-item.html","systems/dsa5/templates/items/item-stat.html","systems/dsa5/templates/items/item-extension.html","systems/dsa5/templates/actors/creature/creature-main.html","systems/dsa5/templates/actors/creature/creature-loot.html","systems/dsa5/templates/actors/creature/creature-notes.html","systems/dsa5/templates/actors/creature/creature-magic.html","systems/dsa5/templates/system/masterHeros.html","systems/dsa5/templates/actors/creature/creature-religion.html","systems/dsa5/templates/actors/parts/characteristics-large.html","systems/dsa5/templates/actors/parts/gearSearch.html","systems/dsa5/templates/actors/parts/magicalSigns.html","systems/dsa5/templates/actors/parts/containerContent.html","systems/dsa5/templates/actors/npc/npc-main.html","systems/dsa5/templates/actors/character/actor-magic.html","systems/dsa5/templates/actors/character/actor-religion.html","systems/dsa5/templates/actors/character/actor-aggregatedtests.html","systems/dsa5/templates/actors/parts/creature-derived-attributes-small.html","systems/dsa5/templates/actors/parts/creature-derived-attributes-large.html","systems/dsa5/templates/actors/parts/status_effects.html","systems/dsa5/templates/actors/parts/purse.html","systems/dsa5/templates/actors/parts/combat_weapon.hbs","systems/dsa5/templates/actors/parts/combat_rangeweapon.hbs","systems/dsa5/templates/actors/parts/horse.html","systems/dsa5/templates/actors/parts/healthbar.html","systems/dsa5/templates/actors/merchant/merchant-commerce.html","systems/dsa5/templates/items/item-header.html","systems/dsa5/templates/items/item-effects.html","systems/dsa5/templates/items/item-aoe.html","systems/dsa5/templates/items/traditionArtifact.html","systems/dsa5/templates/status/advanced_functions.html","systems/dsa5/templates/actors/parts/information.html","systems/dsa5/templates/actors/parts/personaltrait.html","systems/dsa5/templates/actors/parts/combatskills.html","systems/dsa5/templates/actors/parts/attributes.html","systems/dsa5/templates/actors/parts/swarm.html","systems/dsa5/templates/actors/parts/carryandpurse.html","systems/dsa5/templates/actors/parts/specialabilities.html","systems/dsa5/templates/actors/parts/experienceBox.html","systems/dsa5/templates/actors/parts/temperature.html","systems/dsa5/templates/actors/parts/temperatureSmall.html","systems/dsa5/templates/actors/parts/spells.html","systems/dsa5/templates/dialog/parts/expChoices.html","systems/dsa5/templates/actors/parts/liturgies.html","systems/dsa5/templates/items/browse/actor.html","systems/dsa5/templates/items/browse/garadan.html","systems/dsa5/templates/items/browse/culture.html","systems/dsa5/templates/items/browse/species.html","systems/dsa5/templates/items/browse/career.html","systems/dsa5/templates/items/meleeweapon-attack-part.hbs","systems/dsa5/templates/items/rangeweapon-attack-part.hbs","systems/dsa5/templates/actors/parts/specblock.html"]),Actors.unregisterSheet("core",ActorSheet),Actors.registerSheet("dsa5",Ce,{types:["character"],makeDefault:!0}),Actors.registerSheet("dsa5",Ne,{types:["creature"],makeDefault:!0}),Actors.registerSheet("dsa5",Re,{types:["npc"],makeDefault:!0}),Actors.registerSheet("dsa5",Ie,{types:["npc"]}),Actors.registerSheet("dsa5",qt,{types:["creature"]}),Actors.registerSheet("dsa5",Wt,{types:["character"]}),DocumentSheetConfig.registerSheet(ActiveEffect,"dsa5",Z,{makeDefault:!0}),Journal.registerSheet("dsa5",Ut,{makeDefault:!0}),Y.setupSheets(),Hooks.call("registerDSAstyle",b.styles),Kn(),ne.initDoorMinDistance(),jo(CONFIG.JournalEntry.noteIcons,b.noteIcons),K.prepareSoundEffects();let o=game.settings.get("dsa5","globalStyle");b.styles[o]||(o=Object.keys(b.styles)[0]),$("body").addClass(o)});Hooks.once("setup",()=>{if(!["de","en"].includes(game.i18n.lang))console.warn(`DSA5 - ${game.i18n.lang} is not a supported language. Falling back to default language.`),Go();else{let o=game.settings.get("dsa5","forceLanguage");["de","en"].includes(o)&&game.i18n.lang!=o&&Bo(o)}Gt.initHook(),Yi(),Bt.registerButtons(),pt.registerButtons(),CONFIG.Canvas.lightAnimations.daylight={label:"LIGHT.daylight",illuminationShader:an},P.setupFunctions(),F.setupFunctions()});Hooks.once("i18nInit",()=>{qo()});var tn=class extends foundry.applications.api.DialogV2{static{u(this,"ForbiddenLanguageDialog")}async close(e={}){if(["de","en"].includes(game.i18n.lang))return super.close(e)}},Go=u(()=>{new tn({window:{title:"language"},content:"
Your foundry language is not supported by this system. Due to technical reasons your foundry language setting has to be switched to either english or german.
`,buttons:[{action:"ok",icon:"fa fa-check",label:"ok",callback:u(async()=>{await game.settings.set("core","language",o),foundry.utils.debouncedReload()},"callback")},{action:"cancel",icon:"fas fa-times",label:"cancel"}]}).render(!0)},"showWrongLanguageDialog");function qo(){game.dsa5.config.knownShortcuts={[game.i18n.localize("CHARAbbrev.INI").toLowerCase()]:["status","initiative","gearmodifier"],[game.i18n.localize("CHARAbbrev.GS").toLowerCase()]:["status","speed","gearmodifier"],[game.i18n.localize("CHARAbbrev.AsP").toLowerCase()]:["status","astralenergy","gearmodifier"],[game.i18n.localize("CHARAbbrev.LeP").toLowerCase()]:["status","wounds","gearmodifier"],[game.i18n.localize("CHARAbbrev.KaP").toLowerCase()]:["status","karmaenergy","gearmodifier"],[game.i18n.localize("CHARAbbrev.AW").toLowerCase()]:["status","dodge","gearmodifier"],[game.i18n.localize("CHARAbbrev.SK").toLowerCase()]:["status","soulpower","gearmodifier"],[game.i18n.localize("CHARAbbrev.ZK").toLowerCase()]:["status","toughness","gearmodifier"],[game.i18n.localize("CHARAbbrev.FtP").toLowerCase()]:["status","fatePoints","gearmodifier"]};for(let o of Object.keys(b.characteristics))game.dsa5.config.knownShortcuts[game.i18n.localize(`CHARAbbrev.${o.toUpperCase()}`).toLowerCase()]=["characteristics",o.toLowerCase(),"gearmodifier"]}u(qo,"setupKnownEquipmentModifiers");var an=class extends AdaptiveIlluminationShader{static{u(this,"DaylightIlluminationShader")}static fragmentShader=`
${this.SHADER_HEADER}
${this.PERCEIVED_BRIGHTNESS}
@@ -95,4 +95,4 @@ var tr=Object.defineProperty;var u=(o,e)=>tr(o,"name",{value:e,configurable:!0})
${i.join("")}
-
`,r={ammunition:[{label:"ammunitiongroup",attr:"ammunitiongroup.value",type:"select",options:b.ammunitiongroups}],equipment:[{label:"equipmentType",attr:"equipmentType.value",type:"select",options:b.equipmentTypes},{label:"PLANT.region",attr:"region",type:"text"}],book:[{label:"BOOKITEM.format",attr:"format",type:"select",options:b.bookFormats},{label:"BOOKITEM.quality",attr:"quality",type:"select",options:b.bookQualities},{label:"BOOKITEM.exemplarType",attr:"exemplarType",type:"select",options:b.exemplarTypes},{label:"BOOKITEM.availability",attr:"availability",type:"range"}],trap:[],rangeweapon:[{label:"TYPES.Item.combatskill",attr:"combatskill.value",type:"select",options:t},{label:"ammunitiongroup",attr:"ammunitiongroup.value",type:"select",options:b.ammunitiongroups},{label:"PLANT.region",attr:"region",type:"text"}],meleeweapon:[{label:"TYPES.Item.combatskill",attr:"combatskill.value",type:"select",options:a},{label:"guidevalue",attr:"guidevalue.value",type:"select",options:b.combatskillsGuidevalues},{label:"reach",attr:"reach.value",type:"select",options:b.meleeRanges},{label:"PLANT.region",attr:"region",type:"text"}],poison:[{label:"resistanceModifier",attr:"resistance.value",type:"select",options:b.magicResistanceModifiers},{label:"COMBATSKILLCATEGORY.subcategory",attr:"subcategory",type:"select",options:b.poisonSubTypes},{label:"poisonType",attr:"poisonType.value",type:"text"},{label:"PLANT.region",attr:"region",type:"text"}],disease:[{label:"resistanceModifier",attr:"resistance.value",type:"select",options:b.magicResistanceModifiers}],consumable:[{label:"equipmentType",attr:"equipmentType.value",type:"select",options:b.equipmentTypes}],application:[{label:"TYPES.Item.skill",attr:"skill",type:"select",options:e}],trait:[{label:"traitType",attr:"traitType.value",type:"select",options:b.traitCategories}],career:[{label:"mageLevel",attr:"mageLevel.value",type:"select",options:b.mageLevels}],specialability:[{type:"prerendered",attr:"category.value",content:n},{label:"TYPES.Item.combatskill",attr:"list.value",type:"select",options:s,notStrict:!0},{label:"distribution",attr:"distribution",type:"text"}],liturgy:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"}],spell:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"},{label:"feature",attr:"feature",type:"text"}],ritual:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"},{label:"feature",attr:"feature",type:"text"}],ceremony:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"}],spellextension:[{label:"Category",attr:"category",type:"select",options:{spell:"spell",liturgy:"liturgy",ritual:"ritual",ceremony:"ceremony"}}],magictrick:[{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"feature",attr:"feature.value",type:"text"},{label:"distribution",attr:"distribution",type:"text"}],blessing:[{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"feature",attr:"feature.value",type:"text"}],npc:[{label:"TYPES.Item.species",attr:"details.species.value",type:"text"},{label:"TYPES.Item.career",attr:"details.career.value",type:"text"},{label:"TYPES.Item.culture",attr:"details.culture.value",type:"text"}],character:[{label:"TYPES.Item.species",attr:"details.species.value",type:"text"},{label:"TYPES.Item.career",attr:"details.career.value",type:"text"},{label:"TYPES.Item.culture",attr:"details.culture.value",type:"text"}],creature:[{label:"creatureClass",attr:"creatureClass.value",type:"text"},{label:"sizeCategory",attr:"status.size.value",type:"select",options:b.sizeCategories}],armor:[{label:"protection",attr:"protection.value",type:"select",options:{0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"}},{label:"encumbrance",attr:"encumbrance.value",type:"select",options:{0:"0",1:"1",2:"2",3:"3",4:"4"}},{label:"PLANT.region",attr:"region",type:"text"}],plant:[{label:"PLANT.landscape",attr:"location.landscape",type:"text"},{label:"PLANT.region",attr:"location.region",type:"text"},{label:"PLANT.healing",attr:"planttype.healing",type:"checkbox"},{label:"PLANT.poison",attr:"planttype.poison",type:"checkbox"},{label:"PLANT.physical",attr:"planttype.physical",type:"checkbox"},{label:"PLANT.psychic",attr:"planttype.psychic",type:"checkbox"},{label:"PLANT.crop",attr:"planttype.crop",type:"checkbox"},{label:"PLANT.defensive",attr:"planttype.defensive",type:"checkbox"},{label:"PLANT.supernatural",attr:"planttype.supernatural",type:"checkbox"},{label:"PLANT.highNorth",attr:"availability.highNorth",type:"range"},{label:"PLANT.grasLands",attr:"availability.grasLands",type:"range"},{label:"PLANT.swamps",attr:"availability.swamps",type:"range"},{label:"PLANT.woods",attr:"availability.woods",type:"range"},{label:"PLANT.jungle",attr:"availability.jungle",type:"range"},{label:"PLANT.mountains",attr:"availability.mountains",type:"range"},{label:"PLANT.desert",attr:"availability.desert",type:"range"},{label:"PLANT.maraskan",attr:"availability.maraskan",type:"range"}],magicalsign:[],patron:[],demonmark:[],essence:[],imprint:[{label:"Category",attr:"category",type:"text"}]};for(let[l,c]of Object.entries(r))for(let m of c)m.type=="text"&&(m.placeholder=`Library.advancedSearchPlaceholders.${l}.${m.attr}`);Wo(nn,r),game.dsa5.advancedFilters=nn})});var Ca=nn;var{getProperty:rn,duplicate:Uo,debounce:Vo,mergeObject:Ko}=foundry.utils,Kt=class{static{u(this,"SearchDocument")}constructor(e,t={}){let a=e.documentName||e.type;switch(e.documentName){case"Actor":case"Item":a=e.type;break}let s="";if(game.settings.get("dsa5","indexDescription"))switch(a){case"creature":case"npc":case"character":s=rn(e,"system.description.value");break;case"JournalEntry":s=rn(e,"system.content");break;default:s=rn(e,"description.value")}this.document={name:e.name,filterType:a,data:$("
").html(s).text(),id:e.id||e._id,visible:e.visible?e.visible:!0,compendium:e.compendium?e.compendium.metadata.packageName:t.packageName||"",pack:e.pack||(t.packageName?t.id:void 0),img:e.img,price:e.system?.price?.value}}get uuid(){if(this.document.compendium)return`Compendium.${this.document.pack}.${this.document.id}`;switch(this.itemType){case"character":case"creature":case"npc":return`Actor.${this.id}`;case"JournalEntry":return`JournalEntry.${this.id}`;default:return`Item.${this.id}`}}get name(){return this.document.name}get data(){return this.document.data}get id(){return this.document.id}get itemType(){return this.document.filterType}get hasPrice(){return b.equipmentCategories.has(this.document.filterType)}async getItem(){return await fromUuid(this.uuid)}hasPermission(){return this.document.visible}async render(){(await this.getItem()).sheet.render(!0)}get compendium(){return this.document.compendium}get img(){return this.itemType=="JournalEntry"?"systems/dsa5/icons/categories/DSA-Auge.webp":this.document.img}},Da=class extends Kt{static{u(this,"AdvancedSearchDocument")}constructor(e,t){super(e);let a=Ca[t]||[];for(let s of a)this[s.attr]=s.attr.split(".").reduce((i,n)=>i[n]===void 0?{}:i[n],e.system)}},Tt=class o extends Application{static{u(this,"DSA5ItemLibrary")}constructor(e){super(e),this.advancedFiltering=!1,this.journalBuild=!1,this.journalWorldBuild=!1,this.equipmentBuild=!1,this.equipmentWorldBuild,this.zooBuild=!1,this.zooWorldBuild=!1,this.currentDetailFilter={equipment:[],character:[],spell:[],journal:[],zoo:[]},this.journalIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data"]}}),this.equipmentIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data","itemType"],tag:["itemType"]}}),this.zooIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data","itemType"],tag:["itemType"]}}),this.detailFilter={},this.pages={equipment:{},character:{},spell:{},journal:{},zoo:{}},this.filters={equipment:{categories:{armor:!1,ammunition:!1,equipment:!1,meleeweapon:!1,rangeweapon:!1,poison:!1,disease:!1,consumable:!1,plant:!1,book:!1,trap:!1},filterBy:{search:""}},character:{categories:{career:!1,advantage:!1,combatskill:!1,culture:!1,disadvantage:!1,trait:!1,skill:!1,specialability:!1,species:!1,application:!1,demonmark:!1,patron:!1,essence:!1,imprint:!1},filterBy:{search:""}},spell:{categories:{blessing:!1,ceremony:!1,liturgy:!1,magictrick:!1,ritual:!1,spell:!1,spellextension:!1,magicalsign:!1},filterBy:{search:""}},journal:{categories:{},filterBy:{search:""}},zoo:{categories:{npc:!1,character:!1,creature:!1},filterBy:{search:""}}}}async getData(e){let t=await super.getData(e);return t.categories=this.translateFilters(),t.isGM=game.user.isGM,t.advancedMode=this.advancedFiltering?"on":"",t.worldIndexed=game.settings.get("dsa5","indexWorldItems")?"on":"",t.fullTextEnabled=game.settings.get("dsa5","indexDescription")?"on":"",t.filterDuplicateItems=game.settings.get("dsa5","filterDuplicateItems")?"on":"",t.browseEnabled=this.browseEnabled?"on":"",this.advancedFiltering&&(t.advancedFilter=await this.buildDetailFilter("tbd",this.subcategory)),t}translateFilters(){return{equipment:this.buildFilter(this.filters.equipment),character:this.buildFilter(this.filters.character),spell:this.buildFilter(this.filters.spell),zoo:this.buildFilter(this.filters.zoo,"Actor"),journal:this.buildFilter(this.filters.journal)}}purgeAdvancedFilters(){for(let e in this.filters)for(let t in this.filters[e].categories)this.filters[e].categories[t]=!1;$(this._element).find('.filter[type="checkbox"]').prop("checked",!1),this.buildDetailFilter("none","none").then(e=>{$(this._element).find(".advancedSearch .groupbox").html(e)})}buildFilter(e,t="Item"){let a=[];return Object.keys(e.categories).forEach(function(s){a.push({label:game.i18n.localize(`TYPES.${t}.${s}`),selected:e.categories[s],key:s})}),a=a.sort(function(s,i){return s.label.localeCompare(i.label)}),a}static get defaultOptions(){let e=super.defaultOptions;return e.id="DSA5ItemLibrary",e.classes.push("dsa5","itemlibrary"),e.height=800,e.width=800,e.resizable=!0,e.title=game.i18n.localize("ItemLibrary"),e.template="systems/dsa5/templates/system/itemlibrary.html",e.tabs=[{navSelector:".tabs",contentSelector:".content",initial:"equipment"}],e}async getRandomItems(e,t){let a=[],s=this.equipmentIndex;return a.push(...await s.search(e,{field:["itemType"]})),(await Promise.all(this.shuffle(a.filter(i=>i.hasPermission)).slice(0,t+5).map(i=>i.getItem()))).filter(i=>{let n=i.getFlag("dsa5","enchantments");return!n||!n.find(r=>r.talisman)}).slice(0,t)}shuffle(e){let t=e.length,a,s;for(;t!==0;)s=Math.floor(Math.random()*t),t-=1,a=e[t],e[t]=e[s],e[s]=a;return e}async findCompendiumItem(e,t,a=!0){await this.buildEquipmentIndex();let s={field:["name"],where:{itemType:t}},i=await this.equipmentIndex.search(e,s);return a&&(i=i.filter(n=>n.compendium!="")),i=i.sort((n,r)=>{console.log(n.compendium,r.compendium);let l=n.compendium.startsWith("dsa5-core"),c=r.compendium.startsWith("dsa5-core");return l&&c?0:l?1:c?-1:0}),await Promise.all(i.map(n=>n.getItem()))}async getCategoryItems(e,t=!1,a=!1){await this.buildEquipmentIndex();let s=this.equipmentIndex.search(e,{field:["itemType"]});return t?(await Promise.all(s.map(i=>i.getItem()))).map(i=>i.toObject()):a?await Promise.all(s.map(i=>i.getItem())):s}async executeAdvancedFilter(e,t,a,s,i,n=[]){let r=u(f=>{for(let h of a)if(h[2]?f[h[0]]!=h[1]:f[h[0]].indexOf(h[1])==-1)return!1;return!0},"selFnct"),l=u(f=>{for(let h of s)if(f[h[0]].toLowerCase().indexOf(h[1])==-1)return!1;return!0},"txtFnct"),c=u(f=>{for(let h of i)if(f[h[0]]!=h[1])return!1;return!0},"cbFnct"),m=u(f=>{for(let h of n)if(f[h[0]]h[2])return!1;return!0},"rangeFct"),p=t.where(f=>(e==""||f.name.toLowerCase().indexOf(e)!=-1)&&r(f)&&l(f)&&c(f)&&m(f));return p=p.filter(f=>f.hasPermission).sort((f,h)=>f.name.toLowerCase()>h.name.toLowerCase()?1:-1),p}collectDetailSearch(e){let t=[],a=[],s=[];for(let i of e.find("select")){let n=$(i).val();n!=""&&t.push([$(i).attr("name"),n,i.dataset.notstrict!="true"])}for(let i of e.find('input[type="text"]:not(.manualFilter)')){let n=$(i).val();n!=""&&a.push([$(i).attr("name"),n.toLowerCase()])}for(let i of e.find('input[type="checkbox"]:checked:not(.manualFilter)')){let n=$(i).val();n!=""&&s.push([$(i).attr("name"),n.toLowerCase()])}return{sels:t,inps:a,checkboxes:s}}async advancedFilterStuff(e,t){let a=$(this._element).find(".detailFilters"),s=a.attr("data-subc"),i=this.detailFilter[s],n=this.filters[e].filterBy.search.toLowerCase(),{sels:r,inps:l,checkboxes:c}=this.collectDetailSearch(a),m=await this.executeAdvancedFilter(n,i,r,l,c);return this.setBGImage(m,e),m=this.filterDuplications(m),m}async findEquipmentItemDetailed(e,t,a=!0){await this.buildDetailFilter("Item",t);let s=this.detailFilter[t],i=await this.executeAdvancedFilter(e.search||"",s,e.selects||[],e.inputs||[],e.booleans||[],e.rangeSearches||[]);return a&&(i=i.filter(n=>n.compendium!="")),await Promise.all(i.map(n=>n.getItem()))}filterDuplications(e){return game.settings.get("dsa5","filterDuplicateItems")&&(e=[...new Map(e.map(t=>[`${t.name}_${t.type}`,t])).values()]),e}async filterStuff(e,t,a){let s=this.filters[e].filterBy.search,i={field:["name","data"]},n=[],r=!1;for(let l in this.filters[e].categories){if(this.filters[e].categories[l]){let c,m=null;s==""?c=t.search(l,{field:["itemType"],sort:"name",where:{itemType:l}}):c=t.search(s,{...i,sort:"name",where:{itemType:l}});let d=Number(a)||0;c=c.slice(d,Math.min(d+60,c.length)),c.length==60&&(m=`${d+60}`),this.pages[e].next=m,n.push(...c)}r=this.filters[e].categories[l]||r}return r||(n=t.search(s,{...i,limit:60,page:a||!0,sort:"name"}),this.pages[e].next=n.next),n=n.result?n.result:n,n=n.filter(l=>l.hasPermission),this.setBGImage(n,e),n}setBGImage(e,t){$(this._element).find(`.${t} .libcontainer`)[`${e.length>0?"remove":"add"}Class`]("libraryImg")}async getItemTemplate(e,t){return this.browseEnabled&&["Item","Actor"].includes(t)?e.map(a=>`
`,buttons:[{action:"yes",icon:"fa fa-check",label:"yes",callback:u(()=>[!0,!1],"callback")},{action:"all",icon:"fa fa-check",label:"LocalizedIDs.all",callback:u(()=>[!0,!0],"callback")},{action:"no",icon:"fas fa-times",label:"cancel",default:!0,callback:u(()=>[!1,!1],"callback")}]})}catch{h=!1,d=!1}if(y&&!h){this.scenes[y.name]=y;continue}f.folder=a.id,await this.initNotes(f,r,m),y?(f._id=y.id,c.push(f)):l.push(f)}let p=await Scene.create(l,{dsaInit:!0,keepId:!0});for(let f of p){this.scenes[f.name]=f;let h=await f.createThumbnail();await f.update({thumb:h.thumb})}for(let f of c)await game.scenes.get(f._id).update(f),this.scenes[f.name]=game.scenes.get(f._id);if(e.initialScene){let f=this.scenes[e.initialScene];f&&(await game.settings.set("core",NotesLayer.TOGGLE_SETTING,!0),await f.activate(),await f.update({navigation:!0}))}}async loadJson(){let e=this.scopeOptions.initializer||`initialization${this.lang}`;return await(await fetch(`modules/${this.module}/${e}.json`)).json()}async initialize(){this.lock=!0;let e=$(this.element).find('[data-action="initialize"]');e.prepend('');let t={};try{game.settings.settings.has(`${this.moduleScope}.initialized`)&&await game.settings.set(this.moduleScope,"initialized",!0)}catch{}if(this.scopeOptions.scope)await fetch(`modules/${this.module}/${this.scopeOptions.scope}.json`).then(async i=>i.json()).then(async i=>{t=i});else try{await fetch(`modules/${this.module}/adventure${this.lang}.json`).then(async i=>i.json()).then(async i=>{t=i})}catch{try{await fetch(`modules/${this.module}/adventure.json`).then(async i=>i.json()).then(async i=>{t=i})}catch{console.warn(`Could not find book data for ${this.moduleScope} import.`)}}let a=await this.loadJson(),s=a.folders;if(s){let i=await this.getFolderForType("JournalEntry"),n=a.folders[0].name;i&&(this.folders[i.data.name]=i,a.folders.shift());let r=await Folder.create(s);Array.isArray(r)||(r=[r]);for(let c of r)this.folders[c.data.name]=c;let l=[];for(let c in this.folders){let m=this.folders[c].getFlag("dsa5","parent"),d=m==n?game.i18n.localize(`${this.moduleScope}.name`):m;d&&l.push({_id:this.folders[c].id,parent:this.folders[d].id})}await Folder.updateDocuments(l)}if(a.items&&a.items.length>0){let i=await this.getFolderForType("Item"),n=[],r=[];for(let l of a.items){l.folder=i.id;let c=game.items.find(m=>m.name==l.name&&m.folder?.id==i.id);c?(l._id=c.id,r.push(l)):n.push(l)}await C.create(n),await C.updateDocuments(r)}if(a.playlists){let i=await this.getFolderForType("Playlist"),n=[],r=[],c=(await game.packs.get(a.playlists).getDocuments()).map(m=>m.toObject());for(let m of c){m.folder=i.id;let d=game.playlists.find(p=>p.name==m.name&&p.folder?.id==i.id);d?(m._id=d._id,r.push(m)):n.push(m)}await Playlist.create(n,{keepId:!0}),await Playlist.updateDocuments(r)}if(a.scenes&&await this.initScenes(a),a.actors){let i=await this.getFolderForType("Actor"),r=(await game.packs.get(a.actors).getDocuments()).map(f=>f.toObject()),l=[],c=[],m=new Map,d=0;if(ln(t,"chapters")){for(let f of t.chapters)for(let h of f.content)if(h.actors){let y=!1;for(let k of h.actors)m.has(k)||(m.set(k,h.name),y=!0);y&&(await this.getFolderForType("Actor",i.id,h.name,d),d+=1)}}for(let f of r){let h=m.has(f.name)?await this.getFolderForType("Actor",i.id,m.get(f.name)):i;f.folder=h.id,f._id&&delete f._id;let y=game.actors.find(k=>k.name==f.name&&[i.id,h.id].includes(k.folder?.id));y?(f._id=y.id,await y.deleteEmbeddedDocuments("Item",y.items.map(k=>k.id)),c.push(f)):l.push(f)}let p=await Actor.create(l);await Actor.updateDocuments(c);for(let f of p)this.actors[f.name]=f}a.macro&&(Hooks.once("renderCompendium",(i,n,r)=>{n.find(`[data-pack="${a.macro}"] header`).append($(`
`),s&&($("#tooltip").addClass("dsatooltip").html(s),t.dataset.tooltip=s,t.dataset.tooltipClass="dsatooltip")}filterCategory(e,t){let a=e.currentTarget.dataset.filter;a?(t.find(".skillItems").addClass("collapsed"),t.find(`.skillItems[data-category="${a}"]`).removeClass("collapsed"),t.find(".categoryFilter").removeClass("active"),t.find(`.categoryFilter[data-filter="${a}"]`).addClass("active"),this.token?.actor?this.activeFilters=[a]:this.gmFilters=[a]):(t.find(".skillItems").removeClass("collapsed"),t.find(".categoryFilter").removeClass("active"),this.token?.actor?this.activeFilters=[]:this.gmFilters=[])}filterSections(e,t){switch(this.searching=this.searching||"",e.which){case 8:this.searching=this.searching.slice(0,-1);break;default:if(!e.key.match(/^[a-zA-Z0-9öäüÖÄÜ]$/))return;this.searching+=e.key}e.preventDefault(),e.stopPropagation();let a=this.searching.toLowerCase();ge(a);let s=t.find(".sections");a?s.addClass("longLayout"):s.removeClass("longLayout");let i=t.find(".primary");i.removeClass("dsahidden"),i.filter(function(){let n=this.dataset?.name?.toLowerCase().trim();return n?n.indexOf(a)==-1:!0}).addClass("dsahidden");for(let n of s.find(".skillItems")){let r=n.dataset.category,l=$(n);l.toggleClass("dsahidden",l.find(`li.${r}.dsahidden`).length==l.find(`li.${r}`).length)}return!1}async getData(e){let t=await super.getData(e);return game.settings.get("dsa5","hotbarv3")&&await this._h3Data(t),t}get tokenHotbar(){return game.dsa5.apps.tokenHotbar}async _h3Data(e){let t={skills:{},attacks:[]},a=[],s=[],i=!1,n=[],r=this.token?.actor;if(r){if(!["epic","loot"].includes(Yo(r,"system.merchant.merchantType"))){n=(this.activeFilters||[]).filter(k=>k!="gm");let f=r.items.filter(k=>k.type=="combatskill").map(k=>O._calculateCombatSkillValues(k.toObject(),r.system));s=await this.tokenHotbar._effectEntries(r);let h=this.tokenHotbar._brawlEntry(f);if(H.isRiding(r)){let k=this.tokenHotbar._ridingEntry(r);k&&(t.skills.skill=[k])}h&&t.attacks.push(h),t.functions=this.tokenHotbar?._functionEntries()||[];for(let k of r.items)switch(k.type){case"skill":t.skills[k.type]||(t.skills[k.type]=[]),t.skills[k.type].push(this.tokenHotbar._skillEntry(k,"skill"));break;case"spell":case"liturgy":t.skills[k.type]||(t.skills[k.type]=[]),t.skills[k.type].push(this.tokenHotbar._skillEntry(k,"spell"));break;case"trait":Xe.traitTypes.has(k.system.traitType.value)&&t.attacks.push(this.tokenHotbar._traitEntry(k,r.system));break;case"consumable":t.skills[k.type]||(t.skills[k.type]=[]),t.skills[k.type].push(this.tokenHotbar._actionEntry(k,"consumable",{abbrev:k.system.quantity.value}));break;case"meleeweapon":case"rangeweapon":let D=this.tokenHotbar._combatEntry(k,f,r);for(let v of D)k.system.worn.value||(v.cssClass="unequipped"),t.attacks.push(v);default:if(k.getFlag("dsa5","onUseEffect")&&(t.skills[k.type]||(t.skills[k.type]=[]),t.skills[k.type].push(this.tokenHotbar._actionEntry(k,"onUse",{subfunction:"onUse"}))),k.getFlag("dsa5","enchantments")){t.skills[k.type]||(t.skills[k.type]=[]);for(let v of k.getFlag("dsa5","enchantments"))t.skills[k.type].push(this.tokenHotbar._enchantmentEntry(v,"enchantment",k,{subfunction:"enchantment"}))}break}}}else if(game.user.isGM&&!game.settings.get("dsa5","disableTokenhotbarMaster")){n=this.gmFilters||[],t.skills.gm=this.tokenHotbar?._gmEntries()||[];let f=this.tokenHotbar?.skills||await this.tokenHotbar?.prepareSkills()||[];t.skills.skillgm=f,i=!0}let l=45,c=2,m={gm:"systems/dsa5/icons/categories/DSA-Auge.webp",skillgm:"systems/dsa5/icons/categories/Skill.webp"},d={gm:"gmMenu",skillgm:"TYPES.Item.skill"};for(let f of Object.keys(t.skills)){let h=`TYPES.Item.${f}`;a.push({key:f,tooltip:game.i18n.has(h)?game.i18n.localize(h):game.i18n.localize(d[f]),img:C.defaultImages[f]||m[f]})}let p=["body","social","nature","knowledge","trade"];if(t.skills.skill?.sort((f,h)=>p.indexOf(f.addClass)-p.indexOf(h.addClass)||f.name.localeCompare(h.name)),t.skills.skillgm?.sort((f,h)=>p.indexOf(f.addClass)-p.indexOf(h.addClass)||f.name.localeCompare(h.name)),t.attacks.length>0&&(t.attacks.sort((f,h)=>(h.cssClass||"").localeCompare(f.cssClass||"")||f.name.localeCompare(h.name)),a.unshift({key:"attacks",tooltip:game.i18n.localize("Combat"),img:"systems/dsa5/icons/categories/Meleeweapon.webp"})),this.showEffects){if(canvas.tokens.controlled.length>1){let y=await this.tokenHotbar._effectEntries(canvas.tokens.controlled[0].actor,{subfunction:"sharedEffect"});for(let k of canvas.tokens.controlled){let D=(await k.actor.actorEffects()).map(v=>v.name);y=y.filter(v=>D.includes(v.name))}s=y}let h={name:"CONDITION.add",id:"",icon:"icons/svg/aura.svg",cssClass:"effect",abbrev:game.i18n.localize("CONDITION.add")[0],subfunction:"addEffect",indicator:"+"};s.unshift(h)}n.length>0&&(n=Object.keys(t.skills).concat(["macro","attacks"]).filter(f=>!n.includes(f))),Jo(e,{token:{groups:t,effects:s},darkness:canvas?.scene?.environment.darknessLevel||0,hotBarcssClass:"hotbarV3",barWidth:"527px",baseBarHeight:`${l}px`,barHeight:`${(l+7)*c+30}px`,filterCategories:a,selectedCategories:(r?this.activeFilters:this.gmFilters)||[],showEffects:this.showEffects,activeFilters:n,gmMode:i,macros:this._getAllMacros()})}_getAllMacros(){let e=Array.from({length:50},()=>"");for(let[t,a]of Object.entries(game.user.hotbar))e[parseInt(t)-1]=a;return e.map((t,a)=>{let s=t?game.macros.get(t):null;return{slot:a+1,key:a+1,icon:s?.img||null,cssClass:s?"active":"inactive",tooltip:s?s.name:null,macro:s}})}},dn=class o extends ContextMenu{static{u(this,"HotbarV3ContextMenu")}_setPosition(e,t){t=t.closest(".flexrow"),super._setPosition(e,t)}static create(e,t,a,s,{hookName:i="EntryContext",...n}={}){for(let r of e.constructor._getInheritanceChain())Hooks.call(`get${r.name}${i}`,t,s);if(s)return new o(t,a,s,n)}};var{setProperty:Qo,getProperty:Xo}=foundry.utils,Xt=class o{static{u(this,"RollMemory")}constructor(){this.tokens={},this.actors={}}static get wantedKeys(){let e=["vision","targetMovement","shooterMovement","quickChange","mountOptions","narrowSpace","advantageousPosition","doubleAttack","reduceCostSpell","forceSpell","increaseCastingTime","decreaseCastingTime","removeGesture","removeFormula"];return ne.isEnabled||e.push("distance"),e}getPath(e,t,a){let s=a||"",i=t._id||t.type;return e.token?`tokens.${e.token||e.actor}.${i}${s}`:`actors.${e.actor}.${i}${s}`}remember(e,t,a,s){let i=this.formDataSerialize(s);Object.entries(i).length>0&&Qo(this,this.getPath(e,t,a),i)}recall(e,t,a){return Xo(this,this.getPath(e,t,a))}formDataSerialize(e){let t=e.find("form"),a={};return t.find("select").each(function(){let s=$(this).attr("name");o.wantedKeys.includes(s)&&(a[s]=$(this).val())}),t.find('input[type="checkbox"]').each(function(){let s=$(this).attr("name");o.wantedKeys.includes(s)&&(a[s]=this.checked)}),t.find(".specAbs.active").each(function(){a.specAbs||(a.specAbs=[]),a.specAbs.push({id:$(this).attr("data-id"),step:$(this).attr("data-step")})}),e.find('[name="situationalModifiers"] option').each(function(){a.situationalModifiers||(a.situationalModifiers=[]),a.situationalModifiers.push({name:$(this).text().trim(),selected:this.selected})}),a}};Hooks.once("init",()=>{console.log("Initializing DSA5 system"),CONFIG.statusEffects=b.statusEffects,game.dsa5={apps:{DSA5_Utility:g,DSA5Initializer:Yt,DSA5ChatListeners:le,DSA5Payment:Q,SpecialabilityRulesDSA5:F,AdvantageRulesDSA5:P,Migrakel:Je,DSA5Dialog:ae,DSA5StatusEffects:z,DPS:ne,DSATables:B,DSA5SoundEffect:K,RequestRoll:ie,DiceDSA5:R,DSATour:rt,OpposeDSA:ee,EquipmentDamage:W,APTracker:_,DidYouKnow:it,MeasuredTemplateDSA:Le,Riding:H,RuleChaos:N,Trade:xe,DSAActiveEffectConfig:Z},entities:{Actordsa5:O,Itemdsa5:C},sheets:{ActorSheetdsa5:ze,ActorSheetdsa5Character:Ce,ActorSheetdsa5Creature:Ne,ActorSheetdsa5NPC:Re,MerchantSheetMixin:Be,MerchantSheetDSA5:Ie,ItemSheetdsa5:Y},wizards:{CareerWizard:tt,CultureWizard:et,SpeciesWizard:at},view:{tinyNotification:ge,tabSlider:me,clickableAbility:mt},dialogs:{DialogReactDSA5:ke,ReactToSkillDialog:yt,ActAttackDialog:bt,ReactToAttackDialog:kt,RandomGoodsAddition:Ta},macro:Vt,config:b,memory:new Xt,itemLibrary:new Tt},CONFIG.Actor.documentClass=O,CONFIG.Item.documentClass=C,CONFIG.ChatMessage.template="systems/dsa5/templates/chat/chat-message.html",CONFIG.ChatMessage.documentClass=Jt,CONFIG.ui.combat=Ge,CONFIG.ui.hotbar=Qt,CONFIG.Combat.documentClass=vt,CONFIG.Combatant.documentClass=wa,CONFIG.ActiveEffect.documentClass=Me,CONFIG.ActiveEffect.legacyTransferral=!1});sn();
+
`,r={ammunition:[{label:"ammunitiongroup",attr:"ammunitiongroup.value",type:"select",options:b.ammunitiongroups}],equipment:[{label:"equipmentType",attr:"equipmentType.value",type:"select",options:b.equipmentTypes},{label:"PLANT.region",attr:"region",type:"text"}],book:[{label:"BOOKITEM.format",attr:"format",type:"select",options:b.bookFormats},{label:"BOOKITEM.quality",attr:"quality",type:"select",options:b.bookQualities},{label:"BOOKITEM.exemplarType",attr:"exemplarType",type:"select",options:b.exemplarTypes},{label:"BOOKITEM.availability",attr:"availability",type:"range"}],trap:[],rangeweapon:[{label:"TYPES.Item.combatskill",attr:"combatskill.value",type:"select",options:t},{label:"ammunitiongroup",attr:"ammunitiongroup.value",type:"select",options:b.ammunitiongroups},{label:"PLANT.region",attr:"region",type:"text"}],meleeweapon:[{label:"TYPES.Item.combatskill",attr:"combatskill.value",type:"select",options:a},{label:"guidevalue",attr:"guidevalue.value",type:"select",options:b.combatskillsGuidevalues},{label:"reach",attr:"reach.value",type:"select",options:b.meleeRanges},{label:"PLANT.region",attr:"region",type:"text"}],poison:[{label:"resistanceModifier",attr:"resistance.value",type:"select",options:b.magicResistanceModifiers},{label:"COMBATSKILLCATEGORY.subcategory",attr:"subcategory",type:"select",options:b.poisonSubTypes},{label:"poisonType",attr:"poisonType.value",type:"text"},{label:"PLANT.region",attr:"region",type:"text"}],disease:[{label:"resistanceModifier",attr:"resistance.value",type:"select",options:b.magicResistanceModifiers}],consumable:[{label:"equipmentType",attr:"equipmentType.value",type:"select",options:b.equipmentTypes}],application:[{label:"TYPES.Item.skill",attr:"skill",type:"select",options:e}],trait:[{label:"traitType",attr:"traitType.value",type:"select",options:b.traitCategories}],career:[{label:"mageLevel",attr:"mageLevel.value",type:"select",options:b.mageLevels}],specialability:[{type:"prerendered",attr:"category.value",content:n},{label:"TYPES.Item.combatskill",attr:"list.value",type:"select",options:s,notStrict:!0},{label:"distribution",attr:"distribution",type:"text"}],liturgy:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"}],spell:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"},{label:"feature",attr:"feature",type:"text"}],ritual:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"},{label:"feature",attr:"feature",type:"text"}],ceremony:[{label:"resistanceModifier",attr:"resistanceModifier.value",type:"select",options:b.magicResistanceModifiers},{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"distribution",attr:"distribution.value",type:"text"}],spellextension:[{label:"Category",attr:"category",type:"select",options:{spell:"spell",liturgy:"liturgy",ritual:"ritual",ceremony:"ceremony"}}],magictrick:[{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"feature",attr:"feature.value",type:"text"},{label:"distribution",attr:"distribution",type:"text"}],blessing:[{label:"targetCategory",attr:"targetCategory.value",type:"text"},{label:"feature",attr:"feature.value",type:"text"}],npc:[{label:"TYPES.Item.species",attr:"details.species.value",type:"text"},{label:"TYPES.Item.career",attr:"details.career.value",type:"text"},{label:"TYPES.Item.culture",attr:"details.culture.value",type:"text"}],character:[{label:"TYPES.Item.species",attr:"details.species.value",type:"text"},{label:"TYPES.Item.career",attr:"details.career.value",type:"text"},{label:"TYPES.Item.culture",attr:"details.culture.value",type:"text"}],creature:[{label:"creatureClass",attr:"creatureClass.value",type:"text"},{label:"sizeCategory",attr:"status.size.value",type:"select",options:b.sizeCategories}],armor:[{label:"protection",attr:"protection.value",type:"select",options:{0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"}},{label:"encumbrance",attr:"encumbrance.value",type:"select",options:{0:"0",1:"1",2:"2",3:"3",4:"4"}},{label:"PLANT.region",attr:"region",type:"text"}],plant:[{label:"PLANT.landscape",attr:"location.landscape",type:"text"},{label:"PLANT.region",attr:"location.region",type:"text"},{label:"PLANT.healing",attr:"planttype.healing",type:"checkbox"},{label:"PLANT.poison",attr:"planttype.poison",type:"checkbox"},{label:"PLANT.physical",attr:"planttype.physical",type:"checkbox"},{label:"PLANT.psychic",attr:"planttype.psychic",type:"checkbox"},{label:"PLANT.crop",attr:"planttype.crop",type:"checkbox"},{label:"PLANT.defensive",attr:"planttype.defensive",type:"checkbox"},{label:"PLANT.supernatural",attr:"planttype.supernatural",type:"checkbox"},{label:"PLANT.highNorth",attr:"availability.highNorth",type:"range"},{label:"PLANT.grasLands",attr:"availability.grasLands",type:"range"},{label:"PLANT.swamps",attr:"availability.swamps",type:"range"},{label:"PLANT.woods",attr:"availability.woods",type:"range"},{label:"PLANT.jungle",attr:"availability.jungle",type:"range"},{label:"PLANT.mountains",attr:"availability.mountains",type:"range"},{label:"PLANT.desert",attr:"availability.desert",type:"range"},{label:"PLANT.maraskan",attr:"availability.maraskan",type:"range"}],magicalsign:[],patron:[],demonmark:[],essence:[],imprint:[{label:"Category",attr:"category",type:"text"}]};for(let[l,c]of Object.entries(r))for(let m of c)m.type=="text"&&(m.placeholder=`Library.advancedSearchPlaceholders.${l}.${m.attr}`);Wo(nn,r),game.dsa5.advancedFilters=nn})});var Ca=nn;var{getProperty:rn,duplicate:Uo,debounce:Vo,mergeObject:Ko}=foundry.utils,Kt=class{static{u(this,"SearchDocument")}constructor(e,t={}){let a=e.documentName||e.type;switch(e.documentName){case"Actor":case"Item":a=e.type;break}let s="";if(game.settings.get("dsa5","indexDescription"))switch(a){case"creature":case"npc":case"character":s=rn(e,"system.description.value");break;case"JournalEntry":s=rn(e,"system.content");break;default:s=rn(e,"description.value")}this.document={name:e.name,filterType:a,data:$("
").html(s).text(),id:e.id||e._id,visible:e.visible?e.visible:!0,compendium:e.compendium?e.compendium.metadata.packageName:t.packageName||"",pack:e.pack||(t.packageName?t.id:void 0),img:e.img,price:e.system?.price?.value}}get uuid(){if(this.document.compendium)return`Compendium.${this.document.pack}.${this.document.id}`;switch(this.itemType){case"character":case"creature":case"npc":return`Actor.${this.id}`;case"JournalEntry":return`JournalEntry.${this.id}`;default:return`Item.${this.id}`}}get name(){return this.document.name}get data(){return this.document.data}get id(){return this.document.id}get itemType(){return this.document.filterType}get hasPrice(){return b.equipmentCategories.has(this.document.filterType)}async getItem(){return await fromUuid(this.uuid)}hasPermission(){return this.document.visible}async render(){(await this.getItem()).sheet.render(!0)}get compendium(){return this.document.compendium}get img(){return this.itemType=="JournalEntry"?"systems/dsa5/icons/categories/DSA-Auge.webp":this.document.img}},Da=class extends Kt{static{u(this,"AdvancedSearchDocument")}constructor(e,t){super(e);let a=Ca[t]||[];for(let s of a)this[s.attr]=s.attr.split(".").reduce((i,n)=>i[n]===void 0?{}:i[n],e.system)}},Tt=class o extends Application{static{u(this,"DSA5ItemLibrary")}constructor(e){super(e),this.advancedFiltering=!1,this.journalBuild=!1,this.journalWorldBuild=!1,this.equipmentBuild=!1,this.equipmentWorldBuild,this.zooBuild=!1,this.zooWorldBuild=!1,this.currentDetailFilter={equipment:[],character:[],spell:[],journal:[],zoo:[]},this.journalIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data"]}}),this.equipmentIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data","itemType"],tag:["itemType"]}}),this.zooIndex=new FlexSearch({encode:"simple",tokenize:"reverse",cache:!0,doc:{id:"id",field:["name","data","itemType"],tag:["itemType"]}}),this.detailFilter={},this.pages={equipment:{},character:{},spell:{},journal:{},zoo:{}},this.filters={equipment:{categories:{armor:!1,ammunition:!1,equipment:!1,meleeweapon:!1,rangeweapon:!1,poison:!1,disease:!1,consumable:!1,plant:!1,book:!1,trap:!1},filterBy:{search:""}},character:{categories:{career:!1,advantage:!1,combatskill:!1,culture:!1,disadvantage:!1,trait:!1,skill:!1,specialability:!1,species:!1,application:!1,demonmark:!1,patron:!1,essence:!1,imprint:!1},filterBy:{search:""}},spell:{categories:{blessing:!1,ceremony:!1,liturgy:!1,magictrick:!1,ritual:!1,spell:!1,spellextension:!1,magicalsign:!1},filterBy:{search:""}},journal:{categories:{},filterBy:{search:""}},zoo:{categories:{npc:!1,character:!1,creature:!1},filterBy:{search:""}}}}async getData(e){let t=await super.getData(e);return t.categories=this.translateFilters(),t.isGM=game.user.isGM,t.advancedMode=this.advancedFiltering?"on":"",t.worldIndexed=game.settings.get("dsa5","indexWorldItems")?"on":"",t.fullTextEnabled=game.settings.get("dsa5","indexDescription")?"on":"",t.filterDuplicateItems=game.settings.get("dsa5","filterDuplicateItems")?"on":"",t.browseEnabled=this.browseEnabled?"on":"",this.advancedFiltering&&(t.advancedFilter=await this.buildDetailFilter("tbd",this.subcategory)),t}translateFilters(){return{equipment:this.buildFilter(this.filters.equipment),character:this.buildFilter(this.filters.character),spell:this.buildFilter(this.filters.spell),zoo:this.buildFilter(this.filters.zoo,"Actor"),journal:this.buildFilter(this.filters.journal)}}purgeAdvancedFilters(){for(let e in this.filters)for(let t in this.filters[e].categories)this.filters[e].categories[t]=!1;$(this._element).find('.filter[type="checkbox"]').prop("checked",!1),this.buildDetailFilter("none","none").then(e=>{$(this._element).find(".advancedSearch .groupbox").html(e)})}buildFilter(e,t="Item"){let a=[];return Object.keys(e.categories).forEach(function(s){a.push({label:game.i18n.localize(`TYPES.${t}.${s}`),selected:e.categories[s],key:s})}),a=a.sort(function(s,i){return s.label.localeCompare(i.label)}),a}static get defaultOptions(){let e=super.defaultOptions;return e.id="DSA5ItemLibrary",e.classes.push("dsa5","itemlibrary"),e.height=800,e.width=800,e.resizable=!0,e.title=game.i18n.localize("ItemLibrary"),e.template="systems/dsa5/templates/system/itemlibrary.html",e.tabs=[{navSelector:".tabs",contentSelector:".content",initial:"equipment"}],e}async getRandomItems(e,t){let a=[],s=this.equipmentIndex;return a.push(...await s.search(e,{field:["itemType"]})),(await Promise.all(this.shuffle(a.filter(i=>i.hasPermission)).slice(0,t+5).map(i=>i.getItem()))).filter(i=>{let n=i.getFlag("dsa5","enchantments");return!n||!n.find(r=>r.talisman)}).slice(0,t)}shuffle(e){let t=e.length,a,s;for(;t!==0;)s=Math.floor(Math.random()*t),t-=1,a=e[t],e[t]=e[s],e[s]=a;return e}async findCompendiumItem(e,t,a=!0){await this.buildEquipmentIndex();let s={field:["name"],where:{itemType:t}},i=await this.equipmentIndex.search(e,s);return a&&(i=i.filter(n=>n.compendium!="")),i=i.sort((n,r)=>{let l=n.compendium.startsWith("dsa5-core"),c=r.compendium.startsWith("dsa5-core");return l&&c?0:l?1:c?-1:0}),await Promise.all(i.map(n=>n.getItem()))}async getCategoryItems(e,t=!1,a=!1){await this.buildEquipmentIndex();let s=this.equipmentIndex.search(e,{field:["itemType"]});return t?(await Promise.all(s.map(i=>i.getItem()))).map(i=>i.toObject()):a?await Promise.all(s.map(i=>i.getItem())):s}async executeAdvancedFilter(e,t,a,s,i,n=[]){let r=u(f=>{for(let h of a)if(h[2]?f[h[0]]!=h[1]:f[h[0]].indexOf(h[1])==-1)return!1;return!0},"selFnct"),l=u(f=>{for(let h of s)if(f[h[0]].toLowerCase().indexOf(h[1])==-1)return!1;return!0},"txtFnct"),c=u(f=>{for(let h of i)if(f[h[0]]!=h[1])return!1;return!0},"cbFnct"),m=u(f=>{for(let h of n)if(f[h[0]]h[2])return!1;return!0},"rangeFct"),p=t.where(f=>(e==""||f.name.toLowerCase().indexOf(e)!=-1)&&r(f)&&l(f)&&c(f)&&m(f));return p=p.filter(f=>f.hasPermission).sort((f,h)=>f.name.toLowerCase()>h.name.toLowerCase()?1:-1),p}collectDetailSearch(e){let t=[],a=[],s=[];for(let i of e.find("select")){let n=$(i).val();n!=""&&t.push([$(i).attr("name"),n,i.dataset.notstrict!="true"])}for(let i of e.find('input[type="text"]:not(.manualFilter)')){let n=$(i).val();n!=""&&a.push([$(i).attr("name"),n.toLowerCase()])}for(let i of e.find('input[type="checkbox"]:checked:not(.manualFilter)')){let n=$(i).val();n!=""&&s.push([$(i).attr("name"),n.toLowerCase()])}return{sels:t,inps:a,checkboxes:s}}async advancedFilterStuff(e,t){let a=$(this._element).find(".detailFilters"),s=a.attr("data-subc"),i=this.detailFilter[s],n=this.filters[e].filterBy.search.toLowerCase(),{sels:r,inps:l,checkboxes:c}=this.collectDetailSearch(a),m=await this.executeAdvancedFilter(n,i,r,l,c);return this.setBGImage(m,e),m=this.filterDuplications(m),m}async findEquipmentItemDetailed(e,t,a=!0){await this.buildDetailFilter("Item",t);let s=this.detailFilter[t],i=await this.executeAdvancedFilter(e.search||"",s,e.selects||[],e.inputs||[],e.booleans||[],e.rangeSearches||[]);return a&&(i=i.filter(n=>n.compendium!="")),await Promise.all(i.map(n=>n.getItem()))}filterDuplications(e){return game.settings.get("dsa5","filterDuplicateItems")&&(e=[...new Map(e.map(t=>[`${t.name}_${t.type}`,t])).values()]),e}async filterStuff(e,t,a){let s=this.filters[e].filterBy.search,i={field:["name","data"]},n=[],r=!1;for(let l in this.filters[e].categories){if(this.filters[e].categories[l]){let c,m=null;s==""?c=t.search(l,{field:["itemType"],sort:"name",where:{itemType:l}}):c=t.search(s,{...i,sort:"name",where:{itemType:l}});let d=Number(a)||0;c=c.slice(d,Math.min(d+60,c.length)),c.length==60&&(m=`${d+60}`),this.pages[e].next=m,n.push(...c)}r=this.filters[e].categories[l]||r}return r||(n=t.search(s,{...i,limit:60,page:a||!0,sort:"name"}),this.pages[e].next=n.next),n=n.result?n.result:n,n=n.filter(l=>l.hasPermission),this.setBGImage(n,e),n}setBGImage(e,t){$(this._element).find(`.${t} .libcontainer`)[`${e.length>0?"remove":"add"}Class`]("libraryImg")}async getItemTemplate(e,t){return this.browseEnabled&&["Item","Actor"].includes(t)?e.map(a=>`
`,buttons:[{action:"yes",icon:"fa fa-check",label:"yes",callback:u(()=>[!0,!1],"callback")},{action:"all",icon:"fa fa-check",label:"LocalizedIDs.all",callback:u(()=>[!0,!0],"callback")},{action:"no",icon:"fas fa-times",label:"cancel",default:!0,callback:u(()=>[!1,!1],"callback")}]})}catch{h=!1,d=!1}if(y&&!h){this.scenes[y.name]=y;continue}f.folder=a.id,await this.initNotes(f,r,m),y?(f._id=y.id,c.push(f)):l.push(f)}let p=await Scene.create(l,{dsaInit:!0,keepId:!0});for(let f of p){this.scenes[f.name]=f;let h=await f.createThumbnail();await f.update({thumb:h.thumb})}for(let f of c)await game.scenes.get(f._id).update(f),this.scenes[f.name]=game.scenes.get(f._id);if(e.initialScene){let f=this.scenes[e.initialScene];f&&(await game.settings.set("core",NotesLayer.TOGGLE_SETTING,!0),await f.activate(),await f.update({navigation:!0}))}}async loadJson(){let e=this.scopeOptions.initializer||`initialization${this.lang}`;return await(await fetch(`modules/${this.module}/${e}.json`)).json()}async initialize(){this.lock=!0;let e=$(this.element).find('[data-action="initialize"]');e.prepend('');let t={};try{game.settings.settings.has(`${this.moduleScope}.initialized`)&&await game.settings.set(this.moduleScope,"initialized",!0)}catch{}if(this.scopeOptions.scope)await fetch(`modules/${this.module}/${this.scopeOptions.scope}.json`).then(async i=>i.json()).then(async i=>{t=i});else try{await fetch(`modules/${this.module}/adventure${this.lang}.json`).then(async i=>i.json()).then(async i=>{t=i})}catch{try{await fetch(`modules/${this.module}/adventure.json`).then(async i=>i.json()).then(async i=>{t=i})}catch{console.warn(`Could not find book data for ${this.moduleScope} import.`)}}let a=await this.loadJson(),s=a.folders;if(s){let i=await this.getFolderForType("JournalEntry"),n=a.folders[0].name;i&&(this.folders[i.data.name]=i,a.folders.shift());let r=await Folder.create(s);Array.isArray(r)||(r=[r]);for(let c of r)this.folders[c.data.name]=c;let l=[];for(let c in this.folders){let m=this.folders[c].getFlag("dsa5","parent"),d=m==n?game.i18n.localize(`${this.moduleScope}.name`):m;d&&l.push({_id:this.folders[c].id,parent:this.folders[d].id})}await Folder.updateDocuments(l)}if(a.items&&a.items.length>0){let i=await this.getFolderForType("Item"),n=[],r=[];for(let l of a.items){l.folder=i.id;let c=game.items.find(m=>m.name==l.name&&m.folder?.id==i.id);c?(l._id=c.id,r.push(l)):n.push(l)}await D.create(n),await D.updateDocuments(r)}if(a.playlists){let i=await this.getFolderForType("Playlist"),n=[],r=[],c=(await game.packs.get(a.playlists).getDocuments()).map(m=>m.toObject());for(let m of c){m.folder=i.id;let d=game.playlists.find(p=>p.name==m.name&&p.folder?.id==i.id);d?(m._id=d._id,r.push(m)):n.push(m)}await Playlist.create(n,{keepId:!0}),await Playlist.updateDocuments(r)}if(a.scenes&&await this.initScenes(a),a.actors){let i=await this.getFolderForType("Actor"),r=(await game.packs.get(a.actors).getDocuments()).map(f=>f.toObject()),l=[],c=[],m=new Map,d=0;if(ln(t,"chapters")){for(let f of t.chapters)for(let h of f.content)if(h.actors){let y=!1;for(let k of h.actors)m.has(k)||(m.set(k,h.name),y=!0);y&&(await this.getFolderForType("Actor",i.id,h.name,d),d+=1)}}for(let f of r){let h=m.has(f.name)?await this.getFolderForType("Actor",i.id,m.get(f.name)):i;f.folder=h.id,f._id&&delete f._id;let y=game.actors.find(k=>k.name==f.name&&[i.id,h.id].includes(k.folder?.id));y?(f._id=y.id,await y.deleteEmbeddedDocuments("Item",y.items.map(k=>k.id)),c.push(f)):l.push(f)}let p=await Actor.create(l);await Actor.updateDocuments(c);for(let f of p)this.actors[f.name]=f}a.macro&&(Hooks.once("renderCompendium",(i,n,r)=>{n.find(`[data-pack="${a.macro}"] header`).append($(`