aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--webAO/client.b.js2
-rw-r--r--webAO/client.b.js.map2
-rw-r--r--webAO/client.css48
-rw-r--r--webAO/client.html45
-rw-r--r--webAO/client.js113
5 files changed, 162 insertions, 48 deletions
diff --git a/webAO/client.b.js b/webAO/client.b.js
index 5202e12..68799a7 100644
--- a/webAO/client.b.js
+++ b/webAO/client.b.js
@@ -1,2 +1,2 @@
-!function(e){var t={};function n(i){if(t[i])return t[i].exports;var c=t[i]={i:i,l:!1,exports:{}};return e[i].call(c.exports,c,c.exports,n),c.l=!0,c.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var c in e)n.d(i,c,function(t){return e[t]}.bind(null,c));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}({3:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.onOOCEnter=v,t.onEnter=_,t.musiclist_click=E,t.area_click=I,t.changeMusicVolume=b,t.changeSFXVolume=B,t.changeBlipVolume=k,t.changeCharacter=w,t.imgError=x,t.demoError=C,t.ReconnectButton=N,t.RetryButton=L,t.pickchar=D,t.pickemotion=R,t.pickevidence=A,t.addevidence=H,t.editevidence=P,t.delevidence=j,t.cancelevidence=U,t.getIndexFromSelect=Z,t.updateEvidenceIcon=F,t.updateActionCommands=V,t.changeBackgroundOOC=X,t.changeRoleOOC=G,t.randomCharacterOOC=z,t.callmod=q,t.initwt=K,t.initce=W,t.updateBackgroundPreview=J,t.toggleaffect=Q,t.toggleflip=Y,t.togglepresent=ee,t.togglemenu=te,t.toggleshout=ne;var s={};location.search.substr(1).split("&").forEach(function(e){s[e.split("=")[0]]=e.split("=")[1]});var o=s.ip,a=s.mode,l=s.asset||"http://assets.aceattorneyonline.com/base/",d=l+"sounds/music/",r=!1;/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)&&(r=!0);var u=0,m=1,h=0,g=new Date(0),y=function(){function e(t){var n=this;c(this,e),this.serv=new WebSocket("ws://"+t),this.serv.onopen=function(e){return n.onOpen(e)},this.serv.onclose=function(e){return n.onClose(e)},this.serv.onmessage=function(e){return n.onMessage(e)},this.serv.onerror=function(e){return n.onError(e)},this.flip=!1,this.presentable=!1,this.playerID=1,this.charID=-1,this.testimonyID=0,this.chars=[],this.emotes=[],this.evidences=[],this.resources={holdit:{src:"misc/holdit.gif",duration:720},objection:{src:"misc/objection.gif",duration:720},takethat:{src:"misc/takethat.gif",duration:840},witnesstestimony:{src:"misc/witnesstestimony.gif",duration:1560,sfx:"sounds/general/sfx-testimony.wav"},crossexamination:{src:"misc/crossexamination.gif",duration:1600,sfx:"sounds/general/sfx-testimony2.wav"}},this.selectedEmote=-1,this.selectedEvidence=0,this.checkUpdater=null,this.musicList=Object(),this.handlers={MS:function(e){return n.handleMS(e)},CT:function(e){return n.handleCT(e)},MC:function(e){return n.handleMC(e)},RMC:function(e){return n.handleRMC(e)},CI:function(e){return n.handleCI(e)},SC:function(e){return n.handleSC(e)},EI:function(e){return n.handleEI(e)},LE:function(e){return n.handleLE(e)},EM:function(e){return n.handleEM(e)},SM:function(e){return n.handleSM(e)},music:function(e){return n.handlemusic(e)},DONE:function(e){return n.handleDONE(e)},BN:function(e){return n.handleBN(e)},NBG:function(e){return n.handleNBG(e)},HP:function(e){return n.handleHP(e)},RT:function(e){return n.handleRT(e)},ZZ:function(e){return n.handleZZ(e)},ID:function(e){return n.handleID(e)},PN:function(e){return n.handlePN(e)},SI:function(e){return n.handleSI(e)},CharsCheck:function(e){return n.handleCharsCheck(e)},PV:function(e){return n.handlePV(e)},CHECK:function(e){}},this._lastTimeICReceived=new Date(0)}return i(e,[{key:"me",value:function(){return this.chars[this.charID]}},{key:"myEmote",value:function(){return this.emotes[this.selectedEmote]}},{key:"myEvidence",value:function(){return this.presentable?this.selectedEvidence:0}},{key:"sendOOC",value:function(e){this.serv.send("CT#web"+this.playerID+"#"+ce(oe(e))+"#%")}},{key:"sendIC",value:function(e,t,n,i,c,s,o,a,l,d,r,u,m){this.serv.send("MS#chat#"+e+"#"+t+"#"+n+"#"+ce(oe(i))+"#"+c+"#"+s+"#"+o+"#"+this.charID+"#"+a+"#"+h+"#"+d+"#"+r+"#"+u+"#"+m+"#%")}},{key:"sendPE",value:function(e,t,n){this.serv.send("PE#"+ce(oe(e))+"#"+ce(oe(t))+"#"+n+"#%")}},{key:"sendEE",value:function(e,t,n,i){this.serv.send("EE#"+e+"#"+ce(oe(t))+"#"+ce(oe(n))+"#"+i+"#%")}},{key:"sendDE",value:function(e){this.serv.send("DE#"+e+"#%")}},{key:"sendZZ",value:function(e){this.serv.send("ZZ#"+e+"#%")}},{key:"sendRT",value:function(e){"jud"==this.chars[this.charID].side&&this.serv.send("RT#"+e+"#%")}},{key:"sendMusicChange",value:function(e){this.serv.send("MC#"+e+"#"+this.charID+"#%")}},{key:"sendLeaveRoom",value:function(){this.serv.send("FC#%")}},{key:"joinServer",value:function(){var e=this;this.serv.send("HI#"+navigator.userAgent.hashCode()+"#%"),this.serv.send("ID#webAO#2.4.5#%"),this.checkUpdater=setInterval(function(){return e.sendCheck()},5e3)}},{key:"loadResources",value:function(){var e=document.getElementById("evi_select");e.add(new Option("Custom",0));for(var t=1;t<=evidence_arr.length;t++)e.add(new Option(evidence_arr[t-1]));var n=document.getElementById("bg_select");n.add(new Option("Custom",0));for(var i=1;i<=background_arr.length;i++)n.add(new Option(background_arr[i-1]));for(var c=["holdit","objection","takethat"],s=0;s<c.length;s++){T(l+this.resources[c[s]].src,this.callbackLoadImageResources,c[s])}for(var o=["witnesstestimony","crossexamination"],a=0;a<o.length;a++){T(l+"themes/default/"+o[a]+".gif",this.callbackLoadImageResources,o[a]),T(l+this.resources[o[a]].sfx,this.callbackLoadSFXResources,o[a])}}},{key:"callbackLoadImageResources",value:function(e,t,n){e&&(le.resources[t].src=n,de.getAnimLength(n,le.callbackGetResourceLength,t))}},{key:"callbackGetResourceLength",value:function(e,t){le.resources[t].duration=e}},{key:"callbackLoadSFXResources",value:function(e,t,n){e&&(le.resources[t].sfx=n)}},{key:"initialObservBBCode",value:function(){var e=document.getElementById("client_inner_chat");new MutationObserver(function(e){e.forEach(function(e){var t=e.addedNodes;null!==t&&t.forEach(function(e){"C"==e.tagName?e.style.color=e.getAttribute("a"):"M"==e.tagName&&(e.hasAttribute("a")?e.style.backgroundColor=e.getAttribute("a"):(e.style.backgroundColor="yellow",e.style.color="black"))})})}).observe(e,{attributes:!0,childList:!0})}},{key:"sendCharacter",value:function(e){this.serv.send("CC#"+this.playerID+"#"+e+"#web#%")}},{key:"sendMusic",value:function(e){this.serv.send("MC#"+e)}},{key:"sendCheck",value:function(){this.serv.send("CH#"+this.charID+"#%")}},{key:"onOpen",value:function(e){"watch"===a?(document.getElementById("client_loading").style.display="none",document.getElementById("client_charselect").style.display="none"):le.joinServer()}},{key:"onClose",value:function(e){console.error("The connection was closed: "+e.reason+" ("+e.code+")"),1001!==e.code&&(document.getElementById("client_error").style.display="block",document.getElementById("error_id").textContent=e.code,this.cleanup())}},{key:"onMessage",value:function(e){var t=e.data;console.debug(t);var n=t.split("%")[0].split("#"),i=n[0],c=this.handlers[i];void 0!==c?c(n):console.warn("Invalid packet header "+i)}},{key:"onError",value:function(e){console.error("A network error occurred: "+e.reason+" ("+e.code+")"),document.getElementById("client_error").style.display="block",document.getElementById("error_id").textContent=e.code,this.cleanup()}},{key:"cleanup",value:function(){try{this.serv.close(1001)}catch(e){}clearInterval(this.checkUpdater)}},{key:"handleMS",value:function(e){if(e[4]!=de.chatmsg.content){document.getElementById("client_inner_chat").innerHTML="";for(var t={character:-1,preanim:escape(e[2]),nameplate:e[3],name:e[3],speaking:"(b)"+escape(e[4]),silent:"(a)"+escape(e[4]),content:function(e){return e.replace(/\\n/g,"<br>").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)del\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1ins>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'<m a="$1">').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'<c a="$1">').replace(/\[\/c\]/g,"</c>")}(ie(ae(se(e[5])))),side:e[6],sound:escape(e[7]),type:e[8],snddelay:e[10],objection:e[11],evidence:e[12],flip:e[13],flash:e[14],color:e[15],isnew:!0},n=0;n<this.chars.length;n++)if(this.chars[n].name==e[3]){t.character=n;break}t.character==this.charID&&function(){document.getElementById("client_inputbox").value="",u&&(document.getElementById("button_effect_"+u).className="client_button",u=0);h&&(document.getElementById("button_"+h).className="client_button",h=0)}(),de.say(t)}}},{key:"handleCT",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+=ae(se(e[1]))+": "+ae(se(e[2]))+"\r\n",t.scrollTop>t.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=de.music;(t.pause(),t.src=d+e[1],t.play(),e[2]>=0)?S(this.chars[e[2]].name+" changed music to "+e[1]):S("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){de.music.pause(),de.music=new Audio(this.musicList[e[1]]);var t=de.music;t.totime=e[1],t.offset=(new Date).getTime()/1e3,t.addEventListener("loadedmetadata",function(){t.currentTime+=parseFloat(t.totime+((new Date).getTime()/1e3-t.offset)).toFixed(3),t.play()},!1)}},{key:"handleCI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Character "+e[1],this.serv.send("AN#"+(e[1]/10+1)+"#%");for(var t=2;t<e.length-1;t++)if(t%2==0){var n=e[t].split("&");this.chars[e[t-1]]={name:n[0],desc:n[1],evidence:n[3],icon:l+"characters/"+escape(n[0])+"/char_icon.png"}}}},{key:"handleSC",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Characters";for(var t=1;t<e.length-1;t++){var n=e[t].split("&");this.chars[t-1]={name:n[0],desc:n[1],evidence:n[3],icon:l+"characters/"+escape(n[0])+"/char_icon.png"}}this.serv.send("RM#%")}},{key:"handleEI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Evidence "+e[1],this.serv.send("RM#%")}},{key:"handleLE",value:function(e){this.evidences=[];for(var t=1;t<e.length-1;t++){var n=e[t].split("&");this.evidences[t-1]={name:ie(ae(se(n[0]))),desc:ie(ae(se(n[1]))),filename:escape(n[2]),icon:l+"evidence/"+escape(n[2])}}var i=document.getElementById("evidences");i.innerHTML="";for(var c=1;c<=this.evidences.length;c++)i.innerHTML+='<img src="'+this.evidences[c-1].icon+'" id="evi_'+c+'" alt="'+this.evidences[c-1].name+'" class="client_button" onclick="pickevidence('+c+')">'}},{key:"handleEM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music "+e[1],this.serv.send("AM#"+(e[1]/10+1)+"#%");for(var t=document.getElementById("client_musiclist"),n=2;n<e.length-1;n++)if(n%2==0){var i=document.createElement("OPTION");i.text=e[n],t.options.add(i)}}},{key:"handleSM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music ";for(var t=document.getElementById("client_musiclist"),n=!1,i=1;i<e.length-1;i++)if(/\.(?:wav|mp3|mp4|ogg|mid)$/i.test(e[i])&&!n&&(n=!0),n){var c=document.createElement("OPTION");c.text=e[i],t.options.add(c)}else{var s=document.createElement("SPAN");s.className="location-box",s.textContent=e[i],s.onclick=function(){I(this)},document.getElementById("areas").appendChild(s)}var o=document.getElementById("areas"),a=document.createElement("OPTION");a.text=o.lastChild.textContent,t.insertBefore(a,t.firstChild),o.removeChild(o.lastChild),this.serv.send("RD#%")}},{key:"handlemusic",value:function(e){for(var t=0;t<e.length/2;t++)this.musicList[e[2*t]]=e[2*t+1]}},{key:"handleDONE",value:function(e){document.getElementById("client_loading").style.display="none",document.getElementById("client_charselect").style.display="block"}},{key:"handleBN",value:function(e){de.bgname=escape(e[1]);var t=Z("bg_select",escape(e[1]));document.getElementById("bg_select").selectedIndex=t,J(),0==t&&(document.getElementById("bg_filename").value=e[1]),document.getElementById("bg_preview").src=l+"background/"+escape(e[1])+"/defenseempty.png",-1==this.charID?M("jud"):M(this.chars[this.charID].side)}},{key:"handleNBG",value:function(e){}},{key:"handleHP",value:function(e){1==e[1]?document.getElementById("client_defense_hp").style.clip="rect(0px,"+90*e[2]/10+"px,20px,0px)":document.getElementById("client_prosecutor_hp").style.clip="rect(0px,"+90*e[2]/10+"px,20px,0px)"}},{key:"handleRT",value:function(e){"testimony1"==e[1]?this.testimonyID=1:this.testimonyID=2,de.initTestimonyUpdater()}},{key:"handleZZ",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+="$Alert: "+ae(se(e[1]))+"\r\n",t.scrollTop>t.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleHP",value:function(e){1==e[1]?document.getElementById("client_defense_hp").style.clip="rect(0px,"+90*e[2]/10+"px,20px,0px)":document.getElementById("client_prosecutor_hp").style.clip="rect(0px,"+90*e[2]/10+"px,20px,0px)"}},{key:"handleID",value:function(e){this.playerID=e[1]}},{key:"handlePN",value:function(e){this.serv.send("askchaa#%")}},{key:"handleSI",value:function(e){r?this.serv.send("askchar2#%"):this.serv.send("RC#%")}},{key:"handleCharsCheck",value:function(e){document.getElementById("client_chartable").innerHTML="";for(var t=0;t<this.chars.length;t++){if(t%8==0)var n=document.createElement("TR");var i=document.createElement("TD"),c=void 0,s=this.chars[t].icon;c="-1"==e[t+1]?" dark":"",i.innerHTML="<img class='demothing"+c+"' id='demo_"+t+"' src='"+s+"' alt='"+this.chars[t].name+"' onclick='pickchar("+t+")' onerror='demoError(this);'>",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}}},{key:"handlePV",value:function(e){this.charID=e[3],document.getElementById("client_charselect").style.display="none";var t=this.me(),n=this.emotes,i=new XMLHttpRequest;document.getElementById("client_emo").innerHTML="",i.open("GET",l+"characters/"+escape(this.me().name)+"/char.ini",!0),i.responseType="text",i.onload=function(e){if(200==this.status){var i=this.responseText,c=f.parse(i);t.side=c.Options.side,V(t.side);for(var s=1;s<c.Emotions.number;s++){var o=c.Emotions[s].split("#"),a="0",d="0";void 0!==c.SoundN&&(a=c.SoundN[s]),void 0!==c.SoundT&&(d=c.SoundT[s]),n[s]={desc:o[0],speaking:o[1],silent:o[2],zoom:o[3],sfx:a,sfxdelay:d,button_off:l+"characters/"+escape(t.name)+"/emotions/button"+s+"_off.png",button_on:l+"characters/"+escape(t.name)+"/emotions/button"+s+"_on.png"},document.getElementById("client_emo").innerHTML+="<img src='"+n[s].button_off+"' id='emo_"+s+"' alt='"+n[s].desc+"' class='client_button' onclick='pickemotion("+s+")'>"}R(1)}},i.send()}}]),e}(),p=function(){function e(){c(this,e),this.textnow="",this.chatmsg={isnew:!1,content:"",objection:"0",sound:"",startpreanim:!1,startspeaking:!1,side:null,color:"0",snddelay:0,preanimdelay:0},this.blip=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var t=0;t<this.blipChannels.length;t++)this.blipChannels[t]=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blipChannels[t].volume=.5;this.currentBlipChannel=0,this.sfxaudio=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.sfxplayed=0,this.music=new Audio,this.music.play(),this.updater=null,this.testimonyUpdater=null,this.bgname="gs4",this.testimonyTimer=0,this.shoutTimer=0,this.textTimer=0,this._animating=!1}return i(e,[{key:"isAnimating",value:function(){return this._animating}},{key:"setBlipVolume",value:function(e){for(var t=0;t<this.blipChannels.length;t++)this.blipChannels[t].volume=e}},{key:"bgFolder",value:function(){return l+"background/"+this.bgname+"/"}},{key:"say",value:function(e){this.chatmsg=e,S(e.content,e.nameplate),M(e.side),this.textnow="",this.sfxplayed=0,this.textTimer=0,this._animating=!0,clearTimeout(this.updater),"-"!=e.preanim?e.preanimdelay=this.getAnimLength(l+"characters/"+escape(e.name)+"/"+e.preanim+".gif",this.initUpdater):this.initUpdater(0)}},{key:"initUpdater",value:function(e){de.chatmsg.preanimdelay=parseInt(e),de.updater=setTimeout(function(){return de.updateText()},60)}},{key:"initTestimonyUpdater",value:function(){var e=this;if(le.testimonyID>0){var t="";1==le.testimonyID?t="witnesstestimony":2==le.testimonyID&&(t="crossexamination"),new Audio(le.resources[t].sfx).play(),this.testimonyTimer=0,document.getElementById("client_testimony").src=le.resources[t].src,this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60)}}},{key:"getAnimLength",value:function(e,t,n){var i=new XMLHttpRequest;i.open("GET",e,!0),i.responseType="arraybuffer",i.addEventListener("load",function(){var e=gify.getInfo(i.response);console.log(e.duration),t(e.duration,n)}),i.send()}},{key:"updateTestimony",value:function(){var e=this;this.testimonyTimer=this.testimonyTimer+60,1==le.testimonyID?this.testimonyTimer>=le.resources.witnesstestimony.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):2==le.testimonyID?this.testimonyTimer>=le.resources.crossexamination.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):this.disposeTestimony()}},{key:"disposeTestimony",value:function(){le.testimonyID=0,this.testimonyTimer=0,document.getElementById("client_testimony").src="misc/placeholder.gif",clearTimeout(this.testimonyUpdater)}},{key:"updateText",value:function(){var e=this;if(1==this.chatmsg.flip?document.getElementById("client_char").style.transform="scaleX(-1)":document.getElementById("client_char").style.transform="scaleX(1)",this._animating&&(this.updater=setTimeout(function(){return e.updateText()},60)),this.chatmsg.isnew){document.getElementById("client_background").style.backgroundColor="transparent",document.getElementById("client_name").style.display="none",document.getElementById("client_chat").style.display="none",document.getElementById("client_evi").style.opacity="0",document.getElementById("client_evi").style.height="0%";var t={1:"holdit",2:"objection",3:"takethat"}[this.chatmsg.objection];void 0!==t?(document.getElementById("client_shout").src=le.resources[t].src,new Audio(l+"/characters/"+this.chatmsg.name+"/"+t+".wav").play(),this.shoutTimer=850):this.shoutTimer=0,this.chatmsg.isnew=!1,this.chatmsg.startpreanim=!0}if(this.textTimer>=this.shoutTimer&&this.chatmsg.startpreanim)2==this.chatmsg.flash?(this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-stab.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("shake",{direction:"up"})):1==this.chatmsg.flash&&(document.getElementById("client_background").style.backgroundColor="white",this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(document.getElementById("client_shout").src="misc/placeholder.gif",M(this.chatmsg.side),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.preanim+".gif"),this.chatmsg.startpreanim=!1,this.chatmsg.startspeaking=!0;else if(this.textTimer>=this.shoutTimer+this.chatmsg.preanimdelay&&!this.chatmsg.startpreanim)if(this.chatmsg.startspeaking){this.chatmsg.evidence>0&&(document.getElementById("client_evi").style.backgroundImage="url('"+le.evidences[this.chatmsg.evidence-1].icon+"')","def"==this.chatmsg.side?(document.getElementById("client_evi").style.right="1.5em",document.getElementById("client_evi").style.left="initial",$("#client_evi").animate({height:"30%",opacity:1},250)):(document.getElementById("client_evi").style.right="initial",document.getElementById("client_evi").style.left="1.5em",$("#client_evi").animate({height:"30%",opacity:1},250))),$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="misc/placeholder.gif",M(this.chatmsg.side)),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.speaking+".gif",document.getElementById("client_name").style.fontSize=.7*document.getElementById("client_name").offsetHeight+"px",document.getElementById("client_chat").style.fontSize=.25*document.getElementById("client_chat").offsetHeight+"px",document.getElementById("client_name").innerHTML="<p>"+ie(this.chatmsg.nameplate)+"</p>";var n="color: "+({0:"#ffffff",1:"#00ff00",2:"#ff0000",3:"#ffaa00",4:"#0000ff",5:"#ffff00",6:"#aa00aa"}[this.chatmsg.color]||"#ffffff");document.getElementById("client_inner_chat").style=n,this.chatmsg.startspeaking=!1,this.textnow==this.chatmsg.content&&(document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",this._animating=!1,clearTimeout(this.updater))}else this.textnow!=this.chatmsg.content&&(" "!=this.chatmsg.content.charAt(this.textnow.length)&&(this.blipChannels[this.currentBlipChannel].play(),this.currentBlipChannel++,this.currentBlipChannel%=this.blipChannels.length),this.textnow=this.chatmsg.content.substring(0,this.textnow.length+1),document.getElementById("client_inner_chat").innerHTML=this.textnow,this.textnow==this.chatmsg.content&&(this.textTimer=0,this._animating=!1,document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",clearTimeout(this.updater)));!this.sfxplayed&&this.chatmsg.snddelay+this.shoutTimer>=this.textTimer&&(this.sfxaudio.pause(),this.sfxplayed=1,"0"!=this.chatmsg.sound&&"1"!=this.chatmsg.sound&&(this.sfxaudio.src=l+"sounds/general/"+escape(this.chatmsg.sound)+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+60}}]),e}(),f=function(){function e(){c(this,e)}return i(e,null,[{key:"parse",value:function(e){var t={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},n={},i=null;return e.split(/\r\n|\r|\n/).forEach(function(e){if(!t.comment.test(e)&&0!=e.length)if(t.param.test(e)){var c=e.match(t.param);i?n[i][c[1]]=c[2]:n[c[1]]=c[2]}else if(t.section.test(e)){var s=e.match(t.section);n[s[1]]={},i=s[1]}}),n}}]),e}();function v(e){13==e.keyCode&&(le.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function _(e){if(13==e.keyCode){var t=le.me(),n=le.myEmote(),i=le.myEvidence(),c=le.flip?1:0,s=document.getElementById("textcolor").value,o="0",a="0";document.getElementById("sendsfx").checked&&(o=n.sfx,a=n.sfxdelay),le.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,o,n.zoom,a,h,i,c,u,s)}}function E(e){var t=document.getElementById("client_musiclist").value;le.sendMusicChange(t)}function I(e){var t=e.textContent;le.sendMusicChange(t)}function b(){de.music.volume=document.getElementById("client_mvolume").value/100}function B(){de.sfxaudio.volume=document.getElementById("client_svolume").value/100}function k(){de.setBlipVolume(document.getElementById("client_bvolume").value/100)}function w(e){le.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function x(e){return e.onerror="",e.src="misc/placeholder.gif",!0}function C(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function T(e,t,n){var i=new XMLHttpRequest;i.onreadystatechange=function(){4==this.readyState&&200==this.status?t(!0,n,e):t(!1,n,e)},i.open("GET",e,!0),i.send()}function M(e){var t,n=de.bgFolder();switch(document.getElementById("client_fg").style.display="none",document.getElementById("client_bench").style.display="none",e){case"def":document.getElementById("client_court").src=n+"defenseempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",O,e),t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",O,e),t="prosecution";break;case"hld":document.getElementById("client_court").src=n+"helperstand.png",t="defense";break;case"hlp":document.getElementById("client_court").src=n+"prohelperstand.png",t="prosecution";break;case"wit":document.getElementById("client_court").src=n+"witnessempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"estrado.png",t="prosecution";break;case"jud":document.getElementById("client_court").src=n+"judgestand.png",t="prosecution"}5==de.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function O(e,t){var n=de.bgFolder();document.getElementById("client_bench").src="def"==t?e?n+"defensedesk.png":n+"bancodefensa.png":e?n+"prosecutiondesk.png":n+"bancoacusacion.png"}function N(){le.cleanup(),(le=new y(o))&&(a="join",document.getElementById("client_error").style.display="none")}function L(){le.joinServer()}function S(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Date,i=document.createElement("p"),c=document.createElement("span");if(c.id="iclog_name",c.appendChild(document.createTextNode(t)),i.appendChild(c),i.appendChild(document.createTextNode(e)),g.getMinutes()!==n.getMinutes()){var s=document.createElement("span");s.id="iclog_time",s.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(s)}var o=document.getElementById("client_log");o.appendChild(i),o.scrollTop>o.scrollHeight-600&&(o.scrollTop=o.scrollHeight),g=new Date}function D(e){e<1e3?le.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function R(e){-1!=le.selectedEmote&&(document.getElementById("emo_"+le.selectedEmote).src=le.myEmote().button_off),le.selectedEmote=e,document.getElementById("emo_"+e).src=le.myEmote().button_on}function A(e){if(le.selectedEvidence!=e){le.selectedEvidence>0&&(document.getElementById("evi_"+le.selectedEvidence).className="client_button"),document.getElementById("evi_"+e).className="client_button dark",le.selectedEvidence=e,document.getElementById("evi_name").value=le.evidences[e-1].name,document.getElementById("evi_desc").value=le.evidences[e-1].desc;var t=Z("evi_select",le.evidences[e-1].filename);document.getElementById("evi_select").selectedIndex=t,0==t&&(document.getElementById("evi_filename").value=le.evidences[e-1].filename),F(),document.getElementById("evi_add").className="client_button hover_button inactive",document.getElementById("evi_edit").className="client_button hover_button",document.getElementById("evi_cancel").className="client_button hover_button",document.getElementById("evi_del").className="client_button hover_button"}else U()}function H(){var e=document.getElementById("evi_select");le.sendPE(document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function P(){var e=document.getElementById("evi_select"),t=parseInt(le.selectedEvidence)-1;le.sendEE(t,document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function j(){var e=parseInt(le.selectedEvidence)-1;le.sendDE(e),U()}function U(){le.selectedEvidence>0&&(document.getElementById("evi_"+le.selectedEvidence).className="client_button"),le.selectedEvidence=0,document.getElementById("evi_select").selectedIndex=0,F(),document.getElementById("evi_filename").value="",document.getElementById("evi_name").value="",document.getElementById("evi_desc").value="",document.getElementById("evi_icon").style.backgroundImage="url('misc/empty.png')",document.getElementById("evi_add").className="client_button hover_button",document.getElementById("evi_edit").className="client_button hover_button inactive",document.getElementById("evi_cancel").className="client_button hover_button inactive",document.getElementById("evi_del").className="client_button hover_button inactive"}function Z(e,t){for(var n=document.getElementById(e),i=1;i<n.length;++i)if(n.options[i].value==t)return i;return 0}function F(){var e=document.getElementById("evi_select"),t=document.getElementById("evi_filename"),n=document.getElementById("evi_icon");0==e.selectedIndex?(t.style.display="initial",n.style.backgroundImage="url('"+l+"evidence/"+t.value+"')"):(t.style.display="none",n.style.backgroundImage="url('"+l+"evidence/"+e.value+"')")}function V(e){"jud"==e?(document.getElementById("menu_wt").style.display="inline-table",document.getElementById("menu_ce").style.display="inline-table"):(document.getElementById("menu_wt").style.display="none",document.getElementById("menu_ce").style.display="none");for(var t=0,n=document.getElementById("role_select").options;t<n.length;t++)if(e==n[t].value)return void(n.selectedIndex=t)}function X(){var e="",t=document.getElementById("bg_select"),n=document.getElementById("bg_command").value;e=0==t.selectedIndex?document.getElementById("bg_filename").value:t.value,le.sendOOC("/"+n.replace("$1",e))}function G(){var e=document.getElementById("role_select"),t=document.getElementById("role_command").value;le.sendOOC("/"+t.replace("$1",e.value)),V(e.value)}function z(){le.sendOOC("/"+document.getElementById("randomchar_command").value)}function q(){le.sendZZ("")}function K(){le.sendRT("testimony1")}function W(){le.sendRT("testimony2")}function J(){var e=document.getElementById("bg_select"),t=document.getElementById("bg_filename"),n=document.getElementById("bg_preview");0==e.selectedIndex?(t.style.display="initial",n.src=l+"background/"+t.value+"/defenseempty.png"):(t.style.display="none",n.src=l+"background/"+e.value+"/defenseempty.png")}function Q(e){e==u?(document.getElementById("button_effect_"+e).className="client_button",u=0):(document.getElementById("button_effect_"+e).className="client_button dark",u&&(document.getElementById("button_effect_"+u).className="client_button"),u=e)}function Y(){le.flip?document.getElementById("button_flip").className="client_button":document.getElementById("button_flip").className="client_button dark",le.flip=!le.flip}function ee(){le.presentable?document.getElementById("button_present").className="client_button":document.getElementById("button_present").className="client_button dark",le.presentable=!le.presentable}function te(e){e!=m&&(document.getElementById("menu_"+e).className="menu_icon active",document.getElementById("content_"+e).className="menu_content active",document.getElementById("menu_"+m).className="menu_icon",document.getElementById("content_"+m).className="menu_content",m=e)}function ne(e){e==h?(document.getElementById("button_"+e).className="client_button",h=0):(document.getElementById("button_"+e).className="client_button dark",h&&(document.getElementById("button_"+h).className="client_button"),h=e)}function ie(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function ce(e){return e.replace(/#/g,"<pound>").replace(/&/g,"<and>").replace(/%/g,"<percent>").replace(/\$/g,"<dollar>")}function se(e){return e.replace(/<pound>/g,"#").replace(/<and>/g,"&").replace(/<percent>/g,"%").replace(/<dollar>/g,"$")}function oe(e){var t=document.getElementById("client_encoding").value;if("unicode"==t)return e.replace(/[^\0-~]/g,function(e){return"\\u"+("000"+e.charCodeAt().toString(16)).slice(-4)});if("utf16"==t){for(var n=new ArrayBuffer(2*e.length),i=new Uint16Array(n),c=0,s=e.length;c<s;c++)i[c]=e.charCodeAt(c);return String(i)}return e}function ae(e){var t=document.getElementById("client_decoding").value;return"unicode"==t?e.replace(/\\u([\d\w]{1,})/gi,function(e,t){return String.fromCharCode(parseInt(t,16))}):"utf16"==t?String.fromCharCode.apply(null,new Uint16Array(e.split(","))):e}window.onOOCEnter=v,window.onEnter=_,window.musiclist_click=E,window.area_click=I,window.changeMusicVolume=b,window.changeSFXVolume=B,window.changeBlipVolume=k,window.changeCharacter=w,window.imgError=x,window.demoError=C,window.ReconnectButton=N,window.RetryButton=L,window.pickchar=D,window.pickemotion=R,window.pickevidence=A,window.addevidence=H,window.editevidence=P,window.delevidence=j,window.cancelevidence=U,window.getIndexFromSelect=Z,window.updateEvidenceIcon=F,window.updateActionCommands=V,window.changeBackgroundOOC=X,window.changeRoleOOC=G,window.randomCharacterOOC=z,window.callmod=q,window.initwt=K,window.initce=W,window.updateBackgroundPreview=J,window.toggleaffect=Q,window.toggleflip=Y,window.togglepresent=ee,window.togglemenu=te,window.toggleshout=ne,void 0===String.prototype.trim&&(String.prototype.trim=function(){return String(this).replace(/^\s+|\s+$/g,"")}),String.prototype.hashCode=function(){var e,t=0;if(0===this.length)return t;for(e=0;e<this.length;e++)t=(t<<5)-t+this.charCodeAt(e),t|=0;return t};var le=new y(o),de=new p;$(document).ready(function(){le.initialObservBBCode(),le.loadResources()})}});
+!function(e){var t={};function n(i){if(t[i])return t[i].exports;var c=t[i]={i:i,l:!1,exports:{}};return e[i].call(c.exports,c,c.exports,n),c.l=!0,c.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var c in e)n.d(i,c,function(t){return e[t]}.bind(null,c));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}({3:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}();function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.onOOCEnter=v,t.onEnter=_,t.musiclist_click=E,t.area_click=I,t.changeMusicVolume=b,t.changeSFXVolume=B,t.changeBlipVolume=w,t.changeCharacter=k,t.imgError=C,t.demoError=x,t.ReconnectButton=N,t.RetryButton=S,t.pickchar=P,t.pickemotion=L,t.pickevidence=D,t.addevidence=R,t.editevidence=A,t.delevidence=j,t.cancelevidence=U,t.getIndexFromSelect=Z,t.updateEvidenceIcon=F,t.updateActionCommands=V,t.changeBackgroundOOC=X,t.changeRoleOOC=z,t.randomCharacterOOC=G,t.callmod=q,t.initwt=K,t.initce=W,t.addHPD=J,t.redHPD=Q,t.addHPP=Y,t.redHPP=ee,t.updateBackgroundPreview=te,t.toggleaffect=ne,t.toggleflip=ie,t.togglepresent=ce,t.togglemenu=oe,t.toggleshout=se;var o={};location.search.substr(1).split("&").forEach(function(e){o[e.split("=")[0]]=e.split("=")[1]});var s=o.ip,a=o.mode,l=o.asset||"http://assets.aceattorneyonline.com/base/",d=l+"sounds/music/",r=!1;/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)&&(r=!0);var u=0,m=1,h=0,g=new Date(0),y=function(){function e(t){var n=this;c(this,e),this.serv=new WebSocket("ws://"+t),this.serv.onopen=function(e){return n.onOpen(e)},this.serv.onclose=function(e){return n.onClose(e)},this.serv.onmessage=function(e){return n.onMessage(e)},this.serv.onerror=function(e){return n.onError(e)},this.flip=!1,this.presentable=!1,this.hp=[0,0],this.playerID=1,this.charID=-1,this.testimonyID=0,this.chars=[],this.emotes=[],this.evidences=[],this.resources={holdit:{src:"misc/holdit.gif",duration:720},objection:{src:"misc/objection.gif",duration:720},takethat:{src:"misc/takethat.gif",duration:840},witnesstestimony:{src:"misc/witnesstestimony.gif",duration:1560,sfx:"sounds/general/sfx-testimony.wav"},crossexamination:{src:"misc/crossexamination.gif",duration:1600,sfx:"sounds/general/sfx-testimony2.wav"}},this.selectedEmote=-1,this.selectedEvidence=0,this.checkUpdater=null,this.musicList=Object(),this.handlers={MS:function(e){return n.handleMS(e)},CT:function(e){return n.handleCT(e)},MC:function(e){return n.handleMC(e)},RMC:function(e){return n.handleRMC(e)},CI:function(e){return n.handleCI(e)},SC:function(e){return n.handleSC(e)},EI:function(e){return n.handleEI(e)},LE:function(e){return n.handleLE(e)},EM:function(e){return n.handleEM(e)},SM:function(e){return n.handleSM(e)},music:function(e){return n.handlemusic(e)},DONE:function(e){return n.handleDONE(e)},BN:function(e){return n.handleBN(e)},NBG:function(e){return n.handleNBG(e)},HP:function(e){return n.handleHP(e)},RT:function(e){return n.handleRT(e)},ZZ:function(e){return n.handleZZ(e)},ID:function(e){return n.handleID(e)},PN:function(e){return n.handlePN(e)},SI:function(e){return n.handleSI(e)},CharsCheck:function(e){return n.handleCharsCheck(e)},PV:function(e){return n.handlePV(e)},CHECK:function(e){}},this._lastTimeICReceived=new Date(0)}return i(e,[{key:"me",value:function(){return this.chars[this.charID]}},{key:"myEmote",value:function(){return this.emotes[this.selectedEmote]}},{key:"myEvidence",value:function(){return this.presentable?this.selectedEvidence:0}},{key:"sendOOC",value:function(e){this.serv.send("CT#web"+this.playerID+"#"+le(re(e))+"#%")}},{key:"sendIC",value:function(e,t,n,i,c,o,s,a,l,d,r,u,m){this.serv.send("MS#chat#"+e+"#"+t+"#"+n+"#"+le(re(i))+"#"+c+"#"+o+"#"+s+"#"+this.charID+"#"+a+"#"+h+"#"+d+"#"+r+"#"+u+"#"+m+"#%")}},{key:"sendPE",value:function(e,t,n){this.serv.send("PE#"+le(re(e))+"#"+le(re(t))+"#"+n+"#%")}},{key:"sendEE",value:function(e,t,n,i){this.serv.send("EE#"+e+"#"+le(re(t))+"#"+le(re(n))+"#"+i+"#%")}},{key:"sendDE",value:function(e){this.serv.send("DE#"+e+"#%")}},{key:"sendHP",value:function(e,t){this.serv.send("HP#"+e+"#"+t+"#%")}},{key:"sendZZ",value:function(e){this.serv.send("ZZ#"+e+"#%")}},{key:"sendRT",value:function(e){"jud"==this.chars[this.charID].side&&this.serv.send("RT#"+e+"#%")}},{key:"sendMusicChange",value:function(e){this.serv.send("MC#"+e+"#"+this.charID+"#%")}},{key:"sendLeaveRoom",value:function(){this.serv.send("FC#%")}},{key:"joinServer",value:function(){var e=this;this.serv.send("HI#"+navigator.userAgent.hashCode()+"#%"),this.serv.send("ID#webAO#2.4.5#%"),this.checkUpdater=setInterval(function(){return e.sendCheck()},5e3)}},{key:"loadResources",value:function(){var e=document.getElementById("evi_select");e.add(new Option("Custom",0));for(var t=1;t<=evidence_arr.length;t++)e.add(new Option(evidence_arr[t-1]));var n=document.getElementById("bg_select");n.add(new Option("Custom",0));for(var i=1;i<=background_arr.length;i++)n.add(new Option(background_arr[i-1]));for(var c=["holdit","objection","takethat"],o=0;o<c.length;o++){T(l+this.resources[c[o]].src,this.callbackLoadImageResources,c[o])}for(var s=["witnesstestimony","crossexamination"],a=0;a<s.length;a++){T(l+"themes/default/"+s[a]+".gif",this.callbackLoadImageResources,s[a]),T(l+this.resources[s[a]].sfx,this.callbackLoadSFXResources,s[a])}}},{key:"callbackLoadImageResources",value:function(e,t,n){e&&(me.resources[t].src=n,he.getAnimLength(n,me.callbackGetResourceLength,t))}},{key:"callbackGetResourceLength",value:function(e,t){me.resources[t].duration=e}},{key:"callbackLoadSFXResources",value:function(e,t,n){e&&(me.resources[t].sfx=n)}},{key:"initialObservBBCode",value:function(){var e=document.getElementById("client_inner_chat");new MutationObserver(function(e){e.forEach(function(e){var t=e.addedNodes;null!==t&&t.forEach(function(e){"C"==e.tagName?e.style.color=e.getAttribute("a"):"M"==e.tagName&&(e.hasAttribute("a")?e.style.backgroundColor=e.getAttribute("a"):(e.style.backgroundColor="yellow",e.style.color="black"))})})}).observe(e,{attributes:!0,childList:!0})}},{key:"sendCharacter",value:function(e){this.serv.send("CC#"+this.playerID+"#"+e+"#web#%")}},{key:"sendMusic",value:function(e){this.serv.send("MC#"+e)}},{key:"sendCheck",value:function(){this.serv.send("CH#"+this.charID+"#%")}},{key:"onOpen",value:function(e){"watch"===a?(document.getElementById("client_loading").style.display="none",document.getElementById("client_charselect").style.display="none"):me.joinServer()}},{key:"onClose",value:function(e){console.error("The connection was closed: "+e.reason+" ("+e.code+")"),1001!==e.code&&(document.getElementById("client_error").style.display="block",document.getElementById("error_id").textContent=e.code,this.cleanup())}},{key:"onMessage",value:function(e){var t=e.data;console.debug(t);var n=t.split("%")[0].split("#"),i=n[0],c=this.handlers[i];void 0!==c?c(n):console.warn("Invalid packet header "+i)}},{key:"onError",value:function(e){console.error("A network error occurred: "+e.reason+" ("+e.code+")"),document.getElementById("client_error").style.display="block",document.getElementById("error_id").textContent=e.code,this.cleanup()}},{key:"cleanup",value:function(){try{this.serv.close(1001)}catch(e){}clearInterval(this.checkUpdater)}},{key:"handleMS",value:function(e){if(e[4]!=he.chatmsg.content){document.getElementById("client_inner_chat").innerHTML="";for(var t={character:-1,preanim:escape(e[2]),nameplate:e[3],name:e[3],speaking:"(b)"+escape(e[4]),silent:"(a)"+escape(e[4]),content:function(e){return e.replace(/\\n/g,"<br>").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)del\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1ins>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'<m a="$1">').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'<c a="$1">').replace(/\[\/c\]/g,"</c>")}(ae(ue(de(e[5])))),side:e[6],sound:escape(e[7]),type:e[8],snddelay:e[10],objection:e[11],evidence:e[12],flip:e[13],flash:e[14],color:e[15],isnew:!0},n=0;n<this.chars.length;n++)if(this.chars[n].name==e[3]){t.character=n;break}t.character==this.charID&&function(){document.getElementById("client_inputbox").value="",u&&(document.getElementById("button_effect_"+u).className="client_button",u=0);h&&(document.getElementById("button_"+h).className="client_button",h=0)}(),he.say(t)}}},{key:"handleCT",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+=ue(de(e[1]))+": "+ue(de(e[2]))+"\r\n",t.scrollTop>t.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=he.music;(t.pause(),t.src=d+e[1],t.play(),e[2]>=0)?H(this.chars[e[2]].name+" changed music to "+e[1]):H("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){he.music.pause(),he.music=new Audio(this.musicList[e[1]]);var t=he.music;t.totime=e[1],t.offset=(new Date).getTime()/1e3,t.addEventListener("loadedmetadata",function(){t.currentTime+=parseFloat(t.totime+((new Date).getTime()/1e3-t.offset)).toFixed(3),t.play()},!1)}},{key:"handleCI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Character "+e[1],this.serv.send("AN#"+(e[1]/10+1)+"#%");for(var t=2;t<e.length-1;t++)if(t%2==0){var n=e[t].split("&");this.chars[e[t-1]]={name:n[0],desc:n[1],evidence:n[3],icon:l+"characters/"+escape(n[0])+"/char_icon.png"}}}},{key:"handleSC",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Characters";for(var t=1;t<e.length-1;t++){var n=e[t].split("&");this.chars[t-1]={name:n[0],desc:n[1],evidence:n[3],icon:l+"characters/"+escape(n[0])+"/char_icon.png"}}this.serv.send("RM#%")}},{key:"handleEI",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Evidence "+e[1],this.serv.send("RM#%")}},{key:"handleLE",value:function(e){this.evidences=[];for(var t=1;t<e.length-1;t++){var n=e[t].split("&");this.evidences[t-1]={name:ae(ue(de(n[0]))),desc:ae(ue(de(n[1]))),filename:escape(n[2]),icon:l+"evidence/"+escape(n[2])}}var i=document.getElementById("evidences");i.innerHTML="";for(var c=1;c<=this.evidences.length;c++)i.innerHTML+='<img src="'+this.evidences[c-1].icon+'" id="evi_'+c+'" alt="'+this.evidences[c-1].name+'" class="client_button" onclick="pickevidence('+c+')">'}},{key:"handleEM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music "+e[1],this.serv.send("AM#"+(e[1]/10+1)+"#%");for(var t=document.getElementById("client_musiclist"),n=2;n<e.length-1;n++)if(n%2==0){var i=document.createElement("OPTION");i.text=e[n],t.options.add(i)}}},{key:"handleSM",value:function(e){document.getElementById("client_loadingtext").innerHTML="Loading Music ";for(var t=document.getElementById("client_musiclist"),n=!1,i=1;i<e.length-1;i++)if(/\.(?:wav|mp3|mp4|ogg|mid)$/i.test(e[i])&&!n&&(n=!0),n){var c=document.createElement("OPTION");c.text=e[i],t.options.add(c)}else{var o=document.createElement("SPAN");o.className="location-box",o.textContent=e[i],o.onclick=function(){I(this)},document.getElementById("areas").appendChild(o)}var s=document.getElementById("areas"),a=document.createElement("OPTION");a.text=s.lastChild.textContent,t.insertBefore(a,t.firstChild),s.removeChild(s.lastChild),this.serv.send("RD#%")}},{key:"handlemusic",value:function(e){for(var t=0;t<e.length/2;t++)this.musicList[e[2*t]]=e[2*t+1]}},{key:"handleDONE",value:function(e){document.getElementById("client_loading").style.display="none",document.getElementById("client_charselect").style.display="block"}},{key:"handleBN",value:function(e){he.bgname=escape(e[1]);var t=Z("bg_select",escape(e[1]));document.getElementById("bg_select").selectedIndex=t,te(),0==t&&(document.getElementById("bg_filename").value=e[1]),document.getElementById("bg_preview").src=l+"background/"+escape(e[1])+"/defenseempty.png",-1==this.charID?M("jud"):M(this.chars[this.charID].side)}},{key:"handleNBG",value:function(e){}},{key:"handleHP",value:function(e){var t=10*e[2];1==e[1]?(this.hp[0]=e[2],$("#client_defense_hp > .health-bar").animate({width:t+"%"},500)):(this.hp[1]=e[2],$("#client_prosecutor_hp > .health-bar").animate({width:t+"%"},500))}},{key:"handleRT",value:function(e){"testimony1"==e[1]?this.testimonyID=1:this.testimonyID=2,he.initTestimonyUpdater()}},{key:"handleZZ",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+="$Alert: "+ue(de(e[1]))+"\r\n",t.scrollTop>t.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleID",value:function(e){this.playerID=e[1]}},{key:"handlePN",value:function(e){this.serv.send("askchaa#%")}},{key:"handleSI",value:function(e){r?this.serv.send("askchar2#%"):this.serv.send("RC#%")}},{key:"handleCharsCheck",value:function(e){document.getElementById("client_chartable").innerHTML="";for(var t=0;t<this.chars.length;t++){if(t%8==0)var n=document.createElement("TR");var i=document.createElement("TD"),c=void 0,o=this.chars[t].icon;c="-1"==e[t+1]?" dark":"",i.innerHTML="<img class='demothing"+c+"' id='demo_"+t+"' src='"+o+"' alt='"+this.chars[t].name+"' onclick='pickchar("+t+")' onerror='demoError(this);'>",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}}},{key:"handlePV",value:function(e){this.charID=e[3],document.getElementById("client_charselect").style.display="none";var t=this.me(),n=this.emotes,i=new XMLHttpRequest;document.getElementById("client_emo").innerHTML="",i.open("GET",l+"characters/"+escape(this.me().name)+"/char.ini",!0),i.responseType="text",i.onload=function(e){if(200==this.status){var i=this.responseText,c=p.parse(i);t.side=c.Options.side,V(t.side);for(var o=1;o<c.Emotions.number;o++){var s=c.Emotions[o].split("#"),a="0",d="0";void 0!==c.SoundN&&(a=c.SoundN[o]),void 0!==c.SoundT&&(d=c.SoundT[o]),n[o]={desc:s[0],speaking:s[1],silent:s[2],zoom:s[3],sfx:a,sfxdelay:d,button_off:l+"characters/"+escape(t.name)+"/emotions/button"+o+"_off.png",button_on:l+"characters/"+escape(t.name)+"/emotions/button"+o+"_on.png"},document.getElementById("client_emo").innerHTML+="<img src='"+n[o].button_off+"' id='emo_"+o+"' alt='"+n[o].desc+"' class='client_button' onclick='pickemotion("+o+")'>"}L(1)}},i.send()}}]),e}(),f=function(){function e(){c(this,e),this.textnow="",this.chatmsg={isnew:!1,content:"",objection:"0",sound:"",startpreanim:!1,startspeaking:!1,side:null,color:"0",snddelay:0,preanimdelay:0},this.blip=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var t=0;t<this.blipChannels.length;t++)this.blipChannels[t]=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.blipChannels[t].volume=.5;this.currentBlipChannel=0,this.sfxaudio=new Audio(l+"sounds/general/sfx-blipmale.wav"),this.sfxplayed=0,this.music=new Audio,this.music.play(),this.updater=null,this.testimonyUpdater=null,this.bgname="gs4",this.testimonyTimer=0,this.shoutTimer=0,this.textTimer=0,this._animating=!1}return i(e,[{key:"isAnimating",value:function(){return this._animating}},{key:"setBlipVolume",value:function(e){for(var t=0;t<this.blipChannels.length;t++)this.blipChannels[t].volume=e}},{key:"bgFolder",value:function(){return l+"background/"+this.bgname+"/"}},{key:"say",value:function(e){this.chatmsg=e,H(e.content,e.nameplate),M(e.side),this.textnow="",this.sfxplayed=0,this.textTimer=0,this._animating=!0,clearTimeout(this.updater),"-"!=e.preanim?e.preanimdelay=this.getAnimLength(l+"characters/"+escape(e.name)+"/"+e.preanim+".gif",this.initUpdater):this.initUpdater(0)}},{key:"initUpdater",value:function(e){he.chatmsg.preanimdelay=parseInt(e),he.updater=setTimeout(function(){return he.updateText()},60)}},{key:"initTestimonyUpdater",value:function(){var e=this;if(me.testimonyID>0){var t="";1==me.testimonyID?t="witnesstestimony":2==me.testimonyID&&(t="crossexamination"),new Audio(me.resources[t].sfx).play(),this.testimonyTimer=0,document.getElementById("client_testimony").src=me.resources[t].src,this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60)}}},{key:"getAnimLength",value:function(e,t,n){var i=new XMLHttpRequest;i.open("GET",e,!0),i.responseType="arraybuffer",i.addEventListener("load",function(){var e=gify.getInfo(i.response);console.log(e.duration),t(e.duration,n)}),i.send()}},{key:"updateTestimony",value:function(){var e=this;this.testimonyTimer=this.testimonyTimer+60,1==me.testimonyID?this.testimonyTimer>=me.resources.witnesstestimony.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):2==me.testimonyID?this.testimonyTimer>=me.resources.crossexamination.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):this.disposeTestimony()}},{key:"disposeTestimony",value:function(){me.testimonyID=0,this.testimonyTimer=0,document.getElementById("client_testimony").src="misc/placeholder.gif",clearTimeout(this.testimonyUpdater)}},{key:"updateText",value:function(){var e=this;if(1==this.chatmsg.flip?document.getElementById("client_char").style.transform="scaleX(-1)":document.getElementById("client_char").style.transform="scaleX(1)",this._animating&&(this.updater=setTimeout(function(){return e.updateText()},60)),this.chatmsg.isnew){document.getElementById("client_background").style.backgroundColor="transparent",document.getElementById("client_name").style.display="none",document.getElementById("client_chat").style.display="none",document.getElementById("client_evi").style.opacity="0",document.getElementById("client_evi").style.height="0%";var t={1:"holdit",2:"objection",3:"takethat"}[this.chatmsg.objection];void 0!==t?(document.getElementById("client_shout").src=me.resources[t].src,new Audio(l+"/characters/"+this.chatmsg.name+"/"+t+".wav").play(),this.shoutTimer=850):this.shoutTimer=0,this.chatmsg.isnew=!1,this.chatmsg.startpreanim=!0}if(this.textTimer>=this.shoutTimer&&this.chatmsg.startpreanim)2==this.chatmsg.flash?(this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-stab.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("shake",{direction:"up"})):1==this.chatmsg.flash&&(document.getElementById("client_background").style.backgroundColor="white",this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=l+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(document.getElementById("client_shout").src="misc/placeholder.gif",M(this.chatmsg.side),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.preanim+".gif"),this.chatmsg.startpreanim=!1,this.chatmsg.startspeaking=!0;else if(this.textTimer>=this.shoutTimer+this.chatmsg.preanimdelay&&!this.chatmsg.startpreanim)if(this.chatmsg.startspeaking){this.chatmsg.evidence>0&&(document.getElementById("client_evi").style.backgroundImage="url('"+me.evidences[this.chatmsg.evidence-1].icon+"')","def"==this.chatmsg.side?(document.getElementById("client_evi").style.right="1.5em",document.getElementById("client_evi").style.left="initial",$("#client_evi").animate({height:"30%",opacity:1},250)):(document.getElementById("client_evi").style.right="initial",document.getElementById("client_evi").style.left="1.5em",$("#client_evi").animate({height:"30%",opacity:1},250))),$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="misc/placeholder.gif",M(this.chatmsg.side)),document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.speaking+".gif",document.getElementById("client_name").style.fontSize=.7*document.getElementById("client_name").offsetHeight+"px",document.getElementById("client_chat").style.fontSize=.25*document.getElementById("client_chat").offsetHeight+"px",document.getElementById("client_name").innerHTML="<p>"+ae(this.chatmsg.nameplate)+"</p>";var n="color: "+({0:"#ffffff",1:"#00ff00",2:"#ff0000",3:"#ffaa00",4:"#0000ff",5:"#ffff00",6:"#aa00aa"}[this.chatmsg.color]||"#ffffff");document.getElementById("client_inner_chat").style=n,this.chatmsg.startspeaking=!1,this.textnow==this.chatmsg.content&&(document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",this._animating=!1,clearTimeout(this.updater))}else this.textnow!=this.chatmsg.content&&(" "!=this.chatmsg.content.charAt(this.textnow.length)&&(this.blipChannels[this.currentBlipChannel].play(),this.currentBlipChannel++,this.currentBlipChannel%=this.blipChannels.length),this.textnow=this.chatmsg.content.substring(0,this.textnow.length+1),document.getElementById("client_inner_chat").innerHTML=this.textnow,this.textnow==this.chatmsg.content&&(this.textTimer=0,this._animating=!1,document.getElementById("client_char").src=l+"characters/"+escape(this.chatmsg.name)+"/"+this.chatmsg.silent+".gif",clearTimeout(this.updater)));!this.sfxplayed&&this.chatmsg.snddelay+this.shoutTimer>=this.textTimer&&(this.sfxaudio.pause(),this.sfxplayed=1,"0"!=this.chatmsg.sound&&"1"!=this.chatmsg.sound&&(this.sfxaudio.src=l+"sounds/general/"+escape(this.chatmsg.sound)+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+60}}]),e}(),p=function(){function e(){c(this,e)}return i(e,null,[{key:"parse",value:function(e){var t={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},n={},i=null;return e.split(/\r\n|\r|\n/).forEach(function(e){if(!t.comment.test(e)&&0!=e.length)if(t.param.test(e)){var c=e.match(t.param);i?n[i][c[1]]=c[2]:n[c[1]]=c[2]}else if(t.section.test(e)){var o=e.match(t.section);n[o[1]]={},i=o[1]}}),n}}]),e}();function v(e){13==e.keyCode&&(me.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function _(e){if(13==e.keyCode){var t=me.me(),n=me.myEmote(),i=me.myEvidence(),c=me.flip?1:0,o=document.getElementById("textcolor").value,s="0",a="0";document.getElementById("sendsfx").checked&&(s=n.sfx,a=n.sfxdelay),me.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,s,n.zoom,a,h,i,c,u,o)}}function E(e){var t=document.getElementById("client_musiclist").value;me.sendMusicChange(t)}function I(e){var t=e.textContent;me.sendMusicChange(t)}function b(){he.music.volume=document.getElementById("client_mvolume").value/100}function B(){he.sfxaudio.volume=document.getElementById("client_svolume").value/100}function w(){he.setBlipVolume(document.getElementById("client_bvolume").value/100)}function k(e){me.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function C(e){return e.onerror="",e.src="misc/placeholder.gif",!0}function x(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function T(e,t,n){var i=new XMLHttpRequest;i.onreadystatechange=function(){4==this.readyState&&200==this.status?t(!0,n,e):t(!1,n,e)},i.open("GET",e,!0),i.send()}function M(e){var t,n=he.bgFolder();switch(document.getElementById("client_fg").style.display="none",document.getElementById("client_bench").style.display="none",e){case"def":document.getElementById("client_court").src=n+"defenseempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",O,e),t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",T(n+"defensedesk.png",O,e),t="prosecution";break;case"hld":document.getElementById("client_court").src=n+"helperstand.png",t="defense";break;case"hlp":document.getElementById("client_court").src=n+"prohelperstand.png",t="prosecution";break;case"wit":document.getElementById("client_court").src=n+"witnessempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"estrado.png",t="prosecution";break;case"jud":document.getElementById("client_court").src=n+"judgestand.png",t="prosecution"}5==he.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function O(e,t){var n=he.bgFolder();document.getElementById("client_bench").src="def"==t?e?n+"defensedesk.png":n+"bancodefensa.png":e?n+"prosecutiondesk.png":n+"bancoacusacion.png"}function N(){me.cleanup(),(me=new y(s))&&(a="join",document.getElementById("client_error").style.display="none")}function S(){me.joinServer()}function H(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Date,i=document.createElement("p"),c=document.createElement("span");if(c.id="iclog_name",c.appendChild(document.createTextNode(t)),i.appendChild(c),i.appendChild(document.createTextNode(e)),g.getMinutes()!==n.getMinutes()){var o=document.createElement("span");o.id="iclog_time",o.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(o)}var s=document.getElementById("client_log");s.appendChild(i),s.scrollTop>s.scrollHeight-600&&(s.scrollTop=s.scrollHeight),g=new Date}function P(e){e<1e3?me.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function L(e){-1!=me.selectedEmote&&(document.getElementById("emo_"+me.selectedEmote).src=me.myEmote().button_off),me.selectedEmote=e,document.getElementById("emo_"+e).src=me.myEmote().button_on}function D(e){if(me.selectedEvidence!=e){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),document.getElementById("evi_"+e).className="client_button dark",me.selectedEvidence=e,document.getElementById("evi_name").value=me.evidences[e-1].name,document.getElementById("evi_desc").value=me.evidences[e-1].desc;var t=Z("evi_select",me.evidences[e-1].filename);document.getElementById("evi_select").selectedIndex=t,0==t&&(document.getElementById("evi_filename").value=me.evidences[e-1].filename),F(),document.getElementById("evi_add").className="client_button hover_button inactive",document.getElementById("evi_edit").className="client_button hover_button",document.getElementById("evi_cancel").className="client_button hover_button",document.getElementById("evi_del").className="client_button hover_button"}else U()}function R(){var e=document.getElementById("evi_select");me.sendPE(document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function A(){var e=document.getElementById("evi_select"),t=parseInt(me.selectedEvidence)-1;me.sendEE(t,document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),U()}function j(){var e=parseInt(me.selectedEvidence)-1;me.sendDE(e),U()}function U(){me.selectedEvidence>0&&(document.getElementById("evi_"+me.selectedEvidence).className="client_button"),me.selectedEvidence=0,document.getElementById("evi_select").selectedIndex=0,F(),document.getElementById("evi_filename").value="",document.getElementById("evi_name").value="",document.getElementById("evi_desc").value="",document.getElementById("evi_icon").style.backgroundImage="url('misc/empty.png')",document.getElementById("evi_add").className="client_button hover_button",document.getElementById("evi_edit").className="client_button hover_button inactive",document.getElementById("evi_cancel").className="client_button hover_button inactive",document.getElementById("evi_del").className="client_button hover_button inactive"}function Z(e,t){for(var n=document.getElementById(e),i=1;i<n.length;++i)if(n.options[i].value==t)return i;return 0}function F(){var e=document.getElementById("evi_select"),t=document.getElementById("evi_filename"),n=document.getElementById("evi_icon");0==e.selectedIndex?(t.style.display="initial",n.style.backgroundImage="url('"+l+"evidence/"+t.value+"')"):(t.style.display="none",n.style.backgroundImage="url('"+l+"evidence/"+e.value+"')")}function V(e){"jud"==e?(document.getElementById("judge_action").style.display="inline-table",document.getElementById("no_action").style.display="none"):(document.getElementById("no_action").style.display="inline-table",document.getElementById("judge_action").style.display="none");for(var t=0,n=document.getElementById("role_select").options;t<n.length;t++)if(e==n[t].value)return void(n.selectedIndex=t)}function X(){var e="",t=document.getElementById("bg_select"),n=document.getElementById("bg_command").value;e=0==t.selectedIndex?document.getElementById("bg_filename").value:t.value,me.sendOOC("/"+n.replace("$1",e))}function z(){var e=document.getElementById("role_select"),t=document.getElementById("role_command").value;me.sendOOC("/"+t.replace("$1",e.value)),V(e.value)}function G(){me.sendOOC("/"+document.getElementById("randomchar_command").value)}function q(){$("#callmod_dialog").dialog("open")}function K(){me.sendRT("testimony1")}function W(){me.sendRT("testimony2")}function J(){me.sendHP(1,String(parseInt(me.hp[0])+1))}function Q(){me.sendHP(1,String(parseInt(me.hp[0])-1))}function Y(){me.sendHP(2,String(parseInt(me.hp[1])+1))}function ee(){me.sendHP(2,String(parseInt(me.hp[1])-1))}function te(){var e=document.getElementById("bg_select"),t=document.getElementById("bg_filename"),n=document.getElementById("bg_preview");0==e.selectedIndex?(t.style.display="initial",n.src=l+"background/"+t.value+"/defenseempty.png"):(t.style.display="none",n.src=l+"background/"+e.value+"/defenseempty.png")}function ne(e){e==u?(document.getElementById("button_effect_"+e).className="client_button",u=0):(document.getElementById("button_effect_"+e).className="client_button dark",u&&(document.getElementById("button_effect_"+u).className="client_button"),u=e)}function ie(){me.flip?document.getElementById("button_flip").className="client_button":document.getElementById("button_flip").className="client_button dark",me.flip=!me.flip}function ce(){me.presentable?document.getElementById("button_present").className="client_button":document.getElementById("button_present").className="client_button dark",me.presentable=!me.presentable}function oe(e){e!=m&&(document.getElementById("menu_"+e).className="menu_icon active",document.getElementById("content_"+e).className="menu_content active",document.getElementById("menu_"+m).className="menu_icon",document.getElementById("content_"+m).className="menu_content",m=e)}function se(e){e==h?(document.getElementById("button_"+e).className="client_button",h=0):(document.getElementById("button_"+e).className="client_button dark",h&&(document.getElementById("button_"+h).className="client_button"),h=e)}function ae(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function le(e){return e.replace(/#/g,"<pound>").replace(/&/g,"<and>").replace(/%/g,"<percent>").replace(/\$/g,"<dollar>")}function de(e){return e.replace(/<pound>/g,"#").replace(/<and>/g,"&").replace(/<percent>/g,"%").replace(/<dollar>/g,"$")}function re(e){var t=document.getElementById("client_encoding").value;if("unicode"==t)return e.replace(/[^\0-~]/g,function(e){return"\\u"+("000"+e.charCodeAt().toString(16)).slice(-4)});if("utf16"==t){for(var n=new ArrayBuffer(2*e.length),i=new Uint16Array(n),c=0,o=e.length;c<o;c++)i[c]=e.charCodeAt(c);return String(i)}return e}function ue(e){var t=document.getElementById("client_decoding").value;return"unicode"==t?e.replace(/\\u([\d\w]{1,})/gi,function(e,t){return String.fromCharCode(parseInt(t,16))}):"utf16"==t?String.fromCharCode.apply(null,new Uint16Array(e.split(","))):e}window.onOOCEnter=v,window.onEnter=_,window.musiclist_click=E,window.area_click=I,window.changeMusicVolume=b,window.changeSFXVolume=B,window.changeBlipVolume=w,window.changeCharacter=k,window.imgError=C,window.demoError=x,window.ReconnectButton=N,window.RetryButton=S,window.pickchar=P,window.pickemotion=L,window.pickevidence=D,window.addevidence=R,window.editevidence=A,window.delevidence=j,window.cancelevidence=U,window.getIndexFromSelect=Z,window.updateEvidenceIcon=F,window.updateActionCommands=V,window.changeBackgroundOOC=X,window.changeRoleOOC=z,window.randomCharacterOOC=G,window.callmod=q,window.initwt=K,window.initce=W,window.addHPD=J,window.redHPD=Q,window.addHPP=Y,window.redHPP=ee,window.updateBackgroundPreview=te,window.toggleaffect=ne,window.toggleflip=ie,window.togglepresent=ce,window.togglemenu=oe,window.toggleshout=se,void 0===String.prototype.trim&&(String.prototype.trim=function(){return String(this).replace(/^\s+|\s+$/g,"")}),String.prototype.hashCode=function(){var e,t=0;if(0===this.length)return t;for(e=0;e<this.length;e++)t=(t<<5)-t+this.charCodeAt(e),t|=0;return t};var me=new y(s),he=new f;$(document).ready(function(){me.initialObservBBCode(),me.loadResources()}),$(function(){$("#callmod_dialog").dialog({autoOpen:!1,resizable:!1,show:{effect:"drop",direction:"down",duration:500},hide:{effect:"drop",direction:"down",duration:500},height:"auto",width:400,modal:!0,buttons:{Sure:function(){me.sendZZ(""),$(this).dialog("close")},Cancel:function(){$(this).dialog("close")}}})})}});
//# sourceMappingURL=client.b.js.map \ No newline at end of file
diff --git a/webAO/client.b.js.map b/webAO/client.b.js.map
index 0898258..3ec58e5 100644
--- a/webAO/client.b.js.map
+++ b/webAO/client.b.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","clip","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","$","effect","direction","backgroundImage","right","left","animate","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","sendZZ","sendRT","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","String","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '<img src=\"' + this.evidences[i - 1].icon + \r\n\t\t\t\t'\" id=\"evi_' + i +'\" alt=\"' + this.evidences[i - 1].name +\r\n\t\t\t\t'\" class=\"client_button\" ' +\r\n\t\t\t\t'onclick=\"pickevidence('+ i +')\">';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\t// TODO (set by sD)\r\n\t\t// Also, this is broken.\r\n\t\tif (args[1] == 1) {\r\n\t\t\tdocument.getElementById(\"client_defense_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_prosecutor_hp\").style.clip = \"rect(0px,\" + BAR_WIDTH * args[2] / 10 + \"px,\" + BAR_HEIGHT + \"px,0px)\";\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `<img class='demothing${icon_chosen}' id='demo_${i}' ` +\r\n\t\t\t\t`src='${thispick}' alt='${this.chars[i].name}' onclick='pickchar(${i})' ` +\r\n\t\t\t\t`onerror='demoError(this);'>`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"<img src='\" + emotes[i].button_off + \"' id='emo_\" + i + \"' alt='\" + emotes[i].desc + \"' class='client_button' onclick='pickemotion(\" + i + \")'>\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"<p>\" + escapeHtml(this.chatmsg.nameplate) + \"</p>\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"inline-table\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"menu_wt\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"menu_ce\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\t\r\n\tclient.sendZZ(\"\");\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&amp;\")\r\n\t\t.replace(/</g, \"&lt;\")\r\n\t\t.replace(/>/g, \"&gt;\")\r\n\t\t.replace(/\"/g, \"&quot;\")\r\n\t\t.replace(/'/g, \"&#039;\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"<pound>\")\r\n\t\t.replace(/&/g, \"<and>\")\r\n\t\t.replace(/%/g, \"<percent>\")\r\n\t\t.replace(/\\$/g, \"<dollar>\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/<pound>/g, \"#\")\r\n\t\t.replace(/<and>/g, \"&\")\r\n\t\t.replace(/<percent>/g, \"%\")\r\n\t\t.replace(/<dollar>/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"<br>\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '<m a=\"$1\">') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '<c a=\"$1\">') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, '</c>'); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n});\r\n"],"sourceRoot":""} \ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","addHPD","redHPD","addHPP","redHPP","updateBackgroundPreview","toggleaffect","toggleflip","togglepresent","togglemenu","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedMenu","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","presentable","hp","playerID","charID","testimonyID","chars","emotes","evidences","resources","holdit","src","duration","objection","takethat","witnesstestimony","sfx","crossexamination","selectedEmote","selectedEvidence","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","LE","handleLE","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","RT","handleRT","ZZ","handleZZ","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","document","getElementById","add","Option","evidence_arr","length","background_select","background_arr","shouts","FileExist","callbackLoadImageResources","callbackLoadSFXResources","result","resource","client","viewport","getAnimLength","callbackGetResourceLength","target","MutationObserver","mutations","mutation","children","addedNodes","node","tagName","style","getAttribute","hasAttribute","backgroundColor","observe","attributes","childList","character","song","e","display","joinServer","console","error","reason","code","textContent","cleanup","data","debug","header","handler","warn","close","clearInterval","chatmsg","content","innerHTML","preanim","escape","nameplate","estring","replace","decodeBBCode","escapeHtml","decodeChat","unescapeChat","sound","type","snddelay","isnew","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","icon","arg","filename","evidence_box","hmusiclist","newentry","createElement","text","options","flagAudio","newarea","onclick","appendChild","area_box","audio_title","lastChild","insertBefore","firstChild","removeChild","bgname","bg_index","selectedIndex","changeBackground","percent_hp","$","animate","width","initTestimonyUpdater","tr","td","icon_chosen","thispick","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","testimonyUpdater","testimonyTimer","shoutTimer","textTimer","_animating","clearTimeout","initUpdater","animdelay","parseInt","setTimeout","updateText","_this3","updateTestimony","callback","param","request","gifInfo","gify","getInfo","response","log","_this4","disposeTestimony","_this5","transform","opacity","height","shout","1","2","3","effect","direction","backgroundImage","right","left","toggle","fontSize","offsetHeight","stylecolor","0","4","5","6","charAt","substring","regex","section","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myevi","myEvidence","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","el","setBlipVolume","sendLeaveRoom","image","url","xhttp","onreadystatechange","readyState","position","standname","bgfolder","bgFolder","callbackChangeBackground","toadd","arguments","undefined","time","entry","nameField","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","icon_id","sendPE","sendEE","sendDE","select_box","select_element","evidence_filename","evidence_iconbox","role_select","bg_command","role_command","dialog","sendRT","sendHP","String","background_filename","background_preview","menu","unsafe","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","Uint16Array","strLen","selectedDecoding","group","fromCharCode","apply","window","trim","hash","ready","initialObservBBCode","loadResources","autoOpen","resizable","show","hide","modal","buttons","Sure","sendZZ","Cancel"],"mappings":"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","file":"client.b.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\nlet queryDict = {};\r\nlocation.search.substr(1).split(\"&\").forEach(function(item) {\r\n\tqueryDict[item.split(\"=\")[0]] = item.split(\"=\")[1]\r\n});\r\n\r\n/* Server magic */\r\n\r\nconst serverIP = queryDict.ip;\r\nlet mode = queryDict.mode;\r\n\r\nconst AO_HOST = queryDict.asset || \"http://assets.aceattorneyonline.com/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\r\nconst BAR_WIDTH = 90;\r\nconst BAR_HEIGHT = 20;\r\nconst CHAR_SELECT_WIDTH = 8;\r\nconst UPDATE_INTERVAL = 60;\r\n\r\nlet oldLoading = false;\r\nif (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {\r\n\toldLoading = true;\r\n}\r\n\r\nlet selectedEffect = 0;\r\nlet selectedMenu = 1;\r\nlet selectedShout = 0;\r\nlet lastICMessageTime = new Date(0);\r\n\r\nclass Client {\r\n\tconstructor(address) {\r\n\t\tthis.serv = new WebSocket(\"ws://\" + address);\r\n\r\n\t\tthis.serv.onopen = (evt) => this.onOpen(evt);\r\n\t\tthis.serv.onclose = (evt) => this.onClose(evt);\r\n\t\tthis.serv.onmessage = (evt) => this.onMessage(evt);\r\n\t\tthis.serv.onerror = (evt) => this.onError(evt);\r\n\t\t\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\t\t\r\n\t\tthis.hp = [0,0];\r\n\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\t\tthis.testimonyID = 0;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\t\t\r\n\t\tthis.evidences = [];\r\n\t\t\r\n\t\tthis.resources = {\r\n\t\t\t\"holdit\":{\r\n\t\t\t\t\"src\": \"misc/holdit.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"objection\":{\r\n\t\t\t\t\"src\": \"misc/objection.gif\",\r\n\t\t\t\t\"duration\": 720\r\n\t\t\t},\r\n\t\t\t\"takethat\":{\r\n\t\t\t\t\"src\": \"misc/takethat.gif\",\r\n\t\t\t\t\"duration\": 840\r\n\t\t\t},\r\n\t\t\t\"witnesstestimony\":{\r\n\t\t\t\t\"src\": \"misc/witnesstestimony.gif\",\r\n\t\t\t\t\"duration\": 1560,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony.wav\"\r\n\t\t\t},\r\n\t\t\t\"crossexamination\":{\r\n\t\t\t\t\"src\": \"misc/crossexamination.gif\",\r\n\t\t\t\t\"duration\": 1600,\r\n\t\t\t\t\"sfx\": \"sounds/general/sfx-testimony2.wav\"\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tthis.selectedEmote = -1;\r\n\t\tthis.selectedEvidence = 0;\r\n\r\n\t\tthis.checkUpdater = null;\r\n\r\n\t\t// Only used for RMC/`music` packets, not EM/SM/MC packets.\r\n\t\tthis.musicList = Object();\r\n\r\n\t\tthis.handlers = {\r\n\t\t\t\"MS\": (args) => this.handleMS(args),\r\n\t\t\t\"CT\": (args) => this.handleCT(args),\r\n\t\t\t\"MC\": (args) => this.handleMC(args),\r\n\t\t\t\"RMC\": (args) => this.handleRMC(args),\r\n\t\t\t\"CI\": (args) => this.handleCI(args),\r\n\t\t\t\"SC\": (args) => this.handleSC(args),\r\n\t\t\t\"EI\": (args) => this.handleEI(args),\r\n\t\t\t\"LE\": (args) => this.handleLE(args),\r\n\t\t\t\"EM\": (args) => this.handleEM(args),\r\n\t\t\t\"SM\": (args) => this.handleSM(args),\r\n\t\t\t\"music\": (args) => this.handlemusic(args),\r\n\t\t\t\"DONE\": (args) => this.handleDONE(args),\r\n\t\t\t\"BN\": (args) => this.handleBN(args),\t\t\t\r\n\t\t\t\"NBG\": (args) => this.handleNBG(args),\r\n\t\t\t\"HP\": (args) => this.handleHP(args),\r\n\t\t\t\"RT\": (args) => this.handleRT(args),\r\n\t\t\t\"ZZ\": (args) => this.handleZZ(args),\r\n\t\t\t\"ID\": (args) => this.handleID(args),\r\n\t\t\t\"PN\": (args) => this.handlePN(args),\r\n\t\t\t\"SI\": (args) => this.handleSI(args),\r\n\t\t\t\"CharsCheck\": (args) => this.handleCharsCheck(args),\r\n\t\t\t\"PV\": (args) => this.handlePV(args),\r\n\t\t\t\"CHECK\": (args) => {}\r\n\t\t}\r\n\r\n\t\tthis._lastTimeICReceived = new Date(0);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current player's character.\r\n\t */\r\n\tme() {\r\n\t\treturn this.chars[this.charID];\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the player's currently selected emote.\r\n\t */\r\n\tmyEmote() {\r\n\t\treturn this.emotes[this.selectedEmote];\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets the player's currently selected evidence if presentable.\r\n\t */\r\n\tmyEvidence() {\r\n\t\treturn (this.presentable)? this.selectedEvidence : 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an out-of-character chat message.\r\n\t * @param {string} message the message to send\r\n\t */\r\n\tsendOOC(message) {\r\n\t\tthis.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends an in-character chat message.\r\n\t * @param {string} speaking who is speaking\r\n\t * @param {string} name the name of the current character\r\n\t * @param {string} silent whether or not it's silent\r\n\t * @param {string} message the message to be sent\r\n\t * @param {string} side the name of the side in the background\r\n\t * @param {string} ssfxname the name of the sound effect\r\n\t * @param {string} zoom whether or not to zoom\r\n\t * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect\r\n\t * @param {string} objection the number of the shout to play\r\n\t */\r\n\tsendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(encodeChat(message))}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%`\r\n\t\t);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends add evidence command.\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendPE(name, desc, img) {\r\n\t\tthis.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {string} evidence id\r\n\t * @param {string} evidence name\r\n\t * @param {string} evidence description\r\n\t * @param {string} evidence image filename\r\n\t */\r\n\tsendEE(id, name, desc, img) {\r\n\t\tthis.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {string} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {int} side the position\r\n\t * @param {int} hp the health point\r\n\t */\r\n\tsendHP(side,hp) {\r\n\t\tthis.serv.send(`HP#${side}#${hp}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends call mod command.\r\n\t * @param {string} message to mod\r\n\t */\r\n\tsendZZ(msg) {\r\n\t\tthis.serv.send(`ZZ#${msg}#%`);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Sends testimony command.\r\n\t * @param {string} testimony type\r\n\t */\r\n\tsendRT(testimony) {\r\n\t\tif(this.chars[this.charID].side == \"jud\"){\r\n\t\t\tthis.serv.send(`RT#${testimony}#%`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to change the music to the specified track.\r\n\t * @param {string} track the track ID\r\n\t */\r\n\tsendMusicChange(track) {\r\n\t\tthis.serv.send(`MC#${track}#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to leave the room and free the character slot.\r\n\t * \r\n\t * Note: This packet is undocumented. It is not implemented by\r\n\t * either the AO2 client or tsuserver.\r\n\t */\r\n\tsendLeaveRoom() {\r\n\t\tthis.serv.send(\"FC#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Begins the handshake process by sending an identifier\r\n\t * to the server.\r\n\t */\r\n\tjoinServer() {\r\n\t\tthis.serv.send(`HI#${navigator.userAgent.hashCode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.4.5#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Load evidence array to select\r\n\t\tvar evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= evidence_arr.length; i++) {\r\n\t\t evidence_select.add(new Option(evidence_arr[i - 1]));\r\n\t\t}\t\t\r\n\t\t// Load background array to select\r\n\t\tvar background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tfor(let i = 1; i <= background_arr.length; i++) {\r\n\t\t background_select.add(new Option(background_arr[i - 1]));\r\n\t\t}\r\n\t\t// Calculate gif duration of shouts\r\n\t\tlet shouts = [\"holdit\", \"objection\", \"takethat\"];\r\n\t\tfor (let i = 0; i < shouts.length; i++) {\r\n\t\t\tlet shout_src = AO_HOST + this.resources[shouts[i]][\"src\"];\r\n\t\t\tFileExist(shout_src, this.callbackLoadImageResources, shouts[i]);\t\t\r\n\t\t}\r\n\t\t\r\n\t\t// Calculate gif duration of testimony\r\n\t\tlet testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tlet testimony_src = AO_HOST + \"themes/default/\"+ testimony[i] +\".gif\";\r\n\t\t\t// Check iamge existed\r\n\t\t\tFileExist(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tFileExist(AO_HOST + this.resources[testimony[i]][\"sfx\"], this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\t\r\n\t\t// TODO: Cache some resources\r\n\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for image resources.\r\n\t * @param {boolean} result the image is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadImageResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"src\"] = src;\r\n\t\t\tviewport.getAnimLength(src,client.callbackGetResourceLength, resource);\r\n\t\t}\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for animation duration resource\r\n\t * @param {integer} length the animation length\r\n\t * @param {string} resource the resource name\r\n\t */\r\n\tcallbackGetResourceLength(length, resource) {\r\n\t\tclient.resources[resource][\"duration\"] = length; \r\n\t}\r\n\t\r\n\t/**\r\n\t * Callback for sfx resources.\r\n\t * @param {boolean} result the audio is existed or not\r\n\t * @param {string} resource the resource name\r\n\t * @param {string} src the url of resource\r\n\t */\r\n\tcallbackLoadSFXResources(result, resource, src) {\r\n\t\tif(result){\r\n\t\t\tclient.resources[resource][\"sfx\"] = src;\r\n\t\t}\t\r\n\t}\t\r\n\t\r\n\t/**\r\n\t * Create observer to detect BBCode elements\r\n\t * then manipulate them.\r\n\t */\r\n\tinitialObservBBCode() {\r\n\t\tvar target = document.getElementById(\"client_inner_chat\");\r\n\t\tvar observer = new MutationObserver(function(mutations) {\r\n\t\t mutations.forEach(function(mutation) {\r\n\t\t\tvar children = mutation.addedNodes;\r\n\t\t\tif (children !== null) {\r\n\t\t\t\tchildren.forEach( function(node) {\r\n\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t} else if(node.tagName == \"M\"){\r\n\t\t\t\t\t\tif (node.hasAttribute('a')) {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t }); \r\n\t\t});\r\n\t\tvar config = {attributes: true,childList: true};\r\n\t\tobserver.observe(target,config);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to play as a specified character.\r\n\t * @param {number} character the character ID\r\n\t */\r\n\tsendCharacter(character) {\r\n\t\tthis.serv.send(`CC#${this.playerID}#${character}#web#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Requests to select a music track.\r\n\t * @param {number?} song the song to be played\r\n\t */\r\n\tsendMusic(song) {\r\n\t\tthis.serv.send(`MC#${song}`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends a keepalive packet.\r\n\t */\r\n\tsendCheck() {\r\n\t\tthis.serv.send(`CH#${this.charID}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a connection is established to the server.\r\n\t */\r\n\tonOpen(e) {\r\n\t\t// XXX: Why does watching mean just SITTING there and doing nothing?\r\n\t\tif (mode === \"watch\") {\r\n\t\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\t} else {\r\n\t\t\tclient.joinServer();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when the connection to the server closes.\r\n\t * @param {CloseEvent} e\r\n\t */\r\n\tonClose(e) {\r\n\t\tconsole.error(`The connection was closed: ${e.reason} (${e.code})`);\r\n\t\tif (e.code !== 1001) {\r\n\t\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\t\tthis.cleanup();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when a packet is received from the server.\r\n\t * @param {MessageEvent} e\r\n\t */\r\n\tonMessage(e) {\r\n\t\tlet msg = e.data;\r\n\t\tconsole.debug(msg);\r\n\t\tlet lines = msg.split('%');\r\n\t\tlet args = lines[0].split('#');\r\n\t\tlet header = args[0];\r\n\t\tlet handler = this.handlers[header];\r\n\t\tif (typeof handler !== \"undefined\") {\r\n\t\t\thandler(args);\r\n\t\t} else {\r\n\t\t\tconsole.warn(`Invalid packet header ${header}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Triggered when an network error occurs.\r\n\t * @param {ErrorEvent} e \r\n\t */\r\n\tonError(e) {\r\n\t\tconsole.error(`A network error occurred: ${e.reason} (${e.code})`);\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"error_id\").textContent = e.code;\r\n\t\tthis.cleanup();\r\n\t}\r\n\r\n\tcleanup() {\r\n\t\ttry {\r\n\t\t\tthis.serv.close(1001);\r\n\t\t} catch (e) {\r\n\t\t\t// I don't care if this errors\r\n\t\t}\r\n\t\tclearInterval(this.checkUpdater);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an in-character chat message.\r\n\t * @param {*} args packet arguments\r\n\t */\r\n\thandleMS(args) {\r\n\t\t// TODO: this if-statement might be a bug.\r\n\t\tif (args[4] != viewport.chatmsg.content) {\r\n\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = \"\";\r\n\t\t\tlet chatmsg = {\r\n\t\t\t\t// pre: escape(args[2]),\r\n\t\t\t\tcharacter: -1, // Will do a linear search\r\n\t\t\t\tpreanim: escape(args[2]), // XXX: why again?\r\n\t\t\t\tnameplate: args[3], // TODO: parse INI to get this info\r\n\t\t\t\tname: args[3],\r\n\t\t\t\tspeaking: \"(b)\" + escape(args[4]),\r\n\t\t\t\tsilent: \"(a)\" + escape(args[4]),\r\n\t\t\t\tcontent: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only!\r\n\t\t\t\tside: args[6],\r\n\t\t\t\tsound: escape(args[7]),\r\n\t\t\t\ttype: args[8],\r\n\t\t\t\t// charid: args[9],\r\n\t\t\t\tsnddelay: args[10],\r\n\t\t\t\tobjection: args[11],\r\n\t\t\t\tevidence: args[12],\r\n\t\t\t\tflip: args[13],\r\n\t\t\t\tflash: args[14],\r\n\t\t\t\tcolor: args[15],\r\n\t\t\t\tisnew: true,\r\n\t\t\t};\r\n\r\n\t\t\t// The dreaded linear search...\r\n\t\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\t\tif (this.chars[i].name == args[3]) {\r\n\t\t\t\t\tchatmsg.character = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (chatmsg.character == this.charID) {\r\n\t\t\t\tresetICParams();\r\n\t\t\t}\r\n\r\n\t\t\tviewport.say(chatmsg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles an out-of-character chat message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCT(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `${decodeChat(unescapeChat(args[1]))}: ${decodeChat(unescapeChat(args[2]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleMC(args) {\r\n\t\tconst music = viewport.music;\r\n\t\tmusic.pause();\r\n\t\tmusic.src = MUSIC_HOST + args[1];\r\n\t\tmusic.play();\r\n\t\tif (args[2] >= 0) {\r\n\t\t\tlet musicname = this.chars[args[2]].name;\r\n\t\t\tappendICLog(`${musicname} changed music to ${args[1]}`);\r\n\t\t} else {\r\n\t\t\tappendICLog(`The music was changed to ${args[1]}`);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a music change to an arbitrary resource, with an offset in seconds.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRMC(args) {\r\n\t\tviewport.music.pause();\r\n\t\tviewport.music = new Audio(this.musicList[args[1]]);\r\n\t\tconst music = viewport.music;\r\n\t\t// Music offset + drift from song loading\r\n\t\tmusic.totime = args[1];\r\n\t\tmusic.offset = new Date().getTime() / 1000;\r\n\t\tmusic.addEventListener('loadedmetadata', function() {\r\n\t\t\tmusic.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3);\r\n\t\t\tmusic.play();\r\n\t\t}, false);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, bundling multiple characters\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Character \" + args[1];\r\n\t\tthis.serv.send(\"AN#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\t\tthis.chars[args[i - 1]] = {\r\n\t\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming character information, containing only one character\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSC(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Characters\";\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet chargs = args[i].split(\"&\");\r\n\t\t\tthis.chars[i - 1] = {\r\n\t\t\t\t\"name\": chargs[0],\r\n\t\t\t\t\"desc\": chargs[1],\r\n\t\t\t\t\"evidence\": chargs[3],\r\n\t\t\t\t\"icon\": AO_HOST + \"characters/\" + escape(chargs[0]) + \"/char_icon.png\"\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming evidence information, containing only one evidence\r\n\t * item per packet.\r\n\t * \r\n\t * Mostly unimplemented in webAO.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEI(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Evidence \" + args[1];\r\n\t\t//serv.send(\"AE#\" + (args[1] + 1) + \"#%\");\r\n\t\tthis.serv.send(\"RM#%\");\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles incoming evidence list, all evidences at once\r\n\t * item per packet.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleLE(args) {\r\n\t\tthis.evidences = [];\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tvar arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": escapeHtml(decodeChat(unescapeChat(arg[0]))),\r\n\t\t\t\t\"desc\": escapeHtml(decodeChat(unescapeChat(arg[1]))),\r\n\t\t\t\t\"filename\": escape(arg[2]),\r\n\t\t\t\t\"icon\": AO_HOST + \"evidence/\" + escape(arg[2])\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tvar evidence_box = document.getElementById(\"evidences\");\r\n\t\tevidence_box.innerHTML = \"\";\r\n\t\tfor(let i = 1; i <= this.evidences.length; i++){\r\n\t\t\tevidence_box.innerHTML += '<img src=\"' + this.evidences[i - 1].icon + \r\n\t\t\t\t'\" id=\"evi_' + i +'\" alt=\"' + this.evidences[i - 1].name +\r\n\t\t\t\t'\" class=\"client_button\" ' +\r\n\t\t\t\t'onclick=\"pickevidence('+ i +')\">';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `<img class='demothing${icon_chosen}' id='demo_${i}' ` +\r\n\t\t\t\t`src='${thispick}' alt='${this.chars[i].name}' onclick='pickchar(${i})' ` +\r\n\t\t\t\t`onerror='demoError(this);'>`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\tdocument.getElementById(\"client_emo\").innerHTML = \"\"; // Clear emote box\r\n\t\txhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true);\r\n\t\txhr.responseType = 'text';\r\n\t\txhr.onload = function (e) {\r\n\t\t\tif (this.status == 200) {\r\n\t\t\t\tlet linifile = this.responseText;\r\n\t\t\t\tlet pinifile = INI.parse(linifile);\r\n\t\t\t\tme.side = pinifile.Options.side;\r\n\t\t\t\tupdateActionCommands(me.side);\r\n\t\t\t\tfor (let i = 1; i < pinifile.Emotions.number; i++) {\r\n\t\t\t\t\tlet emoteinfo = pinifile.Emotions[i].split('#');\r\n\t\t\t\t\tlet esfx = \"0\";\r\n\t\t\t\t\tlet esfxd = \"0\";\r\n\t\t\t\t\tif (typeof pinifile.SoundN !== 'undefined') {\r\n\t\t\t\t\t\tesfx = pinifile.SoundN[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (typeof pinifile.SoundT !== 'undefined') {\r\n\t\t\t\t\t\tesfxd = pinifile.SoundT[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: emoteinfo[1],\r\n\t\t\t\t\t\tsilent: emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png'\r\n\t\t\t\t\t};\r\n\t\t\t\t\tdocument.getElementById(\"client_emo\").innerHTML += \"<img src='\" + emotes[i].button_off + \"' id='emo_\" + i + \"' alt='\" + emotes[i].desc + \"' class='client_button' onclick='pickemotion(\" + i + \")'>\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"<p>\" + escapeHtml(this.chatmsg.nameplate) + \"</p>\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack = el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&amp;\")\r\n\t\t.replace(/</g, \"&lt;\")\r\n\t\t.replace(/>/g, \"&gt;\")\r\n\t\t.replace(/\"/g, \"&quot;\")\r\n\t\t.replace(/'/g, \"&#039;\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"<pound>\")\r\n\t\t.replace(/&/g, \"<and>\")\r\n\t\t.replace(/%/g, \"<percent>\")\r\n\t\t.replace(/\\$/g, \"<dollar>\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/<pound>/g, \"#\")\r\n\t\t.replace(/<and>/g, \"&\")\r\n\t\t.replace(/<percent>/g, \"%\")\r\n\t\t.replace(/<dollar>/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"<br>\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)del\\]/g, \"<$1del>\") // Deleted [del][/del]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1ins>\") // Underline [u][/u]\r\n\t\t.replace(/\\[(\\/?)sub\\]/g, \"<$1sub>\") // Subscript [sub][/sub]\r\n\t\t.replace(/\\[(\\/?)sup\\]/g, \"<$1sup>\") // Superscript [sup][/sup]\r\n\t\t.replace(/\\[m=([#a-zA-Z0-9]+)\\]/g, '<m a=\"$1\">') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '<c a=\"$1\">') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, '</c>'); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n String.prototype.trim = function() \r\n {\r\n return String(this).replace(/^\\s+|\\s+$/g, '');\r\n };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t chr = this.charCodeAt(i);\r\n\t hash = ((hash << 5) - hash) + chr;\r\n\t hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""} \ No newline at end of file
diff --git a/webAO/client.css b/webAO/client.css
index 60f6645..721ad45 100644
--- a/webAO/client.css
+++ b/webAO/client.css
@@ -327,11 +327,9 @@ img {
#client_bars {
position: relative;
- /*! margin-bottom: 30px; */
text-align: center;
- /* display: flex; */
- /* flex-direction: row; */
- height: 20px;
+ display: flex;
+ display: -webkit-flex;
}
#client_testimony {
@@ -366,15 +364,41 @@ img {
margin-right: auto;
}
-.client_defense {
- /* position: absolute; */
- /* left: 30px; */
- width: 90px;
+#client_defense_hp{
+ text-align: left;
+}
+
+#client_defense_hp > .health-bar{
+ background-color: #169de0;
+}
+
+#client_prosecutor_hp{
+ text-align: right;
+}
+
+#client_prosecutor_hp > .health-bar{
+ background-color: #e01f5f;
+}
+
+
+.health-box {
+ background-color: #555;
height: 20px;
+ width: 50%;
+ margin: 0 auto;
+ border: solid 2px #aaa;
+ border-radius: 5px;
+ box-sizing:border-box;
+ display: block;
}
-.client_prosecutor {
- /* left: 130px; */
+.health-bar {
+ width: 100%;
+ height: 100%;
+ border-radius: 3px;
+ bottom: 0;
+ position: relative;
+ display: inline-block;
}
.client_button {
@@ -462,6 +486,10 @@ img {
font-size: 3em;
}
+.material-icons.em-1-5 {
+ font-size: 1.5em;
+}
+
.location-box{
border-style: double;
background-color: #7B2900;
diff --git a/webAO/client.html b/webAO/client.html
index d2c7b54..88a9f9b 100644
--- a/webAO/client.html
+++ b/webAO/client.html
@@ -5,9 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="client.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
+ <script src="https://code.jquery.com/jquery-migrate-3.0.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<!--<script src="golden/js/goldenlayout.js"></script>-->
- <link type="text/css" rel="stylesheet" href="golden/css/goldenlayout.css" />
+ <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
+ <link type="text/css" rel="stylesheet" href="golden/css/goldenlayout.css" />
<link type="text/css" rel="stylesheet" href="https://golden-layout.com/files/latest/css/goldenlayout-dark-theme.css" />
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src="lib/jdataview.min.js"></script>
@@ -39,12 +41,12 @@
<input id="client_inputbox" class="long" type="text" onkeypress="onEnter(event)" style="padding-left: 1px; padding-right: 1px;">
<meta name="frame-title" lang="en" content="Miscellaneous">
<div id="client_bars">
- <span style="background-image: url(&quot;misc/zdoh.png&quot;); width: 90px; height: 20px;">
- <img class="client_defense" alt="Defense health" id="client_defense_hp" src="misc/advocat.png" style="clip-path: polygon(0px 0px, 90px 0px, 90px 20px, 0px 20px, 0px 0px); clip: rect(0px, 90px, 20px, 0px);">
- </span>
- <span style="background-image: url(&quot;misc/zdoh.png&quot;); width: 90px; height: 20px;" misc="">
- <img class="client_prosecutor" alt="Prosecution health" id="client_prosecutor_hp" src="misc/procuror.png" style="clip-path: polygon(0px 0px, 90px 0px, 90px 20px, 0px 20px, 0px 0px); clip: rect(0px, 90px, 20px, 0px);" misc="">
- </span>
+ <span id="client_defense_hp" class="health-box">
+ <div class="health-bar"></div>
+ </span>
+ <span id="client_prosecutor_hp" class="health-box">
+ <div class="health-bar"></div>
+ </span>
</div>
<div id="client_emo">
</div>
@@ -75,12 +77,29 @@
</div>
<fieldset style="margin:10px;">
<legend>Action Commands</legend>
- <span>
- <span id="menu_wt" onclick="initwt()" class="menu_icon" style="display:none"><i class="material-icons em-3">record_voice_over</i><div>Witness<br>Testimony</div></span>
- <span id="menu_ce" onclick="initce()" class="menu_icon" style="display:none"><i class="material-icons em-3">question_answer</i><div>Cross<br>Examination</div></span>
- <span id="menu_cm" onclick="callmod()" class="menu_icon"><i class="material-icons em-3">report</i><div>Call Mod</div></span>
+ <!----------- Judge Commands --------------->
+ <span id="judge_action" style="display:none">
+ <span id="menu_wt" onclick="initwt()" class="menu_icon"><i class="material-icons em-3">record_voice_over</i><div>Witness<br>Testimony</div></span>
+ <span id="menu_ce" onclick="initce()" class="menu_icon"><i class="material-icons em-3">question_answer</i><div>Cross<br>Examination</div></span>
+ <br>
+ <span style="display:inline-block; vertical-align: middle;">
+ <span id="menu_ahpd" onclick="addHPD()" class="menu_icon" ><i class="material-icons em1-5">add_circle</i></span>
+ <span style="font-size: 1.25em">Defense</span>
+ <span id="menu_rhpd" onclick="redHPD()" class="menu_icon" ><i class="material-icons em1-5">remove_circle</i></span>
+ </span>
+ <span style="display:inline-block; vertical-align: middle;">
+ <span id="menu_ahpp" onclick="addHPP()" class="menu_icon" ><i class="material-icons em-1-5">add_circle</i></span>
+ <span style="font-size: 1.25em">Prosecution</span>
+ <span id="menu_rhpp" onclick="redHPP()" class="menu_icon" ><i class="material-icons em-1-5">remove_circle</i></span>
+ </span>
+ </span>
+ <!----------- No Commands --------------->
+ <span id="no_action">
+ No action available for this role.
</span>
</fieldset>
+ <br>
+ <span id="menu_cm" onclick="callmod()" class="menu_icon"><i class="material-icons em-3">report</i><div>Call Mod</div></span>
</template>
<template id="mainmenu">
@@ -228,6 +247,10 @@
</select>
</template>
+<div id="callmod_dialog" title="Are you sure to call mod?">
+ <p><span class="ui-icon ui-icon-alert" style="float:left; margin:12px 12px 20px 0;"></span>They might be very busy. Are you sure?</p>
+</div>
+
<body>
<span id="sound"></span>
<div id="here"></div>
diff --git a/webAO/client.js b/webAO/client.js
index 68d7c7d..83c34ab 100644
--- a/webAO/client.js
+++ b/webAO/client.js
@@ -42,6 +42,8 @@ class Client {
this.flip = false;
this.presentable = false;
+
+ this.hp = [0,0];
this.playerID = 1;
this.charID = -1;
@@ -192,6 +194,15 @@ class Client {
}
/**
+ * Sends health point command.
+ * @param {int} side the position
+ * @param {int} hp the health point
+ */
+ sendHP(side,hp) {
+ this.serv.send(`HP#${side}#${hp}#%`);
+ }
+
+ /**
* Sends call mod command.
* @param {string} message to mod
*/
@@ -707,13 +718,16 @@ class Client {
* @param {Array} args packet arguments
*/
handleHP(args) {
- // TODO (set by sD)
- // Also, this is broken.
+ let percent_hp = args[2] * 10;
if (args[1] == 1) {
- document.getElementById("client_defense_hp").style.clip = "rect(0px," + BAR_WIDTH * args[2] / 10 + "px," + BAR_HEIGHT + "px,0px)";
+ // Def hp
+ this.hp[0] = args[2];
+ $("#client_defense_hp > .health-bar").animate({ 'width': percent_hp + "%" }, 500);
} else {
- document.getElementById("client_prosecutor_hp").style.clip = "rect(0px," + BAR_WIDTH * args[2] / 10 + "px," + BAR_HEIGHT + "px,0px)";
- }
+ // Pro hp
+ this.hp[1] = args[2];
+ $("#client_prosecutor_hp > .health-bar").animate({ 'width': percent_hp + "%" }, 500);
+ }
}
/**
@@ -744,20 +758,6 @@ class Client {
}
/**
- * Handles a change in the health bars' states.
- * @param {Array} args packet arguments
- */
- handleHP(args) {
- // TODO (set by sD)
- // Also, this is broken.
- if (args[1] == 1) {
- document.getElementById("client_defense_hp").style.clip = "rect(0px," + BAR_WIDTH * args[2] / 10 + "px," + BAR_HEIGHT + "px,0px)";
- } else {
- document.getElementById("client_prosecutor_hp").style.clip = "rect(0px," + BAR_WIDTH * args[2] / 10 + "px," + BAR_HEIGHT + "px,0px)";
- }
- }
-
- /**
* Handles the issuance of a player ID by the server.
* @param {Array} args packet arguments
*/
@@ -1672,11 +1672,11 @@ window.updateEvidenceIcon = updateEvidenceIcon;
*/
export function updateActionCommands(side) {
if(side == "jud"){
- document.getElementById("menu_wt").style.display = "inline-table";
- document.getElementById("menu_ce").style.display = "inline-table";
+ document.getElementById("judge_action").style.display = "inline-table";
+ document.getElementById("no_action").style.display = "none";
} else {
- document.getElementById("menu_wt").style.display = "none";
- document.getElementById("menu_ce").style.display = "none";
+ document.getElementById("no_action").style.display = "inline-table";
+ document.getElementById("judge_action").style.display = "none";
}
//Update role selector
for(let i = 0, role_select = document.getElementById("role_select").options; i < role_select.length; i++){
@@ -1726,8 +1726,8 @@ window.randomCharacterOOC = randomCharacterOOC;
/**
* Call mod.
*/
-export function callmod() {
- client.sendZZ("");
+export function callmod() {
+ $( "#callmod_dialog" ).dialog( "open" );
}
window.callmod = callmod;
@@ -1748,6 +1748,38 @@ export function initce() {
window.initce = initce;
/**
+ * Add defense health point.
+ */
+export function addHPD() {
+ client.sendHP(1,String(parseInt(client.hp[0]) + 1));
+}
+window.addHPD = addHPD;
+
+/**
+ * Reduce defense health point.
+ */
+export function redHPD() {
+ client.sendHP(1,String(parseInt(client.hp[0]) - 1));
+}
+window.redHPD = redHPD;
+
+/**
+ * Add prosecution health point.
+ */
+export function addHPP() {
+ client.sendHP(2,String(parseInt(client.hp[1]) + 1));
+}
+window.addHPP = addHPP;
+
+/**
+ * Reduce prosecution health point.
+ */
+export function redHPP() {
+ client.sendHP(2,String(parseInt(client.hp[1]) - 1));
+}
+window.redHPP = redHPP;
+
+/**
* Update background preview.
*/
export function updateBackgroundPreview() {
@@ -1976,4 +2008,35 @@ let viewport = new Viewport();
$(document).ready(function(){
client.initialObservBBCode();
client.loadResources();
+
});
+
+// Create dialog and link to button
+$( function() {
+ $( "#callmod_dialog" ).dialog({
+ autoOpen: false,
+ resizable: false,
+ show: {
+ effect: "drop",
+ direction:"down",
+ duration: 500
+ },
+ hide: {
+ effect: "drop",
+ direction:"down",
+ duration: 500
+ },
+ height: "auto",
+ width: 400,
+ modal: true,
+ buttons: {
+ "Sure": function() {
+ client.sendZZ("");
+ $( this ).dialog( "close" );
+ },
+ Cancel: function() {
+ $( this ).dialog( "close" );
+ }
+ }
+ });
+}); \ No newline at end of file