"use strict";class InitiativeTracker{static make$Tracker(a,b){var r=Math.max;function c(a){return a.find(`.dm_init__stat`).map((a,b)=>{const c=$(b).find(`input`),d="checkbox"===c.attr("type");return{v:d?c.prop("checked"):c.val(),id:$(b).attr("data-id")}}).get()}function d(){const a=y.statsCols.filter(a=>!a.isDeleted&&a.v).map(({id:b,a:c,o:a,v:d})=>({id:b,a:c,o:a,v:d})),b=I.find(`.dm-init-row`).map((b,d)=>{const e=$(d);if(!e.find(`.dm_init__btn_eye`).hasClass(`btn-primary`))return!1;const f=!!e.find(`.init-wrp-creature`).length,g=c(e),h=g.map(b=>{const c=a.find(a=>a.id===b.id);return c?1!==c.v&&f?{u:!0}:b:null}).filter(Boolean),i=e.find(`.init__cond`),j={n:e.find(`input.name`).val(),i:e.find(`input.score`).val(),a:0+e.hasClass(`dm-init-row-active`),c:i.length?i.map((a,b)=>$(b).data("getState")()).get():[],k:h};e.hasClass("dm-init-row-rename")&&(j.m=e.find(`.dm-init-row-link-name`).text());const k=+e.find(`input.hp`).val(),l=+e.find(`input.hp-max`).val();return y.playerInitShowExactHp?(j.h=k,j.g=l):j.hh=isNaN(k)||isNaN(l)?-1:InitiativeTrackerUtil.getWoundLevel(100*k/l),y.playerInitShowOrdinals&&(j.o=e.find(`.dm_init__number`).attr("data-number")),j}).get().filter(Boolean);return a.forEach(a=>delete a.v),{r:b,c:a,n:O.val()}}function e(){const a=I.find(`.dm-init-row`),b=a.filter(`.dm-init-row-active`).each((a,b)=>{const c=$(b),d=c.find(`.init__cond`);d.length&&d.each((a,b)=>$(b).data("doTickDown")()),c.removeClass(`dm-init-row-active`)});let c=a.index(b.get(b.length-1))+1;const d=a.get(c++);if(d){const b=$(d);let e=b;do if(e.find(`input.name`).val()===b.find(`input.name`).val()&&e.find(`input.score`).val()===b.find(`input.score`).val()){f(e);const b=a.get(c++);e=b?$(b):null}else break;while(e)}else h();D()}function f(a){if(a.addClass(`dm-init-row-active`),y.statsAddColumns){const b=y.statsCols.filter(a=>a.p&&InitiativeTracker.isCheckboxColAuto(a.p));b.forEach(b=>{const c=a.find(`[data-id=${b.id}]`);"cbAutoLow"===b.p?c.find(`input`).prop("checked",!1):"cbAutoHigh"===b.p&&c.find(`input`).prop("checked",!0)})}}async function g(a){function b(a,b,c){const d=InitiativeTrackerUtil.get$condition({name:a,color:b,turns:c,onStateChange:()=>D()});d.appendTo(H)}let{nameOrMeta:d,customName:f,hp:h,hpMax:j,init:k,isActive:l,source:p,conditions:q,isRollInit:u,isRollHp:v,statsCols:w,isVisible:x}=Object.assign({nameOrMeta:"",customName:"",hp:"",hpMax:"",init:"",conditions:[],isRollInit:y.isRollInit,isRollHp:!1,isVisible:!y.playerInitHideNewMonster},a||{});const z=!!p;d instanceof Object&&(d.name=d.name||d.n,d.displayName=d.displayName||d.d,d.scaledTo=d.scaledTo||(d.s?+d.s:null));const A=d instanceof Object?d.displayName:null,B=d instanceof Object?d.name:d,C=$(`<div class="dm-init-row ${l?"dm-init-row-active":""}"/>`),E=$(`<div class="dm-init-row-lhs"/>`).appendTo(C),F=$(`<input class="form-control input-sm name dm-init-name dm-init-lockable dm-init-row-input ${z?"hidden":""}" placeholder="Name">`).val(B).appendTo(E);if(F.on("change",()=>{i(s),D()}),z){const a=I.find(`.dm-init-row`),b=a.find(".init-wrp-creature").filter((a,b)=>$(b).parent().find(`input.name`).val()===B&&$(b).parent().find(`input.source`).val()===p);let e=null;if(b.length)if(1===b.length){const a=$(b.get(0));a.find(`.init-wrp-creature-link`).append(`<span data-number="1" class="dm_init__number">(1)</span>`),e=2}else e=b.map((a,b)=>$(b).find(`span[data-number]`).data("number")).get().reduce((c,a)=>r(+c,+a),0)+1;const h=$(`
					<div class="init-wrp-creature split">
						<span class="init-wrp-creature-link">
							${$((()=>{if("string"==typeof d||null==d.scaledTo)return Renderer.get().render(`{@creature ${B}|${p}}`);else{const a=[B,p,A,Parser.numberToCr(d.scaledTo)];return Renderer.get().render(`{@creature ${a.join("|")}}`)}})()).attr("tabindex","-1")[0].outerHTML}
							${e?` <span data-number="${e}" class="dm_init__number">(${e})</span>`:""}
						</span>
					</div>
				`).appendTo(E),j=a=>{h.find(`a`).addClass("dm-init-row-link-name").text(a),C.addClass("dm-init-row-rename")};f&&j(f);const k=$(`<div/>`).appendTo(h);$(`<button class="btn btn-default btn-xs dm-init-lockable" title="Rename" tabindex="-1"><span class="glyphicon glyphicon-pencil"></span></button>`).click(async()=>{if(!y.isLocked){const a=await InputUiUtil.pGetUserString({title:"Enter Name"});null!=a&&a.trim()&&(j(a),i(y.sort))}}).appendTo(k),$(`<button class="btn btn-success btn-xs dm-init-lockable" title="Add Another (SHIFT for Roll New)" tabindex="-1"><span class="glyphicon glyphicon-plus"></span></button>`).click(async a=>{y.isLocked||(await g({nameOrMeta:d,init:a.shiftKey?"":O.val(),isActive:C.hasClass("dm-init-row-active"),source:p,isRollHp:y.isRollHp,statsCols:a.shiftKey?null:c(C),isVisible:C.find(`.dm_init__btn_eye`).hasClass("btn-primary")}),i(y.sort))}).appendTo(k),$(`<input class="source hidden" value="${p}">`).appendTo(E),d instanceof Object&&d.scaledTo&&($(`<input class="displayName hidden" value="${A}">`).appendTo(E),$(`<input class="scaledCr hidden" value="${d.scaledTo}">`).appendTo(E))}const G=$(`<div class="split"/>`).appendTo(E),H=$(`<div class="init__wrp_conds"/>`).appendTo(G);$(`<button class="btn btn-warning btn-xs dm-init-row-btn dm-init-row-btn-flag" title="Add Condition" tabindex="-1"><span class="glyphicon glyphicon-flag"/></button>`).appendTo(G).on("click",()=>{const{$modalInner:a}=UiUtil.getShowModal({noMinHeight:!0}),c=$(`<div class="dm-init-modal-wrp-rows"/>`).appendTo(a),d=InitiativeTrackerUtil.CONDITIONS;for(let a=0;a<d.length;a+=3){const b=$(`<div class="row mb-2"/>`).appendTo(c);[d[a],d[a+1],d[a+2]].forEach(a=>{const c=$(`<div class="col-4 text-center"/>`).appendTo(b);a&&$(`<button class="btn btn-default btn-xs btn-dm-init-cond" style="background-color: ${a.color} !important;">${a.name}</button>`).appendTo(c).click(()=>{i.val(a.name),j.val(a.color)})})}c.append(`<hr>`),$(`<div class="row mb-2">
						<div class="col-5">Name (optional)</div>
						<div class="col-2 text-center">Color</div>
						<div class="col-5">Duration (optional)</div>
					</div>`).appendTo(c);const e=$(`<div class="row mb-2"/>`).appendTo(c),[f,g,h]=[...[,,,]].map((a,b)=>$(`<div class="col-${1===b?2:5} text-center"/>`).appendTo(e)),i=$(`<input class="form-control">`).on("keydown",a=>{13===a.which&&n.click()}).appendTo(f),j=$(`<input class="form-control" type="color" value="${MiscUtil.randomColor()}">`).appendTo(g),k=$(`<input class="form-control" type="number" step="1" min="1" placeholder="Unlimited">`).on("keydown",a=>{13===a.which&&n.click()}).appendTo(h),l=$(`<div class="row">`).appendTo(c),m=$(`<div class="col-12 text-center">`).appendTo(l),n=$(`<button class="btn btn-primary">Set Condition</button>`).click(()=>{b(i.val().trim(),j.val(),k.val()),$wrpModal.remove()}).appendTo(m)}),$(`<div class="dm-init-row-mid"/>`).appendTo(C);const J=$(`<div class="dm-init-row-rhs"/>`).appendTo(C),K={curHp:h,maxHp:j},L=()=>{const a=InitiativeTrackerUtil.getWoundLevel(100*+M.val()/+N.val());if(~a){const b=InitiativeTrackerUtil.getWoundMeta(a);M.css("color",b.color),N.css("color",b.color)}else M.css("color",""),N.css("color","")},M=$(`<input class="form-control input-sm hp dm-init-row-input text-right dm_init__hp dm_init__hp--current" value="${K.curHp}">`).change(()=>{P(M,"curHp"),D(),L()}).click(()=>M.select()).appendTo(J);J.append(`<div class="dm_init__hp_slash">/</div>`);const N=$(`<input class="form-control input-sm hp-max dm-init-row-input dm_init__hp dm_init__hp--max" value="${K.maxHp}">`).change(()=>{P(N,"maxHp"),D(),L()}).click(()=>N.select()).appendTo(J);L();const O=$(`<input class="form-control input-sm score dm-init-lockable dm-init-row-input text-center dm_init__ipt--rhs" type="number">`).on("change",()=>i(t)).click(()=>O.select()).val(k).appendTo(J);if(z&&(""===K.curHp||""===K.maxHp||""===k)){const a=UrlUtil.URL_TO_HASH_BUILDER[UrlUtil.PG_BESTIARY]({name:B,source:p});await(async()=>{const b=await Renderer.hover.pCacheAndGet(UrlUtil.PG_BESTIARY,p,a);if(!v&&b.hp.average)K.curHp=K.maxHp=b.hp.average,M.val(K.curHp),N.val(K.maxHp);else if(v&&b.hp.formula){const a=Renderer.dice.roll2(b.hp.formula,{user:!1,name:n(b),label:"HP"});K.curHp=K.maxHp=a,M.val(a),N.val(a)}!k&&u&&O.val(o(b)),L()})()}const P=(a,b)=>{const c=a.val().trim();if(c&&/^[-+0-9]*$/.exec(K[b])&&/^[-+0-9]*$/.exec(c)){const d=/^[+-]\d+/.exec(c),e=c.split(/([+-]\d+)/).filter(a=>a);let f=0;e.forEach(a=>f+=+a),K[b]=d?+K[b]+f:/[-+]/.exec(c)?f:+c,a.val(K[b])}else K[b]=c};return InitiativeTracker.get$btnPlayerVisible(x,D,!1,"dm-init-row-btn","dm_init__btn_eye").appendTo(J),$(`<button class="btn btn-danger btn-xs dm-init-row-btn dm-init-lockable" title="Delete" tabindex="-1"><span class="glyphicon glyphicon-trash"/></button>`).appendTo(J).on("click",()=>{y.isLocked||(C.hasClass(`dm-init-row-active`)&&1<I.find(`.dm-init-row`).length&&e(),C.remove(),D())}),Y(C,w),q.forEach(a=>b(a.name,a.color,a.turns)),C.appendTo(I),D(),C}function h(){if(I.find(`.dm-init-row`).length&&!I.find(`.dm-init-row-active`).length){const a=I.find(`.dm-init-row`),b=$(a.get(0));if(f(b),1<a.length)for(let c=1;c<a.length;++c){const d=$(a.get(c));if(d.find(`input.name`).val()===b.find(`input.name`).val()&&d.find(`input.score`).val()===b.find(`input.score`).val())f(d);else break}O.val(+(O.val()||0)+1),D()}}function i(a){if(y.sort===a){const a=I.find(`.dm-init-row`).sort((c,a)=>{let b,d;b=y.sort===s&&$(c).hasClass("dm-init-row-rename")?$(c).find(".dm-init-row-link-name").text():$(c).find(`input.${y.sort===s?"name":"score"}`).val(),d=y.sort===s&&$(a).hasClass("dm-init-row-rename")?$(a).find(".dm-init-row-link-name").text():$(a).find(`input.${y.sort===s?"name":"score"}`).val();let e=0,f=0;if(y.sort===t)b=+b,d=+d,e=y.dir===u?SortUtil.ascSort(b,d):SortUtil.ascSort(d,b);else{let g=0,h=0;const i=$(c).find(`span[data-number]`);i.length&&(g=i.data("number"));const j=$(a).find(`span[data-number]`);j.length&&(h=j.data("number")),e=y.dir===u?SortUtil.ascSortLower(b,d):SortUtil.ascSortLower(d,b),f=y.dir===u?SortUtil.ascSort(g,h):SortUtil.ascSort(h,g)}return e||f});I.append(a),D()}}function j(){y.dir=y.dir===u?v:u}function k(){I.empty(),y.sort=t,y.dir=v,$(`.dm_init__rounds`).val(1),D()}async function l(a,b){_||b||k(),_=!1,await Promise.all((a.r||[]).map(a=>g({nameOrMeta:a.n,customName:a.m,hp:a.h,hpMax:a.g,init:a.i,isActive:a.a,source:a.s,conditions:a.c,statsCols:a.k,isVisible:a.v,isRollInit:null==a.i}))),i(y.sort),h(),Z(),D(),_||b||$(`.dm_init__rounds`).val(1)}function n(a){return`Initiative Tracker \u2014 ${a.name}`}function o(a){return Renderer.dice.roll2(`1d20${Parser.getAbilityModifier(a.dex)}`,{user:!1,name:n(a),label:"Initiative"})}function p(a){return!y.isRollHp&&a.hp.average?`${a.hp.average}`:y.isRollHp&&a.hp.formula?`${Renderer.dice.roll2(a.hp.formula,{user:!1,name:n(a),label:"HP"})}`:""}async function q(a){const b={s:"NUM",d:"DESC",m:!1,g:!0,r:[]};if(y.importIsAddPlayers)if(!a.a)a.p&&a.p.forEach(a=>{[...Array(a.count||1)].forEach(()=>{b.r.push({n:``,h:"",g:"",i:"",a:0,c:[],v:!0})})});else if(a.d){const c={};a.c=a.c||[],a.c.length&&(y.statsAddColumns=!0),a.c.forEach((a,b)=>c[b]=(a||"").toLowerCase()),y.statsCols.forEach(a=>a.isDeleted=!0);const d={};let e=null;a.c.forEach((a,b)=>{if(a=a||"","hp"===a.toLowerCase())return void(e=b);const c=Object.entries(InitiativeTracker.STAT_COLUMNS).find(([b,c])=>c.abv&&c.abv.toLowerCase()===a.toLowerCase()),f={id:CryptUtil.uid(),e:!0,v:2,o:b,p:c?c[0]:"",po:null,a:a};d[b]=f,y.statsCols.push(f)}),a.d.forEach(a=>{const c={n:a.n||"",i:"",a:0,c:[],v:!0};a.x&&a.x.length?(c.k=a.x.map((a,b)=>b===e?null:{id:d[b].id,v:a||""}).filter(Boolean),c.h=null==e?c.g="":c.g=(a.x[e]||"").trim()):c.h=c.g="",b.r.push(c)})}if(a.items&&a.sources&&(a.l={items:a.items,sources:a.sources}),a.l&&a.l.items){const c=await Promise.all(a.l.items.map(a=>{const b=+a.c,c=a.h,d=(()=>{if(a.uid){const b=/_([\d.,]+)$/.exec(a.uid);return b?+b[1]:null}return null})(),e=c.split(HASH_LIST_SEP)[1];return new Promise(a=>{Renderer.hover.pCacheAndGet(UrlUtil.PG_BESTIARY,e,c).then(c=>{null==d?a({count:b,monster:c}):ScaleCreature.scale(c,d).then(c=>{a({count:b,monster:c})})})})}));c.forEach(a=>{const c=y.importIsRollGroups&&y.isRollInit?o(a.monster):null,d=y.importIsRollGroups?p(a.monster):null;[...Array(a.count||1)].forEach(()=>{const e=`${y.importIsRollGroups?d:p(a.monster)}`;b.r.push({n:{name:a.monster.name,displayName:a.monster._displayName,scaledTo:a.monster._isScaledCr},i:y.isRollInit?`${y.importIsRollGroups?c:o(a.monster)}`:null,a:0,s:a.monster.source,c:[],h:e,g:e})})}),await l(b,y.importIsAppend)}else await l(b,y.importIsAppend)}const s="ALPHA",t="NUMBER",u="ASC",v="DESC",w=a=>!!a,x=a=>null==a||!!a,y={sort:b.s||t,dir:b.d||v,isLocked:!1,isRollInit:x(b.m),isRollHp:w(b.m),importIsRollGroups:x(b.g),importIsAddPlayers:x(b.p),importIsAppend:w(b.a),statsAddColumns:w(b.k),playerInitShowExactHp:w(b.piH),playerInitHideNewMonster:x(b.piV),playerInitShowOrdinals:w(b.piO),playerInitShortTokens:x(b.piS),statsCols:b.c||[]},z=$(`<div class="dm-init dm__data-anchor"/>`),A=()=>{};a.reactor.on("panelResize",A),z.on("destroyed",()=>a.reactor.off("panelResize",A));const B={rows:[],serverInfo:null},C=MiscUtil.debounce(()=>{if(null===B.serverInfo)return;B.rows=B.rows.filter(a=>!a.isDeleted),B.serverInfo=B.serverInfo.filter(a=>!a.isDeleted||(a.server.close(),!1));const a=d();try{B.serverInfo.filter(a=>a.server.isActive).forEach(b=>b.server.sendMessage(a))}catch(a){setTimeout(()=>{throw a})}},100),D=()=>{a.doSaveStateDebounced(),C()},E=()=>{const{$modalInner:a}=UiUtil.getShowModal({title:"Import Settings",cbClose:()=>D()});UiUtil.addModalSep(a),UiUtil.$getAddModalRowCb(a,"Roll creature initiative",y,"isRollInit"),UiUtil.$getAddModalRowCb(a,"Roll creature hit points",y,"isRollHp"),UiUtil.$getAddModalRowCb(a,"Roll groups of creatures together",y,"importIsRollGroups"),UiUtil.$getAddModalRowCb(a,"Add players",y,"importIsAddPlayers"),UiUtil.$getAddModalRowCb(a,"Add to existing tracker state",y,"importIsAppend")},F=ContextUtil.getNextGenericMenuId();ContextUtil.doInitContextMenu(F,async(a,b,c,d)=>{switch(+d.data("ctx-id")){case 0:{const a=await EncounterUtil.pGetInitialState();a?await q(a.data):JqueryUtil.doToast({content:`No saved encounter! Please first go to the Bestiary and create one.`,type:"warning"});break}case 1:{const a=Object.values((await EncounterUtil.pGetSavedState()).savedEncounters||{});if(!a.length)return JqueryUtil.doToast({type:"warning",content:"No saved encounters were found! Go to the Bestiary and create some first."});const b=await InputUiUtil.pGetUserEnum({values:a.map(a=>a.name),placeholder:"Select a save",title:"Select Saved Encounter"});null!=b&&(await q(a[b].data));break}case 2:{const a=await DataUtil.pUserUpload();a&&(await q(a));break}case 3:E();}},["From Current Bestiary Encounter","From Saved Bestiary Encounter","From Bestiary Encounter File",null,"Import Settings"]);const G=$(`<div class="dm-init-wrp-header-outer"/>`).appendTo(z),H=$(`
			<div class="dm-init-wrp-header">
				<div class="dm-init-row-lhs dm-init-header">
					<div class="w-100">Creature/Status</div>
				</div>

				<div class="dm-init-row-mid"/>

				<div class="dm-init-row-rhs">
					<div class="dm-init-header dm-init-header--input dm-init-header--input-wide" title="Hit Points">HP</div>
					<div class="dm-init-header dm-init-header--input" title="Initiative Score">#</div>
					<div style="width: 43px;"/>
				</div>
			</div>
		`).appendTo(G),I=$(`<div class="dm-init-wrp-entries"/>`).appendTo(G),J=$(`<div class="dm-init-wrp-controls"/>`).appendTo(z),K=$(`<div class="flex"/>`).appendTo(J),L=$(`<div class="btn-group flex"/>`).appendTo(K),M=$(`<button class="btn btn-primary btn-xs dm-init-lockable" title="Add Player"><span class="glyphicon glyphicon-plus"/></button>`).appendTo(L),N=$(`<button class="btn btn-success btn-xs dm-init-lockable mr-2" title="Add Monster"><span class="glyphicon glyphicon-print"/></button>`).appendTo(L);$(`<button class="btn btn-default btn-xs mr-2" title="Next Turn"><span class="glyphicon glyphicon-step-forward"/></button>`).appendTo(K).click(()=>e());const O=$(`<input class="form-control ipt-sm dm_init__rounds" type="number" min="1" title="Round">`).val(b.n||1).change(()=>D()).appendTo(K),P=$(`<div class="btn-group flex"/>`).appendTo(J);$(`<button title="Sort Alphabetically" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-sort-by-alphabet"/></button>`).appendTo(P).click(()=>{y.sort===s?j():y.sort=s,i(s)}),$(`<button title="Sort Numerically" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-sort-by-order"/></button>`).appendTo(P).click(()=>{y.sort===t?j():y.sort=t,i(t)});const Q=$(`<div class="flex"/>`).appendTo(J);$(`<button class="btn btn-primary btn-xs mr-2" title="Player Window"><span class="glyphicon glyphicon-user"/></button>`).appendTo(Q).click(()=>{const{$modalInner:b}=UiUtil.getShowModal({title:"Configure Player View",isLarge:!0,fullHeight:!0,cbClose:()=>{B.rows.length&&B.rows.forEach(a=>a.$row.detach())}}),c=UiUtil.$getAddModalRow(b,"div"),d=$(`<button class="btn btn-primary btn-text-insert">Generate All</button>`).click(()=>j.click()),e=$(`<button class="btn btn-primary btn-text-insert">Copy Server Tokens</button>`).click(()=>h.click());$$`<div class="row w-100">
					<div class="col-12">
						<p>
						The Player View is part of a peer-to-peer (i.e., serverless) system to allow players to connect to a DM's initiative tracker. Players should use the <a href="inittrackerplayerview.html">Initiative Tracker Player View</a> page to connect to the DM's instance. As a DM, the usage is as follows:
						<ol>
								<li>Add the required number of players, and input (preferably unique) player names.</li>
								<li>Click "${d}," which will generate a "server token" per player. You can click "${e}" to copy them all as a single block of text, or click on the "Server Token" values to copy them individually. Distribute these tokens to your players (via a messaging service of your choice; we recommend <a href="https://discordapp.com/">Discord</a>). Each player should paste their token into the <a href="inittrackerplayerview.html">Initiative Tracker Player View</a>, following the instructions provided therein.</li>
								<li>
									Get a resulting "client token" from each player via a messaging service of your choice. Then, either:
									<ol type="a">
										<li>Click the "Accept Multiple Clients" button, and paste in text containing multiple client tokens. <b>This will try to find tokens in <i>any</i> text, ignoring everything else.</b> Pasting a chatroom log (containing, for example, usernames and timestamps mixed with tokens) is the expected usage.</li>
										<li>Paste each token into the appropriate "Client Token" field and "Accept Client" on each. A token can be identified by the slugified player name in the first few characters.</li>
									</ol>
								</li>
							</ol>
						</p>
						<p>Once a player's client has been "accepted," it will receive updates from the DM's tracker. <i>Please note that this system is highly experimental. Your experience may vary.</i></p>
					</div>
				</div>`.appendTo(c),UiUtil.addModalSep(b);const f=UiUtil.$getAddModalRow(b,"div"),g=$(`<button class="btn btn-xs btn-primary" title="Add Client">Add Player</button>`).click(()=>l()),h=$(`<button class="btn btn-xs btn-primary" title="Copy any available server tokens to the clipboard">Copy Server Tokens</button>`).click(async()=>{const a=B.rows.filter(a=>!a.isDeleted&&!a.$iptTokenClient.attr("disabled"));a.length?(await MiscUtil.pCopyTextToClipboard(a.map(a=>a.$iptTokenServer.val()).join("\n\n")),JqueryUtil.showCopiedEffect(j)):JqueryUtil.doToast({content:`No free server tokens to copy. Generate some!`,type:"warning"})}),i=$(`<button class="btn btn-xs btn-primary" title="Open a prompt into which text containing client tokens can be pasted">Accept Multiple Clients</button>`).click(()=>{const{$modalInner:b,doClose:c}=UiUtil.getShowModal({title:"Accept Multiple Clients"}),d=$(`<textarea class="form-control dm_init__pl_textarea block mb-2"/>`).keydown(()=>d.removeClass("error-background")),e=$(`<button class="btn btn-xs btn-primary block text-center" title="Add Client">Accept Multiple Clients</button>`).click(async()=>{d.removeClass("error-background");const b=d.val();if(!b.trim()||!PeerUtil.containsAnyTokens(b))d.addClass("error-background");else{const d=await PeerUtil.pConnectClientsToServers(B.serverInfo,b);a.doBindAlertOnNavigation(),d.forEach(a=>{a.rowMeta.$iptTokenClient.val(a._tempTokenToDisplay||"").attr("disabled",!0),a.rowMeta.$btnAcceptClientToken.attr("disabled",!0),delete a._tempTokenToDisplay}),c(),C()}});$$`<div>
							<p>Paste text containing one or more client tokens, and click "Accept Multiple Clients"</p>
							${d}
							<div class="flex-vh-center">${e}</div>
						</div>`.appendTo(b)});$$`
					<div class="row w-100">
						<div class="col-12">
							<div class="flex-inline-v-center mr-2">
								<span class="mr-1">Add a player (client):</span>
								${g}
							</div>
							<div class="flex-inline-v-center mr-2">
								<span class="mr-1">Copy all un-paired server tokens:</span>
								${h}
							</div>
							<div class="flex-inline-v-center mr-2">
								<span class="mr-1">Mass-accept clients:</span>
								${i}
							</div>
						</div>
					</div>
				`.appendTo(f),UiUtil.addModalSep(b);const j=$(`<button class="btn btn-primary btn-xs">Generate All</button>`).click(()=>T(B.rows));UiUtil.$getAddModalRow(b,"div").append($$`
					<div class="row w-100">
						<div class="col-2 bold">Player Name</div>
						<div class="col-3-5 bold">Server Token</div>
						<div class="col-1 text-center">${j}</div>
						<div class="col-3-5 bold">Client Token</div>
					</div>
				`);const k=(a,b,c,d,e,f)=>$$`<div class="row w-100 mb-2 flex">
					<div class="col-2">${a}</div>
					<div class="col-3-5">${b}</div>
					<div class="col-1 flex-vh-center">${c}</div>
					<div class="col-3-5">${d}</div>
					<div class="col-1-5 flex-vh-center">${e}</div>
					<div class="col-0-5 flex-vh-center">${f}</div>
				</div>`,l=()=>{const b={id:CryptUtil.uid()},c=$(`<input class="form-control input-sm">`).keydown(a=>{c.removeClass("error-background"),13===a.which&&e.click()}),d=$(`<input class="form-control input-sm copyable code" readonly disabled>`).click(async()=>{await MiscUtil.pCopyTextToClipboard(d.val()),JqueryUtil.showCopiedEffect(d)}).disableSpellcheck(),e=$(`<button class="btn btn-xs btn-primary" title="Generate Server Token">Generate</button>`).click(()=>T([b])),f=$(`<input class="form-control input-sm code" disabled>`).keydown(a=>{f.removeClass("error-background"),13===a.which&&g.click()}).disableSpellcheck(),g=$(`<button class="btn btn-xs btn-primary" title="Accept Client Token" disabled>Accept Client</button>`).click(async()=>{const c=f.val();if(PeerUtil.isValidToken(c))try{await PeerUtil.pConnectClientsToServers([b.serverInfo],c),a.doBindAlertOnNavigation(),f.prop("disabled",!0),g.prop("disabled",!0),C()}catch(a){JqueryUtil.doToast({content:`Failed to accept client token! Are you sure it was valid? (See the log for more details.)`,type:"danger"}),setTimeout(()=>{throw a})}else f.addClass("error-background")}),h=$(`<button class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"/></button>`).click(()=>{b.$row.remove(),b.isDeleted=!0,b.serverInfo&&(b.serverInfo.server.close(),b.serverInfo.isDeleted=!0),n.find(`.row`).length||l()});return b.$row=k(c,d,e,f,g,h).appendTo(n),b.$iptName=c,b.$iptTokenServer=d,b.$btnGenServerToken=e,b.$iptTokenClient=f,b.$btnAcceptClientToken=g,B.rows.push(b),b},m=UiUtil.$getAddModalRow(b,"div"),n=$(`<div class="w-100"/>`).appendTo(m);B.rows.length?B.rows.forEach(a=>a.$row.appendTo(n)):l()});const R=()=>{},S=function(a){this.isClosed||JqueryUtil.doToast({content:`Server error:\n${a?a.message||a:"(Unknown error)"}`,type:"danger"})},T=async a=>{const b=a.filter(a=>!a.isDeleted).filter(a=>!a.isActive);if(b.every(a=>a.isActive))return JqueryUtil.doToast({content:"No rows require Server Token generation!",type:"warning"});let c=!1;if(b.forEach(a=>{a.$iptName.removeClass("error-background"),a.$iptName.val().trim()||(c=!0,a.$iptName.addClass("error-background"))}),c)return;const d=b.map(a=>(a.isActive=!0,a.$iptName.attr("disabled",!0),a.$btnGenServerToken.attr("disabled",!0),a.$iptName.val()));if(B.serverInfo){await B.serverInfo;const a=await PeerUtil.pInitialiseServersAddToExisting(d,B.serverInfo,R,S,{shortTokens:!!y.playerInitShortTokens});return b.map((b,c)=>(b.name=a[c].name,b.serverInfo=a[c],b.$iptTokenServer.val(a[c].textifiedSdp).attr("disabled",!1),a[c].rowMeta=b,b.$iptTokenClient.attr("disabled",!1),b.$btnAcceptClientToken.attr("disabled",!1),a[c].textifiedSdp))}return B.serverInfo=(async()=>{B.serverInfo=await PeerUtil.pInitialiseServers(d,R,S,{shortTokens:!!y.playerInitShortTokens}),b.forEach((a,b)=>{a.name=B.serverInfo[b].name,a.serverInfo=B.serverInfo[b],a.$iptTokenServer.val(B.serverInfo[b].textifiedSdp).attr("disabled",!1),B.serverInfo[b].rowMeta=a,a.$iptTokenClient.attr("disabled",!1),a.$btnAcceptClientToken.attr("disabled",!1)})})(),await B.serverInfo,b.map(a=>a.serverInfo.textifiedSdp)};z.data("doConnectLocal",async a=>{const b={id:CryptUtil.uid(),$row:$(),$iptName:$(`<input value="local">`),$iptTokenServer:$(),$btnGenServerToken:$(),$iptTokenClient:$(),$btnAcceptClientToken:$()};B.rows.push(b);const c=await T([b]),d=await PeerUtil.pInitialiseClient(c[0],b=>a.handleMessage(b),()=>{});a.clientData=d,await PeerUtil.pConnectClientsToServers([b.serverInfo],d.textifiedSdp),C()});const U=$(`<div class="btn-group flex"/>`).appendTo(Q),V=$(`<button class="btn btn-danger btn-xs" title="Lock Tracker"><span class="glyphicon glyphicon-lock"></span></button>`).appendTo(U);V.on("click",()=>{y.isLocked?(V.removeClass("btn-success").addClass("btn-danger").attr("title","Lock Tracker"),$(".dm-init-lockable").removeClass("disabled"),$("input.dm-init-lockable").prop("disabled",!1)):(V.removeClass("btn-danger").addClass("btn-success").attr("title","Unlock Tracker"),$(".dm-init-lockable").addClass("disabled"),$("input.dm-init-lockable").prop("disabled",!0)),y.isLocked=!y.isLocked,Z()}),$(`<button class="btn btn-default btn-xs mr-2"><span class="glyphicon glyphicon-cog"></span></button>`).appendTo(U).click(()=>{const{$modalInner:a}=UiUtil.getShowModal({title:"Settings",cbClose:()=>{Z(),D()}});UiUtil.addModalSep(a),UiUtil.$getAddModalRowCb(a,"Roll initiative",y,"isRollInit"),UiUtil.$getAddModalRowCb(a,"Roll hit points",y,"isRollHp"),UiUtil.addModalSep(a),UiUtil.$getAddModalRowCb(a,"Player View: Show exact HP",y,"playerInitShowExactHp"),UiUtil.$getAddModalRowCb(a,"Player View: Auto-hide new monsters",y,"playerInitHideNewMonster"),UiUtil.$getAddModalRowCb(a,"Player View: Show ordinals",y,"playerInitShowOrdinals","For example, if you add two Goblins, one will be Goblin (1) and the other Goblin (2), rather than having identical names."),UiUtil.$getAddModalRowCb(a,"Player View: Shorten server tokens",y,"playerInitShortTokens","Server tokens will be roughly half as many characters, but will contain non-standard characters."),UiUtil.addModalSep(a);const b=UiUtil.$getAddModalRowCb(a,"Additional Columns",y,"statsAddColumns"),c=UiUtil.$getAddModalRow(a,"div").addClass("ui-modal__row--stats-header").append(`
						<div class="row dm_init__stats_row">
							<div class="col-1-3"/>
							<div class="col-4-9">Contains...</div>
							<div class="col-2-5">Abbreviation</div>
							<div class="col-1-7 text-center help" title="Only affects creatures. Players are always editable.">Editable?</div>
						</div>
					`),d=UiUtil.$getAddModalRow(a,"div").addClass("ui-modal__row--stats");(()=>{const a=$(`<div class="dm_init__stats_rows mb-2"/>`).appendTo(d),b=$(`<div class="text-center"/>`).appendTo(d),c=b=>{b||(b={id:CryptUtil.uid(),v:0,o:y.statsCols.filter(a=>!a.isDeleted).length+1,e:!0,p:"",po:null,a:""},y.statsCols.push(b));const e=$(`
								<select class="form-control input-xs">
									<option value="">(Empty)</option>
									${Object.entries(InitiativeTracker.STAT_COLUMNS).map(([a,b])=>b.isHr?`<option disabled>\u2014</option>`:`<option value="${a}">${b.name}</option>`)}
								</select>
							`).change(()=>{const a=InitiativeTracker.STAT_COLUMNS[e.val()]||{};b.a=a.abv||"",f.val(b.a),b.po=b.p||null,b.p=e.val()||"",D()});b.p&&e.val(b.p);const f=$(`<input class="form-control input-xs" value="${(b.a||"").escapeQuotes()}">`).change(()=>{b.a=f.val(),D()}),g=$(`<input type="checkbox">`).prop("checked",!!b.e).change(()=>{b.e=g.prop("checked"),D()}),h=InitiativeTracker.get$btnPlayerVisible(b.v,()=>{b.v=h.hasClass("btn-primary--half")?2:h.hasClass("btn-primary")?1:0,D()},!0),i=$(`<button class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"/></button>`).click(()=>{m.remove(),b.isDeleted=!0,d.find(`.dm_init__stats_row`).length||c(),D()}),j=()=>{const a={};d.find(`.dm_init__stats_row`).each((b,c)=>a[$(c).attr("data-id")]=b),y.statsCols.forEach(b=>{const c=a[b.id];b.o=null==c?-1:c})},k=$(`<button class="btn btn-xs btn-default"><span class="glyphicon glyphicon-arrow-up"/></button>`).click(()=>{m.prev().length&&(m.prev().before(m),j(),D())}),l=$(`<button class="btn btn-xs btn-default"><span class="glyphicon glyphicon-arrow-down dm_init__stats_down"/></button>`).click(()=>{m.next().length&&(m.next().after(m),j(),D())}),m=$$`
							<div class="row dm_init__stats_row dm_init__stats_row--item" data-id="${b.id}">
								<div class="col-1-3 btn-group text-center dm_init__stats_up_down">${k}${l}</div>
								<div class="col-1-3 dm_init__stats_up_down--spacer"></div>

								<div class="col-4-9">${e}</div>
								<div class="col-2-8">${f}</div>
								<div class="col-1 text-center">${g}</div>
								<div class="col-1 text-center">${h}</div>
								<div class="col-1 text-center dm_init__stats_del">${i}</div>
							</div>
						`.appendTo(a)};$(`<button class="btn btn-xs btn-default"><span class="glyphicon-plus glyphicon dm_init__stats_add"/></button>`).appendTo(b).click(()=>c()),y.statsCols.length?y.statsCols.forEach(a=>c(a)):c()})(),b.change(()=>{c.toggle(b.prop("checked")),d.toggle(b.prop("checked"))}),c.toggle(b.prop("checked")),d.toggle(b.prop("checked"))});const W=$(`<div class="btn-group"/>`).appendTo(Q),X=$(`<button title="Import an encounter from the Bestiary" class="btn btn-success btn-xs dm-init-lockable"><span class="glyphicon glyphicon-upload"/></button>`).appendTo(W).click(a=>{y.isLocked||ContextUtil.handleOpenContextMenu(a,X,F)});$(`<button title="Reset" class="btn btn-danger btn-xs dm-init-lockable"><span class="glyphicon glyphicon-trash"/></button>`).appendTo(W).click(()=>{y.isLocked||confirm("Are you sure?")&&k()}),M.on("click",async()=>{y.isLocked||(await g({isVisible:!0}),i(y.sort),h())}),N.on("click",()=>{if(y.isLocked)return;const b={doClickFirst:!1,isWait:!1},{$modalInner:c,doClose:d}=UiUtil.getShowModal();c.addClass("flex-col");const e=$(`<div class="split" style="flex-shrink: 0"/>`).appendTo(c),f=$(`<input class="ui-search__ipt-search search form-control" autocomplete="off" placeholder="Search...">`).appendTo(e),j=$(`
				<div class="ui-search__ipt-search-sub-wrp" style="padding-right: 0;">
					<div style="margin-right: 7px;">Add</div>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="1" checked> 1</label>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="2"> 2</label>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="3"> 3</label>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="5"> 5</label>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="8"> 8</label>
					<label class="ui-search__ipt-search-sub-lbl"><input type="radio" name="mon-count" class="ui-search__ipt-search-sub-ipt" value="-1"> <input type="number" class="form-control ui-search__ipt-search-sub-ipt-custom" value="13" min="1"></label>
				</div>
			`).appendTo(e);j.find(`.ui-search__ipt-search-sub-ipt-custom`).click(function(){j.find(`.ui-search__ipt-search-sub-ipt[value=-1]`).prop("checked",!0),$(this).select()});const k=()=>{const a=j.find(`[name="mon-count"]`).filter(":checked").val();return"-1"===a?+j.find(`.ui-search__ipt-search-sub-ipt-custom`).val():+a},l=$(`<label class="ui-search__ipt-search-sub-wrp flex-vh-center"> <span>Roll HP</span></label>`).appendTo(e),m=$(`<input class="mr-1" type="checkbox">`).prop("checked",y.isRollHp).on("change",()=>y.isRollHp=m.prop("checked")).prependTo(l),n=$(`<div class="ui-search__wrp-results"/>`).appendTo(c),o=()=>{b.isWait=!0,n.empty().append(UiUtil.getSearchEnter())},p=()=>{b.isWait=!0,n.empty().append(UiUtil.getSearchNoResults())},q=()=>{const c=f.val().trim(),e=75,j=a.availContent.Creature,l=j.search(c,{fields:{n:{boost:5,expand:!0},s:{expand:!0}},bool:"AND",expand:!0}),q=l.length?l.length:j.documentStore.length,r=l.length?l:Object.values(j.documentStore.docs).slice(0,75).map(a=>({doc:a}));if(n.empty(),r.length){const a=async a=>{const b=a.doc.n,c=a.doc.s,e=k();if(!(isNaN(e)||1>e)){if(await g({nameOrMeta:b,source:c,isRollHp:m.prop("checked")}),1<e)for(let a=1;a<e;++a)await g({nameOrMeta:b,source:c,isRollHp:m.prop("checked")});i(y.sort),h(),D(),d()}},c=a=>$(`
							<div class="ui-search__row">
								<span>${a.doc.n}</span>
								<span>${a.doc.s?`<i title="${Parser.sourceJsonToFull(a.doc.s)}">${Parser.sourceJsonToAbv(a.doc.s)}${a.doc.p?` p${a.doc.p}`:""}</i>`:""}</span>
							</div>
						`);if(b.doClickFirst)return a(r[0]),void(b.doClickFirst=!1);const f=r.slice(0,e);if(f.forEach(b=>c(b).on("click",()=>a(b)).appendTo(n)),q>e){const a=q-e;n.append(`<div class="ui-search__row ui-search__row--readonly">...${a} more result${1==a?" was":"s were"} hidden. Refine your search!</div>`)}}else c.trim()?p():o()};UiUtil.bindAutoSearch(f,{flags:b,search:q,showWait:()=>n.empty().append(UiUtil.getSearchLoading())}),f.focus(),q()}),z.data("getState",function(){const a=I.find(`.dm-init-row`).map((a,b)=>{const d=$(b),e=d.find(`.init__cond`),f=d.find(`input.displayName`),g=d.hasClass(`dm-init-row-rename`)?d.find(`.dm-init-row-link-name`).text():null,h=f.length?{n:d.find(`input.name`).val(),d:f.val(),s:d.find(`input.scaledCr`).val()||""}:d.find(`input.name`).val(),i={n:h,k:c(d),h:d.find(`input.hp`).val(),g:d.find(`input.hp-max`).val(),i:d.find(`input.score`).val(),a:0+d.hasClass(`dm-init-row-active`),s:d.find(`input.source`).val(),c:e.length?e.map((a,b)=>$(b).data("getState")()).get():[],v:d.find(`.dm_init__btn_eye`).hasClass(`btn-primary`)};return g&&(i.m=g),i}).get();return{r:a,s:y.sort,d:y.dir,m:y.isRollHp,g:y.importIsRollGroups,p:y.importIsAddPlayers,a:y.importIsAppend,k:y.statsAddColumns,piH:y.playerInitShowExactHp,piV:y.playerInitHideNewMonster,piO:y.playerInitShowOrdinals,piS:y.playerInitShortTokens,c:y.statsCols.filter(a=>!a.isDeleted),n:O.val()}}),z.data("getSummary",()=>{const a=I.find(`.dm-init-row`).map((a,b)=>$(b).find(`input.name`).val()).get();return`${a.length} creature${1===a.length?"":"s"} ${a.length?`(${a.slice(0,3).join(", ")}${3<a.length?"...":""})`:""}`});const Y=(a,b)=>{const d=a.find(`.dm-init-row-mid`);if(!y.statsAddColumns)return d.empty();const e=a.find(`.name`).val(),f=a.find(`.source`).val(),g=!!f,h=(()=>{const a={};return b?b.forEach(b=>a[b.id]={id:b.id,v:b.v}):d.find(`.dm_init__stat`).each((b,c)=>{const d=$(c),e=d.attr("data-id"),f=d.find(`input`);if("true"!==f.attr("populate-running")){const b="checkbox"===f.attr("type");a[e]={v:b?f.prop("checked"):f.val(),id:e}}}),a})();d.empty(),y.statsCols.forEach(a=>{const b=a.p&&InitiativeTracker.isCheckboxCol(a.p),c=(()=>{if(b){const b=$(`<input type="checkbox" class="dm_init__stat_ipt" ${y.isLocked||!a.e&&g?"disabled":""}>`).change(()=>D()),c=()=>{const c=InitiativeTracker.STAT_COLUMNS[a.p];b.prop("checked",c.get()),D()};return a.p&&a.po&&g?c():h[a.id]?b.prop("checked",h[a.id].v):a.p&&c(),b}else{const b=$(`<input class="form-control input-sm dm_init__stat_ipt text-center" ${y.isLocked||!a.e&&g?"disabled":""}>`).change(()=>D()),c=()=>{b.attr("populate-running",!0);const c=InitiativeTracker.STAT_COLUMNS[a.p];if(g&&c){const a=UrlUtil.URL_TO_HASH_BUILDER[UrlUtil.PG_BESTIARY]({name:e,source:f});(async()=>{const d=await Renderer.hover.pCacheAndGet(UrlUtil.PG_BESTIARY,f,a);b.val(c.get(d)),b.removeAttr("populate-running"),D()})()}};return a.p&&a.po&&g?c():h[a.id]?b.val(h[a.id].v):a.p&&c(),b}})(),i=b?"label":"div";$$`<${i} class="dm_init__stat ${b?"flex-vh-center":""}" data-id="${a.id}">${c}</${i}>`.appendTo(d)})},Z=()=>{y.statsCols=y.statsCols.filter(a=>!a.isDeleted).sort((c,a)=>c.o-a.o);const a=H.find(`.dm-init-row-mid`).empty();y.statsAddColumns&&y.statsCols.forEach(b=>{a.append(`<div class="dm_init__stat_head" ${b.p&&InitiativeTracker.STAT_COLUMNS[b.p]?`title="${InitiativeTracker.STAT_COLUMNS[b.p].name}"`:""}>${b.a||""}</div>`)});const b=I.find(`.dm-init-row`);b.each((a,b)=>Y($(b))),y.statsCols.forEach(a=>a.po=null)};let _=!0;return z.data("doConvertAndLoadBestiaryList",a=>q(a)),l(b).then(()=>i(y.sort)),z}static get$btnPlayerVisible(a,b,c,...d){let e=+(a||!1);const f=()=>0==e?`Hidden in player view`:1==e?`Shown in player view`:`Shown in player view on player characters, hidden in player view on monsters`,g=()=>`${0==e?`btn-default`:1==e?`btn-primary`:`btn-primary btn-primary--half`} btn btn-xs ${d.join(" ")}`,h=()=>0==e?`glyphicon glyphicon-eye-close`:`glyphicon glyphicon-eye-open`,i=$(`<span class="glyphicon ${h()}"/>`),j=$$`<button class="${g()}" title="${f()}" tabindex="-1">${i}</button>`.on("click",()=>{0==e?e++:1==e?e=c?2:0:2==e&&(e=0),j.attr("title",f()),j.attr("class",g()),i.attr("class",h()),b()});return j}static isCheckboxCol(a){return"cbAutoLow"===a||"cbNeutral"===a||"cbAutoHigh"===a}static isCheckboxColAuto(a){return"cbAutoLow"===a||"cbAutoHigh"===a}}InitiativeTracker._GET_STAT_COLUMN_HR=()=>({isHr:!0}),InitiativeTracker.STAT_COLUMNS={hr0:InitiativeTracker._GET_STAT_COLUMN_HR(),hpFormula:{name:"HP Formula",get:a=>(a.hp||{}).formula},armorClass:{name:"Armor Class",abv:"AC",get:a=>a.ac[0]?a.ac[0].ac||a.ac[0]:null},passivePerception:{name:"Passive Perception",abv:"PP",get:a=>a.passive},speed:{name:"Speed",abv:"SPD",get:a=>Math.max(0,...Object.values(a.speed||{}).map(a=>a.number?a.number:a).filter(a=>"number"==typeof a))},spellDc:{name:"Spell DC",abv:"DC",get:a=>Math.max(0,...(a.spellcasting||[]).filter(a=>a.headerEntries).map(a=>a.headerEntries.map(a=>{var b=Math.max;const c=[0];return a.replace(/DC (\d+)/g,(...a)=>c.push(+a[1])),b(...c)}).filter(Boolean)))},legendaryActions:{name:"Legendary Actions",abv:"LA",get:a=>a.legendaryActions||a.legendary?3:null},hr1:InitiativeTracker._GET_STAT_COLUMN_HR(),...(()=>{const a={};return Parser.ABIL_ABVS.forEach(b=>{a[`${b}Save`]={name:`${Parser.attAbvToFull(b)} Save`,abv:b.toUpperCase(),get:a=>a.save&&a.save[b]?a.save[b]:Parser.getAbilityModifier(a[b])}}),a})(),hr2:InitiativeTracker._GET_STAT_COLUMN_HR(),...(()=>{const a={};return Parser.ABIL_ABVS.forEach(b=>{a[`${b}Bonus`]={name:`${Parser.attAbvToFull(b)} Bonus`,abv:b.toUpperCase(),get:a=>Parser.getAbilityModifier(a[b])}}),a})(),hr3:InitiativeTracker._GET_STAT_COLUMN_HR(),...(()=>{const a={};return Parser.ABIL_ABVS.forEach(b=>{a[`${b}Score`]={name:`${Parser.attAbvToFull(b)} Score`,abv:b.toUpperCase(),get:a=>a[b]}}),a})(),hr4:InitiativeTracker._GET_STAT_COLUMN_HR(),...(()=>{const a={};return Object.keys(Parser.SKILL_TO_ATB_ABV).sort(SortUtil.ascSort).forEach(b=>{a[b.toCamelCase()]={name:b.toTitleCase(),abv:Parser.skillToShort(b).toUpperCase(),get:a=>a.skill&&a.skill[b]?a.skill[b]:Parser.getAbilityModifier(a[Parser.skillToAbilityAbv(b)])}}),a})(),hr5:InitiativeTracker._GET_STAT_COLUMN_HR(),cbAutoLow:{name:"Checkbox; clears at start of turn",isCb:!0,autoMode:-1,get:()=>!1},cbNeutral:{name:"Checkbox",isCb:!0,get:()=>!1},cbAutoHigh:{name:"Checkbox; ticks at start of turn",isCb:!0,autoMode:1,get:()=>!0}};