aboutsummaryrefslogtreecommitdiff
path: root/webAO/client.b.js.map
blob: feb0e2c3789b599293c6b16927e4ece6f1696d32 (plain)
1
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./webAO/client.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","onOOCEnter","onEnter","musiclist_click","area_click","changeMusicVolume","changeSFXVolume","changeBlipVolume","changeCharacter","imgError","demoError","ReconnectButton","RetryButton","pickchar","pickemotion","pickevidence","addevidence","editevidence","delevidence","cancelevidence","getIndexFromSelect","updateEvidenceIcon","updateActionCommands","changeBackgroundOOC","changeRoleOOC","randomCharacterOOC","callmod","initwt","initce","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 += '<img src=\"' + this.evidences[i - 1].icon + \r\n\t\t\t\t'\" id=\"evi_' + i +'\" alt=\"' + this.evidences[i - 1].name +\r\n\t\t\t\t'\" class=\"client_button\" ' +\r\n\t\t\t\t'onclick=\"pickevidence('+ i +')\">';\t\t\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing multiple entries\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleEM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \" + args[1];\r\n\t\tthis.serv.send(\"AM#\" + ((args[1] / 10) + 1) + \"#%\");\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\");\r\n\t\tfor (let i = 2; i < args.length - 1; i++) {\r\n\t\t\tif (i % 2 == 0) {\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing only one entry\r\n\t * per packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSM(args) {\r\n\t\tdocument.getElementById(\"client_loadingtext\").innerHTML = \"Loading Music \";\r\n\t\tlet hmusiclist = document.getElementById(\"client_musiclist\"), flagAudio = false;\r\n\t\t\r\n\t\tfor (let i = 1; i < args.length - 1; i++) {\r\n\t\t\t// Check when found the song for the first time\r\n\t\t\tif(/\\.(?:wav|mp3|mp4|ogg|mid)$/i.test(args[i]) && !flagAudio){\r\n\t\t\t\tflagAudio = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(flagAudio) {\r\n\t\t\t\t// After reached the audio put everything in the music list\r\n\t\t\t\tlet newentry = document.createElement(\"OPTION\");\r\n\t\t\t\tnewentry.text = args[i];\r\n\t\t\t\thmusiclist.options.add(newentry);\r\n\t\t\t\r\n\t\t\t} else {\r\n\t\t\t\t// Create area button\r\n\t\t\t\tlet newarea = document.createElement(\"SPAN\");\r\n\t\t\t\tnewarea.className = \"location-box\";\r\n\t\t\t\tnewarea.textContent = args[i]; \r\n\t\t\t\tnewarea.onclick = function(){ area_click(this) };\r\n\t\t\t\tdocument.getElementById(\"areas\").appendChild(newarea);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// Move first audio title from area box to music list\r\n\t\tlet area_box = document.getElementById(\"areas\");\r\n\t\tlet audio_title = document.createElement(\"OPTION\");\r\n\t\taudio_title.text = area_box.lastChild.textContent;\r\n\t\thmusiclist.insertBefore(audio_title, hmusiclist.firstChild);\r\n\t\tarea_box.removeChild(area_box.lastChild); // Remove from arae box\r\n\t\t\t\t\r\n\t\tthis.serv.send(\"RD#%\");\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Handles incoming music information, containing all entries\r\n\t * in the same packet.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlemusic(args) {\r\n\t\tfor (let i = 0; i < args.length / 2; i++) {\r\n\t\t\tthis.musicList[args[2 * i]] = args[2 * i + 1];\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the handshake completion packet, meaning the player\r\n\t * is ready to select a character.\r\n\t * \r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleDONE(args) {\r\n\t\tdocument.getElementById(\"client_loading\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a background change.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleBN(args) {\r\n\t\tviewport.bgname = escape(args[1]);\r\n\t\tlet bg_index = getIndexFromSelect(\"bg_select\", escape(args[1]));\r\n\t\tdocument.getElementById(\"bg_select\").selectedIndex = bg_index;\r\n\t\tupdateBackgroundPreview();\r\n\t\tif(bg_index == 0){\r\n\t\t\tdocument.getElementById(\"bg_filename\").value = args[1];\r\n\t\t}\r\n\t\tdocument.getElementById(\"bg_preview\").src = AO_HOST + 'background/' + escape(args[1]) + \"/defenseempty.png\";\r\n\t\tif(this.charID == -1){\r\n\t\t\tchangeBackground(\"jud\");\r\n\t\t} else {\r\n\t\t\tchangeBackground(this.chars[this.charID].side);\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n\thandleNBG(args) {\r\n\t\t// TODO (set by sD)\r\n\t}\r\n\r\n\t/**\r\n\t * Handles a change in the health bars' states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleHP(args) {\r\n\t\tlet percent_hp = args[2] * 10;\r\n\t\tif (args[1] == 1) {\r\n\t\t\t// Def hp\r\n\t\t\tthis.hp[0] = args[2];\r\n\t\t\t$(\"#client_defense_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t} else {\r\n\t\t\t// Pro hp\r\n\t\t\tthis.hp[1] = args[2];\r\n\t\t\t$(\"#client_prosecutor_hp > .health-bar\").animate({ 'width': percent_hp + \"%\" }, 500);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a testimony states.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleRT(args) {\r\n\t\tif (args[1] == \"testimony1\") {\r\n\t\t\t//Witness Testimony\r\n\t\t\tthis.testimonyID = 1;\r\n\t\t} else {\r\n\t\t\t//Cross Examination\r\n\t\t\tthis.testimonyID = 2;\r\n\t\t}\r\n\t\tviewport.initTestimonyUpdater();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles a call mod message.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleZZ(args) {\r\n\t\tconst oocLog = document.getElementById(\"client_ooclog\");\r\n\t\toocLog.innerHTML += `\\$Alert: ${decodeChat(unescapeChat(args[1]))}\\r\\n`;\r\n\t\tif (oocLog.scrollTop > oocLog.scrollHeight - 60) {\r\n\t\t\toocLog.scrollTop = oocLog.scrollHeight;\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Handles the issuance of a player ID by the server.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleID(args) {\r\n\t\tthis.playerID = args[1];\r\n\t}\r\n\r\n\thandlePN(args) {\r\n\t\tthis.serv.send(\"askchaa#%\");\r\n\t}\r\n\r\n\t/**\r\n\t * Received when the server announces its server info,\r\n\t * but we use it as a cue to begin retrieving characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleSI(args) {\r\n\t\tif (oldLoading) {\r\n\t\t\tthis.serv.send(\"askchar2#%\");\r\n\t\t} else {\r\n\t\t\tthis.serv.send(\"RC#%\");\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the list of all used and vacant characters.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandleCharsCheck(args) {\r\n\t\tdocument.getElementById(\"client_chartable\").innerHTML = \"\";\r\n\t\tfor (let i = 0; i < this.chars.length; i++) {\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tvar tr = document.createElement('TR');\r\n\t\t\t}\r\n\t\t\tlet td = document.createElement('TD');\r\n\t\t\tlet icon_chosen;\r\n\t\t\tlet thispick = this.chars[i].icon;\r\n\t\t\tif (args[i + 1] == \"-1\") {\r\n\t\t\t\ticon_chosen = \" dark\";\r\n\t\t\t} else {\r\n\t\t\t\ticon_chosen = \"\";\r\n\t\t\t}\r\n\t\t\ttd.innerHTML = `<img class='demothing${icon_chosen}' id='demo_${i}' ` +\r\n\t\t\t\t`src='${thispick}' alt='${this.chars[i].name}' onclick='pickchar(${i})' ` +\r\n\t\t\t\t`onerror='demoError(this);'>`;\r\n\t\t\ttr.appendChild(td);\r\n\t\t\tif (i % CHAR_SELECT_WIDTH == 0) {\r\n\t\t\t\tdocument.getElementById(\"client_chartable\").appendChild(tr);\r\n\t\t\t}\r\n\t\t}\t\t\r\n\t\t//changeBackground(\"def\");\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the server's assignment of a character for the player to use.\r\n\t * @param {Array} args packet arguments\r\n\t */\r\n\thandlePV(args) {\r\n\t\tthis.charID = args[3];\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tlet me = this.me();\r\n\t\tlet emotes = this.emotes;\r\n\t\tlet xhr = new XMLHttpRequest();\r\n\t\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 += \"<img src='\" + emotes[i].button_off + \"' id='emo_\" + i + \"' alt='\" + emotes[i].desc + \"' class='client_button' onclick='pickemotion(\" + i + \")'>\";\r\n\t\t\t\t}\r\n\t\t\t\tpickemotion(1);\r\n\t\t\t}\r\n\t\t};\r\n\t\txhr.send();\r\n\t}\t\t\r\n}\r\n\r\nclass Viewport {\r\n\tconstructor() {\r\n\t\tthis.textnow = \"\";\r\n\t\tthis.chatmsg = {\r\n\t\t\t\"isnew\": false,\r\n\t\t\t\"content\": \"\",\r\n\t\t\t\"objection\": \"0\",\r\n\t\t\t\"sound\": \"\",\r\n\t\t\t\"startpreanim\": false,\r\n\t\t\t\"startspeaking\": false,\r\n\t\t\t\"side\": null,\r\n\t\t\t\"color\": \"0\",\r\n\t\t\t\"snddelay\": 0,\r\n\t\t\t\"preanimdelay\": 0\r\n\t\t};\r\n\t\tthis.blip = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.blip.volume = 0.5;\r\n\r\n\t\t// Allocate multiple blip audio channels to make blips less jittery\r\n\r\n\t\t// TODO: read blip type (\"gender\") from ini\r\n\t\tthis.blipChannels = new Array(6);\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i] = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\t\tthis.blipChannels[i].volume = 0.5;\r\n\t\t}\r\n\t\tthis.currentBlipChannel = 0;\r\n\r\n\t\tthis.sfxaudio = new Audio(AO_HOST + 'sounds/general/sfx-blipmale.wav');\r\n\t\tthis.sfxplayed = 0;\r\n\r\n\t\tthis.music = new Audio();\r\n\t\tthis.music.play();\r\n\r\n\t\tthis.updater = null;\r\n\t\tthis.testimonyUpdater = null;\r\n\r\n\t\tthis.bgname = \"gs4\";\r\n\t\t\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tthis.shoutTimer = 0;\r\n\t\tthis.textTimer = 0;\r\n\r\n\t\tthis._animating = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns whether or not the viewport is busy\r\n\t * performing a task (animating).\r\n\t */\r\n\tisAnimating() {\r\n\t\treturn this._animating;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the volume of the blip sound.\r\n\t * @param {number} volume\r\n\t */\r\n\tsetBlipVolume(volume) {\r\n\t\tfor (let i = 0; i < this.blipChannels.length; i++) {\r\n\t\t\tthis.blipChannels[i].volume = volume;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the path which the background is located in.\r\n\t */\r\n\tbgFolder() {\r\n\t\treturn `${AO_HOST}background/${this.bgname}/`;\r\n\t}\r\n\r\n\t/**\r\n\t * Sets a new emote.\r\n\t * @param {object} chatmsg the new chat message\r\n\t */\r\n\tsay(chatmsg) {\r\n\t\tthis.chatmsg = chatmsg;\r\n\t\tappendICLog(chatmsg.content, chatmsg.nameplate);\r\n\t\tchangeBackground(chatmsg.side);\r\n\t\tthis.textnow = '';\r\n\t\tthis.sfxplayed = 0;\r\n\t\tthis.textTimer = 0;\r\n\t\tthis._animating = true;\r\n\t\tclearTimeout(this.updater);\r\n\t\t//If preanim existed then determine the length\r\n\t\tif (chatmsg.preanim != \"-\") {\r\n\t\t\tchatmsg.preanimdelay = this.getAnimLength(AO_HOST + 'characters/' + escape(chatmsg.name) + '/' + chatmsg.preanim + '.gif',this.initUpdater);\r\n\t\t} else {\r\n\t\t\tthis.initUpdater(0)\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize updater\r\n\t * @param {int} animdelay the length of pre-animation \r\n\t */\r\n\tinitUpdater(animdelay){\r\n\t\tviewport.chatmsg.preanimdelay = parseInt(animdelay); \r\n\t\tviewport.updater = setTimeout(() => viewport.updateText(), UPDATE_INTERVAL);\r\n\t}\r\n\t\r\n\t/**\r\n\t * Intialize testimony updater \r\n\t */\r\n\tinitTestimonyUpdater(){\t\t\r\n\t\tif(client.testimonyID > 0){\t\t\t\r\n\t\t\tlet testimony = \"\";\r\n\t\t\tif (client.testimonyID == 1) {\r\n\t\t\t\ttestimony = \"witnesstestimony\";\t\t\t\t\r\n\t\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t\ttestimony = \"crossexamination\";\r\n\t\t\t}\r\n\t\t\t(new Audio(client.resources[testimony][\"sfx\"])).play();\r\n\t\t\tthis.testimonyTimer = 0;\r\n\t\t\tdocument.getElementById(\"client_testimony\").src = client.resources[testimony][\"src\"];\r\n\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\t\t\t\t\t\t\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Gets animation length.\r\n\t * @param {string} filename the animation file name\r\n\t * @param {function} callback the callback function\r\n\t * @param {object} param \r\n\t */\r\n\tgetAnimLength(filename, callback, param) {\r\n\t\tvar request = new XMLHttpRequest();\r\n\t\trequest.open('GET', filename, true);\r\n\t\trequest.responseType = 'arraybuffer';\r\n\t\trequest.addEventListener('load', function () {\r\n\t\t\t// Use gify API\r\n\t\t\t// https://github.com/rfrench/gify\r\n\t\t\tvar gifInfo = gify.getInfo(request.response);\r\n\t\t\tconsole.log(gifInfo[\"duration\"]);\r\n\t\t\t// Return animation length\r\n\t\t\tcallback(gifInfo[\"duration\"], param);\r\n\t\t});\r\n\t\trequest.send();\r\n\t}\r\n\t\r\n\t/**\r\n\t * Updates the testimony overaly\r\n\t */\r\n\tupdateTestimony(){\r\n\t\t//Update timer\r\n\t\tthis.testimonyTimer = this.testimonyTimer + UPDATE_INTERVAL;\r\n\t\t\r\n\t\tif (client.testimonyID == 1) {\r\n\t\t\t//Witness Testimony\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"witnesstestimony\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\t\t\t\r\n\t\t} else if (client.testimonyID == 2) {\r\n\t\t\t//Cross Examination\r\n\t\t\tif (this.testimonyTimer >= client.resources[\"crossexamination\"][\"duration\"]){\r\n\t\t\t\t//Finish\r\n\t\t\t\tthis.disposeTestimony();\r\n\t\t\t} else {\r\n\t\t\t\tthis.testimonyUpdater = setTimeout(() => this.updateTestimony(), UPDATE_INTERVAL);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.disposeTestimony();\r\n\t\t}\r\n\t}\r\n\t\r\n\t/**\r\n\t * Dispose the testimony overlay\r\n\t */\r\n\t disposeTestimony(){\r\n\t\tclient.testimonyID = 0;\r\n\t\tthis.testimonyTimer = 0;\r\n\t\tdocument.getElementById(\"client_testimony\").src = \"misc/placeholder.gif\";\r\n\t\tclearTimeout(this.testimonyUpdater);\r\n\t }\r\n\t \r\n\t/**\r\n\t * Updates the chatbox based on the given text.\r\n\t * \r\n\t * XXX: This relies on a global variable `this.chatmsg`!\r\n\t */\r\n\tupdateText() {\r\n\t\t// Flip the character\r\n\t\tif (this.chatmsg.flip == 1){\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(-1)\"; \r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_char\").style.transform = \"scaleX(1)\";\r\n\t\t}\r\n\t\t\t\r\n\t\tif (this._animating) {\r\n\t\t\tthis.updater = setTimeout(() => this.updateText(), UPDATE_INTERVAL);\r\n\t\t}\r\n\r\n\t\tif (this.chatmsg.isnew) {\r\n\t\t\t// Reset screen background\r\n\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"transparent\";\r\n\t\t\t//Hide message and evidence window\r\n\t\t\tdocument.getElementById(\"client_name\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_chat\").style.display = \"none\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.opacity = \"0\";\r\n\t\t\tdocument.getElementById(\"client_evi\").style.height = \"0%\";\r\n\t\t\tconst shouts = {\r\n\t\t\t\t\"1\": \"holdit\",\r\n\t\t\t\t\"2\": \"objection\",\r\n\t\t\t\t\"3\": \"takethat\"\r\n\t\t\t};\r\n\r\n\t\t\tlet shout = shouts[this.chatmsg.objection];\r\n\t\t\tif (typeof shout !== \"undefined\") {\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = client.resources[shout][\"src\"];\r\n\t\t\t\t(new Audio(`${AO_HOST}/characters/${this.chatmsg.name}/${shout}.wav`)).play();\r\n\t\t\t\tthis.shoutTimer = 850;\r\n\t\t\t} else {\r\n\t\t\t\tthis.shoutTimer = 0;\r\n\t\t\t}\r\n\r\n\t\t\tthis.chatmsg.isnew = false;\r\n\t\t\tthis.chatmsg.startpreanim = true;\r\n\t\t}\r\n\r\n\t\tif(this.textTimer >= this.shoutTimer && this.chatmsg.startpreanim) {\r\n\t\t\t// Effect stuff\r\n\t\t\tif (this.chatmsg.flash == 2){\r\n\t\t\t\t//Shake screen\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-stab.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect( \"shake\",{\"direction\":\"up\"});\r\n\t\t\t} else if (this.chatmsg.flash == 1) {\r\n\t\t\t\t//Flash screen\r\n\t\t\t\tdocument.getElementById(\"client_background\").style.backgroundColor = \"white\";\r\n\t\t\t\tthis.sfxaudio.pause();\r\n\t\t\t\tthis.sfxplayed = 1;\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/sfx-realization.wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t\t$('#client_gamewindow').effect(\"pulsate\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//Pre-animation stuff\r\n\t\t\tif(this.chatmsg.preanimdelay > 0){\r\n\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.preanim + \".gif\";\r\n\t\t\t}\r\n\t\t\tthis.chatmsg.startpreanim = false;\r\n\t\t\tthis.chatmsg.startspeaking = true;\r\n\t\t} else if (this.textTimer >= this.shoutTimer + this.chatmsg.preanimdelay && !this.chatmsg.startpreanim) {\r\n\t\t\tif (this.chatmsg.startspeaking) {\r\n\t\t\t\tif(this.chatmsg.evidence > 0){\r\n\t\t\t\t\t// Prepare evidence\r\n\t\t\t\t\tdocument.getElementById(\"client_evi\").style.backgroundImage = \"url('\"+ client.evidences[this.chatmsg.evidence - 1].icon +\"')\";\r\n\t\t\t\t\r\n\t\t\t\t\tif (this.chatmsg.side == 'def'){\r\n\t\t\t\t\t\t// Only def show evidence on right\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"1.5em\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"initial\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.right = \"initial\";\r\n\t\t\t\t\t\tdocument.getElementById(\"client_evi\").style.left = \"1.5em\";\r\n\t\t\t\t\t\t$( \"#client_evi\" ).animate({\r\n\t\t\t\t\t\t\theight: \"30%\",\r\n\t\t\t\t\t\t\topacity: 1\r\n\t\t\t\t\t\t}, 250 );\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$(\"#client_name\").toggle( \"fade\" );\r\n\t\t\t\t$(\"#client_chat\").toggle(\"drop\",{\"direction\":\"down\"});\r\n\t\t\t\tif(this.chatmsg.preanimdelay == 0){\r\n\t\t\t\t\tdocument.getElementById(\"client_shout\").src = \"misc/placeholder.gif\";\r\n\t\t\t\t\tchangeBackground(this.chatmsg.side);\r\n\t\t\t\t}\r\n\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.speaking + \".gif\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").style.fontSize = (document.getElementById(\"client_name\").offsetHeight * 0.7) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_chat\").style.fontSize = (document.getElementById(\"client_chat\").offsetHeight * 0.25) + \"px\";\r\n\t\t\t\tdocument.getElementById(\"client_name\").innerHTML = \"<p>\" + escapeHtml(this.chatmsg.nameplate) + \"</p>\";\r\n\r\n\t\t\t\tconst colors = {\r\n\t\t\t\t\t\"0\": \"#ffffff\",\r\n\t\t\t\t\t\"1\": \"#00ff00\",\r\n\t\t\t\t\t\"2\": \"#ff0000\",\r\n\t\t\t\t\t\"3\": \"#ffaa00\",\r\n\t\t\t\t\t\"4\": \"#0000ff\",\r\n\t\t\t\t\t\"5\": \"#ffff00\",\r\n\t\t\t\t\t\"6\": \"#aa00aa\"\r\n\t\t\t\t}\r\n\t\t\t\tlet stylecolor = \"color: \" + (colors[this.chatmsg.color] || \"#ffffff\");\r\n\t\t\t\tdocument.getElementById(\"client_inner_chat\").style = stylecolor;\r\n\t\t\t\tthis.chatmsg.startspeaking = false;\r\n\r\n\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.textnow != this.chatmsg.content) {\r\n\t\t\t\t\tif (this.chatmsg.content.charAt(this.textnow.length) != \" \") {\r\n\t\t\t\t\t\tthis.blipChannels[this.currentBlipChannel].play();\r\n\t\t\t\t\t\tthis.currentBlipChannel++;\r\n\t\t\t\t\t\tthis.currentBlipChannel %= this.blipChannels.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.textnow = this.chatmsg.content.substring(0, this.textnow.length + 1);\r\n\t\t\t\t\tdocument.getElementById(\"client_inner_chat\").innerHTML = this.textnow;\r\n\t\t\t\t\tif (this.textnow == this.chatmsg.content) {\r\n\t\t\t\t\t\tthis.textTimer = 0;\r\n\t\t\t\t\t\tthis._animating = false;\r\n\t\t\t\t\t\tdocument.getElementById(\"client_char\").src = AO_HOST + \"characters/\" + escape(this.chatmsg.name) + \"/\" + this.chatmsg.silent + \".gif\";\r\n\t\t\t\t\t\tclearTimeout(this.updater);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tif (!this.sfxplayed && this.chatmsg.snddelay + this.shoutTimer >= this.textTimer) {\r\n\t\t\tthis.sfxaudio.pause();\r\n\t\t\tthis.sfxplayed = 1;\r\n\t\t\tif (this.chatmsg.sound != \"0\" && this.chatmsg.sound != \"1\") {\r\n\t\t\t\tthis.sfxaudio.src = AO_HOST + \"sounds/general/\" + escape(this.chatmsg.sound) + \".wav\";\r\n\t\t\t\tthis.sfxaudio.play();\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.textTimer = this.textTimer + UPDATE_INTERVAL;\r\n\t}\r\n}\r\n\r\nclass INI {\r\n\tstatic parse(data) {\r\n\t\tlet regex = {\r\n\t\t\tsection: /^\\s*\\[\\s*([^\\]]*)\\s*\\]\\s*$/,\r\n\t\t\tparam: /^\\s*([\\w\\.\\-\\_]+)\\s*=\\s*(.*?)\\s*$/,\r\n\t\t\tcomment: /^\\s*;.*$/\r\n\t\t};\r\n\t\tlet value = {};\r\n\t\tlet lines = data.split(/\\r\\n|\\r|\\n/);\r\n\t\tlet section = null;\r\n\t\tlines.forEach(function(line) {\r\n\t\t\tif (regex.comment.test(line)) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (line.length == 0) {\r\n\t\t\t\treturn;\r\n\t\t\t} else if (regex.param.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.param);\r\n\t\t\t\tif (section) {\r\n\t\t\t\t\tvalue[section][match[1]] = match[2];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalue[match[1]] = match[2];\r\n\t\t\t\t}\r\n\t\t\t} else if (regex.section.test(line)) {\r\n\t\t\t\tlet match = line.match(regex.section);\r\n\t\t\t\tvalue[match[1]] = {};\r\n\t\t\t\tsection = match[1];\r\n\t\t\t};\r\n\t\t});\r\n\t\treturn value;\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the out-of-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onOOCEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tclient.sendOOC(document.getElementById(\"client_oocinputbox\").value);\r\n\t\tdocument.getElementById(\"client_oocinputbox\").value = \"\";\r\n\t}\r\n}\r\nwindow.onOOCEnter = onOOCEnter;\r\n\r\n/**\r\n * Triggered when the Return key is pressed on the in-character chat input box.\r\n * @param {KeyboardEvent} event\r\n */\r\nexport function onEnter(event) {\r\n\tif (event.keyCode == 13) {\r\n\t\tlet mychar = client.me();\r\n\t\tlet myemo = client.myEmote();\r\n\t\tlet myevi = client.myEvidence();\r\n\t\tlet myflip = ((client.flip)? 1:0);\r\n\t\tlet mycolor = document.getElementById(\"textcolor\").value;\r\n\t\tlet ssfxname = \"0\";\r\n\t\tlet ssfxdelay = \"0\";\r\n\t\tif (document.getElementById(\"sendsfx\").checked) {\r\n\t\t\tssfxname = myemo.sfx;\r\n\t\t\tssfxdelay = myemo.sfxdelay;\r\n\t\t}\r\n\t\tclient.sendIC(myemo.speaking, mychar.name, myemo.silent, document.getElementById(\"client_inputbox\").value, mychar.side, ssfxname, myemo.zoom, ssfxdelay, selectedShout, myevi, myflip, selectedEffect, mycolor);\r\n\t}\r\n}\r\nwindow.onEnter = onEnter;\r\n\r\n/**\r\n * Resets the IC parameters for the player to enter a new chat message.\r\n * This should only be called when the player's previous chat message\r\n * was successfully sent/presented.\r\n */\r\nfunction resetICParams() {\r\n\tdocument.getElementById(\"client_inputbox\").value = \"\";\r\n\tif (selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t}\r\n\tif (selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t}\t\t\r\n}\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function musiclist_click(event) {\r\n\tlet playtrack = document.getElementById(\"client_musiclist\").value;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.musiclist_click = musiclist_click;\r\n\r\n/**\r\n * Triggered when an item on the music list is clicked.\r\n * @param {MouseEvent} event\r\n */\r\nexport function area_click(el) {\r\n\tlet playtrack =  el.textContent;\r\n\tclient.sendMusicChange(playtrack);\r\n}\r\nwindow.area_click = area_click;\r\n\r\n/**\r\n * Triggered by the music volume slider.\r\n */\r\nexport function changeMusicVolume() {\r\n\tviewport.music.volume = document.getElementById(\"client_mvolume\").value / 100;\r\n}\r\nwindow.changeMusicVolume = changeMusicVolume;\r\n\r\n/**\r\n * Triggered by the sound effect volume slider.\r\n */\r\nexport function changeSFXVolume() {\r\n\tviewport.sfxaudio.volume = document.getElementById(\"client_svolume\").value / 100;\r\n}\r\nwindow.changeSFXVolume = changeSFXVolume;\r\n\r\n/**\r\n * Triggered by the blip volume slider.\r\n */\r\nexport function changeBlipVolume() {\r\n\tviewport.setBlipVolume(document.getElementById(\"client_bvolume\").value / 100);\r\n}\r\nwindow.changeBlipVolume = changeBlipVolume;\r\n\r\n/**\r\n * Triggered when a character icon is clicked in the character selection menu.\r\n * @param {MouseEvent} event\r\n */\r\nexport function changeCharacter(event) {\r\n\tclient.sendLeaveRoom();\r\n\tdocument.getElementById(\"client_charselect\").style.display = \"block\";\r\n\tdocument.getElementById(\"client_emo\").innerHTML = \"\";\r\n}\r\nwindow.changeCharacter = changeCharacter;\r\n\r\n/**\r\n * Triggered when there was an error loading a character sprite.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function imgError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"misc/placeholder.gif\";\r\n\treturn true;\r\n}\r\nwindow.imgError = imgError;\r\n\r\n/**\r\n * Triggered when there was an error loading a character icon.\r\n * @param {HTMLImageElement} image the element containing the missing image\r\n */\r\nexport function demoError(image) {\r\n\timage.onerror = \"\";\r\n\timage.src = \"/misc/placeholder.png\";\r\n\treturn true;\r\n}\r\nwindow.demoError = demoError;\r\n\r\n/**\r\n * Checks if an file exists at the specified URI.\r\n * @param {string} url the URI to be checked\r\n * @param {function} callback the function to be called when finished\r\n * @param {object} param \r\n */\r\nfunction FileExist(url,callback,param) {\r\n\tvar xhttp = new XMLHttpRequest();\r\n\txhttp.onreadystatechange = function() {\r\n\t\tif (this.readyState == 4 && this.status == 200) {\r\n\t\t\tcallback(true, param, url);\r\n\t\t} else {\r\n\t\t\tcallback(false, param, url);\r\n\t\t}\r\n\t};\r\n\txhttp.open(\"GET\", url, true);\r\n\txhttp.send();\r\n}\r\n\r\n/**\r\n * Changes the viewport background based on a given position.\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {string} position the position to change into\r\n */\r\nfunction changeBackground(position) {\r\n\tvar standname;\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tdocument.getElementById(\"client_fg\").style.display = \"none\";\r\n\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\tswitch (position) {\r\n\t\tcase \"def\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"defenseempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\";\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"pro\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prosecutorempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tFileExist(bgfolder + \"defensedesk.png\", callbackChangeBackground, position);\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"hld\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"helperstand.png\"\r\n\t\t\tstandname = \"defense\";\r\n\t\t\tbreak;\r\n\t\tcase \"hlp\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"prohelperstand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"wit\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"witnessempty.png\"\r\n\t\t\tdocument.getElementById(\"client_bench\").style.display = \"block\"\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"estrado.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t\tcase \"jud\":\r\n\t\t\tdocument.getElementById(\"client_court\").src = bgfolder + \"judgestand.png\"\r\n\t\t\tstandname = \"prosecution\";\r\n\t\t\tbreak;\r\n\t}\r\n\tif (viewport.chatmsg.type == 5) {\r\n\t\tdocument.getElementById(\"client_bench\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_court\").src = AO_HOST + \"themes/default/\" + standname + \"_speedlines.gif\";\r\n\t}\r\n}\r\n\r\n/**\r\n * Callback for desk resource\r\n * \r\n * Valid positions: `def, pro, hld, hlp, wit, jud`\r\n * @param {boolean} result the image is existed or not\r\n * @param {string} position the position to change into\r\n */\r\nfunction callbackChangeBackground(result,position) {\r\n\tlet bgfolder = viewport.bgFolder();\r\n\tif (position == \"def\"){\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"defensedesk.png\"\r\n\t\t}else{\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancodefensa.png\"\r\n\t\t}\r\n\t} else {\r\n\t\tif(result){\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"prosecutiondesk.png\"\r\n\t\t} else {\r\n\t\t\tdocument.getElementById(\"client_bench\").src = bgfolder + \"bancoacusacion.png\"\r\n\t\t}\t\t\t\r\n\t}\r\n}\r\n\r\n/**\r\n * Triggered when the reconnect button is pushed.\r\n */\r\nexport function ReconnectButton() {\r\n\tclient.cleanup();\r\n\tclient = new Client(serverIP);\r\n\tif (client) {\r\n\t\tmode = \"join\"; // HACK: see client.onOpen\r\n\t\tdocument.getElementById(\"client_error\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.ReconnectButton = ReconnectButton;\r\n\r\n/**\r\n * Triggered when the retry button is pushed (during the loading process).\r\n */\r\nexport function RetryButton() {\r\n\tclient.joinServer();\r\n}\r\nwindow.RetryButton = RetryButton;\r\n\r\n/**\r\n * Appends a message to the in-character chat log.\r\n * @param {string} toadd the string to be added\r\n * @param {string} name the name of the sender\r\n */\r\nfunction appendICLog(toadd, name = \"\", time = new Date()) {\r\n\tconst entry = document.createElement(\"p\");\r\n\tconst nameField = document.createElement(\"span\");\r\n\tnameField.id = \"iclog_name\";\r\n\tnameField.appendChild(document.createTextNode(name));\r\n\tentry.appendChild(nameField);\r\n\tentry.appendChild(document.createTextNode(toadd));\r\n\r\n\t// Only put a timestamp if the minute has changed.\r\n\tif (lastICMessageTime.getMinutes() !== time.getMinutes()) {\r\n\t\tconst timeStamp = document.createElement(\"span\");\r\n\t\ttimeStamp.id = \"iclog_time\";\r\n\t\ttimeStamp.innerText = time.toLocaleTimeString(undefined, {\r\n\t\t\thour: \"numeric\",\r\n\t\t\tminute: \"2-digit\"\r\n\t\t});\r\n\t\tentry.appendChild(timeStamp);\r\n\t}\r\n\r\n\tconst clientLog = document.getElementById(\"client_log\");\r\n\tclientLog.appendChild(entry);\r\n\r\n\tif (clientLog.scrollTop > clientLog.scrollHeight - 600) {\r\n\t\tclientLog.scrollTop = clientLog.scrollHeight;\r\n\t}\r\n\r\n\tlastICMessageTime = new Date();\r\n}\r\n\r\n/**\r\n * Requests to play as a character.\r\n * @param {number} ccharacter the character ID; if this is a large number, then spectator is chosen instead.\r\n */\r\nexport function pickchar(ccharacter) {\r\n\tif (ccharacter < 1000) {\r\n\t\tclient.sendCharacter(ccharacter);\r\n\t} else {\r\n\t\t// Spectator\r\n\t\tdocument.getElementById(\"client_charselect\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_inputbox\").style.display = \"none\";\r\n\t\tdocument.getElementById(\"client_emo\").style.display = \"none\";\r\n\t}\r\n}\r\nwindow.pickchar = pickchar;\r\n\r\n/**\r\n * Highlights and selects an emotion for in-character chat.\r\n * @param {string} emo the new emotion to be selected\r\n */\r\nexport function pickemotion(emo) {\r\n\tif (client.selectedEmote != -1) {\r\n\t\tdocument.getElementById(\"emo_\" + client.selectedEmote).src = client.myEmote().button_off;\r\n\t}\r\n\tclient.selectedEmote = emo\r\n\tdocument.getElementById(\"emo_\" + emo).src = client.myEmote().button_on;\r\n}\r\nwindow.pickemotion = pickemotion;\r\n\r\n/**\r\n * Highlights and selects an evidence for in-character chat.\r\n * @param {string} evidence the evidence to be presented\r\n */\r\nexport function pickevidence(evidence) {\r\n\tif (client.selectedEvidence != evidence) {\r\n\t\t//Update selected evidence\t\t\r\n\t\tif(client.selectedEvidence > 0){\r\n\t\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t\t}\r\n\t\tdocument.getElementById(\"evi_\" + evidence).className = \"client_button dark\";\r\n\t\tclient.selectedEvidence = evidence;\r\n\t\t\r\n\t\t// Show evidence on information window\r\n\t\tdocument.getElementById(\"evi_name\").value = client.evidences[evidence - 1].name;\r\n\t\tdocument.getElementById(\"evi_desc\").value = client.evidences[evidence - 1].desc;\r\n\r\n\t\t//Update Icon\r\n\t\tlet icon_id  = getIndexFromSelect(\"evi_select\", client.evidences[evidence - 1].filename);\r\n\t\tdocument.getElementById(\"evi_select\").selectedIndex = icon_id;\r\n\t\tif (icon_id == 0){\t\t\t\r\n\t\t\tdocument.getElementById(\"evi_filename\").value = client.evidences[evidence - 1].filename;\r\n\t\t}\r\n\t\tupdateEvidenceIcon();\r\n\t\t\r\n\t\t// Update button\r\n\t\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button inactive\";\r\n\t\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button\";\r\n\t\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button\";\r\n\t} else {\r\n\t\tcancelevidence();\r\n\t}\r\n}\r\nwindow.pickevidence = pickevidence;\r\n\r\n/**\r\n * Add evidence.\r\n */\r\nexport function addevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tclient.sendPE( document.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text   \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.addevidence = addevidence;\r\n\r\n/**\r\n * Edit selected evidence.\r\n */\r\nexport function editevidence() {\r\n\tlet evidence_select = document.getElementById('evi_select');\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendEE( id, \r\n\t\tdocument.getElementById('evi_name').value,\r\n\t\tdocument.getElementById('evi_desc').value,\r\n\t\t(evidence_select.selectedIndex == 0)? \r\n\t\t\tdocument.getElementById('evi_filename').value : \r\n\t\t\tevidence_select.options[evidence_select.selectedIndex].text   \r\n\t\t);\r\n\tcancelevidence();\r\n}\r\nwindow.editevidence = editevidence;\r\n\r\n/**\r\n * Delete selected evidence.\r\n */\r\nexport function delevidence() {\r\n\tlet id = parseInt(client.selectedEvidence) - 1;\r\n\tclient.sendDE(id);\r\n\tcancelevidence();\r\n}\r\nwindow.delevidence = delevidence;\r\n\r\n/**\r\n * Cancel evidence selection.\r\n */\r\nexport function cancelevidence() {\r\n\t//Clear evidence data\r\n\tif(client.selectedEvidence > 0){\r\n\t\tdocument.getElementById(\"evi_\" + client.selectedEvidence).className = \"client_button\";\r\n\t}\r\n\tclient.selectedEvidence = 0;\r\n\t\r\n\t// Clear evidence on information window\r\n\tdocument.getElementById(\"evi_select\").selectedIndex = 0;\r\n\tupdateEvidenceIcon(); // Update icon widget\r\n\tdocument.getElementById(\"evi_filename\").value = \"\";\r\n\tdocument.getElementById(\"evi_name\").value = \"\";\r\n\tdocument.getElementById(\"evi_desc\").value = \"\";\r\n\tdocument.getElementById(\"evi_icon\").style.backgroundImage = \"url('misc/empty.png')\"; //Clear icon\r\n\t\r\n\t// Update button\r\n\tdocument.getElementById(\"evi_add\").className = \"client_button hover_button\";\r\n\tdocument.getElementById(\"evi_edit\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_cancel\").className = \"client_button hover_button inactive\";\r\n\tdocument.getElementById(\"evi_del\").className = \"client_button hover_button inactive\";\r\n}\r\nwindow.cancelevidence = cancelevidence;\r\n\r\n/**\r\n * Find index of anything in select box.\r\n * @param {string} select_box the select element name\r\n * @param {string} value the value that need to be compared\r\n */\r\nexport function getIndexFromSelect(select_box, value) {\r\n\t\t//Find if icon alraedy existed in select box\r\n\t\tlet select_element = document.getElementById(select_box);\r\n\t\tfor (let i = 1; i < select_element.length; ++i){\r\n\t\t\tif (select_element.options[i].value == value){\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn 0;\r\n}\r\nwindow.getIndexFromSelect = getIndexFromSelect;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateEvidenceIcon() {\r\n\tlet evidence_select = document.getElementById(\"evi_select\");\r\n\tlet evidence_filename = document.getElementById(\"evi_filename\");\r\n\tlet evidence_iconbox = document.getElementById(\"evi_icon\");\r\n\t\r\n\tif (evidence_select.selectedIndex == 0) {\r\n\t\tevidence_filename.style.display = \"initial\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_filename.value + \"')\";\r\n\t} else {\t\t\r\n\t\tevidence_filename.style.display = \"none\";\r\n\t\tevidence_iconbox.style.backgroundImage = \"url('\" + AO_HOST + 'evidence/' + evidence_select.value + \"')\" ;\r\n\t}\r\n}\r\nwindow.updateEvidenceIcon = updateEvidenceIcon;\r\n\r\n/**\r\n * Update evidence icon.\r\n */\r\nexport function updateActionCommands(side) {\r\n\tif(side == \"jud\"){\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"none\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"no_action\").style.display = \"inline-table\";\r\n\t\tdocument.getElementById(\"judge_action\").style.display = \"none\";\r\n\t}\r\n\t//Update role selector\r\n\tfor(let i = 0, role_select = document.getElementById(\"role_select\").options; i < role_select.length; i++){\r\n\t\t\tif(side == role_select[i].value){\r\n\t\t\t\trole_select.selectedIndex = i;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t}\r\n}\r\nwindow.updateActionCommands = updateActionCommands;\r\n\r\n/**\r\n * Change background via OOC.\r\n */\r\nexport function changeBackgroundOOC() {\r\n\tlet filename = \"\", background_select = document.getElementById(\"bg_select\")\r\n\t\t, bg_command = document.getElementById(\"bg_command\").value;\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tfilename = document.getElementById(\"bg_filename\").value; \r\n\t} else{\r\n\t\tfilename = background_select.value;\r\n\t}\r\n\tclient.sendOOC(\"/\" + bg_command.replace(\"$1\",filename));\r\n}\r\nwindow.changeBackgroundOOC = changeBackgroundOOC;\r\n\r\n/**\r\n * Change role via OOC.\r\n */\r\nexport function changeRoleOOC() {\r\n\tlet role_select = document.getElementById(\"role_select\")\r\n\t\t, role_command = document.getElementById(\"role_command\").value;\r\n\t\t\r\n\tclient.sendOOC(\"/\" + role_command.replace(\"$1\",role_select.value));\r\n\tupdateActionCommands(role_select.value);\r\n}\r\nwindow.changeRoleOOC = changeRoleOOC;\r\n\r\n/**\r\n * Random character via OOC.\r\n */\r\nexport function randomCharacterOOC() {\t\t\r\n\tclient.sendOOC(\"/\" + document.getElementById(\"randomchar_command\").value);\r\n}\r\nwindow.randomCharacterOOC = randomCharacterOOC;\r\n\r\n/**\r\n * Call mod.\r\n */\r\nexport function callmod() {\t\r\n\t$( \"#callmod_dialog\" ).dialog( \"open\" );\t\r\n}\r\nwindow.callmod = callmod;\r\n\r\n/**\r\n * Decalre witness testimony.\r\n */\r\nexport function initwt() {\t\t\r\n\tclient.sendRT(\"testimony1\");\r\n}\r\nwindow.initwt = initwt;\r\n\r\n/**\r\n * Decalre cross examination.\r\n */\r\nexport function initce() {\t\t\r\n\tclient.sendRT(\"testimony2\");\r\n}\r\nwindow.initce = initce;\r\n\r\n/**\r\n * Add defense health point.\r\n */\r\nexport function addHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) + 1));\r\n}\r\nwindow.addHPD = addHPD;\r\n\r\n/**\r\n * Reduce defense health point.\r\n */\r\nexport function redHPD() {\t\t\r\n\tclient.sendHP(1,String(parseInt(client.hp[0]) - 1));\r\n}\r\nwindow.redHPD = redHPD;\r\n\r\n/**\r\n * Add prosecution health point.\r\n */\r\nexport function addHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) + 1));\r\n}\r\nwindow.addHPP = addHPP;\r\n\r\n/**\r\n * Reduce prosecution health point.\r\n */\r\nexport function redHPP() {\t\t\r\n\tclient.sendHP(2,String(parseInt(client.hp[1]) - 1));\r\n}\r\nwindow.redHPP = redHPP;\r\n\r\n/**\r\n * Update background preview.\r\n */\r\nexport function updateBackgroundPreview() {\r\n\tlet background_select = document.getElementById(\"bg_select\");\r\n\tlet background_filename = document.getElementById(\"bg_filename\");\r\n\tlet background_preview = document.getElementById(\"bg_preview\");\r\n\t\r\n\tif (background_select.selectedIndex == 0) {\r\n\t\tbackground_filename.style.display = \"initial\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_filename.value + \"/defenseempty.png\";\r\n\t} else {\r\n\t\tbackground_filename.style.display = \"none\";\r\n\t\tbackground_preview.src = AO_HOST + 'background/' + background_select.value + \"/defenseempty.png\";\r\n\t}\r\n}\r\nwindow.updateBackgroundPreview = updateBackgroundPreview;\r\n\r\n/**\r\n * Highlights and selects an effect for in-character chat.\r\n * If the same effect button is selected, then the effect is canceled.\r\n * @param {string} effect the new effect to be selected\r\n */\r\nexport function toggleaffect(effect) {\r\n\tif (effect == selectedEffect) {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button\";\r\n\t\tselectedEffect = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_effect_\" + effect).className = \"client_button dark\";\r\n\t\tif (selectedEffect) {\r\n\t\t\tdocument.getElementById(\"button_effect_\" + selectedEffect).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedEffect = effect;\r\n\t}\r\n}\r\nwindow.toggleaffect = toggleaffect;\r\n\r\n/**\r\n * Toggle flip for in-character chat.\r\n */\r\nexport function toggleflip() {\r\n\tif (client.flip) {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_flip\").className = \"client_button dark\";\r\n\t}\r\n\tclient.flip = !client.flip;\r\n}\r\nwindow.toggleflip = toggleflip;\r\n\r\n/**\r\n * Toggle presentable for presenting evidence in-character chat.\r\n */\r\nexport function togglepresent() {\r\n\tif (client.presentable) {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button\";\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_present\").className = \"client_button dark\";\r\n\t}\r\n\tclient.presentable = !client.presentable;\r\n}\r\nwindow.togglepresent = togglepresent;\r\n\r\n/**\r\n * Highlights and selects a menu.\r\n * @param {string} menu the menu to be selected\r\n */\r\nexport function togglemenu(menu) {\r\n\tif (menu != selectedMenu) {\r\n\t\tdocument.getElementById(\"menu_\" + menu).className = \"menu_icon active\";\r\n\t\tdocument.getElementById(\"content_\" + menu).className = \"menu_content active\";\r\n\t\tdocument.getElementById(\"menu_\" + selectedMenu).className = \"menu_icon\";\r\n\t\tdocument.getElementById(\"content_\" + selectedMenu).className = \"menu_content\";\r\n\t\tselectedMenu = menu;\r\n\t}\r\n}\r\nwindow.togglemenu = togglemenu;\r\n\r\n/**\r\n * Highlights and selects a shout for in-character chat.\r\n * If the same shout button is selected, then the shout is canceled.\r\n * @param {string} shout the new shout to be selected\r\n */\r\nexport function toggleshout(shout) {\r\n\tif (shout == selectedShout) {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button\";\r\n\t\tselectedShout = 0;\r\n\t} else {\r\n\t\tdocument.getElementById(\"button_\" + shout).className = \"client_button dark\";\r\n\t\tif (selectedShout) {\r\n\t\t\tdocument.getElementById(\"button_\" + selectedShout).className = \"client_button\";\r\n\t\t}\r\n\t\tselectedShout = shout;\r\n\t}\r\n}\r\nwindow.toggleshout = toggleshout;\r\n\r\n/**\r\n * Escapes a string to be HTML-safe.\r\n * \r\n * XXX: This is unnecessary if we use `createTextNode` instead!\r\n * @param {string} unsafe an unsanitized string\r\n */\r\nfunction escapeHtml(unsafe) {\r\n\treturn unsafe\r\n\t\t.replace(/&/g, \"&amp;\")\r\n\t\t.replace(/</g, \"&lt;\")\r\n\t\t.replace(/>/g, \"&gt;\")\r\n\t\t.replace(/\"/g, \"&quot;\")\r\n\t\t.replace(/'/g, \"&#039;\");\r\n}\r\n\r\n/**\r\n * Escapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be escaped\r\n */\r\nfunction escapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/#/g, \"<pound>\")\r\n\t\t.replace(/&/g, \"<and>\")\r\n\t\t.replace(/%/g, \"<percent>\")\r\n\t\t.replace(/\\$/g, \"<dollar>\");\r\n}\r\n\r\n/**\r\n * Unescapes a string to AO1 escape codes.\r\n * @param {string} estring the string to be unescaped\r\n */\r\nfunction unescapeChat(estring) {\r\n\treturn estring\r\n\t\t.replace(/<pound>/g, \"#\")\r\n\t\t.replace(/<and>/g, \"&\")\r\n\t\t.replace(/<percent>/g, \"%\")\r\n\t\t.replace(/<dollar>/g, \"$\");\r\n}\r\n\r\n/**\r\n * Encoding text on client side.\r\n * @param {string} estring the string to be encoded\r\n */\r\nfunction encodeChat(estring) {\r\n\tlet selectedEncoding = document.getElementById(\"client_encoding\").value;\r\n\tif (selectedEncoding == \"unicode\") {\r\n\t\t//Source: https://gist.github.com/mathiasbynens/1243213\r\n\t\treturn estring.replace(/[^\\0-~]/g, function(ch) {\r\n\t\t\treturn \"\\\\u\" + (\"000\" + ch.charCodeAt().toString(16)).slice(-4); });\r\n\t} else if (selectedEncoding == \"utf16\"){\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\tvar buffer = new ArrayBuffer(estring.length*2);\r\n\t\tvar result = new Uint16Array(buffer);\r\n\t\tfor (var i=0, strLen=estring.length; i < strLen; i++) {\r\n\t\t\tresult[i] = estring.charCodeAt(i);\r\n\t\t}\r\n\t\treturn String(result);\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeChat(estring) {\r\n\tlet selectedDecoding = document.getElementById(\"client_decoding\").value;\r\n\tif (selectedDecoding == \"unicode\") {\r\n\t\t//Source: https://stackoverflow.com/questions/7885096/how-do-i-decode-a-string-with-escaped-unicode\r\n        return estring.replace(/\\\\u([\\d\\w]{1,})/gi, function (match, group) {\r\n\t\t\treturn String.fromCharCode(parseInt(group, 16)); } );\r\n\t} else if (selectedDecoding == \"utf16\"){\t\r\n\t\t//Source: https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\r\n\t\treturn String.fromCharCode.apply(null, new Uint16Array(estring.split(\",\")));\r\n\t} else {\r\n\t\treturn estring;\r\n\t}\r\n}\r\n\r\n/**\r\n * Decoding text on client side.\r\n * @param {string} estring the string to be decoded\r\n */\r\nfunction decodeBBCode(estring) {\r\n\treturn estring\r\n\t\t.replace(/\\\\n/g, \"<br>\") // Newline \\n\r\n\t\t.replace(/\\[(\\/?)b\\]/g, \"<$1b>\") // Bold [b][/b]\r\n\t\t.replace(/\\[(\\/?)i\\]/g, \"<$1i>\") // Italic [i][/i]\r\n\t\t.replace(/\\[(\\/?)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, '<m a=\"$1\">') // Markup [m=#0ff]\r\n\t\t.replace(/\\[(\\/?)m\\]/g, '<$1m>') // [m][/m]\r\n\t\t.replace(/\\[c=?([#a-zA-Z0-9]+)\\]/g, '<c a=\"$1\">') // Color [c=red]\r\n\t\t.replace(/\\[\\/c\\]/g, '</c>'); // [/c]\r\n}\r\n\r\n\r\n// TODO: Possibly safe to remove, since we are using a transpiler.\r\nif (typeof(String.prototype.trim) === \"undefined\")\r\n{\r\n    String.prototype.trim = function() \r\n    {\r\n        return String(this).replace(/^\\s+|\\s+$/g, '');\r\n    };\r\n}\r\n\r\n// Used for HDID calculation.\r\nString.prototype.hashCode = function() {\r\n\tvar hash = 0, i, chr;\r\n\tif (this.length === 0) return hash;\r\n\tfor (i = 0; i < this.length; i++) {\r\n\t  chr   = this.charCodeAt(i);\r\n\t  hash  = ((hash << 5) - hash) + chr;\r\n\t  hash |= 0; // Convert to 32bit integer\r\n\t}\r\n\treturn hash;\r\n};\r\n\r\n\r\n//\r\n// Client code\r\n//\r\n\r\nlet client = new Client(serverIP);\r\nlet viewport = new Viewport();\r\n\r\n$(document).ready(function(){\r\n\tclient.initialObservBBCode();\r\n\tclient.loadResources(); \r\n\t\r\n});\r\n\r\n// Create dialog and link to button\t\r\n$( function() {\r\n\t$( \"#callmod_dialog\" ).dialog({\r\n\t\tautoOpen: false,\r\n\t\tresizable: false,\r\n\t\tshow: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\thide: {\r\n\t\t\teffect: \"drop\",\r\n\t\t\tdirection:\"down\",\r\n\t\t\tduration: 500\r\n\t\t},\r\n\t\theight: \"auto\",\r\n\t\twidth: 400,\r\n\t\tmodal: true,\r\n\t\tbuttons: {\r\n\t\t\t\"Sure\": function() {\r\n\t\t\t\tclient.sendZZ(\"\");\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t},\r\n\t\t\tCancel: function() {\r\n\t\t\t\t$( this ).dialog( \"close\" );\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n});"],"sourceRoot":""}