var PlayerState;!function(PlayerState){PlayerState[PlayerState.PREBUFFERING=0]="PREBUFFERING",PlayerState[PlayerState.PLAYING=1]="PLAYING",PlayerState[PlayerState.BUFFERING=2]="BUFFERING",PlayerState[PlayerState.STOPPING=3]="STOPPING",PlayerState[PlayerState.STOPPED=4]="STOPPED"}(PlayerState||(PlayerState={}));class AudioController{constructor(){this.playerState=PlayerState.STOPPED,this.audioCache=[],this.playingAudioCache=[],this._volume=1,this._codecCache=[],this._timeIndex=0,this._latencyBufferLength=3,this.allowBuffering=!0,this.speakerContext=AudioController.globalContext,this.onSpeaking=function(){},this.onSilence=function(){}}static get globalContext(){return this._globalContext?this._globalContext:(this._globalContext=new AudioContext,this._globalContext)}static initializeAudioController(){}initialize(){AudioController._audioInstances.push(this)}close(){AudioController._audioInstances.remove(this)}playBuffer(buffer){switch(buffer.sampleRate!=this.speakerContext.sampleRate&&console.warn("[AudioController] Source sample rate isn't equal to playback sample rate! ("+buffer.sampleRate+" | "+this.speakerContext.sampleRate+")"),this.applyVolume(buffer),this.audioCache.push(buffer),this.playerState!=PlayerState.STOPPED&&this.playerState!=PlayerState.STOPPING||(console.log("[Audio] Starting new playback"),this.playerState=PlayerState.PREBUFFERING),this.playerState){case PlayerState.PREBUFFERING:case PlayerState.BUFFERING:if(this.audioCache.length<=this._latencyBufferLength){if(this.playerState!=PlayerState.BUFFERING)break;if(this.allowBuffering)break}this.playerState==PlayerState.PREBUFFERING?(console.log("[Audio] Prebuffering succeeded (Replaying now)"),this.onSpeaking()):this.allowBuffering&&console.log("[Audio] Buffering succeeded (Replaying now)"),this.playerState=PlayerState.PLAYING;case PlayerState.PLAYING:this.playQueue()}}playQueue(){let buffer;for(;buffer=this.audioCache.pop_front();){this._timeIndexthis.removeNode(player)),this.playingAudioCache.push(player),player.connect(this.speakerContext.destination),player.start(this._timeIndex),this._timeIndex+=buffer.duration}}removeNode(node){this.playingAudioCache.remove(node),this.testBufferQueue()}stopAudio(now=!1){if(this.playerState=PlayerState.STOPPING,now){this.playerState=PlayerState.STOPPED,this.audioCache=[];for(let entry of this.playingAudioCache)entry.stop(0);this.playingAudioCache=[]}this.testBufferQueue()}testBufferQueue(){0==this.audioCache.length&&0==this.playingAudioCache.length&&(this.playerState!=PlayerState.STOPPING?(this.playerState=PlayerState.BUFFERING,this.allowBuffering||console.warn("[Audio] Detected a buffer underflow!")):(this.playerState=PlayerState.STOPPED,this.onSilence()))}get volume(){return this._volume}set volume(val){if(this._volume!=val){this._volume=val;for(let buffer of this.audioCache)this.applyVolume(buffer)}}applyVolume(buffer){for(let channel=0;channel0&&(result+=years+" years "),(years>0||days>0)&&(result+=days+" days "),(years>0||days>0||hours>0)&&(result+=hours+" hours "),(years>0||days>0||hours>0||minutes>0)&&(result+=minutes+" minutes "),years>0||days>0||hours>0||minutes>0||seconds>0?result+=seconds+" seconds ":result="now ",result.substr(0,result.length-1)}AudioController._audioInstances=[],AudioController._timeIndex=0,Array.prototype.remove||(Array.prototype.remove=function(elem){const index=this.indexOf(elem,0);return index>-1&&(this.splice(index,1),!0)}),Array.prototype.pop_front||(Array.prototype.pop_front=function(){if(0!=this.length)return this.splice(0,1)[0]}),Array.prototype.last||(Array.prototype.last=function(){if(0!=this.length)return this[this.length-1]}),"undefined"!=typeof $&&($.spawn||($.spawn=function(tagName){return $(document.createElement(tagName))})),String.prototype.format||(String.prototype.format=function(){const args=arguments;let array=1==args.length&&$.isArray(args[0]);return this.replace(/\{\{|\}\}|\{(\d+)\}/g,function(m,n){return"{{"==m?"{":"}}"==m?"}":array?args[0][n]:args[n]})});class BufferChunk{constructor(buffer){this.buffer=buffer,this.index=0}copyRangeTo(target,maxLength,offset){let copy=Math.min(this.buffer.length-this.index,maxLength);for(let channel=0;channel1?$.spawn("div").append(val):val},jqueriefy:function(val){switch($.isFunction(val)&&(val=val()),typeof val){case"string":return $("
"+val+"
");case"object":return val;case"undefined":return console.warn("Got undefined type!"),$.spawn("div");default:return console.error("Invalid type "+typeof val),$()}},warpProperties(data){if(data instanceof ModalProperties)return data;{let props=new ModalProperties;for(let key in data)props[key]=data[key];return props}}};class ModalProperties{constructor(){this.header=(()=>"HEADER"),this.body=(()=>"BODY"),this.footer=(()=>"FOOTER"),this.closeListener=(()=>{}),this.width="60%",this.hight="auto",this.closeable=!0}registerCloseListener(listener){return this.closeListener?$.isArray(this.closeListener)?this.closeListener.push(listener):this.closeListener=[this.closeListener,listener]:this.closeListener=listener,this}triggerClose(){if($.isArray(this.closeListener))for(let listener of this.closeListener)listener();else this.closeListener()}}class Modal{constructor(props){this.properties=props}get htmlTag(){return this._htmlTag||this._create(),this._htmlTag}_create(){let modal=$.spawn("div");modal.addClass("modal");let content=$.spawn("div");content.addClass("modal-content"),content.css("width",this.properties.width);let header=ModalFunctions.divify(ModalFunctions.jqueriefy(this.properties.header)).addClass("modal-header");this.properties.closeable&&header.append('×');let body=ModalFunctions.divify(ModalFunctions.jqueriefy(this.properties.body)).addClass("modal-body"),footer=ModalFunctions.divify(ModalFunctions.jqueriefy(this.properties.footer)).addClass("modal-footer");content.append(header),content.append(body),content.append(footer),modal.append(content),modal.find(".close").click(function(){this.properties.closeable&&this.close()}.bind(this)),this._htmlTag=modal}open(){this.htmlTag.appendTo($("body")),this.htmlTag.show()}close(){const _this=this;this.htmlTag.animate({opacity:0},()=>{_this.htmlTag.detach()}),this.properties.triggerClose()}}function createModal(data){return new Modal(ModalFunctions.warpProperties(data))}class InputModalProperties extends ModalProperties{}function createInputModal(headMessage,question,validator,callback,props={}){props=ModalFunctions.warpProperties(props);let head=$.spawn("div");head.css("border-bottom","grey solid"),head.css("border-width","1px"),ModalFunctions.jqueriefy(headMessage).appendTo(head);let body=$.spawn("div");ModalFunctions.divify(ModalFunctions.jqueriefy(question)).appendTo(body);let input=$.spawn("input");input.css("width","100%"),input.appendTo(body),console.log(input);let footer=$.spawn("div");footer.addClass("modal-button-group"),footer.css("margin-top","5px");let buttonCancel=$.spawn("button");buttonCancel.text("Cancel");let buttonOk=$.spawn("button");buttonOk.text("Ok"),footer.append(buttonCancel),footer.append(buttonOk),input.on("keydown",function(event){13==event.keyCode&&buttonOk.trigger("click")});input.on("keyup",function(){let text=input.val().toString();(!props.maxLength||text.length<=props.maxLength)&&validator(text)?(input.removeClass("invalid_input"),buttonOk.removeAttr("disabled")):(input.hasClass("invalid_input")||input.addClass("invalid_input"),buttonOk.attr("disabled","true"))});let modal,callbackCalled=!1,wrappedCallback=function(flag){callbackCalled||(callbackCalled=!0,callback(flag))};return buttonOk.on("click",()=>{wrappedCallback(input.val().toString()),modal.close()}),buttonCancel.on("click",()=>{wrappedCallback(!1),modal.close()}),props.header=head,props.body=body,props.footer=footer,props.closeListener=(()=>wrappedCallback(!1)),modal=createModal(props)}function createErrorModal(header,message,props={footer:""}){props=ModalFunctions.warpProperties(props);let head=$.spawn("div");return head.addClass("modal-head-error"),ModalFunctions.divify(ModalFunctions.jqueriefy(header)).appendTo(head),props.header=head,props.body=ModalFunctions.divify(ModalFunctions.jqueriefy(message)),props.footer=ModalFunctions.divify(ModalFunctions.jqueriefy("")),createModal(props)}class VoiceActivityDetector{initialise(){}finalize(){}initialiseNewStream(old,_new){}changeHandle(handle,triggerNewStream){const oldStream=this.handle?this.handle.getMicrophoneStream():void 0;this.handle=handle,triggerNewStream&&this.initialiseNewStream(oldStream,handle?handle.getMicrophoneStream():void 0)}}class VoiceRecorder{constructor(handle){this.on_data=(data=>{}),this.on_end=(()=>{}),this._recording=!1,this.microphoneStream=void 0,this.mediaStream=void 0,this._chunkCount=0,this.handle=handle,this.userMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia,this._deviceId=settings.global("microphone_id","default"),this.audioContext=AudioController.globalContext,this.processor=this.audioContext.createScriptProcessor(VoiceRecorder.BUFFER_SIZE,VoiceRecorder.CHANNELS,VoiceRecorder.CHANNELS),this.processor.addEventListener("audioprocess",ev=>{this.microphoneStream&&this.vadHandler.shouldRecord(ev.inputBuffer)?this.on_data(ev.inputBuffer,0==this._chunkCount++):(0!=this._chunkCount&&this.on_end(),this._chunkCount=0)}),this.mute=this.audioContext.createGain(),this.mute.gain.setValueAtTime(0,0),this.processor.connect(this.mute),this.mute.connect(this.audioContext.destination),this.setVADHander(new PassThroughVAD)}avariable(){return!!this.userMedia}recording(){return this._recording}getMediaStream(){return this.mediaStream}getDestinationContext(){return this.mute}getMicrophoneStream(){return this.microphoneStream}reinitialiseVAD(){let type=settings.global("vad_type","vad");if("ppt"==type){let keyCode=parseInt(settings.global("vad_ppt_key",84..toString()));this.getVADHandler()instanceof PushToTalkVAD?this.getVADHandler().key=keyCode:this.setVADHander(new PushToTalkVAD(keyCode))}else if("pt"==type)this.getVADHandler()instanceof PassThroughVAD||this.setVADHander(new PassThroughVAD);else if("vad"==type){this.getVADHandler()instanceof VoiceActivityDetectorVAD||this.setVADHander(new VoiceActivityDetectorVAD);let threshold=parseInt(settings.global("vad_threshold","50"));this.getVADHandler().percentageThreshold=threshold}else console.warn("Invalid VAD handler! ("+type+")")}setVADHander(handler){this.vadHandler&&(this.vadHandler.changeHandle(null,!0),this.vadHandler.finalize()),this.vadHandler=handler,this.vadHandler.changeHandle(this,!1),this.vadHandler.initialise(),this.vadHandler.initialiseNewStream(void 0,this.microphoneStream)}getVADHandler(){return this.vadHandler}update(flag){this._recording!=flag&&(flag?this.start(this._deviceId):this.stop())}changeDevice(device){this._deviceId!=device&&(this._deviceId=device,settings.changeGlobal("microphone_id",device),this._recording&&(this.stop(),this.start(device)))}start(device){this._deviceId=device,console.log("Attempt recording!"),this._recording=!0,this.userMedia({audio:!0,deviceId:device},this.on_microphone.bind(this),error=>{createErrorModal("Could not resolve microphone!","Could not resolve microphone!
Message: "+error).open(),console.error("Could not get microphone!"),console.error(error)})}stop(){console.log("Stop recording!"),this._recording=!1,this.microphoneStream&&this.microphoneStream.disconnect(),this.microphoneStream=void 0,this.mediaStream&&(this.mediaStream.stop?this.mediaStream.stop():this.mediaStream.getTracks().forEach(value=>{value.stop()})),this.mediaStream=void 0}on_microphone(stream){this.microphoneStream&&this.stop(),console.log("Start recording!"),this.mediaStream=stream;const oldStream=this.microphoneStream;this.microphoneStream=this.audioContext.createMediaStreamSource(stream),this.microphoneStream.connect(this.processor),this.vadHandler.initialiseNewStream(oldStream,this.microphoneStream)}}VoiceRecorder.CHANNEL=0,VoiceRecorder.CHANNELS=1,VoiceRecorder.BUFFER_SIZE=1024;class MuteVAD extends VoiceActivityDetector{shouldRecord(buffer){return!1}}class PassThroughVAD extends VoiceActivityDetector{shouldRecord(buffer){return!0}}class VoiceActivityDetectorVAD extends VoiceActivityDetector{constructor(){super(...arguments),this.continuesCount=0,this.maxContinuesCount=12,this.percentageThreshold=50,this.percentage_listener=($=>{})}initialise(){return this.analyzer=AudioController.globalContext.createAnalyser(),this.analyzer.smoothingTimeConstant=1,this.buffer=new Uint8Array(this.analyzer.fftSize),super.initialise()}initialiseNewStream(old,_new){this.analyzer&&this.analyzer.disconnect(),_new&&_new.connect(this.analyzer)}shouldRecord(buffer){let usage=this.calculateUsage();return $.isFunction(this.percentage_listener)&&this.percentage_listener(usage),usage>=this.percentageThreshold?this.continuesCount=0:this.continuesCount++,this.continuesCount{e.key==String.fromCharCode(this._key)&&(this.pushed=!0)}),this._evListenerUp=(e=>{e.key==String.fromCharCode(this._key)&&(this.pushed=!1)}),this._key=key}initialise(){return document.addEventListener("keydown",this._evListenerDown),document.addEventListener("keyup",this._evListenerUp),super.initialise()}finalize(){return document.removeEventListener("keydown",this._evListenerDown),document.removeEventListener("keyup",this._evListenerUp),super.finalize()}set pushed(flag){this._pushed=flag}set key(key){this._key=key,this._pushed=!1}shouldRecord(buffer){return this._pushed}}class CodecPoolEntry{}class CodecPool{constructor(handle,index,name,creator){this.entries=[],this.maxInstances=2,this._supported=!0,this.creator=creator,this.handle=handle,this.codecIndex=index,this.name=name}initialize(cached){for(let i=0;i{console.log("Release again! (%o)",codec),this.releaseCodec(i+1)}).catch(error=>{this._supported&&createErrorModal("Could not load codec driver","Could not load or initialize codec "+this.name+"
Error: "+JSON.stringify(error)+"").open(),this._supported=!1,console.error(error)})}supported(){return null!=this.creator&&this._supported}ownCodec(clientId,create=!0){return new Promise((resolve,reject)=>{if(!this.creator||!this._supported)return void reject("unsupported codec!");let freeSlot=0;for(let index=0;index{this.ownCodec(clientId,!1).then(resolve).catch(reject)}).catch(error=>{console.error("Could not initialize codec!\nError: %o",error),reject("Could not initialize codec!")}));0==freeSlot&&0==this.entries[index].owner&&(freeSlot=index)}if(create){if(0==freeSlot){freeSlot=this.entries.length;let entry=new CodecPoolEntry;entry.instance=this.creator(),entry.instance.on_encoded_data=(buffer=>this.handle.sendVoicePacket(buffer,this.codecIndex)),this.entries.push(entry)}this.entries[freeSlot].owner=clientId,this.entries[freeSlot].last_access=(new Date).getTime(),this.entries[freeSlot].instance.initialized()?(this.entries[freeSlot].instance.reset(),resolve(this.entries[freeSlot].instance)):this.ownCodec(clientId,!1).then(resolve).catch(reject)}else resolve(void 0)})}releaseCodec(clientId){for(let index=0;indexnew CodecWrapper(CodecWorkerType.WORKER_OPUS,1)),new CodecPool(this,5,"Opus Music",()=>new CodecWrapper(CodecWorkerType.WORKER_OPUS,2))],this.vpacketId=0,this.chunkVPacketId=0,this.client=client,this.voiceRecorder=new VoiceRecorder(this),this.voiceRecorder.on_data=this.handleVoiceData.bind(this),this.voiceRecorder.on_end=this.handleVoiceEnded.bind(this),this.voiceRecorder.reinitialiseVAD(),this.codecPool[4].initialize(2),this.codecPool[5].initialize(2)}codecSupported(type){return this.codecPool.length>type&&this.codecPool[type].supported()}sendVoicePacket(data,codec){if(this.dataChannel){this.vpacketId++,this.vpacketId>65535&&(this.vpacketId=0);let packet=new Uint8Array(data.byteLength+2+3);packet[0]=this.chunkVPacketId++<5?1:0,packet[1]=0,packet[2]=this.vpacketId>>8&255,packet[3]=this.vpacketId>>0&255,packet[4]=codec,packet.set(data,5),this.dataChannel.send(packet)}else console.warn("Could not transfer audio (not connected)")}createSession(){this.rtcPeerConnection=new RTCPeerConnection({});this.dataChannel=this.rtcPeerConnection.createDataChannel("main",{ordered:!1,maxRetransmits:0}),this.dataChannel.onmessage=this.onDataChannelMessage.bind(this),this.dataChannel.onopen=this.onDataChannelOpen.bind(this),this.dataChannel.binaryType="arraybuffer";let sdpConstraints={offerToReceiveAudio:0,offerToReceiveVideo:0};this.rtcPeerConnection.onicecandidate=this.onIceCandidate.bind(this),this.rtcPeerConnection.createOffer(this.onOfferCreated.bind(this),()=>{console.error("Could not create ice offer!")},sdpConstraints)}dropSession(){this.dataChannel&&this.dataChannel.close(),this.rtcPeerConnection&&this.rtcPeerConnection.close()}handleControlPacket(json){"create"===json.request?this.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:json.sdp})):"ice"===json.request&&this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate({candidate:json.candidate,sdpMid:json.session,sdpMLineIndex:json.line}))}onIceCandidate(event){console.log("Got ice candidate! Event:"),console.log(event),event&&event.candidate&&this.client.serverConnection.sendData(JSON.stringify({type:"WebRTC",request:"ice",candidate:event.candidate.candidate,line:event.candidate.sdpMLineIndex,session:event.candidate.sdpMid}))}onOfferCreated(localSession){console.log("Offer created and accepted"),this.rtcPeerConnection.setLocalDescription(localSession),this.client.serverConnection.sendData(JSON.stringify({type:"WebRTC",request:"create",session:localSession}))}onDataChannelOpen(channel){console.log("Got new data channel!")}onDataChannelMessage(message){if(this.client.controlBar.muteOutput)return;let bin=new Uint8Array(message.data),clientId=bin[2]<<8|bin[3],codec=(bin[0],bin[1],bin[4]),client=this.client.channelTree.findClient(clientId);if(!client)return void console.error("Having voice from unknown client? (ClientID: "+clientId+")");let encodedData,codecPool=this.codecPool[codec];codecPool?0==(encodedData=message.data.subarray?message.data.subarray(5):new Uint8Array(message.data,5)).length?(client.getAudioController().stopAudio(),codecPool.releaseCodec(clientId)):codecPool.ownCodec(clientId).then(decoder=>decoder.decodeSamples(client.getAudioController().codecCache(codec),encodedData)).then(buffer=>client.getAudioController().playBuffer(buffer)).catch(error=>{console.error("Could not playback client's ("+clientId+") audio ("+error+")")}):console.error("Could not playback codec "+codec)}handleVoiceData(data,head){if(this.voiceRecorder)return!!this.client.connected&&void(this.client.controlBar.muteInput||(head&&(this.chunkVPacketId=0,this.client.getClient().speaking=!0),this.codecPool[4].ownCodec(this.client.getClientId()).then(encoder=>encoder.encodeSamples(this.client.getClient().getAudioController().codecCache(4),data))))}handleVoiceEnded(){this.voiceRecorder&&(console.log("Voice ended"),this.client.getClient().speaking=!1,this.sendVoicePacket(new Uint8Array(0),4))}}$(document).bind("mousedown",function(e){0==$(e.target).parents(".contextMenu").length&&despawnContextMenu()});let contextMenuCloseFn=void 0;function despawnContextMenu(){let menue=$(".contextMenu");menue.is(":visible")&&(menue.hide(100),contextMenuCloseFn&&contextMenuCloseFn())}var MenuEntryType,sha,helpers,ChannelType,PermissionType,GroupType,GroupTarget;!function(MenuEntryType){MenuEntryType[MenuEntryType.CLOSE=0]="CLOSE",MenuEntryType[MenuEntryType.ENTRY=1]="ENTRY",MenuEntryType[MenuEntryType.HR=2]="HR",MenuEntryType[MenuEntryType.EMPTY=3]="EMPTY"}(MenuEntryType||(MenuEntryType={}));class MenuEntry{static HR(){return{callback:()=>{},type:MenuEntryType.HR,name:"",icon:""}}static EMPTY(){return{callback:()=>{},type:MenuEntryType.EMPTY,name:"",icon:""}}static CLOSE(callback){return{callback:callback,type:MenuEntryType.EMPTY,name:"",icon:""}}}function spawnMenu(x,y,...entries){const menu=$("#contextMenu");menu.empty(),menu.hide(),contextMenuCloseFn=void 0;for(let entry of entries)if(entry.type==MenuEntryType.HR)menu.append("
");else if(entry.type==MenuEntryType.CLOSE)contextMenuCloseFn=entry.callback;else if(entry.type==MenuEntryType.ENTRY){let icon=$.isFunction(entry.icon)?entry.icon():entry.icon;icon=0==icon.length?"icon_empty":"icon "+icon;let tag=$.spawn("li");tag.append("
"),tag.append("
"+($.isFunction(entry.name)?entry.name():entry.name)+"
"),menu.append(tag),entry.disabled||entry.invalidPermission?tag.addClass("disabled"):tag.click(function(){$.isFunction(entry.callback)&&entry.callback(),despawnContextMenu()})}menu.show(100),menu.css({top:y+"px",left:x+"px"})}!function(sha){sha.sha1=function(message){let buffer=message instanceof ArrayBuffer?message:(new TextEncoder).encode(message);return crypto.subtle.digest("SHA-1",buffer)}}(sha||(sha={})),function(helpers){helpers.hashPassword=function(password){return new Promise((resolve,reject)=>{sha.sha1(password).then(result=>{resolve(btoa(String.fromCharCode.apply(null,new Uint8Array(result))))})})}}(helpers||(helpers={})),function(ChannelType){ChannelType[ChannelType.PERMANENT=0]="PERMANENT",ChannelType[ChannelType.SEMI_PERMANENT=1]="SEMI_PERMANENT",ChannelType[ChannelType.TEMPORARY=2]="TEMPORARY"}(ChannelType||(ChannelType={})),function(ChannelType){ChannelType.normalize=function(mode){let value=ChannelType[mode];return(value=value.toLowerCase())[0].toUpperCase()+value.substr(1)}}(ChannelType||(ChannelType={}));class ChannelProperties{constructor(){this.channel_order=0,this.channel_name="",this.channel_topic="",this.channel_password="",this.channel_description="",this.channel_codec=4,this.channel_codec_quality=0,this.channel_codec_is_unencrypted=!1,this.channel_maxclients=-1,this.channel_maxfamilyclients=-1,this.channel_needed_talk_power=1,this.channel_flag_permanent=!1,this.channel_flag_semi_permanent=!1,this.channel_flag_default=!1,this.channel_flag_password=!1,this.channel_flag_maxclients_unlimited=!1,this.channel_flag_maxfamilyclients_inherited=!1,this.channel_flag_maxfamilyclients_unlimited=!1}}class ChannelEntry{constructor(channelId,channelName,parent=null,prevChannel=null){this.properties=new ChannelProperties,this.properties=new ChannelProperties,this.channelId=channelId,this._formatedChannelName=channelName,this.parent=parent,this.prevChannel=prevChannel,this.channelTree=null,this.initializeTag(),this.__updateChannelName()}channelName(){return this.properties.channel_name}formatedChannelName(){return this._formatedChannelName?this._formatedChannelName:this.properties.channel_name}parentChannel(){return this.parent}hasParent(){return null!=this.parent}getChannelId(){return this.channelId}channelClass(){return"channel_full"}siblings(deep=!1){const result=[];if(null==this.channelTree)return[];const self=this;return this.channelTree.channels.forEach(function(entry){let current=entry;if(deep)for(;current;){if(current.parentChannel()==self){result.push(entry);break}current=current.parentChannel()}else current.parentChannel()==self&&result.push(entry)}),result}clients(deep=!1){const result=[];if(null==this.channelTree)return[];const self=this;return this.channelTree.clients.forEach(function(entry){let current=entry.currentChannel();if(deep)for(;current;){if(current.parentChannel()==self){result.push(entry);break}current=current.parentChannel()}else current==self&&result.push(entry)}),result}initializeTag(){let rootTag=$.spawn("div");rootTag.attr("id","channel_"+this.getChannelId()),rootTag.addClass("channel"),this._tag_channel=$.spawn("div"),this._tag_channel.addClass("channelLine"),this._tag_channel.addClass(this._channelAlign);let channelType=$.spawn("div");channelType.addClass("channel_only_normal channel_type icon client-channel_green_subscribed"),this._tag_channel.append(channelType),this._tag_channel.append($.spawn("div").addClass("channel_name_container").append($.spawn("a").addClass("channel_name").text(this.channelName())));let iconTag=$.spawn("span").addClass("icons");iconTag.appendTo(this._tag_channel),iconTag.append($.spawn("div").addClass("channel_only_normal").append($.spawn("div").addClass("icon_entry icon_default icon client-channel_default").attr("title","Default channel"))),iconTag.append($.spawn("div").addClass("channel_only_normal").append($.spawn("div").addClass("icon_entry icon_password icon client-register").attr("title","The channel is password protected"))),iconTag.append($.spawn("div").addClass("channel_only_normal").append($.spawn("div").addClass("icon_entry icon_music icon client-music").attr("title","Music quality"))),iconTag.append($.spawn("div").addClass("channel_only_normal").addClass("icon_entry channel_icon").attr("title","Channel icon"));let container=$.spawn("div"),noSound=$.spawn("div").addClass("icon_entry icon_no_sound icon client-conflict-icon").attr("title","You don't support the channel codec");$.spawn("div").width(10).height(14).css("background","red").css("position","absolute").css("top","1px").css("left","3px").appendTo(container),noSound.appendTo(container),iconTag.append(container),this._tag_siblings=$.spawn("div").addClass("siblings");let tag_siblings_box=$.spawn("div").css("position","absolute").css("width","calc(100% - 16px)").css("margin","0px");this._tag_siblings.appendTo(tag_siblings_box),this._tag_clients=$.spawn("div").addClass("clients");let tag_clients_box=$.spawn("div").css("position","absolute").css("width","calc(100% - 16px)").css("margin","0px");this._tag_clients.appendTo(tag_clients_box),this._tag_root=rootTag,tag_clients_box.appendTo(this._tag_root),tag_siblings_box.appendTo(this._tag_root),this._tag_channel.appendTo(this._tag_root)}rootTag(){return this._tag_root}channelTag(){return this._tag_channel}siblingTag(){return this._tag_siblings}clientTag(){return this._tag_clients}adjustSize(parent=!0){const size=this.originalHeight;let subSize=0,clientSize=0;this.siblings(!1).forEach(function(e){subSize+=e.rootTag().outerHeight(!0)}),this.clients(!1).forEach(function(e){clientSize+=e.tag.outerHeight(!0)}),this._tag_root.css({height:size+subSize+clientSize}),this._tag_siblings.css("margin-top",clientSize+16+"px"),this._tag_clients.css({height:clientSize}),parent&&this.parentChannel()&&this.parentChannel().adjustSize(parent)}initializeListener(){const _this=this;this.channelTag().click(function(){_this.channelTree.onSelect(_this)}),this.channelTag().dblclick(()=>this.joinChannel()),settings.static(Settings.KEY_DISABLE_CONTEXT_MENU,!1)||this.channelTag().on("contextmenu",function(event){event.preventDefault(),_this.channelTree.onSelect(_this),_this.showContextMenu(event.pageX,event.pageY,()=>{_this.channelTree.onSelect(void 0)})})}showContextMenu(x,y,on_close){let channelCreate=this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_TEMPORARY).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_PERMANENT).granted(1),channelModify=this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_DEFAULT).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_TEMPORARY).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_NAME).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_TOPIC).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_DESCRIPTION).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_PASSWORD).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_CODEC).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_CODEC_QUALITY).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_CODEC_LATENCY_FACTOR).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAXCLIENTS).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAXFAMILYCLIENTS).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_SORTORDER).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_NEEDED_TALK_POWER).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_CODEC_ENCRYPTED).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_TEMP_DELETE_DELAY).granted(1)||this.channelTree.client.permissions.neededPermission(PermissionType.B_ICON_MANAGE).granted(1),flagDelete=!0;this.clients(!0).length>0&&(flagDelete=this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_FLAG_FORCE).granted(1)),flagDelete&&(flagDelete=this.properties.channel_flag_permanent?this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_PERMANENT).granted(1):this.properties.channel_flag_semi_permanent?this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_PERMANENT).granted(1):this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_TEMPORARY).granted(1)),spawnMenu(x,y,{type:MenuEntryType.ENTRY,icon:"client-channel_switch",name:"Switch to channel",callback:()=>{this.joinChannel()}},MenuEntry.HR(),{type:MenuEntryType.ENTRY,icon:"client-channel_edit",name:"Edit channel",invalidPermission:!channelModify,callback:()=>{Modals.createChannelModal(this,void 0,changes=>{changes&&(changes.cid=this.channelId,log.info(LogCategory.CHANNEL,"Changed channel properties of channel %s: %o",this.channelName(),changes))})}},{type:MenuEntryType.ENTRY,icon:"client-channel_delete",name:"Delete channel",invalidPermission:!flagDelete,callback:()=>this.channelTree.client.serverConnection.sendCommand("channeldelete",{cid:this.channelId})},MenuEntry.HR(),{type:MenuEntryType.ENTRY,icon:"client-channel_create_sub",name:"Create sub channel",invalidPermission:!(channelCreate&&this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_CHILD).granted(1)),callback:()=>this.channelTree.spawnCreateChannel(this)},{type:MenuEntryType.ENTRY,icon:"client-channel_create",name:"Create channel",invalidPermission:!channelCreate,callback:()=>this.channelTree.spawnCreateChannel()},MenuEntry.CLOSE(on_close))}__updateChannelName(){this._formatedChannelName=void 0;parseType:if(null==this.parentChannel()&&"["==this.properties.channel_name.charAt(0)){let end=this.properties.channel_name.indexOf("]");if(-1==end)break parseType;let options=this.properties.channel_name.substr(1,end-1);if(-1==options.indexOf("spacer"))break parseType;if(options=options.substr(0,options.indexOf("spacer")),console.log("Channel options: '"+options+"'"),0==options.length?options="l":options.length>1&&(options=options[0]),"r"!=options&&"l"!=options&&"c"!=options&&"*"!=options)break parseType;this._channelAlign=options,this._formatedChannelName=this.properties.channel_name.substr(end+1),console.log("Got channel name: "+this._formatedChannelName)}let self=this.channelTag(),channelName=self.find(".channel_name");if(channelName.text(this.formatedChannelName()),channelName.parent().removeClass("l r c *"),(this._formatedChannelName?$.fn.hide:$.fn.show).apply(self.find(".channel_only_normal")),this._formatedChannelName&&(channelName.parent().addClass(this._channelAlign),"*"==this._channelAlign)){let lastSuccess="",index=0;do{channelName.text((lastSuccess=channelName.text())+this.formatedChannelName()),console.log(channelName.parent().width()+" : "+channelName.width()+" : "+channelName.innerWidth()+" : "+channelName.outerWidth())}while(channelName.parent().width()>=channelName.width()&&++index<255);255==index&&console.warn(LogCategory.CHANNEL,"Repeating spacer took too much repeats!"),lastSuccess.length>0&&(channelName.text(lastSuccess),self.addClass("c"))}console.log("Align: "+this._channelAlign)}updateVariables(...variables){let group=log.group(log.LogType.DEBUG,LogCategory.CHANNEL,"Update properties (%i) of %s (%i)",variables.length,this.channelName(),this.getChannelId());for(let variable of variables){let key=variable.key,value=variable.value;if("number"==typeof this.properties[key]&&(this.properties[key]=parseInt(value)),"boolean"==typeof this.properties[key]?this.properties[key]="true"==value||"1"==value:this.properties[key]=value,group.log("Updating property "+key+" = '%s' -> %o",value,this.properties[key]),"channel_name"==key)this.__updateChannelName();else if("channel_order"==key){let order=this.channelTree.findChannel(this.properties.channel_order);this.channelTree.moveChannel(this,order,this.parent)}else if("channel_icon_id"==key){let tag=this.channelTag().find(".icons .channel_icon");(this.properties.channel_icon_id>0?$.fn.show:$.fn.hide).apply(tag),this.properties.channel_icon_id>0&&(tag.children().detach(),this.channelTree.client.fileManager.icons.generateTag(this.properties.channel_icon_id).appendTo(tag))}else"channel_codec"==key?((5==this.properties.channel_codec||3==this.properties.channel_codec?$.fn.show:$.fn.hide).apply(this.channelTag().find(".icons .icon_music")),(this.channelTree.client.voiceConnection.codecSupported(this.properties.channel_codec)?$.fn.hide:$.fn.show).apply(this.channelTag().find(".icons .icon_no_sound"))):"channel_flag_default"==key?(this.properties.channel_flag_default?$.fn.show:$.fn.hide).apply(this.channelTag().find(".icons .icon_default")):"channel_flag_password"==key&&(this.properties.channel_flag_password?$.fn.show:$.fn.hide).apply(this.channelTag().find(".icons .icon_password"));"channel_maxclients"!=key&&"channel_maxfamilyclients"!=key&&"channel_flag_private"!=key&&"channel_flag_password"!=key||this.updateChannelTypeIcon()}group.end()}updateChannelTypeIcon(){let type,tag=this.channelTag().find(".channel_type");tag.removeAttr("class"),tag.addClass("channel_only_normal channel_type icon"),type=1!=this.properties.channel_flag_password||this._cachedPassword?!this.properties.channel_flag_maxclients_unlimited&&this.clients().length>=this.properties.channel_maxclients||!this.properties.channel_flag_maxfamilyclients_unlimited&&this.properties.channel_maxfamilyclients>=0&&this.clients(!0).length>=this.properties.channel_maxfamilyclients?"red":"green":"yellow",tag.addClass("client-channel_"+type+"_subscribed")}createChatTag(braces=!1){let tag=$.spawn("div");return tag.css("display","inline-block"),tag.css("cursor","pointer"),tag.css("font-weight","bold"),tag.css("color","darkblue"),braces?tag.text('"'+this.channelName()+'"'):tag.text(this.channelName()),tag.contextmenu(event=>{event.isDefaultPrevented()||(event.preventDefault(),this.showContextMenu(event.pageX,event.pageY))}),tag.attr("channelId",this.channelId),tag.attr("channelName",this.channelName()),tag}channelType(){return 1==this.properties.channel_flag_permanent?ChannelType.PERMANENT:1==this.properties.channel_flag_semi_permanent?ChannelType.SEMI_PERMANENT:ChannelType.TEMPORARY}joinChannel(){1!=this.properties.channel_flag_password||this._cachedPassword||this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_JOIN_IGNORE_PASSWORD).granted(1)?this.channelTree.client.getServerConnection().joinChannel(this,this._cachedPassword).catch(error=>{error instanceof CommandResult&&781==error.id&&(this._cachedPassword=void 0,this.updateChannelTypeIcon())}):createInputModal("Channel password","Channel password:",()=>!0,text=>{typeof text!=typeof!0&&helpers.hashPassword(text).then(result=>{this._cachedPassword=result,this.joinChannel(),this.updateChannelTypeIcon()})}).open()}}function chat_channel_contextmenu(_element,event){event.preventDefault();let element=$(_element);console.log("Context menue for "+element.attr("channelName"));let chid=Number.parseInt(element.attr("channelId")),channel=globalClient.channelTree.findChannel(chid);channel&&channel.showContextMenu(event.pageX,event.pageY)}!function(Modals){Modals.spawnChangeVolume=function(current,callback){let updateCallback;const connectModal=createModal({header:function(){let header=$.spawn("div");return header.text("Change volume"),header},body:function(){let tag=$("#tmpl_change_volume").tmpl();return tag.find(".volume_slider").on("change",_=>updateCallback(tag.find(".volume_slider").val())),tag.find(".volume_slider").on("input",_=>updateCallback(tag.find(".volume_slider").val())),tag},footer:function(){let tag=$.spawn("div");tag.css("text-align","right"),tag.css("margin-top","3px"),tag.css("margin-bottom","6px"),tag.addClass("modal-button-group");let buttonReset=$.spawn("button");buttonReset.text("Reset"),buttonReset.on("click",function(){updateCallback(100)}),tag.append(buttonReset);let buttonCancel=$.spawn("button");buttonCancel.text("Cancel"),buttonCancel.on("click",function(){updateCallback(100*current),connectModal.close()}),tag.append(buttonCancel);let buttonOk=$.spawn("button");return buttonOk.text("OK"),buttonOk.on("click",function(){connectModal.close()}),tag.append(buttonOk),tag},width:600});updateCallback=(value=>{connectModal.htmlTag.find(".volume_slider").val(value);let number=value-100;connectModal.htmlTag.find(".display_volume").html((0==number?"±":number>0?"+":"")+number+" %"),callback(value/100)}),connectModal.open(),updateCallback(100*current)}}(Modals||(Modals={}));class ClientProperties{constructor(){this.client_version="",this.client_platform="",this.client_nickname="unknown",this.client_unique_identifier="unknown",this.client_description="",this.client_servergroups="",this.client_channel_group_id=0,this.client_lastconnected=0,this.client_flag_avatar="",this.client_output_muted=!1,this.client_away_message="",this.client_away=!1,this.client_input_hardware=!1,this.client_input_muted=!1,this.client_is_channel_commander=!1,this.client_teaforum_id=0,this.client_teaforum_name=""}}class ClientEntry{constructor(clientId,clientName){this.properties=new ClientProperties,this.lastVariableUpdate=0,this._speaking=!1,this._clientId=clientId,this.properties.client_nickname=clientName,this.channelTree=null,this._channel=null,this.audioController=new AudioController;const _this=this;this.audioController.onSpeaking=function(){_this.speaking=!0},this.audioController.onSilence=function(){_this.speaking=!1},this.audioController.initialize()}currentChannel(){return this._channel}clientNickName(){return this.properties.client_nickname}clientUid(){return this.properties.client_unique_identifier}clientId(){return this._clientId}getAudioController(){return this.audioController}initializeListener(){const _this=this;this.tag.click(event=>{_this.channelTree.onSelect(_this)}),settings.static(Settings.KEY_DISABLE_CONTEXT_MENU,!1)||this.tag.on("contextmenu",function(event){return event.preventDefault(),_this.channelTree.onSelect(_this),_this.showContextMenu(event.pageX,event.pageY,()=>{_this.channelTree.onSelect(void 0)}),!1})}showContextMenu(x,y,on_close){const _this=this;spawnMenu(x,y,{type:MenuEntryType.ENTRY,icon:"client-change_nickname",name:"Open text chat",callback:function(){chat.activeChat=_this.chat(!0),chat.focus()}},{type:MenuEntryType.ENTRY,icon:"client-poke",name:"Poke client",callback:function(){createInputModal("Poke client","Poke message:
",text=>!0,result=>{result&&(console.log("Poking client "+_this.clientNickName()+" with message "+result),_this.channelTree.client.serverConnection.sendCommand("clientpoke",{clid:_this.clientId(),msg:result}))},{width:400,maxLength:512}).open()}},{type:MenuEntryType.ENTRY,icon:"client-edit",name:"Change description",callback:function(){createInputModal("Change client description","New description:
",text=>!0,result=>{result&&(console.log("Changing "+_this.clientNickName()+"'s description to "+result),_this.channelTree.client.serverConnection.sendCommand("clientedit",{clid:_this.clientId(),client_description:result}))},{width:400,maxLength:1024}).open()}},MenuEntry.HR(),{type:MenuEntryType.ENTRY,icon:"client-move_client_to_own_channel",name:"Move client to your channel",callback:()=>{this.channelTree.client.serverConnection.sendCommand("clientmove",{clid:this.clientId(),cid:this.channelTree.client.getClient().currentChannel().getChannelId()})}},{type:MenuEntryType.ENTRY,icon:"client-kick_channel",name:"Kick client from channel",callback:function(){createInputModal("Kick client from channel","Kick reason:
",text=>!0,result=>{result&&(console.log("Kicking client "+_this.clientNickName()+" from channel with reason "+result),_this.channelTree.client.serverConnection.sendCommand("clientkick",{clid:_this.clientId(),reasonid:ViewReasonId.VREASON_CHANNEL_KICK,reasonmsg:result}))},{width:400,maxLength:255}).open()}},{type:MenuEntryType.ENTRY,icon:"client-kick_server",name:"Kick client fom server",callback:function(){createInputModal("Kick client from server","Kick reason:
",text=>!0,result=>{result&&(console.log("Kicking client "+_this.clientNickName()+" from server with reason "+result),_this.channelTree.client.serverConnection.sendCommand("clientkick",{clid:_this.clientId(),reasonid:ViewReasonId.VREASON_SERVER_KICK,reasonmsg:result}))},{width:400,maxLength:255}).open()}},{type:MenuEntryType.ENTRY,icon:"client-ban_client",name:"Ban client",invalidPermission:!this.channelTree.client.permissions.neededPermission(PermissionType.I_CLIENT_BAN_MAX_BANTIME).granted(1),callback:()=>{Modals.spawnBanClient(this.properties.client_nickname,(duration,reason)=>{this.channelTree.client.serverConnection.sendCommand("banclient",{uid:this.properties.client_unique_identifier,banreason:reason,time:duration})})}},MenuEntry.HR(),{type:MenuEntryType.ENTRY,icon:"client-volume",name:"Change Volume",callback:()=>{Modals.spawnChangeVolume(this.audioController.volume,volume=>{settings.changeServer("volume_client_"+this.clientUid(),volume),this.audioController.volume=volume,globalClient.selectInfo.currentSelected==this&&globalClient.selectInfo.update()})}},MenuEntry.CLOSE(on_close))}get tag(){if(this._tag)return this._tag;let tag=$.spawn("div");tag.attr("id","client_"+this.clientId()),tag.addClass("client"),tag.append($.spawn("div").addClass("icon_empty")),tag.append($.spawn("div").addClass("icon_client_state").attr("title","Client state")),tag.append($.spawn("div").addClass("name").text(this.clientNickName())),tag.append($.spawn("div").addClass("away").text(this.clientNickName()));let clientIcons=$.spawn("span");return tag.append(clientIcons),this._tag=tag}static chatTag(id,name,uid,braces=!1){let tag=$.spawn("div");return tag.css("cursor","pointer").css("font-weight","bold").css("color","darkblue").css("display","inline-block").css("margin",0),braces?tag.text('"'+name+'"'):tag.text(name),tag.contextmenu(event=>{if(event.isDefaultPrevented())return;event.preventDefault();let client=globalClient.channelTree.findClient(id);client&&client.properties.client_unique_identifier==uid&&client.showContextMenu(event.pageX,event.pageY)}),tag.attr("clientId",id),tag.attr("clientUid",uid),tag.attr("clientName",name),tag}createChatTag(braces=!1){return ClientEntry.chatTag(this.clientId(),this.clientNickName(),this.clientUid(),braces)}set speaking(flag){flag!=this._speaking&&(this._speaking=flag,this.updateClientIcon())}updateClientIcon(){let icon="",clicon="";this.properties.client_away?icon="client-away":this.properties.client_output_muted?icon="client-hardware_output_muted":this.properties.client_input_hardware?this.properties.client_input_muted?icon="client-input_muted":clicon=this._speaking?this.properties.client_is_channel_commander?"client_cc_talk":"client_talk":this.properties.client_is_channel_commander?"client_cc_idle":"client_idle":icon="client-hardware_input_muted",clicon.length>0?this.tag.find(".icon_client_state").attr("class","icon_client_state clicon "+clicon):icon.length>0?this.tag.find(".icon_client_state").attr("class","icon_client_state icon "+icon):this.tag.find(".icon_client_state").attr("class","icon_client_state icon_empty")}updateAwayMessage(){let tag=this.tag.find(".away");1==this.properties.client_away&&this.properties.client_away_message?(tag.text("["+this.properties.client_away_message+"]"),tag.show()):tag.hide()}updateVariables(...variables){let group=log.group(log.LogType.DEBUG,LogCategory.CLIENT,"Update properties (%i) of %s (%i)",variables.length,this.clientNickName(),this.clientId());for(let variable of variables){if("boolean"==typeof this.properties[variable.key]?this.properties[variable.key]="true"==variable.value||"1"==variable.value:"number"==typeof this.properties[variable.key]?this.properties[variable.key]=parseInt(variable.value):this.properties[variable.key]=variable.value,group.log("Updating client "+this.clientId()+". Key "+variable.key+" Value: '"+variable.value+"' ("+typeof this.properties[variable.key]+")"),"client_nickname"==variable.key){this.tag.find(".name").text(variable.value);let chat=this.chat(!1);chat&&(chat.name=variable.value)}"client_away"!=variable.key&&"client_output_muted"!=variable.key&&"client_input_hardware"!=variable.key&&"client_input_muted"!=variable.key&&"client_is_channel_commander"!=variable.key||this.updateClientIcon(),"client_away_message"!=variable.key&&"client_away"!=variable.key||this.updateAwayMessage(),"client_unique_identifier"==variable.key&&(this.audioController.volume=parseFloat(settings.server("volume_client_"+this.clientUid(),"1")),console.error("Updated volume from config "+this.audioController.volume+" - volume_client_"+this.clientUid()+" - "+settings.server("volume_client_"+this.clientUid(),"1")),console.log(this.avatarId()))}group.end()}updateClientVariables(){(0==this.lastVariableUpdate||(new Date).getTime()-6e5>this.lastVariableUpdate)&&(this.lastVariableUpdate=(new Date).getTime(),this.channelTree.client.serverConnection.sendCommand("clientgetvariables",{clid:this.clientId()}))}chat(create=!1){let chatName="client_"+this.clientUid()+":"+this.clientId(),c=chat.findChat(chatName);if(!c&&create){(c=chat.createChat(chatName)).closeable=!0,c.name=this.clientNickName();const _this=this;c.onMessageSend=function(text){_this.channelTree.client.serverConnection.sendMessage(text,ChatType.CLIENT,_this)},c.onClose=function(){return _this.channelTree.client.serverConnection.sendCommand("clientchatclosed",{clid:_this.clientId()}),!0}}return c}updateGroupIcon(group){this.tag.find(".icon_group_"+group.id).detach(),group.properties.iconid>0&&this.tag.find("span").append(this.channelTree.client.fileManager.icons.generateTag(group.properties.iconid).addClass("icon_group_"+group.id))}assignedServerGroupIds(){let result=[];for(let id of this.properties.client_servergroups.split(","))0!=id.length&&result.push(Number.parseInt(id));return result}assignedChannelGroup(){return this.properties.client_channel_group_id}groupAssigned(group){if(group.target==GroupTarget.SERVER){for(let id of this.assignedServerGroupIds())if(id==group.id)return!0;return!1}return group.id==this.assignedChannelGroup()}onDelete(){this.audioController.close(),this.audioController=void 0}calculateOnlineTime(){return Date.now()/1e3-this.properties.client_lastconnected}avatarId(){try{let raw=atob(this.properties.client_unique_identifier),input=hex.encode(function(str){let buf=new ArrayBuffer(str.length),bufView=new Uint8Array(buf);for(let i=0,strLen=str.length;i="0"&&c<="9"?offset=c.charCodeAt(0)-"0".charCodeAt(0):c>="A"&&c<="F"?offset=c.charCodeAt(0)-"A".charCodeAt(0)+10:c>="a"&&c<="f"&&(offset=c.charCodeAt(0)-"a".charCodeAt(0)+10),result+=String.fromCharCode("a".charCodeAt(0)+offset)}return result}catch(e){return}}}class LocalClientEntry extends ClientEntry{constructor(handle){super(0,"local client"),this.handle=handle}showContextMenu(x,y,on_close){const _self=this;spawnMenu(x,y,{name:"Change name",icon:"client-change_nickname",callback:()=>_self.openRename(),type:MenuEntryType.ENTRY},{name:"Change description",icon:"client-edit",callback:()=>{createInputModal("Change own description","New description:
",text=>!0,result=>{result&&(console.log("Changing own description to "+result),_self.channelTree.client.serverConnection.sendCommand("clientedit",{clid:_self.clientId(),client_description:result}))},{width:400,maxLength:1024}).open()},type:MenuEntryType.ENTRY},MenuEntry.CLOSE(on_close))}initializeListener(){super.initializeListener(),this.tag.find(".name").addClass("own_name");const _self=this;this.tag.dblclick(function(){_self.openRename()})}openRename(){const _self=this,elm=this.tag.find(".name");elm.attr("contenteditable","true"),elm.removeClass("own_name"),elm.css("background-color","white"),elm.focus(),_self.renaming=!0,elm.keypress(function(e){if(13==e.keyCode)return $(this).trigger("focusout"),!1}),elm.focusout(function(e){if(!_self.renaming)return;_self.renaming=!1,elm.css("background-color",""),elm.removeAttr("contenteditable"),elm.addClass("own_name");let text=elm.text().toString();_self.clientNickName()!=text&&(elm.text(_self.clientNickName()),_self.handle.serverConnection.updateClient("client_nickname",text).then(e=>{chat.serverChat().appendMessage("Nickname successfully changed")}).catch(e=>{chat.serverChat().appendError("Could not change nickname ("+e.extra_message+")"),_self.openRename()}))})}}function chat_client_contextmenu(_element,event){event.preventDefault();let element=$(_element);console.log("Context menue for "+element.attr("clientName"));let clid=Number.parseInt(element.attr("clientId")),client=globalClient.channelTree.findClient(clid);client&&client.clientUid()==element.attr("clientUid")&&client.showContextMenu(event.pageX,event.pageY)}!function(Modals){Modals.createChannelModal=function(channel,parent,callback){let properties={};const modal=createModal({header:channel?"Edit channel":"Create channel",body:()=>{let template=$("#tmpl_channel_edit").tmpl(channel?channel.properties:new ChannelProperties);return(template=$.spawn("div").append(template)).tabify()},footer:()=>{let footer=$.spawn("div");footer.addClass("modal-button-group"),footer.css("margin","5px");let buttonCancel=$.spawn("button");buttonCancel.text("Cancel").addClass("button_cancel");let buttonOk=$.spawn("button");return buttonOk.text("Ok").addClass("button_ok"),footer.append(buttonCancel),footer.append(buttonOk),footer},width:500});!function(properties,tag,button,create){let updateButton=()=>{0==tag.find(".input_error").length?button.removeAttr("disabled"):button.attr("disabled","true")};tag.find(".channel_name").change(function(){properties.channel_name=this.value,$(this).removeClass("input_error"),(this.value.length<1||this.value.length>40)&&$(this).addClass("input_error"),updateButton()}).prop("disabled",!create&&!globalClient.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_NAME).granted(1)),tag.find(".channel_password").change(function(){properties.channel_flag_password=0!=this.value.length,properties.channel_flag_password&&helpers.hashPassword(this.value).then(pass=>properties.channel_password=pass),$(this).removeClass("input_error"),properties.channel_flag_password||globalClient.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_FORCE_PASSWORD).granted(1)&&$(this).addClass("input_error"),updateButton()}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_PASSWORD:PermissionType.B_CHANNEL_MODIFY_PASSWORD).granted(1)),tag.find(".channel_topic").change(function(){properties.channel_topic=this.value}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_TOPIC:PermissionType.B_CHANNEL_MODIFY_TOPIC).granted(1)),tag.find(".channel_description").change(function(){properties.channel_description=this.value}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_DESCRIPTION:PermissionType.B_CHANNEL_MODIFY_DESCRIPTION).granted(1)),create&&(tag.find(".channel_name").trigger("change"),tag.find(".channel_password").trigger("change"))}(properties,modal.htmlTag.find(".channel_general_properties"),modal.htmlTag.find(".button_ok"),!channel),function(properties,tag,button,parent,create){tag.find('input[name="channel_type"]').change(function(){switch(this.value){case"semi":properties.channel_flag_permanent=!1,properties.channel_flag_semi_permanent=!0;break;case"perm":properties.channel_flag_permanent=!0,properties.channel_flag_semi_permanent=!1;break;default:properties.channel_flag_permanent=!1,properties.channel_flag_semi_permanent=!1}}),tag.find('input[name="channel_type"][value="temp"]').prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_TEMPORARY:PermissionType.B_CHANNEL_MODIFY_MAKE_TEMPORARY).granted(1)),tag.find('input[name="channel_type"][value="semi"]').prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT:PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT).granted(1)),tag.find('input[name="channel_type"][value="perm"]').prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_PERMANENT:PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1)),tag.find('input[name="channel_type"]:not(:disabled)').last().prop("checked",!0).trigger("change"),tag.find('input[name="channel_default"]').change(function(){console.log(this.checked),properties.channel_flag_default=this.checked;let elements=tag.find('input[name="channel_type"]');this.checked?(elements.prop("enabled",!1),elements.prop("checked",!1),tag.find('input[name="channel_type"][value="perm"]').prop("checked",!0).trigger("change")):elements.removeProp("enabled")}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_PERMANENT:PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1)||!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_DEFAULT:PermissionType.B_CHANNEL_MODIFY_MAKE_DEFAULT).granted(1)),tag.find('input[name="talk_power"]').change(function(){properties.channel_needed_talk_power=parseInt(this.value)}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_NEEDED_TALK_POWER:PermissionType.B_CHANNEL_MODIFY_NEEDED_TALK_POWER).granted(1));let orderTag=tag.find(".order_id");for(let channel of parent?parent.siblings():globalClient.channelTree.rootChannel())$.spawn("option").attr("channelId",channel.channelId.toString()).text(channel.channelName()).appendTo(orderTag);orderTag.change(function(){let selected=$(this.options.item(this.selectedIndex));properties.channel_order=parseInt(selected.attr("channelId"))}).prop("disabled",!globalClient.permissions.neededPermission(create?PermissionType.B_CHANNEL_CREATE_WITH_SORTORDER:PermissionType.B_CHANNEL_MODIFY_SORTORDER).granted(1)),orderTag.find("option").last().prop("selected",!0)}(properties,modal.htmlTag.find(".settings_standard"),modal.htmlTag.find(".button_ok"),parent,!channel),modal.htmlTag.find(".button_ok").click(()=>{modal.close(),callback(properties)}),modal.htmlTag.find(".button_cancel").click(()=>{modal.close(),callback()}),modal.open()}}(Modals||(Modals={}));class ChannelTree{constructor(client,htmlTree){if(this.client=client,this.htmlTree=htmlTree,this.reset(),!settings.static(Settings.KEY_DISABLE_CONTEXT_MENU,!1)){let _this=this;this.htmlTree.parent().on("contextmenu",function(event){event.isDefaultPrevented()||(event.preventDefault(),_this.onSelect(void 0),_this.showContextMenu(event.pageX,event.pageY))})}}showContextMenu(x,y,on_close){let channelCreate=this.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_TEMPORARY).granted(1)||this.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT).granted(1)||this.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_PERMANENT).granted(1);spawnMenu(x,y,{type:MenuEntryType.ENTRY,icon:"client-channel_create",name:"Create channel",invalidPermission:!channelCreate,callback:()=>this.spawnCreateChannel()},MenuEntry.CLOSE(on_close))}initialiseHead(serverName){this.server=new ServerEntry(this,serverName),this.server.htmlTag.appendTo(this.htmlTree),this.server.initializeListener()}__deleteAnimation(element){let tag=element instanceof ChannelEntry?element.rootTag():element.tag;this.htmlTree.find(tag).fadeOut("slow",()=>{tag.remove(),element instanceof ChannelEntry?element.parentChannel()&&element.parentChannel().adjustSize(!0):element instanceof ClientEntry&&element.currentChannel().adjustSize(!0)})}rootChannel(){return this.channels.filter(e=>null==e.parent)}deleteChannel(channel){const _this=this;for(let index=0;index .channelLine").addClass("selected"):entry instanceof ClientEntry?entry.tag.addClass("selected"):entry instanceof ServerEntry&&entry.htmlTag.addClass("selected"),this.client.selectInfo.currentSelected=entry}clientsByGroup(group){let result=[];for(let client of this.clients)client.groupAssigned(group)&&result.push(client);return result}clientsByChannel(channel){let result=[];for(let client of this.clients)client.currentChannel()==channel&&result.push(client);return result}reset(){this.server=null,this.clients=[],this.channels=[],this.htmlTree.empty()}spawnCreateChannel(parent){Modals.createChannelModal(void 0,parent,properties=>{properties&&(properties.cpid=parent?parent.channelId:0,log.debug(LogCategory.CHANNEL,"Creating new channel with properties: %o",properties),this.client.serverConnection.sendCommand("channelcreate",properties))})}}class CommandResult{constructor(json){this.json=json,this.id=json.id,this.message=json.msg,this.extra_message="",json.extra_msg&&(this.extra_message=json.extra_msg),this.success=0==this.id}}class ReturnListener{}class ServerConnection{constructor(client){this._connectionState=ConnectionState.UNCONNECTED,this._connectTimeoutHandler=void 0,this._connected=!1,this.on_connect=(()=>{console.log("Socket connected"),chat.serverChat().appendMessage("Logging in..."),this._handshakeHandler.startHandshake()}),this._client=client,this._socket=null,this.commandHandler=new ConnectionCommandHandler(this),this._retCodeIdx=0,this._retListener=[]}generateReturnCode(){return(this._retCodeIdx++).toString()}startConnection(host,port,handshake,timeout=1e3){this._connectTimeoutHandler&&(clearTimeout(this._connectTimeoutHandler),this._connectTimeoutHandler=null,this.disconnect()),this.updateConnectionState(ConnectionState.CONNECTING),this._remoteHost=host,this._remotePort=port,this._handshakeHandler=handshake,this._handshakeHandler.setConnection(this),this._connected=!1,chat.serverChat().appendMessage("Connecting to "+host+":"+port);const self=this;try{let sockCpy;if(this._connectTimeoutHandler=setTimeout(()=>{this.disconnect(),this._client.handleDisconnect(DisconnectReason.CONNECT_FAILURE)},timeout),this._socket=sockCpy=new WebSocket("wss:"+this._remoteHost+":"+this._remotePort),clearTimeout(this._connectTimeoutHandler),this._connectTimeoutHandler=null,this._socket!=sockCpy)return;this._socket.onopen=(()=>{this._socket==sockCpy&&(this._connected=!0,this.on_connect())}),this._socket.onclose=(event=>{this._socket==sockCpy&&this._client.handleDisconnect(this._connected?DisconnectReason.CONNECTION_CLOSED:DisconnectReason.CONNECT_FAILURE,{code:event.code,reason:event.reason,event:event})}),this._socket.onerror=(e=>{this._socket==sockCpy&&(console.log("Got error: ("+self._socket.readyState+")"),console.log(e))}),this._socket.onmessage=(msg=>{this._socket==sockCpy&&self.handleWebSocketMessage(msg.data)}),this.updateConnectionState(ConnectionState.INITIALISING)}catch(e){this.disconnect(),this._client.handleDisconnect(DisconnectReason.CONNECT_FAILURE,e)}}updateConnectionState(state){this._connectionState=state}disconnect(){if(this._connectionState==ConnectionState.UNCONNECTED)return!1;this.updateConnectionState(ConnectionState.UNCONNECTED),this._socket&&this._socket.close(3255,"request disconnect"),this._socket=null;for(let future of this._retListener)future.reject("Connection closed");return this._retListener=[],this._retCodeIdx=0,this._connected=!1,!0}handleWebSocketMessage(data){if("string"==typeof data){let json;try{json=JSON.parse(data)}catch(e){return console.error("Could not parse message json!"),void alert(e)}if(void 0===json.type)return void console.log("Missing data type!");"command"===json.type?this.handleCommand(json):"WebRTC"===json.type?this._client.voiceConnection.handleControlPacket(json):console.log("Unknown command type "+json.type)}}handleCommand(json){let group=log.group(log.LogType.DEBUG,LogCategory.NETWORKING,"Handling command '%s'",json.command);group.log("Handling command '"+json.command+"'"),group.group(log.LogType.TRACE,"Json:").collapsed(!0).log("%o",json).end();try{let fn=this.commandHandler[json.command];if(void 0===fn)return void group.log("Missing command '"+json.command+"'");fn.call(this.commandHandler,json.data)}finally{group.end()}}sendData(data){this._socket.send(data)}commandiefy(input){return JSON.stringify(input,(key,value)=>{switch(typeof value){case"boolean":return 1==value?"1":"0";case"function":return value();default:return value}})}sendCommand(command,data={},logResult=!0){const _this=this;let result=new Promise((resolve,failed)=>{let _data=$.isArray(data)?data:[data],retCode=void 0!==_data[0].return_code?_data[0].return_code:_this.generateReturnCode();_data[0].return_code=retCode;let listener=new ReturnListener;listener.resolve=resolve,listener.reject=failed,listener.code=retCode,listener.timeout=setTimeout(()=>{_this._retListener.remove(listener),listener.reject("timeout")},1500),this._retListener.push(listener),this._socket.send(this.commandiefy({type:"command",command:command,data:_data}))});return new Promise((resolve,failed)=>{result.then(resolve).catch(ex=>{if(logResult)if(ex instanceof CommandResult){let res=ex;res.success||chat.serverChat().appendError(0==res.extra_message.length?res.message:res.extra_message)}else"string"==typeof ex?chat.serverChat().appendError("Command execution resuluts in "+ex):(console.error("Invalid promise result type: "+typeof ex+". Result:"),console.error(ex));failed(ex)})})}get connected(){return this._socket&&this._socket.readyState==WebSocket.OPEN}joinChannel(channel,password=""){return this.sendCommand("clientmove",[{clid:this._client.getClientId(),cid:channel.getChannelId(),cpw:password}])}sendMessage(message,type,target){return type==ChatType.SERVER?this.sendCommand("sendtextmessage",{targetmode:3,target:0,msg:message}):type==ChatType.CHANNEL?this.sendCommand("sendtextmessage",{targetmode:2,target:target.getChannelId(),msg:message}):type==ChatType.CLIENT?this.sendCommand("sendtextmessage",{targetmode:1,target:target.clientId(),msg:message}):void 0}updateClient(key,value){let data={};return data[key]=value,this.sendCommand("clientupdate",data)}}class HandshakeHandler{constructor(identity,name){this.identity=identity,this.name=name}setConnection(con){this.connection=con,this.connection.commandHandler.handshakeidentityproof=this.handleCommandHandshakeIdentityProof.bind(this)}startHandshake(){let data={intention:0,authentication_method:this.identity.type()};this.identity.type()==IdentitifyType.TEAMSPEAK?data.publicKey=this.identity.publicKey():this.identity.type()==IdentitifyType.TEAFORO&&(data.data=this.identity.identityDataJson),this.connection.sendCommand("handshakebegin",data).catch(error=>{console.log(error)})}handleCommandHandshakeIdentityProof(json){let proof;this.identity.type()==IdentitifyType.TEAMSPEAK?proof=this.identity.signMessage(json[0].message):this.identity.type()==IdentitifyType.TEAFORO&&(proof=this.identity.identitySign),this.connection.sendCommand("handshakeindentityproof",{proof:proof}).then(()=>{this.connection.sendCommand("clientinit",{client_nickname:this.name?this.name:this.identity.name(),client_platform:navigator.platform,client_version:navigator.userAgent,client_browser_engine:navigator.product})}).catch(error=>{console.error("Got login error"),console.log(error)})}}class ConnectionCommandHandler{constructor(connection){this.connection=connection,this.error=this.handleCommandResult,this.channellist=this.handleCommandChannelList,this.notifychannelcreated=this.handleCommandChannelCreate,this.notifychanneldeleted=this.handleCommandChannelDelete,this.notifycliententerview=this.handleCommandClientEnterView,this.notifyclientleftview=this.handleCommandClientLeftView,this.notifyclientmoved=this.handleNotifyClientMoved,this.initserver=this.handleCommandServerInit,this.notifychannelmoved=this.handleNotifyChannelMoved,this.notifychanneledited=this.handleNotifyChannelEdited,this.notifytextmessage=this.handleNotifyTextMessage,this.notifyclientupdated=this.handleNotifyClientUpdated,this.notifyserveredited=this.handleNotifyServerEdited,this.notifyserverupdated=this.handleNotifyServerUpdated}handleCommandResult(json){let code=(json=json[0]).return_code;if(0==code.length)return void console.log("Invalid return code! ("+json+")");let retListeners=this.connection._retListener;for(let e of retListeners){if(e.code!=code)continue;retListeners.remove(e);let result=new CommandResult(json);result.success?e.resolve(result):e.reject(result);break}}handleCommandServerInit(json){console.log("Setting up voice "),this.connection._client.voiceConnection.createSession(),json=json[0],this.connection._client.clientId=parseInt(json.aclid),this.connection._client.getClient().updateVariables({key:"client_nickname",value:json.acn});for(let key in json)"aclid"!==key&&"acn"!==key&&this.connection._client.channelTree.server.updateProperty(key,json[key]);chat.serverChat().name=this.connection._client.channelTree.server.properties.virtualserver_name,chat.serverChat().appendMessage("Connected as {0}",!0,this.connection._client.getClient().createChatTag(!0)),globalClient.onConnected()}createChannelFromJson(json,ignoreOrder=!1){let tree=this.connection._client.channelTree,channel=new ChannelEntry(parseInt(json.cid),json.channel_name,tree.findChannel(json.cpid));if(tree.insertChannel(channel),"0"!==json.channel_order){let prev=tree.findChannel(json.channel_order);if(!prev&&0!=json.channel_order&&!ignoreOrder)return void console.error("Invalid channel order id!");let parent=tree.findChannel(json.cpid);if(!parent&&0!=json.cpid)return void console.error("Invalid channel parent");tree.moveChannel(channel,prev,parent)}if(ignoreOrder)for(let ch of tree.channels)ch.properties.channel_order==channel.channelId&&tree.moveChannel(ch,channel,channel.parent);let updates=[];for(let key in json)"cid"!==key&&"cpid"!==key&&"invokerid"!==key&&"invokername"!==key&&"invokeruid"!==key&&"reasonid"!==key&&updates.push({key:key,value:json[key]});channel.updateVariables(...updates)}handleCommandChannelList(json){console.log("Got "+json.length+" new channels");for(let index=0;index> "+json.msg)}else 2==mode?chat.channelChat().appendMessage("{0} >> {1}",!0,ClientEntry.chatTag(json.invokerid,json.invokername,json.invokeruid,!0),json.msg):3==mode&&chat.serverChat().appendMessage("{0} >> {1}",!0,ClientEntry.chatTag(json.invokerid,json.invokername,json.invokeruid,!0),json.msg)}handleNotifyClientUpdated(json){json=json[0];let client=this.connection._client.channelTree.findClient(json.clid);if(!client)return void console.error("Tried to update an non existing client");let updates=[];for(let key in json)"clid"!=key&&updates.push({key:key,value:json[key]});client.updateVariables(...updates),this.connection._client.selectInfo.currentSelected==client&&this.connection._client.selectInfo.update()}handleNotifyServerEdited(json){json=json[0];for(let key in json)"invokerid"!==key&&"invokername"!==key&&"invokeruid"!==key&&"reasonid"!==key&&this.connection._client.channelTree.server.updateProperty(key,json[key])}handleNotifyServerUpdated(json){json=json[0];for(let key in json)"invokerid"!==key&&"invokername"!==key&&"invokeruid"!==key&&"reasonid"!==key&&this.connection._client.channelTree.server.updateProperty(key,json[key]);let info=this.connection._client.selectInfo;info.currentSelected instanceof ServerEntry&&info.update()}}if("undefined"!=typeof customElements){class X_Properties extends HTMLElement{}class X_Property extends HTMLElement{}customElements.define("x-properties",X_Properties,{extends:"div"}),customElements.define("x-property",X_Property,{extends:"div"})}class StaticSettings{static get instance(){return this._instance||(this._instance=new StaticSettings(!0)),this._instance}static transformStO(input,_default){return void 0===input?_default:"string"==typeof _default?input:"number"==typeof _default?parseInt(input):"boolean"==typeof _default?"1"==input||"true"==input:void 0===_default?input:JSON.parse(input)}static transformOtS(input){return"string"==typeof input?input:"number"==typeof input?input.toString():"boolean"==typeof input?input?"1":"0":void 0!==input?JSON.stringify(input):void 0}constructor(_reserved){_reserved&&!StaticSettings._instance?(this._staticPropsTag=$("#properties"),this.initializeStatic()):this._handle=StaticSettings.instance}initializeStatic(){location.search.substr(1).split("&").forEach(part=>{let item=part.split("=");$("").attr("key",item[0]).attr("value",item[1]).appendTo(this._staticPropsTag)})}static(key,_default){if(this._handle)return this._handle.static(key,_default);let result=this._staticPropsTag.find("[key='"+key+"']");return console.log("%d | %o",result.length,result),StaticSettings.transformStO(result.length>0?decodeURIComponent(result.last().attr("value")):void 0,_default)}deleteStatic(key){if(this._handle)return void this._handle.deleteStatic(key);let result=this._staticPropsTag.find("[key='"+key+"']");0!=result.length&&result.detach()}}class Settings extends StaticSettings{constructor(){super(),this.cacheGlobal={},this.cacheServer={},this.updated=!1,this.cacheGlobal=JSON.parse(localStorage.getItem("settings.global")),this.cacheGlobal||(this.cacheGlobal={}),this.saveWorker=setInterval(()=>{this.updated&&this.save()},5e3)}global(key,_default){let result=this.cacheGlobal[key];return StaticSettings.transformStO(result,_default)}server(key,_default){let result=this.cacheServer[key];return StaticSettings.transformStO(result,_default)}changeGlobal(key,value){this.cacheGlobal[key]!=value&&(this.updated=!0,this.cacheGlobal[key]=StaticSettings.transformOtS(value),Settings.UPDATE_DIRECT&&this.save())}changeServer(key,value){this.cacheServer[key]!=value&&(this.updated=!0,this.cacheServer[key]=StaticSettings.transformOtS(value),Settings.UPDATE_DIRECT&&this.save())}setServer(server){if(this.currentServer&&(this.save(),this.cacheServer={},this.currentServer=void 0),this.currentServer=server,this.currentServer){let serverId=this.currentServer.properties.virtualserver_unique_identifier;this.cacheServer=JSON.parse(localStorage.getItem("settings.server_"+serverId)),this.cacheServer||(this.cacheServer={})}}save(){if(this.updated=!1,this.currentServer){let serverId=this.currentServer.properties.virtualserver_unique_identifier,server=JSON.stringify(this.cacheServer);localStorage.setItem("settings.server_"+serverId,server)}let global=JSON.stringify(this.cacheGlobal);localStorage.setItem("settings.global",global)}}Settings.KEY_DISABLE_CONTEXT_MENU="disableContextMenu",Settings.KEY_DISABLE_UNLOAD_DIALOG="disableUnloadDialog",Settings.UPDATE_DIRECT=!0;class InfoBar{constructor(client,htmlTag){this.timers=[],this.intervals=[],this.handle=client,this._htmlTag=htmlTag}createInfoTable(infos){let table=$.spawn("table");for(let key in infos){console.log("Display info "+key);let entry=$.spawn("tr");entry.append($.spawn("td").addClass("info_key").html(key+":"));let value=$.spawn("td");console.log(infos[key]),console.log(MessageHelper.formatElement(infos[key])),MessageHelper.formatElement(infos[key]).forEach(e=>e.appendTo(value)),entry.append(value),table.append(entry)}return table}set currentSelected(entry){this._currentSelected!=entry&&(this._currentSelected=entry,this.buildBar())}get currentSelected(){return this._currentSelected}update(){this.buildBar()}updateServerTimings(){this._htmlTag.find(".uptime").text(formatDate(this._currentSelected.calculateUptime()))}updateClientTimings(){this._htmlTag.find(".online").text(formatDate(this._currentSelected.calculateOnlineTime()))}buildBar(){if(this._htmlTag.empty(),this._currentSelected){for(let timer of this.timers)clearTimeout(timer);for(let timer of this.intervals)clearInterval(timer);if(this._currentSelected instanceof ServerEntry){this._currentSelected.shouldUpdateProperties()&&this._currentSelected.updateProperties();let version=this._currentSelected.properties.virtualserver_version;version.startsWith("TeaSpeak ")&&(version=version.substr("TeaSpeak ".length)),this._htmlTag.append(this.createInfoTable({Name:this._currentSelected.properties.virtualserver_name,Address:"unknown",Type:"TeaSpeak",Version:version+" on "+this._currentSelected.properties.virtualserver_platform,Uptime:""+formatDate(this._currentSelected.calculateUptime())+"","Current Channels":this._currentSelected.properties.virtualserver_channelsonline,"Current Clients":this._currentSelected.properties.virtualserver_clientsonline,"Current Queries":this._currentSelected.properties.virtualserver_queryclientsonline})),this._htmlTag.append($.spawn("div").css("height","100%"));let requestUpdate=$.spawn("button");requestUpdate.css("min-height","16px"),requestUpdate.css("bottom",0),requestUpdate.text("update info"),this._currentSelected.shouldUpdateProperties()?requestUpdate.css("color","green"):(requestUpdate.attr("disabled","true"),requestUpdate.css("color","red")),this._htmlTag.append(requestUpdate);const _server=this._currentSelected,_this=this;requestUpdate.click(function(){_server.updateProperties(),_this.buildBar()}),this.timers.push(setTimeout(function(){requestUpdate.css("color","green"),requestUpdate.removeAttr("disabled")},_server.nextInfoRequest-(new Date).getTime())),this.intervals.push(setInterval(this.updateServerTimings.bind(this),1e3))}else if(this._currentSelected instanceof ChannelEntry){let props=this._currentSelected.properties;this._htmlTag.append(this.createInfoTable({Name:this._currentSelected.createChatTag(),Topic:this._currentSelected.properties.channel_topic,Codec:this._currentSelected.properties.channel_codec,"Codec Quality":this._currentSelected.properties.channel_codec_quality,Type:ChannelType.normalize(this._currentSelected.channelType()),"Current clients":this._currentSelected.channelTree.clientsByChannel(this._currentSelected).length+" / "+(-1==props.channel_maxclients?"Unlimited":props.channel_maxclients),"Subscription Status":"unknown","Voice Data Encryption":"unknown"}))}else if(this._currentSelected instanceof ClientEntry){this._currentSelected.updateClientVariables();let version=this._currentSelected.properties.client_version;version||(version="");let infos={Name:this._currentSelected.createChatTag(),Description:this._currentSelected.properties.client_description,Version:MessageHelper.formatMessage("{0} on {1}",$.spawn("a").attr("title",version).text(version.split(" ")[0]),this._currentSelected.properties.client_platform),"Online since":$.spawn("a").addClass("online").text(formatDate(this._currentSelected.calculateOnlineTime())),Volume:100*this._currentSelected.audioController.volume+" %"};this._currentSelected.properties.client_teaforum_id>0&&(infos["TeaSpeak Account"]=$.spawn("a").attr("href","//forum.teaspeak.de/index.php?members/"+this._currentSelected.properties.client_teaforum_id).attr("target","_blank").text(this._currentSelected.properties.client_teaforum_id)),this._htmlTag.append(this.createInfoTable(infos));{let serverGroups=$.spawn("div");serverGroups.css("display","flex").css("flex-direction","column");let header=$.spawn("div");header.css("display","flex").css("margin-top","5px").css("align-items","center"),$.spawn("div").addClass("icon client-permission_server_groups").appendTo(header),$.spawn("div").text("Server groups:").css("margin-left","3px").css("font-weight","bold").appendTo(header),header.appendTo(serverGroups);for(let groupId of this._currentSelected.assignedServerGroupIds()){let group=this.handle.groups.serverGroup(groupId);if(!group)continue;let groupTag=$.spawn("div");groupTag.css("display","flex").css("margin-top","1px").css("margin-left","10px").css("align-items","center"),this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag),$.spawn("div").text(group.name).css("margin-left","3px").appendTo(groupTag),groupTag.appendTo(serverGroups)}this._htmlTag.append(serverGroups)}{let channelGroup=$.spawn("div");channelGroup.css("display","flex").css("flex-direction","column");let header=$.spawn("div");header.css("display","flex").css("margin-top","10px").css("align-items","center"),$.spawn("div").addClass("icon client-permission_channel").appendTo(header),$.spawn("div").text("Channel group:").css("margin-left","3px").css("font-weight","bold").appendTo(header),header.appendTo(channelGroup);let group=this.handle.groups.channelGroup(this._currentSelected.assignedChannelGroup());if(group){let groupTag=$.spawn("div");groupTag.css("display","flex").css("margin-top","1px").css("margin-left","10px").css("align-items","center"),this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag),$.spawn("div").text(group.name).css("margin-left","3px").appendTo(groupTag),groupTag.appendTo(channelGroup)}this._htmlTag.append(channelGroup)}this._currentSelected.properties.client_flag_avatar.length>0&&this.handle.fileManager.avatars.generateTag(this._currentSelected).css("margin-top","20px").css("max-height","90%").css("max-width","100%").appendTo(this._htmlTag),this.intervals.push(setInterval(this.updateClientTimings.bind(this),1e3))}}}}!function(PermissionType){PermissionType.B_SERVERINSTANCE_HELP_VIEW="b_serverinstance_help_view",PermissionType.B_SERVERINSTANCE_VERSION_VIEW="b_serverinstance_version_view",PermissionType.B_SERVERINSTANCE_INFO_VIEW="b_serverinstance_info_view",PermissionType.B_SERVERINSTANCE_VIRTUALSERVER_LIST="b_serverinstance_virtualserver_list",PermissionType.B_SERVERINSTANCE_BINDING_LIST="b_serverinstance_binding_list",PermissionType.B_SERVERINSTANCE_PERMISSION_LIST="b_serverinstance_permission_list",PermissionType.B_SERVERINSTANCE_PERMISSION_FIND="b_serverinstance_permission_find",PermissionType.B_VIRTUALSERVER_CREATE="b_virtualserver_create",PermissionType.B_VIRTUALSERVER_DELETE="b_virtualserver_delete",PermissionType.B_VIRTUALSERVER_START_ANY="b_virtualserver_start_any",PermissionType.B_VIRTUALSERVER_STOP_ANY="b_virtualserver_stop_any",PermissionType.B_VIRTUALSERVER_CHANGE_MACHINE_ID="b_virtualserver_change_machine_id",PermissionType.B_VIRTUALSERVER_CHANGE_TEMPLATE="b_virtualserver_change_template",PermissionType.B_SERVERQUERY_LOGIN="b_serverquery_login",PermissionType.B_SERVERINSTANCE_TEXTMESSAGE_SEND="b_serverinstance_textmessage_send",PermissionType.B_SERVERINSTANCE_LOG_VIEW="b_serverinstance_log_view",PermissionType.B_SERVERINSTANCE_LOG_ADD="b_serverinstance_log_add",PermissionType.B_SERVERINSTANCE_STOP="b_serverinstance_stop",PermissionType.B_SERVERINSTANCE_MODIFY_SETTINGS="b_serverinstance_modify_settings",PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP="b_serverinstance_modify_querygroup",PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES="b_serverinstance_modify_templates",PermissionType.B_VIRTUALSERVER_SELECT="b_virtualserver_select",PermissionType.B_VIRTUALSERVER_INFO_VIEW="b_virtualserver_info_view",PermissionType.B_VIRTUALSERVER_CONNECTIONINFO_VIEW="b_virtualserver_connectioninfo_view",PermissionType.B_VIRTUALSERVER_CHANNEL_LIST="b_virtualserver_channel_list",PermissionType.B_VIRTUALSERVER_CHANNEL_SEARCH="b_virtualserver_channel_search",PermissionType.B_VIRTUALSERVER_CLIENT_LIST="b_virtualserver_client_list",PermissionType.B_VIRTUALSERVER_CLIENT_SEARCH="b_virtualserver_client_search",PermissionType.B_VIRTUALSERVER_CLIENT_DBLIST="b_virtualserver_client_dblist",PermissionType.B_VIRTUALSERVER_CLIENT_DBSEARCH="b_virtualserver_client_dbsearch",PermissionType.B_VIRTUALSERVER_CLIENT_DBINFO="b_virtualserver_client_dbinfo",PermissionType.B_VIRTUALSERVER_PERMISSION_FIND="b_virtualserver_permission_find",PermissionType.B_VIRTUALSERVER_CUSTOM_SEARCH="b_virtualserver_custom_search",PermissionType.B_VIRTUALSERVER_START="b_virtualserver_start",PermissionType.B_VIRTUALSERVER_STOP="b_virtualserver_stop",PermissionType.B_VIRTUALSERVER_TOKEN_LIST="b_virtualserver_token_list",PermissionType.B_VIRTUALSERVER_TOKEN_ADD="b_virtualserver_token_add",PermissionType.B_VIRTUALSERVER_TOKEN_USE="b_virtualserver_token_use",PermissionType.B_VIRTUALSERVER_TOKEN_DELETE="b_virtualserver_token_delete",PermissionType.B_VIRTUALSERVER_LOG_VIEW="b_virtualserver_log_view",PermissionType.B_VIRTUALSERVER_LOG_ADD="b_virtualserver_log_add",PermissionType.B_VIRTUALSERVER_JOIN_IGNORE_PASSWORD="b_virtualserver_join_ignore_password",PermissionType.B_VIRTUALSERVER_NOTIFY_REGISTER="b_virtualserver_notify_register",PermissionType.B_VIRTUALSERVER_NOTIFY_UNREGISTER="b_virtualserver_notify_unregister",PermissionType.B_VIRTUALSERVER_SNAPSHOT_CREATE="b_virtualserver_snapshot_create",PermissionType.B_VIRTUALSERVER_SNAPSHOT_DEPLOY="b_virtualserver_snapshot_deploy",PermissionType.B_VIRTUALSERVER_PERMISSION_RESET="b_virtualserver_permission_reset",PermissionType.B_VIRTUALSERVER_MODIFY_NAME="b_virtualserver_modify_name",PermissionType.B_VIRTUALSERVER_MODIFY_WELCOMEMESSAGE="b_virtualserver_modify_welcomemessage",PermissionType.B_VIRTUALSERVER_MODIFY_MAXCLIENTS="b_virtualserver_modify_maxclients",PermissionType.B_VIRTUALSERVER_MODIFY_RESERVED_SLOTS="b_virtualserver_modify_reserved_slots",PermissionType.B_VIRTUALSERVER_MODIFY_PASSWORD="b_virtualserver_modify_password",PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_SERVERGROUP="b_virtualserver_modify_default_servergroup",PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_CHANNELGROUP="b_virtualserver_modify_default_channelgroup",PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_CHANNELADMINGROUP="b_virtualserver_modify_default_channeladmingroup",PermissionType.B_VIRTUALSERVER_MODIFY_CHANNEL_FORCED_SILENCE="b_virtualserver_modify_channel_forced_silence",PermissionType.B_VIRTUALSERVER_MODIFY_COMPLAIN="b_virtualserver_modify_complain",PermissionType.B_VIRTUALSERVER_MODIFY_ANTIFLOOD="b_virtualserver_modify_antiflood",PermissionType.B_VIRTUALSERVER_MODIFY_FT_SETTINGS="b_virtualserver_modify_ft_settings",PermissionType.B_VIRTUALSERVER_MODIFY_FT_QUOTAS="b_virtualserver_modify_ft_quotas",PermissionType.B_VIRTUALSERVER_MODIFY_HOSTMESSAGE="b_virtualserver_modify_hostmessage",PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBANNER="b_virtualserver_modify_hostbanner",PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBUTTON="b_virtualserver_modify_hostbutton",PermissionType.B_VIRTUALSERVER_MODIFY_PORT="b_virtualserver_modify_port",PermissionType.B_VIRTUALSERVER_MODIFY_HOST="b_virtualserver_modify_host",PermissionType.B_VIRTUALSERVER_MODIFY_AUTOSTART="b_virtualserver_modify_autostart",PermissionType.B_VIRTUALSERVER_MODIFY_NEEDED_IDENTITY_SECURITY_LEVEL="b_virtualserver_modify_needed_identity_security_level",PermissionType.B_VIRTUALSERVER_MODIFY_PRIORITY_SPEAKER_DIMM_MODIFICATOR="b_virtualserver_modify_priority_speaker_dimm_modificator",PermissionType.B_VIRTUALSERVER_MODIFY_LOG_SETTINGS="b_virtualserver_modify_log_settings",PermissionType.B_VIRTUALSERVER_MODIFY_MIN_CLIENT_VERSION="b_virtualserver_modify_min_client_version",PermissionType.B_VIRTUALSERVER_MODIFY_ICON_ID="b_virtualserver_modify_icon_id",PermissionType.B_VIRTUALSERVER_MODIFY_WEBLIST="b_virtualserver_modify_weblist",PermissionType.B_VIRTUALSERVER_MODIFY_CODEC_ENCRYPTION_MODE="b_virtualserver_modify_codec_encryption_mode",PermissionType.B_VIRTUALSERVER_MODIFY_TEMPORARY_PASSWORDS="b_virtualserver_modify_temporary_passwords",PermissionType.B_VIRTUALSERVER_MODIFY_TEMPORARY_PASSWORDS_OWN="b_virtualserver_modify_temporary_passwords_own",PermissionType.B_VIRTUALSERVER_MODIFY_CHANNEL_TEMP_DELETE_DELAY_DEFAULT="b_virtualserver_modify_channel_temp_delete_delay_default",PermissionType.B_VIRTUALSERVER_MODIFY_MUSIC_BOT_LIMIT="b_virtualserver_modify_music_bot_limit",PermissionType.I_CHANNEL_MIN_DEPTH="i_channel_min_depth",PermissionType.I_CHANNEL_MAX_DEPTH="i_channel_max_depth",PermissionType.B_CHANNEL_GROUP_INHERITANCE_END="b_channel_group_inheritance_end",PermissionType.I_CHANNEL_PERMISSION_MODIFY_POWER="i_channel_permission_modify_power",PermissionType.I_CHANNEL_NEEDED_PERMISSION_MODIFY_POWER="i_channel_needed_permission_modify_power",PermissionType.B_CHANNEL_INFO_VIEW="b_channel_info_view",PermissionType.B_CHANNEL_CREATE_CHILD="b_channel_create_child",PermissionType.B_CHANNEL_CREATE_PERMANENT="b_channel_create_permanent",PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT="b_channel_create_semi_permanent",PermissionType.B_CHANNEL_CREATE_TEMPORARY="b_channel_create_temporary",PermissionType.B_CHANNEL_CREATE_PRIVATE="b_channel_create_private",PermissionType.B_CHANNEL_CREATE_WITH_TOPIC="b_channel_create_with_topic",PermissionType.B_CHANNEL_CREATE_WITH_DESCRIPTION="b_channel_create_with_description",PermissionType.B_CHANNEL_CREATE_WITH_PASSWORD="b_channel_create_with_password",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX8="b_channel_create_modify_with_codec_speex8",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX16="b_channel_create_modify_with_codec_speex16",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX32="b_channel_create_modify_with_codec_speex32",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_CELTMONO48="b_channel_create_modify_with_codec_celtmono48",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE="b_channel_create_modify_with_codec_opusvoice",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSMUSIC="b_channel_create_modify_with_codec_opusmusic",PermissionType.I_CHANNEL_CREATE_MODIFY_WITH_CODEC_MAXQUALITY="i_channel_create_modify_with_codec_maxquality",PermissionType.I_CHANNEL_CREATE_MODIFY_WITH_CODEC_LATENCY_FACTOR_MIN="i_channel_create_modify_with_codec_latency_factor_min",PermissionType.B_CHANNEL_CREATE_WITH_MAXCLIENTS="b_channel_create_with_maxclients",PermissionType.B_CHANNEL_CREATE_WITH_MAXFAMILYCLIENTS="b_channel_create_with_maxfamilyclients",PermissionType.B_CHANNEL_CREATE_WITH_SORTORDER="b_channel_create_with_sortorder",PermissionType.B_CHANNEL_CREATE_WITH_DEFAULT="b_channel_create_with_default",PermissionType.B_CHANNEL_CREATE_WITH_NEEDED_TALK_POWER="b_channel_create_with_needed_talk_power",PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_FORCE_PASSWORD="b_channel_create_modify_with_force_password",PermissionType.I_CHANNEL_CREATE_MODIFY_WITH_TEMP_DELETE_DELAY="i_channel_create_modify_with_temp_delete_delay",PermissionType.B_CHANNEL_MODIFY_PARENT="b_channel_modify_parent",PermissionType.B_CHANNEL_MODIFY_MAKE_DEFAULT="b_channel_modify_make_default",PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT="b_channel_modify_make_permanent",PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT="b_channel_modify_make_semi_permanent",PermissionType.B_CHANNEL_MODIFY_MAKE_TEMPORARY="b_channel_modify_make_temporary",PermissionType.B_CHANNEL_MODIFY_NAME="b_channel_modify_name",PermissionType.B_CHANNEL_MODIFY_TOPIC="b_channel_modify_topic",PermissionType.B_CHANNEL_MODIFY_DESCRIPTION="b_channel_modify_description",PermissionType.B_CHANNEL_MODIFY_PASSWORD="b_channel_modify_password",PermissionType.B_CHANNEL_MODIFY_CODEC="b_channel_modify_codec",PermissionType.B_CHANNEL_MODIFY_CODEC_QUALITY="b_channel_modify_codec_quality",PermissionType.B_CHANNEL_MODIFY_CODEC_LATENCY_FACTOR="b_channel_modify_codec_latency_factor",PermissionType.B_CHANNEL_MODIFY_MAXCLIENTS="b_channel_modify_maxclients",PermissionType.B_CHANNEL_MODIFY_MAXFAMILYCLIENTS="b_channel_modify_maxfamilyclients",PermissionType.B_CHANNEL_MODIFY_SORTORDER="b_channel_modify_sortorder",PermissionType.B_CHANNEL_MODIFY_NEEDED_TALK_POWER="b_channel_modify_needed_talk_power",PermissionType.I_CHANNEL_MODIFY_POWER="i_channel_modify_power",PermissionType.I_CHANNEL_NEEDED_MODIFY_POWER="i_channel_needed_modify_power",PermissionType.B_CHANNEL_MODIFY_MAKE_CODEC_ENCRYPTED="b_channel_modify_make_codec_encrypted",PermissionType.B_CHANNEL_MODIFY_TEMP_DELETE_DELAY="b_channel_modify_temp_delete_delay",PermissionType.B_CHANNEL_DELETE_PERMANENT="b_channel_delete_permanent",PermissionType.B_CHANNEL_DELETE_SEMI_PERMANENT="b_channel_delete_semi_permanent",PermissionType.B_CHANNEL_DELETE_TEMPORARY="b_channel_delete_temporary",PermissionType.B_CHANNEL_DELETE_FLAG_FORCE="b_channel_delete_flag_force",PermissionType.I_CHANNEL_DELETE_POWER="i_channel_delete_power",PermissionType.I_CHANNEL_NEEDED_DELETE_POWER="i_channel_needed_delete_power",PermissionType.B_CHANNEL_JOIN_PERMANENT="b_channel_join_permanent",PermissionType.B_CHANNEL_JOIN_SEMI_PERMANENT="b_channel_join_semi_permanent",PermissionType.B_CHANNEL_JOIN_TEMPORARY="b_channel_join_temporary",PermissionType.B_CHANNEL_JOIN_IGNORE_PASSWORD="b_channel_join_ignore_password",PermissionType.B_CHANNEL_JOIN_IGNORE_MAXCLIENTS="b_channel_join_ignore_maxclients",PermissionType.I_CHANNEL_JOIN_POWER="i_channel_join_power",PermissionType.I_CHANNEL_NEEDED_JOIN_POWER="i_channel_needed_join_power",PermissionType.I_CHANNEL_SUBSCRIBE_POWER="i_channel_subscribe_power",PermissionType.I_CHANNEL_NEEDED_SUBSCRIBE_POWER="i_channel_needed_subscribe_power",PermissionType.I_CHANNEL_DESCRIPTION_VIEW_POWER="i_channel_description_view_power",PermissionType.I_CHANNEL_NEEDED_DESCRIPTION_VIEW_POWER="i_channel_needed_description_view_power",PermissionType.I_ICON_ID="i_icon_id",PermissionType.I_MAX_ICON_FILESIZE="i_max_icon_filesize",PermissionType.B_ICON_MANAGE="b_icon_manage",PermissionType.B_GROUP_IS_PERMANENT="b_group_is_permanent",PermissionType.I_GROUP_AUTO_UPDATE_TYPE="i_group_auto_update_type",PermissionType.I_GROUP_AUTO_UPDATE_MAX_VALUE="i_group_auto_update_max_value",PermissionType.I_GROUP_SORT_ID="i_group_sort_id",PermissionType.I_GROUP_SHOW_NAME_IN_TREE="i_group_show_name_in_tree",PermissionType.B_VIRTUALSERVER_SERVERGROUP_LIST="b_virtualserver_servergroup_list",PermissionType.B_VIRTUALSERVER_SERVERGROUP_PERMISSION_LIST="b_virtualserver_servergroup_permission_list",PermissionType.B_VIRTUALSERVER_SERVERGROUP_CLIENT_LIST="b_virtualserver_servergroup_client_list",PermissionType.B_VIRTUALSERVER_CHANNELGROUP_LIST="b_virtualserver_channelgroup_list",PermissionType.B_VIRTUALSERVER_CHANNELGROUP_PERMISSION_LIST="b_virtualserver_channelgroup_permission_list",PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CLIENT_LIST="b_virtualserver_channelgroup_client_list",PermissionType.B_VIRTUALSERVER_CLIENT_PERMISSION_LIST="b_virtualserver_client_permission_list",PermissionType.B_VIRTUALSERVER_CHANNEL_PERMISSION_LIST="b_virtualserver_channel_permission_list",PermissionType.B_VIRTUALSERVER_CHANNELCLIENT_PERMISSION_LIST="b_virtualserver_channelclient_permission_list",PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE="b_virtualserver_servergroup_create",PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE="b_virtualserver_channelgroup_create",PermissionType.I_SERVER_GROUP_MODIFY_POWER="i_server_group_modify_power",PermissionType.I_SERVER_GROUP_NEEDED_MODIFY_POWER="i_server_group_needed_modify_power",PermissionType.I_SERVER_GROUP_MEMBER_ADD_POWER="i_server_group_member_add_power",PermissionType.I_SERVER_GROUP_NEEDED_MEMBER_ADD_POWER="i_server_group_needed_member_add_power",PermissionType.I_SERVER_GROUP_MEMBER_REMOVE_POWER="i_server_group_member_remove_power",PermissionType.I_SERVER_GROUP_NEEDED_MEMBER_REMOVE_POWER="i_server_group_needed_member_remove_power",PermissionType.I_CHANNEL_GROUP_MODIFY_POWER="i_channel_group_modify_power",PermissionType.I_CHANNEL_GROUP_NEEDED_MODIFY_POWER="i_channel_group_needed_modify_power",PermissionType.I_CHANNEL_GROUP_MEMBER_ADD_POWER="i_channel_group_member_add_power",PermissionType.I_CHANNEL_GROUP_NEEDED_MEMBER_ADD_POWER="i_channel_group_needed_member_add_power",PermissionType.I_CHANNEL_GROUP_MEMBER_REMOVE_POWER="i_channel_group_member_remove_power",PermissionType.I_CHANNEL_GROUP_NEEDED_MEMBER_REMOVE_POWER="i_channel_group_needed_member_remove_power",PermissionType.I_GROUP_MEMBER_ADD_POWER="i_group_member_add_power",PermissionType.I_GROUP_NEEDED_MEMBER_ADD_POWER="i_group_needed_member_add_power",PermissionType.I_GROUP_MEMBER_REMOVE_POWER="i_group_member_remove_power",PermissionType.I_GROUP_NEEDED_MEMBER_REMOVE_POWER="i_group_needed_member_remove_power",PermissionType.I_GROUP_MODIFY_POWER="i_group_modify_power",PermissionType.I_GROUP_NEEDED_MODIFY_POWER="i_group_needed_modify_power",PermissionType.I_DISPLAYED_GROUP_MEMBER_ADD_POWER="i_displayed_group_member_add_power",PermissionType.I_DISPLAYED_GROUP_NEEDED_MEMBER_ADD_POWER="i_displayed_group_needed_member_add_power",PermissionType.I_DISPLAYED_GROUP_MEMBER_REMOVE_POWER="i_displayed_group_member_remove_power",PermissionType.I_DISPLAYED_GROUP_NEEDED_MEMBER_REMOVE_POWER="i_displayed_group_needed_member_remove_power",PermissionType.I_DISPLAYED_GROUP_MODIFY_POWER="i_displayed_group_modify_power",PermissionType.I_DISPLAYED_GROUP_NEEDED_MODIFY_POWER="i_displayed_group_needed_modify_power",PermissionType.I_PERMISSION_MODIFY_POWER="i_permission_modify_power",PermissionType.B_PERMISSION_MODIFY_POWER_IGNORE="b_permission_modify_power_ignore",PermissionType.B_VIRTUALSERVER_SERVERGROUP_DELETE="b_virtualserver_servergroup_delete",PermissionType.B_VIRTUALSERVER_CHANNELGROUP_DELETE="b_virtualserver_channelgroup_delete",PermissionType.I_CLIENT_PERMISSION_MODIFY_POWER="i_client_permission_modify_power",PermissionType.I_CLIENT_NEEDED_PERMISSION_MODIFY_POWER="i_client_needed_permission_modify_power",PermissionType.I_CLIENT_MAX_CLONES_UID="i_client_max_clones_uid",PermissionType.I_CLIENT_MAX_IDLETIME="i_client_max_idletime",PermissionType.I_CLIENT_MAX_AVATAR_FILESIZE="i_client_max_avatar_filesize",PermissionType.I_CLIENT_MAX_CHANNEL_SUBSCRIPTIONS="i_client_max_channel_subscriptions",PermissionType.B_CLIENT_IS_PRIORITY_SPEAKER="b_client_is_priority_speaker",PermissionType.B_CLIENT_SKIP_CHANNELGROUP_PERMISSIONS="b_client_skip_channelgroup_permissions",PermissionType.B_CLIENT_FORCE_PUSH_TO_TALK="b_client_force_push_to_talk",PermissionType.B_CLIENT_IGNORE_BANS="b_client_ignore_bans",PermissionType.B_CLIENT_IGNORE_ANTIFLOOD="b_client_ignore_antiflood",PermissionType.B_CLIENT_ISSUE_CLIENT_QUERY_COMMAND="b_client_issue_client_query_command",PermissionType.B_CLIENT_USE_RESERVED_SLOT="b_client_use_reserved_slot",PermissionType.B_CLIENT_USE_CHANNEL_COMMANDER="b_client_use_channel_commander",PermissionType.B_CLIENT_REQUEST_TALKER="b_client_request_talker",PermissionType.B_CLIENT_AVATAR_DELETE_OTHER="b_client_avatar_delete_other",PermissionType.B_CLIENT_IS_STICKY="b_client_is_sticky",PermissionType.B_CLIENT_IGNORE_STICKY="b_client_ignore_sticky",PermissionType.B_CLIENT_MUSIC_CHANNEL_LIST="b_client_music_channel_list",PermissionType.B_CLIENT_MUSIC_SERVER_LIST="b_client_music_server_list",PermissionType.I_CLIENT_MUSIC_INFO="i_client_music_info",PermissionType.I_CLIENT_MUSIC_NEEDED_INFO="i_client_music_needed_info",PermissionType.B_CLIENT_INFO_VIEW="b_client_info_view",PermissionType.B_CLIENT_PERMISSIONOVERVIEW_VIEW="b_client_permissionoverview_view",PermissionType.B_CLIENT_PERMISSIONOVERVIEW_OWN="b_client_permissionoverview_own",PermissionType.B_CLIENT_REMOTEADDRESS_VIEW="b_client_remoteaddress_view",PermissionType.I_CLIENT_SERVERQUERY_VIEW_POWER="i_client_serverquery_view_power",PermissionType.I_CLIENT_NEEDED_SERVERQUERY_VIEW_POWER="i_client_needed_serverquery_view_power",PermissionType.B_CLIENT_CUSTOM_INFO_VIEW="b_client_custom_info_view",PermissionType.I_CLIENT_KICK_FROM_SERVER_POWER="i_client_kick_from_server_power",PermissionType.I_CLIENT_NEEDED_KICK_FROM_SERVER_POWER="i_client_needed_kick_from_server_power",PermissionType.I_CLIENT_KICK_FROM_CHANNEL_POWER="i_client_kick_from_channel_power",PermissionType.I_CLIENT_NEEDED_KICK_FROM_CHANNEL_POWER="i_client_needed_kick_from_channel_power",PermissionType.I_CLIENT_BAN_POWER="i_client_ban_power",PermissionType.I_CLIENT_NEEDED_BAN_POWER="i_client_needed_ban_power",PermissionType.I_CLIENT_MOVE_POWER="i_client_move_power",PermissionType.I_CLIENT_NEEDED_MOVE_POWER="i_client_needed_move_power",PermissionType.I_CLIENT_COMPLAIN_POWER="i_client_complain_power",PermissionType.I_CLIENT_NEEDED_COMPLAIN_POWER="i_client_needed_complain_power",PermissionType.B_CLIENT_COMPLAIN_LIST="b_client_complain_list",PermissionType.B_CLIENT_COMPLAIN_DELETE_OWN="b_client_complain_delete_own",PermissionType.B_CLIENT_COMPLAIN_DELETE="b_client_complain_delete",PermissionType.B_CLIENT_BAN_LIST="b_client_ban_list",PermissionType.B_CLIENT_BAN_LIST_GLOBAL="b_client_ban_list_global",PermissionType.B_CLIENT_BAN_CREATE="b_client_ban_create",PermissionType.B_CLIENT_BAN_CREATE_GLOBAL="b_client_ban_create_global",PermissionType.B_CLIENT_BAN_EDIT="b_client_ban_edit",PermissionType.B_CLIENT_BAN_EDIT_GLOBAL="b_client_ban_edit_global",PermissionType.B_CLIENT_BAN_DELETE_OWN="b_client_ban_delete_own",PermissionType.B_CLIENT_BAN_DELETE="b_client_ban_delete",PermissionType.B_CLIENT_BAN_DELETE_OWN_GLOBAL="b_client_ban_delete_own_global",PermissionType.B_CLIENT_BAN_DELETE_GLOBAL="b_client_ban_delete_global",PermissionType.I_CLIENT_BAN_MAX_BANTIME="i_client_ban_max_bantime",PermissionType.I_CLIENT_PRIVATE_TEXTMESSAGE_POWER="i_client_private_textmessage_power",PermissionType.I_CLIENT_NEEDED_PRIVATE_TEXTMESSAGE_POWER="i_client_needed_private_textmessage_power",PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND="b_client_server_textmessage_send",PermissionType.B_CLIENT_CHANNEL_TEXTMESSAGE_SEND="b_client_channel_textmessage_send",PermissionType.B_CLIENT_OFFLINE_TEXTMESSAGE_SEND="b_client_offline_textmessage_send",PermissionType.I_CLIENT_TALK_POWER="i_client_talk_power",PermissionType.I_CLIENT_NEEDED_TALK_POWER="i_client_needed_talk_power",PermissionType.I_CLIENT_POKE_POWER="i_client_poke_power",PermissionType.I_CLIENT_NEEDED_POKE_POWER="i_client_needed_poke_power",PermissionType.B_CLIENT_SET_FLAG_TALKER="b_client_set_flag_talker",PermissionType.I_CLIENT_WHISPER_POWER="i_client_whisper_power",PermissionType.I_CLIENT_NEEDED_WHISPER_POWER="i_client_needed_whisper_power",PermissionType.B_CLIENT_MODIFY_DESCRIPTION="b_client_modify_description",PermissionType.B_CLIENT_MODIFY_OWN_DESCRIPTION="b_client_modify_own_description",PermissionType.B_CLIENT_MODIFY_DBPROPERTIES="b_client_modify_dbproperties",PermissionType.B_CLIENT_DELETE_DBPROPERTIES="b_client_delete_dbproperties",PermissionType.B_CLIENT_CREATE_MODIFY_SERVERQUERY_LOGIN="b_client_create_modify_serverquery_login",PermissionType.B_CLIENT_MUSIC_CREATE="b_client_music_create",PermissionType.I_CLIENT_MUSIC_LIMIT="i_client_music_limit",PermissionType.I_CLIENT_MUSIC_DELETE_POWER="i_client_music_delete_power",PermissionType.I_CLIENT_MUSIC_NEEDED_DELETE_POWER="i_client_music_needed_delete_power",PermissionType.I_CLIENT_MUSIC_PLAY_POWER="i_client_music_play_power",PermissionType.I_CLIENT_MUSIC_NEEDED_PLAY_POWER="i_client_music_needed_play_power",PermissionType.I_CLIENT_MUSIC_RENAME_POWER="i_client_music_rename_power",PermissionType.I_CLIENT_MUSIC_NEEDED_RENAME_POWER="i_client_music_needed_rename_power",PermissionType.B_FT_IGNORE_PASSWORD="b_ft_ignore_password",PermissionType.B_FT_TRANSFER_LIST="b_ft_transfer_list",PermissionType.I_FT_FILE_UPLOAD_POWER="i_ft_file_upload_power",PermissionType.I_FT_NEEDED_FILE_UPLOAD_POWER="i_ft_needed_file_upload_power",PermissionType.I_FT_FILE_DOWNLOAD_POWER="i_ft_file_download_power",PermissionType.I_FT_NEEDED_FILE_DOWNLOAD_POWER="i_ft_needed_file_download_power",PermissionType.I_FT_FILE_DELETE_POWER="i_ft_file_delete_power",PermissionType.I_FT_NEEDED_FILE_DELETE_POWER="i_ft_needed_file_delete_power",PermissionType.I_FT_FILE_RENAME_POWER="i_ft_file_rename_power",PermissionType.I_FT_NEEDED_FILE_RENAME_POWER="i_ft_needed_file_rename_power",PermissionType.I_FT_FILE_BROWSE_POWER="i_ft_file_browse_power",PermissionType.I_FT_NEEDED_FILE_BROWSE_POWER="i_ft_needed_file_browse_power",PermissionType.I_FT_DIRECTORY_CREATE_POWER="i_ft_directory_create_power",PermissionType.I_FT_NEEDED_DIRECTORY_CREATE_POWER="i_ft_needed_directory_create_power",PermissionType.I_FT_QUOTA_MB_DOWNLOAD_PER_CLIENT="i_ft_quota_mb_download_per_client",PermissionType.I_FT_QUOTA_MB_UPLOAD_PER_CLIENT="i_ft_quota_mb_upload_per_client"}(PermissionType||(PermissionType={}));class PermissionInfo{}class GrantedPermission{constructor(type,value){this.type=type,this.value=value}granted(requiredValue,required=!0){let result=!1;return-2==this.value&&(result=!required),result=-1==this.value||this.value>=requiredValue,log.trace(LogCategory.PERMISSIONS,"Test needed required: %o | %i | %o => "+result,this,requiredValue,required),result}hasValue(){return-2!=this.value}}class NeededGrantedPermission extends GrantedPermission{constructor(type,value){super(type,value),this.changeListener=[]}}class PermissionManager{constructor(client){this.permissionList=[],this.neededPermissions=[],this.initializedListener=[],this.handle=client,this.handle.serverConnection.commandHandler.notifyclientneededpermissions=this.onNeededPermissions.bind(this),this.handle.serverConnection.commandHandler.notifypermissionlist=this.onPermissionList.bind(this)}initialized(){return this.permissionList.length>0}requestPermissionList(){this.handle.serverConnection.sendCommand("permissionlist")}onPermissionList(json){this.permissionList=[];let group=log.group(log.LogType.TRACE,LogCategory.PERMISSIONS,"Permission mapping");for(let e of json){if(e.group_id_end)continue;let perm=new PermissionInfo;perm.name=e.permname,perm.id=parseInt(e.permid),perm.description=e.permdesc,group.log("%i <> %s -> %s",perm.id,perm.name,perm.description),this.permissionList.push(perm)}group.end(),log.info(LogCategory.PERMISSIONS,"Got %i permissions",this.permissionList.length),this._cacheNeededPermissions&&this.onNeededPermissions(this._cacheNeededPermissions);for(let listener of this.initializedListener)listener(!0)}onNeededPermissions(json){if(0==this.permissionList.length)return log.warn(LogCategory.PERMISSIONS,"Got needed permissions but don't have a permission list!"),void(this._cacheNeededPermissions=json);this._cacheNeededPermissions=void 0;let copy=this.neededPermissions.slice(),addcount=0,group=log.group(log.LogType.TRACE,LogCategory.PERMISSIONS,"Got "+json.length+" needed permissions.");for(let e of json){let entry=void 0;for(let p of copy)if(p.type.id==e.permid){entry=p,copy.remove(p);break}if(!entry){let info=this.resolveInfo(e.permid);if(!info){log.warn(LogCategory.PERMISSIONS,"Could not resolve perm for id %s (%o|%o)",e.permid,e,info);continue}entry=new NeededGrantedPermission(info,-2),this.neededPermissions.push(entry),addcount++}if(entry.value!=parseInt(e.permvalue)){entry.value=parseInt(e.permvalue),group.log("Update needed permission "+entry.type.name+" to "+entry.value);for(let listener of entry.changeListener)listener(entry.value)}}group.end(),log.debug(LogCategory.PERMISSIONS,"Dropping "+copy.length+" needed permissions and added "+addcount+" permissions.");for(let e of copy){e.value=-2;for(let listener of e.changeListener)listener(e.value)}}resolveInfo(key){for(let perm of this.permissionList)if(perm.id==key||perm.name==key)return perm}neededPermission(key){for(let perm of this.neededPermissions)if(perm.type.id==key||perm.type.name==key||perm.type==key)return perm;log.debug(LogCategory.PERMISSIONS,"Could not resolve grant permission %o. Creating a new one.",key);let info=key instanceof PermissionInfo?key:this.resolveInfo(key);if(!info)return void log.warn(LogCategory.PERMISSIONS,"Requested needed permission with invalid key! (%o)",key);let result=new NeededGrantedPermission(info,-2);return this.neededPermissions.push(result),result}}!function(GroupType){GroupType[GroupType.QUERY=0]="QUERY",GroupType[GroupType.TEMPLATE=1]="TEMPLATE",GroupType[GroupType.NORMAL=2]="NORMAL"}(GroupType||(GroupType={})),function(GroupTarget){GroupTarget[GroupTarget.SERVER=0]="SERVER",GroupTarget[GroupTarget.CHANNEL=1]="CHANNEL"}(GroupTarget||(GroupTarget={}));class Group{constructor(handle,id,target,type,name){this.properties={iconid:0},this.requiredModifyPower=0,this.requiredMemberAddPower=0,this.requiredMemberRemovePower=0,this.handle=handle,this.id=id,this.target=target,this.type=type,this.name=name}updateProperty(key,value){if(this.properties[key]=value,"iconid"==key){const _this=this;console.log("Icon id "+_this.properties.iconid),this.handle.handle.channelTree.clientsByGroup(this).forEach(client=>{client.updateGroupIcon(_this)})}}}class GroupManager{constructor(client){this.serverGroups=[],this.channelGroups=[],this.handle=client,this.handle.serverConnection.commandHandler.notifyservergrouplist=this.onServerGroupList.bind(this),this.handle.serverConnection.commandHandler.notifychannelgrouplist=this.onServerGroupList.bind(this)}requestGroups(){this.handle.serverConnection.sendCommand("servergrouplist"),this.handle.serverConnection.sendCommand("channelgrouplist")}serverGroup(id){for(let group of this.serverGroups)if(group.id==id)return group}channelGroup(id){for(let group of this.channelGroups)if(group.id==id)return group}onServerGroupList(json){let target;if(json[0].sgid)target=GroupTarget.SERVER;else{if(!json[0].cgid)return void console.error("Could not resolve group target! => "+json[0]);target=GroupTarget.CHANNEL}target==GroupTarget.SERVER?this.serverGroups=[]:this.channelGroups=[];for(let groupData of json){let type;switch(Number.parseInt(groupData.type)){case 0:type=GroupType.TEMPLATE;break;case 1:type=GroupType.NORMAL;break;case 2:type=GroupType.QUERY;break;default:console.error("Invalid group type: "+groupData.type+" for group "+groupData.name);continue}let group=new Group(this,target==GroupTarget.SERVER?groupData.sgid:groupData.cgid,target,type,groupData.name);for(let key in groupData)"sgid"!=key&&"cgid"!=key&&"type"!=key&&"name"!=key&&group.updateProperty(key,groupData[key]);group.requiredMemberRemovePower=groupData.n_member_removep,group.requiredMemberAddPower=groupData.n_member_addp,group.requiredModifyPower=groupData.n_modifyp,target==GroupTarget.SERVER?this.serverGroups.push(group):this.channelGroups.push(group)}console.log("Got "+json.length+" new "+target+" groups:")}}if("undefined"!=typeof customElements){class X_Tab extends HTMLElement{}class X_Entry extends HTMLElement{}class X_Tag extends HTMLElement{}class X_Content extends HTMLElement{}customElements.define("x-tab",X_Tab,{extends:"div"}),customElements.define("x-entry",X_Entry,{extends:"div"}),customElements.define("x-tag",X_Tag,{extends:"div"}),customElements.define("x-content",X_Content,{extends:"div"})}else console.warn("Could not defied tab customElements!");var DisconnectReason,ConnectionState,ViewReasonId,IdentitifyType,TSIdentityHelper,ChatType,MessageHelper,LogCategory,log,Modals,CodecWorkerType,TabFunctions={tabify(template){console.log("Tabify:"),console.log(template);let tag=$.spawn("div");tag.addClass("tab");let header=$.spawn("div");header.addClass("tab-header");let content=$.spawn("div");content.addClass("tab-content");let silentContent=$.spawn("div");return silentContent.addClass("tab-content-invisible"),template.find("x-entry").each(function(){let hentry=$.spawn("div");hentry.addClass("entry"),hentry.append($(this).find("x-tag").clone(!0,!0));const _entryContent=$(this).find("x-content").clone(!0,!0);silentContent.append(_entryContent),hentry.on("click",function(){hentry.hasClass("selected")||(tag.find(".tab-header .selected").removeClass("selected"),hentry.addClass("selected"),content.children().appendTo(silentContent),console.log(silentContent),content.empty(),content.append(_entryContent))}),console.log(this),header.append(hentry)}),header.find(".entry").first().trigger("click"),tag.append(header),tag.append(content),tag.append(silentContent),tag}};$.fn.asTabWidget||($.fn.asTabWidget=function(){if("X-TAB"==$(this).prop("tagName"))return TabFunctions.tabify($(this));throw"Invalid tag! "+$(this).prop("tagName")}),$.fn.tabify||($.fn.tabify=function(){try{let self=this.asTabWidget();this.replaceWith(self)}catch(object){}return this.find("x-tab").each(function(){$(this).replaceWith($(this).asTabWidget())}),this}),function(Modals){Modals.spawnSettingsModal=function(){let modal;(modal=createModal({header:"Settings",body:()=>{let template=$("#tmpl_settings").tmpl();return template=$.spawn("div").append(template),function(modal,tag){!function(modal,tag){let currentVAD=settings.global("vad_type");tag.find('input[type=radio][name="vad_type"]').change(function(){switch(tag.find(".vad_settings .vad_type").text($(this).attr("display")),tag.find(".vad_settings .vad_type_settings").hide(),tag.find(".vad_settings .vad_type_"+this.value).show(),settings.changeGlobal("vad_type",this.value),globalClient.voiceConnection.voiceRecorder.reinitialiseVAD(),this.value){case"ppt":let keyCode=parseInt(settings.global("vad_ppt_key",84..toString()));tag.find(".vat_ppt_key").text(String.fromCharCode(keyCode));break;case"vad":let slider=tag.find(".vad_vad_slider"),vad=globalClient.voiceConnection.voiceRecorder.getVADHandler();slider.val(vad.percentageThreshold),slider.trigger("change"),globalClient.voiceConnection.voiceRecorder.update(!0),vad.percentage_listener=(per=>{tag.find(".vad_vad_bar_filler").css("width",per+"%")})}}),currentVAD||(currentVAD="ppt");let elm=tag.find('input[type=radio][name="vad_type"][value="'+currentVAD+'"]');elm.attr("checked","true"),tag.find(".vat_ppt_key").click(function(){let modal=createModal({body:"",header:()=>{let head=$.spawn("div");return head.text("Type the key you wish"),head.css("background-color","blue"),head},footer:""});$(document).one("keypress",function(e){console.log("Got key "+e.keyCode),modal.close(),settings.changeGlobal("vad_ppt_key",e.keyCode.toString()),globalClient.voiceConnection.voiceRecorder.reinitialiseVAD(),tag.find(".vat_ppt_key").text(String.fromCharCode(e.keyCode))}),modal.open()});let slider=tag.find(".vad_vad_slider");slider.on("input change",()=>{settings.changeGlobal("vad_threshold",slider.val().toString());let vad=globalClient.voiceConnection.voiceRecorder.getVADHandler();vad instanceof VoiceActivityDetectorVAD&&(vad.percentageThreshold=slider.val()),tag.find(".vad_vad_slider_value").text(slider.val().toString())}),modal.properties.registerCloseListener(()=>{let vad=globalClient.voiceConnection.voiceRecorder.getVADHandler();vad instanceof VoiceActivityDetectorVAD&&(vad.percentage_listener=void 0)}),elm.trigger("change"),console.log(tag);let mselect=tag.find(".voice_microphone_select");console.log(mselect);let mselectError=tag.find(".voice_microphone_select_error");navigator.mediaDevices.enumerateDevices().then(devices=>{let currentDeviceId,currentStream=globalClient.voiceConnection.voiceRecorder.getMediaStream();if(currentStream){let audio=currentStream.getAudioTracks()[0];currentDeviceId=audio.getSettings().deviceId}console.log("Got "+devices.length+" devices:");for(let device of devices)if(console.log(device),"audioinput"==device.kind){let dtag=$.spawn("option");dtag.attr("device-id",device.deviceId),dtag.attr("device-group",device.groupId),dtag.text(device.label),mselect.append(dtag),currentDeviceId&&device.deviceId==currentDeviceId&&mselect.attr("selected","")}}).catch(error=>{console.error("Could not enumerate over devices!"),console.error(error),mselectError.text("Could not get device list!").show()}),mselect.change(event=>{let deviceSelected=mselect.find("option:selected"),deviceId=deviceSelected.attr("device-id");console.log("Selected device: "+deviceId),globalClient.voiceConnection.voiceRecorder.changeDevice(deviceId)})}(modal,tag.find(".settings_voice"))}(modal,template=template.tabify()),template},footer:()=>{let footer=$.spawn("div");footer.addClass("modal-button-group"),footer.css("margin-top","5px"),footer.css("margin-bottom","5px"),footer.css("text-align","right");let buttonOk=$.spawn("button");return buttonOk.text("Ok"),buttonOk.click(()=>modal.close()),footer.append(buttonOk),footer},width:750})).open()}}(Modals||(Modals={}));class ControlBar{constructor(handle,htmlTag){this.handle=handle,this.htmlTag=htmlTag}initialise(){this.htmlTag.find(".btn_connect").click(this.onConnect.bind(this)),this.htmlTag.find(".btn_client_away").click(this.onAway.bind(this)),this.htmlTag.find(".btn_mute_input").click(this.onInputMute.bind(this)),this.htmlTag.find(".btn_mute_output").click(this.onOutputMute.bind(this)),this.htmlTag.find(".btn_open_settings").click(this.onOpenSettings.bind(this)),this.muteInput="1"==settings.global("mute_input"),this.muteOutput="1"==settings.global("mute_output")}onAway(){this.away=!this._away}onInputMute(){this.muteInput=!this._muteInput}onOutputMute(){this.muteOutput=!this._muteOutput}set muteInput(flag){if(this._muteInput==flag)return;this._muteInput=flag;let tag=this.htmlTag.find(".btn_mute_input");flag?(tag.hasClass("activated")||tag.addClass("activated"),tag.find(".icon_x32").attr("class","icon_x32 client-input_muted")):(tag.hasClass("activated")&&tag.removeClass("activated"),tag.find(".icon_x32").attr("class","icon_x32 client-capture")),this.handle.serverConnection.connected&&this.handle.serverConnection.sendCommand("clientupdate",{client_input_muted:this._muteInput}),settings.changeGlobal("mute_input",this._muteInput),this.updateMicrophoneRecordState()}get muteOutput(){return this._muteOutput}set muteOutput(flag){if(this._muteOutput==flag)return;this._muteOutput=flag;let tag=this.htmlTag.find(".btn_mute_output");flag?(tag.hasClass("activated")||tag.addClass("activated"),tag.find(".icon_x32").attr("class","icon_x32 client-output_muted")):(tag.hasClass("activated")&&tag.removeClass("activated"),tag.find(".icon_x32").attr("class","icon_x32 client-volume")),this.handle.serverConnection.connected&&this.handle.serverConnection.sendCommand("clientupdate",{client_output_muted:this._muteOutput}),settings.changeGlobal("mute_output",this._muteOutput),this.updateMicrophoneRecordState()}set away(value){if("boolean"==typeof value){if(this._away==value)return;this._away=value,this._awayMessage=""}else this._awayMessage=value,this._away=!0;let tag=this.htmlTag.find(".btn_client_away");this._away?tag.hasClass("activated")||tag.addClass("activated"):tag.hasClass("activated")&&tag.removeClass("activated"),this.handle.serverConnection.connected&&this.handle.serverConnection.sendCommand("clientupdate",{client_away:this._away,client_away_message:this._awayMessage}),this.updateMicrophoneRecordState()}updateMicrophoneRecordState(){let enabled=!this._muteInput&&!this._muteOutput&&!this._away;this.handle.voiceConnection.voiceRecorder.update(enabled)}updateProperties(){this.handle.serverConnection.connected&&this.handle.serverConnection.sendCommand("clientupdate",{client_input_muted:this._muteInput,client_output_muted:this._muteOutput,client_away:this._away,client_away_message:this._awayMessage})}onOpenSettings(){Modals.spawnSettingsModal()}onConnect(){Modals.spawnConnectModal(settings.static("connect_default_host","ts.TeaSpeak.de"))}}!function(DisconnectReason){DisconnectReason[DisconnectReason.REQUESTED=0]="REQUESTED",DisconnectReason[DisconnectReason.CONNECT_FAILURE=1]="CONNECT_FAILURE",DisconnectReason[DisconnectReason.CONNECTION_CLOSED=2]="CONNECTION_CLOSED",DisconnectReason[DisconnectReason.CONNECTION_FATAL_ERROR=3]="CONNECTION_FATAL_ERROR",DisconnectReason[DisconnectReason.CONNECTION_PING_TIMEOUT=4]="CONNECTION_PING_TIMEOUT",DisconnectReason[DisconnectReason.CLIENT_KICKED=5]="CLIENT_KICKED",DisconnectReason[DisconnectReason.CLIENT_BANNED=6]="CLIENT_BANNED",DisconnectReason[DisconnectReason.SERVER_CLOSED=7]="SERVER_CLOSED",DisconnectReason[DisconnectReason.UNKNOWN=8]="UNKNOWN"}(DisconnectReason||(DisconnectReason={})),function(ConnectionState){ConnectionState[ConnectionState.UNCONNECTED=0]="UNCONNECTED",ConnectionState[ConnectionState.CONNECTING=1]="CONNECTING",ConnectionState[ConnectionState.INITIALISING=2]="INITIALISING",ConnectionState[ConnectionState.CONNECTED=3]="CONNECTED",ConnectionState[ConnectionState.DISCONNECTING=4]="DISCONNECTING"}(ConnectionState||(ConnectionState={})),function(ViewReasonId){ViewReasonId[ViewReasonId.VREASON_USER_ACTION=0]="VREASON_USER_ACTION",ViewReasonId[ViewReasonId.VREASON_MOVED=1]="VREASON_MOVED",ViewReasonId[ViewReasonId.VREASON_SYSTEM=2]="VREASON_SYSTEM",ViewReasonId[ViewReasonId.VREASON_TIMEOUT=3]="VREASON_TIMEOUT",ViewReasonId[ViewReasonId.VREASON_CHANNEL_KICK=4]="VREASON_CHANNEL_KICK",ViewReasonId[ViewReasonId.VREASON_SERVER_KICK=5]="VREASON_SERVER_KICK",ViewReasonId[ViewReasonId.VREASON_BAN=6]="VREASON_BAN",ViewReasonId[ViewReasonId.VREASON_SERVER_STOPPED=7]="VREASON_SERVER_STOPPED",ViewReasonId[ViewReasonId.VREASON_SERVER_LEFT=8]="VREASON_SERVER_LEFT",ViewReasonId[ViewReasonId.VREASON_CHANNEL_UPDATED=9]="VREASON_CHANNEL_UPDATED",ViewReasonId[ViewReasonId.VREASON_EDITED=10]="VREASON_EDITED",ViewReasonId[ViewReasonId.VREASON_SERVER_SHUTDOWN=11]="VREASON_SERVER_SHUTDOWN"}(ViewReasonId||(ViewReasonId={}));class TSClient{constructor(){this._clientId=0,this.selectInfo=new InfoBar(this,$("#select_info")),this.channelTree=new ChannelTree(this,$("#channelTree")),this.serverConnection=new ServerConnection(this),this.fileManager=new FileManager(this),this.permissions=new PermissionManager(this),this.groups=new GroupManager(this),this.voiceConnection=new VoiceConnection(this),this._ownEntry=new LocalClientEntry(this),this.controlBar=new ControlBar(this,$("#control_bar")),this.channelTree.registerClient(this._ownEntry)}setup(){this.controlBar.initialise()}startConnection(addr,identity,name){this.serverConnection&&this.handleDisconnect(DisconnectReason.REQUESTED);let port,host,idx=addr.lastIndexOf(":");-1!=idx?(port=parseInt(addr.substr(idx+1)),host=addr.substr(0,idx)):(host=addr,port=9987),console.log("Start connection to "+host+":"+port),this.channelTree.initialiseHead(addr),this.serverConnection.startConnection(host,port,new HandshakeHandler(identity,name))}getClient(){return this._ownEntry}getClientId(){return this._clientId}set clientId(id){this._clientId=id,this._ownEntry._clientId=id}get clientId(){return this._clientId}getServerConnection(){return this.serverConnection}onConnected(){console.log("Client connected!"),this.channelTree.registerClient(this._ownEntry),settings.setServer(this.channelTree.server),this.permissions.requestPermissionList(),this.serverConnection.sendCommand("channelsubscribeall"),0==this.groups.serverGroups.length&&this.groups.requestGroups(),this.controlBar.updateProperties()}get connected(){return!!this.serverConnection&&this.serverConnection.connected}handleDisconnect(type,data={}){switch(type){case DisconnectReason.REQUESTED:break;case DisconnectReason.CONNECT_FAILURE:console.error("Could not connect to remote host! Exception"),console.error(data),createErrorModal("Could not connect","Could not connect to remote host (Connection refused)
If you're shure that the remot host is up, than you may not allow unsigned certificates.
Click here to accept the remote certificate").open();break;case DisconnectReason.CONNECTION_CLOSED:console.error("Lost connection to remote server!"),createErrorModal("Connection closed","The connection was closed by remote host").open();break;case DisconnectReason.CONNECTION_PING_TIMEOUT:console.error("Connection ping timeout"),createErrorModal("Connection lost","Lost connection to remote host (Ping timeout)
Even possible?").open();break;case DisconnectReason.SERVER_CLOSED:chat.serverChat().appendError("Server closed ({0})",data.reasonmsg),createErrorModal("Server closed","The server is closed.
Reason: "+data.reasonmsg).open();break;default:console.error("Got uncaught disconnect!"),console.error("Type: "+type+" Data:"),console.error(data)}this.selectInfo.currentSelected=null,this.channelTree.reset(),this.voiceConnection.dropSession(),this.serverConnection&&this.serverConnection.disconnect()}}class FileEntry{}class FileListRequest{}class DownloadFileTransfer{constructor(handle,id){this.currentSize=0,this.on_start=(()=>{}),this.on_complete=(()=>{}),this.on_fail=(_=>{}),this.on_data=(_=>{}),this.transferId=id,this._handle=handle}startTransfer(){this.remoteHost&&this.remotePort&&this.transferKey&&this.totalSize?(console.debug("Create new file download to "+this.remoteHost+":"+this.remotePort+" (Key: "+this.transferKey+", Expect "+this.totalSize+" bytes)"),this._active=!0,this._socket=new WebSocket("wss://"+this.remoteHost+":"+this.remotePort),this._socket.onopen=this.onOpen.bind(this),this._socket.onclose=this.onClose.bind(this),this._socket.onmessage=this.onMessage.bind(this),this._socket.onerror=this.onError.bind(this)):this.on_fail("Missing data!")}onOpen(){this._active&&(this._socket.send(this.transferKey),this.on_start())}onMessage(data){if(!this._active)return void console.error("Got data, but socket closed?");this._parseActive=!0;let fileReader=new FileReader;fileReader.onload=(event=>{this.onBinaryData(new Uint8Array(event.target.result)),this._parseActive=!1}),fileReader.readAsArrayBuffer(data.data)}onBinaryData(data){this.currentSize+=data.length,this.on_data(data),this.currentSize==this.totalSize&&(this._succeed=!0,this.on_complete(),this.disconnect())}onError(){this._active&&(this.on_fail("an error occurent"),this.disconnect())}onClose(){this._active&&(this._parseActive||this.on_fail("unexpected close (remote closed)"),this.disconnect())}disconnect(){this._active=!1}}class FileManager{constructor(client){this.listRequests=[],this.pendingDownloadTransfers=[],this.downloadCounter=0,this.handle=client,this.icons=new IconManager(this),this.avatars=new AvatarManager(this),this.handle.serverConnection.commandHandler.notifyfilelist=this.notifyFileList.bind(this),this.handle.serverConnection.commandHandler.notifyfilelistfinished=this.notifyFileListFinished.bind(this),this.handle.serverConnection.commandHandler.notifystartdownload=this.notifyStartDownload.bind(this)}requestFileList(path,channel,password){const _this=this;return new Promise((accept,reject)=>{let req=new FileListRequest;req.path=path,req.entries=[],req.callback=accept,_this.listRequests.push(req),_this.handle.serverConnection.sendCommand("ftgetfilelist",{path:path,cid:channel?channel.channelId:"0",cpw:password||""}).then(()=>{}).catch(reason=>{_this.listRequests.remove(req),reason instanceof CommandResult&&1281==reason.id?accept([]):reject(reason)})})}notifyFileList(json){let entry=void 0;for(let e of this.listRequests)if(e.path==json[0].path){entry=e;break}if(entry)for(let e of json)entry.entries.push(e);else console.error("Invalid file list entry. Path: "+json[0].path)}notifyFileListFinished(json){let entry=void 0;for(let e of this.listRequests)if(e.path==json[0].path){entry=e,this.listRequests.remove(e);break}entry?entry.callback(entry.entries):console.error("Invalid file list entry finish. Path: "+json[0].path)}requestFileDownload(path,file,channel,password){const _this=this;let transfer=new DownloadFileTransfer(this,this.downloadCounter++);return this.pendingDownloadTransfers.push(transfer),new Promise((resolve,reject)=>{transfer._promiseCallback=resolve,_this.handle.serverConnection.sendCommand("ftinitdownload",{path:path,name:file,cid:channel?channel.channelId:"0",cpw:password||"",clientftfid:transfer.transferId}).catch(reason=>{_this.pendingDownloadTransfers.remove(transfer),reject(reason)})})}notifyStartDownload(json){let transfer;json=json[0];for(let e of this.pendingDownloadTransfers)if(e.transferId==json.clientftfid){transfer=e;break}transfer.serverTransferId=json.serverftfid,transfer.transferKey=json.ftkey,transfer.totalSize=json.size,transfer.remotePort=json.port,transfer.remoteHost=json.ip.replace(/,/g,""),"0.0.0.0"!=transfer.remoteHost&&"127.168.0.0"!=transfer.remoteHost||(transfer.remoteHost=this.handle.serverConnection._remoteHost),transfer._promiseCallback(transfer),this.pendingDownloadTransfers.remove(transfer)}}class Icon{}class IconManager{constructor(handle){this.handle=handle}iconList(){return this.handle.requestFileList("/icons")}downloadIcon(id){return this.handle.requestFileDownload("","/icon_"+id)}resolveCached(id){let icon=localStorage.getItem("icon_"+id);if(icon){let i=JSON.parse(icon);if(i.base64.length>0)return i}}loadIcon(id){const _this=this;return new Promise((resolve,reject)=>{let icon=this.resolveCached(id);icon?resolve(icon):_this.downloadIcon(id).then(ft=>{let array=new Uint8Array(0);ft.on_fail=(reason=>{console.error("Could not download icon "+id+" -> "+reason),chat.serverChat().appendError("Fail to download icon {0}. ({1})",id,JSON.stringify(reason)),reject(reason)}),ft.on_start=(()=>{}),ft.on_data=(data=>{array=concatenate(Uint8Array,array,data)}),ft.on_complete=(()=>{let base64=btoa(String.fromCharCode.apply(null,array)),icon=new Icon;icon.base64=base64,icon.id=id,icon.name="icon_"+id,localStorage.setItem("icon_"+id,JSON.stringify(icon)),resolve(icon)}),ft.startTransfer()}).catch(reason=>{console.error("Error while downloading icon! ("+JSON.stringify(reason)+")"),chat.serverChat().appendError("Failed to request download for icon {0}. ({1})",id,JSON.stringify(reason)),reject(reason)})})}generateTag(id){if(0==id)return $("
");if(id<1e3)return $("
");let tag=$.spawn("div");tag.addClass("icon_empty");let img=$.spawn("img");img.attr("width",16).attr("height",16).attr("alt","");let icon=this.resolveCached(id);if(icon)img.attr("src","data:image/png;base64,"+icon.base64),tag.append(img);else{img.attr("src","file://null");let loader=$.spawn("div");loader.addClass("icon_loading"),tag.append(loader),this.loadIcon(id).then(icon=>{img.attr("src","data:image/png;base64,"+icon.base64),console.debug("Icon "+id+" loaded :)"),img.css("opacity",0),tag.append(img),loader.animate({opacity:0},50,function(){$(this).detach(),img.animate({opacity:1},150)})}).catch(reason=>{console.error("Could not load icon "+id+". Reason: "+reason),loader.removeClass("icon_loading").addClass("icon client-warning").attr("tag","Could not load icon "+id)})}return tag}}class Avatar{}class AvatarManager{constructor(handle){this.handle=handle}downloadAvatar(client){return this.handle.requestFileDownload("","/avatar_"+client.avatarId())}resolveCached(client){let avatar=localStorage.getItem("avatar_"+client.properties.client_unique_identifier);if(avatar){let i=JSON.parse(avatar);if(i.base64.length>0&&i.avatarId==client.properties.client_flag_avatar)return i}}loadAvatar(client){const _this=this;return new Promise((resolve,reject)=>{let avatar=this.resolveCached(client);avatar?resolve(avatar):_this.downloadAvatar(client).then(ft=>{let array=new Uint8Array(0);ft.on_fail=(reason=>{console.error("Could not download avatar "+client.properties.client_flag_avatar+" -> "+reason),chat.serverChat().appendError("Fail to download avatar for {0}. ({1})",client.clientNickName(),JSON.stringify(reason)),reject(reason)}),ft.on_start=(()=>{}),ft.on_data=(data=>{array=concatenate(Uint8Array,array,data)}),ft.on_complete=(()=>{let base64=btoa(String.fromCharCode.apply(null,array)),avatar=new Avatar;avatar.base64=base64,avatar.clientUid=client.clientUid(),avatar.avatarId=client.properties.client_flag_avatar,localStorage.setItem("avatar_"+client.properties.client_unique_identifier,JSON.stringify(avatar)),resolve(avatar)}),ft.startTransfer()}).catch(reason=>{console.error("Error while downloading avatar! ("+JSON.stringify(reason)+")"),chat.serverChat().appendError("Failed to request avatar download for {0}. ({1})",client.clientNickName(),JSON.stringify(reason)),reject(reason)})})}generateTag(client){let tag=$.spawn("div"),img=$.spawn("img");img.attr("alt","");let avatar=this.resolveCached(client);avatar=void 0;{let loader=$.spawn("img");loader.attr("src","img/loading_image.svg").css("width","75%"),tag.append(loader),this.loadAvatar(client).then(avatar=>{img.attr("src","data:image/png;base64,"+avatar.base64),console.debug("Avatar "+client.clientNickName()+" loaded :)"),img.css("opacity",0),tag.append(img),loader.animate({opacity:0},50,function(){$(this).detach(),img.animate({opacity:1},150)})}).catch(reason=>{console.error("Could not load avatar for "+client.clientNickName()+". Reason: "+reason),loader.addClass("icon client-warning").attr("tag","Could not load avatar "+client.clientNickName())})}return tag}}!function(IdentitifyType){IdentitifyType[IdentitifyType.TEAFORO=0]="TEAFORO",IdentitifyType[IdentitifyType.TEAMSPEAK=1]="TEAMSPEAK"}(IdentitifyType||(IdentitifyType={})),function(TSIdentityHelper){var Pointer_stringify=Module.Pointer_stringify;let functionLastError,functionDestroyString,functionDestroyIdentity;function unwarpString(str){if(""==str)return"";let message=Pointer_stringify(str);return functionDestroyString(str),message}TSIdentityHelper.setup=function(){return functionDestroyString=Module.cwrap("destroy_string","pointer",[]),functionLastError=Module.cwrap("last_error_message",null,["string"]),TSIdentityHelper.funcationParseIdentity=Module.cwrap("parse_identity","pointer",["string"]),TSIdentityHelper.funcationParseIdentityByFile=Module.cwrap("parse_identity_file","pointer",["string"]),functionDestroyIdentity=Module.cwrap("delete_identity",null,["pointer"]),TSIdentityHelper.funcationCalculateSecurityLevel=Module.cwrap("identity_security_level","pointer",["pointer"]),TSIdentityHelper.funcationExportIdentity=Module.cwrap("identity_export","pointer",["pointer"]),TSIdentityHelper.funcationPublicKey=Module.cwrap("identity_key_public","pointer",["pointer"]),TSIdentityHelper.funcationSignMessage=Module.cwrap("identity_sign","pointer",["pointer","string","number"]),TSIdentityHelper.functionUid=Module.cwrap("identity_uid","pointer",["pointer"]),0==Module.cwrap("tomcrypt_initialize","number",[])()},TSIdentityHelper.last_error=function(){return unwarpString(functionLastError())},TSIdentityHelper.unwarpString=unwarpString,TSIdentityHelper.loadIdentity=function(key){let handle=TSIdentityHelper.funcationParseIdentity(key);if(handle)return new TeamSpeakIdentity(handle,"TeaWeb user")},TSIdentityHelper.loadIdentityFromFileContains=function(contains){let handle=TSIdentityHelper.funcationParseIdentityByFile(contains);if(handle)return new TeamSpeakIdentity(handle,"TeaWeb user")}}(TSIdentityHelper||(TSIdentityHelper={}));class TeamSpeakIdentity{constructor(handle,name){this.handle=handle,this._name=name}securityLevel(){return parseInt(TSIdentityHelper.unwarpString(TSIdentityHelper.funcationCalculateSecurityLevel(this.handle)))}name(){return this._name}uid(){return TSIdentityHelper.unwarpString(TSIdentityHelper.functionUid(this.handle))}type(){return IdentitifyType.TEAMSPEAK}signMessage(message){return TSIdentityHelper.unwarpString(TSIdentityHelper.funcationSignMessage(this.handle,message,message.length))}exported(){return TSIdentityHelper.unwarpString(TSIdentityHelper.funcationExportIdentity(this.handle))}publicKey(){return TSIdentityHelper.unwarpString(TSIdentityHelper.funcationPublicKey(this.handle))}}class TeaForumIdentity{constructor(data,sign){this.identityDataJson=data,this.identityData=JSON.parse(this.identityDataJson),this.identitySign=sign}name(){return this.identityData.user_name}uid(){return"TeaForo#"+this.identityData.user_id}type(){return IdentitifyType.TEAFORO}}!function(ChatType){ChatType[ChatType.GENERAL=0]="GENERAL",ChatType[ChatType.SERVER=1]="SERVER",ChatType[ChatType.CHANNEL=2]="CHANNEL",ChatType[ChatType.CLIENT=3]="CLIENT"}(ChatType||(ChatType={})),function(MessageHelper){MessageHelper.htmlEscape=function(message){const div=document.createElement("div");return div.innerText=message,(message=div.innerHTML).replace(/ /g," ")},MessageHelper.formatElement=function(object){if($.isArray(object)){let result=[];for(let element of object)result.push(...this.formatElement(element));return result}return"string"==typeof object?0==object.length?[]:[$.spawn("a").html(this.htmlEscape(object))]:"object"==typeof object?object instanceof jQuery?[object]:this.formatElement(""):"function"==typeof object?this.formatElement(object()):void 0===object?this.formatElement(""):this.formatElement("")},MessageHelper.formatMessage=function(pattern,...objects){let begin=0,found=0,result=[];do{if(-1==(found=pattern.indexOf("{",found))||pattern.length<=found+1){result.push(...this.formatElement(pattern.substr(begin)));break}if(found>0&&"\\"==pattern[found-1]){found++;continue}let number;result.push(...this.formatElement(pattern.substr(begin,found-begin)));let offset=0;for(;"0123456789".includes(pattern[found+1+offset]);)offset++;number=parseInt(offset>0?pattern.substr(found+1,offset):"0"),"}"==pattern[found+offset+1]?(objects.length "),dateTag.css("margin-right","4px"),dateTag.css("color","dodgerblue"),this._htmlTag=tag,tag.append(dateTag),this.message.forEach(e=>e.appendTo(tag)),tag.hide(),tag}}class ChatEntry{constructor(handle,type,key){this.handle=handle,this.type=type,this.key=key,this._name=key,this.history=[],this.onClose=function(){return!0}}appendError(message,...args){let entries=MessageHelper.formatMessage(message,...args);entries.forEach(e=>e.css("color","red")),this.pushChatMessage(new ChatMessage(entries))}appendMessage(message,fmt=!0,...args){this.pushChatMessage(new ChatMessage(MessageHelper.formatMessage(message,...args)))}pushChatMessage(entry){for(this.history.push(entry);this.history.length>100;){this.history.pop_front().htmlTag.animate({opacity:0},200,function(){$(this).detach()})}if(this.handle.activeChat===this){let box=$(this.handle.htmlTag).find(".messages"),mbox=$(this.handle.htmlTag).find(".message_box"),bottom=box.scrollTop()+box.height()+1>=mbox.height();mbox.append(entry.htmlTag),entry.htmlTag.show().css("opacity","0").animate({opacity:1},100),bottom&&box.scrollTop(mbox.height())}else this.unread=!0}displayHistory(){this.unread=!1;let box=$(this.handle.htmlTag).find(".messages"),mbox=$(this.handle.htmlTag).find(".message_box");mbox.empty();for(let e of this.history)mbox.append(e.htmlTag),e.htmlTag.is(":hidden")&&e.htmlTag.show();box.scrollTop(mbox.height())}get htmlTag(){if(this._htmlTag)return this._htmlTag;let tag=$.spawn("div");tag.addClass("chat"),tag.append('
'),tag.append(""+this._name+"");let closeTag=$.spawn("div");closeTag.addClass("btn_close icon client-tab_close_button"),this._closeable||closeTag.hide(),tag.append(closeTag);const _this=this;return tag.click(function(){_this.handle.activeChat=_this}),tag.on("contextmenu",function(e){e.preventDefault();let actions=[];actions.push({type:MenuEntryType.ENTRY,icon:"",name:"Clear",callback:()=>{_this.history=[],_this.displayHistory()}}),_this.closeable&&actions.push({type:MenuEntryType.ENTRY,icon:"client-tab_close_button",name:"Close",callback:()=>{chat.deleteChat(_this)}}),actions.push({type:MenuEntryType.ENTRY,icon:"client-tab_close_button",name:"Close all private tabs",callback:()=>{}}),spawnMenu(e.pageX,e.pageY,...actions)}),closeTag.click(function(){$.isFunction(_this.onClose)&&!_this.onClose()||_this.handle.deleteChat(_this)}),this._htmlTag=tag,tag}set name(newName){console.log("Change name!"),this._name=newName,this.htmlTag.find(".name").text(this._name)}set closeable(flag){this._closeable!=flag&&(this._closeable=flag,console.log("Set closeable: "+this._closeable),flag?this.htmlTag.find(".btn_close").show():this.htmlTag.find(".btn_close").hide())}set unread(flag){this._unread!=flag&&(this._unread=flag,this.htmlTag.find(".chatIcon").attr("class","chatIcon icon clicon "+this.chatIcon()),flag?this.htmlTag.find(".name").css("color","blue"):this.htmlTag.find(".name").css("color","black"))}chatIcon(){if(this._unread)switch(this.type){case ChatType.CLIENT:return"client-new_chat"}switch(this.type){case ChatType.SERVER:return"client-server_log";case ChatType.CHANNEL:return"client-channel_chat";case ChatType.CLIENT:return"client-player_chat";case ChatType.GENERAL:return"client-channel_chat"}return""}}class ChatBox{constructor(htmlTag){this.htmlTag=htmlTag,this.htmlTag.find(".input button").click(this.onSend.bind(this)),this.htmlTag.find(".input_box").keypress(event=>{if(13==event.keyCode&&!event.shiftKey)return this.onSend(),!1}).on("input",event=>{let text=$(event.target).val().toString();this.testMessage(text)?this.htmlTag.find(".input button").removeAttr("disabled"):this.htmlTag.find(".input button").attr("disabled","true")}).trigger("input"),this.chats=[],this._activeChat=void 0,this.createChat("chat_server",ChatType.SERVER).onMessageSend=(text=>{globalClient.serverConnection?globalClient.serverConnection.sendMessage(text,ChatType.SERVER):chat.serverChat().appendError("Could not send chant message (Not connected)")}),this.createChat("chat_channel",ChatType.CHANNEL).onMessageSend=(text=>{globalClient.serverConnection?globalClient.serverConnection.sendMessage(text,ChatType.CHANNEL,globalClient.getClient().currentChannel()):chat.channelChat().appendError("Could not send chant message (Not connected)")}),globalClient.permissions.initializedListener.push(flag=>{flag&&this.activeChat0(this._activeChat)})}createChat(key,type=ChatType.CLIENT){let chat=new ChatEntry(this,type,key);return this.chats.push(chat),this.htmlTag.find(".chats").append(chat.htmlTag),this._activeChat||(this.activeChat=chat),chat}findChat(key){for(let e of this.chats)if(e.key==key)return e}deleteChat(chat){this.chats.remove(chat),chat.htmlTag.detach(),this._activeChat===chat&&(this.chats.length>0?this.activeChat=this.chats.last():this.activeChat=void 0)}onSend(){let textBox=$(this.htmlTag).find(".input_box"),text=textBox.val().toString();this.testMessage(text)&&(textBox.val(""),$(this.htmlTag).find(".input_box").trigger("input"),this._activeChat&&$.isFunction(this._activeChat.onMessageSend)&&this._activeChat.onMessageSend(text))}set activeChat(chat){-1!==this.chats.indexOf(chat)&&this._activeChat!=chat&&this.activeChat0(chat)}activeChat0(chat){this._activeChat=chat;for(let e of this.chats)e.htmlTag.removeClass("active");let flagAllowSend=!1;if(this._activeChat&&(this._activeChat.htmlTag.addClass("active"),this._activeChat.displayHistory(),globalClient&&globalClient.permissions&&globalClient.permissions.initialized()))switch(this._activeChat.type){case ChatType.CLIENT:flagAllowSend=!0;break;case ChatType.SERVER:flagAllowSend=globalClient.permissions.neededPermission(PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND).granted(1);break;case ChatType.CHANNEL:flagAllowSend=globalClient.permissions.neededPermission(PermissionType.B_CLIENT_CHANNEL_TEXTMESSAGE_SEND).granted(1)}this.htmlTag.find(".input_box").prop("disabled",!flagAllowSend)}get activeChat(){return this._activeChat}channelChat(){return this.findChat("chat_channel")}serverChat(){return this.findChat("chat_server")}focus(){$(this.htmlTag).find(".input_box").focus()}testMessage(message){return(message=message.replace(/ /gi,"").replace(/
/gi,"").replace(/\n/gi,"").replace(//gi,"")).length>0}}!function(LogCategory){LogCategory[LogCategory.CHANNEL=0]="CHANNEL",LogCategory[LogCategory.CLIENT=1]="CLIENT",LogCategory[LogCategory.PERMISSIONS=2]="PERMISSIONS",LogCategory[LogCategory.GENERAL=3]="GENERAL",LogCategory[LogCategory.NETWORKING=4]="NETWORKING"}(LogCategory||(LogCategory={})),function(log_1){let LogType;!function(LogType){LogType[LogType.TRACE=0]="TRACE",LogType[LogType.DEBUG=1]="DEBUG",LogType[LogType.INFO=2]="INFO",LogType[LogType.WARNING=3]="WARNING",LogType[LogType.ERROR=4]="ERROR"}(LogType=log_1.LogType||(log_1.LogType={}));let category_mapping=new Map([[LogCategory.CHANNEL,"Channel "],[LogCategory.CLIENT,"Client "],[LogCategory.PERMISSIONS,"Permission "],[LogCategory.GENERAL,"General "],[LogCategory.NETWORKING,"Network "]]);function logDirect(type,message,...optionalParams){switch(type){case LogType.TRACE:case LogType.DEBUG:console.debug(message,...optionalParams);break;case LogType.INFO:console.log(message,...optionalParams);break;case LogType.WARNING:console.warn(message,...optionalParams);break;case LogType.ERROR:console.error(message,...optionalParams)}}function log(type,category,message,...optionalParams){optionalParams.unshift(category_mapping.get(category)),logDirect(type,message="[%s] "+message,...optionalParams)}log_1.log=log,log_1.trace=function(category,message,...optionalParams){log(LogType.TRACE,category,message,...optionalParams)},log_1.debug=function(category,message,...optionalParams){log(LogType.DEBUG,category,message,...optionalParams)},log_1.info=function(category,message,...optionalParams){log(LogType.INFO,category,message,...optionalParams)},log_1.warn=function(category,message,...optionalParams){log(LogType.WARNING,category,message,...optionalParams)},log_1.error=function(category,message,...optionalParams){log(LogType.ERROR,category,message,...optionalParams)},log_1.group=function(level,category,name,...optionalParams){return name="[%s] "+name,optionalParams.unshift(category_mapping.get(category)),new Group(level,category,name,optionalParams)};class Group{constructor(level,category,name,optionalParams,owner){this.owner=void 0,this._collapsed=!0,this.initialized=!1,this.level=level,this.category=category,this.name=name,this.optionalParams=optionalParams}group(level,name,...optionalParams){return new Group(level,this.category,name,optionalParams,this)}collapsed(flag=!0){return this._collapsed=flag,this}log(message,...optionalParams){return this.initialized||(this._collapsed&&console.groupCollapsed?console.groupCollapsed(this.name,...this.optionalParams):console.group(this.name,...this.optionalParams),this.initialized=!0),logDirect(this.level,message,...optionalParams),this}end(){this.initialized&&console.groupEnd()}}log_1.Group=Group}(log||(log={})),function(Modals){Modals.spawnConnectModal=function(defaultHost="ts.TeaSpeak.de"){let connectIdentity;const connectModal=createModal({header:function(){let header=$.spawn("div");return header.text("Create a new connection"),header},body:function(){let tag=$("#tmpl_connect").contents().clone(),updateFields=function(){connectIdentity?tag.find(".connect_nickname").attr("placeholder",connectIdentity.name()):tag.find(".connect_nickname").attr("");let button=tag.parents(".modal-content").find(".connect_connect_button"),field_address=tag.find(".connect_address"),address=field_address.val().toString(),flag_address=!!address.match(Regex.IP_V4)||!!address.match(Regex.DOMAIN),field_nickname=tag.find(".connect_nickname"),nickname=field_nickname.val().toString(),flag_nickname=0==nickname.length||nickname.length>=3&&nickname.length<=32;flag_address?field_address.hasClass("invalid_input")&&field_address.removeClass("invalid_input"):field_address.hasClass("invalid_input")||field_address.addClass("invalid_input"),flag_nickname?field_nickname.hasClass("invalid_input")&&field_nickname.removeClass("invalid_input"):field_nickname.hasClass("invalid_input")||field_nickname.addClass("invalid_input"),flag_nickname&&flag_address&&connectIdentity?button.removeAttr("disabled"):button.attr("disabled","true")};return tag.find(".connect_address").val(defaultHost),tag.find(".connect_address").on("keyup",()=>updateFields()),tag.find(".connect_nickname").on("keyup",()=>updateFields()),tag.find(".identity_select").on("change",function(){settings.changeGlobal("connect_identity_type",this.value),tag.find(".error_message").hide(),tag.find(".identity_config:not(.identity_config_"+this.value+")").hide(),tag.find(".identity_config_"+this.value).show().trigger("shown")}),tag.find(".identity_select").val(settings.global("connect_identity_type","forum")),setTimeout(()=>tag.find(".identity_select").trigger("change"),0),tag.find(".identity_file").change(function(){const reader=new FileReader;reader.onload=function(){connectIdentity=TSIdentityHelper.loadIdentityFromFileContains(reader.result),console.log(connectIdentity.uid()),connectIdentity?(tag.find(".identity_string").val(connectIdentity.exported()),settings.changeGlobal("connect_identity_teamspeak_identity",connectIdentity.exported())):tag.find(".error_message").text("Could not read identity! "+TSIdentityHelper.last_error()),(connectIdentity?tag.hide:tag.show).apply(tag.find(".error_message")),updateFields()},reader.onerror=(ev=>{tag.find(".error_message").text("Could not read identity file!").show(),updateFields()}),reader.readAsText(this.files[0])}),tag.find(".identity_string").on("change",function(){0==this.value.length?tag.find(".error_message").text("Please select an identity!"):(connectIdentity=TSIdentityHelper.loadIdentity(this.value))?settings.changeGlobal("connect_identity_teamspeak_identity",this.value):tag.find(".error_message").text("Could not parse identity! "+TSIdentityHelper.last_error()),(connectIdentity?tag.hide:tag.show).apply(tag.find(".error_message")),tag.find(".identity_file").val(""),updateFields()}),tag.find(".identity_string").val(settings.global("connect_identity_teamspeak_identity","")),tag.find(".identity_config_teamspeak").on("shown",ev=>{tag.find(".identity_string").trigger("change")}),forumIdentity||tag.find(".identity_config_forum").html("You cant use your TeaSpeak forum account.
You're not connected!"),tag.find(".identity_config_forum").on("shown",ev=>{connectIdentity=forumIdentity,updateFields()}),tag},footer:function(){let tag=$.spawn("div");tag.css("text-align","right"),tag.css("margin-top","3px"),tag.css("margin-bottom","6px"),tag.addClass("modal-button-group");let button=$.spawn("button");return button.addClass("connect_connect_button"),button.text("Connect"),button.on("click",function(){connectModal.close();let address=tag.parents(".modal-content").find(".connect_address").val().toString();globalClient.startConnection(address,connectIdentity,tag.parents(".modal-content").find(".connect_nickname").val().toString())}),tag.append(button),tag},width:600});connectModal.open()};let Regex={DOMAIN:/^(localhost|((([a-zA-Z0-9_-]{0,63}\.){0,253})?[a-zA-Z0-9_-]{0,63}\.[a-zA-Z]{2,5}))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4}))$/,IP_V4:/(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4}))$/,IP_V6:/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/,IP:/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/}}(Modals||(Modals={})),function(Modals){Modals.spawnBanClient=function(name,callback){const connectModal=createModal({header:function(){return"Ban client"},body:function(){let tag=$("#tmpl_client_ban").tmpl({client_name:name}),maxTime=0,unlimited=0==maxTime||-1==maxTime;unlimited&&(maxTime=0);let banTag=tag.find(".ban_duration_type"),durationTag=tag.find(".ban_duration");return banTag.find('option[value="sec"]').prop("disabled",!unlimited&&1>maxTime).attr("duration-scale",1).attr("duration-max",maxTime),banTag.find('option[value="min"]').prop("disabled",!unlimited&&60>maxTime).attr("duration-scale",60).attr("duration-max",maxTime/60),banTag.find('option[value="hours"]').prop("disabled",!unlimited&&3600>maxTime).attr("duration-scale",3600).attr("duration-max",maxTime/3600),banTag.find('option[value="days"]').prop("disabled",!unlimited&&86400>maxTime).attr("duration-scale",86400).attr("duration-max",maxTime/86400),banTag.find('option[value="perm"]').prop("disabled",!unlimited).attr("duration-scale",0),durationTag.change(()=>banTag.trigger("change")),banTag.change(event=>{let element=$(event.target.selectedOptions.item(0));if("perm"!==element.val()){durationTag.prop("disabled",!1);let current=durationTag.val(),max=parseInt(element.attr("duration-max"));max>0&¤t>max?durationTag.val(max):current<=0&&durationTag.val(1),durationTag.attr("max",max)}else durationTag.prop("disabled",!0)}),tag},footer:function(){let tag=$.spawn("div");tag.css("text-align","right"),tag.css("margin-top","3px"),tag.css("margin-bottom","6px"),tag.addClass("modal-button-group");let buttonCancel=$.spawn("button");buttonCancel.text("Cancel"),buttonCancel.on("click",()=>connectModal.close()),tag.append(buttonCancel);let buttonOk=$.spawn("button");return buttonOk.text("OK").addClass("btn_success"),tag.append(buttonOk),tag},width:450});connectModal.open(),connectModal.htmlTag.find(".btn_success").on("click",()=>{connectModal.close();let length=connectModal.htmlTag.find(".ban_duration").val(),duration=connectModal.htmlTag.find(".ban_duration_type option:selected");console.log(duration),console.log(length+"*"+duration.attr("duration-scale")),callback(length*parseInt(duration.attr("duration-scale")),connectModal.htmlTag.find(".ban_reason").val())})}}(Modals||(Modals={}));class BasicCodec{constructor(codecSampleRate){this.on_encoded_data=($=>{}),this.channelCount=1,this.samplesPerUnit=960,this.channelCount=1,this.samplesPerUnit=960,this._audioContext=new OfflineAudioContext(1,1024,44100),this._codecSampleRate=codecSampleRate,this._decodeResampler=new AudioResampler(AudioController.globalContext.sampleRate),this._encodeResampler=new AudioResampler(codecSampleRate)}encodeSamples(cache,pcm){this._encodeResampler.resample(pcm).then(buffer=>this.encodeSamples0(cache,buffer)).catch(error=>console.error("Could not resample PCM data for codec. Error:"+error))}encodeSamples0(cache,buffer){for(cache._chunks.push(new BufferChunk(buffer));cache.bufferedSamples(this.samplesPerUnit)>=this.samplesPerUnit;){let buffer=this._audioContext.createBuffer(this.channelCount,this.samplesPerUnit,this._codecSampleRate),index=0;for(;index{result instanceof Uint8Array?((new Date).getTime()-20>encodeBegin&&console.error("Required time: %d",(new Date).getTime()-encodeBegin),this.on_encoded_data(result)):console.error("[Codec]["+this.name()+"] Could not encode buffer. Result: "+result)})}return!0}decodeSamples(cache,data){return this.decode(data).then(buffer=>this._decodeResampler.resample(buffer))}}!function(CodecWorkerType){CodecWorkerType[CodecWorkerType.WORKER_OPUS=0]="WORKER_OPUS"}(CodecWorkerType||(CodecWorkerType={}));class CodecWrapper extends BasicCodec{constructor(type,channelCount){super(48e3),this._workerListener=[],this._workerCallbackToken="callback_token",this._workerTokeIndex=0,this._initialized=!1,this.type=type,this.channelCount=channelCount}name(){return"Worker for "+CodecWorkerType[this.type]+" Channels "+this.channelCount}initialise(){return this._initializePromise?this._initializePromise:this._initializePromise=this.spawnWorker().then(()=>new Promise((resolve,reject)=>{const token=this.generateToken();this.sendWorkerMessage({command:"initialise",type:this.type,channelCount:this.channelCount,token:token}),this._workerListener.push({token:token,resolve:data=>{console.log("Init result: %o",data),this._initialized=1==data.success,1==data.success?resolve():reject(data.message)}})}))}initialized(){return this._initialized}deinitialise(){this.sendWorkerMessage({command:"deinitialise"})}decode(data){let token=this.generateToken(),result=new Promise((resolve,reject)=>{this._workerListener.push({token:token,resolve:data=>{if(data.success){let array=new Float32Array(data.dataLength);for(let index=0;index{this._workerListener.push({token:token,resolve:data=>{if(data.success){let array=new Uint8Array(data.dataLength);for(let index=0;index{this._workerCallbackReject=reject,this._workerCallbackResolve=resolve,this._worker=new Worker(settings.static("worker_directory","js/workers/")+"WorkerCodec.js"),this._worker.onmessage=(event=>this.onWorkerMessage(JSON.parse(event.data)))})}}let settings,globalClient,chat,forumIdentity;function main(){AudioController.initializeAudioController(),TSIdentityHelper.setup()?(settings=new Settings,globalClient=new TSClient,settings.static("forum_user_data")&&(forumIdentity=new TeaForumIdentity(settings.static("forum_user_data"),settings.static("forum_user_sign"))),chat=new ChatBox($("#chat")),globalClient.setup(),settings.static(Settings.KEY_DISABLE_UNLOAD_DIALOG,!1)||window.addEventListener("beforeunload",function(event){globalClient.serverConnection&&globalClient.serverConnection.connected&&(event.returnValue="Are you really sure?
You're still connected!")}),settings.static("default_connect_url")&&("forum"==settings.static("default_connect_type","forum")?globalClient.startConnection(settings.static("default_connect_url"),forumIdentity):Modals.spawnConnectModal(settings.static("default_connect_url")))):console.error("Could not setup the TeamSpeak identity parser!")}app.loadedListener.push(()=>main());class RawCodec extends BasicCodec{constructor(codecSampleRate){super(codecSampleRate),this.bufferSize=16384}name(){return"raw"}initialise(){return this.converterRaw=Module._malloc(this.bufferSize),this.converter=new Uint8Array(Module.HEAPU8.buffer,this.converterRaw,this.bufferSize),new Promise(resolve=>resolve())}initialized(){return!0}deinitialise(){}decode(data){return new Promise((resolve,reject)=>{this.converter.set(data);let buf=Module.HEAPF32.slice(this.converter.byteOffset/4,this.converter.byteOffset/4+data.length/4),audioBuf=this._audioContext.createBuffer(1,data.length/4,this._codecSampleRate);audioBuf.copyToChannel(buf,0),resolve(audioBuf)})}encode(data){return new Promise(resolve=>resolve(new Uint8Array(data.getChannelData(0))))}reset(){return!0}}var hex;!function(hex){hex.encode=function(buffer){let hexCodes=[],view=new DataView(buffer);for(let i=0;i");return serverIcon.append($.spawn("div").addClass("icon_property icon_empty")),tag.append(serverIcon),this._htmlTag=tag}initializeListener(){const _this=this;this._htmlTag.click(function(){_this.channelTree.onSelect(_this)}),settings.static(Settings.KEY_DISABLE_CONTEXT_MENU,!1)||this.htmlTag.on("contextmenu",function(event){event.preventDefault(),_this.channelTree.onSelect(_this),_this.spawnContextMenu(event.pageX,event.pageY,()=>{_this.channelTree.onSelect(void 0)})})}spawnContextMenu(x,y,on_close=(()=>{})){spawnMenu(x,y,{type:MenuEntryType.ENTRY,icon:"",name:"test",callback:()=>{}},MenuEntry.CLOSE(on_close))}updateProperty(key,value){console.log("Updating property "+key+" => '"+value+"' for the server"),this.properties[key]=value,"virtualserver_name"==key?this.htmlTag.find(".name").text(value):"virtualserver_icon_id"==key&&this.channelTree.client.fileManager&&this.channelTree.client.fileManager.icons&&this.htmlTag.find(".icon_property").replaceWith(this.channelTree.client.fileManager.icons.generateTag(this.properties.virtualserver_icon_id).addClass("icon_property"))}updateProperties(){this.lastInfoRequest=(new Date).getTime(),this.nextInfoRequest=this.lastInfoRequest+1e4,this.channelTree.client.serverConnection.sendCommand("servergetvariables")}shouldUpdateProperties(){return this.nextInfoRequest384e3)throw"The target sample rate is outside the range [3000, 384000]."}resample(buffer){if(buffer.sampleRate==this.targetSampleRate)return new Promise(resolve=>resolve(buffer));let context,source=(context=new OfflineAudioContext(buffer.numberOfChannels,Math.ceil(buffer.length*this.targetSampleRate/buffer.sampleRate),this.targetSampleRate)).createBufferSource();return source.buffer=buffer,source.connect(context.destination),source.start(0),context.startRendering()}}