From 18629bfa646e4b0596a3c1ae9c6a3e3ba58347b9 Mon Sep 17 00:00:00 2001 From: Qube Date: Wed, 18 Jul 2018 21:40:26 +0700 Subject: Add pre-animation, flash, shake, flip, and text color + Fix shout order according to AO2 specification --- webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.css | 16 +++++ webAO/client.html | 31 +++++++-- webAO/client.js | 177 ++++++++++++++++++++++++++++++++++++++++++++------ webAO/misc/flash.png | Bin 0 -> 1731 bytes webAO/misc/flip.png | Bin 0 -> 1576 bytes webAO/misc/shake.png | Bin 0 -> 2018 bytes 8 files changed, 199 insertions(+), 29 deletions(-) create mode 100644 webAO/misc/flash.png create mode 100644 webAO/misc/flip.png create mode 100644 webAO/misc/shake.png diff --git a/webAO/client.b.js b/webAO/client.b.js index 9506442..5d762e5 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,{configurable:!1,enumerable:!0,get:i})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},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=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;nt.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=L.music;(t.pause(),t.src=r+e[1],t.play(),e[2]>=0)?T(this.chars[e[2]].name+" changed music to "+e[1]):T("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){L.music.pause(),L.music=new Audio(this.musicList[e[1]]);var t=L.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",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}w("def")}},{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;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=g.parse(i);t.side=c.Options.side;for(var s=1;s"}S(1)}},i.send()}}]),e}(),p=function(){function e(){c(this,e),this.textnow="",this.chatmsg={isnew:!1,content:"",objection:"0",sound:"",startspeaking:!1,side:null,color:"0",snddelay: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.shoutTimer)if(this.chatmsg.startspeaking){w(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="

"+this.chatmsg.nameplate.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")+"

";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+65}}]),e}(),g=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 f(e){13==e.keyCode&&(H.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function y(e){if(13==e.keyCode){var t=H.me(),n=H.myEmote(),i="0",c="0";document.getElementById("sendsfx").checked&&(i=n.sfx,c=n.sfxdelay),H.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,i,n.zoom,c,d)}}function v(e){var t=document.getElementById("client_musiclist").value;H.sendMusicChange(t)}function E(){L.music.volume=document.getElementById("client_mvolume").value/100}function _(){L.sfxaudio.volume=document.getElementById("client_svolume").value/100}function I(){L.setBlipVolume(document.getElementById("client_bvolume").value/100)}function k(e){H.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function B(e){return e.onerror="",e.src="/misc/placeholder.gif",!0}function b(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function w(e){var t,n=L.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",document.getElementById("client_bench").src=n+"defensedesk.png",t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"prosecutiondesk.png",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==L.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function C(){H.cleanup(),(H=new m(o))&&(a="join",document.getElementById("client_error").style.display="none")}function x(){H.joinServer()}function T(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)),h.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),h=new Date}function M(e){e<1e3?H.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function S(e){-1!=H.selectedEmote&&(document.getElementById("emo_"+H.selectedEmote).src=H.myEmote().button_off),H.selectedEmote=e,document.getElementById("emo_"+e).src=H.myEmote().button_on}function O(e){e==d?(document.getElementById("button_"+e).className="client_button",d=0):(document.getElementById("button_"+e).className="client_button dark",d&&(document.getElementById("button_"+d).className="client_button"),d=e)}function D(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}window.onOOCEnter=f,window.onEnter=y,window.musiclist_click=v,window.changeMusicVolume=E,window.changeSFXVolume=_,window.changeBlipVolume=I,window.changeCharacter=k,window.imgError=B,window.demoError=b,window.ReconnectButton=C,window.RetryButton=x,window.pickchar=M,window.pickemotion=S,window.toggleshout=O,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;et.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=j.music;(t.pause(),t.src=r+e[1],t.play(),e[2]>=0)?M(this.chars[e[2]].name+" changed music to "+e[1]):M("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){j.music.pause(),j.music=new Audio(this.musicList[e[1]]);var t=j.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",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}x("def")}},{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;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,s=f.parse(i);t.side=s.Options.side;for(var c=1;c"}O(1)}},i.send()}}]),e}(),p=function(){function e(){s(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.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="",x(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){$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="",x(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="

"+function(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}(this.chatmsg.nameplate)+"

";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+65}}]),e}(),f=function(){function e(){s(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 s=e.match(t.param);i?n[i][s[1]]=s[2]:n[s[1]]=s[2]}else if(t.section.test(e)){var c=e.match(t.section);n[c[1]]={},i=c[1]}}),n}}]),e}();function y(e){13==e.keyCode&&(P.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function v(e){if(13==e.keyCode){var t=P.me(),n=P.myEmote(),i=P.flip?1:0,s=document.getElementById("textcolor").value,c="0",o="0";document.getElementById("sendsfx").checked&&(c=n.sfx,o=n.sfxdelay),P.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,c,n.zoom,o,h,i,d,s)}}function _(e){var t=document.getElementById("client_musiclist").value;P.sendMusicChange(t)}function E(){j.music.volume=document.getElementById("client_mvolume").value/100}function I(){j.sfxaudio.volume=document.getElementById("client_svolume").value/100}function b(){j.setBlipVolume(document.getElementById("client_bvolume").value/100)}function B(e){P.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function k(e){return e.onerror="",e.src="/misc/placeholder.gif",!0}function w(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function x(e){var t,n=j.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",document.getElementById("client_bench").src=n+"defensedesk.png",t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"prosecutiondesk.png",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==j.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function C(){P.cleanup(),(P=new g(o))&&(a="join",document.getElementById("client_error").style.display="none")}function T(){P.joinServer()}function M(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"),s=document.createElement("span");if(s.id="iclog_name",s.appendChild(document.createTextNode(t)),i.appendChild(s),i.appendChild(document.createTextNode(e)),m.getMinutes()!==n.getMinutes()){var c=document.createElement("span");c.id="iclog_time",c.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(c)}var o=document.getElementById("client_log");o.appendChild(i),o.scrollTop>o.scrollHeight-600&&(o.scrollTop=o.scrollHeight),m=new Date}function S(e){e<1e3?P.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function O(e){-1!=P.selectedEmote&&(document.getElementById("emo_"+P.selectedEmote).src=P.myEmote().button_off),P.selectedEmote=e,document.getElementById("emo_"+e).src=P.myEmote().button_on}function L(e){e==d?(document.getElementById("button_effect_"+e).className="client_button",d=0):(document.getElementById("button_effect_"+e).className="client_button dark",d&&(document.getElementById("button_effect_"+d).className="client_button"),d=e)}function N(){P.flip?document.getElementById("button_flip").className="client_button":document.getElementById("button_flip").className="client_button dark",P.flip=!P.flip}function H(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 D(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}window.onOOCEnter=y,window.onEnter=v,window.musiclist_click=_,window.changeMusicVolume=E,window.changeSFXVolume=I,window.changeBlipVolume=b,window.changeCharacter=B,window.imgError=k,window.demoError=w,window.ReconnectButton=C,window.RetryButton=T,window.pickchar=S,window.pickemotion=O,window.toggleaffect=L,window.toggleflip=N,window.toggleshout=H,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.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\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\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\"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),\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\"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\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(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) {\r\n\t\tthis.serv.send(\r\n\t\t\t`MS#chat#${speaking}#${name}#${silent}` +\r\n\t\t\t`#${escapeChat(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#0#0#0#%`\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\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\tpre: 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: args[5],\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\t// flip: 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 += `${args[1]}: ${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\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\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\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}\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 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 = `${this.chars[i].name}`;\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}\r\n\t\tchangeBackground(\"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\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\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 += \"\" + emotes[i].desc + \"\";\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}\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\"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};\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\r\n\t\tthis.bgname = \"gs4\";\r\n\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\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\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\tif (this.chatmsg.content.trim() == \"\") {\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} else {\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"block\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"block\";\r\n\t\t}\r\n\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\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"takethat\",\r\n\t\t\t\t\"3\": \"objection\"\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_char\").src = AO_HOST + \"misc/\" + shout + \".gif\";\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 800;\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.startspeaking = true;\r\n\t\t}\r\n\r\n\t\tif (this.textTimer >= this.shoutTimer) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\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.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 = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\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\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 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);\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 (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\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 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 image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\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 * 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 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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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"],"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","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","window","trim","hash","charCodeAt"],"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 = 65;\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 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\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\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\"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),\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\"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\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(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, 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(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\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\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: args[5],\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 += `${args[1]}: ${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\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\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\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}\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 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 = `${this.chars[i].name}`;\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}\r\n\t\tchangeBackground(\"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\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\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 += \"\" + emotes[i].desc + \"\";\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}\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\r\n\t\tthis.bgname = \"gs4\";\r\n\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}\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\tconsole.log(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 * 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 */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\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\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\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 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\t\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 = AO_HOST + \"misc/\" + shout + \".gif\";\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 = \"\";\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\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 = \"\";\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 = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\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 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, 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 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 image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\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 * 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 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 * 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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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"],"sourceRoot":""} \ No newline at end of file diff --git a/webAO/client.css b/webAO/client.css index dce841e..5f04c39 100644 --- a/webAO/client.css +++ b/webAO/client.css @@ -174,6 +174,22 @@ img { left: 0; } +#client_shout { + position: absolute; + height: 100%; + width: 100%; + bottom: 0; + left: 0; +} + +#client_background { + position: absolute; + background-color: transparent; + width:100%; + height:auto; + padding-bottom: 75%; +} + #client_name { display: none; height: 7%; diff --git a/webAO/client.html b/webAO/client.html index 0d32c73..8c54a77 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -5,6 +5,7 @@ + @@ -14,15 +15,17 @@ diff --git a/webAO/client.js b/webAO/client.js index 84bd9bd..76ced68 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -26,6 +26,7 @@ if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phon oldLoading = true; } +let selectedEffect = 0; let selectedShout = 0; let lastICMessageTime = new Date(0); @@ -37,6 +38,8 @@ class Client { this.serv.onclose = (evt) => this.onClose(evt); this.serv.onmessage = (evt) => this.onMessage(evt); this.serv.onerror = (evt) => this.onError(evt); + + this.flip = false; this.playerID = 1; this.charID = -1; @@ -111,11 +114,11 @@ class Client { * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect * @param {string} objection the number of the shout to play */ - sendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection) { + sendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, flip, flash, color) { this.serv.send( `MS#chat#${speaking}#${name}#${silent}` + `#${escapeChat(message)}#${side}#${ssfxname}#${zoom}` + - `#${this.charID}#${ssfxdelay}#${selectedShout}#0#0#0#0#%` + `#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%` ); } @@ -243,7 +246,7 @@ class Client { if (args[4] != viewport.chatmsg.content) { document.getElementById("client_inner_chat").innerHTML = ""; let chatmsg = { - pre: escape(args[2]), + // pre: escape(args[2]), character: -1, // Will do a linear search preanim: escape(args[2]), // XXX: why again? nameplate: args[3], // TODO: parse INI to get this info @@ -258,7 +261,7 @@ class Client { snddelay: args[10], objection: args[11], evidence: args[12], - // flip: args[13], + flip: args[13], flash: args[14], color: args[15], isnew: true, @@ -569,10 +572,12 @@ class Viewport { "content": "", "objection": "0", "sound": "", + "startpreanim": false, "startspeaking": false, "side": null, "color": "0", - "snddelay": 0 + "snddelay": 0, + "preanimdelay": 0 }; this.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav'); this.blip.volume = 0.5; @@ -641,7 +646,61 @@ class Viewport { this.textTimer = 0; this._animating = true; clearTimeout(this.updater); - this.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL); + //If preanim existed then determine the length + if (chatmsg.preanim != "-") { + chatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater); + } else { + this.initUpdater(0) + } + } + + /** + * Intialize updater + * @param {int} animdelay the length of pre-animation + */ + initUpdater(animdelay){ + console.log(animdelay); + viewport.chatmsg.preanimdelay = parseInt(animdelay); + viewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL); + } + + /** + * Gets animation length. + * @param {string} filename the animation file name + * @param {function} callback the callback function + */ + getAnimLength(filename,callback) { + //Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA + var request = new XMLHttpRequest(); + request.open('GET', filename, true); + request.responseType = 'arraybuffer'; + request.addEventListener('load', function () { + var arr = new Uint8Array(request.response), + // Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/ + // And http://www.w3.org/Graphics/GIF/spec-gif89a.txt + bin = '', + duration = 0; + + for (var i = 0; i < arr.length; i++) { + bin += String.fromCharCode( arr[i] ) + + // Find a Graphic Control Extension hex(21F904__ ____ __00) + if (arr[i] == 0x21 + && arr[i + 1] == 0xF9 + && arr[i + 2] == 0x04 + && arr[i + 7] == 0x00) { + // Swap 5th and 6th bytes to get the delay per frame + let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF) + + // Should be aware browsers have a minimum frame delay + // e.g. 6ms for IE, 2ms modern browsers (50fps) + duration += delay < 2 ? 10 : (delay+2) + } + } + // Return animation length + callback(duration * 10); + }); + request.send(); } /** @@ -650,41 +709,78 @@ class Viewport { * XXX: This relies on a global variable `this.chatmsg`! */ updateText() { - if (this.chatmsg.content.trim() == "") { - document.getElementById("client_name").style.display = "none"; - document.getElementById("client_chat").style.display = "none"; + // Flip the character + if (this.chatmsg.flip == 1){ + document.getElementById("client_char").style.transform = "scaleX(-1)"; } else { - document.getElementById("client_name").style.display = "block"; - document.getElementById("client_chat").style.display = "block"; + document.getElementById("client_char").style.transform = "scaleX(1)"; } - + if (this._animating) { this.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL); } if (this.chatmsg.isnew) { + // Reset screen background + document.getElementById("client_background").style.backgroundColor = "transparent"; + //Hide message window + document.getElementById("client_name").style.display = "none"; + document.getElementById("client_chat").style.display = "none"; + const shouts = { "1": "holdit", - "2": "takethat", - "3": "objection" + "2": "objection", + "3": "takethat" }; let shout = shouts[this.chatmsg.objection]; if (typeof shout !== "undefined") { - document.getElementById("client_char").src = AO_HOST + "misc/" + shout + ".gif"; + document.getElementById("client_shout").src = AO_HOST + "misc/" + shout + ".gif"; (new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play(); - this.shoutTimer = 800; + this.shoutTimer = 850; } else { this.shoutTimer = 0; } this.chatmsg.isnew = false; - this.chatmsg.startspeaking = true; + this.chatmsg.startpreanim = true; } - if (this.textTimer >= this.shoutTimer) { - if (this.chatmsg.startspeaking) { + if(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) { + // Effect stuff + if (this.chatmsg.flash == 2){ + //Shake screen + this.sfxaudio.pause(); + this.sfxplayed = 1; + this.sfxaudio.src = AO_HOST + "sounds/general/sfx-stab.wav"; + this.sfxaudio.play(); + $('#client_gamewindow').effect( "shake",{"direction":"up"}); + } else if (this.chatmsg.flash == 1) { + //Flash screen + document.getElementById("client_background").style.backgroundColor = "white"; + this.sfxaudio.pause(); + this.sfxplayed = 1; + this.sfxaudio.src = AO_HOST + "sounds/general/sfx-realization.wav"; + this.sfxaudio.play(); + $('#client_gamewindow').effect("pulsate"); + } + + //Pre-animation stuff + if(this.chatmsg.preanimdelay > 0){ + document.getElementById("client_shout").src = ""; changeBackground(this.chatmsg.side); + document.getElementById("client_char").src = AO_HOST + "characters/" + escape(this.chatmsg.name) + "/" + this.chatmsg.preanim + ".gif"; + } + this.chatmsg.startpreanim = false; + this.chatmsg.startspeaking = true; + } else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) { + if (this.chatmsg.startspeaking) { + $("#client_name").toggle( "fade" ); + $("#client_chat").toggle("drop",{"direction":"down"}); + if(this.chatmsg.preanimdelay == 0){ + document.getElementById("client_shout").src = ""; + changeBackground(this.chatmsg.side); + } document.getElementById("client_char").src = AO_HOST + "characters/" + escape(this.chatmsg.name) + "/" + this.chatmsg.speaking + ".gif"; document.getElementById("client_name").style.fontSize = (document.getElementById("client_name").offsetHeight * 0.7) + "px"; document.getElementById("client_chat").style.fontSize = (document.getElementById("client_chat").offsetHeight * 0.25) + "px"; @@ -726,6 +822,7 @@ class Viewport { } } } + if (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) { this.sfxaudio.pause(); this.sfxplayed = 1; @@ -790,13 +887,15 @@ export function onEnter(event) { if (event.keyCode == 13) { let mychar = client.me(); let myemo = client.myEmote(); + let myflip = ((client.flip)? 1:0); + let mycolor = document.getElementById("textcolor").value; let ssfxname = "0"; let ssfxdelay = "0"; if (document.getElementById("sendsfx").checked) { ssfxname = myemo.sfx; ssfxdelay = myemo.sfxdelay; } - client.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById("client_inputbox").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout); + client.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById("client_inputbox").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myflip, selectedEffect, mycolor); } } window.onEnter = onEnter; @@ -808,10 +907,14 @@ window.onEnter = onEnter; */ function resetICParams() { document.getElementById("client_inputbox").value = ""; + if (selectedEffect) { + document.getElementById("button_effect_" + selectedEffect).className = "client_button"; + selectedEffect = 0; + } if (selectedShout) { document.getElementById("button_" + selectedShout).className = "client_button"; selectedShout = 0; - } + } } /** @@ -1024,6 +1127,38 @@ export function pickemotion(emo) { } window.pickemotion = pickemotion; +/** + * Highlights and selects an effect for in-character chat. + * If the same effect button is selected, then the effect is canceled. + * @param {string} effect the new effect to be selected + */ +export function toggleaffect(effect) { + if (effect == selectedEffect) { + document.getElementById("button_effect_" + effect).className = "client_button"; + selectedEffect = 0; + } else { + document.getElementById("button_effect_" + effect).className = "client_button dark"; + if (selectedEffect) { + document.getElementById("button_effect_" + selectedEffect).className = "client_button"; + } + selectedEffect = effect; + } +} +window.toggleaffect = toggleaffect; + +/** + * Toggle flip for in-character chat. + */ +export function toggleflip() { + if (client.flip) { + document.getElementById("button_flip").className = "client_button"; + } else { + document.getElementById("button_flip").className = "client_button dark"; + } + client.flip = !client.flip; +} +window.toggleflip = toggleflip; + /** * Highlights and selects a shout for in-character chat. * If the same shout button is selected, then the shout is canceled. diff --git a/webAO/misc/flash.png b/webAO/misc/flash.png new file mode 100644 index 0000000..acbcdb8 Binary files /dev/null and b/webAO/misc/flash.png differ diff --git a/webAO/misc/flip.png b/webAO/misc/flip.png new file mode 100644 index 0000000..bfe2929 Binary files /dev/null and b/webAO/misc/flip.png differ diff --git a/webAO/misc/shake.png b/webAO/misc/shake.png new file mode 100644 index 0000000..1a51968 Binary files /dev/null and b/webAO/misc/shake.png differ -- cgit From 93c2650aac8a12797701d8ca6002db560d7b4529 Mon Sep 17 00:00:00 2001 From: Qube Date: Wed, 18 Jul 2018 23:12:29 +0700 Subject: Add client side encoding-decoding option (Unicode Escape and UTF-16 Array) --- webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.html | 15 +++++++++++++ webAO/client.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/webAO/client.b.js b/webAO/client.b.js index 5d762e5..b74c947 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 s=t[i]={i:i,l:!1,exports:{}};return e[i].call(s.exports,s,s.exports,n),s.l=!0,s.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 s in e)n.d(i,s,function(t){return e[t]}.bind(null,s));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;nt.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=j.music;(t.pause(),t.src=r+e[1],t.play(),e[2]>=0)?M(this.chars[e[2]].name+" changed music to "+e[1]):M("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){j.music.pause(),j.music=new Audio(this.musicList[e[1]]);var t=j.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",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}x("def")}},{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;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,s=f.parse(i);t.side=s.Options.side;for(var c=1;c"}O(1)}},i.send()}}]),e}(),p=function(){function e(){s(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.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="",x(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){$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="",x(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="

"+function(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}(this.chatmsg.nameplate)+"

";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+65}}]),e}(),f=function(){function e(){s(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 s=e.match(t.param);i?n[i][s[1]]=s[2]:n[s[1]]=s[2]}else if(t.section.test(e)){var c=e.match(t.section);n[c[1]]={},i=c[1]}}),n}}]),e}();function y(e){13==e.keyCode&&(P.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function v(e){if(13==e.keyCode){var t=P.me(),n=P.myEmote(),i=P.flip?1:0,s=document.getElementById("textcolor").value,c="0",o="0";document.getElementById("sendsfx").checked&&(c=n.sfx,o=n.sfxdelay),P.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,c,n.zoom,o,h,i,d,s)}}function _(e){var t=document.getElementById("client_musiclist").value;P.sendMusicChange(t)}function E(){j.music.volume=document.getElementById("client_mvolume").value/100}function I(){j.sfxaudio.volume=document.getElementById("client_svolume").value/100}function b(){j.setBlipVolume(document.getElementById("client_bvolume").value/100)}function B(e){P.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function k(e){return e.onerror="",e.src="/misc/placeholder.gif",!0}function w(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function x(e){var t,n=j.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",document.getElementById("client_bench").src=n+"defensedesk.png",t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"prosecutiondesk.png",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==j.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=l+"themes/default/"+t+"_speedlines.gif")}function C(){P.cleanup(),(P=new g(o))&&(a="join",document.getElementById("client_error").style.display="none")}function T(){P.joinServer()}function M(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"),s=document.createElement("span");if(s.id="iclog_name",s.appendChild(document.createTextNode(t)),i.appendChild(s),i.appendChild(document.createTextNode(e)),m.getMinutes()!==n.getMinutes()){var c=document.createElement("span");c.id="iclog_time",c.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(c)}var o=document.getElementById("client_log");o.appendChild(i),o.scrollTop>o.scrollHeight-600&&(o.scrollTop=o.scrollHeight),m=new Date}function S(e){e<1e3?P.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function O(e){-1!=P.selectedEmote&&(document.getElementById("emo_"+P.selectedEmote).src=P.myEmote().button_off),P.selectedEmote=e,document.getElementById("emo_"+e).src=P.myEmote().button_on}function L(e){e==d?(document.getElementById("button_effect_"+e).className="client_button",d=0):(document.getElementById("button_effect_"+e).className="client_button dark",d&&(document.getElementById("button_effect_"+d).className="client_button"),d=e)}function N(){P.flip?document.getElementById("button_flip").className="client_button":document.getElementById("button_flip").className="client_button dark",P.flip=!P.flip}function H(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 D(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}window.onOOCEnter=y,window.onEnter=v,window.musiclist_click=_,window.changeMusicVolume=E,window.changeSFXVolume=I,window.changeBlipVolume=b,window.changeCharacter=B,window.imgError=k,window.demoError=w,window.ReconnectButton=C,window.RetryButton=T,window.pickchar=S,window.pickemotion=O,window.toggleaffect=L,window.toggleflip=N,window.toggleshout=H,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;et.scrollHeight-60&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=V.music;(t.pause(),t.src=l+e[1],t.play(),e[2]>=0)?M(this.chars[e[2]].name+" changed music to "+e[1]):M("The music was changed to "+e[1])}},{key:"handleRMC",value:function(e){V.music.pause(),V.music=new Audio(this.musicList[e[1]]);var t=V.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",n.appendChild(i),t%8==0&&document.getElementById("client_chartable").appendChild(n)}C("def")}},{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;i.open("GET",r+"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;for(var s=1;s"}O(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(r+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var t=0;t=this.shoutTimer&&this.chatmsg.startpreanim)2==this.chatmsg.flash?(this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=r+"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=r+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(document.getElementById("client_shout").src="",C(this.chatmsg.side),document.getElementById("client_char").src=r+"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){$("#client_name").toggle("fade"),$("#client_chat").toggle("drop",{direction:"down"}),0==this.chatmsg.preanimdelay&&(document.getElementById("client_shout").src="",C(this.chatmsg.side)),document.getElementById("client_char").src=r+"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="

"+function(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}(this.chatmsg.nameplate)+"

";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=r+"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=r+"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=r+"sounds/general/"+escape(this.chatmsg.sound)+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+65}}]),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 y(e){13==e.keyCode&&(R.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function v(e){if(13==e.keyCode){var t=R.me(),n=R.myEmote(),i=R.flip?1:0,c=document.getElementById("textcolor").value,s="0",o="0";document.getElementById("sendsfx").checked&&(s=n.sfx,o=n.sfxdelay),R.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,s,n.zoom,o,h,i,d,c)}}function _(e){var t=document.getElementById("client_musiclist").value;R.sendMusicChange(t)}function E(){V.music.volume=document.getElementById("client_mvolume").value/100}function I(){V.sfxaudio.volume=document.getElementById("client_svolume").value/100}function b(){V.setBlipVolume(document.getElementById("client_bvolume").value/100)}function B(e){R.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function k(e){return e.onerror="",e.src="/misc/placeholder.gif",!0}function w(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function C(e){var t,n=V.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",document.getElementById("client_bench").src=n+"defensedesk.png",t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",document.getElementById("client_bench").src=n+"prosecutiondesk.png",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==V.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=r+"themes/default/"+t+"_speedlines.gif")}function x(){R.cleanup(),(R=new g(o))&&(a="join",document.getElementById("client_error").style.display="none")}function T(){R.joinServer()}function M(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)),m.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),m=new Date}function S(e){e<1e3?R.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function O(e){-1!=R.selectedEmote&&(document.getElementById("emo_"+R.selectedEmote).src=R.myEmote().button_off),R.selectedEmote=e,document.getElementById("emo_"+e).src=R.myEmote().button_on}function L(e){e==d?(document.getElementById("button_effect_"+e).className="client_button",d=0):(document.getElementById("button_effect_"+e).className="client_button dark",d&&(document.getElementById("button_effect_"+d).className="client_button"),d=e)}function N(){R.flip?document.getElementById("button_flip").className="client_button":document.getElementById("button_flip").className="client_button dark",R.flip=!R.flip}function H(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 D(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function A(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(/\/g,"$")}function P(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 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\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\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\"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),\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\"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\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(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, 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(message)}#${side}#${ssfxname}#${zoom}` +\r\n\t\t\t`#${this.charID}#${ssfxdelay}#${selectedShout}#0#${flip}#${flash}#${color}#%`\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\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: args[5],\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 += `${args[1]}: ${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\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\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\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}\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 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 = `${this.chars[i].name}`;\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}\r\n\t\tchangeBackground(\"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\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\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 += \"\" + emotes[i].desc + \"\";\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}\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\r\n\t\tthis.bgname = \"gs4\";\r\n\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}\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\tconsole.log(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 * 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 */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\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\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\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 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\t\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 = AO_HOST + \"misc/\" + shout + \".gif\";\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 = \"\";\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\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 = \"\";\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 = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\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 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, 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 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 image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\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 * 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 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 * 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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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"],"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","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","toggleaffect","toggleflip","toggleshout","queryDict","location","search","substr","split","forEach","item","serverIP","ip","AO_HOST","asset","MUSIC_HOST","oldLoading","test","navigator","userAgent","selectedEffect","selectedShout","lastICMessageTime","Date","Client","address","_this","this","_classCallCheck","serv","WebSocket","onopen","evt","onOpen","onclose","onClose","onmessage","onMessage","onerror","onError","flip","playerID","charID","chars","emotes","selectedEmote","checkUpdater","musicList","handlers","MS","args","handleMS","CT","handleCT","MC","handleMC","RMC","handleRMC","CI","handleCI","SC","handleSC","EI","handleEI","EM","handleEM","SM","handleSM","music","handlemusic","DONE","handleDONE","BN","handleBN","NBG","handleNBG","HP","handleHP","ID","handleID","PN","handlePN","SI","handleSI","CharsCheck","handleCharsCheck","PV","handlePV","CHECK","_lastTimeICReceived","message","send","escapeChat","encodeChat","speaking","silent","side","ssfxname","zoom","ssfxdelay","objection","flash","color","track","_this2","hashCode","setInterval","sendCheck","character","song","e","document","getElementById","style","display","client","joinServer","console","error","reason","code","textContent","cleanup","msg","data","debug","header","handler","warn","close","clearInterval","viewport","chatmsg","content","innerHTML","preanim","escape","nameplate","decodeChat","unescapeChat","sound","type","snddelay","evidence","isnew","length","className","resetICParams","say","oocLog","scrollTop","scrollHeight","pause","src","play","appendICLog","Audio","totime","offset","getTime","addEventListener","currentTime","parseFloat","toFixed","chargs","desc","icon","hmusiclist","newentry","createElement","text","options","add","bgname","clip","tr","td","icon_chosen","thispick","appendChild","changeBackground","me","xhr","XMLHttpRequest","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","sfx","sfxdelay","button_off","button_on","Viewport","textnow","startpreanim","startspeaking","preanimdelay","blip","volume","blipChannels","Array","currentBlipChannel","sfxaudio","sfxplayed","updater","shoutTimer","textTimer","_animating","clearTimeout","getAnimLength","initUpdater","animdelay","log","parseInt","setTimeout","updateText","filename","callback","request","arr","Uint8Array","response","duration","String","fromCharCode","delay","_this3","transform","backgroundColor","shout","1","2","3","$","effect","direction","toggle","fontSize","offsetHeight","unsafe","replace","escapeHtml","stylecolor","0","4","5","6","charAt","substring","regex","section","param","comment","line","match","event","keyCode","sendOOC","mychar","myemo","myEmote","myflip","mycolor","checked","sendIC","playtrack","sendMusicChange","setBlipVolume","sendLeaveRoom","image","position","standname","bgfolder","bgFolder","toadd","arguments","undefined","time","entry","nameField","id","createTextNode","getMinutes","timeStamp","innerText","toLocaleTimeString","hour","minute","clientLog","ccharacter","sendCharacter","emo","estring","selectedEncoding","ch","charCodeAt","toString","slice","buffer","ArrayBuffer","result","Uint16Array","strLen","selectedDecoding","group","apply","window","trim","hash"],"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 = 65;\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 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\r\n\t\tthis.playerID = 1;\r\n\t\tthis.charID = -1;\r\n\r\n\t\tthis.chars = [];\r\n\t\tthis.emotes = [];\r\n\r\n\t\tthis.selectedEmote = -1;\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\"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),\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\"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\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, 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}#0#${flip}#${flash}#${color}#%`\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\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: decodeChat(unescapeChat(args[5])),\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\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\");\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\tnewentry.text = args[i];\r\n\t\t\thmusiclist.options.add(newentry);\r\n\t\t}\r\n\t\tthis.serv.send(\"RD#%\");\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}\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 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 = `${this.chars[i].name}`;\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}\r\n\t\tchangeBackground(\"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\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\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 += \"\" + emotes[i].desc + \"\";\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}\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\r\n\t\tthis.bgname = \"gs4\";\r\n\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}\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\tconsole.log(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 * 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 */\r\n\tgetAnimLength(filename,callback) {\r\n\t\t//Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA\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\tvar arr = new Uint8Array(request.response),\r\n\t\t\t// Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\r\n\t\t\t// And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\r\n\t\t\tbin = '', \r\n\t\t\tduration = 0;\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arr.length; i++) {\t\t\t\t\r\n\t\t\t\tbin += String.fromCharCode( arr[i] )\r\n\r\n\t\t\t\t// Find a Graphic Control Extension hex(21F904__ ____ __00)\r\n\t\t\t\tif (arr[i] == 0x21 \r\n\t\t\t\t && arr[i + 1] == 0xF9 \r\n\t\t\t\t && arr[i + 2] == 0x04 \r\n\t\t\t\t && arr[i + 7] == 0x00) {\r\n\t\t\t\t // Swap 5th and 6th bytes to get the delay per frame\r\n\t\t\t\t let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF)\r\n\t\t\t\t \r\n\t\t\t\t // Should be aware browsers have a minimum frame delay \r\n\t\t\t\t // e.g. 6ms for IE, 2ms modern browsers (50fps)\r\n\t\t\t\t duration += delay < 2 ? 10 : (delay+2)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(duration * 10);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\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 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\t\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 = AO_HOST + \"misc/\" + shout + \".gif\";\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 = \"\";\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\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 = \"\";\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 = \"

\" + escapeHtml(this.chatmsg.nameplate) + \"

\";\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 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, 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 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 image exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n */\r\nfunction ImageExist(url) {\r\n\tvar img = new Image();\r\n\timg.src = url;\r\n\treturn img.height != 0;\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\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\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\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 * 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 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 * 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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(/\\/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// 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"],"sourceRoot":""} \ No newline at end of file diff --git a/webAO/client.html b/webAO/client.html index 8c54a77..4c34982 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -61,6 +61,21 @@ + + - - @@ -158,18 +214,6 @@ - - - -
diff --git a/webAO/client.js b/webAO/client.js index a9e95b5..68d7c7d 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -19,7 +19,7 @@ const MUSIC_HOST = AO_HOST + "sounds/music/"; const BAR_WIDTH = 90; const BAR_HEIGHT = 20; const CHAR_SELECT_WIDTH = 8; -const UPDATE_INTERVAL = 65; +const UPDATE_INTERVAL = 60; let oldLoading = false; if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) { @@ -45,10 +45,36 @@ class Client { 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; @@ -71,9 +97,11 @@ class Client { "SM": (args) => this.handleSM(args), "music": (args) => this.handlemusic(args), "DONE": (args) => this.handleDONE(args), - "BN": (args) => this.handleBN(args), + "BN": (args) => this.handleBN(args), "NBG": (args) => this.handleNBG(args), "HP": (args) => this.handleHP(args), + "RT": (args) => this.handleRT(args), + "ZZ": (args) => this.handleZZ(args), "ID": (args) => this.handleID(args), "PN": (args) => this.handlePN(args), "SI": (args) => this.handleSI(args), @@ -159,9 +187,27 @@ class Client { * Sends delete evidence command. * @param {string} evidence id */ - sendDE(id, name, desc, img) { + sendDE(id) { this.serv.send(`DE#${id}#%`); } + + /** + * Sends call mod command. + * @param {string} message to mod + */ + sendZZ(msg) { + this.serv.send(`ZZ#${msg}#%`); + } + + /** + * Sends testimony command. + * @param {string} testimony type + */ + sendRT(testimony) { + if(this.chars[this.charID].side == "jud"){ + this.serv.send(`RT#${testimony}#%`); + } + } /** * Requests to change the music to the specified track. @@ -207,10 +253,60 @@ class Client { for(let i = 1; i <= background_arr.length; i++) { background_select.add(new Option(background_arr[i - 1])); } + // Calculate gif duration of shouts + let shouts = ["holdit", "objection", "takethat"]; + for (let i = 0; i < shouts.length; i++) { + let shout_src = AO_HOST + this.resources[shouts[i]]["src"]; + FileExist(shout_src, this.callbackLoadImageResources, shouts[i]); + } + + // Calculate gif duration of testimony + let testimony = ["witnesstestimony", "crossexamination"]; + for (let i = 0; i < testimony.length; i++) { + let testimony_src = AO_HOST + "themes/default/"+ testimony[i] +".gif"; + // Check iamge existed + FileExist(testimony_src, this.callbackLoadImageResources, testimony[i]); + // Check sfx existed + FileExist(AO_HOST + this.resources[testimony[i]]["sfx"], this.callbackLoadSFXResources, testimony[i]); + } // TODO: Cache some resources } + /** + * Callback for image resources. + * @param {boolean} result the image is existed or not + * @param {string} resource the resource name + * @param {string} src the url of resource + */ + callbackLoadImageResources(result, resource, src) { + if(result){ + client.resources[resource]["src"] = src; + viewport.getAnimLength(src,client.callbackGetResourceLength, resource); + } + } + + /** + * Callback for animation duration resource + * @param {integer} length the animation length + * @param {string} resource the resource name + */ + callbackGetResourceLength(length, resource) { + client.resources[resource]["duration"] = length; + } + + /** + * Callback for sfx resources. + * @param {boolean} result the audio is existed or not + * @param {string} resource the resource name + * @param {string} src the url of resource + */ + callbackLoadSFXResources(result, resource, src) { + if(result){ + client.resources[resource]["sfx"] = src; + } + } + /** * Create observer to detect BBCode elements * then manipulate them. @@ -594,7 +690,12 @@ class Client { document.getElementById("bg_filename").value = args[1]; } document.getElementById("bg_preview").src = AO_HOST + 'background/' + escape(args[1]) + "/defenseempty.png"; - + if(this.charID == -1){ + changeBackground("jud"); + } else { + changeBackground(this.chars[this.charID].side); + } + } handleNBG(args) { @@ -615,6 +716,47 @@ class Client { } } + /** + * Handles a testimony states. + * @param {Array} args packet arguments + */ + handleRT(args) { + if (args[1] == "testimony1") { + //Witness Testimony + this.testimonyID = 1; + } else { + //Cross Examination + this.testimonyID = 2; + } + viewport.initTestimonyUpdater(); + } + + /** + * Handles a call mod message. + * @param {Array} args packet arguments + */ + handleZZ(args) { + const oocLog = document.getElementById("client_ooclog"); + oocLog.innerHTML += `\$Alert: ${decodeChat(unescapeChat(args[1]))}\r\n`; + if (oocLog.scrollTop > oocLog.scrollHeight - 60) { + oocLog.scrollTop = oocLog.scrollHeight; + } + } + + /** + * 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 @@ -665,8 +807,8 @@ class Client { if (i % CHAR_SELECT_WIDTH == 0) { document.getElementById("client_chartable").appendChild(tr); } - } - changeBackground("def"); + } + //changeBackground("def"); } /** @@ -679,6 +821,7 @@ class Client { let me = this.me(); let emotes = this.emotes; let xhr = new XMLHttpRequest(); + document.getElementById("client_emo").innerHTML = ""; // Clear emote box xhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true); xhr.responseType = 'text'; xhr.onload = function (e) { @@ -686,6 +829,7 @@ class Client { let linifile = this.responseText; let pinifile = INI.parse(linifile); me.side = pinifile.Options.side; + updateActionCommands(me.side); for (let i = 1; i < pinifile.Emotions.number; i++) { let emoteinfo = pinifile.Emotions[i].split('#'); let esfx = "0"; @@ -750,9 +894,11 @@ class Viewport { this.music.play(); this.updater = null; + this.testimonyUpdater = null; this.bgname = "gs4"; - + + this.testimonyTimer = 0; this.shoutTimer = 0; this.textTimer = 0; @@ -802,7 +948,7 @@ class Viewport { chatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater); } else { this.initUpdater(0) - } + } } /** @@ -814,45 +960,83 @@ class Viewport { viewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL); } + /** + * Intialize testimony updater + */ + initTestimonyUpdater(){ + if(client.testimonyID > 0){ + let testimony = ""; + if (client.testimonyID == 1) { + testimony = "witnesstestimony"; + } else if (client.testimonyID == 2) { + testimony = "crossexamination"; + } + (new Audio(client.resources[testimony]["sfx"])).play(); + this.testimonyTimer = 0; + document.getElementById("client_testimony").src = client.resources[testimony]["src"]; + this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); + } + } + /** * Gets animation length. * @param {string} filename the animation file name * @param {function} callback the callback function + * @param {object} param */ - getAnimLength(filename,callback) { - //Source (Thanks to Ryman): https://codepen.io/Ryman/pen/wzioA + getAnimLength(filename, callback, param) { var request = new XMLHttpRequest(); request.open('GET', filename, true); request.responseType = 'arraybuffer'; request.addEventListener('load', function () { - var arr = new Uint8Array(request.response), - // Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/ - // And http://www.w3.org/Graphics/GIF/spec-gif89a.txt - bin = '', - duration = 0; - - for (var i = 0; i < arr.length; i++) { - bin += String.fromCharCode( arr[i] ) - - // Find a Graphic Control Extension hex(21F904__ ____ __00) - if (arr[i] == 0x21 - && arr[i + 1] == 0xF9 - && arr[i + 2] == 0x04 - && arr[i + 7] == 0x00) { - // Swap 5th and 6th bytes to get the delay per frame - let delay = (arr[i + 5] << 8) | (arr[i + 4] & 0xFF) - - // Should be aware browsers have a minimum frame delay - // e.g. 6ms for IE, 2ms modern browsers (50fps) - duration += delay < 2 ? 10 : (delay) - } - } + // Use gify API + // https://github.com/rfrench/gify + var gifInfo = gify.getInfo(request.response); + console.log(gifInfo["duration"]); // Return animation length - callback(duration * 10); + callback(gifInfo["duration"], param); }); request.send(); } - + + /** + * Updates the testimony overaly + */ + updateTestimony(){ + //Update timer + this.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL; + + if (client.testimonyID == 1) { + //Witness Testimony + if (this.testimonyTimer >= client.resources["witnesstestimony"]["duration"]){ + //Finish + this.disposeTestimony(); + } else { + this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); + } + } else if (client.testimonyID == 2) { + //Cross Examination + if (this.testimonyTimer >= client.resources["crossexamination"]["duration"]){ + //Finish + this.disposeTestimony(); + } else { + this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); + } + } else { + this.disposeTestimony(); + } + } + + /** + * Dispose the testimony overlay + */ + disposeTestimony(){ + client.testimonyID = 0; + this.testimonyTimer = 0; + document.getElementById("client_testimony").src = "misc/placeholder.gif"; + clearTimeout(this.testimonyUpdater); + } + /** * Updates the chatbox based on the given text. * @@ -886,7 +1070,7 @@ class Viewport { let shout = shouts[this.chatmsg.objection]; if (typeof shout !== "undefined") { - document.getElementById("client_shout").src = AO_HOST + "misc/" + shout + ".gif"; + document.getElementById("client_shout").src = client.resources[shout]["src"]; (new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play(); this.shoutTimer = 850; } else { @@ -1169,13 +1353,22 @@ export function demoError(image) { window.demoError = demoError; /** - * Checks if an image exists at the specified URI. + * Checks if an file exists at the specified URI. * @param {string} url the URI to be checked + * @param {function} callback the function to be called when finished + * @param {object} param */ -function ImageExist(url) { - var img = new Image(); - img.src = url; - return img.height != 0; +function FileExist(url,callback,param) { + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + callback(true, param, url); + } else { + callback(false, param, url); + } + }; + xhttp.open("GET", url, true); + xhttp.send(); } /** @@ -1193,21 +1386,13 @@ function changeBackground(position) { case "def": document.getElementById("client_court").src = bgfolder + "defenseempty.png" document.getElementById("client_bench").style.display = "block"; - if(ImageExist(bgfolder + "defensedesk.png")){ - document.getElementById("client_bench").src = bgfolder + "defensedesk.png" - }else{ - document.getElementById("client_bench").src = bgfolder + "bancodefensa.png" - } + FileExist(bgfolder + "defensedesk.png", callbackChangeBackground, position); standname = "defense"; break; case "pro": document.getElementById("client_court").src = bgfolder + "prosecutorempty.png" document.getElementById("client_bench").style.display = "block" - if(ImageExist(bgfolder + "defensedesk.png")){ - document.getElementById("client_bench").src = bgfolder + "prosecutiondesk.png" - } else { - document.getElementById("client_bench").src = bgfolder + "bancoacusacion.png" - } + FileExist(bgfolder + "defensedesk.png", callbackChangeBackground, position); standname = "prosecution"; break; case "hld": @@ -1235,6 +1420,30 @@ function changeBackground(position) { } } +/** + * Callback for desk resource + * + * Valid positions: `def, pro, hld, hlp, wit, jud` + * @param {boolean} result the image is existed or not + * @param {string} position the position to change into + */ +function callbackChangeBackground(result,position) { + let bgfolder = viewport.bgFolder(); + if (position == "def"){ + if(result){ + document.getElementById("client_bench").src = bgfolder + "defensedesk.png" + }else{ + document.getElementById("client_bench").src = bgfolder + "bancodefensa.png" + } + } else { + if(result){ + document.getElementById("client_bench").src = bgfolder + "prosecutiondesk.png" + } else { + document.getElementById("client_bench").src = bgfolder + "bancoacusacion.png" + } + } +} + /** * Triggered when the reconnect button is pushed. */ @@ -1459,7 +1668,28 @@ export function updateEvidenceIcon() { window.updateEvidenceIcon = updateEvidenceIcon; /** - * Change background. + * Update evidence icon. + */ +export function updateActionCommands(side) { + if(side == "jud"){ + document.getElementById("menu_wt").style.display = "inline-table"; + document.getElementById("menu_ce").style.display = "inline-table"; + } else { + document.getElementById("menu_wt").style.display = "none"; + document.getElementById("menu_ce").style.display = "none"; + } + //Update role selector + for(let i = 0, role_select = document.getElementById("role_select").options; i < role_select.length; i++){ + if(side == role_select[i].value){ + role_select.selectedIndex = i; + return; + } + } +} +window.updateActionCommands = updateActionCommands; + +/** + * Change background via OOC. */ export function changeBackgroundOOC() { let filename = "", background_select = document.getElementById("bg_select") @@ -1473,6 +1703,50 @@ export function changeBackgroundOOC() { } window.changeBackgroundOOC = changeBackgroundOOC; +/** + * Change role via OOC. + */ +export function changeRoleOOC() { + let role_select = document.getElementById("role_select") + , role_command = document.getElementById("role_command").value; + + client.sendOOC("/" + role_command.replace("$1",role_select.value)); + updateActionCommands(role_select.value); +} +window.changeRoleOOC = changeRoleOOC; + +/** + * Random character via OOC. + */ +export function randomCharacterOOC() { + client.sendOOC("/" + document.getElementById("randomchar_command").value); +} +window.randomCharacterOOC = randomCharacterOOC; + +/** + * Call mod. + */ +export function callmod() { + client.sendZZ(""); +} +window.callmod = callmod; + +/** + * Decalre witness testimony. + */ +export function initwt() { + client.sendRT("testimony1"); +} +window.initwt = initwt; + +/** + * Decalre cross examination. + */ +export function initce() { + client.sendRT("testimony2"); +} +window.initce = initce; + /** * Update background preview. */ diff --git a/webAO/lib/gify.min.js b/webAO/lib/gify.min.js new file mode 100644 index 0000000..8656d4a --- /dev/null +++ b/webAO/lib/gify.min.js @@ -0,0 +1 @@ +var gify=function(){"use strict";function t(t){return 3*Math.pow(2,1+a(t.slice(5,8)))}function e(t){for(var e=[],i=7;i>=0;i--)e.push(t&1<S&&!s.isBrowserDuration&&(s.isBrowserDuration=!0),p.delay=S,s.duration+=S,s.durationIE+=60>S?l:S,s.durationSafari+=20>S?l:S,s.durationChrome+=20>S?l:S,s.durationFirefox+=20>S?l:S,s.durationOpera+=20>S?l:S;var f=e(d.getUint8(u+3)),C=f.slice(3,6).join("");p.disposal=parseInt(C,2),u+=8}else u++}else{u+=2;var k=r(d,u,!0);switch(z){case 255:var y=d.getString(8,u+1);"NETSCAPE"===y&&(s.loopCount=d.getUint8(u+14,!0));break;case 206:p.identifier=k.data;break;case 254:p.comments.push(k.data);break;case 1:p.text=k.data}u+=k.size}break;case 44:p.left=d.getUint16(u+1,!0),p.top=d.getUint16(u+3,!0),p.width=d.getUint16(u+5,!0),p.height=d.getUint16(u+7,!0);var f=e(d.getUint8(u+9,!0));if(f[0]){var B=t(f);p.localPalette=!0,p.localPaletteSize=B/3,u+=B}if(f[1]&&(p.interlace=!0),s.images.push(p),g++,p=n(),p.identifier=g.toString(),s.images.length>1&&!s.animated&&(s.animated=!0,o))return s;u+=11;var k=r(d,u,!1);u+=k.size;break;case 59:return s;default:u++}}catch(x){return s.valid=!1,s}if(u>=a.byteLength)return s}return s}var l=100;return{isAnimated:function(t){var e=o(t,!0);return e.animated},getInfo:function(t){return o(t,!1)}}}(); \ No newline at end of file diff --git a/webAO/lib/jdataview.min.js b/webAO/lib/jdataview.min.js new file mode 100644 index 0000000..38e31b9 --- /dev/null +++ b/webAO/lib/jdataview.min.js @@ -0,0 +1,50 @@ +(function(global){var compatibility={ArrayBuffer:typeof ArrayBuffer!=='undefined',DataView:typeof DataView!=='undefined'&&('getFloat64'in DataView.prototype||'getFloat64'in new DataView(new ArrayBuffer(1))),NodeBuffer:typeof Buffer!=='undefined'&&'readInt16LE'in Buffer.prototype};var dataTypes={'Int8':1,'Int16':2,'Int32':4,'Uint8':1,'Uint16':2,'Uint32':4,'Float32':4,'Float64':8};var nodeNaming={'Int8':'Int8','Int16':'Int16','Int32':'Int32','Uint8':'UInt8','Uint16':'UInt16','Uint32':'UInt32','Float32':'Float','Float64':'Double'};var jDataView=function(buffer,byteOffset,byteLength,littleEndian){if(!(this instanceof jDataView)){throw new Error("jDataView constructor may not be called as a function");} +this.buffer=buffer;if(!(compatibility.NodeBuffer&&buffer instanceof Buffer)&&!(compatibility.ArrayBuffer&&buffer instanceof ArrayBuffer)&&typeof buffer!=='string'){throw new TypeError('jDataView buffer has an incompatible type');} +this._isArrayBuffer=compatibility.ArrayBuffer&&buffer instanceof ArrayBuffer;this._isDataView=compatibility.DataView&&this._isArrayBuffer;this._isNodeBuffer=compatibility.NodeBuffer&&buffer instanceof Buffer;this._littleEndian=littleEndian===undefined?false:littleEndian;var bufferLength=this._isArrayBuffer?buffer.byteLength:buffer.length;if(byteOffset===undefined){byteOffset=0;} +this.byteOffset=byteOffset;if(byteLength===undefined){byteLength=bufferLength-byteOffset;} +this.byteLength=byteLength;if(!this._isDataView){if(typeof byteOffset!=='number'){throw new TypeError('jDataView byteOffset is not a number');} +if(typeof byteLength!=='number'){throw new TypeError('jDataView byteLength is not a number');} +if(byteOffset<0){throw new Error('jDataView byteOffset is negative');} +if(byteLength<0){throw new Error('jDataView byteLength is negative');}} +if(this._isDataView){this._view=new DataView(buffer,byteOffset,byteLength);this._start=0;} +this._start=byteOffset;if(byteOffset+byteLength>bufferLength){throw new Error("jDataView (byteOffset + byteLength) value is out of bounds");} +this._offset=0;if(this._isDataView){for(var type in dataTypes){if(!dataTypes.hasOwnProperty(type)){continue;} +(function(type,view){var size=dataTypes[type];view['get'+type]=function(byteOffset,littleEndian){if(littleEndian===undefined){littleEndian=view._littleEndian;} +if(byteOffset===undefined){byteOffset=view._offset;} +view._offset=byteOffset+size;return view._view['get'+type](byteOffset,littleEndian);}})(type,this);}}else if(this._isNodeBuffer&&compatibility.NodeBuffer){for(var type in dataTypes){if(!dataTypes.hasOwnProperty(type)){continue;} +var name;if(type==='Int8'||type==='Uint8'){name='read'+nodeNaming[type];}else if(littleEndian){name='read'+nodeNaming[type]+'LE';}else{name='read'+nodeNaming[type]+'BE';} +(function(type,view,name){var size=dataTypes[type];view['get'+type]=function(byteOffset,littleEndian){if(littleEndian===undefined){littleEndian=view._littleEndian;} +if(byteOffset===undefined){byteOffset=view._offset;} +view._offset=byteOffset+size;return view.buffer[name](view._start+byteOffset);}})(type,this,name);}}else{for(var type in dataTypes){if(!dataTypes.hasOwnProperty(type)){continue;} +(function(type,view){var size=dataTypes[type];view['get'+type]=function(byteOffset,littleEndian){if(littleEndian===undefined){littleEndian=view._littleEndian;} +if(byteOffset===undefined){byteOffset=view._offset;} +view._offset=byteOffset+size;if(view._isArrayBuffer&&(view._start+byteOffset)%size===0&&(size===1||littleEndian)){return new global[type+'Array'](view.buffer,view._start+byteOffset,1)[0];}else{if(typeof byteOffset!=='number'){throw new TypeError('jDataView byteOffset is not a number');} +if(byteOffset+size>view.byteLength){throw new Error('jDataView (byteOffset + size) value is out of bounds');} +return view['_get'+type](view._start+byteOffset,littleEndian);}}})(type,this);}}};if(compatibility.NodeBuffer){jDataView.createBuffer=function(){var buffer=new Buffer(arguments.length);for(var i=0;ithis.byteLength){throw new Error('jDataView length or (byteOffset+length) value is out of bounds');} +if(this._isNodeBuffer){value=this.buffer.toString('ascii',this._start+byteOffset,this._start+byteOffset+length);} +else{value='';for(var i=0;i127?65533:char);}} +this._offset=byteOffset+length;return value;},getChar:function(byteOffset){return this.getString(1,byteOffset);},tell:function(){return this._offset;},seek:function(byteOffset){if(typeof byteOffset!=='number'){throw new TypeError('jDataView byteOffset is not a number');} +if(byteOffset<0||byteOffset>this.byteLength){throw new Error('jDataView byteOffset value is out of bounds');} +return this._offset=byteOffset;},_endianness:function(byteOffset,pos,max,littleEndian){return byteOffset+(littleEndian?max-pos-1:pos);},_getFloat64:function(byteOffset,littleEndian){var b0=this._getUint8(this._endianness(byteOffset,0,8,littleEndian)),b1=this._getUint8(this._endianness(byteOffset,1,8,littleEndian)),b2=this._getUint8(this._endianness(byteOffset,2,8,littleEndian)),b3=this._getUint8(this._endianness(byteOffset,3,8,littleEndian)),b4=this._getUint8(this._endianness(byteOffset,4,8,littleEndian)),b5=this._getUint8(this._endianness(byteOffset,5,8,littleEndian)),b6=this._getUint8(this._endianness(byteOffset,6,8,littleEndian)),b7=this._getUint8(this._endianness(byteOffset,7,8,littleEndian)),sign=1-(2*(b0>>7)),exponent=((((b0<<1)&0xff)<<3)|(b1>>4))-(Math.pow(2,10)-1),mantissa=((b1&0x0f)*Math.pow(2,48))+(b2*Math.pow(2,40))+(b3*Math.pow(2,32))+ +(b4*Math.pow(2,24))+(b5*Math.pow(2,16))+(b6*Math.pow(2,8))+b7;if(exponent===1024){if(mantissa!==0){return NaN;}else{return sign*Infinity;}} +if(exponent===-1023){return sign*mantissa*Math.pow(2,-1022-52);} +return sign*(1+mantissa*Math.pow(2,-52))*Math.pow(2,exponent);},_getFloat32:function(byteOffset,littleEndian){var b0=this._getUint8(this._endianness(byteOffset,0,4,littleEndian)),b1=this._getUint8(this._endianness(byteOffset,1,4,littleEndian)),b2=this._getUint8(this._endianness(byteOffset,2,4,littleEndian)),b3=this._getUint8(this._endianness(byteOffset,3,4,littleEndian)),sign=1-(2*(b0>>7)),exponent=(((b0<<1)&0xff)|(b1>>7))-127,mantissa=((b1&0x7f)<<16)|(b2<<8)|b3;if(exponent===128){if(mantissa!==0){return NaN;}else{return sign*Infinity;}} +if(exponent===-127){return sign*mantissa*Math.pow(2,-126-23);} +return sign*(1+mantissa*Math.pow(2,-23))*Math.pow(2,exponent);},_getInt32:function(byteOffset,littleEndian){var b=this._getUint32(byteOffset,littleEndian);return b>Math.pow(2,31)-1?b-Math.pow(2,32):b;},_getUint32:function(byteOffset,littleEndian){var b3=this._getUint8(this._endianness(byteOffset,0,4,littleEndian)),b2=this._getUint8(this._endianness(byteOffset,1,4,littleEndian)),b1=this._getUint8(this._endianness(byteOffset,2,4,littleEndian)),b0=this._getUint8(this._endianness(byteOffset,3,4,littleEndian));return(b3*Math.pow(2,24))+(b2<<16)+(b1<<8)+b0;},_getInt16:function(byteOffset,littleEndian){var b=this._getUint16(byteOffset,littleEndian);return b>Math.pow(2,15)-1?b-Math.pow(2,16):b;},_getUint16:function(byteOffset,littleEndian){var b1=this._getUint8(this._endianness(byteOffset,0,2,littleEndian)),b0=this._getUint8(this._endianness(byteOffset,1,2,littleEndian));return(b1<<8)+b0;},_getInt8:function(byteOffset){var b=this._getUint8(byteOffset);return b>Math.pow(2,7)-1?b-Math.pow(2,8):b;},_getUint8:function(byteOffset){if(this._isArrayBuffer){return new Uint8Array(this.buffer,byteOffset,1)[0];} +else if(this._isNodeBuffer){return this.buffer[byteOffset];}else{return this.buffer.charCodeAt(byteOffset)&0xff;}}};if(typeof jQuery!=='undefined'&&jQuery.fn.jquery>="1.6.2"){var convertResponseBodyToText=function(byteArray){var scrambledStr;try{scrambledStr=IEBinaryToArray_ByteStr(byteArray);}catch(e){var IEBinaryToArray_ByteStr_Script="Function IEBinaryToArray_ByteStr(Binary)\r\n"+" IEBinaryToArray_ByteStr = CStr(Binary)\r\n"+"End Function\r\n"+"Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+" Dim lastIndex\r\n"+" lastIndex = LenB(Binary)\r\n"+" if lastIndex mod 2 Then\r\n"+" IEBinaryToArray_ByteStr_Last = AscB( MidB( Binary, lastIndex, 1 ) )\r\n"+" Else\r\n"+" IEBinaryToArray_ByteStr_Last = -1\r\n"+" End If\r\n"+"End Function\r\n";window.execScript(IEBinaryToArray_ByteStr_Script,'vbscript');scrambledStr=IEBinaryToArray_ByteStr(byteArray);} +var lastChr=IEBinaryToArray_ByteStr_Last(byteArray),result="",i=0,l=scrambledStr.length%8,thischar;while(i>8);} +l=scrambledStr.length +while(i>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8,(thischar=scrambledStr.charCodeAt(i++),thischar&0xff),thischar>>8);} +if(lastChr>-1){result+=String.fromCharCode(lastChr);} +return result;};jQuery.ajaxSetup({converters:{'* dataview':function(data){return new jDataView(data);}},accepts:{dataview:"text/plain; charset=x-user-defined"},responseHandler:{dataview:function(responses,options,xhr){if('mozResponseArrayBuffer'in xhr){responses.text=xhr.mozResponseArrayBuffer;} +else if('responseType'in xhr&&xhr.responseType==='arraybuffer'&&xhr.response){responses.text=xhr.response;} +else if('responseBody'in xhr){responses.text=convertResponseBodyToText(xhr.responseBody);} +else{responses.text=xhr.responseText;}}}});jQuery.ajaxPrefilter('dataview',function(options,originalOptions,jqXHR){if(jQuery.support.ajaxResponseType){if(!options.hasOwnProperty('xhrFields')){options.xhrFields={};} +options.xhrFields.responseType='arraybuffer';} +options.mimeType='text/plain; charset=x-user-defined';});} +global.jDataView=(global.module||{}).exports=jDataView;if(typeof module!=='undefined'){module.exports=jDataView;}})(this); \ No newline at end of file diff --git a/webAO/misc/character_change.png b/webAO/misc/character_change.png new file mode 100644 index 0000000..ef210c8 Binary files /dev/null and b/webAO/misc/character_change.png differ diff --git a/webAO/misc/character_random.png b/webAO/misc/character_random.png new file mode 100644 index 0000000..e90267e Binary files /dev/null and b/webAO/misc/character_random.png differ diff --git a/webAO/misc/crossexamination.gif b/webAO/misc/crossexamination.gif new file mode 100644 index 0000000..a7754b6 Binary files /dev/null and b/webAO/misc/crossexamination.gif differ diff --git a/webAO/misc/holdit.gif b/webAO/misc/holdit.gif new file mode 100644 index 0000000..5f71ac6 Binary files /dev/null and b/webAO/misc/holdit.gif differ diff --git a/webAO/misc/objection.gif b/webAO/misc/objection.gif new file mode 100644 index 0000000..6aae2e5 Binary files /dev/null and b/webAO/misc/objection.gif differ diff --git a/webAO/misc/takethat.gif b/webAO/misc/takethat.gif new file mode 100644 index 0000000..dd03310 Binary files /dev/null and b/webAO/misc/takethat.gif differ diff --git a/webAO/misc/witnesstestimony.gif b/webAO/misc/witnesstestimony.gif new file mode 100644 index 0000000..03b4900 Binary files /dev/null and b/webAO/misc/witnesstestimony.gif differ diff --git a/webAO/sounds/general/sfx-testimony.wav b/webAO/sounds/general/sfx-testimony.wav new file mode 100644 index 0000000..ddbe9ea Binary files /dev/null and b/webAO/sounds/general/sfx-testimony.wav differ diff --git a/webAO/sounds/general/sfx-testimony2.wav b/webAO/sounds/general/sfx-testimony2.wav new file mode 100644 index 0000000..a49506e Binary files /dev/null and b/webAO/sounds/general/sfx-testimony2.wav differ diff --git a/webAO/ui.b.js b/webAO/ui.b.js index 22c0b2d..c0538b1 100644 --- a/webAO/ui.b.js +++ b/webAO/ui.b.js @@ -1,2 +1,2 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.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 o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));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=0)}([function(e,t,n){"use strict";var i=new(function(e){return e&&e.__esModule?e:{default:e}}(n(1)).default)({settings:{showPopoutIcon:!1,showCloseIcon:!1},dimensions:{minItemHeight:40},content:[{type:"row",content:[{type:"column",width:40,content:[{type:"component",componentName:"template",title:"Game",componentState:{id:"client_wrapper"}},{type:"component",title:"Miscellaneous",height:5,componentName:"template",componentState:{id:"misc"}}]},{type:"column",content:[{type:"row",height:65,content:[{type:"stack",content:[{type:"component",title:"Main",componentName:"template",componentState:{id:"mainmenu"}},{type:"component",title:"Log",componentName:"template",componentState:{id:"log"}}]},{type:"component",title:"Server chat",width:30,componentName:"template",componentState:{id:"ooc"}}]},{type:"row",content:[{type:"component",title:"Music",componentName:"template",componentState:{id:"music"}},{type:"stack",content:[{type:"component",title:"Settings",componentName:"template",componentState:{id:"client_settings"}},{type:"component",title:"About",componentName:"template",componentState:{id:"about"}}]}]}]}]}]});i.registerComponent("template",function(e,t){var n=document.querySelector("#"+t.id);e.getElement().html(n.content)}),i.init()},function(e,t,n){"use strict";(function(e){var n,i,o,s=function(){function e(e,t){for(var n=0;n]+)>)/gi,""))};var i=n(40),o=n.n(i),s=n(60),a=(n.n(s),"function"!=typeof/./&&"object"!=("undefined"==typeof Int8Array?"undefined":r(Int8Array))?function(e){return"function"==typeof e||!1}:function(e){return"[object Function]"===toString.call(e)})},function(e,t,n){var i=n(0),o="__all";t.a=o,t.b=function(){return function e(){c(this,e),this._mSubscriptions={},this._mSubscriptions[o]=[],this.on=function(e,t,n){if(!Object(i.h)(t))throw new Error("Tried to listen to event "+e+" with non-function callback "+t);this._mSubscriptions[e]||(this._mSubscriptions[e]=[]),this._mSubscriptions[e].push({fn:t,ctx:n})},this.emit=function(e){var t,n,i;i=Array.prototype.slice.call(arguments,1);var s=this._mSubscriptions[e];if(s)for(s=s.slice(),t=0;t'),s.childElementContainer=s.element,s._splitterSize=t.config.dimensions.borderWidth,s._splitterGrabSize=t.config.dimensions.borderGrabWidth,s._isColumn=e,s._dimension=e?"height":"width",s._splitter=[],s._splitterPosition=null,s._splitterMinPosition=null,s._splitterMaxPosition=null,s}return l(i,h.a),s(i,[{key:"addChild",value:function(e,t,i){var o,s,r,a;if(e=this.layoutManager._$normalizeContentItem(e,this),void 0===t&&(t=this.contentItems.length),0this.contentItems.length-this._isDocked())throw new Error("Can't dock child when it is last in "+this.config.type);var u={column:{first:"top",last:"bottom"},row:{first:"left",last:"right"}}[this.config.type][r?"last":"first"];e.header.position()!=u&&e.header.position(u),this._splitter[a]&&this._splitter[a].element.hide();var d=this._isDocked();for(l=0;lr(t)&&0=this.contentItems.length)){o=this._calculateAbsoluteSizes();for(var d=0;da)){for(e=l/a,c=l,d=0;dthis._splitterMinPosition&&ithis._nDistance||t(this._nY)>this._nDistance)&&(clearTimeout(this._timeout),this._startDrag()),this._bDragging&&this.emit("drag",this._nX,this._nY,e)}}},{key:"onMouseUp",value:function(e){null!=this._timeout&&(clearTimeout(this._timeout),this._eBody.removeClass("lm_dragging"),this._eElement.removeClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events",""),this._oDocument.unbind("mousemove touchmove",this._fMove),this._oDocument.unbind("mouseup touchend",this._fUp),!0===this._bDragging&&(this._bDragging=!1,this.emit("dragStop",e,this._nOriginalX+this._nX)))}},{key:"_startDrag",value:function(){this._bDragging=!0,this._eBody.addClass("lm_dragging"),this._eElement.addClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events","none"),this.emit("dragStart",this._nOriginalX,this._nOriginalY)}},{key:"_getCoordinates",value:function(e){return{x:(e=Object(o.e)(e)).pageX,y:e.pageY}}}]),t}();t.a=r},function(e,t,n){var i=n(9);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e){e.exports=function(e){return"object"==(void 0===e?"undefined":r(e))?null!==e:"function"==typeof e}},function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var i=n(0);t.a=function(){function e(){if(c(this,e),this._keys=["settings","hasHeaders","constrainDragToContainer","selectionEnabled","dimensions","borderWidth","minItemHeight","minItemWidth","headerHeight","dragProxyWidth","dragProxyHeight","labels","close","maximise","minimise","popout","content","componentName","componentState","id","width","type","height","isClosable","title","popoutWholeStack","openPopouts","parentId","activeItemIndex","reorderEnabled","borderGrabWidth"],36'),o.childElementContainer=o.element,o._containerElement=i,o._containerElement.append(o.element),o}return l(t,i.a),s(t,[{key:"addChild",value:function(e){if(0'),o._activeContentItem=null;var s=e.config;return o._header={show:!0===s.settings.hasHeaders&&!1!==t.hasHeaders,popout:s.settings.showPopoutIcon&&s.labels.popout,maximise:s.settings.showMaximiseIcon&&s.labels.maximise,close:s.settings.showCloseIcon&&s.labels.close,minimise:s.labels.minimise},s.header&&Object(d.b)(o._header,s.header),t.header&&Object(d.b)(o._header,t.header),t.content&&t.content[0]&&t.content[0].header&&Object(d.b)(o._header,t.content[0].header),o._dropZones={},o._dropSegment=null,o._contentAreaDimensions=null,o._dropIndex=null,o.isStack=!0,o.childElementContainer=$('
'),o.header=new u.a(e,o),o.element.on("mouseleave mouseenter",Object(d.c)(function(e){this._docker&&this._docker.docked&&this.childElementContainer[this._docker.dimension]("mouseenter"==e.type?this._docker.realSize:0)},o)),o.element.append(o.header.element),o.element.append(o.childElementContainer),o._setupHeaderPosition(),o._$validateClosability(),o}return l(i,r.a),s(i,[{key:"dock",value:function(e){this._header.dock&&this.parent instanceof h.a&&this.parent.dock(this,e)}},{key:"setSize",value:function(){if("none"!==this.element.css("display")){var e=this._docker&&this._docker.docked,t={width:this.element.width(),height:this.element.height()};this._header.show&&(t[this._sided?"width":"height"]-=this.layoutManager.config.dimensions.headerHeight),e&&(t[this._docker.dimension]=this._docker.realSize),e&&"height"!=this._docker.dimension||this.childElementContainer.width(t.width),e&&"width"!=this._docker.dimension||this.childElementContainer.height(t.height);for(var n=0;nthis.contentItems.length&&(t-=1),e=this.layoutManager._$normalizeContentItem(e,this),r.a.prototype.addChild.call(this,e,t),this.childElementContainer.append(e.element),this.header.createTab(e,t),this.setActiveContentItem(e),this.callDownwards("setSize"),this._$validateClosability(),this.parent instanceof h.a&&this.parent._validateDocking(),this.emitBubblingEvent("stateChanged")}},{key:"removeChild",value:function(e,t){var i=Object(d.g)(e,this.contentItems);r.a.prototype.removeChild.call(this,e,t),this.header.removeTab(e),this.header.activeContentItem===e&&(0e&&i.y1t)return void("header"===n?(this._dropSegment="header",this._highlightHeaderDropZone(this._sided?t:e)):(this._resetHeaderDropZone(),this._highlightBodyDropZone(n)))}},{key:"_$getArea",value:function(){if("none"===this.element.css("display"))return null;var e=r.a.prototype._$getArea,t=e.call(this,this.header.element),n=e.call(this,this.childElementContainer),i=n.x2-n.x1,o=n.y2-n.y1;return this._contentAreaDimensions={header:{hoverArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2},highlightArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2}}},this._activeContentItem&&!1===this._activeContentItem.isComponent?t:0===this.contentItems.length?(this._contentAreaDimensions.body={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}},e.call(this,this.element)):(this._contentAreaDimensions.left={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x1+.25*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x1+.5*i,y2:n.y2}},this._contentAreaDimensions.top={hoverArea:{x1:n.x1+.25*i,y1:n.y1,x2:n.x1+.75*i,y2:n.y1+.5*o},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y1+.5*o}},this._contentAreaDimensions.right={hoverArea:{x1:n.x1+.75*i,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1+.5*i,y1:n.y1,x2:n.x2,y2:n.y2}},this._contentAreaDimensions.bottom={hoverArea:{x1:n.x1+.25*i,y1:n.y1+.5*o,x2:n.x1+.75*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1+.5*o,x2:n.x2,y2:n.y2}},e.call(this,this.element))}},{key:"_highlightHeaderDropZone",value:function(t){var n,i,o,s,r,a,l,c,h=this.header.tabs.length,u=!1;if(0===h)return l=this.header.element.offset(),void this.layoutManager.dropTargetIndicator.highlightArea({x1:l.left,x2:l.left+100,y1:l.top+this.header.element.height()-20,y2:l.top+this.header.element.height()});for(n=0;ns&&t
        '),!0===i.layoutManager.config.settings.selectionEnabled&&(i.element.addClass("lm_selectable"),i.element.on("click touchstart",Object(h.c)(i._onHeaderClick,i))),i.tabsContainer=i.element.find(".lm_tabs"),i.tabDropdownContainer=i.element.find(".lm_tabdropdown_list"),i.tabDropdownContainer.hide(),i.controlsContainer=i.element.find(".lm_controls"),i.parent=n,i.parent.on("resize",i._updateTabSizes,i),i.tabs=[],i.tabsMarkedForRemoval=[],i.activeContentItem=null,i.closeButton=null,i.dockButton=null,i.tabDropdownButton=null,i.hideAdditionalTabsDropdown=Object(h.c)(i._hideAdditionalTabsDropdown,i),$(document).mouseup(i.hideAdditionalTabsDropdown),i._lastVisibleTabIndex=-1,i._tabControlOffset=i.layoutManager.config.settings.tabControlOffset,i._createControls(),i}return l(t,i.b),s(t,[{key:"createTab",value:function(e,t){var n,i;for(i=0;ithis._lastVisibleTabIndex){for(o=this.tabs[this.parent.config.activeItemIndex],n=this.parent.config.activeItemIndex;0r){if(u)i===d&&(n.css({"z-index":"auto","margin-left":""}),this.tabsContainer.append(n));else if((c=0
        '),this.titleElement=this.element.find(".lm_title"),this.closeElement=this.element.find(".lm_close_tab"),this.closeElement[n.config.isClosable?"show":"hide"](),this.isActive=!1,this.setTitle(n.config.title),this.contentItem.on("titleChanged",this.setTitle,this),this._layoutManager=this.contentItem.layoutManager,!0===this._layoutManager.config.settings.reorderEnabled&&!0===n.config.reorderEnabled&&(this._dragListener=new i.a(this.element),this._dragListener.on("dragStart",this._onDragStart,this),this.contentItem.on("destroy",this._dragListener.destroy,this._dragListener)),this._onTabClickFn=Object(r.c)(this._onTabClick,this),this._onCloseClickFn=Object(r.c)(this._onCloseClick,this),this.element.on("mousedown touchstart",this._onTabClickFn),this.contentItem.config.isClosable?(this.closeElement.on("click touchstart",this._onCloseClickFn),this.closeElement.on("mousedown",this._onCloseMousedown)):this.closeElement.remove(),this.contentItem.tab=this,this.contentItem.emit("tab",this),this.contentItem.layoutManager.emit("tabCreated",this),this.contentItem.isComponent&&(this.contentItem.container.tab=this,this.contentItem.container.emit("tab",this))}return s(e,[{key:"setTitle",value:function(e){this.element.attr("title",Object(r.k)(e)),this.titleElement.html(e)}},{key:"setActive",value:function(e){e===this.isActive||(this.isActive=e,e?this.element.addClass("lm_active"):this.element.removeClass("lm_active"))}},{key:"_$destroy",value:function(){this.element.off("mousedown touchstart",this._onTabClickFn),this.closeElement.off("click touchstart",this._onCloseClickFn),this._dragListener&&(this.contentItem.off("destroy",this._dragListener.destroy,this._dragListener),this._dragListener.off("dragStart",this._onDragStart),this._dragListener=null),this.element.remove()}},{key:"_onDragStart",value:function(e,t){return this.header._canDestroy?(!0===this.contentItem.parent.isMaximised&&this.contentItem.parent.toggleMaximise(),void new o.a(e,t,this._dragListener,this._layoutManager,this.contentItem,this.header.parent)):null}},{key:"_onTabClick",value:function(e){if(0===e.button||"touchstart"===e.type){var t=this.header.parent.getActiveContentItem();this.contentItem!==t&&this.header.parent.setActiveContentItem(this.contentItem)}else 1===e.button&&this.contentItem.config.isClosable&&this._onCloseClick(e)}},{key:"_onCloseClick",value:function(e){e.stopPropagation(),this.header._canDestroy&&this.header.parent.removeChild(this.contentItem)}},{key:"_onCloseMousedown",value:function(e){e.stopPropagation()}}]),e}()},function(e,t,n){var i=n(1),o=n(0),r=function(e){function t(e,n,i,s,r,l){var h;c(this,t),(h=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)))._dragListener=i,h._layoutManager=s,h._contentItem=r,h._originalParent=l,h._area=null,h._lastValidArea=null,h._dragListener.on("drag",h._onDrag,h),h._dragListener.on("dragStop",h._onDrop,h),h.element=$('
        '),l&&l._side&&(h._sided=l._sided,h.element.addClass("lm_"+l._side),0<=["right","bottom"].indexOf(l._side)&&h.element.find(".lm_content").after(h.element.find(".lm_header"))),h.element.css({left:e,top:n}),h.element.find(".lm_tab").attr("title",Object(o.k)(h._contentItem.config.title)),h.element.find(".lm_title").html(h._contentItem.config.title),h.childElementContainer=h.element.find(".lm_content"),h.childElementContainer.append(r.element),h._undisplayTree(),h._layoutManager._$calculateItemAreas(),h._setDimensions(),$(document.body).append(h.element);var u=h._layoutManager.container.offset();return h._minX=u.left,h._minY=u.top,h._maxX=h._layoutManager.container.width()+h._minX,h._maxY=h._layoutManager.container.height()+h._minY,h._width=h.element.width(),h._height=h.element.height(),h._setDropPosition(e,n),h}return l(t,i.b),s(t,[{key:"_onDrag",value:function(e,t,n){var i=(n=Object(o.e)(n)).pageX,s=n.pageY;(i>this._minX&&ithis._minY&&s'),this._header.on("destroy",this._$destroy,this),this._action=o,this.element.on("click touchstart",this._action),this._header.controlsContainer.append(this.element)}return s(e,[{key:"_$destroy",value:function(){this.element.off(),this.element.remove()}}]),e}()},function(e,t,n){var i=n(3),o=n(33),r=function(e){function t(e,n,i){c(this,t);var s=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,i)),r=e.getComponent(s.config.componentName),l=$.extend(!0,{},s.config.componentState||{});return l.componentName=s.config.componentName,s.componentName=s.config.componentName,""===s.config.title&&(s.config.title=s.config.componentName),s.isComponent=!0,s.container=new o.a(s.config,s,e),s.instance=new r(s.container,l),s.element=s.container._element,s}return l(t,i.a),s(t,[{key:"close",value:function(){this.parent.removeChild(this)}},{key:"setSize",value:function(){"none"!==this.element.css("display")&&this.container._$setSize(this.element.width(),this.element.height())}},{key:"_$init",value:function(){i.a.prototype._$init.call(this),this.container.emit("open")}},{key:"_$hide",value:function(){this.container.hide(),i.a.prototype._$hide.call(this)}},{key:"_$show",value:function(){this.container.show(),i.a.prototype._$show.call(this)}},{key:"_$shown",value:function(){this.container.shown(),i.a.prototype._$shown.call(this)}},{key:"_$destroy",value:function(){this.container.emit("destroy",this),i.a.prototype._$destroy.call(this)}},{key:"_$getArea",value:function(){return null}}]),t}();t.a=r},function(e,t,n){var i=n(1),o=function(e){function t(e,n,i){var o;return c(this,t),(o=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this))).width=null,o.height=null,o.title=e.componentName,o.parent=n,o.layoutManager=i,o.isHidden=!1,o._config=e,o._element=$('
        '),o._contentElement=o._element.find(".lm_content"),o}return l(t,i.b),s(t,[{key:"getElement",value:function(){return this._contentElement}},{key:"hide",value:function(){this.emit("hide"),this.isHidden=!0,this._element.hide()}},{key:"show",value:function(){this.emit("show"),this.isHidden=!1,this._element.show(),(0!=this.height||0!=this.width)&&this.emit("shown")}},{key:"setSize",value:function(e,t){for(var n,i,o,s,r=this.parent,a=this;!r.isColumn&&!r.isRow;)if(a=r,(r=r.parent).isRoot)return!1;for(n=("height"===(i=r.isColumn?"height":"width")?t:e)/(this[i]*(1/(a.config[i]/100)))*100,o=(a.config[i]-n)/(r.contentItems.length-1),s=0;s'),n._creationTimeoutPassed=!1,n._subWindowsCreated=!1,n._dragSources=[],n._updatingColumnsResponsive=!1,n._firstLoad=!0,n.width=null,n.height=null,n.root=null,n.openPopouts=[],n.selectedItem=null,n.isSubWindow=!1,n.eventHub=new f.a(n),n.config=n._createConfig(e),n.container=t,n.dropTargetIndicator=null,n.transitionIndicator=null,n.tabDropPlaceholder=$('
        '),!0===n.isSubWindow&&$("body").css("visibility","hidden"),n._typeToItem={column:Object(C.c)(p.a,n,[!0]),row:Object(C.c)(p.a,n,[!1]),stack:g.a,component:y.a},n}return l(i,h.b),s(i,[{key:"minifyConfig",value:function(e){return(new d.a).minifyConfig(e)}},{key:"unminifyConfig",value:function(e){return(new d.a).unminifyConfig(e)}},{key:"registerComponent",value:function(e,t){if("function"!=typeof t)throw new Error("Please register a constructor function");if(void 0!==this._components[e])throw new Error("Component "+e+" is already registered");this._components[e]=t}},{key:"toConfig",value:function(e){var t,n,i;if(!1===this.isInitialised)throw new Error("Can't create config, layout not yet initialised");if(e&&!(e instanceof v.a))throw new Error("Root must be a ContentItem");for((t={settings:Object(C.b)({},this.config.settings),dimensions:Object(C.b)({},this.config.dimensions),labels:Object(C.b)({},this.config.labels)}).content=[],(n=function(e,t){var i,o;for(i in t.config)"content"!==i&&(e[i]=t.config[i]);if(t.contentItems.length)for(e.content=[],o=0;o(i=this._itemAreas[n]).x1&&ei.y1&&ti.surface&&(o=i.surface,s=i);return s}},{key:"_$createRootItemAreas",value:function(){var e={y2:0,x2:0,y1:"y2",x1:"x2"};for(var t in e){var n=this.root._$getArea();n.side=t,n[t]=e[t]?n[e[t]]-50:50,n.surface=(n.x2-n.x1)*(n.y2-n.y1),this._itemAreas.push(n)}}},{key:"_$calculateItemAreas",value:function(){var e,t,n=this._getAllContentItems();if(this._itemAreas=[],1!==n.length){for(this._$createRootItemAreas(),e=0;e
        ');e.click(Object(C.c)(function(){this.emit("popIn")},this)),document.title=Object(C.k)(this.config.content[0].title),$("head").append($("body link, body style, template, .gl_keep")),this.container=$("body").html("").css("visibility","visible").append(e),document.body.offsetHeight,window.__glInstance=this}},{key:"_createSubWindows",value:function(){var e,t;for(e=0;e=e)){var i=this.config.dimensions.minItemWidth;if(!(e*i<=this.width)){this._updatingColumnsResponsive=!0;for(var o,s=n(t(this.width/i),1),r=this.root.contentItems[0],a=this._findAllStackContainers()[0],l=0;ll;)i(a,n=t[l++])&&(~s(c,n)||c.push(n));return c}},function(e,t,n){var i=n(46);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var i=n(17),o=n(48),s=n(49);e.exports=function(e){return function(t,n,r){var a,l=i(t),c=o(l.length),h=s(r,c);if(e&&n!=n){for(;c>h;)if((a=l[h++])!=a)return!0}else for(;c>h;h++)if((e||h in l)&&l[h]===n)return e||h||0;return!e&&-1}}},function(t,n,i){var o=i(18);t.exports=function(t){return 0(t=s(t))?n(t+i,0):e(t,i)}},function(e,t,n){var i=n(2),o=n(4),s="__core-js_shared__",r=o[s]||(o[s]={});(e.exports=function(e,t){return r[e]||(r[e]=void 0===t?{}:t)})("versions",[]).push({version:i.version,mode:n(51)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e){e.exports=!0},function(e){var t=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++t+n).toString(36))}},function(e,t,n){var i=n(21),o=n(2),s=n(10);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*s(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(55);e.exports=function(e,t,n){return i(e),void 0===t?e:1===n?function(n){return e.call(t,n)}:2===n?function(n,i){return e.call(t,n,i)}:3===n?function(n,i,o){return e.call(t,n,i,o)}:function(){return e.apply(t,arguments)}}},function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var i=n(22),o=n(59);e.exports=n(5)?function(e,t,n){return i.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=!n(5)&&!n(10)(function(){return 7!=Object.defineProperty(n(23)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(9);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){e.exports={default:n(61),__esModule:!0}},function(e,t,n){n(62);var i=n(2).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){var i=n(21);i(i.S,"Object",{create:n(63)})},function(e,t,n){var i=n(8),o=n(64),s=n(20),r=n(19)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(23)("iframe"),i=s.length;for(t.style.display="none",n(65).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + - + + @@ -39,12 +41,12 @@
        - - Defense health - - - Prosecution health - + +
        +
        + +
        +
        @@ -75,12 +77,29 @@
        Action Commands - - - - report
        Call Mod
        + + + + + No action available for this role.
        +
        + report
        Call Mod
        +
        +

        They might be very busy. Are you sure?

        +
        +
        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; @@ -191,6 +193,15 @@ class Client { this.serv.send(`DE#${id}#%`); } + /** + * 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); + } } /** @@ -743,20 +757,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; @@ -1747,6 +1747,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. */ @@ -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 -- cgit From 67443e853de53562fc8d85a9655324e246ef22ba Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 11:25:30 +0700 Subject: Add jquery ui mobile support + bbcode description in guide. --- webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.css | 1 + webAO/client.html | 18 +++++++++++++++++- webAO/client.js | 4 ++-- webAO/lib/jquery.ui.touch-punch.min.js | 11 +++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 webAO/lib/jquery.ui.touch-punch.min.js diff --git a/webAO/client.b.js b/webAO/client.b.js index 68799a7..0ad9cb7 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").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,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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'}},{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 .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",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"}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;t0){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="

        "+ae(this.chatmsg.nameplate)+"

        ";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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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'}},{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 .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",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"}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;t0){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="

        "+ae(this.chatmsg.nameplate)+"

        ";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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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 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 += '\"'';\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 = `${this.chars[i].name}`;\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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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 +{"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 += '\"'';\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 = `${this.chars[i].name}`;\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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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 721ad45..d62bc6f 100644 --- a/webAO/client.css +++ b/webAO/client.css @@ -220,6 +220,7 @@ img { } #client_chat { + font-size: 1em; display: none; width: 98%; /* fallback if needed */ width: calc(100% - 4px); diff --git a/webAO/client.html b/webAO/client.html index 88a9f9b..9ec1970 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -12,6 +12,7 @@ + @@ -211,7 +212,22 @@ - + + + BBcode * Only work on webAO +
          +
        1. \n : new line
        2. +
        3. [b][/b] : bolded text
        4. +
        5. [i][/i] : italicized text
        6. +
        7. [u][/u] : underlined text
        8. +
        9. [s][/s] : strikethrough text
        10. +
        11. [sub][/sub] : subscript text
        12. +
        13. [sup][/sup] : superscript text
        14. +
        15. [m=#0f0][/m] : highlighted text
        16. +
        17. [c=cyan][/c] : colorized text
        18. +
        +
        +
        diff --git a/webAO/client.js b/webAO/client.js index 83c34ab..10e8c81 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -1965,8 +1965,8 @@ function decodeBBCode(estring) { .replace(/\\n/g, "
        ") // Newline \n .replace(/\[(\/?)b\]/g, "<$1b>") // Bold [b][/b] .replace(/\[(\/?)i\]/g, "<$1i>") // Italic [i][/i] - .replace(/\[(\/?)del\]/g, "<$1del>") // Deleted [del][/del] - .replace(/\[(\/?)u\]/g, "<$1ins>") // Underline [u][/u] + .replace(/\[(\/?)s\]/g, "<$1del>") // Strikethrough [s][/s] + .replace(/\[(\/?)u\]/g, "<$1u>") // Underline [u][/u] .replace(/\[(\/?)sub\]/g, "<$1sub>") // Subscript [sub][/sub] .replace(/\[(\/?)sup\]/g, "<$1sup>") // Superscript [sup][/sup] .replace(/\[m=([#a-zA-Z0-9]+)\]/g, '') // Markup [m=#0ff] diff --git a/webAO/lib/jquery.ui.touch-punch.min.js b/webAO/lib/jquery.ui.touch-punch.min.js new file mode 100644 index 0000000..31272ce --- /dev/null +++ b/webAO/lib/jquery.ui.touch-punch.min.js @@ -0,0 +1,11 @@ +/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + */ +!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); \ No newline at end of file -- cgit From bdf8f9f3391ee80ec7a3d99d62f845ac7dfa0f7e Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 14:39:06 +0700 Subject: Add option to edit server chat name (a.k.a Fake name) and adjust settings menu. --- webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.html | 30 ++++++++++++++++-------------- webAO/client.js | 4 +++- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/webAO/client.b.js b/webAO/client.b.js index 0ad9cb7..b6d597d 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").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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'}},{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 .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",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"}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;t0){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="

        "+ae(this.chatmsg.nameplate)+"

        ";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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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'}},{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 .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",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"}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;t0){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",O(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",O(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="

        "+ae(this.chatmsg.nameplate)+"

        ";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 O(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",M,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",M,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 M(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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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 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 += '\"'';\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 = `${this.chars[i].name}`;\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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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 +{"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","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","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#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${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// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\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 += '\"'';\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 = `${this.chars[i].name}`;\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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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.html b/webAO/client.html index 9ec1970..5a8bd0e 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -168,6 +168,8 @@ + +

        - +
        Music
        +
        SFX
        +
        Blip
        +
        + Change + Change +

        +

        - +

        - * If you not sure what does this means, please don't change the settings. -
        + * If you not sure what does this means, please don't change these following settings. +

        -
        +

        -
        +

        -

        -
        Music
        -
        SFX
        -
        Blip
        -
        - Change - Change
        @@ -252,7 +254,7 @@ diff --git a/webAO/client.js b/webAO/client.js index 10e8c81..bd9a840 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -141,7 +141,7 @@ class Client { * @param {string} message the message to send */ sendOOC(message) { - this.serv.send(`CT#web${this.playerID}#${escapeChat(encodeChat(message))}#%`); + this.serv.send(`CT#${escapeChat(encodeChat(document.getElementById("OOC_name").value))}#${escapeChat(encodeChat(message))}#%`); } /** @@ -252,6 +252,8 @@ class Client { * Load game resources. */ loadResources() { + // Set to playerID to server chat name + document.getElementById("OOC_name").value = "web" + this.playerID; // Load evidence array to select var evidence_select = document.getElementById("evi_select"); evidence_select.add(new Option("Custom", 0)); -- cgit From 0fb8cc82d9824b0e798eedb97f062c915d8752bc Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 15:23:23 +0700 Subject: Update README --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bfba5f3..1d977ec 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,20 @@ # Attorney Online Web Client +webAO client only feature: + - BBcode + - Client side encoding-decoding (Unicode escape/UTF-16 array) + - Location (spilt from music list) + - Change background UI via menu + +Planned feature: + - Record testimony on client side (Judge role) + - Play testimony during cross-examination + - Defense, prosecution and judge can skip message.(forward/backward) + - Show Guilty/Not Guilty message (Judge role) + Link to the client in this repo: http://attorneyonline.000webhostapp.com Guide to installing it locally: https://docs.google.com/document/d/1X4OjG0tfoTZayqY9MM6fqzL_aGMKFAECg7NSQRYafAU/edit This is a client for the Attorney Online roleplaying chatroom written in HTML and Javascript. -It works with the serverD software when the server has WebSockets enabled. +It works with the tsuserver3/serverD software when the server has WebSockets enabled. -- cgit From b8f6c358d2f82153f107d4bc0beef394925b5082 Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 15:31:05 +0700 Subject: Edit README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1d977ec..f7a0504 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Attorney Online Web Client -webAO client only feature: +webAO client only features: - BBcode - Client side encoding-decoding (Unicode escape/UTF-16 array) - Location (spilt from music list) - Change background UI via menu -Planned feature: +Planned features: - Record testimony on client side (Judge role) - Play testimony during cross-examination - - Defense, prosecution and judge can skip message.(forward/backward) + - Defense, prosecution and judge can skip testimony message.(forward/backward) - Show Guilty/Not Guilty message (Judge role) Link to the client in this repo: http://attorneyonline.000webhostapp.com -- cgit From 4cf6fb8e8609dbf84149d0410393f9e3436fea91 Mon Sep 17 00:00:00 2001 From: Qube Date: Sat, 21 Jul 2018 21:07:06 +0700 Subject: Convert all character animation name to lowercase if user use asset from default asset site. --- webAO/client.b.js | 2 +- webAO/client.b.js.map | 2 +- webAO/client.js | 14 ++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/webAO/client.b.js b/webAO/client.b.js index b6d597d..46ab840 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").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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'}},{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 .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",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"}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;t0){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",O(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",O(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="

        "+ae(this.chatmsg.nameplate)+"

        ";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 O(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",M,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",M,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 M(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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}(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;nt.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)?S(this.chars[e[2]].name+" changed music to "+e[1]):S("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'}},{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 .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",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,c="http://assets.aceattorneyonline.com/base/"==l;i.withCredentials=!1,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,o=p.parse(i);t.side=o.Options.side,V(t.side);for(var s=1;s"}P(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;t0){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",O(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",O(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="

        "+ae(this.chatmsg.nameplate)+"

        ";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 O(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",M,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",M,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 M(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 L(){me.cleanup(),(me=new y(s))&&(a="join",document.getElementById("client_error").style.display="none")}function N(){me.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 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 H(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 P(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/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return e.replace(/#/g,"").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function de(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//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 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#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${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// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\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 += '\"'';\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 = `${this.chars[i].name}`;\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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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 +{"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","document","getElementById","speaking","silent","side","ssfxname","zoom","ssfxdelay","evidence","flash","color","desc","img","id","msg","testimony","track","_this2","hashCode","setInterval","sendCheck","evidence_select","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","isOfficialAssets","withCredentials","open","responseType","onload","status","linifile","responseText","pinifile","INI","parse","Options","Emotions","number","emoteinfo","esfx","esfxd","SoundN","SoundT","toLowerCase","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#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${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// Set to playerID to server chat name\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\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 += '\"'';\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 = `${this.chars[i].name}`;\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\tlet isOfficialAssets = (AO_HOST == \"http://assets.aceattorneyonline.com/base/\");\r\n\t\txhr.withCredentials = false;\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: (isOfficialAssets)? emoteinfo[0].toLowerCase() : emoteinfo[0],\r\n\t\t\t\t\t\tspeaking: (isOfficialAssets)? emoteinfo[1].toLowerCase() : emoteinfo[1],\r\n\t\t\t\t\t\tsilent: (isOfficialAssets)? emoteinfo[2].toLowerCase() : emoteinfo[2],\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: (isOfficialAssets)? esfx.toLowerCase() : esfx,\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_off.png',\r\n\t\t\t\t\t\tbutton_on: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : 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 += \"\" + emotes[i].desc + \"\";\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 = \"

        \" + escapeHtml(this.chatmsg.nameplate) + \"

        \";\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//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, \"
        \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, '') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, ''); // [/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.js b/webAO/client.js index bd9a840..18363aa 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -823,6 +823,8 @@ class Client { let me = this.me(); let emotes = this.emotes; let xhr = new XMLHttpRequest(); + let isOfficialAssets = (AO_HOST == "http://assets.aceattorneyonline.com/base/"); + xhr.withCredentials = false; document.getElementById("client_emo").innerHTML = ""; // Clear emote box xhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true); xhr.responseType = 'text'; @@ -843,14 +845,14 @@ class Client { esfxd = pinifile.SoundT[i]; } emotes[i] = { - desc: emoteinfo[0], - speaking: emoteinfo[1], - silent: emoteinfo[2], + desc: (isOfficialAssets)? emoteinfo[0].toLowerCase() : emoteinfo[0], + speaking: (isOfficialAssets)? emoteinfo[1].toLowerCase() : emoteinfo[1], + silent: (isOfficialAssets)? emoteinfo[2].toLowerCase() : emoteinfo[2], zoom: emoteinfo[3], - sfx: esfx, + sfx: (isOfficialAssets)? esfx.toLowerCase() : esfx, sfxdelay: esfxd, - button_off: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_off.png', - button_on: AO_HOST + 'characters/' + escape(me.name) + '/emotions/button' + i + '_on.png' + button_off: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_off.png', + button_on: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_on.png' }; document.getElementById("client_emo").innerHTML += "" + emotes[i].desc + ""; } -- cgit From 2f18d565cb06de3826aee13fd07356adf29d9cbc Mon Sep 17 00:00:00 2001 From: gameboyprinter Date: Mon, 20 Aug 2018 18:46:00 -0500 Subject: refactor part 1 --- webAO/client.css | 196 +++++++--------- webAO/client.html | 424 +++++++++++++++++++-------------- webAO/client.js | 683 ++++++++++++++++++++++++++++-------------------------- webAO/ui.js | 93 ++++---- 4 files changed, 742 insertions(+), 654 deletions(-) diff --git a/webAO/client.css b/webAO/client.css index d62bc6f..a76ef6f 100644 --- a/webAO/client.css +++ b/webAO/client.css @@ -1,13 +1,13 @@ -body { - font-family: "Ace Attorney","メイリオ",Meiryo,Hiragino Kaku Gothic Pro,"ヒラギノ角ゴ Pro W3",Osaka,"MS Gothic","MS Pゴシック",Tahoma,Sans; +body { + font-family: "Ace Attorney", "メイリオ", Meiryo, Hiragino Kaku Gothic Pro, "ヒラギノ角ゴ Pro W3", Osaka, "MS Gothic", "MS Pゴシック", Tahoma, Sans; } img { image-rendering: -moz-crisp-edges; - image-rendering: -o-crisp-edges; - image-rendering: -webkit-optimize-contrast; - image-rendering: crisp-edges; - -ms-interpolation-mode: nearest-neighbor; + image-rendering: -o-crisp-edges; + image-rendering: -webkit-optimize-contrast; + image-rendering: crisp-edges; + -ms-interpolation-mode: nearest-neighbor; } #about-logo { @@ -16,20 +16,26 @@ img { image-rendering: auto; } -@keyframes error_blink { - 0% { color: white; } - 50% { color: red; } - 100% { color: white; } +@keyframes error_blink { + 0% { + color: white; + } + 50% { + color: red; + } + 100% { + color: white; + } } .error { position: absolute; width: 50vw; height: 25vh; - top: 50%; - left: 50%; - margin-right: -50%; - transform: translate(-50%, -50%); + top: 50%; + left: 50%; + margin-right: -50%; + transform: translate(-50%, -50%); display: flex; margin: 0 auto; justify-content: center; @@ -47,10 +53,10 @@ img { position: absolute; width: 90vw; height: 30vh; - top: 50%; - left: 50%; - margin-right: -50%; - transform: translate(-50%, -50%); + top: 50%; + left: 50%; + margin-right: -50%; + transform: translate(-50%, -50%); justify-content: center; display: flex; align-items: center; @@ -62,10 +68,7 @@ img { #client_gamewindow { position: relative; - /*! top: 0; */ - /*! left: 0; */ - /*! width: 100%; */ - padding-bottom: 75%; + padding-bottom: 75%; } #client_charselect { @@ -99,19 +102,9 @@ img { } #client_wrapper { - /*! position: absolute; */ - /*! top: 0; */ - /*! left: 0; */ background-color: #888888; - /*! height: 99%; */ - /*! width: 512px; */ - /*! margin: 0; */ - /*! padding: 0; */ - /*! float: left; */ - /*! resize: horizontal; */ overflow: auto; - overflow-y:hidden; - /*! border: 1px solid; */ + overflow-y: hidden; min-width: 256px; resize: horizontal; } @@ -129,11 +122,7 @@ img { } #client_settings { - /*! position: absolute; */ - /*! top: 100%; */ width: 100%; - /*! grid-column: 1; */ - /*! grid-row: 2; */ } .area_btn { @@ -161,8 +150,8 @@ img { position: absolute; height: auto; width: 100%; - bottom: 0; - left: 0; + bottom: 0; + left: 0; } #client_fg { @@ -178,7 +167,7 @@ img { opacity: 0; position: absolute; background-repeat: no-repeat; - background-size: contain; + background-size: contain; height: 0%; width: auto; top: 1.5em; @@ -195,16 +184,16 @@ img { #client_background { position: absolute; background-color: transparent; - width:100%; - height:auto; + width: 100%; + height: auto; padding-bottom: 75%; } #client_name { display: none; height: 7%; - border: 1px solid rgba(255,255,255,0.7); - background:rgba(73,0,254,0.5); + border: 1px solid rgba(255, 255, 255, 0.7); + background: rgba(73, 0, 254, 0.5); top: 63%; border-radius: 3px; position: absolute; @@ -222,12 +211,12 @@ img { #client_chat { font-size: 1em; display: none; - width: 98%; /* fallback if needed */ - width: calc(100% - 4px); + width: 98%; + width: calc(100% - 4px); margin: auto; height: 30%; - border: 2px solid rgba(255,255,255,0.7); - background-color: rgba(0,0,0,0.5); + border: 2px solid rgba(255, 255, 255, 0.7); + background-color: rgba(0, 0, 0, 0.5); top: 70%; border-radius: 4px; position: absolute; @@ -243,6 +232,7 @@ img { margin: 4px; color: white; } + .long { width: 100%; background-color: #dddddd; @@ -253,40 +243,28 @@ img { } #client_chatlog { - /*! width: 244px; */ - /*! height: 100%; */ - /*! background: #dbdbdb url("misc/chat2.png") no-repeat; */ - /*! padding: 0; */ - /*! position: absolute; */ top: 0; right: 0; - /* grid-column: 2; */ flex: 1; } #client_log { position: relative; - /* top: 3px; */ - /*! left: 10px; */ height: 100%; - /*! width: 99%; */ color: white; word-break: keep-all; - word-wrap:break-word; + word-wrap: break-word; overflow-wrap: break-word; overflow-y: scroll; font-size: medium; - /* margin-bottom: 10px; */ background-color: #242424; border: black; border-style: solid; - /* max-width: 50em; */ - /* min-height: 30em; */ text-align: start; line-height: .85em; } -#client_log > p { +#client_log>p { line-height: 1.1em; } @@ -302,9 +280,6 @@ img { } #client_ooclog { - /*! width: 99%; */ - /* margin-top: 25px; */ - /* height: 50%; */ position: relative; background-color: #242424; color: white; @@ -320,8 +295,6 @@ img { #client_musiclist { width: 99%; - /* margin-top: 20px; */ - /*! height: 50%; */ background-color: #222; color: white; } @@ -329,21 +302,21 @@ img { #client_bars { position: relative; text-align: center; - display: flex; + display: flex; display: -webkit-flex; } #client_testimony { display: block; - position: absolute; - width: 100%; - height: auto; + position: absolute; + width: 100%; + height: auto; } #evi_icon { background-image: url('misc/empty.png'); background-repeat: no-repeat; - background-size: contain; + background-size: contain; } #bg_preview { @@ -352,9 +325,9 @@ img { width: 100%; height: 100%; border-style: double; - border-radius: 7px; - border-color: white; - border-width: 3px; + border-radius: 7px; + border-color: white; + border-width: 3px; } .slider { @@ -365,35 +338,34 @@ img { margin-right: auto; } -#client_defense_hp{ +#client_defense_hp { text-align: left; } -#client_defense_hp > .health-bar{ +#client_defense_hp>.health-bar { background-color: #169de0; } -#client_prosecutor_hp{ +#client_prosecutor_hp { text-align: right; } -#client_prosecutor_hp > .health-bar{ +#client_prosecutor_hp>.health-bar { background-color: #e01f5f; } - .health-box { background-color: #555; height: 20px; width: 50%; - margin: 0 auto; + margin: 0 auto; border: solid 2px #aaa; border-radius: 5px; - box-sizing:border-box; + box-sizing: border-box; display: block; } -.health-bar { +.health-bar { width: 100%; height: 100%; border-radius: 3px; @@ -406,24 +378,24 @@ img { padding: 1px; } -.client_button.hover_button.inactive{ +.client_button.hover_button.inactive { display: none; } -.client_button.hover_button:hover{ - margin:-2px; +.client_button.hover_button:hover { + margin: -2px; border-radius: 5px; border-style: dashed; - border-width: 2px; - border-color: #FFD081; + border-width: 2px; + border-color: #FFD081; } -.client_button.hover_button:hover{ - margin:-2px; +.client_button.hover_button:hover { + margin: -2px; border-radius: 5px; border-style: dashed; - border-width: 2px; - border-color: #FFD081; + border-width: 2px; + border-color: #FFD081; } .dark { @@ -458,51 +430,51 @@ img { margin-right: -50%; } -.menu_content{ - margin: 15px 15px; +.menu_content { + margin: 15px 15px; display: none; } -.menu_content.active{ +.menu_content.active { display: block; } -.menu_icon{ +.menu_icon { cursor: pointer; - line-height:15px; + line-height: 15px; display: inline-table; margin: 10px 15px; opacity: 1; } -.menu_icon.active{ +.menu_icon.active { opacity: 0.25; } -.menu_icon:hover{ +.menu_icon:hover { color: #FFD081; } -.material-icons.em-3 { - font-size: 3em; +.material-icons.em-3 { + font-size: 3em; } -.material-icons.em-1-5 { - font-size: 1.5em; +.material-icons.em-1-5 { + font-size: 1.5em; } -.location-box{ +.location-box { border-style: double; background-color: #7B2900; - min-width: 120px; - margin: 5px; - display: inline-block; - padding: 10px; - border-radius: 7px; - border-color: white; - border-width: 3px; + min-width: 120px; + margin: 5px; + display: inline-block; + padding: 10px; + border-radius: 7px; + border-color: white; + border-width: 3px; } -.location-box:hover{ +.location-box:hover { border-color: #FFD081; } \ No newline at end of file diff --git a/webAO/client.html b/webAO/client.html index 5a8bd0e..2343264 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -1,54 +1,56 @@ - - Attorney Online session - - - - + + + + Attorney Online session + + + + - - + + - - + + - +
        -

        They might be very busy. Are you sure?

        +

        + They might be very busy. Are you sure?

        - -
        -
        -

        Loading

        - -
        -
        - -
        -
        - + +
        +
        +

        Loading

        + +
        +
        + +
        +
        + + \ No newline at end of file diff --git a/webAO/client.js b/webAO/client.js index 18363aa..feafde3 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -1,11 +1,11 @@ /* * Glorious webAO - * made by sD, refactored by oldmud0 + * made by sD, refactored by oldmud0 and Qubrick * credits to aleks for original idea and source -*/ + */ let queryDict = {}; -location.search.substr(1).split("&").forEach(function(item) { +location.search.substr(1).split("&").forEach(function (item) { queryDict[item.split("=")[0]] = item.split("=")[1] }); @@ -35,43 +35,43 @@ class Client { constructor(address) { this.serv = new WebSocket("ws://" + address); - this.serv.onopen = (evt) => this.onOpen(evt); - this.serv.onclose = (evt) => this.onClose(evt); + this.serv.onopen = (evt) => this.onOpen(evt); + this.serv.onclose = (evt) => this.onClose(evt); this.serv.onmessage = (evt) => this.onMessage(evt); - this.serv.onerror = (evt) => this.onError(evt); - + this.serv.onerror = (evt) => this.onError(evt); + this.flip = false; this.presentable = false; - - this.hp = [0,0]; + + this.hp = [0, 0]; this.playerID = 1; this.charID = -1; this.testimonyID = 0; this.chars = []; - this.emotes = []; + this.emotes = []; this.evidences = []; - + this.resources = { - "holdit":{ + "holdit": { "src": "misc/holdit.gif", "duration": 720 }, - "objection":{ + "objection": { "src": "misc/objection.gif", "duration": 720 }, - "takethat":{ + "takethat": { "src": "misc/takethat.gif", "duration": 840 }, - "witnesstestimony":{ + "witnesstestimony": { "src": "misc/witnesstestimony.gif", "duration": 1560, "sfx": "sounds/general/sfx-testimony.wav" }, - "crossexamination":{ + "crossexamination": { "src": "misc/crossexamination.gif", "duration": 1600, "sfx": "sounds/general/sfx-testimony2.wav" @@ -87,29 +87,29 @@ class Client { this.musicList = Object(); this.handlers = { - "MS": (args) => this.handleMS(args), - "CT": (args) => this.handleCT(args), - "MC": (args) => this.handleMC(args), - "RMC": (args) => this.handleRMC(args), - "CI": (args) => this.handleCI(args), - "SC": (args) => this.handleSC(args), - "EI": (args) => this.handleEI(args), - "LE": (args) => this.handleLE(args), - "EM": (args) => this.handleEM(args), - "SM": (args) => this.handleSM(args), - "music": (args) => this.handlemusic(args), - "DONE": (args) => this.handleDONE(args), - "BN": (args) => this.handleBN(args), - "NBG": (args) => this.handleNBG(args), - "HP": (args) => this.handleHP(args), - "RT": (args) => this.handleRT(args), - "ZZ": (args) => this.handleZZ(args), - "ID": (args) => this.handleID(args), - "PN": (args) => this.handlePN(args), - "SI": (args) => this.handleSI(args), + "MS": (args) => this.handleMS(args), + "CT": (args) => this.handleCT(args), + "MC": (args) => this.handleMC(args), + "RMC": (args) => this.handleRMC(args), + "CI": (args) => this.handleCI(args), + "SC": (args) => this.handleSC(args), + "EI": (args) => this.handleEI(args), + "LE": (args) => this.handleLE(args), + "EM": (args) => this.handleEM(args), + "SM": (args) => this.handleSM(args), + "music": (args) => this.handlemusic(args), + "DONE": (args) => this.handleDONE(args), + "BN": (args) => this.handleBN(args), + "NBG": (args) => this.handleNBG(args), + "HP": (args) => this.handleHP(args), + "RT": (args) => this.handleRT(args), + "ZZ": (args) => this.handleZZ(args), + "ID": (args) => this.handleID(args), + "PN": (args) => this.handlePN(args), + "SI": (args) => this.handleSI(args), "CharsCheck": (args) => this.handleCharsCheck(args), - "PV": (args) => this.handlePV(args), - "CHECK": (args) => {} + "PV": (args) => this.handlePV(args), + "CHECK": (args) => {} } this._lastTimeICReceived = new Date(0); @@ -128,12 +128,12 @@ class Client { myEmote() { return this.emotes[this.selectedEmote]; } - + /** * Gets the player's currently selected evidence if presentable. */ myEvidence() { - return (this.presentable)? this.selectedEvidence : 0; + return this.presentable ? this.selectedEvidence : 0; } /** @@ -153,8 +153,12 @@ class Client { * @param {string} side the name of the side in the background * @param {string} ssfxname the name of the sound effect * @param {string} zoom whether or not to zoom - * @param {string} ssfxdelay the delay (in milliseconds) to play the sound effect + * @param {number} ssfxdelay the delay (in milliseconds) to play the sound effect * @param {string} objection the number of the shout to play + * @param {string} evidence the filename of evidence to show + * @param {number} flip change to 1 to reverse sprite for position changes + * @param {string} flash screen flash effect + * @param {string} color text color */ sendIC(speaking, name, silent, message, side, ssfxname, zoom, ssfxdelay, objection, evidence, flip, flash, color) { this.serv.send( @@ -163,7 +167,7 @@ class Client { `#${this.charID}#${ssfxdelay}#${selectedShout}#${evidence}#${flip}#${flash}#${color}#%` ); } - + /** * Sends add evidence command. * @param {string} evidence name @@ -173,10 +177,10 @@ class Client { sendPE(name, desc, img) { this.serv.send(`PE#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`); } - + /** * Sends edit evidence command. - * @param {string} evidence id + * @param {number} evidence id * @param {string} evidence name * @param {string} evidence description * @param {string} evidence image filename @@ -184,24 +188,24 @@ class Client { sendEE(id, name, desc, img) { this.serv.send(`EE#${id}#${escapeChat(encodeChat(name))}#${escapeChat(encodeChat(desc))}#${img}#%`); } - + /** * Sends delete evidence command. - * @param {string} evidence id + * @param {number} evidence id */ sendDE(id) { this.serv.send(`DE#${id}#%`); } - + /** * Sends health point command. - * @param {int} side the position - * @param {int} hp the health point + * @param {number} side the position + * @param {number} hp the health point */ - sendHP(side,hp) { + sendHP(side, hp) { this.serv.send(`HP#${side}#${hp}#%`); } - + /** * Sends call mod command. * @param {string} message to mod @@ -209,13 +213,13 @@ class Client { sendZZ(msg) { this.serv.send(`ZZ#${msg}#%`); } - + /** * Sends testimony command. * @param {string} testimony type */ sendRT(testimony) { - if(this.chars[this.charID].side == "jud"){ + if (this.chars[this.charID].side == "jud") { this.serv.send(`RT#${testimony}#%`); } } @@ -247,7 +251,7 @@ class Client { this.serv.send("ID#webAO#2.4.5#%"); this.checkUpdater = setInterval(() => this.sendCheck(), 5000); } - + /** * Load game resources. */ @@ -255,37 +259,37 @@ class Client { // Set to playerID to server chat name document.getElementById("OOC_name").value = "web" + this.playerID; // Load evidence array to select - var evidence_select = document.getElementById("evi_select"); + const evidence_select = document.getElementById("evi_select"); evidence_select.add(new Option("Custom", 0)); - for(let i = 1; i <= evidence_arr.length; i++) { - evidence_select.add(new Option(evidence_arr[i - 1])); - } + evidence_arr.forEach(evidence => { + evidence_select.add(new Option(evidence)); + }); // Load background array to select - var background_select = document.getElementById("bg_select"); + const background_select = document.getElementById("bg_select"); background_select.add(new Option("Custom", 0)); - for(let i = 1; i <= background_arr.length; i++) { - background_select.add(new Option(background_arr[i - 1])); - } + background_arr.forEach(background => { + background_select.add(new Option(background)); + }); // Calculate gif duration of shouts - let shouts = ["holdit", "objection", "takethat"]; + const shouts = ["holdit", "objection", "takethat"]; for (let i = 0; i < shouts.length; i++) { let shout_src = AO_HOST + this.resources[shouts[i]]["src"]; - FileExist(shout_src, this.callbackLoadImageResources, shouts[i]); + FileExist(shout_src, this.callbackLoadImageResources, shouts[i]); } - + // Calculate gif duration of testimony - let testimony = ["witnesstestimony", "crossexamination"]; + const testimony = ["witnesstestimony", "crossexamination"]; for (let i = 0; i < testimony.length; i++) { - let testimony_src = AO_HOST + "themes/default/"+ testimony[i] +".gif"; - // Check iamge existed + const testimony_src = `${AO_HOST}themes/default/${testimony[i]}.gif`; + // Check image existed FileExist(testimony_src, this.callbackLoadImageResources, testimony[i]); // Check sfx existed FileExist(AO_HOST + this.resources[testimony[i]]["sfx"], this.callbackLoadSFXResources, testimony[i]); - } + } // TODO: Cache some resources - + } - + /** * Callback for image resources. * @param {boolean} result the image is existed or not @@ -293,21 +297,21 @@ class Client { * @param {string} src the url of resource */ callbackLoadImageResources(result, resource, src) { - if(result){ + if (result) { client.resources[resource]["src"] = src; - viewport.getAnimLength(src,client.callbackGetResourceLength, resource); - } + viewport.getAnimLength(src, client.callbackGetResourceLength, resource); + } } - + /** * Callback for animation duration resource * @param {integer} length the animation length * @param {string} resource the resource name */ callbackGetResourceLength(length, resource) { - client.resources[resource]["duration"] = length; + client.resources[resource]["duration"] = length; } - + /** * Callback for sfx resources. * @param {boolean} result the audio is existed or not @@ -315,38 +319,41 @@ class Client { * @param {string} src the url of resource */ callbackLoadSFXResources(result, resource, src) { - if(result){ + if (result) { client.resources[resource]["sfx"] = src; - } - } - + } + } + /** * Create observer to detect BBCode elements * then manipulate them. */ initialObservBBCode() { - var target = document.getElementById("client_inner_chat"); - var observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - var children = mutation.addedNodes; - if (children !== null) { - children.forEach( function(node) { - if (node.tagName == "C") { - node.style.color = node.getAttribute("a"); - } else if(node.tagName == "M"){ - if (node.hasAttribute('a')) { - node.style.backgroundColor = node.getAttribute("a"); - } else { - node.style.backgroundColor = "yellow"; - node.style.color = "black"; + const target = document.getElementById("client_inner_chat"); + const observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + var children = mutation.addedNodes; + if (children !== null) { + children.forEach(function (node) { + if (node.tagName == "C") { + node.style.color = node.getAttribute("a"); + } else if (node.tagName == "M") { + if (node.hasAttribute('a')) { + node.style.backgroundColor = node.getAttribute("a"); + } else { + node.style.backgroundColor = "yellow"; + node.style.color = "black"; + } } - } - }); - } - }); + }); + } + }); }); - var config = {attributes: true,childList: true}; - observer.observe(target,config); + const config = { + attributes: true, + childList: true + }; + observer.observe(target, config); } /** @@ -436,6 +443,15 @@ class Client { clearInterval(this.checkUpdater); } + /** + * + * @param {string} msg chat message to prepare for display + */ + prepChat(msg){ + // TODO: make this less awful + return decodeBBCode(escapeHtml(decodeChat(unescapeChat(msg)))); + } + /** * Handles an in-character chat message. * @param {*} args packet arguments @@ -452,7 +468,7 @@ class Client { name: args[3], speaking: "(b)" + escape(args[4]), silent: "(a)" + escape(args[4]), - content: decodeBBCode(escapeHtml(decodeChat(unescapeChat(args[5])))), // Escape HTML tag, Use BBCode Only! + content: prepChat(args[5]), // Escape HTML tag, Use BBCode Only! side: args[6], sound: escape(args[7]), type: args[8], @@ -522,7 +538,7 @@ class Client { // Music offset + drift from song loading music.totime = args[1]; music.offset = new Date().getTime() / 1000; - music.addEventListener('loadedmetadata', function() { + music.addEventListener('loadedmetadata', function () { music.currentTime += parseFloat(music.totime + (new Date().getTime() / 1000 - music.offset)).toFixed(3); music.play(); }, false); @@ -580,7 +596,7 @@ class Client { //serv.send("AE#" + (args[1] + 1) + "#%"); this.serv.send("RM#%"); } - + /** * Handles incoming evidence list, all evidences at once * item per packet. @@ -590,7 +606,7 @@ class Client { handleLE(args) { this.evidences = []; for (let i = 1; i < args.length - 1; i++) { - var arg = args[i].split("&"); + const arg = args[i].split("&"); this.evidences[i - 1] = { "name": escapeHtml(decodeChat(unescapeChat(arg[0]))), "desc": escapeHtml(decodeChat(unescapeChat(arg[1]))), @@ -598,14 +614,15 @@ class Client { "icon": AO_HOST + "evidence/" + escape(arg[2]) } } - - var evidence_box = document.getElementById("evidences"); + + const evidence_box = document.getElementById("evidences"); evidence_box.innerHTML = ""; - for(let i = 1; i <= this.evidences.length; i++){ - evidence_box.innerHTML += '' + this.evidences[i - 1].name +
-				''; + for (let i = 1; i <= this.evidences.length; i++) { + evidence_box.innerHTML += `${this.evidences[i - 1].name}`; } } @@ -634,38 +651,41 @@ class Client { */ handleSM(args) { document.getElementById("client_loadingtext").innerHTML = "Loading Music "; - let hmusiclist = document.getElementById("client_musiclist"), flagAudio = false; - + const hmusiclist = document.getElementById("client_musiclist"); + let flagAudio = false; + for (let i = 1; i < args.length - 1; i++) { // Check when found the song for the first time - if(/\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){ + if (/\.(?:wav|mp3|mp4|ogg|opus)$/i.test(args[i]) && !flagAudio) { flagAudio = true; } - - if(flagAudio) { + + if (flagAudio) { // After reached the audio put everything in the music list let newentry = document.createElement("OPTION"); newentry.text = args[i]; hmusiclist.options.add(newentry); - + } else { // Create area button let newarea = document.createElement("SPAN"); newarea.className = "location-box"; - newarea.textContent = args[i]; - newarea.onclick = function(){ area_click(this) }; + newarea.textContent = args[i]; + newarea.onclick = function () { + area_click(this) + }; document.getElementById("areas").appendChild(newarea); } } - + // Move first audio title from area box to music list let area_box = document.getElementById("areas"); let audio_title = document.createElement("OPTION"); audio_title.text = area_box.lastChild.textContent; hmusiclist.insertBefore(audio_title, hmusiclist.firstChild); area_box.removeChild(area_box.lastChild); // Remove from arae box - - this.serv.send("RD#%"); + + this.serv.send("RD#%"); } /** @@ -696,19 +716,19 @@ class Client { */ handleBN(args) { viewport.bgname = escape(args[1]); - let bg_index = getIndexFromSelect("bg_select", escape(args[1])); + const bg_index = getIndexFromSelect("bg_select", escape(args[1])); document.getElementById("bg_select").selectedIndex = bg_index; updateBackgroundPreview(); - if(bg_index == 0){ + if (bg_index == 0) { document.getElementById("bg_filename").value = args[1]; } document.getElementById("bg_preview").src = AO_HOST + 'background/' + escape(args[1]) + "/defenseempty.png"; - if(this.charID == -1){ + if (this.charID == -1) { changeBackground("jud"); } else { changeBackground(this.chars[this.charID].side); } - + } handleNBG(args) { @@ -720,18 +740,22 @@ class Client { * @param {Array} args packet arguments */ handleHP(args) { - let percent_hp = args[2] * 10; + const percent_hp = args[2] * 10; if (args[1] == 1) { // Def hp this.hp[0] = args[2]; - $("#client_defense_hp > .health-bar").animate({ 'width': percent_hp + "%" }, 500); + $("#client_defense_hp > .health-bar").animate({ + 'width': percent_hp + "%" + }, 500); } else { // Pro hp this.hp[1] = args[2]; - $("#client_prosecutor_hp > .health-bar").animate({ 'width': percent_hp + "%" }, 500); - } + $("#client_prosecutor_hp > .health-bar").animate({ + 'width': percent_hp + "%" + }, 500); + } } - + /** * Handles a testimony states. * @param {Array} args packet arguments @@ -746,7 +770,7 @@ class Client { } viewport.initTestimonyUpdater(); } - + /** * Handles a call mod message. * @param {Array} args packet arguments @@ -758,7 +782,7 @@ class Client { oocLog.scrollTop = oocLog.scrollHeight; } } - + /** * Handles the issuance of a player ID by the server. * @param {Array} args packet arguments @@ -809,7 +833,7 @@ class Client { if (i % CHAR_SELECT_WIDTH == 0) { document.getElementById("client_chartable").appendChild(tr); } - } + } //changeBackground("def"); } @@ -823,7 +847,6 @@ class Client { let me = this.me(); let emotes = this.emotes; let xhr = new XMLHttpRequest(); - let isOfficialAssets = (AO_HOST == "http://assets.aceattorneyonline.com/base/"); xhr.withCredentials = false; document.getElementById("client_emo").innerHTML = ""; // Clear emote box xhr.open('GET', AO_HOST + 'characters/' + escape(this.me().name) + '/char.ini', true); @@ -844,23 +867,29 @@ class Client { if (typeof pinifile.SoundT !== 'undefined') { esfxd = pinifile.SoundT[i]; } + // Make sure the asset server is case insensitive, or that everything on it is lowercase emotes[i] = { - desc: (isOfficialAssets)? emoteinfo[0].toLowerCase() : emoteinfo[0], - speaking: (isOfficialAssets)? emoteinfo[1].toLowerCase() : emoteinfo[1], - silent: (isOfficialAssets)? emoteinfo[2].toLowerCase() : emoteinfo[2], + desc: emoteinfo[0].toLowerCase(), + speaking: emoteinfo[1].toLowerCase(), + silent: emoteinfo[2].toLowerCase(), zoom: emoteinfo[3], - sfx: (isOfficialAssets)? esfx.toLowerCase() : esfx, + sfx: esfx.toLowerCase(), sfxdelay: esfxd, - button_off: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_off.png', - button_on: AO_HOST + 'characters/' + ((isOfficialAssets)? escape(me.name).toLowerCase() : escape(me.name)) + '/emotions/button' + i + '_on.png' + button_off: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_off.png`, + button_on: AO_HOST + `'characters/${escape(me.name).toLowerCase()}/emotions/button${i}_on.png` }; - document.getElementById("client_emo").innerHTML += "" + emotes[i].desc + ""; + document.getElementById("client_emo").innerHTML += + `${emotes[i].desc}`; } pickemotion(1); } }; xhr.send(); - } + } } class Viewport { @@ -901,7 +930,7 @@ class Viewport { this.testimonyUpdater = null; this.bgname = "gs4"; - + this.testimonyTimer = 0; this.shoutTimer = 0; this.textTimer = 0; @@ -949,39 +978,39 @@ class Viewport { clearTimeout(this.updater); //If preanim existed then determine the length if (chatmsg.preanim != "-") { - chatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater); + chatmsg.preanimdelay = this.getAnimLength(`${AO_HOST}characters/${escape(chatmsg.name)}/${chatmsg.preanim}.gif`, this.initUpdater); } else { - this.initUpdater(0) + this.initUpdater(0); } } - + /** * Intialize updater - * @param {int} animdelay the length of pre-animation + * @param {number} animdelay the length of pre-animation */ - initUpdater(animdelay){ - viewport.chatmsg.preanimdelay = parseInt(animdelay); + initUpdater(animdelay) { + viewport.chatmsg.preanimdelay = parseInt(animdelay); viewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL); } - + /** * Intialize testimony updater */ - initTestimonyUpdater(){ - if(client.testimonyID > 0){ + initTestimonyUpdater() { + if (client.testimonyID > 0) { let testimony = ""; if (client.testimonyID == 1) { - testimony = "witnesstestimony"; + testimony = "witnesstestimony"; } else if (client.testimonyID == 2) { testimony = "crossexamination"; } (new Audio(client.resources[testimony]["sfx"])).play(); this.testimonyTimer = 0; document.getElementById("client_testimony").src = client.resources[testimony]["src"]; - this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); + this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); } } - + /** * Gets animation length. * @param {string} filename the animation file name @@ -1002,25 +1031,25 @@ class Viewport { }); request.send(); } - + /** * Updates the testimony overaly */ - updateTestimony(){ + updateTestimony() { //Update timer this.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL; - + if (client.testimonyID == 1) { //Witness Testimony - if (this.testimonyTimer >= client.resources["witnesstestimony"]["duration"]){ + if (this.testimonyTimer >= client.resources["witnesstestimony"]["duration"]) { //Finish this.disposeTestimony(); } else { this.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL); - } + } } else if (client.testimonyID == 2) { //Cross Examination - if (this.testimonyTimer >= client.resources["crossexamination"]["duration"]){ + if (this.testimonyTimer >= client.resources["crossexamination"]["duration"]) { //Finish this.disposeTestimony(); } else { @@ -1030,17 +1059,17 @@ class Viewport { this.disposeTestimony(); } } - + /** * Dispose the testimony overlay */ - disposeTestimony(){ + disposeTestimony() { client.testimonyID = 0; this.testimonyTimer = 0; document.getElementById("client_testimony").src = "misc/placeholder.gif"; clearTimeout(this.testimonyUpdater); - } - + } + /** * Updates the chatbox based on the given text. * @@ -1048,12 +1077,12 @@ class Viewport { */ updateText() { // Flip the character - if (this.chatmsg.flip == 1){ - document.getElementById("client_char").style.transform = "scaleX(-1)"; + if (this.chatmsg.flip == 1) { + document.getElementById("client_char").style.transform = "scaleX(-1)"; } else { document.getElementById("client_char").style.transform = "scaleX(1)"; } - + if (this._animating) { this.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL); } @@ -1085,15 +1114,17 @@ class Viewport { this.chatmsg.startpreanim = true; } - if(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) { + if (this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) { // Effect stuff - if (this.chatmsg.flash == 2){ + if (this.chatmsg.flash == 2) { //Shake screen this.sfxaudio.pause(); this.sfxplayed = 1; this.sfxaudio.src = AO_HOST + "sounds/general/sfx-stab.wav"; this.sfxaudio.play(); - $('#client_gamewindow').effect( "shake",{"direction":"up"}); + $('#client_gamewindow').effect("shake", { + "direction": "up" + }); } else if (this.chatmsg.flash == 1) { //Flash screen document.getElementById("client_background").style.backgroundColor = "white"; @@ -1103,9 +1134,9 @@ class Viewport { this.sfxaudio.play(); $('#client_gamewindow').effect("pulsate"); } - + //Pre-animation stuff - if(this.chatmsg.preanimdelay > 0){ + if (this.chatmsg.preanimdelay > 0) { document.getElementById("client_shout").src = "misc/placeholder.gif"; changeBackground(this.chatmsg.side); document.getElementById("client_char").src = AO_HOST + "characters/" + escape(this.chatmsg.name) + "/" + this.chatmsg.preanim + ".gif"; @@ -1114,31 +1145,33 @@ class Viewport { this.chatmsg.startspeaking = true; } else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) { if (this.chatmsg.startspeaking) { - if(this.chatmsg.evidence > 0){ + if (this.chatmsg.evidence > 0) { // Prepare evidence - document.getElementById("client_evi").style.backgroundImage = "url('"+ client.evidences[this.chatmsg.evidence - 1].icon +"')"; - - if (this.chatmsg.side == 'def'){ + document.getElementById("client_evi").style.backgroundImage = "url('" + client.evidences[this.chatmsg.evidence - 1].icon + "')"; + + if (this.chatmsg.side == 'def') { // Only def show evidence on right document.getElementById("client_evi").style.right = "1.5em"; document.getElementById("client_evi").style.left = "initial"; - $( "#client_evi" ).animate({ + $("#client_evi").animate({ height: "30%", opacity: 1 - }, 250 ); + }, 250); } else { document.getElementById("client_evi").style.right = "initial"; document.getElementById("client_evi").style.left = "1.5em"; - $( "#client_evi" ).animate({ + $("#client_evi").animate({ height: "30%", opacity: 1 - }, 250 ); + }, 250); } } - - $("#client_name").toggle( "fade" ); - $("#client_chat").toggle("drop",{"direction":"down"}); - if(this.chatmsg.preanimdelay == 0){ + + $("#client_name").toggle("fade"); + $("#client_chat").toggle("drop", { + "direction": "down" + }); + if (this.chatmsg.preanimdelay == 0) { document.getElementById("client_shout").src = "misc/placeholder.gif"; changeBackground(this.chatmsg.side); } @@ -1183,7 +1216,7 @@ class Viewport { } } } - + if (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) { this.sfxaudio.pause(); this.sfxplayed = 1; @@ -1206,7 +1239,7 @@ class INI { let value = {}; let lines = data.split(/\r\n|\r|\n/); let section = null; - lines.forEach(function(line) { + lines.forEach(function (line) { if (regex.comment.test(line)) { return; } else if (line.length == 0) { @@ -1249,7 +1282,7 @@ export function onEnter(event) { let mychar = client.me(); let myemo = client.myEmote(); let myevi = client.myEvidence(); - let myflip = ((client.flip)? 1:0); + let myflip = ((client.flip) ? 1 : 0); let mycolor = document.getElementById("textcolor").value; let ssfxname = "0"; let ssfxdelay = "0"; @@ -1276,7 +1309,7 @@ function resetICParams() { if (selectedShout) { document.getElementById("button_" + selectedShout).className = "client_button"; selectedShout = 0; - } + } } /** @@ -1294,7 +1327,7 @@ window.musiclist_click = musiclist_click; * @param {MouseEvent} event */ export function area_click(el) { - let playtrack = el.textContent; + let playtrack = el.textContent; client.sendMusicChange(playtrack); } window.area_click = area_click; @@ -1357,14 +1390,14 @@ export function demoError(image) { window.demoError = demoError; /** - * Checks if an file exists at the specified URI. + * Checks if a file exists at the specified URI. * @param {string} url the URI to be checked * @param {function} callback the function to be called when finished * @param {object} param */ -function FileExist(url,callback,param) { +function fileExists(url, callback, param) { var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function() { + xhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { callback(true, param, url); } else { @@ -1431,20 +1464,20 @@ function changeBackground(position) { * @param {boolean} result the image is existed or not * @param {string} position the position to change into */ -function callbackChangeBackground(result,position) { +function callbackChangeBackground(result, position) { let bgfolder = viewport.bgFolder(); - if (position == "def"){ - if(result){ + if (position == "def") { + if (result) { document.getElementById("client_bench").src = bgfolder + "defensedesk.png" - }else{ + } else { document.getElementById("client_bench").src = bgfolder + "bancodefensa.png" } } else { - if(result){ + if (result) { document.getElementById("client_bench").src = bgfolder + "prosecutiondesk.png" } else { document.getElementById("client_bench").src = bgfolder + "bancoacusacion.png" - } + } } } @@ -1507,7 +1540,7 @@ function appendICLog(toadd, name = "", time = new Date()) { * Requests to play as a character. * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead. */ -export function pickchar(ccharacter) { +export function pickChar(ccharacter) { if (ccharacter < 1000) { client.sendCharacter(ccharacter); } else { @@ -1517,46 +1550,46 @@ export function pickchar(ccharacter) { document.getElementById("client_emo").style.display = "none"; } } -window.pickchar = pickchar; +window.pickChar = pickChar; /** * Highlights and selects an emotion for in-character chat. * @param {string} emo the new emotion to be selected */ -export function pickemotion(emo) { +export function pickEmotion(emo) { if (client.selectedEmote != -1) { document.getElementById("emo_" + client.selectedEmote).src = client.myEmote().button_off; } client.selectedEmote = emo document.getElementById("emo_" + emo).src = client.myEmote().button_on; } -window.pickemotion = pickemotion; +window.pickEmotion = pickEmotion; /** * Highlights and selects an evidence for in-character chat. * @param {string} evidence the evidence to be presented */ -export function pickevidence(evidence) { - if (client.selectedEvidence != evidence) { +export function pickEvidence(evidence) { + if (client.selectedEvidence !== evidence) { //Update selected evidence - if(client.selectedEvidence > 0){ + if (client.selectedEvidence > 0) { document.getElementById("evi_" + client.selectedEvidence).className = "client_button"; } document.getElementById("evi_" + evidence).className = "client_button dark"; client.selectedEvidence = evidence; - + // Show evidence on information window document.getElementById("evi_name").value = client.evidences[evidence - 1].name; document.getElementById("evi_desc").value = client.evidences[evidence - 1].desc; //Update Icon - let icon_id = getIndexFromSelect("evi_select", client.evidences[evidence - 1].filename); + let icon_id = getIndexFromSelect("evi_select", client.evidences[evidence - 1].filename); document.getElementById("evi_select").selectedIndex = icon_id; - if (icon_id == 0){ + if (icon_id == 0) { document.getElementById("evi_filename").value = client.evidences[evidence - 1].filename; } updateEvidenceIcon(); - + // Update button document.getElementById("evi_add").className = "client_button hover_button inactive"; document.getElementById("evi_edit").className = "client_button hover_button"; @@ -1566,60 +1599,60 @@ export function pickevidence(evidence) { cancelevidence(); } } -window.pickevidence = pickevidence; +window.pickEvidence = pickEvidence; /** * Add evidence. */ -export function addevidence() { +export function addEvidence() { let evidence_select = document.getElementById('evi_select'); - client.sendPE( document.getElementById('evi_name').value, + client.sendPE(document.getElementById('evi_name').value, document.getElementById('evi_desc').value, - (evidence_select.selectedIndex == 0)? - document.getElementById('evi_filename').value : - evidence_select.options[evidence_select.selectedIndex].text - ); + (evidence_select.selectedIndex == 0) ? + document.getElementById('evi_filename').value : + evidence_select.options[evidence_select.selectedIndex].text + ); cancelevidence(); } -window.addevidence = addevidence; +window.addEvidence = addEvidence; /** * Edit selected evidence. */ -export function editevidence() { +export function editEvidence() { let evidence_select = document.getElementById('evi_select'); let id = parseInt(client.selectedEvidence) - 1; - client.sendEE( id, + client.sendEE(id, document.getElementById('evi_name').value, document.getElementById('evi_desc').value, - (evidence_select.selectedIndex == 0)? - document.getElementById('evi_filename').value : - evidence_select.options[evidence_select.selectedIndex].text - ); + (evidence_select.selectedIndex == 0) ? + document.getElementById('evi_filename').value : + evidence_select.options[evidence_select.selectedIndex].text + ); cancelevidence(); } -window.editevidence = editevidence; +window.editEvidence = editEvidence; /** * Delete selected evidence. */ -export function delevidence() { +export function deleteEvidence() { let id = parseInt(client.selectedEvidence) - 1; client.sendDE(id); cancelevidence(); } -window.delevidence = delevidence; +window.deleteEvidence = deleteEvidence; /** * Cancel evidence selection. */ -export function cancelevidence() { +export function cancelEvidence() { //Clear evidence data - if(client.selectedEvidence > 0){ + if (client.selectedEvidence > 0) { document.getElementById("evi_" + client.selectedEvidence).className = "client_button"; } client.selectedEvidence = 0; - + // Clear evidence on information window document.getElementById("evi_select").selectedIndex = 0; updateEvidenceIcon(); // Update icon widget @@ -1627,14 +1660,14 @@ export function cancelevidence() { document.getElementById("evi_name").value = ""; document.getElementById("evi_desc").value = ""; document.getElementById("evi_icon").style.backgroundImage = "url('misc/empty.png')"; //Clear icon - + // Update button 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"; } -window.cancelevidence = cancelevidence; +window.cancelEvidence = cancelEvidence; /** * Find index of anything in select box. @@ -1642,14 +1675,14 @@ window.cancelevidence = cancelevidence; * @param {string} value the value that need to be compared */ export function getIndexFromSelect(select_box, value) { - //Find if icon alraedy existed in select box - let select_element = document.getElementById(select_box); - for (let i = 1; i < select_element.length; ++i){ - if (select_element.options[i].value == value){ - return i; - } + //Find if icon alraedy existed in select box + let select_element = document.getElementById(select_box); + for (let i = 1; i < select_element.length; ++i) { + if (select_element.options[i].value == value) { + return i; } - return 0; + } + return 0; } window.getIndexFromSelect = getIndexFromSelect; @@ -1660,13 +1693,13 @@ export function updateEvidenceIcon() { let evidence_select = document.getElementById("evi_select"); let evidence_filename = document.getElementById("evi_filename"); let evidence_iconbox = document.getElementById("evi_icon"); - - if (evidence_select.selectedIndex == 0) { + + if (evidence_select.selectedIndex === 0) { evidence_filename.style.display = "initial"; - evidence_iconbox.style.backgroundImage = "url('" + AO_HOST + 'evidence/' + evidence_filename.value + "')"; - } else { + evidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_filename.value})`; + } else { evidence_filename.style.display = "none"; - evidence_iconbox.style.backgroundImage = "url('" + AO_HOST + 'evidence/' + evidence_select.value + "')" ; + evidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_select.value})`; } } window.updateEvidenceIcon = updateEvidenceIcon; @@ -1675,7 +1708,7 @@ window.updateEvidenceIcon = updateEvidenceIcon; * Update evidence icon. */ export function updateActionCommands(side) { - if(side == "jud"){ + if (side == "jud") { document.getElementById("judge_action").style.display = "inline-table"; document.getElementById("no_action").style.display = "none"; } else { @@ -1683,11 +1716,11 @@ export function updateActionCommands(side) { 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++){ - if(side == role_select[i].value){ - role_select.selectedIndex = i; - return; - } + for (let i = 0, role_select = document.getElementById("role_select").options; i < role_select.length; i++) { + if (side == role_select[i].value) { + role_select.selectedIndex = i; + return; + } } } window.updateActionCommands = updateActionCommands; @@ -1696,14 +1729,15 @@ window.updateActionCommands = updateActionCommands; * Change background via OOC. */ export function changeBackgroundOOC() { - let filename = "", background_select = document.getElementById("bg_select") - , bg_command = document.getElementById("bg_command").value; + let filename = "", + background_select = document.getElementById("bg_select"), + bg_command = document.getElementById("bg_command").value; if (background_select.selectedIndex == 0) { - filename = document.getElementById("bg_filename").value; - } else{ + filename = document.getElementById("bg_filename").value; + } else { filename = background_select.value; } - client.sendOOC("/" + bg_command.replace("$1",filename)); + client.sendOOC("/" + bg_command.replace("$1", filename)); } window.changeBackgroundOOC = changeBackgroundOOC; @@ -1711,10 +1745,10 @@ window.changeBackgroundOOC = changeBackgroundOOC; * Change role via OOC. */ export function changeRoleOOC() { - let role_select = document.getElementById("role_select") - , role_command = document.getElementById("role_command").value; - - client.sendOOC("/" + role_command.replace("$1",role_select.value)); + let role_select = document.getElementById("role_select"), + role_command = document.getElementById("role_command").value; + + client.sendOOC("/" + role_command.replace("$1", role_select.value)); updateActionCommands(role_select.value); } window.changeRoleOOC = changeRoleOOC; @@ -1722,7 +1756,7 @@ window.changeRoleOOC = changeRoleOOC; /** * Random character via OOC. */ -export function randomCharacterOOC() { +export function randomCharacterOOC() { client.sendOOC("/" + document.getElementById("randomchar_command").value); } window.randomCharacterOOC = randomCharacterOOC; @@ -1730,56 +1764,56 @@ window.randomCharacterOOC = randomCharacterOOC; /** * Call mod. */ -export function callmod() { - $( "#callmod_dialog" ).dialog( "open" ); +export function callMod() { + $("#callmod_dialog").dialog("open"); } -window.callmod = callmod; +window.callMod = callMod; /** - * Decalre witness testimony. + * Declare witness testimony. */ -export function initwt() { +export function initWT() { client.sendRT("testimony1"); } -window.initwt = initwt; +window.initWT = initWT; /** - * Decalre cross examination. + * Declare cross examination. */ -export function initce() { +export function initCE() { client.sendRT("testimony2"); } -window.initce = initce; +window.initCE = initCE; /** - * Add defense health point. + * Increment defense health point. */ -export function addHPD() { - client.sendHP(1,String(parseInt(client.hp[0]) + 1)); +export function addHPD() { + client.sendHP(1, String(parseInt(client.hp[0]) + 1)); } window.addHPD = addHPD; /** - * Reduce defense health point. + * Decrement defense health point. */ -export function redHPD() { - client.sendHP(1,String(parseInt(client.hp[0]) - 1)); +export function redHPD() { + client.sendHP(1, String(parseInt(client.hp[0]) - 1)); } window.redHPD = redHPD; /** - * Add prosecution health point. + * Increment prosecution health point. */ -export function addHPP() { - client.sendHP(2,String(parseInt(client.hp[1]) + 1)); +export function addHPP() { + client.sendHP(2, String(parseInt(client.hp[1]) + 1)); } window.addHPP = addHPP; /** - * Reduce prosecution health point. + * Decrement prosecution health point. */ -export function redHPP() { - client.sendHP(2,String(parseInt(client.hp[1]) - 1)); +export function redHPP() { + client.sendHP(2, String(parseInt(client.hp[1]) - 1)); } window.redHPP = redHPP; @@ -1790,7 +1824,7 @@ export function updateBackgroundPreview() { let background_select = document.getElementById("bg_select"); let background_filename = document.getElementById("bg_filename"); let background_preview = document.getElementById("bg_preview"); - + if (background_select.selectedIndex == 0) { background_filename.style.display = "initial"; background_preview.src = AO_HOST + 'background/' + background_filename.value + "/defenseempty.png"; @@ -1806,7 +1840,7 @@ window.updateBackgroundPreview = updateBackgroundPreview; * If the same effect button is selected, then the effect is canceled. * @param {string} effect the new effect to be selected */ -export function toggleaffect(effect) { +export function toggleEffect(effect) { if (effect == selectedEffect) { document.getElementById("button_effect_" + effect).className = "client_button"; selectedEffect = 0; @@ -1818,12 +1852,12 @@ export function toggleaffect(effect) { selectedEffect = effect; } } -window.toggleaffect = toggleaffect; +window.toggleEffect = toggleEffect; /** * Toggle flip for in-character chat. */ -export function toggleflip() { +export function toggleFlip() { if (client.flip) { document.getElementById("button_flip").className = "client_button"; } else { @@ -1831,12 +1865,12 @@ export function toggleflip() { } client.flip = !client.flip; } -window.toggleflip = toggleflip; +window.toggleFlip = toggleFlip; /** * Toggle presentable for presenting evidence in-character chat. */ -export function togglepresent() { +export function togglePresent() { if (client.presentable) { document.getElementById("button_present").className = "client_button"; } else { @@ -1844,13 +1878,13 @@ export function togglepresent() { } client.presentable = !client.presentable; } -window.togglepresent = togglepresent; +window.togglePresent = togglePresent; /** * Highlights and selects a menu. * @param {string} menu the menu to be selected */ -export function togglemenu(menu) { +export function toggleMenu(menu) { if (menu != selectedMenu) { document.getElementById("menu_" + menu).className = "menu_icon active"; document.getElementById("content_" + menu).className = "menu_content active"; @@ -1859,14 +1893,14 @@ export function togglemenu(menu) { selectedMenu = menu; } } -window.togglemenu = togglemenu; +window.toggleMenu = toggleMenu; /** * Highlights and selects a shout for in-character chat. * If the same shout button is selected, then the shout is canceled. * @param {string} shout the new shout to be selected */ -export function toggleshout(shout) { +export function toggleShout(shout) { if (shout == selectedShout) { document.getElementById("button_" + shout).className = "client_button"; selectedShout = 0; @@ -1878,7 +1912,7 @@ export function toggleshout(shout) { selectedShout = shout; } } -window.toggleshout = toggleshout; +window.toggleShout = toggleShout; /** * Escapes a string to be HTML-safe. @@ -1927,13 +1961,14 @@ function encodeChat(estring) { let selectedEncoding = document.getElementById("client_encoding").value; if (selectedEncoding == "unicode") { //Source: https://gist.github.com/mathiasbynens/1243213 - return estring.replace(/[^\0-~]/g, function(ch) { - return "\\u" + ("000" + ch.charCodeAt().toString(16)).slice(-4); }); - } else if (selectedEncoding == "utf16"){ + return estring.replace(/[^\0-~]/g, function (ch) { + return "\\u" + ("000" + ch.charCodeAt().toString(16)).slice(-4); + }); + } else if (selectedEncoding == "utf16") { //Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String - var buffer = new ArrayBuffer(estring.length*2); + var buffer = new ArrayBuffer(estring.length * 2); var result = new Uint16Array(buffer); - for (var i=0, strLen=estring.length; i < strLen; i++) { + for (var i = 0, strLen = estring.length; i < strLen; i++) { result[i] = estring.charCodeAt(i); } return String(result); @@ -1950,9 +1985,10 @@ function decodeChat(estring) { let selectedDecoding = document.getElementById("client_decoding").value; if (selectedDecoding == "unicode") { //Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode - return estring.replace(/\\u([\d\w]{1,})/gi, function (match, group) { - return String.fromCharCode(parseInt(group, 16)); } ); - } else if (selectedDecoding == "utf16"){ + return estring.replace(/\\u([\d\w]{1,})/gi, function (match, group) { + return String.fromCharCode(parseInt(group, 16)); + }); + } else if (selectedDecoding == "utf16") { //Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String return String.fromCharCode.apply(null, new Uint16Array(estring.split(","))); } else { @@ -1981,22 +2017,21 @@ function decodeBBCode(estring) { // TODO: Possibly safe to remove, since we are using a transpiler. -if (typeof(String.prototype.trim) === "undefined") -{ - String.prototype.trim = function() - { - return String(this).replace(/^\s+|\s+$/g, ''); - }; +if (typeof (String.prototype.trim) === "undefined") { + String.prototype.trim = function () { + return String(this).replace(/^\s+|\s+$/g, ''); + }; } // Used for HDID calculation. -String.prototype.hashCode = function() { - var hash = 0, i, chr; +String.prototype.hashCode = function () { + var hash = 0, + i, chr; if (this.length === 0) return hash; for (i = 0; i < this.length; i++) { - chr = this.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer } return hash; }; @@ -2009,37 +2044,37 @@ String.prototype.hashCode = function() { let client = new Client(serverIP); let viewport = new Viewport(); -$(document).ready(function(){ +$(document).ready(function () { client.initialObservBBCode(); - client.loadResources(); - + client.loadResources(); + }); // Create dialog and link to button -$( function() { - $( "#callmod_dialog" ).dialog({ +$(function () { + $("#callmod_dialog").dialog({ autoOpen: false, resizable: false, show: { effect: "drop", - direction:"down", + direction: "down", duration: 500 }, hide: { effect: "drop", - direction:"down", + direction: "down", duration: 500 }, height: "auto", width: 400, modal: true, buttons: { - "Sure": function() { + Sure: function () { client.sendZZ(""); - $( this ).dialog( "close" ); + $(this).dialog("close"); }, - Cancel: function() { - $( this ).dialog( "close" ); + Cancel: function () { + $(this).dialog("close"); } } }); diff --git a/webAO/ui.js b/webAO/ui.js index 56e0dcd..557ca4a 100644 --- a/webAO/ui.js +++ b/webAO/ui.js @@ -8,65 +8,66 @@ var config = { dimensions: { minItemHeight: 40 }, - content: [ - { + content: [{ type: "row", - content: [ - { + content: [{ type: "column", width: 40, - content: [ - { - type: "component", - componentName: "template", - title: "Game", - componentState: { id: "client_wrapper" } + content: [{ + type: "component", + componentName: "template", + title: "Game", + componentState: { + id: "client_wrapper" } - ] + }] }, { type: "column", - content: [ - { + content: [{ type: "row", - height: 65, - content: [ - { - type: "stack", - content: [ - { - type: "component", - title: "Main", - componentName: "template", - componentState: { id: "mainmenu" } - }, - { - type: "component", - title: "Log", - componentName: "template", - componentState: { id: "log" } - } - ] - }, - { + height: 65, + content: [{ + type: "stack", + content: [{ + type: "component", + title: "Main", + componentName: "template", + componentState: { + id: "mainmenu" + } + }, + { + type: "component", + title: "Log", + componentName: "template", + componentState: { + id: "log" + } + } + ] + }, + { type: "component", title: "Music", - width: 30, + width: 30, componentName: "template", - componentState: { id: "music" } - } - ] + componentState: { + id: "music" + } + } + ] }, { type: "row", - content: [ - { - type: "component", - title: "Server chat", - componentName: "template", - componentState: { id: "ooc" } - } - ] + content: [{ + type: "component", + title: "Server chat", + componentName: "template", + componentState: { + id: "ooc" + } + }] } ] } @@ -75,7 +76,7 @@ var config = { }; var golden = new GoldenLayout(config); -golden.registerComponent("template", function(container, componentState) { +golden.registerComponent("template", function (container, componentState) { let template = document.querySelector(`#${componentState.id}`); container.getElement().html(template.content); // TODO: support multiple locales -- cgit From 077fcf719b1a9383b4170f33a77c95024d6f7188 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Mon, 3 Sep 2018 22:48:46 -0500 Subject: Continue code cleanup --- .eslintrc.js | 36 +++++++++++ webAO/client.html | 46 +++++++------- webAO/client.js | 176 +++++++++++++++++++++++++++--------------------------- 3 files changed, 148 insertions(+), 110 deletions(-) create mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..c3c75e8 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,36 @@ +module.exports = { + "env": { + "browser": true, + "es6": true, + "jquery": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 2016, + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "warn", + "double" + ], + "semi": [ + "error", + "always" + ], + "no-console": [ + "off" + ], + "no-unused-vars": [ + "warn" + ] + } +}; \ No newline at end of file diff --git a/webAO/client.html b/webAO/client.html index 2343264..3db7762 100644 --- a/webAO/client.html +++ b/webAO/client.html @@ -55,9 +55,9 @@
        - Hold it! - OBJECTION! - Take That! + Hold it! + OBJECTION! + Take That!

        @@ -75,21 +75,21 @@

        - Flip + Flip - Flash - Shake + Flash + Shake
        Action Commands

        - + report
        Call Mod
        @@ -130,23 +130,23 @@
        ↓ Main Menu ↓
        - + work
        Evidence
        - + room
        Location
        - + settings
        Settings
        - + description
        Guide
        - + person
        About
        @@ -176,16 +176,16 @@

        - Add Evidence - Edit Evidence - Cancel Evidence - Remove Evidence + Add Evidence + Edit Evidence + Cancel Evidence + Remove Evidence

        - Present + Present
        @@ -341,9 +341,11 @@ -
        +

        - They might be very busy. Are you sure?

        + + Are you sure you want to call a moderator? +

        @@ -354,7 +356,7 @@
        - +
        - +
        @@ -74,14 +71,12 @@

        - Flip - Flash Shake
        - Action Commands + Actions
        - -
        +
        +
        + +
        '),s.childElementContainer=s.element,s._splitterSize=t.config.dimensions.borderWidth,s._splitterGrabSize=t.config.dimensions.borderGrabWidth,s._isColumn=e,s._dimension=e?"height":"width",s._splitter=[],s._splitterPosition=null,s._splitterMinPosition=null,s._splitterMaxPosition=null,s}return l(i,h.a),s(i,[{key:"addChild",value:function(e,t,i){var o,s,r,a;if(e=this.layoutManager._$normalizeContentItem(e,this),void 0===t&&(t=this.contentItems.length),0this.contentItems.length-this._isDocked())throw new Error("Can't dock child when it is last in "+this.config.type);var u={column:{first:"top",last:"bottom"},row:{first:"left",last:"right"}}[this.config.type][r?"last":"first"];e.header.position()!=u&&e.header.position(u),this._splitter[a]&&this._splitter[a].element.hide();var d=this._isDocked();for(l=0;lr(t)&&0=this.contentItems.length)){o=this._calculateAbsoluteSizes();for(var d=0;da)){for(e=l/a,c=l,d=0;dthis._splitterMinPosition&&ithis._nDistance||t(this._nY)>this._nDistance)&&(clearTimeout(this._timeout),this._startDrag()),this._bDragging&&this.emit("drag",this._nX,this._nY,e)}}},{key:"onMouseUp",value:function(e){null!=this._timeout&&(clearTimeout(this._timeout),this._eBody.removeClass("lm_dragging"),this._eElement.removeClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events",""),this._oDocument.unbind("mousemove touchmove",this._fMove),this._oDocument.unbind("mouseup touchend",this._fUp),!0===this._bDragging&&(this._bDragging=!1,this.emit("dragStop",e,this._nOriginalX+this._nX)))}},{key:"_startDrag",value:function(){this._bDragging=!0,this._eBody.addClass("lm_dragging"),this._eElement.addClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events","none"),this.emit("dragStart",this._nOriginalX,this._nOriginalY)}},{key:"_getCoordinates",value:function(e){return{x:(e=Object(o.e)(e)).pageX,y:e.pageY}}}]),t}();t.a=r},function(e,t,n){var i=n(9);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e){e.exports=function(e){return"object"==(void 0===e?"undefined":r(e))?null!==e:"function"==typeof e}},function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var i=n(0);t.a=function(){function e(){if(c(this,e),this._keys=["settings","hasHeaders","constrainDragToContainer","selectionEnabled","dimensions","borderWidth","minItemHeight","minItemWidth","headerHeight","dragProxyWidth","dragProxyHeight","labels","close","maximise","minimise","popout","content","componentName","componentState","id","width","type","height","isClosable","title","popoutWholeStack","openPopouts","parentId","activeItemIndex","reorderEnabled","borderGrabWidth"],36'),o.childElementContainer=o.element,o._containerElement=i,o._containerElement.append(o.element),o}return l(t,i.a),s(t,[{key:"addChild",value:function(e){if(0'),o._activeContentItem=null;var s=e.config;return o._header={show:!0===s.settings.hasHeaders&&!1!==t.hasHeaders,popout:s.settings.showPopoutIcon&&s.labels.popout,maximise:s.settings.showMaximiseIcon&&s.labels.maximise,close:s.settings.showCloseIcon&&s.labels.close,minimise:s.labels.minimise},s.header&&Object(d.b)(o._header,s.header),t.header&&Object(d.b)(o._header,t.header),t.content&&t.content[0]&&t.content[0].header&&Object(d.b)(o._header,t.content[0].header),o._dropZones={},o._dropSegment=null,o._contentAreaDimensions=null,o._dropIndex=null,o.isStack=!0,o.childElementContainer=$('
        '),o.header=new u.a(e,o),o.element.on("mouseleave mouseenter",Object(d.c)(function(e){this._docker&&this._docker.docked&&this.childElementContainer[this._docker.dimension]("mouseenter"==e.type?this._docker.realSize:0)},o)),o.element.append(o.header.element),o.element.append(o.childElementContainer),o._setupHeaderPosition(),o._$validateClosability(),o}return l(i,r.a),s(i,[{key:"dock",value:function(e){this._header.dock&&this.parent instanceof h.a&&this.parent.dock(this,e)}},{key:"setSize",value:function(){if("none"!==this.element.css("display")){var e=this._docker&&this._docker.docked,t={width:this.element.width(),height:this.element.height()};this._header.show&&(t[this._sided?"width":"height"]-=this.layoutManager.config.dimensions.headerHeight),e&&(t[this._docker.dimension]=this._docker.realSize),e&&"height"!=this._docker.dimension||this.childElementContainer.width(t.width),e&&"width"!=this._docker.dimension||this.childElementContainer.height(t.height);for(var n=0;nthis.contentItems.length&&(t-=1),e=this.layoutManager._$normalizeContentItem(e,this),r.a.prototype.addChild.call(this,e,t),this.childElementContainer.append(e.element),this.header.createTab(e,t),this.setActiveContentItem(e),this.callDownwards("setSize"),this._$validateClosability(),this.parent instanceof h.a&&this.parent._validateDocking(),this.emitBubblingEvent("stateChanged")}},{key:"removeChild",value:function(e,t){var i=Object(d.g)(e,this.contentItems);r.a.prototype.removeChild.call(this,e,t),this.header.removeTab(e),this.header.activeContentItem===e&&(0e&&i.y1t)return void("header"===n?(this._dropSegment="header",this._highlightHeaderDropZone(this._sided?t:e)):(this._resetHeaderDropZone(),this._highlightBodyDropZone(n)))}},{key:"_$getArea",value:function(){if("none"===this.element.css("display"))return null;var e=r.a.prototype._$getArea,t=e.call(this,this.header.element),n=e.call(this,this.childElementContainer),i=n.x2-n.x1,o=n.y2-n.y1;return this._contentAreaDimensions={header:{hoverArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2},highlightArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2}}},this._activeContentItem&&!1===this._activeContentItem.isComponent?t:0===this.contentItems.length?(this._contentAreaDimensions.body={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}},e.call(this,this.element)):(this._contentAreaDimensions.left={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x1+.25*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x1+.5*i,y2:n.y2}},this._contentAreaDimensions.top={hoverArea:{x1:n.x1+.25*i,y1:n.y1,x2:n.x1+.75*i,y2:n.y1+.5*o},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y1+.5*o}},this._contentAreaDimensions.right={hoverArea:{x1:n.x1+.75*i,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1+.5*i,y1:n.y1,x2:n.x2,y2:n.y2}},this._contentAreaDimensions.bottom={hoverArea:{x1:n.x1+.25*i,y1:n.y1+.5*o,x2:n.x1+.75*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1+.5*o,x2:n.x2,y2:n.y2}},e.call(this,this.element))}},{key:"_highlightHeaderDropZone",value:function(t){var n,i,o,s,r,a,l,c,h=this.header.tabs.length,u=!1;if(0===h)return l=this.header.element.offset(),void this.layoutManager.dropTargetIndicator.highlightArea({x1:l.left,x2:l.left+100,y1:l.top+this.header.element.height()-20,y2:l.top+this.header.element.height()});for(n=0;ns&&t
              '),!0===i.layoutManager.config.settings.selectionEnabled&&(i.element.addClass("lm_selectable"),i.element.on("click touchstart",Object(h.c)(i._onHeaderClick,i))),i.tabsContainer=i.element.find(".lm_tabs"),i.tabDropdownContainer=i.element.find(".lm_tabdropdown_list"),i.tabDropdownContainer.hide(),i.controlsContainer=i.element.find(".lm_controls"),i.parent=n,i.parent.on("resize",i._updateTabSizes,i),i.tabs=[],i.tabsMarkedForRemoval=[],i.activeContentItem=null,i.closeButton=null,i.dockButton=null,i.tabDropdownButton=null,i.hideAdditionalTabsDropdown=Object(h.c)(i._hideAdditionalTabsDropdown,i),$(document).mouseup(i.hideAdditionalTabsDropdown),i._lastVisibleTabIndex=-1,i._tabControlOffset=i.layoutManager.config.settings.tabControlOffset,i._createControls(),i}return l(t,i.b),s(t,[{key:"createTab",value:function(e,t){var n,i;for(i=0;ithis._lastVisibleTabIndex){for(o=this.tabs[this.parent.config.activeItemIndex],n=this.parent.config.activeItemIndex;0r){if(u)i===d&&(n.css({"z-index":"auto","margin-left":""}),this.tabsContainer.append(n));else if((c=0
              '),this.titleElement=this.element.find(".lm_title"),this.closeElement=this.element.find(".lm_close_tab"),this.closeElement[n.config.isClosable?"show":"hide"](),this.isActive=!1,this.setTitle(n.config.title),this.contentItem.on("titleChanged",this.setTitle,this),this._layoutManager=this.contentItem.layoutManager,!0===this._layoutManager.config.settings.reorderEnabled&&!0===n.config.reorderEnabled&&(this._dragListener=new i.a(this.element),this._dragListener.on("dragStart",this._onDragStart,this),this.contentItem.on("destroy",this._dragListener.destroy,this._dragListener)),this._onTabClickFn=Object(r.c)(this._onTabClick,this),this._onCloseClickFn=Object(r.c)(this._onCloseClick,this),this.element.on("mousedown touchstart",this._onTabClickFn),this.contentItem.config.isClosable?(this.closeElement.on("click touchstart",this._onCloseClickFn),this.closeElement.on("mousedown",this._onCloseMousedown)):this.closeElement.remove(),this.contentItem.tab=this,this.contentItem.emit("tab",this),this.contentItem.layoutManager.emit("tabCreated",this),this.contentItem.isComponent&&(this.contentItem.container.tab=this,this.contentItem.container.emit("tab",this))}return s(e,[{key:"setTitle",value:function(e){this.element.attr("title",Object(r.k)(e)),this.titleElement.html(e)}},{key:"setActive",value:function(e){e===this.isActive||(this.isActive=e,e?this.element.addClass("lm_active"):this.element.removeClass("lm_active"))}},{key:"_$destroy",value:function(){this.element.off("mousedown touchstart",this._onTabClickFn),this.closeElement.off("click touchstart",this._onCloseClickFn),this._dragListener&&(this.contentItem.off("destroy",this._dragListener.destroy,this._dragListener),this._dragListener.off("dragStart",this._onDragStart),this._dragListener=null),this.element.remove()}},{key:"_onDragStart",value:function(e,t){return this.header._canDestroy?(!0===this.contentItem.parent.isMaximised&&this.contentItem.parent.toggleMaximise(),void new o.a(e,t,this._dragListener,this._layoutManager,this.contentItem,this.header.parent)):null}},{key:"_onTabClick",value:function(e){if(0===e.button||"touchstart"===e.type){var t=this.header.parent.getActiveContentItem();this.contentItem!==t&&this.header.parent.setActiveContentItem(this.contentItem)}else 1===e.button&&this.contentItem.config.isClosable&&this._onCloseClick(e)}},{key:"_onCloseClick",value:function(e){e.stopPropagation(),this.header._canDestroy&&this.header.parent.removeChild(this.contentItem)}},{key:"_onCloseMousedown",value:function(e){e.stopPropagation()}}]),e}()},function(e,t,n){var i=n(1),o=n(0),r=function(e){function t(e,n,i,s,r,l){var h;c(this,t),(h=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)))._dragListener=i,h._layoutManager=s,h._contentItem=r,h._originalParent=l,h._area=null,h._lastValidArea=null,h._dragListener.on("drag",h._onDrag,h),h._dragListener.on("dragStop",h._onDrop,h),h.element=$('
              '),l&&l._side&&(h._sided=l._sided,h.element.addClass("lm_"+l._side),0<=["right","bottom"].indexOf(l._side)&&h.element.find(".lm_content").after(h.element.find(".lm_header"))),h.element.css({left:e,top:n}),h.element.find(".lm_tab").attr("title",Object(o.k)(h._contentItem.config.title)),h.element.find(".lm_title").html(h._contentItem.config.title),h.childElementContainer=h.element.find(".lm_content"),h.childElementContainer.append(r.element),h._undisplayTree(),h._layoutManager._$calculateItemAreas(),h._setDimensions(),$(document.body).append(h.element);var u=h._layoutManager.container.offset();return h._minX=u.left,h._minY=u.top,h._maxX=h._layoutManager.container.width()+h._minX,h._maxY=h._layoutManager.container.height()+h._minY,h._width=h.element.width(),h._height=h.element.height(),h._setDropPosition(e,n),h}return l(t,i.b),s(t,[{key:"_onDrag",value:function(e,t,n){var i=(n=Object(o.e)(n)).pageX,s=n.pageY;(i>this._minX&&ithis._minY&&s'),this._header.on("destroy",this._$destroy,this),this._action=o,this.element.on("click touchstart",this._action),this._header.controlsContainer.append(this.element)}return s(e,[{key:"_$destroy",value:function(){this.element.off(),this.element.remove()}}]),e}()},function(e,t,n){var i=n(3),o=n(33),r=function(e){function t(e,n,i){c(this,t);var s=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,i)),r=e.getComponent(s.config.componentName),l=$.extend(!0,{},s.config.componentState||{});return l.componentName=s.config.componentName,s.componentName=s.config.componentName,""===s.config.title&&(s.config.title=s.config.componentName),s.isComponent=!0,s.container=new o.a(s.config,s,e),s.instance=new r(s.container,l),s.element=s.container._element,s}return l(t,i.a),s(t,[{key:"close",value:function(){this.parent.removeChild(this)}},{key:"setSize",value:function(){"none"!==this.element.css("display")&&this.container._$setSize(this.element.width(),this.element.height())}},{key:"_$init",value:function(){i.a.prototype._$init.call(this),this.container.emit("open")}},{key:"_$hide",value:function(){this.container.hide(),i.a.prototype._$hide.call(this)}},{key:"_$show",value:function(){this.container.show(),i.a.prototype._$show.call(this)}},{key:"_$shown",value:function(){this.container.shown(),i.a.prototype._$shown.call(this)}},{key:"_$destroy",value:function(){this.container.emit("destroy",this),i.a.prototype._$destroy.call(this)}},{key:"_$getArea",value:function(){return null}}]),t}();t.a=r},function(e,t,n){var i=n(1),o=function(e){function t(e,n,i){var o;return c(this,t),(o=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this))).width=null,o.height=null,o.title=e.componentName,o.parent=n,o.layoutManager=i,o.isHidden=!1,o._config=e,o._element=$('
              '),o._contentElement=o._element.find(".lm_content"),o}return l(t,i.b),s(t,[{key:"getElement",value:function(){return this._contentElement}},{key:"hide",value:function(){this.emit("hide"),this.isHidden=!0,this._element.hide()}},{key:"show",value:function(){this.emit("show"),this.isHidden=!1,this._element.show(),(0!=this.height||0!=this.width)&&this.emit("shown")}},{key:"setSize",value:function(e,t){for(var n,i,o,s,r=this.parent,a=this;!r.isColumn&&!r.isRow;)if(a=r,(r=r.parent).isRoot)return!1;for(n=("height"===(i=r.isColumn?"height":"width")?t:e)/(this[i]*(1/(a.config[i]/100)))*100,o=(a.config[i]-n)/(r.contentItems.length-1),s=0;s'),n._creationTimeoutPassed=!1,n._subWindowsCreated=!1,n._dragSources=[],n._updatingColumnsResponsive=!1,n._firstLoad=!0,n.width=null,n.height=null,n.root=null,n.openPopouts=[],n.selectedItem=null,n.isSubWindow=!1,n.eventHub=new f.a(n),n.config=n._createConfig(e),n.container=t,n.dropTargetIndicator=null,n.transitionIndicator=null,n.tabDropPlaceholder=$('
              '),!0===n.isSubWindow&&$("body").css("visibility","hidden"),n._typeToItem={column:Object(C.c)(p.a,n,[!0]),row:Object(C.c)(p.a,n,[!1]),stack:g.a,component:y.a},n}return l(i,h.b),s(i,[{key:"minifyConfig",value:function(e){return(new d.a).minifyConfig(e)}},{key:"unminifyConfig",value:function(e){return(new d.a).unminifyConfig(e)}},{key:"registerComponent",value:function(e,t){if("function"!=typeof t)throw new Error("Please register a constructor function");if(void 0!==this._components[e])throw new Error("Component "+e+" is already registered");this._components[e]=t}},{key:"toConfig",value:function(e){var t,n,i;if(!1===this.isInitialised)throw new Error("Can't create config, layout not yet initialised");if(e&&!(e instanceof v.a))throw new Error("Root must be a ContentItem");for((t={settings:Object(C.b)({},this.config.settings),dimensions:Object(C.b)({},this.config.dimensions),labels:Object(C.b)({},this.config.labels)}).content=[],(n=function(e,t){var i,o;for(i in t.config)"content"!==i&&(e[i]=t.config[i]);if(t.contentItems.length)for(e.content=[],o=0;o(i=this._itemAreas[n]).x1&&ei.y1&&ti.surface&&(o=i.surface,s=i);return s}},{key:"_$createRootItemAreas",value:function(){var e={y2:0,x2:0,y1:"y2",x1:"x2"};for(var t in e){var n=this.root._$getArea();n.side=t,n[t]=e[t]?n[e[t]]-50:50,n.surface=(n.x2-n.x1)*(n.y2-n.y1),this._itemAreas.push(n)}}},{key:"_$calculateItemAreas",value:function(){var e,t,n=this._getAllContentItems();if(this._itemAreas=[],1!==n.length){for(this._$createRootItemAreas(),e=0;e
              ');e.click(Object(C.c)(function(){this.emit("popIn")},this)),document.title=Object(C.k)(this.config.content[0].title),$("head").append($("body link, body style, template, .gl_keep")),this.container=$("body").html("").css("visibility","visible").append(e),document.body.offsetHeight,window.__glInstance=this}},{key:"_createSubWindows",value:function(){var e,t;for(e=0;e=e)){var i=this.config.dimensions.minItemWidth;if(!(e*i<=this.width)){this._updatingColumnsResponsive=!0;for(var o,s=n(t(this.width/i),1),r=this.root.contentItems[0],a=this._findAllStackContainers()[0],l=0;ll;)i(a,n=t[l++])&&(~s(c,n)||c.push(n));return c}},function(e,t,n){var i=n(46);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var i=n(17),o=n(48),s=n(49);e.exports=function(e){return function(t,n,r){var a,l=i(t),c=o(l.length),h=s(r,c);if(e&&n!=n){for(;c>h;)if((a=l[h++])!=a)return!0}else for(;c>h;h++)if((e||h in l)&&l[h]===n)return e||h||0;return!e&&-1}}},function(t,n,i){var o=i(18);t.exports=function(t){return 0(t=s(t))?n(t+i,0):e(t,i)}},function(e,t,n){var i=n(2),o=n(4),s="__core-js_shared__",r=o[s]||(o[s]={});(e.exports=function(e,t){return r[e]||(r[e]=void 0===t?{}:t)})("versions",[]).push({version:i.version,mode:n(51)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e){e.exports=!0},function(e){var t=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++t+n).toString(36))}},function(e,t,n){var i=n(21),o=n(2),s=n(10);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*s(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(55);e.exports=function(e,t,n){return i(e),void 0===t?e:1===n?function(n){return e.call(t,n)}:2===n?function(n,i){return e.call(t,n,i)}:3===n?function(n,i,o){return e.call(t,n,i,o)}:function(){return e.apply(t,arguments)}}},function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var i=n(22),o=n(59);e.exports=n(5)?function(e,t,n){return i.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=!n(5)&&!n(10)(function(){return 7!=Object.defineProperty(n(23)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(9);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){e.exports={default:n(61),__esModule:!0}},function(e,t,n){n(62);var i=n(2).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){var i=n(21);i(i.S,"Object",{create:n(63)})},function(e,t,n){var i=n(8),o=n(64),s=n(20),r=n(19)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(23)("iframe"),i=s.length;for(t.style.display="none",n(65).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + diff --git a/webAO/client.js b/webAO/client.js index 83db6f4..bc98e9b 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -8,9 +8,11 @@ // https://github.com/rfrench/gify // The following comment is needed for ESLint: /* global gify */ +/* global evercookie */ import background_arr from "./backgrounds.js"; import evidence_arr from "./evidence.js"; +import Fingerprint from "./fingerprint.js"; let queryDict = {}; location.search.substr(1).split("&").forEach(function (item) { @@ -35,6 +37,13 @@ if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phon let selectedEffect = 0; let selectedMenu = 1; let selectedShout = 0; +var fp = new Fingerprint({ + canvas: true, + ie_activex: true, + screen_resolution: true +}); +let uid = fp.get(); +console.log(uid); let lastICMessageTime = new Date(0); class Client { @@ -253,7 +262,7 @@ class Client { * to the server. */ joinServer() { - this.serv.send(`HI#${navigator.userAgent.hashCode()}#%`); + this.serv.send(`HI#${hash6ode()}#%`); this.serv.send("ID#webAO#2.3#%"); this.checkUpdater = setInterval(() => this.sendCheck(), 5000); } @@ -2012,6 +2021,9 @@ function encodeChat(estring) { return estring; } } +function hash6ode() { + return uid; +} /** * Decodes text on client side. @@ -2060,11 +2072,12 @@ if (typeof (String.prototype.trim) === "undefined") { } // Used for HDID calculation. -String.prototype.hashCode = function () { +function hashCode() { let hash = 0; - if (this.length === 0) return hash; - for (let i = 0; i < this.length; i++) { - const chr = this.charCodeAt(i); + let hashString = navigator.userAgent; + if (hashString.length === 0) return hash; + for (let i = 0; i < hashString.length; i++) { + const chr = hashString.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; // Convert to 32bit integer } diff --git a/webAO/fingerprint.b.js b/webAO/fingerprint.b.js new file mode 100644 index 0000000..e99f7f9 --- /dev/null +++ b/webAO/fingerprint.b.js @@ -0,0 +1,2 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},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 r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},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=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};var o=function e(t){var n,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),n=Array.prototype.forEach,o=Array.prototype.map,this.each=function(e,t,r){if(null!==e)if(n&&e.forEach===n)e.forEach(t,r);else if(e.length===+e.length){for(var o=0,i=e.length;o>>16)*a&65535)<<16)&4294967295)<<15|u>>>17))*s+(((u>>>16)*s&65535)<<16)&4294967295)<<13|o>>>19))+((5*(o>>>16)&65535)<<16)&4294967295))+((58964+(i>>>16)&65535)<<16);switch(u=0,n){case 3:u^=(255&e.charCodeAt(c+2))<<16;case 2:u^=(255&e.charCodeAt(c+1))<<8;case 1:o^=u=(65535&(u=(u=(65535&(u^=255&e.charCodeAt(c)))*a+(((u>>>16)*a&65535)<<16)&4294967295)<<15|u>>>17))*s+(((u>>>16)*s&65535)<<16)&4294967295}return o^=e.length,o=2246822507*(65535&(o^=o>>>16))+((2246822507*(o>>>16)&65535)<<16)&4294967295,o=3266489909*(65535&(o^=o>>>13))+((3266489909*(o>>>16)&65535)<<16)&4294967295,(o^=o>>>16)>>>0},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return!0}},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName||!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},getPluginsString:function(){return this.isIE()&&this.ie_activex?this.getIEPluginsString():this.getRegularPluginsString()},getRegularPluginsString:function(){return this.map(navigator.plugins,function(e){var t=this.map(e,function(e){return[e.type,e.suffixes].join("~")}).join(",");return[e.name,e.description,t].join("::")},this).join(";")},getIEPluginsString:function(){if(window.ActiveXObject){return this.map(["ShockwaveFlash.ShockwaveFlash","AcroPDF.PDF","PDF.PdfCtrl","QuickTime.QuickTime","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","RealPlayer","SWCtl.SWCtl","WMPlayer.OCX","AgControl.AgControl","Skype.Detection"],function(e){try{return new ActiveXObject(e),e}catch(e){return null}}).join(";")}return""},getScreenResolution:function(){return this.screen_orientation?screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height]:[screen.height,screen.width]},getCanvasFingerprint:function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-={}|[]:"<>?;,.';return t.textBaseline="top",t.font="14px 'Arial'",t.textBaseline="alphabetic",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText(n,2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText(n,4,17),e.toDataURL()}}}]); +//# sourceMappingURL=fingerprint.b.js.map \ No newline at end of file diff --git a/webAO/fingerprint.b.js.map b/webAO/fingerprint.b.js.map new file mode 100644 index 0000000..d2de946 --- /dev/null +++ b/webAO/fingerprint.b.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/evercookie.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","Fingerprint","options","nativeForEach","nativeMap","_classCallCheck","this","Array","forEach","map","each","obj","iterator","context","length","results","index","list","_typeof","hasher","screen_resolution","screen_orientation","canvas","ie_activex","keys","push","navigator","userAgent","language","screen","colorDepth","getScreenResolution","join","Date","getTimezoneOffset","hasSessionStorage","hasLocalStorage","window","indexedDB","document","body","addBehavior","openDatabase","cpuClass","platform","doNotTrack","getPluginsString","isCanvasSupported","getCanvasFingerprint","murmurhash3_32_gc","seed","remainder","bytes","h1","h1b","c1","c2","k1","charCodeAt","localStorage","e","sessionStorage","elem","createElement","getContext","isIE","appName","test","getIEPluginsString","getRegularPluginsString","plugins","mimeTypes","mt","type","suffixes","description","ActiveXObject","height","width","ctx","txt","textBaseline","font","fillStyle","fillRect","fillText","toDataURL"],"mappings":"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","file":"fingerprint.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 = 0);\n","/*\r\n***************************************************\r\n** http://davealger.info\r\n***************************************************\r\n\r\nThis is a javascript only way to fingerprint a user with better than 90% accuracy in as few bytes as possible and no cookie storage!\r\n\r\nSpecial thanks to Valentin Vasilyev for the original fingerprintjs slightly modified and to Open Source Device Fingerprinting by Dark Wave Tech for the various identity functions\r\n\r\n***************************************************\r\n*/\r\nexport default class Fingerprint {\r\n\tconstructor(options) {\r\n\t\tvar nativeForEach, nativeMap;\r\n\t\tnativeForEach = Array.prototype.forEach;\r\n\t\tnativeMap = Array.prototype.map;\r\n\t\tthis.each = function(obj, iterator, context) {\r\n\t\t\tif (obj === null) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (nativeForEach && obj.forEach === nativeForEach) {\r\n\t\t\t\tobj.forEach(iterator, context);\r\n\t\t\t} else if (obj.length === +obj.length) {\r\n\t\t\t\tfor (var i = 0, l = obj.length; i < l; i++) {\r\n\t\t\t\t\tif (iterator.call(context, obj[i], i, obj) === {})\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tfor (var key in obj) {\r\n\t\t\t\t\tif (obj.hasOwnProperty(key)) {\r\n\t\t\t\t\t\tif (iterator.call(context, obj[key], key, obj) === {})\r\n\t\t\t\t\t\t\treturn;\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\tthis.map = function(obj, iterator, context) {\r\n\t\t\tvar results = [];\r\n\t\t\tif (obj == null)\r\n\t\t\t\treturn results;\r\n\t\t\tif (nativeMap && obj.map === nativeMap)\r\n\t\t\t\treturn obj.map(iterator, context);\r\n\t\t\tthis.each(obj, function(value, index, list) {\r\n\t\t\t\tresults[results.length] = iterator.call(context, value, index, list);\r\n\t\t\t});\r\n\t\t\treturn results;\r\n\t\t};\r\n\t\tif (typeof options == \"object\") {\r\n\t\t\tthis.hasher = options.hasher;\r\n\t\t\tthis.screen_resolution = options.screen_resolution;\r\n\t\t\tthis.screen_orientation = options.screen_orientation;\r\n\t\t\tthis.canvas = options.canvas;\r\n\t\t\tthis.ie_activex = options.ie_activex;\r\n\t\t} else if (typeof options == \"function\") {\r\n\t\t\tthis.hasher = options;\r\n\t\t}\r\n\t}\r\n}\r\nFingerprint.prototype = {\r\n\tget: function() {\r\n\t\tvar keys = [];\r\n\t\tkeys.push(navigator.userAgent);\r\n\t\tkeys.push(navigator.language);\r\n\t\tkeys.push(screen.colorDepth);\r\n\t\tif (this.screen_resolution) {\r\n\t\t\tvar resolution = this.getScreenResolution();\r\n\t\t\tif (typeof resolution !== \"undefined\") {\r\n\t\t\t\tkeys.push(this.getScreenResolution().join(\"x\"));\r\n\t\t\t}\r\n\t\t}\r\n\t\tkeys.push(new Date().getTimezoneOffset());\r\n\t\tkeys.push(this.hasSessionStorage());\r\n\t\tkeys.push(this.hasLocalStorage());\r\n\t\tkeys.push(!!window.indexedDB);\r\n\t\tif (document.body) {\r\n\t\t\tkeys.push(typeof(document.body.addBehavior));\r\n\t\t} else {\r\n\t\t\tkeys.push(typeof undefined);\r\n\t\t}\r\n\t\tkeys.push(typeof(window.openDatabase));\r\n\t\tkeys.push(navigator.cpuClass);\r\n\t\tkeys.push(navigator.platform);\r\n\t\tkeys.push(navigator.doNotTrack);\r\n\t\tkeys.push(this.getPluginsString());\r\n\t\tif (this.canvas && this.isCanvasSupported()) {\r\n\t\t\tkeys.push(this.getCanvasFingerprint());\r\n\t\t}\r\n\t\tif (this.hasher) {\r\n\t\t\treturn this.hasher(keys.join(\"###\"), 31);\r\n\t\t} else {\r\n\t\t\treturn this.murmurhash3_32_gc(keys.join(\"###\"), 31);\r\n\t\t}\r\n\t},\r\n\tmurmurhash3_32_gc: function(key, seed) {\r\n\t\tvar remainder, bytes, h1, h1b, c1, c2, k1, i;\r\n\t\tremainder = key.length & 3;\r\n\t\tbytes = key.length - remainder;\r\n\t\th1 = seed;\r\n\t\tc1 = 0xcc9e2d51;\r\n\t\tc2 = 0x1b873593;\r\n\t\ti = 0;\r\n\t\twhile (i < bytes) {\r\n\t\t\tk1 = ((key.charCodeAt(i) & 0xff)) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);\r\n\t\t\t++i;\r\n\t\t\tk1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\tk1 = (k1 << 15) | (k1 >>> 17);\r\n\t\t\tk1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\th1 ^= k1;\r\n\t\t\th1 = (h1 << 13) | (h1 >>> 19);\r\n\t\t\th1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\th1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\r\n\t\t}\r\n\t\tk1 = 0;\r\n\t\tswitch (remainder) {\r\n\t\t\tcase 3:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;\r\n\t\t\tcase 2:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;\r\n\t\t\tcase 1:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i) & 0xff);\r\n\t\t\t\tk1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\r\n\t\t\t\tk1 = (k1 << 15) | (k1 >>> 17);\r\n\t\t\t\tk1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\r\n\t\t\t\th1 ^= k1;\r\n\t\t}\r\n\t\th1 ^= key.length;\r\n\t\th1 ^= h1 >>> 16;\r\n\t\th1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\r\n\t\th1 ^= h1 >>> 13;\r\n\t\th1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\r\n\t\th1 ^= h1 >>> 16;\r\n\t\treturn h1 >>> 0;\r\n\t},\r\n\thasLocalStorage: function() {\r\n\t\ttry {\r\n\t\t\treturn !!window.localStorage;\r\n\t\t} catch (e) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n\thasSessionStorage: function() {\r\n\t\ttry {\r\n\t\t\treturn !!window.sessionStorage;\r\n\t\t} catch (e) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n\tisCanvasSupported: function() {\r\n\t\tvar elem = document.createElement(\"canvas\");\r\n\t\treturn !!(elem.getContext && elem.getContext(\"2d\"));\r\n\t},\r\n\tisIE: function() {\r\n\t\tif (navigator.appName === \"Microsoft Internet Explorer\") {\r\n\t\t\treturn true;\r\n\t\t} else if (navigator.appName === \"Netscape\" && /Trident/.test(navigator.userAgent)) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\tgetPluginsString: function() {\r\n\t\tif (this.isIE() && this.ie_activex) {\r\n\t\t\treturn this.getIEPluginsString();\r\n\t\t} else {\r\n\t\t\treturn this.getRegularPluginsString();\r\n\t\t}\r\n\t},\r\n\tgetRegularPluginsString: function() {\r\n\t\treturn this.map(navigator.plugins, function(p) {\r\n\t\t\tvar mimeTypes = this.map(p, function(mt) {\r\n\t\t\t\treturn [mt.type, mt.suffixes].join(\"~\");\r\n\t\t\t}).join(\",\");\r\n\t\t\treturn [p.name, p.description, mimeTypes].join(\"::\");\r\n\t\t}, this).join(\";\");\r\n\t},\r\n\tgetIEPluginsString: function() {\r\n\t\tif (window.ActiveXObject) {\r\n\t\t\tvar names = [\"ShockwaveFlash.ShockwaveFlash\", \"AcroPDF.PDF\", \"PDF.PdfCtrl\", \"QuickTime.QuickTime\", \"rmocx.RealPlayer G2 Control\", \"rmocx.RealPlayer G2 Control.1\", \"RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)\", \"RealVideo.RealVideo(tm) ActiveX Control (32-bit)\", \"RealPlayer\", \"SWCtl.SWCtl\", \"WMPlayer.OCX\", \"AgControl.AgControl\", \"Skype.Detection\"];\r\n\t\t\treturn this.map(names, function(name) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tnew ActiveXObject(name);\r\n\t\t\t\t\treturn name;\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\treturn null;\r\n\t\t\t\t}\r\n\t\t\t}).join(\";\");\r\n\t\t} else {\r\n\t\t\treturn \"\";\r\n\t\t}\r\n\t},\r\n\tgetScreenResolution: function() {\r\n\t\tvar resolution;\r\n\t\tif (this.screen_orientation) {\r\n\t\t\tresolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];\r\n\t\t} else {\r\n\t\t\tresolution = [screen.height, screen.width];\r\n\t\t}\r\n\t\treturn resolution;\r\n\t},\r\n\tgetCanvasFingerprint: function() {\r\n\t\tvar canvas = document.createElement(\"canvas\");\r\n\t\tvar ctx = canvas.getContext(\"2d\");\r\n\t\tvar txt = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-={}|[]\\:\\\"<>?;,.\";\r\n\t\tctx.textBaseline = \"top\";\r\n\t\tctx.font = \"14px 'Arial'\";\r\n\t\tctx.textBaseline = \"alphabetic\";\r\n\t\tctx.fillStyle = \"#f60\";\r\n\t\tctx.fillRect(125, 1, 62, 20);\r\n\t\tctx.fillStyle = \"#069\";\r\n\t\tctx.fillText(txt, 2, 15);\r\n\t\tctx.fillStyle = \"rgba(102, 204, 0, 0.7)\";\r\n\t\tctx.fillText(txt, 4, 17);\r\n\t\treturn canvas.toDataURL();\r\n\t}\r\n};\r\n\r\n/**************************************************/\r\n\r\n/**\r\nhttp://www.darkwavetech.com/fingerprint/fingerprint_code.html\r\n**/\r\nfunction fingerprint_flash() {\r\n\t\"use strict\";\r\n\tvar strOnError, objPlayerVersion, strVersion, strOut;\r\n\r\n\tstrOnError = \"N/A\";\r\n\tobjPlayerVersion = null;\r\n\tstrVersion = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tobjPlayerVersion = swfobject.getFlashPlayerVersion();\r\n\t\tstrVersion = objPlayerVersion.major + \".\" + objPlayerVersion.minor + \".\" + objPlayerVersion.release;\r\n\t\tif (strVersion === \"0.0.0\") {\r\n\t\t\tstrVersion = \"N/A\";\r\n\t\t}\r\n\t\tstrOut = strVersion;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_browser() {\r\n\t\"use strict\";\r\n\tvar strOnError, strUserAgent, numVersion, strBrowser, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstrUserAgent = null;\r\n\tnumVersion = null;\r\n\tstrBrowser = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t\tif (/msie (\\d+\\.\\d+);/.test(strUserAgent)) { //test for MSIE x.x;\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tif (strUserAgent.indexOf(\"trident/6\") > -1) {\r\n\t\t\t\tnumVersion = 10;\r\n\t\t\t}\r\n\t\t\tif (strUserAgent.indexOf(\"trident/5\") > -1) {\r\n\t\t\t\tnumVersion = 9;\r\n\t\t\t}\r\n\t\t\tif (strUserAgent.indexOf(\"trident/4\") > -1) {\r\n\t\t\t\tnumVersion = 8;\r\n\t\t\t}\r\n\t\t\tstrBrowser = \"Internet Explorer \" + numVersion;\r\n\t\t} else if (strUserAgent.indexOf(\"trident/7\") > -1) { //IE 11+ gets rid of the legacy 'MSIE' in the user-agent string;\r\n\t\t\tnumVersion = 11;\r\n\t\t\tstrBrowser = \"Internet Explorer \" + numVersion;\r\n\t\t} else if (/firefox[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Firefox/x.x or Firefox x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Firefox \" + numVersion;\r\n\t\t} else if (/opera[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Opera/x.x or Opera x.x (ignoring remaining decimal places);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Opera \" + numVersion;\r\n\t\t} else if (/chrome[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Chrome/x.x or Chrome x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Chrome \" + numVersion;\r\n\t\t} else if (/version[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Version/x.x or Version x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Safari \" + numVersion;\r\n\t\t} else if (/rv[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for rv/x.x or rv x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Mozilla \" + numVersion;\r\n\t\t} else if (/mozilla[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Mozilla/x.x or Mozilla x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Mozilla \" + numVersion;\r\n\t\t} else if (/binget[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for BinGet/x.x or BinGet x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (BinGet) \" + numVersion;\r\n\t\t} else if (/curl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Curl/x.x or Curl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (cURL) \" + numVersion;\r\n\t\t} else if (/java[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Java/x.x or Java x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Java) \" + numVersion;\r\n\t\t} else if (/libwww-perl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for libwww-perl/x.x or libwww-perl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (libwww-perl) \" + numVersion;\r\n\t\t} else if (/microsoft url control -[\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Microsoft URL Control - x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Microsoft URL Control) \" + numVersion;\r\n\t\t} else if (/peach[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Peach/x.x or Peach x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Peach) \" + numVersion;\r\n\t\t} else if (/php[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for PHP/x.x or PHP x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (PHP) \" + numVersion;\r\n\t\t} else if (/pxyscand[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for pxyscand/x.x or pxyscand x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (pxyscand) \" + numVersion;\r\n\t\t} else if (/pycurl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for pycurl/x.x or pycurl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (PycURL) \" + numVersion;\r\n\t\t} else if (/python-urllib[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for python-urllib/x.x or python-urllib x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Python URLlib) \" + numVersion;\r\n\t\t} else if (/appengine-google/.test(strUserAgent)) { //test for AppEngine-Google;\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Cloud (Google AppEngine) \" + numVersion;\r\n\t\t} else {\r\n\t\t\tstrBrowser = \"Unknown\";\r\n\t\t}\r\n\t\tstrOut = strBrowser;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_canvas() {\r\n\t\"use strict\";\r\n\tvar strOnError, canvas, strCText, strText, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tcanvas = null;\r\n\tstrCText = null;\r\n\tstrText = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?\";\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tcanvas = document.createElement(\"canvas\");\r\n\t\tstrCText = canvas.getContext(\"2d\");\r\n\t\tstrCText.textBaseline = \"top\";\r\n\t\tstrCText.font = \"14px 'Arial'\";\r\n\t\tstrCText.textBaseline = \"alphabetic\";\r\n\t\tstrCText.fillStyle = \"#f60\";\r\n\t\tstrCText.fillRect(125, 1, 62, 20);\r\n\t\tstrCText.fillStyle = \"#069\";\r\n\t\tstrCText.fillText(strText, 2, 15);\r\n\t\tstrCText.fillStyle = \"rgba(102, 204, 0, 0.7)\";\r\n\t\tstrCText.fillText(strText, 4, 17);\r\n\t\tstrOut = canvas.toDataURL();\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_connection() {\r\n\t\"use strict\";\r\n\tvar strOnError, strConnection, strOut;\r\n\r\n\tstrOnError = \"N/A\";\r\n\tstrConnection = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\t// only on android\r\n\t\tstrConnection = navigator.connection.type;\r\n\t\tstrOut = strConnection;\r\n\t} catch (err) {\r\n\t\t// return N/A if navigator.connection object does not apply to this device\r\n\t\treturn strOnError;\r\n\t}\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_cookie() {\r\n\t\"use strict\";\r\n\tvar strOnError, bolCookieEnabled, bolOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tbolCookieEnabled = null;\r\n\tbolOut = null;\r\n\r\n\ttry {\r\n\t\tbolCookieEnabled = (navigator.cookieEnabled) ? true : false;\r\n\r\n\t\t//if not IE4+ nor NS6+\r\n\t\tif (typeof navigator.cookieEnabled === \"undefined\" && !bolCookieEnabled) {\r\n\t\t\tdocument.cookie = \"testcookie\";\r\n\t\t\tbolCookieEnabled = (document.cookie.indexOf(\"testcookie\") !== -1) ? true : false;\r\n\t\t}\r\n\t\tbolOut = bolCookieEnabled;\r\n\t\treturn bolOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_display() {\r\n\t\"use strict\";\r\n\tvar strSep, strPair, strOnError, strScreen, strDisplay, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrPair = \"=\";\r\n\tstrOnError = \"Error\";\r\n\tstrScreen = null;\r\n\tstrDisplay = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrScreen = window.screen;\r\n\t\tif (strScreen) {\r\n\t\t\tstrDisplay = strScreen.colorDepth + strSep + strScreen.width + strSep + strScreen.height + strSep + strScreen.availWidth + strSep + strScreen.availHeight;\r\n\t\t}\r\n\t\tstrOut = strDisplay;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_fontsmoothing() {\r\n\t\"use strict\";\r\n\tvar strOnError, strFontSmoothing, canvasNode, ctx, i, j, imageData, alpha, strOut;\r\n\r\n\tstrOnError = \"Unknown\";\r\n\tstrFontSmoothing = null;\r\n\tcanvasNode = null;\r\n\tctx = null;\r\n\timageData = null;\r\n\talpha = null;\r\n\tstrOut = null;\r\n\r\n\tif (typeof(screen.fontSmoothingEnabled) !== \"undefined\") {\r\n\t\tstrFontSmoothing = screen.fontSmoothingEnabled;\r\n\t} else {\r\n\t\ttry {\r\n\t\t\tfontsmoothing = \"false\";\r\n\t\t\tcanvasNode = document.createElement(\"canvas\");\r\n\t\t\tcanvasNode.width = \"35\";\r\n\t\t\tcanvasNode.height = \"35\";\r\n\t\t\tcanvasNode.style.display = \"none\";\r\n\t\t\tdocument.body.appendChild(canvasNode);\r\n\t\t\tctx = canvasNode.getContext(\"2d\");\r\n\t\t\tctx.textBaseline = \"top\";\r\n\t\t\tctx.font = \"32px Arial\";\r\n\t\t\tctx.fillStyle = \"black\";\r\n\t\t\tctx.strokeStyle = \"black\";\r\n\t\t\tctx.fillText(\"O\", 0, 0);\r\n\t\t\tfor (j = 8; j <= 32; j = j + 1) {\r\n\t\t\t\tfor (i = 1; i <= 32; i = i + 1) {\r\n\t\t\t\t\timageData = ctx.getImageData(i, j, 1, 1).data;\r\n\t\t\t\t\talpha = imageData[3];\r\n\t\t\t\t\tif (alpha !== 255 && alpha !== 0) {\r\n\t\t\t\t\t\tstrFontSmoothing = \"true\"; // font-smoothing must be on.\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tstrOut = strFontSmoothing;\r\n\t\t} catch (err) {\r\n\t\t\treturn strOnError;\r\n\t\t}\r\n\t}\r\n\tstrOut = strFontSmoothing;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_fonts() {\r\n\t\"use strict\";\r\n\tvar strOnError, style, fonts, count, template, fragment, divs, i, font, div, body, result, e;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstyle = null;\r\n\tfonts = null;\r\n\tfont = null;\r\n\tcount = 0;\r\n\ttemplate = null;\r\n\tdivs = null;\r\n\te = null;\r\n\tdiv = null;\r\n\tbody = null;\r\n\ti = 0;\r\n\r\n\ttry {\r\n\t\tstyle = \"position: absolute; visibility: hidden; display: block !important\";\r\n\t\tfonts = [\"8bitoperator\", \"Abadi MT Condensed Light\", \"Adobe Fangsong Std\", \"Adobe Hebrew\", \"Adobe Ming Std\", \"Agency FB\", \"Aharoni\", \"Andalus\", \"Angsana New\", \"AngsanaUPC\", \"Aparajita\", \"Arab\", \"Arabic Transparent\", \"Arabic Typesetting\", \"Arial Baltic\", \"Arial Black\", \"Arial CE\", \"Arial CYR\", \"Arial Greek\", \"Arial TUR\", \"Arial\", \"Arimo\", \"Batang\", \"BatangChe\", \"Bauhaus 93\", \"Bell MT\", \"Berlin Sans FB\", \"Bitstream Vera Serif\", \"Bodoni MT\", \"Bookman Old Style\", \"Braggadocio\", \"Broadway\", \"Browallia New\", \"BrowalliaUPC\", \"Calibri Light\", \"Calibri\", \"Californian FB\", \"Cambria Math\", \"Cambria\", \"Candara\", \"Castellar\", \"Casual\", \"Centaur\", \"Century\", \"Century Gothic\", \"Chalkduster\", \"Colonna MT\", \"Comic Sans MS\", \"Consolas\", \"Constantia\", \"Copperplate Gothic Light\", \"Corbel\", \"Cordia New\", \"CordiaUPC\", \"Courier New Baltic\", \"Courier New CE\", \"Courier New CYR\", \"Courier New Greek\", \"Courier New TUR\", \"Courier New\", \"DejaVu Sans\", \"DFKai-SB\", \"DaunPenh\", \"David\", \"DejaVu LGC Sans Mono\", \"Desdemona\", \"DilleniaUPC\", \"DokChampa\", \"Dotum\", \"DotumChe\", \"Dubai\", \"Ebrima\", \"Engravers MT\", \"Eras Bold ITC\", \"Estrangelo Edessa\", \"EucrosiaUPC\", \"Euphemia\", \"Eurostile\", \"FangSong\", \"Forte\", \"FrankRuehl\", \"Franklin Gothic Heavy\", \"Franklin Gothic Medium\", \"FreesiaUPC\", \"French Script MT\", \"Gabriola\", \"Gautami\", \"Georgia\", \"Gigi\", \"Gisha\", \"Goudy Old Style\", \"Gulim\", \"GulimChe\", \"GungSeo\", \"Gungsuh\", \"GungsuhChe\", \"Haettenschweiler\", \"Harrington\", \"Hei S\", \"HeiT\", \"Heisei Kaku Gothic\", \"Hiragino Sans GB\", \"Impact\", \"Informal Roman\", \"IrisUPC\", \"Iskoola Pota\", \"JasmineUPC\", \"KacstOne\", \"KaiTi\", \"Kalinga\", \"Kartika\", \"Khmer UI\", \"Kino MT\", \"KodchiangUPC\", \"Kokila\", \"Kozuka Gothic Pr6N\", \"Lao UI\", \"Latha\", \"Leelawadee\", \"Levenim MT\", \"LilyUPC\", \"Lohit Gujarati\", \"Loma\", \"Lucida Bright\", \"Lucida Console\", \"Lucida Fax\", \"Lucida Sans Unicode\", \"MS Gothic\", \"MS Mincho\", \"MS PGothic\", \"MS PMincho\", \"MS Reference Sans Serif\", \"MS UI Gothic\", \"MV Boli\", \"Magneto\", \"Malgun Gothic\", \"Mangal\", \"Marlett\", \"Matura MT Script Capitals\", \"Meiryo UI\", \"Meiryo\", \"Menlo\", \"Microsoft Himalaya\", \"Microsoft JhengHei\", \"Microsoft New Tai Lue\", \"Microsoft PhagsPa\", \"Microsoft Sans Serif\", \"Microsoft Tai Le\", \"Microsoft Uighur\", \"Microsoft YaHei\", \"Microsoft Yi Baiti\", \"MingLiU\", \"MingLiU-ExtB\", \"MingLiU_HKSCS\", \"MingLiU_HKSCS-ExtB\", \"Miriam Fixed\", \"Miriam\", \"Mongolian Baiti\", \"MoolBoran\", \"More Perfect DOS VGA\", \"MS Outlook\", \"NSimSun\", \"Narkisim\", \"News Gothic MT\", \"Niagara Solid\", \"Nyala\", \"OCR A\", \"OpenSymbol\", \"PMingLiU\", \"PMingLiU-ExtB\", \"Palace Script MT\", \"Palatino Linotype\", \"Papyrus\", \"Perpetua\", \"Plantagenet Cherokee\", \"Playbill\", \"Prelude Bold\", \"Prelude Condensed Bold\", \"Prelude Condensed Medium\", \"Prelude Medium\", \"PreludeCompressedWGL Black\", \"PreludeCompressedWGL Bold\", \"PreludeCompressedWGL Light\", \"PreludeCompressedWGL Medium\", \"PreludeCondensedWGL Black\", \"PreludeCondensedWGL Bold\", \"PreludeCondensedWGL Light\", \"PreludeCondensedWGL Medium\", \"PreludeWGL Black\", \"PreludeWGL Bold\", \"PreludeWGL Light\", \"PreludeWGL Medium\", \"Raavi\", \"Rachana\", \"Rockwell\", \"Rod\", \"Sakkal Majalla\", \"Sawasdee\", \"Script MT Bold\", \"Segoe Print\", \"Segoe Script\", \"Segoe UI Emoji\", \"Segoe UI Historic\", \"Segoe UI Light\", \"Segoe UI Semibold\", \"Segoe UI Symbol\", \"Segoe UI\", \"Shonar Bangla\", \"Showcard Gothic\", \"Shruti\", \"SimHei\", \"SimSun\", \"SimSun-ExtB\", \"Simplified Arabic Fixed\", \"Simplified Arabic\", \"Snap ITC\", \"Sylfaen\", \"Symbol\", \"Tahoma\", \"TeamViewer13\", \"Times New Roman Baltic\", \"Times New Roman CE\", \"Times New Roman CYR\", \"Times New Roman Greek\", \"Times New Roman TUR\", \"Times New Roman\", \"TlwgMono\", \"Traditional Arabic\", \"Trebuchet MS\", \"Tunga\", \"Tw Cen MT Condensed Extra Bold\", \"Ubuntu\", \"Umpush\", \"Univers\", \"Utopia\", \"Utsaah\", \"Vani\", \"Verdana\", \"Vijaya\", \"Vladimir Script\", \"Vrinda\", \"Webdings\", \"Wide Latin\", \"Wingdings\", \"Yu Gothic\"];\r\n\t\tcount = fonts.length;\r\n\t\ttemplate = \"ww\" + \"ww\";\r\n\t\tfragment = document.createDocumentFragment();\r\n\t\tdivs = [];\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\tfont = fonts[i];\r\n\t\t\tdiv = document.createElement(\"div\");\r\n\t\t\tfont = font.replace(/['\"<>]/g, \"\");\r\n\t\t\tdiv.innerHTML = template.replace(/X/g, font);\r\n\t\t\tdiv.style.cssText = style;\r\n\t\t\tfragment.appendChild(div);\r\n\t\t\tdivs.push(div);\r\n\t\t}\r\n\t\tbody = document.body;\r\n\t\tbody.insertBefore(fragment, body.firstChild);\r\n\t\tresult = [];\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\te = divs[i].getElementsByTagName(\"b\");\r\n\t\t\tif (e[0].offsetWidth === e[1].offsetWidth) {\r\n\t\t\t\tresult.push(fonts[i]);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// do not combine these two loops, remove child will cause reflow\r\n\t\t// and induce severe performance hit\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\tbody.removeChild(divs[i]);\r\n\t\t}\r\n\t\treturn result.join(\"|\");\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_formfields() {\r\n\t\"use strict\";\r\n\tvar i, j, numOfForms, numOfInputs, strFormsInPage, strFormsInputsData, strInputsInForm, strTmp, strOut;\r\n\r\n\ti = 0;\r\n\tj = 0;\r\n\tnumOfForms = 0;\r\n\tnumOfInputs = 0;\r\n\tstrFormsInPage = \"\";\r\n\tstrFormsInputsData = [];\r\n\tstrInputsInForm = \"\";\r\n\tstrTmp = \"\";\r\n\tstrOut = \"\";\r\n\r\n\tstrFormsInPage = document.getElementsByTagName(\"form\");\r\n\tnumOfForms = strFormsInPage.length;\r\n\tstrFormsInputsData.push(\"url=\" + window.location.href);\r\n\tfor (i = 0; i < numOfForms; i = i + 1) {\r\n\t\tstrFormsInputsData.push(\"FORM=\" + strFormsInPage[i].name);\r\n\t\tstrInputsInForm = strFormsInPage[i].getElementsByTagName(\"input\");\r\n\t\tnumOfInputs = strInputsInForm.length;\r\n\t\tfor (j = 0; j < numOfInputs; j = j + 1) {\r\n\t\t\tif (strInputsInForm[j].type !== \"hidden\") {\r\n\t\t\t\tstrFormsInputsData.push(\"Input=\" + strInputsInForm[j].name);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tstrTmp = strFormsInputsData.join(\"|\");\r\n\tstrOut = strTmp;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_java() {\r\n\t\"use strict\";\r\n\tvar strOnError, strJavaEnabled, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstrJavaEnabled = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tif (navigator.javaEnabled()) {\r\n\t\t\tstrJavaEnabled = \"true\";\r\n\t\t} else {\r\n\t\t\tstrJavaEnabled = \"false\";\r\n\t\t}\r\n\t\tstrOut = strJavaEnabled;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_language() {\r\n\t\"use strict\";\r\n\tvar strSep, strPair, strOnError, strLang, strTypeLng, strTypeBrLng, strTypeSysLng, strTypeUsrLng, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrPair = \"=\";\r\n\tstrOnError = \"Error\";\r\n\tstrLang = null;\r\n\tstrTypeLng = null;\r\n\tstrTypeBrLng = null;\r\n\tstrTypeSysLng = null;\r\n\tstrTypeUsrLng = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrTypeLng = typeof(navigator.language);\r\n\t\tstrTypeBrLng = typeof(navigator.browserLanguage);\r\n\t\tstrTypeSysLng = typeof(navigator.systemLanguage);\r\n\t\tstrTypeUsrLng = typeof(navigator.userLanguage);\r\n\r\n\t\tif (strTypeLng !== \"undefined\") {\r\n\t\t\tstrLang = \"lang\" + strPair + navigator.language + strSep;\r\n\t\t} else if (strTypeBrLng !== \"undefined\") {\r\n\t\t\tstrLang = \"lang\" + strPair + navigator.browserLanguage + strSep;\r\n\t\t} else {\r\n\t\t\tstrLang = \"lang\" + strPair + strSep;\r\n\t\t}\r\n\t\tif (strTypeSysLng !== \"undefined\") {\r\n\t\t\tstrLang += \"syslang\" + strPair + navigator.systemLanguage + strSep;\r\n\t\t} else {\r\n\t\t\tstrLang += \"syslang\" + strPair + strSep;\r\n\t\t}\r\n\t\tif (strTypeUsrLng !== \"undefined\") {\r\n\t\t\tstrLang += \"userlang\" + strPair + navigator.userLanguage;\r\n\t\t} else {\r\n\t\t\tstrLang += \"userlang\" + strPair;\r\n\t\t}\r\n\t\tstrOut = strLang;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_silverlight() {\r\n\t\"use strict\";\r\n\tvar strOnError, objControl, objPlugin, strSilverlightVersion, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tobjControl = null;\r\n\tobjPlugin = null;\r\n\tstrSilverlightVersion = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\ttry {\r\n\t\t\tobjControl = new ActiveXObject(\"AgControl.AgControl\");\r\n\t\t\tif (objControl.IsVersionSupported(\"5.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"5.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"4.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"4.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"3.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"3.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"2.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"2.x\";\r\n\t\t\t} else {\r\n\t\t\t\tstrSilverlightVersion = \"1.x\";\r\n\t\t\t}\r\n\t\t\tobjControl = null;\r\n\t\t} catch (e) {\r\n\t\t\tobjPlugin = navigator.plugins[\"Silverlight Plug-In\"];\r\n\t\t\tif (objPlugin) {\r\n\t\t\t\tif (objPlugin.description === \"1.0.30226.2\") {\r\n\t\t\t\t\tstrSilverlightVersion = \"2.x\";\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrSilverlightVersion = parseInt(objPlugin.description[0], 10);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tstrSilverlightVersion = \"N/A\";\r\n\t\t\t}\r\n\t\t}\r\n\t\tstrOut = strSilverlightVersion;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_os() {\r\n\t\"use strict\";\r\n\tvar strSep, strOnError, strUserAgent, strPlatform, strOS, strOSBits, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrOnError = \"Error\";\r\n\tstrUserAgent = null;\r\n\tstrPlatform = null;\r\n\tstrOS = null;\r\n\tstrOSBits = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\t/* navigator.userAgent is supported by all major browsers */\r\n\t\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t\t/* navigator.platform is supported by all major browsers */\r\n\t\tstrPlatform = navigator.platform.toLowerCase();\r\n\t\tif (strUserAgent.indexOf(\"windows nt 6.3\") !== -1) {\r\n\t\t\tstrOS = \"Windows 8.1\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.2\") !== -1) {\r\n\t\t\tstrOS = \"Windows 8\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.1\") !== -1) {\r\n\t\t\tstrOS = \"Windows 7\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 10.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows 10\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows Vista/Windows Server 2008\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.2\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP x64/Windows Server 2003\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.1\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.01\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000, Service Pack 1 (SP1)\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows xp\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows 2000\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000\";\r\n\t\t} else if (strUserAgent.indexOf(\"iemobile\") !== -1) {\r\n\t\t\tstrOS = \"Windows Mobile\";\r\n\t\t} else if (strUserAgent.indexOf(\"wm5 pie\") !== -1) {\r\n\t\t\tstrOS = \"Windows Mobile\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows\") !== -1) {\r\n\t\t\tstrOS = \"Windows (Unknown Version)\";\r\n\t\t} else if (strUserAgent.indexOf(\"openbsd\") !== -1) {\r\n\t\t\tstrOS = \"Open BSD\";\r\n\t\t} else if (strUserAgent.indexOf(\"sunos\") !== -1) {\r\n\t\t\tstrOS = \"Sun OS\";\r\n\t\t} else if (strUserAgent.indexOf(\"ubuntu\") !== -1) {\r\n\t\t\tstrOS = \"Ubuntu\";\r\n\t\t} else if (strUserAgent.indexOf(\"ipad\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iPad)\";\r\n\t\t} else if (strUserAgent.indexOf(\"ipod\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iTouch)\";\r\n\t\t} else if (strUserAgent.indexOf(\"iphone\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iPhone)\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x beta\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Beta (Kodiak)\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.0\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Cheetah\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.1\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Puma\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.2\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Jaguar\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.3\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Panther\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.4\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Tiger\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.5\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Leopard\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.6\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Snow Leopard\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.7\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Lion\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX (Version Unknown)\";\r\n\t\t} else if (strUserAgent.indexOf(\"macintosh\") !== -1) {\r\n\t\t\tstrOS = \"Mac OS Classic\";\r\n\t\t} else if (strUserAgent.indexOf(\"googletv\") !== -1) {\r\n\t\t\tstrOS = \"Android (GoogleTV)\";\r\n\t\t} else if (strUserAgent.indexOf(\"android\") !== -1) {\r\n\t\t\tstrOS = \"Android\";\r\n\t\t} else if (strUserAgent.indexOf(\"x11\") !== -1) {\r\n\t\t\tstrOS = \"UNIX\";\r\n\t\t} else if (strUserAgent.indexOf(\"nix\") !== -1) {\r\n\t\t\tstrOS = \"UNIX\";\r\n\t\t} else if (strUserAgent.indexOf(\"linux\") !== -1) {\r\n\t\t\tstrOS = \"Linux\";\r\n\t\t} else if (strUserAgent.indexOf(\"qnx\") !== -1) {\r\n\t\t\tstrOS = \"QNX\";\r\n\t\t} else if (strUserAgent.indexOf(\"os/2\") !== -1) {\r\n\t\t\tstrOS = \"IBM OS/2\";\r\n\t\t} else if (strUserAgent.indexOf(\"beos\") !== -1) {\r\n\t\t\tstrOS = \"BeOS\";\r\n\t\t} else if (strUserAgent.indexOf(\"playbook\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry (Playbook)\";\r\n\t\t} else if (strUserAgent.indexOf(\"wnd.rim\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry (IE/FF Emulator)\";\r\n\t\t} else if (strUserAgent.indexOf(\"blackberry\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry\";\r\n\t\t} else if (strUserAgent.indexOf(\"palm\") !== -1) {\r\n\t\t\tstrOS = \"Palm OS\";\r\n\t\t} else if (strUserAgent.indexOf(\"webos\") !== -1) {\r\n\t\t\tstrOS = \"WebOS\";\r\n\t\t} else if (strUserAgent.indexOf(\"hpwos\") !== -1) {\r\n\t\t\tstrOS = \"WebOS (HP)\";\r\n\t\t} else if (strUserAgent.indexOf(\"kindle\") !== -1) {\r\n\t\t\tstrOS = \"Kindle\";\r\n\t\t} else if (strUserAgent.indexOf(\"wii\") !== -1) {\r\n\t\t\tstrOS = \"Nintendo (Wii)\";\r\n\t\t} else if (strUserAgent.indexOf(\"nintendo ds\") !== -1) {\r\n\t\t\tstrOS = \"Nintendo (DS)\";\r\n\t\t} else if (strUserAgent.indexOf(\"playstation 3\") !== -1) {\r\n\t\t\tstrOS = \"Sony (Playstation Console)\";\r\n\t\t} else if (strUserAgent.indexOf(\"playstation portable\") !== -1) {\r\n\t\t\tstrOS = \"Sony (Playstation Portable)\";\r\n\t\t} else if (strUserAgent.indexOf(\"webtv\") !== -1) {\r\n\t\t\tstrOS = \"MSN TV (WebTV)\";\r\n\t\t} else if (strUserAgent.indexOf(\"inferno\") !== -1) {\r\n\t\t\tstrOS = \"Inferno\";\r\n\t\t} else {\r\n\t\t\tstrOS = \"Unknown\";\r\n\t\t}\r\n\t\tif (strPlatform.indexOf(\"x64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"wow64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"win64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"win32\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x32\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x86\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits*\";\r\n\t\t} else if (strPlatform.indexOf(\"ppc\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"alpha\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"68k\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"iphone\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"android\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else {\r\n\t\t\tstrOSBits = \"Unknown\";\r\n\t\t}\r\n\t\tstrOut = strOS + strSep + strOSBits;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_useragent() {\r\n\t\"use strict\";\r\n\tvar strSep, strTmp, strUserAgent, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrTmp = null;\r\n\tstrUserAgent = null;\r\n\tstrOut = null;\r\n\r\n\t/* navigator.userAgent is supported by all major browsers */\r\n\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t/* navigator.platform is supported by all major browsers */\r\n\tstrTmp = strUserAgent + strSep + navigator.platform;\r\n\t/* navigator.cpuClass only supported in IE */\r\n\tif (navigator.cpuClass) {\r\n\t\tstrTmp += strSep + navigator.cpuClass;\r\n\t}\r\n\t/* navigator.browserLanguage only supported in IE, Safari and Chrome */\r\n\tif (navigator.browserLanguage) {\r\n\t\tstrTmp += strSep + navigator.browserLanguage;\r\n\t} else {\r\n\t\tstrTmp += strSep + navigator.language;\r\n\t}\r\n\tstrOut = strTmp;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_timezone() {\r\n\t\"use strict\";\r\n\tvar strOnError, dtDate, numOffset, numGMTHours, numOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tdtDate = null;\r\n\tnumOffset = null;\r\n\tnumGMTHours = null;\r\n\tnumOut = null;\r\n\r\n\ttry {\r\n\t\tdtDate = new Date();\r\n\t\tnumOffset = dtDate.getTimezoneOffset();\r\n\t\tnumGMTHours = (numOffset / 60) * (-1);\r\n\t\tnumOut = numGMTHours;\r\n\t\treturn numOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_touch() {\r\n\t\"use strict\";\r\n\tvar bolTouchEnabled, bolOut;\r\n\r\n\tbolTouchEnabled = false;\r\n\tbolOut = null;\r\n\r\n\ttry {\r\n\t\tif (document.createEvent(\"TouchEvent\")) {\r\n\t\t\tbolTouchEnabled = true;\r\n\t\t}\r\n\t\tbolOut = bolTouchEnabled;\r\n\t\treturn bolOut;\r\n\t} catch (ignore) {\r\n\t\tbolOut = bolTouchEnabled\r\n\t\treturn bolOut;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_truebrowser() {\r\n\t\"use strict\";\r\n\tvar strBrowser, strUserAgent, strOut;\r\n\r\n\tstrBrowser = \"Unknown\";\r\n\tstrUserAgent = null;\r\n\tstrOut = null;\r\n\r\n\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\r\n\t/* Checks for different browsers, cannot use Try/Catch block */\r\n\tif (document.all && document.getElementById && navigator.savePreferences && (strUserAgent.indexOf(\"Netfront\") < 0) && navigator.appName !== \"Blazer\") {\r\n\t\tstrBrowser = \"Escape 5\";\r\n\t} else if (navigator.vendor === \"KDE\") {\r\n\t\tstrBrowser = \"Konqueror\";\r\n\t} else if (document.childNodes && !document.all && !navigator.taintEnabled && !navigator.accentColorName) {\r\n\t\tstrBrowser = \"Safari\";\r\n\t} else if (document.childNodes && !document.all && !navigator.taintEnabled && navigator.accentColorName) {\r\n\t\tstrBrowser = \"OmniWeb 4.5+\";\r\n\t} else if (navigator.__ice_version) {\r\n\t\tstrBrowser = \"ICEBrowser\";\r\n\t} else if (window.ScriptEngine && ScriptEngine().indexOf(\"InScript\") + 1 && document.createElement) {\r\n\t\tstrBrowser = \"iCab 3+\";\r\n\t} else if (window.ScriptEngine && ScriptEngine().indexOf(\"InScript\") + 1) {\r\n\t\tstrBrowser = \"iCab 2-\";\r\n\t} else if (strUserAgent.indexOf(\"hotjava\") + 1 && (navigator.accentColorName) === \"undefined\") {\r\n\t\tstrBrowser = \"HotJava\";\r\n\t} else if (document.layers && !document.classes) {\r\n\t\tstrBrowser = \"Omniweb 4.2-\";\r\n\t} else if (document.layers && !navigator.mimeTypes[\"*\"]) {\r\n\t\tstrBrowser = \"Escape 4\";\r\n\t} else if (document.layers) {\r\n\t\tstrBrowser = \"Netscape 4\";\r\n\t} else if (window.opera && document.getElementsByClassName) {\r\n\t\tstrBrowser = \"Opera 9.5+\";\r\n\t} else if (window.opera && window.getComputedStyle) {\r\n\t\tstrBrowser = \"Opera 8\";\r\n\t} else if (window.opera && document.childNodes) {\r\n\t\tstrBrowser = \"Opera 7\";\r\n\t} else if (window.opera) {\r\n\t\tstrBrowser = \"Opera \" + window.opera.version();\r\n\t} else if (navigator.appName.indexOf(\"WebTV\") + 1) {\r\n\t\tstrBrowser = \"WebTV\";\r\n\t} else if (strUserAgent.indexOf(\"netgem\") + 1) {\r\n\t\tstrBrowser = \"Netgem NetBox\";\r\n\t} else if (strUserAgent.indexOf(\"opentv\") + 1) {\r\n\t\tstrBrowser = \"OpenTV\";\r\n\t} else if (strUserAgent.indexOf(\"ipanel\") + 1) {\r\n\t\tstrBrowser = \"iPanel MicroBrowser\";\r\n\t} else if (document.getElementById && !document.childNodes) {\r\n\t\tstrBrowser = \"Clue browser\";\r\n\t} else if (navigator.product && navigator.product.indexOf(\"Hv\") === 0) {\r\n\t\tstrBrowser = \"Tkhtml Hv3+\";\r\n\t} else if (typeof InstallTrigger !== \"undefined\") {\r\n\t\tstrBrowser = \"Firefox\";\r\n\t} else if (window.atob) {\r\n\t\tstrBrowser = \"Internet Explorer 10+\";\r\n\t} else if (XDomainRequest && window.performance) {\r\n\t\tstrBrowser = \"Internet Explorer 9\";\r\n\t} else if (XDomainRequest) {\r\n\t\tstrBrowser = \"Internet Explorer 8\";\r\n\t} else if (document.documentElement && document.documentElement.style.maxHeight !== \"undefined\") {\r\n\t\tstrBrowser = \"Internet Explorer 7\"; //xxxxx\r\n\t} else if (document.compatMode && document.all) {\r\n\t\tstrBrowser = \"Internet Explorer 6\"; //xxxxx\r\n\t} else if (window.createPopup) {\r\n\t\tstrBrowser = \"Internet Explorer 5.5\";\r\n\t} else if (window.attachEvent) {\r\n\t\tstrBrowser = \"Internet Explorer 5\";\r\n\t} else if (document.all && navigator.appName !== \"Microsoft Pocket Internet Explorer\") {\r\n\t\tstrBrowser = \"Internet Explorer 4\";\r\n\t} else if ((strUserAgent.indexOf(\"msie\") + 1) && window.ActiveXObject) {\r\n\t\tstrBrowser = \"Pocket Internet Explorer\";\r\n\t} else if (document.getElementById && ((strUserAgent.indexOf(\"netfront\") + 1) || navigator.appName === \"Blazer\" || navigator.product === \"Gecko\" || (navigator.appName.indexOf(\"PSP\") + 1) || (navigator.appName.indexOf(\"PLAYSTATION 3\") + 1))) {\r\n\t\tstrBrowser = \"NetFront 3+\";\r\n\t} else if (navigator.product === \"Gecko\" && !navigator.savePreferences) {\r\n\t\tstrBrowser = \"Gecko engine (Mozilla, Netscape 6+ etc.)\";\r\n\t} else if (window.chrome) {\r\n\t\tstrBrowser = \"Chrome\";\r\n\t}\r\n\tstrOut = strBrowser;\r\n\treturn strOut;\r\n}\r\n\r\nvar glbOnError = \"N/A\"\r\nvar glbSep = \"|\";\r\n\r\nfunction activeXDetect(componentClassID) {\r\n\t\"use strict\";\r\n\tvar strComponentVersion, strOut;\r\n\r\n\tstrComponentVersion = \"\";\r\n\tstrOut = \"\";\r\n\r\n\ttry {\r\n\t\tstrComponentVersion = document.body.getComponentVersion(\"{\" + componentClassID + \"}\", \"ComponentID\");\r\n\t\tif (strComponentVersion !== null) {\r\n\t\t\tstrOut = strComponentVersion;\r\n\t\t} else {\r\n\t\t\tstrOut = false;\r\n\t\t}\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}\r\n\r\nfunction stripIllegalChars(strValue) {\r\n\t\"use strict\";\r\n\tvar iCounter, strOriginal, strOut;\r\n\r\n\tiCounter = 0;\r\n\tstrOriginal = \"\";\r\n\tstrOut = \"\";\r\n\r\n\ttry {\r\n\t\tstrOriginal = strValue.toLowerCase();\r\n\t\tfor (iCounter = 0; iCounter < strOriginal.length; iCounter = iCounter + 1) {\r\n\t\t\tif (strOriginal.charAt(iCounter) !== \"\\n\" && strOriginal.charAt(iCounter) !== \"/\" && strOriginal.charAt(iCounter) !== \"\\\\\") {\r\n\t\t\t\tstrOut = strOut + strOriginal.charAt(iCounter);\r\n\t\t\t} else if (strOriginal.charAt(iCounter) === \"\\n\") {\r\n\t\t\t\tstrOut = strOut + \"n\";\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}\r\n\r\nfunction hashtable_containsKey(key) {\r\n\t\"use strict\";\r\n\tvar bolExists, iCounter;\r\n\r\n\tbolExists = false;\r\n\tiCounter = 0;\r\n\r\n\tfor (iCounter = 0; iCounter < this.hashtable.length; iCounter = iCounter + 1) {\r\n\t\tif (iCounter === key && this.hashtable[iCounter] !== null) {\r\n\t\t\tbolExists = true;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn bolExists;\r\n}\r\n\r\nfunction hashtable_get(key) {\r\n\t\"use strict\";\r\n\treturn this.hashtable[key];\r\n}\r\n\r\nfunction hashtable_keys() {\r\n\t\"use strict\";\r\n\tvar keys, iCounter;\r\n\r\n\tkeys = [];\r\n\tiCounter = 0;\r\n\r\n\tfor (iCounter in this.hashtable) {\r\n\t\tif (this.hashtable[iCounter] !== null) {\r\n\t\t\tkeys.push(iCounter);\r\n\t\t}\r\n\t}\r\n\treturn keys;\r\n}\r\n\r\nfunction hashtable_put(key, value) {\r\n\t\"use strict\";\r\n\tif (key === null || value === null) {\r\n\t\tthrow \"NullPointerException {\" + key + \"},{\" + value + \"}\";\r\n\t}\r\n\tthis.hashtable[key] = value;\r\n}\r\n\r\nfunction hashtable_size() {\r\n\t\"use strict\";\r\n\tvar iSize, iCounter, iOut;\r\n\r\n\tiSize = 0;\r\n\tiCounter = 0;\r\n\tiOut = 0;\r\n\r\n\tfor (iCounter in this.hashtable) {\r\n\t\tif (this.hashtable[iCounter] !== null) {\r\n\t\t\tiSize = iSize + 1;\r\n\t\t}\r\n\t}\r\n\tiOut = iSize;\r\n\treturn iOut;\r\n}\r\n\r\nfunction Hashtable() {\r\n\t\"use strict\";\r\n\tthis.containsKey = hashtable_containsKey;\r\n\tthis.get = hashtable_get;\r\n\tthis.keys = hashtable_keys;\r\n\tthis.put = hashtable_put;\r\n\tthis.size = hashtable_size;\r\n\tthis.hashtable = [];\r\n}\r\n\r\n/* Detect Plugins */\r\nfunction fingerprint_plugins() {\r\n\t\"use strict\";\r\n\tvar htIEComponents, strKey, strName, strVersion, strTemp, bolFirst, iCount, strMimeType, strOut;\r\n\r\n\ttry {\r\n\t\t/* Create hashtable of IE components */\r\n\t\thtIEComponents = new Hashtable();\r\n\t\thtIEComponents.put(\"7790769C-0471-11D2-AF11-00C04FA35D02\", \"AddressBook\"); // Address Book\r\n\t\thtIEComponents.put(\"47F67D00-9E55-11D1-BAEF-00C04FC2D130\", \"AolArtFormat\"); // AOL ART Image Format Support\r\n\t\thtIEComponents.put(\"76C19B38-F0C8-11CF-87CC-0020AFEECF20\", \"ArabicDS\"); // Arabic Text Display Support\r\n\t\thtIEComponents.put(\"76C19B34-F0C8-11CF-87CC-0020AFEECF20\", \"ChineseSDS\"); // Chinese (Simplified) Text Display Support\r\n\t\thtIEComponents.put(\"76C19B33-F0C8-11CF-87CC-0020AFEECF20\", \"ChineseTDS\"); // Chinese (traditional) Text Display Support\r\n\t\thtIEComponents.put(\"238F6F83-B8B4-11CF-8771-00A024541EE3\", \"CitrixICA\"); // Citrix ICA Client\r\n\t\thtIEComponents.put(\"283807B5-2C60-11D0-A31D-00AA00B92C03\", \"DirectAnim\"); // DirectAnimation\r\n\t\thtIEComponents.put(\"44BBA848-CC51-11CF-AAFA-00AA00B6015C\", \"DirectShow\"); // DirectShow\r\n\t\thtIEComponents.put(\"9381D8F2-0288-11D0-9501-00AA00B911A5\", \"DynHTML\"); // Dynamic HTML Data Binding\r\n\t\thtIEComponents.put(\"4F216970-C90C-11D1-B5C7-0000F8051515\", \"DynHTML4Java\"); // Dynamic HTML Data Binding for Java\r\n\t\thtIEComponents.put(\"D27CDB6E-AE6D-11CF-96B8-444553540000\", \"Flash\"); // Macromedia Flash\r\n\t\thtIEComponents.put(\"76C19B36-F0C8-11CF-87CC-0020AFEECF20\", \"HebrewDS\"); // Hebrew Text Display Support\r\n\t\thtIEComponents.put(\"630B1DA0-B465-11D1-9948-00C04F98BBC9\", \"IEBrwEnh\"); // Internet Explorer Browsing Enhancements\r\n\t\thtIEComponents.put(\"08B0E5C0-4FCB-11CF-AAA5-00401C608555\", \"IEClass4Java\"); // Internet Explorer Classes for Java\r\n\t\thtIEComponents.put(\"45EA75A0-A269-11D1-B5BF-0000F8051515\", \"IEHelp\"); // Internet Explorer Help\r\n\t\thtIEComponents.put(\"DE5AED00-A4BF-11D1-9948-00C04F98BBC9\", \"IEHelpEng\"); // Internet Explorer Help Engine\r\n\t\thtIEComponents.put(\"89820200-ECBD-11CF-8B85-00AA005B4383\", \"IE5WebBrw\"); // Internet Explorer 5/6 Web Browser\r\n\t\thtIEComponents.put(\"5A8D6EE0-3E18-11D0-821E-444553540000\", \"InetConnectionWiz\"); // Internet Connection Wizard\r\n\t\thtIEComponents.put(\"76C19B30-F0C8-11CF-87CC-0020AFEECF20\", \"JapaneseDS\"); // Japanese Text Display Support\r\n\t\thtIEComponents.put(\"76C19B31-F0C8-11CF-87CC-0020AFEECF20\", \"KoreanDS\"); // Korean Text Display Support\r\n\t\thtIEComponents.put(\"76C19B50-F0C8-11CF-87CC-0020AFEECF20\", \"LanguageAS\"); // Language Auto-Selection\r\n\t\thtIEComponents.put(\"08B0E5C0-4FCB-11CF-AAA5-00401C608500\", \"MsftVM\"); // Microsoft virtual machine\r\n\t\thtIEComponents.put(\"5945C046-LE7D-LLDL-BC44-00C04FD912BE\", \"MSNMessengerSrv\"); // MSN Messenger Service\r\n\t\thtIEComponents.put(\"44BBA842-CC51-11CF-AAFA-00AA00B6015B\", \"NetMeetingNT\"); // NetMeeting NT\r\n\t\thtIEComponents.put(\"3AF36230-A269-11D1-B5BF-0000F8051515\", \"OfflineBrwPack\"); // Offline Browsing Pack\r\n\t\thtIEComponents.put(\"44BBA840-CC51-11CF-AAFA-00AA00B6015C\", \"OutlookExpress\"); // Outlook Express\r\n\t\thtIEComponents.put(\"76C19B32-F0C8-11CF-87CC-0020AFEECF20\", \"PanEuropeanDS\"); // Pan-European Text Display Support\r\n\t\thtIEComponents.put(\"4063BE15-3B08-470D-A0D5-B37161CFFD69\", \"QuickTime\"); // Apple Quick Time\r\n\t\thtIEComponents.put(\"DE4AF3B0-F4D4-11D3-B41A-0050DA2E6C21\", \"QuickTimeCheck\"); // Apple Quick Time Check\r\n\t\thtIEComponents.put(\"3049C3E9-B461-4BC5-8870-4C09146192CA\", \"RealPlayer\"); // RealPlayer Download and Record Plugin for IE\r\n\t\thtIEComponents.put(\"2A202491-F00D-11CF-87CC-0020AFEECF20\", \"ShockwaveDir\"); // Macromedia Shockwave Director\r\n\t\thtIEComponents.put(\"3E01D8E0-A72B-4C9F-99BD-8A6E7B97A48D\", \"Skype\"); // Skype\r\n\t\thtIEComponents.put(\"CC2A9BA0-3BDD-11D0-821E-444553540000\", \"TaskScheduler\"); // Task Scheduler\r\n\t\thtIEComponents.put(\"76C19B35-F0C8-11CF-87CC-0020AFEECF20\", \"ThaiDS\"); // Thai Text Display Support\r\n\t\thtIEComponents.put(\"3BF42070-B3B1-11D1-B5C5-0000F8051515\", \"Uniscribe\"); // Uniscribe\r\n\t\thtIEComponents.put(\"4F645220-306D-11D2-995D-00C04F98BBC9\", \"VBScripting\"); // Visual Basic Scripting Support v5.6\r\n\t\thtIEComponents.put(\"76C19B37-F0C8-11CF-87CC-0020AFEECF20\", \"VietnameseDS\"); // Vietnamese Text Display Support\r\n\t\thtIEComponents.put(\"10072CEC-8CC1-11D1-986E-00A0C955B42F\", \"VML\"); // Vector Graphics Rendering (VML)\r\n\t\thtIEComponents.put(\"90E2BA2E-DD1B-4CDE-9134-7A8B86D33CA7\", \"WebEx\"); // WebEx Productivity Tools\r\n\t\thtIEComponents.put(\"73FA19D0-2D75-11D2-995D-00C04F98BBC9\", \"WebFolders\"); // Web Folders\r\n\t\thtIEComponents.put(\"89820200-ECBD-11CF-8B85-00AA005B4340\", \"WinDesktopUpdateNT\"); // Windows Desktop Update NT\r\n\t\thtIEComponents.put(\"9030D464-4C02-4ABF-8ECC-5164760863C6\", \"WinLive\"); // Windows Live ID Sign-in Helper\r\n\t\thtIEComponents.put(\"6BF52A52-394A-11D3-B153-00C04F79FAA6\", \"WinMediaPlayer\"); // Windows Media Player (Versions 7, 8 or 9)\r\n\t\thtIEComponents.put(\"22D6F312-B0F6-11D0-94AB-0080C74C7E95\", \"WinMediaPlayerTrad\"); // Windows Media Player (Traditional Versions)\r\n\r\n\t\tstrTemp = \"\";\r\n\t\tbolFirst = true;\r\n\r\n\t\t/* strOpera gives full path of the file, extract the filenames, ignoring description and length */\r\n\t\tif (navigator.plugins.length > 0) {\r\n\t\t\tfor (iCount = 0; iCount < navigator.plugins.length; iCount = iCount + 1) {\r\n\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\tstrTemp += navigator.plugins[iCount].name;\r\n\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrTemp += glbSep + navigator.plugins[iCount].name;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (navigator.mimeTypes.length > 0) {\r\n\t\t\tstrMimeType = navigator.mimeTypes;\r\n\t\t\tfor (iCount = 0; iCount < strMimeType.length; iCount = iCount + 1) {\r\n\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\tstrTemp += strMimeType[iCount].description;\r\n\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrTemp += glbSep + strMimeType[iCount].description;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tdocument.body.addBehavior(\"#default#clientCaps\");\r\n\t\t\tstrKey = htIEComponents.keys();\r\n\t\t\tfor (iCount = 0; iCount < htIEComponents.size(); iCount = iCount + 1) {\r\n\t\t\t\tstrVersion = activeXDetect(strKey[iCount]);\r\n\t\t\t\tstrName = htIEComponents.get(strKey[iCount]);\r\n\t\t\t\tif (strVersion) {\r\n\t\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\t\tstrTemp = strName + glbPair + strVersion;\r\n\t\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tstrTemp += glbSep + strName + glbPair + strVersion;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tstrTemp = strTemp.replace(/,/g, \".\");\r\n\t\t}\r\n\t\tstrTemp = stripIllegalChars(strTemp);\r\n\t\tif (strTemp === \"\") {\r\n\t\t\tstrTemp = \"None\";\r\n\t\t}\r\n\t\tstrOut = strTemp;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}"],"sourceRoot":""} \ No newline at end of file diff --git a/webAO/fingerprint.js b/webAO/fingerprint.js new file mode 100644 index 0000000..8fa2063 --- /dev/null +++ b/webAO/fingerprint.js @@ -0,0 +1,1192 @@ +/* +*************************************************** +** http://davealger.info +*************************************************** + +This is a javascript only way to fingerprint a user with better than 90% accuracy in as few bytes as possible and no cookie storage! + +Special thanks to Valentin Vasilyev for the original fingerprintjs slightly modified and to Open Source Device Fingerprinting by Dark Wave Tech for the various identity functions + +*************************************************** +*/ +export default class Fingerprint { + constructor(options) { + var nativeForEach, nativeMap; + nativeForEach = Array.prototype.forEach; + nativeMap = Array.prototype.map; + this.each = function(obj, iterator, context) { + if (obj === null) { + return; + } + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === {}) + return; + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (iterator.call(context, obj[key], key, obj) === {}) + return; + } + } + } + }; + this.map = function(obj, iterator, context) { + var results = []; + if (obj == null) + return results; + if (nativeMap && obj.map === nativeMap) + return obj.map(iterator, context); + this.each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }; + if (typeof options == "object") { + this.hasher = options.hasher; + this.screen_resolution = options.screen_resolution; + this.screen_orientation = options.screen_orientation; + this.canvas = options.canvas; + this.ie_activex = options.ie_activex; + } else if (typeof options == "function") { + this.hasher = options; + } + } +} +Fingerprint.prototype = { + get: function() { + var keys = []; + keys.push(navigator.userAgent); + keys.push(navigator.language); + keys.push(screen.colorDepth); + if (this.screen_resolution) { + var resolution = this.getScreenResolution(); + if (typeof resolution !== "undefined") { + keys.push(this.getScreenResolution().join("x")); + } + } + keys.push(new Date().getTimezoneOffset()); + keys.push(this.hasSessionStorage()); + keys.push(this.hasLocalStorage()); + keys.push(!!window.indexedDB); + if (document.body) { + keys.push(typeof(document.body.addBehavior)); + } else { + keys.push(typeof undefined); + } + keys.push(typeof(window.openDatabase)); + keys.push(navigator.cpuClass); + keys.push(navigator.platform); + keys.push(navigator.doNotTrack); + keys.push(this.getPluginsString()); + if (this.canvas && this.isCanvasSupported()) { + keys.push(this.getCanvasFingerprint()); + } + if (this.hasher) { + return this.hasher(keys.join("###"), 31); + } else { + return this.murmurhash3_32_gc(keys.join("###"), 31); + } + }, + murmurhash3_32_gc: function(key, seed) { + var remainder, bytes, h1, h1b, c1, c2, k1, i; + remainder = key.length & 3; + bytes = key.length - remainder; + h1 = seed; + c1 = 0xcc9e2d51; + c2 = 0x1b873593; + i = 0; + while (i < bytes) { + k1 = ((key.charCodeAt(i) & 0xff)) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24); + ++i; + k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff; + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff; + h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16)); + } + k1 = 0; + switch (remainder) { + case 3: + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + case 2: + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + case 1: + k1 ^= (key.charCodeAt(i) & 0xff); + k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; + h1 ^= k1; + } + h1 ^= key.length; + h1 ^= h1 >>> 16; + h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff; + h1 ^= h1 >>> 16; + return h1 >>> 0; + }, + hasLocalStorage: function() { + try { + return !!window.localStorage; + } catch (e) { + return true; + } + }, + hasSessionStorage: function() { + try { + return !!window.sessionStorage; + } catch (e) { + return true; + } + }, + isCanvasSupported: function() { + var elem = document.createElement("canvas"); + return !!(elem.getContext && elem.getContext("2d")); + }, + isIE: function() { + if (navigator.appName === "Microsoft Internet Explorer") { + return true; + } else if (navigator.appName === "Netscape" && /Trident/.test(navigator.userAgent)) { + return true; + } + return false; + }, + getPluginsString: function() { + if (this.isIE() && this.ie_activex) { + return this.getIEPluginsString(); + } else { + return this.getRegularPluginsString(); + } + }, + getRegularPluginsString: function() { + return this.map(navigator.plugins, function(p) { + var mimeTypes = this.map(p, function(mt) { + return [mt.type, mt.suffixes].join("~"); + }).join(","); + return [p.name, p.description, mimeTypes].join("::"); + }, this).join(";"); + }, + getIEPluginsString: function() { + if (window.ActiveXObject) { + var names = ["ShockwaveFlash.ShockwaveFlash", "AcroPDF.PDF", "PDF.PdfCtrl", "QuickTime.QuickTime", "rmocx.RealPlayer G2 Control", "rmocx.RealPlayer G2 Control.1", "RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)", "RealVideo.RealVideo(tm) ActiveX Control (32-bit)", "RealPlayer", "SWCtl.SWCtl", "WMPlayer.OCX", "AgControl.AgControl", "Skype.Detection"]; + return this.map(names, function(name) { + try { + new ActiveXObject(name); + return name; + } catch (e) { + return null; + } + }).join(";"); + } else { + return ""; + } + }, + getScreenResolution: function() { + var resolution; + if (this.screen_orientation) { + resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height]; + } else { + resolution = [screen.height, screen.width]; + } + return resolution; + }, + getCanvasFingerprint: function() { + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-={}|[]\:\"<>?;,."; + ctx.textBaseline = "top"; + ctx.font = "14px 'Arial'"; + ctx.textBaseline = "alphabetic"; + ctx.fillStyle = "#f60"; + ctx.fillRect(125, 1, 62, 20); + ctx.fillStyle = "#069"; + ctx.fillText(txt, 2, 15); + ctx.fillStyle = "rgba(102, 204, 0, 0.7)"; + ctx.fillText(txt, 4, 17); + return canvas.toDataURL(); + } +}; + +/**************************************************/ + +/** +http://www.darkwavetech.com/fingerprint/fingerprint_code.html +**/ +function fingerprint_flash() { + "use strict"; + var strOnError, objPlayerVersion, strVersion, strOut; + + strOnError = "N/A"; + objPlayerVersion = null; + strVersion = null; + strOut = null; + + try { + objPlayerVersion = swfobject.getFlashPlayerVersion(); + strVersion = objPlayerVersion.major + "." + objPlayerVersion.minor + "." + objPlayerVersion.release; + if (strVersion === "0.0.0") { + strVersion = "N/A"; + } + strOut = strVersion; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_browser() { + "use strict"; + var strOnError, strUserAgent, numVersion, strBrowser, strOut; + + strOnError = "Error"; + strUserAgent = null; + numVersion = null; + strBrowser = null; + strOut = null; + + try { + strUserAgent = navigator.userAgent.toLowerCase(); + if (/msie (\d+\.\d+);/.test(strUserAgent)) { //test for MSIE x.x; + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + if (strUserAgent.indexOf("trident/6") > -1) { + numVersion = 10; + } + if (strUserAgent.indexOf("trident/5") > -1) { + numVersion = 9; + } + if (strUserAgent.indexOf("trident/4") > -1) { + numVersion = 8; + } + strBrowser = "Internet Explorer " + numVersion; + } else if (strUserAgent.indexOf("trident/7") > -1) { //IE 11+ gets rid of the legacy 'MSIE' in the user-agent string; + numVersion = 11; + strBrowser = "Internet Explorer " + numVersion; + } else if (/firefox[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Firefox/x.x or Firefox x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Firefox " + numVersion; + } else if (/opera[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Opera/x.x or Opera x.x (ignoring remaining decimal places); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Opera " + numVersion; + } else if (/chrome[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Chrome/x.x or Chrome x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Chrome " + numVersion; + } else if (/version[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Version/x.x or Version x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Safari " + numVersion; + } else if (/rv[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for rv/x.x or rv x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Mozilla " + numVersion; + } else if (/mozilla[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Mozilla/x.x or Mozilla x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Mozilla " + numVersion; + } else if (/binget[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for BinGet/x.x or BinGet x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (BinGet) " + numVersion; + } else if (/curl[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Curl/x.x or Curl x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (cURL) " + numVersion; + } else if (/java[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Java/x.x or Java x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (Java) " + numVersion; + } else if (/libwww-perl[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for libwww-perl/x.x or libwww-perl x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (libwww-perl) " + numVersion; + } else if (/microsoft url control -[\s](\d+\.\d+)/.test(strUserAgent)) { //test for Microsoft URL Control - x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (Microsoft URL Control) " + numVersion; + } else if (/peach[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for Peach/x.x or Peach x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (Peach) " + numVersion; + } else if (/php[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for PHP/x.x or PHP x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (PHP) " + numVersion; + } else if (/pxyscand[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for pxyscand/x.x or pxyscand x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (pxyscand) " + numVersion; + } else if (/pycurl[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for pycurl/x.x or pycurl x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (PycURL) " + numVersion; + } else if (/python-urllib[\/\s](\d+\.\d+)/.test(strUserAgent)) { //test for python-urllib/x.x or python-urllib x.x (ignoring remaining digits); + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Library (Python URLlib) " + numVersion; + } else if (/appengine-google/.test(strUserAgent)) { //test for AppEngine-Google; + numVersion = Number(RegExp.$1); // capture x.x portion and store as a number + strBrowser = "Cloud (Google AppEngine) " + numVersion; + } else { + strBrowser = "Unknown"; + } + strOut = strBrowser; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_canvas() { + "use strict"; + var strOnError, canvas, strCText, strText, strOut; + + strOnError = "Error"; + canvas = null; + strCText = null; + strText = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?"; + strOut = null; + + try { + canvas = document.createElement("canvas"); + strCText = canvas.getContext("2d"); + strCText.textBaseline = "top"; + strCText.font = "14px 'Arial'"; + strCText.textBaseline = "alphabetic"; + strCText.fillStyle = "#f60"; + strCText.fillRect(125, 1, 62, 20); + strCText.fillStyle = "#069"; + strCText.fillText(strText, 2, 15); + strCText.fillStyle = "rgba(102, 204, 0, 0.7)"; + strCText.fillText(strText, 4, 17); + strOut = canvas.toDataURL(); + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_connection() { + "use strict"; + var strOnError, strConnection, strOut; + + strOnError = "N/A"; + strConnection = null; + strOut = null; + + try { + // only on android + strConnection = navigator.connection.type; + strOut = strConnection; + } catch (err) { + // return N/A if navigator.connection object does not apply to this device + return strOnError; + } + return strOut; +} + +function fingerprint_cookie() { + "use strict"; + var strOnError, bolCookieEnabled, bolOut; + + strOnError = "Error"; + bolCookieEnabled = null; + bolOut = null; + + try { + bolCookieEnabled = (navigator.cookieEnabled) ? true : false; + + //if not IE4+ nor NS6+ + if (typeof navigator.cookieEnabled === "undefined" && !bolCookieEnabled) { + document.cookie = "testcookie"; + bolCookieEnabled = (document.cookie.indexOf("testcookie") !== -1) ? true : false; + } + bolOut = bolCookieEnabled; + return bolOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_display() { + "use strict"; + var strSep, strPair, strOnError, strScreen, strDisplay, strOut; + + strSep = "|"; + strPair = "="; + strOnError = "Error"; + strScreen = null; + strDisplay = null; + strOut = null; + + try { + strScreen = window.screen; + if (strScreen) { + strDisplay = strScreen.colorDepth + strSep + strScreen.width + strSep + strScreen.height + strSep + strScreen.availWidth + strSep + strScreen.availHeight; + } + strOut = strDisplay; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_fontsmoothing() { + "use strict"; + var strOnError, strFontSmoothing, canvasNode, ctx, i, j, imageData, alpha, strOut; + + strOnError = "Unknown"; + strFontSmoothing = null; + canvasNode = null; + ctx = null; + imageData = null; + alpha = null; + strOut = null; + + if (typeof(screen.fontSmoothingEnabled) !== "undefined") { + strFontSmoothing = screen.fontSmoothingEnabled; + } else { + try { + fontsmoothing = "false"; + canvasNode = document.createElement("canvas"); + canvasNode.width = "35"; + canvasNode.height = "35"; + canvasNode.style.display = "none"; + document.body.appendChild(canvasNode); + ctx = canvasNode.getContext("2d"); + ctx.textBaseline = "top"; + ctx.font = "32px Arial"; + ctx.fillStyle = "black"; + ctx.strokeStyle = "black"; + ctx.fillText("O", 0, 0); + for (j = 8; j <= 32; j = j + 1) { + for (i = 1; i <= 32; i = i + 1) { + imageData = ctx.getImageData(i, j, 1, 1).data; + alpha = imageData[3]; + if (alpha !== 255 && alpha !== 0) { + strFontSmoothing = "true"; // font-smoothing must be on. + } + } + } + strOut = strFontSmoothing; + } catch (err) { + return strOnError; + } + } + strOut = strFontSmoothing; + return strOut; +} + +function fingerprint_fonts() { + "use strict"; + var strOnError, style, fonts, count, template, fragment, divs, i, font, div, body, result, e; + + strOnError = "Error"; + style = null; + fonts = null; + font = null; + count = 0; + template = null; + divs = null; + e = null; + div = null; + body = null; + i = 0; + + try { + style = "position: absolute; visibility: hidden; display: block !important"; + fonts = ["8bitoperator", "Abadi MT Condensed Light","Ace Attorney", "Adobe Fangsong Std", "Adobe Hebrew", "Adobe Ming Std", "Agency FB", "Aharoni", "Andalus", "Angsana New", "AngsanaUPC", "Aparajita", "Arab", "Arabic Transparent", "Arabic Typesetting", "Arial Baltic", "Arial Black", "Arial CE", "Arial CYR", "Arial Greek", "Arial TUR", "Arial", "Arimo", "Batang", "BatangChe", "Bauhaus 93", "Bell MT", "Berlin Sans FB", "Bitstream Vera Serif", "Bodoni MT", "Bookman Old Style", "Braggadocio", "Broadway", "Browallia New", "BrowalliaUPC", "Calibri Light", "Calibri", "Californian FB", "Cambria Math", "Cambria", "Candara", "Castellar", "Casual", "Centaur", "Century", "Century Gothic", "Chalkduster", "Colonna MT", "Comic Sans MS", "Consolas", "Constantia", "Copperplate Gothic Light", "Corbel", "Cordia New", "CordiaUPC", "Courier New Baltic", "Courier New CE", "Courier New CYR", "Courier New Greek", "Courier New TUR", "Courier New", "DejaVu Sans", "DFKai-SB","DINEngschrift", "DaunPenh", "David", "DejaVu LGC Sans Mono", "Desdemona", "DilleniaUPC", "DokChampa", "Dotum", "DotumChe", "Dubai", "Ebrima", "Engravers MT", "Eras Bold ITC", "Estrangelo Edessa", "EucrosiaUPC", "Euphemia", "Eurostile", "FangSong", "Forte", "FrankRuehl", "Franklin Gothic Heavy", "Franklin Gothic Medium", "FreesiaUPC", "French Script MT", "Gabriola", "Gautami", "Georgia", "Gigi", "Gisha", "Goudy Old Style", "Gulim", "GulimChe", "GungSeo", "Gungsuh", "GungsuhChe", "Haettenschweiler", "Harrington", "Hei S", "HeiT", "Heisei Kaku Gothic", "Hiragino Sans GB", "Impact", "Informal Roman", "IrisUPC", "Iskoola Pota", "JasmineUPC", "KacstOne", "KaiTi", "Kalinga", "Kartika", "Khmer UI", "Kino MT", "KodchiangUPC", "Kokila", "Kozuka Gothic Pr6N", "Lao UI", "Latha", "Leelawadee", "Levenim MT", "LilyUPC", "Lohit Gujarati", "Loma", "Lucida Bright", "Lucida Console", "Lucida Fax", "Lucida Sans Unicode", "MS Gothic", "MS Mincho", "MS PGothic", "MS PMincho", "MS Reference Sans Serif", "MS UI Gothic", "MV Boli", "Magneto", "Malgun Gothic", "Mangal", "Marlett", "Matura MT Script Capitals", "Meiryo UI", "Meiryo", "Menlo", "Microsoft Himalaya", "Microsoft JhengHei", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Sans Serif", "Microsoft Tai Le", "Microsoft Uighur", "Microsoft YaHei", "Microsoft Yi Baiti", "MingLiU", "MingLiU-ExtB", "MingLiU_HKSCS", "MingLiU_HKSCS-ExtB", "Miriam Fixed", "Miriam", "Mongolian Baiti", "MoolBoran", "More Perfect DOS VGA", "MS Outlook", "NSimSun", "Narkisim", "News Gothic MT", "Niagara Solid", "Nyala", "OCR A","Ocean Sans Std", "OpenSymbol", "PMingLiU", "PMingLiU-ExtB", "Palace Script MT", "Palatino Linotype", "Papyrus", "Perpetua", "Plantagenet Cherokee", "Playbill", "Prelude Bold", "Prelude Condensed Bold", "Prelude Condensed Medium", "Prelude Medium", "PreludeCompressedWGL Black", "PreludeCompressedWGL Bold", "PreludeCompressedWGL Light", "PreludeCompressedWGL Medium", "PreludeCondensedWGL Black", "PreludeCondensedWGL Bold", "PreludeCondensedWGL Light", "PreludeCondensedWGL Medium", "PreludeWGL Black", "PreludeWGL Bold", "PreludeWGL Light", "PreludeWGL Medium", "Raavi", "Rachana", "Rockwell", "Rod", "Sakkal Majalla", "Sawasdee", "Script MT Bold", "Segoe Print", "Segoe Script", "Segoe UI Emoji", "Segoe UI Historic", "Segoe UI Light", "Segoe UI Semibold", "Segoe UI Symbol", "Segoe UI", "Shonar Bangla", "Showcard Gothic", "Shruti", "SimHei", "SimSun", "SimSun-ExtB", "Simplified Arabic Fixed", "Simplified Arabic", "Snap ITC", "Sylfaen", "Symbol", "Tahoma", "TeamViewer13", "Times New Roman Baltic", "Times New Roman CE", "Times New Roman CYR", "Times New Roman Greek", "Times New Roman TUR", "Times New Roman", "TlwgMono", "Traditional Arabic", "Trebuchet MS", "Tunga", "Tw Cen MT Condensed Extra Bold", "Ubuntu", "Umpush", "Univers", "Utopia", "Utsaah", "Vani", "Verdana", "Vijaya", "Vladimir Script", "Vrinda", "Webdings", "Wide Latin", "Wingdings", "Yu Gothic", "Zrnic Rg"]; + count = fonts.length; + template = "ww" + "ww"; + fragment = document.createDocumentFragment(); + divs = []; + for (i = 0; i < count; i = i + 1) { + font = fonts[i]; + div = document.createElement("div"); + font = font.replace(/['"<>]/g, ""); + div.innerHTML = template.replace(/X/g, font); + div.style.cssText = style; + fragment.appendChild(div); + divs.push(div); + } + body = document.body; + body.insertBefore(fragment, body.firstChild); + result = []; + for (i = 0; i < count; i = i + 1) { + e = divs[i].getElementsByTagName("b"); + if (e[0].offsetWidth === e[1].offsetWidth) { + result.push(fonts[i]); + } + } + // do not combine these two loops, remove child will cause reflow + // and induce severe performance hit + for (i = 0; i < count; i = i + 1) { + body.removeChild(divs[i]); + } + return result.join("|"); + } catch (err) { + return strOnError; + } +} + +function fingerprint_formfields() { + "use strict"; + var i, j, numOfForms, numOfInputs, strFormsInPage, strFormsInputsData, strInputsInForm, strTmp, strOut; + + i = 0; + j = 0; + numOfForms = 0; + numOfInputs = 0; + strFormsInPage = ""; + strFormsInputsData = []; + strInputsInForm = ""; + strTmp = ""; + strOut = ""; + + strFormsInPage = document.getElementsByTagName("form"); + numOfForms = strFormsInPage.length; + strFormsInputsData.push("url=" + window.location.href); + for (i = 0; i < numOfForms; i = i + 1) { + strFormsInputsData.push("FORM=" + strFormsInPage[i].name); + strInputsInForm = strFormsInPage[i].getElementsByTagName("input"); + numOfInputs = strInputsInForm.length; + for (j = 0; j < numOfInputs; j = j + 1) { + if (strInputsInForm[j].type !== "hidden") { + strFormsInputsData.push("Input=" + strInputsInForm[j].name); + } + } + } + strTmp = strFormsInputsData.join("|"); + strOut = strTmp; + return strOut; +} + +function fingerprint_java() { + "use strict"; + var strOnError, strJavaEnabled, strOut; + + strOnError = "Error"; + strJavaEnabled = null; + strOut = null; + + try { + if (navigator.javaEnabled()) { + strJavaEnabled = "true"; + } else { + strJavaEnabled = "false"; + } + strOut = strJavaEnabled; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_language() { + "use strict"; + var strSep, strPair, strOnError, strLang, strTypeLng, strTypeBrLng, strTypeSysLng, strTypeUsrLng, strOut; + + strSep = "|"; + strPair = "="; + strOnError = "Error"; + strLang = null; + strTypeLng = null; + strTypeBrLng = null; + strTypeSysLng = null; + strTypeUsrLng = null; + strOut = null; + + try { + strTypeLng = typeof(navigator.language); + strTypeBrLng = typeof(navigator.browserLanguage); + strTypeSysLng = typeof(navigator.systemLanguage); + strTypeUsrLng = typeof(navigator.userLanguage); + + if (strTypeLng !== "undefined") { + strLang = "lang" + strPair + navigator.language + strSep; + } else if (strTypeBrLng !== "undefined") { + strLang = "lang" + strPair + navigator.browserLanguage + strSep; + } else { + strLang = "lang" + strPair + strSep; + } + if (strTypeSysLng !== "undefined") { + strLang += "syslang" + strPair + navigator.systemLanguage + strSep; + } else { + strLang += "syslang" + strPair + strSep; + } + if (strTypeUsrLng !== "undefined") { + strLang += "userlang" + strPair + navigator.userLanguage; + } else { + strLang += "userlang" + strPair; + } + strOut = strLang; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_silverlight() { + "use strict"; + var strOnError, objControl, objPlugin, strSilverlightVersion, strOut; + + strOnError = "Error"; + objControl = null; + objPlugin = null; + strSilverlightVersion = null; + strOut = null; + + try { + try { + objControl = new ActiveXObject("AgControl.AgControl"); + if (objControl.IsVersionSupported("5.0")) { + strSilverlightVersion = "5.x"; + } else if (objControl.IsVersionSupported("4.0")) { + strSilverlightVersion = "4.x"; + } else if (objControl.IsVersionSupported("3.0")) { + strSilverlightVersion = "3.x"; + } else if (objControl.IsVersionSupported("2.0")) { + strSilverlightVersion = "2.x"; + } else { + strSilverlightVersion = "1.x"; + } + objControl = null; + } catch (e) { + objPlugin = navigator.plugins["Silverlight Plug-In"]; + if (objPlugin) { + if (objPlugin.description === "1.0.30226.2") { + strSilverlightVersion = "2.x"; + } else { + strSilverlightVersion = parseInt(objPlugin.description[0], 10); + } + } else { + strSilverlightVersion = "N/A"; + } + } + strOut = strSilverlightVersion; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_os() { + "use strict"; + var strSep, strOnError, strUserAgent, strPlatform, strOS, strOSBits, strOut; + + strSep = "|"; + strOnError = "Error"; + strUserAgent = null; + strPlatform = null; + strOS = null; + strOSBits = null; + strOut = null; + + try { + /* navigator.userAgent is supported by all major browsers */ + strUserAgent = navigator.userAgent.toLowerCase(); + /* navigator.platform is supported by all major browsers */ + strPlatform = navigator.platform.toLowerCase(); + if (strUserAgent.indexOf("windows nt 6.3") !== -1) { + strOS = "Windows 8.1"; + } else if (strUserAgent.indexOf("windows nt 6.2") !== -1) { + strOS = "Windows 8"; + } else if (strUserAgent.indexOf("windows nt 6.1") !== -1) { + strOS = "Windows 7"; + } else if (strUserAgent.indexOf("windows nt 10.0") !== -1) { + strOS = "Windows 10"; + } else if (strUserAgent.indexOf("windows nt 6.0") !== -1) { + strOS = "Windows Vista/Windows Server 2008"; + } else if (strUserAgent.indexOf("windows nt 5.2") !== -1) { + strOS = "Windows XP x64/Windows Server 2003"; + } else if (strUserAgent.indexOf("windows nt 5.1") !== -1) { + strOS = "Windows XP"; + } else if (strUserAgent.indexOf("windows nt 5.01") !== -1) { + strOS = "Windows 2000, Service Pack 1 (SP1)"; + } else if (strUserAgent.indexOf("windows xp") !== -1) { + strOS = "Windows XP"; + } else if (strUserAgent.indexOf("windows 2000") !== -1) { + strOS = "Windows 2000"; + } else if (strUserAgent.indexOf("windows nt 5.0") !== -1) { + strOS = "Windows 2000"; + } else if (strUserAgent.indexOf("iemobile") !== -1) { + strOS = "Windows Mobile"; + } else if (strUserAgent.indexOf("wm5 pie") !== -1) { + strOS = "Windows Mobile"; + } else if (strUserAgent.indexOf("windows") !== -1) { + strOS = "Windows (Unknown Version)"; + } else if (strUserAgent.indexOf("openbsd") !== -1) { + strOS = "Open BSD"; + } else if (strUserAgent.indexOf("sunos") !== -1) { + strOS = "Sun OS"; + } else if (strUserAgent.indexOf("ubuntu") !== -1) { + strOS = "Ubuntu"; + } else if (strUserAgent.indexOf("ipad") !== -1) { + strOS = "iOS (iPad)"; + } else if (strUserAgent.indexOf("ipod") !== -1) { + strOS = "iOS (iTouch)"; + } else if (strUserAgent.indexOf("iphone") !== -1) { + strOS = "iOS (iPhone)"; + } else if (strUserAgent.indexOf("mac os x beta") !== -1) { + strOS = "Mac OSX Beta (Kodiak)"; + } else if (strUserAgent.indexOf("mac os x 10.0") !== -1) { + strOS = "Mac OSX Cheetah"; + } else if (strUserAgent.indexOf("mac os x 10.1") !== -1) { + strOS = "Mac OSX Puma"; + } else if (strUserAgent.indexOf("mac os x 10.2") !== -1) { + strOS = "Mac OSX Jaguar"; + } else if (strUserAgent.indexOf("mac os x 10.3") !== -1) { + strOS = "Mac OSX Panther"; + } else if (strUserAgent.indexOf("mac os x 10.4") !== -1) { + strOS = "Mac OSX Tiger"; + } else if (strUserAgent.indexOf("mac os x 10.5") !== -1) { + strOS = "Mac OSX Leopard"; + } else if (strUserAgent.indexOf("mac os x 10.6") !== -1) { + strOS = "Mac OSX Snow Leopard"; + } else if (strUserAgent.indexOf("mac os x 10.7") !== -1) { + strOS = "Mac OSX Lion"; + } else if (strUserAgent.indexOf("mac os x") !== -1) { + strOS = "Mac OSX (Version Unknown)"; + } else if (strUserAgent.indexOf("macintosh") !== -1) { + strOS = "Mac OS Classic"; + } else if (strUserAgent.indexOf("googletv") !== -1) { + strOS = "Android (GoogleTV)"; + } else if (strUserAgent.indexOf("android") !== -1) { + strOS = "Android"; + } else if (strUserAgent.indexOf("x11") !== -1) { + strOS = "UNIX"; + } else if (strUserAgent.indexOf("nix") !== -1) { + strOS = "UNIX"; + } else if (strUserAgent.indexOf("linux") !== -1) { + strOS = "Linux"; + } else if (strUserAgent.indexOf("qnx") !== -1) { + strOS = "QNX"; + } else if (strUserAgent.indexOf("os/2") !== -1) { + strOS = "IBM OS/2"; + } else if (strUserAgent.indexOf("beos") !== -1) { + strOS = "BeOS"; + } else if (strUserAgent.indexOf("playbook") !== -1) { + strOS = "Blackberry (Playbook)"; + } else if (strUserAgent.indexOf("wnd.rim") !== -1) { + strOS = "Blackberry (IE/FF Emulator)"; + } else if (strUserAgent.indexOf("blackberry") !== -1) { + strOS = "Blackberry"; + } else if (strUserAgent.indexOf("palm") !== -1) { + strOS = "Palm OS"; + } else if (strUserAgent.indexOf("webos") !== -1) { + strOS = "WebOS"; + } else if (strUserAgent.indexOf("hpwos") !== -1) { + strOS = "WebOS (HP)"; + } else if (strUserAgent.indexOf("kindle") !== -1) { + strOS = "Kindle"; + } else if (strUserAgent.indexOf("wii") !== -1) { + strOS = "Nintendo (Wii)"; + } else if (strUserAgent.indexOf("nintendo ds") !== -1) { + strOS = "Nintendo (DS)"; + } else if (strUserAgent.indexOf("playstation 3") !== -1) { + strOS = "Sony (Playstation Console)"; + } else if (strUserAgent.indexOf("playstation portable") !== -1) { + strOS = "Sony (Playstation Portable)"; + } else if (strUserAgent.indexOf("webtv") !== -1) { + strOS = "MSN TV (WebTV)"; + } else if (strUserAgent.indexOf("inferno") !== -1) { + strOS = "Inferno"; + } else { + strOS = "Unknown"; + } + if (strPlatform.indexOf("x64") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("wow64") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("win64") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("win32") !== -1) { + strOSBits = "32 bits"; + } else if (strPlatform.indexOf("x64") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("x32") !== -1) { + strOSBits = "32 bits"; + } else if (strPlatform.indexOf("x86") !== -1) { + strOSBits = "32 bits*"; + } else if (strPlatform.indexOf("ppc") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("alpha") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("68k") !== -1) { + strOSBits = "64 bits"; + } else if (strPlatform.indexOf("iphone") !== -1) { + strOSBits = "32 bits"; + } else if (strPlatform.indexOf("android") !== -1) { + strOSBits = "32 bits"; + } else { + strOSBits = "Unknown"; + } + strOut = strOS + strSep + strOSBits; + return strOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_useragent() { + "use strict"; + var strSep, strTmp, strUserAgent, strOut; + + strSep = "|"; + strTmp = null; + strUserAgent = null; + strOut = null; + + /* navigator.userAgent is supported by all major browsers */ + strUserAgent = navigator.userAgent.toLowerCase(); + /* navigator.platform is supported by all major browsers */ + strTmp = strUserAgent + strSep + navigator.platform; + /* navigator.cpuClass only supported in IE */ + if (navigator.cpuClass) { + strTmp += strSep + navigator.cpuClass; + } + /* navigator.browserLanguage only supported in IE, Safari and Chrome */ + if (navigator.browserLanguage) { + strTmp += strSep + navigator.browserLanguage; + } else { + strTmp += strSep + navigator.language; + } + strOut = strTmp; + return strOut; +} + +function fingerprint_timezone() { + "use strict"; + var strOnError, dtDate, numOffset, numGMTHours, numOut; + + strOnError = "Error"; + dtDate = null; + numOffset = null; + numGMTHours = null; + numOut = null; + + try { + dtDate = new Date(); + numOffset = dtDate.getTimezoneOffset(); + numGMTHours = (numOffset / 60) * (-1); + numOut = numGMTHours; + return numOut; + } catch (err) { + return strOnError; + } +} + +function fingerprint_touch() { + "use strict"; + var bolTouchEnabled, bolOut; + + bolTouchEnabled = false; + bolOut = null; + + try { + if (document.createEvent("TouchEvent")) { + bolTouchEnabled = true; + } + bolOut = bolTouchEnabled; + return bolOut; + } catch (ignore) { + bolOut = bolTouchEnabled + return bolOut; + } +} + +function fingerprint_truebrowser() { + "use strict"; + var strBrowser, strUserAgent, strOut; + + strBrowser = "Unknown"; + strUserAgent = null; + strOut = null; + + strUserAgent = navigator.userAgent.toLowerCase(); + + /* Checks for different browsers, cannot use Try/Catch block */ + if (document.all && document.getElementById && navigator.savePreferences && (strUserAgent.indexOf("Netfront") < 0) && navigator.appName !== "Blazer") { + strBrowser = "Escape 5"; + } else if (navigator.vendor === "KDE") { + strBrowser = "Konqueror"; + } else if (document.childNodes && !document.all && !navigator.taintEnabled && !navigator.accentColorName) { + strBrowser = "Safari"; + } else if (document.childNodes && !document.all && !navigator.taintEnabled && navigator.accentColorName) { + strBrowser = "OmniWeb 4.5+"; + } else if (navigator.__ice_version) { + strBrowser = "ICEBrowser"; + } else if (window.ScriptEngine && ScriptEngine().indexOf("InScript") + 1 && document.createElement) { + strBrowser = "iCab 3+"; + } else if (window.ScriptEngine && ScriptEngine().indexOf("InScript") + 1) { + strBrowser = "iCab 2-"; + } else if (strUserAgent.indexOf("hotjava") + 1 && (navigator.accentColorName) === "undefined") { + strBrowser = "HotJava"; + } else if (document.layers && !document.classes) { + strBrowser = "Omniweb 4.2-"; + } else if (document.layers && !navigator.mimeTypes["*"]) { + strBrowser = "Escape 4"; + } else if (document.layers) { + strBrowser = "Netscape 4"; + } else if (window.opera && document.getElementsByClassName) { + strBrowser = "Opera 9.5+"; + } else if (window.opera && window.getComputedStyle) { + strBrowser = "Opera 8"; + } else if (window.opera && document.childNodes) { + strBrowser = "Opera 7"; + } else if (window.opera) { + strBrowser = "Opera " + window.opera.version(); + } else if (navigator.appName.indexOf("WebTV") + 1) { + strBrowser = "WebTV"; + } else if (strUserAgent.indexOf("netgem") + 1) { + strBrowser = "Netgem NetBox"; + } else if (strUserAgent.indexOf("opentv") + 1) { + strBrowser = "OpenTV"; + } else if (strUserAgent.indexOf("ipanel") + 1) { + strBrowser = "iPanel MicroBrowser"; + } else if (document.getElementById && !document.childNodes) { + strBrowser = "Clue browser"; + } else if (navigator.product && navigator.product.indexOf("Hv") === 0) { + strBrowser = "Tkhtml Hv3+"; + } else if (typeof InstallTrigger !== "undefined") { + strBrowser = "Firefox"; + } else if (window.atob) { + strBrowser = "Internet Explorer 10+"; + } else if (XDomainRequest && window.performance) { + strBrowser = "Internet Explorer 9"; + } else if (XDomainRequest) { + strBrowser = "Internet Explorer 8"; + } else if (document.documentElement && document.documentElement.style.maxHeight !== "undefined") { + strBrowser = "Internet Explorer 7"; //xxxxx + } else if (document.compatMode && document.all) { + strBrowser = "Internet Explorer 6"; //xxxxx + } else if (window.createPopup) { + strBrowser = "Internet Explorer 5.5"; + } else if (window.attachEvent) { + strBrowser = "Internet Explorer 5"; + } else if (document.all && navigator.appName !== "Microsoft Pocket Internet Explorer") { + strBrowser = "Internet Explorer 4"; + } else if ((strUserAgent.indexOf("msie") + 1) && window.ActiveXObject) { + strBrowser = "Pocket Internet Explorer"; + } else if (document.getElementById && ((strUserAgent.indexOf("netfront") + 1) || navigator.appName === "Blazer" || navigator.product === "Gecko" || (navigator.appName.indexOf("PSP") + 1) || (navigator.appName.indexOf("PLAYSTATION 3") + 1))) { + strBrowser = "NetFront 3+"; + } else if (navigator.product === "Gecko" && !navigator.savePreferences) { + strBrowser = "Gecko engine (Mozilla, Netscape 6+ etc.)"; + } else if (window.chrome) { + strBrowser = "Chrome"; + } + strOut = strBrowser; + return strOut; +} + +var glbOnError = "N/A" +var glbSep = "|"; + +function activeXDetect(componentClassID) { + "use strict"; + var strComponentVersion, strOut; + + strComponentVersion = ""; + strOut = ""; + + try { + strComponentVersion = document.body.getComponentVersion("{" + componentClassID + "}", "ComponentID"); + if (strComponentVersion !== null) { + strOut = strComponentVersion; + } else { + strOut = false; + } + return strOut; + } catch (err) { + return glbOnError; + } +} + +function stripIllegalChars(strValue) { + "use strict"; + var iCounter, strOriginal, strOut; + + iCounter = 0; + strOriginal = ""; + strOut = ""; + + try { + strOriginal = strValue.toLowerCase(); + for (iCounter = 0; iCounter < strOriginal.length; iCounter = iCounter + 1) { + if (strOriginal.charAt(iCounter) !== "\n" && strOriginal.charAt(iCounter) !== "/" && strOriginal.charAt(iCounter) !== "\\") { + strOut = strOut + strOriginal.charAt(iCounter); + } else if (strOriginal.charAt(iCounter) === "\n") { + strOut = strOut + "n"; + } + } + return strOut; + } catch (err) { + return glbOnError; + } +} + +function hashtable_containsKey(key) { + "use strict"; + var bolExists, iCounter; + + bolExists = false; + iCounter = 0; + + for (iCounter = 0; iCounter < this.hashtable.length; iCounter = iCounter + 1) { + if (iCounter === key && this.hashtable[iCounter] !== null) { + bolExists = true; + break; + } + } + return bolExists; +} + +function hashtable_get(key) { + "use strict"; + return this.hashtable[key]; +} + +function hashtable_keys() { + "use strict"; + var keys, iCounter; + + keys = []; + iCounter = 0; + + for (iCounter in this.hashtable) { + if (this.hashtable[iCounter] !== null) { + keys.push(iCounter); + } + } + return keys; +} + +function hashtable_put(key, value) { + "use strict"; + if (key === null || value === null) { + throw "NullPointerException {" + key + "},{" + value + "}"; + } + this.hashtable[key] = value; +} + +function hashtable_size() { + "use strict"; + var iSize, iCounter, iOut; + + iSize = 0; + iCounter = 0; + iOut = 0; + + for (iCounter in this.hashtable) { + if (this.hashtable[iCounter] !== null) { + iSize = iSize + 1; + } + } + iOut = iSize; + return iOut; +} + +function Hashtable() { + "use strict"; + this.containsKey = hashtable_containsKey; + this.get = hashtable_get; + this.keys = hashtable_keys; + this.put = hashtable_put; + this.size = hashtable_size; + this.hashtable = []; +} + +/* Detect Plugins */ +function fingerprint_plugins() { + "use strict"; + var htIEComponents, strKey, strName, strVersion, strTemp, bolFirst, iCount, strMimeType, strOut; + + try { + /* Create hashtable of IE components */ + htIEComponents = new Hashtable(); + htIEComponents.put("7790769C-0471-11D2-AF11-00C04FA35D02", "AddressBook"); // Address Book + htIEComponents.put("47F67D00-9E55-11D1-BAEF-00C04FC2D130", "AolArtFormat"); // AOL ART Image Format Support + htIEComponents.put("76C19B38-F0C8-11CF-87CC-0020AFEECF20", "ArabicDS"); // Arabic Text Display Support + htIEComponents.put("76C19B34-F0C8-11CF-87CC-0020AFEECF20", "ChineseSDS"); // Chinese (Simplified) Text Display Support + htIEComponents.put("76C19B33-F0C8-11CF-87CC-0020AFEECF20", "ChineseTDS"); // Chinese (traditional) Text Display Support + htIEComponents.put("238F6F83-B8B4-11CF-8771-00A024541EE3", "CitrixICA"); // Citrix ICA Client + htIEComponents.put("283807B5-2C60-11D0-A31D-00AA00B92C03", "DirectAnim"); // DirectAnimation + htIEComponents.put("44BBA848-CC51-11CF-AAFA-00AA00B6015C", "DirectShow"); // DirectShow + htIEComponents.put("9381D8F2-0288-11D0-9501-00AA00B911A5", "DynHTML"); // Dynamic HTML Data Binding + htIEComponents.put("4F216970-C90C-11D1-B5C7-0000F8051515", "DynHTML4Java"); // Dynamic HTML Data Binding for Java + htIEComponents.put("D27CDB6E-AE6D-11CF-96B8-444553540000", "Flash"); // Macromedia Flash + htIEComponents.put("76C19B36-F0C8-11CF-87CC-0020AFEECF20", "HebrewDS"); // Hebrew Text Display Support + htIEComponents.put("630B1DA0-B465-11D1-9948-00C04F98BBC9", "IEBrwEnh"); // Internet Explorer Browsing Enhancements + htIEComponents.put("08B0E5C0-4FCB-11CF-AAA5-00401C608555", "IEClass4Java"); // Internet Explorer Classes for Java + htIEComponents.put("45EA75A0-A269-11D1-B5BF-0000F8051515", "IEHelp"); // Internet Explorer Help + htIEComponents.put("DE5AED00-A4BF-11D1-9948-00C04F98BBC9", "IEHelpEng"); // Internet Explorer Help Engine + htIEComponents.put("89820200-ECBD-11CF-8B85-00AA005B4383", "IE5WebBrw"); // Internet Explorer 5/6 Web Browser + htIEComponents.put("5A8D6EE0-3E18-11D0-821E-444553540000", "InetConnectionWiz"); // Internet Connection Wizard + htIEComponents.put("76C19B30-F0C8-11CF-87CC-0020AFEECF20", "JapaneseDS"); // Japanese Text Display Support + htIEComponents.put("76C19B31-F0C8-11CF-87CC-0020AFEECF20", "KoreanDS"); // Korean Text Display Support + htIEComponents.put("76C19B50-F0C8-11CF-87CC-0020AFEECF20", "LanguageAS"); // Language Auto-Selection + htIEComponents.put("08B0E5C0-4FCB-11CF-AAA5-00401C608500", "MsftVM"); // Microsoft virtual machine + htIEComponents.put("5945C046-LE7D-LLDL-BC44-00C04FD912BE", "MSNMessengerSrv"); // MSN Messenger Service + htIEComponents.put("44BBA842-CC51-11CF-AAFA-00AA00B6015B", "NetMeetingNT"); // NetMeeting NT + htIEComponents.put("3AF36230-A269-11D1-B5BF-0000F8051515", "OfflineBrwPack"); // Offline Browsing Pack + htIEComponents.put("44BBA840-CC51-11CF-AAFA-00AA00B6015C", "OutlookExpress"); // Outlook Express + htIEComponents.put("76C19B32-F0C8-11CF-87CC-0020AFEECF20", "PanEuropeanDS"); // Pan-European Text Display Support + htIEComponents.put("4063BE15-3B08-470D-A0D5-B37161CFFD69", "QuickTime"); // Apple Quick Time + htIEComponents.put("DE4AF3B0-F4D4-11D3-B41A-0050DA2E6C21", "QuickTimeCheck"); // Apple Quick Time Check + htIEComponents.put("3049C3E9-B461-4BC5-8870-4C09146192CA", "RealPlayer"); // RealPlayer Download and Record Plugin for IE + htIEComponents.put("2A202491-F00D-11CF-87CC-0020AFEECF20", "ShockwaveDir"); // Macromedia Shockwave Director + htIEComponents.put("3E01D8E0-A72B-4C9F-99BD-8A6E7B97A48D", "Skype"); // Skype + htIEComponents.put("CC2A9BA0-3BDD-11D0-821E-444553540000", "TaskScheduler"); // Task Scheduler + htIEComponents.put("76C19B35-F0C8-11CF-87CC-0020AFEECF20", "ThaiDS"); // Thai Text Display Support + htIEComponents.put("3BF42070-B3B1-11D1-B5C5-0000F8051515", "Uniscribe"); // Uniscribe + htIEComponents.put("4F645220-306D-11D2-995D-00C04F98BBC9", "VBScripting"); // Visual Basic Scripting Support v5.6 + htIEComponents.put("76C19B37-F0C8-11CF-87CC-0020AFEECF20", "VietnameseDS"); // Vietnamese Text Display Support + htIEComponents.put("10072CEC-8CC1-11D1-986E-00A0C955B42F", "VML"); // Vector Graphics Rendering (VML) + htIEComponents.put("90E2BA2E-DD1B-4CDE-9134-7A8B86D33CA7", "WebEx"); // WebEx Productivity Tools + htIEComponents.put("73FA19D0-2D75-11D2-995D-00C04F98BBC9", "WebFolders"); // Web Folders + htIEComponents.put("89820200-ECBD-11CF-8B85-00AA005B4340", "WinDesktopUpdateNT"); // Windows Desktop Update NT + htIEComponents.put("9030D464-4C02-4ABF-8ECC-5164760863C6", "WinLive"); // Windows Live ID Sign-in Helper + htIEComponents.put("6BF52A52-394A-11D3-B153-00C04F79FAA6", "WinMediaPlayer"); // Windows Media Player (Versions 7, 8 or 9) + htIEComponents.put("22D6F312-B0F6-11D0-94AB-0080C74C7E95", "WinMediaPlayerTrad"); // Windows Media Player (Traditional Versions) + + strTemp = ""; + bolFirst = true; + + /* strOpera gives full path of the file, extract the filenames, ignoring description and length */ + if (navigator.plugins.length > 0) { + for (iCount = 0; iCount < navigator.plugins.length; iCount = iCount + 1) { + if (bolFirst === true) { + strTemp += navigator.plugins[iCount].name; + bolFirst = false; + } else { + strTemp += glbSep + navigator.plugins[iCount].name; + } + } + } else if (navigator.mimeTypes.length > 0) { + strMimeType = navigator.mimeTypes; + for (iCount = 0; iCount < strMimeType.length; iCount = iCount + 1) { + if (bolFirst === true) { + strTemp += strMimeType[iCount].description; + bolFirst = false; + } else { + strTemp += glbSep + strMimeType[iCount].description; + } + } + } else { + document.body.addBehavior("#default#clientCaps"); + strKey = htIEComponents.keys(); + for (iCount = 0; iCount < htIEComponents.size(); iCount = iCount + 1) { + strVersion = activeXDetect(strKey[iCount]); + strName = htIEComponents.get(strKey[iCount]); + if (strVersion) { + if (bolFirst === true) { + strTemp = strName + glbPair + strVersion; + bolFirst = false; + } else { + strTemp += glbSep + strName + glbPair + strVersion; + } + } + } + strTemp = strTemp.replace(/,/g, "."); + } + strTemp = stripIllegalChars(strTemp); + if (strTemp === "") { + strTemp = "None"; + } + strOut = strTemp; + return strOut; + } catch (err) { + return glbOnError; + } +} \ No newline at end of file diff --git a/webAO/ui.b.js b/webAO/ui.b.js index f7f1f9f..ab28f59 100644 --- a/webAO/ui.b.js +++ b/webAO/ui.b.js @@ -1,2 +1,2 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},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=5)}([,,,function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){"use strict";(function(e){var n,i,o,s,r=function(){function e(e,t){for(var n=0;n]+)>)/gi,""))};var i=n(40),o=n.n(i),s=n(60),r=(n.n(s),"function"!=typeof/./&&"object"!=("undefined"==typeof Int8Array?"undefined":a(Int8Array))?function(e){return"function"==typeof e||!1}:function(e){return"[object Function]"===toString.call(e)})},function(e,t,n){var i=n(0),o="__all";t.a=o,t.b=function(){return function e(){h(this,e),this._mSubscriptions={},this._mSubscriptions[o]=[],this.on=function(e,t,n){if(!Object(i.h)(t))throw new Error("Tried to listen to event "+e+" with non-function callback "+t);this._mSubscriptions[e]||(this._mSubscriptions[e]=[]),this._mSubscriptions[e].push({fn:t,ctx:n})},this.emit=function(e){var t,n,i;i=Array.prototype.slice.call(arguments,1);var s=this._mSubscriptions[e];if(s)for(s=s.slice(),t=0;t'),s.childElementContainer=s.element,s._splitterSize=t.config.dimensions.borderWidth,s._splitterGrabSize=t.config.dimensions.borderGrabWidth,s._isColumn=e,s._dimension=e?"height":"width",s._splitter=[],s._splitterPosition=null,s._splitterMinPosition=null,s._splitterMaxPosition=null,s}return c(i,a.a),r(i,[{key:"addChild",value:function(e,t,i){var o,s,r,l;if(e=this.layoutManager._$normalizeContentItem(e,this),void 0===t&&(t=this.contentItems.length),0this.contentItems.length-this._isDocked())throw new Error("Can't dock child when it is last in "+this.config.type);var u={column:{first:"top",last:"bottom"},row:{first:"left",last:"right"}}[this.config.type][r?"last":"first"];e.header.position()!=u&&e.header.position(u),this._splitter[a]&&this._splitter[a].element.hide();var d=this._isDocked();for(l=0;ls(t)&&0=this.contentItems.length)){o=this._calculateAbsoluteSizes();for(var d=0;da)){for(e=l/a,c=l,d=0;dthis._splitterMinPosition&&ithis._nDistance||t(this._nY)>this._nDistance)&&(clearTimeout(this._timeout),this._startDrag()),this._bDragging&&this.emit("drag",this._nX,this._nY,e)}}},{key:"onMouseUp",value:function(e){null!=this._timeout&&(clearTimeout(this._timeout),this._eBody.removeClass("lm_dragging"),this._eElement.removeClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events",""),this._oDocument.unbind("mousemove touchmove",this._fMove),this._oDocument.unbind("mouseup touchend",this._fUp),!0===this._bDragging&&(this._bDragging=!1,this.emit("dragStop",e,this._nOriginalX+this._nX)))}},{key:"_startDrag",value:function(){this._bDragging=!0,this._eBody.addClass("lm_dragging"),this._eElement.addClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events","none"),this.emit("dragStart",this._nOriginalX,this._nOriginalY)}},{key:"_getCoordinates",value:function(e){return{x:(e=Object(o.e)(e)).pageX,y:e.pageY}}}]),t}();t.a=s},function(e,t,n){var i=n(9);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e){e.exports=function(e){return"object"==(void 0===e?"undefined":a(e))?null!==e:"function"==typeof e}},function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var i=n(0);t.a=function(){function e(){if(h(this,e),this._keys=["settings","hasHeaders","constrainDragToContainer","selectionEnabled","dimensions","borderWidth","minItemHeight","minItemWidth","headerHeight","dragProxyWidth","dragProxyHeight","labels","close","maximise","minimise","popout","content","componentName","componentState","id","width","type","height","isClosable","title","popoutWholeStack","openPopouts","parentId","activeItemIndex","reorderEnabled","borderGrabWidth"],36'),o.childElementContainer=o.element,o._containerElement=i,o._containerElement.append(o.element),o}return c(t,i.a),r(t,[{key:"addChild",value:function(e){if(0'),o._activeContentItem=null;var s=e.config;return o._header={show:!0===s.settings.hasHeaders&&!1!==t.hasHeaders,popout:s.settings.showPopoutIcon&&s.labels.popout,maximise:s.settings.showMaximiseIcon&&s.labels.maximise,close:s.settings.showCloseIcon&&s.labels.close,minimise:s.labels.minimise},s.header&&Object(d.b)(o._header,s.header),t.header&&Object(d.b)(o._header,t.header),t.content&&t.content[0]&&t.content[0].header&&Object(d.b)(o._header,t.content[0].header),o._dropZones={},o._dropSegment=null,o._contentAreaDimensions=null,o._dropIndex=null,o.isStack=!0,o.childElementContainer=$('
              '),o.header=new u.a(e,o),o.element.on("mouseleave mouseenter",Object(d.c)(function(e){this._docker&&this._docker.docked&&this.childElementContainer[this._docker.dimension]("mouseenter"==e.type?this._docker.realSize:0)},o)),o.element.append(o.header.element),o.element.append(o.childElementContainer),o._setupHeaderPosition(),o._$validateClosability(),o}return c(i,s.a),r(i,[{key:"dock",value:function(e){this._header.dock&&this.parent instanceof a.a&&this.parent.dock(this,e)}},{key:"setSize",value:function(){if("none"!==this.element.css("display")){var e=this._docker&&this._docker.docked,t={width:this.element.width(),height:this.element.height()};this._header.show&&(t[this._sided?"width":"height"]-=this.layoutManager.config.dimensions.headerHeight),e&&(t[this._docker.dimension]=this._docker.realSize),e&&"height"!=this._docker.dimension||this.childElementContainer.width(t.width),e&&"width"!=this._docker.dimension||this.childElementContainer.height(t.height);for(var n=0;nthis.contentItems.length&&(t-=1),e=this.layoutManager._$normalizeContentItem(e,this),s.a.prototype.addChild.call(this,e,t),this.childElementContainer.append(e.element),this.header.createTab(e,t),this.setActiveContentItem(e),this.callDownwards("setSize"),this._$validateClosability(),this.parent instanceof a.a&&this.parent._validateDocking(),this.emitBubblingEvent("stateChanged")}},{key:"removeChild",value:function(e,t){var i=Object(d.g)(e,this.contentItems);s.a.prototype.removeChild.call(this,e,t),this.header.removeTab(e),this.header.activeContentItem===e&&(0e&&i.y1t)return void("header"===n?(this._dropSegment="header",this._highlightHeaderDropZone(this._sided?t:e)):(this._resetHeaderDropZone(),this._highlightBodyDropZone(n)))}},{key:"_$getArea",value:function(){if("none"===this.element.css("display"))return null;var e=s.a.prototype._$getArea,t=e.call(this,this.header.element),n=e.call(this,this.childElementContainer),i=n.x2-n.x1,o=n.y2-n.y1;return this._contentAreaDimensions={header:{hoverArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2},highlightArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2}}},this._activeContentItem&&!1===this._activeContentItem.isComponent?t:0===this.contentItems.length?(this._contentAreaDimensions.body={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}},e.call(this,this.element)):(this._contentAreaDimensions.left={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x1+.25*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x1+.5*i,y2:n.y2}},this._contentAreaDimensions.top={hoverArea:{x1:n.x1+.25*i,y1:n.y1,x2:n.x1+.75*i,y2:n.y1+.5*o},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y1+.5*o}},this._contentAreaDimensions.right={hoverArea:{x1:n.x1+.75*i,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1+.5*i,y1:n.y1,x2:n.x2,y2:n.y2}},this._contentAreaDimensions.bottom={hoverArea:{x1:n.x1+.25*i,y1:n.y1+.5*o,x2:n.x1+.75*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1+.5*o,x2:n.x2,y2:n.y2}},e.call(this,this.element))}},{key:"_highlightHeaderDropZone",value:function(t){var n,i,o,s,r,a,l,c,h=this.header.tabs.length,u=!1;if(0===h)return l=this.header.element.offset(),void this.layoutManager.dropTargetIndicator.highlightArea({x1:l.left,x2:l.left+100,y1:l.top+this.header.element.height()-20,y2:l.top+this.header.element.height()});for(n=0;ns&&t
                    '),!0===i.layoutManager.config.settings.selectionEnabled&&(i.element.addClass("lm_selectable"),i.element.on("click touchstart",Object(a.c)(i._onHeaderClick,i))),i.tabsContainer=i.element.find(".lm_tabs"),i.tabDropdownContainer=i.element.find(".lm_tabdropdown_list"),i.tabDropdownContainer.hide(),i.controlsContainer=i.element.find(".lm_controls"),i.parent=n,i.parent.on("resize",i._updateTabSizes,i),i.tabs=[],i.tabsMarkedForRemoval=[],i.activeContentItem=null,i.closeButton=null,i.dockButton=null,i.tabDropdownButton=null,i.hideAdditionalTabsDropdown=Object(a.c)(i._hideAdditionalTabsDropdown,i),$(document).mouseup(i.hideAdditionalTabsDropdown),i._lastVisibleTabIndex=-1,i._tabControlOffset=i.layoutManager.config.settings.tabControlOffset,i._createControls(),i}return c(t,i.b),r(t,[{key:"createTab",value:function(e,t){var n,i;for(i=0;ithis._lastVisibleTabIndex){for(o=this.tabs[this.parent.config.activeItemIndex],n=this.parent.config.activeItemIndex;0r){if(u)i===d&&(n.css({"z-index":"auto","margin-left":""}),this.tabsContainer.append(n));else if((c=0
                    '),this.titleElement=this.element.find(".lm_title"),this.closeElement=this.element.find(".lm_close_tab"),this.closeElement[n.config.isClosable?"show":"hide"](),this.isActive=!1,this.setTitle(n.config.title),this.contentItem.on("titleChanged",this.setTitle,this),this._layoutManager=this.contentItem.layoutManager,!0===this._layoutManager.config.settings.reorderEnabled&&!0===n.config.reorderEnabled&&(this._dragListener=new i.a(this.element),this._dragListener.on("dragStart",this._onDragStart,this),this.contentItem.on("destroy",this._dragListener.destroy,this._dragListener)),this._onTabClickFn=Object(s.c)(this._onTabClick,this),this._onCloseClickFn=Object(s.c)(this._onCloseClick,this),this.element.on("mousedown touchstart",this._onTabClickFn),this.contentItem.config.isClosable?(this.closeElement.on("click touchstart",this._onCloseClickFn),this.closeElement.on("mousedown",this._onCloseMousedown)):this.closeElement.remove(),this.contentItem.tab=this,this.contentItem.emit("tab",this),this.contentItem.layoutManager.emit("tabCreated",this),this.contentItem.isComponent&&(this.contentItem.container.tab=this,this.contentItem.container.emit("tab",this))}return r(e,[{key:"setTitle",value:function(e){this.element.attr("title",Object(s.k)(e)),this.titleElement.html(e)}},{key:"setActive",value:function(e){e===this.isActive||(this.isActive=e,e?this.element.addClass("lm_active"):this.element.removeClass("lm_active"))}},{key:"_$destroy",value:function(){this.element.off("mousedown touchstart",this._onTabClickFn),this.closeElement.off("click touchstart",this._onCloseClickFn),this._dragListener&&(this.contentItem.off("destroy",this._dragListener.destroy,this._dragListener),this._dragListener.off("dragStart",this._onDragStart),this._dragListener=null),this.element.remove()}},{key:"_onDragStart",value:function(e,t){return this.header._canDestroy?(!0===this.contentItem.parent.isMaximised&&this.contentItem.parent.toggleMaximise(),void new o.a(e,t,this._dragListener,this._layoutManager,this.contentItem,this.header.parent)):null}},{key:"_onTabClick",value:function(e){if(0===e.button||"touchstart"===e.type){var t=this.header.parent.getActiveContentItem();this.contentItem!==t&&this.header.parent.setActiveContentItem(this.contentItem)}else 1===e.button&&this.contentItem.config.isClosable&&this._onCloseClick(e)}},{key:"_onCloseClick",value:function(e){e.stopPropagation(),this.header._canDestroy&&this.header.parent.removeChild(this.contentItem)}},{key:"_onCloseMousedown",value:function(e){e.stopPropagation()}}]),e}()},function(e,t,n){var i=n(1),o=n(0),s=function(e){function t(e,n,i,s,r,a){var c;h(this,t),(c=l(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)))._dragListener=i,c._layoutManager=s,c._contentItem=r,c._originalParent=a,c._area=null,c._lastValidArea=null,c._dragListener.on("drag",c._onDrag,c),c._dragListener.on("dragStop",c._onDrop,c),c.element=$('
                    '),a&&a._side&&(c._sided=a._sided,c.element.addClass("lm_"+a._side),0<=["right","bottom"].indexOf(a._side)&&c.element.find(".lm_content").after(c.element.find(".lm_header"))),c.element.css({left:e,top:n}),c.element.find(".lm_tab").attr("title",Object(o.k)(c._contentItem.config.title)),c.element.find(".lm_title").html(c._contentItem.config.title),c.childElementContainer=c.element.find(".lm_content"),c.childElementContainer.append(r.element),c._undisplayTree(),c._layoutManager._$calculateItemAreas(),c._setDimensions(),$(document.body).append(c.element);var u=c._layoutManager.container.offset();return c._minX=u.left,c._minY=u.top,c._maxX=c._layoutManager.container.width()+c._minX,c._maxY=c._layoutManager.container.height()+c._minY,c._width=c.element.width(),c._height=c.element.height(),c._setDropPosition(e,n),c}return c(t,i.b),r(t,[{key:"_onDrag",value:function(e,t,n){var i=(n=Object(o.e)(n)).pageX,s=n.pageY;(i>this._minX&&ithis._minY&&s'),this._header.on("destroy",this._$destroy,this),this._action=o,this.element.on("click touchstart",this._action),this._header.controlsContainer.append(this.element)}return r(e,[{key:"_$destroy",value:function(){this.element.off(),this.element.remove()}}]),e}()},function(e,t,n){var i=n(3),o=n(33),s=function(e){function t(e,n,i){h(this,t);var s=l(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,i)),r=e.getComponent(s.config.componentName),a=$.extend(!0,{},s.config.componentState||{});return a.componentName=s.config.componentName,s.componentName=s.config.componentName,""===s.config.title&&(s.config.title=s.config.componentName),s.isComponent=!0,s.container=new o.a(s.config,s,e),s.instance=new r(s.container,a),s.element=s.container._element,s}return c(t,i.a),r(t,[{key:"close",value:function(){this.parent.removeChild(this)}},{key:"setSize",value:function(){"none"!==this.element.css("display")&&this.container._$setSize(this.element.width(),this.element.height())}},{key:"_$init",value:function(){i.a.prototype._$init.call(this),this.container.emit("open")}},{key:"_$hide",value:function(){this.container.hide(),i.a.prototype._$hide.call(this)}},{key:"_$show",value:function(){this.container.show(),i.a.prototype._$show.call(this)}},{key:"_$shown",value:function(){this.container.shown(),i.a.prototype._$shown.call(this)}},{key:"_$destroy",value:function(){this.container.emit("destroy",this),i.a.prototype._$destroy.call(this)}},{key:"_$getArea",value:function(){return null}}]),t}();t.a=s},function(e,t,n){var i=n(1),o=function(e){function t(e,n,i){var o;return h(this,t),(o=l(this,(t.__proto__||Object.getPrototypeOf(t)).call(this))).width=null,o.height=null,o.title=e.componentName,o.parent=n,o.layoutManager=i,o.isHidden=!1,o._config=e,o._element=$('
                    '),o._contentElement=o._element.find(".lm_content"),o}return c(t,i.b),r(t,[{key:"getElement",value:function(){return this._contentElement}},{key:"hide",value:function(){this.emit("hide"),this.isHidden=!0,this._element.hide()}},{key:"show",value:function(){this.emit("show"),this.isHidden=!1,this._element.show(),(0!=this.height||0!=this.width)&&this.emit("shown")}},{key:"setSize",value:function(e,t){for(var n,i,o,s,r=this.parent,a=this;!r.isColumn&&!r.isRow;)if(a=r,(r=r.parent).isRoot)return!1;for(n=("height"===(i=r.isColumn?"height":"width")?t:e)/(this[i]*(1/(a.config[i]/100)))*100,o=(a.config[i]-n)/(r.contentItems.length-1),s=0;s'),n._creationTimeoutPassed=!1,n._subWindowsCreated=!1,n._dragSources=[],n._updatingColumnsResponsive=!1,n._firstLoad=!0,n.width=null,n.height=null,n.root=null,n.openPopouts=[],n.selectedItem=null,n.isSubWindow=!1,n.eventHub=new f.a(n),n.config=n._createConfig(e),n.container=t,n.dropTargetIndicator=null,n.transitionIndicator=null,n.tabDropPlaceholder=$('
                    '),!0===n.isSubWindow&&$("body").css("visibility","hidden"),n._typeToItem={column:Object(C.c)(p.a,n,[!0]),row:Object(C.c)(p.a,n,[!1]),stack:g.a,component:y.a},n}return c(i,s.b),r(i,[{key:"minifyConfig",value:function(e){return(new d.a).minifyConfig(e)}},{key:"unminifyConfig",value:function(e){return(new d.a).unminifyConfig(e)}},{key:"registerComponent",value:function(e,t){if("function"!=typeof t)throw new Error("Please register a constructor function");if(void 0!==this._components[e])throw new Error("Component "+e+" is already registered");this._components[e]=t}},{key:"toConfig",value:function(e){var t,n,i;if(!1===this.isInitialised)throw new Error("Can't create config, layout not yet initialised");if(e&&!(e instanceof v.a))throw new Error("Root must be a ContentItem");for((t={settings:Object(C.b)({},this.config.settings),dimensions:Object(C.b)({},this.config.dimensions),labels:Object(C.b)({},this.config.labels)}).content=[],(n=function(e,t){var i,o;for(i in t.config)"content"!==i&&(e[i]=t.config[i]);if(t.contentItems.length)for(e.content=[],o=0;o(i=this._itemAreas[n]).x1&&ei.y1&&ti.surface&&(o=i.surface,s=i);return s}},{key:"_$createRootItemAreas",value:function(){var e={y2:0,x2:0,y1:"y2",x1:"x2"};for(var t in e){var n=this.root._$getArea();n.side=t,n[t]=e[t]?n[e[t]]-50:50,n.surface=(n.x2-n.x1)*(n.y2-n.y1),this._itemAreas.push(n)}}},{key:"_$calculateItemAreas",value:function(){var e,t,n=this._getAllContentItems();if(this._itemAreas=[],1!==n.length){for(this._$createRootItemAreas(),e=0;e
                    ');e.click(Object(C.c)(function(){this.emit("popIn")},this)),document.title=Object(C.k)(this.config.content[0].title),$("head").append($("body link, body style, template, .gl_keep")),this.container=$("body").html("").css("visibility","visible").append(e),document.body.offsetHeight,window.__glInstance=this}},{key:"_createSubWindows",value:function(){var e,t;for(e=0;e=e)){var i=this.config.dimensions.minItemWidth;if(!(e*i<=this.width)){this._updatingColumnsResponsive=!0;for(var o,s=n(t(this.width/i),1),r=this.root.contentItems[0],a=this._findAllStackContainers()[0],l=0;ll;)i(a,n=t[l++])&&(~s(c,n)||c.push(n));return c}},function(e,t,n){var i=n(46);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var i=n(17),o=n(48),s=n(49);e.exports=function(e){return function(t,n,r){var a,l=i(t),c=o(l.length),h=s(r,c);if(e&&n!=n){for(;c>h;)if((a=l[h++])!=a)return!0}else for(;c>h;h++)if((e||h in l)&&l[h]===n)return e||h||0;return!e&&-1}}},function(t,n,i){var o=i(18);t.exports=function(t){return 0(t=s(t))?n(t+i,0):e(t,i)}},function(e,t,n){var i=n(2),o=n(4),s="__core-js_shared__",r=o[s]||(o[s]={});(e.exports=function(e,t){return r[e]||(r[e]=void 0===t?{}:t)})("versions",[]).push({version:i.version,mode:n(51)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e){e.exports=!0},function(e){var t=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++t+n).toString(36))}},function(e,t,n){var i=n(21),o=n(2),s=n(10);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*s(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(55);e.exports=function(e,t,n){return i(e),void 0===t?e:1===n?function(n){return e.call(t,n)}:2===n?function(n,i){return e.call(t,n,i)}:3===n?function(n,i,o){return e.call(t,n,i,o)}:function(){return e.apply(t,arguments)}}},function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var i=n(22),o=n(59);e.exports=n(5)?function(e,t,n){return i.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=!n(5)&&!n(10)(function(){return 7!=Object.defineProperty(n(23)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(9);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){e.exports={default:n(61),__esModule:!0}},function(e,t,n){n(62);var i=n(2).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){var i=n(21);i(i.S,"Object",{create:n(63)})},function(e,t,n){var i=n(8),o=n(64),s=n(20),r=n(19)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(23)("iframe"),i=s.length;for(t.style.display="none",n(65).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" - diff --git a/webAO/client.js b/webAO/client.js index bc98e9b..e2c665f 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -8,7 +8,6 @@ // https://github.com/rfrench/gify // The following comment is needed for ESLint: /* global gify */ -/* global evercookie */ import background_arr from "./backgrounds.js"; import evidence_arr from "./evidence.js"; -- cgit From d3d32c7dcdfcbf388749173684afe5d0920f2d44 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 20 Feb 2019 16:20:54 +0100 Subject: i didnt read longbytes nice comment he is right --- webAO/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/client.js b/webAO/client.js index e2c665f..f9fa2b9 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -36,7 +36,7 @@ if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phon let selectedEffect = 0; let selectedMenu = 1; let selectedShout = 0; -var fp = new Fingerprint({ +let fp = new Fingerprint({ canvas: true, ie_activex: true, screen_resolution: true -- cgit From 615a1c3855208a3edddd5ceefaaae19d6b4cc217 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 20 Feb 2019 16:23:28 +0100 Subject: added cookie info --- webAO/master.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webAO/master.html b/webAO/master.html index 58473b4..f7c0f63 100644 --- a/webAO/master.html +++ b/webAO/master.html @@ -29,7 +29,7 @@
                    -

                    Please note that the webclient is still in beta


                    +

                    This page uses cookie. By clicking on a server you agree that a cookie is saved on your computer.


                    The downloadable client is recommended


                    The green servers are more likely to work, red ones will not

                    -- cgit From b66ae3ac96f07077d716e2d09650882eedfe3589 Mon Sep 17 00:00:00 2001 From: Headshot <36455681+headshot2017@users.noreply.github.com> Date: Wed, 20 Feb 2019 20:04:45 -0400 Subject: literally not readable (#9) --- webAO/master.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webAO/master.html b/webAO/master.html index f7c0f63..d5d71e2 100644 --- a/webAO/master.html +++ b/webAO/master.html @@ -29,7 +29,7 @@
                    -

                    This page uses cookie. By clicking on a server you agree that a cookie is saved on your computer.


                    +

                    This page uses cookies. By clicking on a server you agree that a cookie is saved on your computer.


                    The downloadable client is recommended


                    The green servers are more likely to work, red ones will not

                    @@ -39,4 +39,4 @@
                    - \ No newline at end of file + -- cgit From 31bfac3f0ec613710ba00c92202ab7de910b4d05 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 23 Mar 2019 19:00:51 +0100 Subject: npm update --- package-lock.json | 6748 +++++++++++++++-------------------------------------- package.json | 23 +- webpack.config.js | 21 +- 3 files changed, 1850 insertions(+), 4942 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20547d5..3d305b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1298 +1,1129 @@ { "name": "webao", - "version": "2.3.0", + "version": "2.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", - "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", - "dev": true, - "requires": { - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "debug": "^3.1.0", - "webassemblyjs": "1.4.3" + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", + "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.3.4", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.3.4", + "@babel/types": "^7.3.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - } - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", - "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", - "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", - "dev": true, - "requires": { - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", "dev": true, "requires": { - "ms": "2.0.0" + "minimist": "^1.2.0" } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, - "@webassemblyjs/helper-code-frame": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", - "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.4.3" + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" } }, - "@webassemblyjs/helper-fsm": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", - "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", - "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", - "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/leb128": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", - "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", "dev": true, "requires": { - "leb": "^0.3.0" + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/validation": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", - "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", + "@babel/helper-call-delegate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", + "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/wasm-edit": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", - "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/helper-wasm-section": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "@webassemblyjs/wasm-opt": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "@webassemblyjs/wast-printer": "1.4.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@babel/helper-define-map": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", + "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" } }, - "@webassemblyjs/wasm-gen": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", - "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/leb128": "1.4.3" + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/wasm-opt": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", - "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-buffer": "1.4.3", - "@webassemblyjs/wasm-gen": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/wasm-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", - "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/helper-wasm-bytecode": "1.4.3", - "@webassemblyjs/leb128": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "webassemblyjs": "1.4.3" + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/wast-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", - "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "@babel/helper-hoist-variables": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", + "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/floating-point-hex-parser": "1.4.3", - "@webassemblyjs/helper-code-frame": "1.4.3", - "@webassemblyjs/helper-fsm": "1.4.3", - "long": "^3.2.0", - "webassemblyjs": "1.4.3" + "@babel/types": "^7.0.0" } }, - "@webassemblyjs/wast-printer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", - "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "long": "^3.2.0" + "@babel/types": "^7.0.0" } }, - "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", "dev": true, "requires": { - "acorn": "^5.0.0" + "@babel/types": "^7.0.0" } }, - "ajv": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", - "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", + "@babel/helper-module-transforms": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", + "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0", - "uri-js": "^4.2.1" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.10" } }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "any-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", - "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", "dev": true, - "optional": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "@babel/types": "^7.0.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", "dev": true }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "@babel/helper-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", + "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "lodash": "^4.17.10" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", "dev": true, "requires": { - "array-uniq": "^1.0.1" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "@babel/helper-replace-supers": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.3.4.tgz", + "integrity": "sha512-pvObL9WVf2ADs+ePg0jrqlhHoxRXlOa+SHRHzAXIz2xkYuOHfGl+fKxPMaS4Fq+uje8JQPobnertBBvyrWnQ1A==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.3.4", + "@babel/types": "^7.3.4" } }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", "dev": true, "requires": { - "util": "0.10.3" + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", - "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "atob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true - }, - "babel-cli": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", - "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "@babel/helpers": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.3.0" } }, - "babel-helper-bindify-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", - "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" } }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" } }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" } }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.4.tgz", + "integrity": "sha512-j7VQmbbkA+qrzNqbKHrBsW3ddFnOeva6wzSe/zB7T+xaxGc+RCpwo44wCmRixAIGRoIpmVgvzFzNJqQcO3/9RA==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" } }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" } }, - "babel-helper-explode-class": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", - "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", + "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", "dev": true, "requires": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" } }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "@babel/plugin-transform-async-to-generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.3.4.tgz", + "integrity": "sha512-Y7nCzv2fw/jEZ9f678MuKdMo99MFDJMT/PvD9LisrR5JDFcJH6vYeH6RnjVt3p5tceyGRvTtEN0VOlU+rgHZjA==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" } }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "@babel/plugin-transform-block-scoping": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.3.4.tgz", + "integrity": "sha512-blRr2O8IOZLAOJklXLV4WhcEzpYafYQKSGT3+R26lWG41u/FODJuBggehtOwilVAcFu393v3OFj+HmaE6tVjhA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.11" } }, - "babel-loader": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz", - "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==", + "@babel/plugin-transform-classes": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.4.tgz", + "integrity": "sha512-J9fAvCFBkXEvBimgYxCjvaVDzL6thk0j0dBvCeZmIUDBwyt+nv6HfbImsSrWsYXfDNDivyANgJlFXDUWRTZBuA==", "dev": true, "requires": { - "find-cache-dir": "^1.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.1.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.3.4", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "@babel/plugin-transform-destructuring": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.3.2.tgz", + "integrity": "sha512-Lrj/u53Ufqxl/sGxyjsJ2XNtNuEjDyjpqdhMNh5aZ+XFOdThL46KBj27Uem4ggoezSYBxKWAil6Hu8HtwqesYw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-async-generators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", - "dev": true - }, - "babel-plugin-syntax-class-constructor-call": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", - "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", - "dev": true - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", - "dev": true - }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", - "dev": true - }, - "babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-export-extensions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", - "dev": true - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-generator-functions": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", - "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "@babel/plugin-transform-dotall-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", + "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" } }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-class-constructor-call": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", - "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", "dev": true, "requires": { - "babel-plugin-syntax-class-constructor-call": "^6.18.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "@babel/plugin-transform-for-of": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", + "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", - "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "@babel/plugin-transform-function-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", + "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", "dev": true, "requires": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", + "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" } }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "@babel/plugin-transform-modules-systemjs": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.3.4.tgz", + "integrity": "sha512-VZ4+jlGOF36S7TjKs8g4ojp4MEI+ebCQZdswWb/T9I4X84j8OtFAyjXjt/M16iIm5RIZn0UMQgg/VgIwo/87vw==", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz", + "integrity": "sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "regexp-tree": "^0.1.0" } }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "@babel/plugin-transform-new-target": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", + "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" } }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "@babel/plugin-transform-parameters": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz", + "integrity": "sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw==", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-call-delegate": "^7.1.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "@babel/plugin-transform-regenerator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.3.4.tgz", + "integrity": "sha512-hvJg8EReQvXT6G9H2MvNPXkv9zK36Vxa1+csAVTpE1J3j0zlHplw76uudEbJxgvqZzAq9Yh45FLD4pk5mKRFQA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "regenerator-transform": "^0.13.4" } }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" } }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "@babel/plugin-transform-template-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", + "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "@babel/plugin-transform-unicode-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", + "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" } }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "@babel/preset-env": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", + "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.3.4", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.3.4", + "@babel/plugin-transform-classes": "^7.3.4", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.2.0", + "@babel/plugin-transform-function-name": "^7.2.0", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-modules-systemjs": "^7.3.4", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.3.4", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.2.0", + "browserslist": "^4.3.4", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" } }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" } }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" } }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" } }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "@webassemblyjs/wast-printer": "1.8.5" } }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" } }, - "babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", "dev": true, "requires": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" } }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", "dev": true, "requires": { - "babel-plugin-syntax-flow": "^6.18.0", - "babel-runtime": "^6.22.0" + "@xtuc/ieee754": "^1.2.0" } }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", "dev": true, "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" + "@xtuc/long": "4.2.2" } }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" } }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" } }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, - "babel-preset-stage-1": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", - "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", "dev": true, "requires": { - "babel-plugin-transform-class-constructor-call": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-preset-stage-2": "^6.24.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", "dev": true, "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" } }, - "babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "color-convert": "^1.9.0" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", + "integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "babel-loader": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz", + "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "util.promisify": "^1.0.0" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1351,18 +1182,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -1373,27 +1192,21 @@ "dev": true }, "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true - }, - "binaryextensions": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.1.tgz", - "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", "dev": true }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, "bn.js": { @@ -1413,14 +1226,32 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "brorand": { @@ -1455,14 +1286,15 @@ } }, "browserify-des": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "browserify-rsa": { @@ -1500,13 +1332,14 @@ } }, "browserslist": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.7.tgz", - "integrity": "sha512-oYVLxFVqpX9uMhOIQBLtZL+CX4uY8ZpWcjNTaxyWl5rO8yA9SSNikFnAfvk8J3P/7z3BZwNmEqFKaJoYltj3MQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.1.tgz", + "integrity": "sha512-/pPw5IAUyqaQXGuD5vS8tcbudyPZ241jk1W5pQBsGDfcjNQt7p8qxZhgMNuygDShte1PibLFexecWUPgmVLfrg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000835", - "electron-to-chromium": "^1.3.45" + "caniuse-lite": "^1.0.30000949", + "electron-to-chromium": "^1.3.116", + "node-releases": "^1.1.11" } }, "buffer": { @@ -1521,9 +1354,9 @@ } }, "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "buffer-xor": { @@ -1532,12 +1365,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -1545,23 +1372,24 @@ "dev": true }, "cacache": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", - "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", - "dev": true, - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", "y18n": "^4.0.0" } }, @@ -1580,105 +1408,65 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", - "dev": true, - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - } } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", "dev": true }, "caniuse-lite": { - "version": "1.0.30000840", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000840.tgz", - "integrity": "sha512-Lw6AaouV6lh7TgIdQtLiUFKKO2mtDnZFkzCq5/V6tqs4ZI0OGVSDCEt1uegZ3OOBEBUYuVw3Hhr9DQSbgVofFA==", + "version": "1.0.30000950", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000950.tgz", + "integrity": "sha512-Cs+4U9T0okW2ftBsCIHuEYXXkki7mjXmjCh4c6PzYShk04qDEr76/iC7KwhLoWoY65wcra1XOsRD+S7BptEb5A==", "dev": true }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", "dev": true, - "optional": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "readdirp": "^2.2.1", + "upath": "^1.1.0" } }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true }, "chrome-trace-event": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", - "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", + "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } }, "cipher-base": { "version": "1.0.4", @@ -1710,192 +1498,55 @@ "requires": { "is-descriptor": "^0.1.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" } }, - "cli-spinners": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", - "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "colors": "1.0.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } + "color-name": "1.1.3" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", - "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true }, "commondir": { @@ -1944,10 +1595,13 @@ "dev": true }, "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } }, "copy-concurrently": { "version": "1.0.5", @@ -1969,12 +1623,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "core-js": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", - "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -2018,29 +1666,6 @@ "sha.js": "^2.4.8" } }, - "cross-env": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.5.tgz", - "integrity": "sha512-GSiNTbvTU3pXzewRKGP0Y+rVP2CzifY2pqSEdtHzLLj41pRdkrgY7e4uSnBoR/pmYaqZr/lwwjg/Q4kNX30hWQ==", - "dev": true, - "requires": { - "cross-spawn": "^5.1.0", - "is-windows": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2079,30 +1704,12 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, - "dargs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", - "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", - "dev": true - }, - "date-fns": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", - "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==", - "dev": true - }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2124,21 +1731,15 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { - "mimic-response": "^1.0.0" + "object-keys": "^1.0.12" } }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true - }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -2177,18 +1778,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -2202,25 +1791,10 @@ "minimalistic-assert": "^1.0.0" } }, - "detect-conflict": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", - "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, "diffie-hellman": { @@ -2234,32 +1808,16 @@ "randombytes": "^2.0.0" } }, - "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" - } - }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, "duplexify": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { "end-of-stream": "^1.0.0", @@ -2268,34 +1826,16 @@ "stream-shift": "^1.0.0" } }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "ejs": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", - "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", - "dev": true - }, "electron-to-chromium": { - "version": "1.3.45", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.45.tgz", - "integrity": "sha1-RYrBscXHYM6IEaFtK/vZfsMLr7g=", - "dev": true - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "version": "1.3.116", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.116.tgz", + "integrity": "sha512-NKwKAXzur5vFCZYBHpdWjTMO8QptNLNP80nItkSIgUOapPAo9Uia+RvkCaZJtO7fhQaVElSvBPWEc2ku6cKsPA==", "dev": true }, "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -2323,9 +1863,9 @@ } }, "enhanced-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz", - "integrity": "sha512-jox/62b2GofV1qTUQTMPEJSDIGycS43evqYzD/KVtEb9OCoki9cnacUPxCrZa7JfPzZSYOCZhu9O9luaMxAX8g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -2333,12 +1873,6 @@ "tapable": "^1.0.0" } }, - "envinfo": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-4.4.2.tgz", - "integrity": "sha512-5rfRs+m+6pwoKRCFqpsA5+qsLngFms1aWPrxfKbrObCzQaPc3M3yPloZx+BL9UE3dK58cxw36XVQbFRSCCfGSQ==", - "dev": true - }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -2348,23 +1882,29 @@ "prr": "~1.0.1" } }, - "error": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", - "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, "escape-string-regexp": { @@ -2374,21 +1914,15 @@ "dev": true }, "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -2411,9 +1945,9 @@ "dev": true }, "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, "evp_bytestokey": { @@ -2427,57 +1961,55 @@ } }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "is-extendable": "^0.1.0" } } } }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -2508,262 +2040,44 @@ } } }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-glob": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.1.tgz", - "integrity": "sha512-wSyW1TBK3ia5V+te0rGPXudeMHoUQW6O5Y9oATiaGhpENmEifPDlOdhpsnlj5HoG6ttIvGiY1DdCmI9X2xGMhg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.1", - "micromatch": "^3.1.10" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "is-descriptor": "^1.0.0" } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-extendable": "^0.1.0" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -2788,154 +2102,101 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } } } }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", "dev": true }, "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^3.0.0" } }, - "first-chunk-stream": { + "findup-sync": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } } }, - "flow-parser": { - "version": "0.72.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.72.0.tgz", - "integrity": "sha512-kFaDtviKlD/rHi6NRp42KTbnPgz/nKcWUJQhqDnLDeKA8uGcRVSy0YlQjaf9M3pFo5PgC3SNFnCPpQGLtHjH2w==", - "dev": true - }, "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" } }, "for-in": { @@ -2944,15 +2205,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -2972,12 +2224,6 @@ "readable-stream": "^2.0.0" } }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -2997,14 +2243,14 @@ "dev": true }, "fsevents": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.3.tgz", - "integrity": "sha512-X+57O5YkDTiEQGiw8i7wYc2nQgweIekqkepI8Q3y4wVlurgBt2SuwxTeYUYMZIGpLZH3r/TsMjczCMXE5ZOt7Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { "nan": "^2.9.2", - "node-pre-gyp": "^0.9.0" + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -3016,7 +2262,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3025,7 +2272,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, @@ -3037,19 +2284,21 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -3057,17 +2306,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3085,7 +2337,7 @@ } }, "deep-extend": { - "version": "0.4.2", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -3134,7 +2386,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, @@ -3154,12 +2406,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -3184,7 +2436,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3196,6 +2449,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3210,6 +2464,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3217,19 +2472,21 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, @@ -3241,6 +2498,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3252,7 +2510,7 @@ "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.2.4", "bundled": true, "dev": true, "optional": true, @@ -3263,18 +2521,18 @@ } }, "node-pre-gyp": { - "version": "0.9.1", + "version": "0.10.3", "bundled": true, "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -3291,13 +2549,13 @@ } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.5", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true, @@ -3321,7 +2579,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3333,6 +2592,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3372,12 +2632,12 @@ "optional": true }, "rc": { - "version": "1.2.6", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "~0.4.0", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -3407,18 +2667,19 @@ } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3433,7 +2694,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "dev": true, "optional": true @@ -3454,6 +2715,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3473,6 +2735,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3484,17 +2747,17 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, @@ -3505,37 +2768,48 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "get-value": { "version": "2.0.6", @@ -3543,83 +2817,10 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, - "gh-got": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gh-got/-/gh-got-6.0.0.tgz", - "integrity": "sha512-F/mS+fsWQMo1zfgG9MD8KWvTWPPzzhuVwY++fhQ5Ggd+0P+CAMHtzMZhNxG+TqGfHDChJKsbh6otfMGqO2AKBw==", - "dev": true, - "requires": { - "got": "^7.0.0", - "is-plain-obj": "^1.1.0" - }, - "dependencies": { - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "github-username": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/github-username/-/github-username-4.1.0.tgz", - "integrity": "sha1-y+KABBiDIG2kISrp5LXxacML9Bc=", - "dev": true, - "requires": { - "gh-got": "^6.0.0" - } - }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3630,58 +2831,27 @@ "path-is-absolute": "^1.0.0" } }, - "glob-all": { + "glob-parent": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz", - "integrity": "sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "glob": "^7.0.5", - "yargs": "~1.2.6" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { - "minimist": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", - "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", - "dev": true - }, - "yargs": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", - "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "minimist": "^0.1.0" + "is-extglob": "^2.1.0" } } } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -3707,102 +2877,38 @@ } }, "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", - "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "fast-glob": "^2.0.2", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - } - }, - "got": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz", - "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - } + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "grouped-queue": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz", - "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", - "dev": true, - "requires": { - "lodash": "^4.17.2" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "function-bind": "^1.1.1" } }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -3812,14 +2918,6 @@ "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "has-values": { @@ -3832,26 +2930,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -3874,13 +2952,13 @@ } }, "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "requires": { "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.1" } }, "hmac-drbg": { @@ -3894,56 +2972,25 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "requires": { "parse-passwd": "^1.0.0" } }, - "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", - "dev": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ieee754": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", - "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", "dev": true }, "iferr": { @@ -3952,19 +2999,13 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, - "ignore": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", - "dev": true - }, "import-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { - "pkg-dir": "^2.0.0", + "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" } }, @@ -3974,15 +3015,6 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -4011,89 +3043,12 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "inquirer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", - "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.1.0", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^5.5.2", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, - "into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", - "dev": true, - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -4104,9 +3059,9 @@ } }, "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "is-accessor-descriptor": { @@ -4116,14 +3071,19 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -4139,14 +3099,11 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true }, "is-data-descriptor": { "version": "0.1.4", @@ -4155,8 +3112,25 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -4176,21 +3150,6 @@ } } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -4198,20 +3157,11 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -4219,69 +3169,34 @@ "dev": true }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "^2.1.1" } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" - } - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, - "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", - "dev": true, - "requires": { - "symbol-observable": "^0.2.2" - }, - "dependencies": { - "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", - "dev": true - } - } - }, - "is-odd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", - "dev": true, - "requires": { - "is-number": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4289,47 +3204,15 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-scoped": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-scoped/-/is-scoped-1.0.0.tgz", - "integrity": "sha1-RJypgpnnEwOCViieyytUDcQ3yzA=", + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, "requires": { - "scoped-regex": "^1.0.0" + "has": "^1.0.1" } }, "is-stream": { @@ -4338,11 +3221,14 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } }, "is-windows": { "version": "1.0.2", @@ -4356,12 +3242,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isbinaryfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", - "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4369,82 +3249,27 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "jscodeshift": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.0.tgz", - "integrity": "sha512-JAcQINNMFpdzzpKJN8k5xXjF3XDuckB1/48uScSzcnNyK199iWEc9AxKL9OoX5144M2w5zEx9Qs4/E/eBZZUlw==", - "dev": true, - "requires": { - "babel-plugin-transform-flow-strip-types": "^6.8.0", - "babel-preset-es2015": "^6.9.0", - "babel-preset-stage-1": "^6.5.0", - "babel-register": "^6.9.0", - "babylon": "^7.0.0-beta.30", - "colors": "^1.1.2", - "flow-parser": "^0.*", - "lodash": "^4.13.1", - "micromatch": "^2.3.7", - "neo-async": "^2.5.0", - "node-dir": "0.1.8", - "nomnom": "^1.8.1", - "recast": "^0.14.1", - "temp": "^0.8.1", - "write-file-atomic": "^1.2.0" - }, - "dependencies": { - "babylon": { - "version": "7.0.0-beta.46", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.46.tgz", - "integrity": "sha512-WFJlg2WatdkXRFMpk7BN/Uzzkjkcjk+WaqnrSCpay+RYl4ypW9ZetZyT9kNt22IH/BQNst3M6PaaBn9IXsUNrg==", - "dev": true - } - } - }, "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json-parse-better-errors": { @@ -4454,368 +3279,109 @@ "dev": true }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, - "keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "json-buffer": "3.0.0" + "invert-kv": "^2.0.0" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "invert-kv": "^1.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "leb": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", - "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, - "listr": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz", - "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "figures": "^1.7.0", - "indent-string": "^2.1.0", - "is-observable": "^0.2.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.4.0", - "listr-verbose-renderer": "^0.4.0", - "log-symbols": "^1.0.2", - "log-update": "^1.0.2", - "ora": "^0.2.3", - "p-map": "^1.1.1", - "rxjs": "^5.4.2", - "stream-to-observable": "^0.2.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - } + "js-tokens": "^3.0.0 || ^4.0.0" } }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz", - "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^1.0.2", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - } - } - }, - "listr-verbose-renderer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", - "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-cursor": "^1.0.2", - "date-fns": "^1.27.2", - "figures": "^1.7.0" - }, - "dependencies": { - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - } - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", - "dev": true - }, - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "log-update": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", - "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", - "dev": true, - "requires": { - "ansi-escapes": "^1.0.0", - "cli-cursor": "^1.0.2" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - } + "yallist": "^3.0.2" } }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "pify": "^4.0.1", + "semver": "^5.6.0" } }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", "dev": true }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { - "pify": "^3.0.0" + "p-defer": "^1.0.0" } }, "map-cache": { @@ -4833,93 +3399,26 @@ "object-visit": "^1.0.0" } }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mem-fs": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz", - "integrity": "sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw=", - "dev": true, - "requires": { - "through2": "^2.0.0", - "vinyl": "^1.1.0", - "vinyl-file": "^2.0.0" - } - }, - "mem-fs-editor": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.2.tgz", - "integrity": "sha512-QHvdXLLNmwJXxKdf7x27aNUren6IoPxwcM8Sfd+S6/ddQQMcYdEtVKsh6ilpqMrU18VQuKZEaH0aCGt3JDbA0g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", "dev": true, "requires": { - "commondir": "^1.0.1", - "deep-extend": "^0.5.1", - "ejs": "^2.5.9", - "glob": "^7.0.3", - "globby": "^8.0.0", - "isbinaryfile": "^3.0.2", - "mkdirp": "^0.5.0", - "multimatch": "^2.0.0", - "rimraf": "^2.2.8", - "through2": "^2.0.0", - "vinyl": "^2.0.1" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - } + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" } }, "memory-fs": { @@ -4932,31 +3431,25 @@ "readable-stream": "^2.0.1" } }, - "merge2": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", - "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", - "dev": true - }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "miller-rabin": { @@ -4970,15 +3463,9 @@ } }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", "dev": true }, "minimalistic-assert": { @@ -5003,15 +3490,15 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "mississippi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", - "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", "dev": true, "requires": { "concat-stream": "^1.5.0", @@ -5020,7 +3507,7 @@ "flush-write-stream": "^1.0.0", "from2": "^2.1.0", "parallel-transform": "^1.1.0", - "pump": "^2.0.1", + "pump": "^3.0.0", "pumpify": "^1.3.3", "stream-each": "^1.1.0", "through2": "^2.0.0" @@ -5054,6 +3541,14 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } } }, "move-concurrently": { @@ -5076,35 +3571,17 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.1.tgz", + "integrity": "sha512-I6YB/YEuDeUZMmhscXKxGgZlFnhsn5y0hgOZBadkzfTRrZBtJDZeg6eQf7PYMIEclwmorTKK8GztsyOUSVBREA==", "dev": true, "optional": true }, "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -5112,57 +3589,30 @@ "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", "is-windows": "^1.0.2", "kind-of": "^6.0.2", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } } }, "neo-async": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", - "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", "dev": true }, "nice-try": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", - "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", - "dev": true - }, - "node-dir": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.8.tgz", - "integrity": "sha1-VfuN62mQcHB/tn+RpGDwRIKUx30=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", "dev": true, "requires": { "assert": "^1.1.1", @@ -5172,7 +3622,7 @@ "constants-browserify": "^1.0.0", "crypto-browserify": "^3.11.0", "domain-browser": "^1.1.1", - "events": "^1.0.0", + "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", "path-browserify": "0.0.0", @@ -5186,7 +3636,7 @@ "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", "url": "^0.11.0", - "util": "^0.10.3", + "util": "^0.11.0", "vm-browserify": "0.0.4" }, "dependencies": { @@ -5198,72 +3648,20 @@ } } }, - "nomnom": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", - "dev": true, - "requires": { - "chalk": "~0.4.0", - "underscore": "~1.6.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" - } - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "node-releases": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.11.tgz", + "integrity": "sha512-8v1j5KfP+s5WOTa1spNUAOfreajQPN12JXbRR0oDE+YrJBQCXBnNqUDj27EKpPLOoSiU3tKi3xGPB+JaOdUEQQ==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "semver": "^5.3.0" } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -5280,12 +3678,6 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -5305,9 +3697,24 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } } }, + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -5315,24 +3722,16 @@ "dev": true, "requires": { "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" } }, "object.pick": { @@ -5342,14 +3741,6 @@ "dev": true, "requires": { "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "once": { @@ -5361,108 +3752,28 @@ "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "ora": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", - "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "cli-cursor": "^1.0.2", - "cli-spinners": "^0.1.2", - "object-assign": "^4.0.1" - }, - "dependencies": { - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - } - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true - }, - "p-each-series": { + "p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "dev": true, - "requires": { - "p-reduce": "^1.0.0" - } + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true }, "p-finally": { "version": "1.0.0", @@ -5471,66 +3782,39 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true - }, - "p-lazy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-lazy/-/p-lazy-1.0.0.tgz", - "integrity": "sha1-7FPIAvLuOsKPFmzILQsrAt4nqDU=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", "dev": true }, "p-limit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", - "dev": true - }, - "p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", - "dev": true - }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-finally": "^1.0.0" + "p-limit": "^2.0.0" } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", "dev": true }, "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", "dev": true }, "parallel-transform": { @@ -5545,38 +3829,17 @@ } }, "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", "dev": true, "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parse-passwd": { @@ -5622,24 +3885,15 @@ "dev": true }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -5650,33 +3904,18 @@ } }, "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "^2.1.0" + "find-up": "^3.0.0" } }, "posix-character-classes": { @@ -5685,30 +3924,6 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.1.tgz", - "integrity": "sha1-wa0g6APndJ+vkFpAnSNn4Gu+cyU=", - "dev": true - }, - "pretty-bytes": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", - "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", - "dev": true - }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -5739,29 +3954,24 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "public-encrypt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -5769,33 +3979,34 @@ } }, "pumpify": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.0.tgz", - "integrity": "sha512-UWi0klDoq8xtVzlMRgENV9F7iCTZExaJQSQL187UXsxpk9NnrKGqTqqUNYAKGOzucSOxs2+jUnRNI+rLviPhJg==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } } }, "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -5808,35 +4019,10 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, - "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -5852,37 +4038,6 @@ "safe-buffer": "^5.1.0" } }, - "read-chunk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", - "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", - "dev": true, - "requires": { - "pify": "^3.0.0", - "safe-buffer": "^5.1.1" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -5899,44 +4054,14 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "recast": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", - "integrity": "sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A==", - "dev": true, - "requires": { - "ast-types": "0.11.3", - "esprima": "~4.0.0", - "private": "~0.1.5", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "resolve": "^1.1.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regenerate": { @@ -5945,30 +4070,22 @@ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "regenerate-unicode-properties": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz", + "integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==", "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "regenerate": "^1.4.0" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "regenerator-transform": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", + "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3" + "private": "^0.1.6" } }, "regex-not": { @@ -5981,27 +4098,36 @@ "safe-regex": "^1.1.0" } }, + "regexp-tree": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.5.tgz", + "integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==", + "dev": true + }, "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" } }, "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", "dev": true }, "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -6022,9 +4148,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, "repeat-string": { @@ -6033,21 +4159,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6061,12 +4172,12 @@ "dev": true }, "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "^1.0.6" } }, "resolve-cwd": { @@ -6100,25 +4211,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -6126,12 +4218,12 @@ "dev": true }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "ripemd160": { @@ -6144,15 +4236,6 @@ "inherits": "^2.0.1" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -6162,15 +4245,6 @@ "aproba": "^1.1.1" } }, - "rxjs": { - "version": "5.5.10", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz", - "integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6186,38 +4260,27 @@ "ret": "~0.1.10" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", "ajv-keywords": "^3.1.0" } }, - "scoped-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz", - "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", - "dev": true - }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "serialize-javascript": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", - "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", "dev": true }, "set-blocking": { @@ -6226,12 +4289,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -6286,41 +4343,12 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, - "shelljs": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", - "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -6405,18 +4433,6 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true } } }, @@ -6427,21 +4443,23 @@ "dev": true, "requires": { "kind-of": "^3.2.0" - } - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", "dev": true }, "source-map": { @@ -6464,12 +4482,21 @@ } }, "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.11.tgz", + "integrity": "sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ==", "dev": true, "requires": { - "source-map": "^0.5.6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -6478,38 +4505,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -6520,12 +4515,12 @@ } }, "ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "safe-buffer": "^5.1.1" + "figgy-pudding": "^3.5.1" } }, "static-extend": { @@ -6550,9 +4545,9 @@ } }, "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { "inherits": "~2.0.1", @@ -6560,9 +4555,9 @@ } }, "stream-each": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", - "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", "dev": true, "requires": { "end-of-stream": "^1.1.0", @@ -6570,9 +4565,9 @@ } }, "stream-http": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", - "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", @@ -6588,27 +4583,6 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, - "stream-to-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz", - "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", - "dev": true, - "requires": { - "any-observable": "^0.2.0" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -6617,23 +4591,6 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "string_decoder": { @@ -6646,31 +4603,12 @@ } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", - "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "first-chunk-stream": "^2.0.0", - "strip-bom": "^2.0.0" + "ansi-regex": "^3.0.0" } }, "strip-eof": { @@ -6680,75 +4618,73 @@ "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, "tapable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", - "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", "dev": true }, - "temp": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", "dev": true, "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" }, "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "textextensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.2.0.tgz", - "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "terser-webpack-plugin": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz", + "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==", + "dev": true, + "requires": { + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.16.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } }, "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { - "readable-stream": "^2.1.5", + "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", @@ -6758,15 +4694,6 @@ "setimmediate": "^1.0.4" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -6774,9 +4701,9 @@ "dev": true }, "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-object-path": { @@ -6786,6 +4713,17 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, "to-regex": { @@ -6808,17 +4746,6 @@ "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } } }, "trim-right": { @@ -6827,6 +4754,12 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -6839,58 +4772,32 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true }, - "uglifyjs-webpack-plugin": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz", - "integrity": "sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw==", + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", "dev": true, "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "schema-utils": "^0.4.5", - "serialize-javascript": "^1.4.0", - "source-map": "^0.6.1", - "uglify-es": "^3.3.4", - "webpack-sources": "^1.1.0", - "worker-farm": "^1.5.2" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" } }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", "dev": true }, "union-value": { @@ -6929,18 +4836,18 @@ } }, "unique-filename": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", - "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { "unique-slug": "^2.0.0" } }, "unique-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", - "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", "dev": true, "requires": { "imurmurhash": "^0.1.4" @@ -6983,31 +4890,19 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true } } }, - "untildify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", - "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=", - "dev": true - }, "upath": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz", - "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, "uri-js": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", - "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -7037,59 +4932,19 @@ } } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, "use": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } + "inherits": "2.0.3" } }, "util-deprecate": { @@ -7098,455 +4953,60 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, "v8-compile-cache": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz", - "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", + "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", "dev": true }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { - "user-home": "^1.1.1" + "indexof": "0.0.1" } }, - "validate-npm-package-license": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", - "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.3.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^2.0.0", - "vinyl": "^1.1.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.1.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webassemblyjs": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", - "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/validation": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "@webassemblyjs/wast-parser": "1.4.3", - "long": "^3.2.0" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" } }, "webpack": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.8.3.tgz", - "integrity": "sha512-/hfAjBISycdK597lxONjKEFX7dSIU1PsYwC3XlXUXoykWBlv9QV5HnO+ql3HvrrgfBJ7WXdnjO9iGPR2aAc5sw==", + "version": "4.29.6", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.6.tgz", + "integrity": "sha512-MwBwpiE1BQpMDkbnUUaW6K8RFZjljJHArC6tWQJoFm0oQtfoSebtg4Y7/QHnJ/SddtjYLHaKGX64CFjG5rehJw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.4.3", - "@webassemblyjs/wasm-edit": "1.4.3", - "@webassemblyjs/wasm-parser": "1.4.3", - "acorn": "^5.0.0", - "acorn-dynamic-import": "^3.0.0", + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.0.5", + "acorn-dynamic-import": "^4.0.0", "ajv": "^6.1.0", "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^0.1.1", - "enhanced-resolve": "^4.0.0", - "eslint-scope": "^3.7.1", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.3.0", "loader-utils": "^1.1.0", "memory-fs": "~0.4.1", @@ -7554,417 +5014,36 @@ "mkdirp": "~0.5.0", "neo-async": "^2.5.0", "node-libs-browser": "^2.0.0", - "schema-utils": "^0.4.4", - "tapable": "^1.0.0", - "uglifyjs-webpack-plugin": "^1.2.4", + "schema-utils": "^1.0.0", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", "watchpack": "^1.5.0", - "webpack-sources": "^1.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "webpack-addons": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/webpack-addons/-/webpack-addons-1.1.5.tgz", - "integrity": "sha512-MGO0nVniCLFAQz1qv22zM02QPjcpAoJdy7ED0i3Zy7SY1IecgXCm460ib7H/Wq7e9oL5VL6S2BxaObxwIcag0g==", - "dev": true, - "requires": { - "jscodeshift": "^0.4.0" - }, - "dependencies": { - "ast-types": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz", - "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==", - "dev": true - }, - "jscodeshift": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.4.1.tgz", - "integrity": "sha512-iOX6If+hsw0q99V3n31t4f5VlD1TQZddH08xbT65ZqA7T4Vkx68emrDZMUOLVvCEAJ6NpAk7DECe3fjC/t52AQ==", - "dev": true, - "requires": { - "async": "^1.5.0", - "babel-plugin-transform-flow-strip-types": "^6.8.0", - "babel-preset-es2015": "^6.9.0", - "babel-preset-stage-1": "^6.5.0", - "babel-register": "^6.9.0", - "babylon": "^6.17.3", - "colors": "^1.1.2", - "flow-parser": "^0.*", - "lodash": "^4.13.1", - "micromatch": "^2.3.7", - "node-dir": "0.1.8", - "nomnom": "^1.8.1", - "recast": "^0.12.5", - "temp": "^0.8.1", - "write-file-atomic": "^1.2.0" - } - }, - "recast": { - "version": "0.12.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz", - "integrity": "sha512-y7ANxCWmMW8xLOaiopiRDlyjQ9ajKRENBH+2wjntIbk3A6ZR1+BLQttkmSHMY7Arl+AAZFwJ10grg2T6f1WI8A==", - "dev": true, - "requires": { - "ast-types": "0.10.1", - "core-js": "^2.4.1", - "esprima": "~4.0.0", - "private": "~0.1.5", - "source-map": "~0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "webpack-sources": "^1.3.0" } }, "webpack-cli": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.1.3.tgz", - "integrity": "sha512-5AsKoL/Ccn8iTrwk3uErdyhetGH+c7VRQ7Itim2GL0IhBRq5rtojVDk00buMRmFmBpw1RvHXq97Gup965LbozA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.0.tgz", + "integrity": "sha512-t1M7G4z5FhHKJ92WRKwZ1rtvi7rHc0NZoZRbSkol0YKl4HvcC8+DsmGDmK7MmZxHSAetHagiOsjOB6MmzC2TUw==", "dev": true, "requires": { - "chalk": "^2.3.2", + "chalk": "^2.4.1", "cross-spawn": "^6.0.5", - "diff": "^3.5.0", - "enhanced-resolve": "^4.0.0", - "envinfo": "^4.4.2", - "glob-all": "^3.1.0", + "enhanced-resolve": "^4.1.0", + "findup-sync": "^2.0.0", "global-modules": "^1.0.0", - "got": "^8.2.0", - "import-local": "^1.0.0", - "inquirer": "^5.1.0", - "interpret": "^1.0.4", - "jscodeshift": "^0.5.0", - "listr": "^0.13.0", + "import-local": "^2.0.0", + "interpret": "^1.1.0", "loader-utils": "^1.1.0", - "lodash": "^4.17.5", - "log-symbols": "^2.2.0", - "mkdirp": "^0.5.1", - "p-each-series": "^1.0.0", - "p-lazy": "^1.0.0", - "prettier": "^1.5.3", - "supports-color": "^5.3.0", - "v8-compile-cache": "^1.1.2", - "webpack-addons": "^1.1.5", - "yargs": "^11.1.0", - "yeoman-environment": "^2.0.0", - "yeoman-generator": "^2.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "supports-color": "^5.5.0", + "v8-compile-cache": "^2.0.2", + "yargs": "^12.0.5" } }, "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", "dev": true, "requires": { "source-list-map": "^2.0.0", @@ -7980,9 +5059,9 @@ } }, "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -8013,6 +5092,12 @@ "strip-ansi": "^3.0.1" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -8032,6 +5117,15 @@ "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -8041,17 +5135,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -8065,212 +5148,39 @@ "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true }, "yargs": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", - "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "os-locale": "^3.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^2.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - } + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" } }, "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" - } - }, - "yeoman-environment": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.1.1.tgz", - "integrity": "sha512-IBLwCUrJrDxBYuwdYm1wuF3O/CR2LpXR0rFS684QOrU6x69DPPrsdd20dZOFaedZ/M9sON7po73WhO3I1CbgNQ==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^3.1.0", - "diff": "^3.3.1", - "escape-string-regexp": "^1.0.2", - "globby": "^8.0.1", - "grouped-queue": "^0.3.3", - "inquirer": "^5.2.0", - "is-scoped": "^1.0.0", - "lodash": "^4.17.10", - "log-symbols": "^2.1.0", - "mem-fs": "^1.1.0", - "strip-ansi": "^4.0.0", - "text-table": "^0.2.0", - "untildify": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "yeoman-generator": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", - "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", - "dev": true, - "requires": { - "async": "^2.6.0", - "chalk": "^2.3.0", - "cli-table": "^0.3.1", - "cross-spawn": "^6.0.5", - "dargs": "^5.1.0", - "dateformat": "^3.0.3", - "debug": "^3.1.0", - "detect-conflict": "^1.0.0", - "error": "^7.0.2", - "find-up": "^2.1.0", - "github-username": "^4.0.0", - "istextorbinary": "^2.2.1", - "lodash": "^4.17.10", - "make-dir": "^1.1.0", - "mem-fs-editor": "^4.0.0", - "minimist": "^1.2.0", - "pretty-bytes": "^4.0.2", - "read-chunk": "^2.1.0", - "read-pkg-up": "^3.0.0", - "rimraf": "^2.6.2", - "run-async": "^2.0.0", - "shelljs": "^0.8.0", - "text-table": "^0.2.0", - "through2": "^2.0.0", - "yeoman-environment": "^2.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, - "requires": { - "lodash": "^4.14.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } diff --git a/package.json b/package.json index 1ff0779..d72b6f0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,14 @@ { "name": "webao", - "version": "2.3.0", + "version": "2.6.0", "description": "Web-based Attorney Online client", "main": "client.js", "scripts": { + "babel": "babel ui.js -o ui.b.js", "webpack": "webpack", "deploy": "cross-env NODE_ENV=production webpack -p", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "build": "webpack" }, "repository": { "type": "git", @@ -18,14 +20,11 @@ }, "homepage": "https://github.com/stonedDiscord/stonedDiscord.github.io#readme", "devDependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.26.3", - "babel-loader": "^7.1.4", - "babel-preset-env": "^1.7.0", - "babel-preset-es2015": "^6.24.1", - "cross-env": "^5.1.5", - "uglify-es": "3.3.9", - "webpack": "^4.8.3", - "webpack-cli": "^2.1.3" - } + "@babel/core": "^7.3.4", + "@babel/preset-env": "^7.3.4", + "babel-loader": "^8.0.5", + "webpack": "^4.29.6", + "webpack-cli": "^3.3.0" + }, + "dependencies": {} } diff --git a/webpack.config.js b/webpack.config.js index 197e91c..8032471 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,6 @@ module.exports = { entry: { ui: './webAO/ui.js', - fingerprint: './webAO/fingerprint.js', client: './webAO/client.js' }, output: { @@ -9,18 +8,18 @@ module.exports = { }, module: { rules: [ - { - test: /\.js?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['es2015'] - } - } + { + test: /\.m?js$/, + exclude: /(node_modules|bower_components)/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'] + } } + } ] - }, + }, devtool: 'source-map' } \ No newline at end of file -- cgit From 56f0f87b6d8f6d7e0572543f83956c2c1db459f8 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 23 Mar 2019 19:15:36 +0100 Subject: b& --- webAO/client.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webAO/client.js b/webAO/client.js index f9fa2b9..f7ab8b2 100644 --- a/webAO/client.js +++ b/webAO/client.js @@ -111,6 +111,7 @@ class Client { "LE": (args) => this.handleLE(args), "EM": (args) => this.handleEM(args), "SM": (args) => this.handleSM(args), + "BD": (args) => this.handleBD(args), "music": (args) => this.handlemusic(args), "DONE": (args) => this.handleDONE(args), "BN": (args) => this.handleBN(args), @@ -707,6 +708,14 @@ class Client { this.serv.send("RD#%"); } + /** + * Handles the banned packet + * @param {Array} args packet arguments + */ + handleBD(args) { + document.getElementById("client_loadingtext").innerHTML = "Banned: " + args[1]; + } + /** * Handles incoming music information, containing all entries * in the same packet. -- cgit From 2367bd601ad039eee872894977af7ef055ca9cc5 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 23 Mar 2019 19:15:51 +0100 Subject: more npm --- .babelrc | 9 --------- .eslintrc.js | 35 ----------------------------------- 2 files changed, 44 deletions(-) delete mode 100644 .babelrc delete mode 100644 .eslintrc.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 5d36355..0000000 --- a/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "presets": [ - ["env", { - "targets": { - "browsers": ["last 2 versions", "ie >= 11"] - } - }] - ] - } \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 3b5d12a..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "es6": true, - "jquery": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 2016, - "sourceType": "module" - }, - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "off" - ], - "quotes": [ - "warn", - "double" - ], - "semi": [ - "error", - "always" - ], - "no-console": [ - "off" - ], - "no-unused-vars": [ - "warn" - ], - } -}; \ No newline at end of file -- cgit From 4226220f412eddd1f709944b5ceb575b69e4591a Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Sat, 23 Mar 2019 19:16:05 +0100 Subject: webpack did its thing --- dist/client.b.js | 2 ++ dist/client.b.js.map | 1 + dist/ui.b.js | 2 ++ dist/ui.b.js.map | 1 + 4 files changed, 6 insertions(+) create mode 100644 dist/client.b.js create mode 100644 dist/client.b.js.map create mode 100644 dist/ui.b.js create mode 100644 dist/ui.b.js.map diff --git a/dist/client.b.js b/dist/client.b.js new file mode 100644 index 0000000..a2bc630 --- /dev/null +++ b/dist/client.b.js @@ -0,0 +1,2 @@ +!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.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 o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));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";n.r(t);var i=["Anime","birthday","Christmas","CountyCourt","CruiseCourt","default","DGDEnglishCourt","DGSJapanCourt","DualDestinies","EnglishCourt","gs4","GS4Night","HD","Khura'in","mlp","NewCourt","RuinedCourt","Sky","SpaceCourt","Themis","TouhouCourt","WitchTrialCourt","Zetta"],o=["1.png","2.png","3.png","4.png","5.png","6.png","empty.png","lawyerbadge.png"];function c(e){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var a=function e(t){var n,i;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),n=Array.prototype.forEach,i=Array.prototype.map,this.each=function(e,t,i){if(null!==e)if(n&&e.forEach===n)e.forEach(t,i);else if(e.length===+e.length){for(var o=0,c=e.length;o>>16)*a&65535)<<16)&4294967295)<<15|r>>>17))*s+(((r>>>16)*s&65535)<<16)&4294967295)<<13|o>>>19))+((5*(o>>>16)&65535)<<16)&4294967295))+((58964+(c>>>16)&65535)<<16);switch(r=0,n){case 3:r^=(255&e.charCodeAt(l+2))<<16;case 2:r^=(255&e.charCodeAt(l+1))<<8;case 1:o^=r=(65535&(r=(r=(65535&(r^=255&e.charCodeAt(l)))*a+(((r>>>16)*a&65535)<<16)&4294967295)<<15|r>>>17))*s+(((r>>>16)*s&65535)<<16)&4294967295}return o^=e.length,o=2246822507*(65535&(o^=o>>>16))+((2246822507*(o>>>16)&65535)<<16)&4294967295,o=3266489909*(65535&(o^=o>>>13))+((3266489909*(o>>>16)&65535)<<16)&4294967295,(o^=o>>>16)>>>0},hasLocalStorage:function(){try{return!!window.localStorage}catch(e){return!0}},hasSessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName||!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},getPluginsString:function(){return this.isIE()&&this.ie_activex?this.getIEPluginsString():this.getRegularPluginsString()},getRegularPluginsString:function(){return this.map(navigator.plugins,function(e){var t=this.map(e,function(e){return[e.type,e.suffixes].join("~")}).join(",");return[e.name,e.description,t].join("::")},this).join(";")},getIEPluginsString:function(){if(window.ActiveXObject){return this.map(["ShockwaveFlash.ShockwaveFlash","AcroPDF.PDF","PDF.PdfCtrl","QuickTime.QuickTime","rmocx.RealPlayer G2 Control","rmocx.RealPlayer G2 Control.1","RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)","RealVideo.RealVideo(tm) ActiveX Control (32-bit)","RealPlayer","SWCtl.SWCtl","WMPlayer.OCX","AgControl.AgControl","Skype.Detection"],function(e){try{return new ActiveXObject(e),e}catch(e){return null}}).join(";")}return""},getScreenResolution:function(){return this.screen_orientation?screen.height>screen.width?[screen.height,screen.width]:[screen.width,screen.height]:[screen.height,screen.width]},getCanvasFingerprint:function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-={}|[]:"<>?;,.';return t.textBaseline="top",t.font="14px 'Arial'",t.textBaseline="alphabetic",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText(n,2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText(n,4,17),e.toDataURL()}};function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n").replace(/\[(\/?)b\]/g,"<$1b>").replace(/\[(\/?)i\]/g,"<$1i>").replace(/\[(\/?)s\]/g,"<$1del>").replace(/\[(\/?)u\]/g,"<$1u>").replace(/\[(\/?)sub\]/g,"<$1sub>").replace(/\[(\/?)sup\]/g,"<$1sup>").replace(/\[m=([#a-zA-Z0-9]+)\]/g,'').replace(/\[(\/?)m\]/g,"<$1m>").replace(/\[c=?([#a-zA-Z0-9]+)\]/g,'').replace(/\[\/c\]/g,"")}},{key:"handleMS",value:function(e){if(e[4]!=ve.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:this.prepChat(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;nt.scrollHeight-600&&(t.scrollTop=t.scrollHeight)}},{key:"handleMC",value:function(e){var t=ve.music;if(t.pause(),t.src=g+e[1].toLowerCase(),t.play(),e[2]>=0){var n=this.chars[e[2]].name;j("".concat(n," changed music to ").concat(e[1]))}else j("The music was changed to ".concat(e[1]))}},{key:"handleRMC",value:function(e){ve.music.pause(),ve.music=new Audio(this.musicList[e[1]]);var t=ve.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')}},{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 .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,ve.initTestimonyUpdater()}},{key:"handleZZ",value:function(e){var t=document.getElementById("client_ooclog");t.innerHTML+="$Alert: ".concat(pe(ge(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){f?this.serv.send("askchar2#%"):this.serv.send("RC#%")}},{key:"handleCharsCheck",value:function(e){var t;document.getElementById("client_chartable").innerHTML="";for(var n=0;n",t.appendChild(i),n%8==0&&document.getElementById("client_chartable").appendChild(t)}}},{key:"handlePV",value:function(e){this.charID=e[3],document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="";var t=this.me(),n=this.emotes,i=document.getElementById("client_emo");i.innerHTML="",i.style.display="";var o=new XMLHttpRequest;o.withCredentials=!1,o.open("GET",h+"characters/"+escape(this.me().name.toLowerCase())+"/char.ini",!0),o.responseType="text",o.onload=function(e){if(200==this.status){var o=this.responseText,c=b.parse(o);t.side=c.Options.side,K(t.side);for(var a=1;a<=c.Emotions.number;a++){var s=c.Emotions[a].split("#"),r="0",l="0";void 0!==c.SoundN&&(r=c.SoundN[a]),void 0!==c.SoundT&&(l=c.SoundT[a]),n[a]={desc:s[0].toLowerCase(),speaking:s[1].toLowerCase(),silent:s[2].toLowerCase(),zoom:s[3],sfx:r.toLowerCase(),sfxdelay:l,button_off:h+"characters/".concat(escape(t.name).toLowerCase(),"/emotions/button").concat(a,"_off.png"),button_on:h+"characters/".concat(escape(t.name).toLowerCase(),"/emotions/button").concat(a,"_on.png")},i.innerHTML+="').concat(n[a].desc,'')}U(1)}},o.send()}}]),e}(),I=function(){function e(){s(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(h+"sounds/general/sfx-blipmale.wav"),this.blip.volume=.5,this.blipChannels=new Array(6);for(var t=0;t0){var t="";1==ye.testimonyID?t="witnesstestimony":2==ye.testimonyID&&(t="crossexamination"),new Audio(ye.resources[t].sfx).play(),this.testimonyTimer=0;var n=document.getElementById("client_testimony");n.src=ye.resources[t].src,n.style.display="",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==ye.testimonyID?this.testimonyTimer>=ye.resources.witnesstestimony.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):2==ye.testimonyID?this.testimonyTimer>=ye.resources.crossexamination.duration?this.disposeTestimony():this.testimonyUpdater=setTimeout(function(){return e.updateTestimony()},60):this.disposeTestimony()}},{key:"disposeTestimony",value:function(){ye.testimonyID=0,this.testimonyTimer=0,document.getElementById("client_testimony").style.display="none",clearTimeout(this.testimonyUpdater)}},{key:"updateText",value:function(){var e=this,t=document.getElementById("client_name"),n=document.getElementById("client_chat"),i=document.getElementById("client_char"),o=document.getElementById("client_evi"),c=document.getElementById("client_background"),a=document.getElementById("client_shout"),s=document.getElementById("client_inner_chat");if(1==this.chatmsg.flip?i.style.transform="scaleX(-1)":i.style.transform="scaleX(1)",this._animating&&(this.updater=setTimeout(function(){return e.updateText()},60)),this.chatmsg.isnew){c.style.backgroundColor="transparent",t.style.display="none",n.style.display="none",o.style.opacity="0",o.style.height="0%";var r={1:"holdit",2:"objection",3:"takethat"}[this.chatmsg.objection];void 0!==r?(a.src=ye.resources[r].src,new Audio("".concat(h,"characters/").concat(this.chatmsg.name.toLowerCase(),"/").concat(r,".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=h+"sounds/general/sfx-stab.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("shake",{direction:"up"})):1==this.chatmsg.flash&&(c.style.backgroundColor="white",this.sfxaudio.pause(),this.sfxplayed=1,this.sfxaudio.src=h+"sounds/general/sfx-realization.wav",this.sfxaudio.play(),$("#client_gamewindow").effect("pulsate")),this.chatmsg.preanimdelay>0&&(a.src="misc/placeholder.gif",N(this.chatmsg.side),i.src=h+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.preanim.toLowerCase()+".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){for(this.chatmsg.evidence>0&&(o.style.backgroundImage="url('"+ye.evidences[this.chatmsg.evidence-1].icon+"')","def"==this.chatmsg.side?(o.style.right="1.5em",o.style.left="initial",$("#client_evi").animate({height:"30%",opacity:1},250)):(o.style.right="initial",o.style.left="1.5em",$("#client_evi").animate({height:"30%",opacity:1},250))),t.style.display="block",t.style.fontSize=.7*t.offsetHeight+"px";t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(this.chatmsg.nameplate)),n.style.display="block",n.style.fontSize=.25*n.offsetHeight+"px";s.style.color={0:"#ffffff",1:"#00ff00",2:"#ff0000",3:"#ffaa00",4:"#0000ff",5:"#ffff00",6:"#aa00aa"}[this.chatmsg.color]||"#ffffff",this.chatmsg.startspeaking=!1,0==this.chatmsg.preanimdelay&&(a.src="misc/placeholder.gif",N(this.chatmsg.side)),i.src=h+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.speaking.toLowerCase()+".gif",this.textnow==this.chatmsg.content&&(i.src=h+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.silent.toLowerCase()+".gif",this._animating=!1,clearTimeout(this.updater))}else if(this.textnow!=this.chatmsg.content){for(" "!=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);s.hasChildNodes();)s.removeChild(s.firstChild);s.appendChild(document.createTextNode(this.textnow)),this.textnow==this.chatmsg.content&&(this.textTimer=0,this._animating=!1,i.src=h+"characters/"+escape(this.chatmsg.name.toLowerCase())+"/"+this.chatmsg.silent.toLowerCase()+".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=h+"sounds/general/"+escape(this.chatmsg.sound.toLowerCase())+".wav",this.sfxaudio.play())),this.textTimer=this.textTimer+60}}]),e}(),b=function(){function e(){s(this,e)}return l(e,null,[{key:"parse",value:function(e){var t={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([\w.\-_]+)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},n={},i=e.split(/\r\n|\r|\n/),o=null;return i.forEach(function(e){if(!t.comment.test(e)&&0!=e.length)if(t.param.test(e)){var i=e.match(t.param);o?n[o][i[1]]=i[2]:n[i[1]]=i[2]}else if(t.section.test(e)){var c=e.match(t.section);n[c[1]]={},o=c[1]}}),n}}]),e}();function C(e){13==e.keyCode&&(ye.sendOOC(document.getElementById("client_oocinputbox").value),document.getElementById("client_oocinputbox").value="")}function B(e){if(13==e.keyCode){var t=ye.me(),n=ye.myEmote(),i=ye.myEvidence(),o=ye.flip?1:0,c=document.getElementById("textcolor").value,a="0",s="0";document.getElementById("sendsfx").checked&&(a=n.sfx,s=n.sfxdelay),ye.sendIC(n.speaking,t.name,n.silent,document.getElementById("client_inputbox").value,t.side,a,n.zoom,s,v,i,o,p,c)}}function k(e){var t=document.getElementById("client_musiclist").value;ye.sendMusicChange(t)}function x(e){var t=e.textContent;ye.sendMusicChange(t);var n=document.createElement("div");n.className="hrtext",n.textContent="switched to ".concat(e.textContent),document.getElementById("client_log").appendChild(n)}function T(){ve.music.volume=document.getElementById("client_mvolume").value/100}function S(){ve.sfxaudio.volume=document.getElementById("client_svolume").value/100}function L(){ve.setBlipVolume(document.getElementById("client_bvolume").value/100)}function O(e){ye.sendLeaveRoom(),document.getElementById("client_charselect").style.display="block",document.getElementById("client_emo").innerHTML=""}function M(e){return e.onerror="",e.src="misc/placeholder.gif",!0}function P(e){return e.onerror="",e.src="/misc/placeholder.png",!0}function D(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 N(e){var t,n=ve.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",D(n+"defensedesk.png",A,e),t="defense";break;case"pro":document.getElementById("client_court").src=n+"prosecutorempty.png",document.getElementById("client_bench").style.display="block",D(n+"defensedesk.png",A,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==ve.chatmsg.type&&(document.getElementById("client_bench").style.display="none",document.getElementById("client_court").src=h+"themes/default/"+t+"_speedlines.gif")}function A(e,t){var n=ve.bgFolder();document.getElementById("client_bench").src="def"==t?e?n+"defensedesk.png":n+"bancodefensa.png":e?n+"prosecutiondesk.png":n+"bancoacusacion.png"}function R(){ye.cleanup(),(ye=new w(u))&&(m="join",document.getElementById("client_error").style.display="none")}function H(){ye.joinServer()}function j(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"),o=document.createElement("span");if(o.id="iclog_name",o.appendChild(document.createTextNode(t)),i.appendChild(o),i.appendChild(document.createTextNode(e)),_.getMinutes()!==n.getMinutes()){var c=document.createElement("span");c.id="iclog_time",c.innerText=n.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"}),i.appendChild(c)}var a=document.getElementById("client_log");a.appendChild(i),a.scrollTop>a.scrollHeight-800&&(a.scrollTop=a.scrollHeight),_=new Date}function F(e){e<1e3?ye.sendCharacter(e):(document.getElementById("client_charselect").style.display="none",document.getElementById("client_inputbox").style.display="none",document.getElementById("client_emo").style.display="none")}function U(e){-1!=ye.selectedEmote&&(document.getElementById("emo_"+ye.selectedEmote).src=ye.myEmote().button_off),ye.selectedEmote=e,document.getElementById("emo_"+e).src=ye.myEmote().button_on}function Z(e){if(ye.selectedEvidence!==e){ye.selectedEvidence>0&&(document.getElementById("evi_"+ye.selectedEvidence).className="client_button"),document.getElementById("evi_"+e).className="client_button dark",ye.selectedEvidence=e,document.getElementById("evi_name").value=ye.evidences[e-1].name,document.getElementById("evi_desc").value=ye.evidences[e-1].desc;var t=W("evi_select",ye.evidences[e-1].filename);document.getElementById("evi_select").selectedIndex=t,0==t&&(document.getElementById("evi_filename").value=ye.evidences[e-1].filename),q(),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 z()}function X(){var e=document.getElementById("evi_select");ye.sendPE(document.getElementById("evi_name").value,document.getElementById("evi_desc").value,0==e.selectedIndex?document.getElementById("evi_filename").value:e.options[e.selectedIndex].text),z()}function G(){var e=document.getElementById("evi_select"),t=parseInt(ye.selectedEvidence)-1;ye.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),z()}function V(){var e=parseInt(ye.selectedEvidence)-1;ye.sendDE(e),z()}function z(){ye.selectedEvidence>0&&(document.getElementById("evi_"+ye.selectedEvidence).className="client_button"),ye.selectedEvidence=0,document.getElementById("evi_select").selectedIndex=0,q(),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 W(e,t){for(var n=document.getElementById(e),i=1;i").replace(/&/g,"").replace(/%/g,"").replace(/\$/g,"")}function ge(e){return e.replace(//g,"#").replace(//g,"&").replace(//g,"%").replace(//g,"$")}function fe(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),o=0,c=e.length;o>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\tk1 = (k1 << 15) | (k1 >>> 17);\r\n\t\t\tk1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\th1 ^= k1;\r\n\t\t\th1 = (h1 << 13) | (h1 >>> 19);\r\n\t\t\th1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\r\n\t\t\th1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\r\n\t\t}\r\n\t\tk1 = 0;\r\n\t\tswitch (remainder) {\r\n\t\t\tcase 3:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;\r\n\t\t\tcase 2:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;\r\n\t\t\tcase 1:\r\n\t\t\t\tk1 ^= (key.charCodeAt(i) & 0xff);\r\n\t\t\t\tk1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\r\n\t\t\t\tk1 = (k1 << 15) | (k1 >>> 17);\r\n\t\t\t\tk1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\r\n\t\t\t\th1 ^= k1;\r\n\t\t}\r\n\t\th1 ^= key.length;\r\n\t\th1 ^= h1 >>> 16;\r\n\t\th1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\r\n\t\th1 ^= h1 >>> 13;\r\n\t\th1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\r\n\t\th1 ^= h1 >>> 16;\r\n\t\treturn h1 >>> 0;\r\n\t},\r\n\thasLocalStorage: function() {\r\n\t\ttry {\r\n\t\t\treturn !!window.localStorage;\r\n\t\t} catch (e) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n\thasSessionStorage: function() {\r\n\t\ttry {\r\n\t\t\treturn !!window.sessionStorage;\r\n\t\t} catch (e) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n\tisCanvasSupported: function() {\r\n\t\tvar elem = document.createElement(\"canvas\");\r\n\t\treturn !!(elem.getContext && elem.getContext(\"2d\"));\r\n\t},\r\n\tisIE: function() {\r\n\t\tif (navigator.appName === \"Microsoft Internet Explorer\") {\r\n\t\t\treturn true;\r\n\t\t} else if (navigator.appName === \"Netscape\" && /Trident/.test(navigator.userAgent)) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\tgetPluginsString: function() {\r\n\t\tif (this.isIE() && this.ie_activex) {\r\n\t\t\treturn this.getIEPluginsString();\r\n\t\t} else {\r\n\t\t\treturn this.getRegularPluginsString();\r\n\t\t}\r\n\t},\r\n\tgetRegularPluginsString: function() {\r\n\t\treturn this.map(navigator.plugins, function(p) {\r\n\t\t\tvar mimeTypes = this.map(p, function(mt) {\r\n\t\t\t\treturn [mt.type, mt.suffixes].join(\"~\");\r\n\t\t\t}).join(\",\");\r\n\t\t\treturn [p.name, p.description, mimeTypes].join(\"::\");\r\n\t\t}, this).join(\";\");\r\n\t},\r\n\tgetIEPluginsString: function() {\r\n\t\tif (window.ActiveXObject) {\r\n\t\t\tvar names = [\"ShockwaveFlash.ShockwaveFlash\", \"AcroPDF.PDF\", \"PDF.PdfCtrl\", \"QuickTime.QuickTime\", \"rmocx.RealPlayer G2 Control\", \"rmocx.RealPlayer G2 Control.1\", \"RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)\", \"RealVideo.RealVideo(tm) ActiveX Control (32-bit)\", \"RealPlayer\", \"SWCtl.SWCtl\", \"WMPlayer.OCX\", \"AgControl.AgControl\", \"Skype.Detection\"];\r\n\t\t\treturn this.map(names, function(name) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tnew ActiveXObject(name);\r\n\t\t\t\t\treturn name;\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\treturn null;\r\n\t\t\t\t}\r\n\t\t\t}).join(\";\");\r\n\t\t} else {\r\n\t\t\treturn \"\";\r\n\t\t}\r\n\t},\r\n\tgetScreenResolution: function() {\r\n\t\tvar resolution;\r\n\t\tif (this.screen_orientation) {\r\n\t\t\tresolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];\r\n\t\t} else {\r\n\t\t\tresolution = [screen.height, screen.width];\r\n\t\t}\r\n\t\treturn resolution;\r\n\t},\r\n\tgetCanvasFingerprint: function() {\r\n\t\tvar canvas = document.createElement(\"canvas\");\r\n\t\tvar ctx = canvas.getContext(\"2d\");\r\n\t\tvar txt = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-={}|[]\\:\\\"<>?;,.\";\r\n\t\tctx.textBaseline = \"top\";\r\n\t\tctx.font = \"14px 'Arial'\";\r\n\t\tctx.textBaseline = \"alphabetic\";\r\n\t\tctx.fillStyle = \"#f60\";\r\n\t\tctx.fillRect(125, 1, 62, 20);\r\n\t\tctx.fillStyle = \"#069\";\r\n\t\tctx.fillText(txt, 2, 15);\r\n\t\tctx.fillStyle = \"rgba(102, 204, 0, 0.7)\";\r\n\t\tctx.fillText(txt, 4, 17);\r\n\t\treturn canvas.toDataURL();\r\n\t}\r\n};\r\n\r\n/**************************************************/\r\n\r\n/**\r\nhttp://www.darkwavetech.com/fingerprint/fingerprint_code.html\r\n**/\r\nfunction fingerprint_flash() {\r\n\t\"use strict\";\r\n\tvar strOnError, objPlayerVersion, strVersion, strOut;\r\n\r\n\tstrOnError = \"N/A\";\r\n\tobjPlayerVersion = null;\r\n\tstrVersion = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tobjPlayerVersion = swfobject.getFlashPlayerVersion();\r\n\t\tstrVersion = objPlayerVersion.major + \".\" + objPlayerVersion.minor + \".\" + objPlayerVersion.release;\r\n\t\tif (strVersion === \"0.0.0\") {\r\n\t\t\tstrVersion = \"N/A\";\r\n\t\t}\r\n\t\tstrOut = strVersion;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_browser() {\r\n\t\"use strict\";\r\n\tvar strOnError, strUserAgent, numVersion, strBrowser, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstrUserAgent = null;\r\n\tnumVersion = null;\r\n\tstrBrowser = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t\tif (/msie (\\d+\\.\\d+);/.test(strUserAgent)) { //test for MSIE x.x;\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tif (strUserAgent.indexOf(\"trident/6\") > -1) {\r\n\t\t\t\tnumVersion = 10;\r\n\t\t\t}\r\n\t\t\tif (strUserAgent.indexOf(\"trident/5\") > -1) {\r\n\t\t\t\tnumVersion = 9;\r\n\t\t\t}\r\n\t\t\tif (strUserAgent.indexOf(\"trident/4\") > -1) {\r\n\t\t\t\tnumVersion = 8;\r\n\t\t\t}\r\n\t\t\tstrBrowser = \"Internet Explorer \" + numVersion;\r\n\t\t} else if (strUserAgent.indexOf(\"trident/7\") > -1) { //IE 11+ gets rid of the legacy 'MSIE' in the user-agent string;\r\n\t\t\tnumVersion = 11;\r\n\t\t\tstrBrowser = \"Internet Explorer \" + numVersion;\r\n\t\t} else if (/firefox[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Firefox/x.x or Firefox x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Firefox \" + numVersion;\r\n\t\t} else if (/opera[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Opera/x.x or Opera x.x (ignoring remaining decimal places);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Opera \" + numVersion;\r\n\t\t} else if (/chrome[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Chrome/x.x or Chrome x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Chrome \" + numVersion;\r\n\t\t} else if (/version[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Version/x.x or Version x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Safari \" + numVersion;\r\n\t\t} else if (/rv[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for rv/x.x or rv x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Mozilla \" + numVersion;\r\n\t\t} else if (/mozilla[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Mozilla/x.x or Mozilla x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Mozilla \" + numVersion;\r\n\t\t} else if (/binget[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for BinGet/x.x or BinGet x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (BinGet) \" + numVersion;\r\n\t\t} else if (/curl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Curl/x.x or Curl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (cURL) \" + numVersion;\r\n\t\t} else if (/java[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Java/x.x or Java x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Java) \" + numVersion;\r\n\t\t} else if (/libwww-perl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for libwww-perl/x.x or libwww-perl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (libwww-perl) \" + numVersion;\r\n\t\t} else if (/microsoft url control -[\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Microsoft URL Control - x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Microsoft URL Control) \" + numVersion;\r\n\t\t} else if (/peach[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for Peach/x.x or Peach x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Peach) \" + numVersion;\r\n\t\t} else if (/php[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for PHP/x.x or PHP x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (PHP) \" + numVersion;\r\n\t\t} else if (/pxyscand[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for pxyscand/x.x or pxyscand x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (pxyscand) \" + numVersion;\r\n\t\t} else if (/pycurl[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for pycurl/x.x or pycurl x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (PycURL) \" + numVersion;\r\n\t\t} else if (/python-urllib[\\/\\s](\\d+\\.\\d+)/.test(strUserAgent)) { //test for python-urllib/x.x or python-urllib x.x (ignoring remaining digits);\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Library (Python URLlib) \" + numVersion;\r\n\t\t} else if (/appengine-google/.test(strUserAgent)) { //test for AppEngine-Google;\r\n\t\t\tnumVersion = Number(RegExp.$1); // capture x.x portion and store as a number\r\n\t\t\tstrBrowser = \"Cloud (Google AppEngine) \" + numVersion;\r\n\t\t} else {\r\n\t\t\tstrBrowser = \"Unknown\";\r\n\t\t}\r\n\t\tstrOut = strBrowser;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_canvas() {\r\n\t\"use strict\";\r\n\tvar strOnError, canvas, strCText, strText, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tcanvas = null;\r\n\tstrCText = null;\r\n\tstrText = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?\";\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tcanvas = document.createElement(\"canvas\");\r\n\t\tstrCText = canvas.getContext(\"2d\");\r\n\t\tstrCText.textBaseline = \"top\";\r\n\t\tstrCText.font = \"14px 'Arial'\";\r\n\t\tstrCText.textBaseline = \"alphabetic\";\r\n\t\tstrCText.fillStyle = \"#f60\";\r\n\t\tstrCText.fillRect(125, 1, 62, 20);\r\n\t\tstrCText.fillStyle = \"#069\";\r\n\t\tstrCText.fillText(strText, 2, 15);\r\n\t\tstrCText.fillStyle = \"rgba(102, 204, 0, 0.7)\";\r\n\t\tstrCText.fillText(strText, 4, 17);\r\n\t\tstrOut = canvas.toDataURL();\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_connection() {\r\n\t\"use strict\";\r\n\tvar strOnError, strConnection, strOut;\r\n\r\n\tstrOnError = \"N/A\";\r\n\tstrConnection = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\t// only on android\r\n\t\tstrConnection = navigator.connection.type;\r\n\t\tstrOut = strConnection;\r\n\t} catch (err) {\r\n\t\t// return N/A if navigator.connection object does not apply to this device\r\n\t\treturn strOnError;\r\n\t}\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_cookie() {\r\n\t\"use strict\";\r\n\tvar strOnError, bolCookieEnabled, bolOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tbolCookieEnabled = null;\r\n\tbolOut = null;\r\n\r\n\ttry {\r\n\t\tbolCookieEnabled = (navigator.cookieEnabled) ? true : false;\r\n\r\n\t\t//if not IE4+ nor NS6+\r\n\t\tif (typeof navigator.cookieEnabled === \"undefined\" && !bolCookieEnabled) {\r\n\t\t\tdocument.cookie = \"testcookie\";\r\n\t\t\tbolCookieEnabled = (document.cookie.indexOf(\"testcookie\") !== -1) ? true : false;\r\n\t\t}\r\n\t\tbolOut = bolCookieEnabled;\r\n\t\treturn bolOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_display() {\r\n\t\"use strict\";\r\n\tvar strSep, strPair, strOnError, strScreen, strDisplay, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrPair = \"=\";\r\n\tstrOnError = \"Error\";\r\n\tstrScreen = null;\r\n\tstrDisplay = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrScreen = window.screen;\r\n\t\tif (strScreen) {\r\n\t\t\tstrDisplay = strScreen.colorDepth + strSep + strScreen.width + strSep + strScreen.height + strSep + strScreen.availWidth + strSep + strScreen.availHeight;\r\n\t\t}\r\n\t\tstrOut = strDisplay;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_fontsmoothing() {\r\n\t\"use strict\";\r\n\tvar strOnError, strFontSmoothing, canvasNode, ctx, i, j, imageData, alpha, strOut;\r\n\r\n\tstrOnError = \"Unknown\";\r\n\tstrFontSmoothing = null;\r\n\tcanvasNode = null;\r\n\tctx = null;\r\n\timageData = null;\r\n\talpha = null;\r\n\tstrOut = null;\r\n\r\n\tif (typeof(screen.fontSmoothingEnabled) !== \"undefined\") {\r\n\t\tstrFontSmoothing = screen.fontSmoothingEnabled;\r\n\t} else {\r\n\t\ttry {\r\n\t\t\tfontsmoothing = \"false\";\r\n\t\t\tcanvasNode = document.createElement(\"canvas\");\r\n\t\t\tcanvasNode.width = \"35\";\r\n\t\t\tcanvasNode.height = \"35\";\r\n\t\t\tcanvasNode.style.display = \"none\";\r\n\t\t\tdocument.body.appendChild(canvasNode);\r\n\t\t\tctx = canvasNode.getContext(\"2d\");\r\n\t\t\tctx.textBaseline = \"top\";\r\n\t\t\tctx.font = \"32px Arial\";\r\n\t\t\tctx.fillStyle = \"black\";\r\n\t\t\tctx.strokeStyle = \"black\";\r\n\t\t\tctx.fillText(\"O\", 0, 0);\r\n\t\t\tfor (j = 8; j <= 32; j = j + 1) {\r\n\t\t\t\tfor (i = 1; i <= 32; i = i + 1) {\r\n\t\t\t\t\timageData = ctx.getImageData(i, j, 1, 1).data;\r\n\t\t\t\t\talpha = imageData[3];\r\n\t\t\t\t\tif (alpha !== 255 && alpha !== 0) {\r\n\t\t\t\t\t\tstrFontSmoothing = \"true\"; // font-smoothing must be on.\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tstrOut = strFontSmoothing;\r\n\t\t} catch (err) {\r\n\t\t\treturn strOnError;\r\n\t\t}\r\n\t}\r\n\tstrOut = strFontSmoothing;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_fonts() {\r\n\t\"use strict\";\r\n\tvar strOnError, style, fonts, count, template, fragment, divs, i, font, div, body, result, e;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstyle = null;\r\n\tfonts = null;\r\n\tfont = null;\r\n\tcount = 0;\r\n\ttemplate = null;\r\n\tdivs = null;\r\n\te = null;\r\n\tdiv = null;\r\n\tbody = null;\r\n\ti = 0;\r\n\r\n\ttry {\r\n\t\tstyle = \"position: absolute; visibility: hidden; display: block !important\";\r\n\t\tfonts = [\"8bitoperator\", \"Abadi MT Condensed Light\",\"Ace Attorney\", \"Adobe Fangsong Std\", \"Adobe Hebrew\", \"Adobe Ming Std\", \"Agency FB\", \"Aharoni\", \"Andalus\", \"Angsana New\", \"AngsanaUPC\", \"Aparajita\", \"Arab\", \"Arabic Transparent\", \"Arabic Typesetting\", \"Arial Baltic\", \"Arial Black\", \"Arial CE\", \"Arial CYR\", \"Arial Greek\", \"Arial TUR\", \"Arial\", \"Arimo\", \"Batang\", \"BatangChe\", \"Bauhaus 93\", \"Bell MT\", \"Berlin Sans FB\", \"Bitstream Vera Serif\", \"Bodoni MT\", \"Bookman Old Style\", \"Braggadocio\", \"Broadway\", \"Browallia New\", \"BrowalliaUPC\", \"Calibri Light\", \"Calibri\", \"Californian FB\", \"Cambria Math\", \"Cambria\", \"Candara\", \"Castellar\", \"Casual\", \"Centaur\", \"Century\", \"Century Gothic\", \"Chalkduster\", \"Colonna MT\", \"Comic Sans MS\", \"Consolas\", \"Constantia\", \"Copperplate Gothic Light\", \"Corbel\", \"Cordia New\", \"CordiaUPC\", \"Courier New Baltic\", \"Courier New CE\", \"Courier New CYR\", \"Courier New Greek\", \"Courier New TUR\", \"Courier New\", \"DejaVu Sans\", \"DFKai-SB\",\"DINEngschrift\", \"DaunPenh\", \"David\", \"DejaVu LGC Sans Mono\", \"Desdemona\", \"DilleniaUPC\", \"DokChampa\", \"Dotum\", \"DotumChe\", \"Dubai\", \"Ebrima\", \"Engravers MT\", \"Eras Bold ITC\", \"Estrangelo Edessa\", \"EucrosiaUPC\", \"Euphemia\", \"Eurostile\", \"FangSong\", \"Forte\", \"FrankRuehl\", \"Franklin Gothic Heavy\", \"Franklin Gothic Medium\", \"FreesiaUPC\", \"French Script MT\", \"Gabriola\", \"Gautami\", \"Georgia\", \"Gigi\", \"Gisha\", \"Goudy Old Style\", \"Gulim\", \"GulimChe\", \"GungSeo\", \"Gungsuh\", \"GungsuhChe\", \"Haettenschweiler\", \"Harrington\", \"Hei S\", \"HeiT\", \"Heisei Kaku Gothic\", \"Hiragino Sans GB\", \"Impact\", \"Informal Roman\", \"IrisUPC\", \"Iskoola Pota\", \"JasmineUPC\", \"KacstOne\", \"KaiTi\", \"Kalinga\", \"Kartika\", \"Khmer UI\", \"Kino MT\", \"KodchiangUPC\", \"Kokila\", \"Kozuka Gothic Pr6N\", \"Lao UI\", \"Latha\", \"Leelawadee\", \"Levenim MT\", \"LilyUPC\", \"Lohit Gujarati\", \"Loma\", \"Lucida Bright\", \"Lucida Console\", \"Lucida Fax\", \"Lucida Sans Unicode\", \"MS Gothic\", \"MS Mincho\", \"MS PGothic\", \"MS PMincho\", \"MS Reference Sans Serif\", \"MS UI Gothic\", \"MV Boli\", \"Magneto\", \"Malgun Gothic\", \"Mangal\", \"Marlett\", \"Matura MT Script Capitals\", \"Meiryo UI\", \"Meiryo\", \"Menlo\", \"Microsoft Himalaya\", \"Microsoft JhengHei\", \"Microsoft New Tai Lue\", \"Microsoft PhagsPa\", \"Microsoft Sans Serif\", \"Microsoft Tai Le\", \"Microsoft Uighur\", \"Microsoft YaHei\", \"Microsoft Yi Baiti\", \"MingLiU\", \"MingLiU-ExtB\", \"MingLiU_HKSCS\", \"MingLiU_HKSCS-ExtB\", \"Miriam Fixed\", \"Miriam\", \"Mongolian Baiti\", \"MoolBoran\", \"More Perfect DOS VGA\", \"MS Outlook\", \"NSimSun\", \"Narkisim\", \"News Gothic MT\", \"Niagara Solid\", \"Nyala\", \"OCR A\",\"Ocean Sans Std\", \"OpenSymbol\", \"PMingLiU\", \"PMingLiU-ExtB\", \"Palace Script MT\", \"Palatino Linotype\", \"Papyrus\", \"Perpetua\", \"Plantagenet Cherokee\", \"Playbill\", \"Prelude Bold\", \"Prelude Condensed Bold\", \"Prelude Condensed Medium\", \"Prelude Medium\", \"PreludeCompressedWGL Black\", \"PreludeCompressedWGL Bold\", \"PreludeCompressedWGL Light\", \"PreludeCompressedWGL Medium\", \"PreludeCondensedWGL Black\", \"PreludeCondensedWGL Bold\", \"PreludeCondensedWGL Light\", \"PreludeCondensedWGL Medium\", \"PreludeWGL Black\", \"PreludeWGL Bold\", \"PreludeWGL Light\", \"PreludeWGL Medium\", \"Raavi\", \"Rachana\", \"Rockwell\", \"Rod\", \"Sakkal Majalla\", \"Sawasdee\", \"Script MT Bold\", \"Segoe Print\", \"Segoe Script\", \"Segoe UI Emoji\", \"Segoe UI Historic\", \"Segoe UI Light\", \"Segoe UI Semibold\", \"Segoe UI Symbol\", \"Segoe UI\", \"Shonar Bangla\", \"Showcard Gothic\", \"Shruti\", \"SimHei\", \"SimSun\", \"SimSun-ExtB\", \"Simplified Arabic Fixed\", \"Simplified Arabic\", \"Snap ITC\", \"Sylfaen\", \"Symbol\", \"Tahoma\", \"TeamViewer13\", \"Times New Roman Baltic\", \"Times New Roman CE\", \"Times New Roman CYR\", \"Times New Roman Greek\", \"Times New Roman TUR\", \"Times New Roman\", \"TlwgMono\", \"Traditional Arabic\", \"Trebuchet MS\", \"Tunga\", \"Tw Cen MT Condensed Extra Bold\", \"Ubuntu\", \"Umpush\", \"Univers\", \"Utopia\", \"Utsaah\", \"Vani\", \"Verdana\", \"Vijaya\", \"Vladimir Script\", \"Vrinda\", \"Webdings\", \"Wide Latin\", \"Wingdings\", \"Yu Gothic\", \"Zrnic Rg\"];\r\n\t\tcount = fonts.length;\r\n\t\ttemplate = \"ww\" + \"ww\";\r\n\t\tfragment = document.createDocumentFragment();\r\n\t\tdivs = [];\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\tfont = fonts[i];\r\n\t\t\tdiv = document.createElement(\"div\");\r\n\t\t\tfont = font.replace(/['\"<>]/g, \"\");\r\n\t\t\tdiv.innerHTML = template.replace(/X/g, font);\r\n\t\t\tdiv.style.cssText = style;\r\n\t\t\tfragment.appendChild(div);\r\n\t\t\tdivs.push(div);\r\n\t\t}\r\n\t\tbody = document.body;\r\n\t\tbody.insertBefore(fragment, body.firstChild);\r\n\t\tresult = [];\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\te = divs[i].getElementsByTagName(\"b\");\r\n\t\t\tif (e[0].offsetWidth === e[1].offsetWidth) {\r\n\t\t\t\tresult.push(fonts[i]);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// do not combine these two loops, remove child will cause reflow\r\n\t\t// and induce severe performance hit\r\n\t\tfor (i = 0; i < count; i = i + 1) {\r\n\t\t\tbody.removeChild(divs[i]);\r\n\t\t}\r\n\t\treturn result.join(\"|\");\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_formfields() {\r\n\t\"use strict\";\r\n\tvar i, j, numOfForms, numOfInputs, strFormsInPage, strFormsInputsData, strInputsInForm, strTmp, strOut;\r\n\r\n\ti = 0;\r\n\tj = 0;\r\n\tnumOfForms = 0;\r\n\tnumOfInputs = 0;\r\n\tstrFormsInPage = \"\";\r\n\tstrFormsInputsData = [];\r\n\tstrInputsInForm = \"\";\r\n\tstrTmp = \"\";\r\n\tstrOut = \"\";\r\n\r\n\tstrFormsInPage = document.getElementsByTagName(\"form\");\r\n\tnumOfForms = strFormsInPage.length;\r\n\tstrFormsInputsData.push(\"url=\" + window.location.href);\r\n\tfor (i = 0; i < numOfForms; i = i + 1) {\r\n\t\tstrFormsInputsData.push(\"FORM=\" + strFormsInPage[i].name);\r\n\t\tstrInputsInForm = strFormsInPage[i].getElementsByTagName(\"input\");\r\n\t\tnumOfInputs = strInputsInForm.length;\r\n\t\tfor (j = 0; j < numOfInputs; j = j + 1) {\r\n\t\t\tif (strInputsInForm[j].type !== \"hidden\") {\r\n\t\t\t\tstrFormsInputsData.push(\"Input=\" + strInputsInForm[j].name);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tstrTmp = strFormsInputsData.join(\"|\");\r\n\tstrOut = strTmp;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_java() {\r\n\t\"use strict\";\r\n\tvar strOnError, strJavaEnabled, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tstrJavaEnabled = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tif (navigator.javaEnabled()) {\r\n\t\t\tstrJavaEnabled = \"true\";\r\n\t\t} else {\r\n\t\t\tstrJavaEnabled = \"false\";\r\n\t\t}\r\n\t\tstrOut = strJavaEnabled;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_language() {\r\n\t\"use strict\";\r\n\tvar strSep, strPair, strOnError, strLang, strTypeLng, strTypeBrLng, strTypeSysLng, strTypeUsrLng, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrPair = \"=\";\r\n\tstrOnError = \"Error\";\r\n\tstrLang = null;\r\n\tstrTypeLng = null;\r\n\tstrTypeBrLng = null;\r\n\tstrTypeSysLng = null;\r\n\tstrTypeUsrLng = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\tstrTypeLng = typeof(navigator.language);\r\n\t\tstrTypeBrLng = typeof(navigator.browserLanguage);\r\n\t\tstrTypeSysLng = typeof(navigator.systemLanguage);\r\n\t\tstrTypeUsrLng = typeof(navigator.userLanguage);\r\n\r\n\t\tif (strTypeLng !== \"undefined\") {\r\n\t\t\tstrLang = \"lang\" + strPair + navigator.language + strSep;\r\n\t\t} else if (strTypeBrLng !== \"undefined\") {\r\n\t\t\tstrLang = \"lang\" + strPair + navigator.browserLanguage + strSep;\r\n\t\t} else {\r\n\t\t\tstrLang = \"lang\" + strPair + strSep;\r\n\t\t}\r\n\t\tif (strTypeSysLng !== \"undefined\") {\r\n\t\t\tstrLang += \"syslang\" + strPair + navigator.systemLanguage + strSep;\r\n\t\t} else {\r\n\t\t\tstrLang += \"syslang\" + strPair + strSep;\r\n\t\t}\r\n\t\tif (strTypeUsrLng !== \"undefined\") {\r\n\t\t\tstrLang += \"userlang\" + strPair + navigator.userLanguage;\r\n\t\t} else {\r\n\t\t\tstrLang += \"userlang\" + strPair;\r\n\t\t}\r\n\t\tstrOut = strLang;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_silverlight() {\r\n\t\"use strict\";\r\n\tvar strOnError, objControl, objPlugin, strSilverlightVersion, strOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tobjControl = null;\r\n\tobjPlugin = null;\r\n\tstrSilverlightVersion = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\ttry {\r\n\t\t\tobjControl = new ActiveXObject(\"AgControl.AgControl\");\r\n\t\t\tif (objControl.IsVersionSupported(\"5.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"5.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"4.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"4.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"3.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"3.x\";\r\n\t\t\t} else if (objControl.IsVersionSupported(\"2.0\")) {\r\n\t\t\t\tstrSilverlightVersion = \"2.x\";\r\n\t\t\t} else {\r\n\t\t\t\tstrSilverlightVersion = \"1.x\";\r\n\t\t\t}\r\n\t\t\tobjControl = null;\r\n\t\t} catch (e) {\r\n\t\t\tobjPlugin = navigator.plugins[\"Silverlight Plug-In\"];\r\n\t\t\tif (objPlugin) {\r\n\t\t\t\tif (objPlugin.description === \"1.0.30226.2\") {\r\n\t\t\t\t\tstrSilverlightVersion = \"2.x\";\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrSilverlightVersion = parseInt(objPlugin.description[0], 10);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tstrSilverlightVersion = \"N/A\";\r\n\t\t\t}\r\n\t\t}\r\n\t\tstrOut = strSilverlightVersion;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_os() {\r\n\t\"use strict\";\r\n\tvar strSep, strOnError, strUserAgent, strPlatform, strOS, strOSBits, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrOnError = \"Error\";\r\n\tstrUserAgent = null;\r\n\tstrPlatform = null;\r\n\tstrOS = null;\r\n\tstrOSBits = null;\r\n\tstrOut = null;\r\n\r\n\ttry {\r\n\t\t/* navigator.userAgent is supported by all major browsers */\r\n\t\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t\t/* navigator.platform is supported by all major browsers */\r\n\t\tstrPlatform = navigator.platform.toLowerCase();\r\n\t\tif (strUserAgent.indexOf(\"windows nt 6.3\") !== -1) {\r\n\t\t\tstrOS = \"Windows 8.1\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.2\") !== -1) {\r\n\t\t\tstrOS = \"Windows 8\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.1\") !== -1) {\r\n\t\t\tstrOS = \"Windows 7\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 10.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows 10\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 6.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows Vista/Windows Server 2008\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.2\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP x64/Windows Server 2003\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.1\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.01\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000, Service Pack 1 (SP1)\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows xp\") !== -1) {\r\n\t\t\tstrOS = \"Windows XP\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows 2000\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows nt 5.0\") !== -1) {\r\n\t\t\tstrOS = \"Windows 2000\";\r\n\t\t} else if (strUserAgent.indexOf(\"iemobile\") !== -1) {\r\n\t\t\tstrOS = \"Windows Mobile\";\r\n\t\t} else if (strUserAgent.indexOf(\"wm5 pie\") !== -1) {\r\n\t\t\tstrOS = \"Windows Mobile\";\r\n\t\t} else if (strUserAgent.indexOf(\"windows\") !== -1) {\r\n\t\t\tstrOS = \"Windows (Unknown Version)\";\r\n\t\t} else if (strUserAgent.indexOf(\"openbsd\") !== -1) {\r\n\t\t\tstrOS = \"Open BSD\";\r\n\t\t} else if (strUserAgent.indexOf(\"sunos\") !== -1) {\r\n\t\t\tstrOS = \"Sun OS\";\r\n\t\t} else if (strUserAgent.indexOf(\"ubuntu\") !== -1) {\r\n\t\t\tstrOS = \"Ubuntu\";\r\n\t\t} else if (strUserAgent.indexOf(\"ipad\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iPad)\";\r\n\t\t} else if (strUserAgent.indexOf(\"ipod\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iTouch)\";\r\n\t\t} else if (strUserAgent.indexOf(\"iphone\") !== -1) {\r\n\t\t\tstrOS = \"iOS (iPhone)\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x beta\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Beta (Kodiak)\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.0\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Cheetah\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.1\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Puma\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.2\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Jaguar\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.3\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Panther\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.4\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Tiger\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.5\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Leopard\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.6\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Snow Leopard\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x 10.7\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX Lion\";\r\n\t\t} else if (strUserAgent.indexOf(\"mac os x\") !== -1) {\r\n\t\t\tstrOS = \"Mac OSX (Version Unknown)\";\r\n\t\t} else if (strUserAgent.indexOf(\"macintosh\") !== -1) {\r\n\t\t\tstrOS = \"Mac OS Classic\";\r\n\t\t} else if (strUserAgent.indexOf(\"googletv\") !== -1) {\r\n\t\t\tstrOS = \"Android (GoogleTV)\";\r\n\t\t} else if (strUserAgent.indexOf(\"android\") !== -1) {\r\n\t\t\tstrOS = \"Android\";\r\n\t\t} else if (strUserAgent.indexOf(\"x11\") !== -1) {\r\n\t\t\tstrOS = \"UNIX\";\r\n\t\t} else if (strUserAgent.indexOf(\"nix\") !== -1) {\r\n\t\t\tstrOS = \"UNIX\";\r\n\t\t} else if (strUserAgent.indexOf(\"linux\") !== -1) {\r\n\t\t\tstrOS = \"Linux\";\r\n\t\t} else if (strUserAgent.indexOf(\"qnx\") !== -1) {\r\n\t\t\tstrOS = \"QNX\";\r\n\t\t} else if (strUserAgent.indexOf(\"os/2\") !== -1) {\r\n\t\t\tstrOS = \"IBM OS/2\";\r\n\t\t} else if (strUserAgent.indexOf(\"beos\") !== -1) {\r\n\t\t\tstrOS = \"BeOS\";\r\n\t\t} else if (strUserAgent.indexOf(\"playbook\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry (Playbook)\";\r\n\t\t} else if (strUserAgent.indexOf(\"wnd.rim\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry (IE/FF Emulator)\";\r\n\t\t} else if (strUserAgent.indexOf(\"blackberry\") !== -1) {\r\n\t\t\tstrOS = \"Blackberry\";\r\n\t\t} else if (strUserAgent.indexOf(\"palm\") !== -1) {\r\n\t\t\tstrOS = \"Palm OS\";\r\n\t\t} else if (strUserAgent.indexOf(\"webos\") !== -1) {\r\n\t\t\tstrOS = \"WebOS\";\r\n\t\t} else if (strUserAgent.indexOf(\"hpwos\") !== -1) {\r\n\t\t\tstrOS = \"WebOS (HP)\";\r\n\t\t} else if (strUserAgent.indexOf(\"kindle\") !== -1) {\r\n\t\t\tstrOS = \"Kindle\";\r\n\t\t} else if (strUserAgent.indexOf(\"wii\") !== -1) {\r\n\t\t\tstrOS = \"Nintendo (Wii)\";\r\n\t\t} else if (strUserAgent.indexOf(\"nintendo ds\") !== -1) {\r\n\t\t\tstrOS = \"Nintendo (DS)\";\r\n\t\t} else if (strUserAgent.indexOf(\"playstation 3\") !== -1) {\r\n\t\t\tstrOS = \"Sony (Playstation Console)\";\r\n\t\t} else if (strUserAgent.indexOf(\"playstation portable\") !== -1) {\r\n\t\t\tstrOS = \"Sony (Playstation Portable)\";\r\n\t\t} else if (strUserAgent.indexOf(\"webtv\") !== -1) {\r\n\t\t\tstrOS = \"MSN TV (WebTV)\";\r\n\t\t} else if (strUserAgent.indexOf(\"inferno\") !== -1) {\r\n\t\t\tstrOS = \"Inferno\";\r\n\t\t} else {\r\n\t\t\tstrOS = \"Unknown\";\r\n\t\t}\r\n\t\tif (strPlatform.indexOf(\"x64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"wow64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"win64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"win32\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x64\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x32\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"x86\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits*\";\r\n\t\t} else if (strPlatform.indexOf(\"ppc\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"alpha\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"68k\") !== -1) {\r\n\t\t\tstrOSBits = \"64 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"iphone\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else if (strPlatform.indexOf(\"android\") !== -1) {\r\n\t\t\tstrOSBits = \"32 bits\";\r\n\t\t} else {\r\n\t\t\tstrOSBits = \"Unknown\";\r\n\t\t}\r\n\t\tstrOut = strOS + strSep + strOSBits;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_useragent() {\r\n\t\"use strict\";\r\n\tvar strSep, strTmp, strUserAgent, strOut;\r\n\r\n\tstrSep = \"|\";\r\n\tstrTmp = null;\r\n\tstrUserAgent = null;\r\n\tstrOut = null;\r\n\r\n\t/* navigator.userAgent is supported by all major browsers */\r\n\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\t/* navigator.platform is supported by all major browsers */\r\n\tstrTmp = strUserAgent + strSep + navigator.platform;\r\n\t/* navigator.cpuClass only supported in IE */\r\n\tif (navigator.cpuClass) {\r\n\t\tstrTmp += strSep + navigator.cpuClass;\r\n\t}\r\n\t/* navigator.browserLanguage only supported in IE, Safari and Chrome */\r\n\tif (navigator.browserLanguage) {\r\n\t\tstrTmp += strSep + navigator.browserLanguage;\r\n\t} else {\r\n\t\tstrTmp += strSep + navigator.language;\r\n\t}\r\n\tstrOut = strTmp;\r\n\treturn strOut;\r\n}\r\n\r\nfunction fingerprint_timezone() {\r\n\t\"use strict\";\r\n\tvar strOnError, dtDate, numOffset, numGMTHours, numOut;\r\n\r\n\tstrOnError = \"Error\";\r\n\tdtDate = null;\r\n\tnumOffset = null;\r\n\tnumGMTHours = null;\r\n\tnumOut = null;\r\n\r\n\ttry {\r\n\t\tdtDate = new Date();\r\n\t\tnumOffset = dtDate.getTimezoneOffset();\r\n\t\tnumGMTHours = (numOffset / 60) * (-1);\r\n\t\tnumOut = numGMTHours;\r\n\t\treturn numOut;\r\n\t} catch (err) {\r\n\t\treturn strOnError;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_touch() {\r\n\t\"use strict\";\r\n\tvar bolTouchEnabled, bolOut;\r\n\r\n\tbolTouchEnabled = false;\r\n\tbolOut = null;\r\n\r\n\ttry {\r\n\t\tif (document.createEvent(\"TouchEvent\")) {\r\n\t\t\tbolTouchEnabled = true;\r\n\t\t}\r\n\t\tbolOut = bolTouchEnabled;\r\n\t\treturn bolOut;\r\n\t} catch (ignore) {\r\n\t\tbolOut = bolTouchEnabled\r\n\t\treturn bolOut;\r\n\t}\r\n}\r\n\r\nfunction fingerprint_truebrowser() {\r\n\t\"use strict\";\r\n\tvar strBrowser, strUserAgent, strOut;\r\n\r\n\tstrBrowser = \"Unknown\";\r\n\tstrUserAgent = null;\r\n\tstrOut = null;\r\n\r\n\tstrUserAgent = navigator.userAgent.toLowerCase();\r\n\r\n\t/* Checks for different browsers, cannot use Try/Catch block */\r\n\tif (document.all && document.getElementById && navigator.savePreferences && (strUserAgent.indexOf(\"Netfront\") < 0) && navigator.appName !== \"Blazer\") {\r\n\t\tstrBrowser = \"Escape 5\";\r\n\t} else if (navigator.vendor === \"KDE\") {\r\n\t\tstrBrowser = \"Konqueror\";\r\n\t} else if (document.childNodes && !document.all && !navigator.taintEnabled && !navigator.accentColorName) {\r\n\t\tstrBrowser = \"Safari\";\r\n\t} else if (document.childNodes && !document.all && !navigator.taintEnabled && navigator.accentColorName) {\r\n\t\tstrBrowser = \"OmniWeb 4.5+\";\r\n\t} else if (navigator.__ice_version) {\r\n\t\tstrBrowser = \"ICEBrowser\";\r\n\t} else if (window.ScriptEngine && ScriptEngine().indexOf(\"InScript\") + 1 && document.createElement) {\r\n\t\tstrBrowser = \"iCab 3+\";\r\n\t} else if (window.ScriptEngine && ScriptEngine().indexOf(\"InScript\") + 1) {\r\n\t\tstrBrowser = \"iCab 2-\";\r\n\t} else if (strUserAgent.indexOf(\"hotjava\") + 1 && (navigator.accentColorName) === \"undefined\") {\r\n\t\tstrBrowser = \"HotJava\";\r\n\t} else if (document.layers && !document.classes) {\r\n\t\tstrBrowser = \"Omniweb 4.2-\";\r\n\t} else if (document.layers && !navigator.mimeTypes[\"*\"]) {\r\n\t\tstrBrowser = \"Escape 4\";\r\n\t} else if (document.layers) {\r\n\t\tstrBrowser = \"Netscape 4\";\r\n\t} else if (window.opera && document.getElementsByClassName) {\r\n\t\tstrBrowser = \"Opera 9.5+\";\r\n\t} else if (window.opera && window.getComputedStyle) {\r\n\t\tstrBrowser = \"Opera 8\";\r\n\t} else if (window.opera && document.childNodes) {\r\n\t\tstrBrowser = \"Opera 7\";\r\n\t} else if (window.opera) {\r\n\t\tstrBrowser = \"Opera \" + window.opera.version();\r\n\t} else if (navigator.appName.indexOf(\"WebTV\") + 1) {\r\n\t\tstrBrowser = \"WebTV\";\r\n\t} else if (strUserAgent.indexOf(\"netgem\") + 1) {\r\n\t\tstrBrowser = \"Netgem NetBox\";\r\n\t} else if (strUserAgent.indexOf(\"opentv\") + 1) {\r\n\t\tstrBrowser = \"OpenTV\";\r\n\t} else if (strUserAgent.indexOf(\"ipanel\") + 1) {\r\n\t\tstrBrowser = \"iPanel MicroBrowser\";\r\n\t} else if (document.getElementById && !document.childNodes) {\r\n\t\tstrBrowser = \"Clue browser\";\r\n\t} else if (navigator.product && navigator.product.indexOf(\"Hv\") === 0) {\r\n\t\tstrBrowser = \"Tkhtml Hv3+\";\r\n\t} else if (typeof InstallTrigger !== \"undefined\") {\r\n\t\tstrBrowser = \"Firefox\";\r\n\t} else if (window.atob) {\r\n\t\tstrBrowser = \"Internet Explorer 10+\";\r\n\t} else if (XDomainRequest && window.performance) {\r\n\t\tstrBrowser = \"Internet Explorer 9\";\r\n\t} else if (XDomainRequest) {\r\n\t\tstrBrowser = \"Internet Explorer 8\";\r\n\t} else if (document.documentElement && document.documentElement.style.maxHeight !== \"undefined\") {\r\n\t\tstrBrowser = \"Internet Explorer 7\"; //xxxxx\r\n\t} else if (document.compatMode && document.all) {\r\n\t\tstrBrowser = \"Internet Explorer 6\"; //xxxxx\r\n\t} else if (window.createPopup) {\r\n\t\tstrBrowser = \"Internet Explorer 5.5\";\r\n\t} else if (window.attachEvent) {\r\n\t\tstrBrowser = \"Internet Explorer 5\";\r\n\t} else if (document.all && navigator.appName !== \"Microsoft Pocket Internet Explorer\") {\r\n\t\tstrBrowser = \"Internet Explorer 4\";\r\n\t} else if ((strUserAgent.indexOf(\"msie\") + 1) && window.ActiveXObject) {\r\n\t\tstrBrowser = \"Pocket Internet Explorer\";\r\n\t} else if (document.getElementById && ((strUserAgent.indexOf(\"netfront\") + 1) || navigator.appName === \"Blazer\" || navigator.product === \"Gecko\" || (navigator.appName.indexOf(\"PSP\") + 1) || (navigator.appName.indexOf(\"PLAYSTATION 3\") + 1))) {\r\n\t\tstrBrowser = \"NetFront 3+\";\r\n\t} else if (navigator.product === \"Gecko\" && !navigator.savePreferences) {\r\n\t\tstrBrowser = \"Gecko engine (Mozilla, Netscape 6+ etc.)\";\r\n\t} else if (window.chrome) {\r\n\t\tstrBrowser = \"Chrome\";\r\n\t}\r\n\tstrOut = strBrowser;\r\n\treturn strOut;\r\n}\r\n\r\nvar glbOnError = \"N/A\"\r\nvar glbSep = \"|\";\r\n\r\nfunction activeXDetect(componentClassID) {\r\n\t\"use strict\";\r\n\tvar strComponentVersion, strOut;\r\n\r\n\tstrComponentVersion = \"\";\r\n\tstrOut = \"\";\r\n\r\n\ttry {\r\n\t\tstrComponentVersion = document.body.getComponentVersion(\"{\" + componentClassID + \"}\", \"ComponentID\");\r\n\t\tif (strComponentVersion !== null) {\r\n\t\t\tstrOut = strComponentVersion;\r\n\t\t} else {\r\n\t\t\tstrOut = false;\r\n\t\t}\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}\r\n\r\nfunction stripIllegalChars(strValue) {\r\n\t\"use strict\";\r\n\tvar iCounter, strOriginal, strOut;\r\n\r\n\tiCounter = 0;\r\n\tstrOriginal = \"\";\r\n\tstrOut = \"\";\r\n\r\n\ttry {\r\n\t\tstrOriginal = strValue.toLowerCase();\r\n\t\tfor (iCounter = 0; iCounter < strOriginal.length; iCounter = iCounter + 1) {\r\n\t\t\tif (strOriginal.charAt(iCounter) !== \"\\n\" && strOriginal.charAt(iCounter) !== \"/\" && strOriginal.charAt(iCounter) !== \"\\\\\") {\r\n\t\t\t\tstrOut = strOut + strOriginal.charAt(iCounter);\r\n\t\t\t} else if (strOriginal.charAt(iCounter) === \"\\n\") {\r\n\t\t\t\tstrOut = strOut + \"n\";\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}\r\n\r\nfunction hashtable_containsKey(key) {\r\n\t\"use strict\";\r\n\tvar bolExists, iCounter;\r\n\r\n\tbolExists = false;\r\n\tiCounter = 0;\r\n\r\n\tfor (iCounter = 0; iCounter < this.hashtable.length; iCounter = iCounter + 1) {\r\n\t\tif (iCounter === key && this.hashtable[iCounter] !== null) {\r\n\t\t\tbolExists = true;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn bolExists;\r\n}\r\n\r\nfunction hashtable_get(key) {\r\n\t\"use strict\";\r\n\treturn this.hashtable[key];\r\n}\r\n\r\nfunction hashtable_keys() {\r\n\t\"use strict\";\r\n\tvar keys, iCounter;\r\n\r\n\tkeys = [];\r\n\tiCounter = 0;\r\n\r\n\tfor (iCounter in this.hashtable) {\r\n\t\tif (this.hashtable[iCounter] !== null) {\r\n\t\t\tkeys.push(iCounter);\r\n\t\t}\r\n\t}\r\n\treturn keys;\r\n}\r\n\r\nfunction hashtable_put(key, value) {\r\n\t\"use strict\";\r\n\tif (key === null || value === null) {\r\n\t\tthrow \"NullPointerException {\" + key + \"},{\" + value + \"}\";\r\n\t}\r\n\tthis.hashtable[key] = value;\r\n}\r\n\r\nfunction hashtable_size() {\r\n\t\"use strict\";\r\n\tvar iSize, iCounter, iOut;\r\n\r\n\tiSize = 0;\r\n\tiCounter = 0;\r\n\tiOut = 0;\r\n\r\n\tfor (iCounter in this.hashtable) {\r\n\t\tif (this.hashtable[iCounter] !== null) {\r\n\t\t\tiSize = iSize + 1;\r\n\t\t}\r\n\t}\r\n\tiOut = iSize;\r\n\treturn iOut;\r\n}\r\n\r\nfunction Hashtable() {\r\n\t\"use strict\";\r\n\tthis.containsKey = hashtable_containsKey;\r\n\tthis.get = hashtable_get;\r\n\tthis.keys = hashtable_keys;\r\n\tthis.put = hashtable_put;\r\n\tthis.size = hashtable_size;\r\n\tthis.hashtable = [];\r\n}\r\n\r\n/* Detect Plugins */\r\nfunction fingerprint_plugins() {\r\n\t\"use strict\";\r\n\tvar htIEComponents, strKey, strName, strVersion, strTemp, bolFirst, iCount, strMimeType, strOut;\r\n\r\n\ttry {\r\n\t\t/* Create hashtable of IE components */\r\n\t\thtIEComponents = new Hashtable();\r\n\t\thtIEComponents.put(\"7790769C-0471-11D2-AF11-00C04FA35D02\", \"AddressBook\"); // Address Book\r\n\t\thtIEComponents.put(\"47F67D00-9E55-11D1-BAEF-00C04FC2D130\", \"AolArtFormat\"); // AOL ART Image Format Support\r\n\t\thtIEComponents.put(\"76C19B38-F0C8-11CF-87CC-0020AFEECF20\", \"ArabicDS\"); // Arabic Text Display Support\r\n\t\thtIEComponents.put(\"76C19B34-F0C8-11CF-87CC-0020AFEECF20\", \"ChineseSDS\"); // Chinese (Simplified) Text Display Support\r\n\t\thtIEComponents.put(\"76C19B33-F0C8-11CF-87CC-0020AFEECF20\", \"ChineseTDS\"); // Chinese (traditional) Text Display Support\r\n\t\thtIEComponents.put(\"238F6F83-B8B4-11CF-8771-00A024541EE3\", \"CitrixICA\"); // Citrix ICA Client\r\n\t\thtIEComponents.put(\"283807B5-2C60-11D0-A31D-00AA00B92C03\", \"DirectAnim\"); // DirectAnimation\r\n\t\thtIEComponents.put(\"44BBA848-CC51-11CF-AAFA-00AA00B6015C\", \"DirectShow\"); // DirectShow\r\n\t\thtIEComponents.put(\"9381D8F2-0288-11D0-9501-00AA00B911A5\", \"DynHTML\"); // Dynamic HTML Data Binding\r\n\t\thtIEComponents.put(\"4F216970-C90C-11D1-B5C7-0000F8051515\", \"DynHTML4Java\"); // Dynamic HTML Data Binding for Java\r\n\t\thtIEComponents.put(\"D27CDB6E-AE6D-11CF-96B8-444553540000\", \"Flash\"); // Macromedia Flash\r\n\t\thtIEComponents.put(\"76C19B36-F0C8-11CF-87CC-0020AFEECF20\", \"HebrewDS\"); // Hebrew Text Display Support\r\n\t\thtIEComponents.put(\"630B1DA0-B465-11D1-9948-00C04F98BBC9\", \"IEBrwEnh\"); // Internet Explorer Browsing Enhancements\r\n\t\thtIEComponents.put(\"08B0E5C0-4FCB-11CF-AAA5-00401C608555\", \"IEClass4Java\"); // Internet Explorer Classes for Java\r\n\t\thtIEComponents.put(\"45EA75A0-A269-11D1-B5BF-0000F8051515\", \"IEHelp\"); // Internet Explorer Help\r\n\t\thtIEComponents.put(\"DE5AED00-A4BF-11D1-9948-00C04F98BBC9\", \"IEHelpEng\"); // Internet Explorer Help Engine\r\n\t\thtIEComponents.put(\"89820200-ECBD-11CF-8B85-00AA005B4383\", \"IE5WebBrw\"); // Internet Explorer 5/6 Web Browser\r\n\t\thtIEComponents.put(\"5A8D6EE0-3E18-11D0-821E-444553540000\", \"InetConnectionWiz\"); // Internet Connection Wizard\r\n\t\thtIEComponents.put(\"76C19B30-F0C8-11CF-87CC-0020AFEECF20\", \"JapaneseDS\"); // Japanese Text Display Support\r\n\t\thtIEComponents.put(\"76C19B31-F0C8-11CF-87CC-0020AFEECF20\", \"KoreanDS\"); // Korean Text Display Support\r\n\t\thtIEComponents.put(\"76C19B50-F0C8-11CF-87CC-0020AFEECF20\", \"LanguageAS\"); // Language Auto-Selection\r\n\t\thtIEComponents.put(\"08B0E5C0-4FCB-11CF-AAA5-00401C608500\", \"MsftVM\"); // Microsoft virtual machine\r\n\t\thtIEComponents.put(\"5945C046-LE7D-LLDL-BC44-00C04FD912BE\", \"MSNMessengerSrv\"); // MSN Messenger Service\r\n\t\thtIEComponents.put(\"44BBA842-CC51-11CF-AAFA-00AA00B6015B\", \"NetMeetingNT\"); // NetMeeting NT\r\n\t\thtIEComponents.put(\"3AF36230-A269-11D1-B5BF-0000F8051515\", \"OfflineBrwPack\"); // Offline Browsing Pack\r\n\t\thtIEComponents.put(\"44BBA840-CC51-11CF-AAFA-00AA00B6015C\", \"OutlookExpress\"); // Outlook Express\r\n\t\thtIEComponents.put(\"76C19B32-F0C8-11CF-87CC-0020AFEECF20\", \"PanEuropeanDS\"); // Pan-European Text Display Support\r\n\t\thtIEComponents.put(\"4063BE15-3B08-470D-A0D5-B37161CFFD69\", \"QuickTime\"); // Apple Quick Time\r\n\t\thtIEComponents.put(\"DE4AF3B0-F4D4-11D3-B41A-0050DA2E6C21\", \"QuickTimeCheck\"); // Apple Quick Time Check\r\n\t\thtIEComponents.put(\"3049C3E9-B461-4BC5-8870-4C09146192CA\", \"RealPlayer\"); // RealPlayer Download and Record Plugin for IE\r\n\t\thtIEComponents.put(\"2A202491-F00D-11CF-87CC-0020AFEECF20\", \"ShockwaveDir\"); // Macromedia Shockwave Director\r\n\t\thtIEComponents.put(\"3E01D8E0-A72B-4C9F-99BD-8A6E7B97A48D\", \"Skype\"); // Skype\r\n\t\thtIEComponents.put(\"CC2A9BA0-3BDD-11D0-821E-444553540000\", \"TaskScheduler\"); // Task Scheduler\r\n\t\thtIEComponents.put(\"76C19B35-F0C8-11CF-87CC-0020AFEECF20\", \"ThaiDS\"); // Thai Text Display Support\r\n\t\thtIEComponents.put(\"3BF42070-B3B1-11D1-B5C5-0000F8051515\", \"Uniscribe\"); // Uniscribe\r\n\t\thtIEComponents.put(\"4F645220-306D-11D2-995D-00C04F98BBC9\", \"VBScripting\"); // Visual Basic Scripting Support v5.6\r\n\t\thtIEComponents.put(\"76C19B37-F0C8-11CF-87CC-0020AFEECF20\", \"VietnameseDS\"); // Vietnamese Text Display Support\r\n\t\thtIEComponents.put(\"10072CEC-8CC1-11D1-986E-00A0C955B42F\", \"VML\"); // Vector Graphics Rendering (VML)\r\n\t\thtIEComponents.put(\"90E2BA2E-DD1B-4CDE-9134-7A8B86D33CA7\", \"WebEx\"); // WebEx Productivity Tools\r\n\t\thtIEComponents.put(\"73FA19D0-2D75-11D2-995D-00C04F98BBC9\", \"WebFolders\"); // Web Folders\r\n\t\thtIEComponents.put(\"89820200-ECBD-11CF-8B85-00AA005B4340\", \"WinDesktopUpdateNT\"); // Windows Desktop Update NT\r\n\t\thtIEComponents.put(\"9030D464-4C02-4ABF-8ECC-5164760863C6\", \"WinLive\"); // Windows Live ID Sign-in Helper\r\n\t\thtIEComponents.put(\"6BF52A52-394A-11D3-B153-00C04F79FAA6\", \"WinMediaPlayer\"); // Windows Media Player (Versions 7, 8 or 9)\r\n\t\thtIEComponents.put(\"22D6F312-B0F6-11D0-94AB-0080C74C7E95\", \"WinMediaPlayerTrad\"); // Windows Media Player (Traditional Versions)\r\n\r\n\t\tstrTemp = \"\";\r\n\t\tbolFirst = true;\r\n\r\n\t\t/* strOpera gives full path of the file, extract the filenames, ignoring description and length */\r\n\t\tif (navigator.plugins.length > 0) {\r\n\t\t\tfor (iCount = 0; iCount < navigator.plugins.length; iCount = iCount + 1) {\r\n\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\tstrTemp += navigator.plugins[iCount].name;\r\n\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrTemp += glbSep + navigator.plugins[iCount].name;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (navigator.mimeTypes.length > 0) {\r\n\t\t\tstrMimeType = navigator.mimeTypes;\r\n\t\t\tfor (iCount = 0; iCount < strMimeType.length; iCount = iCount + 1) {\r\n\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\tstrTemp += strMimeType[iCount].description;\r\n\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrTemp += glbSep + strMimeType[iCount].description;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tdocument.body.addBehavior(\"#default#clientCaps\");\r\n\t\t\tstrKey = htIEComponents.keys();\r\n\t\t\tfor (iCount = 0; iCount < htIEComponents.size(); iCount = iCount + 1) {\r\n\t\t\t\tstrVersion = activeXDetect(strKey[iCount]);\r\n\t\t\t\tstrName = htIEComponents.get(strKey[iCount]);\r\n\t\t\t\tif (strVersion) {\r\n\t\t\t\t\tif (bolFirst === true) {\r\n\t\t\t\t\t\tstrTemp = strName + glbPair + strVersion;\r\n\t\t\t\t\t\tbolFirst = false;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tstrTemp += glbSep + strName + glbPair + strVersion;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tstrTemp = strTemp.replace(/,/g, \".\");\r\n\t\t}\r\n\t\tstrTemp = stripIllegalChars(strTemp);\r\n\t\tif (strTemp === \"\") {\r\n\t\t\tstrTemp = \"None\";\r\n\t\t}\r\n\t\tstrOut = strTemp;\r\n\t\treturn strOut;\r\n\t} catch (err) {\r\n\t\treturn glbOnError;\r\n\t}\r\n}","/*\r\n * Glorious webAO\r\n * made by sD, refactored by oldmud0 and Qubrick\r\n * credits to aleks for original idea and source\r\n*/\r\n\r\n// Uses the Gify library:\r\n// https://github.com/rfrench/gify\r\n// The following comment is needed for ESLint:\r\n/* global gify */\r\n\r\nimport background_arr from \"./backgrounds.js\";\r\nimport evidence_arr from \"./evidence.js\";\r\nimport Fingerprint from \"./fingerprint.js\";\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://s3.wasabisys.com/webao/base/\";\r\nconst MUSIC_HOST = AO_HOST + \"sounds/music/\";\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 fp = new Fingerprint({\r\n\tcanvas: true,\r\n\tie_activex: true,\r\n\tscreen_resolution: true\r\n});\r\nlet uid = fp.get();\r\nconsole.log(uid);\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\r\n\t\tthis.flip = false;\r\n\t\tthis.presentable = false;\r\n\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 = [];\r\n\t\tthis.evidences = [];\r\n\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\"BD\": (args) => this.handleBD(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),\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\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#${escapeChat(encodeChat(document.getElementById(\"OOC_name\").value))}#${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 {number} 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 * @param {string} evidence the filename of evidence to show\r\n\t * @param {number} flip change to 1 to reverse sprite for position changes\r\n\t * @param {string} flash screen flash effect\r\n\t * @param {string} color text color\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\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\r\n\t/**\r\n\t * Sends edit evidence command.\r\n\t * @param {number} 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\r\n\t/**\r\n\t * Sends delete evidence command.\r\n\t * @param {number} evidence id\r\n\t */\r\n\tsendDE(id) {\r\n\t\tthis.serv.send(`DE#${id}#%`);\r\n\t}\r\n\r\n\t/**\r\n\t * Sends health point command.\r\n\t * @param {number} side the position\r\n\t * @param {number} 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\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\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#${hash6ode()}#%`);\r\n\t\tthis.serv.send(\"ID#webAO#2.3#%\");\r\n\t\tthis.checkUpdater = setInterval(() => this.sendCheck(), 5000);\r\n\t}\r\n\r\n\t/**\r\n\t * Load game resources.\r\n\t */\r\n\tloadResources() {\r\n\t\t// Set to playerID to server chat name\r\n\t\t// TODO: Make a text box for this!\r\n\t\tdocument.getElementById(\"OOC_name\").value = \"web\" + this.playerID;\r\n\r\n\t\t// Load evidence array to select\r\n\t\tconst evidence_select = document.getElementById(\"evi_select\");\r\n\t\tevidence_select.add(new Option(\"Custom\", 0));\r\n\t\tevidence_arr.forEach(evidence => {\r\n\t\t\tevidence_select.add(new Option(evidence));\r\n\t\t});\r\n\r\n\t\t// Load background array to select\r\n\t\tconst background_select = document.getElementById(\"bg_select\");\r\n\t\tbackground_select.add(new Option(\"Custom\", 0));\r\n\t\tbackground_arr.forEach(background => {\r\n\t\t\tbackground_select.add(new Option(background));\r\n\t\t});\r\n\t\t// Calculate gif duration of shouts\r\n\t\tconst 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\"].toLowerCase();\r\n\t\t\tfileExists(shout_src, this.callbackLoadImageResources, shouts[i]);\r\n\t\t}\r\n\r\n\t\t// Calculate gif duration of testimony\r\n\t\tconst testimony = [\"witnesstestimony\", \"crossexamination\"];\r\n\t\tfor (let i = 0; i < testimony.length; i++) {\r\n\t\t\tconst testimony_src = `${AO_HOST}themes/default/${testimony[i]}.gif`;\r\n\t\t\t// Check image existed\r\n\t\t\tfileExists(testimony_src, this.callbackLoadImageResources, testimony[i]);\r\n\t\t\t// Check sfx existed\r\n\t\t\tfileExists(AO_HOST + this.resources[testimony[i]][\"sfx\"].toLowerCase(), this.callbackLoadSFXResources, testimony[i]);\r\n\t\t}\r\n\t\t// TODO: Cache some resources\r\n\r\n\t}\r\n\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}\r\n\t}\r\n\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\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}\r\n\t}\r\n\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\tconst target = document.getElementById(\"client_inner_chat\");\r\n\t\tconst observer = new MutationObserver(function (mutations) {\r\n\t\t\tmutations.forEach(function (mutation) {\r\n\t\t\t\tconst children = mutation.addedNodes;\r\n\t\t\t\tif (children !== null) {\r\n\t\t\t\t\tchildren.forEach(function (node) {\r\n\t\t\t\t\t\tif (node.tagName == \"C\") {\r\n\t\t\t\t\t\t\tnode.style.color = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t} else if (node.tagName == \"M\") {\r\n\t\t\t\t\t\t\tif (node.hasAttribute(\"a\")) {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = node.getAttribute(\"a\");\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tnode.style.backgroundColor = \"yellow\";\r\n\t\t\t\t\t\t\t\tnode.style.color = \"black\";\r\n\t\t\t\t\t\t\t}\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\tconst config = {\r\n\t\t\tattributes: true,\r\n\t\t\tchildList: true\r\n\t\t};\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 * XXX: a nasty hack made by gameboyprinter.\r\n\t * @param {string} msg chat message to prepare for display \r\n\t */\r\n\tprepChat(msg){\r\n\t\t// TODO: make this less awful\r\n\t\treturn decodeBBCode(unescapeChat(decodeChat(msg)));\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\tconst 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: this.prepChat(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 - 600) {\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].toLowerCase();\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].toLowerCase()) + \"/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].toLowerCase()) + \"/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\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\tconst arg = args[i].split(\"&\");\r\n\t\t\tthis.evidences[i - 1] = {\r\n\t\t\t\t\"name\": decodeChat(unescapeChat(arg[0])),\r\n\t\t\t\t\"desc\": 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].toLowerCase())\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst 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 += ``;\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\tconst hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tlet flagAudio = false;\r\n\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|opus)$/i.test(args[i]) && !flagAudio) {\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\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\tconst 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} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tconst 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 () {\r\n\t\t\t\t\tarea_click(this);\r\n\t\t\t\t};\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// We need to check if the last area that we got was actually a category\r\n\t\t// header for music. If it was, then move it over to the music list.\r\n\t\tconst area_box = document.getElementById(\"areas\");\r\n\t\tif (area_box.lastChild.textContent.startsWith(\"=\")) {\r\n\t\t\tconst audio_title = document.createElement(\"OPTION\");\r\n\t\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\t\tarea_box.removeChild(area_box.lastChild);\r\n\t\t}\r\n\r\n\t\tthis.serv.send(\"RD#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the banned packet\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBD(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Banned: \" + args[1];\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\tconst 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].toLowerCase()) + \"/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\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\tconst 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({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 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({\r\n\t\t\t\t\"width\": percent_hp + \"%\"\r\n\t\t\t}, 500);\r\n\t\t}\r\n\t}\r\n\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\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\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\tlet tr;\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\ttr = document.createElement(\"TR\");\r\n\t\t\t}\r\n\t\t\tconst td = document.createElement(\"TD\");\r\n\t\t\tlet icon_chosen = \"\";\r\n\t\t\tconst 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}\r\n\t\t\ttd.innerHTML = `${this.chars[i].name}\";\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}\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\tdocument.getElementById(\"client_inputbox\").style.display = \"\";\r\n\t\tconst me = this.me();\r\n\t\tconst emotes = this.emotes;\r\n\t\tconst emotesList = document.getElementById(\"client_emo\");\r\n\t\temotesList.innerHTML = \"\"; // Clear emote box\r\n\t\temotesList.style.display = \"\";\r\n\t\tconst xhr = new XMLHttpRequest();\r\n\t\txhr.withCredentials = false;\r\n\t\txhr.open(\"GET\", AO_HOST + \"characters/\" + escape(this.me().name.toLowerCase()) + \"/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\tconst linifile = this.responseText;\r\n\t\t\t\tconst 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\tconst 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\t// Make sure the asset server is case insensitive, or that everything on it is lowercase\r\n\t\t\t\t\temotes[i] = {\r\n\t\t\t\t\t\tdesc: emoteinfo[0].toLowerCase(),\r\n\t\t\t\t\t\tspeaking: emoteinfo[1].toLowerCase(),\r\n\t\t\t\t\t\tsilent: emoteinfo[2].toLowerCase(),\r\n\t\t\t\t\t\tzoom: emoteinfo[3],\r\n\t\t\t\t\t\tsfx: esfx.toLowerCase(),\r\n\t\t\t\t\t\tsfxdelay: esfxd,\r\n\t\t\t\t\t\tbutton_off: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_off.png`,\r\n\t\t\t\t\t\tbutton_on: AO_HOST + `characters/${escape(me.name).toLowerCase()}/emotions/button${i}_on.png`\r\n\t\t\t\t\t};\r\n\t\t\t\t\temotesList.innerHTML += \r\n\t\t\t\t\t\t`\"${emotes[i].desc}\"\r\n\t\t\t\t\t\t`;\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}\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\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.toLowerCase()}/`;\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.toLowerCase())}/${chatmsg.preanim.toLowerCase()}.gif`, this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {number} 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\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater() {\r\n\t\tif (client.testimonyID > 0) {\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\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\tconst testimonyOverlay = document.getElementById(\"client_testimony\");\r\n\t\t\ttestimonyOverlay.src = client.resources[testimony][\"src\"];\r\n\t\t\ttestimonyOverlay.style.display = \"\";\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t}\r\n\t}\r\n\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\tconst 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\tconst 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\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\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}\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\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\tdisposeTestimony() {\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").style.display = \"none\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t}\r\n\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\tconst nameBox = document.getElementById(\"client_name\");\r\n\t\tconst chatBox = document.getElementById(\"client_chat\");\r\n\t\tconst charSprite = document.getElementById(\"client_char\");\r\n\t\tconst eviBox = document.getElementById(\"client_evi\");\r\n\t\tconst background = document.getElementById(\"client_background\");\r\n\t\tconst shoutSprite = document.getElementById(\"client_shout\");\r\n\t\tconst chatBoxInner = document.getElementById(\"client_inner_chat\");\r\n\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1) {\r\n\t\t\tcharSprite.style.transform = \"scaleX(-1)\";\r\n\t\t} else {\r\n\t\t\tcharSprite.style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\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\tbackground.style.backgroundColor = \"transparent\";\r\n\t\t\t// Hide message and evidence window\r\n\t\t\tnameBox.style.display = \"none\";\r\n\t\t\tchatBox.style.display = \"none\";\r\n\t\t\teviBox.style.opacity = \"0\";\r\n\t\t\teviBox.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\tshoutSprite.src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}characters/${this.chatmsg.name.toLowerCase()}/${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\", {\r\n\t\t\t\t\t\"direction\": \"up\"\r\n\t\t\t\t});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tbackground.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\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif (this.chatmsg.preanimdelay > 0) {\r\n\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.preanim.toLowerCase() + \".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\teviBox.style.backgroundImage = \"url('\" + client.evidences[this.chatmsg.evidence - 1].icon + \"')\";\r\n\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\teviBox.style.right = \"1.5em\";\r\n\t\t\t\t\t\teviBox.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\teviBox.style.right = \"initial\";\r\n\t\t\t\t\t\teviBox.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\r\n\t\t\t\tnameBox.style.display = \"block\";\r\n\t\t\t\tnameBox.style.fontSize = (nameBox.offsetHeight * 0.7) + \"px\";\r\n\r\n\t\t\t\twhile (nameBox.hasChildNodes()) {\r\n\t\t\t\t\tnameBox.removeChild(nameBox.firstChild);\r\n\t\t\t\t}\r\n\t\t\t\tnameBox.appendChild(document.createTextNode(this.chatmsg.nameplate));\r\n\r\n\t\t\t\tchatBox.style.display = \"block\";\r\n\t\t\t\tchatBox.style.fontSize = (chatBox.offsetHeight * 0.25) + \"px\";\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\tchatBoxInner.style.color = colors[this.chatmsg.color] || \"#ffffff\";\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.chatmsg.preanimdelay == 0) {\r\n\t\t\t\t\tshoutSprite.src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.speaking.toLowerCase() + \".gif\";\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".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\r\n\t\t\t\t\twhile (chatBoxInner.hasChildNodes()) {\r\n\t\t\t\t\t\tchatBoxInner.removeChild(chatBoxInner.firstChild);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tchatBoxInner.appendChild(document.createTextNode(this.textnow));\r\n\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\tcharSprite.src = AO_HOST + \"characters/\" + escape(this.chatmsg.name.toLowerCase()) + \"/\" + this.chatmsg.silent.toLowerCase() + \".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\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.toLowerCase()) + \".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}\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\tconst 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 area list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tconst area = el.textContent;\r\n\tclient.sendMusicChange(area);\r\n\r\n\tconst areaHr = document.createElement(\"div\");\r\n\tareaHr.className = \"hrtext\";\r\n\tareaHr.textContent = `switched to ${el.textContent}`;\r\n\tdocument.getElementById(\"client_log\").appendChild(areaHr);\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 a 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 fileExists(url, callback, param) {\r\n\tconst 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\tlet standname;\r\n\tconst 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\tcase \"def\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"pro\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tfileExists(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"hld\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\";\r\n\t\tstandname = \"defense\";\r\n\t\tbreak;\r\n\tcase \"hlp\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"wit\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\";\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\";\r\n\t\tstandname = \"prosecution\";\r\n\t\tbreak;\r\n\tcase \"jud\":\r\n\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\";\r\n\t\tstandname = \"prosecution\";\r\n\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}\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 - 800) {\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\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) {\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\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\tevidence_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);\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\tevidence_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);\r\n\tcancelEvidence();\r\n}\r\nwindow.editEvidence = editEvidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function deleteEvidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelEvidence();\r\n}\r\nwindow.deleteEvidence = deleteEvidence;\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\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\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//Find if icon alraedy existed in select box\r\n\tconst select_element = document.getElementById(select_box);\r\n\tfor (let i = 1; i < select_element.length; ++i) {\r\n\t\tif (select_element.options[i].value == value) {\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\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\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.toLowerCase()})`;\r\n\t} else {\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = `url(${AO_HOST}evidence/${evidence_select.value.toLowerCase()})`;\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\tif (side == role_select[i].value) {\r\n\t\t\trole_select.selectedIndex = i;\r\n\t\t\treturn;\r\n\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 = \"\",\r\n\t\tbackground_select = document.getElementById(\"bg_select\"),\r\n\t\tbg_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\trole_command = document.getElementById(\"role_command\").value;\r\n\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() {\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() {\r\n\t$(\"#callmod_dialog\").dialog(\"open\");\r\n}\r\nwindow.callMod = callMod;\r\n\r\n/**\r\n * Declare witness testimony.\r\n */\r\nexport function initWT() {\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initWT = initWT;\r\n\r\n/**\r\n * Declare cross examination.\r\n */\r\nexport function initCE() {\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initCE = initCE;\r\n\r\n/**\r\n * Increment defense health point.\r\n */\r\nexport function addHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Decrement defense health point.\r\n */\r\nexport function redHPD() {\r\n\tclient.sendHP(1, String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Increment prosecution health point.\r\n */\r\nexport function addHPP() {\r\n\tclient.sendHP(2, String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Decrement prosecution health point.\r\n */\r\nexport function redHPP() {\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\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.toLowerCase() + \"/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.toLowerCase() + \"/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 toggleEffect(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.toggleEffect = toggleEffect;\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, \"&\")\r\n\t\t.replace(//g, \">\")\r\n\t\t.replace(/\"/g, \""\")\r\n\t\t.replace(/'/g, \"'\");\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, \"\")\r\n\t\t.replace(/&/g, \"\")\r\n\t\t.replace(/%/g, \"\")\r\n\t\t.replace(/\\$/g, \"\");\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(//g, \"#\")\r\n\t\t.replace(//g, \"&\")\r\n\t\t.replace(//g, \"%\")\r\n\t\t.replace(//g, \"$\");\r\n}\r\n\r\n/**\r\n * Encode 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// This approach works by escaping all special characters to Unicode escape sequences.\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\t});\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\tconst buffer = new ArrayBuffer(estring.length * 2);\r\n\t\tconst result = new Uint16Array(buffer);\r\n\t\tfor (let 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\nfunction hash6ode() {\r\n\treturn uid;\r\n}\r\n\r\n/**\r\n * Decodes 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\t\treturn estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16));\r\n\t\t});\r\n\t} else if (selectedDecoding == \"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\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, \"
                    \") // 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(/\\[(\\/?)s\\]/g, \"<$1del>\") // Strikethrough [s][/s]\r\n\t\t.replace(/\\[(\\/?)u\\]/g, \"<$1u>\") // 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, \"\") // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, \"<$1m>\") // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, \"\") // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, \"\"); // [/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\tString.prototype.trim = function () {\r\n\t\treturn String(this).replace(/^\\s+|\\s+$/g, \"\");\r\n\t};\r\n}\r\n\r\n// Used for HDID calculation.\r\nfunction hashCode() {\r\n\tlet hash = 0;\r\n\tlet hashString = navigator.userAgent;\r\n\tif (hashString.length === 0) return hash;\r\n\tfor (let i = 0; i < hashString.length; i++) {\r\n\t\tconst chr = hashString.charCodeAt(i);\r\n\t\thash = ((hash << 5) - hash) + chr;\r\n\t\thash |= 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\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\tSure: 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/dist/ui.b.js b/dist/ui.b.js new file mode 100644 index 0000000..2881736 --- /dev/null +++ b/dist/ui.b.js @@ -0,0 +1,2 @@ +!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.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 o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));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=1)}([function(e,t,n){(function(e){var n,i,o,s;function r(e){var t="function"==typeof Map?new Map:void 0;return(r=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,i)}function i(){return a(e,arguments,u(this).constructor)}return i.prototype=Object.create(e.prototype,{constructor:{value:i,enumerable:!1,writable:!0,configurable:!0}}),m(i,e)})(e)}function a(e,t,n){return(a=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}()?Reflect.construct:function(e,t,n){var i=[null];i.push.apply(i,t);var o=new(Function.bind.apply(e,i));return n&&m(o,n.prototype),o}).apply(null,arguments)}function l(e,t){for(var n=0;n]+)>)/gi,""))};var i=n(40),o=n.n(i),s=n(60),r=(n.n(s),"object"!=("undefined"==typeof Int8Array?"undefined":g(Int8Array))?function(e){return"function"==typeof e||!1}:function(e){return"[object Function]"===toString.call(e)})},function(e,t,n){"use strict";var i=n(0),o="__all";t.a=o,t.b=function(){return function e(){p(this,e),this._mSubscriptions={},this._mSubscriptions[o]=[],this.on=function(e,t,n){if(!Object(i.h)(t))throw new Error("Tried to listen to event "+e+" with non-function callback "+t);this._mSubscriptions[e]||(this._mSubscriptions[e]=[]),this._mSubscriptions[e].push({fn:t,ctx:n})},this.emit=function(e){var t,n,i;i=Array.prototype.slice.call(arguments,1);var s=this._mSubscriptions[e];if(s)for(s=s.slice(),t=0;t'),s.childElementContainer=s.element,s._splitterSize=t.config.dimensions.borderWidth,s._splitterGrabSize=t.config.dimensions.borderGrabWidth,s._isColumn=e,s._dimension=e?"height":"width",s._splitter=[],s._splitterPosition=null,s._splitterMinPosition=null,s._splitterMaxPosition=null,s}return f(i,r.a),c(i,[{key:"addChild",value:function(e,t,i){var o,s,a,l;if(e=this.layoutManager._$normalizeContentItem(e,this),void 0===t&&(t=this.contentItems.length),0this.contentItems.length-this._isDocked())throw new Error("Can't dock child when it is last in "+this.config.type);var u={column:{first:"top",last:"bottom"},row:{first:"left",last:"right"}}[this.config.type][r?"last":"first"];e.header.position()!=u&&e.header.position(u),this._splitter[a]&&this._splitter[a].element.hide();var f=this._isDocked();for(l=0;ls(t)&&0=this.contentItems.length)){o=this._calculateAbsoluteSizes();for(var d=0;da)){for(e=l/a,c=l,d=0;dthis._splitterMinPosition&&ithis._nDistance||t(this._nY)>this._nDistance)&&(clearTimeout(this._timeout),this._startDrag()),this._bDragging&&this.emit("drag",this._nX,this._nY,e)}}},{key:"onMouseUp",value:function(e){null!=this._timeout&&(clearTimeout(this._timeout),this._eBody.removeClass("lm_dragging"),this._eElement.removeClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events",""),this._oDocument.unbind("mousemove touchmove",this._fMove),this._oDocument.unbind("mouseup touchend",this._fUp),!0===this._bDragging&&(this._bDragging=!1,this.emit("dragStop",e,this._nOriginalX+this._nX)))}},{key:"_startDrag",value:function(){this._bDragging=!0,this._eBody.addClass("lm_dragging"),this._eElement.addClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events","none"),this.emit("dragStart",this._nOriginalX,this._nOriginalY)}},{key:"_getCoordinates",value:function(e){return{x:(e=Object(o.e)(e)).pageX,y:e.pageY}}}]),t}();t.a=s},function(e,t,n){var i=n(9);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e){e.exports=function(e){return"object"==g(e)?null!==e:"function"==typeof e}},function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){"use strict";var i=n(0);t.a=function(){function e(){if(p(this,e),this._keys=["settings","hasHeaders","constrainDragToContainer","selectionEnabled","dimensions","borderWidth","minItemHeight","minItemWidth","headerHeight","dragProxyWidth","dragProxyHeight","labels","close","maximise","minimise","popout","content","componentName","componentState","id","width","type","height","isClosable","title","popoutWholeStack","openPopouts","parentId","activeItemIndex","reorderEnabled","borderGrabWidth"],36'),o.childElementContainer=o.element,o._containerElement=i,o._containerElement.append(o.element),o}return f(t,i.a),c(t,[{key:"addChild",value:function(e){if(0'),o._activeContentItem=null;var s=e.config;return o._header={show:!0===s.settings.hasHeaders&&!1!==t.hasHeaders,popout:s.settings.showPopoutIcon&&s.labels.popout,maximise:s.settings.showMaximiseIcon&&s.labels.maximise,close:s.settings.showCloseIcon&&s.labels.close,minimise:s.labels.minimise},s.header&&Object(l.b)(o._header,s.header),t.header&&Object(l.b)(o._header,t.header),t.content&&t.content[0]&&t.content[0].header&&Object(l.b)(o._header,t.content[0].header),o._dropZones={},o._dropSegment=null,o._contentAreaDimensions=null,o._dropIndex=null,o.isStack=!0,o.childElementContainer=$('
                    '),o.header=new a.a(e,d(o)),o.element.on("mouseleave mouseenter",Object(l.c)(function(e){this._docker&&this._docker.docked&&this.childElementContainer[this._docker.dimension]("mouseenter"==e.type?this._docker.realSize:0)},d(o))),o.element.append(o.header.element),o.element.append(o.childElementContainer),o._setupHeaderPosition(),o._$validateClosability(),o}return f(i,s.a),c(i,[{key:"dock",value:function(e){this._header.dock&&this.parent instanceof r.a&&this.parent.dock(this,e)}},{key:"setSize",value:function(){if("none"!==this.element.css("display")){var e=this._docker&&this._docker.docked,t={width:this.element.width(),height:this.element.height()};this._header.show&&(t[this._sided?"width":"height"]-=this.layoutManager.config.dimensions.headerHeight),e&&(t[this._docker.dimension]=this._docker.realSize),e&&"height"!=this._docker.dimension||this.childElementContainer.width(t.width),e&&"width"!=this._docker.dimension||this.childElementContainer.height(t.height);for(var n=0;nthis.contentItems.length&&(t-=1),e=this.layoutManager._$normalizeContentItem(e,this),s.a.prototype.addChild.call(this,e,t),this.childElementContainer.append(e.element),this.header.createTab(e,t),this.setActiveContentItem(e),this.callDownwards("setSize"),this._$validateClosability(),this.parent instanceof r.a&&this.parent._validateDocking(),this.emitBubblingEvent("stateChanged")}},{key:"removeChild",value:function(e,t){var i=Object(l.g)(e,this.contentItems);s.a.prototype.removeChild.call(this,e,t),this.header.removeTab(e),this.header.activeContentItem===e&&(0e&&i.y1t)return void("header"===n?(this._dropSegment="header",this._highlightHeaderDropZone(this._sided?t:e)):(this._resetHeaderDropZone(),this._highlightBodyDropZone(n)))}},{key:"_$getArea",value:function(){if("none"===this.element.css("display"))return null;var e=s.a.prototype._$getArea,t=e.call(this,this.header.element),n=e.call(this,this.childElementContainer),i=n.x2-n.x1,o=n.y2-n.y1;return this._contentAreaDimensions={header:{hoverArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2},highlightArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2}}},this._activeContentItem&&!1===this._activeContentItem.isComponent?t:0===this.contentItems.length?(this._contentAreaDimensions.body={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}},e.call(this,this.element)):(this._contentAreaDimensions.left={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x1+.25*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x1+.5*i,y2:n.y2}},this._contentAreaDimensions.top={hoverArea:{x1:n.x1+.25*i,y1:n.y1,x2:n.x1+.75*i,y2:n.y1+.5*o},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y1+.5*o}},this._contentAreaDimensions.right={hoverArea:{x1:n.x1+.75*i,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1+.5*i,y1:n.y1,x2:n.x2,y2:n.y2}},this._contentAreaDimensions.bottom={hoverArea:{x1:n.x1+.25*i,y1:n.y1+.5*o,x2:n.x1+.75*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1+.5*o,x2:n.x2,y2:n.y2}},e.call(this,this.element))}},{key:"_highlightHeaderDropZone",value:function(t){var n,i,o,s,r,a,l,c,h=this.header.tabs.length,u=!1;if(0===h)return l=this.header.element.offset(),void this.layoutManager.dropTargetIndicator.highlightArea({x1:l.left,x2:l.left+100,y1:l.top+this.header.element.height()-20,y2:l.top+this.header.element.height()});for(n=0;ns&&t
                          '),!0===i.layoutManager.config.settings.selectionEnabled&&(i.element.addClass("lm_selectable"),i.element.on("click touchstart",Object(r.c)(i._onHeaderClick,d(i)))),i.tabsContainer=i.element.find(".lm_tabs"),i.tabDropdownContainer=i.element.find(".lm_tabdropdown_list"),i.tabDropdownContainer.hide(),i.controlsContainer=i.element.find(".lm_controls"),i.parent=n,i.parent.on("resize",i._updateTabSizes,d(i)),i.tabs=[],i.tabsMarkedForRemoval=[],i.activeContentItem=null,i.closeButton=null,i.dockButton=null,i.tabDropdownButton=null,i.hideAdditionalTabsDropdown=Object(r.c)(i._hideAdditionalTabsDropdown,d(i)),$(document).mouseup(i.hideAdditionalTabsDropdown),i._lastVisibleTabIndex=-1,i._tabControlOffset=i.layoutManager.config.settings.tabControlOffset,i._createControls(),i}return f(t,i.b),c(t,[{key:"createTab",value:function(e,t){var n,i;for(i=0;ithis._lastVisibleTabIndex){for(o=this.tabs[this.parent.config.activeItemIndex],n=this.parent.config.activeItemIndex;0r){if(u)i===d&&(n.css({"z-index":"auto","margin-left":""}),this.tabsContainer.append(n));else if((c=0
                          '),this.titleElement=this.element.find(".lm_title"),this.closeElement=this.element.find(".lm_close_tab"),this.closeElement[n.config.isClosable?"show":"hide"](),this.isActive=!1,this.setTitle(n.config.title),this.contentItem.on("titleChanged",this.setTitle,this),this._layoutManager=this.contentItem.layoutManager,!0===this._layoutManager.config.settings.reorderEnabled&&!0===n.config.reorderEnabled&&(this._dragListener=new i.a(this.element),this._dragListener.on("dragStart",this._onDragStart,this),this.contentItem.on("destroy",this._dragListener.destroy,this._dragListener)),this._onTabClickFn=Object(s.c)(this._onTabClick,this),this._onCloseClickFn=Object(s.c)(this._onCloseClick,this),this.element.on("mousedown touchstart",this._onTabClickFn),this.contentItem.config.isClosable?(this.closeElement.on("click touchstart",this._onCloseClickFn),this.closeElement.on("mousedown",this._onCloseMousedown)):this.closeElement.remove(),this.contentItem.tab=this,this.contentItem.emit("tab",this),this.contentItem.layoutManager.emit("tabCreated",this),this.contentItem.isComponent&&(this.contentItem.container.tab=this,this.contentItem.container.emit("tab",this))}return c(e,[{key:"setTitle",value:function(e){this.element.attr("title",Object(s.k)(e)),this.titleElement.html(e)}},{key:"setActive",value:function(e){e===this.isActive||(this.isActive=e,e?this.element.addClass("lm_active"):this.element.removeClass("lm_active"))}},{key:"_$destroy",value:function(){this.element.off("mousedown touchstart",this._onTabClickFn),this.closeElement.off("click touchstart",this._onCloseClickFn),this._dragListener&&(this.contentItem.off("destroy",this._dragListener.destroy,this._dragListener),this._dragListener.off("dragStart",this._onDragStart),this._dragListener=null),this.element.remove()}},{key:"_onDragStart",value:function(e,t){return this.header._canDestroy?(!0===this.contentItem.parent.isMaximised&&this.contentItem.parent.toggleMaximise(),void new o.a(e,t,this._dragListener,this._layoutManager,this.contentItem,this.header.parent)):null}},{key:"_onTabClick",value:function(e){if(0===e.button||"touchstart"===e.type){var t=this.header.parent.getActiveContentItem();this.contentItem!==t&&this.header.parent.setActiveContentItem(this.contentItem)}else 1===e.button&&this.contentItem.config.isClosable&&this._onCloseClick(e)}},{key:"_onCloseClick",value:function(e){e.stopPropagation(),this.header._canDestroy&&this.header.parent.removeChild(this.contentItem)}},{key:"_onCloseMousedown",value:function(e){e.stopPropagation()}}]),e}()},function(e,t,n){"use strict";var i=n(1),o=n(0),s=function(e){function t(e,n,i,s,r,a){var l;p(this,t),(l=h(this,u(t).call(this)))._dragListener=i,l._layoutManager=s,l._contentItem=r,l._originalParent=a,l._area=null,l._lastValidArea=null,l._dragListener.on("drag",l._onDrag,d(l)),l._dragListener.on("dragStop",l._onDrop,d(l)),l.element=$('
                          '),a&&a._side&&(l._sided=a._sided,l.element.addClass("lm_"+a._side),0<=["right","bottom"].indexOf(a._side)&&l.element.find(".lm_content").after(l.element.find(".lm_header"))),l.element.css({left:e,top:n}),l.element.find(".lm_tab").attr("title",Object(o.k)(l._contentItem.config.title)),l.element.find(".lm_title").html(l._contentItem.config.title),l.childElementContainer=l.element.find(".lm_content"),l.childElementContainer.append(r.element),l._undisplayTree(),l._layoutManager._$calculateItemAreas(),l._setDimensions(),$(document.body).append(l.element);var c=l._layoutManager.container.offset();return l._minX=c.left,l._minY=c.top,l._maxX=l._layoutManager.container.width()+l._minX,l._maxY=l._layoutManager.container.height()+l._minY,l._width=l.element.width(),l._height=l.element.height(),l._setDropPosition(e,n),l}return f(t,i.b),c(t,[{key:"_onDrag",value:function(e,t,n){var i=(n=Object(o.e)(n)).pageX,s=n.pageY;(i>this._minX&&ithis._minY&&s'),this._header.on("destroy",this._$destroy,this),this._action=o,this.element.on("click touchstart",this._action),this._header.controlsContainer.append(this.element)}return c(e,[{key:"_$destroy",value:function(){this.element.off(),this.element.remove()}}]),e}()},function(e,t,n){"use strict";var i=n(3),o=n(33),s=function(e){function t(e,n,i){var s;p(this,t),s=h(this,u(t).call(this,e,n,i));var r=e.getComponent(s.config.componentName),a=$.extend(!0,{},s.config.componentState||{});return a.componentName=s.config.componentName,s.componentName=s.config.componentName,""===s.config.title&&(s.config.title=s.config.componentName),s.isComponent=!0,s.container=new o.a(s.config,d(s),e),s.instance=new r(s.container,a),s.element=s.container._element,s}return f(t,i.a),c(t,[{key:"close",value:function(){this.parent.removeChild(this)}},{key:"setSize",value:function(){"none"!==this.element.css("display")&&this.container._$setSize(this.element.width(),this.element.height())}},{key:"_$init",value:function(){i.a.prototype._$init.call(this),this.container.emit("open")}},{key:"_$hide",value:function(){this.container.hide(),i.a.prototype._$hide.call(this)}},{key:"_$show",value:function(){this.container.show(),i.a.prototype._$show.call(this)}},{key:"_$shown",value:function(){this.container.shown(),i.a.prototype._$shown.call(this)}},{key:"_$destroy",value:function(){this.container.emit("destroy",this),i.a.prototype._$destroy.call(this)}},{key:"_$getArea",value:function(){return null}}]),t}();t.a=s},function(e,t,n){"use strict";var i=n(1),o=function(e){function t(e,n,i){var o;return p(this,t),(o=h(this,u(t).call(this))).width=null,o.height=null,o.title=e.componentName,o.parent=n,o.layoutManager=i,o.isHidden=!1,o._config=e,o._element=$('
                          '),o._contentElement=o._element.find(".lm_content"),o}return f(t,i.b),c(t,[{key:"getElement",value:function(){return this._contentElement}},{key:"hide",value:function(){this.emit("hide"),this.isHidden=!0,this._element.hide()}},{key:"show",value:function(){this.emit("show"),this.isHidden=!1,this._element.show(),(0!=this.height||0!=this.width)&&this.emit("shown")}},{key:"setSize",value:function(e,t){for(var n,i,o,s,r=this.parent,a=this;!r.isColumn&&!r.isRow;)if(a=r,(r=r.parent).isRoot)return!1;for(n=("height"===(i=r.isColumn?"height":"width")?t:e)/(this[i]*(1/(a.config[i]/100)))*100,o=(a.config[i]-n)/(r.contentItems.length-1),s=0;s'),n._creationTimeoutPassed=!1,n._subWindowsCreated=!1,n._dragSources=[],n._updatingColumnsResponsive=!1,n._firstLoad=!0,n.width=null,n.height=null,n.root=null,n.openPopouts=[],n.selectedItem=null,n.isSubWindow=!1,n.eventHub=new l.a(d(n)),n.config=n._createConfig(e),n.container=t,n.dropTargetIndicator=null,n.transitionIndicator=null,n.tabDropPlaceholder=$('
                          '),!0===n.isSubWindow&&$("body").css("visibility","hidden"),n._typeToItem={column:Object(E.c)(y.a,d(n),[!0]),row:Object(E.c)(y.a,d(n),[!1]),stack:v.a,component:_.a},n}return f(i,s.b),c(i,[{key:"minifyConfig",value:function(e){return(new a.a).minifyConfig(e)}},{key:"unminifyConfig",value:function(e){return(new a.a).unminifyConfig(e)}},{key:"registerComponent",value:function(e,t){if("function"!=typeof t)throw new Error("Please register a constructor function");if(void 0!==this._components[e])throw new Error("Component "+e+" is already registered");this._components[e]=t}},{key:"toConfig",value:function(e){var t,n,i;if(!1===this.isInitialised)throw new Error("Can't create config, layout not yet initialised");if(e&&!(e instanceof b.a))throw new Error("Root must be a ContentItem");for((t={settings:Object(E.b)({},this.config.settings),dimensions:Object(E.b)({},this.config.dimensions),labels:Object(E.b)({},this.config.labels)}).content=[],(n=function(e,t){var i,o;for(i in t.config)"content"!==i&&(e[i]=t.config[i]);if(t.contentItems.length)for(e.content=[],o=0;o(i=this._itemAreas[n]).x1&&ei.y1&&ti.surface&&(o=i.surface,s=i);return s}},{key:"_$createRootItemAreas",value:function(){var e={y2:0,x2:0,y1:"y2",x1:"x2"};for(var t in e){var n=this.root._$getArea();n.side=t,n[t]=e[t]?n[e[t]]-50:50,n.surface=(n.x2-n.x1)*(n.y2-n.y1),this._itemAreas.push(n)}}},{key:"_$calculateItemAreas",value:function(){var e,t,n=this._getAllContentItems();if(this._itemAreas=[],1!==n.length){for(this._$createRootItemAreas(),e=0;e
                          ');e.click(Object(E.c)(function(){this.emit("popIn")},this)),document.title=Object(E.k)(this.config.content[0].title),$("head").append($("body link, body style, template, .gl_keep")),this.container=$("body").html("").css("visibility","visible").append(e),document.body.offsetHeight,window.__glInstance=this}},{key:"_createSubWindows",value:function(){var e,t;for(e=0;e=e)){var i=this.config.dimensions.minItemWidth;if(!(e*i<=this.width)){this._updatingColumnsResponsive=!0;for(var o,s=n(t(this.width/i),1),r=this.root.contentItems[0],a=this._findAllStackContainers()[0],l=0;ll;)i(a,n=t[l++])&&(~s(c,n)||c.push(n));return c}},function(e,t,n){var i=n(46);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var i=n(17),o=n(48),s=n(49);e.exports=function(e){return function(t,n,r){var a,l=i(t),c=o(l.length),h=s(r,c);if(e&&n!=n){for(;c>h;)if((a=l[h++])!=a)return!0}else for(;c>h;h++)if((e||h in l)&&l[h]===n)return e||h||0;return!e&&-1}}},function(t,n,i){var o=i(18);t.exports=function(t){return 0(t=s(t))?n(t+i,0):e(t,i)}},function(e,t,n){var i=n(2),o=n(4),s="__core-js_shared__",r=o[s]||(o[s]={});(e.exports=function(e,t){return r[e]||(r[e]=void 0===t?{}:t)})("versions",[]).push({version:i.version,mode:n(51)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e){e.exports=!0},function(e){var t=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++t+n).toString(36))}},function(e,t,n){var i=n(21),o=n(2),s=n(10);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*s(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(55);e.exports=function(e,t,n){return i(e),void 0===t?e:1===n?function(n){return e.call(t,n)}:2===n?function(n,i){return e.call(t,n,i)}:3===n?function(n,i,o){return e.call(t,n,i,o)}:function(){return e.apply(t,arguments)}}},function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var i=n(22),o=n(59);e.exports=n(5)?function(e,t,n){return i.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=!n(5)&&!n(10)(function(){return 7!=Object.defineProperty(n(23)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(9);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){e.exports={default:n(61),__esModule:!0}},function(e,t,n){n(62);var i=n(2).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){var i=n(21);i(i.S,"Object",{create:n(63)})},function(e,t,n){var i=n(8),o=n(64),s=n(20),r=n(19)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(23)("iframe"),i=s.length;for(t.style.display="none",n(65).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + '),s.childElementContainer=s.element,s._splitterSize=t.config.dimensions.borderWidth,s._splitterGrabSize=t.config.dimensions.borderGrabWidth,s._isColumn=e,s._dimension=e?"height":"width",s._splitter=[],s._splitterPosition=null,s._splitterMinPosition=null,s._splitterMaxPosition=null,s}return f(i,r.a),c(i,[{key:"addChild",value:function(e,t,i){var o,s,a,l;if(e=this.layoutManager._$normalizeContentItem(e,this),void 0===t&&(t=this.contentItems.length),0this.contentItems.length-this._isDocked())throw new Error("Can't dock child when it is last in "+this.config.type);var u={column:{first:"top",last:"bottom"},row:{first:"left",last:"right"}}[this.config.type][r?"last":"first"];e.header.position()!=u&&e.header.position(u),this._splitter[a]&&this._splitter[a].element.hide();var f=this._isDocked();for(l=0;ls(t)&&0=this.contentItems.length)){o=this._calculateAbsoluteSizes();for(var d=0;da)){for(e=l/a,c=l,d=0;dthis._splitterMinPosition&&ithis._nDistance||t(this._nY)>this._nDistance)&&(clearTimeout(this._timeout),this._startDrag()),this._bDragging&&this.emit("drag",this._nX,this._nY,e)}}},{key:"onMouseUp",value:function(e){null!=this._timeout&&(clearTimeout(this._timeout),this._eBody.removeClass("lm_dragging"),this._eElement.removeClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events",""),this._oDocument.unbind("mousemove touchmove",this._fMove),this._oDocument.unbind("mouseup touchend",this._fUp),!0===this._bDragging&&(this._bDragging=!1,this.emit("dragStop",e,this._nOriginalX+this._nX)))}},{key:"_startDrag",value:function(){this._bDragging=!0,this._eBody.addClass("lm_dragging"),this._eElement.addClass("lm_dragging"),this._oDocument.find("iframe").css("pointer-events","none"),this.emit("dragStart",this._nOriginalX,this._nOriginalY)}},{key:"_getCoordinates",value:function(e){return{x:(e=Object(o.e)(e)).pageX,y:e.pageY}}}]),t}();t.a=s},function(e,t,n){var i=n(9);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e){e.exports=function(e){return"object"==g(e)?null!==e:"function"==typeof e}},function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){"use strict";var i=n(0);t.a=function(){function e(){if(p(this,e),this._keys=["settings","hasHeaders","constrainDragToContainer","selectionEnabled","dimensions","borderWidth","minItemHeight","minItemWidth","headerHeight","dragProxyWidth","dragProxyHeight","labels","close","maximise","minimise","popout","content","componentName","componentState","id","width","type","height","isClosable","title","popoutWholeStack","openPopouts","parentId","activeItemIndex","reorderEnabled","borderGrabWidth"],36'),o.childElementContainer=o.element,o._containerElement=i,o._containerElement.append(o.element),o}return f(t,i.a),c(t,[{key:"addChild",value:function(e){if(0'),o._activeContentItem=null;var s=e.config;return o._header={show:!0===s.settings.hasHeaders&&!1!==t.hasHeaders,popout:s.settings.showPopoutIcon&&s.labels.popout,maximise:s.settings.showMaximiseIcon&&s.labels.maximise,close:s.settings.showCloseIcon&&s.labels.close,minimise:s.labels.minimise},s.header&&Object(l.b)(o._header,s.header),t.header&&Object(l.b)(o._header,t.header),t.content&&t.content[0]&&t.content[0].header&&Object(l.b)(o._header,t.content[0].header),o._dropZones={},o._dropSegment=null,o._contentAreaDimensions=null,o._dropIndex=null,o.isStack=!0,o.childElementContainer=$('
                          '),o.header=new a.a(e,d(o)),o.element.on("mouseleave mouseenter",Object(l.c)(function(e){this._docker&&this._docker.docked&&this.childElementContainer[this._docker.dimension]("mouseenter"==e.type?this._docker.realSize:0)},d(o))),o.element.append(o.header.element),o.element.append(o.childElementContainer),o._setupHeaderPosition(),o._$validateClosability(),o}return f(i,s.a),c(i,[{key:"dock",value:function(e){this._header.dock&&this.parent instanceof r.a&&this.parent.dock(this,e)}},{key:"setSize",value:function(){if("none"!==this.element.css("display")){var e=this._docker&&this._docker.docked,t={width:this.element.width(),height:this.element.height()};this._header.show&&(t[this._sided?"width":"height"]-=this.layoutManager.config.dimensions.headerHeight),e&&(t[this._docker.dimension]=this._docker.realSize),e&&"height"!=this._docker.dimension||this.childElementContainer.width(t.width),e&&"width"!=this._docker.dimension||this.childElementContainer.height(t.height);for(var n=0;nthis.contentItems.length&&(t-=1),e=this.layoutManager._$normalizeContentItem(e,this),s.a.prototype.addChild.call(this,e,t),this.childElementContainer.append(e.element),this.header.createTab(e,t),this.setActiveContentItem(e),this.callDownwards("setSize"),this._$validateClosability(),this.parent instanceof r.a&&this.parent._validateDocking(),this.emitBubblingEvent("stateChanged")}},{key:"removeChild",value:function(e,t){var i=Object(l.g)(e,this.contentItems);s.a.prototype.removeChild.call(this,e,t),this.header.removeTab(e),this.header.activeContentItem===e&&(0e&&i.y1t)return void("header"===n?(this._dropSegment="header",this._highlightHeaderDropZone(this._sided?t:e)):(this._resetHeaderDropZone(),this._highlightBodyDropZone(n)))}},{key:"_$getArea",value:function(){if("none"===this.element.css("display"))return null;var e=s.a.prototype._$getArea,t=e.call(this,this.header.element),n=e.call(this,this.childElementContainer),i=n.x2-n.x1,o=n.y2-n.y1;return this._contentAreaDimensions={header:{hoverArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2},highlightArea:{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2}}},this._activeContentItem&&!1===this._activeContentItem.isComponent?t:0===this.contentItems.length?(this._contentAreaDimensions.body={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}},e.call(this,this.element)):(this._contentAreaDimensions.left={hoverArea:{x1:n.x1,y1:n.y1,x2:n.x1+.25*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x1+.5*i,y2:n.y2}},this._contentAreaDimensions.top={hoverArea:{x1:n.x1+.25*i,y1:n.y1,x2:n.x1+.75*i,y2:n.y1+.5*o},highlightArea:{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y1+.5*o}},this._contentAreaDimensions.right={hoverArea:{x1:n.x1+.75*i,y1:n.y1,x2:n.x2,y2:n.y2},highlightArea:{x1:n.x1+.5*i,y1:n.y1,x2:n.x2,y2:n.y2}},this._contentAreaDimensions.bottom={hoverArea:{x1:n.x1+.25*i,y1:n.y1+.5*o,x2:n.x1+.75*i,y2:n.y2},highlightArea:{x1:n.x1,y1:n.y1+.5*o,x2:n.x2,y2:n.y2}},e.call(this,this.element))}},{key:"_highlightHeaderDropZone",value:function(t){var n,i,o,s,r,a,l,c,h=this.header.tabs.length,u=!1;if(0===h)return l=this.header.element.offset(),void this.layoutManager.dropTargetIndicator.highlightArea({x1:l.left,x2:l.left+100,y1:l.top+this.header.element.height()-20,y2:l.top+this.header.element.height()});for(n=0;ns&&t
                                '),!0===i.layoutManager.config.settings.selectionEnabled&&(i.element.addClass("lm_selectable"),i.element.on("click touchstart",Object(r.c)(i._onHeaderClick,d(i)))),i.tabsContainer=i.element.find(".lm_tabs"),i.tabDropdownContainer=i.element.find(".lm_tabdropdown_list"),i.tabDropdownContainer.hide(),i.controlsContainer=i.element.find(".lm_controls"),i.parent=n,i.parent.on("resize",i._updateTabSizes,d(i)),i.tabs=[],i.tabsMarkedForRemoval=[],i.activeContentItem=null,i.closeButton=null,i.dockButton=null,i.tabDropdownButton=null,i.hideAdditionalTabsDropdown=Object(r.c)(i._hideAdditionalTabsDropdown,d(i)),$(document).mouseup(i.hideAdditionalTabsDropdown),i._lastVisibleTabIndex=-1,i._tabControlOffset=i.layoutManager.config.settings.tabControlOffset,i._createControls(),i}return f(t,i.b),c(t,[{key:"createTab",value:function(e,t){var n,i;for(i=0;ithis._lastVisibleTabIndex){for(o=this.tabs[this.parent.config.activeItemIndex],n=this.parent.config.activeItemIndex;0r){if(u)i===d&&(n.css({"z-index":"auto","margin-left":""}),this.tabsContainer.append(n));else if((c=0
                                '),this.titleElement=this.element.find(".lm_title"),this.closeElement=this.element.find(".lm_close_tab"),this.closeElement[n.config.isClosable?"show":"hide"](),this.isActive=!1,this.setTitle(n.config.title),this.contentItem.on("titleChanged",this.setTitle,this),this._layoutManager=this.contentItem.layoutManager,!0===this._layoutManager.config.settings.reorderEnabled&&!0===n.config.reorderEnabled&&(this._dragListener=new i.a(this.element),this._dragListener.on("dragStart",this._onDragStart,this),this.contentItem.on("destroy",this._dragListener.destroy,this._dragListener)),this._onTabClickFn=Object(s.c)(this._onTabClick,this),this._onCloseClickFn=Object(s.c)(this._onCloseClick,this),this.element.on("mousedown touchstart",this._onTabClickFn),this.contentItem.config.isClosable?(this.closeElement.on("click touchstart",this._onCloseClickFn),this.closeElement.on("mousedown",this._onCloseMousedown)):this.closeElement.remove(),this.contentItem.tab=this,this.contentItem.emit("tab",this),this.contentItem.layoutManager.emit("tabCreated",this),this.contentItem.isComponent&&(this.contentItem.container.tab=this,this.contentItem.container.emit("tab",this))}return c(e,[{key:"setTitle",value:function(e){this.element.attr("title",Object(s.k)(e)),this.titleElement.html(e)}},{key:"setActive",value:function(e){e===this.isActive||(this.isActive=e,e?this.element.addClass("lm_active"):this.element.removeClass("lm_active"))}},{key:"_$destroy",value:function(){this.element.off("mousedown touchstart",this._onTabClickFn),this.closeElement.off("click touchstart",this._onCloseClickFn),this._dragListener&&(this.contentItem.off("destroy",this._dragListener.destroy,this._dragListener),this._dragListener.off("dragStart",this._onDragStart),this._dragListener=null),this.element.remove()}},{key:"_onDragStart",value:function(e,t){return this.header._canDestroy?(!0===this.contentItem.parent.isMaximised&&this.contentItem.parent.toggleMaximise(),void new o.a(e,t,this._dragListener,this._layoutManager,this.contentItem,this.header.parent)):null}},{key:"_onTabClick",value:function(e){if(0===e.button||"touchstart"===e.type){var t=this.header.parent.getActiveContentItem();this.contentItem!==t&&this.header.parent.setActiveContentItem(this.contentItem)}else 1===e.button&&this.contentItem.config.isClosable&&this._onCloseClick(e)}},{key:"_onCloseClick",value:function(e){e.stopPropagation(),this.header._canDestroy&&this.header.parent.removeChild(this.contentItem)}},{key:"_onCloseMousedown",value:function(e){e.stopPropagation()}}]),e}()},function(e,t,n){"use strict";var i=n(1),o=n(0),s=function(e){function t(e,n,i,s,r,a){var l;p(this,t),(l=h(this,u(t).call(this)))._dragListener=i,l._layoutManager=s,l._contentItem=r,l._originalParent=a,l._area=null,l._lastValidArea=null,l._dragListener.on("drag",l._onDrag,d(l)),l._dragListener.on("dragStop",l._onDrop,d(l)),l.element=$('
                                '),a&&a._side&&(l._sided=a._sided,l.element.addClass("lm_"+a._side),0<=["right","bottom"].indexOf(a._side)&&l.element.find(".lm_content").after(l.element.find(".lm_header"))),l.element.css({left:e,top:n}),l.element.find(".lm_tab").attr("title",Object(o.k)(l._contentItem.config.title)),l.element.find(".lm_title").html(l._contentItem.config.title),l.childElementContainer=l.element.find(".lm_content"),l.childElementContainer.append(r.element),l._undisplayTree(),l._layoutManager._$calculateItemAreas(),l._setDimensions(),$(document.body).append(l.element);var c=l._layoutManager.container.offset();return l._minX=c.left,l._minY=c.top,l._maxX=l._layoutManager.container.width()+l._minX,l._maxY=l._layoutManager.container.height()+l._minY,l._width=l.element.width(),l._height=l.element.height(),l._setDropPosition(e,n),l}return f(t,i.b),c(t,[{key:"_onDrag",value:function(e,t,n){var i=(n=Object(o.e)(n)).pageX,s=n.pageY;(i>this._minX&&ithis._minY&&s'),this._header.on("destroy",this._$destroy,this),this._action=o,this.element.on("click touchstart",this._action),this._header.controlsContainer.append(this.element)}return c(e,[{key:"_$destroy",value:function(){this.element.off(),this.element.remove()}}]),e}()},function(e,t,n){"use strict";var i=n(3),o=n(33),s=function(e){function t(e,n,i){var s;p(this,t),s=h(this,u(t).call(this,e,n,i));var r=e.getComponent(s.config.componentName),a=$.extend(!0,{},s.config.componentState||{});return a.componentName=s.config.componentName,s.componentName=s.config.componentName,""===s.config.title&&(s.config.title=s.config.componentName),s.isComponent=!0,s.container=new o.a(s.config,d(s),e),s.instance=new r(s.container,a),s.element=s.container._element,s}return f(t,i.a),c(t,[{key:"close",value:function(){this.parent.removeChild(this)}},{key:"setSize",value:function(){"none"!==this.element.css("display")&&this.container._$setSize(this.element.width(),this.element.height())}},{key:"_$init",value:function(){i.a.prototype._$init.call(this),this.container.emit("open")}},{key:"_$hide",value:function(){this.container.hide(),i.a.prototype._$hide.call(this)}},{key:"_$show",value:function(){this.container.show(),i.a.prototype._$show.call(this)}},{key:"_$shown",value:function(){this.container.shown(),i.a.prototype._$shown.call(this)}},{key:"_$destroy",value:function(){this.container.emit("destroy",this),i.a.prototype._$destroy.call(this)}},{key:"_$getArea",value:function(){return null}}]),t}();t.a=s},function(e,t,n){"use strict";var i=n(1),o=function(e){function t(e,n,i){var o;return p(this,t),(o=h(this,u(t).call(this))).width=null,o.height=null,o.title=e.componentName,o.parent=n,o.layoutManager=i,o.isHidden=!1,o._config=e,o._element=$('
                                '),o._contentElement=o._element.find(".lm_content"),o}return f(t,i.b),c(t,[{key:"getElement",value:function(){return this._contentElement}},{key:"hide",value:function(){this.emit("hide"),this.isHidden=!0,this._element.hide()}},{key:"show",value:function(){this.emit("show"),this.isHidden=!1,this._element.show(),(0!=this.height||0!=this.width)&&this.emit("shown")}},{key:"setSize",value:function(e,t){for(var n,i,o,s,r=this.parent,a=this;!r.isColumn&&!r.isRow;)if(a=r,(r=r.parent).isRoot)return!1;for(n=("height"===(i=r.isColumn?"height":"width")?t:e)/(this[i]*(1/(a.config[i]/100)))*100,o=(a.config[i]-n)/(r.contentItems.length-1),s=0;s'),n._creationTimeoutPassed=!1,n._subWindowsCreated=!1,n._dragSources=[],n._updatingColumnsResponsive=!1,n._firstLoad=!0,n.width=null,n.height=null,n.root=null,n.openPopouts=[],n.selectedItem=null,n.isSubWindow=!1,n.eventHub=new l.a(d(n)),n.config=n._createConfig(e),n.container=t,n.dropTargetIndicator=null,n.transitionIndicator=null,n.tabDropPlaceholder=$('
                                '),!0===n.isSubWindow&&$("body").css("visibility","hidden"),n._typeToItem={column:Object(E.c)(y.a,d(n),[!0]),row:Object(E.c)(y.a,d(n),[!1]),stack:v.a,component:_.a},n}return f(i,s.b),c(i,[{key:"minifyConfig",value:function(e){return(new a.a).minifyConfig(e)}},{key:"unminifyConfig",value:function(e){return(new a.a).unminifyConfig(e)}},{key:"registerComponent",value:function(e,t){if("function"!=typeof t)throw new Error("Please register a constructor function");if(void 0!==this._components[e])throw new Error("Component "+e+" is already registered");this._components[e]=t}},{key:"toConfig",value:function(e){var t,n,i;if(!1===this.isInitialised)throw new Error("Can't create config, layout not yet initialised");if(e&&!(e instanceof b.a))throw new Error("Root must be a ContentItem");for((t={settings:Object(E.b)({},this.config.settings),dimensions:Object(E.b)({},this.config.dimensions),labels:Object(E.b)({},this.config.labels)}).content=[],(n=function(e,t){var i,o;for(i in t.config)"content"!==i&&(e[i]=t.config[i]);if(t.contentItems.length)for(e.content=[],o=0;o(i=this._itemAreas[n]).x1&&ei.y1&&ti.surface&&(o=i.surface,s=i);return s}},{key:"_$createRootItemAreas",value:function(){var e={y2:0,x2:0,y1:"y2",x1:"x2"};for(var t in e){var n=this.root._$getArea();n.side=t,n[t]=e[t]?n[e[t]]-50:50,n.surface=(n.x2-n.x1)*(n.y2-n.y1),this._itemAreas.push(n)}}},{key:"_$calculateItemAreas",value:function(){var e,t,n=this._getAllContentItems();if(this._itemAreas=[],1!==n.length){for(this._$createRootItemAreas(),e=0;e
                                ');e.click(Object(E.c)(function(){this.emit("popIn")},this)),document.title=Object(E.k)(this.config.content[0].title),$("head").append($("body link, body style, template, .gl_keep")),this.container=$("body").html("").css("visibility","visible").append(e),document.body.offsetHeight,window.__glInstance=this}},{key:"_createSubWindows",value:function(){var e,t;for(e=0;e=e)){var i=this.config.dimensions.minItemWidth;if(!(e*i<=this.width)){this._updatingColumnsResponsive=!0;for(var o,s=n(t(this.width/i),1),r=this.root.contentItems[0],a=this._findAllStackContainers()[0],l=0;ll;)i(a,n=t[l++])&&(~s(c,n)||c.push(n));return c}},function(e,t,n){var i=n(46);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==i(e)?e.split(""):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var i=n(17),o=n(48),s=n(49);e.exports=function(e){return function(t,n,r){var a,l=i(t),c=o(l.length),h=s(r,c);if(e&&n!=n){for(;c>h;)if((a=l[h++])!=a)return!0}else for(;c>h;h++)if((e||h in l)&&l[h]===n)return e||h||0;return!e&&-1}}},function(t,n,i){var o=i(18);t.exports=function(t){return 0(t=s(t))?n(t+i,0):e(t,i)}},function(e,t,n){var i=n(2),o=n(4),s="__core-js_shared__",r=o[s]||(o[s]={});(e.exports=function(e,t){return r[e]||(r[e]=void 0===t?{}:t)})("versions",[]).push({version:i.version,mode:n(51)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e){e.exports=!0},function(e){var t=0,n=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++t+n).toString(36))}},function(e,t,n){var i=n(21),o=n(2),s=n(10);e.exports=function(e,t){var n=(o.Object||{})[e]||Object[e],r={};r[e]=t(n),i(i.S+i.F*s(function(){n(1)}),"Object",r)}},function(e,t,n){var i=n(55);e.exports=function(e,t,n){return i(e),void 0===t?e:1===n?function(n){return e.call(t,n)}:2===n?function(n,i){return e.call(t,n,i)}:3===n?function(n,i,o){return e.call(t,n,i,o)}:function(){return e.apply(t,arguments)}}},function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var i=n(22),o=n(59);e.exports=n(5)?function(e,t,n){return i.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){e.exports=!n(5)&&!n(10)(function(){return 7!=Object.defineProperty(n(23)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var i=n(9);e.exports=function(e,t){if(!i(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!i(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!i(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){e.exports={default:n(61),__esModule:!0}},function(e,t,n){n(62);var i=n(2).Object;e.exports=function(e,t){return i.create(e,t)}},function(e,t,n){var i=n(21);i(i.S,"Object",{create:n(63)})},function(e,t,n){var i=n(8),o=n(64),s=n(20),r=n(19)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(23)("iframe"),i=s.length;for(t.style.display="none",n(65).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("