|
function $parcel$export(t,a,n,r){Object.defineProperty(t,a,{get:n,set:r,enumerable:!0,configurable:!0})}var $parcel$global="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},$parcel$modules={},$parcel$inits={},parcelRequire=$parcel$global.parcelRequire84b7;null==parcelRequire&&((parcelRequire=function(t){if(t in $parcel$modules)return $parcel$modules[t].exports;if(t in $parcel$inits){var a=$parcel$inits[t];delete $parcel$inits[t];var n={id:t,exports:{}};return $parcel$modules[t]=n,a.call(n.exports,n,n.exports),n.exports}var r=Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}).register=function(t,a){$parcel$inits[t]=a},$parcel$global.parcelRequire84b7=parcelRequire),parcelRequire.register("4rd87",function(module,exports){$parcel$export(module.exports,"OverlayConfig",()=>OverlayConfig),$parcel$export(module.exports,"FILTERS",()=>FILTERS);var $ce8jp=parcelRequire("ce8jp"),$dmUqi=parcelRequire("dmUqi"),$bFZU7=parcelRequire("bFZU7"),$eeGZt=parcelRequire("eeGZt"),$coMHP=parcelRequire("coMHP"),$eYkM9=parcelRequire("eYkM9"),$9IngI=parcelRequire("9IngI"),$bZ3HW=parcelRequire("bZ3HW");class OverlayConfig extends FormApplication{constructor(t,a,n,r){super({},{}),this.config=t??{},this.config.id=n,this.callback=a,this.token=canvas.tokens.get(r._id),this.previewConfig=deepClone(this.config)}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-overlay-config",classes:["sheet"],template:"modules/token-variants/templates/overlayConfig.html",resizable:!1,minimizable:!1,title:"Overlay Settings",width:500,height:"auto",//tabs: [{ navSelector: '.sheet-tabs', contentSelector: '.content', initial: 'misc' }, ],
|
|
tabs:[{navSelector:'.tabs[data-group="main"]',contentSelector:"form",initial:"misc"},{navSelector:'.tabs[data-group="html"]',contentSelector:'.tab[data-tab="html"]',initial:"template"}]})}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(html){super.activateListeners(html),html.find(".reticle").on("click",t=>{let a=this.getPreviewIcons();a.length&&(0,$bZ3HW.Reticle).activate({tvaOverlay:a[0].icon,app:this,config:this.previewConfig})});let imgLinkDisable=function(t){html.find(".img-link-disable").prop("disabled",t)};html.find(".image-link").on("click",t=>{let a=$(t.target).closest(".form-group").find('[name="imgLinked"]'),n=$(t.target).closest("button");a.is(":checked")?(a.prop("checked",!1),n.removeClass("active"),imgLinkDisable(!1)):(a.prop("checked",!0),n.addClass("active"),imgLinkDisable(!0))}),imgLinkDisable(!!this.config.imgLinked),html.find(".repeat").on("change",t=>{let a=$(t.target).closest("fieldset"),n=a.find(".content");t.target.checked?(n.show(),a.addClass("active")):(n.hide(),a.removeClass("active")),this.setPosition()});// Insert Controls to the Shape Legend
|
|
let shapeLegends=html.find(".shape-legend"),config=this.config;shapeLegends.each(function(t){let a=$(this);a.append(` <a class="cloneShape" data-index="${t}" title="Clone"><i class="fas fa-clone"></i></a>
|
|
<a class="deleteShape" data-index="${t}" title="Remove"><i class="fas fa-trash-alt"></i></a>`),0!=t&&a.append(` <a class="moveShapeUp" data-index="${t}" title="Move Up"><i class="fas fa-arrow-up"></i></a>`),t!=shapeLegends.length-1&&a.append(` <a class="moveShapeDown" data-index="${t}" title="Move Down"><i class="fas fa-arrow-down"></i></a>`),a.append(`<input class="shape-legend-input" type="text" name="shapes.${t}.label" value="${config.shapes?.[t]?.label??""}">`)}),// Shape listeners
|
|
html.find(".addShape").on("click",this._onAddShape.bind(this)),html.find(".addEvent").on("click",this._onAddEvent.bind(this)),html.find(".deleteShape").on("click",this._onDeleteShape.bind(this)),html.find(".deleteEvent").on("click",this._onDeleteEvent.bind(this)),html.find(".moveShapeUp").on("click",this._onMoveShapeUp.bind(this)),html.find(".moveShapeDown").on("click",this._onMoveShapeDown.bind(this)),html.find(".cloneShape").on("click",this._onCloneShape.bind(this)),html.find("input,select").on("change",this._onInputChange.bind(this)),html.find("textarea").on("change",this._onInputChange.bind(this));let parentId=html.find('[name="parentID"]');parentId.on("change",t=>{"TOKEN"===t.target.value?html.find(".token-specific-fields").show():html.find(".token-specific-fields").hide(),this.setPosition()}),parentId.trigger("change"),html.find('[name="ui"]').on("change",t=>{"TOKEN"===parentId.val()&&(t.target.checked?html.find(".ui-hide").hide():html.find(".ui-hide").show(),this.setPosition())}).trigger("change"),html.find('[name="filter"]').on("change",t=>{html.find(".filterOptions").empty();let a=$(genFilterOptionControls(t.target.value));html.find(".filterOptions").append(a),this.setPosition({height:"auto"}),this.activateListeners(a)}),html.find(".token-variants-image-select-button").click(t=>{(0,$coMHP.showArtSelect)(this.token?.name??"overlay",{searchType:$eeGZt.SEARCH_TYPE.TOKEN,callback:(a,n)=>{a&&$(t.target).closest(".form-group").find("input").val(a).trigger("change")}})}),html.find(".presetImport").on("click",t=>{let a=$(t.target).closest(".form-group").find(".tmfxPreset").val();if(a){let n=TokenMagic.getPreset(a);n&&$(t.target).closest(".form-group").find("textarea").val(JSON.stringify(n,null,2)).trigger("input")}});// Controls for locking scale sliders together
|
|
let scaleState={locked:!0};// Range inputs need to be triggered when slider moves to initiate preview
|
|
html.find(".range-value").siblings('[type="range"]').on("change",t=>{$(t.target).siblings(".range-value").val(t.target.value).trigger("change")});let lockButtons=$(html).find(".scaleLock > a"),sliderScaleWidth=$(html).find('[name="scaleX"]'),sliderScaleHeight=$(html).find('[name="scaleY"]'),sliderWidth=html.find(".scaleX"),sliderHeight=html.find(".scaleY");lockButtons.on("click",function(){scaleState.locked=!scaleState.locked,lockButtons.html(scaleState.locked?'<i class="fas fa-link"></i>':'<i class="fas fa-unlink"></i>')}),sliderScaleWidth.on("change",function(){scaleState.locked&&sliderScaleWidth.val()!==sliderScaleHeight.val()&&(sliderScaleHeight.val(sliderScaleWidth.val()).trigger("change"),sliderHeight.val(sliderScaleWidth.val()))}),sliderScaleHeight.on("change",function(){scaleState.locked&&sliderScaleWidth.val()!==sliderScaleHeight.val()&&(sliderScaleWidth.val(sliderScaleHeight.val()).trigger("change"),sliderWidth.val(sliderScaleHeight.val()))}),html.on("change",".scaleX",()=>{sliderScaleWidth.trigger("change")}),html.on("change",".scaleY",()=>{sliderScaleHeight.trigger("change")}),html.find(".me-edit-json").on("click",async event=>{let params;let textarea=$(event.target).closest(".form-group").find("textarea");try{params=eval(textarea.val())}catch(e){console.warn("TVA |",e)}if(params){let param;if(Array.isArray(params)){if(1===params.length)param=params[0];else{let i=await promptParamChoice(params);if(i<0)return;param=params[i]}}else param=params;param&&game.modules.get("multi-token-edit").api.showGenericForm(param,param.filterType??"TMFX",{inputChangeCallback:t=>{mergeObject(param,t,{inplace:!0}),textarea.val(JSON.stringify(params,null,2)).trigger("input")}})}});let underlay=html.find('[name="underlay"]'),top=html.find('[name="top"]'),bottom=html.find('[name="bottom"]');underlay.change(function(){this.checked?top.prop("checked",!1):bottom.prop("checked",!1)}),top.change(function(){this.checked&&(underlay.prop("checked",!1),bottom.prop("checked",!1))}),bottom.change(function(){this.checked&&(underlay.prop("checked",!0),top.prop("checked",!1))});let linkScale=html.find('[name="linkScale"]'),linkDimensions=html.find('[name="linkDimensionsX"], [name="linkDimensionsY"]'),linkStageScale=html.find('[name="linkStageScale"]');linkScale.change(function(){this.checked&&(linkDimensions.prop("checked",!1),linkStageScale.prop("checked",!1))}),linkDimensions.change(function(){this.checked&&(linkScale.prop("checked",!1),linkStageScale.prop("checked",!1))}),linkStageScale.change(function(){this.checked&&(linkScale.prop("checked",!1),linkDimensions.prop("checked",!1))});// Setting border color for property expression
|
|
let limitOnProperty=html.find('[name="limitOnProperty"]');limitOnProperty.on("input",t=>{let a=$(t.target);""===a.val()?(a.removeClass("tvaValid"),a.removeClass("tvaInvalid")):a.val().match($dmUqi.VALID_EXPRESSION)?(a.addClass("tvaValid"),a.removeClass("tvaInvalid")):(a.addClass("tvaInvalid"),a.removeClass("tvaValid"))}),limitOnProperty.trigger("input"),html.find(".create-variable").on("click",this._onCreateVariable.bind(this)),html.find(".delete-variable").on("click",this._onDeleteVariable.bind(this))}_onDeleteVariable(t){let a=$(t.target).closest("tr").data("index");null!=a&&(this.config=this._getSubmitData(),this.config.variables||(this.config.variables=[]),this.config.variables.splice(a,1),this.render(!0))}_onCreateVariable(t){this.config=this._getSubmitData(),this.config.variables||(this.config.variables=[]),this.config.variables.push({name:"",value:""}),this.render(!0)}_onAddShape(t){let a=$(t.target).siblings("select").val();a=deepClone($ce8jp.OVERLAY_SHAPES[a]),a=mergeObject(deepClone($ce8jp.CORE_SHAPE),{shape:a}),this.config=this._getSubmitData(),this.config.shapes||(this.config.shapes=[]),this.config.shapes.push(a),this.render(!0)}_onAddEvent(t){let a=$(t.target).siblings("select").val();this.config=this._getSubmitData(),this.config.interactivity||(this.config.interactivity=[]),this.config.interactivity.push({listener:a,macro:"",script:""}),this.render(!0)}_onDeleteShape(t){let a=$(t.target).closest(".deleteShape").data("index");null!=a&&(this.config=this._getSubmitData(),this.config.shapes||(this.config.shapes=[]),this.config.shapes.splice(a,1),this.render(!0))}_onDeleteEvent(t){let a=$(t.target).closest(".deleteEvent").data("index");null!=a&&(this.config=this._getSubmitData(),this.config.interactivity||(this.config.interactivity=[]),this.config.interactivity.splice(a,1),this.render(!0))}_onCloneShape(t){let a=$(t.target).closest(".cloneShape").data("index");if(!a&&0!=a||(this.config=this._getSubmitData(),!this.config.shapes))return;let n=deepClone(this.config.shapes[a]);n.label&&(n.label=n.label+" - Copy"),this.config.shapes.push(n),this.render(!0)}_onMoveShapeUp(t){let a=$(t.target).closest(".moveShapeUp").data("index");a&&(this.config=this._getSubmitData(),this.config.shapes||(this.config.shapes=[]),this.config.shapes.length>=2&&this._swapShapes(a,a-1),this.render(!0))}_onMoveShapeDown(t){let a=$(t.target).closest(".moveShapeDown").data("index");(a||0==a)&&(this.config=this._getSubmitData(),this.config.shapes||(this.config.shapes=[]),this.config.shapes.length>=2&&this._swapShapes(a,a+1),this.render(!0))}_swapShapes(t,a){let n=this.config.shapes[t];this.config.shapes[t]=this.config.shapes[a],this.config.shapes[a]=n}_convertColor(t){try{let a=Color.fromString(t),n=a.rgb;return n.push(1),n}catch(t){return[1,1,1,1]}}async _onInputChange(t){if(this.previewConfig=this._getSubmitData(),"color"===t.target.type){let a=$(t.target).siblings(".color");a.val(t.target.value).trigger("change");return}this._applyPreviews()}getPreviewIcons(){if(!this.config.id)return[];let t=this.token?[this.token]:canvas.tokens.placeables,a=[];for(let n of t)if(n.tvaOverlays)for(let t of n.tvaOverlays)t.overlayConfig&&t.overlayConfig.id===this.config.id&&(this.token?a.push({token:n,icon:t}):(0,$9IngI.getFlagMappings)(n).find(t=>t.id===this.config.id)||a.push({token:n,icon:t}));return a}async _applyPreviews(){let t=this.getPreviewIcons();for(let a of t){let t=(0,$bFZU7.evaluateOverlayExpressions)(deepClone(this.previewConfig),a.token,{overlayConfig:this.previewConfig});a.icon.refresh(t,{preview:!0,previewTexture:await (0,$bFZU7.genTexture)(a.token,t)})}}async _removePreviews(){let t=this.getPreviewIcons();for(let a of t)a.icon.refresh()}async getData(t){let a=super.getData(t);a.filters=Object.keys(PIXI.filters),a.filters.push("OutlineOverlayFilter"),a.filters.sort(),a.tmfxActive=game.modules.get("tokenmagic")?.active,a.tmfxActive&&(a.tmfxPresets=TokenMagic.getPresets().map(t=>t.name),a.filters.unshift("Token Magic FX")),a.filters.unshift("NONE");let n=mergeObject($ce8jp.DEFAULT_OVERLAY_CONFIG,this.config,{inplace:!1});if(a.ceActive=game.modules.get("dfreds-convenient-effects")?.active,a.ceActive&&(a.ceEffects=game.dfreds.effects.all.map(t=>t.name)),a.macros=game.macros.map(t=>t.name),"NONE"!==n.filter){let t=genFilterOptionControls(n.filter,n.filterOptions);t?n.filterOptions=t:n.filterOptions=null}else n.filterOptions=null;a.users=game.users.map(t=>({id:t.id,name:t.name,selected:n.limitedUsers.includes(t.id)})),a.fonts=Object.keys(CONFIG.fontDefinitions);let r=(0,$dmUqi.getAllEffectMappings)(this.token,!0).filter(t=>t.id!==this.config.id),[o,s]=(0,$eYkM9.sortMappingsToGroups)(r);// Cache Partials
|
|
for(let t of(a.parents=s,a.parentID||(a.parentID="TOKEN"),a.anchor||(a.anchor={x:.5,y:.5}),Object.keys($ce8jp.OVERLAY_SHAPES)))await getTemplate(`modules/token-variants/templates/partials/shape${t}.html`);return await getTemplate("modules/token-variants/templates/partials/repeating.html"),await getTemplate("modules/token-variants/templates/partials/interpolateColor.html"),a.allShapes=Object.keys($ce8jp.OVERLAY_SHAPES),a.textAlignmentOptions=[{value:"left",label:"Left"},{value:"center",label:"Center"},{value:"right",label:"Right"},{value:"justify",label:"Justify"}],"linkDimensionsX"in n||!n.linkDimensions||(n.linkDimensionsX=!0,n.linkDimensionsY=!0),mergeObject(a,n)}_getHeaderButtons(){let t=super._getHeaderButtons();return t.unshift({label:"Core Variables",class:".core-variables",icon:"fas fa-file-import fa-fw",onclick:()=>{let t=`
|
|
<table>
|
|
<tr><th>Variable</th><th>Description</th></tr>
|
|
<tr><td>@hp</td><td>Actor Health</td></tr>
|
|
<tr><td>@hpMax</td><td>Actor Health (Max)</td></tr>
|
|
<tr><td>@gridSize</td><td>Grid Size (Pixels)</td></tr>
|
|
<tr><td>@label</td><td>Mapping's Label Field</td></tr>
|
|
</table>
|
|
`;new Dialog({title:"Core Variables",content:t,buttons:{}}).render(!0)}}),t}async close(t={}){super.close(t),this._removePreviews()}_getSubmitData(){let t=super._getSubmitData();return(t=expandObject(t)).repeating||delete t.repeat,t.text.repeating||delete t.text.repeat,t.shapes&&(t.shapes=Object.values(t.shapes),t.shapes.forEach(t=>{t.repeating||delete t.repeat})),t.interactivity?t.interactivity=Object.values(t.interactivity).map(t=>(t.macro=t.macro.trim(),t.script=t.script.trim(),t.tmfxPreset&&(t.tmfxPreset=t.tmfxPreset.trim()),t.ceEffect&&(t.ceEffect=t.ceEffect.trim()),t)).filter(t=>t.macro||t.script||t.ceEffect||t.tmfxPreset):t.interactivity=[],t.variables&&(t.variables=Object.values(t.variables),t.variables=t.variables.filter(t=>t.name.trim()&&t.value.trim())),t.limitedUsers?("string"===getType(t.limitedUsers)&&(t.limitedUsers=[t.limitedUsers]),t.limitedUsers=t.limitedUsers.filter(t=>t)):t.limitedUsers=[],t.limitOnEffect=t.limitOnEffect.trim(),t.limitOnProperty=t.limitOnProperty.trim(),"TOKEN"===t.parentID&&(t.parentID=""),"OutlineOverlayFilter"===t.filter&&"filterOptions.outlineColor"in t?t["filterOptions.outlineColor"]=this._convertColor(t["filterOptions.outlineColor"]):"BevelFilter"===t.filter?("filterOptions.lightColor"in t&&(t["filterOptions.lightColor"]=Number(Color.fromString(t["filterOptions.lightColor"]))),"filterOptions.shadowColor"in t&&(t["filterOptions.shadowColor"]=Number(Color.fromString(t["filterOptions.shadowColor"])))):["DropShadowFilter","GlowFilter","OutlineFilter","FilterFire"].includes(t.filter)&&"filterOptions.color"in t&&(t["filterOptions.color"]=Number(Color.fromString(t["filterOptions.color"]))),t}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){this.callback&&this.callback(a)}}let FILTERS={OutlineOverlayFilter:{defaultValues:{outlineColor:[0,0,0,1],trueThickness:1,animate:!1},controls:[{type:"color",name:"outlineColor"},{type:"range",label:"Thickness",name:"trueThickness",min:0,max:5,step:.01},{type:"boolean",label:"Oscillate",name:"animate"}],argType:"args"},AlphaFilter:{defaultValues:{alpha:1},controls:[{type:"range",name:"alpha",min:0,max:1,step:.01}],argType:"args"},BlurFilter:{defaultValues:{strength:8,quality:4},controls:[{type:"range",name:"strength",min:0,max:20,step:1},{type:"range",name:"quality",min:0,max:20,step:1}],argType:"args"},BlurFilterPass:{defaultValues:{horizontal:!1,strength:8,quality:4},controls:[{type:"boolean",name:"horizontal"},{type:"range",name:"strength",min:0,max:20,step:1},{type:"range",name:"quality",min:0,max:20,step:1}],argType:"args"},NoiseFilter:{defaultValues:{noise:.5,seed:4475160954091},controls:[{type:"range",name:"noise",min:0,max:1,step:.01},{type:"range",name:"seed",min:0,max:1e5,step:1}],argType:"args"},AdjustmentFilter:{defaultValues:{gamma:1,saturation:1,contrast:1,brightness:1,red:1,green:1,blue:1,alpha:1},controls:[{type:"range",name:"gamma",min:0,max:1,step:.01},{type:"range",name:"saturation",min:0,max:1,step:.01},{type:"range",name:"contrast",min:0,max:1,step:.01},{type:"range",name:"brightness",min:0,max:1,step:.01},{type:"range",name:"red",min:0,max:1,step:.01},{type:"range",name:"green",min:0,max:1,step:.01},{type:"range",name:"blue",min:0,max:1,step:.01},{type:"range",name:"alpha",min:0,max:1,step:.01}],argType:"options"},AdvancedBloomFilter:{defaultValues:{threshold:.5,bloomScale:1,brightness:1,blur:8,quality:4},controls:[{type:"range",name:"threshold",min:0,max:1,step:.01},{type:"range",name:"bloomScale",min:0,max:5,step:.01},{type:"range",name:"brightness",min:0,max:1,step:.01},{type:"range",name:"blur",min:0,max:20,step:1},{type:"range",name:"quality",min:0,max:20,step:1}],argType:"options"},AsciiFilter:{defaultValues:{size:8},controls:[{type:"range",name:"size",min:0,max:20,step:.01}],argType:"args"},BevelFilter:{defaultValues:{rotation:45,thickness:2,lightColor:16777215,lightAlpha:.7,shadowColor:0,shadowAlpha:.7},controls:[{type:"range",name:"rotation",min:0,max:360,step:1},{type:"range",name:"thickness",min:0,max:20,step:.01},{type:"color",name:"lightColor"},{type:"range",name:"lightAlpha",min:0,max:1,step:.01},{type:"color",name:"shadowColor"},{type:"range",name:"shadowAlpha",min:0,max:1,step:.01}],argType:"options"},BloomFilter:{defaultValues:{blur:2,quality:4},controls:[{type:"range",name:"blur",min:0,max:20,step:1},{type:"range",name:"quality",min:0,max:20,step:1}],argType:"args"},BulgePinchFilter:{defaultValues:{radius:100,strength:1},controls:[{type:"range",name:"radius",min:0,max:500,step:1},{type:"range",name:"strength",min:-1,max:1,step:.01}],argType:"options"},CRTFilter:{defaultValues:{curvature:1,lineWidth:1,lineContrast:.25,verticalLine:!1,noise:.3,noiseSize:1,seed:0,vignetting:.3,vignettingAlpha:1,vignettingBlur:.3,time:0},controls:[{type:"range",name:"curvature",min:0,max:20,step:.01},{type:"range",name:"lineWidth",min:0,max:20,step:.01},{type:"range",name:"lineContrast",min:0,max:5,step:.01},{type:"boolean",name:"verticalLine"},{type:"range",name:"noise",min:0,max:2,step:.01},{type:"range",name:"noiseSize",min:0,max:20,step:.01},{type:"range",name:"seed",min:0,max:1e5,step:1},{type:"range",name:"vignetting",min:0,max:20,step:.01},{type:"range",name:"vignettingAlpha",min:0,max:1,step:.01},{type:"range",name:"vignettingBlur",min:0,max:5,step:.01},{type:"range",name:"time",min:0,max:1e4,step:1}],argType:"options"},DotFilter:{defaultValues:{scale:1,angle:5},controls:[{type:"range",name:"scale",min:0,max:50,step:1},{type:"range",name:"angle",min:0,max:360,step:.1}],argType:"args"},DropShadowFilter:{defaultValues:{rotation:45,distance:5,color:0,alpha:.5,shadowOnly:!1,blur:2,quality:3},controls:[{type:"range",name:"rotation",min:0,max:360,step:.1},{type:"range",name:"distance",min:0,max:100,step:.1},{type:"color",name:"color"},{type:"range",name:"alpha",min:0,max:1,step:.01},{type:"boolean",name:"shadowOnly"},{type:"range",name:"blur",min:0,max:20,step:.1},{type:"range",name:"quality",min:0,max:20,step:1}],argType:"options"},EmbossFilter:{defaultValues:{strength:5},controls:[{type:"range",name:"strength",min:0,max:20,step:1}],argType:"args"},GlitchFilter:{defaultValues:{slices:5,offset:100,direction:0,fillMode:0,seed:0,average:!1,minSize:8,sampleSize:512},controls:[{type:"range",name:"slices",min:0,max:50,step:1},{type:"range",name:"distance",min:0,max:1e3,step:1},{type:"range",name:"direction",min:0,max:360,step:.1},{type:"select",name:"fillMode",options:[{value:0,label:"TRANSPARENT"},{value:1,label:"ORIGINAL"},{value:2,label:"LOOP"},{value:3,label:"CLAMP"},{value:4,label:"MIRROR"}]},{type:"range",name:"seed",min:0,max:1e4,step:1},{type:"boolean",name:"average"},{type:"range",name:"minSize",min:0,max:500,step:1},{type:"range",name:"sampleSize",min:0,max:1024,step:1}],argType:"options"},GlowFilter:{defaultValues:{distance:10,outerStrength:4,innerStrength:0,color:16777215,quality:.1,knockout:!1},controls:[{type:"range",name:"distance",min:1,max:50,step:1},{type:"range",name:"outerStrength",min:0,max:20,step:1},{type:"range",name:"innerStrength",min:0,max:20,step:1},{type:"color",name:"color"},{type:"range",name:"quality",min:0,max:5,step:.1},{type:"boolean",name:"knockout"}],argType:"options"},GodrayFilter:{defaultValues:{angle:30,gain:.5,lacunarity:2.5,parallel:!0,time:0,alpha:1},controls:[{type:"range",name:"angle",min:0,max:360,step:.1},{type:"range",name:"gain",min:0,max:5,step:.01},{type:"range",name:"lacunarity",min:0,max:5,step:.01},{type:"boolean",name:"parallel"},{type:"range",name:"time",min:0,max:1e4,step:1},{type:"range",name:"alpha",min:0,max:1,step:.01}],argType:"options"},KawaseBlurFilter:{defaultValues:{blur:4,quality:3,clamp:!1},controls:[{type:"range",name:"blur",min:0,max:20,step:.1},{type:"range",name:"quality",min:0,max:20,step:1},{type:"boolean",name:"clamp"}],argType:"args"},OldFilmFilter:{defaultValues:{sepia:.3,noise:.3,noiseSize:1,scratch:.5,scratchDensity:.3,scratchWidth:1,vignetting:.3,vignettingAlpha:1,vignettingBlur:.3},controls:[{type:"range",name:"sepia",min:0,max:1,step:.01},{type:"range",name:"noise",min:0,max:1,step:.01},{type:"range",name:"noiseSize",min:0,max:5,step:.01},{type:"range",name:"scratch",min:0,max:5,step:.01},{type:"range",name:"scratchDensity",min:0,max:5,step:.01},{type:"range",name:"scratchWidth",min:0,max:20,step:.01},{type:"range",name:"vignetting",min:0,max:1,step:.01},{type:"range",name:"vignettingAlpha",min:0,max:1,step:.01},{type:"range",name:"vignettingBlur",min:0,max:5,step:.01}],argType:"options"},OutlineFilter:{defaultValues:{thickness:1,color:0,quality:.1},controls:[{type:"range",name:"thickness",min:0,max:20,step:.1},{type:"color",name:"color"},{type:"range",name:"quality",min:0,max:1,step:.01}],argType:"args"},PixelateFilter:{defaultValues:{size:1},controls:[{type:"range",name:"size",min:1,max:100,step:1}],argType:"args"},RGBSplitFilter:{defaultValues:{red:[-10,0],green:[0,10],blue:[0,0]},controls:[{type:"point",name:"red",min:0,max:50,step:1},{type:"point",name:"green",min:0,max:50,step:1},{type:"point",name:"blue",min:0,max:50,step:1}],argType:"args"},RadialBlurFilter:{defaultValues:{angle:0,center:[0,0],radius:-1},controls:[{type:"range",name:"angle",min:0,max:360,step:1},{type:"point",name:"center",min:0,max:1e3,step:1},{type:"range",name:"radius",min:-1,max:1e3,step:1}],argType:"args"},ReflectionFilter:{defaultValues:{mirror:!0,boundary:.5,amplitude:[0,20],waveLength:[30,100],alpha:[1,1],time:0},controls:[{type:"boolean",name:"mirror"},{type:"range",name:"boundary",min:0,max:1,step:.01},{type:"point",name:"amplitude",min:0,max:100,step:1},{type:"point",name:"waveLength",min:0,max:500,step:1},{type:"point",name:"alpha",min:0,max:1,step:.01},{type:"range",name:"time",min:0,max:1e4,step:1}],argType:"options"},DisplacementFilter:{defaultValues:{sprite:"",textureScale:1,displacementScale:1},controls:[{type:"text",name:"sprite"},{type:"range",name:"textureScale",min:0,max:100,step:.1},{type:"range",name:"displacementScale",min:0,max:100,step:.1}],argType:"options"},"Token Magic FX":{defaultValues:{params:[]},controls:[{type:"tmfxPreset",name:"tmfxPreset"},{type:"json",name:"params"}]}};function genFilterOptionControls(t,a={}){if(!(t in FILTERS))return;let n=mergeObject(FILTERS[t].defaultValues,a),r=getControlValues(t,n),o=FILTERS[t].controls,s="<fieldset><legend>Options</legend>";for(let t of o)s+=genControl(t,r);return s+"</fieldset>"}function getControlValues(t,a){return"OutlineOverlayFilter"===t?a.outlineColor=Color.fromRGB(a.outlineColor).toString():"BevelFilter"===t?(a.lightColor=Color.from(a.lightColor).toString(),a.shadowColor=Color.from(a.shadowColor).toString()):["DropShadowFilter","GlowFilter","OutlineFilter"].includes(t)&&(a.color=Color.from(a.color).toString()),a}function genControl(t,a){let n=a[t.name],r=t.name,o=t.label??r.charAt(0).toUpperCase()+r.slice(1),s=t.type;if("color"===s)return`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<input class="color" type="text" name="filterOptions.${r}" value="${n}">
|
|
<input type="color" value="${n}" data-edit="filterOptions.${r}">
|
|
</div>
|
|
</div>
|
|
`;if("range"===s)return`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<input type="range" name="filterOptions.${r}" value="${n}" min="${t.min}" max="${t.max}" step="${t.step}">
|
|
<span class="range-value">${n}</span>
|
|
</div>
|
|
</div>
|
|
`;if("boolean"===s)return`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<input type="checkbox" name="filterOptions.${r}" data-dtype="Boolean" value="${n}" ${n?"checked":""}>
|
|
</div>
|
|
</div>
|
|
`;if("select"===s){let a=`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<select name="${r}">
|
|
`;for(let r of t.options)a+=`<option value="${r.value}" ${n===r.value?'selected="selected"':""}>${r.label}</option>`;return a+"</select></div></div>"}if("point"===s)return`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<input type="range" name="filterOptions.${r}" value="${n[0]}" min="${t.min}" max="${t.max}" step="${t.step}">
|
|
<span class="range-value">${n[0]}</span>
|
|
</div>
|
|
<div class="form-fields">
|
|
<input type="range" name="filterOptions.${r}" value="${n[1]}" min="${t.min}" max="${t.max}" step="${t.step}">
|
|
<span class="range-value">${n[1]}</span>
|
|
</div>
|
|
</div>
|
|
`;if("json"===s){let t=`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<textarea style="width: 450px; height: 200px;" name="filterOptions.${r}">${n}</textarea>
|
|
</div>`;return game.modules.get("multi-token-edit")?.api.showGenericForm&&(t+=`
|
|
<div style="text-align: right; color: orangered;">
|
|
<a> <i class="me-edit-json fas fa-edit" title="Show Generic Form"></i></a>
|
|
</div>`),t+="</div>"}if("text"===s)return`
|
|
<div class="form-group">
|
|
<label>${o}</label>
|
|
<div class="form-fields">
|
|
<input type="text" name="filterOptions.${r}" value="${n}">
|
|
</div>
|
|
</div>
|
|
`;else if("tmfxPreset"===s&&game.modules.get("tokenmagic")?.active)return`
|
|
<div class="form-group">
|
|
<label>Preset <span class="units">(TMFX)</span></label>
|
|
<div class="form-fields">
|
|
<input list="tmfxPresets" class="tmfxPreset">
|
|
<button type="button" class="presetImport"><i class="fas fa-download"></i></button>
|
|
</div>
|
|
`;return""}async function promptParamChoice(t){return new Promise((a,n)=>{let r={};for(let n=0;n<t.length;n++){let o=t[n].filterType??t[n].filterId;r[o]={label:o,callback:()=>{a(n)}}}let o=new Dialog({title:"Select Filter To Edit",content:"",buttons:r,close:()=>a(-1)});o.render(!0)})}}),parcelRequire.register("ce8jp",function(t,a){$parcel$export(t.exports,"DEFAULT_ACTIVE_EFFECT_CONFIG",()=>n),$parcel$export(t.exports,"DEFAULT_OVERLAY_CONFIG",()=>r),$parcel$export(t.exports,"OVERLAY_SHAPES",()=>o),$parcel$export(t.exports,"CORE_SHAPE",()=>s);let n={id:"",label:"",expression:"",codeExp:"",imgName:"",imgSrc:"",priority:50,config:null,overlay:!1,alwaysOn:!1,tokens:void 0,disabled:!1,overlayConfig:null,targetActors:null,group:"Default"},r={img:"",imgLinked:!1,alpha:1,scaleX:1,scaleY:1,offsetX:0,offsetY:0,angle:0,filter:"NONE",filterOptions:{},inheritTint:!1,top:!1,bottom:!1,underlay:!1,linkRotation:!0,linkMirror:!0,linkOpacity:!1,linkScale:!0,linkDimensionX:!1,linkDimensionY:!1,linkStageScale:!1,mirror:!1,tint:null,loop:!0,playOnce:!1,animation:{rotate:!1,duration:5e3,clockwise:!0,relative:!1},limitedUsers:[],limitedToOwner:!1,limitOnProperty:"",alwaysVisible:!1,text:{text:"",align:CONFIG.canvasTextStyle.align,fontSize:CONFIG.canvasTextStyle.fontSize,fontFamily:CONFIG.canvasTextStyle.fontFamily,fill:CONFIG.canvasTextStyle.fill,dropShadow:CONFIG.canvasTextStyle.dropShadow,strokeThickness:CONFIG.canvasTextStyle.strokeThickness,stroke:CONFIG.canvasTextStyle.stroke,curve:{angle:0,radius:0,invert:!1},letterSpacing:CONFIG.canvasTextStyle.letterSpacing,repeating:!1,wordWrap:!1,wordWrapWidth:200,breakWords:!1,maxHeight:0},parentID:"",id:null,anchor:{x:.5,y:.5},shapes:[],variables:[],interactivity:[],ui:!1},o={Rectangle:{type:"rectangle",x:0,y:0,width:100,height:100,radius:0,repeating:!1},Ellipse:{type:"ellipse",x:0,y:0,width:50,height:50,repeating:!1},Polygon:{type:"polygon",x:0,y:0,points:"0,1,0.95,0.31,0.59,-0.81,-0.59,-0.81,-0.95,0.31",scale:50,repeating:!1},Torus:{type:"torus",x:0,y:0,innerRadius:50,outerRadius:100,startAngle:0,endAngle:180,repeating:!1}},s={line:{width:1,color:"#000000",alpha:1},fill:{color:"#ffffff",color2:"",prc:"",alpha:1}}}),parcelRequire.register("dmUqi",function(module,exports){let EFFECT_M_TIMER;$parcel$export(module.exports,"registerEffectMappingHooks",()=>registerEffectMappingHooks),$parcel$export(module.exports,"updateWithEffectMapping",()=>updateWithEffectMapping),$parcel$export(module.exports,"getTokenEffects",()=>getTokenEffects),$parcel$export(module.exports,"getAllEffectMappings",()=>getAllEffectMappings),$parcel$export(module.exports,"setOverlayVisibility",()=>setOverlayVisibility),$parcel$export(module.exports,"toggleTemplate",()=>toggleTemplate),$parcel$export(module.exports,"toggleTemplateOnSelected",()=>toggleTemplateOnSelected),$parcel$export(module.exports,"getTokenHP",()=>getTokenHP),$parcel$export(module.exports,"VALID_EXPRESSION",()=>VALID_EXPRESSION),$parcel$export(module.exports,"evaluateComparator",()=>evaluateComparator);var $9IngI=parcelRequire("9IngI"),$eeGZt=parcelRequire("eeGZt"),$bFZU7=parcelRequire("bFZU7"),$e9LRe=parcelRequire("e9LRe"),$hClLE=parcelRequire("hClLE");let EXPRESSION_MATCH_RE=/(\\\()|(\\\))|(\|\|)|(\&\&)|(\\\!)/g,PF2E_ITEM_TYPES=["condition","effect","weapon","equipment"],ITEM_TYPES=["equipment","weapon"],feature_id="EffectMappings";function registerEffectMappingHooks(){if(!$9IngI.FEATURE_CONTROL[feature_id]){["canvasReady","createActiveEffect","deleteActiveEffect","preUpdateActiveEffect","updateActiveEffect","createCombatant","deleteCombatant","preUpdateCombat","updateCombat","deleteCombat","preUpdateToken","preUpdateActor","updateActor","updateToken","createToken","preUpdateItem","updateItem","createItem","deleteItem"].forEach(t=>(0,$e9LRe.unregisterHook)(feature_id,t));return}game.user.isGM&&((0,$e9LRe.registerHook)(feature_id,"canvasReady",_refreshTokenMappings),_refreshTokenMappings()),(0,$e9LRe.registerHook)(feature_id,"createActiveEffect",(t,a,n)=>{if(!t.parent||t.disabled||game.userId!==n)return;let r=t.name??t.label;_updateImageOnEffectChange(r,t.parent,!0)}),(0,$e9LRe.registerHook)(feature_id,"deleteActiveEffect",(t,a,n)=>{if(!t.parent||t.disabled||game.userId!==n)return;let r=t.name??t.label;_updateImageOnEffectChange(r,t.parent,!1)}),(0,$e9LRe.registerHook)(feature_id,"preUpdateActiveEffect",_preUpdateActiveEffect),(0,$e9LRe.registerHook)(feature_id,"updateActiveEffect",_updateActiveEffect),(0,$e9LRe.registerHook)(feature_id,"preUpdateToken",_preUpdateToken),(0,$e9LRe.registerHook)(feature_id,"preUpdateActor",_preUpdateActor),(0,$e9LRe.registerHook)(feature_id,"updateActor",_updateActor),(0,$e9LRe.registerHook)(feature_id,"updateToken",_updateToken),(0,$e9LRe.registerHook)(feature_id,"createToken",_createToken),(0,$e9LRe.registerHook)(feature_id,"createCombatant",_createCombatant),(0,$e9LRe.registerHook)(feature_id,"deleteCombatant",(t,a,n)=>{game.userId===n&&_deleteCombatant(t)}),(0,$e9LRe.registerHook)(feature_id,"preUpdateCombat",_preUpdateCombat),(0,$e9LRe.registerHook)(feature_id,"updateCombat",_updateCombat),(0,$e9LRe.registerHook)(feature_id,"deleteCombat",(t,a,n)=>{game.userId===n&&t.combatants.forEach(t=>{_deleteCombatant(t)})});let t="pf2e"===game.system.id?PF2E_ITEM_TYPES:ITEM_TYPES;// Want to track condition/effect previous name so that the config can be reverted for it
|
|
(0,$e9LRe.registerHook)(feature_id,"preUpdateItem",(a,n,r,o)=>{game.user.id===o&&t.includes(a.type)&&(r["token-variants-old-name"]=a.name),_preUpdateAssign(a.parent,n,r)}),(0,$e9LRe.registerHook)(feature_id,"createItem",(a,n,r)=>{game.userId===r&&t.includes(a.type)&&a.parent&&_updateImageOnEffectChange(a.name,a.parent,!0)}),(0,$e9LRe.registerHook)(feature_id,"deleteItem",(a,n,r)=>{game.userId===r&&t.includes(a.type)&&a.parent&&!a.disabled&&_updateImageOnEffectChange(a.name,a.parent,!1)}),// Status Effects can be applied "stealthily" on item equip/un-equip
|
|
(0,$e9LRe.registerHook)(feature_id,"updateItem",_updateItem)}async function _refreshTokenMappings(){for(let t of canvas.tokens.placeables)await updateWithEffectMapping(t)}function _createCombatant(t,a,n){if(game.userId!==n)return;let r=t._token||canvas.tokens.get(t.tokenId);r&&r.actor&&updateWithEffectMapping(r,{added:["token-variants-combat"]})}function _preUpdateActiveEffect(t,a,n,r){t.parent&&game.userId===r&&"label"in a&&(n["token-variants-old-name"]=t.label)}function _updateActiveEffect(t,a,n,r){if(!t.parent||game.userId!==r)return;let o=[],s=[];"disabled"in a&&(a.disabled?s.push(t.label):o.push(t.label)),"label"in a&&(s.push(n["token-variants-old-name"]),o.push(a.label)),(o.length||s.length)&&_updateImageOnMultiEffectChange(t.parent,o,s)}function _preUpdateToken(t,a,n,r){if(game.user.id!==r||a.actorId)return;let o=getTokenEffects(t,!0);o.length&&setProperty(n,"token-variants.preUpdateEffects",o),"dnd5e"===game.system.id&&t.actor?.isPolymorphed&&setProperty(n,"token-variants.wasPolymorphed",!0)}async function _updateToken(t,a,n,r){if(game.user.id!==r||a.actorId)return;// TODO
|
|
t.object?.tvaOverlays?.forEach(t=>t.htmlOverlay?.render());let o=[],s=[],l=getProperty(n,"token-variants.preUpdateEffects")||[],c=getTokenEffects(t,!0);(0,$eeGZt.determineAddedRemovedEffects)(o,s,c,l),o.length||s.length||"actorLink"in a?updateWithEffectMapping(t,{added:o,removed:s}):getProperty(n,"token-variants.wasPolymorphed")&&!t.actor?.isPolymorphed&&updateWithEffectMapping(t),game.userId===r&&"hidden"in a&&updateWithEffectMapping(t,{added:a.hidden?["token-variants-visibility"]:[],removed:a.hidden?[]:["token-variants-visibility"]})}function _preUpdateActor(t,a,n,r){game.user.id===r&&_preUpdateAssign(t,a,n)}async function _updateActor(t,a,n,r){if(game.user.id===r){if("flags"in a&&"token-variants"in a.flags){let n=a.flags["token-variants"];if("effectMappings"in n||"-=effectMappings"in n){let a=t.token?[t.token]:(0,$eeGZt.getAllActorTokens)(t,!0,!$9IngI.TVA_CONFIG.mappingsCurrentSceneOnly);for(let t of(a.forEach(t=>updateWithEffectMapping(t)),a))t.object&&$9IngI.TVA_CONFIG.filterEffectIcons&&await t.object.drawEffects()}}_preUpdateCheck(t,n)}}function _preUpdateAssign(t,a,n){if(!t)return;// Determine which comparators are applicable so that we can compare after the
|
|
// actor update
|
|
let r=t.token?[t.token]:(0,$eeGZt.getAllActorTokens)(t,!0,!$9IngI.TVA_CONFIG.mappingsCurrentSceneOnly);for(let o of($9IngI.TVA_CONFIG.internalEffects.hpChange.enabled&&r.length&&applyHpChangeEffect(t,a,r),r)){let t=getTokenEffects(o,!0);t.length&&setProperty(n,"token-variants."+o.id+".preUpdateEffects",t)}}function _preUpdateCheck(t,a,n=[],r=[]){if(!t)return;let o=t.token?[t.token]:(0,$eeGZt.getAllActorTokens)(t,!0,!$9IngI.TVA_CONFIG.mappingsCurrentSceneOnly);for(let t of o){// Check if effects changed by comparing them against the ones calculated in preUpdate*
|
|
let o=[...n],s=[...r],l=getTokenEffects(t,!0),c=getProperty(a,"token-variants."+t.id+".preUpdateEffects")??[];(0,$eeGZt.determineAddedRemovedEffects)(o,s,l,c),(o.length||s.length)&&updateWithEffectMapping(t,{added:o,removed:s})}}function _createToken(t,a,n){n&&n===game.user.id&&updateWithEffectMapping(t)}function _preUpdateCombat(t,a,n,r){game.userId===r&&(n["token-variants"]={combatantId:t?.combatant?.token?.id,nextCombatantId:t?.nextCombatant?.token?.id})}function _updateCombat(t,a,n,r){if(game.userId!==r)return;let o=n["token-variants"]?.combatantId,s=n["token-variants"]?.nextCombatantId,l=t?.combatant?.token?.id,c=t?.nextCombatant?.token?.id,p=function(t,a=[],n=[]){if(game.user.isGM){let r=canvas.tokens.get(t);r&&updateWithEffectMapping(r,{added:a,removed:n})}else{let r={handlerName:"effectMappings",args:{tokenId:t,sceneId:canvas.scene.id,added:a,removed:n},type:"UPDATE"};game.socket?.emit("module.token-variants",r)}};o!==l&&(o&&p(o,[],["combat-turn"]),l&&p(l,["combat-turn"],[])),s!==c&&(s&&p(s,[],["combat-turn-next"]),c&&p(c,["combat-turn-next"],[]))}function _updateItem(t,a,n,r){let o=[],s=[];game.user.id===r&&(n["token-variants-old-name"]!==t.name&&(o.push(t.name),s.push(n["token-variants-old-name"])),_preUpdateCheck(t.parent,n,o,s))}let EFFECT_M_QUEUES={};async function updateWithEffectMapping(t,{added:a=[],removed:n=[]}={}){let r=function(){for(let t of Object.keys(EFFECT_M_QUEUES)){let a=EFFECT_M_QUEUES[t];_updateWithEffectMapping(a.token,a.opts.added,a.opts.removed)}EFFECT_M_QUEUES={}};if(clearTimeout(EFFECT_M_TIMER),t.id in EFFECT_M_QUEUES){let r=EFFECT_M_QUEUES[t.id].opts;a.forEach(t=>r.added.add(t)),n.forEach(t=>r.removed.add(t))}else EFFECT_M_QUEUES[t.id]={token:t,opts:{added:new Set(a),removed:new Set(n)}};EFFECT_M_TIMER=setTimeout(r,100)}async function _updateWithEffectMapping(t,a,n){let r;let o=t.object??t._object??t;t=t.document??t;let s=t.getFlag("token-variants","name")||(0,$eeGZt.getFileName)(t.texture.src),l=t.getFlag("token-variants","defaultImg"),c=!$9IngI.TVA_CONFIG.disableTokenUpdateAnimation,p={},f=t.object?.hasActiveHUD,d=canvas.tokens.hud.object?.id===t.id&&canvas.tokens.hud._statusEffects,g=getTokenEffects(t);// If effect is included in `added` or `removed` we need to:
|
|
// 1. Insert it into `effects` if it's not there in case of 'added' and place it on top of the list
|
|
// 2. Remove it in case of 'removed'
|
|
for(let t of a){let a=g.findIndex(a=>a===t);-1===a?g.push(t):a<g.length-1&&(g.splice(a,1),g.push(t))}for(let t of n){let a=g.findIndex(a=>a===t);-1!==a&&g.splice(a,1)}let h=getAllEffectMappings(t);// 3. Configurations may contain effect names in a form of a logical expressions
|
|
// We need to evaluate them and insert them into effects/added/removed if needed
|
|
for(let r of h)evaluateMappingExpression(r,g,t,a,n);// Accumulate all scripts that will need to be run after the update
|
|
let u=[],m=[];for(let a of n){let n=h.find(t=>t.id===a)?.config?.tv_script;n&&(n.onRemove&&(n.onRemove.includes("tvaUpdate")?m.push(n.onRemove):u.push({script:n.onRemove,token:t})),n.tmfxPreset&&u.push({tmfxPreset:n.tmfxPreset,token:t,action:"remove"}),n.ceEffect?.name&&u.push({ceEffect:n.ceEffect,token:t,action:"remove"}),n.macroOnApply&&u.push({macro:n.macroOnApply,token:t}))}for(let n of a){let a=h.find(t=>t.id===n)?.config?.tv_script;a&&(a.onApply&&(a.onApply.includes("tvaUpdate")?m.push(a.onApply):u.push({script:a.onApply,token:t})),a.tmfxPreset&&u.push({tmfxPreset:a.tmfxPreset,token:t,action:"apply"}),a.ceEffect?.name&&u.push({ceEffect:a.ceEffect,token:t,action:"apply"}),a.macroOnRemove&&u.push({macro:a.macroOnRemove,token:t}))}// Next we're going to determine what configs need to be applied and in what order
|
|
// Filter effects that do not have a mapping and sort based on priority
|
|
g=h.filter(t=>g.includes(t.id)).sort((t,a)=>t.priority-a.priority);// Check if image update should be prevented based on module settings
|
|
let y=!1;if($9IngI.TVA_CONFIG.disableImageChangeOnPolymorphed&&t.actor?.isPolymorphed)y=!0;else if($9IngI.TVA_CONFIG.disableImageUpdateOnNonPrototype&&t.actor?.prototypeToken?.texture?.src!==t.texture.src){y=!0;let a=t.texture.src;for(let t of h)if(t.imgSrc===a){y=!1;break}}if(y&&(l=""),g.length>0){let n;// Some effect mappings may not have images, find a mapping with one if it exists
|
|
let o={imgSrc:"",imgName:""};if(!y){for(let n=g.length-1;n>=0;n--)if(g[n].imgSrc){let r=g[n].imgSrc;if((r.includes("*")||r.includes("{")&&r.includes("}"))&&!a.has(g[n].overlayConfig?.effect)){o.imgSrc=t.texture.src,o.imgName=(0,$eeGZt.getFileName)(o.imgSrc);break}o.imgSrc=g[n].imgSrc,o.imgName=g[n].imgName;break}}if($9IngI.TVA_CONFIG.stackStatusConfig)for(let t of(n={},g))n=mergeObject(n,t.config);else for(let t=g.length-1;t>=0;t--)if(g[t].config&&0!==Object.keys(g[t].config).length){n=g[t].config;break}!o.imgSrc&&l?(delete p.flags?.["token-variants"]?.defaultImg,setProperty(p,"flags.token-variants.-=defaultImg",null),o.imgSrc=l.imgSrc,o.imgName=l.imgName):!l&&o.imgSrc&&setProperty(p,"flags.token-variants.defaultImg",{imgSrc:t.texture.src,imgName:s}),r=()=>(0,$eeGZt.updateTokenImage)(o.imgSrc??null,{token:t,imgName:o.imgName?o.imgName:s,tokenUpdate:p,callback:_postTokenUpdateProcessing.bind(null,t,f,d,u),config:n,animate:c})}if(0===g.length&&l?(delete p.flags?.["token-variants"]?.defaultImg,setProperty(p,"flags.token-variants.-=defaultImg",null),r=()=>(0,$eeGZt.updateTokenImage)(l.imgSrc,{token:t,imgName:l.imgName,tokenUpdate:p,callback:_postTokenUpdateProcessing.bind(null,t,f,d,u),animate:c})):0===g.length&&t.getFlag("token-variants","usingCustomConfig")&&(r=()=>(0,$eeGZt.updateTokenImage)(t.texture.src,{token:t,imgName:s,tokenUpdate:p,callback:_postTokenUpdateProcessing.bind(null,t,f,d,u),animate:c})),r){if(m.length)for(let a=0;a<m.length;a++)a===m.length-1?await (0,$eeGZt.tv_executeScript)(m[a],{token:t,tvaUpdate:()=>{r()}}):await (0,$eeGZt.tv_executeScript)(m[a],{token:t,tvaUpdate:()=>{}});else r()}else(u.length||m.length)&&(_postTokenUpdateProcessing(t,f,d,u),_postTokenUpdateProcessing(t,f,d,m));(0,$bFZU7.broadcastOverlayRedraw)(o)}async function _postTokenUpdateProcessing(t,a,n,r){for(let o of(a&&t.object&&(canvas.tokens.hud.bind(t.object),n&&canvas.tokens.hud._toggleStatusEffects(!0)),r))o.script?await (0,$eeGZt.tv_executeScript)(o.script,{token:o.token}):o.tmfxPreset?await (0,$eeGZt.applyTMFXPreset)(o.token,o.tmfxPreset,o.action):o.ceEffect?await (0,$eeGZt.applyCEEffect)(o.token,o.ceEffect,o.action):o.macro&&await (0,$eeGZt.executeMacro)(o.macro,t)}function getAllEffectMappings(t=null,a=!1){let n=(0,$9IngI.getFlagMappings)(t),r=new Set;// TODO: replace with a setting
|
|
n.forEach(t=>r.add($9IngI.TVA_CONFIG.mergeGroup?t.group:t.label));// Sort out global mappings that do not apply to this actor
|
|
let o=$9IngI.TVA_CONFIG.globalMappings;if(t?.actor?.type){let a=t.actor.type;o=o.filter(t=>!!(!t.targetActors||t.targetActors.includes(a))&&!r.has($9IngI.TVA_CONFIG.mergeGroup?t.group:t.label))}return n=n.concat(o),a||(n=n.filter(t=>!t.disabled)),n}async function setOverlayVisibility({userName:t=null,userId:a=null,label:n=null,group:r=null,token:o=null,visible:s=!0}={}){if(!n&&!r||(t&&(a=game.users.find(a=>a.name===t)?.id),!a))return;let l=(0,$9IngI.getFlagMappings)(o),c=$9IngI.TVA_CONFIG.globalMappings,p=!1,f=!1,d=function(t){t=t.filter(t=>t.overlay&&(t.label===n||t.group===r));let o=!1;return t.length&&(o=!0),t.forEach(t=>{let n=t.overlayConfig;s?(n.limitedUsers||(n.limitedUsers=[]),n.limitedUsers.find(t=>t===a)||n.limitedUsers.push(a)):n.limitedUsers&&(n.limitedUsers=n.limitedUsers.filter(t=>t!==a))}),o};if(p=d(l),(f=d(c))&&await (0,$9IngI.updateSettings)({globalMappings:c}),p){let t=game.actors.get(o.document.actorId);t&&await t.setFlag("token-variants","effectMappings",l)}(p||f)&&(0,$bFZU7.drawOverlays)(o)}function _getTemplateMappings(t){return($9IngI.TVA_CONFIG.templateMappings.find(a=>a.name===t)??$hClLE.CORE_TEMPLATES.find(a=>a.name===t))?.mappings}async function applyTemplate(t,a=null,n=null){if(a&&(n=_getTemplateMappings(a)),!t||!n)return;let r=game.actors.get(t.actor.id);if(!r)return;let o=deepClone(n);o.forEach(a=>a.tokens=[t.id]);let s=(0,$eeGZt.mergeMappings)(o,(0,$9IngI.getFlagMappings)(r));await r.setFlag("token-variants","effectMappings",s),await updateWithEffectMapping(t),(0,$bFZU7.drawOverlays)(t)}async function removeTemplate(t,a=null,n=null){if(a&&(n=_getTemplateMappings(a)),!t||!n)return;let r=game.actors.get(t.actor.id);if(!r)return;let o=(0,$9IngI.getFlagMappings)(r);n.forEach(a=>{let n=o.findIndex(t=>t.id===a.id);-1!==n&&(o[n].tokens=o[n].tokens.filter(a=>a!==t.id),0===o[n].tokens.length&&o.splice(n,1))}),o.length?await r.setFlag("token-variants","effectMappings",o):await r.unsetFlag("token-variants","effectMappings"),await updateWithEffectMapping(t),(0,$bFZU7.drawOverlays)(t)}function toggleTemplate(t,a=null,n=null){if(a&&(n=_getTemplateMappings(a)),!t||!n)return;let r=game.actors.get(t.actor.id);if(!r)return;let o=(0,$9IngI.getFlagMappings)(r);o.some(a=>n.some(n=>n.id===a.id&&a.tokens?.includes(t.id)))?removeTemplate(t,null,n):applyTemplate(t,null,n)}function toggleTemplateOnSelected(t=null,a=null){canvas.tokens.controlled.forEach(n=>toggleTemplate(n,t,a))}function getHPChangeEffect(t,a){let n=t.actor?.getFlag("token-variants","internalEffects")||{},r=getProperty(t,`${isNewerVersion("11",game.version)?"actorData":"delta"}.flags.token-variants.internalEffects`);r&&mergeObject(n,r),null!=n["hp--"]&&a.push("hp--"),null!=n["hp++"]&&a.push("hp++")}function applyHpChangeEffect(t,a,n){let r=Number($9IngI.TVA_CONFIG.internalEffects.hpChange.duration),o=getProperty(a,`system.${$9IngI.TVA_CONFIG.systemHpPath}.value`);if(null!=o){let[s,l]=getTokenHP(n[0]);s!==o&&(s<o?(setProperty(a,"flags.token-variants.internalEffects.-=hp--",null),setProperty(a,"flags.token-variants.internalEffects.hp++",o-s),r&&setTimeout(()=>{t.update({"flags.token-variants.internalEffects.-=hp++":null})},1e3*r)):(setProperty(a,"flags.token-variants.internalEffects.-=hp++",null),setProperty(a,"flags.token-variants.internalEffects.hp--",o-s),r&&setTimeout(()=>{t.update({"flags.token-variants.internalEffects.-=hp--":null})},1e3*r)))}}function getTokenEffects(t,a=!1){let n=t.document??t,r=[],o=game.combats.some(a=>a.combatants.some(a=>a.tokenId===t.id));o&&r.push("token-variants-combat"),game.combat?.started&&(game.combat?.combatant?.token?.id===t.id?r.push("combat-turn"):game.combat?.nextCombatant?.token?.id===t.id&&r.push("combat-turn-next")),n.hidden&&r.push("token-variants-visibility"),$9IngI.TVA_CONFIG.internalEffects.hpChange.enabled&&getHPChangeEffect(n,r),n.actorLink?getEffectsFromActor(t.actor,r):"pf2e"===game.system.id?(n.delta?.items||[]).forEach(t=>{_activePF2EItem(t)&&r.push(t.name)}):((n.effects||[]).filter(t=>!t.disabled&&!t.isSuppressed).forEach(t=>r.push(t.label)),getEffectsFromActor(t.actor,r)),// Expression/Mapping effects
|
|
evaluateComparatorEffects(t,r),evaluateStateEffects(t,r);// Include mappings marked as always applicable
|
|
// as well as the ones defined as logical expressions if needed
|
|
let s=getAllEffectMappings(t);for(let o of s)if(!o.tokens?.length||o.tokens.includes(n.id)){if(o.alwaysOn)r.unshift(o.id);else if(a){let a=evaluateMappingExpression(o,r,t);a&&r.unshift(o.id)}}return r}function getEffectsFromActor(t,a=[]){return t&&("pf2e"===game.system.id?(t.items||[]).forEach((t,n)=>{_activePF2EItem(t)&&a.push(t.name)}):((t.effects||[]).forEach((t,n)=>{t.disabled||t.isSuppressed||a.push(t.name??t.label)}),(t.items||[]).forEach(t=>{ITEM_TYPES.includes(t.type)&&t.system.equipped&&a.push(t.name??t.label)}))),a}function _activePF2EItem(t){return!!PF2E_ITEM_TYPES.includes(t.type)&&("active"in t?t.active:!("isEquipped"in t)||t.isEquipped)}let VALID_EXPRESSION=RegExp('([a-zA-Z\\-\\.\\+]+)([><=]+)(".*"|-?\\d+)(%{0,1})');function evaluateComparator(t,a){let n=a.match(VALID_EXPRESSION);if(n){let a,r;let o=n[1];"hp"===o?[a,r]=getTokenHP(t):"hp++"===o||"hp--"===o?([a,r]=getTokenHP(t),a=getProperty(t,`actor.flags.token-variants.internalEffects.${o}`)??0):a=getProperty(t,o),null==a&&(a=0);let s=n[2],l=Number(n[3]);isNaN(l)&&("true"===(l=n[3].substring(1,n[3].length-1))&&(l=!0),"false"===l&&(l=!1),(!0===l||!1===l)&&(a=!isEmpty(a)&&!!a));let c=!!n[4];"rotation"===o?r=360:null==r&&(r=999999);let p=c?a/r*100:a,f=!1;return"="===s?f=p==l:">"===s?f=p>l:"<"===s?f=p<l:">="===s?f=p>=l:"<="===s?f=p<=l:"<>"===s&&(f=p<l||p>l),f}return!1}function evaluateComparatorEffects(t,a=[]){t=t.document??t;let n=getAllEffectMappings(t),r=new Set;for(let a of n){let n=a.expression.split(EXPRESSION_MATCH_RE).filter(Boolean).map(t=>t.trim()).filter(Boolean);for(let a=0;a<n.length;a++)evaluateComparator(t,n[a])&&r.add(n[a])}return(// Remove duplicate expressions and insert into effects
|
|
r.forEach(t=>a.unshift(t)),a)}function evaluateStateEffects(t,a){if("pf2e"===game.system.id){let n=game.settings.get("pf2e","deathIcon");(t.document??t).overlayEffect===n&&a.push("Dead")}}/**
|
|
* Replaces {1,a,5,b} type string in the expressions with (1|a|5|b)
|
|
* @param {*} exp
|
|
* @returns
|
|
*/function _findReplaceBracketWildcard(t){let a="",n=0;for(;n>=0;){let r=t.indexOf("\\\\\\{",n);if(-1===r)return a+t.substring(n,t.length);{let o=t.indexOf("\\\\\\}",r);-1!==o&&(a+=t.substring(n,r)+"("+t.substring(r+4,o).split(",").join("|")+")"),n=o+4}}return a??t}function _testRegExEffect(t,a){let n=t.replace(/[/\-\\^$+?.()|[\]{}]/g,"\\$&").replaceAll("\\\\*",".*");return n=RegExp("^"+(n=_findReplaceBracketWildcard(n))+"$"),a.find(t=>n.test(t))}function evaluateMappingExpression(mapping,effects,token,added=new Set,removed=new Set){let arrExpression=mapping.expression.split(EXPRESSION_MATCH_RE).filter(Boolean).map(t=>t.trim()).filter(Boolean),temp="",hasAdded=!1,hasRemoved=!1;for(let exp of arrExpression){if((0,$eeGZt.EXPRESSION_OPERATORS).includes(exp)){temp+=exp.replace("\\","");continue}if(/\\\*|\\{.*\\}/g.test(exp)){_testRegExEffect(exp,effects)?temp+="true":temp+="false",_testRegExEffect(exp,added)?hasAdded=!0:_testRegExEffect(exp,removed)&&(hasRemoved=!0);continue}effects.includes(exp)?temp+="true":temp+="false",!hasAdded&&added.has(exp)&&(hasAdded=!0),!hasRemoved&&removed.has(exp)&&(hasRemoved=!0)}try{let evaluation=eval(temp);// Evaluate JS code
|
|
if(mapping.codeExp)try{token=token.document??token,eval(mapping.codeExp)?mapping.expression||(evaluation=!0):evaluation=!1}catch(e){evaluation=!1}return evaluation?hasAdded||hasRemoved?(added.add(mapping.id),effects.push(mapping.id)):effects.unshift(mapping.id):(hasRemoved||hasAdded)&&removed.add(mapping.id),evaluation}catch(e){}return!1}function _getTokenHPv11(t){let a;return a=t.actorLink?getProperty(t.actor?.system,$9IngI.TVA_CONFIG.systemHpPath):mergeObject(getProperty(t.actor?.system,$9IngI.TVA_CONFIG.systemHpPath)||{},getProperty(t.delta?.system)||{},{inplace:!1}),[a?.value,a?.max]}function getTokenHP(t){let a;return isNewerVersion("11",game.version)?(a=t.actorLink?getProperty(t.actor.system,$9IngI.TVA_CONFIG.systemHpPath):mergeObject(getProperty(t.actor.system,$9IngI.TVA_CONFIG.systemHpPath)||{},getProperty(t.actorData?.system)||{},{inplace:!1}),[a?.value,a?.max]):_getTokenHPv11(t)}async function _updateImageOnEffectChange(t,a,n=!0){let r=a.token?[a.token]:(0,$eeGZt.getAllActorTokens)(a,!0,!$9IngI.TVA_CONFIG.mappingsCurrentSceneOnly);for(let a of r)await updateWithEffectMapping(a,{added:n?[t]:[],removed:n?[]:[t]})}async function _updateImageOnMultiEffectChange(t,a=[],n=[]){if(!t)return;let r=t.token?[t.token]:(0,$eeGZt.getAllActorTokens)(t,!0,!$9IngI.TVA_CONFIG.mappingsCurrentSceneOnly);for(let t of r)await updateWithEffectMapping(t,{added:a,removed:n})}async function _deleteCombatant(t){let a=t._token||canvas.tokens.get(t.tokenId);a&&a.actor&&await updateWithEffectMapping(a,{removed:["token-variants-combat"]})}}),parcelRequire.register("9IngI",function(t,a){$parcel$export(t.exports,"TVA_CONFIG",()=>g),$parcel$export(t.exports,"FEATURE_CONTROL",()=>h),$parcel$export(t.exports,"registerSettings",()=>u),$parcel$export(t.exports,"migrateMappings",()=>m),$parcel$export(t.exports,"updateSettings",()=>O),$parcel$export(t.exports,"getFlagMappings",()=>y),$parcel$export(t.exports,"exportSettingsToJSON",()=>v),$parcel$export(t.exports,"importSettingsFromJSON",()=>k),$parcel$export(t.exports,"getSearchOptions",()=>w);var n=parcelRequire("eeGZt"),r=parcelRequire("bhyh6"),o=parcelRequire("3pmR9"),s=parcelRequire("dxtrh"),l=parcelRequire("aDMsz"),c=parcelRequire("fVv34"),p=parcelRequire("8MWlo"),f=parcelRequire("e9LRe"),d=parcelRequire("3pMx9");let g={debug:!1,disableNotifs:!1,searchPaths:[{text:"modules/caeora-maps-tokens-assets/assets/tokens",cache:!0,source:"undefined"==typeof ForgeAPI?"data":"forge-bazaar",types:["Portrait","Token","PortraitAndToken"]}],forgeSearchPaths:{},worldHud:{displayOnlySharedImages:!1,disableIfTHWEnabled:!1,includeKeywords:!1,updateActorImage:!1,useNameSimilarity:!1,includeWildcard:!0,showFullPath:!1,animate:!0},hud:{enableSideMenu:!0,displayAsImage:!0,imageOpacity:50},keywordSearch:!0,excludedKeywords:"and,for",runSearchOnPath:!1,searchFilters:{},algorithm:{exact:!1,fuzzy:!0,fuzzyLimit:100,fuzzyThreshold:.3,fuzzyArtSelectPercentSlider:!0},tokenConfigs:[],randomizer:{actorCreate:!1,tokenCreate:!1,tokenCopyPaste:!1,tokenName:!0,keywords:!1,shared:!1,wildcard:!1,representedActorDisable:!1,linkedActorDisable:!0,popupOnDisable:!1,diffImages:!1,syncImages:!1},popup:{disableAutoPopupOnActorCreate:!0,disableAutoPopupOnTokenCreate:!0,disableAutoPopupOnTokenCopyPaste:!0,twoPopups:!1,twoPopupsNoDialog:!1},imgurClientId:"",stackStatusConfig:!0,mergeGroup:!1,staticCache:!1,staticCacheFile:"modules/token-variants/token-variants-cache.json",tilesEnabled:!0,compendiumMapper:{missingOnly:!1,diffImages:!1,showImages:!0,cache:!1,autoDisplayArtSelect:!0,syncImages:!1,overrideCategory:!1,category:"Token",missingImages:[{document:"all",image:CONST.DEFAULT_TOKEN}],searchOptions:{}},permissions:{popups:{1:!1,2:!1,3:!0,4:!0},portrait_right_click:{1:!1,2:!1,3:!0,4:!0},image_path_button:{1:!1,2:!1,3:!0,4:!0},hud:{1:!0,2:!0,3:!0,4:!0},hudFullAccess:{1:!1,2:!1,3:!0,4:!0},statusConfig:{1:!1,2:!1,3:!0,4:!0}},globalMappings:[],templateMappings:[],customImageCategories:[],displayEffectIconsOnHover:!1,disableEffectIcons:!1,filterEffectIcons:!1,filterCustomEffectIcons:!0,filterIconList:[],updateTokenProto:!1,imgNameContainsDimensions:!1,imgNameContainsFADimensions:!1,playVideoOnHover:!0,pauseVideoOnHoverOut:!1,disableImageChangeOnPolymorphed:!1,disableImageUpdateOnNonPrototype:!1,disableTokenUpdateAnimation:!1,mappingsCurrentSceneOnly:!1,invisibleImage:"",systemHpPath:"",internalEffects:{hpChange:{enabled:!1,duration:null}},hideElevationTooltip:!1,hideTokenBorder:!1},h={EffectMappings:!0,EffectIcons:!0,Overlays:!0,UserMappings:!0,Wildcards:!0,PopUpAndRandomize:!0,HUD:!0,HideElement:!0};function u(){game.settings.register("token-variants","featureControl",{scope:"world",config:!1,type:Object,default:h,onChange:async t=>{mergeObject(h,t),(0,f.registerAllHooks)(),(0,d.registerAllWrappers)()}}),mergeObject(h,game.settings.get("token-variants","featureControl")),game.settings.registerMenu("token-variants","settings",{name:"Configure Settings",hint:"Configure Token Variant Art settings",label:"Settings",scope:"world",icon:"fas fa-cog",type:c.default,restricted:!0});let t={"cyberpunk-red-core":"derivedStats.hp",lfg:"health",worldbuilding:"health",twodsix:"hits"};g.systemHpPath=t[game.system.id]??"attributes.hp",game.settings.register("token-variants","effectMappingToggleGroups",{scope:"world",config:!1,type:Object,default:{Default:!0}}),game.settings.register("token-variants","settings",{scope:"world",config:!1,type:Object,default:g,onChange:async t=>{// Generate a diff, it will be required when doing post-processing of the modified settings
|
|
let a=T(g,t),r=!1;if("permissions"in a&&!(0,n.userRequiresImageCache)(g.permissions)&&(0,n.userRequiresImageCache)(t.permissions)&&(r=!0),// Update live settings
|
|
mergeObject(g,t),g.filterEffectIcons&&("filterCustomEffectIcons"in a||"filterIconList"in a))for(let t of canvas.tokens.placeables)(0,n.waitForTokenTexture)(t,t=>{t.drawEffects()});if(("searchPaths"in a||"forgeSearchPaths"in a)&&(0,n.userRequiresImageCache)(g.permissions)&&(r=!0),r&&await (0,p.cacheImages)(),a.staticCache){let t=a.staticCacheFile?a.staticCacheFile:g.staticCacheFile;(0,p.saveCache)(t)}if(g.hud=game.settings.get("token-variants","hudSettings"),(0,f.registerAllHooks)(),(0,d.registerAllWrappers)(),"displayEffectIconsOnHover"in a)for(let t of canvas.tokens.placeables)t.effects&&(t.effects.visible=!a.displayEffectIconsOnHover);if("hideElevationTooltip"in a)for(let t of canvas.tokens.placeables)t.tooltip&&(t.tooltip.text=t._getTooltipText());if("hideTokenBorder"in a)for(let t of canvas.tokens.placeables)t.border&&(t.border.visible=!a.hideTokenBorder);if("filterEffectIcons"in a||"disableEffectIcons"in a)for(let t of canvas.tokens.placeables)t.drawEffects()}}),game.settings.register("token-variants","debug",{scope:"world",config:!1,type:Boolean,default:g.debug,onChange:t=>g.debug=t}),"undefined"!=typeof ForgeAPI&&game.settings.registerMenu("token-variants","forgeSearchPaths",{name:game.i18n.localize("token-variants.settings.forge-search-paths.Name"),hint:game.i18n.localize("token-variants.settings.forge-search-paths.Hint"),icon:"fas fa-search",type:r.ForgeSearchPaths,scope:"client",restricted:!1}),game.settings.register("token-variants","tokenConfigs",{scope:"world",config:!1,type:Array,default:g.tokenConfigs,onChange:t=>g.tokenConfigs=t}),game.settings.registerMenu("token-variants","tokenHUDSettings",{name:game.i18n.localize("token-variants.settings.token-hud.Name"),hint:game.i18n.localize("token-variants.settings.token-hud.Hint"),scope:"client",icon:"fas fa-images",type:o.default,restricted:!1}),game.settings.registerMenu("token-variants","compendiumMapper",{name:game.i18n.localize("token-variants.settings.compendium-mapper.Name"),hint:game.i18n.localize("token-variants.settings.compendium-mapper.Hint"),scope:"world",icon:"fas fa-cogs",type:s.default,restricted:!0}),game.settings.register("token-variants","compendiumMapper",{scope:"world",config:!1,type:Object,default:g.compendiumMapper,onChange:t=>g.compendiumMapper=t}),game.settings.register("token-variants","hudSettings",{scope:"client",config:!1,type:Object,default:g.hud,onChange:t=>g.hud=t}),game.settings.registerMenu("token-variants","importExport",{name:"Import/Export",hint:game.i18n.localize("token-variants.settings.import-export.Hint"),scope:"world",icon:"fas fa-toolbox",type:l.default,restricted:!0});// Read settings
|
|
let a=game.settings.get("token-variants","settings");for(let t in mergeObject(g,a),isEmpty(g.searchFilters)&&(0,n.BASE_IMAGE_CATEGORIES).forEach(t=>{g.searchFilters[t]={include:"",exclude:"",regex:""}}),g.forgeSearchPaths)g.forgeSearchPaths[t].paths=g.forgeSearchPaths[t].paths.map(t=>(t.source||(t.source="forgevtt"),t.types||(t.tiles?t.types=["Tile"]:t.types=["Portrait","Token","PortraitAndToken"]),t));"Object"===getType(a.globalMappings)&&Hooks.once("ready",()=>{g.globalMappings=m(a.globalMappings),setTimeout(()=>O({globalMappings:g.globalMappings}),1e4)}),// Read client settings
|
|
g.hud=game.settings.get("token-variants","hudSettings")}function m(t,a=[]){if(!t)return[];if("Object"===getType(t)){let n=[];for(let[a,r]of Object.entries(t))r.label||(r.label=a.replaceAll("\xb6",".")),r.expression||(r.expression=a.replaceAll("\xb6",".")),r.id||(r.id=randomID(8)),delete r.effect,r.overlayConfig&&(r.overlayConfig.id=r.id),delete r.overlayConfig?.effect,n.push(r);// Convert parents to parentIDs
|
|
let r=n.concat(a);for(let t of n)if(t.overlayConfig?.parent){if("Token (Placeable)"===t.overlayConfig.parent)t.overlayConfig.parentID="TOKEN";else{let a=r.find(a=>a.label===t.overlayConfig.parent);a?t.overlayConfig.parentID=a.id:t.overlayConfig.parentID=""}delete t.overlayConfig.parent}return n}return t}function y(t){if(!t)return[];let a=t.document??t,n=a.actor?.id;if(n&&!(a=game.actors.get(n)))return[];// 23/07/2023
|
|
let r=a.getFlag("token-variants","effectMappings")??[];return"Object"===getType(r)&&(r=m(r,g.globalMappings),a.setFlag("token-variants","effectMappings",r)),r}function v(){let t=deepClone(g),a="token-variants-settings.json";saveDataToFile(JSON.stringify(t,null,2),"text/json",a)}async function k(t){if("string"==typeof t&&(t=JSON.parse(t)),t.forgeSearchPaths)for(let a in t.forgeSearchPaths)t.forgeSearchPaths[a].paths=t.forgeSearchPaths[a].paths.map(t=>(t.source||(t.source="forgevtt"),t.types||(t.tiles?t.types=["Tile"]:t.types=["Portrait","Token","PortraitAndToken"]),t));// 09/07/2022 Convert filters to new format if old one is still in use
|
|
if(t.searchFilters&&null!=t.searchFilters.portraitFilterInclude){let a=t.searchFilters;t.searchFilters={Portrait:{include:a.portraitFilterInclude??"",exclude:a.portraitFilterExclude??"",regex:a.portraitFilterRegex??""},Token:{include:a.tokenFilterInclude??"",exclude:a.tokenFilterExclude??"",regex:a.tokenFilterRegex??""},PortraitAndToken:{include:a.generalFilterInclude??"",exclude:a.generalFilterExclude??"",regex:a.generalFilterRegex??""}},t.compendiumMapper&&delete t.compendiumMapper.searchFilters}// Global Mappings need special merge
|
|
if(t.globalMappings){let a=m(t.globalMappings);for(let t of a){let a=g.globalMappings.findIndex(a=>t.label===a.label);-1===a?g.globalMappings.push(t):g.globalMappings[a]=t}t.globalMappings=g.globalMappings}O(t)}function b(t,a,r=!1){let o=(0,n.BASE_IMAGE_CATEGORIES).concat(a??g.customImageCategories);for(let a in t)!o.includes(a)&&(delete t[a],r&&delete g.searchFilters[a]);for(let n of a)null==t[n]&&(t[n]={include:"",exclude:"",regex:""})}async function O(t){let a=mergeObject(deepClone(g),t,{insertKeys:!1});"customImageCategories"in t&&(b(a.searchFilters,t.customImageCategories,!0),a.compendiumMapper?.searchOptions?.searchFilters!=null&&(b(a.compendiumMapper.searchOptions.searchFilters,t.customImageCategories),g.compendiumMapper.searchOptions.searchFilters=a.compendiumMapper.searchOptions.searchFilters)),await game.settings.set("token-variants","settings",a)}function T(t,a,{inner:n=!1}={}){function r(t,a){let r=getType(t);if(r!==getType(a))return[!0,a];if("Array"===r)return[!x(t,a),a];if("Object"===r){if(isEmpty(t)!==isEmpty(a))return[!0,a];let r=T(t,a,{inner:n});return[!isEmpty(r),r]}return[t!==a,a]}// Recursively call the _difference function
|
|
return Object.keys(a).reduce((o,s)=>{if(n&&!(s in t))return o;let[l,c]=r(t[s],a[s]);return l&&(o[s]=c),o},{})}function x(t,a){return a instanceof Array&&a.length===t.length&&t.every((t,n)=>"Object"===getType(t)?0===Object.keys(T(t,a[n])).length:a[n]===t)}function w(){return{keywordSearch:g.keywordSearch,excludedKeywords:g.excludedKeywords,runSearchOnPath:g.runSearchOnPath,algorithm:g.algorithm,searchFilters:g.searchFilters}}}),parcelRequire.register("eeGZt",function(t,a){$parcel$export(t.exports,"EXPRESSION_OPERATORS",()=>p),$parcel$export(t.exports,"SEARCH_TYPE",()=>f),$parcel$export(t.exports,"BASE_IMAGE_CATEGORIES",()=>d),$parcel$export(t.exports,"startBatchUpdater",()=>u),$parcel$export(t.exports,"updateTokenImage",()=>v),$parcel$export(t.exports,"getFileName",()=>C),$parcel$export(t.exports,"updateActorImage",()=>k),$parcel$export(t.exports,"keyPressed",()=>O),$parcel$export(t.exports,"registerKeybinds",()=>T),$parcel$export(t.exports,"getTokenConfig",()=>x),$parcel$export(t.exports,"setTokenConfig",()=>S),$parcel$export(t.exports,"decodeURISafely",()=>en),$parcel$export(t.exports,"getFileNameWithExt",()=>I),$parcel$export(t.exports,"getFilePath",()=>F),$parcel$export(t.exports,"simplifyName",()=>A),$parcel$export(t.exports,"simplifyPath",()=>E),$parcel$export(t.exports,"decodeURIComponentSafely",()=>er),$parcel$export(t.exports,"parseKeywords",()=>N),$parcel$export(t.exports,"isImage",()=>P),$parcel$export(t.exports,"isVideo",()=>_),$parcel$export(t.exports,"callForgeVTT",()=>R),$parcel$export(t.exports,"getFilters",()=>D),$parcel$export(t.exports,"userRequiresImageCache",()=>M),$parcel$export(t.exports,"waitForTokenTexture",()=>H),$parcel$export(t.exports,"flattenSearchResults",()=>j),$parcel$export(t.exports,"tv_executeScript",()=>X),$parcel$export(t.exports,"executeMacro",()=>z),$parcel$export(t.exports,"applyTMFXPreset",()=>L),$parcel$export(t.exports,"toggleTMFXPreset",()=>U),$parcel$export(t.exports,"applyCEEffect",()=>B),$parcel$export(t.exports,"toggleCEEffect",()=>W),$parcel$export(t.exports,"determineAddedRemovedEffects",()=>q),$parcel$export(t.exports,"nameForgeRandomize",()=>Z),$parcel$export(t.exports,"uploadTokenImage",()=>Q),$parcel$export(t.exports,"getAllActorTokens",()=>et),$parcel$export(t.exports,"string2Hex",()=>ea),$parcel$export(t.exports,"mergeMappings",()=>eo);var n=parcelRequire("9IngI"),r=parcelRequire("coMHP"),o=parcelRequire("eYkM9"),s=parcelRequire("dxtrh"),l=parcelRequire("cs88A");let c=new RegExp(/[^A-Za-z0-9/\\]/g),p=["\\(","\\)","&&","||","\\!"],f={PORTRAIT:"Portrait",TOKEN:"Token",PORTRAIT_AND_TOKEN:"PortraitAndToken",TILE:"Tile",ITEM:"Item",JOURNAL:"JournalEntry",MACRO:"Macro"},d=["Portrait","Token","PortraitAndToken","Tile","Item","JournalEntry","Macro","RollTable"],g={popupOverride:!1,config:!1},h={TOKEN:[],TOKEN_CALLBACKS:[],TOKEN_CONTEXT:{animate:!0},ACTOR:[],ACTOR_CONTEXT:null};function u(){canvas.app.ticker.add(()=>{h.TOKEN.length&&(canvas.scene.updateEmbeddedDocuments("Token",h.TOKEN,h.TOKEN_CONTEXT).then(()=>{for(let t of h.TOKEN_CALLBACKS)t();h.TOKEN_CALLBACKS=[]}),h.TOKEN=[]),0!==h.ACTOR.length&&(h.ACTOR_CONTEXT?Actor.updateDocuments(h.ACTOR,h.ACTOR_CONTEXT):Actor.updateDocuments(h.ACTOR),h.ACTOR=[],h.ACTOR_CONTEXT=null)})}function m(t,a,n=null,r=!0){a._id=t,h.TOKEN.push(a),h.TOKEN_CONTEXT={animate:r},n&&h.TOKEN_CALLBACKS.push(n)}function y(t,a,n=null){a._id=t,h.ACTOR.push(a),h.ACTOR_CONTEXT=n}async function v(t,{token:a=null,actor:r=null,imgName:o=null,tokenUpdate:s={},actorUpdate:l={},pack:c="",callback:p=null,config:f,animate:d=!0,update:g=null,applyDefaultConfig:h=!0}={}){if(!(a||r)){console.warn(game.i18n.localize("token-variants.notifications.warn.update-image-no-token-actor"));return}// Check if it's a wildcard image
|
|
if(a=a?.document??a,t&&t.includes("*")||t.includes("{")&&t.includes("}")){let a=await J(t);a.length&&(t=a[Math.floor(Math.random()*a.length)])}!r&&a.actor&&(r=game.actors.get(a.actor.id));let u=(t,a)=>{let n=[];if(t)n=t.getFlag("token-variants","defaultConfig")||[];else if(a){let t=a.prototypeToken;"token-variants"in t.flags&&"defaultConfig"in t["token-variants"]&&(n=t["token-variants"].defaultConfig)}return expandObject(Object.fromEntries(n))},v=(t,a)=>{let n=flattenObject(t);K.dataToForm(n);let r=flattenObject(a),o=filterObject(n,r);// Flags need special treatment as once set they are not removed via absence of them in the update
|
|
for(let[t,a]of Object.entries(r))if(t.startsWith("flags.")&&!(t in n)){let a=t.split(".");a[a.length-1]="-="+a[a.length-1],o[a.join(".")]=null}return Object.entries(o)},k=s;t&&(setProperty(k,"texture.src",t),o&&C(t)===o?setProperty(k,"flags.token-variants.-=name",null):setProperty(k,"flags.token-variants.name",o));let b=mergeObject(w(t||a?.texture.src,o,a),f??{}),O=a?.getFlag("token-variants","usingCustomConfig"),T=u(a);if((!isEmpty(b)||O)&&(k=V(k,T)),isEmpty(b))O&&(setProperty(k,"flags.token-variants.-=usingCustomConfig",null),delete k?.flags?.["token-variants"]?.defaultConfig,setProperty(k,"flags.token-variants.-=defaultConfig",null));else{if(a){setProperty(k,"flags.token-variants.usingCustomConfig",!0);let t=a.document??a,n=t.toObject?t.toObject():deepClone(t),r=v(mergeObject(n,T),b);setProperty(k,"flags.token-variants.defaultConfig",r)}else if(r&&!a){setProperty(k,"flags.token-variants.usingCustomConfig",!0);let t=r.prototypeToken instanceof Object?r.prototypeToken:r.prototypeToken.toObject(),a=v(t,b);setProperty(k,"flags.token-variants.defaultConfig",a)}b.flags||delete b.flags,k=V(k,b)}h||(setProperty(k,"flags.token-variants.-=usingCustomConfig",null),delete k?.flags?.["token-variants"]?.defaultConfig,setProperty(k,"flags.token-variants.-=defaultConfig",null)),!isEmpty(k)&&(r&&!a&&(K.formToData(r.prototypeToken,k),l.token=k,c?y(r.id,l,{pack:c}):await (r.document??r).update(l)),a&&(K.formToData(a,k),n.TVA_CONFIG.updateTokenProto&&a.actor&&(g?mergeObject(g,{token:k}):a.actorLink?setTimeout(()=>y(a.actor.id,{token:k}),500):setTimeout(()=>a.actor.update({token:k}),500)),g?mergeObject(g,k):a.object?m(a.id,k,p,d):(await a.update(k,{animate:d}),p())))}async function k(t,a,n=!0,r=""){t&&(n?await (t.document??t).update({img:a}):y(t.id,{img:a},r?{pack:r}:null))}async function b(){for(let t of canvas.tiles.controlled){let a=t.document.getFlag("token-variants","tileName")||t.id;(0,r.showArtSelect)(a,{callback:async function(a,n){t.document.update({img:a})},searchType:f.TILE})}}function O(t){return"v"===t?game.keyboard.downKeys.has("KeyV"):g[t]}function T(){game.keybindings.register("token-variants","popupOverride",{name:"Popup Override",hint:"When held will trigger popups even when they are disabled.",editable:[{key:"ShiftLeft"}],onDown:()=>{g.popupOverride=!0},onUp:()=>{g.popupOverride=!1},restricted:!1,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","config",{name:"Config",hint:"When held during a mouse Left-Click of an Image or an Active Affect will display a configuration window.",editable:[{key:"ShiftLeft"}],onDown:()=>{g.config=!0},onUp:()=>{g.config=!1},restricted:!1,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","showArtSelectPortrait",{name:"Show Art Select: Portrait",hint:"Brings up an Art Select pop-up to change the portrait images of the selected tokens.",editable:[{key:"Digit1",modifiers:["Shift"]}],onDown:()=>{for(let t of canvas.tokens.controlled){let a=t.actor;a&&(0,r.showArtSelect)(a.name,{callback:async function(t,n){await k(a,t)},searchType:f.PORTRAIT,object:a})}n.TVA_CONFIG.tilesEnabled&&0===canvas.tokens.controlled.length&&b()},restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","showArtSelectToken",{name:"Show Art Select: Token",hint:"Brings up an Art Select pop-up to change the token images of the selected tokens.",editable:[{key:"Digit2",modifiers:["Shift"]}],onDown:()=>{for(let t of canvas.tokens.controlled)(0,r.showArtSelect)(t.name,{callback:async function(a,n){v(a,{actor:t.actor,imgName:n,token:t})},searchType:f.TOKEN,object:t});n.TVA_CONFIG.tilesEnabled&&0===canvas.tokens.controlled.length&&b()},restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","showArtSelectGeneral",{name:"Show Art Select: Portrait+Token",hint:"Brings up an Art Select pop-up to change both Portrait and Token images of the selected tokens.",editable:[{key:"Digit3",modifiers:["Shift"]}],onDown:()=>{for(let t of canvas.tokens.controlled){let a=t.actor;(0,r.showArtSelect)(t.name,{callback:async function(n,r){a&&await k(a,n),v(n,{actor:t.actor,imgName:r,token:t})},searchType:f.PORTRAIT_AND_TOKEN,object:t})}n.TVA_CONFIG.tilesEnabled&&0===canvas.tokens.controlled.length&&b()},restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","openGlobalMappings",{name:"Open Global Effect Configurations",hint:"Brings up the settings window for Global Effect Configurations",editable:[{key:"KeyG",modifiers:["Shift"]}],onDown:()=>{let t=game.settings.get("core",DefaultTokenConfig.SETTING),a=new foundry.data.PrototypeToken(t),n=new TokenDocument(a,{actor:null});new(0,o.default)(n,{globalMappings:!0}).render(!0)},restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","compendiumMapper",{name:"Compendium Mapper",hint:"Opens Compendium Mapper",editable:[{key:"KeyM",modifiers:["Shift"]}],onDown:()=>{new(0,s.default)().render(!0)},restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL}),game.keybindings.register("token-variants","toggleTemplate",{name:"Toggle Template Dialog",hint:"Brings up a dialog from which you can toggle templates on currently selected tokens.",editable:[],onDown:l.toggleTemplateDialog,restricted:!0,precedence:CONST.KEYBINDING_PRECEDENCE.NORMAL})}function x(t,a){a||(a=C(t));let r=((0,n.TVA_CONFIG).tokenConfigs||[]).flat();return r.find(n=>n.tvImgSrc==t&&n.tvImgName==a)??{}}function w(t,a,r){if(!t)return{};let o={};for(let a of n.TVA_CONFIG.searchPaths)a.config&&t.startsWith(a.text)&&mergeObject(o,a.config);let s=x(t,a??C(t));if(!isEmpty(s))for(var l in s=deepClone(s),delete s.tvImgSrc,delete s.tvImgName,r&&K.formToData(r,s),s)l.startsWith("tvTab_")||(o[l]=s[l]);return(n.TVA_CONFIG.imgNameContainsDimensions||n.TVA_CONFIG.imgNameContainsFADimensions)&&ei(t,o),o}function S(t,a,r){let o=((0,n.TVA_CONFIG).tokenConfigs||[]).flat(),s=o.findIndex(n=>n.tvImgSrc==t&&n.tvImgName==a),l=!r||0===Object.keys(r).length;return l||(r.tvImgSrc=t,r.tvImgName=a),-1==s||l?-1!=s&&l?o.splice(s,1):l||o.push(r):o[s]=r,(0,n.updateSettings)({tokenConfigs:o}),!l}function C(t){return t?en(t).split("\\").pop().split("/").pop().split(".").slice(0,-1).join("."):""}function I(t){return t?en(t).split("\\").pop().split("/").pop():""}function F(t){return en(t).match(/(.*)[\/\\]/)[1]||""}function A(t){return t.replace(c,"").toLowerCase()}function E(t){return er(t).replace(c,"").toLowerCase()}function N(t){return t.split(/\W/).map(t=>A(t)).filter(t=>""!=t)}function P(t){var a=t.split(".");return["jpg","jpeg","png","svg","webp","gif"].includes(a=a[a.length-1].toLowerCase())}function _(t){var a=t.split(".");return["mp4","ogg","webm","m4v"].includes(a=a[a.length-1].toLowerCase())}async function R(t,a){return new Promise(async(n,r)=>{if("undefined"==typeof ForgeVTT||!ForgeVTT.usingTheForge)return n({});let o=`${ForgeVTT.FORGE_URL}/api/assets/browse`,s=new XMLHttpRequest;s.withCredentials=!0,s.open("POST",o),s.setRequestHeader("Access-Key",a),s.setRequestHeader("X-XSRF-TOKEN",await ForgeAPI.getXSRFToken()),s.responseType="json",s.onreadystatechange=()=>{4===s.readyState&&n(s.response)},s.onerror=t=>{n({code:500,error:t.message})};let l={path:t,options:{recursive:!0}};l=JSON.stringify(l),s.setRequestHeader("Content-type","application/json; charset=utf-8"),s.send(l)})}function D(t,a){return(a=// Select filters based on type of search
|
|
(a=a||n.TVA_CONFIG.searchFilters)[t]?a[t]:{include:"",exclude:"",regex:""}).regex&&(a.regex=new RegExp(a.regex)),a}function M(t){let a=t||n.TVA_CONFIG.permissions,r=game.user.role;return a.popups[r]||a.portrait_right_click[r]||a.image_path_button[r]||a.hudFullAccess[r]}async function H(t,a,n=40){// v10/v9 compatibility
|
|
if(!t.mesh||!t.mesh.texture){--n>1&&new Promise(t=>setTimeout(t,1)).then(()=>H(t,a,n));return}a(t)}function j(t){let a=[];return t&&t.forEach(t=>{a=a.concat(t)}),a}function V(t,a={},{insertKeys:n=!0,insertValues:r=!0,overwrite:o=!0,recursive:s=!0,inplace:l=!0,enforceTypes:c=!1}={},p=0){if(a=a||{},!(t instanceof Object)||!(a instanceof Object))throw Error("One of original or other are not Objects!");let f={insertKeys:n,insertValues:r,overwrite:o,recursive:s,inplace:l,enforceTypes:c};// Iterate over the other object
|
|
for(let n of(0===p&&(l||(t=deepClone(t)),Object.keys(t).some(t=>/\./.test(t))&&(t=expandObject(t)),Object.keys(a).some(t=>/\./.test(t))&&(a=expandObject(a))),Object.keys(a))){let r=a[n];t.hasOwnProperty("-="+n)&&(t[n]=t["-="+n],delete t["-="+n]),t.hasOwnProperty(n)?Y(t,n,r,f,p+1):G(t,n,r,f,p+1)}return t}/**
|
|
* A helper function for merging objects when the target key does not exist in the original
|
|
* @private
|
|
*/function G(t,a,n,{insertKeys:r,insertValues:o}={},s){// Recursively create simple objects
|
|
if(n?.constructor===Object){t[a]=V({},n,{insertKeys:!0,inplace:!0});return}// Delete a key
|
|
// if (k.startsWith('-=')) {
|
|
// delete original[k.slice(2)];
|
|
// return;
|
|
// }
|
|
// Insert a key
|
|
let l=s<=1&&r||s>1&&o;l&&(t[a]=n)}/**
|
|
* A helper function for merging objects when the target key exists in the original
|
|
* @private
|
|
*/function Y(t,a,n,{insertKeys:r,insertValues:o,enforceTypes:s,overwrite:l,recursive:c}={},p){let f=t[a],d=getType(n),g=getType(f);// Recursively merge an inner object
|
|
if("Object"===d&&"Object"===g&&c)return V(f,n,{insertKeys:r,insertValues:o,overwrite:l,inplace:!0,enforceTypes:s},p);// Overwrite an existing value
|
|
if(l){if("undefined"!==g&&d!==g&&s)throw Error("Mismatched data types encountered during object merge.");t[a]=n}}async function X(t,{actor:a,token:n,tvaUpdate:r}={}){// Add variables to the evaluation scope
|
|
let o=ChatMessage.getSpeaker(),s=game.user.character;n=n?.object||n||(canvas.ready?canvas.tokens.get(o.token):null),a=a||n?.actor||game.actors.get(o.actor);// Attempt script execution
|
|
let l=(async function(){}).constructor;try{let c=l("speaker","actor","token","character","tvaUpdate",`${t}`);await c.call(null,o,a,n,s,r)}catch(t){ui.notifications.error("There was an error in your script syntax. See the console (F12) for details"),console.error(t)}}async function z(t,a){a=a?.object||a,game.macros.find(a=>a.name===t)?.execute({token:a})}async function L(t,a,n="apply"){if(t=t.object??t,game.modules.get("tokenmagic")?.active&&t.document){let r=TokenMagic.getPreset(a);r&&("apply"===n?await TokenMagic.addUpdateFilters(t,r):"remove"===n&&await TokenMagic.deleteFilters(t,a))}}async function U(t,a){t=t.object??t,game.modules.get("tokenmagic")?.active&&t.document&&(TokenMagic.hasFilterId(t,a)?L(t,a,"remove"):L(t,a,"apply"))}async function B(t,a,n="apply"){if(game.modules.get("dfreds-convenient-effects")?.active){if(!a.apply&&!a.remove)return;if(!a.apply||!a.remove){if("apply"!==n)return;a.remove&&(n="remove")}let r=t.actor?.uuid;r&&("apply"===n?await game.dfreds.effectInterface.addEffect({effectName:a.name,uuid:r,origin:"token-variants",overlay:!1}):await game.dfreds.effectInterface.removeEffect({effectName:a.name,uuid:r}))}}async function W(t,a){if(game.modules.get("dfreds-convenient-effects")?.active){let n=(t.document??t).actor?.uuid;await game.dfreds.effectInterface.toggleEffect(a,{uuids:[n],overlay:!1})}}class K{static dataToForm(t){"texture.scaleX"in t&&(t.scale=Math.abs(t["texture.scaleX"]),t.mirrorX=t["texture.scaleX"]<0),"texture.scaleY"in t&&(t.scale=Math.abs(t["texture.scaleY"]),t.mirrorY=t["texture.scaleY"]<0)}static formToData(t,a){// Scale/mirroring
|
|
if("scale"in a||"mirrorX"in a||"mirrorY"in a){let n=t.document?t.document:t;"scale"in a||(a.scale=Math.abs(n.texture.scaleX)),"mirrorX"in a||(a.mirrorX=n.texture.scaleX<0),"mirrorY"in a||(a.mirrorY=n.texture.scaleY<0),setProperty(a,"texture.scaleX",a.scale*(a.mirrorX?-1:1)),setProperty(a,"texture.scaleY",a.scale*(a.mirrorY?-1:1)),["scale","mirrorX","mirrorY"].forEach(t=>delete a[t])}}}function q(t,a,n,r){for(let a of n)r.includes(a)||t.push(a);for(let t of r)n.includes(t)||a.push(t)}async function J(t){let a="data",n={wildcard:!0};// Support non-user sources
|
|
if(/\.s3\./.test(t)){a="s3";let{bucket:r,keyPrefix:o}=FilePicker.parseS3URL(t);r&&(n.bucket=r,t=o)}else t.startsWith("icons/")&&(a="public");// Retrieve wildcard content
|
|
try{let r=await FilePicker.browse(a,t,n);return r.files}catch(t){}return[]}async function Z(t){let a=t.nameForge;if(a?.randomize&&a?.models){let t=game.modules.get("nameforge");if(t?.active){let n=[];for(let r of a.models){let a=getProperty(t.models,r);if(a){let r=await t.api.createModel(a);r&&n.push(t.api.generateName(r)[0])}}return n[Math.floor(Math.random()*n.length)]}}return null}async function Q(t,a){let n=ee(t,a);if(n){let t=canvas.app.renderer.extract.base64(n,"image/webp",1),r=await fetch(t),o=await r.blob(),s=a.name+".webp",l=new File([o],s,{type:"image/webp"});await FilePicker.upload("data",a.path,l,{})}}/**
|
|
* Modified version of 'dev7355608' captureCanvas function. Captures combined Token and Overlay image
|
|
*/function ee(t,{scale:a=3,width:n=null,height:r=null}={}){if(!canvas.ready||!t)return;n=n??t.texture.width,r=r??t.texture.height,a*=Math.min(n/t.texture.width,r/t.texture.height);let o=canvas.app.renderer,s={...canvas.scene._viewPosition};o.resize(n??o.screen.width,r??o.screen.height),n=canvas.screenDimensions[0]=o.screen.width,r=canvas.screenDimensions[1]=o.screen.height,canvas.stage.position.set(n/2,r/2),canvas.pan({x:t.center.x,y:t.center.y,scale:a});let l=PIXI.RenderTexture.create({width:n,height:r,resolution:t.texture.resolution}),c=canvas.stage.enableTempParent();canvas.stage.updateTransform(),canvas.stage.disableTempParent(c);let p=[t.mesh];for(let a of(t.tvaOverlays&&(p=p.concat(t.tvaOverlays)),p.sort(t=>t.sort),p))o.render(a,{renderTexture:l,skipUpdateTransform:!0,clear:!1});return canvas._onResize(),canvas.pan(s),l}function et(t,a=!1,n=!1){if(t.isToken)return n?[t.token]:t.token.object?[t.token.object]:[];let r=[];return(game.scenes.forEach(n=>n.tokens.forEach(n=>{n.actorId!==t.id||(a&&n.actorLink?r.push(n):a||r.push(n))})),n)?r:r.map(t=>t.object).filter(t=>t)}function ei(t,a={}){let r;let o=C(t);if(n.TVA_CONFIG.imgNameContainsDimensions){let t=o.match(/_height(.*)_/)?.[1];t&&(a.height=parseFloat(t));let n=o.match(/_width(.*)_/)?.[1];n&&(a.width=parseFloat(n)),(r=o.match(/_scale(.*)_/)?.[1])&&(r=Math.max(parseFloat(r),.2))}return n.TVA_CONFIG.imgNameContainsFADimensions&&(r=o.match(/_Scale(\d+)_/)?.[1])&&(r=Math.max(parseInt(r)/100,.2)),r&&(a["texture.scaleX"]=r,a["texture.scaleY"]=r),a}function ea(t){return PIXI.utils.string2hex(t)}function en(t){try{return decodeURI(t)}catch(a){return console.warn("URI Component not decodable: "+t),t}}function er(t){try{return decodeURIComponent(t)}catch(a){return console.warn("URI Component not decodable: "+t),t}}function eo(t,a){let n={};for(let r of t){let t=a.findIndex(t=>t.label===r.label&&t.group===r.group);-1===t?a.push(r):(n[a.id]=r.id,a[t].tokens?.length&&(r.tokens||(r.tokens=[]),a[t].tokens.forEach(t=>{r.tokens.includes(t)||r.tokens.push(t)})),a[t]=r)}return(// If parent's id has been changed we need to update all the children
|
|
a.forEach(t=>{let a=t.overlayConfig?.parentID;a&&a in n&&(t.overlayConfig.parentID=n[a])}),a)}}),parcelRequire.register("coMHP",function(t,a){$parcel$export(t.exports,"isInitialized",()=>u),$parcel$export(t.exports,"showArtSelect",()=>v);var n=parcelRequire("9IngI"),r=parcelRequire("7OP4c"),o=parcelRequire("eeGZt"),s=parcelRequire("bFZU7"),l=parcelRequire("dmUqi"),c=parcelRequire("8MWlo"),p=parcelRequire("e9LRe"),f=parcelRequire("3pMx9"),d=parcelRequire("kPeJW"),g=parcelRequire("cs88A");// Tracks if module has been initialized
|
|
let h=!1;function u(){return h}let m=[];/**
|
|
* Initialize the Token Variants module on Foundry VTT init
|
|
*/async function y(){// Initialization should only be performed once
|
|
if(!h){for(let t of(s.FONT_LOADING.loading=FontConfig.loadFont("fontAwesome",{editor:!1,fonts:[{urls:["fonts/fontawesome/webfonts/fa-solid-900.ttf"]}]}),// Want this to be executed once the module has initialized
|
|
m.push(()=>{// Need to wait for icons do be drawn first however I could not find a way
|
|
// to wait until that has occurred. Instead we'll just wait for some static
|
|
// amount of time.
|
|
new Promise(t=>setTimeout(t,500)).then(()=>{for(let t of canvas.tokens.placeables)(0,s.drawOverlays)(t),n.TVA_CONFIG.disableEffectIcons?(0,o.waitForTokenTexture)(t,t=>{t.effects.removeChildren().forEach(t=>t.destroy()),t.effects.bg=t.effects.addChild(new PIXI.Graphics),t.effects.overlay=null}):n.TVA_CONFIG.filterEffectIcons&&(0,o.waitForTokenTexture)(t,t=>{t.drawEffects()})})}),(0,o.userRequiresImageCache)()&&(0,c.cacheImages)(),// Register ALL Hooks
|
|
(0,p.registerAllHooks)(),// Startup ticker that will periodically call 'updateEmbeddedDocuments' with all the accrued updates since the last tick
|
|
(0,o.startBatchUpdater)(),(0,p.registerHook)("Search","renderArtSelect",()=>{r.ArtSelect.executing=!1}),// Handle broadcasts
|
|
game.socket?.on("module.token-variants",t=>{if("forgeSearchPaths"===t.handlerName&&"UPDATE"===t.type){// Workaround for forgeSearchPaths setting to be updated by non-GM clients
|
|
if(!game.user.isGM)return;let a=!game.users.filter(t=>t.isGM&&(t.active||t.isActive)).some(t=>t.id<game.user.id);a&&n.updateSettings({forgeSearchPaths:t.args})}else if("drawOverlays"===t.handlerName&&"UPDATE"===t.type){if(t.args.all){if(canvas.scene.id!==t.args.sceneId)for(let t of canvas.tokens.placeables)s.drawOverlays(t)}else if(t.args.actorId){let a=game.actors.get(t.args.actorId);a&&a.getActiveTokens(!0)?.forEach(t=>s.drawOverlays(t))}else if(t.args.tokenId){let a=canvas.tokens.get(t.args.tokenId);a&&s.drawOverlays(a)}}else if("effectMappings"===t.handlerName){if(!game.user.isGM)return;let a=!game.users.filter(t=>t.isGM&&(t.active||t.isActive)).some(t=>t.id<game.user.id);if(!a)return;let n=t.args,r=game.scenes.get(n.sceneId)?.tokens.get(n.tokenId);r&&l.updateWithEffectMapping(r,{added:n.added,removed:n.removed})}}),h=!0,m))t();m=[]}}async function v(t,{callback:a=null,searchType:n=o.SEARCH_TYPE.PORTRAIT_AND_TOKEN,object:s=null,force:l=!1,preventClose:p=!1,image1:f="",image2:d="",displayMode:g=r.ArtSelect.IMAGE_DISPLAY.NONE,multipleSelection:h=!1,searchOptions:u={},allImages:m=null}={}){if((0,c.isCaching)())return;let y=Object.values(ui.windows).filter(t=>t instanceof r.ArtSelect);if(r.ArtSelect.executing||!l&&0!==y.length){(0,r.addToArtSelectQueue)(t,{callback:a,searchType:n,object:s,preventClose:p,searchOptions:u,allImages:m});return}r.ArtSelect.executing=!0,m||(m=await (0,c.doImageSearch)(t,{searchType:n,searchOptions:u})),new(0,r.ArtSelect)(t,{allImages:m,searchType:n,callback:a,object:s,preventClose:p,image1:f,image2:d,displayMode:g,multipleSelection:h,searchOptions:u}).render(!0)}// Initialize module
|
|
(0,p.registerHook)("main","ready",y,{once:!0}),// Register API and Keybinds
|
|
(0,p.registerHook)("main","init",function(){(0,n.registerSettings)(),(0,f.registerAllWrappers)(),(0,o.registerKeybinds)();let t={cacheImages:c.cacheImages,doImageSearch:c.doImageSearch,doRandomSearch:c.doRandomSearch,getTokenEffects:l.getTokenEffects,showArtSelect:v,updateTokenImage:o.updateTokenImage,exportSettingsToJSON:n.exportSettingsToJSON,assignUserSpecificImage:d.assignUserSpecificImage,assignUserSpecificImageToSelected:d.assignUserSpecificImageToSelected,unassignUserSpecificImage:d.unassignUserSpecificImage,unassignUserSpecificImageFromSelected:d.unassignUserSpecificImageFromSelected,setOverlayVisibility:l.setOverlayVisibility,toggleTemplateDialog:g.toggleTemplateDialog,toggleTemplate:l.toggleTemplate,toggleTemplateOnSelected:l.toggleTemplateOnSelected,TVA_CONFIG:n.TVA_CONFIG};Object.defineProperty(t,"hooks",{get:()=>deepClone(p.REGISTERED_HOOKS),configurable:!0}),Object.defineProperty(t,"wrappers",{get:()=>deepClone(f.REGISTERED_WRAPPERS),configurable:!0}),game.modules.get("token-variants").api=t})}),parcelRequire.register("7OP4c",function(t,a){$parcel$export(t.exports,"addToArtSelectQueue",()=>l),$parcel$export(t.exports,"ArtSelect",()=>d),$parcel$export(t.exports,"addToQueue",()=>c),$parcel$export(t.exports,"renderFromQueue",()=>p),$parcel$export(t.exports,"insertArtSelectButton",()=>g);var n=parcelRequire("7P4Bo"),r=parcelRequire("eeGZt"),o=parcelRequire("coMHP"),s=parcelRequire("9IngI");function l(t,a){d.queue.push({search:t,options:a}),$("button#token-variant-art-clear-queue").html(`Clear Queue (${d.queue.length})`).show()}function c(t,a){d.queue.push({search:t,options:a})}function p(t=!1){if(!t){let t=Object.values(ui.windows).filter(t=>t instanceof d);if(0!==t.length){0!==d.queue.length&&$("button#token-variant-art-clear-queue").html(`Clear Queue (${d.queue.length})`).show();return}}let a=d.queue.shift();a?.options.execute&&(a.options.execute(),a=d.queue.shift()),a&&(0,o.showArtSelect)(a.search,a.options)}function f(t,a){let n=0;return function(...r){clearTimeout(n),n=setTimeout(t.bind(this,...r),a||0)}}class d extends FormApplication{static queue=[];static instance=null;// showArtSelect(...) can take a while to fully execute and it is possible for it to be called
|
|
// multiple times in very quick succession especially if copy pasting tokens or importing actors.
|
|
// This variable set early in the function execution is used to queue additional requests rather
|
|
// than continue execution
|
|
static executing=!1;static IMAGE_DISPLAY={NONE:0,PORTRAIT:1,TOKEN:2,PORTRAIT_TOKEN:3,IMAGE:4};constructor(t,{preventClose:a=!1,object:n=null,callback:o=null,searchType:l=null,allImages:c=null,image1:p="",image2:f="",displayMode:g=d.IMAGE_DISPLAY.NONE,multipleSelection:h=!1,searchOptions:u={}}={}){let m=game.i18n.localize("token-variants.windows.art-select.select-variant");l===r.SEARCH_TYPE.TOKEN?m=game.i18n.localize("token-variants.windows.art-select.select-token-art"):l===r.SEARCH_TYPE.PORTRAIT&&(m=game.i18n.localize("token-variants.windows.art-select.select-portrait-art")),super({},{closeOnSubmit:!1,width:d.WIDTH||500,height:d.HEIGHT||500,left:d.LEFT,top:d.TOP,title:m}),this.search=t,this.allImages=c,this.callback=o,this.doc=n,this.preventClose=a,this.image1=p,this.image2=f,this.displayMode=g,this.multipleSelection=h,this.searchType=l,this.searchOptions=mergeObject(u,(0,s.getSearchOptions)(),{overwrite:!1}),d.instance=this;let y="ArtSelect";Object.defineProperty(d.prototype.constructor,"name",{value:y})}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-art-select",classes:["sheet"],template:"modules/token-variants/templates/artSelect.html",resizable:!0,minimizable:!1})}_getHeaderButtons(){let t=super._getHeaderButtons();return t.unshift({label:"FilePicker",class:"file-picker",icon:"fas fa-file-import fa-fw",onclick:()=>{new FilePicker({type:"imagevideo",callback:t=>{this.preventClose||this.close(),this.callback&&this.callback(t,(0,r.getFileName)(t))}}).render()}}),t.unshift({label:"Image Category",class:"type",icon:"fas fa-swatchbook",onclick:()=>{d.instance&&d.instance._typeSelect()}}),t}_typeSelect(){let t=(0,r.BASE_IMAGE_CATEGORIES).concat(s.TVA_CONFIG.customImageCategories),a={};for(let n of t){let t=n;n===this.searchType&&(t="<b>>>> "+t+" <<<</b>"),a[n]={label:t,callback:()=>{this.searchType!==n&&(this.searchType=n,this._performSearch(this.search,!0))}}}new Dialog({title:"Select Image Category and Filter",content:"<style>.dialog .dialog-button {flex: 0 0 auto;}</style>",buttons:a}).render(!0)}async getData(t){let a=super.getData(t);this.doc instanceof Item&&(a.item=!0,a.description=this.doc.system?.description?.value??"");let n=this.searchOptions,o=n.algorithm,l=((0,s.TVA_CONFIG).tokenConfigs||[]).flat(),c=o.fuzzy,p=new Map,f=!1,g=function(t,a,n="<mark>",r="</mark>",o=null){if(!a)return t;let s=o?o.repeat(t.length):t,l="",c=0;for(let o of a)l+=s.slice(c,o[0])+(n+t.slice(o[0],o[1]+1)+r),c=o[1]+1;return l+s.slice(c,s.length)},h=function(t){if(!c)return t.path;let a=Math.ceil((1-t.score)*100)+"%";return n.runSearchOnPath?a+"\n"+g(t.path,t.indices,"","","-")+"\n"+t.path:a};return this.allImages.forEach((t,a)=>{let o=[];t.forEach(t=>{f=!0;let a=(0,r.isVideo)(t.path),s=(0,r.isImage)(t.path);o.push({path:t.path,img:s,vid:a,type:a||s,name:t.name,label:c&&!n.runSearchOnPath?g(t.name,t.indices):t.name,title:h(t),hasConfig:(this.searchType===r.SEARCH_TYPE.TOKEN||this.searchType===r.SEARCH_TYPE.PORTRAIT_AND_TOKEN)&&!!l.find(a=>a.tvImgSrc==t.path&&a.tvImgName==t.name)})}),p.set(a,o)}),f&&(a.allImages=p),a.search=this.search,a.queue=d.queue.length,a.image1=this.image1,a.image2=this.image2,a.displayMode=this.displayMode,a.multipleSelection=this.multipleSelection,a.displaySlider=o.fuzzy&&o.fuzzyArtSelectPercentSlider,a.fuzzyThreshold=o.fuzzyThreshold,a.displaySlider&&(a.fuzzyThreshold=100-100*a.fuzzyThreshold,a.fuzzyThreshold=a.fuzzyThreshold.toFixed(0)),a.autoplay=!s.TVA_CONFIG.playVideoOnHover,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t);let a=this.callback,o=()=>this.close(),l=this.doc,c=this.preventClose,p=this.multipleSelection,g=t.find(".token-variants-grid-box");g.hover(function(){if(s.TVA_CONFIG.playVideoOnHover){let t=$(this).siblings("video");t.length&&(t[0].play(),$(this).siblings(".fa-play").hide())}},function(){if(s.TVA_CONFIG.pauseVideoOnHoverOut){let t=$(this).siblings("video");t.length&&(t[0].pause(),t[0].currentTime=0,$(this).siblings(".fa-play").show())}}),g.map(t=>{g[t].addEventListener("click",async function(t){(0,r.keyPressed)("config")?l&&new(0,n.default)(l,{},t.target.dataset.name,t.target.dataset.filename).render(!0):(c||o(),a&&a(t.target.dataset.name,t.target.dataset.filename))}),p&&g[t].addEventListener("contextmenu",async function(t){$(t.target).toggleClass("selected")})});let h=t.find("#custom-art-search");h.focus(),h[0].selectionStart=h[0].selectionEnd=1e4,h.on("input",f(t=>{this._performSearch(t.target.value)},350)),t.find("button#token-variant-art-clear-queue").on("click",t=>{d.queue=d.queue.filter(t=>t.options.execute),$(t.target).hide()}),$(t).find('[name="fuzzyThreshold"]').change(t=>{$(t.target).siblings(".token-variants-range-value").html(`${parseFloat(t.target.value).toFixed(0)}%`),this.searchOptions.algorithm.fuzzyThreshold=(100-t.target.value)/100}).change(f(t=>{this._performSearch(this.search,!0)},350)),p&&(t.find("button#token-variant-art-return-selected").on("click",()=>{if(a){let n=[];t.find(".token-variants-grid-box.selected").siblings(".token-variants-grid-image").each(function(){n.push(this.getAttribute("src"))}),a(n)}o()}),t.find("button#token-variant-art-return-all").on("click",()=>{if(a){let n=[];t.find(".token-variants-grid-image").each(function(){n.push(this.getAttribute("src"))}),a(n)}o()}))}_performSearch(t,a=!1){(a||this.search.trim()!==t.trim())&&(0,o.showArtSelect)(t,{callback:this.callback,searchType:this.searchType,object:this.doc,force:!0,image1:this.image1,image2:this.image2,displayMode:this.displayMode,multipleSelection:this.multipleSelection,searchOptions:this.searchOptions,preventClose:this.preventClose})}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){a&&a.search!=this.search?this._performSearch(a.search):this.close()}setPosition(t={}){t.width&&(d.WIDTH=t.width),t.height&&(d.HEIGHT=t.height),t.top&&(d.TOP=t.top),t.left&&(d.LEFT=t.left),super.setPosition(t)}async close(t={}){let a=d.queue.shift();if(a?.options.execute&&(a.options.execute(),a=d.queue.shift()),a)a.options.force=!0,(0,o.showArtSelect)(a.search,a.options);else{// For some reason there might be app instances that have not closed themselves by this point
|
|
// If there are, close them now
|
|
let a=Object.values(ui.windows).filter(t=>t instanceof d).filter(t=>t.appId!==this.appId);for(let t of a)t.close();return super.close(t)}}}function g(t,a,{search:n="",searchType:s=r.SEARCH_TYPE.TOKEN}={}){let l=$(`<button
|
|
class="token-variants-image-select-button"
|
|
type="button"
|
|
data-type="imagevideo"
|
|
data-target="${a}"
|
|
title="${game.i18n.localize("token-variants.windows.art-select.select-variant")}">
|
|
<i class="fas fa-images"></i>
|
|
</button>`);l.on("click",()=>{(0,o.showArtSelect)(n,{callback:(t,n)=>{l.siblings(`[name="${a}"]`).val(t)},searchType:s})});let c=t.find(`[name="${a}"]`);return c.after(l),!!c.length}}),parcelRequire.register("7P4Bo",function(t,a){$parcel$export(t.exports,"default",()=>r);var n=parcelRequire("eeGZt");class r extends TokenConfig{constructor(t,a,n,r,o,s){let l;super(l=t instanceof Actor?new TokenDocument(t.token,{actor:t}):new TokenDocument(t.document,{actor:game.actors.get(t.actorId)}),a),this.imgSrc=n,this.imgName=r,this.callback=o,this.config=s,this.config&&(this.flags=this.config.flags,this.tv_script=this.config.tv_script)}_getSubmitData(t={}){if(!this.form)throw Error("The FormApplication subclass has no registered form element");let a=new FormDataExtended(this.form,{editors:this.editors}),n=a.object;return t&&(n=foundry.utils.flattenObject(foundry.utils.mergeObject(n,t))),"detectionModes.0.id"in n||(n.detectionModes=[]),// Treat "None" as null for bar attributes
|
|
n["bar1.attribute"]||=null,n["bar2.attribute"]||=null,n}async _updateObject(t,a){let r={},o=$(t.target).closest("form");if(o.find(".form-group").each(function(t){let n=$(this).find(".tva-config-checkbox > input");n.length&&n.is(":checked")&&$(this).find("[name]").each(function(t){let n=$(this).attr("name");r[n]=a[n]})}),this.tv_script&&(r.tv_script=this.tv_script),this.config){let t=expandObject(r);t.flags=t.flags?mergeObject(this.flags||{},t.flags):this.flags,this.callback&&this.callback(t)}else{let t=(0,n.setTokenConfig)(this.imgSrc,this.imgName,r);this.callback&&this.callback(t)}}applyCustomConfig(){let t=flattenObject(this.config||(0,n.getTokenConfig)(this.imgSrc,this.imgName)),a=$(this.form);for(let n of Object.keys(t)){let r=a.find(`[name="${n}"]`);r.is(":checkbox")?r.prop("checked",t[n]):r.val(t[n]),r.trigger("change")}}// *************
|
|
// consider moving html injection to:
|
|
// _replaceHTML | _injectHTML
|
|
async activateListeners(t){await super.activateListeners(t),// Disable image path controls
|
|
$(t).find(".token-variants-image-select-button").prop("disabled",!0),$(t).find(".file-picker").prop("disabled",!0),$(t).find(".image").prop("disabled",!0),// Remove 'Assign Token' button
|
|
$(t).find(".assign-token").remove();// Add checkboxes to control inclusion of specific tabs in the custom config
|
|
let a=this.config||(0,n.getTokenConfig)(this.imgSrc,this.imgName);this.tv_script=a.tv_script,$(t).on("change",".tva-config-checkbox",this._onCheckboxChange);let r=function(t){// Checkbox is not added for the Image Path group
|
|
if(!$(t).find('[name="img"]').length){let n=!1;if(a){let r=flattenObject(a);$(t).find("[name]").each(function(t){let a=$(this).attr("name");a in r&&(n=!0)})}let r=$(`<div class="tva-config-checkbox"><input type="checkbox" data-dtype="Boolean" ${n?'checked=""':""}></div>`);$(t).find("p.hint").length?$(t).find("p.hint").before(r):$(t).append(r),r.find("input").trigger("change")}};// Add checkboxes to each form-group to control highlighting and which fields will are to be saved
|
|
$(t).find(".form-group").each(function(t){r(this)}),// Add 'update' and 'remove' config buttons
|
|
$(t).find(".sheet-footer > button").remove(),$(t).find(".sheet-footer").append('<button type="submit" value="1"><i class="far fa-save"></i> Save Config</button>'),a&&($(t).find(".sheet-footer").append('<button type="button" class="remove-config"><i class="fas fa-trash"></i> Remove Config</button>'),t.find(".remove-config").click(this._onRemoveConfig.bind(this))),// Pre-select image or appearance tab
|
|
$(t).find('.tabs > .item[data-tab="image"] > i').trigger("click"),$(t).find('.tabs > .item[data-tab="appearance"] > i').trigger("click"),document.activeElement.blur();// TokenConfig might be changed by some modules after activateListeners is processed
|
|
// Look out for these updates and add checkboxes for any newly added form-groups
|
|
let s=t=>{t.forEach(t=>{t.addedNodes.forEach(t=>{"DIV"===t.nodeName&&"form-group"===t.className&&(r(t),this.applyCustomConfig())})})},l=new MutationObserver(s);l.observe(t[0],{characterData:!1,attributes:!1,childList:!0,subtree:!0}),// On any field being changed we want to automatically select the form-group to be included in the update
|
|
$(t).on("change","input, select",o),$(t).on("click","button",o),this.applyCustomConfig()}async _onCheckboxChange(t){let a=$(t.target);a.closest(".form-group").css({"outline-color":a.is(":checked")?"green":"#ffcc6e","outline-width":"2px","outline-style":"dotted","margin-bottom":"5px"}),a.closest(".tva-config-checkbox").css({"outline-color":a.is(":checked")?"green":"#ffcc6e","outline-width":"2px","outline-style":"solid"})}async _onRemoveConfig(t){if(this.config)this.callback&&this.callback({});else{let t=(0,n.setTokenConfig)(this.imgSrc,this.imgName,null);this.callback&&this.callback(t)}this.close()}get id(){return`token-custom-config-${this.object.id}`}_getHeaderButtons(){let t=super._getHeaderButtons();return t}}// Toggle checkbox if input has been detected inside it's form-group
|
|
async function o(t){"tva-config-checkbox"!==t.target.parentNode.className&&$(t.target).closest(".form-group").find(".tva-config-checkbox input").prop("checked",!0)}}),parcelRequire.register("bFZU7",function(module,exports){$parcel$export(module.exports,"FONT_LOADING",()=>FONT_LOADING),$parcel$export(module.exports,"drawOverlays",()=>drawOverlays),$parcel$export(module.exports,"evaluateOverlayExpressions",()=>evaluateOverlayExpressions),$parcel$export(module.exports,"genTexture",()=>genTexture),$parcel$export(module.exports,"removeMarkedOverlays",()=>removeMarkedOverlays),$parcel$export(module.exports,"interpolateColor",()=>interpolateColor),$parcel$export(module.exports,"broadcastOverlayRedraw",()=>broadcastOverlayRedraw);var $9IngI=parcelRequire("9IngI"),$8QbcE=parcelRequire("8QbcE"),$eeGZt=parcelRequire("eeGZt"),$dmUqi=parcelRequire("dmUqi");let FONT_LOADING={};async function drawOverlays(t){if(t.tva_drawing_overlays)return;t.tva_drawing_overlays=!0;let a=(0,$dmUqi.getAllEffectMappings)(t),n=(0,$dmUqi.getTokenEffects)(t,!0),r=a.filter(t=>t.overlay&&n.includes(t.id)).sort((t,a)=>(t.priority-t.overlayConfig?.parentID?0:999)-(a.priority-a.overlayConfig?.parentID?0:999));// See if the whole stack or just top of the stack should be used according to settings
|
|
r.length&&(r=$9IngI.TVA_CONFIG.stackStatusConfig?r:[r[r.length-1]]);// Process strings as expressions
|
|
let o=r.map(a=>evaluateOverlayExpressions(deepClone(a.overlayConfig),t,a));o.length?(0,$eeGZt.waitForTokenTexture)(t,async t=>{t.tvaOverlays||(t.tvaOverlays=[]),// Temporarily mark every overlay for removal.
|
|
// We'll only keep overlays that are still applicable to the token
|
|
_markAllOverlaysForRemoval(t);// To keep track of the overlay order
|
|
let a=0,n=0;for(let r of o){let o=_findTVAOverlay(r.id,t);if(o){let a=diffObject(o.overlayConfig,r);if(isEmpty(a)?(a.text?.text||a.shapes)&&o.setTexture(await genTexture(t,r),{configuration:r}):r.img?.includes("*")||r.img?.includes("{")&&r.img?.includes("}")?o.refresh(r):a.img||a.text||a.shapes||a.repeat||a.html?o.setTexture(await genTexture(t,r),{configuration:r}):a.parentID?(o.parent?.removeChild(o)?.destroy(),o=null):o.refresh(r),"ui"in a){o.parent.removeChild(o);let t=r.ui?canvas.tokens:canvas.primary;o=t.addChild(o)}}if(!o){if(r.parentID){let a=_findTVAOverlay(r.parentID,t);a&&!a.tvaRemove&&(o=a.addChildAuto(new $8QbcE.TVAOverlay(await genTexture(t,r),t,r)))}else{let a=r.ui?canvas.tokens:canvas.primary;o=a.addChild(new $8QbcE.TVAOverlay(await genTexture(t,r),t,r))}o&&t.tvaOverlays.push(o)}// If the sprite has a parent confirm that the parent has not been removed
|
|
if(o?.overlayConfig.parentID){let a=_findTVAOverlay(o.overlayConfig.parentID,t);(!a||a.tvaRemove)&&(o=null)}o&&(o.tvaRemove=!1,o.overlayConfig.underlay?(n-=.01,o.overlaySort=n):(a+=.01,o.overlaySort=a))}removeMarkedOverlays(t),t.tva_drawing_overlays=!1}):(_removeAllOverlays(t),t.tva_drawing_overlays=!1)}async function genTexture(t,a){let n=a.imgLinked?t.document.texture.src:a.img?.trim();return n?await generateImage(t,a,n):a.text?.text!=null?await generateTextTexture(t,a):a.shapes?.length?await generateShapeTexture(t,a.shapes):a.html?.template?{html:!0,texture:await loadTexture("modules\\token-variants\\img\\html_bg.webp")}:{texture:await loadTexture("modules/token-variants/img/token-images.svg")}}async function generateImage(t,a,n){if(n.includes("*")||n.includes("{")&&n.includes("}")){let t=await wildcardImageSearch(n);t.length&&t.length&&(n=t[Math.floor(Math.random()*t.length)])}let r=await loadTexture(n,{fallback:"modules/token-variants/img/token-images.svg"});// Repeat image if needed
|
|
// Repeating the shape if necessary
|
|
if(a.repeating&&a.repeat){let t;let n=a.repeat;t=n.isPercentage?Math.ceil(n.value/n.maxValue/(n.increment/100)):Math.ceil(n.value/n.increment);let o=0,s=0,l=n.maxRows??1/0,c=0,p=0,f=n.paddingX??0,d=n.paddingY??0,g=new PIXI.Container;for(;t>0;){let a=new PIXI.Sprite(r);if(a.x=c,a.y=p,g.addChild(a),c+=r.width+f,t--,o++,0!=t&&o>=n.perRow){if((s+=1)>=l)break;p+=r.height+d,c=0,o=0}}r=_renderContainer(g,r.resolution)}return{texture:r}}function _renderContainer(t,a,{width:n=null,height:r=null}={}){let o=t.getLocalBounds(),s=new PIXI.Matrix;s.tx=-o.x,s.ty=-o.y;let l=PIXI.RenderTexture.create({width:n??o.width,height:r??o.height,resolution:a});return isNewerVersion("11",game.version)?canvas.app.renderer.render(t,l,!0,s,!1):canvas.app.renderer.render(t,{renderTexture:l,clear:!0,transform:s,skipUpdateTransform:!1}),l.destroyable=!0,l}// Return width and height of the drawn shape
|
|
function _drawShape(t,a,n=0,r=0){if("rectangle"===a.type)return t.drawRoundedRect(a.x+n,a.y+r,a.width,a.height,a.radius),[a.width,a.height];if("ellipse"===a.type)return t.drawEllipse(a.x+n+a.width,a.y+r+a.height,a.width,a.height),[2*a.width,2*a.height];if("polygon"===a.type)t.drawPolygon(a.points.split(",").map((t,n)=>Number(t)*a.scale+(n%2==0?a.x:a.y)));else if("torus"===a.type)return drawTorus(t,a.x+n+a.outerRadius,a.y+r+a.outerRadius,a.innerRadius,a.outerRadius,Math.toRadians(a.startAngle),a.endAngle>=360?2*Math.PI:Math.toRadians(a.endAngle)),[2*a.outerRadius,2*a.outerRadius]}async function generateShapeTexture(t,a){let n=new PIXI.Graphics;for(let t of a){n.beginFill(interpolateColor(t.fill.color,t.fill.interpolateColor),t.fill.alpha),n.lineStyle(t.line.width,(0,$eeGZt.string2Hex)(t.line.color),t.line.alpha);let a=t.shape;// Repeating the shape if necessary
|
|
if(t.repeating&&t.repeat){let r;let o=t.repeat;r=o.isPercentage?Math.ceil(o.value/o.maxValue/(o.increment/100)):Math.ceil(o.value/o.increment);let s=0,l=0,c=o.maxRows??1/0,p=0,f=0,d=o.paddingX??0,g=o.paddingY??0;for(;r>0;){let[t,h]=_drawShape(n,a,p,f);if(p+=t+d,r--,s++,0!=r&&s>=o.perRow){if((l+=1)>=c)break;f+=h+g,p=0,s=0}}}else _drawShape(n,a)}return(// Store original graphics dimensions as these may change when children are added
|
|
n.shapesWidth=Number(n.width),n.shapesHeight=Number(n.height),{texture:PIXI.Texture.EMPTY,shapes:n})}function drawTorus(t,a,n,r,o,s=0,l=2*Math.PI){if(Math.abs(l-s)>=2*Math.PI)return t.drawCircle(a,n,o).beginHole().drawCircle(a,n,r).endHole();t.finishPoly(),t.arc(a,n,r,l,s,!0).arc(a,n,o,s,l,!1).finishPoly()}function interpolateColor(t,a,n=!1){if(!a||!a.color2||!a.prc)return n?t:(0,$eeGZt.string2Hex)(t);if(!PIXI.Color)return _interpolateV10(t,a,n);let r=a.prc;t=new PIXI.Color(t);let o=new PIXI.Color(a.color2),s=rgb2hsv(t.red,t.green,t.blue),l=rgb2hsv(o.red,o.green,o.blue),c=l[0]-s[0],p=c+(Math.abs(c)>180?c<0?360:-360:0),f=s[0]+p*r,d=(1-r)*s[1]+r*l[1],g=(1-r)*s[2]+r*l[2],h=new PIXI.Color({h:f,s:100*d,v:100*g});return n?h.toHex():h.toNumber()}function _interpolateV10(t,a,n=!1){let r=a.prc;t=PIXI.utils.hex2rgb((0,$eeGZt.string2Hex)(t));let o=PIXI.utils.hex2rgb((0,$eeGZt.string2Hex)(a.color2)),s=rgb2hsv(t[0],t[1],t[2]),l=rgb2hsv(o[0],o[1],o[2]),c=l[0]-s[0],p=c+(Math.abs(c)>180?c<0?360:-360:0),f=s[0]+p*r,d=(1-r)*s[1]+r*l[1],g=(1-r)*s[2]+r*l[2],h=Color.fromHSV([f/360,d,g]);return n?h.toString():Number(h)}/**
|
|
* Converts a color from RGB to HSV space.
|
|
* Source: https://stackoverflow.com/questions/8022885/rgb-to-hsv-color-in-javascript/54070620#54070620
|
|
*/function rgb2hsv(t,a,n){let r=Math.max(t,a,n),o=r-Math.min(t,a,n),s=o&&(r==t?(a-n)/o:r==a?2+(n-t)/o:4+(t-a)/o);return[60*(s<0?s+6:s),r&&o/r,r]}let CORE_VARIABLES={"@hp":t=>$dmUqi.getTokenHP(t)?.[0],"@hpMax":t=>$dmUqi.getTokenHP(t)?.[1],"@gridSize":()=>canvas.grid?.size,"@label":(t,a)=>a.label};function _evaluateString(t,a,n){let r=n.overlayConfig?.variables,o=RegExp("@\\w+","gi");t=t.replace(o,function(t){let o=t.substr(1,t.length),s=r?.find(t=>t.name===o);return s?s.value:t in CORE_VARIABLES?CORE_VARIABLES[t](a,n):t});let s=RegExp("{{.*?}}","gi");return t=t.replace(s,function(t){let r=t.substring(2,t.length-2);if(n&&"effect"===r)return n.expression;if(a&&"hp"===r)return $dmUqi.getTokenHP(a)?.[0];if(a&&"hpMax"===r)return $dmUqi.getTokenHP(a)?.[1];let o=getProperty(a.document??a,r);return o??0}).replace("\\n","\n")}function _executeString(evalString,token){try{let actor=token.actor,result=eval(evalString);// So that actor is easily accessible within eval() scope
|
|
return getType(result),result}catch(e){}return evalString}function evaluateOverlayExpressions(t,a,n){for(let[r,o]of Object.entries(t))["label","interactivity","variables","id","parentID","limitedUsers","filter","limitOnProperty","html"].includes(r)||(t[r]=_evaluateObjExpressions(o,a,n));return t}// Evaluate provided object values substituting in {{path.to.property}} with token properties, and performing eval() on strings
|
|
function _evaluateObjExpressions(t,a,n){let r=getType(t);if("string"===r){let r=_evaluateString(t,a,n);return _executeString(r,a)}if("Array"===r)for(let r=0;r<t.length;r++)t[r]=_evaluateObjExpressions(t[r],a,n);else if("Object"===r)for(let[r,o]of Object.entries(t))if("text"===r&&"string"===getType(o)&&o){let s=_evaluateString(o,a,n),l=_executeString(s,a);"string"!==getType(l)?t[r]=s:t[r]=l}else t[r]=_evaluateObjExpressions(o,a,n);return t}async function generateTextTexture(t,a){await FONT_LOADING.loading;let n=a.text.text;// Repeating the string if necessary
|
|
if(a.text.repeating&&a.text.repeat){let t,r="",o=a.text.repeat;t=o.isPercentage?Math.ceil(o.value/o.maxValue/(o.increment/100)):Math.ceil(o.value/o.increment);let s=0,l=0,c=o.maxRows??1/0;for(;t>0;)if(r+=n,t--,s++,0!=t&&s>=o.perRow){if((l+=1)>=c)break;r+="\n",s=0}n=r}let r=PreciseText.getTextStyle({...a.text,fontFamily:[a.text.fontFamily,"fontAwesome"].join(","),fill:interpolateColor(a.text.fill,a.text.interpolateColor,!0)}),o=new PreciseText(n,r);o.updateText(!1);let s=o.texture,l=a.text.maxHeight?Math.min(s.height,a.text.maxHeight):null,c=a.text.curve;if(!l&&!c?.radius&&!c?.angle)return s.textLabel=n,{texture:s};let p=new PIXI.Container;if(c?.radius||c?.angle){// Curve the text
|
|
let t=a.text.letterSpacing??0,n=c.angle?(s.width+t)/(2*Math.PI)/(c.angle/360):c.radius,r=100,o=Math.PI/r,l=r-Math.round(s.width/(n*Math.PI)*r);l/=2;let f=[];for(let t=r-l;t>l;t--){let a=n*Math.cos(o*t),r=n*Math.sin(o*t);f.push(new PIXI.Point(a,c.invert?r:-r))}let d=new PIXI.SimpleRope(s,f);p.addChild(d)}else p.addChild(new PIXI.Sprite(s));let f=_renderContainer(p,2,{height:l});return o.destroy(),f.textLabel=n,{texture:f}}function _markAllOverlaysForRemoval(t){for(let a of t.tvaOverlays)a instanceof $8QbcE.TVAOverlay&&(a.tvaRemove=!0)}function removeMarkedOverlays(t){let a=[];for(let n of t.tvaOverlays)n.tvaRemove?n.parent?.removeChild(n)?.destroy():a.push(n);t.tvaOverlays=a}function _findTVAOverlay(t,a){for(let n of a.tvaOverlays)if(n.overlayConfig?.id===t)return n;return null}function _removeAllOverlays(t){if(t.tvaOverlays)for(let a of t.tvaOverlays)a.parent?.removeChild(a)?.destroy();t.tvaOverlays=null}function broadcastOverlayRedraw(t){// Need to broadcast to other users to re-draw the overlay
|
|
t&&drawOverlays(t);let a=t.document?.actorLink?t.actor?.id:null,n={handlerName:"drawOverlays",args:{tokenId:t.id,actorId:a},type:"UPDATE"};game.socket?.emit("module.token-variants",n)}}),parcelRequire.register("8QbcE",function(module,exports){$parcel$export(module.exports,"TVAOverlay",()=>TVAOverlay);var $4rd87=parcelRequire("4rd87"),$dmUqi=parcelRequire("dmUqi"),$1u5p6=parcelRequire("1u5p6"),$ce8jp=parcelRequire("ce8jp"),$bFZU7=parcelRequire("bFZU7"),$eeGZt=parcelRequire("eeGZt"),$8ZZXW=parcelRequire("8ZZXW");class TVAOverlay extends TokenMesh{constructor(t,a,n){super(a),t.shapes&&(t.shapes=this.addChild(t.shapes)),this.pseudoTexture=t,this.texture=t.texture,//this.setTexture(pTexture, { refresh: false });
|
|
this.ready=!1,this.overlaySort=0,this.overlayConfig=mergeObject($ce8jp.DEFAULT_OVERLAY_CONFIG,n,{inplace:!1}),t.html&&this.addHTMLOverlay(),"linkDimensionsX"in this.overlayConfig||!this.overlayConfig.linkDimensions||(this.overlayConfig.linkDimensionsX=!0,this.overlayConfig.linkDimensionsY=!0),this._registerHooks(this.overlayConfig),this._tvaPlay().then(()=>this.refresh()),// Workaround needed for v11 visible property
|
|
Object.defineProperty(this,"visible",{get:this._customVisible,set:function(){},configurable:!0}),this.eventMode="passive",this.enableInteractivity(this.overlayConfig)}enableInteractivity(){if(this.mouseInteractionManager&&!this.overlayConfig.interactivity?.length){this.removeAllListeners(),this.mouseInteractionManager=null,this.cursor=null,this.eventMode="passive";return}if(this.mouseInteractionManager||!this.overlayConfig.interactivity?.length)return;this.overlayConfig.ui||"passive"!==canvas.primary.eventMode||(canvas.primary.eventMode="passive"),this.eventMode="static",this.cursor="pointer";let t=this.object,a=this,n=function(n,r){a.overlayConfig.interactivity.forEach(a=>{a.listener===r&&(n.preventDefault(),n.stopPropagation(),a.script&&(0,$eeGZt.tv_executeScript)(a.script,{token:t}),a.macro&&(0,$eeGZt.executeMacro)(a.macro,t),a.ceEffect&&(0,$eeGZt.toggleCEEffect)(t,a.ceEffect),a.tmfxPreset&&(0,$eeGZt.toggleTMFXPreset)(t,a.tmfxPreset))})},r={hoverIn:()=>!0,hoverOut:()=>!0,clickLeft:()=>!0,clickLeft2:()=>!0,clickRight:()=>!0,clickRight2:()=>!0,dragStart:()=>!1},o={hoverIn:t=>n(t,"hoverIn"),hoverOut:t=>n(t,"hoverOut"),clickLeft:t=>n(t,"clickLeft"),clickLeft2:t=>n(t,"clickLeft2"),clickRight:t=>n(t,"clickRight"),clickRight2:t=>n(t,"clickRight2"),dragLeftStart:null,dragLeftMove:null,dragLeftDrop:null,dragLeftCancel:null,dragRightStart:null,dragRightMove:null,dragRightDrop:null,dragRightCancel:null,longPress:null},s={target:null},l=new MouseInteractionManager(this,canvas.stage,r,o,s);this.mouseInteractionManager=l.activate()}_customVisible(){let t=this.overlayConfig;if(!this.ready||!(this.object.visible||t.alwaysVisible)||t.limitedToOwner&&!this.object.owner||t.limitedUsers?.length&&!t.limitedUsers.includes(game.user.id))return!1;if(t.limitOnEffect||t.limitOnProperty){let a=ChatMessage.getSpeaker(),n=canvas.ready?canvas.tokens.get(a.token):null;if(!n||t.limitOnEffect&&!(0,$dmUqi.getTokenEffects)(n).includes(t.limitOnEffect)||t.limitOnProperty&&!(0,$dmUqi.evaluateComparator)(n.document,t.limitOnProperty))return!1}return!t.limitOnHover&&!t.limitOnControl&&!t.limitOnHighlight&&!t.limitOnHUD&&!t.limitOnTarget&&!t.limitOnAnyTarget||!!(t.limitOnHover&&canvas.controls.ruler._state===Ruler.STATES.INACTIVE&&this.object.hover||t.limitOnControl&&this.object.controlled||t.limitOnHighlight&&(canvas.tokens.highlightObjects??canvas.tokens._highlight)||t.limitOnHUD&&this.object.hasActiveHUD||t.limitOnAnyTarget&&this.object.targeted.size||t.limitOnTarget&&this.object.targeted.some(t=>t.id===game.userId))}// Overlays have the same sort order as the parent
|
|
get sort(){return this.object.document.sort||0}get _lastSortedIndex(){return(this.object.mesh._lastSortedIndex||0)+this.overlaySort}get elevation(){let t=this.object.mesh?.data.elevation;return this.overlayConfig.top?t+=9999:this.overlayConfig.bottom&&(t-=9999),t}set _lastSortedIndex(t){}async _tvaPlay(){// Ensure playback state for video
|
|
let t=foundry.utils.getProperty(this.texture,"baseTexture.resource.source");if(t&&"VIDEO"===t.tagName){// Detach video from others
|
|
let a=t.cloneNode();this.overlayConfig.playOnce&&(a.onended=()=>{this.alpha=0,this.tvaVideoEnded=!0}),await new Promise(t=>a.oncanplay=t),this.texture=PIXI.Texture.from(a,{resourceOptions:{autoPlay:!1}});let n={loop:this.overlayConfig.loop&&!this.overlayConfig.playOnce,volume:0,offset:0,playing:!0};game.video.play(a,n)}}addChildAuto(...t){return this.pseudoTexture?.shapes?this.pseudoTexture.shapes.addChild(...t):this.addChild(...t)}setTexture(t,{preview:a=!1,refresh:n=!0,configuration:r=null}={}){a?(this._swapChildren(t),this.originalTexture?this._destroyTexture():(this.originalTexture=this.pseudoTexture,this.originalTexture.shapes&&this.removeChild(this.originalTexture.shapes)),this.pseudoTexture=t,this.texture=t.texture,t.shapes&&(t.shapes=this.addChild(t.shapes))):this.originalTexture?(this._swapChildren(this.originalTexture),this._destroyTexture(),this.pseudoTexture=this.originalTexture,this.texture=this.originalTexture.texture,this.originalTexture.shapes&&(this.pseudoTexture.shapes=this.addChild(this.originalTexture.shapes)),delete this.originalTexture):(this._swapChildren(t),this._destroyTexture(),this.pseudoTexture=t,this.texture=t.texture,t.shapes&&(this.pseudoTexture.shapes=this.addChild(t.shapes))),this.pseudoTexture.html&&this.addHTMLOverlay(),n&&this.refresh(r,{fullRefresh:!a})}refresh(t,{preview:a=!1,fullRefresh:n=!0,previewTexture:r=null}={}){if(!this.overlayConfig||!this.texture)return;(r||this.originalTexture)&&this.setTexture(r,{preview:!!r,refresh:!1}),t&&this._registerHooks(t);let o=mergeObject(this.overlayConfig,t??{},{inplace:!a});if(a&&this.htmlOverlay&&this.htmlOverlay.render(o,!0),this.enableInteractivity(o),n){let t=foundry.utils.getProperty(this.texture,"baseTexture.resource.source");t&&"VIDEO"===t.tagName&&(!t.loop&&o.loop?game.video.play(t):t.loop&&!o.loop&&game.video.stop(t),t.loop=o.loop)}let s=this.pseudoTexture.shapes,l=s??this.texture;if(o.linkScale&&!o.parentID){let t=this.scale,a=l.width/l.height;a>=1?(t.x=this.object.w*this.object.document.texture.scaleX/l.width,t.y=Number(t.x)):(t.y=this.object.h*this.object.document.texture.scaleY/l.height,t.x=Number(t.y))}else o.linkStageScale?(this.scale.x=1/canvas.stage.scale.x,this.scale.y=1/canvas.stage.scale.y):o.linkDimensionsX||o.linkDimensionsY?(o.linkDimensionsX&&(this.scale.x=this.object.document.width),o.linkDimensionsY&&(this.scale.y=this.object.document.height)):(this.scale.x=o.width?o.width/l.width:1,this.scale.y=o.height?o.height/l.height:1);// Adjust scale according to config
|
|
this.scale.x=this.scale.x*o.scaleX,this.scale.y=this.scale.y*o.scaleY,o.linkMirror&&!o.parentID&&(this.scale.x=Math.abs(this.scale.x)*(this.object.document.texture.scaleX<0?-1:1),this.scale.y=Math.abs(this.scale.y)*(this.object.document.texture.scaleY<0?-1:1)),this.anchor&&(o.anchor?this.anchor.set(o.anchor.x,o.anchor.y):this.anchor.set(.5,.5));let c=0,p=0;s?(s.position.x=-this.anchor.x*s.width,s.position.y=-this.anchor.y*s.height,o.animation.relative&&(this.pivot.set(0,0),s.pivot.set((.5-this.anchor.x)*s.width,(.5-this.anchor.y)*s.height),c=s.pivot.x*this.scale.x,p=s.pivot.y*this.scale.y)):o.animation.relative&&(c=(.5-this.anchor.x)*this.width,p=(.5-this.anchor.y)*this.height,this.pivot.set((.5-this.anchor.x)*this.texture.width,(.5-this.anchor.y)*this.texture.height));// Position
|
|
let f=o.pOffsetX||0,d=o.pOffsetY||0;if(o.parentID){let t=this.parent.anchor??{x:0,y:0},a=(this.parent.shapesWidth??this.parent.width)/this.parent.scale.x,n=(this.parent.shapesHeight??this.parent.height)/this.parent.scale.y;this.position.set(f+-o.offsetX*a-t.x*a+a/2,d+-o.offsetY*n-t.y*n+n/2)}else o.animation.relative?this.position.set(this.object.document.x+this.object.w/2+f+-o.offsetX*this.object.w+c,this.object.document.y+this.object.h/2+d+-o.offsetY*this.object.h+p):(this.position.set(this.object.document.x+this.object.w/2,this.object.document.y+this.object.h/2),this.pivot.set(-f/this.scale.x+o.offsetX*this.object.w/this.scale.x,-d/this.scale.y+o.offsetY*this.object.h/this.scale.y));this.tvaVideoEnded||(this.alpha=o.linkOpacity?this.object.document.alpha:o.alpha),n?o.linkRotation?this.angle=this.object.document.rotation+o.angle:this.angle=o.angle:!o.animation.rotate&&o.linkRotation&&(this.angle=this.object.document.rotation+o.angle);// Apply color tinting
|
|
let g=o.inheritTint?this.object.document.texture.tint:(0,$bFZU7.interpolateColor)(o.tint,o.interpolateColor,!0);this.tint=g?Color.from(g):16777215,s&&(s.tint=this.tint,s.alpha=this.alpha),n&&(o.animation.rotate?this.animate(o):this.stopAnimation()),n&&this._applyFilters(o),a&&this.children&&this.children.forEach(t=>{t instanceof TVAOverlay&&t.refresh(null,{preview:!0})}),this.htmlOverlay&&this.htmlOverlay.setPosition({left:this.x-this.pivot.x*this.scale.x-this.width*this.anchor.x,top:this.y-this.pivot.y*this.scale.y-this.height*this.anchor.y,width:this.width,height:this.height,angle:this.angle}),this.ready=!0}_activateTicker(){this._deactivateTicker(),canvas.app.ticker.add(this.updatePosition,this,PIXI.UPDATE_PRIORITY.HIGH)}_deactivateTicker(){canvas.app.ticker.remove(this.updatePosition,this)}updatePosition(){let t=canvas.canvasCoordinatesFromClient({x:window.innerWidth/2+this.overlayConfig.offsetX*window.innerWidth,y:window.innerHeight/2+this.overlayConfig.offsetY*window.innerHeight});this.position.set(t.x,t.y)}async _applyFilters(t){let a;let n=t.filter,r=PIXI.filters[n],o=mergeObject($4rd87.FILTERS[n]?.defaultValues||{},t.filterOptions);if(r){if($4rd87.FILTERS[n]?.argType==="args"){let t=[],s=$4rd87.FILTERS[n]?.controls;s&&s.forEach(a=>t.push(o[a.name])),a=new r(...t)}else a=$4rd87.FILTERS[n]?.argType==="options"?new r(o):new r}else if("OutlineOverlayFilter"===n)(a=OutlineFilter.create(o)).thickness=o.trueThickness??1,a.animate=o.animate??!1;else if("Token Magic FX"===n){this.applyTVAFilters(await constructTMFXFilters(o.params||[],this));return}a?(this.applyTVAFilters([a]),this.filters=[a]):this.removeTVAFilters(),this.overlayConfig.ui&&this.overlayConfig.bottom?this.applyReverseMask():this.removeReverseMask()}applyReverseMask(){if(!this.filters?.find(t=>t.tvaReverse)){let t=this.filters||[],a=ReverseMaskFilter.create({uMaskSampler:canvas.primary.tokensRenderTexture,channel:"a"});a.tvaReverse=!0,t.push(a),this.filters=t}this.filters||(filters=[])}removeReverseMask(){this.filters?.length&&(this.filters=this.filters.filter(t=>!t.tvaReverse))}applyTVAFilters(t){t?.length&&(this.removeTVAFilters(),this.filters=(this.filters||[]).concat(t))}removeTVAFilters(){this.filters&&(this.filters=this.filters.filter(t=>!t.tvaFilter))}async stopAnimation(){this.animationName&&CanvasAnimation.terminateAnimation(this.animationName)}async animate(t){this.animationName||(this.animationName=this.object.sourceId+"."+randomID(5));let a=this.angle+(t.animation.clockwise?360:-360),n=[{parent:this,attribute:"angle",to:a}],r=await CanvasAnimation.animate(n,{duration:t.animation.duration,name:this.animationName});r&&this.animate(t)}_registerHooks(t){t.linkStageScale?(0,$1u5p6.registerOverlayRefreshHook)(this,"canvasPan"):(0,$1u5p6.unregisterOverlayRefreshHooks)(this,"canvasPan")}_swapChildren(t){let a=this.pseudoTexture;if(a.shapes){this.removeChild(this.pseudoTexture.shapes);let n=a.shapes.removeChildren();t?.shapes?n.forEach(a=>t.shapes.addChild(a)?.refresh()):n.forEach(t=>this.addChild(t)?.refresh())}else if(t?.shapes){let a=this.removeChildren();a.forEach(a=>t.shapes.addChild(a)?.refresh())}}_destroyTexture(){(this.texture.textLabel||this.texture.destroyable)&&this.texture.destroy(!0),this.pseudoTexture?.shapes?(this.removeChild(this.pseudoTexture.shapes),this.pseudoTexture.shapes.destroy()):this.pseudoTexture?.html&&this.removeHTMLOverlay()}destroy(){if(this.stopAnimation(),(0,$1u5p6.unregisterOverlayRefreshHooks)(this),this.children){for(let t of this.children)t instanceof TVAOverlay&&(t.tvaRemove=!0);(0,$bFZU7.removeMarkedOverlays)(this.object),this.pseudoTexture.shapes&&(this.pseudoTexture.shapes.children.forEach(t=>t.destroy()),this.removeChild(this.pseudoTexture.shapes)?.destroy())}if(this.texture.textLabel||this.texture.destroyable)return super.destroy(!0);this.texture?.baseTexture.resource?.source?.tagName==="VIDEO"&&this.texture.baseTexture.destroy(),this.removeHTMLOverlay(),super.destroy()}// Foundry BUG Fix
|
|
calculateTrimmedVertices(){return PIXI.Sprite.prototype.calculateTrimmedVertices.call(this)}addHTMLOverlay(){this.htmlOverlay||(this.htmlOverlay=new $8ZZXW.HTMLOverlay(this.overlayConfig,this.object))}removeHTMLOverlay(){this.htmlOverlay&&this.htmlOverlay.remove(),this.htmlOverlay=null}}async function constructTMFXFilters(paramsArray,sprite){if("undefined"==typeof TokenMagic)return[];try{paramsArray=eval(paramsArray)}catch(e){return[]}if(Array.isArray(paramsArray)||(paramsArray=TokenMagic.getPreset(paramsArray)),!(paramsArray instanceof Array&¶msArray.length>0))return[];let filters=[];for(let params of paramsArray){if(!params.hasOwnProperty("filterType")||!TMFXFilterTypes.hasOwnProperty(params.filterType))return[];params.hasOwnProperty("rank")||(params.rank=5e3),params.hasOwnProperty("filterId")&&null!=params.filterId||(params.filterId=randomID()),params.hasOwnProperty("enabled")&&"boolean"==typeof params.enabled||(params.enabled=!0),params.filterInternalId=randomID();let gms=game.users.filter(t=>t.isGM);params.filterOwner=gms.length?gms[0].id:game.data.userId,// params.placeableType = placeable._TMFXgetPlaceableType();
|
|
params.updateId=randomID();let filterClass=await getTMFXFilter(params.filterType);if(filterClass){filterClass.prototype.assignPlaceable=function(){this.targetPlaceable=sprite.object,this.placeableImg=sprite},filterClass.prototype._TMFXsetAnimeFlag=async function(){};let filter=new filterClass(params);filter&&(// Patch fixes
|
|
filter.placeableImg=sprite,filter.targetPlaceable=sprite.object,// end of fixes
|
|
filter.tvaFilter=!0,filters.unshift(filter))}}return filters}async function getTMFXFilter(t){if(t in TMFXFilterTypes){if(t in LOADED_TMFXFilters)return LOADED_TMFXFilters[t];try{let a=TMFXFilterTypes[t],n=await import(`../../../tokenmagic/fx/filters/${a}.js`);if(n&&n[a])return LOADED_TMFXFilters[t]=n[a],n[a]}catch(t){}}return null}let LOADED_TMFXFilters={},TMFXFilterTypes={adjustment:"FilterAdjustment",distortion:"FilterDistortion",oldfilm:"FilterOldFilm",glow:"FilterGlow",outline:"FilterOutline",bevel:"FilterBevel",xbloom:"FilterXBloom",shadow:"FilterDropShadow",twist:"FilterTwist",zoomblur:"FilterZoomBlur",blur:"FilterBlur",bulgepinch:"FilterBulgePinch",zapshadow:"FilterRemoveShadow",ray:"FilterRays",fog:"FilterFog",xfog:"FilterXFog",electric:"FilterElectric",wave:"FilterWaves",shockwave:"FilterShockwave",fire:"FilterFire",fumes:"FilterFumes",smoke:"FilterSmoke",flood:"FilterFlood",images:"FilterMirrorImages",field:"FilterForceField",xray:"FilterXRays",liquid:"FilterLiquid",xglow:"FilterGleamingGlow",pixel:"FilterPixelate",web:"FilterSpiderWeb",ripples:"FilterSolarRipples",globes:"FilterGlobes",transform:"FilterTransform",splash:"FilterSplash",polymorph:"FilterPolymorph",xfire:"FilterXFire",sprite:"FilterSprite",replaceColor:"FilterReplaceColor",ddTint:"FilterDDTint"};class OutlineFilter extends OutlineOverlayFilter{/** @inheritdoc */static createFragmentShader(){return`
|
|
varying vec2 vTextureCoord;
|
|
varying vec2 vFilterCoord;
|
|
uniform sampler2D uSampler;
|
|
|
|
uniform vec2 thickness;
|
|
uniform vec4 outlineColor;
|
|
uniform vec4 filterClamp;
|
|
uniform float alphaThreshold;
|
|
uniform float time;
|
|
uniform bool knockout;
|
|
uniform bool wave;
|
|
|
|
${this.CONSTANTS}
|
|
${this.WAVE()}
|
|
|
|
void main(void) {
|
|
float dist = distance(vFilterCoord, vec2(0.5)) * 2.0;
|
|
vec4 ownColor = texture2D(uSampler, vTextureCoord);
|
|
vec4 wColor = wave ? outlineColor *
|
|
wcos(0.0, 1.0, dist * 75.0,
|
|
-time * 0.01 + 3.0 * dot(vec4(1.0), ownColor))
|
|
* 0.33 * (1.0 - dist) : vec4(0.0);
|
|
float texAlpha = smoothstep(alphaThreshold, 1.0, ownColor.a);
|
|
vec4 curColor;
|
|
float maxAlpha = 0.;
|
|
vec2 displaced;
|
|
for ( float angle = 0.0; angle <= TWOPI; angle += ${this.#e.toFixed(7)} ) {
|
|
displaced.x = vTextureCoord.x + thickness.x * cos(angle);
|
|
displaced.y = vTextureCoord.y + thickness.y * sin(angle);
|
|
curColor = texture2D(uSampler, clamp(displaced, filterClamp.xy, filterClamp.zw));
|
|
curColor.a = clamp((curColor.a - 0.6) * 2.5, 0.0, 1.0);
|
|
maxAlpha = max(maxAlpha, curColor.a);
|
|
}
|
|
float resultAlpha = max(maxAlpha, texAlpha);
|
|
vec3 result = (ownColor.rgb + outlineColor.rgb * (1.0 - texAlpha)) * resultAlpha;
|
|
gl_FragColor = vec4((ownColor.rgb + outlineColor.rgb * (1. - ownColor.a)) * resultAlpha, resultAlpha);
|
|
}
|
|
`}static get #e(){switch(canvas.performance.mode){case CONST.CANVAS_PERFORMANCE_MODES.LOW:return 2*Math.PI/10;case CONST.CANVAS_PERFORMANCE_MODES.MED:return 2*Math.PI/20;default:return 2*Math.PI/30}}}}),parcelRequire.register("1u5p6",function(t,a){$parcel$export(t.exports,"registerOverlayHooks",()=>p),$parcel$export(t.exports,"registerOverlayRefreshHook",()=>d),$parcel$export(t.exports,"unregisterOverlayRefreshHooks",()=>g);var n=parcelRequire("9IngI"),r=parcelRequire("8ZZXW"),o=parcelRequire("8QbcE"),s=parcelRequire("bFZU7"),l=parcelRequire("e9LRe");let c="Overlays";function p(){if(!n.FEATURE_CONTROL[c]){["refreshToken","destroyToken","updateActor","renderCombatTracker","updateToken","createToken","renderHeadsUpDisplay"].forEach(t=>(0,l.unregisterHook)(c,t));return}(0,l.registerHook)(c,"createToken",async function(t){t.object&&(0,s.drawOverlays)(t.object)}),(0,l.registerHook)(c,"updateToken",async function(t){t.object&&(0,s.drawOverlays)(t.object)}),(0,l.registerHook)(c,"refreshToken",t=>{if(t.tvaOverlays)for(let a of t.tvaOverlays)a instanceof o.TVAOverlay&&a.refresh(null,{preview:!1,fullRefresh:!1})}),(0,l.registerHook)(c,"destroyToken",t=>{if(t.tvaOverlays)for(let a of t.tvaOverlays)a.parent?.removeChild(a)?.destroy()}),(0,l.registerHook)(c,"updateActor",async function(t){t.getActiveTokens&&t.getActiveTokens(!0).forEach(t=>{(0,s.drawOverlays)(t)})}),(0,l.registerHook)(c,"renderCombatTracker",function(){for(let t of canvas.tokens.placeables)(0,s.drawOverlays)(t)}),(0,l.registerHook)(c,"renderHeadsUpDisplay",()=>{(0,r.HTMLOverlay).hudRendered()})}let f={};function d(t,a){a in f?f[a].find(a=>a==t)||f[a].push(t):((0,l.registerHook)("TVAOverlayRefresh",a,()=>{f[a]?.forEach(t=>t.refresh())}),f[a]=[t])}function g(t,a=null){let n=function(a){if(f[a]){let n=f[a].findIndex(a=>a==t);n>-1&&(f[a].splice(n,1),f[a].length||((0,l.unregisterHook)("TVAOverlayRefresh",a),delete f[a]))}};a?n(a):Object.keys(f).forEach(t=>n(t))}}),parcelRequire.register("8ZZXW",function(module,exports){$parcel$export(module.exports,"HTMLOverlay",()=>HTMLOverlay);class HTMLOverlay{static container=null;static renderQueue=[];static hudReady=!1;static hudRendered(){HTMLOverlay.hudReady=!0,HTMLOverlay.renderQueue.forEach(t=>t.render()),HTMLOverlay.renderQueue=[]}constructor(t,a){this.overlayConfig=t,this.token=a,this.render()}render(t=null,a=!1){if(!HTMLOverlay.hudReady){HTMLOverlay.renderQueue.push(this);return}HTMLOverlay.container||(HTMLOverlay.container=$('<div id="tva-html-overlays"></div>'),$("#hud").append(HTMLOverlay.container)),this.element&&this.remove(),t&&(this.overlayConfig=t),this.element=$(renderTemplate(this.overlayConfig,this.getData(),a)),HTMLOverlay.container.append(this.element),this.activateListeners(this.element),this.setPosition()}remove(){this.element&&this.element.remove(),this.element=null}getData(t={}){let a=this.token.document.toObject();return foundry.utils.mergeObject(a,{isGM:game.user.isGM})}setPosition({left:t,top:a,width:n,height:r,scale:o,angle:s,origin:l}={}){if(!HTMLOverlay.hudReady)return;let c=canvas.dimensions.size/100,p={width:n||100*this.token.document.width,height:r||100*this.token.document.height,left:t??this.token.document.x,top:a??this.token.document.y};1!==c&&(p.transform=`scale(${c})`),this.element.css(p),null!=s&&this.element.css({transform:"rotate("+s+"deg)"}),null!=l&&this.element.css({"transform-origin":l.x+"px "+l.y+"px"})}/** @override */activateListeners(html){try{eval(this.overlayConfig.html.listeners)}catch(e){}}}let _templateCache={};function _compile(t){return Handlebars.compile('<div class="tva-html-overlay"> <section class="window-content"><form>'+t+"</form></section></div>")}function constructTemplate(t,a=!1){if(_templateCache.hasOwnProperty(t.id)){if(a)return _compile(t.html.template)}else{let a=_compile(t.html.template);Handlebars.registerPartial(t.id,a),_templateCache[t.id]=a}return _templateCache[t.id]}function renderTemplate(t,a,n=!1){let r=constructTemplate(t,n);return console.log(a.x),r(a||{},{allowProtoMethodsByDefault:!0,allowProtoPropertiesByDefault:!0})}}),parcelRequire.register("e9LRe",function(t,a){$parcel$export(t.exports,"REGISTERED_HOOKS",()=>g),$parcel$export(t.exports,"registerHook",()=>h),$parcel$export(t.exports,"unregisterHook",()=>u),$parcel$export(t.exports,"registerAllHooks",()=>m);var n=parcelRequire("aVtQz"),r=parcelRequire("6Jwr7"),o=parcelRequire("1u5p6"),s=parcelRequire("dmUqi"),l=parcelRequire("1MaGd"),c=parcelRequire("7Bay0"),p=parcelRequire("4VMEk"),f=parcelRequire("aTVyJ"),d=parcelRequire("9IngI");let g={};function h(t,a,n,{once:r=!1}={}){if(t in g||(g[t]={}),a in g[t])return;d.TVA_CONFIG.debug&&console.info("TVA | Registering Hook",{feature_id:t,name:a,fn:n,once:r});let o=Hooks.on(a,n,{once:r});g[t][a]=o}function u(t,a){t in g&&a in g[t]&&(d.TVA_CONFIG.debug&&console.info("TVA | Un-Registering Hook",{feature_id:t,name:a,id:g[t][a]}),Hooks.off(a,g[t][a]),delete g[t][a])}function m(){// Hide effect icons
|
|
(0,n.registerEffectIconHooks)(),// Display overlays
|
|
(0,o.registerOverlayHooks)(),// Insert Art Select buttons and contextmenu listeners
|
|
(0,r.registerArtSelectButtonHooks)(),// Effect Mapping related listening for state changes and applying configurations
|
|
(0,s.registerEffectMappingHooks)(),// Display HUD buttons for Tokens and Tiles
|
|
(0,l.registerHUDHooks)(),// Default Wildcard image controls
|
|
(0,p.registerWildcardHooks)(),// User to Image mappings for Tile and Tokens
|
|
(0,c.registerUserMappingHooks)(),// Handle pop-ups and randomization on token/actor create
|
|
(0,f.registerPopRandomizeHooks)()}}),parcelRequire.register("aVtQz",function(t,a){$parcel$export(t.exports,"registerEffectIconHooks",()=>s);var n=parcelRequire("9IngI"),r=parcelRequire("e9LRe");let o="EffectIcons";function s(){n.FEATURE_CONTROL[o]&&n.TVA_CONFIG.displayEffectIconsOnHover?(0,r.registerHook)(o,"hoverToken",(t,a)=>{t.effects&&(t.effects.visible=a)}):(0,r.unregisterHook)(o,"hoverToken"),n.FEATURE_CONTROL[o]&&n.TVA_CONFIG.displayEffectIconsOnHover?(0,r.registerHook)(o,"highlightObjects",t=>{if(canvas.tokens.active)for(let a of canvas.tokens.placeables)a.effects&&(a.effects.visible=t||a.hover)}):(0,r.unregisterHook)(o,"highlightObjects")}}),parcelRequire.register("6Jwr7",function(t,a){$parcel$export(t.exports,"registerArtSelectButtonHooks",()=>p);var n=parcelRequire("7OP4c"),r=parcelRequire("coMHP"),o=parcelRequire("9IngI"),s=parcelRequire("eeGZt"),l=parcelRequire("e9LRe");let c="ArtSelect";function p(){o.TVA_CONFIG.permissions.portrait_right_click[game.user.role]?((0,l.registerHook)(c,"renderActorSheet",T),(0,l.registerHook)(c,"renderItemSheet",v),(0,l.registerHook)(c,"renderItemActionSheet",v),(0,l.registerHook)(c,"renderJournalSheet",b),(0,l.registerHook)(c,"renderRollTableConfig",O)):["renderActorSheet","renderItemSheet","renderItemActionSheet","renderJournalSheet","renderRollTableConfig"].forEach(t=>(0,l.unregisterHook)(c,t)),o.TVA_CONFIG.permissions.image_path_button[game.user.role]?((0,l.registerHook)(c,"renderTileConfig",m),(0,l.registerHook)(c,"renderMeasuredTemplateConfig",d),(0,l.registerHook)(c,"renderTokenConfig",f),(0,l.registerHook)(c,"renderDrawingConfig",g),(0,l.registerHook)(c,"renderNoteConfig",h),(0,l.registerHook)(c,"renderSceneConfig",u),(0,l.registerHook)(c,"renderMacroConfig",k),(0,l.registerHook)(c,"renderActiveEffectConfig",y)):["renderTileConfig","renderMeasuredTemplateConfig","renderTokenConfig","renderDrawingConfig","renderNoteConfig","renderSceneConfig","renderActiveEffectConfig"].forEach(t=>(0,l.unregisterHook)(c,t))}function f(t,a){(0,n.insertArtSelectButton)(a,"texture.src",{search:t.object.name,searchType:s.SEARCH_TYPE.TOKEN})}function d(t,a){(0,n.insertArtSelectButton)(a,"texture",{search:"Template",searchType:s.SEARCH_TYPE.TILE})}function g(t,a){(0,n.insertArtSelectButton)(a,"texture",{search:"Drawing",searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Drawing")?"Drawing":s.SEARCH_TYPE.TILE})}function h(t,a){(0,n.insertArtSelectButton)(a,"icon.custom",{search:"Note",searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Note")?"Note":s.SEARCH_TYPE.ITEM})}function u(t,a){(0,n.insertArtSelectButton)(a,"background.src",{search:t.object.name,searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Scene")?"Scene":s.SEARCH_TYPE.TILE}),(0,n.insertArtSelectButton)(a,"foreground",{search:t.object.name,searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Scene")?"Scene":s.SEARCH_TYPE.TILE}),(0,n.insertArtSelectButton)(a,"fogOverlay",{search:t.object.name,searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Fog")?"Fog":s.SEARCH_TYPE.TILE})}function m(t,a){(0,n.insertArtSelectButton)(a,"texture.src",{search:t.object.getFlag("token-variants","tileName")||"Tile",searchType:s.SEARCH_TYPE.TILE})}function y(t,a){let l=(0,n.insertArtSelectButton)(a,"icon",{search:t.object.name||"Active Effect",searchType:(0,o.TVA_CONFIG).customImageCategories.includes("Active Effect")?"Active Effect":s.SEARCH_TYPE.ITEM});if(!l){let n=$(a).find(".effect-icon");n.on("contextmenu",()=>{(0,r.showArtSelect)(t.object?.name??"Active Effect",{searchType:s.SEARCH_TYPE.ITEM,callback:t=>n.attr("src",t)})})}}function v(t,a,n){$(a).find('img.profile, .profile-img, [data-edit="img"]').on("contextmenu",()=>{let a=t.object;a&&(0,r.showArtSelect)(a.name,{searchType:s.SEARCH_TYPE.ITEM,callback:t=>a.update({img:t})})})}function k(t,a,n){let o=$(a).find(".sheet-header > img");o.on("contextmenu",()=>{(0,r.showArtSelect)(t.object?.name??"Macro",{searchType:s.SEARCH_TYPE.MACRO,callback:t=>o.attr("src",t)})})}function b(t,a,n){$(a).find(".header-button.entry-image").on("contextmenu",()=>{let a=t.object;a&&(0,r.showArtSelect)(a.name,{searchType:s.SEARCH_TYPE.JOURNAL,callback:t=>a.update({img:t})})})}function O(t,a){$(a).find(".result-image").on("contextmenu",a=>{let n=t.object;if(!n)return;let l=$(a.target).closest(".result-image").find("img");(0,r.showArtSelect)(n.name,{searchType:(0,o.TVA_CONFIG).customImageCategories.includes("RollTable")?"RollTable":s.SEARCH_TYPE.ITEM,callback:n=>{l.attr("src",n),t._onSubmit(a)}})})}/**
|
|
* Adds right-click listener to Actor Sheet profile image to open up
|
|
* the 'Art Select' screen.
|
|
*/function T(t,a,n){if(n.editable&&o.TVA_CONFIG.permissions.portrait_right_click[game.user.role]){let n=null,o={all:[".profile",".profile-img",".profile-image"],pf2e:[".player-image",".actor-icon",".sheet-header img",".actor-image"]};for(let t of o.all)if(n=a[0].querySelector(t))break;if(!n&&game.system.id in o){for(let t of o[game.system.id])if(n=a[0].querySelector(t))break}if(!n){console.warn("TVA |",game.i18n.localize("token-variants.notifications.warn.profile-image-not-found"));return}n.addEventListener("contextmenu",function(a){(0,r.showArtSelect)(t.object.name,{callback:(a,n)=>(0,s.updateActorImage)(t.object,a),searchType:s.SEARCH_TYPE.PORTRAIT,object:t.object})},!1)}}}),parcelRequire.register("1MaGd",function(t,a){$parcel$export(t.exports,"registerHUDHooks",()=>c);var n=parcelRequire("io0n7"),r=parcelRequire("6aWyX"),o=parcelRequire("9IngI"),s=parcelRequire("e9LRe");let l="HUD";function c(){o.FEATURE_CONTROL[l]&&o.TVA_CONFIG.tilesEnabled?(0,s.registerHook)(l,"renderTileHUD",n.renderTileHUD):(0,s.unregisterHook)(l,"renderTileHUD"),o.FEATURE_CONTROL[l]&&(o.TVA_CONFIG.permissions.hudFullAccess[game.user.role]||o.TVA_CONFIG.permissions.hud[game.user.role])?(0,s.registerHook)(l,"renderTokenHUD",r.renderTokenHUD):(0,s.unregisterHook)(l,"renderTokenHUD")}}),parcelRequire.register("io0n7",function(t,a){$parcel$export(t.exports,"renderTileHUD",()=>c);var n=parcelRequire("eeGZt"),r=parcelRequire("9IngI"),o=parcelRequire("byeN2"),s=parcelRequire("8MWlo"),l=parcelRequire("aBy72");async function c(t,a,n,o="",s=null){let l=t.object,c=r.TVA_CONFIG.hud;if(!c.enableSideMenu||!r.TVA_CONFIG.tilesEnabled)return;let g=$(`
|
|
<div class="control-icon" data-action="token-variants-side-selector">
|
|
<img
|
|
id="token-variants-side-button"
|
|
src="modules/token-variants/img/token-images.svg"
|
|
width="36"
|
|
height="36"
|
|
title="${game.i18n.localize("token-variants.windows.art-select.select-variant")}"
|
|
/>
|
|
</div>
|
|
`);a.find("div.right").last().append(g),a.find("div.right").click(d),g.click(t=>p(t,l)),g.contextmenu(t=>f(t,l))}async function p(t,a){if((0,n.keyPressed)("config")){v(a);return}let r=$(t.target).closest(".control-icon");// De-activate 'Status Effects'
|
|
r.closest("div.right").find("div.control-icon.effects").removeClass("active"),r.closest("div.right").find(".status-effects").removeClass("active"),// Remove contextmenu
|
|
r.find(".contextmenu").remove(),// Toggle variants side menu
|
|
r.toggleClass("active");let o=r.find(".token-variants-wrap");if(r.hasClass("active")){if(!o.length){if(!(o=await g(a)))return;r.find("img").after(o)}o.addClass("active")}else o.removeClass("active")}function f(t,a){// Display side menu if button is not active yet
|
|
let r=$(t.target).closest(".control-icon");if(r.hasClass("active")||r.addClass("active"),r.find(".contextmenu").length)// Contextmenu already displayed. Remove and activate images
|
|
r.find(".contextmenu").remove(),r.removeClass("active").trigger("click");else{// Contextmenu is not displayed. Hide images, create it and add it
|
|
r.find(".token-variants-wrap.images").removeClass("active");let t=$(`
|
|
<div class="token-variants-wrap contextmenu active">
|
|
<div class="token-variants-context-menu active">
|
|
<input class="token-variants-side-search" type="text" />
|
|
<button class="flags" type="button"><i class="fab fa-font-awesome-flag"></i><label>Flags</label></button>
|
|
<button class="file-picker" type="button"><i class="fas fa-file-import fa-fw"></i><label>Browse Folders</label></button>
|
|
</div>
|
|
</div>
|
|
`);r.append(t),// Register contextmenu listeners
|
|
t.find(".token-variants-side-search").on("keydown",t=>m(t,a)).on("click",t=>{t.preventDefault(),t.stopPropagation()}),t.find(".flags").click(t=>{t.preventDefault(),t.stopPropagation(),new(0,o.default)(a).render(!0)}),t.find(".file-picker").click(async t=>{t.preventDefault(),t.stopPropagation(),new FilePicker({type:"folder",callback:async(t,o)=>{let s=await FilePicker.browse(o.activeSource,o.result.target),l=s.files.filter(t=>(0,n.isImage)(t)||(0,n.isVideo)(t));if(l.length){r.find(".token-variants-wrap").remove();let t=await g(a,null,l);t&&(t.addClass("active"),r.append(t))}}}).render(!0)})}}function d(t){let a=$(t.target).closest(".control-icon"),n=a.attr("data-action");switch(n){case"effects":case"thwildcard-selector":break;// Effects button
|
|
default:return}$(t.target).closest("div.right").find('.control-icon[data-action="token-variants-side-selector"]').removeClass("active"),$(t.target).closest("div.right").find(".token-variants-wrap").removeClass("active")}async function g(t,a=null,o=null){let l=r.TVA_CONFIG.hud,c=r.TVA_CONFIG.worldHud,p=r.TVA_CONFIG.permissions.hudFullAccess[game.user.role],f=[],d=[],g=new Set,m=t=>{g.has(t.path)?f.find(a=>a.path===t.path&&a.name===t.name)||f.push(t):(f.push(t),g.add(t.path))};if(o)f=o.map(t=>({path:t,name:(0,n.getFileName)(t)}));else{if(null!==a&&!a)return;if(!a){(d=t.document.getFlag("token-variants","variants")||[]).forEach(t=>{for(let a of t.names)m({path:t.imgSrc,name:a})});// Parse directory flag and include the images
|
|
let a=t.document.getFlag("token-variants","directory");if(a){let t;try{let n=a.path,r=a.source,o="";r.startsWith("s3:")&&(o=r.substring(3,r.length),r="s3");let s=await FilePicker.browse(r,n,{type:"imagevideo",bucket:o});t=s.files}catch(a){t=[]}t.forEach(t=>{((0,n.isImage)(t)||(0,n.isVideo)(t))&&m({path:t,name:(0,n.getFileName)(t)})})}}// Perform the search if needed
|
|
let r=a??t.document.getFlag("token-variants","tileName"),o=!r||!a&&c.displayOnlySharedImages,l=o?null:await (0,s.doImageSearch)(r,{searchType:n.SEARCH_TYPE.TILE,searchOptions:{keywordSearch:c.includeKeywords}});l&&l.forEach(t=>{f.push(...t)})}// Retrieving the possibly custom name attached as a flag to the token
|
|
let v=t.document.getFlag("token-variants","name");v||(v=(0,n.getFileName)(t.document.texture.src));let k=[];for(let a of f){let r=(0,n.isImage)(a.path),o=(0,n.isVideo)(a.path),s=!1;game.user.isGM&&d.forEach(t=>{t.imgSrc===a.path&&t.names.includes(a.name)&&(s=!0)});let l=t.document.getFlag("token-variants","userMappings")||{},[c,p]=y(l,a.path,a.name);k.push({route:a.path,name:a.name,used:a.path===t.document.texture.src&&a.name===v,img:r,vid:o,unknownType:!r&&!o,shared:s,hasConfig:!1,title:c,style:game.user.isGM&&p?"box-shadow: "+p+";":null})}//
|
|
// Render
|
|
//
|
|
let b=l.displayAsImage,O=l.imageOpacity/100,T=$(await renderTemplate("modules/token-variants/templates/sideSelect.html",{imagesParsed:k,imageDisplay:b,imageOpacity:O,autoplay:!r.TVA_CONFIG.playVideoOnHover}));return(// Activate listeners
|
|
T.find("video").hover(function(){r.TVA_CONFIG.playVideoOnHover&&(this.play(),$(this).siblings(".fa-play").hide())},function(){r.TVA_CONFIG.pauseVideoOnHoverOut&&(this.pause(),this.currentTime=0,$(this).siblings(".fa-play").show())}),T.find(".token-variants-button-select").click(a=>h(a,t)),p&&T.find(".token-variants-button-select").on("contextmenu",a=>u(a,t)),T)}async function h(t,a){if(t.preventDefault(),t.stopPropagation(),!a)return;let r=$(t.target).closest(".token-variants-button-select"),o=r.attr("data-name"),s=r.attr("data-filename");if(o){canvas.tiles.hud.clear(),await a.document.update({img:o});try{(0,n.getFileName)(o)!==s&&await a.document.setFlag("token-variants","name",s)}catch(t){}}}async function u(t,a){if(t.preventDefault(),t.stopPropagation(),!a)return;let r=$(t.target).closest(".token-variants-button-select"),o=r.attr("data-name"),s=r.attr("data-filename");if(!o||!s)return;if((0,n.keyPressed)("config")&&game.user.isGM){let t=(t,a)=>{let n=t.document.getFlag("token-variants","userMappings")||{},o=r.attr("data-filename"),[s,l]=y(n,a,o);r.closest(".token-variants-wrap").find(`.token-variants-button-select[data-name='${a}']`).css("box-shadow",l).prop("title",s)};new(0,l.default)(a,o,t).render(!0);return}let c=a.document.getFlag("token-variants","variants")||[],p=!1,f=!1;for(let t of c)if(t.imgSrc===o){let a=t.names.filter(t=>t!=t);0===a.length?p=!0:a.length===t.names.length&&a.push(s),t.names=a,f=!0;break}p?c=c.filter(t=>t.imgSrc!==o):f||c.push({imgSrc:o,names:[s]}),// Set shared variants as a flag
|
|
a.document.unsetFlag("token-variants","variants"),c.length>0&&a.document.setFlag("token-variants","variants",c),r.find(".fa-share").toggleClass("active")}async function m(t,a){if("Enter"===t.key||13===t.keyCode){if(t.preventDefault(),t.target.value.length>=3){let n=$(t.target).closest(".control-icon");n.find(".token-variants-wrap").remove();let r=await g(a,t.target.value);r&&(r.addClass("active"),n.append(r))}return!1}}function y(t,a,n){let o=r.TVA_CONFIG.worldHud.showFullPath?a:n,s="",l=2;for(let[n,r]of Object.entries(t))if(r===a){let t=game.users.get(n);if(!t)continue;0===s.length?s=`inset 0 0 0 ${l}px ${t.color}`:s+=`, inset 0 0 0 ${l}px ${t.color}`,l+=2,o+=`
|
|
Displayed to: ${t.name}`}return[o,s]}function v(t){let a=t.document.getFlag("token-variants","tileName")||t.id;new Dialog({title:"Assign a name to the Tile (3+ chars)",content:`<table style="width:100%"><tr><th style="width:50%"><label>Tile Name</label></th><td style="width:50%"><input type="text" name="input" value="${a}"/></td></tr></table>`,buttons:{Ok:{label:"Save",callback:a=>{let n=a.find("input").val();n&&(canvas.tiles.hud.clear(),t.document.setFlag("token-variants","tileName",n))}}}}).render(!0)}}),parcelRequire.register("byeN2",function(t,a){$parcel$export(t.exports,"default",()=>n);class n extends FormApplication{constructor(t){super({},{}),t instanceof Tile?(this.objectToFlag=t.document,this.isTile=!0):this.objectToFlag=game.actors.get(t.document.actorId)||t.document}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-token-flags",classes:["sheet"],template:"modules/token-variants/templates/flagsConfig.html",resizable:!0,minimizable:!1,title:"Flags",width:500})}async getData(t){let a=super.getData(t),n=this.objectToFlag.getFlag("token-variants","popups"),r=this.objectToFlag.getFlag("token-variants","disableNameSearch"),o=this.objectToFlag.getFlag("token-variants","directory")||{};return mergeObject(a,{popups:n,popupsSetFlag:null!=n,disableNameSearch:r,disableNameSearchSetFlag:null!=r,directory:o.path,directorySource:o.source,directorySetFlag:!isEmpty(o),tile:this.isTile})}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find(".controlFlag").click(t=>{$(t.target).siblings(".flag").prop("disabled",!t.target.checked)}),t.find(".directory-fp").click(a=>{new FilePicker({type:"folder",activeSource:"data",callback:(n,r)=>{t.find('[name="directory"]').val(r.result.target),$(a.target).closest("button").attr("title","Directory: "+r.result.target);let o=t.find('[name="directorySource"]');"s3"===r.activeSource?o.val(`s3:${r.result.bucket}`):o.val(r.activeSource)}}).render(!0)})}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){"directory"in a&&(a.directory={path:a.directory,source:a.directorySource}),["popups","disableNameSearch","directory"].forEach(t=>{t in a?this.objectToFlag.setFlag("token-variants",t,a[t]):this.objectToFlag.unsetFlag("token-variants",t)})}}}),parcelRequire.register("8MWlo",function(t,a){$parcel$export(t.exports,"isCaching",()=>c),$parcel$export(t.exports,"doImageSearch",()=>f),$parcel$export(t.exports,"doRandomSearch",()=>d),$parcel$export(t.exports,"doSyncSearch",()=>g),$parcel$export(t.exports,"findImagesFuzzy",()=>k),$parcel$export(t.exports,"saveCache",()=>w),$parcel$export(t.exports,"cacheImages",()=>S);var n=parcelRequire("coMHP"),r=parcelRequire("RzsBm"),o=parcelRequire("9IngI"),s=parcelRequire("eeGZt");// True if in the middle of caching image paths
|
|
let l=!1;function c(){return l}// Cached images
|
|
let p={};async function f(t,{searchType:a=SEARCH_TYPE.PORTRAIT_AND_TOKEN,simpleResults:n=!1,callback:r=null,searchOptions:c={}}={}){if(l)return;c=mergeObject(c,(0,o.getSearchOptions)(),{overwrite:!1}),t=t.trim(),o.TVA_CONFIG.debug&&console.info("TVA | STARTING: Art Search",t,a,c);let p=[t],f=new Map,d=(0,s.parseKeywords)(c.excludedKeywords);c.keywordSearch&&(p=p.concat(t.split(/[_\- :,\|\(\)\[\]]/).filter(t=>t.length>2&&!d.includes(t.toLowerCase())).reverse()));let g=new Set;for(let t of p){if(void 0!==f.get(t))continue;let n=await O(t,a,c);n=n.filter(t=>!g.has(t)),f.set(t,n),n.forEach(g.add,g)}return o.TVA_CONFIG.debug&&console.info("TVA | ENDING: Art Search"),n&&(f=Array.from(g).map(t=>t.path)),r&&r(f),f}async function d(t,{searchType:a=SEARCH_TYPE.PORTRAIT_AND_TOKEN,actor:n=null,callback:r=null,randomizerOptions:o={},searchOptions:c={}}={}){if(l)return null;let p=(0,s.flattenSearchResults)(await h(t,{searchType:a,actor:n,randomizerOptions:o,searchOptions:c}));if(0===p.length)return null;// Pick random image
|
|
let f=Math.floor(Math.random()*p.length);return r&&r([p[f].path,p[f].name]),[p[f].path,p[f].name]}async function g(t,a,{searchType:n=SEARCH_TYPE.TOKEN,actor:o=null,randomizerOptions:c={}}={}){if(l)return null;let p=(0,s.flattenSearchResults)(await h(t,{searchType:n,actor:o,randomizerOptions:c})),f=new r.Fuse(p,{keys:["name"],minMatchCharLength:1,ignoreLocation:!0,threshold:.4}),d=f.search(a);return d&&0!==d.length?[d[0].item.path,d[0].item.name]:null}async function h(t,{searchType:a=SEARCH_TYPE.PORTRAIT_AND_TOKEN,actor:n=null,randomizerOptions:r={},searchOptions:l={}}={}){let c=mergeObject(r,o.TVA_CONFIG.randomizer,{overwrite:!1});if(!(c.tokenName||c.actorName||c.keywords||c.shared||c.wildcard))return null;// Randomizer settings take precedence
|
|
l.keywordSearch=c.keywords,c.actorName&&n&&(t=n.name);// Gather all images
|
|
let p=c.actorName||c.tokenName||c.keywords?await f(t,{searchType:a,searchOptions:l}):new Map;if(c.tokenName||c.actorName||p.delete(t),c.shared&&n){let t=n.getFlag("token-variants","variants")||[];if(0!=t.length){let a=[];t.forEach(t=>{t.names.forEach(n=>{a.push({path:t.imgSrc,name:n})})}),p.set("variants95436723",a)}}if(c.wildcard&&n){let t=n.prototypeToken.texture.src;if(t.includes("*")||t.includes("{")&&t.includes("}")){// Modified version of Actor.getTokenImages()
|
|
let a=async a=>{if(a._tokenImages)return a._tokenImages;let n="data",r={wildcard:!0};// Support non-user sources
|
|
if(/\.s3\./.test(t)){n="s3";let{bucket:a,keyPrefix:o}=FilePicker.parseS3URL(t);a&&(r.bucket=a,t=o)}else t.startsWith("icons/")&&(n="public");// Retrieve wildcard content
|
|
try{let a=await FilePicker.browse(n,t,r);return a.files}catch(t){return[]}},r=(await a(n)).filter(t=>!t.includes("*")&&((0,s.isImage)(t)||(0,s.isVideo)(t))).map(t=>({path:t,name:(0,s.getFileName)(t)}));p.set("variants95436623",r)}}return p}/**
|
|
* Recursive image search through a directory
|
|
* @param {*} path starting path
|
|
* @param {*} options.apiKey ForgeVTT AssetLibrary API key
|
|
* @param {*} found_images all the images found
|
|
* @returns void
|
|
*/async function u(t,{apiKey:a=""}={},n){let r={};t.source||(t.source="data");let l=t.types.sort().join(",");try{if(t.source.startsWith("s3:"))r=await FilePicker.browse("s3",t.text,{bucket:t.source.replace("s3:","")});else if(t.source.startsWith("forgevtt")){if(a){let n=await (0,s.callForgeVTT)(t.text,a);r.files=n.files.map(t=>t.url)}else r=await FilePicker.browse("forgevtt",t.text,{recursive:!0})}else if(t.source.startsWith("forge-bazaar"))r=await FilePicker.browse("forge-bazaar",t.text,{recursive:!0});else if(t.source.startsWith("imgur")){await fetch("https://api.imgur.com/3/gallery/album/"+t.text,{headers:{Authorization:"Client-ID "+(o.TVA_CONFIG.imgurClientId?o.TVA_CONFIG.imgurClientId:"df9d991443bb222"),Accept:"application/json"}}).then(t=>t.json()).then(async function(t){t.success&&t.data.images.forEach(t=>{let a=t.title??t.description??(0,s.getFileName)(t.link);m({path:(0,s.decodeURISafely)(t.link),name:a},l,n)})}).catch(t=>console.warn("TVA |",t));return}else if(t.source.startsWith("rolltable")){let a=game.tables.contents.find(a=>a.name===t.text);if(a)for(let t of a.results){let a=t.img,r=t.text||(0,s.getFileName)(a);m({path:(0,s.decodeURISafely)(a),name:r},l,n)}else{let a=t.text;ui.notifications.warn(game.i18n.format("token-variants.notifications.warn.invalid-table",{rollTableName:a}))}return}else if(t.source.startsWith("json")){await fetch(t.text,{headers:{Accept:"application/json"}}).then(t=>t.json()).then(async function(t){!t.length>0||t.forEach(t=>{let a=t.name??(0,s.getFileName)(t.path);m({path:(0,s.decodeURISafely)(t.path),name:a,tags:t.tags},l,n)})}).catch(t=>console.warn("TVA |",t));return}else r=await FilePicker.browse(t.source,t.text)}catch(a){console.warn(`TVA | ${game.i18n.localize("token-variants.notifications.warn.path-not-found")} ${t.source}:${t.text}`);return}if("."!=r.target){// ForgeVTT requires special treatment
|
|
// Bazaar paths fail recursive search if one level above root
|
|
if(r.files&&r.files.forEach(t=>{m({path:(0,s.decodeURISafely)(t),name:(0,s.getFileName)(t)},l,n)}),t.source.startsWith("forgevtt")||t.source.startsWith("forge-bazaar")&&!["modules","systems","worlds","assets"].includes(t.text.replaceAll(/[\/\\]/g,"")))return;for(let o of r.dirs)await u({text:o,source:t.source,types:t.types},{apiKey:a},n)}}function m(t,a,n){((0,s.isImage)(t.path)||(0,s.isVideo)(t.path))&&(null==n[a]?n[a]=[t]:n[a].push(t))}/**
|
|
* Recursive walks through all paths exposed to the module and caches them
|
|
* @param {*} searchType
|
|
* @returns
|
|
*/async function y(t){let a={},n=v(o.TVA_CONFIG.searchPaths,t);for(let t of n)(t.cache&&l||!t.cache&&!l)&&await u(t,{},a);// ForgeVTT specific path handling
|
|
let r="undefined"!=typeof ForgeAPI?await ForgeAPI.getUserId():"";for(let n in o.TVA_CONFIG.forgeSearchPaths){let s=o.TVA_CONFIG.forgeSearchPaths[n].apiKey,c=v(o.TVA_CONFIG.forgeSearchPaths[n].paths,t);if(n===r)for(let t of c)(t.cache&&l||!t.cache&&!l)&&await u(t,{},a);else if(s)for(let t of c)(t.cache&&l||!t.cache&&!l)&&t.share&&await u(t,{apiKey:s},a)}return a}function v(t,a){return a?t.filter(t=>t.types.includes(a)):t}async function k(t,a,n,l=!1){let c;o.TVA_CONFIG.debug&&console.info("TVA | STARTING: Fuzzy Image Search",t,a,n,l);let f=(0,s.getFilters)(a,n.searchFilters),d=new r.Fuse([],{keys:[!l&&n.runSearchOnPath?"path":"name","tags"],includeScore:!0,includeMatches:!0,minMatchCharLength:1,ignoreLocation:!0,threshold:n.algorithm.fuzzyThreshold}),g=await y(a);for(let t of[p,g])for(let r in t){let o=r.split(",");if(o.includes(a))for(let a of t[r])x(a.name,a.path,f,n.runSearchOnPath)&&d.add(a)}return c=""===t?d.getIndex().docs.slice(0,n.algorithm.fuzzyLimit):(c=d.search(t).slice(0,n.algorithm.fuzzyLimit)).map(t=>(t.item.indices=t.matches[0].indices,t.item.score=t.score,t.item)),o.TVA_CONFIG.debug&&console.info("TVA | ENDING: Fuzzy Image Search",c),c}async function b(t,a,n){o.TVA_CONFIG.debug&&console.info("TVA | STARTING: Exact Image Search",t,a,n);let r=await y(a),l=(0,s.simplifyName)(t),c=(0,s.getFilters)(a,n.searchFilters),f=[];for(let t of[p,r])for(let r in t){let o=r.split(",");if(o.includes(a))for(let a of t[r])T(l,a.path,a.name,c,n.runSearchOnPath)&&f.push(a)}return o.TVA_CONFIG.debug&&console.info("TVA | ENDING: Exact Image Search",f),f}async function O(t,a="",n={}){let r=mergeObject(n,(0,o.getSearchOptions)(),{overwrite:!1});return r.algorithm.exact?await b(t,a,r):await k(t,a,r)}/**
|
|
* Checks if image path and name match the provided search text and filters
|
|
* @param imagePath image path
|
|
* @param imageName image name
|
|
* @param filters filters to be applied
|
|
* @returns true|false
|
|
*/function T(t,a,n,r,o){// Is the search text contained in the name/path
|
|
let l=o?(0,s.simplifyPath)(a):(0,s.simplifyName)(n);return!!l.includes(t)&&(!r||x(n,a,r,o))}function x(t,a,n,r){// Filters are applied to path depending on the 'runSearchOnPath' setting, and actual or custom rolltable name
|
|
let o;return(o=r?(0,s.decodeURIComponentSafely)(a):(0,s.getFileName)(a)===t?(0,s.getFileNameWithExt)(a):t,n.regex)?n.regex.test(o):!(n.include&&!o.includes(n.include)||n.exclude&&o.includes(n.exclude))}async function w(t){let a={},n=Object.keys(p);for(let t of n)for(let n of(t in a||(a[t]=[]),p[t]))n.tags?a[t].push([n.path,n.name,n.tags]):(0,s.getFileName)(n.path)===n.name?a[t].push(n.path):a[t].push([n.path,n.name]);let r=new File([JSON.stringify(a)],(0,s.getFileNameWithExt)(t),{type:"text/plain"});FilePicker.upload("data",(0,s.getFilePath)(t),r)}async function S({staticCache:t=o.TVA_CONFIG.staticCache,staticCacheFile:a=o.TVA_CONFIG.staticCacheFile}={}){if(l)return;if(l=!0,!(0,n.isInitialized)()&&t&&await C(a)){l=!1;return}o.TVA_CONFIG.disableNotifs||ui.notifications.info(game.i18n.format("token-variants.notifications.info.caching-started")),o.TVA_CONFIG.debug&&console.info("TVA | STARTING: Token Caching");let r=await y();p=r,o.TVA_CONFIG.debug&&console.info("TVA | ENDING: Token Caching"),l=!1,o.TVA_CONFIG.disableNotifs||ui.notifications.info(game.i18n.format("token-variants.notifications.info.caching-finished",{imageCount:Object.keys(p).reduce((t,a)=>t+p[a].length,0)})),t&&game.user.isGM&&w(a)}async function C(t){p={};try{await jQuery.getJSON(t,t=>{for(let a in t)for(let n of(p[a]=[],t[a]))Array.isArray(n)?3===n.length?p[a].push({path:n[0],name:n[1],tags:n[2]}):p[a].push({path:n[0],name:n[1]}):p[a].push({path:n,name:(0,s.getFileName)(n)});o.TVA_CONFIG.disableNotifs||ui.notifications.info(`Token Variant Art: Using Static Cache (${Object.keys(p).reduce((t,a)=>t+p[a].length,0)} images)`)})}catch(t){return ui.notifications.warn("Token Variant Art: Static Cache not found"),p={},!1}return!0}}),parcelRequire.register("RzsBm",function(t,a){/**
|
|
* Fuse.js v6.5.3 - Lightweight fuzzy-search (http://fusejs.io)
|
|
*
|
|
* Copyright (c) 2021 Kiro Risk (http://kiro.me)
|
|
* All Rights Reserved. Apache Software License 2.0
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*/function n(t,a){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);a&&(r=r.filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable})),n.push.apply(n,r)}return n}function r(t){for(var a=1;a<arguments.length;a++){var r=null!=arguments[a]?arguments[a]:{};a%2?n(Object(r),!0).forEach(function(a){p(t,a,r[a])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach(function(a){Object.defineProperty(t,a,Object.getOwnPropertyDescriptor(r,a))})}return t}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function s(t,a){if(!(t instanceof a))throw TypeError("Cannot call a class as a function")}function l(t,a){for(var n=0;n<a.length;n++){var r=a[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function c(t,a,n){return a&&l(t.prototype,a),n&&l(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}function p(t,a,n){return a in t?Object.defineProperty(t,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[a]=n,t}function f(t,a){if("function"!=typeof a&&null!==a)throw TypeError("Super expression must either be null or a function");Object.defineProperty(t,"prototype",{value:Object.create(a&&a.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),writable:!1}),a&&g(t,a)}function d(t){return(d=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function g(t,a){return(g=Object.setPrototypeOf||function(t,a){return t.__proto__=a,t})(t,a)}function h(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(t){return!1}}function u(t){if(void 0===t)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function m(t,a){if(a&&("object"==typeof a||"function"==typeof a))return a;if(void 0!==a)throw TypeError("Derived constructors may only return object or undefined");return u(t)}function y(t){var a=h();return function(){var n,r=d(t);if(a){var o=d(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return m(this,n)}}function v(t){return k(t)||b(t)||O(t)||x()}function k(t){if(Array.isArray(t))return T(t)}function b(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}function O(t,a){if(t){if("string"==typeof t)return T(t,a);var n=Object.prototype.toString.call(t).slice(8,-1);if("Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return T(t,a)}}function T(t,a){(null==a||a>t.length)&&(a=t.length);for(var n=0,r=Array(a);n<a;n++)r[n]=t[n];return r}function x(){throw TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function w(t){return Array.isArray?Array.isArray(t):"[object Array]"===D(t)}// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js
|
|
$parcel$export(t.exports,"Fuse",()=>eG);var S=1/0;function C(t){// Exit early for strings to avoid a performance hit in some environments.
|
|
if("string"==typeof t)return t;var a=t+"";return"0"==a&&1/t==-S?"-0":a}function I(t){return null==t?"":C(t)}function F(t){return"string"==typeof t}function A(t){return"number"==typeof t}// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js
|
|
function E(t){return!0===t||!1===t||P(t)&&"[object Boolean]"==D(t)}function N(t){return"object"===o(t)}// Checks if `value` is object-like.
|
|
function P(t){return N(t)&&null!==t}function _(t){return null!=t}function R(t){return!t.trim().length}// Gets the `toStringTag` of `value`.
|
|
// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js
|
|
function D(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":Object.prototype.toString.call(t)}var M="Incorrect 'index' type",H=function(t){return"Invalid value for key ".concat(t)},j=function(t){return"Pattern length exceeds max of ".concat(t,".")},V=function(t){return"Missing ".concat(t," property in key")},G=function(t){return"Property 'weight' in key '".concat(t,"' must be a positive integer")},Y=Object.prototype.hasOwnProperty,X=/*#__PURE__*/function(){function t(a){var n=this;s(this,t),this._keys=[],this._keyMap={};var r=0;a.forEach(function(t){var a=z(t);r+=a.weight,n._keys.push(a),n._keyMap[a.id]=a,r+=a.weight}),this._keys.forEach(function(t){t.weight/=r})}return c(t,[{key:"get",value:function(t){return this._keyMap[t]}},{key:"keys",value:function(){return this._keys}},{key:"toJSON",value:function(){return JSON.stringify(this._keys)}}]),t}();function z(t){var a=null,n=null,r=null,o=1;if(F(t)||w(t))r=t,a=L(t),n=U(t);else{if(!Y.call(t,"name"))throw Error(V("name"));var s=t.name;if(r=s,Y.call(t,"weight")&&(o=t.weight)<=0)throw Error(G(s));a=L(s),n=U(s)}return{path:a,id:n,weight:o,src:r}}function L(t){return w(t)?t:t.split(".")}function U(t){return w(t)?t.join("."):t}var B={// Whether the matches should be included in the result set. When `true`, each record in the result
|
|
// set will include the indices of the matched characters.
|
|
// These can consequently be used for highlighting purposes.
|
|
includeMatches:!1,// When `true`, the matching function will continue to the end of a search pattern even if
|
|
// a perfect match has already been located in the string.
|
|
findAllMatches:!1,// Minimum number of characters that must be matched before a result is considered a match
|
|
minMatchCharLength:1},W={// Approximately where in the text is the pattern expected to be found?
|
|
location:0,// At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
|
|
// (of both letters and location), a threshold of '1.0' would match anything.
|
|
threshold:.6,// Determines how close the match must be to the fuzzy location (specified above).
|
|
// An exact letter match which is 'distance' characters away from the fuzzy location
|
|
// would score as a complete mismatch. A distance of '0' requires the match be at
|
|
// the exact location specified, a threshold of '1000' would require a perfect match
|
|
// to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
|
|
distance:100},K={// When `true`, it enables the use of unix-like search commands
|
|
useExtendedSearch:!1,// The get function to use when fetching an object's properties.
|
|
// The default will search nested paths *ie foo.bar.baz*
|
|
getFn:function(t,a){var n=[],r=!1;return function t(a,o,s){if(_(a)){if(o[s]){var l=a[o[s]];if(_(l)){// If we're at the last value in the path, and if it's a string/number/bool,
|
|
// add it to the list
|
|
if(s===o.length-1&&(F(l)||A(l)||E(l)))n.push(I(l));else if(w(l)){r=!0;// Search each item in the array.
|
|
for(var c=0,p=l.length;c<p;c+=1)t(l[c],o,s+1)}else o.length&&t(l,o,s+1)}}else n.push(a)}}(t,F(a)?a.split("."):a,0),r?n:n[0]},// When `true`, search will ignore `location` and `distance`, so it won't matter
|
|
// where in the string the pattern appears.
|
|
// More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score
|
|
ignoreLocation:!1,// When `true`, the calculation for the relevance score (used for sorting) will
|
|
// ignore the field-length norm.
|
|
// More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm
|
|
ignoreFieldNorm:!1,// The weight to determine how much field length norm effects scoring.
|
|
fieldNormWeight:1},q=r(r(r(r({},{// When `true`, the algorithm continues searching to the end of the input even if a perfect
|
|
// match is found before the end of the same input.
|
|
isCaseSensitive:!1,// When true, the matching function will continue to the end of a search pattern even if
|
|
includeScore:!1,// List of properties that will be searched. This also supports nested properties.
|
|
keys:[],// Whether to sort the result list, by score
|
|
shouldSort:!0,// Default sort function: sort by ascending score, ascending index
|
|
sortFn:function(t,a){return t.score===a.score?t.idx<a.idx?-1:1:t.score<a.score?-1:1}}),B),W),K),J=/[^ ]+/g;// Set to 3 decimals to reduce index size.
|
|
function Z(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,a);return{get:function(a){var o=a.match(J).length;if(n.has(o))return n.get(o);var s=parseFloat(Math.round(1/Math.pow(o,.5*t)*r)/r);return n.set(o,s),s},clear:function(){n.clear()}}}var Q=/*#__PURE__*/function(){function t(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=a.getFn,r=void 0===n?q.getFn:n,o=a.fieldNormWeight,l=void 0===o?q.fieldNormWeight:o;s(this,t),this.norm=Z(l,3),this.getFn=r,this.isCreated=!1,this.setIndexRecords()}return c(t,[{key:"setSources",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=t}},{key:"setIndexRecords",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=t}},{key:"setKeys",value:function(){var t=this,a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=a,this._keysMap={},a.forEach(function(a,n){t._keysMap[a.id]=n})}},{key:"create",value:function(){var t=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,F(this.docs[0])?this.docs.forEach(function(a,n){t._addString(a,n)}):this.docs.forEach(function(a,n){t._addObject(a,n)}),this.norm.clear())}},{key:"add",value:function(t){var a=this.size();F(t)?this._addString(t,a):this._addObject(t,a)}},{key:"removeAt",value:function(t){this.records.splice(t,1);// Change ref index of every subsquent doc
|
|
for(var a=t,n=this.size();a<n;a+=1)this.records[a].i-=1}},{key:"getValueForItemAtKeyId",value:function(t,a){return t[this._keysMap[a]]}},{key:"size",value:function(){return this.records.length}},{key:"_addString",value:function(t,a){if(!(!_(t)||R(t))){var n={v:t,i:a,n:this.norm.get(t)};this.records.push(n)}}},{key:"_addObject",value:function(t,a){var n=this,r={i:a,$:{}};this.keys.forEach(function(a,o){var s=n.getFn(t,a.path);if(_(s)){if(w(s))!function(){for(var t=[],a=[{nestedArrIndex:-1,value:s}];a.length;){var l=a.pop(),c=l.nestedArrIndex,p=l.value;if(_(p)){if(F(p)&&!R(p)){var f={v:p,i:c,n:n.norm.get(p)};t.push(f)}else w(p)&&p.forEach(function(t,n){a.push({nestedArrIndex:n,value:t})})}}r.$[o]=t}();else if(!R(s)){var l={v:s,n:n.norm.get(s)};r.$[o]=l}}}),this.records.push(r)}},{key:"toJSON",value:function(){return{keys:this.keys,records:this.records}}}]),t}();function ee(t,a){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,o=void 0===r?q.getFn:r,s=n.fieldNormWeight,l=void 0===s?q.fieldNormWeight:s,c=new Q({getFn:o,fieldNormWeight:l});return c.setKeys(t.map(z)),c.setSources(a),c.create(),c}function et(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=a.getFn,r=void 0===n?q.getFn:n,o=a.fieldNormWeight,s=void 0===o?q.fieldNormWeight:o,l=t.keys,c=t.records,p=new Q({getFn:r,fieldNormWeight:s});return p.setKeys(l),p.setIndexRecords(c),p}function ei(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=a.errors,r=void 0===n?0:n,o=a.currentLocation,s=void 0===o?0:o,l=a.expectedLocation,c=void 0===l?0:l,p=a.distance,f=void 0===p?q.distance:p,d=a.ignoreLocation,g=void 0===d?q.ignoreLocation:d,h=r/t.length;if(g)return h;var u=Math.abs(c-s);return f?h+u/f:u?1:h}function ea(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:q.minMatchCharLength,n=[],r=-1,o=-1,s=0,l=t.length;s<l;s+=1){var c=t[s];c&&-1===r?r=s:c||-1===r||((o=s-1)-r+1>=a&&n.push([r,o]),r=-1)}// (i-1 - start) + 1 => i - start
|
|
return t[s-1]&&s-r>=a&&n.push([r,s-1]),n}// Machine word size
|
|
var en=32;function er(t,a,n){var r,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},s=o.location,l=void 0===s?q.location:s,c=o.distance,p=void 0===c?q.distance:c,f=o.threshold,d=void 0===f?q.threshold:f,g=o.findAllMatches,h=void 0===g?q.findAllMatches:g,u=o.minMatchCharLength,m=void 0===u?q.minMatchCharLength:u,y=o.includeMatches,v=void 0===y?q.includeMatches:y,k=o.ignoreLocation,b=void 0===k?q.ignoreLocation:k;if(a.length>en)throw Error(j(en));for(var O=a.length,T=t.length,x=Math.max(0,Math.min(l,T)),w=d,S=x,C=m>1||v,I=C?Array(T):[];(r=t.indexOf(a,S))>-1;)if(w=Math.min(ei(a,{currentLocation:r,expectedLocation:x,distance:p,ignoreLocation:b}),w),S=r+O,C)for(var F=0;F<O;)I[r+F]=1,F+=1;// Reset the best location
|
|
S=-1;for(var A=[],E=1,N=O+T,P=1<<O-1,_=0;_<O;_+=1){for(// Scan for the best match; each iteration allows for one more error.
|
|
// Run a binary search to determine how far from the match location we can stray
|
|
// at this error level.
|
|
var R=0,D=N;R<D;)ei(a,{errors:_,currentLocation:x+D,expectedLocation:x,distance:p,ignoreLocation:b})<=w?R=D:N=D,D=Math.floor((N-R)/2+R);// Use the result from this iteration as the maximum for the next.
|
|
N=D;var M=Math.max(1,x-D+1),H=h?T:Math.min(x+D,T)+O,V=Array(H+2);V[H+1]=(1<<_)-1;for(var G=H;G>=M;G-=1){var Y=G-1,X=n[t.charAt(Y)];if(C&&(I[Y]=+!!X),// First pass: exact match
|
|
V[G]=(V[G+1]<<1|1)&X,_&&(V[G]|=(A[G+1]|A[G])<<1|1|A[G+1]),V[G]&P&&(E=ei(a,{errors:_,currentLocation:Y,expectedLocation:x,distance:p,ignoreLocation:b}))<=w){if(// Indeed it is
|
|
w=E,(S=Y)<=x)break;// When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.
|
|
M=Math.max(1,2*x-S)}}// No hope for a (better) match at greater error levels.
|
|
if(ei(a,{errors:_+1,currentLocation:x,expectedLocation:x,distance:p,ignoreLocation:b})>w)break;A=V}var z={isMatch:S>=0,// Count exact matches (those with a score of 0) to be "almost" exact
|
|
score:Math.max(.001,E)};if(C){var L=ea(I,m);L.length?v&&(z.indices=L):z.isMatch=!1}return z}function eo(t){for(var a={},n=0,r=t.length;n<r;n+=1){var o=t.charAt(n);a[o]=(a[o]||0)|1<<r-n-1}return a}var es=/*#__PURE__*/function(){function t(a){var n=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=r.location,l=void 0===o?q.location:o,c=r.threshold,p=void 0===c?q.threshold:c,f=r.distance,d=void 0===f?q.distance:f,g=r.includeMatches,h=void 0===g?q.includeMatches:g,u=r.findAllMatches,m=void 0===u?q.findAllMatches:u,y=r.minMatchCharLength,v=void 0===y?q.minMatchCharLength:y,k=r.isCaseSensitive,b=void 0===k?q.isCaseSensitive:k,O=r.ignoreLocation,T=void 0===O?q.ignoreLocation:O;if(s(this,t),this.options={location:l,threshold:p,distance:d,includeMatches:h,findAllMatches:m,minMatchCharLength:v,isCaseSensitive:b,ignoreLocation:T},this.pattern=b?a:a.toLowerCase(),this.chunks=[],this.pattern.length){var x=function(t,a){n.chunks.push({pattern:t,alphabet:eo(t),startIndex:a})},w=this.pattern.length;if(w>en){for(var S=0,C=w%en,I=w-C;S<I;)x(this.pattern.substr(S,en),S),S+=en;if(C){var F=w-en;x(this.pattern.substr(F),F)}}else x(this.pattern,0)}}return c(t,[{key:"searchIn",value:function(t){var a=this.options,n=a.isCaseSensitive,r=a.includeMatches;// Exact match
|
|
if(n||(t=t.toLowerCase()),this.pattern===t){var o={isMatch:!0,score:0};return r&&(o.indices=[[0,t.length-1]]),o}// Otherwise, use Bitap algorithm
|
|
var s=this.options,l=s.location,c=s.distance,p=s.threshold,f=s.findAllMatches,d=s.minMatchCharLength,g=s.ignoreLocation,h=[],u=0,m=!1;this.chunks.forEach(function(a){var n=a.pattern,o=a.alphabet,s=a.startIndex,y=er(t,n,o,{location:l+s,distance:c,threshold:p,findAllMatches:f,minMatchCharLength:d,includeMatches:r,ignoreLocation:g}),k=y.isMatch,b=y.score,O=y.indices;k&&(m=!0),u+=b,k&&O&&(h=[].concat(v(h),v(O)))});var y={isMatch:m,score:m?u/this.chunks.length:1};return m&&r&&(y.indices=h),y}}]),t}(),el=/*#__PURE__*/function(){function t(a){s(this,t),this.pattern=a}return c(t,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(t){return ec(t,this.multiRegex)}},{key:"isSingleMatch",value:function(t){return ec(t,this.singleRegex)}}]),t}();function ec(t,a){var n=t.match(a);return n?n[1]:null}var ep=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=t===this.pattern;return{isMatch:a,score:a?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),n}(el),ef=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=-1===t.indexOf(this.pattern);return{isMatch:a,score:a?0:1,indices:[0,t.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),n}(el),ed=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=t.startsWith(this.pattern);return{isMatch:a,score:a?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),n}(el),eg=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=!t.startsWith(this.pattern);return{isMatch:a,score:a?0:1,indices:[0,t.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),n}(el),eh=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=t.endsWith(this.pattern);return{isMatch:a,score:a?0:1,indices:[t.length-this.pattern.length,t.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),n}(el),eu=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){var a=!t.endsWith(this.pattern);return{isMatch:a,score:a?0:1,indices:[0,t.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),n}(el),em=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},l=o.location,c=void 0===l?q.location:l,p=o.threshold,f=void 0===p?q.threshold:p,d=o.distance,g=void 0===d?q.distance:d,h=o.includeMatches,u=void 0===h?q.includeMatches:h,m=o.findAllMatches,y=void 0===m?q.findAllMatches:m,v=o.minMatchCharLength,k=void 0===v?q.minMatchCharLength:v,b=o.isCaseSensitive,O=void 0===b?q.isCaseSensitive:b,T=o.ignoreLocation,x=void 0===T?q.ignoreLocation:T;return s(this,n),(r=a.call(this,t))._bitapSearch=new es(t,{location:c,threshold:f,distance:g,includeMatches:u,findAllMatches:y,minMatchCharLength:k,isCaseSensitive:O,ignoreLocation:x}),r}return c(n,[{key:"search",value:function(t){return this._bitapSearch.searchIn(t)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(el),ey=/*#__PURE__*/function(t){f(n,t);var a=y(n);function n(t){return s(this,n),a.call(this,t)}return c(n,[{key:"search",value:function(t){for(var a,n=0,r=[],o=this.pattern.length;(a=t.indexOf(this.pattern,n))>-1;)n=a+o,r.push([a,n-1]);var s=!!r.length;return{isMatch:s,score:s?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(el),ev=[ep,ey,ed,eg,eu,eh,ef,em],ek=ev.length,eb=/ +(?=([^\"]*\"[^\"]*\")*[^\"]*$)/,eO="|";// Example:
|
|
// "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]]
|
|
function eT(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t.split(eO).map(function(t){for(var n=t.trim().split(eb).filter(function(t){return t&&!!t.trim()}),r=[],o=0,s=n.length;o<s;o+=1){for(var l=n[o],c=!1,p=-1;!c&&++p<ek;){var f=ev[p],d=f.isMultiMatch(l);d&&(r.push(new f(d,a)),c=!0)}if(!c)for(// 2. Handle single query matches (i.e, once that are *not* quoted)
|
|
p=-1;++p<ek;){var g=ev[p],h=g.isSingleMatch(l);if(h){r.push(new g(h,a));break}}}return r})}// to a singl match
|
|
var ex=new Set([em.type,ey.type]),ew=/*#__PURE__*/function(){function t(a){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=n.isCaseSensitive,o=void 0===r?q.isCaseSensitive:r,l=n.includeMatches,c=void 0===l?q.includeMatches:l,p=n.minMatchCharLength,f=void 0===p?q.minMatchCharLength:p,d=n.ignoreLocation,g=void 0===d?q.ignoreLocation:d,h=n.findAllMatches,u=void 0===h?q.findAllMatches:h,m=n.location,y=void 0===m?q.location:m,v=n.threshold,k=void 0===v?q.threshold:v,b=n.distance,O=void 0===b?q.distance:b;s(this,t),this.query=null,this.options={isCaseSensitive:o,includeMatches:c,minMatchCharLength:f,findAllMatches:u,ignoreLocation:g,location:y,threshold:k,distance:O},this.pattern=o?a:a.toLowerCase(),this.query=eT(this.pattern,this.options)}return c(t,[{key:"searchIn",value:function(t){var a=this.query;if(!a)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;t=n.isCaseSensitive?t:t.toLowerCase();for(var o=0,s=[],l=0,c=0,p=a.length;c<p;c+=1){var f=a[c];// Reset indices
|
|
s.length=0,o=0;for(var d=0,g=f.length;d<g;d+=1){var h=f[d],u=h.search(t),m=u.isMatch,y=u.indices,k=u.score;if(m){if(o+=1,l+=k,r){var b=h.constructor.type;ex.has(b)?s=[].concat(v(s),v(y)):s.push(y)}}else{l=0,o=0,s.length=0;break}}// OR condition, so if TRUE, return
|
|
if(o){var O={isMatch:!0,score:l/o};return r&&(O.indices=s),O}}// Nothing was matched
|
|
return{isMatch:!1,score:1}}}],[{key:"condition",value:function(t,a){return a.useExtendedSearch}}]),t}(),eS=[];function eC(){eS.push.apply(eS,arguments)}function eI(t,a){for(var n=0,r=eS.length;n<r;n+=1){var o=eS[n];if(o.condition(t,a))return new o(t,a)}return new es(t,a)}var eF={AND:"$and",OR:"$or"},eA={PATH:"$path",PATTERN:"$val"},eE=function(t){return!!(t[eF.AND]||t[eF.OR])},eN=function(t){return!!t[eA.PATH]},eP=function(t){return!w(t)&&N(t)&&!eE(t)},e_=function(t){return p({},eF.AND,Object.keys(t).map(function(a){return p({},a,t[a])}))};// the appropriate `Searcher` instance
|
|
function eR(t,a){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.auto,o=void 0===r||r,s=function t(n){var r=Object.keys(n),s=eN(n);if(!s&&r.length>1&&!eE(n))return t(e_(n));if(eP(n)){var l=s?n[eA.PATH]:r[0],c=s?n[eA.PATTERN]:n[l];if(!F(c))throw Error(H(l));var p={keyId:U(l),pattern:c};return o&&(p.searcher=eI(c,a)),p}var f={children:[],operator:r[0]};return r.forEach(function(a){var r=n[a];w(r)&&r.forEach(function(a){f.children.push(t(a))})}),f};return eE(t)||(t=e_(t)),s(t)}function eD(t,a){var n=a.ignoreFieldNorm,r=void 0===n?q.ignoreFieldNorm:n;t.forEach(function(t){var a=1;t.matches.forEach(function(t){var n=t.key,o=t.norm,s=t.score,l=n?n.weight:null;a*=Math.pow(0===s&&l?Number.EPSILON:s,(l||1)*(r?1:o))}),t.score=a})}function eM(t,a){var n=t.matches;a.matches=[],_(n)&&n.forEach(function(t){if(_(t.indices)&&t.indices.length){var n=t.indices,r=t.value,o={indices:n,value:r};t.key&&(o.key=t.key.src),t.idx>-1&&(o.refIndex=t.idx),a.matches.push(o)}})}function eH(t,a){a.score=t.score}function ej(t,a){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,o=void 0===r?q.includeMatches:r,s=n.includeScore,l=void 0===s?q.includeScore:s,c=[];return o&&c.push(eM),l&&c.push(eH),t.map(function(t){var n=t.idx,r={item:a[n],refIndex:n};return c.length&&c.forEach(function(a){a(t,r)}),r})}var eV=/*#__PURE__*/function(){function t(a){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;s(this,t),this.options=r(r({},q),n),this.options.useExtendedSearch,this._keyStore=new X(this.options.keys),this.setCollection(a,o)}return c(t,[{key:"setCollection",value:function(t,a){if(this._docs=t,a&&!(a instanceof Q))throw Error(M);this._myIndex=a||ee(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(t){_(t)&&(this._docs.push(t),this._myIndex.add(t))}},{key:"remove",value:function(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function()/* doc, idx */{return!1},a=[],n=0,r=this._docs.length;n<r;n+=1){var o=this._docs[n];t(o,n)&&(this.removeAt(n),n-=1,r-=1,a.push(o))}return a}},{key:"removeAt",value:function(t){this._docs.splice(t,1),this._myIndex.removeAt(t)}},{key:"getIndex",value:function(){return this._myIndex}},{key:"search",value:function(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=a.limit,r=void 0===n?-1:n,o=this.options,s=o.includeMatches,l=o.includeScore,c=o.shouldSort,p=o.sortFn,f=o.ignoreFieldNorm,d=F(t)?F(this._docs[0])?this._searchStringList(t):this._searchObjectList(t):this._searchLogical(t);return eD(d,{ignoreFieldNorm:f}),c&&d.sort(p),A(r)&&r>-1&&(d=d.slice(0,r)),ej(d,this._docs,{includeMatches:s,includeScore:l})}},{key:"_searchStringList",value:function(t){var a=eI(t,this.options),n=this._myIndex.records,r=[];return n.forEach(function(t){var n=t.v,o=t.i,s=t.n;if(_(n)){var l=a.searchIn(n),c=l.isMatch,p=l.score,f=l.indices;c&&r.push({item:n,idx:o,matches:[{score:p,value:n,norm:s,indices:f}]})}}),r}},{key:"_searchLogical",value:function(t){var a=this,n=eR(t,this.options),r=function t(n,r,o){if(!n.children){var s=n.keyId,l=n.searcher,c=a._findMatches({key:a._keyStore.get(s),value:a._myIndex.getValueForItemAtKeyId(r,s),searcher:l});return c&&c.length?[{idx:o,item:r,matches:c}]:[]}for(var p=[],f=0,d=n.children.length;f<d;f+=1){var g=t(n.children[f],r,o);if(g.length)p.push.apply(p,v(g));else if(n.operator===eF.AND)return[]}return p},o=this._myIndex.records,s={},l=[];return o.forEach(function(t){var a=t.$,o=t.i;if(_(a)){var c=r(n,a,o);c.length&&(s[o]||(s[o]={idx:o,item:a,matches:[]},l.push(s[o])),c.forEach(function(t){var a,n=t.matches;(a=s[o].matches).push.apply(a,v(n))}))}}),l}},{key:"_searchObjectList",value:function(t){var a=this,n=eI(t,this.options),r=this._myIndex,o=r.keys,s=r.records,l=[];return s.forEach(function(t){var r=t.$,s=t.i;if(_(r)){var c=[];// Iterate over every key (i.e, path), and fetch the value at that key
|
|
o.forEach(function(t,o){c.push.apply(c,v(a._findMatches({key:t,value:r[o],searcher:n})))}),c.length&&l.push({idx:s,item:r,matches:c})}}),l}},{key:"_findMatches",value:function(t){var a=t.key,n=t.value,r=t.searcher;if(!_(n))return[];var o=[];if(w(n))n.forEach(function(t){var n=t.v,s=t.i,l=t.n;if(_(n)){var c=r.searchIn(n),p=c.isMatch,f=c.score,d=c.indices;p&&o.push({score:f,key:a,value:n,idx:s,norm:l,indices:d})}});else{var s=n.v,l=n.n,c=r.searchIn(s),p=c.isMatch,f=c.score,d=c.indices;p&&o.push({score:f,key:a,value:s,norm:l,indices:d})}return o}}]),t}();eV.version="6.5.3",eV.createIndex=ee,eV.parseIndex=et,eV.config=q,eV.parseQuery=eR,eC(ew);var eG=eV}),parcelRequire.register("aBy72",function(t,a){$parcel$export(t.exports,"default",()=>s);var n=parcelRequire("9IngI"),r=parcelRequire("eeGZt"),o=parcelRequire("7OP4c");class s extends FormApplication{constructor(t,a,n){super({},{}),this.object=t,this.img=a,this.regenStyle=n}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-user-list",classes:["sheet"],template:"modules/token-variants/templates/userList.html",resizable:!1,minimizable:!1,title:"User To Image",width:300})}async getData(t){let a=super.getData(t),r=this.object.document.getFlag("token-variants","userMappings")||{},o=[];return game.users.forEach(t=>{o.push({avatar:t.avatar,name:t.name,apply:t.id in r&&r[t.id]===this.img,userId:t.id,color:t.color})}),a.users=o,a.invisibleImage=n.TVA_CONFIG.invisibleImage,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),(0,o.insertArtSelectButton)(t,"invisibleImage",{search:"Invisible Image",searchType:r.SEARCH_TYPE.TOKEN})}async _updateObject(t,a){let o=this.object.document.getFlag("token-variants","userMappings")||{};a.invisibleImage!==n.TVA_CONFIG.invisibleImage&&(0,n.updateSettings)({invisibleImage:(0,r.decodeURISafely)(a.invisibleImage)}),delete a.invisibleImage;let s=[this.img];for(let[t,n]of Object.entries(a))n?(o[t]&&o[t]!==this.img&&s.push(o[t]),o[t]=this.img):o[t]===this.img&&(delete o[t],o["-="+t]=null);for(let t of(0===Object.keys(o).filter(t=>!t.startsWith("-=")).length?await this.object.document.unsetFlag("token-variants","userMappings"):await this.object.document.setFlag("token-variants","userMappings",o),s))this.regenStyle(this.object,t)}}}),parcelRequire.register("6aWyX",function(t,a){$parcel$export(t.exports,"TOKEN_HUD_VARIANTS",()=>d),$parcel$export(t.exports,"renderTokenHUD",()=>g);var n=parcelRequire("eeGZt"),r=parcelRequire("7P4Bo"),o=parcelRequire("eYkM9"),s=parcelRequire("9IngI"),l=parcelRequire("aBy72"),c=parcelRequire("byeN2"),p=parcelRequire("9Z21J"),f=parcelRequire("8MWlo");let d={variants:null,actor:null};async function g(t,a,n,r="",o=null){x(n);let l=s.TVA_CONFIG.hud,c=s.TVA_CONFIG.permissions.hudFullAccess[game.user.role],p=s.TVA_CONFIG.permissions.hud[game.user.role];// Check if the HUD button should be displayed
|
|
if(!l.enableSideMenu||!p&&!c||n.flags["token-variants"]?.disableHUDButton)return;let f=game.actors.get(n.actorId);// Disable button if Token HUD Wildcard is enabled and appropriate setting is set
|
|
if(s.TVA_CONFIG.worldHud.disableIfTHWEnabled&&game.modules.get("token-hud-wildcard")?.active&&f&&f.prototypeToken.randomImg)return;let d=$(`
|
|
<div class="control-icon" data-action="token-variants-side-selector">
|
|
<img
|
|
id="token-variants-side-button"
|
|
src="modules/token-variants/img/token-images.svg"
|
|
width="36"
|
|
height="36"
|
|
title="Left-click: Image Menu
Right-click: Search & Additional settings"
|
|
/>
|
|
</div>
|
|
`);a.find("div.right").last().append(d),a.find("div.right").click(m),d.click(t=>h(t,n)),c&&d.contextmenu(r=>u(r,t,a,n))}async function h(t,a){let n=$(t.target).closest(".control-icon");// De-activate 'Status Effects'
|
|
n.closest("div.right").find("div.control-icon.effects").removeClass("active"),n.closest("div.right").find(".status-effects").removeClass("active"),// Remove contextmenu
|
|
n.find(".contextmenu").remove(),// Toggle variants side menu
|
|
n.toggleClass("active");let r=n.find(".token-variants-wrap");if(n.hasClass("active")){if(!r.length){if(!(r=await y(a)))return;n.find("img").after(r)}r.addClass("active")}else r.removeClass("active")}function u(t,a,r,s){// Display side menu if button is not active yet
|
|
let l=$(t.target).closest(".control-icon");if(l.hasClass("active")||l.addClass("active"),l.find(".contextmenu").length)// Contextmenu already displayed. Remove and activate images
|
|
l.find(".contextmenu").remove(),l.removeClass("active").trigger("click");else{// Contextmenu is not displayed. Hide images, create it and add it
|
|
l.find(".token-variants-wrap.images").removeClass("active");let t=$(`
|
|
<div class="token-variants-wrap contextmenu active">
|
|
<div class="token-variants-context-menu active">
|
|
<input class="token-variants-side-search" type="text" />
|
|
<button class="flags" type="button"><i class="fab fa-font-awesome-flag"></i><label>Flags</label></button>
|
|
<button class="file-picker" type="button"><i class="fas fa-file-import fa-fw"></i><label>Browse Folders</label></button>
|
|
<button class="effectConfig" type="button"><i class="fas fa-sun"></i><label>Mappings</label></button>
|
|
<button class="randomizerConfig" type="button"><i class="fas fa-dice"></i><label>Randomizer</label></button>
|
|
</div>
|
|
</div>
|
|
`);l.append(t),// Register contextmenu listeners
|
|
t.find(".token-variants-side-search").on("keyup",t=>b(t,s)).on("click",t=>{t.preventDefault(),t.stopPropagation()}),t.find(".flags").click(t=>{let a=canvas.tokens.get(s._id);a&&(t.preventDefault(),t.stopPropagation(),new(0,c.default)(a).render(!0))}),t.find(".file-picker").click(async t=>{t.preventDefault(),t.stopPropagation(),new FilePicker({type:"imagevideo",callback:async(t,a)=>{let r=await FilePicker.browse(a.activeSource,a.result.target),o=r.files.filter(t=>(0,n.isImage)(t)||(0,n.isVideo)(t));if(o.length){l.find(".token-variants-wrap").remove();let t=await y(s,"",o);t&&(t.addClass("active"),l.append(t))}}}).render(!0)}),t.find(".effectConfig").click(t=>{new(0,o.default)(s).render(!0)}),t.find(".randomizerConfig").click(t=>{new(0,p.default)(s).render(!0)})}}function m(t){let a=$(t.target).closest(".control-icon"),n=a.attr("data-action");switch(n){case"effects":case"thwildcard-selector":break;// Effects button
|
|
default:return}$(t.target).closest("div.right").find('.control-icon[data-action="token-variants-side-selector"]').removeClass("active"),$(t.target).closest("div.right").find(".token-variants-wrap").removeClass("active")}async function y(t,a="",r=null){let o=s.TVA_CONFIG.hud,l=s.TVA_CONFIG.worldHud,c=s.TVA_CONFIG.permissions.hudFullAccess[game.user.role],p=s.TVA_CONFIG.permissions.hud[game.user.role],d=game.actors.get(t.actorId),g=[],h=[],u=new Set,m=t=>{u.has(t.path)?g.find(a=>a.path===t.path&&a.name===t.name)||g.push(t):(g.push(t),u.add(t.path))};if(h=w(d),r)g=r.map(t=>({path:(0,n.decodeURISafely)(t),name:(0,n.getFileName)(t)}));else{if(!a&&(t.texture?.src&&t.texture?.src!==CONST.DEFAULT_TOKEN&&m({path:(0,n.decodeURISafely)(t.texture.src),name:t.flags?.["token-variants"]?.name??(0,n.getFileName)(t.texture.src)}),d)){// Insert default token image
|
|
let t=d.prototypeToken?.flags["token-variants"]?.randomImgDefault||d.prototypeToken?.flags["token-hud-wildcard"]?.default||"";// Parse directory flag and include the images
|
|
if(t&&m({path:(0,n.decodeURISafely)(t),name:(0,n.getFileName)(t)}),(c||p)&&h.forEach(t=>{for(let a of t.names)m({path:(0,n.decodeURISafely)(t.imgSrc),name:a})}),c||p){let t=d.getFlag("token-variants","directory");if(t){let a;try{let n=t.path,r=t.source,o="";r.startsWith("s3:")&&(o=r.substring(3,r.length),r="s3");let s=await FilePicker.browse(r,n,{type:"imagevideo",bucket:o});a=s.files}catch(t){a=[]}a=a.forEach(t=>{((0,n.isImage)(t)||(0,n.isVideo)(t))&&m({path:(0,n.decodeURISafely)(t),name:(0,n.getFileName)(t)})})}}if((c||p)&&l.includeWildcard&&!l.displayOnlySharedImages){// Merge wildcard images
|
|
let t=d.prototypeToken.texture.src;if(d.prototypeToken.randomImg)(await d.getTokenImages()).filter(t=>!t.includes("*")).forEach(t=>{m({path:(0,n.decodeURISafely)(t),name:(0,n.getFileName)(t)})});else if(t.includes("*")||t.includes("{")||t.includes("}")){// Modified version of Actor.getTokenImages()
|
|
let t=async()=>{if(d._tokenImages)return d._tokenImages;let t="data",a=d.prototypeToken.texture.src,n={wildcard:!0};// Support non-user sources
|
|
if(/\.s3\./.test(a)){t="s3";let{bucket:r,keyPrefix:o}=FilePicker.parseS3URL(a);r&&(n.bucket=r,a=o)}else a.startsWith("icons/")&&(t="public");// Retrieve wildcard content
|
|
try{let r=await FilePicker.browse(t,a,n);d._tokenImages=r.files}catch(t){d._tokenImages=[]}return d._tokenImages};(await t()).filter(t=>!t.includes("*")&&((0,n.isImage)(t)||(0,n.isVideo)(t))).forEach(t=>{m({path:(0,n.decodeURISafely)(t),name:(0,n.getFileName)(t)})})}}}// Perform image search if needed
|
|
if(c){let r;if(a?r=a.length>2?a:null:l.displayOnlySharedImages||d?.getFlag("token-variants","disableNameSearch")||t.name.length>2&&(r=t.name),r){let t=await (0,f.doImageSearch)(r,{searchType:n.SEARCH_TYPE.TOKEN,searchOptions:{keywordSearch:l.includeKeywords}});// Merge full search, and keywords into a single array
|
|
t&&t.forEach(t=>{t.forEach(t=>m(t))})}}}// Retrieving the possibly custom name attached as a flag to the token
|
|
let y="";y=t.flags["token-variants"]&&t.flags["token-variants"].name?t.flags["token-variants"].name:(0,n.getFileName)(t.texture.src);let b=[],T=((0,s.TVA_CONFIG).tokenConfigs||[]).flat(),x=canvas.tokens.get(t._id),S=x.document.getFlag("token-variants","userMappings")||{};for(let a of g){let r=(0,n.isImage)(a.path),o=(0,n.isVideo)(a.path),l=!!T.find(t=>t.tvImgSrc===a.path&&t.tvImgName===a.name),c=!1;s.TVA_CONFIG.permissions.hudFullAccess[game.user.role]&&h.forEach(t=>{t.imgSrc===a.path&&t.names.includes(a.name)&&(c=!0)});let[p,f]=O(S,a.path,a.name);b.push({route:a.path,name:a.name,used:a.path===t.texture.src&&a.name===y,img:r,vid:o,unknownType:!r&&!o,shared:c,hasConfig:l,title:p,style:game.user.isGM&&f?"box-shadow: "+f+";":null})}//
|
|
// Render
|
|
//
|
|
let C=o.displayAsImage,I=o.imageOpacity/100,F=$(await renderTemplate("modules/token-variants/templates/sideSelect.html",{imagesParsed:b,imageDisplay:C,imageOpacity:I,tokenHud:!0}));return(// Activate listeners
|
|
F.find("video").hover(function(){s.TVA_CONFIG.playVideoOnHover&&(this.play(),$(this).siblings(".fa-play").hide())},function(){s.TVA_CONFIG.pauseVideoOnHoverOut&&(this.pause(),this.currentTime=0,$(this).siblings(".fa-play").show())}),F.find(".token-variants-button-select").click(a=>v(a,t._id)),c&&F.find(".token-variants-button-select").on("contextmenu",a=>k(a,t._id)),F)}async function v(t,a){t.preventDefault(),t.stopPropagation();let o=canvas.tokens.controlled.find(t=>t.document.id===a);if(!o)return;let l=s.TVA_CONFIG.worldHud,c=$(t.target).closest(".token-variants-button-select"),p=c.attr("data-name"),f=c.attr("data-filename");if(p&&f){if((0,n.keyPressed)("config")&&game.user.isGM){let t=t=>{let a=c.find(".fa-cog");t?a.addClass("active"):a.removeClass("active")};new(0,r.default)(o,{},p,f,t).render(!0)}else if(o.document.texture.src===p){let t=o.document.getFlag("token-variants","name");t||(t=(0,n.getFileName)(o.document.texture.src)),t!==f&&(await (0,n.updateTokenImage)(p,{token:o,imgName:f,animate:l.animate}),o.actor&&l.updateActorImage&&(l.useNameSimilarity?T(p,f,o.actor):(0,n.updateActorImage)(o.actor,p,{imgName:f})))}else await (0,n.updateTokenImage)(p,{token:o,imgName:f,animate:l.animate}),o.actor&&l.updateActorImage&&(l.useNameSimilarity?T(p,f,o.actor):(0,n.updateActorImage)(o.actor,p,{imgName:f}))}}async function k(t,a){t.preventDefault(),t.stopPropagation();let r=canvas.tokens.controlled.find(t=>t.document.id===a);if(!r)return;let o=$(t.target).closest(".token-variants-button-select"),s=o.attr("data-name"),c=o.attr("data-filename");if(s&&c){if((0,n.keyPressed)("config")&&game.user.isGM){let t=(t,a)=>{let n=t.document.getFlag("token-variants","userMappings")||{},r=o.attr("data-filename"),[s,l]=O(n,a,r);o.closest(".token-variants-wrap").find(`.token-variants-button-select[data-name='${a}']`).css("box-shadow",l).prop("title",s)};new(0,l.default)(r,s,t).render(!0)}else if(r.actor){let t=game.actors.get(r.actor.id),a=w(t),n=!1,l=!1;for(let t of a)if(t.imgSrc===s){let a=t.names.filter(t=>t!=t);0===a.length?n=!0:a.length===t.names.length&&a.push(c),t.names=a,l=!0;break}n?a=a.filter(t=>t.imgSrc!==s):l||a.push({imgSrc:s,names:[c]}),// Set shared variants as an actor flag
|
|
S(t,a),o.find(".fa-share").toggleClass("active")}}}async function b(t,a){if(t.preventDefault(),t.stopPropagation(),("Enter"===t.key||13===t.keyCode)&&t.target.value.length>=3){let n=$(t.target).closest(".control-icon");n.find(".token-variants-wrap").remove();let r=await y(a,t.target.value);r&&(r.addClass("active"),n.append(r))}}function O(t,a,n){let r=s.TVA_CONFIG.worldHud.showFullPath?a:n,o="",l=2;for(let[n,s]of Object.entries(t))if(s===a){let t=game.users.get(n);if(!t)continue;0===o.length?o=`inset 0 0 0 ${l}px ${t.color}`:o+=`, inset 0 0 0 ${l}px ${t.color}`,l+=2,r+=`
|
|
Displayed to: ${t.name}`}return[r,o]}async function T(t,a,r){let o=await (0,f.findImagesFuzzy)(a,n.SEARCH_TYPE.PORTRAIT,{algorithm:{fuzzyThreshold:.4,fuzzyLimit:50}},!0);o&&0!==o.length?(0,n.updateActorImage)(r,o[0].path,{imgName:o[0].name}):(0,n.updateActorImage)(r,t,{imgName:a})}function x(t){s.TVA_CONFIG.permissions.statusConfig[game.user.role]&&t.actorId&&game.actors.get(t.actorId)&&($('.control-icon[data-action="effects"]').find("img:first").click(a=>{a.preventDefault(),(0,n.keyPressed)("config")&&(a.stopPropagation(),new(0,o.default)(t).render(!0))}),$('.control-icon[data-action="visibility"]').find("img").click(a=>{a.preventDefault(),(0,n.keyPressed)("config")&&(a.stopPropagation(),new(0,o.default)(t,{createMapping:{label:"In Combat",expression:"token-variants-visibility"}}).render(!0))}),$('.control-icon[data-action="combat"]').find("img").click(a=>{a.preventDefault(),(0,n.keyPressed)("config")&&(a.stopPropagation(),new(0,o.default)(t,{createMapping:{label:"In Combat",expression:"token-variants-combat"}}).render(!0))}),$(".status-effects").find("img").click(a=>{if(a.preventDefault(),(0,n.keyPressed)("config")){a.stopPropagation();let n=a.target.getAttribute("title");"pf2e"===game.system.id&&(n=$(a.target).closest("picture").attr("title")),new(0,o.default)(t,{createMapping:{label:n,expression:n}}).render(!0)}}))}function w(t){return d.variants?d.variants:t?.getFlag("token-variants","variants")||[]}function S(t,a){d.variants=a,d.actor=t}}),parcelRequire.register("eYkM9",function(t,a){let n;$parcel$export(t.exports,"default",()=>v),$parcel$export(t.exports,"sortMappingsToGroups",()=>O);var r=parcelRequire("coMHP"),o=parcelRequire("eeGZt"),s=parcelRequire("7P4Bo"),l=parcelRequire("9IngI"),c=parcelRequire("b9QOF"),p=parcelRequire("4pjFr"),f=parcelRequire("4rd87"),d=parcelRequire("cs88A"),g=parcelRequire("ce8jp"),h=parcelRequire("dmUqi"),u=parcelRequire("bFZU7"),m=parcelRequire("fTFXO");let y="modules\\token-variants\\img\\empty.webp";class v extends FormApplication{constructor(t,{globalMappings:a=!1,callback:r=null,createMapping:o=null}={}){super({},{title:(a?"GLOBAL ":"ACTOR ")+"Mappings"}),this.token=t,a&&(this.globalMappings=deepClone(l.TVA_CONFIG.globalMappings).filter(Boolean)),a||(this.objectToFlag=game.actors.get(t.actorId)),this.callback=r,n=game.settings.get("token-variants","effectMappingToggleGroups")||{Default:!0},this.createMapping=o}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-active-effect-config",classes:["sheet"],template:"modules/token-variants/templates/effectMappingForm.html",resizable:!0,minimizable:!1,closeOnSubmit:!1,width:1020,height:"auto",scrollY:["ol.token-variant-table"]})}_processConfig(t){t.config||(t.config={});let a=Object.keys(t.config).filter(a=>t.config[a]).length;return t.config.flags&&a--,t.config.tv_script&&a--,{id:t.id||randomID(8),label:t.label,expression:t.expression,codeExp:t.codeExp,hasCodeExp:!!t.codeExp,highlightedExpression:k(t.expression),imgName:t.imgName,imgSrc:t.imgSrc,isVideo:!!t.imgSrc&&(0,o.isVideo)(t.imgSrc),priority:t.priority,hasConfig:!!t.config&&!isEmpty(t.config),hasScript:t.config&&t.config.tv_script,hasTokenConfig:a>0,config:t.config,overlay:t.overlay,alwaysOn:t.alwaysOn,tokens:t.tokens,tokensString:t.tokens?.join(",")??"",tokenIDs:t.tokens?.length?"Assigned Tokens\n"+t.tokens.join("\n")+"\n\n[CLICK TO UNASSIGN]":"",disabled:t.disabled,overlayConfig:t.overlayConfig,targetActors:t.targetActors,group:t.group,parentID:t.overlayConfig?.parentID}}async getData(t){let a=super.getData(t);a.NO_IMAGE=y;let n=[];if(this.object.mappings)n=this.object.mappings.map(this._processConfig);else{let t=this.globalMappings??(0,l.getFlagMappings)(this.objectToFlag);n=t.map(this._processConfig),this.createMapping&&!t.find(t=>t.expression===this.createMapping.expression)&&n.push(this._processConfig(this._getNewEffectConfig(this.createMapping))),this.createMapping=null}n=n.sort((t,a)=>{if(!t.label&&a.label)return -1;if(t.label&&!a.label)return 1;if(!t.overlayConfig?.parentID&&a.overlayConfig?.parentID)return -1;if(t.overlayConfig?.parentID&&!a.overlayConfig?.parentID)return 1;let n=t.priority-a.priority;return 0===n?t.label.localeCompare(a.label):n});let[r,o]=O(n);return a.groups=Object.keys(o),this.object.mappings=r,a.groupedMappings=o,a.global=!!this.globalMappings,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find(".delete-mapping").click(this._onRemove.bind(this)),t.find(".clone-mapping").click(this._onClone.bind(this)),t.find(".create-mapping").click(this._onCreate.bind(this)),t.find(".save-mappings").click(this._onSaveMappings.bind(this)),l.TVA_CONFIG.permissions.image_path_button[game.user.role]&&(t.find(".mapping-image img").click(this._onImageClick.bind(this)),t.find(".mapping-image img").mousedown(this._onImageMouseDown.bind(this)),t.find(".mapping-image video").click(this._onImageClick.bind(this)),t.find(".mapping-target").click(this._onConfigureApplicableActors.bind(this))),t.find(".mapping-image img").contextmenu(this._onImageRightClick.bind(this)),t.find(".mapping-image video").contextmenu(this._onImageRightClick.bind(this)),t.find(".mapping-config i.config").click(this._onConfigClick.bind(this)),t.find(".mapping-config i.config-edit").click(this._onConfigEditClick.bind(this)),t.find(".mapping-config i.config-script").click(this._onConfigScriptClick.bind(this)),t.find(".mapping-overlay i.overlay-config").click(this._onOverlayConfigClick.bind(this)),t.on("contextmenu",".mapping-overlay i.overlay-config",this._onOverlayConfigRightClick.bind(this)),t.find(".mapping-overlay input").on("change",this._onOverlayChange).trigger("change"),t.find(".div-input").on("input paste focus click",this._onExpressionChange),t.find(".group-toggle > a").on("click",this._onGroupToggle.bind(this)).each(function(){let t=$(this).closest(".group-toggle"),a=t.data("group");n[a]||$(this).trigger("click")}),this.setPosition({width:1020}),t.find(".mapping-disable > input").on("change",this._onDisable.bind(this)),t.find(".group-disable > a").on("click",this._onGroupDisable.bind(this)),t.find(".group-delete").on("click",this._onGroupDelete.bind(this)),t.find(".mapping-group > input").on("change",this._onGroupChange.bind(this)),t.find(".expression-switch").on("click",this._onExpressionSwitch.bind(this)),t.find(".expression-code textarea").focus(t=>$(t.target).animate({height:"10em"},500,()=>this.setPosition())).focusout(t=>$(t.target).animate({height:"1em"},500,()=>{this._state===Application.RENDER_STATES.RENDERED&&this.setPosition()})),t.find(".tokens").on("click",this._onTokensRemove.bind(this))}async _onTokensRemove(t){await this._onSubmit(t);let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];n.tokens=void 0,this.render()}_onExpressionSwitch(t){let a=$(t.target).closest(".expression-container"),n=a.find(".div-input"),r=a.find(".expression-code");r.hasClass("hidden")?(r.removeClass("hidden"),n.addClass("hidden")):(r.addClass("hidden"),n.removeClass("hidden"))}async _onDisable(t){let a=$(t.target).closest(".table-row").data("group"),n=$(t.target).closest(".token-variant-table").find(`.group-disable[data-group="${a}"]`),r=$(t.target).closest(".token-variant-table").find(`[data-group="${a}"] > .mapping-disable`),o=r.find("input:checked").length;r.length!==o?n.addClass("active"):n.removeClass("active")}async _onGroupDisable(t){let a=$(t.target).closest(".group-disable"),n=a.data("group"),r=$(t.target).closest("form").find(`[data-group="${n}"]`).find(".mapping-disable > input");a.hasClass("active")?(a.removeClass("active"),r.prop("checked",!0)):(a.addClass("active"),r.prop("checked",!1))}async _onGroupDelete(t){let a=$(t.target).closest(".group-delete"),n=a.data("group");await this._onSubmit(t),this.object.mappings=this.object.mappings.filter(t=>t.group!==n),this.render()}async _onGroupChange(t){let a=$(t.target),n=a.val().trim();n||(n="Default"),a.val(n),await this._onSubmit(t),this.render()}_onGroupToggle(t){let a=$(t.target).closest(".group-toggle"),r=a.data("group"),o=$(t.target).closest("form");o.find(`li[data-group="${r}"]`).toggle(),a.hasClass("active")?(a.removeClass("active"),a.find("i").addClass("fa-rotate-180"),n[r]=!1):(a.addClass("active"),a.find("i").removeClass("fa-rotate-180"),n[r]=!0),game.settings.set("token-variants","effectMappingToggleGroups",n),this.setPosition({height:"auto"})}async _onExpressionChange(t){var a=t.target;// The rest of the function is to handle operator highlighting and management of the caret position
|
|
if(// Update the hidden input field so that the text entered in the div will be submitted via the form
|
|
$(a).siblings("input").val(t.target.innerText),!a.childNodes.length)return;// Calculate the true/total caret offset within the div
|
|
let n=window.getSelection(),r=n.focusNode,o=n.focusOffset;for(let t of a.childNodes){if(t===r||t.childNodes[0]===r)break;o+="SPAN"===t.nodeName?t.innerText.length:t.length}// Highlight the operators and update the div
|
|
let s=k(t.target.innerText);$(t.target).html(s),// Set the new caret position with the div
|
|
b(a,o)}async _onOverlayChange(t){t.target.checked?$(t.target).siblings("a").show():$(t.target).siblings("a").hide()}async _onOverlayConfigClick(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];new(0,f.OverlayConfig)(n.overlayConfig,t=>{n.overlayConfig=t;let r=$(a).find(".mapping-overlay > a");t?.parentID&&"TOKEN"!==t.parentID?(r.addClass("child"),r.attr("title","Child Of: "+t.parentID)):(r.removeClass("child"),r.attr("title",""))},n.id,this.token).render(!0)}async _onOverlayConfigRightClick(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];(0,d.showOverlayJsonConfigDialog)(n.overlayConfig,t=>n.overlayConfig=t)}async _toggleActiveControls(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index],r=$(t.target).closest(".mapping-config").find(".config"),o=$(t.target).closest(".mapping-config").find(".config-edit"),s=$(t.target).closest(".mapping-config").find(".config-script"),l=Object.keys(n.config).filter(t=>n.config[t]).length;n.config.flags&&l--,n.config.tv_script&&l--,l?r.addClass("active"):r.removeClass("active"),Object.keys(n.config).filter(t=>n.config[t]).length?o.addClass("active"):o.removeClass("active"),n.config.tv_script?s.addClass("active"):s.removeClass("active")}async _onConfigScriptClick(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];new(0,p.default)(n.config?.tv_script,a=>{n.config||(n.config={}),a?n.config.tv_script=a:delete n.config.tv_script,this._toggleActiveControls(t)}).render(!0)}async _onConfigEditClick(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];new(0,c.default)(n.config,a=>{n.config=a,this._toggleActiveControls(t)}).render(!0)}async _onConfigClick(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];new(0,s.default)(this.token,{},null,null,a=>{(!a||isEmpty(a))&&((a={}).tv_script=n.config.tv_script,a.flags=n.config.flags),n.config=a,this._toggleActiveControls(t)},n.config?n.config:{}).render(!0)}_removeImage(t){let a=$(t.target).closest(".mapping-image").find("video"),n=$(t.target).closest(".mapping-image").find("img");a.add(n).attr("src","").attr("title",""),a.hide(),n.show(),n.attr("src",y),$(t.target).siblings(".imgSrc").val(""),$(t.target).siblings(".imgName").val("")}async _onImageMouseDown(t){2===t.which&&this._removeImage(t)}async _onImageClick(t){if((0,o.keyPressed)("config")){this._removeImage(t);return}let a=this.token.name;if("Unknown"===a){let n=t.currentTarget.closest(".table-row"),r=this.object.mappings[n.dataset.index];a=r.label}(0,r.showArtSelect)(a,{searchType:o.SEARCH_TYPE.TOKEN,callback:(a,n)=>{let r=$(t.target).closest(".mapping-image").find("video"),s=$(t.target).closest(".mapping-image").find("img");r.add(s).attr("src",a).attr("title",n),(0,o.isVideo)(a)?(r.show(),s.hide()):(r.hide(),s.show()),$(t.target).siblings(".imgSrc").val(a),$(t.target).siblings(".imgName").val(n)}})}async _onImageRightClick(t){if((0,o.keyPressed)("config")){this._removeImage(t);return}let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index];new FilePicker({type:"imagevideo",current:n.imgSrc,callback:a=>{let n=$(t.target).closest(".mapping-image").find("video"),r=$(t.target).closest(".mapping-image").find("img");n.add(r).attr("src",a).attr("title",(0,o.getFileName)(a)),(0,o.isVideo)(a)?(n.show(),r.hide()):(n.hide(),r.show()),$(t.target).siblings(".imgSrc").val(a),$(t.target).siblings(".imgName").val((0,o.getFileName)(a))}}).render()}async _onRemove(t){t.preventDefault(),await this._onSubmit(t);let a=t.currentTarget.closest(".table-row");this.object.mappings.splice(a.dataset.index,1),this.render()}async _onClone(t){t.preventDefault(),await this._onSubmit(t);let a=t.currentTarget.closest(".table-row"),n=deepClone(this.object.mappings[a.dataset.index]);n.label=n.label+" - Copy",n.id=randomID(8),this.object.mappings.push(n),this.render()}async _onCreate(t){t.preventDefault(),await this._onSubmit(t),this.object.mappings.push(this._getNewEffectConfig()),this.render()}_getNewEffectConfig({label:t="",expression:a=""}={}){return(// if (textOverlay) {
|
|
// TOGGLED_GROUPS['Text Overlays'] = true;
|
|
// return {
|
|
// id: randomID(8),
|
|
// label: label,
|
|
// expression: label,
|
|
// highlightedExpression: highlightOperators(label),
|
|
// imgName: '',
|
|
// imgSrc: '',
|
|
// priority: 50,
|
|
// overlay: false,
|
|
// alwaysOn: false,
|
|
// disabled: false,
|
|
// group: 'Text Overlays',
|
|
// overlay: true,
|
|
// overlayConfig: mergeObject(
|
|
// DEFAULT_OVERLAY_CONFIG,
|
|
// {
|
|
// img: '',
|
|
// linkScale: false,
|
|
// linkRotation: false,
|
|
// linkMirror: false,
|
|
// offsetY: 0.5 + Math.round(Math.random() * 0.3 * 100) / 100,
|
|
// offsetX: 0,
|
|
// scaleX: 0.68,
|
|
// scaleY: 0.68,
|
|
// text: {
|
|
// text: '{{effect}}',
|
|
// fontFamily: CONFIG.defaultFontFamily,
|
|
// fontSize: 36,
|
|
// fill: new Color(Math.round(Math.random() * 16777215)).toString(),
|
|
// stroke: '#000000',
|
|
// strokeThickness: 2,
|
|
// dropShadow: false,
|
|
// curve: {
|
|
// radius: 160,
|
|
// invert: false,
|
|
// },
|
|
// },
|
|
// animation: {
|
|
// rotate: true,
|
|
// duration: 10000 + Math.round(Math.random() * 14000) + 10000,
|
|
// clockwise: true,
|
|
// },
|
|
// },
|
|
// { inplace: false }
|
|
// ),
|
|
// };
|
|
// } else {
|
|
n.Default=!0,mergeObject(deepClone(g.DEFAULT_ACTIVE_EFFECT_CONFIG),{label:t,expression:a,id:randomID(8)}));// }
|
|
}_getHeaderButtons(){let t=super._getHeaderButtons();return t.unshift({label:"Export",class:"token-variants-export",icon:"fas fa-file-export",onclick:t=>this._exportConfigs(t)}),t.unshift({label:"Import",class:"token-variants-import",icon:"fas fa-file-import",onclick:t=>this._importConfigs(t)}),t.unshift({label:"Templates",class:"token-variants-templates",icon:"fa-solid fa-book",onclick:async t=>{new(0,m.Templates)({mappings:this.globalMappings??(0,l.getFlagMappings)(this.objectToFlag),callback:(a,n)=>{this._insertMappings(t,n)}}).render(!0)}}),this.globalMappings||(t.unshift({label:"Copy Global Config",class:"token-variants-copy-global",icon:"fas fa-globe",onclick:t=>this._copyGlobalConfig(t)}),t.unshift({label:"Open Global",class:"token-variants-open-global",icon:"fas fa-globe",onclick:async t=>{await this.close(),new v(this.token,{globalMappings:!0}).render(!0)}}),t.unshift({label:"",class:"token-variants-print-token",icon:"fa fa-print",onclick:()=>(0,d.showTokenCaptureDialog)(canvas.tokens.get(this.token._id))})),t}async _exportConfigs(t){let a;let n="";if(this.globalMappings)a={globalMappings:deepClone(l.TVA_CONFIG.globalMappings)},n="token-variants-global-mappings.json";else{a={globalMappings:deepClone((0,l.getFlagMappings)(this.objectToFlag))};let t=this.objectToFlag.name??"Actor";n="token-variants-"+(t=t.replace(/[/\\?%*:|"<>]/g,"-"))+".json"}a&&!isEmpty(a)&&saveDataToFile(JSON.stringify(a,null,2),"text/json",n)}async _importConfigs(t){let a=await renderTemplate("templates/apps/import-data.html",{entity:"token-variants",name:"settings"}),n=new Promise((n,r)=>{new Dialog({title:"Import Effect Configurations",content:a,buttons:{import:{icon:'<i class="fas fa-file-import"></i>',label:game.i18n.localize("token-variants.common.import"),callback:a=>{let r=a.find("form")[0];if(!r.data.files.length)return ui.notifications?.error("You did not upload a data file!");readTextFromFile(r.data.files[0]).then(a=>{if(!(a=JSON.parse(a))||!("globalMappings"in a))return ui.notifications?.error("No mappings found within the file!");this._insertMappings(t,(0,l.migrateMappings)(a.globalMappings)),n(!0)})}},no:{icon:'<i class="fas fa-times"></i>',label:"Cancel",callback:t=>n(!1)}},default:"import"},{width:400}).render(!0)});return await n}_copyGlobalConfig(t){(0,d.showMappingSelectDialog)(l.TVA_CONFIG.globalMappings,{title1:"Global Mappings",title2:"Select Mappings to Copy:",buttonTitle:"Copy",callback:a=>{this._insertMappings(t,a)}})}async _insertMappings(t,a){let n=deepClone(a).map(this._processConfig);await this._onSubmit(t),(0,o.mergeMappings)(n,this.object.mappings),this.render()}_onConfigureApplicableActors(t){let a=t.currentTarget.closest(".table-row"),n=this.object.mappings[a.dataset.index],r=(game.system.entityTypes??game.system.documentTypes).Actor,o=[];for(let t of r){let a=CONFIG.Actor?.typeLabels?.[t]??t;o.push({id:t,label:game.i18n.has(a)?game.i18n.localize(a):t,enabled:!n.targetActors||n.targetActors.includes(t)})}let s='<form style="overflow-y: scroll; height:250x;">';for(let t of o)s+=`
|
|
<div class="form-group">
|
|
<label>${t.label}</label>
|
|
<div class="form-fields">
|
|
<input type="checkbox" name="${t.id}" data-dtype="Boolean" ${t.enabled?"checked":""}>
|
|
</div>
|
|
</div>
|
|
`;s+='</form><div class="form-group"><button type="button" class="select-all">Select all</div>',new Dialog({title:"Configure Applicable Actors",content:s,buttons:{Ok:{label:"Save",callback:async t=>{let a=[];t.find('input[type="checkbox"]').each(function(){this.checked&&a.push(this.name)}),n.targetActors=a}}},render:t=>{t.find(".select-all").click(()=>{t.find('input[type="checkbox"]').prop("checked",!0)})}}).render(!0)}// TODO fix this spaghetti code related to globalMappings...
|
|
async _onSaveMappings(t){if(await this._onSubmit(t),this.objectToFlag||this.globalMappings){// First filter out empty mappings
|
|
let t=this.object.mappings;// Make sure a priority is assigned
|
|
for(let a of t=t.filter(t=>!!t.label?.trim()||!!t.expression?.trim()))a.priority=a.priority?a.priority:50,a.overlayConfig=a.overlayConfig??{},a.overlayConfig.label=a.label;if(0!==t.length){let a=t.map(t=>mergeObject(g.DEFAULT_ACTIVE_EFFECT_CONFIG,t,{inplace:!1,insertKeys:!1,recursive:!1}));this.globalMappings?(0,l.updateSettings)({globalMappings:a}):await this.objectToFlag.setFlag("token-variants","effectMappings",a)}else this.globalMappings?(0,l.updateSettings)({globalMappings:[]}):await this.objectToFlag.unsetFlag("token-variants","effectMappings");let a=this.globalMappings?canvas.tokens.placeables:this.objectToFlag.getActiveTokens();for(let t of a)l.TVA_CONFIG.filterEffectIcons&&await t.drawEffects(),await (0,h.updateWithEffectMapping)(t),(0,u.drawOverlays)(t);// Instruct users on other scenes to refresh the overlays
|
|
let n={handlerName:"drawOverlays",args:{all:!0,sceneId:canvas.scene.id},type:"UPDATE"};game.socket?.emit("module.token-variants",n)}this.callback&&this.callback(),this.close()}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){let n=expandObject(a).mappings??{};// Merge form data with internal mappings
|
|
for(let t=0;t<this.object.mappings.length;t++){let a=n[t],r=this.object.mappings[t];r.id=a.id,r.label=a.label.replaceAll(String.fromCharCode(160)," "),r.expression=a.expression.replaceAll(String.fromCharCode(160)," "),r.codeExp=a.codeExp?.trim(),r.imgSrc=a.imgSrc,r.imgName=a.imgName,r.priority=a.priority,r.overlay=a.overlay,r.alwaysOn=a.alwaysOn,r.tokens=a.tokens?.split(","),r.disabled=a.disabled,r.group=a.group}}}// Insert <span/> around operators
|
|
function k(t){// text = text.replaceAll(' ', ' ');
|
|
let a=RegExp('([a-zA-Z\\.\\-\\|\\+]+)([><=]+)(".*?"|-?\\d+)(%{0,1})',"gi");for(let n of(t=t.replace(a,function(t){return'<span class="hp-expression">'+t+"</span>"}),["\\(","\\)","&&","||","\\!","\\*","\\{","\\}"]))t=t.replaceAll(n,`<span>${n}</span>`);return t}// Move caret to a specific point in a DOM element
|
|
function b(t,a){for(var n of t.childNodes)if(3==n.nodeType){if(n.length>=a){var r=document.createRange(),o=window.getSelection();return r.setStart(n,a),r.collapse(!0),o.removeAllRanges(),o.addRange(r),-1;// We are done
|
|
}a-=n.length}else if(-1==(a=b(n,a)))return -1;// No need to finish the for loop
|
|
return a}function O(t){t.sort((t,a)=>{if(!t.label&&a.label)return -1;if(t.label&&!a.label)return 1;if(!t.overlayConfig?.parentID&&a.overlayConfig?.parentID)return -1;if(t.overlayConfig?.parentID&&!a.overlayConfig?.parentID)return 1;let n=t.priority-a.priority;return 0===n?t.label.localeCompare(a.label):n});let a={Default:{list:[],active:!1}};return t.forEach((t,n)=>{t.i=n,t.group&&t.group.trim()||(t.group="Default"),t.group in a||(a[t.group]={list:[],active:!1}),t.disabled||(a[t.group].active=!0),a[t.group].list.push(t)}),[t,a]}}),parcelRequire.register("b9QOF",function(t,a){$parcel$export(t.exports,"default",()=>n);class n extends FormApplication{constructor(t,a){super({},{}),this.config=t,this.callback=a}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-config-json-edit",classes:["sheet"],template:"modules/token-variants/templates/configJsonEdit.html",resizable:!0,minimizable:!1,title:"Edit Token Configuration",width:400,height:380})}async getData(t){let a=super.getData(t);return a.hasConfig=null!=this.config&&0!==Object.keys(this.config).length,a.config=JSON.stringify(a.hasConfig?this.config:{},null,2),a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.on("input",".command textarea",this._validateJSON.bind(this)),// Override 'Tab' key to insert spaces
|
|
t.on("keydown",".command textarea",function(t){if("Tab"===t.key&&!t.shiftKey){t.preventDefault();var a=this.selectionStart,n=this.selectionEnd;return this.value=this.value.substring(0,a)+" "+this.value.substring(n),this.selectionStart=this.selectionEnd=a+2,!1}}),t.find(".remove").click(this._onRemove.bind(this)),t.find(".format").click(this._onFormat.bind(this))}async _validateJSON(t){let a=$(t.target).closest("form").find('button[type="submit"], button.format');try{this.config=JSON.parse(t.target.value),this.config=expandObject(this.config),this.flag=this.config.flag,a.prop("disabled",!1)}catch(t){a.prop("disabled",!0)}}async _onRemove(t){this.config={},this.submit()}async _onFormat(t){$(t.target).closest("form").find('textarea[name="config"]').val(JSON.stringify(this.config,null,2))}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){this.callback&&this.callback(this.config)}}}),parcelRequire.register("4pjFr",function(t,a){$parcel$export(t.exports,"default",()=>n);class n extends FormApplication{constructor(t,a){super({},{}),this.script=t,this.callback=a}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-config-script-edit",classes:["sheet"],template:"modules/token-variants/templates/configScriptEdit.html",resizable:!0,minimizable:!1,title:"Scripts",width:640,height:640})}async getData(t){let a=super.getData(t),n=this.script?this.script:{};return a.hasScript=!isEmpty(n),a.onApply=n.onApply,a.onRemove=n.onRemove,a.macroOnApply=n.macroOnApply,a.macroOnRemove=n.macroOnRemove,a.tmfxPreset=n.tmfxPreset,a.tmfxActive=game.modules.get("tokenmagic")?.active,a.tmfxActive&&(a.tmfxPresets=TokenMagic.getPresets().map(t=>t.name)),a.ceActive=game.modules.get("dfreds-convenient-effects")?.active,a.ceActive&&(a.ceEffect=n.ceEffect??{apply:!0,remove:!0},a.ceEffects=game.dfreds.effects.all.map(t=>t.name)),a.macros=game.macros.map(t=>t.name),a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),// Override 'Tab' key to insert spaces
|
|
t.on("keydown",".command textarea",function(t){if("Tab"===t.key&&!t.shiftKey){t.preventDefault();var a=this.selectionStart,n=this.selectionEnd;return this.value=this.value.substring(0,a)+" "+this.value.substring(n),this.selectionStart=this.selectionEnd=a+2,!1}}),t.find(".remove").click(this._onRemove.bind(this))}async _onRemove(t){this.callback&&this.callback(null),this.close()}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){a=expandObject(a),["onApply","onRemove","macroOnApply","macroOnRemove"].forEach(t=>{a[t]=a[t].trim()}),a.ceEffect?.name&&(a.ceEffect.name=a.ceEffect.name.trim()),a.onApply||a.onRemove||a.tmfxPreset||a.ceEffect.name||a.macroOnApply||a.macroOnRemove?this.callback&&this.callback(a):this.callback&&this.callback(null)}}}),parcelRequire.register("cs88A",function(t,a){$parcel$export(t.exports,"showOverlayJsonConfigDialog",()=>p),$parcel$export(t.exports,"showPathSelectCategoryDialog",()=>f),$parcel$export(t.exports,"showPathSelectConfigForm",()=>d),$parcel$export(t.exports,"showTokenCaptureDialog",()=>g),$parcel$export(t.exports,"showMappingSelectDialog",()=>h),$parcel$export(t.exports,"showUserTemplateCreateDialog",()=>u),$parcel$export(t.exports,"toggleTemplateDialog",()=>m);var n=parcelRequire("dmUqi");parcelRequire("hClLE");var r=parcelRequire("9IngI"),o=parcelRequire("eeGZt"),s=parcelRequire("eYkM9"),l=parcelRequire("fTFXO"),c=parcelRequire("7P4Bo");function p(t,a){let n=deepClone(t||{});delete n.effect;let r=`<div style="height: 300px;" class="form-group stacked command"><textarea style="height: 300px;" class="configJson">${JSON.stringify(n,null,2)}</textarea></div>`;new Dialog({title:"Overlay Configuration",content:r,buttons:{yes:{icon:"<i class='fas fa-save'></i>",label:"Save",callback:t=>{let n=$(t).find(".configJson").val();if(n)try{n=JSON.parse(n)}catch(t){console.warn("TVA |",t),n={}}else n={};a(n)}}},default:"yes"}).render(!0)}async function f(t){t.preventDefault();let a=$(t.target).closest(".path-category").find("input"),n=a.val().split(","),s=(0,o.BASE_IMAGE_CATEGORIES).concat(r.TVA_CONFIG.customImageCategories),l='<div class="token-variants-popup-settings">',c=[],p=[];for(let t=0;t<s.length;t++)t>0&&t+1!=s.length&&t%4==0&&(c.push(p),p=[]),p.push(s[t]);for(let t of(p.length&&c.push(p),c)){for(let a of(l+='<header class="table-header flexrow">',t))l+=`<label>${a}</label>`;for(let a of(l+='</header><ul class="setting-list"><li class="setting form-group"><div class="form-fields">',t))l+=`<input class="category" type="checkbox" name="${a}" data-dtype="Boolean" ${n.includes(a)?"checked":""}>`;l+="</div></li></ul>"}l+="</div>",new Dialog({title:"Image Categories/Filters",content:l,buttons:{yes:{icon:"<i class='fas fa-save'></i>",label:"Apply",callback:t=>{let n=[];$(t).find(".category").each(function(){$(this).is(":checked")&&n.push($(this).attr("name"))}),a.val(n.join(","))}}},default:"yes"}).render(!0)}async function d(t){t.preventDefault();let a=$(t.target).closest(".path-config").find("input"),n={};try{n=JSON.parse(a.val())}catch(t){}let r=game.settings.get("core",DefaultTokenConfig.SETTING),o=new foundry.data.PrototypeToken(r),s=new TokenDocument(o,{actor:null});new(0,c.default)(s,{},null,null,t=>{t||(t={}),(null==t.flags||isEmpty(t.flags))&&delete t.flags,a.val(JSON.stringify(t));let n=a.siblings(".select-config");isEmpty(t)?n.removeClass("active"):n.addClass("active")},n).render(!0)}async function g(t){if(!t)return;let a=`<form>
|
|
<div class="form-group">
|
|
<label>Image Name</label>
|
|
<input type="text" name="name" value="${t.name}">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Image Path</label>
|
|
<div class="form-fields">
|
|
<input type="text" name="path" value="modules/token-variants/">
|
|
<button type="button" class="file-picker" data-type="folder" data-target="path" title="Browse Folders" tabindex="-1">
|
|
<i class="fas fa-file-import fa-fw"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group slim">
|
|
<label>Width <span class="units">(pixels)</span></label>
|
|
<div class="form-fields">
|
|
<input type="number" step="1" name="width" value="${t.mesh.texture.width}">
|
|
</div>
|
|
</div>
|
|
<div class="form-group slim">
|
|
<label>Height <span class="units">(pixels)</span></label>
|
|
<div class="form-fields">
|
|
<input type="number" step="1" name="height" value="${t.mesh.texture.height}">
|
|
</div>
|
|
</div>
|
|
<div class="form-group slim">
|
|
<label>Scale</label>
|
|
<div class="form-fields">
|
|
<input type="number" step="any" name="scale" value="3">
|
|
</div>
|
|
</div>
|
|
</form>`;new Dialog({title:"Save Token/Overlay Image",content:a,buttons:{yes:{icon:"<i class='fas fa-save'></i>",label:"Save",callback:a=>{let n={};$(a).find("[name]").each(function(){let t=parseFloat(this.value);isNaN(t)&&(t=this.value),n[this.name]=t}),(0,o.uploadTokenImage)(t,n)}}},render:t=>{t.find(".file-picker").click(()=>{new FilePicker({type:"folder",current:t.find('[name="path"]').val(),callback:a=>{t.find('[name="path"]').val(a)}}).render()})},default:"yes"}).render(!0)}function h(t,{title1:a="Mappings",title2:n="Select Mappings",buttonTitle:r="Confirm",callback:o=null}={}){if(!t||!t.length)return;let l=`<form style="overflow-y: scroll; height:400px;"><h2>${n}</h2>`,[c,p]=(0,s.sortMappingsToGroups)(t);for(let[t,a]of Object.entries(p))if(a.list.length)for(let n of(l+=`<h4 style="text-align:center;"><b>${t}</b></h4>`,a.list))l+=`
|
|
<div class="form-group">
|
|
<label>${n.label}</label>
|
|
<div class="form-fields">
|
|
<input type="checkbox" name="${n.id}" data-dtype="Boolean">
|
|
</div>
|
|
</div>
|
|
`;l+='</form><div class="form-group"><button type="button" class="select-all">Select all</div>',new Dialog({title:a,content:l,buttons:{Ok:{label:r,callback:async a=>{if(!o)return;let n=[];a.find('input[type="checkbox"]').each(function(){if(this.checked){let a=t.find(t=>t.id===this.name);if(a){let t=deepClone(a);n.push(t),delete t.targetActors}}}),o(n)}}},render:t=>{t.find(".select-all").click(()=>{t.find('input[type="checkbox"]').prop("checked",!0)})}}).render(!0)}function u(t){let a=`
|
|
<div class="form-group">
|
|
<label>Template Name</label>
|
|
<div class="form-fields">
|
|
<input type="text" name="templateName" data-dtype="String" value="">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Hover Text (optional)</label>
|
|
<div class="form-fields">
|
|
<input type="text" name="templateHint" data-dtype="String" value="">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Hover Image (optional)</label>
|
|
<div class="form-fields">
|
|
<input type="text" name="img" data-dtype="String" value="">
|
|
</div>
|
|
</div>`;new Dialog({title:"Mapping Templates",content:a,buttons:{create:{label:"Create Template",callback:a=>{let n=a.find('[name="templateName"]').val().trim(),o=a.find('[name="templateHint"]').val().trim(),s=a.find('[name="img"]').val().trim();n.trim()&&((0,r.TVA_CONFIG).templateMappings.push({id:randomID(),name:n,hint:o,img:s,mappings:deepClone(t)}),(0,r.updateSettings)({templateMappings:r.TVA_CONFIG.templateMappings}))}},cancel:{label:"Cancel"}},default:"cancel"}).render(!0)}function m(){new(0,l.Templates)({callback:(t,a)=>(0,n.toggleTemplateOnSelected)(t,a)}).render(!0)}}),parcelRequire.register("hClLE",function(t,a){$parcel$export(t.exports,"CORE_TEMPLATES",()=>n);let n=[{name:"Tint Red when HP is bellow 10%",hint:"Tint token red when HP falls bellow 10%",img:"https://user-images.githubusercontent.com/7693704/243428871-c52130b3-2f12-4de7-a86e-fabc67e865a9.png",group:"Health",mappings:[{id:"MmLSOlJx",label:"Tint Red",expression:"hp<=10%",imgName:"",imgSrc:"",priority:50,config:{texture:{tint:"#ff0000"}},overlay:!1,alwaysOn:!1,disabled:!1,overlayConfig:{label:"Tint Red"},group:"Low HP",i:0}],id:"Ob9LP35K"},{name:"Health State Text Overlay",hint:`Displays text overlay based on percentage health.
|
|
0% < hp <= 25% : Critical
|
|
25% < hp <= 50% : Bloodied
|
|
50% < hp <= 75% : Wounded
|
|
75% < hp : Healthy`,img:"https://user-images.githubusercontent.com/7693704/243426356-ceab629c-c16c-42b3-9004-af7dafb62eb7.png",group:"Health",mappings:[{id:"jqaFdwkQ",label:"Bloodied",expression:"hp>25% && hp<=50%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Bloodied",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ff5900",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Bloodied",id:"jqaFdwkQ"},group:"Health State Overlay",i:0},{id:"m4GQVz5O",label:"Critical",expression:"hp>0 && hp<=25%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Critical",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ff0000",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Critical",id:"m4GQVz5O"},group:"Health State Overlay",i:1},{id:"H1wrS5N1",label:"Healthy",expression:"hp>75%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Healthy",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#2bff00",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Healthy",id:"H1wrS5N1"},group:"Health State Overlay",i:2},{id:"IojJZS7v",label:"Wounded",expression:"hp>50% && hp<=75%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Wounded",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ffbb00",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Wounded",id:"IojJZS7v"},group:"Health State Overlay",i:3}],id:"JNClkgGU"},{name:"Health State Text Overlay - Passed Check",hint:"Same as Health State Text Overlay except also requiring the Token actor to have Reveal Health active effect applied to it.",img:"https://user-images.githubusercontent.com/7693704/243429385-f62b111c-3d9c-4cd8-9c27-f5b13e09fea2.png",group:"Health",mappings:[{id:"k0XbFE7a",label:"Bloodied",expression:"Reveal Health && hp>25% && hp<=50%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Bloodied",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ff5900",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Bloodied",id:"k0XbFE7a"},group:"Health State Overlay - Passed Check",i:0},{id:"a1VxhnWK",label:"Critical",expression:"Reveal Health && hp>0 && hp<=25%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Critical",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ff0000",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Critical",id:"a1VxhnWK"},group:"Health State Overlay - Passed Check",i:1},{id:"DNuBTXe8",label:"Healthy",expression:"Reveal Health && hp>75%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Healthy",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#2bff00",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Healthy",id:"DNuBTXe8"},group:"Health State Overlay - Passed Check",i:2},{id:"ROPjrvLu",label:"Wounded",expression:"Reveal Health && hp>50% && hp<=75%",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.51,scaleX:.76,scaleY:.76,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Wounded",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ffbb00",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:null}},label:"Wounded",id:"ROPjrvLu"},group:"Health State Overlay - Passed Check",i:3}],id:"0ZJQiOdD"},{name:"Fancy Nameplate",hint:"Displays a curved red nameplate underneath the token.",img:"https://user-images.githubusercontent.com/7693704/244439674-12510686-2f72-44b3-8a1d-e6cc7fbb00c6.png",mappings:[{id:"DTbwvQiG",label:"Token Nameplate",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{parent:"",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionX:!1,linkDimensionY:!1,linkOpacity:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.51,scaleX:.68,scaleY:.68,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"{{name}}",fontFamily:"Modesto Condensed",fontSize:36,letterSpacing:0,fill:"#ff0000",dropShadow:"true",strokeThickness:3,stroke:"#111111",curve:{radius:450,invert:!0}},shapes:[{line:{width:1,color:"#111111",alpha:1},fill:{color:"#111111",alpha:1}}],label:"Token Nameplate"},group:"Nameplate",i:0}],id:"Ik1uNcWU"},{name:"Info Box #1",hint:"Displays information about the token/actor when hovering over or controlling them. This box will adjust to canvas zoom.",img:"https://user-images.githubusercontent.com/7693704/244441852-b50f3ca6-e0c3-4ce0-b498-ddd00edcbdca.png",system:"dnd5e",group:"Info",mappings:[{id:"W8BPK9hv",label:"Box Background",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"W8BPK9hv",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!0,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.55,offsetY:0,scaleX:.73,scaleY:.73,angle:0,anchor:{x:0,y:.5},filter:"DropShadowFilter",filterOptions:{rotation:45,distance:16.9,color:"#000000",alpha:.52,shadowOnly:!1,blur:2,quality:3},alwaysVisible:!1,limitedUsers:[],limitOnHover:!0,limitOnHighlight:!1,limitOnControl:!0,limitOnEffect:"",limitOnProperty:"",text:{text:"",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"rectangle",x:"0",y:"0",width:"450",height:"200",radius:"0"},label:"",line:{width:2,color:"#ffffff",alpha:1},fill:{color:"#508fe2",color2:"",prc:"",alpha:.55}}],effect:"",label:"Box Background"},group:"Info Box",i:0},{id:"bkoP4Qpo",label:"Legendary Actions",expression:"actor.system.resources.legact.max>0",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"bkoP4Qpo",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.47,offsetY:-.02,scaleX:.5,scaleY:.5,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Legendary: Action {{actor.system.resources.legact.value}}/{{actor.system.resources.legact.max}} Resistance {{actor.system.resources.legres.value}}/{{actor.system.resources.legres.max}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Legendary Actions"},group:"Info Box",i:1},{id:"OvcWUW13",label:"Mods",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"OvcWUW13",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.38,scaleX:.57,scaleY:.57,angle:0,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"STR {{actor.system.abilities.str.mod}} DEX {{actor.system.abilities.dex.mod}} CON {{actor.system.abilities.con.mod}} INT {{actor.system.abilities.int.mod}} WIS {{actor.system.abilities.wis.mod}} CHA {{actor.system.abilities.cha.mod}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Mods"},group:"Info Box",i:2},{id:"jybTYLTB",label:"Token Name",expression:"",imgName:"",imgSrc:"",priority:51,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"jybTYLTB",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.47,offsetY:.35,scaleX:.77,scaleY:.77,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Name: {{name}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Token Name"},group:"Info Box",i:3},{id:"bGbHPbw6",label:"HP",expression:"hp>40%",imgName:"",imgSrc:"",priority:52,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"bGbHPbw6",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.47,offsetY:.23,scaleX:.82,scaleY:.82,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"HP: {{actor.system.attributes.hp.value}}/{{actor.system.attributes.hp.max}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#6b6b6b",curve:{radius:0,invert:!1}},effect:"",label:"HP"},group:"Info Box",i:4},{id:"S9gXdyGY",label:"Low HP",expression:"hp<=40%",imgName:"",imgSrc:"",priority:52,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"S9gXdyGY",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.47,offsetY:.23,scaleX:.82,scaleY:.82,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"HP: {{actor.system.attributes.hp.value}}/{{actor.system.attributes.hp.max}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#ff0000",dropShadow:"true",strokeThickness:1,stroke:"#6b6b6b",curve:{radius:0,invert:!1}},effect:"",label:"Low HP"},group:"Info Box",i:5},{id:"k9Ws74Hc",label:"Actor AC",expression:"",imgName:"",imgSrc:"",priority:53,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"k9Ws74Hc",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.25,offsetY:.46,scaleX:1,scaleY:1,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"AC: {{actor.system.attributes.ac.value}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Actor AC"},group:"Info Box",i:6},{id:"eIxjLZmy",label:"Movement Label",expression:"",imgName:"",imgSrc:"",priority:54,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"eIxjLZmy",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.25,offsetY:.2,scaleX:.61,scaleY:.61,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Movement",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Movement Label"},group:"Info Box",i:7},{id:"k5xYpZAZ",label:"Movement Walk",expression:"",imgName:"",imgSrc:"",priority:55,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"k5xYpZAZ",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.36,offsetY:-.03,scaleX:1,scaleY:1,angle:0,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"{{actor.system.attributes.movement.walk}}ft",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Movement Walk"},group:"Info Box",i:8},{id:"dHHZRQXG",label:"Movement Fly",expression:"",imgName:"",imgSrc:"",priority:56,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"dHHZRQXG",parentID:"W8BPK9hv",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.36,offsetY:-.16,scaleX:.33,scaleY:.33,angle:0,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Fly {{actor.system.attributes.movement.fly}}, Swim {{actor.system.attributes.movement.swim}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Movement Fly"},group:"Info Box",i:9}],id:"wuMcLy3T"},{name:"Info Box #2",hint:"Displays information about the token/actor when hovering over or controlling them. This box will adjust to canvas zoom.",img:"https://user-images.githubusercontent.com/7693704/244750685-81988600-5153-4d29-acb0-2c62111bed14.png",system:"dnd5e",mappings:[{id:"f0pV6Pnl",label:"Box Background",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"f0pV6Pnl",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!0,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.55,offsetY:0,scaleX:1,scaleY:1,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!0,limitOnHighlight:!1,limitOnControl:!0,limitOnEffect:"",limitOnProperty:"",text:{text:"",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"rectangle",x:"0",y:"0",width:"200",height:"300",radius:"0"},label:"",line:{width:2,color:"#ffffff",alpha:1},fill:{color:"#2e5a94",color2:"",prc:"",alpha:.9}}],effect:"",label:"Box Background"},group:"Info Box #2",i:0},{id:"n2Adi1fi",label:"HP",expression:"",imgName:"",imgSrc:"",priority:51,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"n2Adi1fi",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.45,offsetY:.42,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"HP: {{actor.system.attributes.hp.value}}/{{actor.system.attributes.hp.max}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"HP"},group:"Info Box #2",i:1},{id:"hCKVzw3Z",label:" AC",expression:"",imgName:"",imgSrc:"",priority:52,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"hCKVzw3Z",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.45,offsetY:.31,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"AC: {{actor.system.attributes.ac.value}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:" AC"},group:"Info Box #2",i:2},{id:"2nYmUTwu",label:" Speed",expression:"",imgName:"",imgSrc:"",priority:53,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"2nYmUTwu",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.45,offsetY:.2,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Speed: {{actor.system.attributes.movement.walk}}ft",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:" Speed"},group:"Info Box #2",i:3},{id:"s1NtDiUV",label:"Perception",expression:"",imgName:"",imgSrc:"",priority:54,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"s1NtDiUV",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:.15,scaleX:.84,scaleY:.84,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Perception",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Perception"},group:"Info Box #2",i:4},{id:"jYeRIoG2",label:"Passive Perception",expression:"",imgName:"",imgSrc:"",priority:55,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"jYeRIoG2",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.47,offsetY:0,scaleX:.51,scaleY:.51,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Passive: {{actor.system.skills.prc.passive}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Passive Perception"},group:"Info Box #2",i:5},{id:"KYMdkTVI",label:"Active Perception",expression:"",imgName:"",imgSrc:"",priority:56,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"KYMdkTVI",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.48,offsetY:0,scaleX:.51,scaleY:.51,angle:0,anchor:{x:1,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Active: {{actor.system.skills.prc.total}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Active Perception"},group:"Info Box #2",i:6},{id:"Ewbg54II",label:"CHA",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"Ewbg54II",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.31,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"CHA\\n{{actor.system.abilities.cha.mod}} {{actor.system.abilities.cha.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"CHA"},group:"Info Box #2",i:7},{id:"2le1Nagp",label:"CON",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"2le1Nagp",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.31,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"CON\\n{{actor.system.abilities.con.mod}} {{actor.system.abilities.con.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"CON"},group:"Info Box #2",i:8},{id:"ahKmjzLj",label:"DEX",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"ahKmjzLj",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"DEX\\n{{actor.system.abilities.dex.mod}} {{actor.system.abilities.dex.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"DEX"},group:"Info Box #2",i:9},{id:"gQzyq0zm",label:"INT",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"gQzyq0zm",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.32,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"INT\\n{{actor.system.abilities.int.mod}} {{actor.system.abilities.int.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"INT"},group:"Info Box #2",i:10},{id:"hYGg1oAt",label:"STR",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"hYGg1oAt",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.32,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"STR\\n{{actor.system.abilities.str.mod}} {{actor.system.abilities.str.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"STR"},group:"Info Box #2",i:11},{id:"uQ5zS3K6",label:"WIS",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"uQ5zS3K6",parentID:"f0pV6Pnl",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"WIS\\n{{actor.system.abilities.wis.mod}} {{actor.system.abilities.wis.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"WIS"},group:"Info Box #2",i:12}],id:"Wtq9HDsX"},{name:"Info Box #3",hint:"Displays information about the token/actor when hovering over or controlling them. This box will adjust to canvas zoom.",img:"https://user-images.githubusercontent.com/7693704/244750246-794625b9-9e1d-4322-9265-fc295f02ca2b.png",system:"dnd5e",mappings:[{id:"Gt11vjXV",label:"Box Background",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"Gt11vjXV",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!0,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.55,offsetY:0,scaleX:1,scaleY:1,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!0,limitOnHighlight:!1,limitOnControl:!0,limitOnEffect:"",limitOnProperty:"",text:{text:"",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"rectangle",x:"0",y:"0",width:"240",height:"300",radius:"0"},label:"",line:{width:2,color:"#ffffff",alpha:1},fill:{color:"#2e5a94",color2:"",prc:"",alpha:.9}}],effect:"",label:"Box Background"},group:"Info Box #3",i:0},{id:"o4XWzdDM",label:"HP",expression:"",imgName:"",imgSrc:"",priority:51,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"o4XWzdDM",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.44,offsetY:.42,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.attributes.hp.value}}/{{actor.system.attributes.hp.max}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"HP"},group:"Info Box #3",i:1},{id:"eAv2dSV6",label:"AC",expression:"",imgName:"",imgSrc:"",priority:52,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"eAv2dSV6",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.43,offsetY:.28,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.attributes.ac.value}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"AC"},group:"Info Box #3",i:2},{id:"SCfkWTni",label:"Fly Speed",expression:"",imgName:"",imgSrc:"",priority:53,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"SCfkWTni",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.04,offsetY:.13,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.attributes.movement.fly}}ft",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Fly Speed"},group:"Info Box #3",i:3},{id:"e5LPzVta",label:"Walk Speed",expression:"",imgName:"",imgSrc:"",priority:53,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"e5LPzVta",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.45,offsetY:.13,scaleX:.84,scaleY:.84,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.attributes.movement.walk}}ft",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Walk Speed"},group:"Info Box #3",i:4},{id:"XlopagaT",label:"Passive Perception",expression:"",imgName:"",imgSrc:"",priority:55,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"XlopagaT",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.45,offsetY:-.02,scaleX:.83,scaleY:.83,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.skills.prc.passive}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Passive Perception"},group:"Info Box #3",i:5},{id:"CeXgVxA0",label:"Active Perception",expression:"",imgName:"",imgSrc:"",priority:56,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"CeXgVxA0",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.03,offsetY:-.02,scaleX:.83,scaleY:.83,angle:0,anchor:{x:0,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" {{actor.system.skills.prc.total}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Active Perception"},group:"Info Box #3",i:6},{id:"0WWf1iGM",label:"CHA",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"0WWf1iGM",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.31,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"CHA\\n{{actor.system.abilities.cha.mod}} {{actor.system.abilities.cha.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"CHA"},group:"Info Box #3",i:7},{id:"AU8tTXat",label:"CON",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"AU8tTXat",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.31,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"CON\\n{{actor.system.abilities.con.mod}} {{actor.system.abilities.con.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"CON"},group:"Info Box #3",i:8},{id:"JZKNmgvY",label:"DEX",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"JZKNmgvY",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"DEX\\n{{actor.system.abilities.dex.mod}} {{actor.system.abilities.dex.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"DEX"},group:"Info Box #3",i:9},{id:"AUGurJtx",label:"INT",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"AUGurJtx",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.32,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"INT\\n{{actor.system.abilities.int.mod}} {{actor.system.abilities.int.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"INT"},group:"Info Box #3",i:10},{id:"z0PMTFxo",label:"STR",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"z0PMTFxo",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:.32,offsetY:-.11,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"STR\\n{{actor.system.abilities.str.mod}} {{actor.system.abilities.str.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"STR"},group:"Info Box #3",i:11},{id:"YXUiGPBv",label:"WIS",expression:"",imgName:"",imgSrc:"",priority:57,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"YXUiGPBv",parentID:"Gt11vjXV",underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!0,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:-.3,scaleX:.51,scaleY:.51,angle:0,anchor:{x:.5,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"WIS\\n{{actor.system.abilities.wis.mod}} {{actor.system.abilities.wis.save}}",fontFamily:"Signika",fontSize:36,letterSpacing:0,fill:"#FFFFFF",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"WIS"},group:"Info Box #3",i:12}],id:"vQJ3coCJ"},{name:"Facing Direction",hint:"Displays an arrow in the top-right corner of the token showing the direction it is facing.",img:"https://user-images.githubusercontent.com/7693704/244647284-2213caf5-6d49-4413-ab5f-83901ffbc8e6.png",mappings:[{id:"9UEOkJ1J",label:"Arrow",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"9UEOkJ1J",parentID:"",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!0,animation:{relative:!0,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.5,offsetY:.5,scaleX:.51,scaleY:.51,angle:90,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"➢",fontFamily:"Signika",fontSize:63,letterSpacing:0,fill:"#ff0000",dropShadow:null,strokeThickness:3,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Arrow"},group:"Facing Direction",i:0}],id:"Z8CTgmOg"},{name:"Combat Markers",hint:"Displays rotating markers for tokens in combat.",img:"https://user-images.githubusercontent.com/7693704/257478593-81b9192d-1ffe-4f0b-8e5d-806218d7e25f.png",mappings:[{id:"9R3glzOK",label:"Your Turn is Next!",expression:"combat-turn-next",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{label:"Your Turn is Next!",parent:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!0,duration:3e4,clockwise:!0},linkMirror:!1,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!1,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:0,scaleX:1.6,scaleY:1.6,angle:0,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"Next Turn = = = = = = Next turn = = = = = ",fontFamily:"Signika",fontSize:41,letterSpacing:0,fill:"#e6a800",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:125,invert:!1}},effect:""},group:"Combat",i:0},{id:"qoWG5AD0",label:"Your Turn!",expression:"combat-turn",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{label:"Your Turn!",parent:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!0,duration:3e4,clockwise:!0},linkMirror:!1,linkScale:!0,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!1,playOnce:!1,img:"",alpha:1,tint:"",offsetX:0,offsetY:0,scaleX:1.6,scaleY:1.6,angle:0,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"= Your Turn = = = = = = Your turn = = = = = ",fontFamily:"Signika",fontSize:41,letterSpacing:0,fill:"#00ace6",dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:125,invert:!1}},effect:""},group:"Combat",i:1}],id:"YpoX5zxO"},{name:"Disposition Markers",hint:"Displays circles underneath tokens coloured based on their disposition.",img:"https://user-images.githubusercontent.com/7693704/246497702-5de47dc9-21ef-43a1-86db-b3f85eb8ddb1.png",mappings:[{id:"TzP6MBC1",label:"Friendly",expression:"disposition=1",codeExp:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"TzP6MBC1",parentID:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",imgLinked:!1,repeating:!1,alpha:"1",tint:"#1acb2f",interpolateColor:{color2:"",prc:""},width:"",height:"",scaleX:"0.24",scaleY:"0.24",angle:"0",pOffsetX:"",pOffsetY:"",offsetX:"0",offsetY:"0",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnHUD:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#FFFFFF",interpolateColor:{color2:"",prc:""},fontSize:"36",align:"center",letterSpacing:"0",dropShadow:"true",strokeThickness:"1",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"0",radius:"0",invert:!1}},shapes:[{shape:{type:"ellipse",x:"0",y:"0",width:"{{object.w}} * @scale",height:"{{object.h}} * @scale"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#ffffff",alpha:"0.75",interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"ellipse",x:"{{object.w}} * @inner",y:"{{object.w}} * @inner",width:"{{object.w}} * @scale - {{object.w}} * @inner",height:"{{object.h}} * @scale - {{object.h}} * @inner"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#b8b8b8",alpha:"0.7",interpolateColor:{color2:"",prc:""}},repeating:!1}],variables:[{name:"scale",value:"2.3"},{name:"inner",value:"0.3"}],effect:"",interactivity:[],label:"Friendly"},group:"Disposition Markers",i:2},{id:"oIsQWISB",label:"Hostile",expression:"disposition=-1",codeExp:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"oIsQWISB",parentID:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",imgLinked:!1,repeating:!1,alpha:"1",tint:"#eb0000",interpolateColor:{color2:"",prc:""},width:"",height:"",scaleX:"0.24",scaleY:"0.24",angle:"0",pOffsetX:"",pOffsetY:"",offsetX:"0",offsetY:"0",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnHUD:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#FFFFFF",interpolateColor:{color2:"",prc:""},fontSize:"36",align:"center",letterSpacing:"0",dropShadow:"true",strokeThickness:"1",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"0",radius:"0",invert:!1}},shapes:[{shape:{type:"ellipse",x:"0",y:"0",width:"{{object.w}} * @scale",height:"{{object.h}} * @scale"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#ffffff",alpha:"0.75",interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"ellipse",x:"{{object.w}} * @inner",y:"{{object.w}} * @inner",width:"{{object.w}} * @scale - {{object.w}} * @inner",height:"{{object.h}} * @scale - {{object.h}} * @inner"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#b8b8b8",alpha:"0.7",interpolateColor:{color2:"",prc:""}},repeating:!1}],variables:[{name:"scale",value:"2.3"},{name:"inner",value:"0.3"}],effect:"",interactivity:[],label:"Hostile"},group:"Disposition Markers",i:3},{id:"fYxJ9Bbc",label:"Neutral",expression:"disposition=0",codeExp:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"fYxJ9Bbc",parentID:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",imgLinked:!1,repeating:!1,alpha:"1",tint:"",interpolateColor:{color2:"",prc:""},width:"",height:"",scaleX:"0.24",scaleY:"0.24",angle:"0",pOffsetX:"",pOffsetY:"",offsetX:"0",offsetY:"0",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnHUD:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#FFFFFF",interpolateColor:{color2:"",prc:""},fontSize:"36",align:"center",letterSpacing:"0",dropShadow:"true",strokeThickness:"1",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"0",radius:"0",invert:!1}},shapes:[{shape:{type:"ellipse",x:"0",y:"0",width:"{{object.w}} * @scale",height:"{{object.h}} * @scale"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#ffffff",alpha:"0.75",interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"ellipse",x:"{{object.w}} * @inner",y:"{{object.w}} * @inner",width:"{{object.w}} * @scale - {{object.w}} * @inner",height:"{{object.h}} * @scale - {{object.h}} * @inner"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#b8b8b8",alpha:"0.7",interpolateColor:{color2:"",prc:""}},repeating:!1}],variables:[{name:"scale",value:"2.3"},{name:"inner",value:"0.3"}],effect:"",interactivity:[],label:"Neutral"},group:"Disposition Markers",i:4},{id:"PyEXXb5J",label:"Secret",expression:"disposition=-2",codeExp:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!1,disabled:!1,overlayConfig:{id:"PyEXXb5J",parentID:"",underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",imgLinked:!1,repeating:!1,alpha:"1",tint:"#ba24ff",interpolateColor:{color2:"",prc:""},width:"",height:"",scaleX:"0.24",scaleY:"0.24",angle:"0",pOffsetX:"",pOffsetY:"",offsetX:"0",offsetY:"0",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnHUD:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#FFFFFF",interpolateColor:{color2:"",prc:""},fontSize:"36",align:"center",letterSpacing:"0",dropShadow:"true",strokeThickness:"1",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"0",radius:"0",invert:!1}},shapes:[{shape:{type:"ellipse",x:"0",y:"0",width:"{{object.w}} * @scale",height:"{{object.h}} * @scale"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#ffffff",alpha:"0.75",interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"ellipse",x:"{{object.w}} * @inner",y:"{{object.w}} * @inner",width:"{{object.w}} * @scale - {{object.w}} * @inner",height:"{{object.h}} * @scale - {{object.h}} * @inner"},label:"",line:{width:"0",color:"#000000",alpha:"1"},fill:{color:"#b8b8b8",alpha:"0.7",interpolateColor:{color2:"",prc:""}},repeating:!1}],variables:[{name:"scale",value:"2.3"},{name:"inner",value:"0.3"}],effect:"",interactivity:[],label:"Secret"},group:"Disposition Markers",i:5}],id:"yjqfAagB"},{name:"Health Bar",hint:"A recreation of the standard health bar using Overlays.",img:"https://user-images.githubusercontent.com/7693704/257246890-d41894a0-7f40-4e91-a47a-bc10d6f198e6.png",group:"Health",mappings:[{id:"dgIBKbcU",label:"Health Bar",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"dgIBKbcU",parentID:"",ui:!0,underlay:!0,bottom:!0,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:1,tint:"",interpolateColor:{color2:"",prc:""},offsetX:0,offsetY:-.5,scaleX:1,scaleY:1,angle:0,anchor:{x:.5,y:1},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#FFFFFF",interpolateColor:{color2:"",prc:""},fontSize:36,align:"left",letterSpacing:0,dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"rectangle",x:"0",y:"0",width:"{{object.w}}",height:"{{object.h}} * @height",radius:"3"},label:"",line:{width:1,color:"#000000",alpha:1},fill:{color:"#5c5c5c",alpha:.65,interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"rectangle",x:"0",y:"0",width:"{{object.w}} * ( {{hp}} / {{hpMax}} )",height:"{{object.h}} * @height",radius:"3"},label:"",line:{width:1,color:"#000000",alpha:1},fill:{color:"#ff0000",alpha:1,interpolateColor:{color2:"#74da0e",prc:"{{hp}} / {{hpMax}}"}},repeating:!1}],variables:[{name:"height",value:"0.079"}],effect:"",label:"Health Bar"},group:"Health Bar",i:0}],id:"GDyvkEB4"},{name:"Health Ring",hint:"A ring shaped health bar.",img:"https://user-images.githubusercontent.com/7693704/257246432-a339394f-489a-4436-9d4b-427c285d4f27.png",group:"Health",mappings:[{id:"erOTHzIc",label:"Health Ring",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"erOTHzIc",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:1,tint:"",interpolateColor:{color2:"",prc:""},offsetX:0,offsetY:0,scaleX:1.02,scaleY:1.02,angle:-90,anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#ffffff",interpolateColor:{color2:"",prc:""},fontSize:36,align:"left",letterSpacing:0,dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"torus",x:"0",y:"0",innerRadius:"{{object.w}} / @ringScale * @innerRadius",outerRadius:"{{object.w}} / @ringScale * @outerRadius",startAngle:"0",endAngle:"360"},label:"Background",line:{width:0,color:"#000000",alpha:1},fill:{color:"#b0b0b0",alpha:.6,interpolateColor:{color2:"",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"{{object.w}} / @ringScale * @innerRadius",outerRadius:"{{object.w}} / @ringScale * @outerRadius",startAngle:"0",endAngle:"{{hp}} / {{hpMax}} * 360"},label:"Health Tracker",line:{width:0,color:"#000000",alpha:1},fill:{color:"#ff0000",alpha:1,interpolateColor:{color2:"#74da0e",prc:"{{hp}} / {{hpMax}}"}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"{{object.w}} / @ringScale * @innerRadius",outerRadius:"{{object.w}} / @ringScale * @outerRadius",startAngle:"0",endAngle:"360"},label:"Outline",line:{width:1,color:"#000000",alpha:1},fill:{color:"#b0b0b0",alpha:0,interpolateColor:{color2:"",prc:""}},repeating:!1}],variables:[{name:"ringScale",value:"1.8"},{name:"innerRadius",value:"0.9"},{name:"outerRadius",value:"1.0"}],effect:"",label:"Health Ring"},group:"Health Ring",i:0}],id:"yITi94hC"},{name:"Health Hearts",hint:"Displays up to 10 hearts to the right of the token based on their current health. Each heart is representative of 10% of the health.",img:"https://user-images.githubusercontent.com/7693704/257349483-1864d4ca-a2de-468d-872d-6d8c2847434a.png",group:"Health",mappings:[{id:"4uCpbtHY",label:"Hearts",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"4uCpbtHY",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!0,linkDimensionsY:!0,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",alpha:1,tint:"",offsetX:-.53,offsetY:.5,scaleX:.5,scaleY:.5,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:" ",repeating:!0,repeat:{value:"{{hp}}",increment:"10",isPercentage:!0,maxValue:"{{hpMax}}",perRow:"2",maxRows:""},fontFamily:"Signika",fill:"#ff0000",fontSize:36,align:"left",letterSpacing:0,dropShadow:null,strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},effect:"",label:"Hearts"},group:"Health Hearts",i:0}],id:"T2DrD0Em"},{name:"Health Circles",hint:"Displays up to 10 circles to the right of the token based on their current health. Each circle is representative of 10% of the health.",img:"https://user-images.githubusercontent.com/7693704/257476414-c42bdbc0-c57b-4367-8207-3e2e4273094f.png",group:"Health",mappings:[{id:"0vETg18v",label:"Health Circles",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"0vETg18v",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!0,linkDimensionsY:!0,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:1,tint:"",interpolateColor:{color2:"",prc:""},offsetX:-.52,offsetY:.6,scaleX:.46,scaleY:.46,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#ffffff",interpolateColor:{color2:"",prc:""},fontSize:36,align:"left",letterSpacing:0,dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"ellipse",x:"0",y:"0",width:"25",height:"25"},label:"",line:{width:1,color:"#000000",alpha:1},fill:{color:"#ff0000",alpha:1,interpolateColor:{color2:"#74da0e",prc:"{{hp}} / {{hpMax}}"}},repeating:!0,repeat:{value:"{{hp}}",increment:"10",isPercentage:!0,maxValue:"{{hpMax}}",perRow:"2",maxRows:"",paddingX:"3",paddingY:"3"}}],effect:"",label:"Health Circles"},group:"Health Circles",i:0}],id:"kJ0Fi54w"},{name:"Health Squares",hint:"Displays up to 10 squares to the right of the token based on their current health. Each square is representative of 10% of the health.",img:"https://user-images.githubusercontent.com/7693704/257477099-689cd23a-0e4a-4d9a-aaa2-bf88b169ede8.png",group:"Health",mappings:[{id:"0vETg18v",label:"Health Squares",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"0vETg18v",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!1,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:5e3,clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!0,linkDimensionsY:!0,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:1,tint:"",interpolateColor:{color2:"",prc:""},offsetX:-.52,offsetY:.6,scaleX:.46,scaleY:.46,angle:0,anchor:{x:0,y:0},filter:"NONE",alwaysVisible:!1,limitedUsers:[],limitOnHover:!1,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#ffffff",interpolateColor:{color2:"",prc:""},fontSize:36,align:"left",letterSpacing:0,dropShadow:"true",strokeThickness:1,stroke:"#111111",curve:{radius:0,invert:!1}},shapes:[{shape:{type:"rectangle",x:"0",y:"0",width:"50",height:"50",radius:"0"},label:"",line:{width:1,color:"#000000",alpha:1},fill:{color:"#ff0000",alpha:1,interpolateColor:{color2:"#74da0e",prc:"{{hp}} / {{hpMax}}"}},repeating:!0,repeat:{value:"{{hp}}",increment:"10",isPercentage:!0,maxValue:"{{hpMax}}",perRow:"2",maxRows:"",paddingX:"3",paddingY:"3"}}],effect:"",label:"Health Squares"},group:"Health Squares",i:0}],id:"zzeRhmmk"},{name:"Spell Slot Ring",hint:"Remaining spell slots represented as a ring.",img:"https://user-images.githubusercontent.com/7693704/261663740-444d86b9-ee9f-4a2f-963f-6886a2af29cc.png",system:"dnd5e",mappings:[{id:"1SS3KhwM",label:"Spell Slot Ring",expression:"",imgName:"",imgSrc:"",priority:50,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"1SS3KhwM",parentID:"",ui:!0,underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:"1",tint:"",interpolateColor:{color2:"",prc:""},width:"{{object.w}} * @Scale",height:"{{object.w}} * @Scale",scaleX:"1",scaleY:"1",angle:"0",offsetX:"0",offsetY:"0",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!0,limitedUsers:[],limitOnHover:!0,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"",repeating:!1,fontFamily:"Signika",fill:"#ffffff",interpolateColor:{color2:"",prc:""},fontSize:"36",align:"left",letterSpacing:"0",dropShadow:"true",strokeThickness:"1",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"0",radius:"0",invert:!1}},shapes:[{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer ",startAngle:"0",endAngle:"360"},label:"BaseLayer",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#3b3b3b",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90",endAngle:"-90 + ( {{actor.system.spells.spell1.value}} * @Tick )"},label:"1st level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff0000",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 4 * @Tick )",endAngle:"-90 + ( 4 * @Tick ) + ( {{actor.system.spells.spell2.value}} * @Tick )"},label:"2nd Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff8800",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 7 * @Tick )",endAngle:"-90 + ( 7 * @Tick ) + ( {{actor.system.spells.spell3.value}} * @Tick )"},label:"3rd Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ffdd00",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 10 * @Tick )",endAngle:"-90 + ( 10 * @Tick ) + ( {{actor.system.spells.spell4.value}} * @Tick )"},label:"4th Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#37ff00",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 13 * @Tick )",endAngle:"-90 + ( 13 * @Tick ) + ( {{actor.system.spells.spell5.value}} * @Tick )"},label:"5th Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#00ffcc",alpha:"0.95",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 16 * @Tick )",endAngle:"-90 + ( 16 * @Tick ) + ( {{actor.system.spells.spell6.value}} * @Tick )"},label:"6th Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#00b3ff",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 18 * @Tick )",endAngle:"-90 + ( 18 * @Tick ) + ( {{actor.system.spells.spell7.value}} * @Tick )"},label:"7th Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#001eff",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 20 * @Tick )",endAngle:"-90 + ( 20 * @Tick ) + ( {{actor.system.spells.spell8.value}} * @Tick )"},label:"8th Level",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ae00ff",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 21 * @Tick )",endAngle:"-90 + ( 21 * @Tick ) + ( {{actor.system.spells.spell9.value}} * @Tick )"},label:"9th Level - Copy",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"1",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90",endAngle:"-90 + ( 1 * @Tick )"},label:"Outline 1",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 1 * @Tick )",endAngle:"-90 + ( 2 * @Tick )"},label:"Outline 2",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 2 * @Tick )",endAngle:"-90 + ( 3 * @Tick )"},label:"Outline 3",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 3 * @Tick )",endAngle:"-90 + ( 4 * @Tick )"},label:"Outline 4",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 4 * @Tick )",endAngle:"-90 + ( 5 * @Tick )"},label:"Outline 5",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 5 * @Tick )",endAngle:"-90 + ( 6 * @Tick )"},label:"Outline 6",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 6 * @Tick )",endAngle:"-90 + ( 7 * @Tick )"},label:"Outline 7",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 7 * @Tick )",endAngle:"-90 + ( 8 * @Tick )"},label:"Outline 8",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 8 * @Tick )",endAngle:"-90 + ( 9 * @Tick )"},label:"Outline 9",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 9 * @Tick )",endAngle:"-90 + ( 10 * @Tick )"},label:"Outline 10",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 10 * @Tick )",endAngle:"-90 + ( 11 * @Tick )"},label:"Outline 11",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 11 * @Tick )",endAngle:"-90 + ( 12 * @Tick )"},label:"Outline 12",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 12 * @Tick )",endAngle:"-90 + ( 13 * @Tick )"},label:"Outline 13",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 13 * @Tick )",endAngle:"-90 + ( 14 * @Tick )"},label:"Outline 14",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 14 * @Tick )",endAngle:"-90 + ( 15 * @Tick )"},label:"Outline 15",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 15 * @Tick )",endAngle:"-90 + ( 16 * @Tick )"},label:"Outline 16",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 16 * @Tick )",endAngle:"-90 + ( 17 * @Tick )"},label:"Outline 17",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 17 * @Tick )",endAngle:"-90 + ( 18 * @Tick )"},label:"Outline 18",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 18 * @Tick )",endAngle:"-90 + ( 19 * @Tick )"},label:"Outline 19",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 19 * @Tick )",endAngle:"-90 + ( 20 * @Tick )"},label:"Outline 20",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 20 * @Tick )",endAngle:"-90 + ( 21 * @Tick )"},label:"Outline 21",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1},{shape:{type:"torus",x:"0",y:"0",innerRadius:"@Inner",outerRadius:"@Outer",startAngle:"-90 + ( 21 * @Tick )",endAngle:"-90 + ( 22 * @Tick )"},label:"Outline 22",line:{width:"1",color:"#000000",alpha:"1"},fill:{color:"#ff00ea",alpha:"0",interpolateColor:{color2:"#ffffff",prc:""}},repeating:!1}],variables:[{name:"Tick",value:"16.3636363636363636"},{name:"Inner",value:"66"},{name:"Outer",value:"80"},{name:"Scale",value:"1.8"}],effect:"",label:"Spell Slot Ring"},group:"Spell Slot Ring",i:0},{id:"3IAo8ZUu",label:"Spell Slot Numbers",expression:"",imgName:"",imgSrc:"",priority:60,config:{},overlay:!0,alwaysOn:!0,disabled:!1,overlayConfig:{id:"3IAo8ZUu",parentID:"",underlay:!1,bottom:!1,top:!0,inheritTint:!1,linkRotation:!1,animation:{relative:!1,rotate:!1,duration:"5000",clockwise:!0},linkMirror:!1,linkScale:!1,linkDimensionsX:!1,linkDimensionsY:!1,linkOpacity:!1,linkStageScale:!1,loop:!0,playOnce:!1,img:"",repeating:!1,alpha:"1",tint:"",interpolateColor:{color2:"",prc:""},width:"{{object.w}} * @Scale",height:"{{object.w}} * @Scale",scaleX:"1",scaleY:"1",angle:"1",offsetX:"0",offsetY:"0.009",anchor:{x:.5,y:.5},filter:"NONE",alwaysVisible:!1,limitedToOwner:!0,limitedUsers:[],limitOnHover:!0,limitOnHighlight:!1,limitOnControl:!1,limitOnEffect:"",limitOnProperty:"",text:{text:"4455566778911112223334",repeating:!1,fontFamily:"Signika",fill:"#ffffff",interpolateColor:{color2:"",prc:""},fontSize:"45",align:"left",letterSpacing:"41.5",dropShadow:null,strokeThickness:"4",stroke:"#111111",wordWrap:!1,wordWrapWidth:"200",breakWords:!1,maxHeight:"0",curve:{angle:"360",radius:"220",invert:!1}},variables:[{name:"Scale",value:"1.85"}],effect:"",label:"Spell Slot Numbers"},group:"Spell Slot Ring",i:1}],id:"FeFzTjjE"}]}),parcelRequire.register("fTFXO",function(t,a){$parcel$export(t.exports,"Templates",()=>s);var n=parcelRequire("hClLE"),r=parcelRequire("9IngI"),o=parcelRequire("cs88A");class s extends FormApplication{constructor({mappings:t=null,callback:a=null}={}){super({},{}),this.mappings=t,this.callback=a}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-templates",classes:["sheet"],template:"modules/token-variants/templates/templates.html",resizable:!1,minimizable:!1,title:"Mapping Templates",width:500,height:"auto"})}async getData(t){let a=super.getData(t);for(let t of(this.category||(this.category=r.TVA_CONFIG.templateMappings?.length?"user":"core"),"user"===this.category?this.templates=r.TVA_CONFIG.templateMappings:"core"===this.category?this.templates=n.CORE_TEMPLATES:this.templates=await d(),this.templates))t.hint=t.hint?.replace(/(\r\n|\n|\r)/gm,"<br>");return a.category=this.category,a.templates=this.templates,a.allowDelete="user"===this.category,a.allowCreate="user"===this.category,a.allowCopy="community"===this.category||"core"===this.category,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t);// Position tooltip
|
|
let a=t.closest("#token-variants-templates");t.find(".template").on("mouseover",t=>{let n=$(t.target).closest(".template"),r=n.position(),o=n.find(".tooltiptext"),s=a.position();o.css("top",s.top+r.top).css("left",s.left+r.left);// Lazy load image
|
|
let l=n.find("img");l.attr("src")||l.attr("src",l.data("src"))}),this.callback&&t.find(".template").on("click",async t=>{let a,n;let r=$(t.target).closest(".template"),o=r.data("id"),s=r.data("url");if(s){let t=await h(s);t&&(a=t.mappings)}else if(o){let t=this.templates.find(t=>t.id===o);t&&(n=t.name,a=t.mappings)}a&&this.callback(n,a)}),t.find(".search").on("input",()=>{let a=t.find(".search").val().trim().toLowerCase();t.find(".template-list li").each(function(){let t=$(this),n=t.find(".description").text().trim().toLowerCase(),r=t.data("name").trim().toLowerCase(),o=t.data("creator").trim().toLowerCase();r.includes(a)||n.includes(a)||o.includes(a)?t.show():t.hide()})}),t.find('[name="category"]').on("change",t=>{this.category=t.target.value,this.render(!0)}),t.find(".delete").on("click",async t=>{t.preventDefault(),t.stopPropagation();let a=$(t.target).closest(".template").data("id");a&&(await (0,r.updateSettings)({templateMappings:(0,r.TVA_CONFIG).templateMappings.filter(t=>t.id!==a)}),this.render(!0))}),t.find(".copy").on("click",async t=>{t.preventDefault(),t.stopPropagation();let a=$(t.target).closest(".template").data("id");if(a){let o;if("core"===this.category)o=deepClone((0,n.CORE_TEMPLATES).find(t=>t.id===a));else{let a=$(t.target).closest(".template").data("url");a&&(o=await h(a))}o&&((0,r.TVA_CONFIG).templateMappings.push(o),await (0,r.updateSettings)({templateMappings:r.TVA_CONFIG.templateMappings}),ui.notifications.info(`Template {${o.name}} copied to User templates.`),this.render(!0))}}),t.find(".create").on("click",()=>{(0,o.showMappingSelectDialog)(this.mappings,{title1:"Create Template",callback:t=>{t.length&&(0,o.showUserTemplateCreateDialog)(t)}})})}_getHeaderButtons(){let t=super._getHeaderButtons();return t.unshift({label:"Upload Template",class:".token-variants-submit-template",icon:"fa-solid fa-cloud-arrow-up",onclick:()=>{new l().render(!0)}}),t}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){}}class l extends FormApplication{constructor(){super({},{})}static apiKey="AIzaSyCJpwIkpjrG10jaHwcpllvSChxRPawcMXE";static get pk(){let t="AIzaSyCJpw",a="IkpjrG10jaHwcpllv",n="SChxRPawcMXE";return t+a+n}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-template-submission",classes:["sheet"],template:"modules/token-variants/templates/templateSubmission.html",resizable:!0,minimizable:!1,closeOnSubmit:!1,title:"Upload Template",width:500,height:"auto"})}async getData(t){let a=super.getData(t);return a.systemID=game.system.id,a.systemTitle=game.system.title,a.templates=r.TVA_CONFIG.templateMappings,a}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){if(!a.template)return;let n=(0,r.TVA_CONFIG).templateMappings.find(t=>t.id===a.template);if(!n)return;let o=a.name.trim()||n.name,s=a.hint.trim()||n.hint?.trim(),l=a.createdBy.trim(),c=a.system,f=randomID(),d=a.img.trim(),g=p({id:f,name:o,hint:s,img:d,createdBy:l,system:c,mappings:n.mappings});g&&this.close()}}function c(t,a,n){t[n]&&""!==t[n]&&(a[n]={stringValue:t[n]})}async function p(t){let a={};["name","hint","img","id","createdBy","system"].forEach(n=>c(t,a,n)),a.mappings={stringValue:JSON.stringify(t.mappings)},a.createTime={integerValue:new Date().getTime()},a.approved={booleanValue:!1};let n=await fetch(`https://firestore.googleapis.com/v1/projects/tva---templates/databases/(default)/documents/templates?key=${l.pk}`,{method:"POST",body:JSON.stringify({fields:a}),headers:{Accept:"application/json","Content-Type":"application/json"}});return n.ok&&200===n.status?(ui.notifications.info("Template submission completed."),!0):(ui.notifications.warn("Template submission failed."),!1)}let f={structuredQuery:{select:{fields:[{fieldPath:"id"},{fieldPath:"name"},{fieldPath:"hint"},{fieldPath:"createdBy"},{fieldPath:"img"},{fieldPath:"system"}]},where:{fieldFilter:{field:{fieldPath:"approved"},op:"EQUAL",value:{booleanValue:!0}}},from:[{collectionId:"templates"}],orderBy:[{field:{fieldPath:"createTime"}}],offset:0,limit:50}};async function d(t=null){let a=await fetch(`https://firestore.googleapis.com/v1/projects/tva---templates/databases/(default)/documents:runQuery?key=${l.pk}`,{method:"POST",body:JSON.stringify(f),headers:{Accept:"application/json","Content-Type":"application/json"}}),n=[];if(a.ok&&200===a.status){let t=await a.json();for(let a of t)"document"in a&&n.push(g(a.document))}else ui.notifications.warn("Failed to retrieve Community templates.");return n}function g(t){let a={};return["id","name","mappings","createdBy","img","hint","system"].forEach(n=>{a[n]=t.fields[n]?.stringValue||""}),a.mappings?a.mappings=JSON.parse(a.mappings):a.fileURL=t.name,a.createdBy||(a.createdBy="Anonymous"),a}async function h(t){let a=await fetch(`https://firestore.googleapis.com/v1/${t}?key=${l.pk}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"}});if(a.ok&&200===a.status){let t=await a.json();return g(t)}return null}}),parcelRequire.register("9Z21J",function(t,a){$parcel$export(t.exports,"default",()=>n);class n extends FormApplication{constructor(t){super({},{}),this.actor=game.actors.get(t.actorId)}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-token-flags",classes:["sheet"],template:"modules/token-variants/templates/randomizerConfig.html",resizable:!0,minimizable:!1,title:"Randomizer",width:500})}async getData(t){let a=super.getData(t),n=this.actor.getFlag("token-variants","randomizerSettings")||{};return a.randomizer=n,a.hasSettings=!isEmpty(n),a.nameForgeActive=game.modules.get("nameforge")?.active,a.randomizer.nameForge?.models&&Array.isArray(a.randomizer.nameForge.models)&&(a.randomizer.nameForge.models=a.randomizer.nameForge.models.join(",")),a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find(".selectNameForgeModels").click(this._selectNameForgeModels.bind(this));// Can't have both tokenName and actorName checkboxes checked at the same time
|
|
let a=t.find('input[name="randomizer.tokenName"]'),n=t.find('input[name="randomizer.actorName"]');a.change(()=>{a.is(":checked")&&n.prop("checked",!1)}),n.change(()=>{n.is(":checked")&&a.prop("checked",!1)})}_selectNameForgeModels(t){let a=$(t.target).siblings("input"),n=a.val().split(","),r=function(t,a){return`
|
|
<div class="form-group">
|
|
<label>${t}</label>
|
|
<div class="form-fields">
|
|
<input type="checkbox" name="model" value="${a}" data-dtype="Boolean" ${n?.find(t=>t===a)?"checked":""}>
|
|
</div>
|
|
</div>
|
|
`},o='<form style="overflow-y: scroll; height:400px;">',s=game.modules.get("nameforge").models;for(let[t,a]of Object.entries(s.defaultModels))o+=r(a.name,"defaultModels."+t);for(let[t,a]of Object.entries(s.userModels))o+=r(a.name,"userModels."+t);o+="</form>",new Dialog({title:"Name Forge Models",content:o,buttons:{Ok:{label:"Select",callback:async t=>{let n=[];t.find('input[type="checkbox"]').each(function(){this.checked&&n.push(this.value)}),a.val(n.join(","))}}}}).render(!0)}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){if("remove"===t.submitter.value)await this.actor.unsetFlag("token-variants","randomizerSettings");else{let t=expandObject(a);t.randomizer.nameForge?.models&&(t.randomizer.nameForge.models=t.randomizer.nameForge.models.split(",")),this.actor.setFlag("token-variants","randomizerSettings",t.randomizer)}}}}),parcelRequire.register("7Bay0",function(t,a){$parcel$export(t.exports,"registerUserMappingHooks",()=>s);var n=parcelRequire("9IngI"),r=parcelRequire("e9LRe");let o="UserMappings";function s(){if(!n.FEATURE_CONTROL[o]){["updateToken","updateTile","sightRefresh"].forEach(t=>(0,r.unregisterHook)(o,t));return}(0,r.registerHook)(o,"updateToken",l),(0,r.registerHook)(o,"updateTile",c),(0,r.registerHook)(o,"sightRefresh",p)}async function l(t,a){// Update User Specific Image
|
|
if(a.flags?.["token-variants"]&&("userMappings"in a.flags["token-variants"]||"-=userMappings"in a.flags["token-variants"])){let a=canvas.tokens.get(t.id);a&&(await a.draw(),canvas.effects.visibility.restrictVisibility())}}async function c(t,a){// Update User Specific Image
|
|
if(a.flags?.["token-variants"]&&("userMappings"in a.flags["token-variants"]||"-=userMappings"in a.flags["token-variants"])){let a=canvas.tiles.get(t.id);a&&(await a.draw(),canvas.effects.visibility.restrictVisibility())}}function p(){if(!game.user.isGM){for(let t of canvas.tokens.placeables)f(t)&&(t.visible=!1);for(let t of canvas.tiles.placeables)f(t)&&(t.visible=!1)}}function f(t){let a=(t.document.getFlag("token-variants","userMappings")||{})?.[game.userId];return a===n.TVA_CONFIG.invisibleImage}}),parcelRequire.register("4VMEk",function(t,a){$parcel$export(t.exports,"registerWildcardHooks",()=>c);var n=parcelRequire("7OP4c"),r=parcelRequire("9IngI"),o=parcelRequire("eeGZt"),s=parcelRequire("e9LRe");let l="Wildcards";function c(){if(!r.FEATURE_CONTROL[l]){["renderTokenConfig","preCreateToken"].forEach(t=>(0,s.unregisterHook)(l,t));return}// Insert default random image field
|
|
(0,s.registerHook)(l,"renderTokenConfig",p),// Set Default Wildcard images if needed
|
|
(0,s.registerHook)(l,"preCreateToken",f)}async function p(t,a){let r=a.find('input[name="randomImg"]');if(r.length&&!a.find(".token-variants-proto").length){let s=t.actor?.prototypeToken?.flags["token-variants"]?.randomImgDefault||t.actor?.prototypeToken?.flags["token-hud-wildcard"]?.default||"",l=await renderTemplate("/modules/token-variants/templates/protoTokenElement.html",{defaultImg:s,disableHUDButton:t.object?.getFlag("token-variants","disableHUDButton")});r.closest(".form-group").after(l);let c=a.find(".token-variants-proto");c.find("button").click(t=>{t.preventDefault();let a=c.find("input");new FilePicker({current:a.val(),field:a[0]}).browse(s)}),(0,n.insertArtSelectButton)(c,"flags.token-variants.randomImgDefault",{search:t.object.name,searchType:o.SEARCH_TYPE.TOKEN});// Hide/Show Default Img Form Group
|
|
let p=c.find(".imagevideo").closest(".form-group"),f=function(a){a?p.show():p.hide(),t.setPosition()};r.on("click",t=>f(t.target.checked)),f(r.is(":checked"))}}function f(t,a,n,s){if(game.user.id!==s)return;let l={};if(t.actor?.prototypeToken?.randomImg){let a=t.actor?.prototypeToken?.flags["token-variants"]?.randomImgDefault||t.actor?.prototypeToken?.flags["token-hud-wildcard"]?.default||"";a&&(l["texture.src"]=a)}(r.TVA_CONFIG.imgNameContainsDimensions||r.TVA_CONFIG.imgNameContainsFADimensions)&&(0,o.updateTokenImage)(l["texture.src"]??t.texture.src,{token:t,update:l}),isEmpty(l)||t.updateSource(l)}}),parcelRequire.register("aTVyJ",function(t,a){$parcel$export(t.exports,"registerPopRandomizeHooks",()=>p);var n=parcelRequire("coMHP"),r=parcelRequire("8MWlo"),o=parcelRequire("9IngI"),s=parcelRequire("eeGZt"),l=parcelRequire("e9LRe");let c="PopUpAndRandomize";function p(){o.FEATURE_CONTROL[c]?((0,l.registerHook)(c,"createActor",d),(0,l.registerHook)(c,"createToken",f)):["createActor","createToken"].forEach(t=>(0,l.unregisterHook)(c,t))}async function f(t,a,l){if(l&&game.user.id!=l)return;// Check if random search is enabled and if so perform it
|
|
let c=game.actors.get(t.actorId)?.getFlag("token-variants","randomizerSettings"),p=mergeObject(o.TVA_CONFIG.randomizer,c??{},{inplace:!1,recursive:!1}),f=(0,s.keyPressed)("v"),d=t.actor?game.actors.get(t.actor.id):t.document??t,m=d.getFlag("token-variants","popups");if(f&&p.tokenCopyPaste||!f&&p.tokenCreate){let a=!0;if(c?a=!!c:(p.representedActorDisable&&t.actor&&(a=!1),p.linkedActorDisable&&t.actorLink&&(a=!1),g(p,t.actor)&&(a=!1)),a){// Randomize Token Name if need be
|
|
let a=await (0,s.nameForgeRandomize)(p);a&&t.update({name:a});let n=await (0,r.doRandomSearch)(t.name,{searchType:s.SEARCH_TYPE.TOKEN,actor:t.actor,randomizerOptions:p});if(n&&await (0,s.updateTokenImage)(n[0],{token:t,actor:t.actor,imgName:n[1]}),!n)return;if(p.diffImages){let a;(a=p.syncImages?await (0,r.doSyncSearch)(t.name,n[1],{actor:t.actor,searchType:s.SEARCH_TYPE.PORTRAIT,randomizerOptions:p}):await (0,r.doRandomSearch)(t.name,{searchType:s.SEARCH_TYPE.PORTRAIT,actor:t.actor,randomizerOptions:p}))&&await (0,s.updateActorImage)(t.actor,a[0])}else p.tokenToPortrait&&await (0,s.updateActorImage)(t.actor,n[0]);return}if(null==m&&!p.popupOnDisable)return}else if(p.tokenCreate||p.tokenCopyPaste)return;// Check if pop-up is enabled and if so open it
|
|
if(!o.TVA_CONFIG.permissions.popups[game.user.role])return;let y=(0,s.keyPressed)("popupOverride");if(!f||!o.TVA_CONFIG.popup.disableAutoPopupOnTokenCopyPaste){if((!y||y&&f)&&(o.TVA_CONFIG.popup.disableAutoPopupOnTokenCreate&&!f||null==m&&h(t.actor)||null!=m&&!m))return;(0,n.showArtSelect)(t.name,{callback:async function(a,n){o.TVA_CONFIG.popup.twoPopups?(await (0,s.updateActorImage)(t.actor,a),u(t.actor,a,n,t)):(0,s.updateTokenImage)(a,{actor:t.actor,imgName:n,token:t})},searchType:o.TVA_CONFIG.popup.twoPopups?s.SEARCH_TYPE.PORTRAIT:s.SEARCH_TYPE.TOKEN,object:t,preventClose:o.TVA_CONFIG.popup.twoPopups&&o.TVA_CONFIG.popup.twoPopupsNoDialog})}}async function d(t,a,l){if(l&&game.user.id!=l)return;// Check if random search is enabled and if so perform it
|
|
let c=o.TVA_CONFIG.randomizer;if(c.actorCreate){let a=!0;if(c.linkedActorDisable&&t.prototypeToken.actorLink&&(a=!1),g(c,t)&&(a=!1),a){let a=await (0,r.doRandomSearch)(t.name,{searchType:s.SEARCH_TYPE.PORTRAIT,actor:t});if(a&&await (0,s.updateActorImage)(t,a[0]),!a)return;if(c.diffImages){let n;(n=c.syncImages?await (0,r.doSyncSearch)(t.name,a[1],{actor:t}):await (0,r.doRandomSearch)(t.name,{searchType:s.SEARCH_TYPE.TOKEN,actor:t}))&&await (0,s.updateTokenImage)(n[0],{actor:t,imgName:n[1]})}return}if(!c.popupOnDisable)return}// Check if pop-up is enabled and if so open it
|
|
if(o.TVA_CONFIG.permissions.popups[game.user.role]){if(o.TVA_CONFIG.popup.disableAutoPopupOnActorCreate&&!(0,s.keyPressed)("popupOverride")||h(t))return;(0,n.showArtSelect)(t.name,{callback:async function(a,n){let r=t.getActiveTokens(),l=1===r.length?r[0]:null;await (0,s.updateActorImage)(t,a),o.TVA_CONFIG.popup.twoPopups?u(t,a,n,l):(0,s.updateTokenImage)(a,{actor:t,imgName:n,token:l})},searchType:o.TVA_CONFIG.popup.twoPopups?s.SEARCH_TYPE.PORTRAIT:s.SEARCH_TYPE.PORTRAIT_AND_TOKEN,object:t,preventClose:o.TVA_CONFIG.popup.twoPopups&&o.TVA_CONFIG.popup.twoPopupsNoDialog})}}function g(t,a){return!!a&&(t[`${a.type}Disable`]??!1)}function h(t){return!!t&&(o.TVA_CONFIG.popup[`${t.type}Disable`]??!1)}function u(t,a,r,l){o.TVA_CONFIG.popup.twoPopups&&o.TVA_CONFIG.popup.twoPopupsNoDialog?(0,n.showArtSelect)((l??t.prototypeToken).name,{callback:(a,n)=>(0,s.updateTokenImage)(a,{actor:t,imgName:n,token:l}),searchType:s.SEARCH_TYPE.TOKEN,object:l||t,force:!0}):o.TVA_CONFIG.popup.twoPopups&&new Dialog({title:"Portrait -> Token",content:`<p>${game.i18n.localize("token-variants.windows.art-select.apply-same-art")}</p>`,buttons:{one:{icon:'<i class="fas fa-check"></i>',callback:()=>{(0,s.updateTokenImage)(a,{actor:t,imgName:r,token:l});let n=Object.values(ui.windows).filter(t=>t instanceof ArtSelect);for(let t of n)t.close()}},two:{icon:'<i class="fas fa-times"></i>',callback:()=>{(0,n.showArtSelect)((l??t.prototypeToken).name,{callback:(a,n)=>(0,s.updateTokenImage)(a,{actor:t,imgName:n,token:l}),searchType:s.SEARCH_TYPE.TOKEN,object:l||t,force:!0})}}},default:"one"}).render(!0)}}),parcelRequire.register("3pMx9",function(t,a){$parcel$export(t.exports,"REGISTERED_WRAPPERS",()=>l),$parcel$export(t.exports,"registerWrapper",()=>c),$parcel$export(t.exports,"unregisterWrapper",()=>p),$parcel$export(t.exports,"registerAllWrappers",()=>f);var n=parcelRequire("fFpXf"),r=parcelRequire("9znht"),o=parcelRequire("56MAr"),s=parcelRequire("kPeJW");let l={};function c(t,a,n,r="WRAPPER"){"function"==typeof libWrapper&&(t in l||(l[t]={}),a in l[t]||(l[t][a]=libWrapper.register("token-variants",a,n,r)))}function p(t,a){"function"==typeof libWrapper&&t in l&&a in l[t]&&(libWrapper.unregister("token-variants",l[t][a]),delete l[t][a])}function f(){// User to Image mappings for Tile and Tokens
|
|
(0,s.registerUserMappingWrappers)(),// Hide effect icons
|
|
(0,n.registerEffectIconWrappers)(),// Token HUD Variants Management
|
|
(0,o.registerHUDWrappers)(),// Hide Core Token Elements
|
|
(0,r.registerHideElementWrappers)()}}),parcelRequire.register("fFpXf",function(t,a){$parcel$export(t.exports,"registerEffectIconWrappers",()=>l);var n=parcelRequire("dmUqi"),r=parcelRequire("9IngI"),o=parcelRequire("3pMx9");let s="EffectIcons";function l(){(0,o.unregisterWrapper)(s,"Token.prototype.drawEffects"),(0,o.unregisterWrapper)(s,"CombatTracker.prototype.getData"),r.FEATURE_CONTROL[s]&&(r.TVA_CONFIG.disableEffectIcons||!r.TVA_CONFIG.filterEffectIcons||["pf1e","pf2e"].includes(game.system.id)?r.TVA_CONFIG.disableEffectIcons?(0,o.registerWrapper)(s,"Token.prototype.drawEffects",p,"OVERRIDE"):r.TVA_CONFIG.displayEffectIconsOnHover&&(0,o.registerWrapper)(s,"Token.prototype.drawEffects",c,"WRAPPER"):(0,o.registerWrapper)(s,"Token.prototype.drawEffects",d,"OVERRIDE"),(r.TVA_CONFIG.disableEffectIcons||r.TVA_CONFIG.filterCustomEffectIcons)&&(0,o.registerWrapper)(s,"CombatTracker.prototype.getData",f,"WRAPPER"))}async function c(t,...a){let n=await t(...a);return this.effects.visible=this.hover,n}async function p(...t){this.effects.removeChildren().forEach(t=>t.destroy()),this.effects.bg=this.effects.addChild(new PIXI.Graphics),this.effects.overlay=null}async function f(t,...a){let n=await t(...a);if(n&&n.combat&&n.turns){let t=n.combat;for(let a of n.turns){let n=t.combatants.find(t=>t.id===a.id);if(n){if(r.TVA_CONFIG.disableEffectIcons)a.effects=new Set;else if(r.TVA_CONFIG.filterEffectIcons){let t=g(n.token);// modified to filter restricted effects
|
|
if(// Copied from CombatTracker.getData(...)
|
|
a.effects=new Set,n.token&&(n.token.effects.forEach(t=>a.effects.add(t)),n.token.overlayEffect&&a.effects.add(n.token.overlayEffect)),n.actor)for(let r of n.actor.temporaryEffects)r.statuses.has(CONFIG.specialStatusEffects.DEFEATED)||r.icon&&!t.includes(r.name??r.label)&&a.effects.add(r.icon);// end of copy
|
|
}}}}return n}async function d(...t){this.effects.renderable=!1,this.effects.removeChildren().forEach(t=>t.destroy()),this.effects.bg=this.effects.addChild(new PIXI.Graphics),this.effects.overlay=null;// Categorize new effects
|
|
let a=this.document.effects,n=this.actor?.temporaryEffects||[],o={src:this.document.overlayEffect,tint:null};if(r.TVA_CONFIG.displayEffectIconsOnHover&&(this.effects.visible=this.hover),a.length||n.length){let t=g(this.document);n=n.filter(a=>!t.includes(a.name??a.label)),a=a.filter(// for tokens without representing actors effects are just stored as paths to icons
|
|
a=>"string"==typeof a||!t.includes(a.name??a.label))}// End of modifications
|
|
// Draw status effects
|
|
if(a.length||n.length){let t=[];// Draw actor effects first
|
|
for(let a of n){if(!a.icon)continue;let n=Color.from(a.tint??null);if(a.getFlag("core","overlay")){o={src:a.icon,tint:n};continue}t.push(this._drawEffect(a.icon,n))}// Next draw token effects
|
|
for(let n of a)t.push(this._drawEffect(n,null));await Promise.all(t)}// Draw overlay effect
|
|
this.effects.overlay=await this._drawOverlay(o.src,o.tint),this._refreshEffects(),this.effects.renderable=!0}function g(t){let a=r.TVA_CONFIG.filterIconList;if(r.TVA_CONFIG.filterCustomEffectIcons){let r=(0,n.getAllEffectMappings)(t);r&&(a=a.concat(r.map(t=>t.expression)))}return a}}),parcelRequire.register("9znht",function(t,a){$parcel$export(t.exports,"registerHideElementWrappers",()=>s);var n=parcelRequire("9IngI"),r=parcelRequire("3pMx9");let o="HideElement";function s(){(0,r.unregisterWrapper)(o,"Token.prototype._getTooltipText"),n.FEATURE_CONTROL[o]&&n.TVA_CONFIG.hideElevationTooltip&&(0,r.registerWrapper)(o,"Token.prototype._getTooltipText",l,"WRAPPER"),(0,r.unregisterWrapper)(o,"Token.prototype._refreshBorder"),n.FEATURE_CONTROL[o]&&n.TVA_CONFIG.hideTokenBorder&&(0,r.registerWrapper)(o,"Token.prototype._refreshBorder",c,"OVERRIDE")}function l(t,...a){return t(...a),""}function c(...t){}}),parcelRequire.register("56MAr",function(t,a){$parcel$export(t.exports,"registerHUDWrappers",()=>c);var n=parcelRequire("6aWyX"),r=parcelRequire("bZ3HW"),o=parcelRequire("9IngI"),s=parcelRequire("3pMx9");let l="HUD";function c(){(0,s.unregisterWrapper)(l,"TokenHUD.prototype.clear"),o.FEATURE_CONTROL[l]&&(0,s.registerWrapper)(l,"TokenHUD.prototype.clear",p,"MIXED")}function p(t,...a){// HUD should not close if we're in assisted overlay positioning mode
|
|
if(f(),!r.Reticle.active||"hud"!==r.Reticle.mode)return t(...a)}async function f(){let{actor:t,variants:a}=n.TOKEN_HUD_VARIANTS;t&&(a?.length?t.setFlag("token-variants","variants",a):t.unsetFlag("token-variants","variants")),n.TOKEN_HUD_VARIANTS.actor=null,n.TOKEN_HUD_VARIANTS.variants=null}}),parcelRequire.register("bZ3HW",function(t,a){$parcel$export(t.exports,"Reticle",()=>l);var n=parcelRequire("eYkM9"),r=parcelRequire("4rd87"),o=parcelRequire("8QbcE"),s=parcelRequire("bFZU7");class l{static app;static fields;static reticleOverlay;static active=!1;static hitTest;static token=null;static dialog=null;// Offset calculation controls
|
|
static mode="tooltip";static increment=1;static _onReticleMove(t){if(this.reticleOverlay.isMouseDown){let a=t.data.getLocalPosition(this.reticleOverlay);this.config.pOffsetX=0,this.config.pOffsetY=0,this.config.offsetX=0,this.config.offsetY=0,"token"===this.mode&&(this.config.linkRotation=!0,this.config.linkMirror=!0),this.tvaOverlay.refresh(this.config,{preview:!0});let n={x:this.tvaOverlay.x,y:this.tvaOverlay.y};if(this.tvaOverlay.overlayConfig.parentID){let t=this.tvaOverlay;do t=t.parent,n.x+=t.x,n.y+=t.y;while(!(t instanceof o.TVAOverlay))}let r=a.x-n.x,s=a.y-n.y,l=0;// let lPos = event.data.getLocalPosition(this.tvaOverlay);
|
|
// console.log(lPos);
|
|
// // let dx = lPos.x;
|
|
// // let dy = lPos.y;
|
|
if(!this.config.animation.relative&&(l=this.config.angle,this.config.linkRotation&&(l+=this.tvaOverlay.object.document.rotation)),[r,s]=f(0,0,r,s,l),r=p(r,this.increment),s=p(s,this.increment),"static"===this.mode)this.config.pOffsetX=r,this.config.pOffsetY=s;else if("token"===this.mode)this.config.offsetX=-r/this.tvaOverlay.object.w,this.config.offsetY=-s/this.tvaOverlay.object.h;else{let t,a,n=this.tvaOverlay.object;this.tvaOverlay.overlayConfig.parentID?(t=(this.tvaOverlay.parent.shapesWidth??this.tvaOverlay.parent.width)/this.tvaOverlay.parent.scale.x,a=(this.tvaOverlay.parent.shapesHeight??this.tvaOverlay.parent.height)/this.tvaOverlay.parent.scale.y):(t=n.w,a=n.h),"tooltip"===this.mode?(Math.abs(r)>=t/2?(this.config.offsetX=.5*(r<0?1:-1),r+=t/2*(r<0?1:-1)):(this.config.offsetX=-r/this.tvaOverlay.object.w,r=0),Math.abs(s)>=a/2?(this.config.offsetY=.5*(s<0?1:-1),s+=a/2*(s<0?1:-1)):(this.config.offsetY=-s/this.tvaOverlay.object.h,s=0)):Math.abs(r)>=t/2?(this.config.offsetX=.5*(r<0?1:-1),r+=t/2*(r<0?1:-1)):Math.abs(s)>=a/2?(this.config.offsetY=.5*(s<0?1:-1),s+=a/2*(s<0?1:-1)):(this.config.offsetX=-r/this.tvaOverlay.object.w,r=0,this.config.offsetY=-s/this.tvaOverlay.object.h,s=0),this.config.pOffsetX=r,this.config.pOffsetY=s}this.tvaOverlay.refresh(this.config,{preview:!0})}}static minimizeApps(){Object.values(ui.windows).forEach(t=>{(t instanceof r.OverlayConfig||t instanceof n.default)&&t.minimize()})}static maximizeApps(){Object.values(ui.windows).forEach(t=>{(t instanceof r.OverlayConfig||t instanceof n.default)&&t.maximize()})}static activate({tvaOverlay:t=null,config:a={}}={}){if(this.deactivate()||!canvas.ready||!t||!a)return!1;this.reticleOverlay&&this.reticleOverlay.destroy(!0);let n=canvas.app.renderer.plugins.interaction;return n.cursorStyles.reticle||(n.cursorStyles.reticle="url('modules/token-variants/img/reticle.webp'), auto"),this.tvaOverlay=t,this.minimizeApps(),this.config=(0,s.evaluateOverlayExpressions)(deepClone(a),this.tvaOverlay.object,{overlayConfig:a}),// Setup the overlay to be always visible while we're adjusting its position
|
|
this.config.alwaysVisible=!0,this.active=!0,// Create the reticle overlay
|
|
this.reticleOverlay=new PIXI.Container,this.reticleOverlay.hitArea=canvas.dimensions.rect,this.reticleOverlay.cursor="reticle",this.reticleOverlay.interactive=!0,this.reticleOverlay.zIndex=1/0,this.reticleOverlay.on("mousedown",t=>{t.preventDefault(),2!=t.data.originalEvent.which&&2!=t.data.originalEvent.nativeEvent.which&&(this.reticleOverlay.isMouseDown=!0,this._onReticleMove(t))}),this.reticleOverlay.on("pointermove",t=>{t.preventDefault(),// event.stopPropagation();
|
|
this._onReticleMove(t)}),this.reticleOverlay.on("mouseup",t=>{t.preventDefault(),this.reticleOverlay.isMouseDown=!1}),this.reticleOverlay.on("click",t=>{t.preventDefault(),(2==t.data.originalEvent.which||2==t.data.originalEvent.nativeEvent.which)&&this.deactivate()}),canvas.stage.addChild(this.reticleOverlay),this.dialog=c(),!0}static deactivate(){if(this.active){this.reticleOverlay&&this.reticleOverlay.parent?.removeChild(this.reticleOverlay),this.active=!1,this.tvaOverlay=null,this.dialog&&this.dialog._state!==Application.RENDER_STATES.CLOSED&&this.dialog.close(!0),this.dialog=null,this.maximizeApps();let t=Object.values(ui.windows).find(t=>t instanceof r.OverlayConfig);if(!t){this.config=null;return}let a=$(t.form);return["pOffsetX","pOffsetY","offsetX","offsetY"].forEach(t=>{t in this.config&&a.find(`[name="${t}"]`).val(this.config[t])}),"token"===this.mode?(["linkRotation","linkMirror"].forEach(t=>{a.find(`[name="${t}"]`).prop("checked",!0)}),["linkDimensionsX","linkDimensionsY"].forEach(t=>{a.find(`[name="${t}"]`).prop("checked",!1)})):["linkRotation","linkMirror"].forEach(t=>{a.find(`[name="${t}"]`).prop("checked",!1)}),"hud"===this.mode&&a.find('[name="ui"]').prop("checked",!0).trigger("change"),a.find('[name="anchor.x"]').val(this.config.anchor.x),a.find('[name="anchor.y"]').val(this.config.anchor.y).trigger("change"),this.config=null,!0}}}function c(){let t=new Dialog({title:"Set Overlay Position",content:`
|
|
<style>
|
|
.images { display: flex; }
|
|
.images a { flex: 20%; width: 50px; margin: 2px; }
|
|
.images a.active img { border-color: orange; border-width: 2px; }
|
|
.anchorlbl {margin: auto; display: table; }
|
|
</style>
|
|
<div class="images">
|
|
<a data-id="token"><img src="modules/token-variants/img/token_mode.png"></img></a>
|
|
<a data-id="tooltip"><img src="modules/token-variants/img/tooltip_mode.png"></img></a>
|
|
<a data-id="hud"><img src="modules/token-variants/img/hud_mode.png"></img></a>
|
|
<a data-id="static"><img src="modules/token-variants/img/static_mode.png"></img></a>
|
|
</div>
|
|
<br>
|
|
<label class="anchorlbl">Anchor</label>
|
|
<div class="tva-anchor">
|
|
<input type="radio" class="top left" name="anchor">
|
|
<input type="radio" class="top center" name="anchor">
|
|
<input type="radio" class="top right" name="anchor">
|
|
<input type="radio" class="mid left" name="anchor">
|
|
<input type="radio" class="mid center" name="anchor">
|
|
<input type="radio" class="mid right" name="anchor">
|
|
<input type="radio" class="bot left" name="anchor">
|
|
<input type="radio" class="bot center" name="anchor">
|
|
<input type="radio" class="bot right" name="anchor">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Step Size</label>
|
|
<div class="form-fields">
|
|
<input type="number" name="step" min="0" step="1" value="${l.increment}">
|
|
</div>
|
|
</div>
|
|
<p class="notes"><b>Left-Click</b> to move the overlay</p>
|
|
<p class="notes"><b>Middle-Click</b> or <b>Close Dialog</b> to exit overlay positioning</p>
|
|
`,buttons:{},render:t=>{// Mode Images
|
|
let a=t.find(".images a");t.find(".images a").on("click",t=>{a.removeClass("active");let n=$(t.target).closest("a");n.addClass("active"),l.mode=n.data("id")}),t.find(`[data-id="${l.mode}"]`).addClass("active");// Anchor
|
|
let n=l.config?.anchor?.x||0,r=l.config?.anchor?.y||0,o="";n<.5?o+=".left":n>.5?o+=".right":o+=".center",r<.5?o+=".top":r>.5?o+=".bot":o+=".mid",t.find(".tva-anchor").find(o).prop("checked",!0),// end - Pre-select anchor
|
|
t.find('input[name="anchor"]').on("change",t=>{let a,n;let r=$(t.target);a=r.hasClass("left")?0:r.hasClass("center")?.5:1,n=r.hasClass("top")?0:r.hasClass("mid")?.5:1,l.config.anchor.x=a,l.config.anchor.y=n}),t.find('[name="step"]').on("input",t=>{l.increment=$(t.target).val()||1})},close:()=>l.deactivate()});return t.render(!0),setTimeout(()=>t.setPosition({left:200,top:window.innerHeight/2,height:"auto"}),100),t}function p(t,a,n=0){return Math.ceil((t-n)/a)*a+n}function f(t,a,n,r,o){var s=Math.PI/180*o,l=Math.cos(s),c=Math.sin(s);return[l*(n-t)+c*(r-a)+t,l*(r-a)-c*(n-t)+a]}}),parcelRequire.register("kPeJW",function(t,a){$parcel$export(t.exports,"registerUserMappingWrappers",()=>l),$parcel$export(t.exports,"assignUserSpecificImage",()=>d),$parcel$export(t.exports,"unassignUserSpecificImage",()=>h),$parcel$export(t.exports,"assignUserSpecificImageToSelected",()=>g),$parcel$export(t.exports,"unassignUserSpecificImageFromSelected",()=>u);var n=parcelRequire("9IngI"),r=parcelRequire("eeGZt"),o=parcelRequire("3pMx9");let s="UserMappings";function l(){(0,o.registerWrapper)(s,"Tile.prototype.draw",c),(0,o.registerWrapper)(s,"Token.prototype.draw",c)}async function c(t,...a){let n,r;// If the Token/Tile has a UserToImage mappings momentarily set document.texture.src to it
|
|
// so that it's texture gets loaded instead of the actual Token image
|
|
let o=this.document.getFlag("token-variants","userMappings")||{},s=o[game.userId];return s?(r=this.document.texture.src,this.document.texture.src=s,this.tva_iconOverride=s,n=await t(...a),this.document.texture.src=r,p(this,s)):(p(this),n=await t(...a)),n}/**
|
|
* If the img is the same as TVA_CONFIG.invisibleImage then we'll override the isVisible
|
|
* getter to return false of this client if it's not a GM. Reset it to default if not.
|
|
* @param {*} obj object whose isVisible is to be overriden
|
|
* @param {*} img UserToImage mapping
|
|
*/function p(t,a){if(a&&(0,r.decodeURISafely)(a)===n.TVA_CONFIG.invisibleImage&&!t.tva_customVisibility){let a=f(t).get;Object.defineProperty(t,"isVisible",{get:function(){let t=a.call(this);return(!t||!!game.user.isGM)&&t},configurable:!0}),t.tva_customVisibility=!0}else!a&&t.tva_customVisibility&&(Object.defineProperty(t,"isVisible",f(t)),delete t.tva_customVisibility)}function f(t){let a=Object.getPrototypeOf(t),n=null;for(;a&&!(n=Object.getOwnPropertyDescriptor(a,"isVisible"));)a=Object.getPrototypeOf(a);return n}function d(t,a,{userName:n=null,userId:r=null}={}){if(!a)return h(t,{userName:n,userId:r});if(n instanceof Array){for(let r of n)d(t,a,{userName:r});return}if(r instanceof Array){for(let n of r)d(t,a,{userId:n});return}let o=r;if(!o&&n&&(o=game.users.find(t=>t.name===n)?.id),!o)return;let s=t.document??t,l=s.getFlag("token-variants","userMappings")||{};l[o]=a,s.setFlag("token-variants","userMappings",l)}function g(t,a={}){let n=[...canvas.tokens.controlled];for(let r of n)d(r,t,a)}function h(t,{userName:a=null,userId:n=null}={}){if(a instanceof Array){for(let n of a)h(t,{userName:n});return}if(n instanceof Array){for(let a of n)h(t,{userId:a});return}let r=n;if(!r&&a&&(r=game.users.find(t=>t.name===a)?.id),r){let a={};a["flags.token-variants.userMappings.-="+r]=null,(t.document??t).update(a)}else a||n||(t.document??t).unsetFlag("token-variants","userMappings")}function u(t={}){let a=[...canvas.tokens.controlled];for(let n of a)h(n,t)}}),parcelRequire.register("dxtrh",function(t,a){$parcel$export(t.exports,"default",()=>g);var n=parcelRequire("coMHP"),r=parcelRequire("eeGZt"),o=parcelRequire("7OP4c"),s=parcelRequire("9IngI"),l=parcelRequire("fVv34"),c=parcelRequire("2jMtH"),p=parcelRequire("8MWlo");async function f(t,a,n,o,s){let l=o.ignorePortrait,c=o.ignoreToken;if(o.diffImages){let a=[];o.ignorePortrait||0==((a=await (0,p.doImageSearch)(t.name,{searchType:s??r.SEARCH_TYPE.PORTRAIT,simpleResults:!0,searchOptions:o.searchOptions}))??[]).length||(l=!0,await (0,r.updateActorImage)(t,a[0],!1,o.compendium)),o.ignoreToken||0==((a=await (0,p.doImageSearch)(t.prototypeToken.name,{searchType:r.SEARCH_TYPE.TOKEN,simpleResults:!0,searchOptions:o.searchOptions}))??[]).length||(c=!0,(0,r.updateTokenImage)(a[0],{actor:t,pack:o.compendium,applyDefaultConfig:!1}))}else{let a=await (0,p.doImageSearch)(t.name,{searchType:s??r.SEARCH_TYPE.PORTRAIT_AND_TOKEN,simpleResults:!0,searchOptions:o.searchOptions});0!=(a??[]).length&&(l=c=!0,(0,r.updateTokenImage)(a[0],{actor:t,actorUpdate:{img:a[0]},pack:o.compendium,applyDefaultConfig:!1}))}!(c&&l)&&o.autoDisplayArtSelect&&d(t,a,n,o,s)}function d(t,a,s,l,c){l.diffImages?l.ignorePortrait||l.ignoreToken?l.ignorePortrait?(0,o.addToQueue)(t.name,{searchType:c??r.SEARCH_TYPE.TOKEN,object:t,image1:a,image2:s,displayMode:o.ArtSelect.IMAGE_DISPLAY.TOKEN,searchOptions:l.searchOptions,callback:async function(a,n){(0,r.updateTokenImage)(a,{actor:t,imgName:n,applyDefaultConfig:!1})}}):l.ignoreToken&&(0,o.addToQueue)(t.name,{searchType:c??r.SEARCH_TYPE.PORTRAIT,object:t,image1:a,image2:s,displayMode:o.ArtSelect.IMAGE_DISPLAY.PORTRAIT,searchOptions:l.searchOptions,callback:async function(a,n){await (0,r.updateActorImage)(t,a)}}):(0,o.addToQueue)(t.name,{searchType:c??r.SEARCH_TYPE.PORTRAIT,object:t,preventClose:!0,image1:a,image2:s,displayMode:o.ArtSelect.IMAGE_DISPLAY.PORTRAIT,searchOptions:l.searchOptions,callback:async function(a,p){await (0,r.updateActorImage)(t,a),(0,n.showArtSelect)(t.prototypeToken.name,{searchType:c??r.SEARCH_TYPE.TOKEN,object:t,force:!0,image1:a,image2:s,displayMode:o.ArtSelect.IMAGE_DISPLAY.TOKEN,searchOptions:l.searchOptions,callback:(a,n)=>(0,r.updateTokenImage)(a,{actor:t,imgName:n,applyDefaultConfig:!1})})}}):(0,o.addToQueue)(t.name,{searchType:c??r.SEARCH_TYPE.PORTRAIT_AND_TOKEN,object:t,image1:a,image2:s,displayMode:o.ArtSelect.IMAGE_DISPLAY.PORTRAIT_TOKEN,searchOptions:l.searchOptions,callback:async function(a,n){await (0,r.updateActorImage)(t,a),(0,r.updateTokenImage)(a,{actor:t,imgName:n,applyDefaultConfig:!1})}})}class g extends FormApplication{constructor(){super({},{}),this.searchOptions=deepClone((0,s.getSearchOptions)()),mergeObject(this.searchOptions,deepClone(s.TVA_CONFIG.compendiumMapper.searchOptions)),this._fixSearchPaths()}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-compendium-map-config",classes:["sheet"],template:"modules/token-variants/templates/compendiumMap.html",resizable:!1,minimizable:!1,title:game.i18n.localize("token-variants.settings.compendium-mapper.Name"),width:500})}async getData(t){let a=super.getData(t);a=mergeObject(a,s.TVA_CONFIG.compendiumMapper);let n=["Actor","Cards","Item","Macro","RollTable"];a.supportedPacks=n.join(", ");let o=[];return game.packs.forEach(t=>{!t.locked&&n.includes(t.documentName)&&o.push({title:t.title,id:t.collection,type:t.documentName})}),a.compendiums=o,a.compendium=s.TVA_CONFIG.compendiumMapper.compendium,a.categories=(0,r.BASE_IMAGE_CATEGORIES).concat(s.TVA_CONFIG.customImageCategories),a.category=s.TVA_CONFIG.compendiumMapper.category,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find(".token-variants-override-category").change(this._onCategoryOverride).trigger("change"),t.find(".token-variants-auto-apply").change(this._onAutoApply),t.find(".token-variants-diff-images").change(this._onDiffImages),t.find(".token-variants-search-options").on("click",this._onSearchOptions.bind(this)),t.find(".token-variants-missing-images").on("click",this._onMissingImages.bind(this)),$(t).find('[name="compendium"]').change(this._onCompendiumSelect.bind(this)).trigger("change")}async _onAutoApply(t){$(t.target).closest("form").find(".token-variants-auto-art-select").prop("disabled",!t.target.checked)}async _onCategoryOverride(t){$(t.target).closest("form").find(".token-variants-category").prop("disabled",!t.target.checked)}async _onDiffImages(t){$(t.target).closest("form").find(".token-variants-tp-ignore").prop("disabled",!t.target.checked)}async _onCompendiumSelect(t){let a=game.packs.get($(t.target).val());a&&$(t.target).closest("form").find(".token-specific").css("visibility","Actor"===a.documentName?"visible":"hidden")}_fixSearchPaths(){this.searchOptions.searchPaths?.length||(this.searchOptions.searchPaths=deepClone(s.TVA_CONFIG.searchPaths))}async _onSearchOptions(t){this._fixSearchPaths(),new(0,l.default)(this.searchOptions,{searchPaths:!0,searchFilters:!0,searchAlgorithm:!0,randomizer:!1,features:!1,popup:!1,permissions:!1,worldHud:!1,misc:!1,activeEffects:!1}).render(!0)}async _onMissingImages(t){new(0,c.default)().render(!0)}async startMapping(t){let a;if(t.diffImages&&t.ignoreToken&&t.ignorePortrait)return;let n=s.TVA_CONFIG.searchPaths;t.searchOptions.searchPaths?.length&&(s.TVA_CONFIG.searchPaths=t.searchOptions.searchPaths),(t.cache||!(0,r.userRequiresImageCache)()||t.searchOptions.searchPaths?.length)&&await (0,p.cacheImages)();let l=function(){t.searchOptions.searchPaths?.length&&(s.TVA_CONFIG.searchPaths=n,(0,p.cacheImages)())},c=game.packs.get(t.compendium),g=(0,s.TVA_CONFIG).compendiumMapper.missingImages.filter(t=>"all"===t.document||t.document===c.documentName).map(t=>t.image),h=t.overrideCategory?t.category:null,u=!1;a="Actor"===c.documentName?async function(a){let n=await c.getDocument(a._id);if("#[CF_tempEntity]"===n.name)return;// Compendium Folders module's control entity
|
|
let o=n.img!==CONST.DEFAULT_TOKEN&&!g.includes(n.img),s=n.prototypeToken.texture.src!==CONST.DEFAULT_TOKEN&&!g.includes(n.prototypeToken.texture.src);t.syncImages&&o!==s&&(o?await (0,r.updateTokenImage)(n.img,{actor:n,applyDefaultConfig:!1}):await (0,r.updateActorImage)(n,n.prototypeToken.texture.src),o=s=!0);let l=!(t.missingOnly&&o)&&!t.ignorePortrait,p=!(t.missingOnly&&s)&&!t.ignoreToken,m=t.showImages?n.img:"",y=t.showImages?n.prototypeToken.texture.src:"";(l||p)&&(t.autoApply?await f(n,m,y,t,h):(u=!0,d(n,m,y,t,h)))}:async function(a){let n=await c.getDocument(a._id);if("#[CF_tempEntity]"===n.name)return;// Compendium Folders module's control entity
|
|
let s="";(n.schema.fields.img||n.schema.fields.texture)&&(s=(n.schema.fields.img??n.schema.fields.texture).initial());let l=null!=n.img&&n.img!==s&&!g.includes(n.img),f=!1;if(!t.missingOnly||!l){if(t.autoApply){let a=await (0,p.doImageSearch)(n.name,{searchType:h??c.documentName,simpleResults:!0,searchOptions:t.searchOptions});0!=(a??[]).length&&(f=!0,await (0,r.updateActorImage)(n,a[0],!1,t.compendium))}t.autoApply&&(!t.autoDisplayArtSelect||f)||(u=!0,(0,o.addToQueue)(n.name,{searchType:h??c.documentName,object:n,image1:t.showImages?n.img:"",displayMode:o.ArtSelect.IMAGE_DISPLAY.IMAGE,searchOptions:t.searchOptions,callback:async function(t,a){await (0,r.updateActorImage)(n,t)}}))}};let m=[];if(c.index.forEach(t=>{m.push(t)}),t.autoApply){let t,n=!0,r=!1,s=0,p=$(`<p>CACHING 0/${m.length}</p>`),f=async function(){for(;n&&s<m.length;)await new Promise((t,n)=>{setTimeout(async()=>{await a(m[s]),t()},10)}),s++,p.html(`${s}/${m.length}`);(r||s===m.length)&&(t?.close(!0),(0,o.addToQueue)("DUMMY",{execute:l}),(0,o.renderFromQueue)())};(t=new Dialog({title:`Mapping: ${c.title}`,content:`
|
|
<div style="text-align:center;" class="fa-3x"><i class="fas fa-spinner fa-pulse"></i></div>
|
|
<div style="text-align:center;" class="counter"></div>
|
|
<button style="width:100%;" class="pause"><i class="fas fa-play-circle"></i> Pause/Start</button>`,buttons:{cancel:{icon:'<i class="fas fa-stop-circle"></i>',label:"Cancel"}},default:"cancel",render:t=>{t.find(".counter").append(p);let a=t.find(".fa-spinner");t.find(".pause").on("click",()=>{n?(n=!1,a.removeClass("fa-pulse")):(n=!0,f(),a.addClass("fa-pulse"))}),setTimeout(async()=>f(),1e3)},close:()=>{r||(r=!0,n?n=!1:f())}})).render(!0)}else{let n=m.map(a);Promise.all(n).then(()=>{(0,o.addToQueue)("DUMMY",{execute:l}),(0,o.renderFromQueue)(),t.missingOnly&&!u&&ui.notifications.warn("Token Variant Art: No documents found containing missing images.")})}}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){(!this.searchOptions.searchPaths?.length||isEmpty(diffObject(this.searchOptions.searchPaths,s.TVA_CONFIG.searchPaths)))&&(this.searchOptions.searchPaths=[]),a.searchOptions=this.searchOptions,await (0,s.updateSettings)({compendiumMapper:a}),a.compendium&&this.startMapping(a)}}}),parcelRequire.register("fVv34",function(t,a){$parcel$export(t.exports,"default",()=>c);var n=parcelRequire("8MWlo"),r=parcelRequire("9IngI"),o=parcelRequire("eeGZt"),s=parcelRequire("eYkM9"),l=parcelRequire("cs88A");class c extends FormApplication{constructor(t,{searchPaths:a=!0,searchFilters:n=!0,searchAlgorithm:o=!0,randomizer:s=!0,popup:l=!0,permissions:c=!0,worldHud:p=!0,misc:f=!0,activeEffects:d=!0,features:g=!1}={}){super({},{}),this.enabledTabs={searchPaths:a,searchFilters:n,searchAlgorithm:o,randomizer:s,features:g,popup:l,permissions:c,worldHud:p,misc:f,activeEffects:d},this.settings=foundry.utils.deepClone(r.TVA_CONFIG),t&&(this.settings=mergeObject(this.settings,t,{insertKeys:!1}),this.dummySettings=t)}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-configure-settings",classes:["sheet"],template:"modules/token-variants/templates/configureSettings.html",resizable:!1,minimizable:!1,title:"Configure Settings",width:700,height:"auto",tabs:[{navSelector:".sheet-tabs",contentSelector:".content",initial:"searchPaths"}]})}async getData(t){let a=super.getData(t),n=this.settings;a.enabledTabs=this.enabledTabs;// === Search Paths ===
|
|
let r=n.searchPaths.map(t=>{let a={};return a.text=t.text,a.icon=this._pathIcon(t.source||""),a.cache=t.cache,a.source=t.source||"",a.types=t.types.join(","),a.config=JSON.stringify(t.config??{}),a.hasConfig=t.config&&!isEmpty(t.config),a});for(let t in a.searchPaths=r,// === Search Filters ===
|
|
a.searchFilters=n.searchFilters,a.searchFilters)a.searchFilters[t].label=t;// === Algorithm ===
|
|
a.algorithm=deepClone(n.algorithm),a.algorithm.fuzzyThreshold=100-100*a.algorithm.fuzzyThreshold,// === Randomizer ===
|
|
// Get all actor types defined by the game system
|
|
a.randomizer=deepClone(n.randomizer);let o=(game.system.entityTypes??game.system.documentTypes).Actor;a.randomizer.actorTypes=o.reduce((t,a)=>{let r=CONFIG.Actor?.typeLabels?.[a]??a;return t[a]={label:game.i18n.has(r)?game.i18n.localize(r):a,disable:n.randomizer[`${a}Disable`]??!1},t},{}),a.randomizer.tokenToPortraitDisabled=!(n.randomizer.tokenCreate||n.randomizer.tokenCopyPaste)||a.randomizer.diffImages,// === Pop-up ===
|
|
a.popup=deepClone(n.popup),// Get all actor types defined by the game system
|
|
a.popup.actorTypes=o.reduce((t,a)=>{let r=CONFIG.Actor?.typeLabels?.[a]??a;return t[a]={type:a,label:game.i18n.has(r)?game.i18n.localize(r):a,disable:n.popup[`${a}Disable`]??!1},t},{});// Split into arrays of max length 3
|
|
let s=[],l=[],c=0;for(let[t,n]of Object.entries(a.popup.actorTypes))l.push(n),++c%3==0&&(s.push(l),l=[]);return l.length>0&&s.push(l),a.popup.actorTypes=s,// === Permissions ===
|
|
a.permissions=n.permissions,// === Token HUD ===
|
|
a.worldHud=deepClone(n.worldHud),a.worldHud.tokenHUDWildcardActive=game.modules.get("token-hud-wildcard")?.active,// === Internal Effects ===
|
|
a.internalEffects=deepClone(n.internalEffects),// === Misc ===
|
|
a.keywordSearch=n.keywordSearch,a.excludedKeywords=n.excludedKeywords,a.systemHpPath=n.systemHpPath,a.runSearchOnPath=n.runSearchOnPath,a.imgurClientId=n.imgurClientId,a.enableStatusConfig=n.enableStatusConfig,a.disableNotifs=n.disableNotifs,a.staticCache=n.staticCache,a.staticCacheFile=n.staticCacheFile,a.stackStatusConfig=n.stackStatusConfig,a.mergeGroup=n.mergeGroup,a.customImageCategories=n.customImageCategories.join(","),a.disableEffectIcons=n.disableEffectIcons,a.displayEffectIconsOnHover=n.displayEffectIconsOnHover,a.filterEffectIcons=n.filterEffectIcons,a.hideElevationTooltip=n.hideElevationTooltip,a.hideTokenBorder=n.hideTokenBorder,a.filterCustomEffectIcons=n.filterCustomEffectIcons,a.filterIconList=n.filterIconList.join(","),a.tilesEnabled=n.tilesEnabled,a.updateTokenProto=n.updateTokenProto,a.imgNameContainsDimensions=n.imgNameContainsDimensions,a.imgNameContainsFADimensions=n.imgNameContainsFADimensions,a.playVideoOnHover=n.playVideoOnHover,a.pauseVideoOnHoverOut=n.pauseVideoOnHoverOut,a.disableImageChangeOnPolymorphed=n.disableImageChangeOnPolymorphed,a.disableImageUpdateOnNonPrototype=n.disableImageUpdateOnNonPrototype,a.disableTokenUpdateAnimation=n.disableTokenUpdateAnimation,a.mappingsCurrentSceneOnly=n.mappingsCurrentSceneOnly,// Controls
|
|
a.pathfinder=["pf1e","pf2e"].includes(game.system.id),a.dnd5e="dnd5e"===game.system.id,a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),// Search Paths
|
|
super.activateListeners(t),t.find("a.create-path").click(this._onCreatePath.bind(this)),t.on("input",".searchSource",this._onSearchSourceTextChange.bind(this)),$(t).on("click","a.delete-path",this._onDeletePath.bind(this)),$(t).on("click","a.convert-imgur",this._onConvertImgurPath.bind(this)),$(t).on("click","a.convert-json",this._onConvertJsonPath.bind(this)),$(t).on("click",".path-image.source-icon a",this._onBrowseFolder.bind(this)),$(t).on("click","a.select-category",(0,l.showPathSelectCategoryDialog).bind(this)),$(t).on("click","a.select-config",(0,l.showPathSelectConfigForm).bind(this)),// Search Filters
|
|
t.on("input","input.filterRegex",this._validateRegex.bind(this));// Active Effects
|
|
let a=t.find('[name="disableEffectIcons"]'),r=t.find('[name="filterEffectIcons"]');a.on("change",t=>{t.target.checked&&r.prop("checked",!1)}).trigger("change"),r.on("change",t=>{t.target.checked&&a.prop("checked",!1)});// Algorithm
|
|
let o=$(t).find('div[data-tab="searchAlgorithm"]');o.find('input[name="algorithm.exact"]').change(t=>{$(t.target).closest("form").find('input[name="algorithm.fuzzy"]').prop("checked",!t.target.checked)}),o.find('input[name="algorithm.fuzzy"]').change(t=>{$(t.target).closest("form").find('input[name="algorithm.exact"]').prop("checked",!t.target.checked)}),o.find('input[name="algorithm.fuzzyThreshold"]').change(t=>{$(t.target).siblings(".token-variants-range-value").html(`${t.target.value}%`)});// Randomizer
|
|
let c=t.find('input[name="randomizer.tokenCreate"]'),p=t.find('input[name="randomizer.tokenCopyPaste"]'),f=t.find('input[name="randomizer.tokenToPortrait"]'),d=()=>{f.prop("disabled",!(c.is(":checked")||p.is(":checked")))};c.change(d),p.change(d);let g=t.find('input[name="randomizer.diffImages"]'),h=t.find('input[name="randomizer.syncImages"]');g.change(()=>{h.prop("disabled",!g.is(":checked")),f.prop("disabled",g.is(":checked"))}),// Token HUD
|
|
t.find('input[name="worldHud.updateActorImage"]').change(t=>{$(t.target).closest("form").find('input[name="worldHud.useNameSimilarity"]').prop("disabled",!t.target.checked)}),// Static Cache
|
|
t.find("button.token-variants-cache-images").click(t=>{let a=$(t.target).closest(".tab"),r=a.find('input[name="staticCache"]'),o=a.find('input[name="staticCacheFile"]');(0,n.cacheImages)({staticCache:r.is(":checked"),staticCacheFile:o.val()})}),// Global Mappings
|
|
t.find("button.token-variants-global-mapping").click(()=>{let t=game.settings.get("core",DefaultTokenConfig.SETTING),a=new foundry.data.PrototypeToken(t),n=new TokenDocument(a,{actor:null});new(0,s.default)(n,{globalMappings:!0}).render(!0)})}/**
|
|
* Validates regex entered into Search Filter's RegEx input field
|
|
*/async _validateRegex(t){this._validRegex(t.target.value)?t.target.style.backgroundColor="":t.target.style.backgroundColor="#ff7066"}_validRegex(t){if(t)try{new RegExp(t)}catch(t){return!1}return!0}/**
|
|
* Open a FilePicker so the user can select a local folder to use as an image source
|
|
*/async _onBrowseFolder(t){let a=$(t.target).closest(".table-row").find(".path-text input"),n=$(t.target).closest(".table-row").find(".path-source input"),r=n.val()||"data",o=a.val();if(r.startsWith("s3:")){let t=r.replace("s3:","");o=`${game.data.files.s3?.endpoint.protocol}//${t}.${game.data.files.s3?.endpoint.host}/${o}`}else if(r.startsWith("rolltable")){let t='<select style="width: 100%;" name="table-name" id="output-tableKey">';game.tables.forEach(a=>{t+=`<option value='${a.name}'>${a.name}</option>`}),t+="</select>",new Dialog({title:"Select a Rolltable",content:t,buttons:{yes:{icon:"<i class='fas fa-check'></i>",label:"Select",callback:t=>{a.val();let n=t.find("select[name='table-name']").val();a.val(n)}}},default:"yes"}).render(!0);return}"json"===r?new FilePicker({type:"text",activeSource:"data",current:o,callback:(t,n)=>{a.val(t)}}).render(!0):new FilePicker({type:"folder",activeSource:r,current:o,callback:(t,r)=>{a.val(r.result.target),"s3"===r.activeSource?n.val(`s3:${r.result.bucket}`):n.val(r.activeSource)}}).render(!0)}/**
|
|
* Converts Imgur path to a rolltable
|
|
*/async _onConvertImgurPath(t){t.preventDefault();let a=$(t.target).closest(".table-row").find(".path-text input"),n=$(t.target).closest(".table-row").find(".path-source input"),o=a.val(),s=""===r.TVA_CONFIG.imgurClientId?"df9d991443bb222":r.TVA_CONFIG.imgurClientId;fetch("https://api.imgur.com/3/gallery/album/"+o,{headers:{Authorization:"Client-ID "+s,Accept:"application/json"}}).then(t=>t.json()).then((async function(t){if(!t.success&&"localhost"===location.hostname){ui.notifications.warn(game.i18n.format("token-variants.notifications.warn.imgur-localhost"));return}let r=t.data,s=[];r.images.forEach((t,a)=>{s.push({type:0,text:t.title??t.description??"",weight:1,range:[a+1,a+1],collection:"Text",drawn:!1,img:t.link})}),await RollTable.create({name:r.title,description:"Token Variant Art auto generated RollTable: https://imgur.com/gallery/"+o,results:s,replacement:!0,displayRoll:!0,img:"modules/token-variants/img/token-images.svg"}),a.val(r.title),n.val("rolltable").trigger("input")}).bind(this)).catch(t=>console.warn("TVA | ",t))}/**
|
|
* Converts Json path to a rolltable
|
|
*/async _onConvertJsonPath(t){t.preventDefault();let a=$(t.target).closest(".table-row").find(".path-text input"),n=$(t.target).closest(".table-row").find(".path-source input"),r=a.val();fetch(r,{headers:{Accept:"application/json"}}).then(t=>t.json()).then((async function(t){if(!t.length>0){ui.notifications.warn(game.i18n.format("token-variants.notifications.warn.json-localhost"));return}let s=t;s.title=(0,o.getFileName)(r);let l=[];s.forEach((t,a)=>{l.push({type:0,text:t.name??"",weight:1,range:[a+1,a+1],collection:"Text",drawn:!1,img:t.path})}),await RollTable.create({name:s.title,description:"Token Variant Art auto generated RollTable: "+r,results:l,replacement:!0,displayRoll:!0,img:"modules/token-variants/img/token-images.svg"}),a.val(s.title),n.val("rolltable").trigger("input")}).bind(this)).catch(t=>console.warn("TVA | ",t))}/**
|
|
* Generates a new search path row
|
|
*/async _onCreatePath(t){t.preventDefault();let a=$(t.currentTarget).closest(".token-variant-table"),n=`
|
|
<li class="table-row flexrow">
|
|
<div class="path-image source-icon">
|
|
<a><i class="${this._pathIcon("")}"></i></a>
|
|
</div>
|
|
<div class="path-source">
|
|
<input class="searchSource" type="text" name="searchPaths.source" value="" placeholder="data"/>
|
|
</div>
|
|
<div class="path-text">
|
|
<input class="searchPath" type="text" name="searchPaths.text" value="" placeholder="Path to folder"/>
|
|
</div>
|
|
<div class="imgur-control">
|
|
<a class="convert-imgur" title="Convert to Rolltable"><i class="fas fa-angle-double-left"></i></a>
|
|
</div>
|
|
<div class="json-control">
|
|
<a class="convert-json" title="Convert to Rolltable"><i class="fas fa-angle-double-left"></i></a>
|
|
</div>
|
|
<div class="path-category">
|
|
<a class="select-category" title="Select image categories/filters"><i class="fas fa-swatchbook"></i></a>
|
|
<input type="hidden" name="searchPaths.types" value="Portrait,Token,PortraitAndToken">
|
|
</div>
|
|
<div class="path-config">
|
|
<a class="select-config" title="Apply configuration to images under this path."><i class="fas fa-cog fa-lg"></i></a>
|
|
<input type="hidden" name="searchPaths.config" value="{}">
|
|
</div>
|
|
<div class="path-cache">
|
|
<input type="checkbox" name="searchPaths.cache" data-dtype="Boolean" checked/>
|
|
</div>
|
|
<div class="path-controls">
|
|
<a class="delete-path" title="Delete path"><i class="fas fa-trash"></i></a>
|
|
</div>
|
|
</li>
|
|
`;a.append(n),this._reIndexPaths(a),this.setPosition()}async _reIndexPaths(t){t.find(".path-source").find("input").each(function(t){$(this).attr("name",`searchPaths.${t}.source`)}),t.find(".path-text").find("input").each(function(t){$(this).attr("name",`searchPaths.${t}.text`)}),t.find(".path-cache").find("input").each(function(t){$(this).attr("name",`searchPaths.${t}.cache`)}),t.find(".path-category").find("input").each(function(t){$(this).attr("name",`searchPaths.${t}.types`)}),t.find(".path-config").find("input").each(function(t){$(this).attr("name",`searchPaths.${t}.config`)})}async _onDeletePath(t){t.preventDefault();let a=t.currentTarget.closest(".table-row");a.remove();let n=$(t.currentTarget).closest(".token-variant-table");this._reIndexPaths(n),this.setPosition()}async _onSearchSourceTextChange(t){let a=this._pathIcon(t.target.value),n="fas fa-info"===a,r="fas fa-brackets-curly"===a,o=$(t.currentTarget).closest(".table-row").find(".imgur-control");n?o.addClass("active"):o.removeClass("active");let s=$(t.currentTarget).closest(".table-row").find(".json-control");r?s.addClass("active"):s.removeClass("active"),$(t.currentTarget).closest(".table-row").find(".path-image i").attr("class",a)}// Return icon appropriate for the path provided
|
|
_pathIcon(t){return t.startsWith("s3")?"fas fa-database":t.startsWith("rolltable")?"fas fa-dice":t.startsWith("forgevtt")||t.startsWith("forge-bazaar")?"fas fa-hammer":t.startsWith("imgur")?"fas fa-info":t.startsWith("json")?"fas fa-brackets-curly":"fas fa-folder"}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){let n=this.settings;// Search Filters
|
|
for(let t in a=expandObject(a),// Search Paths
|
|
n.searchPaths=a.hasOwnProperty("searchPaths")?Object.values(a.searchPaths):[],n.searchPaths.forEach(t=>{if(t.source||(t.source="data"),t.types?t.types=t.types.split(","):t.types=[],t.config)try{t.config=JSON.parse(t.config)}catch(a){delete t.config}else delete t.config}),a.searchFilters)this._validRegex(a.searchFilters[t].regex)||(a.searchFilters[t].regex="");mergeObject(n.searchFilters,a.searchFilters),// Algorithm
|
|
a.algorithm.fuzzyLimit=parseInt(a.algorithm.fuzzyLimit),(isNaN(a.algorithm.fuzzyLimit)||a.algorithm.fuzzyLimit<1)&&(a.algorithm.fuzzyLimit=50),a.algorithm.fuzzyThreshold=(100-a.algorithm.fuzzyThreshold)/100,mergeObject(n.algorithm,a.algorithm),// Randomizer
|
|
mergeObject(n.randomizer,a.randomizer),// Pop-up
|
|
mergeObject(n.popup,a.popup),// Permissions
|
|
mergeObject(n.permissions,a.permissions),// Token HUD
|
|
mergeObject(n.worldHud,a.worldHud),// Internal Effects
|
|
mergeObject(n.internalEffects,a.internalEffects),// Misc
|
|
mergeObject(n,{keywordSearch:a.keywordSearch,excludedKeywords:a.excludedKeywords,systemHpPath:a.systemHpPath?.trim(),runSearchOnPath:a.runSearchOnPath,imgurClientId:a.imgurClientId,enableStatusConfig:a.enableStatusConfig,disableNotifs:a.disableNotifs,staticCache:a.staticCache,staticCacheFile:a.staticCacheFile,tilesEnabled:a.tilesEnabled,stackStatusConfig:a.stackStatusConfig,mergeGroup:a.mergeGroup,customImageCategories:(a.customImageCategories||"").split(",").map(t=>t.trim()).filter(t=>t),disableEffectIcons:a.disableEffectIcons,displayEffectIconsOnHover:a.displayEffectIconsOnHover,filterEffectIcons:a.filterEffectIcons,hideElevationTooltip:a.hideElevationTooltip,hideTokenBorder:a.hideTokenBorder,filterCustomEffectIcons:a.filterCustomEffectIcons,filterIconList:(a.filterIconList||"").split(",").map(t=>t.trim()).filter(t=>t),updateTokenProto:a.updateTokenProto,imgNameContainsDimensions:a.imgNameContainsDimensions,imgNameContainsFADimensions:a.imgNameContainsFADimensions,playVideoOnHover:a.playVideoOnHover,pauseVideoOnHoverOut:a.pauseVideoOnHoverOut,disableImageChangeOnPolymorphed:a.disableImageChangeOnPolymorphed,disableImageUpdateOnNonPrototype:a.disableImageUpdateOnNonPrototype,disableTokenUpdateAnimation:a.disableTokenUpdateAnimation,mappingsCurrentSceneOnly:a.mappingsCurrentSceneOnly}),// Global Mappings
|
|
n.globalMappings=r.TVA_CONFIG.globalMappings,this.dummySettings?p(this.dummySettings,n,{insertKeys:!1}):(0,r.updateSettings)(n)}}function p(t,a={},{insertKeys:n=!0,insertValues:r=!0,overwrite:o=!0,recursive:s=!0,inplace:l=!0,enforceTypes:c=!1}={},p=0){if(a=a||{},!(t instanceof Object)||!(a instanceof Object))throw Error("One of original or other are not Objects!");let g={insertKeys:n,insertValues:r,overwrite:o,recursive:s,inplace:l,enforceTypes:c};// Iterate over the other object
|
|
for(let n of(0===p&&(l||(t=deepClone(t)),Object.keys(t).some(t=>/\./.test(t))&&(t=expandObject(t)),Object.keys(a).some(t=>/\./.test(t))&&(a=expandObject(a))),Object.keys(a))){let r=a[n];t.hasOwnProperty(n)?d(t,n,r,g,p+1):f(t,n,r,g,p+1)}return t}function f(t,a,n,{insertKeys:r,insertValues:o}={},s){// Recursively create simple objects
|
|
if(n?.constructor===Object&&r){t[a]=p({},n,{insertKeys:!0,inplace:!0});return}// Delete a key
|
|
if(a.startsWith("-=")){delete t[a.slice(2)];return}// Insert a key
|
|
let l=s<=1&&r||s>1&&o;l&&(t[a]=n)}function d(t,a,n,{insertKeys:r,insertValues:o,enforceTypes:s,overwrite:l,recursive:c}={},f){let d=t[a],g=getType(n),h=getType(d);// Recursively merge an inner object
|
|
if("Object"===g&&"Object"===h&&c)return p(d,n,{insertKeys:r,insertValues:o,overwrite:l,inplace:!0,enforceTypes:s},f);// Overwrite an existing value
|
|
if(l){if("undefined"!==h&&g!==h&&s)throw Error("Mismatched data types encountered during object merge.");t[a]=n}}}),parcelRequire.register("2jMtH",function(t,a){$parcel$export(t.exports,"default",()=>s);var n=parcelRequire("9IngI"),r=parcelRequire("eeGZt"),o=parcelRequire("coMHP");class s extends FormApplication{constructor(){super({},{})}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-missing-images",classes:["sheet"],template:"modules/token-variants/templates/missingImageConfig.html",resizable:!0,minimizable:!1,title:"Define Missing Images",width:560,height:"auto"})}async getData(t){let a=super.getData(t);return this.missingImages||(this.missingImages=deepClone(n.TVA_CONFIG.compendiumMapper.missingImages)),a.missingImages=this.missingImages,a.documents=["all","Actor","Cards","Item","Macro","RollTable"],a}_processFormData(t){Array.isArray(t.document)||(t.document=[t.document],t.image=[t.image]);let a=[];for(let n=0;n<t.document.length;n++)a.push({document:t.document[n],image:t.image[n]});return a}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.on("click",".add-row",()=>{let t=this._getSubmitData();this.missingImages=this._processFormData(t),this.missingImages.push({document:"all",image:CONST.DEFAULT_TOKEN}),this.render()}),t.on("click",".delete-row",t=>{let a=this._getSubmitData();this.missingImages=this._processFormData(a);let n=$(t.target).closest("li")[0].dataset.index;this.missingImages.splice(n,1),this.render()}),t.on("click",".file-picker",t=>{new FilePicker({type:"imagevideo",callback:a=>{$(t.target).closest("li").find('[name="image"]').val(a),$(t.target).closest("li").find("img").attr("src",a)}}).render()}),t.on("click",".duplicate-picker",t=>{let a='<select style="width: 100%;" name="compendium">';game.packs.forEach(t=>{a+=`<option value='${t.collection}'>${t.title}</option>`}),a+="</select>",new Dialog({title:"Compendiums",content:a,buttons:{yes:{icon:"<i class='far fa-search'></i>",label:"Search for Duplicates",callback:a=>{let n=new Set,s=new Set,l=game.packs.get(a.find("[name='compendium']").val());l.index.forEach(t=>{n.has(t.img)&&s.add(t.img),n.add(t.img)}),s.size||ui.notifications.info("No duplicates found in: "+l.title);let c=Array.from(s).map(t=>({path:t,name:(0,r.getFileName)(t)})),p=new Map;p.set("Duplicates",c),(0,o.showArtSelect)("Duplicates",{allImages:p,callback:a=>{$(t.target).closest("li").find('[name="image"]').val(a),$(t.target).closest("li").find("img").attr("src",a)}})}}},default:"yes"}).render(!0)})}async _updateObject(t,a){(0,n.updateSettings)({compendiumMapper:{missingImages:this._processFormData(a)}})}}}),parcelRequire.register("bhyh6",function(t,a){$parcel$export(t.exports,"ForgeSearchPaths",()=>o);var n=parcelRequire("9IngI"),r=parcelRequire("cs88A");class o extends FormApplication{constructor(){super({},{})}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-search-paths",classes:["sheet"],template:"modules/token-variants/templates/forgeSearchPaths.html",resizable:!0,minimizable:!1,closeOnSubmit:!1,title:game.i18n.localize("token-variants.settings.search-paths.Name"),width:592,height:"auto",scrollY:["ol.token-variant-table"],dragDrop:[{dragSelector:null,dropSelector:null}]})}async getData(t){this.object.paths||(this.object.paths=await this._getPaths());let a=this.object.paths.map(t=>{let a={};return a.text=t.text,a.cache=t.cache,a.share=t.share,a.types=t.types.join(","),a.config=JSON.stringify(t.config??{}),a}),n=super.getData(t);return n.paths=a,n.apiKey=this.apiKey,n}async _getPaths(){let t=deepClone(n.TVA_CONFIG.forgeSearchPaths)||{};return this.userId="undefined"!=typeof ForgeAPI?await ForgeAPI.getUserId():"tempUser",this.apiKey=t[this.userId]?.apiKey,t[this.userId]?.paths||[]}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find("a.create-path").click(this._onCreatePath.bind(this)),$(t).on("click","a.select-category",(0,r.showPathSelectCategoryDialog).bind(this)),$(t).on("click","a.select-config",(0,r.showPathSelectConfigForm).bind(this)),t.find("a.delete-path").click(this._onDeletePath.bind(this)),t.find("button.reset").click(this._onReset.bind(this)),t.find("button.update").click(this._onUpdate.bind(this)),$(t).on("click",".path-image.source-icon a",this._onBrowseFolder.bind(this))}/**
|
|
* Open a FilePicker so the user can select a local folder to use as an image source
|
|
*/async _onBrowseFolder(t){let a=$(t.target).closest(".table-row").find(".path-text input");new FilePicker({type:"folder",activeSource:"forgevtt",current:a.val(),callback:(t,n)=>{"forgevtt"!==n.activeSource?ui.notifications.warn("Token Variant Art: Only 'Assets Library' paths are supported"):a.val(n.result.target)}}).render(!0)}async _onCreatePath(t){t.preventDefault(),await this._onSubmit(t),this.object.paths.push({text:"",cache:!0,share:!0,types:["Portrait","Token","PortraitAndToken"]}),this.render()}async _onDeletePath(t){t.preventDefault(),await this._onSubmit(t);let a=t.currentTarget.closest(".table-row");this.object.paths.splice(a.dataset.index,1),this.render()}_onReset(t){t.preventDefault(),this.object.paths=this._getPaths(),this.render()}async _onUpdate(t){t.preventDefault(),await this._onSubmit(t),this._updatePaths()}async _updateObject(t,a){let n=expandObject(a);n.paths=n.hasOwnProperty("paths")?Object.values(n.paths):[],n.paths.forEach((t,a)=>{if(this.object.paths[a]={text:t.text,cache:t.cache,share:t.share,source:t.source,types:t.types.split(",")},t.config)try{t.config=JSON.parse(t.config),isEmpty(t.config)||(this.object.paths[a].config=t.config)}catch(t){}}),this.apiKey=n.apiKey}_cleanPaths(){// Cleanup empty and duplicate paths
|
|
let t=new Set;return this.object.paths.filter(a=>!(!a.text||t.has(a.text))&&(t.add(a.text),!0))}_updatePaths(){if(this.userId){let t=deepClone(n.TVA_CONFIG.forgeSearchPaths)||{};if(t[this.userId]={paths:this._cleanPaths(),apiKey:this.apiKey},game.user.isGM)(0,n.updateSettings)({forgeSearchPaths:t});else{// Workaround for forgeSearchPaths setting to be updated by non-GM clients
|
|
let a={handlerName:"forgeSearchPaths",args:t,type:"UPDATE"};game.socket?.emit("module.token-variants",a)}}}async close(t={}){return await this._onSubmit(event),this._updatePaths(),super.close(t)}}}),parcelRequire.register("3pmR9",function(t,a){$parcel$export(t.exports,"default",()=>r);var n=parcelRequire("9IngI");class r extends FormApplication{constructor(){super({},{title:"Token HUD Settings"})}static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-hud-settings",classes:["sheet"],template:"modules/token-variants/templates/tokenHUDClientSettings.html",resizable:!1,minimizable:!1,title:"",width:500})}async getData(t){let a=super.getData(t);return mergeObject(a,n.TVA_CONFIG.hud)}/**
|
|
* @param {Event} event
|
|
* @param {Object} formData
|
|
*/async _updateObject(t,a){game.settings.set("token-variants","hudSettings",mergeObject(n.TVA_CONFIG.hud,a))}}}),parcelRequire.register("aDMsz",function(t,a){$parcel$export(t.exports,"default",()=>r);var n=parcelRequire("9IngI");class r extends FormApplication{static get defaultOptions(){return mergeObject(super.defaultOptions,{id:"token-variants-import-export",classes:["sheet"],template:"modules/token-variants/templates/importExport.html",resizable:!1,minimizable:!1,title:"Import/Export",width:250})}/**
|
|
* @param {JQuery} html
|
|
*/activateListeners(t){super.activateListeners(t),t.find(".import").click(this._importFromJSONDialog.bind(this)),t.find(".export").click(()=>{(0,n.exportSettingsToJSON)(),this.close()})}async _importFromJSONDialog(){let t=await renderTemplate("templates/apps/import-data.html",{entity:"token-variants",name:"settings"}),a=new Promise((a,r)=>{new Dialog({title:game.i18n.localize("token-variants.settings.import-export.window.import-dialog"),content:t,buttons:{import:{icon:'<i class="fas fa-file-import"></i>',label:game.i18n.localize("token-variants.common.import"),callback:t=>{let r=t.find("form")[0];if(!r.data.files.length)return ui.notifications?.error("You did not upload a data file!");readTextFromFile(r.data.files[0]).then(t=>{(0,n.importSettingsFromJSON)(t),a(!0)})}},no:{icon:'<i class="fas fa-times"></i>',label:"Cancel",callback:t=>a(!1)}},default:"import"},{width:400}).render(!0)});return this.close(),await a}}}),parcelRequire("coMHP");//# sourceMappingURL=bundle.js.map
|
|
|
|
//# sourceMappingURL=bundle.js.map
|