var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["a5a03ca85c8240449664e3b10fd8fcc34885e4fa5642d49e9e09fc9a59670cdc"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["a5a03ca85c8240449664e3b10fd8fcc34885e4fa5642d49e9e09fc9a59670cdc"] = "a5a03ca85c8240449664e3b10fd8fcc34885e4fa5642d49e9e09fc9a59670cdc"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Wl8vrliw", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (68,48)" }, { name: "TRAT_MvL", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (84,51)" }, { name: "NHpPYFZ5", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (91,51)" }, { name: "xmHiPaM0", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (104,51)" }, { name: "bkWPmlLQ", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (122,34)" }, { name: "VLiaGQGx", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (227,43)" }, { name: "qDGtVdSI", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (235,44)" }, { name: "GkVHr9AU", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (242,39)" }, { name: "laReoH3i", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (346,56)" }, { name: "hs5uHkoO", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (356,60)" }, { name: "lr1fckIz", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (367,55)" }, { name: "dy0SUBbK", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (371,56)" }, { name: "Cw58TNMU", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (375,56)" }, { name: "N46z9byK", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (379,52)" }, { name: "DychQff8", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (389,56)" }, { name: "fJ5NHwOd", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (397,56)" }, { name: "ja_xbzKa", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (398,53)" }, { name: "EES58bn8", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (406,55)" }, { name: "PMONgu7p", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (411,55)" }, { name: "E3YbqUC5", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (415,52)" }, { name: "SYcW1j9s", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (426,55)" }, { name: "QG0sTpJs", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (431,55)" }, { name: "PeE5Y0gF", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (437,52)" }, { name: "LnZyAOSW", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (564,48)" }, { name: "UIzPrFR8", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (567,48)" }, { name: "n5XDhypA", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (652,47)" }, { name: "jIjjhpiZ", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (656,51)" }, { name: "NBBzTYcx", path: "D:/TeaSpeak/web/shared/js/BrowserIPC.ts (669,34)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var bipc; (function (bipc) { function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } class BasicIPCHandler { constructor() { this._channels = []; this._query_results = {}; this._cert_accept_callbacks = {}; this._cert_accept_succeeded = {}; } setup() { this.unique_id = uuidv4(); /* lets get an unique identifier */ } get_local_address() { return this.unique_id; } handle_message(message) { //log.trace(LogCategory.IPC, tr("Received message %o"), message); if (message.receiver === BasicIPCHandler.BROADCAST_UNIQUE_ID) { if (message.type == "process-query") { log.debug(LogCategory.IPC, _translations.Wl8vrliw || (_translations.Wl8vrliw = tr("Received a device query from %s.")), message.sender); this.send_message("process-query-response", { request_query_id: message.data.query_id, request_timestamp: message.data.timestamp, device_id: this.unique_id, protocol: BasicIPCHandler.PROTOCOL_VERSION }, message.sender); return; } } else if (message.receiver === this.unique_id) { if (message.type == "process-query-response") { const response = message.data; if (this._query_results[response.request_query_id]) this._query_results[response.request_query_id].push(response); else { log.warn(LogCategory.IPC, _translations.TRAT_MvL || (_translations.TRAT_MvL = tr("Received a query response for an unknown request."))); } return; } else if (message.type == "certificate-accept-callback") { const data = message.data; if (!this._cert_accept_callbacks[data.request_id]) { log.warn(LogCategory.IPC, _translations.NHpPYFZ5 || (_translations.NHpPYFZ5 = tr("Received certificate accept callback for an unknown request ID."))); return; } this._cert_accept_callbacks[data.request_id](); delete this._cert_accept_callbacks[data.request_id]; this.send_message("certificate-accept-succeeded", {}, message.sender); return; } else if (message.type == "certificate-accept-succeeded") { if (!this._cert_accept_succeeded[message.sender]) { log.warn(LogCategory.IPC, _translations.xmHiPaM0 || (_translations.xmHiPaM0 = tr("Received certificate accept succeeded, but haven't a callback."))); return; } this._cert_accept_succeeded[message.sender](); return; } } if (message.type === "channel") { const data = message.data; let channel_invoked = false; for (const channel of this._channels) if (channel.channel_id === data.channel_id && (typeof (channel.target_id) === "undefined" || channel.target_id === message.sender)) { if (channel.message_handler) channel.message_handler(message.sender, message.receiver === BasicIPCHandler.BROADCAST_UNIQUE_ID, data); channel_invoked = true; } if (!channel_invoked) { console.warn(_translations.bkWPmlLQ || (_translations.bkWPmlLQ = tr("Received channel message for unknown channel (%s)")), data.channel_id); } } } create_channel(target_id, channel_id) { let channel = { target_id: target_id, channel_id: channel_id || uuidv4(), message_handler: undefined, send_message: (type, data, target) => { if (typeof target !== "undefined") { if (typeof channel.target_id === "string" && target != channel.target_id) throw "target id does not match channel target"; } this.send_message("channel", { type: type, data: data, channel_id: channel.channel_id }, target || channel.target_id || BasicIPCHandler.BROADCAST_UNIQUE_ID); } }; this._channels.push(channel); return channel; } channels() { return this._channels; } delete_channel(channel) { this._channels = this._channels.filter(e => e !== channel); } query_processes(timeout) { return __awaiter(this, void 0, void 0, function* () { const query_id = uuidv4(); this._query_results[query_id] = []; this.send_message("process-query", { query_id: query_id, timestamp: Date.now() }); yield new Promise(resolve => setTimeout(resolve, timeout || 250)); const result = this._query_results[query_id]; delete this._query_results[query_id]; return result; }); } register_certificate_accept_callback(callback) { const id = uuidv4(); this._cert_accept_callbacks[id] = callback; return this.unique_id + ":" + id; } post_certificate_accpected(id, timeout) { return new Promise((resolve, reject) => { const data = id.split(":"); const timeout_id = setTimeout(() => { delete this._cert_accept_succeeded[data[0]]; clearTimeout(timeout_id); reject("timeout"); }, timeout || 250); this._cert_accept_succeeded[data[0]] = () => { delete this._cert_accept_succeeded[data[0]]; clearTimeout(timeout_id); resolve(); }; this.send_message("certificate-accept-callback", { request_id: data[1] }, data[0]); }); } } BasicIPCHandler.BROADCAST_UNIQUE_ID = "00000000-0000-4000-0000-000000000000"; BasicIPCHandler.PROTOCOL_VERSION = 1; bipc.BasicIPCHandler = BasicIPCHandler; class BroadcastChannelIPC extends BasicIPCHandler { constructor() { super(); } setup() { super.setup(); this.channel = new BroadcastChannel(BroadcastChannelIPC.CHANNEL_NAME); this.channel.onmessage = this.on_message.bind(this); this.channel.onmessageerror = this.on_error.bind(this); } on_message(event) { if (typeof (event.data) !== "string") { log.warn(LogCategory.IPC, _translations.VLiaGQGx || (_translations.VLiaGQGx = tr("Received message with an invalid type (%s): %o")), typeof (event.data), event.data); return; } let message; try { message = JSON.parse(event.data); } catch (error) { log.error(LogCategory.IPC, _translations.qDGtVdSI || (_translations.qDGtVdSI = tr("Received an invalid encoded message: %o")), event.data); return; } super.handle_message(message); } on_error(event) { log.warn(LogCategory.IPC, _translations.GkVHr9AU || (_translations.GkVHr9AU = tr("Received error: %o")), event); } send_message(type, data, target) { const message = {}; message.sender = this.unique_id; message.receiver = target ? target : BasicIPCHandler.BROADCAST_UNIQUE_ID; message.timestamp = Date.now(); message.type = type; message.data = data; this.channel.postMessage(JSON.stringify(message)); } } BroadcastChannelIPC.CHANNEL_NAME = "TeaSpeak-Web"; let connect; (function (connect) { /* The connect process: * 1. Broadcast an offer * 2. Wait 50ms for all offer responses or until the first one respond with "ok" * 3. Select (if possible) on accepted offer and execute the connect */ class ConnectHandler { constructor(ipc_handler) { this.callback_available = () => false; this.callback_execute = () => false; this._pending_connect_offers = []; this._pending_connects_requests = []; this.ipc_handler = ipc_handler; } setup() { this.ipc_channel = this.ipc_handler.create_channel(undefined, ConnectHandler.CHANNEL_NAME); this.ipc_channel.message_handler = this.on_message.bind(this); } on_message(sender, broadcast, message) { if (broadcast) { if (message.type == "offer") { const data = message.data; const response = { accepted: this.callback_available(data.data), request_id: data.request_id }; if (response.accepted) { log.debug(LogCategory.IPC, _translations.laReoH3i || (_translations.laReoH3i = tr("Received new connect offer from %s: %s")), sender, data.request_id); const ld = { remote_handler: sender, data: data.data, id: data.request_id, timeout: 0 }; this._pending_connect_offers.push(ld); ld.timeout = setTimeout(() => { log.debug(LogCategory.IPC, _translations.hs5uHkoO || (_translations.hs5uHkoO = tr("Dropping connect request %s, because we never received an execute.")), ld.id); this._pending_connect_offers.remove(ld); }, 120 * 1000); } this.ipc_channel.send_message("offer-answer", response, sender); } } else { if (message.type == "offer-answer") { const data = message.data; const request = this._pending_connects_requests.find(e => e.id === data.request_id); if (!request) { log.warn(LogCategory.IPC, _translations.lr1fckIz || (_translations.lr1fckIz = tr("Received connect offer answer with unknown request id (%s).")), data.request_id); return; } if (!data.accepted) { log.debug(LogCategory.IPC, _translations.dy0SUBbK || (_translations.dy0SUBbK = tr("Client %s rejected the connect offer (%s).")), sender, request.id); return; } if (request.remote_handler) { log.debug(LogCategory.IPC, _translations.Cw58TNMU || (_translations.Cw58TNMU = tr("Client %s accepted the connect offer (%s), but offer has already been accepted.")), sender, request.id); return; } log.debug(LogCategory.IPC, _translations.N46z9byK || (_translations.N46z9byK = tr("Client %s accepted the connect offer (%s). Request local acceptance.")), sender, request.id); request.remote_handler = sender; clearTimeout(request.timeout); request.callback_avail().then(flag => { if (!flag) { request.callback_failed("local avail rejected"); return; } log.debug(LogCategory.IPC, _translations.DychQff8 || (_translations.DychQff8 = tr("Executing connect with client %s")), request.remote_handler); this.ipc_channel.send_message("execute", { request_id: request.id }, request.remote_handler); request.timeout = setTimeout(() => { request.callback_failed("connect execute timeout"); }, 1000); }).catch(error => { log.error(LogCategory.IPC, _translations.fJ5NHwOd || (_translations.fJ5NHwOd = tr("Local avail callback caused an error: %o")), error); request.callback_failed(_translations.ja_xbzKa || (_translations.ja_xbzKa = tr("local avail callback caused an error"))); }); } else if (message.type == "executed") { const data = message.data; const request = this._pending_connects_requests.find(e => e.id === data.request_id); if (!request) { log.warn(LogCategory.IPC, _translations.EES58bn8 || (_translations.EES58bn8 = tr("Received connect executed with unknown request id (%s).")), data.request_id); return; } if (request.remote_handler != sender) { log.warn(LogCategory.IPC, _translations.PMONgu7p || (_translations.PMONgu7p = tr("Received connect executed for request %s, but from wrong client: %s (expected %s)")), data.request_id, sender, request.remote_handler); return; } log.debug(LogCategory.IPC, _translations.E3YbqUC5 || (_translations.E3YbqUC5 = tr("Received connect executed response from client %s for request %s. Succeeded: %o (%s)")), sender, data.request_id, data.succeeded, data.message); clearTimeout(request.timeout); if (data.succeeded) request.callback_success(); else request.callback_failed(data.message); } else if (message.type == "execute") { const data = message.data; const request = this._pending_connect_offers.find(e => e.id === data.request_id); if (!request) { log.warn(LogCategory.IPC, _translations.SYcW1j9s || (_translations.SYcW1j9s = tr("Received connect execute with unknown request id (%s).")), data.request_id); return; } if (request.remote_handler != sender) { log.warn(LogCategory.IPC, _translations.QG0sTpJs || (_translations.QG0sTpJs = tr("Received connect execute for request %s, but from wrong client: %s (expected %s)")), data.request_id, sender, request.remote_handler); return; } clearTimeout(request.timeout); this._pending_connect_offers.remove(request); log.debug(LogCategory.IPC, _translations.PeE5Y0gF || (_translations.PeE5Y0gF = tr("Executing connect for %s")), data.request_id); const cr = this.callback_execute(request.data); const response = { request_id: data.request_id, succeeded: typeof (cr) !== "string" && cr, message: typeof (cr) === "string" ? cr : "", }; this.ipc_channel.send_message("executed", response, request.remote_handler); } } } post_connect_request(data, callback_avail) { return new Promise((resolve, reject) => { const pd = { data: data, id: uuidv4(), timeout: 0, callback_success: () => { this._pending_connects_requests.remove(pd); clearTimeout(pd.timeout); resolve(); }, callback_failed: error => { this._pending_connects_requests.remove(pd); clearTimeout(pd.timeout); reject(error); }, callback_avail: callback_avail, }; this._pending_connects_requests.push(pd); this.ipc_channel.send_message("offer", { request_id: pd.id, data: pd.data }); pd.timeout = setTimeout(() => { pd.callback_failed("received no response to offer"); }, 50); }); } } ConnectHandler.CHANNEL_NAME = "connect"; connect.ConnectHandler = ConnectHandler; })(connect = bipc.connect || (bipc.connect = {})); let mproxy; (function (mproxy) { class MethodProxy { constructor(ipc_handler, connect_params) { this._proxied_methods = {}; this._proxied_callbacks = {}; this.ipc_handler = ipc_handler; this._ipc_parameters = connect_params; this._connected = false; this._slave = typeof (connect_params) !== "undefined"; this._local = typeof (connect_params) !== "undefined" && connect_params.channel_id === "local" && connect_params.client_id === "local"; } setup() { if (this._local) { this._connected = true; this.on_connected(); } else { if (this._slave) this._ipc_channel = this.ipc_handler.create_channel(this._ipc_parameters.client_id, this._ipc_parameters.channel_id); else this._ipc_channel = this.ipc_handler.create_channel(); this._ipc_channel.message_handler = this._handle_message.bind(this); if (this._slave) this._ipc_channel.send_message("initialize", {}); } } finalize() { if (!this._local) { if (this._connected) this._ipc_channel.send_message("finalize", {}); this.ipc_handler.delete_channel(this._ipc_channel); this._ipc_channel = undefined; } for (const promise of Object.values(this._proxied_callbacks)) promise.reject("disconnected"); this._proxied_callbacks = {}; this._connected = false; this.on_disconnected(); } register_method(method) { let method_name; if (typeof method === "function") { log.debug(LogCategory.IPC, _translations.LnZyAOSW || (_translations.LnZyAOSW = tr("Registering method proxy for %s")), method.name); method_name = method.name; } else { log.debug(LogCategory.IPC, _translations.UIzPrFR8 || (_translations.UIzPrFR8 = tr("Registering method proxy for %s")), method); method_name = method; } if (!this[method_name]) throw "method is missing in current object"; this._proxied_methods[method_name] = this[method_name]; if (!this._local) { this[method_name] = (...args) => { if (!this._connected) return Promise.reject("not connected"); const proxy_callback = { promise_id: uuidv4() }; this._proxied_callbacks[proxy_callback.promise_id] = proxy_callback; proxy_callback.promise = new Promise((resolve, reject) => { proxy_callback.resolve = resolve; proxy_callback.reject = reject; }); this._ipc_channel.send_message("invoke", { promise_id: proxy_callback.promise_id, arguments: [...args], method_name: method_name }); return proxy_callback.promise; }; } } _handle_message(remote_id, boradcast, message) { if (message.type === "finalize") { this._handle_finalize(); } else if (message.type === "initialize") { this._handle_remote_callback(remote_id); } else if (message.type === "invoke") { this._handle_invoke(message.data); } else if (message.type === "result") { this._handle_result(message.data); } } _handle_finalize() { this.on_disconnected(); this.finalize(); this._connected = false; } _handle_remote_callback(remote_id) { if (!this._ipc_channel.target_id) { if (this._slave) throw "initialize wrong state!"; this._ipc_channel.target_id = remote_id; /* now we're able to send messages */ this.on_connected(); this._ipc_channel.send_message("initialize", true); } else { if (!this._slave) throw "initialize wrong state!"; this.on_connected(); } this._connected = true; } _send_result(promise_id, success, message) { this._ipc_channel.send_message("result", { promise_id: promise_id, result: message, success: success }); } _handle_invoke(data) { if (this._proxied_methods[data.method_name]) throw "we could not invoke a local proxied method!"; if (!this[data.method_name]) { this._send_result(data.promise_id, false, "missing method"); return; } try { log.info(LogCategory.IPC, _translations.n5XDhypA || (_translations.n5XDhypA = tr("Invoking method %s with arguments: %o")), data.method_name, data.arguments); const promise = this[data.method_name](...data.arguments); promise.then(result => { log.info(LogCategory.IPC, _translations.jIjjhpiZ || (_translations.jIjjhpiZ = tr("Result: %o")), result); this._send_result(data.promise_id, true, result); }).catch(error => { this._send_result(data.promise_id, false, error); }); } catch (error) { this._send_result(data.promise_id, false, error); return; } } _handle_result(data) { if (!this._proxied_callbacks[data.promise_id]) { console.warn(_translations.NBBzTYcx || (_translations.NBBzTYcx = tr("Received proxy method result for unknown promise"))); return; } const callback = this._proxied_callbacks[data.promise_id]; delete this._proxied_callbacks[data.promise_id]; if (data.success) callback.resolve(data.result); else callback.reject(data.result); } generate_connect_parameters() { if (this._slave) throw "only masters can generate connect parameters!"; if (!this._ipc_channel) throw "please call setup() before"; return { channel_id: this._ipc_channel.channel_id, client_id: this.ipc_handler.get_local_address() }; } is_slave() { return this._local || this._slave; } /* the popout modal */ is_master() { return this._local || !this._slave; } /* the host (teaweb application) */ } mproxy.MethodProxy = MethodProxy; })(mproxy = bipc.mproxy || (bipc.mproxy = {})); let handler; let connect_handler; function setup() { if (!supported()) return; handler = new BroadcastChannelIPC(); handler.setup(); connect_handler = new connect.ConnectHandler(handler); connect_handler.setup(); } bipc.setup = setup; function get_handler() { return handler; } bipc.get_handler = get_handler; function get_connect_handler() { return connect_handler; } bipc.get_connect_handler = get_connect_handler; function supported() { /* ios does not support this */ return typeof (window.BroadcastChannel) !== "undefined"; } bipc.supported = supported; })(bipc || (bipc = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e9465f7ab2e9767c098f57c8330ffbeb335dfeb60c7988bf4ae7bdaefb93a0be"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e9465f7ab2e9767c098f57c8330ffbeb335dfeb60c7988bf4ae7bdaefb93a0be"] = "e9465f7ab2e9767c098f57c8330ffbeb335dfeb60c7988bf4ae7bdaefb93a0be"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Z7deKCo1", path: "D:/TeaSpeak/web/shared/js/log.ts (168,30)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } //Used by CertAccept popup var LogCategory; (function (LogCategory) { LogCategory[LogCategory["CHANNEL"] = 0] = "CHANNEL"; LogCategory[LogCategory["CHANNEL_PROPERTIES"] = 1] = "CHANNEL_PROPERTIES"; LogCategory[LogCategory["CLIENT"] = 2] = "CLIENT"; LogCategory[LogCategory["BOOKMARKS"] = 3] = "BOOKMARKS"; LogCategory[LogCategory["SERVER"] = 4] = "SERVER"; LogCategory[LogCategory["PERMISSIONS"] = 5] = "PERMISSIONS"; LogCategory[LogCategory["GENERAL"] = 6] = "GENERAL"; LogCategory[LogCategory["NETWORKING"] = 7] = "NETWORKING"; LogCategory[LogCategory["VOICE"] = 8] = "VOICE"; LogCategory[LogCategory["CHAT"] = 9] = "CHAT"; LogCategory[LogCategory["AUDIO"] = 10] = "AUDIO"; LogCategory[LogCategory["I18N"] = 11] = "I18N"; LogCategory[LogCategory["IPC"] = 12] = "IPC"; LogCategory[LogCategory["IDENTITIES"] = 13] = "IDENTITIES"; LogCategory[LogCategory["STATISTICS"] = 14] = "STATISTICS"; LogCategory[LogCategory["DNS"] = 15] = "DNS"; })(LogCategory || (LogCategory = {})); var log; (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.CHANNEL_PROPERTIES, "Channel "], [LogCategory.CLIENT, "Client "], [LogCategory.SERVER, "Server "], [LogCategory.BOOKMARKS, "Bookmark "], [LogCategory.PERMISSIONS, "Permission "], [LogCategory.GENERAL, "General "], [LogCategory.NETWORKING, "Network "], [LogCategory.VOICE, "Voice "], [LogCategory.AUDIO, "Audio "], [LogCategory.CHANNEL, "Chat "], [LogCategory.I18N, "I18N "], [LogCategory.IDENTITIES, "Identities "], [LogCategory.IPC, "IPC "], [LogCategory.STATISTICS, "Statistics "], [LogCategory.DNS, "DNS "] ]); log_1.enabled_mapping = new Map([ [LogCategory.CHANNEL, true], [LogCategory.CHANNEL_PROPERTIES, false], [LogCategory.CLIENT, true], [LogCategory.SERVER, true], [LogCategory.BOOKMARKS, true], [LogCategory.PERMISSIONS, true], [LogCategory.GENERAL, true], [LogCategory.NETWORKING, true], [LogCategory.VOICE, true], [LogCategory.AUDIO, true], [LogCategory.CHAT, true], [LogCategory.I18N, false], [LogCategory.IDENTITIES, true], [LogCategory.IPC, true], [LogCategory.STATISTICS, true], [LogCategory.DNS, true] ]); //Values will be overridden by initialize() log_1.level_mapping = new Map([ [LogType.TRACE, true], [LogType.DEBUG, true], [LogType.INFO, true], [LogType.WARNING, true], [LogType.ERROR, true] ]); let GroupMode; (function (GroupMode) { GroupMode[GroupMode["NATIVE"] = 0] = "NATIVE"; GroupMode[GroupMode["PREFIX"] = 1] = "PREFIX"; })(GroupMode || (GroupMode = {})); const group_mode = GroupMode.PREFIX; //Category Example: ?log.i18n.enabled=0 //Level Example A: ?log.level.trace.enabled=0 //Level Example B: ?log.level=0 function initialize(default_level) { for (const category of Object.keys(LogCategory).map(e => parseInt(e))) { if (isNaN(category)) continue; const category_name = LogCategory[category].toLowerCase(); log_1.enabled_mapping.set(category, settings.static_global("log." + category_name.toLowerCase() + ".enabled", log_1.enabled_mapping.get(category))); } const base_level = settings.static_global("log.level", default_level); for (const level of Object.keys(LogType).map(e => parseInt(e))) { if (isNaN(level)) continue; const level_name = LogType[level].toLowerCase(); log_1.level_mapping.set(level, settings.static_global("log." + level_name + ".enabled", level >= base_level)); } } log_1.initialize = initialize; function logDirect(type, message, ...optionalParams) { if (!log_1.level_mapping.get(type)) return; 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); break; } } function log(type, category, message, ...optionalParams) { if (!log_1.enabled_mapping.get(category)) return; optionalParams.unshift(category_mapping.get(category)); message = "[%s] " + message; logDirect(type, message, ...optionalParams); } log_1.log = log; function trace(category, message, ...optionalParams) { log(LogType.TRACE, category, message, ...optionalParams); } log_1.trace = trace; function debug(category, message, ...optionalParams) { log(LogType.DEBUG, category, message, ...optionalParams); } log_1.debug = debug; function info(category, message, ...optionalParams) { log(LogType.INFO, category, message, ...optionalParams); } log_1.info = info; function warn(category, message, ...optionalParams) { log(LogType.WARNING, category, message, ...optionalParams); } log_1.warn = warn; function error(category, message, ...optionalParams) { log(LogType.ERROR, category, message, ...optionalParams); } log_1.error = error; function group(level, category, name, ...optionalParams) { name = "[%s] " + name; optionalParams.unshift(category_mapping.get(category)); return new Group(group_mode, level, category, name, optionalParams); } log_1.group = group; function table(level, category, title, arguments) { if (group_mode == GroupMode.NATIVE) { console.groupCollapsed(title); console.table(arguments); console.groupEnd(); } else { if (!log_1.enabled_mapping.get(category) || !log_1.level_mapping.get(level)) return; logDirect(level, _translations.Z7deKCo1 || (_translations.Z7deKCo1 = tr("Snipped table \"%s\"")), title); } } log_1.table = table; class Group { constructor(mode, level, category, name, optionalParams, owner = undefined) { this.owner = undefined; this._collapsed = false; this.initialized = false; this.level = level; this.mode = mode; this.category = category; this.name = name; this.optionalParams = optionalParams; this.enabled = log_1.enabled_mapping.get(category); } group(level, name, ...optionalParams) { return new Group(this.mode, level, this.category, name, optionalParams, this); } collapsed(flag = true) { this._collapsed = flag; return this; } log(message, ...optionalParams) { if (!this.enabled) return this; if (!this.initialized) { if (this.mode == GroupMode.NATIVE) { if (this._collapsed && console.groupCollapsed) console.groupCollapsed(this.name, ...this.optionalParams); else console.group(this.name, ...this.optionalParams); } else { this._log_prefix = " "; let parent = this.owner; while (parent) { if (parent.mode == GroupMode.PREFIX) this._log_prefix = this._log_prefix + parent._log_prefix; else break; } } this.initialized = true; } if (this.mode == GroupMode.NATIVE) logDirect(this.level, message, ...optionalParams); else { logDirect(this.level, "[%s] " + this._log_prefix + message, category_mapping.get(this.category), ...optionalParams); } return this; } end() { if (this.initialized) { if (this.mode == GroupMode.NATIVE) console.groupEnd(); } } get prefix() { return this._log_prefix; } set prefix(prefix) { this._log_prefix = prefix; } } log_1.Group = Group; })(log || (log = {})); var LogType = log.LogType; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["20f9ceefb8afb92246cf15502902caa1a99609daaa67d6f61840b5171d8bbc8d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["20f9ceefb8afb92246cf15502902caa1a99609daaa67d6f61840b5171d8bbc8d"] = "20f9ceefb8afb92246cf15502902caa1a99609daaa67d6f61840b5171d8bbc8d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "zYWR4o3Z", path: "D:/TeaSpeak/web/shared/js/proto.ts (65,31)" }, { name: "iE5caXLV", path: "D:/TeaSpeak/web/shared/js/proto.ts (69,31)" }, { name: "TjsDTpLS", path: "D:/TeaSpeak/web/shared/js/proto.ts (91,26)" }, { name: "gwdhfC2P", path: "D:/TeaSpeak/web/shared/js/proto.ts (244,33)" }, { name: "owW67Cw3", path: "D:/TeaSpeak/web/shared/js/proto.ts (246,32)" }, { name: "CdWCrwjn", path: "D:/TeaSpeak/web/shared/js/proto.ts (248,33)" }, { name: "HTRvaP1x", path: "D:/TeaSpeak/web/shared/js/proto.ts (250,35)" }, { name: "bgcJDudo", path: "D:/TeaSpeak/web/shared/js/proto.ts (252,35)" }, { name: "q1rcyqp9", path: "D:/TeaSpeak/web/shared/js/proto.ts (254,18)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } if (!JSON.map_to) { JSON.map_to = function (object, json, variables, validator, variable_direction) { if (!validator) validator = (a, b) => true; if (!variables) { variables = []; if (!variable_direction || variable_direction == 0) { for (let field in json) variables.push(field); } else if (variable_direction == 1) { for (let field in object) variables.push(field); } } else if (!Array.isArray(variables)) { variables = [variables]; } let updates = 0; for (let field of variables) { if (typeof json[field] === "undefined") { console.trace(_translations.zYWR4o3Z || (_translations.zYWR4o3Z = tr("Json does not contains %s")), field); continue; } if (!validator(field, json[field])) { console.trace(_translations.iE5caXLV || (_translations.iE5caXLV = tr("Validator results in false for %s")), field); continue; } if (JSON.map_field_to(object, json[field], field)) updates++; } return updates; }; } if (!JSON.map_field_to) { JSON.map_field_to = function (object, value, field) { let field_type = typeof (object[field]); let new_object; if (field_type == "string" || field_type == "object" || field_type == "undefined") new_object = value; else if (field_type == "number") new_object = parseFloat(value); else if (field_type == "boolean") new_object = value == "1" || value == "true"; else { console.warn(_translations.TjsDTpLS || (_translations.TjsDTpLS = tr("Invalid object type %s for entry %s")), field_type, field); return false; } if (new_object === object[field]) return false; object[field] = new_object; return true; }; } if (!Array.prototype.remove) { Array.prototype.remove = function (elem) { const index = this.indexOf(elem, 0); if (index > -1) { this.splice(index, 1); return true; } return false; }; } if (!Array.prototype.pop_front) { Array.prototype.pop_front = function () { if (this.length == 0) return undefined; return this.splice(0, 1)[0]; }; } if (!Array.prototype.last) { Array.prototype.last = function () { if (this.length == 0) return undefined; return this[this.length - 1]; }; } if (typeof ($) !== "undefined") { if (!$.spawn) { $.spawn = function (tagName) { return $(document.createElement(tagName)); }; } if (!$.fn.renderTag) { $.fn.renderTag = function (values) { let result; if (this.render) { result = $(this.render(values)); } else { const template = window.jsrender.render[this.attr("id")]; if (!template) { console.error("Tried to render template %o, but template is not available!", this.attr("id")); throw "missing template " + this.attr("id"); } /* result = window.jsrender.templates("tmpl_permission_entry", $("#tmpl_permission_entry").html()); result = window.jsrender.templates("xxx", this.html()); */ result = template(values); result = $(result); } result.find("node").each((index, element) => { $(element).replaceWith(values[$(element).attr("key")] || (values[0] || [])[$(element).attr("key")]); }); return result; }; } if (!$.fn.hasScrollBar) $.fn.hasScrollBar = function (direction) { if (this.length <= 0) return false; const scroll_height = this.get(0).scrollHeight > this.height(); const scroll_width = this.get(0).scrollWidth > this.width(); if (typeof (direction) === "string") { if (direction === "height") return scroll_height; if (direction === "width") return scroll_width; } return scroll_width || scroll_height; }; if (!$.fn.visible_height) $.fn.visible_height = function () { const original_style = this.attr("style"); this.css({ position: 'absolute!important', visibility: 'hidden!important', display: 'block!important' }); const result = this.height(); this.attr("style", original_style || ""); return result; }; if (!$.fn.visible_width) $.fn.visible_width = function () { const original_style = this.attr("style"); this.css({ position: 'absolute!important', visibility: 'hidden!important', display: 'block!important' }); const result = this.width(); this.attr("style", original_style || ""); return result; }; if (!$.fn.firstParent) $.fn.firstParent = function (selector) { if (this.is(selector)) return this; return this.parent(selector); }; } if (!String.prototype.format) { String.prototype.format = function () { const args = arguments; let array = args.length == 1 && $.isArray(args[0]); return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) { if (m == "{{") { return "{"; } if (m == "}}") { return "}"; } return array ? args[0][n] : args[n]; }); }; } function concatenate(resultConstructor, ...arrays) { let totalLength = 0; for (const arr of arrays) { totalLength += arr.length; } const result = new resultConstructor(totalLength); let offset = 0; for (const arr of arrays) { result.set(arr, offset); offset += arr.length; } return result; } function formatDate(secs) { let years = Math.floor(secs / (60 * 60 * 24 * 365)); let days = Math.floor(secs / (60 * 60 * 24)) % 365; let hours = Math.floor(secs / (60 * 60)) % 24; let minutes = Math.floor(secs / 60) % 60; let seconds = Math.floor(secs % 60); let result = ""; if (years > 0) result += years + " " + (_translations.gwdhfC2P || (_translations.gwdhfC2P = tr("years"))) + " "; if (years > 0 || days > 0) result += days + " " + (_translations.owW67Cw3 || (_translations.owW67Cw3 = tr("days"))) + " "; if (years > 0 || days > 0 || hours > 0) result += hours + " " + (_translations.CdWCrwjn || (_translations.CdWCrwjn = tr("hours"))) + " "; if (years > 0 || days > 0 || hours > 0 || minutes > 0) result += minutes + " " + (_translations.HTRvaP1x || (_translations.HTRvaP1x = tr("minutes"))) + " "; if (years > 0 || days > 0 || hours > 0 || minutes > 0 || seconds > 0) result += seconds + " " + (_translations.bgcJDudo || (_translations.bgcJDudo = tr("seconds"))) + " "; else result = (_translations.q1rcyqp9 || (_translations.q1rcyqp9 = tr("now"))) + " "; return result.substr(0, result.length - 1); } function calculate_width(text) { let element = $.spawn("div"); element.text(text) .css("display", "none") .css("margin", 0); $("body").append(element); let size = element.width(); element.detach(); return size; } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["da3cc8c2045432c24c8da99176efcb06d5865aeca6fdc4cbb6208410d361cae2"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["da3cc8c2045432c24c8da99176efcb06d5865aeca6fdc4cbb6208410d361cae2"] = "da3cc8c2045432c24c8da99176efcb06d5865aeca6fdc4cbb6208410d361cae2"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /* interface Window { TextEncoder: any; } */ var sha; (function (sha) { /* * [js-sha1]{@link https://github.com/emn178/js-sha1} * * @version 0.6.0 * @author Chen, Yi-Cyuan [emn178@gmail.com] * @copyright Chen, Yi-Cyuan 2014-2017 * @license MIT */ /*jslint bitwise: true */ (function () { 'use strict'; let root = typeof window === 'object' ? window : {}; let NODE_JS = !root.JS_SHA1_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; if (NODE_JS) { root = global; } let COMMON_JS = !root.JS_SHA1_NO_COMMON_JS && typeof module === 'object' && module.exports; let AMD = typeof define === 'function' && define.amd; let HEX_CHARS = '0123456789abcdef'.split(''); let EXTRA = [-2147483648, 8388608, 32768, 128]; let SHIFT = [24, 16, 8, 0]; let OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; let blocks = []; let createOutputMethod = function (outputType) { return function (message) { return new Sha1(true).update(message)[outputType](); }; }; let createMethod = function () { let method = createOutputMethod('hex'); if (NODE_JS) { method = nodeWrap(method); } method.create = function () { return new Sha1(); }; method.update = function (message) { return method.create().update(message); }; for (var i = 0; i < OUTPUT_TYPES.length; ++i) { var type = OUTPUT_TYPES[i]; method[type] = createOutputMethod(type); } return method; }; var nodeWrap = function (method) { var crypto = eval("require('crypto')"); var Buffer = eval("require('buffer').Buffer"); var nodeMethod = function (message) { if (typeof message === 'string') { return crypto.createHash('sha1').update(message, 'utf8').digest('hex'); } else if (message.constructor === ArrayBuffer) { message = new Uint8Array(message); } else if (message.length === undefined) { return method(message); } return crypto.createHash('sha1').update(new Buffer(message)).digest('hex'); }; return nodeMethod; }; function Sha1(sharedMemory) { if (sharedMemory) { blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; this.blocks = blocks; } else { this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; } this.h0 = 0x67452301; this.h1 = 0xEFCDAB89; this.h2 = 0x98BADCFE; this.h3 = 0x10325476; this.h4 = 0xC3D2E1F0; this.block = this.start = this.bytes = this.hBytes = 0; this.finalized = this.hashed = false; this.first = true; } Sha1.prototype.update = function (message) { if (this.finalized) { return; } var notString = typeof (message) !== 'string'; if (notString && message.constructor === root.ArrayBuffer) { message = new Uint8Array(message); } var code, index = 0, i, length = message.length || 0, blocks = this.blocks; while (index < length) { if (this.hashed) { this.hashed = false; blocks[0] = this.block; blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; } if (notString) { for (i = this.start; index < length && i < 64; ++index) { blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; } } else { for (i = this.start; index < length && i < 64; ++index) { code = message.charCodeAt(index); if (code < 0x80) { blocks[i >> 2] |= code << SHIFT[i++ & 3]; } else if (code < 0x800) { blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; } else if (code < 0xd800 || code >= 0xe000) { blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; } else { code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; } } } this.lastByteIndex = i; this.bytes += i - this.start; if (i >= 64) { this.block = blocks[16]; this.start = i - 64; this.hash(); this.hashed = true; } else { this.start = i; } } if (this.bytes > 4294967295) { this.hBytes += this.bytes / 4294967296 << 0; this.bytes = this.bytes % 4294967296; } return this; }; Sha1.prototype.finalize = function () { if (this.finalized) { return; } this.finalized = true; var blocks = this.blocks, i = this.lastByteIndex; blocks[16] = this.block; blocks[i >> 2] |= EXTRA[i & 3]; this.block = blocks[16]; if (i >= 56) { if (!this.hashed) { this.hash(); } blocks[0] = this.block; blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; } blocks[14] = this.hBytes << 3 | this.bytes >>> 29; blocks[15] = this.bytes << 3; this.hash(); }; Sha1.prototype.hash = function () { var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4; var f, j, t, blocks = this.blocks; for (j = 16; j < 80; ++j) { t = blocks[j - 3] ^ blocks[j - 8] ^ blocks[j - 14] ^ blocks[j - 16]; blocks[j] = (t << 1) | (t >>> 31); } for (j = 0; j < 20; j += 5) { f = (b & c) | ((~b) & d); t = (a << 5) | (a >>> 27); e = t + f + e + 1518500249 + blocks[j] << 0; b = (b << 30) | (b >>> 2); f = (a & b) | ((~a) & c); t = (e << 5) | (e >>> 27); d = t + f + d + 1518500249 + blocks[j + 1] << 0; a = (a << 30) | (a >>> 2); f = (e & a) | ((~e) & b); t = (d << 5) | (d >>> 27); c = t + f + c + 1518500249 + blocks[j + 2] << 0; e = (e << 30) | (e >>> 2); f = (d & e) | ((~d) & a); t = (c << 5) | (c >>> 27); b = t + f + b + 1518500249 + blocks[j + 3] << 0; d = (d << 30) | (d >>> 2); f = (c & d) | ((~c) & e); t = (b << 5) | (b >>> 27); a = t + f + a + 1518500249 + blocks[j + 4] << 0; c = (c << 30) | (c >>> 2); } for (; j < 40; j += 5) { f = b ^ c ^ d; t = (a << 5) | (a >>> 27); e = t + f + e + 1859775393 + blocks[j] << 0; b = (b << 30) | (b >>> 2); f = a ^ b ^ c; t = (e << 5) | (e >>> 27); d = t + f + d + 1859775393 + blocks[j + 1] << 0; a = (a << 30) | (a >>> 2); f = e ^ a ^ b; t = (d << 5) | (d >>> 27); c = t + f + c + 1859775393 + blocks[j + 2] << 0; e = (e << 30) | (e >>> 2); f = d ^ e ^ a; t = (c << 5) | (c >>> 27); b = t + f + b + 1859775393 + blocks[j + 3] << 0; d = (d << 30) | (d >>> 2); f = c ^ d ^ e; t = (b << 5) | (b >>> 27); a = t + f + a + 1859775393 + blocks[j + 4] << 0; c = (c << 30) | (c >>> 2); } for (; j < 60; j += 5) { f = (b & c) | (b & d) | (c & d); t = (a << 5) | (a >>> 27); e = t + f + e - 1894007588 + blocks[j] << 0; b = (b << 30) | (b >>> 2); f = (a & b) | (a & c) | (b & c); t = (e << 5) | (e >>> 27); d = t + f + d - 1894007588 + blocks[j + 1] << 0; a = (a << 30) | (a >>> 2); f = (e & a) | (e & b) | (a & b); t = (d << 5) | (d >>> 27); c = t + f + c - 1894007588 + blocks[j + 2] << 0; e = (e << 30) | (e >>> 2); f = (d & e) | (d & a) | (e & a); t = (c << 5) | (c >>> 27); b = t + f + b - 1894007588 + blocks[j + 3] << 0; d = (d << 30) | (d >>> 2); f = (c & d) | (c & e) | (d & e); t = (b << 5) | (b >>> 27); a = t + f + a - 1894007588 + blocks[j + 4] << 0; c = (c << 30) | (c >>> 2); } for (; j < 80; j += 5) { f = b ^ c ^ d; t = (a << 5) | (a >>> 27); e = t + f + e - 899497514 + blocks[j] << 0; b = (b << 30) | (b >>> 2); f = a ^ b ^ c; t = (e << 5) | (e >>> 27); d = t + f + d - 899497514 + blocks[j + 1] << 0; a = (a << 30) | (a >>> 2); f = e ^ a ^ b; t = (d << 5) | (d >>> 27); c = t + f + c - 899497514 + blocks[j + 2] << 0; e = (e << 30) | (e >>> 2); f = d ^ e ^ a; t = (c << 5) | (c >>> 27); b = t + f + b - 899497514 + blocks[j + 3] << 0; d = (d << 30) | (d >>> 2); f = c ^ d ^ e; t = (b << 5) | (b >>> 27); a = t + f + a - 899497514 + blocks[j + 4] << 0; c = (c << 30) | (c >>> 2); } this.h0 = this.h0 + a << 0; this.h1 = this.h1 + b << 0; this.h2 = this.h2 + c << 0; this.h3 = this.h3 + d << 0; this.h4 = this.h4 + e << 0; }; Sha1.prototype.hex = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4; return HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F]; }; Sha1.prototype.toString = Sha1.prototype.hex; Sha1.prototype.digest = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4; return [ (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF ]; }; Sha1.prototype.array = Sha1.prototype.digest; Sha1.prototype.arrayBuffer = function () { this.finalize(); var buffer = new ArrayBuffer(20); var dataView = new DataView(buffer); dataView.setUint32(0, this.h0); dataView.setUint32(4, this.h1); dataView.setUint32(8, this.h2); dataView.setUint32(12, this.h3); dataView.setUint32(16, this.h4); return buffer; }; var exports = createMethod(); if (COMMON_JS) { module.exports = exports; } else { root._sha1 = exports; if (AMD) { define(function () { return exports; }); } } })(); function encode_text(buffer) { if (window.TextEncoder) { return new TextEncoder().encode(buffer).buffer; } let utf8 = unescape(encodeURIComponent(buffer)); let result = new Uint8Array(utf8.length); for (let i = 0; i < utf8.length; i++) { result[i] = utf8.charCodeAt(i); } return result.buffer; } sha.encode_text = encode_text; function sha1(message) { if (!(typeof (message) === "string" || message instanceof ArrayBuffer)) throw "Invalid type!"; let buffer = message instanceof ArrayBuffer ? message : encode_text(message); if (!crypto || !crypto.subtle || !crypto.subtle.digest || /Edge/.test(navigator.userAgent)) return new Promise(resolve => { resolve(_sha1.arrayBuffer(buffer)); }); else return crypto.subtle.digest("SHA-1", buffer); } sha.sha1 = sha1; })(sha || (sha = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["935e0da2013d91ea7f19563d4f99c3afd9a64fbd92648d10f12100847a7e2706"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["935e0da2013d91ea7f19563d4f99c3afd9a64fbd92648d10f12100847a7e2706"] = "935e0da2013d91ea7f19563d4f99c3afd9a64fbd92648d10f12100847a7e2706"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "vp3qN7Lv", path: "D:/TeaSpeak/web/shared/js/utils/helpers.ts (64,17)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var helpers; (function (helpers) { function hashPassword(password) { return new Promise((resolve, reject) => { sha.sha1(password).then(result => { resolve(btoa(String.fromCharCode.apply(null, new Uint8Array(result)))); }); }); } helpers.hashPassword = hashPassword; })(helpers || (helpers = {})); class LaterPromise extends Promise { constructor() { super((resolve, reject) => { }); this._handle = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); this._time = Date.now(); } resolved(object) { this._resolve(object); } rejected(reason) { this._reject(reason); } function_rejected() { return error => this.rejected(error); } time() { return this._time; } /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. * @param onrejected The callback to execute when the Promise is rejected. * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled, onrejected) { return this._handle.then(onfulfilled, onrejected); } /** * Attaches a callback for only the rejection of the Promise. * @param onrejected The callback to execute when the Promise is rejected. * @returns A Promise for the completion of the callback. */ catch(onrejected) { return this._handle.then(onrejected); } } const copy_to_clipboard = str => { console.log(_translations.vp3qN7Lv || (_translations.vp3qN7Lv = tr("Copy text to clipboard: %s")), str); const el = document.createElement('textarea'); el.value = str; el.setAttribute('readonly', ''); el.style.position = 'absolute'; el.style.left = '-9999px'; document.body.appendChild(el); const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; el.select(); document.execCommand('copy'); document.body.removeChild(el); if (selected) { document.getSelection().removeAllRanges(); document.getSelection().addRange(selected); } }; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["ea470d3765848757dcda6d47b98223fcb9ac6df163ab3f988099385249d28f40"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["ea470d3765848757dcda6d47b98223fcb9ac6df163ab3f988099385249d28f40"] = "ea470d3765848757dcda6d47b98223fcb9ac6df163ab3f988099385249d28f40"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "hhpJHMRa", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (279,36)" }, { name: "knrsc2gO", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (286,36)" }, { name: "xE5tdDeb", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (293,36)" }, { name: "QB55gRZX", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (300,36)" }, { name: "MbfBEncM", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (307,36)" }, { name: "Vsb7qSul", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (410,44)" }, { name: "ue16j2uQ", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (509,28)" }, { name: "uA6gN1CT", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (514,28)" }, { name: "Q5gkqCHu", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (525,23)" }, { name: "ZbnjV_nC", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (540,40)" }, { name: "_NrpAgeh", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (547,40)" }, { name: "QmKAmMQq", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (554,40)" }, { name: "K_D5E5Qr", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (565,23)" }, { name: "SE5yjugN", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (572,59)" }, { name: "xQ2nlySI", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (599,23)" }, { name: "Z8BBjPN6", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (611,23)" }, { name: "pWVzIrse", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (614,41)" }, { name: "gDrg7wuy", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (614,73)" }, { name: "N3R6GVVn", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (620,42)" }, { name: "JmxXwa_z", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (620,98)" }, { name: "TWGmtLXk", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (628,23)" }, { name: "i2ZLxHht", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (634,23)" }, { name: "lytbqzbt", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (712,82)" }, { name: "UH_cWHFT", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (835,30)" }, { name: "LeX07FON", path: "D:/TeaSpeak/web/shared/js/ui/channel.ts (835,54)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// var ChannelType; (function (ChannelType) { ChannelType[ChannelType["PERMANENT"] = 0] = "PERMANENT"; ChannelType[ChannelType["SEMI_PERMANENT"] = 1] = "SEMI_PERMANENT"; ChannelType[ChannelType["TEMPORARY"] = 2] = "TEMPORARY"; })(ChannelType || (ChannelType = {})); (function (ChannelType) { function normalize(mode) { let value = ChannelType[mode]; value = value.toLowerCase(); return value[0].toUpperCase() + value.substr(1); } ChannelType.normalize = normalize; })(ChannelType || (ChannelType = {})); var ChannelSubscribeMode; (function (ChannelSubscribeMode) { ChannelSubscribeMode[ChannelSubscribeMode["SUBSCRIBED"] = 0] = "SUBSCRIBED"; ChannelSubscribeMode[ChannelSubscribeMode["UNSUBSCRIBED"] = 1] = "UNSUBSCRIBED"; ChannelSubscribeMode[ChannelSubscribeMode["INHERITED"] = 2] = "INHERITED"; })(ChannelSubscribeMode || (ChannelSubscribeMode = {})); class ChannelProperties { constructor() { this.channel_order = 0; this.channel_name = ""; this.channel_name_phonetic = ""; this.channel_topic = ""; this.channel_password = ""; this.channel_codec = 4; this.channel_codec_quality = 0; this.channel_codec_is_unencrypted = false; this.channel_maxclients = -1; this.channel_maxfamilyclients = -1; this.channel_needed_talk_power = 1; this.channel_flag_permanent = false; this.channel_flag_semi_permanent = false; this.channel_flag_default = false; this.channel_flag_password = false; this.channel_flag_maxclients_unlimited = false; this.channel_flag_maxfamilyclients_inherited = false; this.channel_flag_maxfamilyclients_unlimited = false; this.channel_icon_id = 0; this.channel_delete_delay = 0; //Only after request this.channel_description = ""; this.channel_flag_conversation_private = true; /* TeamSpeak mode */ this.channel_conversation_history_length = -1; } } class ChannelEntry { constructor(channelId, channelName, parent = null) { this.properties = new ChannelProperties(); this._channel_name_alignment = undefined; this._channel_name_formatted = undefined; this._family_index = 0; this._destroyed = false; this._cached_channel_description = undefined; this._cached_channel_description_promise = undefined; this._cached_channel_description_promise_resolve = undefined; this._cached_channel_description_promise_reject = undefined; this.properties = new ChannelProperties(); this.channelId = channelId; this.properties.channel_name = channelName; this.parent = parent; this.channelTree = null; this.initializeTag(); this.__updateChannelName(); } destroy() { this._destroyed = true; if (this._tag_root) { this._tag_root.remove(); /* removes also all other tags */ this._tag_root = undefined; } this._tag_siblings = undefined; this._tag_channel = undefined; this._tag_clients = undefined; this._cached_channel_description_promise = undefined; this._cached_channel_description_promise_resolve = undefined; this._cached_channel_description_promise_reject = undefined; this.channel_previous = undefined; this.parent = undefined; this.channel_next = undefined; this.channelTree = undefined; } channelName() { return this.properties.channel_name; } formattedChannelName() { return this._channel_name_formatted || this.properties.channel_name; } getChannelDescription() { if (this._cached_channel_description) return new Promise(resolve => resolve(this._cached_channel_description)); if (this._cached_channel_description_promise) return this._cached_channel_description_promise; this.channelTree.client.serverConnection.send_command("channelgetdescription", { cid: this.channelId }).catch(error => { this._cached_channel_description_promise_reject(error); }); return this._cached_channel_description_promise = new Promise((resolve, reject) => { this._cached_channel_description_promise_resolve = resolve; this._cached_channel_description_promise_reject = reject; }); } parent_channel() { return this.parent; } hasParent() { return this.parent != null; } getChannelId() { return this.channelId; } children(deep = false) { const result = []; if (this.channelTree == null) return []; const self = this; this.channelTree.channels.forEach(function (entry) { let current = entry; if (deep) { while (current) { if (current.parent_channel() == self) { result.push(entry); break; } current = current.parent_channel(); } } else if (current.parent_channel() == self) result.push(entry); }); return result; } clients(deep = false) { const result = []; if (this.channelTree == null) return []; const self = this; this.channelTree.clients.forEach(function (entry) { let current = entry.currentChannel(); if (deep) { while (current) { if (current == self) { result.push(entry); break; } current = current.parent_channel(); } } else if (current == self) result.push(entry); }); return result; } clients_ordered() { const clients = this.clients(false); clients.sort((a, b) => { if (a.properties.client_talk_power < b.properties.client_talk_power) return 1; if (a.properties.client_talk_power > b.properties.client_talk_power) return -1; if (a.properties.client_nickname > b.properties.client_nickname) return 1; if (a.properties.client_nickname < b.properties.client_nickname) return -1; return 0; }); return clients; } update_family_index(enforce) { const current_index = this._family_index; const new_index = this.calculate_family_index(true); if (current_index == new_index && !enforce) return; this._tag_channel.css("z-index", this._family_index); this._tag_channel.css("padding-left", ((this._family_index + 1) * 16 + 10) + "px"); } calculate_family_index(enforce_recalculate = false) { if (this._family_index !== undefined && !enforce_recalculate) return this._family_index; this._family_index = 0; let channel = this.parent_channel(); while (channel) { this._family_index++; channel = channel.parent_channel(); } return this._family_index; } initializeTag() { const tag_channel = $.spawn("div").addClass("tree-entry channel"); { const container_entry = $.spawn("div").addClass("container-channel"); container_entry.attr("channel-id", this.channelId); container_entry.addClass(this._channel_name_alignment); /* unread marker */ { container_entry.append($.spawn("div") .addClass("marker-text-unread hidden") .attr("conversation", this.channelId)); } /* channel icon (type) */ { container_entry.append($.spawn("div") .addClass("show-channel-normal-only channel-type icon client-channel_green_subscribed")); } /* channel name */ { container_entry.append($.spawn("div") .addClass("container-channel-name") .append($.spawn("a") .addClass("channel-name") .text(this.channelName()))); } /* all icons (last element) */ { //Icons let container_icons = $.spawn("span").addClass("icons"); //Default icon (5) container_icons.append($.spawn("div") .addClass("show-channel-normal-only icon_entry icon_default icon client-channel_default") .attr("title", _translations.hhpJHMRa || (_translations.hhpJHMRa = tr("Default channel")))); //Password icon (4) container_icons.append($.spawn("div") .addClass("show-channel-normal-only icon_entry icon_password icon client-register") .attr("title", _translations.knrsc2gO || (_translations.knrsc2gO = tr("The channel is password protected")))); //Music icon (3) container_icons.append($.spawn("div") .addClass("show-channel-normal-only icon_entry icon_music icon client-music") .attr("title", _translations.xE5tdDeb || (_translations.xE5tdDeb = tr("Music quality")))); //Channel moderated (2) container_icons.append($.spawn("div") .addClass("show-channel-normal-only icon_entry icon_moderated icon client-moderated") .attr("title", _translations.QB55gRZX || (_translations.QB55gRZX = tr("Channel is moderated")))); //Channel Icon (1) container_icons.append($.spawn("div") .addClass("show-channel-normal-only icon_entry channel_icon") .attr("title", _translations.MbfBEncM || (_translations.MbfBEncM = tr("Channel icon")))); //Default no sound (0) let container = $.spawn("div") .css("position", "relative") .addClass("icon_no_sound"); let noSound = $.spawn("div") .addClass("icon_entry icon client-conflict-icon") .attr("title", "You don't support the channel codec"); let bg = $.spawn("div") .width(10) .height(14) .css("background", "red") .css("position", "absolute") .css("top", "1px") .css("left", "3px") .css("z-index", "-1"); bg.appendTo(container); noSound.appendTo(container); container_icons.append(container); container_icons.appendTo(container_entry); } tag_channel.append(this._tag_channel = container_entry); this.update_family_index(true); } { const container_client = $.spawn("div").addClass("container-clients"); tag_channel.append(this._tag_clients = container_client); } { const container_children = $.spawn("div").addClass("container-children"); tag_channel.append(this._tag_siblings = container_children); } /* setInterval(() => { let color = (Math.random() * 10000000).toString(16).substr(0, 6); tag_channel.css("background", "#" + color); }, 150); */ this._tag_root = tag_channel; } rootTag() { return this._tag_root; } channelTag() { return this._tag_channel; } siblingTag() { return this._tag_siblings; } clientTag() { return this._tag_clients; } reorderClients(sync) { if (this._reorder_timer) { if (!sync) return; clearTimeout(this._reorder_timer); this._reorder_timer = undefined; } else if (!sync) { this._reorder_timer = setTimeout(() => { this._reorder_timer = undefined; this.reorderClients(true); }, 5); return; } let clients = this.clients(); if (clients.length > 1) { clients.sort((a, b) => { if (a.properties.client_talk_power < b.properties.client_talk_power) return 1; if (a.properties.client_talk_power > b.properties.client_talk_power) return -1; if (a.properties.client_nickname > b.properties.client_nickname) return 1; if (a.properties.client_nickname < b.properties.client_nickname) return -1; return 0; }); clients.reverse(); for (let index = 0; index + 1 < clients.length; index++) clients[index].tag.before(clients[index + 1].tag); log.debug(LogCategory.CHANNEL, _translations.Vsb7qSul || (_translations.Vsb7qSul = tr("Reordered channel clients: %d")), clients.length); for (let client of clients) { log.debug(LogCategory.CHANNEL, "- %i %s", client.properties.client_talk_power, client.properties.client_nickname); } } } initializeListener() { const tag_channel = this.channelTag(); tag_channel.on('click', () => this.channelTree.onSelect(this)); tag_channel.on('dblclick', () => { if ($.isArray(this.channelTree.currently_selected)) { //Multiselect return; } this.joinChannel(); }); let last_touch = 0; let touch_start = 0; tag_channel.on('touchend', event => { /* if over 250ms then its not a click its more a drag */ if (Date.now() - touch_start > 250) { touch_start = 0; return; } if (Date.now() - last_touch > 750) { last_touch = Date.now(); return; } last_touch = Date.now(); /* double touch */ tag_channel.trigger('dblclick'); }); tag_channel.on('touchstart', event => { touch_start = Date.now(); }); if (!settings.static(Settings.KEY_DISABLE_CONTEXT_MENU, false)) { this.channelTag().on("contextmenu", (event) => { event.preventDefault(); if ($.isArray(this.channelTree.currently_selected)) { //Multiselect (this.channelTree.currently_selected_context_callback || ((_) => null))(event); return; } this.channelTree.onSelect(this, true); this.showContextMenu(event.pageX, event.pageY, () => { this.channelTree.onSelect(undefined, true); }); }); } } showContextMenu(x, y, on_close = undefined) { let channelCreate = !![ PermissionType.B_CHANNEL_CREATE_TEMPORARY, PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT, PermissionType.B_CHANNEL_CREATE_PERMANENT ].find(e => this.channelTree.client.permissions.neededPermission(e).granted(1)); let channelModify = !![ PermissionType.B_CHANNEL_MODIFY_MAKE_DEFAULT, PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT, PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT, PermissionType.B_CHANNEL_MODIFY_MAKE_TEMPORARY, PermissionType.B_CHANNEL_MODIFY_NAME, PermissionType.B_CHANNEL_MODIFY_TOPIC, PermissionType.B_CHANNEL_MODIFY_DESCRIPTION, PermissionType.B_CHANNEL_MODIFY_PASSWORD, PermissionType.B_CHANNEL_MODIFY_CODEC, PermissionType.B_CHANNEL_MODIFY_CODEC_QUALITY, PermissionType.B_CHANNEL_MODIFY_CODEC_LATENCY_FACTOR, PermissionType.B_CHANNEL_MODIFY_MAXCLIENTS, PermissionType.B_CHANNEL_MODIFY_MAXFAMILYCLIENTS, PermissionType.B_CHANNEL_MODIFY_SORTORDER, PermissionType.B_CHANNEL_MODIFY_NEEDED_TALK_POWER, PermissionType.B_CHANNEL_MODIFY_MAKE_CODEC_ENCRYPTED, PermissionType.B_CHANNEL_MODIFY_TEMP_DELETE_DELAY, PermissionType.B_ICON_MANAGE ].find(e => this.channelTree.client.permissions.neededPermission(e).granted(1)); let flagDelete = true; if (this.clients(true).length > 0) flagDelete = this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_FLAG_FORCE).granted(1); if (flagDelete) { if (this.properties.channel_flag_permanent) flagDelete = this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_PERMANENT).granted(1); else if (this.properties.channel_flag_semi_permanent) flagDelete = this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_PERMANENT).granted(1); else flagDelete = this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_DELETE_TEMPORARY).granted(1); } let trigger_close = true; const bold = text => contextmenu.get_provider().html_format_enabled() ? "" + text + "" : text; contextmenu.spawn_context_menu(x, y, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_switch", name: bold(_translations.ue16j2uQ || (_translations.ue16j2uQ = tr("Switch to channel"))), callback: () => this.joinChannel() }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_switch", name: bold(_translations.uA6gN1CT || (_translations.uA6gN1CT = tr("Join text channel"))), callback: () => { this.channelTree.client.side_bar.channel_conversations().set_current_channel(this.getChannelId()); this.channelTree.client.side_bar.show_channel_conversations(); }, visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT) }, { type: contextmenu.MenuEntryType.HR, name: '' }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.Q5gkqCHu || (_translations.Q5gkqCHu = tr("Show channel info")), callback: () => { trigger_close = false; Modals.openChannelInfo(this); }, icon_class: "client-about" }, ...(() => { const local_client = this.channelTree.client.getClient(); if (!local_client || local_client.currentChannel() !== this) return [ contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon: "client-subscribe_to_channel", name: bold(_translations.ZbnjV_nC || (_translations.ZbnjV_nC = tr("Subscribe to channel"))), callback: () => this.subscribe(), visible: !this.flag_subscribed }, { type: contextmenu.MenuEntryType.ENTRY, icon: "client-channel_unsubscribed", name: bold(_translations._NrpAgeh || (_translations._NrpAgeh = tr("Unsubscribe from channel"))), callback: () => this.unsubscribe(), visible: this.flag_subscribed }, { type: contextmenu.MenuEntryType.ENTRY, icon: "client-subscribe_mode", name: bold(_translations.QmKAmMQq || (_translations.QmKAmMQq = tr("Use inherited subscribe mode"))), callback: () => this.unsubscribe(true), visible: this.subscribe_mode != ChannelSubscribeMode.INHERITED } ]; return []; })(), contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_edit", name: _translations.K_D5E5Qr || (_translations.K_D5E5Qr = tr("Edit channel")), invalidPermission: !channelModify, callback: () => { Modals.createChannelModal(this.channelTree.client, this, undefined, this.channelTree.client.permissions, (changes, permissions) => { if (changes) { changes["cid"] = this.channelId; this.channelTree.client.serverConnection.send_command("channeledit", changes); log.info(LogCategory.CHANNEL, _translations.SE5yjugN || (_translations.SE5yjugN = tr("Changed channel properties of channel %s: %o")), this.channelName(), changes); } if (permissions && permissions.length > 0) { let perms = []; for (let perm of permissions) { perms.push({ permvalue: perm.value, permnegated: false, permskip: false, permid: perm.type.id }); } perms[0]["cid"] = this.channelId; this.channelTree.client.serverConnection.send_command("channeladdperm", perms, { flagset: ["continueonerror"] }).then(() => { this.channelTree.client.sound.play(Sound.CHANNEL_EDITED_SELF); }); } }); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_delete", name: _translations.xQ2nlySI || (_translations.xQ2nlySI = tr("Delete channel")), invalidPermission: !flagDelete, callback: () => { this.channelTree.client.serverConnection.send_command("channeldelete", { cid: this.channelId }).then(() => { this.channelTree.client.sound.play(Sound.CHANNEL_DELETED); }); } }, contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-addon-collection", name: _translations.Z8BBjPN6 || (_translations.Z8BBjPN6 = tr("Create music bot")), callback: () => { this.channelTree.client.serverConnection.send_command("musicbotcreate", { cid: this.channelId }).then(() => { createInfoModal(_translations.pWVzIrse || (_translations.pWVzIrse = tr("Bot successfully created")), _translations.gDrg7wuy || (_translations.gDrg7wuy = tr("Bot has been successfully created."))).open(); }).catch(error => { if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.N3R6GVVn || (_translations.N3R6GVVn = tr("Failed to create bot")), MessageHelper.formatMessage(_translations.JmxXwa_z || (_translations.JmxXwa_z = tr("Failed to create the music bot:
{0}")), error)).open(); }); } }, contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_create_sub", name: _translations.TWGmtLXk || (_translations.TWGmtLXk = tr("Create sub channel")), invalidPermission: !(channelCreate && this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_CHILD).granted(1)), callback: () => this.channelTree.spawnCreateChannel(this) }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_create", name: _translations.i2ZLxHht || (_translations.i2ZLxHht = tr("Create channel")), invalidPermission: !channelCreate, callback: () => this.channelTree.spawnCreateChannel() }, contextmenu.Entry.CLOSE(() => trigger_close ? on_close() : {})); } handle_frame_resized() { if (this._channel_name_formatted === "align-repetitive") this.__updateChannelName(); } __updateChannelName() { this._channel_name_formatted = undefined; parse_type: if (this.parent_channel() == null && this.properties.channel_name.charAt(0) == '[') { let end = this.properties.channel_name.indexOf(']'); if (end == -1) break parse_type; let options = this.properties.channel_name.substr(1, end - 1); if (options.indexOf("spacer") == -1) break parse_type; options = options.substr(0, options.indexOf("spacer")); if (options.length == 0) options = "l"; else if (options.length > 1) options = options[0]; switch (options) { case "r": this._channel_name_alignment = "align-right"; break; case "l": this._channel_name_alignment = "align-left"; break; case "c": this._channel_name_alignment = "align-center"; break; case "*": this._channel_name_alignment = "align-repetitive"; break; default: this._channel_name_alignment = undefined; break parse_type; } this._channel_name_formatted = this.properties.channel_name.substr(end + 1) || ""; } this._tag_channel.find(".show-channel-normal-only").toggleClass("channel-normal", this._channel_name_formatted === undefined); const tag_container_name = this._tag_channel.find(".container-channel-name"); tag_container_name.removeClass(ChannelEntry.NAME_ALIGNMENTS.join(" ")); const tag_name = tag_container_name.find(".channel-name"); let text = this._channel_name_formatted === undefined ? this.properties.channel_name : this._channel_name_formatted; if (this._channel_name_formatted !== undefined) { tag_container_name.addClass(this._channel_name_alignment); if (this._channel_name_alignment == "align-repetitive" && text.length > 0) { while (text.length < 1024 * 8) text += text; } } tag_name.text(text); } recalculate_repetitive_name() { if (this._channel_name_alignment == "align-repetitive") this.__updateChannelName(); } updateVariables(...variables) { let group = log.group(log.LogType.DEBUG, LogCategory.CHANNEL_PROPERTIES, _translations.lytbqzbt || (_translations.lytbqzbt = tr("Update properties (%i) of %s (%i)")), variables.length, this.channelName(), this.getChannelId()); { const entries = []; for (const variable of variables) entries.push({ key: variable.key, value: variable.value, type: typeof (this.properties[variable.key]) }); log.table(LogType.DEBUG, LogCategory.PERMISSIONS, "Clannel update properties", entries); } let info_update = false; for (let variable of variables) { let key = variable.key; let value = variable.value; JSON.map_field_to(this.properties, value, variable.key); if (key == "channel_name") { this.__updateChannelName(); info_update = true; } else if (key == "channel_order") { let order = this.channelTree.findChannel(this.properties.channel_order); this.channelTree.moveChannel(this, order, this.parent); } else if (key == "channel_icon_id") { /* For more detail lookup client::updateVariables and client_icon_id! * ATTENTION: This is required! */ this.properties.channel_icon_id = variable.value >>> 0; let tag = this.channelTag().find(".icons .channel_icon"); (this.properties.channel_icon_id > 0 ? $.fn.show : $.fn.hide).apply(tag); if (this.properties.channel_icon_id > 0) { tag.children().detach(); this.channelTree.client.fileManager.icons.generateTag(this.properties.channel_icon_id).appendTo(tag); } info_update = true; } else if (key == "channel_codec") { (this.properties.channel_codec == 5 || this.properties.channel_codec == 3 ? $.fn.show : $.fn.hide).apply(this.channelTag().find(".icons .icon_music")); this.channelTag().find(".icons .icon_no_sound").toggle(!(this.channelTree.client.serverConnection.support_voice() && this.channelTree.client.serverConnection.voice_connection().decoding_supported(this.properties.channel_codec))); } else if (key == "channel_flag_default") { (this.properties.channel_flag_default ? $.fn.show : $.fn.hide).apply(this.channelTag().find(".icons .icon_default")); } else if (key == "channel_flag_password") (this.properties.channel_flag_password ? $.fn.show : $.fn.hide).apply(this.channelTag().find(".icons .icon_password")); else if (key == "channel_needed_talk_power") (this.properties.channel_needed_talk_power > 0 ? $.fn.show : $.fn.hide).apply(this.channelTag().find(".icons .icon_moderated")); else if (key == "channel_description") { this._cached_channel_description = undefined; if (this._cached_channel_description_promise_resolve) this._cached_channel_description_promise_resolve(value); this._cached_channel_description_promise = undefined; this._cached_channel_description_promise_resolve = undefined; this._cached_channel_description_promise_reject = undefined; } if (key == "channel_maxclients" || key == "channel_maxfamilyclients" || key == "channel_flag_private" || key == "channel_flag_password") { this.updateChannelTypeIcon(); info_update = true; } if (key == "channel_flag_conversation_private") { const conversations = this.channelTree.client.side_bar.channel_conversations(); const conversation = conversations.conversation(this.channelId, false); if (conversation) conversation.set_flag_private(this.properties.channel_flag_conversation_private); } } group.end(); if (info_update) { const _client = this.channelTree.client.getClient(); if (_client.currentChannel() === this) this.channelTree.client.side_bar.info_frame().update_channel_talk(); //TODO chat channel! } } updateChannelTypeIcon() { let tag = this.channelTag().find(".channel-type"); tag.removeAttr('class'); tag.addClass("show-channel-normal-only channel-type icon"); if (this._channel_name_formatted === undefined) tag.addClass("channel-normal"); let type; if (this.properties.channel_flag_password == true && !this._cachedPassword) type = "yellow"; else if ((!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(true).length >= this.properties.channel_maxfamilyclients)) type = "red"; else type = "green"; tag.addClass("client-channel_" + type + (this._flag_subscribed ? "_subscribed" : "")); } generate_bbcode() { return "[url=channel://" + this.channelId + "/" + encodeURIComponent(this.properties.channel_name) + "]" + this.formattedChannelName() + "[/url]"; } generate_tag(braces = false) { return $(htmltags.generate_channel({ channel_name: this.properties.channel_name, channel_id: this.channelId, add_braces: braces })); } channelType() { if (this.properties.channel_flag_permanent == true) return ChannelType.PERMANENT; if (this.properties.channel_flag_semi_permanent == true) return ChannelType.SEMI_PERMANENT; return ChannelType.TEMPORARY; } joinChannel() { if (this.properties.channel_flag_password == true && !this._cachedPassword && !this.channelTree.client.permissions.neededPermission(PermissionType.B_CHANNEL_JOIN_IGNORE_PASSWORD).granted(1)) { createInputModal(_translations.UH_cWHFT || (_translations.UH_cWHFT = tr("Channel password")), _translations.LeX07FON || (_translations.LeX07FON = tr("Channel password:")), () => true, text => { if (typeof (text) == typeof (true)) return; helpers.hashPassword(text).then(result => { this._cachedPassword = result; this.joinChannel(); this.updateChannelTypeIcon(); }); }).open(); } else if (this.channelTree.client.getClient().currentChannel() != this) this.channelTree.client.getServerConnection().command_helper.joinChannel(this, this._cachedPassword).then(() => { this.channelTree.client.sound.play(Sound.CHANNEL_JOINED); }).catch(error => { if (error instanceof CommandResult) { if (error.id == 781) { //Invalid password this._cachedPassword = undefined; this.updateChannelTypeIcon(); } } }); } cached_password() { return this._cachedPassword; } subscribe() { return __awaiter(this, void 0, void 0, function* () { if (this.subscribe_mode == ChannelSubscribeMode.SUBSCRIBED) return; this.subscribe_mode = ChannelSubscribeMode.SUBSCRIBED; const connection = this.channelTree.client.getServerConnection(); if (!this.flag_subscribed && connection) yield connection.send_command('channelsubscribe', { 'cid': this.getChannelId() }); else this.flag_subscribed = false; }); } unsubscribe(inherited_subscription_mode) { return __awaiter(this, void 0, void 0, function* () { const connection = this.channelTree.client.getServerConnection(); let unsubscribe; if (inherited_subscription_mode) { this.subscribe_mode = ChannelSubscribeMode.INHERITED; unsubscribe = this.flag_subscribed && !this.channelTree.client.client_status.channel_subscribe_all; } else { this.subscribe_mode = ChannelSubscribeMode.UNSUBSCRIBED; unsubscribe = this.flag_subscribed; } if (unsubscribe) { if (connection) yield connection.send_command('channelunsubscribe', { 'cid': this.getChannelId() }); else this.flag_subscribed = false; for (const client of this.clients(false)) this.channelTree.deleteClient(client, false); } }); } get flag_subscribed() { return this._flag_subscribed; } set flag_subscribed(flag) { if (this._flag_subscribed == flag) return; this._flag_subscribed = flag; this.updateChannelTypeIcon(); } get subscribe_mode() { return typeof (this._subscribe_mode) !== 'undefined' ? this._subscribe_mode : (this._subscribe_mode = this.channelTree.client.settings.server(Settings.FN_SERVER_CHANNEL_SUBSCRIBE_MODE(this.channelId), ChannelSubscribeMode.INHERITED)); } set subscribe_mode(mode) { if (this.subscribe_mode == mode) return; this._subscribe_mode = mode; this.channelTree.client.settings.changeServer(Settings.FN_SERVER_CHANNEL_SUBSCRIBE_MODE(this.channelId), mode); } set flag_text_unread(flag) { this._tag_channel.find(".marker-text-unread").toggleClass("hidden", !flag); } log_data() { return { channel_name: this.channelName(), channel_id: this.channelId }; } } ChannelEntry.NAME_ALIGNMENTS = ["align-left", "align-center", "align-right", "align-repetitive"]; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3a726f47d44c83f2e45a85cc387e80ebef9b1d8512dfcad3ffb69d77002c410e"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3a726f47d44c83f2e45a85cc387e80ebef9b1d8512dfcad3ffb69d77002c410e"] = "3a726f47d44c83f2e45a85cc387e80ebef9b1d8512dfcad3ffb69d77002c410e"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "jlXiTChR", path: "D:/TeaSpeak/web/shared/js/PPTListener.ts (161,31)" }, { name: "nn_CMtx4", path: "D:/TeaSpeak/web/shared/js/PPTListener.ts (163,31)" }, { name: "ivWvObQX", path: "D:/TeaSpeak/web/shared/js/PPTListener.ts (165,31)" }, { name: "NjOPG_IO", path: "D:/TeaSpeak/web/shared/js/PPTListener.ts (167,31)" }, { name: "UUiQqGoU", path: "D:/TeaSpeak/web/shared/js/PPTListener.ts (170,20)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var KeyCode; (function (KeyCode) { KeyCode[KeyCode["KEY_CANCEL"] = 3] = "KEY_CANCEL"; KeyCode[KeyCode["KEY_HELP"] = 6] = "KEY_HELP"; KeyCode[KeyCode["KEY_BACK_SPACE"] = 8] = "KEY_BACK_SPACE"; KeyCode[KeyCode["KEY_TAB"] = 9] = "KEY_TAB"; KeyCode[KeyCode["KEY_CLEAR"] = 12] = "KEY_CLEAR"; KeyCode[KeyCode["KEY_RETURN"] = 13] = "KEY_RETURN"; KeyCode[KeyCode["KEY_ENTER"] = 14] = "KEY_ENTER"; KeyCode[KeyCode["KEY_SHIFT"] = 16] = "KEY_SHIFT"; KeyCode[KeyCode["KEY_CONTROL"] = 17] = "KEY_CONTROL"; KeyCode[KeyCode["KEY_ALT"] = 18] = "KEY_ALT"; KeyCode[KeyCode["KEY_PAUSE"] = 19] = "KEY_PAUSE"; KeyCode[KeyCode["KEY_CAPS_LOCK"] = 20] = "KEY_CAPS_LOCK"; KeyCode[KeyCode["KEY_ESCAPE"] = 27] = "KEY_ESCAPE"; KeyCode[KeyCode["KEY_SPACE"] = 32] = "KEY_SPACE"; KeyCode[KeyCode["KEY_PAGE_UP"] = 33] = "KEY_PAGE_UP"; KeyCode[KeyCode["KEY_PAGE_DOWN"] = 34] = "KEY_PAGE_DOWN"; KeyCode[KeyCode["KEY_END"] = 35] = "KEY_END"; KeyCode[KeyCode["KEY_HOME"] = 36] = "KEY_HOME"; KeyCode[KeyCode["KEY_LEFT"] = 37] = "KEY_LEFT"; KeyCode[KeyCode["KEY_UP"] = 38] = "KEY_UP"; KeyCode[KeyCode["KEY_RIGHT"] = 39] = "KEY_RIGHT"; KeyCode[KeyCode["KEY_DOWN"] = 40] = "KEY_DOWN"; KeyCode[KeyCode["KEY_PRINTSCREEN"] = 44] = "KEY_PRINTSCREEN"; KeyCode[KeyCode["KEY_INSERT"] = 45] = "KEY_INSERT"; KeyCode[KeyCode["KEY_DELETE"] = 46] = "KEY_DELETE"; KeyCode[KeyCode["KEY_0"] = 48] = "KEY_0"; KeyCode[KeyCode["KEY_1"] = 49] = "KEY_1"; KeyCode[KeyCode["KEY_2"] = 50] = "KEY_2"; KeyCode[KeyCode["KEY_3"] = 51] = "KEY_3"; KeyCode[KeyCode["KEY_4"] = 52] = "KEY_4"; KeyCode[KeyCode["KEY_5"] = 53] = "KEY_5"; KeyCode[KeyCode["KEY_6"] = 54] = "KEY_6"; KeyCode[KeyCode["KEY_7"] = 55] = "KEY_7"; KeyCode[KeyCode["KEY_8"] = 56] = "KEY_8"; KeyCode[KeyCode["KEY_9"] = 57] = "KEY_9"; KeyCode[KeyCode["KEY_SEMICOLON"] = 59] = "KEY_SEMICOLON"; KeyCode[KeyCode["KEY_EQUALS"] = 61] = "KEY_EQUALS"; KeyCode[KeyCode["KEY_A"] = 65] = "KEY_A"; KeyCode[KeyCode["KEY_B"] = 66] = "KEY_B"; KeyCode[KeyCode["KEY_C"] = 67] = "KEY_C"; KeyCode[KeyCode["KEY_D"] = 68] = "KEY_D"; KeyCode[KeyCode["KEY_E"] = 69] = "KEY_E"; KeyCode[KeyCode["KEY_F"] = 70] = "KEY_F"; KeyCode[KeyCode["KEY_G"] = 71] = "KEY_G"; KeyCode[KeyCode["KEY_H"] = 72] = "KEY_H"; KeyCode[KeyCode["KEY_I"] = 73] = "KEY_I"; KeyCode[KeyCode["KEY_J"] = 74] = "KEY_J"; KeyCode[KeyCode["KEY_K"] = 75] = "KEY_K"; KeyCode[KeyCode["KEY_L"] = 76] = "KEY_L"; KeyCode[KeyCode["KEY_M"] = 77] = "KEY_M"; KeyCode[KeyCode["KEY_N"] = 78] = "KEY_N"; KeyCode[KeyCode["KEY_O"] = 79] = "KEY_O"; KeyCode[KeyCode["KEY_P"] = 80] = "KEY_P"; KeyCode[KeyCode["KEY_Q"] = 81] = "KEY_Q"; KeyCode[KeyCode["KEY_R"] = 82] = "KEY_R"; KeyCode[KeyCode["KEY_S"] = 83] = "KEY_S"; KeyCode[KeyCode["KEY_T"] = 84] = "KEY_T"; KeyCode[KeyCode["KEY_U"] = 85] = "KEY_U"; KeyCode[KeyCode["KEY_V"] = 86] = "KEY_V"; KeyCode[KeyCode["KEY_W"] = 87] = "KEY_W"; KeyCode[KeyCode["KEY_X"] = 88] = "KEY_X"; KeyCode[KeyCode["KEY_Y"] = 89] = "KEY_Y"; KeyCode[KeyCode["KEY_Z"] = 90] = "KEY_Z"; KeyCode[KeyCode["KEY_LEFT_CMD"] = 91] = "KEY_LEFT_CMD"; KeyCode[KeyCode["KEY_RIGHT_CMD"] = 93] = "KEY_RIGHT_CMD"; KeyCode[KeyCode["KEY_CONTEXT_MENU"] = 93] = "KEY_CONTEXT_MENU"; KeyCode[KeyCode["KEY_NUMPAD0"] = 96] = "KEY_NUMPAD0"; KeyCode[KeyCode["KEY_NUMPAD1"] = 97] = "KEY_NUMPAD1"; KeyCode[KeyCode["KEY_NUMPAD2"] = 98] = "KEY_NUMPAD2"; KeyCode[KeyCode["KEY_NUMPAD3"] = 99] = "KEY_NUMPAD3"; KeyCode[KeyCode["KEY_NUMPAD4"] = 100] = "KEY_NUMPAD4"; KeyCode[KeyCode["KEY_NUMPAD5"] = 101] = "KEY_NUMPAD5"; KeyCode[KeyCode["KEY_NUMPAD6"] = 102] = "KEY_NUMPAD6"; KeyCode[KeyCode["KEY_NUMPAD7"] = 103] = "KEY_NUMPAD7"; KeyCode[KeyCode["KEY_NUMPAD8"] = 104] = "KEY_NUMPAD8"; KeyCode[KeyCode["KEY_NUMPAD9"] = 105] = "KEY_NUMPAD9"; KeyCode[KeyCode["KEY_MULTIPLY"] = 106] = "KEY_MULTIPLY"; KeyCode[KeyCode["KEY_ADD"] = 107] = "KEY_ADD"; KeyCode[KeyCode["KEY_SEPARATOR"] = 108] = "KEY_SEPARATOR"; KeyCode[KeyCode["KEY_SUBTRACT"] = 109] = "KEY_SUBTRACT"; KeyCode[KeyCode["KEY_DECIMAL"] = 110] = "KEY_DECIMAL"; KeyCode[KeyCode["KEY_DIVIDE"] = 111] = "KEY_DIVIDE"; KeyCode[KeyCode["KEY_F1"] = 112] = "KEY_F1"; KeyCode[KeyCode["KEY_F2"] = 113] = "KEY_F2"; KeyCode[KeyCode["KEY_F3"] = 114] = "KEY_F3"; KeyCode[KeyCode["KEY_F4"] = 115] = "KEY_F4"; KeyCode[KeyCode["KEY_F5"] = 116] = "KEY_F5"; KeyCode[KeyCode["KEY_F6"] = 117] = "KEY_F6"; KeyCode[KeyCode["KEY_F7"] = 118] = "KEY_F7"; KeyCode[KeyCode["KEY_F8"] = 119] = "KEY_F8"; KeyCode[KeyCode["KEY_F9"] = 120] = "KEY_F9"; KeyCode[KeyCode["KEY_F10"] = 121] = "KEY_F10"; KeyCode[KeyCode["KEY_F11"] = 122] = "KEY_F11"; KeyCode[KeyCode["KEY_F12"] = 123] = "KEY_F12"; KeyCode[KeyCode["KEY_F13"] = 124] = "KEY_F13"; KeyCode[KeyCode["KEY_F14"] = 125] = "KEY_F14"; KeyCode[KeyCode["KEY_F15"] = 126] = "KEY_F15"; KeyCode[KeyCode["KEY_F16"] = 127] = "KEY_F16"; KeyCode[KeyCode["KEY_F17"] = 128] = "KEY_F17"; KeyCode[KeyCode["KEY_F18"] = 129] = "KEY_F18"; KeyCode[KeyCode["KEY_F19"] = 130] = "KEY_F19"; KeyCode[KeyCode["KEY_F20"] = 131] = "KEY_F20"; KeyCode[KeyCode["KEY_F21"] = 132] = "KEY_F21"; KeyCode[KeyCode["KEY_F22"] = 133] = "KEY_F22"; KeyCode[KeyCode["KEY_F23"] = 134] = "KEY_F23"; KeyCode[KeyCode["KEY_F24"] = 135] = "KEY_F24"; KeyCode[KeyCode["KEY_NUM_LOCK"] = 144] = "KEY_NUM_LOCK"; KeyCode[KeyCode["KEY_SCROLL_LOCK"] = 145] = "KEY_SCROLL_LOCK"; KeyCode[KeyCode["KEY_COMMA"] = 188] = "KEY_COMMA"; KeyCode[KeyCode["KEY_PERIOD"] = 190] = "KEY_PERIOD"; KeyCode[KeyCode["KEY_SLASH"] = 191] = "KEY_SLASH"; KeyCode[KeyCode["KEY_BACK_QUOTE"] = 192] = "KEY_BACK_QUOTE"; KeyCode[KeyCode["KEY_OPEN_BRACKET"] = 219] = "KEY_OPEN_BRACKET"; KeyCode[KeyCode["KEY_BACK_SLASH"] = 220] = "KEY_BACK_SLASH"; KeyCode[KeyCode["KEY_CLOSE_BRACKET"] = 221] = "KEY_CLOSE_BRACKET"; KeyCode[KeyCode["KEY_QUOTE"] = 222] = "KEY_QUOTE"; KeyCode[KeyCode["KEY_META"] = 224] = "KEY_META"; })(KeyCode || (KeyCode = {})); var ppt; (function (ppt) { let EventType; (function (EventType) { EventType[EventType["KEY_PRESS"] = 0] = "KEY_PRESS"; EventType[EventType["KEY_RELEASE"] = 1] = "KEY_RELEASE"; EventType[EventType["KEY_TYPED"] = 2] = "KEY_TYPED"; })(EventType = ppt.EventType || (ppt.EventType = {})); let SpecialKey; (function (SpecialKey) { SpecialKey[SpecialKey["CTRL"] = 0] = "CTRL"; SpecialKey[SpecialKey["WINDOWS"] = 1] = "WINDOWS"; SpecialKey[SpecialKey["SHIFT"] = 2] = "SHIFT"; SpecialKey[SpecialKey["ALT"] = 3] = "ALT"; })(SpecialKey = ppt.SpecialKey || (ppt.SpecialKey = {})); function key_description(key) { let result = ""; if (key.key_shift) result += " + " + (_translations.jlXiTChR || (_translations.jlXiTChR = tr("Shift"))); if (key.key_alt) result += " + " + (_translations.nn_CMtx4 || (_translations.nn_CMtx4 = tr("Alt"))); if (key.key_ctrl) result += " + " + (_translations.ivWvObQX || (_translations.ivWvObQX = tr("CTRL"))); if (key.key_windows) result += " + " + (_translations.NjOPG_IO || (_translations.NjOPG_IO = tr("Win"))); if (!result && !key.key_code) return _translations.UUiQqGoU || (_translations.UUiQqGoU = tr("unset")); if (key.key_code) result += " + " + key.key_code; return result.substr(3); } ppt.key_description = key_description; })(ppt || (ppt = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e85c12b4ba32fa88e1cf62cff6c27ebb393473443cb8a69f01892fe496e32840"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e85c12b4ba32fa88e1cf62cff6c27ebb393473443cb8a69f01892fe496e32840"] = "e85c12b4ba32fa88e1cf62cff6c27ebb393473443cb8a69f01892fe496e32840"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var ElementType; (function (ElementType) { ElementType[ElementType["HEADER"] = 0] = "HEADER"; ElementType[ElementType["BODY"] = 1] = "BODY"; ElementType[ElementType["FOOTER"] = 2] = "FOOTER"; })(ElementType || (ElementType = {})); const ModalFunctions = { divify: function (val) { if (val.length > 1) return $.spawn("div").append(val); return val; }, jqueriefy: function (val, type) { if (typeof (val) === "function") val = val(); if (val instanceof jQuery) return val; if (Array.isArray(val)) { if (val.length == 0) return undefined; return val.map(e => this.jqueriefy(e)); } switch (typeof val) { case "string": if (type == ElementType.HEADER) return $.spawn("div").addClass("modal-title").text(val); return $("
" + val + "
"); case "object": return val; case "undefined": return undefined; default: console.error(("Invalid type %o"), typeof val); return $(); } }, warpProperties(data) { if (data instanceof ModalProperties) { return data; } else { const props = new ModalProperties(); for (const key of Object.keys(data)) props[key] = data[key]; return props; } } }; class ModalProperties { constructor() { this.header = () => "HEADER"; this.body = () => "BODY"; this.footer = () => "FOOTER"; this.closeListener = () => { }; this.height = "auto"; this.closeable = true; this.template_properties = {}; this.trigger_tab = true; this.full_size = false; } registerCloseListener(listener) { if (this.closeListener) { if ($.isArray(this.closeListener)) this.closeListener.push(listener); else this.closeListener = [this.closeListener, listener]; } else this.closeListener = listener; return this; } triggerClose() { if ($.isArray(this.closeListener)) for (let listener of this.closeListener) listener(); else this.closeListener(); } } var modal; (function (modal) { function initialize_modals() { register_global_events(); } modal.initialize_modals = initialize_modals; const scrollSize = 18; function scroll_bar_clicked(event) { const x = event.pageX, y = event.pageY, e = $(event.target); if (e.hasScrollBar("height")) { const top = e.offset().top; const right = e.offset().left + e.width(); const bottom = top + e.height(); const left = right - scrollSize; if ((y >= top && y <= bottom) && (x >= left && x <= right)) return true; } if (e.hasScrollBar("width")) { const bottom = e.offset().top + e.height(); const top = bottom - scrollSize; const left = e.offset().left; const right = left + e.width(); if ((y >= top && y <= bottom) && (x >= left && x <= right)) return true; } return false; } function register_global_events() { $(document).on('mousedown', (event) => { /* pageX or pageY are undefined if this is an event executed via .trigger('click'); */ if (_global_modal_count == 0 || typeof (event.pageX) === "undefined" || typeof (event.pageY) === "undefined") return; let element = event.target; const original = element; do { if (element.classList.contains('modal-content')) break; if (!element.classList.contains('modal')) continue; if (element == _global_modal_last && _global_modal_last_time + 100 > Date.now()) break; if (element === original && scroll_bar_clicked(event)) { _global_modal_last_time = Date.now(); break; } $(element).find("> .modal-dialog > .modal-content > .modal-header .button-modal-close").trigger('click'); break; } while ((element = element.parentElement)); }); $(document).on('keyup', (event) => { if (_global_modal_count == 0 || typeof (event.target) === "undefined") return; if (event.key !== "Escape") return; let element = event.target; if (element.nodeName == "HTMLInputElement" || element.nodeName == "HTMLSelectElement" || element.nodeName == "HTMLTextAreaElement") return; do { if (element.classList.contains('modal-content')) break; if (!element.classList.contains('modal')) continue; if (element == _global_modal_last && _global_modal_last_time + 100 > Date.now()) break; $(element).find("> .modal-dialog > .modal-content > .modal-header .button-modal-close").trigger('click'); break; } while ((element = element.parentElement)); }); } })(modal || (modal = {})); modal.initialize_modals(); let _global_modal_count = 0; let _global_modal_last; let _global_modal_last_time; class Modal { constructor(props) { this.open_listener = []; this.close_listener = []; this.properties = props; this.shown = false; } get htmlTag() { if (!this._htmlTag) this._create(); return this._htmlTag; } _create() { const header = ModalFunctions.jqueriefy(this.properties.header, ElementType.HEADER); const body = ModalFunctions.jqueriefy(this.properties.body, ElementType.BODY); const footer = ModalFunctions.jqueriefy(this.properties.footer, ElementType.FOOTER); //FIXME: cache template const template = $(this.properties.template || "#tmpl_modal"); const properties = { modal_header: header, modal_body: body, modal_footer: footer, closeable: this.properties.closeable, full_size: this.properties.full_size }; if (this.properties.template_properties) Object.assign(properties, this.properties.template_properties); const tag = template.renderTag(properties); if (typeof (this.properties.width) !== "undefined" && typeof (this.properties.min_width) !== "undefined") tag.find(".modal-content") .css("min-width", this.properties.min_width) .css("width", this.properties.width); else if (typeof (this.properties.width) !== "undefined") //Legacy support tag.find(".modal-content").css("min-width", this.properties.width); else if (typeof (this.properties.min_width) !== "undefined") tag.find(".modal-content").css("min-width", this.properties.min_width); this.close_elements = tag.find(".button-modal-close"); this.close_elements.toggle(this.properties.closeable).on('click', event => { if (this.properties.closeable) this.close(); }); this._htmlTag = tag; this._htmlTag.find("input").on('change', event => { $(event.target).parents(".form-group").toggleClass('is-filled', !!event.target.value); }); //TODO: After the animation! this._htmlTag.on('hide.bs.modal', event => !this.properties.closeable || this.close()); this._htmlTag.on('hidden.bs.modal', event => this._htmlTag.remove()); } open() { if (this.shown) return; _global_modal_last_time = Date.now(); _global_modal_last = this.htmlTag[0]; this.shown = true; this.htmlTag.appendTo($("body")); _global_modal_count++; this.htmlTag.show(); setTimeout(() => this.htmlTag.addClass('shown'), 0); setTimeout(() => { for (const listener of this.open_listener) listener(); this.htmlTag.find(".tab").trigger('tab.resize'); }, 300); } close() { if (!this.shown) return; _global_modal_count--; if (_global_modal_last === this.htmlTag[0]) _global_modal_last = undefined; this.shown = false; this.htmlTag.removeClass('shown'); setTimeout(() => { this.htmlTag.remove(); this._htmlTag = undefined; }, 300); this.properties.triggerClose(); for (const listener of this.close_listener) listener(); } set_closeable(flag) { if (flag === this.properties.closeable) return; this.properties.closeable = flag; this.close_elements.toggle(flag); } } function createModal(data) { return new Modal(ModalFunctions.warpProperties(data)); } class InputModalProperties extends ModalProperties { } function createInputModal(headMessage, question, validator, callback, props = {}) { props = ModalFunctions.warpProperties(props); props.template_properties || (props.template_properties = {}); props.template_properties.field_title = props.field_title; props.template_properties.field_label = props.field_label; props.template_properties.field_placeholder = props.field_placeholder; props.template_properties.error_message = props.error_message; props.template = "#tmpl_modal_input"; props.header = headMessage; props.template_properties.question = ModalFunctions.jqueriefy(question); const modal = createModal(props); const input = modal.htmlTag.find(".container-value input"); const button_cancel = modal.htmlTag.find(".button-cancel"); const button_submit = modal.htmlTag.find(".button-submit"); let submited = false; input.on('keyup change', event => { const str = input.val(); const valid = str !== undefined && validator(str); input.attr("pattern", valid ? null : "^[a]{1000}$").toggleClass("is-invalid", !valid); button_submit.prop("disabled", !valid); }); input.on('keydown', event => { if (event.keyCode !== KeyCode.KEY_RETURN || event.shiftKey) return; if (button_submit.prop("disabled")) return; button_submit.trigger('click'); }); button_submit.on('click', event => { if (!submited) { submited = true; const str = input.val(); if (str !== undefined && validator(str)) callback(str); else callback(false); } modal.close(); }).prop("disabled", !validator("")); /* disabled if empty input isn't allowed */ button_cancel.on('click', event => { if (!submited) { submited = true; callback(false); } modal.close(); }); modal.open_listener.push(() => input.focus()); modal.close_listener.push(() => button_cancel.trigger('click')); return modal; } function createErrorModal(header, message, props = { footer: undefined }) { props = ModalFunctions.warpProperties(props); (props.template_properties || (props.template_properties = {})).header_class = "modal-header-error"; props.header = header; props.body = message; const modal = createModal(props); modal.htmlTag.find(".modal-body").addClass("modal-error"); return modal; } function createInfoModal(header, message, props = { footer: undefined }) { props = ModalFunctions.warpProperties(props); (props.template_properties || (props.template_properties = {})).header_class = "modal-header-info"; props.header = header; props.body = message; const modal = createModal(props); modal.htmlTag.find(".modal-body").addClass("modal-info"); return modal; } $.fn.modalize = function (entry_callback, properties) { properties = properties || {}; entry_callback = entry_callback || ((a, b, c) => undefined); let tag_modal = this[0].tagName.toLowerCase() == "modal" ? this : undefined; /* TODO may throw exception? */ let tag_head = tag_modal ? tag_modal.find("modal-header") : ModalFunctions.jqueriefy(properties.header); let tag_body = tag_modal ? tag_modal.find("modal-body") : this; let tag_footer = tag_modal ? tag_modal.find("modal-footer") : ModalFunctions.jqueriefy(properties.footer); const result = entry_callback(tag_head, tag_body, tag_footer) || {}; properties.header = result.header || tag_head; properties.body = result.body || tag_body; properties.footer = result.footer || tag_footer; return createModal(properties); }; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["daf6447bfb4db78245da21e8a415df1fbffd01dea2eead594ce099db160614b4"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["daf6447bfb4db78245da21e8a415df1fbffd01dea2eead594ce099db160614b4"] = "daf6447bfb4db78245da21e8a415df1fbffd01dea2eead594ce099db160614b4"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "WyjTP88B", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChangeVolume.ts (14,29)" }, { name: "Ajoev9cN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChangeVolume.ts (14,57)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { //TODO: Use the max limit! let modal; function spawnChangeVolume(client, local, current, max, callback) { if (modal) modal.close(); let new_value; modal = createModal({ header: local ? _translations.WyjTP88B || (_translations.WyjTP88B = tr("Change local volume")) : _translations.Ajoev9cN || (_translations.Ajoev9cN = tr("Change remote volume")), body: function () { let tag = $("#tmpl_change_volume").renderTag({ client: htmltags.generate_client_object({ add_braces: false, client_name: client.clientNickName(), client_unique_id: client.properties.client_unique_identifier, client_id: client.clientId() }), local: local }); const container_value = tag.find(".info .value"); const set_value = value => { const number = value > 100 ? value - 100 : 100 - value; container_value.html((value == 100 ? "±" : value > 100 ? "+" : "-") + number + "%"); new_value = value / 100; if (local) callback(new_value); }; set_value(current * 100); const slider_tag = tag.find(".container-slider"); const slider = sliderfy(slider_tag, { initial_value: current * 100, step: 1, max_value: 200, min_value: 0, unit: '%' }); slider_tag.on('change', event => set_value(parseInt(slider_tag.attr("value")))); tag.find(".button-save").on('click', event => { if (typeof (new_value) !== "undefined") callback(new_value); modal.close(); }); tag.find(".button-cancel").on('click', event => { callback(current); modal.close(); }); tag.find(".button-reset").on('click', event => { slider.value(100); }); tag.find(".button-apply").on('click', event => { callback(new_value); new_value = undefined; }); return tag.children(); }, footer: null, width: 600 }); modal.close_listener.push(() => modal = undefined); modal.open(); modal.htmlTag.find(".modal-body").addClass("modal-volume"); } Modals.spawnChangeVolume = spawnChangeVolume; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["8826f72b6f1d2cf9a2064e176a47bf3754cd63eaf3c1a19fc6ed100e765e2fe8"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["8826f72b6f1d2cf9a2064e176a47bf3754cd63eaf3c1a19fc6ed100e765e2fe8"] = "8826f72b6f1d2cf9a2064e176a47bf3754cd63eaf3c1a19fc6ed100e765e2fe8"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "KEIZ2p_a", path: "D:/TeaSpeak/web/shared/js/ui/client_move.ts (53,40)" }, { name: "crLZ2vSF", path: "D:/TeaSpeak/web/shared/js/ui/client_move.ts (115,40)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// class ClientMover { constructor(tree) { this.enabled = true; this._active = false; this.origin_point = undefined; this.channel_tree = tree; } is_active() { return this._active; } hover_text() { if ($.isArray(this.selected_client)) { return this.selected_client.filter(client => !!client).map(client => client.clientNickName()).join(", "); } else if (this.selected_client) { return this.selected_client.clientNickName(); } else return ""; } bbcode_text() { if ($.isArray(this.selected_client)) { return this.selected_client.filter(client => !!client).map(client => client.create_bbcode()).join(", "); } else if (this.selected_client) { return this.selected_client.create_bbcode(); } else return ""; } activate(client, callback, event) { this.finish_listener(undefined); if (!this.enabled) return false; this.selected_client = client; this.callback = callback; log.debug(LogCategory.GENERAL, _translations.KEIZ2p_a || (_translations.KEIZ2p_a = tr("Starting mouse move"))); ClientMover.listener_root.on('mouseup', this._bound_finish = this.finish_listener.bind(this)).on('mousemove', this._bound_move = this.move_listener.bind(this)); { const content = ClientMover.move_element.find(".container"); content.empty(); content.append($.spawn("a").text(this.hover_text())); } this.move_listener(event); } move_listener(event) { if (!this.enabled) return; //console.log("Mouse move: " + event.pageX + " - " + event.pageY); if (!event.pageX || !event.pageY) return; if (!this.origin_point) this.origin_point = { x: event.pageX, y: event.pageY }; ClientMover.move_element.css({ "top": (event.pageY - 1) + "px", "left": (event.pageX + 10) + "px" }); if (!this._active) { const d_x = this.origin_point.x - event.pageX; const d_y = this.origin_point.y - event.pageY; this._active = Math.sqrt(d_x * d_x + d_y * d_y) > 5 * 5; if (this._active) { if ($.isArray(this.selected_client)) { this.channel_tree.onSelect(this.selected_client[0], true); for (const client of this.selected_client.slice(1)) this.channel_tree.onSelect(client, false, true); } else { this.channel_tree.onSelect(this.selected_client, true); } ClientMover.move_element.show(); } } const elements = document.elementsFromPoint(event.pageX, event.pageY); while (elements.length > 0) { if (elements[0].classList.contains("container-channel")) break; elements.pop_front(); } if (this.hovered_channel) { this.hovered_channel.classList.remove("move-selected"); this.hovered_channel = undefined; } if (elements.length > 0) { elements[0].classList.add("move-selected"); this.hovered_channel = elements[0]; } } finish_listener(event) { ClientMover.move_element.hide(); log.debug(LogCategory.GENERAL, _translations.crLZ2vSF || (_translations.crLZ2vSF = tr("Finishing mouse move"))); const channel_id = this.hovered_channel ? parseInt(this.hovered_channel.getAttribute("channel-id")) : 0; ClientMover.listener_root.unbind('mouseleave', this._bound_finish); ClientMover.listener_root.unbind('mouseup', this._bound_finish); ClientMover.listener_root.unbind('mousemove', this._bound_move); if (this.hovered_channel) { this.hovered_channel.classList.remove("move-selected"); this.hovered_channel = undefined; } this.origin_point = undefined; if (!this._active) { this.selected_client = undefined; this.callback = undefined; return; } this._active = false; if (this.callback) { if (!channel_id) this.callback(undefined); else { this.callback(this.channel_tree.findChannel(channel_id)); } this.callback = undefined; } /* test for the chat box */ { const elements = document.elementsFromPoint(event.pageX, event.pageY); console.error(elements); while (elements.length > 0) { if (elements[0].classList.contains("client-chat-box-field")) break; elements.pop_front(); } if (elements.length > 0) { const element = $(elements[0]); element.val((element.val() || "") + this.bbcode_text()); } } } deactivate() { this.callback = undefined; this.finish_listener(undefined); } } ClientMover.listener_root = $(document); ClientMover.move_element = $("#mouse-move"); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["4246282d77c925162d2c06841ca915232cba6ac6d2a1d1085c05fb0ff54920bb"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["4246282d77c925162d2c06841ca915232cba6ac6d2a1d1085c05fb0ff54920bb"] = "4246282d77c925162d2c06841ca915232cba6ac6d2a1d1085c05fb0ff54920bb"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "imtMC86F", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (154,41)" }, { name: "aVeKeOqo", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (158,45)" }, { name: "SkYDkDbr", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (174,45)" }, { name: "K9iUYVHs", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (323,87)" }, { name: "MKsTvtiO", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (323,109)" }, { name: "sKUcAWYo", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (394,19)" }, { name: "NkRVbrEL", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (408,19)" }, { name: "DQmH806h", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (415,19)" }, { name: "FBafbYH1", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (420,27)" }, { name: "QONLfGGw", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (426,27)" }, { name: "XQqk0hQm", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (482,25)" }, { name: "Wamj6lZp", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (492,23)" }, { name: "NAP7iNGX", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (499,23)" }, { name: "wle1DPL6", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (501,38)" }, { name: "IhKp1U6b", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (501,57)" }, { name: "wfJ0cnuF", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (516,23)" }, { name: "SkDvmbF4", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (518,38)" }, { name: "UUmz0RUR", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (518,71)" }, { name: "IqCkK5LB", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (536,23)" }, { name: "mgE4Z1Js", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (546,23)" }, { name: "Gj78RvOz", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (548,38)" }, { name: "xhyckLyH", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (548,70)" }, { name: "ZCjZNTae", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (564,23)" }, { name: "PXTiLlh1", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (566,38)" }, { name: "U9VbSk_j", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (566,69)" }, { name: "t1_5DwD9", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (582,23)" }, { name: "_SOYYOpq", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (623,23)" }, { name: "LGRXJbyk", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (636,23)" }, { name: "HXDWIypp", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (649,23)" }, { name: "qPADwJeS", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (655,23)" }, { name: "mwXcnRVj", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (820,70)" }, { name: "BwKYcCsM", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (891,47)" }, { name: "TWJRawAz", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1143,25)" }, { name: "QXkvf75y", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1149,23)" }, { name: "eo0BTEUD", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1152,38)" }, { name: "cGSxzOs8", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1152,68)" }, { name: "KltoFGs6", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1154,41)" }, { name: "XbLxNlO8", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1319,23)" }, { name: "pmicCstj", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1324,38)" }, { name: "vqukZhk9", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1324,72)" }, { name: "KwxFZl6L", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1336,23)" }, { name: "mYzzfhcQ", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1340,38)" }, { name: "ZTCZj4qo", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1340,75)" }, { name: "JLASYUDm", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1362,23)" }, { name: "ecR9BnOb", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1373,42)" }, { name: "bjVFcLvv", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1373,69)" }, { name: "cCQHXsEN", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1375,42)" }, { name: "z0TAFloZ", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1375,75)" }, { name: "v3a_2VKL", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1381,23)" }, { name: "qP0cnomf", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1385,38)" }, { name: "yQiADIEs", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1385,66)" }, { name: "LAv5uiVz", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1396,50)" }, { name: "y7NwSbFu", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1408,23)" }, { name: "l4FBtA8t", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1418,23)" }, { name: "I7AyThLI", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1420,38)" }, { name: "Xd1D_Zzu", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1420,70)" }, { name: "mWrcl55N", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1422,41)" }, { name: "GjpMhrnj", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1436,23)" }, { name: "xbWCjjmW", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1447,23)" }, { name: "eRh0JpMP", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1468,23)" }, { name: "J7K_FqfX", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1481,23)" }, { name: "RjNsfIH5", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1485,83)" }, { name: "UryMTw7o", path: "D:/TeaSpeak/web/shared/js/ui/client.ts (1486,39)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var ClientType; (function (ClientType) { ClientType[ClientType["CLIENT_VOICE"] = 0] = "CLIENT_VOICE"; ClientType[ClientType["CLIENT_QUERY"] = 1] = "CLIENT_QUERY"; ClientType[ClientType["CLIENT_INTERNAL"] = 2] = "CLIENT_INTERNAL"; ClientType[ClientType["CLIENT_WEB"] = 3] = "CLIENT_WEB"; ClientType[ClientType["CLIENT_MUSIC"] = 4] = "CLIENT_MUSIC"; ClientType[ClientType["CLIENT_UNDEFINED"] = 5] = "CLIENT_UNDEFINED"; })(ClientType || (ClientType = {})); class ClientProperties { constructor() { this.client_type = ClientType.CLIENT_VOICE; //TeamSpeaks type this.client_type_exact = ClientType.CLIENT_VOICE; this.client_database_id = 0; 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_created = 0; this.client_totalconnections = 0; this.client_flag_avatar = ""; this.client_icon_id = 0; this.client_away_message = ""; this.client_away = false; this.client_country = ""; this.client_input_hardware = false; this.client_output_hardware = false; this.client_input_muted = false; this.client_output_muted = false; this.client_is_channel_commander = false; this.client_teaforo_id = 0; this.client_teaforo_name = ""; this.client_teaforo_flags = 0; /* 0x01 := Banned | 0x02 := Stuff | 0x04 := Premium */ /* not updated in view! */ this.client_month_bytes_uploaded = 0; this.client_month_bytes_downloaded = 0; this.client_total_bytes_uploaded = 0; this.client_total_bytes_downloaded = 0; this.client_talk_power = 0; this.client_is_priority_speaker = false; } } class ClientConnectionInfo { constructor() { this.connection_bandwidth_received_last_minute_control = -1; this.connection_bandwidth_received_last_minute_keepalive = -1; this.connection_bandwidth_received_last_minute_speech = -1; this.connection_bandwidth_received_last_second_control = -1; this.connection_bandwidth_received_last_second_keepalive = -1; this.connection_bandwidth_received_last_second_speech = -1; this.connection_bandwidth_sent_last_minute_control = -1; this.connection_bandwidth_sent_last_minute_keepalive = -1; this.connection_bandwidth_sent_last_minute_speech = -1; this.connection_bandwidth_sent_last_second_control = -1; this.connection_bandwidth_sent_last_second_keepalive = -1; this.connection_bandwidth_sent_last_second_speech = -1; this.connection_bytes_received_control = -1; this.connection_bytes_received_keepalive = -1; this.connection_bytes_received_speech = -1; this.connection_bytes_sent_control = -1; this.connection_bytes_sent_keepalive = -1; this.connection_bytes_sent_speech = -1; this.connection_packets_received_control = -1; this.connection_packets_received_keepalive = -1; this.connection_packets_received_speech = -1; this.connection_packets_sent_control = -1; this.connection_packets_sent_keepalive = -1; this.connection_packets_sent_speech = -1; this.connection_ping = -1; this.connection_ping_deviation = -1; this.connection_server2client_packetloss_control = -1; this.connection_server2client_packetloss_keepalive = -1; this.connection_server2client_packetloss_speech = -1; this.connection_server2client_packetloss_total = -1; this.connection_client2server_packetloss_speech = -1; this.connection_client2server_packetloss_keepalive = -1; this.connection_client2server_packetloss_control = -1; this.connection_client2server_packetloss_total = -1; this.connection_filetransfer_bandwidth_sent = -1; this.connection_filetransfer_bandwidth_received = -1; this.connection_connected_time = -1; this.connection_idle_time = -1; this.connection_client_port = -1; } } class ClientEntry { constructor(clientId, clientName, properties = new ClientProperties()) { this.lastVariableUpdate = 0; this.events = new events.Registry(); this._properties = properties; this._properties.client_nickname = clientName; this._clientId = clientId; this.channelTree = null; this._channel = null; } destroy() { if (this._tag) { this._tag.remove(); this._tag = undefined; } if (this._audio_handle) { log.warn(LogCategory.AUDIO, _translations.imtMC86F || (_translations.imtMC86F = tr("Destroying client with an active audio handle. This could cause memory leaks!"))); try { this._audio_handle.abort_replay(); } catch (error) { log.warn(LogCategory.AUDIO, _translations.aVeKeOqo || (_translations.aVeKeOqo = tr("Failed to abort replay: %o")), error); } this._audio_handle.callback_playback = undefined; this._audio_handle.callback_stopped = undefined; this._audio_handle = undefined; } this._channel = undefined; } tree_unregistered() { this.channelTree = undefined; if (this._audio_handle) { try { this._audio_handle.abort_replay(); } catch (error) { log.warn(LogCategory.AUDIO, _translations.SkYDkDbr || (_translations.SkYDkDbr = tr("Failed to abort replay: %o")), error); } this._audio_handle.callback_playback = undefined; this._audio_handle.callback_stopped = undefined; this._audio_handle = undefined; } this._channel = undefined; } set_audio_handle(handle) { if (this._audio_handle === handle) return; if (this._audio_handle) { this._audio_handle.callback_playback = undefined; this._audio_handle.callback_stopped = undefined; } //TODO may ensure that the id is the same? this._audio_handle = handle; if (!handle) { this.speaking = false; return; } handle.callback_playback = () => this.speaking = true; handle.callback_stopped = () => this.speaking = false; } get_audio_handle() { return this._audio_handle; } get properties() { return this._properties; } currentChannel() { return this._channel; } clientNickName() { return this.properties.client_nickname; } clientUid() { return this.properties.client_unique_identifier; } clientId() { return this._clientId; } is_muted() { return !!this._audio_muted; } set_muted(flag, update_icon, force) { if (this._audio_muted === flag && !force) return; if (flag) { this.channelTree.client.serverConnection.send_command('clientmute', { clid: this.clientId() }); } else if (this._audio_muted) { this.channelTree.client.serverConnection.send_command('clientunmute', { clid: this.clientId() }); } this._audio_muted = flag; this.channelTree.client.settings.changeServer("mute_client_" + this.clientUid(), flag); if (this._audio_handle) { if (flag) { this._audio_handle.set_volume(0); } else { this._audio_handle.set_volume(this._audio_volume); } } if (update_icon) this.updateClientSpeakIcon(); for (const client of this.channelTree.clients) { if (client === this || client.properties.client_unique_identifier != this.properties.client_unique_identifier) continue; client.set_muted(flag, true); } } initializeListener() { if (this._listener_initialized) return; this._listener_initialized = true; this.tag.on('mouseup', event => { if (!this.channelTree.client_mover.is_active()) { this.channelTree.onSelect(this); } }); if (!(this instanceof LocalClientEntry) && !(this instanceof MusicClientEntry)) this.tag.dblclick(event => { if ($.isArray(this.channelTree.currently_selected)) { //Multiselect return; } this.open_text_chat(); }); if (!settings.static(Settings.KEY_DISABLE_CONTEXT_MENU, false)) { this.tag.on("contextmenu", (event) => { event.preventDefault(); if ($.isArray(this.channelTree.currently_selected)) { //Multiselect (this.channelTree.currently_selected_context_callback || ((_) => null))(event); return; } this.channelTree.onSelect(this, true); this.showContextMenu(event.pageX, event.pageY, () => { }); return false; }); } this.tag.on('mousedown', event => { if (event.which != 1) return; //Only the left button let clients = this.channelTree.currently_selected; if (ppt.key_pressed(ppt.SpecialKey.SHIFT)) { if (clients != this && !($.isArray(clients) && clients.indexOf(this) != -1)) clients = $.isArray(clients) ? [...clients, this] : [clients, this]; } else { clients = this; } this.channelTree.client_mover.activate(clients, target => { if (!target) return; for (const client of $.isArray(clients) ? clients : [clients]) { if (target == client._channel) continue; const source = client._channel; const self = this.channelTree.client.getClient(); this.channelTree.client.serverConnection.send_command("clientmove", { clid: client.clientId(), cid: target.getChannelId() }).then(event => { if (client.clientId() == this.channelTree.client.clientId) this.channelTree.client.sound.play(Sound.CHANNEL_JOINED); else if (target !== source && target != self.currentChannel()) this.channelTree.client.sound.play(Sound.USER_MOVED); }); } this.channelTree.onSelect(); }, event); }); } contextmenu_info() { return [ { type: contextmenu.MenuEntryType.ENTRY, name: this.properties.client_type_exact === ClientType.CLIENT_MUSIC ? _translations.K9iUYVHs || (_translations.K9iUYVHs = tr("Show bot info")) : _translations.MKsTvtiO || (_translations.MKsTvtiO = tr("Show client info")), callback: () => { this.channelTree.client.side_bar.show_client_info(this); }, icon_class: "client-about", visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CLIENT) }, { callback: () => { }, type: contextmenu.MenuEntryType.HR, name: "", visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CLIENT) } ]; } assignment_context() { let server_groups = []; for (let group of this.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) { if (group.type != GroupType.NORMAL) continue; let entry = {}; //TODO: May add the server group icon? entry.checkbox_checked = this.groupAssigned(group); entry.name = group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]"; if (this.groupAssigned(group)) { entry.callback = () => { this.channelTree.client.serverConnection.send_command("servergroupdelclient", { sgid: group.id, cldbid: this.properties.client_database_id }); }; entry.disabled = !this.channelTree.client.permissions.neededPermission(PermissionType.I_GROUP_MEMBER_ADD_POWER).granted(group.requiredMemberRemovePower); } else { entry.callback = () => { this.channelTree.client.serverConnection.send_command("servergroupaddclient", { sgid: group.id, cldbid: this.properties.client_database_id }); }; entry.disabled = !this.channelTree.client.permissions.neededPermission(PermissionType.I_GROUP_MEMBER_REMOVE_POWER).granted(group.requiredMemberAddPower); } entry.type = contextmenu.MenuEntryType.CHECKBOX; server_groups.push(entry); } let channel_groups = []; for (let group of this.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) { if (group.type != GroupType.NORMAL) continue; let entry = {}; //TODO: May add the channel group icon? entry.checkbox_checked = this.assignedChannelGroup() == group.id; entry.name = group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]"; entry.callback = () => { this.channelTree.client.serverConnection.send_command("setclientchannelgroup", { cldbid: this.properties.client_database_id, cgid: group.id, cid: this.currentChannel().channelId }); }; entry.disabled = !this.channelTree.client.permissions.neededPermission(PermissionType.I_GROUP_MEMBER_ADD_POWER).granted(group.requiredMemberRemovePower); entry.type = contextmenu.MenuEntryType.CHECKBOX; channel_groups.push(entry); } return [{ type: contextmenu.MenuEntryType.SUB_MENU, icon_class: "client-permission_server_groups", name: _translations.sKUcAWYo || (_translations.sKUcAWYo = tr("Set server group")), sub_menu: [ { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-permission_server_groups", name: "Server groups dialog", callback: () => this.open_assignment_modal() }, contextmenu.Entry.HR(), ...server_groups ] }, { type: contextmenu.MenuEntryType.SUB_MENU, icon_class: "client-permission_channel", name: _translations.NkRVbrEL || (_translations.NkRVbrEL = tr("Set channel group")), sub_menu: [ ...channel_groups ] }, { type: contextmenu.MenuEntryType.SUB_MENU, icon_class: "client-permission_client", name: _translations.DQmH806h || (_translations.DQmH806h = tr("Permissions")), sub_menu: [ { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-permission_client", name: _translations.FBafbYH1 || (_translations.FBafbYH1 = tr("Client permissions")), callback: () => Modals.spawnPermissionEdit(this.channelTree.client, "clp", { unique_id: this.clientUid() }).open() }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-permission_client", name: _translations.QONLfGGw || (_translations.QONLfGGw = tr("Client channel permissions")), callback: () => Modals.spawnPermissionEdit(this.channelTree.client, "clchp", { unique_id: this.clientUid(), channel_id: this._channel ? this._channel.channelId : undefined }).open() } ] }]; } open_assignment_modal() { Modals.createServerGroupAssignmentModal(this, (groups, flag) => { if (groups.length == 0) return Promise.resolve(true); if (groups.length == 1) { if (flag) { return this.channelTree.client.serverConnection.send_command("servergroupaddclient", { sgid: groups[0], cldbid: this.properties.client_database_id }).then(result => true); } else return this.channelTree.client.serverConnection.send_command("servergroupdelclient", { sgid: groups[0], cldbid: this.properties.client_database_id }).then(result => true); } else { const data = groups.map(e => { return { sgid: e }; }); data[0]["cldbid"] = this.properties.client_database_id; if (flag) { return this.channelTree.client.serverConnection.send_command("clientaddservergroup", data, { flagset: ["continueonerror"] }).then(result => true); } else return this.channelTree.client.serverConnection.send_command("clientdelservergroup", data, { flagset: ["continueonerror"] }).then(result => true); } }); } open_text_chat() { const chat = this.channelTree.client.side_bar; const conversation = chat.private_conversations().find_conversation({ name: this.clientNickName(), client_id: this.clientId(), unique_id: this.clientUid() }, { attach: true, create: true }); chat.private_conversations().set_selected_conversation(conversation); chat.show_private_conversations(); chat.private_conversations().try_input_focus(); } showContextMenu(x, y, on_close = undefined) { let trigger_close = true; contextmenu.spawn_context_menu(x, y, ...this.contextmenu_info(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-change_nickname", name: (contextmenu.get_provider().html_format_enabled() ? "" : "") + (_translations.XQqk0hQm || (_translations.XQqk0hQm = tr("Open text chat"))) + (contextmenu.get_provider().html_format_enabled() ? "" : ""), callback: () => { this.open_text_chat(); } }, contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-about", name: _translations.Wamj6lZp || (_translations.Wamj6lZp = tr("Show client info")), callback: () => Modals.openClientInfo(this) }, contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-poke", name: _translations.NAP7iNGX || (_translations.NAP7iNGX = tr("Poke client")), callback: () => { createInputModal(_translations.wle1DPL6 || (_translations.wle1DPL6 = tr("Poke client")), _translations.IhKp1U6b || (_translations.IhKp1U6b = tr("Poke message:
")), text => true, result => { if (typeof (result) === "string") { //TODO tr console.log("Poking client " + this.clientNickName() + " with message " + result); this.channelTree.client.serverConnection.send_command("clientpoke", { clid: this.clientId(), msg: result }); } }, { width: 400, maxLength: 512 }).open(); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-edit", name: _translations.wfJ0cnuF || (_translations.wfJ0cnuF = tr("Change description")), callback: () => { createInputModal(_translations.SkDvmbF4 || (_translations.SkDvmbF4 = tr("Change client description")), _translations.UUmz0RUR || (_translations.UUmz0RUR = tr("New description:
")), text => true, result => { if (typeof (result) === "string") { //TODO tr console.log("Changing " + this.clientNickName() + "'s description to " + result); this.channelTree.client.serverConnection.send_command("clientedit", { clid: this.clientId(), client_description: result }); } }, { width: 400, maxLength: 1024 }).open(); } }, contextmenu.Entry.HR(), ...this.assignment_context(), contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-move_client_to_own_channel", name: _translations.IqCkK5LB || (_translations.IqCkK5LB = tr("Move client to your channel")), callback: () => { this.channelTree.client.serverConnection.send_command("clientmove", { clid: this.clientId(), cid: this.channelTree.client.getClient().currentChannel().getChannelId() }); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-kick_channel", name: _translations.mgE4Z1Js || (_translations.mgE4Z1Js = tr("Kick client from channel")), callback: () => { createInputModal(_translations.Gj78RvOz || (_translations.Gj78RvOz = tr("Kick client from channel")), _translations.xhyckLyH || (_translations.xhyckLyH = tr("Kick reason:
")), text => true, result => { if (typeof (result) !== 'boolean' || result) { //TODO tr console.log("Kicking client " + this.clientNickName() + " from channel with reason " + result); this.channelTree.client.serverConnection.send_command("clientkick", { clid: this.clientId(), reasonid: ViewReasonId.VREASON_CHANNEL_KICK, reasonmsg: result }); } }, { width: 400, maxLength: 255 }).open(); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-kick_server", name: _translations.ZCjZNTae || (_translations.ZCjZNTae = tr("Kick client fom server")), callback: () => { createInputModal(_translations.PXTiLlh1 || (_translations.PXTiLlh1 = tr("Kick client from server")), _translations.U9VbSk_j || (_translations.U9VbSk_j = tr("Kick reason:
")), text => true, result => { if (typeof (result) !== 'boolean' || result) { //TODO tr console.log("Kicking client " + this.clientNickName() + " from server with reason " + result); this.channelTree.client.serverConnection.send_command("clientkick", { clid: this.clientId(), reasonid: ViewReasonId.VREASON_SERVER_KICK, reasonmsg: result }); } }, { width: 400, maxLength: 255 }).open(); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-ban_client", name: _translations.t1_5DwD9 || (_translations.t1_5DwD9 = tr("Ban client")), invalidPermission: !this.channelTree.client.permissions.neededPermission(PermissionType.I_CLIENT_BAN_MAX_BANTIME).granted(1), callback: () => { Modals.spawnBanClient(this.channelTree.client, [{ name: this.properties.client_nickname, unique_id: this.properties.client_unique_identifier }], (data) => { this.channelTree.client.serverConnection.send_command("banclient", { uid: this.properties.client_unique_identifier, banreason: data.reason, time: data.length }, { flagset: [data.no_ip ? "no-ip" : "", data.no_hwid ? "no-hardware-id" : "", data.no_name ? "no-nickname" : ""] }).then(() => { this.channelTree.client.sound.play(Sound.USER_BANNED); }); }); } }, contextmenu.Entry.HR(), /* { type: MenuEntryType.ENTRY, icon: "client-kick_server", name: "Add group to client", invalidPermission: true, //!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.send_command("banclient", { uid: this.properties.client_unique_identifier, banreason: reason, time: duration }); }); } }, MenuEntry.HR(), */ { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-volume", name: _translations._SOYYOpq || (_translations._SOYYOpq = tr("Change Volume")), callback: () => { Modals.spawnChangeVolume(this, true, this._audio_volume, undefined, volume => { this._audio_volume = volume; this.channelTree.client.settings.changeServer("volume_client_" + this.clientUid(), volume); if (this._audio_handle) this._audio_handle.set_volume(volume); //TODO: Update in info }); } }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.LGRXJbyk || (_translations.LGRXJbyk = tr("Change playback latency")), callback: () => { Modals.spawnChangeLatency(this, this._audio_handle.latency_settings(), () => { this._audio_handle.reset_latency_settings(); return this._audio_handle.latency_settings(); }, settings => this._audio_handle.latency_settings(settings), this._audio_handle.support_flush ? () => { this._audio_handle.flush(); } : undefined); }, visible: this._audio_handle && this._audio_handle.support_latency_settings() }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-input_muted_local", name: _translations.HXDWIypp || (_translations.HXDWIypp = tr("Mute client")), visible: !this._audio_muted, callback: () => this.set_muted(true, true) }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-input_muted_local", name: _translations.qPADwJeS || (_translations.qPADwJeS = tr("Unmute client")), visible: this._audio_muted, callback: () => this.set_muted(false, true) }, contextmenu.Entry.CLOSE(() => trigger_close && on_close ? on_close() : {})); } get tag() { if (this._tag) return this._tag; let container_client = $.spawn("div") .addClass("tree-entry client") .attr("client-id", this.clientId()); /* unread marker */ { container_client.append($.spawn("div") .addClass("marker-text-unread hidden") .attr("private-conversation", this._clientId)); } container_client.append($.spawn("div") .addClass("icon_client_state") .attr("title", "Client state")); container_client.append($.spawn("div") .addClass("group-prefix") .attr("title", "Server groups prefixes") .hide()); container_client.append($.spawn("div") .addClass("client-name") .text(this.clientNickName())); container_client.append($.spawn("div") .addClass("group-suffix") .attr("title", "Server groups suffix") .hide()); container_client.append($.spawn("div") .addClass("client-away-message") .text(this.clientNickName())); let container_icons = $.spawn("div").addClass("container-icons"); container_icons.append($.spawn("div") .addClass("icon icon_talk_power client-input_muted") .hide()); container_icons.append($.spawn("div") .addClass("container-icons-group")); container_icons.append($.spawn("div") .addClass("container-icon-client")); container_client.append(container_icons); this._tag = container_client; this.initializeListener(); return this._tag; } static bbcodeTag(id, name, uid) { return "[url=client://" + id + "/" + uid + "~" + encodeURIComponent(name) + "]" + name + "[/url]"; } static chatTag(id, name, uid, braces = false) { return $(htmltags.generate_client({ client_name: name, client_id: id, client_unique_id: uid, add_braces: braces })); } create_bbcode() { return ClientEntry.bbcodeTag(this.clientId(), this.clientNickName(), this.clientUid()); } createChatTag(braces = false) { return ClientEntry.chatTag(this.clientId(), this.clientNickName(), this.clientUid(), braces); } set speaking(flag) { if (flag === this._speaking) return; this._speaking = flag; this.updateClientSpeakIcon(); } updateClientStatusIcons() { let talk_power = this.properties.client_talk_power >= this._channel.properties.channel_needed_talk_power; if (talk_power) this.tag.find(".icon_talk_power").hide(); else this.tag.find(".icon_talk_power").show(); } updateClientSpeakIcon() { let icon = ""; let clicon = ""; if (this.properties.client_type_exact == ClientType.CLIENT_QUERY) { icon = "client-server_query"; console.log("Server query!"); } else { if (this.properties.client_away) { icon = "client-away"; } else if (this._audio_muted && !(this instanceof LocalClientEntry)) { icon = "client-input_muted_local"; } else if (!this.properties.client_output_hardware) { icon = "client-hardware_output_muted"; } else if (this.properties.client_output_muted) { icon = "client-output_muted"; } else if (!this.properties.client_input_hardware) { icon = "client-hardware_input_muted"; } else if (this.properties.client_input_muted) { icon = "client-input_muted"; } else { if (this._speaking) { if (this.properties.client_is_channel_commander) clicon = "client_cc_talk"; else clicon = "client_talk"; } else { if (this.properties.client_is_channel_commander) clicon = "client_cc_idle"; else clicon = "client_idle"; } } } if (clicon.length > 0) this.tag.find(".icon_client_state").attr('class', 'icon_client_state clicon ' + clicon); else if (icon.length > 0) this.tag.find(".icon_client_state").attr('class', 'icon_client_state icon ' + icon); else this.tag.find(".icon_client_state").attr('class', 'icon_client_state icon_empty'); } updateAwayMessage() { let tag = this.tag.find(".client-away-message"); if (this.properties.client_away == true && this.properties.client_away_message) { tag.text("[" + this.properties.client_away_message + "]"); tag.show(); } else { tag.hide(); } } updateVariables(...variables) { let group = log.group(log.LogType.DEBUG, LogCategory.CLIENT, _translations.mwXcnRVj || (_translations.mwXcnRVj = tr("Update properties (%i) of %s (%i)")), variables.length, this.clientNickName(), this.clientId()); let update_icon_status = false; let update_icon_speech = false; let update_away = false; let reorder_channel = false; let update_avatar = false; { const entries = []; for (const variable of variables) entries.push({ key: variable.key, value: variable.value, type: typeof (this.properties[variable.key]) }); log.table(LogType.DEBUG, LogCategory.PERMISSIONS, "Client update properties", entries); } for (const variable of variables) { const old_value = this._properties[variable.key]; JSON.map_field_to(this._properties, variable.value, variable.key); if (variable.key == "client_nickname") { if (variable.value !== old_value && typeof (old_value) === "string") { if (!(this instanceof LocalClientEntry)) { /* own changes will be logged somewhere else */ this.channelTree.client.log.log(log.server.Type.CLIENT_NICKNAME_CHANGED, { own_client: false, client: this.log_data(), new_name: variable.value, old_name: old_value }); } } this.tag.find(".client-name").text(variable.value); const chat = this.channelTree.client.side_bar; const conversation = chat.private_conversations().find_conversation({ name: this.clientNickName(), client_id: this.clientId(), unique_id: this.clientUid() }, { attach: false, create: false }); if (conversation) conversation.set_client_name(variable.value); reorder_channel = true; } if (variable.key == "client_away" || variable.key == "client_input_hardware" || variable.key == "client_output_hardware" || variable.key == "client_output_muted" || variable.key == "client_input_muted" || variable.key == "client_is_channel_commander") { update_icon_speech = true; } if (variable.key == "client_away_message" || variable.key == "client_away") { update_away = true; } if (variable.key == "client_unique_identifier") { this._audio_volume = parseFloat(this.channelTree.client.settings.server("volume_client_" + this.clientUid(), "1")); const mute_status = this.channelTree.client.settings.server("mute_client_" + this.clientUid(), false); this.set_muted(mute_status, false, mute_status); /* force only needed when we want to mute the client */ if (this._audio_handle) this._audio_handle.set_volume(this._audio_muted ? 0 : this._audio_volume); update_icon_speech = true; log.debug(LogCategory.CLIENT, _translations.BwKYcCsM || (_translations.BwKYcCsM = tr("Loaded client (%s) server specific properties. Volume: %o Muted: %o.")), this.clientUid(), this._audio_volume, this._audio_muted); } if (variable.key == "client_talk_power") { reorder_channel = true; update_icon_status = true; } if (variable.key == "client_icon_id") { /* yeah we like javascript. Due to JS wiered integer behaviour parsing for example fails for 18446744073409829863. * parseInt("18446744073409829863") evaluates to 18446744073409829000. * In opposite "18446744073409829863" >>> 0 evaluates to 3995244544, which is the icon id :) */ this.properties.client_icon_id = variable.value >>> 0; this.updateClientIcon(); } if (variable.key == "client_channel_group_id" || variable.key == "client_servergroups") this.update_displayed_client_groups(); else if (variable.key == "client_flag_avatar") update_avatar = true; } /* process updates after variables have been set */ if (this._channel && reorder_channel) this._channel.reorderClients(); if (update_icon_speech) this.updateClientSpeakIcon(); if (update_icon_status) this.updateClientStatusIcons(); if (update_away) this.updateAwayMessage(); const side_bar = this.channelTree.client.side_bar; { const client_info = side_bar.client_info(); if (client_info.current_client() === this) client_info.set_current_client(this, true); /* force an update */ } if (update_avatar) { this.channelTree.client.fileManager.avatars.update_cache(this.avatarId(), this.properties.client_flag_avatar); const conversations = side_bar.private_conversations(); const conversation = conversations.find_conversation({ name: this.clientNickName(), unique_id: this.clientUid(), client_id: this.clientId() }, { create: false, attach: false }); if (conversation) conversation.update_avatar(); } group.end(); this.events.fire("property_update", { properties: variables.map(e => e.key) }); } update_displayed_client_groups() { this.tag.find(".container-icons-group").children().remove(); for (let id of this.assignedServerGroupIds()) this.updateGroupIcon(this.channelTree.client.groups.serverGroup(id)); this.update_group_icon_order(); this.updateGroupIcon(this.channelTree.client.groups.channelGroup(this.properties.client_channel_group_id)); let prefix_groups = []; let suffix_groups = []; for (const group_id of this.assignedServerGroupIds()) { const group = this.channelTree.client.groups.serverGroup(group_id); if (!group) continue; if (group.properties.namemode == 1) prefix_groups.push(group.name); else if (group.properties.namemode == 2) suffix_groups.push(group.name); } const tag_group_prefix = this.tag.find(".group-prefix"); const tag_group_suffix = this.tag.find(".group-suffix"); if (prefix_groups.length > 0) { tag_group_prefix.text("[" + prefix_groups.join("][") + "]").show(); } else { tag_group_prefix.hide(); } if (suffix_groups.length > 0) { tag_group_suffix.text("[" + suffix_groups.join("][") + "]").show(); } else { tag_group_suffix.hide(); } } updateClientVariables(force_update) { if (Date.now() - 10 * 60 * 1000 < this._info_variables_promise_timestamp && this._info_variables_promise && (typeof (force_update) !== "boolean" || force_update)) return this._info_variables_promise; this._info_variables_promise_timestamp = Date.now(); return (this._info_variables_promise = new Promise((resolve, reject) => { this.channelTree.client.serverConnection.send_command("clientgetvariables", { clid: this.clientId() }).then(() => resolve()).catch(error => { this._info_connection_promise_timestamp = 0; /* not succeeded */ reject(error); }); })); } updateClientIcon() { this.tag.find(".container-icon-client").children().remove(); if (this.properties.client_icon_id > 0) { this.channelTree.client.fileManager.icons.generateTag(this.properties.client_icon_id).attr("title", "Client icon") .appendTo(this.tag.find(".container-icon-client")); } } updateGroupIcon(group) { if (!group) return; const container = this.tag.find(".container-icons-group"); container.find(".icon_group_" + group.id).remove(); if (group.properties.iconid > 0) { container.append($.spawn("div").attr('group-power', group.properties.sortid) .addClass("container-group-icon icon_group_" + group.id) .append(this.channelTree.client.fileManager.icons.generateTag(group.properties.iconid)).attr("title", group.name)); } } update_group_icon_order() { const container = this.tag.find(".container-icons-group"); container.append(...[...container.children()].sort((a, b) => parseInt(a.getAttribute("group-power")) - parseInt(b.getAttribute("group-power")))); } assignedServerGroupIds() { let result = []; for (let id of this.properties.client_servergroups.split(",")) { if (id.length == 0) continue; 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 true; return false; } else return group.id == this.assignedChannelGroup(); } onDelete() { } calculateOnlineTime() { return Date.now() / 1000 - this.properties.client_lastconnected; } avatarId() { function str2ab(str) { let buf = new ArrayBuffer(str.length); // 2 bytes for each char let bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } try { let raw = atob(this.properties.client_unique_identifier); let input = hex.encode(str2ab(raw)); let result = ""; for (let index = 0; index < input.length; index++) { let c = input.charAt(index); let offset = 0; if (c >= '0' && c <= '9') offset = c.charCodeAt(0) - '0'.charCodeAt(0); else if (c >= 'A' && c <= 'F') offset = c.charCodeAt(0) - 'A'.charCodeAt(0) + 0x0A; else if (c >= 'a' && c <= 'f') offset = c.charCodeAt(0) - 'a'.charCodeAt(0) + 0x0A; result += String.fromCharCode('a'.charCodeAt(0) + offset); } return result; } catch (e) { //invalid base 64 (like music bot etc) return undefined; } } update_family_index() { if (!this._channel) return; const index = this._channel.calculate_family_index(); this.tag.css('padding-left', (5 + (index + 2) * 16) + "px"); } log_data() { return { client_unique_id: this.properties.client_unique_identifier, client_name: this.clientNickName(), client_id: this._clientId }; } /* max 1s ago, so we could update every second */ request_connection_info() { if (Date.now() - 900 < this._info_connection_promise_timestamp && this._info_connection_promise) return this._info_connection_promise; if (this._info_connection_promise_reject) this._info_connection_promise_resolve("timeout"); let _local_reject; /* to ensure we're using the right resolve! */ this._info_connection_promise = new Promise((resolve, reject) => { this._info_connection_promise_resolve = resolve; this._info_connection_promise_reject = reject; _local_reject = reject; }); this._info_connection_promise_timestamp = Date.now(); this.channelTree.client.serverConnection.send_command("getconnectioninfo", { clid: this._clientId }).catch(error => _local_reject(error)); return this._info_connection_promise; } set_connection_info(info) { if (!this._info_connection_promise_resolve) return; this._info_connection_promise_resolve(info); this._info_connection_promise_resolve = undefined; this._info_connection_promise_reject = undefined; } set flag_text_unread(flag) { this._tag.find(".marker-text-unread").toggleClass("hidden", !flag); } } class LocalClientEntry extends ClientEntry { constructor(handle) { super(0, "local client"); this.handle = handle; } showContextMenu(x, y, on_close = undefined) { const _self = this; contextmenu.spawn_context_menu(x, y, ...this.contextmenu_info(), { name: (contextmenu.get_provider().html_format_enabled() ? "" : "") + (_translations.TWJRawAz || (_translations.TWJRawAz = tr("Change name"))) + (contextmenu.get_provider().html_format_enabled() ? "" : ""), icon_class: "client-change_nickname", callback: () => _self.openRename(), type: contextmenu.MenuEntryType.ENTRY }, { name: _translations.QXkvf75y || (_translations.QXkvf75y = tr("Change description")), icon_class: "client-edit", callback: () => { createInputModal(_translations.eo0BTEUD || (_translations.eo0BTEUD = tr("Change own description")), _translations.cGSxzOs8 || (_translations.cGSxzOs8 = tr("New description:
")), text => true, result => { if (result) { console.log(_translations.KltoFGs6 || (_translations.KltoFGs6 = tr("Changing own description to %s")), result); _self.channelTree.client.serverConnection.send_command("clientedit", { clid: _self.clientId(), client_description: result }); } }, { width: 400, maxLength: 1024 }).open(); }, type: contextmenu.MenuEntryType.ENTRY }, contextmenu.Entry.HR(), ...this.assignment_context(), contextmenu.Entry.CLOSE(on_close)); } initializeListener() { if (this._listener_initialized) this.tag.off(); this._listener_initialized = false; /* could there be a better system */ super.initializeListener(); this.tag.find(".client-name").addClass("client-name-own"); this.tag.on('dblclick', () => { if (Array.isArray(this.channelTree.currently_selected)) { //Multiselect return; } this.openRename(); }); } openRename() { this.channelTree.client_mover.enabled = false; const elm = this.tag.find(".client-name"); elm.attr("contenteditable", "true"); elm.removeClass("client-name-own"); elm.css("background-color", "white"); elm.focus(); this.renaming = true; elm.on('keypress', event => { if (event.keyCode == KeyCode.KEY_RETURN) { $(event.target).trigger("focusout"); return false; } }); elm.on('focusout', event => { this.channelTree.client_mover.enabled = true; if (!this.renaming) return; this.renaming = false; elm.css("background-color", ""); elm.removeAttr("contenteditable"); elm.addClass("client-name-own"); let text = elm.text().toString(); if (this.clientNickName() == text) return; elm.text(this.clientNickName()); const old_name = this.clientNickName(); this.handle.serverConnection.command_helper.updateClient("client_nickname", text).then((e) => { settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, text); this.channelTree.client.log.log(log.server.Type.CLIENT_NICKNAME_CHANGED, { client: this.log_data(), old_name: old_name, new_name: text, own_client: true }); }).catch((e) => { this.channelTree.client.log.log(log.server.Type.CLIENT_NICKNAME_CHANGE_FAILED, { reason: e.extra_message }); this.openRename(); }); }); } } class MusicClientProperties extends ClientProperties { constructor() { super(...arguments); this.player_state = 0; this.player_volume = 0; this.client_playlist_id = 0; this.client_disabled = false; this.client_flag_notify_song_change = false; this.client_bot_type = 0; this.client_uptime_mode = 0; } } /* * command[index]["song_id"] = element ? element->getSongId() : 0; command[index]["song_url"] = element ? element->getUrl() : ""; command[index]["song_invoker"] = element ? element->getInvoker() : 0; command[index]["song_loaded"] = false; auto entry = dynamic_pointer_cast(element); if(entry) { auto data = entry->song_loaded_data(); command[index]["song_loaded"] = entry->song_loaded() && data; if(entry->song_loaded() && data) { command[index]["song_title"] = data->title; command[index]["song_description"] = data->description; command[index]["song_thumbnail"] = data->thumbnail; command[index]["song_length"] = data->length.count(); } } */ class SongInfo { constructor() { this.song_id = 0; this.song_url = ""; this.song_invoker = 0; this.song_loaded = false; /* only if song_loaded = true */ this.song_title = ""; this.song_description = ""; this.song_thumbnail = ""; this.song_length = 0; } } class MusicClientPlayerInfo extends SongInfo { constructor() { super(...arguments); this.bot_id = 0; this.player_state = 0; this.player_buffered_index = 0; this.player_replay_index = 0; this.player_max_index = 0; this.player_seekable = false; this.player_title = ""; this.player_description = ""; } } class MusicClientEntry extends ClientEntry { constructor(clientId, clientName) { super(clientId, clientName, new MusicClientProperties()); this._info_promise_age = 0; } destroy() { super.destroy(); this._info_promise = undefined; this._info_promise_reject = undefined; this._info_promise_resolve = undefined; } get properties() { return this._properties; } showContextMenu(x, y, on_close = undefined) { let trigger_close = true; contextmenu.spawn_context_menu(x, y, ...this.contextmenu_info(), { name: (contextmenu.get_provider().html_format_enabled() ? "" : "") + (_translations.XbLxNlO8 || (_translations.XbLxNlO8 = tr("Change bot name"))) + (contextmenu.get_provider().html_format_enabled() ? "" : ""), icon_class: "client-change_nickname", disabled: false, callback: () => { createInputModal(_translations.pmicCstj || (_translations.pmicCstj = tr("Change music bots nickname")), _translations.vqukZhk9 || (_translations.vqukZhk9 = tr("New nickname:
")), text => text.length >= 3 && text.length <= 31, result => { if (result) { this.channelTree.client.serverConnection.send_command("clientedit", { clid: this.clientId(), client_nickname: result }); } }, { width: "40em", min_width: "10em", maxLength: 255 }).open(); }, type: contextmenu.MenuEntryType.ENTRY }, { name: _translations.KwxFZl6L || (_translations.KwxFZl6L = tr("Change bot description")), icon_class: "client-edit", disabled: false, callback: () => { createInputModal(_translations.mYzzfhcQ || (_translations.mYzzfhcQ = tr("Change music bots description")), _translations.ZTCZj4qo || (_translations.ZTCZj4qo = tr("New description:
")), text => true, result => { if (typeof (result) === 'string') { this.channelTree.client.serverConnection.send_command("clientedit", { clid: this.clientId(), client_description: result }); } }, { width: "60em", min_width: "10em", maxLength: 255 }).open(); }, type: contextmenu.MenuEntryType.ENTRY }, /* { name: tr("Open music panel"), icon: "client-edit", disabled: true, callback: () => {}, type: MenuEntryType.ENTRY }, */ { name: _translations.JLASYUDm || (_translations.JLASYUDm = tr("Open bot's playlist")), icon_class: "client-edit", disabled: false, callback: () => { this.channelTree.client.serverConnection.command_helper.request_playlist_list().then(lists => { for (const entry of lists) { if (entry.playlist_id == this.properties.client_playlist_id) { Modals.spawnPlaylistEdit(this.channelTree.client, entry); return; } } createErrorModal(_translations.ecR9BnOb || (_translations.ecR9BnOb = tr("Invalid permissions")), _translations.bjVFcLvv || (_translations.bjVFcLvv = tr("You dont have to see the bots playlist."))).open(); }).catch(error => { createErrorModal(_translations.cCQHXsEN || (_translations.cCQHXsEN = tr("Failed to query playlist.")), _translations.z0TAFloZ || (_translations.z0TAFloZ = tr("Failed to query playlist info."))).open(); }); }, type: contextmenu.MenuEntryType.ENTRY }, { name: _translations.v3a_2VKL || (_translations.v3a_2VKL = tr("Quick url replay")), icon_class: "client-edit", disabled: false, callback: () => { createInputModal(_translations.qP0cnomf || (_translations.qP0cnomf = tr("Please enter the URL")), _translations.yQiADIEs || (_translations.yQiADIEs = tr("URL:")), text => true, result => { if (result) { this.channelTree.client.serverConnection.send_command("musicbotqueueadd", { bot_id: this.properties.client_database_id, type: "yt", url: result }).catch(error => { if (error instanceof CommandResult) { error = error.extra_message || error.message; } //TODO tr createErrorModal(_translations.LAv5uiVz || (_translations.LAv5uiVz = tr("Failed to replay url")), "Failed to enqueue url:
" + error).open(); }); } }, { width: 400, maxLength: 255 }).open(); }, type: contextmenu.MenuEntryType.ENTRY }, contextmenu.Entry.HR(), ...super.assignment_context(), contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-move_client_to_own_channel", name: _translations.y7NwSbFu || (_translations.y7NwSbFu = tr("Move client to your channel")), callback: () => { this.channelTree.client.serverConnection.send_command("clientmove", { clid: this.clientId(), cid: this.channelTree.client.getClient().currentChannel().getChannelId() }); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-kick_channel", name: _translations.l4FBtA8t || (_translations.l4FBtA8t = tr("Kick client from channel")), callback: () => { createInputModal(_translations.I7AyThLI || (_translations.I7AyThLI = tr("Kick client from channel")), _translations.Xd1D_Zzu || (_translations.Xd1D_Zzu = tr("Kick reason:
")), text => true, result => { if (typeof (result) !== 'boolean' || result) { console.log(_translations.mWrcl55N || (_translations.mWrcl55N = tr("Kicking client %o from channel with reason %o")), this.clientNickName(), result); this.channelTree.client.serverConnection.send_command("clientkick", { clid: this.clientId(), reasonid: ViewReasonId.VREASON_CHANNEL_KICK, reasonmsg: result }); } }, { width: 400, maxLength: 255 }).open(); } }, contextmenu.Entry.HR(), { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-volume", name: _translations.GjpMhrnj || (_translations.GjpMhrnj = tr("Change local volume")), callback: () => { Modals.spawnChangeVolume(this, true, this._audio_handle.get_volume(), undefined, volume => { this.channelTree.client.settings.changeServer("volume_client_" + this.clientUid(), volume); this._audio_handle.set_volume(volume); }); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-volume", name: _translations.xbWCjjmW || (_translations.xbWCjjmW = tr("Change remote volume")), callback: () => { let max_volume = this.channelTree.client.permissions.neededPermission(PermissionType.I_CLIENT_MUSIC_CREATE_MODIFY_MAX_VOLUME).value; if (max_volume < 0) max_volume = 100; Modals.spawnChangeVolume(this, false, this.properties.player_volume, max_volume / 100, value => { if (typeof (value) !== "number") return; this.channelTree.client.serverConnection.send_command("clientedit", { clid: this.clientId(), player_volume: value, }).then(() => { //TODO: Update in info }); }); } }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.eRh0JpMP || (_translations.eRh0JpMP = tr("Change playback latency")), callback: () => { Modals.spawnChangeLatency(this, this._audio_handle.latency_settings(), () => { this._audio_handle.reset_latency_settings(); return this._audio_handle.latency_settings(); }, settings => this._audio_handle.latency_settings(settings), this._audio_handle.support_flush ? () => { this._audio_handle.flush(); } : undefined); }, visible: this._audio_handle && this._audio_handle.support_latency_settings() }, contextmenu.Entry.HR(), { name: _translations.J7K_FqfX || (_translations.J7K_FqfX = tr("Delete bot")), icon_class: "client-delete", disabled: false, callback: () => { const tag = $.spawn("div").append(MessageHelper.formatMessage(_translations.RjNsfIH5 || (_translations.RjNsfIH5 = tr("Do you really want to delete {0}")), this.createChatTag(false))); Modals.spawnYesNo(_translations.UryMTw7o || (_translations.UryMTw7o = tr("Are you sure?")), $.spawn("div").append(tag), result => { if (result) { this.channelTree.client.serverConnection.send_command("musicbotdelete", { bot_id: this.properties.client_database_id }); } }); }, type: contextmenu.MenuEntryType.ENTRY }, contextmenu.Entry.CLOSE(() => trigger_close && on_close ? on_close() : {})); } initializeListener() { super.initializeListener(); } handlePlayerInfo(json) { if (json) { const info = new MusicClientPlayerInfo(); JSON.map_to(info, json); if (this._info_promise_resolve) this._info_promise_resolve(info); this._info_promise_reject = undefined; this._info_promise_resolve = undefined; } } requestPlayerInfo(max_age = 1000) { if (this._info_promise !== undefined && this._info_promise_age > 0 && Date.now() - max_age <= this._info_promise_age) return this._info_promise; this._info_promise_age = Date.now(); this._info_promise = new Promise((resolve, reject) => { this._info_promise_reject = reject; this._info_promise_resolve = resolve; }); this.channelTree.client.serverConnection.send_command("musicbotplayerinfo", { bot_id: this.properties.client_database_id }); return this._info_promise; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["05ca7973a11a972f3d6b90eb9141fa51cfc36ba0897d1a7ec39adb5cbe0a6f99"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["05ca7973a11a972f3d6b90eb9141fa51cfc36ba0897d1a7ec39adb5cbe0a6f99"] = "05ca7973a11a972f3d6b90eb9141fa51cfc36ba0897d1a7ec39adb5cbe0a6f99"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "BJLONISG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerEdit.ts (35,21)" }, { name: "GqQnNwWS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerEdit.ts (211,29)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function createServerModal(server, callback) { const properties = Object.assign({}, server.properties); let _valid_states = { general: false }; let _toggle_valid = (key, value) => { if (typeof (key) === "string") { _valid_states[key] = value; } let flag = true; for (const key of Object.keys(_valid_states)) if (!_valid_states[key]) { flag = false; break; } if (flag) { flag = false; for (const property_name of Object.keys(properties)) { if (server.properties[property_name] !== properties[property_name]) { flag = true; break; } } } button_save.prop("disabled", !flag); }; const modal = createModal({ header: _translations.BJLONISG || (_translations.BJLONISG = tr("Manage the Virtual Server")), body: () => { const template = $("#tmpl_server_edit").renderTag(Object.assign(Object.assign({}, server.properties), { server_icon: server.channelTree.client.fileManager.icons.generateTag(server.properties.virtualserver_icon_id) })); /* the tab functionality */ { const container_tabs = template.find(".container-categories"); container_tabs.find(".categories .entry").on('click', event => { const entry = $(event.target); container_tabs.find(".bodies > .body").addClass("hidden"); container_tabs.find(".categories > .selected").removeClass("selected"); entry.addClass("selected"); container_tabs.find(".bodies > .body." + entry.attr("container")).removeClass("hidden"); }); container_tabs.find(".entry").first().trigger('click'); } apply_general_listener(template.find(".container-general"), server, properties, _toggle_valid); apply_host_listener(template.find(".container-host"), server, properties, _toggle_valid); apply_network_listener(template.find(".container-network"), server, properties, _toggle_valid, modal); apply_security_listener(template.find(".container-security"), server, properties, _toggle_valid); apply_messages_listener(template.find(".container-messages"), server, properties, _toggle_valid); apply_misc_listener(template.find(".container-misc"), server, properties, _toggle_valid); return template.contents(); }, footer: null, min_width: "35em" }); tooltip(modal.htmlTag); const button_save = modal.htmlTag.find(".button-save"); button_save.on('click', event => { const changed = {}; for (const property_name of Object.keys(properties)) if (server.properties[property_name] !== properties[property_name]) changed[property_name] = properties[property_name]; callback(changed).then(() => { _toggle_valid(undefined); }); }); modal.htmlTag.find(".button-cancel").on('click', event => { modal.close(); callback(); }); _toggle_valid("general", true); modal.htmlTag.find(".modal-body").addClass("modal-server-edit modal-blue"); modal.open(); } Modals.createServerModal = createServerModal; function apply_general_listener(tag, server, properties, callback_valid) { /* name */ { const container = tag.find(".virtualserver_name"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_NAME).granted(1); container.on('change', event => { properties.virtualserver_name = container.val(); const invalid = properties.virtualserver_name.length > 70 || properties.virtualserver_name.length < 1; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_name", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* icon */ { tag.find(".button-select-icon").on('click', event => { Modals.spawnIconSelect(server.channelTree.client, id => { const icon_node = tag.find(".icon-preview"); icon_node.children().remove(); icon_node.append(server.channelTree.client.fileManager.icons.generateTag(id)); console.log("Selected icon ID: %d", id); properties.virtualserver_icon_id = id; callback_valid(undefined); //Toggle save button update }, properties.virtualserver_icon_id); }); tag.find(".button-icon-remove").on('click', event => { const icon_node = tag.find(".icon-preview"); icon_node.children().remove(); icon_node.append(server.channelTree.client.fileManager.icons.generateTag(0)); console.log("Remove server icon"); properties.virtualserver_icon_id = 0; callback_valid(undefined); //Toggle save button update }); } /* password */ { //TODO: On save let the user retype his password? const container = tag.find(".virtualserver_password"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_PASSWORD).granted(1); container.on('change', event => { const password = container.val(); properties.virtualserver_flag_password = !!password; if (properties.virtualserver_flag_password) { helpers.hashPassword(password).then(pass => properties.virtualserver_password = pass); } callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* slots */ { const container_max = tag.find(".virtualserver_maxclients"); const container_reserved = tag.find(".virtualserver_reserved_slots"); /* max users */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_MAXCLIENTS).granted(1); container_max.on('change', event => { properties.virtualserver_maxclients = parseInt(container_max.val()); const invalid = properties.virtualserver_maxclients < 1 || properties.virtualserver_maxclients > 1024; container_max.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_maxclients", !invalid); container_reserved.trigger('change'); /* update the flag */ }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* reserved */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_RESERVED_SLOTS).granted(1); container_reserved.on('change', event => { properties.virtualserver_reserved_slots = parseInt(container_reserved.val()); const invalid = properties.virtualserver_reserved_slots > properties.virtualserver_maxclients; container_reserved.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_reserved_slots", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } } /* Welcome message */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_WELCOMEMESSAGE).granted(1); const container = tag.find(".container-welcome-message"); const input = container.find("textarea"); const insert_tag = (open, close) => { if (input.prop("disabled")) return; const node = input[0]; if (node.selectionStart || node.selectionStart == 0) { const startPos = node.selectionStart; const endPos = node.selectionEnd; node.value = node.value.substring(0, startPos) + open + node.value.substring(startPos, endPos) + close + node.value.substring(endPos); node.selectionEnd = endPos + open.length; node.selectionStart = node.selectionEnd; } else { node.value += open + close; node.selectionEnd = node.value.length - close.length; node.selectionStart = node.selectionEnd; } input.focus().trigger('change'); }; input.on('change', event => { console.log(_translations.GqQnNwWS || (_translations.GqQnNwWS = tr("Welcome message edited: %o")), input.val()); properties.virtualserver_welcomemessage = input.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); container.find(".button-bold").on('click', () => insert_tag('[b]', '[/b]')); container.find(".button-italic").on('click', () => insert_tag('[i]', '[/i]')); container.find(".button-underline").on('click', () => insert_tag('[u]', '[/u]')); container.find(".button-color input").on('change', event => { insert_tag('[color=' + event.target.value + ']', '[/color]'); }); } } function apply_network_listener(tag, server, properties, callback_valid, modal) { /* binding */ { /* host */ { const container = tag.find(".virtualserver_host"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOST).granted(1); container.on('change', event => { properties.virtualserver_host = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_host)); } /* port */ { const container = tag.find(".virtualserver_port"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_PORT).granted(1); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_port = value; const valid = value >= 1 && value < 65536; callback_valid("virtualserver_port", valid); container.firstParent(".input-boxed").toggleClass("is-invalid", !valid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_port)); } /* TeamSpeak server list */ { const container = tag.find(".virtualserver_weblist_enabled"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_WEBLIST).granted(1); container.on('change', event => { properties.virtualserver_weblist_enabled = container.prop("checked"); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".checkbox").toggleClass("disabled", !permission); server.updateProperties().then(() => container.prop("checked", server.properties.virtualserver_weblist_enabled)); } } /* file download */ { /* bandwidth */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_FT_SETTINGS).granted(1); const container = tag.find(".virtualserver_max_download_total_bandwidth"); container.on('change', event => { properties.virtualserver_max_download_total_bandwidth = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_max_download_total_bandwidth)); } /* Quota */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_FT_QUOTAS).granted(1); const container = tag.find(".virtualserver_download_quota"); container.on('change', event => { properties.virtualserver_download_quota = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_download_quota)); } } /* file upload */ { /* bandwidth */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_FT_SETTINGS).granted(1); const container = tag.find(".virtualserver_max_upload_total_bandwidth"); container.on('change', event => { properties.virtualserver_max_upload_total_bandwidth = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_max_upload_total_bandwidth)); } /* Quota */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_FT_QUOTAS).granted(1); const container = tag.find(".virtualserver_upload_quota"); container.on('change', event => { properties.virtualserver_upload_quota = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_upload_quota)); } } /* quota info */ { server.updateProperties().then(() => { tag.find(".value.virtualserver_month_bytes_downloaded").text(MessageHelper.network.format_bytes(server.properties.virtualserver_month_bytes_downloaded)); tag.find(".value.virtualserver_month_bytes_uploaded").text(MessageHelper.network.format_bytes(server.properties.virtualserver_month_bytes_uploaded)); tag.find(".value.virtualserver_total_bytes_downloaded").text(MessageHelper.network.format_bytes(server.properties.virtualserver_total_bytes_downloaded)); tag.find(".value.virtualserver_total_bytes_uploaded").text(MessageHelper.network.format_bytes(server.properties.virtualserver_total_bytes_uploaded)); }); } /* quota update task */ if (server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CONNECTIONINFO_VIEW).granted(1)) { const month_bytes_downloaded = tag.find(".value.virtualserver_month_bytes_downloaded")[0]; const month_bytes_uploaded = tag.find(".value.virtualserver_month_bytes_uploaded")[0]; const total_bytes_downloaded = tag.find(".value.virtualserver_total_bytes_downloaded")[0]; const total_bytes_uploaded = tag.find(".value.virtualserver_total_bytes_uploaded")[0]; let id = setInterval(() => { if (!modal.shown) { clearInterval(id); return; } server.request_connection_info().then(info => { if (info.connection_filetransfer_bytes_sent_month && month_bytes_downloaded) month_bytes_downloaded.innerText = MessageHelper.network.format_bytes(info.connection_filetransfer_bytes_sent_month); if (info.connection_filetransfer_bytes_received_month && month_bytes_uploaded) month_bytes_uploaded.innerText = MessageHelper.network.format_bytes(info.connection_filetransfer_bytes_received_month); if (info.connection_filetransfer_bytes_sent_total && total_bytes_downloaded) total_bytes_downloaded.innerText = MessageHelper.network.format_bytes(info.connection_filetransfer_bytes_sent_total); if (info.connection_filetransfer_bytes_received_total && total_bytes_uploaded) total_bytes_uploaded.innerText = MessageHelper.network.format_bytes(info.connection_filetransfer_bytes_received_total); }); }, 1000); modal.close_listener.push(() => clearInterval(id)); } } function apply_host_listener(tag, server, properties, callback_valid) { /* host message */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTMESSAGE).granted(1); /* message */ { const container = tag.find(".virtualserver_hostmessage"); container.on('change', event => { properties.virtualserver_hostmessage = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* mode */ { const container = tag.find(".virtualserver_hostmessage_mode"); container.on('change', event => { properties.virtualserver_hostmessage_mode = Math.min(3, Math.max(0, parseInt(container.val()))); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } } /* host banner */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBANNER).granted(1); /* URL */ { const container = tag.find(".virtualserver_hostbanner_url"); container.on('change', event => { properties.virtualserver_hostbanner_url = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* Image URL/Image Preview */ { const container = tag.find(".virtualserver_hostbanner_gfx_url"); const container_preview = tag.find(".container-host-message .container-gfx-preview img"); container.on('change', event => { properties.virtualserver_hostbanner_gfx_url = container.val(); container_preview.attr("src", properties.virtualserver_hostbanner_gfx_url).toggle(!!properties.virtualserver_hostbanner_gfx_url); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* Image Refresh */ { const container = tag.find(".virtualserver_hostbanner_gfx_interval"); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_hostbanner_gfx_interval = value; const invalid = value < 60 && value != 0; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_hostbanner_gfx_interval", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* mode */ { const container = tag.find(".virtualserver_hostbanner_mode"); container.on('change', event => { properties.virtualserver_hostbanner_mode = Math.min(2, Math.max(0, parseInt(container.val()))); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } } /* host button */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBUTTON).granted(1); /* URL */ { const container = tag.find(".virtualserver_hostbutton_url"); container.on('change', event => { properties.virtualserver_hostbutton_url = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* Tooltip */ { const container = tag.find(".virtualserver_hostbutton_tooltip"); container.on('change', event => { properties.virtualserver_hostbutton_tooltip = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* Icon URL/Icon Preview */ { const container = tag.find(".virtualserver_hostbutton_gfx_url"); const container_preview = tag.find(".container-host-button .container-gfx-preview img"); container.on('change', event => { properties.virtualserver_hostbutton_gfx_url = container.val(); container_preview.attr("src", properties.virtualserver_hostbutton_gfx_url).toggle(!!properties.virtualserver_hostbutton_gfx_url); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } } } function apply_security_listener(tag, server, properties, callback_valid) { /* Anti flood */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_ANTIFLOOD).granted(1); /* reduce */ { const container = tag.find(".virtualserver_antiflood_points_tick_reduce"); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_antiflood_points_tick_reduce = value; const invalid = value < 1 || value > 999999; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_antiflood_points_tick_reduce", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_antiflood_points_tick_reduce)); } /* block commands */ { const container = tag.find(".virtualserver_antiflood_points_needed_command_block"); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_antiflood_points_needed_command_block = value; const invalid = value < 1 || value > 999999; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_antiflood_points_needed_command_block", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_antiflood_points_needed_command_block)); } /* block ip */ { const container = tag.find(".virtualserver_antiflood_points_needed_ip_block"); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_antiflood_points_needed_ip_block = value; const invalid = value < 1 || value > 999999; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_antiflood_points_needed_ip_block", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_antiflood_points_needed_ip_block)); } } /* encryption */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_CODEC_ENCRYPTION_MODE).granted(1); const container = tag.find(".virtualserver_codec_encryption_mode"); container.on('change', event => { properties.virtualserver_codec_encryption_mode = Math.min(2, Math.max(0, parseInt(container.val()))); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* security level */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_NEEDED_IDENTITY_SECURITY_LEVEL).granted(1); const container = tag.find(".virtualserver_needed_identity_security_level"); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_needed_identity_security_level = value; const invalid = value < 8 || value > 99; container.firstParent(".input-boxed").toggleClass("is-invalid", invalid); callback_valid("virtualserver_needed_identity_security_level", !invalid); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_needed_identity_security_level)); } } function apply_messages_listener(tag, server, properties, callback_valid) { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_MESSAGES).granted(1); /* channel topic */ { const container = tag.find(".virtualserver_default_channel_topic"); container.on('change', event => { properties.virtualserver_default_channel_topic = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* channel description */ { const container = tag.find(".virtualserver_default_channel_description"); container.on('change', event => { properties.virtualserver_default_channel_description = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_default_channel_description)); } /* client description */ { const container = tag.find(".virtualserver_default_client_description"); container.on('change', event => { properties.virtualserver_default_client_description = container.val(); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_default_client_description)); } } function apply_misc_listener(tag, server, properties, callback_valid) { /* default groups */ { /* Server Group */ { const container = tag.find(".virtualserver_default_server_group"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_SERVERGROUP).granted(1); container.on('change', event => { properties.virtualserver_default_server_group = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); for (const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) { if (group.type != 2) continue; let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id); if (group.id == server.properties.virtualserver_default_server_group) group_tag.prop("selected", true); group_tag.appendTo(container); } } /* Music Group */ { const container = tag.find(".virtualserver_default_music_group"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_MUSICGROUP).granted(1); container.on('change', event => { properties.virtualserver_default_music_group = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); for (const group of server.channelTree.client.groups.serverGroups.sort(GroupManager.sorter())) { if (group.type != 2) continue; let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id); if (group.id == server.properties.virtualserver_default_music_group) group_tag.prop("selected", true); group_tag.appendTo(container); } } /* Channel Admin Group */ { const container = tag.find(".virtualserver_default_channel_admin_group"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_CHANNELADMINGROUP).granted(1); container.on('change', event => { properties.virtualserver_default_channel_admin_group = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); for (const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) { if (group.type != 2) continue; let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id); if (group.id == server.properties.virtualserver_default_channel_admin_group) group_tag.prop("selected", true); group_tag.appendTo(container); } } /* Channel Guest Group */ { const container = tag.find(".virtualserver_default_channel_group"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_DEFAULT_CHANNELGROUP).granted(1); container.on('change', event => { properties.virtualserver_default_channel_group = parseInt(container.val()); callback_valid(undefined); //Toggle save button update }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); for (const group of server.channelTree.client.groups.channelGroups.sort(GroupManager.sorter())) { if (group.type != 2) continue; let group_tag = $.spawn("option").text(group.name + " [" + (group.properties.savedb ? "perm" : "tmp") + "]").attr("group-id", group.id); if (group.id == server.properties.virtualserver_default_channel_group) group_tag.prop("selected", true); group_tag.appendTo(container); } } } /* complains */ { const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_COMPLAIN).granted(1); /* ban threshold */ { const container = tag.find(".virtualserver_complain_autoban_count"); container.on('change', event => { properties.virtualserver_complain_autoban_count = parseInt(container.val()); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_complain_autoban_count)); } /* ban time */ { const container = tag.find(".virtualserver_complain_autoban_time"); container.on('change', event => { properties.virtualserver_complain_autoban_time = parseInt(container.val()); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_complain_autoban_time)); } /* auto remove time */ { const container = tag.find(".virtualserver_complain_remove_time"); container.on('change', event => { properties.virtualserver_complain_remove_time = parseInt(container.val()); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_complain_remove_time)); } } /* others */ { /* clients before silence */ { const container = tag.find(".virtualserver_min_clients_in_channel_before_forced_silence"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_CHANNEL_FORCED_SILENCE).granted(1); container.on('change', event => { const value = parseInt(container.val()); properties.virtualserver_min_clients_in_channel_before_forced_silence = value; callback_valid("virtualserver_min_clients_in_channel_before_forced_silence", value > 1); container.firstParent(".input-boxed").toggleClass("is-invalid", value <= 1); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); server.updateProperties().then(() => container.val(server.properties.virtualserver_min_clients_in_channel_before_forced_silence)); } /* priority speaker dim factor */ { const container = tag.find(".virtualserver_priority_speaker_dimm_modificator"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_PRIORITY_SPEAKER_DIMM_MODIFICATOR).granted(1); container.on('change', event => { properties.virtualserver_priority_speaker_dimm_modificator = parseInt(container.val()); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } /* channel delete delay */ { const container = tag.find(".virtualserver_channel_temp_delete_delay_default"); const permission = server.channelTree.client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_CHANNEL_TEMP_DELETE_DELAY_DEFAULT).granted(1); container.on('change', event => { properties.virtualserver_channel_temp_delete_delay_default = parseInt(container.val()); callback_valid(undefined); }).prop("disabled", !permission).firstParent(".input-boxed").toggleClass("disabled", !permission); } } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["6079f752d3ed1818f65c23c2166c43f6d4e67d4994e5849c20b0297e41e704b6"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["6079f752d3ed1818f65c23c2166c43f6d4e67d4994e5849c20b0297e41e704b6"] = "6079f752d3ed1818f65c23c2166c43f6d4e67d4994e5849c20b0297e41e704b6"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "xl5h3fOx", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (209,23)" }, { name: "n60We1tw", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (218,23)" }, { name: "xTkdlACq", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (226,23)" }, { name: "dKIgGTUq", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (235,23)" }, { name: "zjiyeNdR", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (238,54)" }, { name: "simVGxCY", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (239,37)" }, { name: "MKb9CCNC", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (257,23)" }, { name: "aUKw1raS", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (262,23)" }, { name: "CDsTVwgK", path: "D:/TeaSpeak/web/shared/js/ui/server.ts (271,70)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// class ServerProperties { constructor() { this.virtualserver_host = ""; this.virtualserver_port = 0; this.virtualserver_name = ""; this.virtualserver_name_phonetic = ""; this.virtualserver_icon_id = 0; this.virtualserver_version = "unknown"; this.virtualserver_platform = "unknown"; this.virtualserver_unique_identifier = ""; this.virtualserver_clientsonline = 0; this.virtualserver_queryclientsonline = 0; this.virtualserver_channelsonline = 0; this.virtualserver_uptime = 0; this.virtualserver_created = 0; this.virtualserver_maxclients = 0; this.virtualserver_reserved_slots = 0; this.virtualserver_password = ""; this.virtualserver_flag_password = false; this.virtualserver_ask_for_privilegekey = false; this.virtualserver_welcomemessage = ""; this.virtualserver_hostmessage = ""; this.virtualserver_hostmessage_mode = 0; this.virtualserver_hostbanner_url = ""; this.virtualserver_hostbanner_gfx_url = ""; this.virtualserver_hostbanner_gfx_interval = 0; this.virtualserver_hostbanner_mode = 0; this.virtualserver_hostbutton_tooltip = ""; this.virtualserver_hostbutton_url = ""; this.virtualserver_hostbutton_gfx_url = ""; this.virtualserver_codec_encryption_mode = 0; this.virtualserver_default_music_group = 0; this.virtualserver_default_server_group = 0; this.virtualserver_default_channel_group = 0; this.virtualserver_default_channel_admin_group = 0; //Special requested properties this.virtualserver_default_client_description = ""; this.virtualserver_default_channel_description = ""; this.virtualserver_default_channel_topic = ""; this.virtualserver_antiflood_points_tick_reduce = 0; this.virtualserver_antiflood_points_needed_command_block = 0; this.virtualserver_antiflood_points_needed_ip_block = 0; this.virtualserver_country_code = "XX"; this.virtualserver_complain_autoban_count = 0; this.virtualserver_complain_autoban_time = 0; this.virtualserver_complain_remove_time = 0; this.virtualserver_needed_identity_security_level = 8; this.virtualserver_weblist_enabled = false; this.virtualserver_min_clients_in_channel_before_forced_silence = 0; this.virtualserver_channel_temp_delete_delay_default = 60; this.virtualserver_priority_speaker_dimm_modificator = -18; this.virtualserver_max_upload_total_bandwidth = 0; this.virtualserver_upload_quota = 0; this.virtualserver_max_download_total_bandwidth = 0; this.virtualserver_download_quota = 0; this.virtualserver_month_bytes_downloaded = 0; this.virtualserver_month_bytes_uploaded = 0; this.virtualserver_total_bytes_downloaded = 0; this.virtualserver_total_bytes_uploaded = 0; } } class ServerEntry { constructor(tree, name, address) { this.info_request_promise = undefined; this.info_request_promise_resolve = undefined; this.info_request_promise_reject = undefined; this.lastInfoRequest = 0; this.nextInfoRequest = 0; this._destroyed = false; this.properties = new ServerProperties(); this.channelTree = tree; this.remote_address = Object.assign({}, address); /* close the address because it might get changed due to the DNS resolve */ this.properties.virtualserver_name = name; } get htmlTag() { if (this._destroyed) throw "destoryed"; if (this._htmlTag) return this._htmlTag; let tag = $.spawn("div").addClass("tree-entry server"); /* unread marker */ { tag.append($.spawn("div") .addClass("marker-text-unread hidden") .attr("conversation", 0)); } tag.append($.spawn("div") .addClass("server_type icon client-server_green")); tag.append($.spawn("div") .addClass("name") .text(this.properties.virtualserver_name)); tag.append($.spawn("div") .addClass("icon_property icon_empty")); return this._htmlTag = tag; } destroy() { this._destroyed = true; if (this._htmlTag) { this._htmlTag.remove(); this._htmlTag = undefined; } this.info_request_promise = undefined; this.info_request_promise_resolve = undefined; this.info_request_promise_reject = undefined; this.channelTree = undefined; this.remote_address = undefined; } initializeListener() { this._htmlTag.on('click', () => { this.channelTree.onSelect(this); this.updateProperties(); /* just prepare to show some server info */ }); if (!settings.static(Settings.KEY_DISABLE_CONTEXT_MENU, false)) { this.htmlTag.on("contextmenu", (event) => { event.preventDefault(); if ($.isArray(this.channelTree.currently_selected)) { //Multiselect (this.channelTree.currently_selected_context_callback || ((_) => null))(event); return; } this.channelTree.onSelect(this, true); this.spawnContextMenu(event.pageX, event.pageY, () => { this.channelTree.onSelect(undefined, true); }); }); } } spawnContextMenu(x, y, on_close = () => { }) { let trigger_close = true; contextmenu.spawn_context_menu(x, y, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.xl5h3fOx || (_translations.xl5h3fOx = tr("Show server info")), callback: () => { trigger_close = false; Modals.openServerInfo(this); }, icon_class: "client-about" }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-invite_buddy", name: _translations.n60We1tw || (_translations.n60We1tw = tr("Invite buddy")), callback: () => Modals.spawnInviteEditor(this.channelTree.client) }, { type: contextmenu.MenuEntryType.HR, name: '' }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_switch", name: _translations.xTkdlACq || (_translations.xTkdlACq = tr("Join server text channel")), callback: () => { this.channelTree.client.side_bar.channel_conversations().set_current_channel(0); this.channelTree.client.side_bar.show_channel_conversations(); }, visible: !settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT) }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-virtualserver_edit", name: _translations.dKIgGTUq || (_translations.dKIgGTUq = tr("Edit")), callback: () => { Modals.createServerModal(this, properties => { log.info(LogCategory.SERVER, _translations.zjiyeNdR || (_translations.zjiyeNdR = tr("Changing server properties %o")), properties); console.log(_translations.simVGxCY || (_translations.simVGxCY = tr("Changed properties: %o")), properties); if (properties) { if (Object.keys(properties)) { return this.channelTree.client.serverConnection.send_command("serveredit", properties).then(() => { this.channelTree.client.sound.play(Sound.SERVER_EDITED_SELF); }); } } return Promise.resolve(); }); } }, { type: contextmenu.MenuEntryType.HR, visible: true, name: '' }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-iconviewer", name: _translations.MKb9CCNC || (_translations.MKb9CCNC = tr("View icons")), callback: () => Modals.spawnIconSelect(this.channelTree.client) }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: 'client-iconsview', name: _translations.aUKw1raS || (_translations.aUKw1raS = tr("View avatars")), visible: false, callback: () => Modals.spawnAvatarList(this.channelTree.client) }, contextmenu.Entry.CLOSE(() => trigger_close ? on_close() : {})); } updateVariables(is_self_notify, ...variables) { let group = log.group(log.LogType.DEBUG, LogCategory.SERVER, _translations.CDsTVwgK || (_translations.CDsTVwgK = tr("Update properties (%i)")), variables.length); { const entries = []; for (const variable of variables) entries.push({ key: variable.key, value: variable.value, type: typeof (this.properties[variable.key]) }); log.table(LogType.DEBUG, LogCategory.PERMISSIONS, "Server update properties", entries); } let update_bannner = false, update_button = false; for (let variable of variables) { JSON.map_field_to(this.properties, variable.value, variable.key); if (variable.key == "virtualserver_name") { this.htmlTag.find(".name").text(variable.value); this.channelTree.client.tag_connection_handler.find(".server-name").text(variable.value); server_connections.update_ui(); } else if (variable.key == "virtualserver_icon_id") { /* For more detail lookup client::updateVariables and client_icon_id! * ATTENTION: This is required! */ this.properties.virtualserver_icon_id = variable.value >>> 0; const bmarks = bookmarks.bookmarks_flat() .filter(e => e.server_properties.server_address === this.remote_address.host && e.server_properties.server_port == this.remote_address.port) .filter(e => e.last_icon_id !== this.properties.virtualserver_icon_id); if (bmarks.length > 0) { bmarks.forEach(e => { e.last_icon_id = this.properties.virtualserver_icon_id; }); bookmarks.save_bookmark(); top_menu.rebuild_bookmarks(); control_bar.update_bookmarks(); } if (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")); } else if (variable.key.indexOf('hostbanner') != -1) { update_bannner = true; } else if (variable.key.indexOf('hostbutton') != -1) { update_button = true; } } if (update_bannner) this.channelTree.client.hostbanner.update(); if (update_button) if (control_bar.current_connection_handler() === this.channelTree.client) control_bar.apply_server_hostbutton(); group.end(); if (is_self_notify && this.info_request_promise_resolve) { this.info_request_promise_resolve(); this.info_request_promise = undefined; this.info_request_promise_reject = undefined; this.info_request_promise_resolve = undefined; } connection_log.update_address_info({ hostname: this.remote_address.host, port: this.remote_address.port }, { clients_online: this.properties.virtualserver_clientsonline, clients_total: this.properties.virtualserver_maxclients, country: this.properties.virtualserver_country_code, flag_password: this.properties.virtualserver_flag_password, name: this.properties.virtualserver_name, icon_id: this.properties.virtualserver_icon_id, password_hash: undefined /* we've here no clue */ }); } /* this result !must! be cached for at least a second */ updateProperties() { if (this.info_request_promise && Date.now() - this.lastInfoRequest < 1000) return this.info_request_promise; this.lastInfoRequest = Date.now(); this.nextInfoRequest = this.lastInfoRequest + 10 * 1000; this.channelTree.client.serverConnection.send_command("servergetvariables").catch(error => { this.info_request_promise_reject(error); this.info_request_promise = undefined; this.info_request_promise_reject = undefined; this.info_request_promise_resolve = undefined; }); return this.info_request_promise = new Promise((resolve, reject) => { this.info_request_promise_reject = reject; this.info_request_promise_resolve = resolve; }); } /* max 1s ago, so we could update every second */ request_connection_info() { if (Date.now() - 900 < this._info_connection_promise_timestamp && this._info_connection_promise) return this._info_connection_promise; if (this._info_connection_promise_reject) this._info_connection_promise_resolve("timeout"); let _local_reject; /* to ensure we're using the right resolve! */ this._info_connection_promise = new Promise((resolve, reject) => { this._info_connection_promise_resolve = resolve; this._info_connection_promise_reject = reject; _local_reject = reject; }); this._info_connection_promise_timestamp = Date.now(); this.channelTree.client.serverConnection.send_command("serverrequestconnectioninfo", {}, { process_result: false }).catch(error => _local_reject(error)); return this._info_connection_promise; } set_connection_info(info) { if (!this._info_connection_promise_resolve) return; this._info_connection_promise_resolve(info); this._info_connection_promise_resolve = undefined; this._info_connection_promise_reject = undefined; } shouldUpdateProperties() { return this.nextInfoRequest < Date.now(); } calculateUptime() { if (this.properties.virtualserver_uptime == 0 || this.lastInfoRequest == 0) return this.properties.virtualserver_uptime; return this.properties.virtualserver_uptime + (new Date().getTime() - this.lastInfoRequest) / 1000; } set flag_text_unread(flag) { this._htmlTag.find(".marker-text-unread").toggleClass("hidden", !flag); } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5e6667919c371c71e6b16bc446ba82c5a2073d295e0e7274d5af19bf6357bc7c"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5e6667919c371c71e6b16bc446ba82c5a2073d295e0e7274d5af19bf6357bc7c"] = "5e6667919c371c71e6b16bc446ba82c5a2073d295e0e7274d5af19bf6357bc7c"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "m49fBygK", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (98,46)" }, { name: "wwys9akP", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (241,30)" }, { name: "i7HT3n9l", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (241,58)" }, { name: "CSYw4ecH", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (255,37)" }, { name: "OpoQAmLI", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (255,57)" }, { name: "pLzs3OvD", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (259,30)" }, { name: "I6qHm5Vw", path: "D:/TeaSpeak/web/shared/js/bookmarks.ts (259,62)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var bookmarks; (function (bookmarks_1) { function guid() { function s4() { return Math .floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } bookmarks_1.boorkmak_connect = (mark, new_tab) => { const profile = profiles.find_profile(mark.connect_profile) || profiles.default_profile(); if (profile.valid()) { const connection = (typeof (new_tab) !== "boolean" || !new_tab) ? server_connections.active_connection_handler() : server_connections.spawn_server_connection_handler(); server_connections.set_active_connection_handler(connection); connection.startConnection(mark.server_properties.server_address + ":" + mark.server_properties.server_port, profile, true, { nickname: mark.nickname === "Another TeaSpeak user" || !mark.nickname ? profile.connect_username() : mark.nickname, password: mark.server_properties.server_password_hash ? { password: mark.server_properties.server_password_hash, hashed: true } : mark.server_properties.server_password ? { hashed: false, password: mark.server_properties.server_password } : undefined }); } else { Modals.spawnConnectModal({}, { url: mark.server_properties.server_address + ":" + mark.server_properties.server_port, enforce: true }, { profile: profile, enforce: true }); } }; let BookmarkType; (function (BookmarkType) { BookmarkType[BookmarkType["ENTRY"] = 0] = "ENTRY"; BookmarkType[BookmarkType["DIRECTORY"] = 1] = "DIRECTORY"; })(BookmarkType = bookmarks_1.BookmarkType || (bookmarks_1.BookmarkType = {})); let _bookmark_config; function bookmark_config() { if (_bookmark_config) return _bookmark_config; let bookmark_json = localStorage.getItem("bookmarks"); let bookmarks; try { bookmarks = JSON.parse(bookmark_json) || {}; } catch (error) { log.error(LogCategory.BOOKMARKS, _translations.m49fBygK || (_translations.m49fBygK = tr("Failed to load bookmarks: %o")), error); bookmarks = {}; } _bookmark_config = bookmarks; _bookmark_config.root_bookmark = _bookmark_config.root_bookmark || { content: [], display_name: "root", type: BookmarkType.DIRECTORY }; if (!_bookmark_config.default_added) { _bookmark_config.default_added = true; create_bookmark("TeaSpeak official Test-Server", _bookmark_config.root_bookmark, { server_address: "ts.teaspeak.de", server_port: 9987 }, undefined); save_config(); } const fix_parent = (parent, entry) => { entry.parent = parent; if (entry.type === BookmarkType.DIRECTORY) for (const child of entry.content) fix_parent(entry, child); }; for (const entry of _bookmark_config.root_bookmark.content) fix_parent(_bookmark_config.root_bookmark, entry); return _bookmark_config; } function save_config() { localStorage.setItem("bookmarks", JSON.stringify(bookmark_config(), (key, value) => { if (key === "parent") return undefined; return value; })); } function bookmarks() { return bookmark_config().root_bookmark; } bookmarks_1.bookmarks = bookmarks; function bookmarks_flat() { const result = []; const _flat = (bookmark) => { if (bookmark.type == BookmarkType.DIRECTORY) for (const book of bookmark.content) _flat(book); else result.push(bookmark); }; _flat(bookmark_config().root_bookmark); return result; } bookmarks_1.bookmarks_flat = bookmarks_flat; function find_bookmark_recursive(parent, uuid) { for (const entry of parent.content) { if (entry.unique_id == uuid) return entry; if (entry.type == BookmarkType.DIRECTORY) { const result = find_bookmark_recursive(entry, uuid); if (result) return result; } } return undefined; } function find_bookmark(uuid) { return find_bookmark_recursive(bookmarks(), uuid); } bookmarks_1.find_bookmark = find_bookmark; function parent_bookmark(bookmark) { const books = [bookmarks()]; while (!books.length) { const directory = books.pop_front(); if (directory.type == BookmarkType.DIRECTORY) { const cast = directory; if (cast.content.indexOf(bookmark) != -1) return cast; books.push(...cast.content); } } return bookmarks(); } bookmarks_1.parent_bookmark = parent_bookmark; function create_bookmark(display_name, directory, server_properties, nickname) { const bookmark = { display_name: display_name, server_properties: server_properties, nickname: nickname, type: BookmarkType.ENTRY, connect_profile: "default", unique_id: guid(), parent: directory }; directory.content.push(bookmark); return bookmark; } bookmarks_1.create_bookmark = create_bookmark; function create_bookmark_directory(parent, name) { const bookmark = { type: BookmarkType.DIRECTORY, display_name: name, content: [], unique_id: guid(), parent: parent }; parent.content.push(bookmark); return bookmark; } bookmarks_1.create_bookmark_directory = create_bookmark_directory; //TODO test if the new parent is within the old bookmark function change_directory(parent, bookmark) { delete_bookmark(bookmark); parent.content.push(bookmark); } bookmarks_1.change_directory = change_directory; function save_bookmark(bookmark) { save_config(); /* nvm we dont give a fuck... saving everything */ } bookmarks_1.save_bookmark = save_bookmark; function delete_bookmark_recursive(parent, bookmark) { const index = parent.content.indexOf(bookmark); if (index != -1) parent.content.remove(bookmark); else for (const entry of parent.content) if (entry.type == BookmarkType.DIRECTORY) delete_bookmark_recursive(entry, bookmark); } function delete_bookmark(bookmark) { delete_bookmark_recursive(bookmarks(), bookmark); } bookmarks_1.delete_bookmark = delete_bookmark; function add_current_server() { const ch = server_connections.active_connection_handler(); if (ch && ch.connected) { const ce = ch.getClient(); const name = ce ? ce.clientNickName() : undefined; createInputModal(_translations.wwys9akP || (_translations.wwys9akP = tr("Enter bookmarks name")), _translations.i7HT3n9l || (_translations.i7HT3n9l = tr("Please enter the bookmarks name:
")), text => text.length > 0, result => { if (result) { const bookmark = create_bookmark(result, bookmarks(), { server_port: ch.serverConnection.remote_address().port, server_address: ch.serverConnection.remote_address().host, server_password: "", server_password_hash: "" }, name); save_bookmark(bookmark); control_bar.update_bookmarks(); top_menu.rebuild_bookmarks(); createInfoModal(_translations.CSYw4ecH || (_translations.CSYw4ecH = tr("Server added")), _translations.OpoQAmLI || (_translations.OpoQAmLI = tr("Server has been successfully added to your bookmarks."))).open(); } }).open(); } else { createErrorModal(_translations.pLzs3OvD || (_translations.pLzs3OvD = tr("You have to be connected")), _translations.I6qHm5Vw || (_translations.I6qHm5Vw = tr("You have to be connected!"))).open(); } } bookmarks_1.add_current_server = add_current_server; })(bookmarks || (bookmarks = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["018fe975688693bb1725f14cbed0da456c9f39bf59179b3ef5c42e2f016eafb3"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["018fe975688693bb1725f14cbed0da456c9f39bf59179b3ef5c42e2f016eafb3"] = "018fe975688693bb1725f14cbed0da456c9f39bf59179b3ef5c42e2f016eafb3"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Ng2RgJmg", path: "D:/TeaSpeak/web/shared/js/ui/elements/context_menu.ts (58,27)" }, { name: "RN9mTViM", path: "D:/TeaSpeak/web/shared/js/ui/elements/context_menu.ts (94,31)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var contextmenu; (function (contextmenu) { let MenuEntryType; (function (MenuEntryType) { MenuEntryType[MenuEntryType["CLOSE"] = 0] = "CLOSE"; MenuEntryType[MenuEntryType["ENTRY"] = 1] = "ENTRY"; MenuEntryType[MenuEntryType["CHECKBOX"] = 2] = "CHECKBOX"; MenuEntryType[MenuEntryType["HR"] = 3] = "HR"; MenuEntryType[MenuEntryType["SUB_MENU"] = 4] = "SUB_MENU"; })(MenuEntryType = contextmenu.MenuEntryType || (contextmenu.MenuEntryType = {})); class Entry { static HR() { return { callback: () => { }, type: MenuEntryType.HR, name: "", icon: "" }; } ; static CLOSE(callback) { return { callback: callback, type: MenuEntryType.CLOSE, name: "", icon: "" }; } } contextmenu.Entry = Entry; let provider; function spawn_context_menu(x, y, ...entries) { if (!provider) { console.error(_translations.Ng2RgJmg || (_translations.Ng2RgJmg = tr("Failed to spawn context menu! Missing provider!"))); return; } provider.spawn_context_menu(x, y, ...entries); } contextmenu.spawn_context_menu = spawn_context_menu; function despawn_context_menu() { if (!provider) return; provider.despawn_context_menu(); } contextmenu.despawn_context_menu = despawn_context_menu; function get_provider() { return provider; } contextmenu.get_provider = get_provider; function set_provider(_provider) { provider = _provider; provider.initialize(); } contextmenu.set_provider = set_provider; })(contextmenu || (contextmenu = {})); class HTMLContextMenuProvider { constructor() { this._close_callbacks = []; this._visible = false; } despawn_context_menu() { if (!this._visible) return; let menu = this._context_menu || (this._context_menu = $(".context-menu")); menu.animate({ opacity: 0 }, 100, () => menu.css("display", "none")); this._visible = false; for (const callback of this._close_callbacks) { if (typeof (callback) !== "function") { console.error(_translations.RN9mTViM || (_translations.RN9mTViM = tr("Given close callback is not a function!. Callback: %o")), callback); continue; } callback(); } this._close_callbacks = []; } finalize() { $(document).unbind('click', this._global_click_listener); } initialize() { this._global_click_listener = this.on_global_click.bind(this); $(document).bind('click', this._global_click_listener); } on_global_click(event) { //let menu = this._context_menu || (this._context_menu = $(".context-menu")); if (!this._visible) return; if ($(event.target).parents(".context-menu").length == 0) { this.despawn_context_menu(); event.preventDefault(); } } generate_tag(entry) { if (entry.type == contextmenu.MenuEntryType.HR) { return $.spawn("hr"); } else if (entry.type == contextmenu.MenuEntryType.ENTRY) { let icon = entry.icon_class; if (!icon || icon.length == 0) icon = "icon_empty"; else icon = "icon " + icon; let tag = $.spawn("div").addClass("entry"); tag.append($.spawn("div").addClass(icon)); tag.append($.spawn("div").html($.isFunction(entry.name) ? entry.name() : entry.name)); if (entry.disabled || entry.invalidPermission) tag.addClass("disabled"); else { tag.on('click', () => { if ($.isFunction(entry.callback)) entry.callback(); entry.callback = undefined; /* for some reason despawn_context_menu() causes a second click event? */ this.despawn_context_menu(); }); } return tag; } else if (entry.type == contextmenu.MenuEntryType.CHECKBOX) { let checkbox = $.spawn("label").addClass("ccheckbox"); $.spawn("input").attr("type", "checkbox").prop("checked", !!entry.checkbox_checked).appendTo(checkbox); $.spawn("span").addClass("checkmark").appendTo(checkbox); let tag = $.spawn("div").addClass("entry"); tag.append(checkbox); tag.append($.spawn("div").html($.isFunction(entry.name) ? entry.name() : entry.name)); if (entry.disabled || entry.invalidPermission) tag.addClass("disabled"); else { tag.on('click', () => { if ($.isFunction(entry.callback)) entry.callback(); entry.callback = undefined; /* for some reason despawn_context_menu() causes a second click event? */ this.despawn_context_menu(); }); } return tag; } else if (entry.type == contextmenu.MenuEntryType.SUB_MENU) { let icon = entry.icon_class; if (!icon || icon.length == 0) icon = "icon_empty"; else icon = "icon " + icon; let tag = $.spawn("div").addClass("entry").addClass("sub-container"); tag.append($.spawn("div").addClass(icon)); tag.append($.spawn("div").html($.isFunction(entry.name) ? entry.name() : entry.name)); tag.append($.spawn("div").addClass("arrow right")); if (entry.disabled || entry.invalidPermission) tag.addClass("disabled"); else { let menu = $.spawn("div").addClass("sub-menu").addClass("context-menu-container"); for (const e of entry.sub_menu) { if (typeof (entry.visible) === 'boolean' && !entry.visible) continue; menu.append(this.generate_tag(e)); } menu.appendTo(tag); } return tag; } return $.spawn("div").text("undefined"); } spawn_context_menu(x, y, ...entries) { this._visible = true; let menu_tag = this._context_menu || (this._context_menu = $(".context-menu")); menu_tag.finish().empty().css("opacity", "0"); const menu_container = $.spawn("div").addClass("context-menu-container"); this._close_callbacks = []; for (const entry of entries) { if (typeof (entry.visible) === 'boolean' && !entry.visible) continue; if (entry.type == contextmenu.MenuEntryType.CLOSE) { if (entry.callback) this._close_callbacks.push(entry.callback); } else menu_container.append(this.generate_tag(entry)); } menu_tag.append(menu_container); menu_tag.animate({ opacity: 1 }, 100).css("display", "block"); const width = menu_container.visible_width(); if (x + width + 5 > window.innerWidth) menu_container.addClass("left"); // In the right position (the mouse) menu_tag.css({ "top": y + "px", "left": x + "px" }); } html_format_enabled() { return true; } } contextmenu.set_provider(new HTMLContextMenuProvider()); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["a1623e51d6c35dbe60874645b6eef1afcb564cc0ae6cd3c8ed09e710029bd1d4"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["a1623e51d6c35dbe60874645b6eef1afcb564cc0ae6cd3c8ed09e710029bd1d4"] = "a1623e51d6c35dbe60874645b6eef1afcb564cc0ae6cd3c8ed09e710029bd1d4"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "X2HpQ_9N", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (7,31)" }, { name: "RinYtSD0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (7,52)" }, { name: "M3qtba3_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (79,56)" }, { name: "XMi8o_cF", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (86,25)" }, { name: "JtIjuu6P", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (187,29)" }, { name: "QNuA03ZM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (423,33)" }, { name: "_AdLCqU0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (434,33)" }, { name: "F527rAOv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (467,33)" }, { name: "ljiyqr1d", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (480,33)" }, { name: "TKSMPptf", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (490,44)" }, { name: "I5FeAjFN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalCreateChannel.ts (506,56)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var Modals; (function (Modals) { function createChannelModal(connection, channel, parent, permissions, callback) { let properties = {}; //The changes properties const modal = createModal({ header: channel ? _translations.X2HpQ_9N || (_translations.X2HpQ_9N = tr("Edit channel")) : _translations.RinYtSD0 || (_translations.RinYtSD0 = tr("Create channel")), body: () => { const render_properties = {}; Object.assign(render_properties, channel ? channel.properties : { channel_flag_maxfamilyclients_unlimited: true, channel_flag_maxclients_unlimited: true, }); render_properties["channel_icon_tab"] = connection.fileManager.icons.generateTag(channel ? channel.properties.channel_icon_id : 0); render_properties["channel_icon_general"] = connection.fileManager.icons.generateTag(channel ? channel.properties.channel_icon_id : 0); render_properties["create"] = !channel; let template = $("#tmpl_channel_edit").renderTag(render_properties); /* the tab functionality */ { const container_tabs = template.find(".container-advanced"); container_tabs.find(".categories .entry").on('click', event => { const entry = $(event.target); container_tabs.find(".bodies > .body").addClass("hidden"); container_tabs.find(".categories > .selected").removeClass("selected"); entry.addClass("selected"); container_tabs.find(".bodies > .body." + entry.attr("container")).removeClass("hidden"); }); container_tabs.find(".entry").first().trigger('click'); } /* Advanced/normal switch */ { const input = template.find(".input-advanced-mode"); const container_mode = template.find(".mode-container"); const container_advanced = container_mode.find(".container-advanced"); const container_simple = container_mode.find(".container-simple"); input.on('change', event => { const advanced = input.prop("checked"); settings.changeGlobal(Settings.KEY_CHANNEL_EDIT_ADVANCED, advanced); container_mode.css("overflow", "hidden"); container_advanced.show().toggleClass("hidden", !advanced); container_simple.show().toggleClass("hidden", advanced); setTimeout(() => { container_advanced.toggle(advanced); container_simple.toggle(!advanced); container_mode.css("overflow", "visible"); }, 300); }).prop("checked", settings.static_global(Settings.KEY_CHANNEL_EDIT_ADVANCED)).trigger('change'); } return template.tabify().children(); /* the "render" div */ }, footer: null, width: 500 }); modal.htmlTag.find(".modal-body").addClass("modal-channel modal-blue"); applyGeneralListener(connection, properties, modal.htmlTag.find(".container-general"), modal.htmlTag.find(".button_ok"), channel); applyStandardListener(connection, properties, modal.htmlTag.find(".container-standard"), modal.htmlTag.find(".container-simple"), parent, channel); applyPermissionListener(connection, properties, modal.htmlTag.find(".container-permissions"), modal.htmlTag.find(".button_ok"), permissions, channel); applyAudioListener(connection, properties, modal.htmlTag.find(".container-audio"), modal.htmlTag.find(".container-simple"), channel); applyAdvancedListener(connection, properties, modal.htmlTag.find(".container-misc"), modal.htmlTag.find(".button_ok"), channel); let updated = []; modal.htmlTag.find(".button_ok").click(() => { modal.htmlTag.find(".container-permissions").find("input[permission]").each((index, _element) => { let element = $(_element); if (element.val() == element.attr("original-value")) return; let permission = permissions.resolveInfo(element.attr("permission")); if (!permission) { log.error(LogCategory.PERMISSIONS, _translations.M3qtba3_ || (_translations.M3qtba3_ = tr("Failed to resolve channel permission for name %o")), element.attr("permission")); element.prop("disabled", true); return; } updated.push(new PermissionValue(permission, element.val())); }); console.log(_translations.XMi8o_cF || (_translations.XMi8o_cF = tr("Updated permissions %o")), updated); }).click(() => { modal.close(); for (const key of Object.keys(channel ? channel.properties : {})) if (channel.properties[key] == properties[key]) delete properties[key]; callback(properties, updated); //First may create the channel }); tooltip(modal.htmlTag); modal.htmlTag.find(".button_cancel").click(() => { modal.close(); callback(); }); modal.open(); if (!channel) modal.htmlTag.find(".channel_name").focus(); } Modals.createChannelModal = createChannelModal; function applyGeneralListener(connection, properties, tag, button, channel) { let updateButton = () => { const status = tag.find(".input_error").length != 0; console.log("Disabled: %o", status); button.prop("disabled", status); }; { const channel_name = tag.find(".channel_name"); tag.find(".channel_name").on('change keyup', function () { properties.channel_name = this.value; channel_name.toggleClass("input_error", this.value.length < 1 || this.value.length > 40); updateButton(); }).prop("disabled", channel && !connection.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_NAME).granted(1)); } tag.find(".button-select-icon").on('click', event => { Modals.spawnIconSelect(connection, id => { const icon_node = tag.find(".icon-preview"); icon_node.children().remove(); icon_node.append(connection.fileManager.icons.generateTag(id)); console.log("Selected icon ID: %d", id); properties.channel_icon_id = id; }, channel ? channel.properties.channel_icon_id : 0); }); tag.find(".button-icon-remove").on('click', event => { const icon_node = tag.find(".icon-preview"); icon_node.children().remove(); icon_node.append(connection.fileManager.icons.generateTag(0)); console.log("Remove channel icon"); properties.channel_icon_id = 0; }); { const channel_password = tag.find(".channel_password"); tag.find(".channel_password").change(function () { properties.channel_flag_password = this.value.length != 0; if (properties.channel_flag_password) helpers.hashPassword(this.value).then(pass => properties.channel_password = pass); channel_password.removeClass("input_error"); if (!properties.channel_flag_password) if (connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_FORCE_PASSWORD).granted(1)) channel_password.addClass("input_error"); updateButton(); }).prop("disabled", !connection.permissions.neededPermission(!channel ? 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", !connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_TOPIC : PermissionType.B_CHANNEL_MODIFY_TOPIC).granted(1)); { const container = tag.find(".container-description"); const input = container.find("textarea"); const insert_tag = (open, close) => { if (input.prop("disabled")) return; const node = input[0]; if (node.selectionStart || node.selectionStart == 0) { const startPos = node.selectionStart; const endPos = node.selectionEnd; node.value = node.value.substring(0, startPos) + open + node.value.substring(startPos, endPos) + close + node.value.substring(endPos); node.selectionEnd = endPos + open.length; node.selectionStart = node.selectionEnd; } else { node.value += open + close; node.selectionEnd = node.value.length - close.length; node.selectionStart = node.selectionEnd; } input.focus().trigger('change'); }; input.on('change', event => { console.log(_translations.JtIjuu6P || (_translations.JtIjuu6P = tr("Channel description edited: %o")), input.val()); properties.channel_description = input.val(); }); container.find(".button-bold").on('click', () => insert_tag('[b]', '[/b]')); container.find(".button-italic").on('click', () => insert_tag('[i]', '[/i]')); container.find(".button-underline").on('click', () => insert_tag('[u]', '[/u]')); container.find(".button-color input").on('change', event => { insert_tag('[color=' + event.target.value + ']', '[/color]'); }); } tag.find(".channel_description").change(function () { properties.channel_description = this.value; }).prop("disabled", !connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_DESCRIPTION : PermissionType.B_CHANNEL_MODIFY_DESCRIPTION).granted(1)); if (!channel) { setTimeout(() => { tag.find(".channel_name").trigger("change"); tag.find(".channel_password").trigger('change'); }, 0); } } function applyStandardListener(connection, properties, tag, simple, parent, channel) { /* Channel type */ { const input_advanced_type = tag.find("input[name='channel_type']"); let _in_update = false; const update_simple_type = () => { if (_in_update) return; let type; if (properties.channel_flag_default || (typeof (properties.channel_flag_default) === "undefined" && channel && channel.properties.channel_flag_default)) type = "def"; else if (properties.channel_flag_permanent || (typeof (properties.channel_flag_permanent) === "undefined" && channel && channel.properties.channel_flag_permanent)) type = "perm"; else if (properties.channel_flag_semi_permanent || (typeof (properties.channel_flag_semi_permanent) === "undefined" && channel && channel.properties.channel_flag_semi_permanent)) type = "semi"; else type = "temp"; simple.find("option[name='channel-type'][value='" + type + "']").prop("selected", true); }; input_advanced_type.on('change', event => { const value = [...input_advanced_type].find(e => e.checked).value; switch (value) { case "semi": properties.channel_flag_permanent = false; properties.channel_flag_semi_permanent = true; break; case "perm": properties.channel_flag_permanent = true; properties.channel_flag_semi_permanent = false; break; default: properties.channel_flag_permanent = false; properties.channel_flag_semi_permanent = false; break; } update_simple_type(); }); const permission_temp = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_TEMPORARY : PermissionType.B_CHANNEL_MODIFY_MAKE_TEMPORARY).granted(1); const permission_semi = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT : PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT).granted(1); const permission_perm = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_PERMANENT : PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1); const permission_default = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_PERMANENT : PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1) && connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_DEFAULT : PermissionType.B_CHANNEL_MODIFY_MAKE_DEFAULT).granted(1); /* advanced type listeners */ const container_types = tag.find(".container-channel-type"); const tag_type_temp = container_types.find(".type-temp"); const tag_type_semi = container_types.find(".type-semi"); const tag_type_perm = container_types.find(".type-perm"); const select_default = tag.find(".input-flag-default"); { select_default.on('change', event => { const node = select_default[0]; properties.channel_flag_default = node.checked; if (node.checked) tag_type_perm.find("input").prop("checked", true); tag_type_temp .toggleClass("disabled", node.checked || !permission_temp) .find("input").prop("disabled", node.checked || !permission_temp); tag_type_semi .toggleClass("disabled", node.checked || !permission_semi) .find("input").prop("disabled", node.checked || !permission_semi); tag_type_perm .toggleClass("disabled", node.checked || !permission_perm) .find("input").prop("disabled", node.checked || !permission_perm); update_simple_type(); }).prop("disabled", !permission_default).trigger('change').parent().toggleClass("disabled", !permission_default); } /* simple */ { simple.find("option[name='channel-type'][value='def']").prop("disabled", !permission_default); simple.find("option[name='channel-type'][value='perm']").prop("disabled", !permission_perm); simple.find("option[name='channel-type'][value='semi']").prop("disabled", !permission_semi); simple.find("option[name='channel-type'][value='temp']").prop("disabled", !permission_temp); simple.find("select[name='channel-type']").on('change', event => { try { _in_update = true; switch (event.target.value) { case "temp": properties.channel_flag_permanent = false; properties.channel_flag_semi_permanent = false; properties.channel_flag_default = false; select_default.prop("checked", false).trigger('change'); tag_type_temp.trigger('click'); break; case "semi": properties.channel_flag_permanent = false; properties.channel_flag_semi_permanent = true; properties.channel_flag_default = false; select_default.prop("checked", false).trigger('change'); tag_type_semi.trigger('click'); break; case "perm": properties.channel_flag_permanent = true; properties.channel_flag_semi_permanent = false; properties.channel_flag_default = false; select_default.prop("checked", false).trigger('change'); tag_type_perm.trigger('click'); break; case "def": properties.channel_flag_permanent = true; properties.channel_flag_semi_permanent = false; properties.channel_flag_default = true; select_default.prop("checked", true).trigger('change'); break; } } finally { _in_update = false; /* We dont need to update the simple type because we changed the advanced part to the just changed simple part */ //update_simple_type(); } }); } /* init */ setTimeout(() => { if (!channel) { if (permission_perm) tag_type_perm.find("input").trigger('click'); else if (permission_semi) tag_type_semi.find("input").trigger('click'); else tag_type_temp.find("input").trigger('click'); } else { if (channel.properties.channel_flag_permanent) tag_type_perm.find("input").trigger('click'); else if (channel.properties.channel_flag_semi_permanent) tag_type_semi.find("input").trigger('click'); else tag_type_temp.find("input").trigger('click'); } }, 0); } /* Talk power */ { const permission = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_NEEDED_TALK_POWER : PermissionType.B_CHANNEL_MODIFY_NEEDED_TALK_POWER).granted(1); const input_advanced = tag.find("input[name='talk_power']").prop("disabled", !permission); const input_simple = simple.find("input[name='talk_power']").prop("disabled", !permission); input_advanced.on('change', event => { properties.channel_needed_talk_power = parseInt(input_advanced.val()); input_simple.val(input_advanced.val()); }); input_simple.on('change', event => { properties.channel_needed_talk_power = parseInt(input_simple.val()); input_advanced.val(input_simple.val()); }); } /* Channel order */ { const permission = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_SORTORDER : PermissionType.B_CHANNEL_MODIFY_SORTORDER).granted(1); const advanced_order_id = tag.find(".order_id").prop("disabled", !permission); const simple_order_id = simple.find(".order_id").prop("disabled", !permission); for (let previous_channel of (parent ? parent.children() : connection.channelTree.rootChannel())) { let selected = channel && channel.properties.channel_order == previous_channel.channelId; $.spawn("option").attr("channelId", previous_channel.channelId.toString()).prop("selected", selected).text(previous_channel.channelName()).appendTo(advanced_order_id); $.spawn("option").attr("channelId", previous_channel.channelId.toString()).prop("selected", selected).text(previous_channel.channelName()).appendTo(simple_order_id); } advanced_order_id.on('change', event => { simple_order_id[0].selectedIndex = advanced_order_id[0].selectedIndex; const selected = $(advanced_order_id[0].options.item(advanced_order_id[0].selectedIndex)); properties.channel_order = parseInt(selected.attr("channelId")); }); simple_order_id.on('change', event => { advanced_order_id[0].selectedIndex = simple_order_id[0].selectedIndex; const selected = $(simple_order_id[0].options.item(simple_order_id[0].selectedIndex)); properties.channel_order = parseInt(selected.attr("channelId")); }); } /* Advanced only */ { const container_max_users = tag.find(".container-max-users"); const container_unlimited = container_max_users.find(".container-unlimited"); const container_limited = container_max_users.find(".container-limited"); const input_unlimited = container_unlimited.find("input[value='unlimited']"); const input_limited = container_limited.find("input[value='limited']"); const input_limit = container_limited.find(".channel_maxclients"); const permission = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_MAXCLIENTS : PermissionType.B_CHANNEL_MODIFY_MAXCLIENTS).granted(1); if (!permission) { input_unlimited.prop("disabled", true); input_limited.prop("disabled", true); input_limit.prop("disabled", true); container_limited.addClass("disabled"); container_unlimited.addClass("disabled"); } else { container_max_users.find("input[name='max_users']").on('change', event => { const node = event.target; console.log(_translations.QNuA03ZM || (_translations.QNuA03ZM = tr("Channel max user mode: %o")), node.value); const flag = node.value === "unlimited"; input_limit .prop("disabled", flag) .parent().toggleClass("disabled", flag); properties.channel_flag_maxclients_unlimited = flag; }); input_limit.on('change', event => { properties.channel_maxclients = parseInt(input_limit.val()); console.log(_translations._AdLCqU0 || (_translations._AdLCqU0 = tr("Changed max user limit to %o")), properties.channel_maxclients); }); setTimeout(() => container_max_users.find("input:checked").trigger('change'), 100); } } { const container_max_users = tag.find(".container-max-family-users"); const container_unlimited = container_max_users.find(".container-unlimited"); const container_inherited = container_max_users.find(".container-inherited"); const container_limited = container_max_users.find(".container-limited"); const input_unlimited = container_unlimited.find("input[value='unlimited']"); const input_inherited = container_inherited.find("input[value='inherited']"); const input_limited = container_limited.find("input[value='limited']"); const input_limit = container_limited.find(".channel_maxfamilyclients"); const permission = connection.permissions.neededPermission(!channel ? PermissionType.B_CHANNEL_CREATE_WITH_MAXCLIENTS : PermissionType.B_CHANNEL_MODIFY_MAXCLIENTS).granted(1); if (!permission) { input_unlimited.prop("disabled", true); input_inherited.prop("disabled", true); input_limited.prop("disabled", true); input_limit.prop("disabled", true); container_limited.addClass("disabled"); container_unlimited.addClass("disabled"); container_inherited.addClass("disabled"); } else { container_max_users.find("input[name='max_family_users']").on('change', event => { const node = event.target; console.log(_translations.F527rAOv || (_translations.F527rAOv = tr("Channel max family user mode: %o")), node.value); const flag_unlimited = node.value === "unlimited"; const flag_inherited = node.value === "inherited"; input_limit .prop("disabled", flag_unlimited || flag_inherited) .parent().toggleClass("disabled", flag_unlimited || flag_inherited); properties.channel_flag_maxfamilyclients_unlimited = flag_unlimited; properties.channel_flag_maxfamilyclients_inherited = flag_inherited; }); input_limit.on('change', event => { properties.channel_maxfamilyclients = parseInt(input_limit.val()); console.log(_translations.ljiyqr1d || (_translations.ljiyqr1d = tr("Changed max family user limit to %o")), properties.channel_maxfamilyclients); }); setTimeout(() => container_max_users.find("input:checked").trigger('change'), 100); } } } function applyPermissionListener(connection, properties, tag, button, permissions, channel) { let apply_permissions = (channel_permissions) => { log.trace(LogCategory.CHANNEL, _translations.TKSMPptf || (_translations.TKSMPptf = tr("Received channel permissions: %o")), channel_permissions); let required_power = -2; for (let cperm of channel_permissions) if (cperm.type.name == PermissionType.I_CHANNEL_NEEDED_MODIFY_POWER) { required_power = cperm.value; break; } tag.find("input[permission]").each((index, _element) => { let element = $(_element); element.attr("original-value", 0); element.val(0); let permission = permissions.resolveInfo(element.attr("permission")); if (!permission) { log.error(LogCategory.PERMISSIONS, _translations.I5FeAjFN || (_translations.I5FeAjFN = tr("Failed to resolve channel permission for name %o")), element.attr("permission")); element.prop("disabled", true); return; } for (let cperm of channel_permissions) if (cperm.type == permission) { element.val(cperm.value); element.attr("original-value", cperm.value); return; } }); const permission = permissions.neededPermission(PermissionType.I_CHANNEL_PERMISSION_MODIFY_POWER).granted(required_power, false); tag.find("input[permission]").prop("disabled", !permission).parent(".input-boxed").toggleClass("disabled", !permission); //No permissions }; if (channel) { permissions.requestChannelPermissions(channel.getChannelId()).then(apply_permissions).catch((error) => { tag.find("input[permission]").prop("disabled", true); console.log("Failed to receive channel permissions (%o)", error); }); } else apply_permissions([]); } function applyAudioListener(connection, properties, tag, simple, channel) { const bandwidth_mapping = [ /* SPEEX narrow */ [2.49, 2.69, 2.93, 3.17, 3.17, 3.56, 3.56, 4.05, 4.05, 4.44, 5.22], /* SPEEX wide */ [2.69, 2.93, 3.17, 3.42, 3.76, 4.25, 4.74, 5.13, 5.62, 6.40, 7.37], /* SPEEX ultra */ [2.73, 3.12, 3.37, 3.61, 4.00, 4.49, 4.93, 5.32, 5.81, 6.59, 7.57], /* CELT */ [6.10, 6.10, 7.08, 7.08, 7.08, 8.06, 8.06, 8.06, 8.06, 10.01, 13.92], /* Opus Voice */ [2.73, 3.22, 3.71, 4.20, 4.74, 5.22, 5.71, 6.20, 6.74, 7.23, 7.71], /* Opus Music */ [3.08, 3.96, 4.83, 5.71, 6.59, 7.47, 8.35, 9.23, 10.11, 10.99, 11.87] ]; let update_template = () => { let codec = properties.channel_codec; if (!codec && channel) codec = channel.properties.channel_codec; if (!codec) return; let quality = properties.channel_codec_quality; if (!quality && channel) quality = channel.properties.channel_codec_quality; if (!quality) return; let template_name = "custom"; { if (codec == 4 && quality == 4) template_name = "voice_mobile"; else if (codec == 4 && quality == 6) template_name = "voice_desktop"; else if (codec == 5 && quality == 6) template_name = "music"; } tag.find("input[name='voice_template'][value='" + template_name + "']").prop("checked", true); simple.find("option[name='voice_template'][value='" + template_name + "']").prop("selected", true); let bandwidth; if (codec < 0 || codec > bandwidth_mapping.length) bandwidth = 0; else bandwidth = bandwidth_mapping[codec][quality] || 0; /* OOB access results in undefined, but is allowed */ tag.find(".container-needed-bandwidth").text(bandwidth.toFixed(2) + " KiB/s"); }; let change_codec = codec => { if (properties.channel_codec == codec) return; tag.find(".voice_codec option").prop("selected", false).eq(codec).prop("selected", true); properties.channel_codec = codec; update_template(); }; const container_quality = tag.find(".container-quality"); const slider_quality = sliderfy(container_quality.find(".container-slider"), { initial_value: properties.channel_codec_quality || 6, unit: "", min_value: 1, max_value: 10, step: 1, value_field: container_quality.find(".container-value") }); let change_quality = (quality) => { if (properties.channel_codec_quality == quality) return; properties.channel_codec_quality = quality; slider_quality.value(quality); update_template(); }; container_quality.find(".container-slider").on('change', event => { properties.channel_codec_quality = slider_quality.value(); update_template(); }); tag.find("input[name='voice_template']").change(function () { switch (this.value) { case "custom": break; case "music": change_codec(5); change_quality(6); break; case "voice_desktop": change_codec(4); change_quality(6); break; case "voice_mobile": change_codec(4); change_quality(4); break; } }); simple.find("select[name='voice_template']").change(function () { switch (this.value) { case "custom": break; case "music": change_codec(5); change_quality(6); break; case "voice_desktop": change_codec(4); change_quality(6); break; case "voice_mobile": change_codec(4); change_quality(4); break; } }); /* disable not granted templates */ { tag.find("input[name='voice_template'][value='voice_mobile']") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE).granted(1)); simple.find("option[name='voice_template'][value='voice_mobile']") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE).granted(1)); tag.find("input[name='voice_template'][value=\"voice_desktop\"]") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE).granted(1)); simple.find("option[name='voice_template'][value=\"voice_desktop\"]") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE).granted(1)); tag.find("input[name='voice_template'][value=\"music\"]") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSMUSIC).granted(1)); simple.find("option[name='voice_template'][value=\"music\"]") .prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSMUSIC).granted(1)); } let codecs = tag.find(".voice_codec option"); codecs.eq(0).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX8).granted(1)); codecs.eq(1).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX16).granted(1)); codecs.eq(2).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_SPEEX32).granted(1)); codecs.eq(3).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_CELTMONO48).granted(1)); codecs.eq(4).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSVOICE).granted(1)); codecs.eq(5).prop("disabled", !connection.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_CODEC_OPUSMUSIC).granted(1)); tag.find(".voice_codec").change(function () { if ($(this.item(this.selectedIndex)).prop("disabled")) return false; change_codec(this.selectedIndex); }); if (!channel) { change_codec(4); change_quality(6); } else { change_codec(channel.properties.channel_codec); change_quality(channel.properties.channel_codec_quality); } update_template(); } function applyAdvancedListener(connection, properties, tag, button, channel) { tag.find(".channel_name_phonetic").change(function () { properties.channel_topic = this.value; }); { const permission = connection.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_TEMP_DELETE_DELAY).granted(1); tag.find(".channel_delete_delay").change(function () { properties.channel_delete_delay = parseInt(this.value); }).prop("disabled", !permission).parent(".input-boxed").toggleClass("disabled", !permission); } { tag.find(".button-delete-max").on('click', event => { const power = connection.permissions.neededPermission(PermissionType.I_CHANNEL_CREATE_MODIFY_WITH_TEMP_DELETE_DELAY).value; let value = power == -2 ? 0 : power == -1 ? (7 * 24 * 60 * 60) : power; tag.find(".channel_delete_delay").val(value).trigger('change'); }); } { const permission = connection.permissions.neededPermission(PermissionType.B_CHANNEL_MODIFY_MAKE_CODEC_ENCRYPTED).granted(1); tag.find(".channel_codec_is_unencrypted").change(function () { properties.channel_codec_is_unencrypted = parseInt(this.value) == 0; }).prop("disabled", !permission).parent(".input-boxed").toggleClass("disabled", !permission); } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["d35da4bcda041ba972f8c87abdaa890518d6cde71d37e7f860e12e42688c97ce"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["d35da4bcda041ba972f8c87abdaa890518d6cde71d37e7f860e12e42688c97ce"] = "d35da4bcda041ba972f8c87abdaa890518d6cde71d37e7f860e12e42688c97ce"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "h0T6RPkj", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (129,23)" }, { name: "GFlIOGAL", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (264,27)" }, { name: "UCLC4ivJ", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (351,45)" }, { name: "ZrJ02URc", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (532,21)" }, { name: "HSzvJwwR", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (535,21)" }, { name: "Ody_8yeT", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (545,23)" }, { name: "ATXAwxWL", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (547,38)" }, { name: "vsK8laF1", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (547,58)" }, { name: "jMleGq7P", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (563,19)" }, { name: "fkTEx1Wh", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (578,23)" }, { name: "SlAO2UCb", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (580,38)" }, { name: "beWd2uCp", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (580,71)" }, { name: "Utc4LAwu", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (598,27)" }, { name: "hPN4f_xI", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (600,42)" }, { name: "jhZR81Qh", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (600,74)" }, { name: "Y10NXL7W", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (615,27)" }, { name: "CMX4tuF2", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (641,27)" }, { name: "u_LRSiVw", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (647,90)" }, { name: "O6jNMfCB", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (649,43)" }, { name: "yFR88s_P", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (712,44)" }, { name: "rAA5IByZ", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (716,52)" }, { name: "Fh5FtgZp", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (890,34)" }, { name: "pBoepRGH", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (894,26)" }, { name: "hSPoFqAs", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (911,34)" }, { name: "rbZFNFYt", path: "D:/TeaSpeak/web/shared/js/ui/view.ts (915,26)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /// /// /// /// /// /// class ChannelTree { constructor(client) { this.channels = []; this.clients = []; this.currently_selected = undefined; this.currently_selected_context_callback = undefined; this._tree_detached = false; this._focused = false; this._reorder_channels = new Set(); this.client = client; this._tag_container = $.spawn("div").addClass("channel-tree-container"); this._tag_entries = $.spawn("div").addClass("channel-tree"); this.client_mover = new ClientMover(this); this.reset(); if (!settings.static(Settings.KEY_DISABLE_CONTEXT_MENU, false)) { this._tag_container.on("contextmenu", (event) => { if (event.isDefaultPrevented()) return; for (const element of document.elementsFromPoint(event.pageX, event.pageY)) if (element.classList.contains("channelLine") || element.classList.contains("client")) return; event.preventDefault(); if ($.isArray(this.currently_selected)) { //Multiselect (this.currently_selected_context_callback || ((_) => null))(event); } else { this.onSelect(undefined); this.showContextMenu(event.pageX, event.pageY); } }); } this._tag_container.on('resize', this.handle_resized.bind(this)); this._listener_document_key = event => this.handle_key_press(event); this._listener_document_click = event => { this._focused = false; let element = event.target; while (element) { if (element === this._tag_container[0]) { this._focused = true; break; } element = element.parentNode; } }; document.addEventListener('click', this._listener_document_click); document.addEventListener('keydown', this._listener_document_key); } tag_tree() { return this._tag_container; } destroy() { this._listener_document_click && document.removeEventListener('click', this._listener_document_click); this._listener_document_click = undefined; this._listener_document_key && document.removeEventListener('keydown', this._listener_document_key); this._listener_document_key = undefined; if (this.server) { this.server.destroy(); this.server = undefined; } this.reset(); /* cleanup channel and clients */ this.channel_first = undefined; this.channel_last = undefined; this._tag_container.remove(); this.currently_selected = undefined; this.currently_selected_context_callback = undefined; } hide_channel_tree() { this._tag_entries.detach(); this._tree_detached = true; } show_channel_tree() { this._tree_detached = false; this._tag_entries.appendTo(this._tag_container); this.channels.forEach(e => { e.recalculate_repetitive_name(); e.reorderClients(); }); } showContextMenu(x, y, on_close = undefined) { 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); contextmenu.spawn_context_menu(x, y, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-channel_create", name: _translations.h0T6RPkj || (_translations.h0T6RPkj = tr("Create channel")), invalidPermission: !channelCreate, callback: () => this.spawnCreateChannel() }, contextmenu.Entry.CLOSE(on_close)); } initialiseHead(serverName, address) { if (this.server) { this.server.destroy(); this.server = undefined; } this.server = new ServerEntry(this, serverName, address); this.server.htmlTag.appendTo(this._tag_entries); this.server.initializeListener(); } __deleteAnimation(element) { let tag = element instanceof ChannelEntry ? element.rootTag() : element.tag; tag.fadeOut("slow", () => { tag.detach(); element.destroy(); }); } rootChannel() { return this.channels.filter(e => e.parent == undefined); } deleteChannel(channel) { const _this = this; for (let index = 0; index < this.channels.length; index++) { let entry = this.channels[index]; let currentEntry = this.channels[index]; while (currentEntry != undefined && currentEntry != null) { if (currentEntry == channel) { _this.channels.remove(entry); _this.__deleteAnimation(entry); entry.channelTree = null; index--; break; } else currentEntry = currentEntry.parent_channel(); } } this.channels.remove(channel); this.__deleteAnimation(channel); channel.channelTree = null; if (channel.channel_previous) channel.channel_previous.channel_next = channel.channel_next; if (channel.channel_next) channel.channel_next.channel_previous = channel.channel_previous; if (channel == this.channel_first) this.channel_first = channel.channel_next; if (channel == this.channel_last) this.channel_last = channel.channel_previous; } insertChannel(channel) { channel.channelTree = this; this.channels.push(channel); let elm = undefined; let tag = this._tag_entries; let previous_channel = null; if (channel.hasParent()) { let parent = channel.parent_channel(); let siblings = parent.children(); if (siblings.length == 0) { elm = parent.rootTag(); previous_channel = null; } else { previous_channel = siblings.last(); elm = previous_channel.tag; } tag = parent.siblingTag(); } else { previous_channel = this.channel_last; if (!this.channel_last) this.channel_last = channel; if (!this.channel_first) this.channel_first = channel; } channel.channel_previous = previous_channel; channel.channel_next = undefined; if (previous_channel) { channel.channel_next = previous_channel.channel_next; previous_channel.channel_next = channel; if (channel.channel_next) channel.channel_next.channel_previous = channel; } let entry = channel.rootTag(); if (!this._tree_detached) entry.css({ display: "none" }).fadeIn("slow"); entry.appendTo(tag); if (elm != undefined) elm.after(entry); if (channel.channel_previous == channel) /* shall never happen */ channel.channel_previous = undefined; if (channel.channel_next == channel) /* shall never happen */ channel.channel_next = undefined; channel.initializeListener(); channel.update_family_index(); } findChannel(channelId) { for (let index = 0; index < this.channels.length; index++) if (this.channels[index].getChannelId() == channelId) return this.channels[index]; return undefined; } find_channel_by_name(name, parent, force_parent = true) { for (let index = 0; index < this.channels.length; index++) if (this.channels[index].channelName() == name && (!force_parent || parent == this.channels[index].parent)) return this.channels[index]; return undefined; } moveChannel(channel, channel_previous, parent) { if (channel_previous != null && channel_previous.parent != parent) { console.error(_translations.GFlIOGAL || (_translations.GFlIOGAL = tr("Invalid channel move (different parents! (%o|%o)")), channel_previous.parent, parent); return; } if (channel.channel_next) channel.channel_next.channel_previous = channel.channel_previous; if (channel.channel_previous) channel.channel_previous.channel_next = channel.channel_next; if (channel == this.channel_last) this.channel_last = channel.channel_previous; if (channel == this.channel_first) this.channel_first = channel.channel_next; channel.channel_next = undefined; channel.channel_previous = channel_previous; channel.parent = parent; if (channel_previous) { if (channel_previous == this.channel_last) this.channel_last = channel; channel.channel_next = channel_previous.channel_next; channel_previous.channel_next = channel; channel_previous.rootTag().after(channel.rootTag()); if (channel.channel_next) channel.channel_next.channel_previous = channel; } else { if (parent) { let children = parent.children(); if (children.length <= 1) { //Self should be already in there let left = channel.rootTag(); left.appendTo(parent.siblingTag()); channel.channel_next = undefined; } else { channel.channel_previous = undefined; channel.rootTag().prependTo(parent.siblingTag()); channel.channel_next = children[1]; /* children 0 shall be the channel itself */ channel.channel_next.channel_previous = channel; } } else { this._tag_entries.find(".server").after(channel.rootTag()); channel.channel_next = this.channel_first; if (this.channel_first) this.channel_first.channel_previous = channel; this.channel_first = channel; } } channel.update_family_index(); channel.children(true).forEach(e => e.update_family_index()); channel.clients(true).forEach(e => e.update_family_index()); if (channel.channel_previous == channel) { /* shall never happen */ channel.channel_previous = undefined; debugger; } if (channel.channel_next == channel) { /* shall never happen */ channel.channel_next = undefined; debugger; } } deleteClient(client, animate_tag) { const old_channel = client.currentChannel(); this.clients.remove(client); if (typeof (animate_tag) !== "boolean" || animate_tag) this.__deleteAnimation(client); else client.tag.detach(); client.onDelete(); if (old_channel) { this.client.side_bar.info_frame().update_channel_client_count(old_channel); } const voice_connection = this.client.serverConnection.voice_connection(); if (client.get_audio_handle()) { if (!voice_connection) { log.warn(LogCategory.VOICE, _translations.UCLC4ivJ || (_translations.UCLC4ivJ = tr("Deleting client with a voice handle, but we haven't a voice connection!"))); } else { voice_connection.unregister_client(client.get_audio_handle()); } } client.set_audio_handle(undefined); } registerClient(client) { this.clients.push(client); client.channelTree = this; const voice_connection = this.client.serverConnection.voice_connection(); if (voice_connection) client.set_audio_handle(voice_connection.register_client(client.clientId())); } unregisterClient(client) { if (!this.clients.remove(client)) return; client.tree_unregistered(); } insertClient(client, channel) { let newClient = this.findClient(client.clientId()); if (newClient) client = newClient; //Got new client :) else { this.registerClient(client); } client["_channel"] = channel; let tag = client.tag; if (!this._show_queries && client.properties.client_type == ClientType.CLIENT_QUERY) client.tag.hide(); else if (!this._tree_detached) tag.css("display", "none").fadeIn("slow"); tag.appendTo(channel.clientTag()); channel.reorderClients(); /* schedule a reorder for this channel. */ this._reorder_channels.add(client.currentChannel()); if (!this._update_timer) { this._update_timer = setTimeout(() => { this._update_timer = undefined; for (const channel of this._reorder_channels) { channel.updateChannelTypeIcon(); this.client.side_bar.info_frame().update_channel_client_count(channel); } this._reorder_channels.clear(); }, 5); } client.update_family_index(); /* why the hell is this here?! */ return client; } moveClient(client, channel) { let oldChannel = client.currentChannel(); client["_channel"] = channel; let tag = client.tag; tag.detach(); tag.appendTo(client.currentChannel().clientTag()); if (oldChannel) { oldChannel.updateChannelTypeIcon(); this.client.side_bar.info_frame().update_channel_client_count(oldChannel); } if (channel) { channel.reorderClients(); channel.updateChannelTypeIcon(); this.client.side_bar.info_frame().update_channel_client_count(channel); } client.updateClientStatusIcons(); client.update_family_index(); } findClient(clientId) { for (let index = 0; index < this.clients.length; index++) { if (this.clients[index].clientId() == clientId) return this.clients[index]; } return undefined; } find_client_by_dbid(client_dbid) { for (let index = 0; index < this.clients.length; index++) { if (this.clients[index].properties.client_database_id == client_dbid) return this.clients[index]; } return undefined; } find_client_by_unique_id(unique_id) { for (let index = 0; index < this.clients.length; index++) { if (this.clients[index].properties.client_unique_identifier == unique_id) return this.clients[index]; } return undefined; } static same_selected_type(a, b) { if (a instanceof ChannelEntry) return b instanceof ChannelEntry; if (a instanceof ClientEntry) return b instanceof ClientEntry; if (a instanceof ServerEntry) return b instanceof ServerEntry; return a == b; } onSelect(entry, enforce_single, flag_shift) { if (this.currently_selected && (ppt.key_pressed(ppt.SpecialKey.SHIFT) || flag_shift) && entry instanceof ClientEntry) { //Currently we're only supporting client multiselects :D if (!entry) return; //Nowhere if ($.isArray(this.currently_selected)) { if (!ChannelTree.same_selected_type(this.currently_selected[0], entry)) return; //Not the same type } else if (ChannelTree.same_selected_type(this.currently_selected, entry)) { this.currently_selected = [this.currently_selected]; } if (entry instanceof ChannelEntry) this.currently_selected_context_callback = this.callback_multiselect_channel.bind(this); if (entry instanceof ClientEntry) this.currently_selected_context_callback = this.callback_multiselect_client.bind(this); } else this.currently_selected = undefined; if (!$.isArray(this.currently_selected) || enforce_single) { this.currently_selected = entry; this._tag_entries.find(".selected").each(function (idx, e) { $(e).removeClass("selected"); }); } else { for (const e of this.currently_selected) if (e == entry) { this.currently_selected.remove(e); if (entry instanceof ChannelEntry) entry.channelTag().removeClass("selected"); else if (entry instanceof ClientEntry) entry.tag.removeClass("selected"); else if (entry instanceof ServerEntry) entry.htmlTag.removeClass("selected"); if (this.currently_selected.length == 1) this.currently_selected = this.currently_selected[0]; else if (this.currently_selected.length == 0) this.currently_selected = undefined; //Already selected return; } this.currently_selected.push(entry); } if (entry instanceof ChannelEntry) entry.channelTag().addClass("selected"); else if (entry instanceof ClientEntry) entry.tag.addClass("selected"); else if (entry instanceof ServerEntry) entry.htmlTag.addClass("selected"); if (!$.isArray(this.currently_selected)) { if (this.currently_selected instanceof ClientEntry && settings.static_global(Settings.KEY_SWITCH_INSTANT_CLIENT)) { if (this.currently_selected instanceof MusicClientEntry) this.client.side_bar.show_music_player(this.currently_selected); else this.client.side_bar.show_client_info(this.currently_selected); } else if (this.currently_selected instanceof ChannelEntry && settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)) { this.client.side_bar.channel_conversations().set_current_channel(this.currently_selected.channelId); this.client.side_bar.show_channel_conversations(); } else if (this.currently_selected instanceof ServerEntry && settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)) { this.client.side_bar.channel_conversations().set_current_channel(0); this.client.side_bar.show_channel_conversations(); } } } callback_multiselect_channel(event) { console.log(_translations.ZrJ02URc || (_translations.ZrJ02URc = tr("Multiselect channel"))); } callback_multiselect_client(event) { console.log(_translations.HSzvJwwR || (_translations.HSzvJwwR = tr("Multiselect client"))); const clients = this.currently_selected; const music_only = clients.map(e => e instanceof MusicClientEntry ? 0 : 1).reduce((a, b) => a + b, 0) == 0; const music_entry = clients.map(e => e instanceof MusicClientEntry ? 1 : 0).reduce((a, b) => a + b, 0) > 0; const local_client = clients.map(e => e instanceof LocalClientEntry ? 1 : 0).reduce((a, b) => a + b, 0) > 0; let entries = []; if (!music_entry && !local_client) { //Music bots or local client cant be poked entries.push({ type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-poke", name: _translations.Ody_8yeT || (_translations.Ody_8yeT = tr("Poke clients")), callback: () => { createInputModal(_translations.ATXAwxWL || (_translations.ATXAwxWL = tr("Poke clients")), _translations.vsK8laF1 || (_translations.vsK8laF1 = tr("Poke message:
")), text => true, result => { if (typeof (result) === "string") { for (const client of this.currently_selected) this.client.serverConnection.send_command("clientpoke", { clid: client.clientId(), msg: result }); } }, { width: 400, maxLength: 512 }).open(); } }); } entries.push({ type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-move_client_to_own_channel", name: _translations.jMleGq7P || (_translations.jMleGq7P = tr("Move clients to your channel")), callback: () => { const target = this.client.getClient().currentChannel().getChannelId(); for (const client of clients) this.client.serverConnection.send_command("clientmove", { clid: client.clientId(), cid: target }); } }); if (!local_client) { //local client cant be kicked and/or banned or kicked entries.push(contextmenu.Entry.HR()); entries.push({ type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-kick_channel", name: _translations.fkTEx1Wh || (_translations.fkTEx1Wh = tr("Kick clients from channel")), callback: () => { createInputModal(_translations.SlAO2UCb || (_translations.SlAO2UCb = tr("Kick clients from channel")), _translations.beWd2uCp || (_translations.beWd2uCp = tr("Kick reason:
")), text => true, result => { if (result) { for (const client of clients) this.client.serverConnection.send_command("clientkick", { clid: client.clientId(), reasonid: ViewReasonId.VREASON_CHANNEL_KICK, reasonmsg: result }); } }, { width: 400, maxLength: 255 }).open(); } }); if (!music_entry) { //Music bots cant be banned or kicked entries.push({ type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-kick_server", name: _translations.Utc4LAwu || (_translations.Utc4LAwu = tr("Kick clients fom server")), callback: () => { createInputModal(_translations.hPN4f_xI || (_translations.hPN4f_xI = tr("Kick clients from server")), _translations.jhZR81Qh || (_translations.jhZR81Qh = tr("Kick reason:
")), text => true, result => { if (result) { for (const client of clients) this.client.serverConnection.send_command("clientkick", { clid: client.clientId(), reasonid: ViewReasonId.VREASON_SERVER_KICK, reasonmsg: result }); } }, { width: 400, maxLength: 255 }).open(); } }, { type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-ban_client", name: _translations.Y10NXL7W || (_translations.Y10NXL7W = tr("Ban clients")), invalidPermission: !this.client.permissions.neededPermission(PermissionType.I_CLIENT_BAN_MAX_BANTIME).granted(1), callback: () => { Modals.spawnBanClient(this.client, (clients).map(entry => { return { name: entry.clientNickName(), unique_id: entry.properties.client_unique_identifier }; }), (data) => { for (const client of clients) this.client.serverConnection.send_command("banclient", { uid: client.properties.client_unique_identifier, banreason: data.reason, time: data.length }, { flagset: [data.no_ip ? "no-ip" : "", data.no_hwid ? "no-hardware-id" : "", data.no_name ? "no-nickname" : ""] }).then(() => { this.client.sound.play(Sound.USER_BANNED); }); }); } }); } if (music_only) { entries.push(contextmenu.Entry.HR()); entries.push({ name: _translations.CMX4tuF2 || (_translations.CMX4tuF2 = tr("Delete bots")), icon_class: "client-delete", disabled: false, callback: () => { const param_string = clients.map((_, index) => "{" + index + "}").join(', '); const param_values = clients.map(client => client.createChatTag(true)); const tag = $.spawn("div").append(...MessageHelper.formatMessage((_translations.u_LRSiVw || (_translations.u_LRSiVw = tr("Do you really want to delete "))) + param_string, ...param_values)); const tag_container = $.spawn("div").append(tag); Modals.spawnYesNo(_translations.O6jNMfCB || (_translations.O6jNMfCB = tr("Are you sure?")), tag_container, result => { if (result) { for (const client of clients) this.client.serverConnection.send_command("musicbotdelete", { botid: client.properties.client_database_id }); } }); }, type: contextmenu.MenuEntryType.ENTRY }); } } contextmenu.spawn_context_menu(event.pageX, event.pageY, ...entries); } clientsByGroup(group) { let result = []; for (let client of this.clients) { if (client.groupAssigned(group)) result.push(client); } return result; } clientsByChannel(channel) { let result = []; for (let client of this.clients) { if (client.currentChannel() == channel) result.push(client); } return result; } reset() { const voice_connection = this.client.serverConnection ? this.client.serverConnection.voice_connection() : undefined; for (const client of this.clients) { if (client.get_audio_handle() && voice_connection) { voice_connection.unregister_client(client.get_audio_handle()); client.set_audio_handle(undefined); } client.destroy(); } this.clients = []; for (const channel of this.channels) channel.destroy(); this.channels = []; this._tag_entries.children().detach(); //Dont remove listeners this.channel_first = undefined; this.channel_last = undefined; } spawnCreateChannel(parent) { Modals.createChannelModal(this.client, undefined, parent, this.client.permissions, (properties, permissions) => { if (!properties) return; properties["cpid"] = parent ? parent.channelId : 0; log.debug(LogCategory.CHANNEL, _translations.yFR88s_P || (_translations.yFR88s_P = tr("Creating a new channel.\nProperties: %o\nPermissions: %o")), properties); this.client.serverConnection.send_command("channelcreate", properties).then(() => { let channel = this.find_channel_by_name(properties.channel_name, parent, true); if (!channel) { log.error(LogCategory.CHANNEL, _translations.rAA5IByZ || (_translations.rAA5IByZ = tr("Failed to resolve channel after creation. Could not apply permissions!"))); return; } if (permissions && permissions.length > 0) { let perms = []; for (let perm of permissions) { perms.push({ permvalue: perm.value, permnegated: false, permskip: false, permid: perm.type.id }); } perms[0]["cid"] = channel.channelId; return this.client.serverConnection.send_command("channeladdperm", perms, { flagset: ["continueonerror"] }).then(() => new Promise(resolve => { resolve(channel); })); } return new Promise(resolve => { resolve(channel); }); }).then(channel => { this.client.log.log(log.server.Type.CHANNEL_CREATE, { channel: channel.log_data(), creator: this.client.getClient().log_data(), own_action: true }); this.client.sound.play(Sound.CHANNEL_CREATED); }); }); } handle_resized() { for (let channel of this.channels) channel.handle_frame_resized(); } select_next_channel(channel, select_client) { if (select_client) { const clients = channel.clients_ordered(); if (clients.length > 0) { this.onSelect(clients[0], true); return; } } const children = channel.children(); if (children.length > 0) { this.onSelect(children[0], true); return; } const next = channel.channel_next; if (next) { this.onSelect(next, true); return; } let parent = channel.parent_channel(); while (parent) { const p_next = parent.channel_next; if (p_next) { this.onSelect(p_next, true); return; } parent = parent.parent_channel(); } } handle_key_press(event) { //console.log("Keydown: %o | %o | %o", this._focused, this.currently_selected, Array.isArray(this.currently_selected)); if (!this._focused || !this.currently_selected || Array.isArray(this.currently_selected)) return; if (event.keyCode == KeyCode.KEY_UP) { event.preventDefault(); if (this.currently_selected instanceof ChannelEntry) { let previous = this.currently_selected.channel_previous; if (previous) { while (true) { const siblings = previous.children(); if (siblings.length == 0) break; previous = siblings.last(); } const clients = previous.clients_ordered(); if (clients.length > 0) { this.onSelect(clients.last(), true); return; } else { this.onSelect(previous, true); return; } } else if (this.currently_selected.hasParent()) { const channel = this.currently_selected.parent_channel(); const clients = channel.clients_ordered(); if (clients.length > 0) { this.onSelect(clients.last(), true); return; } else { this.onSelect(channel, true); return; } } else this.onSelect(this.server, true); } else if (this.currently_selected instanceof ClientEntry) { const channel = this.currently_selected.currentChannel(); const clients = channel.clients_ordered(); const index = clients.indexOf(this.currently_selected); if (index > 0) { this.onSelect(clients[index - 1], true); return; } this.onSelect(channel, true); return; } } else if (event.keyCode == KeyCode.KEY_DOWN) { event.preventDefault(); if (this.currently_selected instanceof ChannelEntry) { this.select_next_channel(this.currently_selected, true); } else if (this.currently_selected instanceof ClientEntry) { const channel = this.currently_selected.currentChannel(); const clients = channel.clients_ordered(); const index = clients.indexOf(this.currently_selected); if (index + 1 < clients.length) { this.onSelect(clients[index + 1], true); return; } this.select_next_channel(channel, false); } else if (this.currently_selected instanceof ServerEntry) this.onSelect(this.channel_first, true); } else if (event.keyCode == KeyCode.KEY_RETURN) { if (this.currently_selected instanceof ChannelEntry) { this.currently_selected.joinChannel(); } } } toggle_server_queries(flag) { if (this._show_queries == flag) return; this._show_queries = flag; const channels = []; for (const client of this.clients) if (client.properties.client_type == ClientType.CLIENT_QUERY) { if (this._show_queries) client.tag.show(); else client.tag.hide(); if (channels.indexOf(client.currentChannel()) == -1) channels.push(client.currentChannel()); } } get_first_channel() { return this.channel_first; } unsubscribe_all_channels(subscribe_specified) { if (!this.client.serverConnection || !this.client.serverConnection.connected()) return; this.client.serverConnection.send_command('channelunsubscribeall').then(() => { const channels = []; for (const channel of this.channels) { if (channel.subscribe_mode == ChannelSubscribeMode.SUBSCRIBED) channels.push(channel.getChannelId()); } if (channels.length > 0) { this.client.serverConnection.send_command('channelsubscribe', channels.map(e => { return { cid: e }; })).catch(error => { console.warn(_translations.Fh5FtgZp || (_translations.Fh5FtgZp = tr("Failed to subscribe to specific channels (%o)")), channels); }); } }).catch(error => { console.warn(_translations.pBoepRGH || (_translations.pBoepRGH = tr("Failed to unsubscribe to all channels! (%o)")), error); }); } subscribe_all_channels() { if (!this.client.serverConnection || !this.client.serverConnection.connected()) return; this.client.serverConnection.send_command('channelsubscribeall').then(() => { const channels = []; for (const channel of this.channels) { if (channel.subscribe_mode == ChannelSubscribeMode.UNSUBSCRIBED) channels.push(channel.getChannelId()); } if (channels.length > 0) { this.client.serverConnection.send_command('channelunsubscribe', channels.map(e => { return { cid: e }; })).catch(error => { console.warn(_translations.hSPoFqAs || (_translations.hSPoFqAs = tr("Failed to unsubscribe to specific channels (%o)")), channels); }); } }).catch(error => { console.warn(_translations.rbZFNFYt || (_translations.rbZFNFYt = tr("Failed to subscribe to all channels! (%o)")), error); }); } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["aab7a9e827e45917f2b7350a68a622a37c8a253931f6051bba900999e332204d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["aab7a9e827e45917f2b7350a68a622a37c8a253931f6051bba900999e332204d"] = "aab7a9e827e45917f2b7350a68a622a37c8a253931f6051bba900999e332204d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Li5Gw9CA", path: "D:/TeaSpeak/web/shared/js/settings.ts (379,44)" }, { name: "uS6cXSmH", path: "D:/TeaSpeak/web/shared/js/settings.ts (382,34)" }, { name: "u4KNLKf0", path: "D:/TeaSpeak/web/shared/js/settings.ts (382,72)" }, { name: "F6RUQNLg", path: "D:/TeaSpeak/web/shared/js/settings.ts (494,48)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// //Used by CertAccept popup if (typeof (customElements) !== "undefined") { try { 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' }); } catch (error) { console.warn("failed to define costum elements"); } } class SettingsBase { static transformStO(input, _default, default_type) { default_type = default_type || typeof _default; if (typeof input === "undefined") return _default; if (default_type === "string") return input; else if (default_type === "number") return parseInt(input); else if (default_type === "boolean") return (input == "1" || input == "true"); else if (default_type === "undefined") return input; return JSON.parse(input); } static transformOtS(input) { if (typeof input === "string") return input; else if (typeof input === "number") return input.toString(); else if (typeof input === "boolean") return input ? "1" : "0"; else if (typeof input === "undefined") return undefined; return JSON.stringify(input); } static resolveKey(key, _default, resolver, default_type) { let value = resolver(key.key); if (!value) { /* trying fallbacks */ for (const fallback of key.fallback_keys || []) { value = resolver(fallback); if (typeof (value) === "string") { /* fallback key succeeded */ const importer = (key.fallback_imports || {})[fallback]; if (importer) return importer(value); break; } } } if (typeof (value) !== 'string') return _default; return SettingsBase.transformStO(value, _default, default_type); } static keyify(key) { if (typeof (key) === "string") return { key: key }; if (typeof (key) === "object" && key.key) return key; throw "key is not a key"; } } SettingsBase.UPDATE_DIRECT = true; class StaticSettings extends SettingsBase { constructor(_reserved = undefined) { super(); if (_reserved && !StaticSettings._instance) { this._staticPropsTag = $("#properties"); this.initializeStatic(); } else { this._handle = StaticSettings.instance; } } static get instance() { if (!this._instance) this._instance = new StaticSettings(true); return this._instance; } initializeStatic() { let search; if (window.opener && window.opener !== window) { search = new URL(window.location.href).search; } else { search = location.search; } search.substr(1).split("&").forEach(part => { let item = part.split("="); $("") .attr("key", item[0]) .attr("value", item[1]) .appendTo(this._staticPropsTag); }); } static(key, _default, default_type) { if (this._handle) return this._handle.static(key, _default, default_type); key = StaticSettings.keyify(key); return StaticSettings.resolveKey(key, _default, key => { let result = this._staticPropsTag.find("[key='" + key + "']"); if (result.length > 0) return decodeURIComponent(result.last().attr('value')); return false; }, default_type); } deleteStatic(key) { if (this._handle) { this._handle.deleteStatic(key); return; } key = StaticSettings.keyify(key); let result = this._staticPropsTag.find("[key='" + key.key + "']"); if (result.length != 0) result.detach(); } } class Settings extends StaticSettings { constructor() { super(); this.cacheGlobal = {}; this.updated = false; const json = localStorage.getItem("settings.global"); try { this.cacheGlobal = JSON.parse(json); } catch (error) { log.error(LogCategory.GENERAL, _translations.Li5Gw9CA || (_translations.Li5Gw9CA = tr("Failed to load global settings!\nJson: %s\nError: %o")), json, error); const show_popup = () => { createErrorModal(_translations.uS6cXSmH || (_translations.uS6cXSmH = tr("Failed to load global settings")), _translations.u4KNLKf0 || (_translations.u4KNLKf0 = tr("Failed to load global client settings!\nLookup console for more information."))).open(); }; if (!loader.finished()) loader.register_task(loader.Stage.LOADED, { priority: 0, name: "Settings error", function: () => __awaiter(this, void 0, void 0, function* () { return show_popup(); }) }); else show_popup(); } if (!this.cacheGlobal) this.cacheGlobal = {}; this.saveWorker = setInterval(() => { if (this.updated) this.save(); }, 5 * 1000); } static initialize() { settings = new Settings(); } static_global(key, _default) { const actual_default = typeof (_default) === "undefined" && typeof (key) === "object" && 'default_value' in key ? key.default_value : _default; const default_object = { seed: Math.random() }; let _static = this.static(key, default_object, typeof _default); if (_static !== default_object) return StaticSettings.transformStO(_static, actual_default); return this.global(key, actual_default); } global(key, _default) { const actual_default = typeof (_default) === "undefined" && typeof (key) === "object" && 'default_value' in key ? key.default_value : _default; return StaticSettings.resolveKey(Settings.keyify(key), actual_default, key => this.cacheGlobal[key]); } changeGlobal(key, value) { key = Settings.keyify(key); if (this.cacheGlobal[key.key] == value) return; this.updated = true; this.cacheGlobal[key.key] = StaticSettings.transformOtS(value); if (Settings.UPDATE_DIRECT) this.save(); } save() { this.updated = false; let global = JSON.stringify(this.cacheGlobal); localStorage.setItem("settings.global", global); if (localStorage.save) localStorage.save(); } } Settings.KEY_USER_IS_NEW = { key: 'user_is_new_user', default_value: true }; Settings.KEY_DISABLE_COSMETIC_SLOWDOWN = { key: 'disable_cosmetic_slowdown', description: 'Disable the cosmetic slowdows in some processes, like icon upload.' }; Settings.KEY_DISABLE_CONTEXT_MENU = { key: 'disableContextMenu', description: 'Disable the context menu for the channel tree which allows to debug the DOM easier' }; Settings.KEY_DISABLE_GLOBAL_CONTEXT_MENU = { key: 'disableGlobalContextMenu', description: 'Disable the general context menu prevention', default_value: false }; Settings.KEY_DISABLE_UNLOAD_DIALOG = { key: 'disableUnloadDialog', description: 'Disables the unload popup on side closing' }; Settings.KEY_DISABLE_VOICE = { key: 'disableVoice', description: 'Disables the voice bridge. If disabled, the audio and codec workers aren\'t required anymore' }; Settings.KEY_DISABLE_MULTI_SESSION = { key: 'disableMultiSession', default_value: false, require_restart: true }; Settings.KEY_LOAD_DUMMY_ERROR = { key: 'dummy_load_error', description: 'Triggers a loading error at the end of the loading process.' }; /* Control bar */ Settings.KEY_CONTROL_MUTE_INPUT = { key: 'mute_input' }; Settings.KEY_CONTROL_MUTE_OUTPUT = { key: 'mute_output' }; Settings.KEY_CONTROL_SHOW_QUERIES = { key: 'show_server_queries' }; Settings.KEY_CONTROL_CHANNEL_SUBSCRIBE_ALL = { key: 'channel_subscribe_all' }; /* Connect parameters */ Settings.KEY_FLAG_CONNECT_DEFAULT = { key: 'connect_default' }; Settings.KEY_CONNECT_ADDRESS = { key: 'connect_address' }; Settings.KEY_CONNECT_PROFILE = { key: 'connect_profile', default_value: 'default' }; Settings.KEY_CONNECT_USERNAME = { key: 'connect_username' }; Settings.KEY_CONNECT_PASSWORD = { key: 'connect_password' }; Settings.KEY_FLAG_CONNECT_PASSWORD = { key: 'connect_password_hashed' }; Settings.KEY_CONNECT_HISTORY = { key: 'connect_history' }; Settings.KEY_CONNECT_NO_DNSPROXY = { key: 'connect_no_dnsproxy', default_value: false }; Settings.KEY_CERTIFICATE_CALLBACK = { key: 'certificate_callback' }; /* sounds */ Settings.KEY_SOUND_MASTER = { key: 'audio_master_volume', default_value: 100 }; Settings.KEY_SOUND_MASTER_SOUNDS = { key: 'audio_master_volume_sounds', default_value: 100 }; Settings.KEY_CHAT_FIXED_TIMESTAMPS = { key: 'chat_fixed_timestamps', default_value: false, description: 'Enables fixed timestamps for chat messages and disabled the updating once (2 seconds ago... etc)' }; Settings.KEY_CHAT_COLLOQUIAL_TIMESTAMPS = { key: 'chat_colloquial_timestamps', default_value: true, description: 'Enabled colloquial timestamp formatting like "Yesterday at ..." or "Today at ..."' }; Settings.KEY_CHAT_COLORED_EMOJIES = { key: 'chat_colored_emojies', default_value: true, description: 'Enables colored emojies powered by Twemoji' }; Settings.KEY_CHAT_TAG_URLS = { key: 'chat_tag_urls', default_value: true, description: 'Automatically link urls with [url]' }; Settings.KEY_CHAT_ENABLE_MARKDOWN = { key: 'chat_enable_markdown', default_value: true, description: 'Enabled markdown chat support.' }; Settings.KEY_CHAT_ENABLE_BBCODE = { key: 'chat_enable_bbcode', default_value: false, description: 'Enabled bbcode support in chat.' }; Settings.KEY_CHAT_IMAGE_WHITELIST_REGEX = { key: 'chat_image_whitelist_regex', default_value: JSON.stringify([]) }; Settings.KEY_SWITCH_INSTANT_CHAT = { key: 'switch_instant_chat', default_value: true, description: 'Directly switch to channel chat on channel select' }; Settings.KEY_SWITCH_INSTANT_CLIENT = { key: 'switch_instant_client', default_value: true, description: 'Directly switch to client info on client select' }; Settings.KEY_HOSTBANNER_BACKGROUND = { key: 'hostbanner_background', default_value: false, description: 'Enables a default background begind the hostbanner' }; Settings.KEY_CHANNEL_EDIT_ADVANCED = { key: 'channel_edit_advanced', default_value: false, description: 'Edit channels in advanced mode with a lot more settings' }; Settings.KEY_PERMISSIONS_SHOW_ALL = { key: 'permissions_show_all', default_value: false, description: 'Show all permissions even thou they dont make sense for the server/channel group' }; Settings.KEY_TEAFORO_URL = { key: "teaforo_url", default_value: "https://forum.teaspeak.de/" }; Settings.KEY_FONT_SIZE = { key: "font_size" }; Settings.KEY_ICON_SIZE = { key: "icon_size", default_value: 100 }; Settings.KEY_LAST_INVITE_LINK_TYPE = { key: "last_invite_link_type", default_value: "tea-web" }; Settings.FN_INVITE_LINK_SETTING = name => { return { key: 'invite_link_setting_' + name }; }; Settings.FN_SERVER_CHANNEL_SUBSCRIBE_MODE = channel => { return { key: 'channel_subscribe_mode_' + channel }; }; Settings.FN_PROFILE_RECORD = name => { return { key: 'profile_record' + name }; }; Settings.KEYS = (() => { const result = []; for (const key in Settings) { if (!key.toUpperCase().startsWith("KEY_")) continue; if (key.toUpperCase() == "KEYS") continue; result.push(key); } return result; })(); class ServerSettings extends SettingsBase { constructor() { super(); this.cacheServer = {}; this._server_settings_updated = false; this._destroyed = false; this._server_save_worker = setInterval(() => { if (this._server_settings_updated) this.save(); }, 5 * 1000); } destroy() { this._destroyed = true; this._server_unique_id = undefined; this.cacheServer = undefined; clearInterval(this._server_save_worker); this._server_save_worker = undefined; } server(key, _default) { if (this._destroyed) throw "destroyed"; return StaticSettings.resolveKey(Settings.keyify(key), _default, key => this.cacheServer[key]); } changeServer(key, value) { if (this._destroyed) throw "destroyed"; key = Settings.keyify(key); if (this.cacheServer[key.key] == value) return; this._server_settings_updated = true; this.cacheServer[key.key] = StaticSettings.transformOtS(value); if (Settings.UPDATE_DIRECT) this.save(); } setServer(server_unique_id) { if (this._destroyed) throw "destroyed"; if (this._server_unique_id) { this.save(); this.cacheServer = {}; this._server_unique_id = undefined; } this._server_unique_id = server_unique_id; if (this._server_unique_id) { const json = localStorage.getItem("settings.server_" + server_unique_id); try { this.cacheServer = JSON.parse(json); } catch (error) { log.error(LogCategory.GENERAL, _translations.F6RUQNLg || (_translations.F6RUQNLg = tr("Failed to load server settings for server %s!\nJson: %s\nError: %o")), server_unique_id, json, error); } if (!this.cacheServer) this.cacheServer = {}; } } save() { if (this._destroyed) throw "destroyed"; this._server_settings_updated = false; if (this._server_unique_id) { let server = JSON.stringify(this.cacheServer); localStorage.setItem("settings.server_" + this._server_unique_id, server); if (localStorage.save) localStorage.save(); } } } let settings; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["9905e0706fb3679c8418586821d6454792687444f209b49eeb1a5af522c90114"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["9905e0706fb3679c8418586821d6454792687444f209b49eeb1a5af522c90114"] = "9905e0706fb3679c8418586821d6454792687444f209b49eeb1a5af522c90114"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Iazp8WAl", path: "D:/TeaSpeak/web/shared/js/connection/ConnectionBase.ts (168,30)" }, { name: "osT4NYsM", path: "D:/TeaSpeak/web/shared/js/connection/ConnectionBase.ts (197,35)" }, { name: "kb_ARAZP", path: "D:/TeaSpeak/web/shared/js/connection/ConnectionBase.ts (209,35)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var connection; (function (connection_1) { connection_1.CommandOptionDefaults = { flagset: [], process_result: true, timeout: 1000 }; class AbstractServerConnection { constructor(client) { this.client = client; this.command_helper = new connection_1.CommandHelper(this); } } connection_1.AbstractServerConnection = AbstractServerConnection; let voice; (function (voice) { let 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 = voice.PlayerState || (voice.PlayerState = {})); class AbstractVoiceConnection { constructor(connection) { this.connection = connection; } } voice.AbstractVoiceConnection = AbstractVoiceConnection; })(voice = connection_1.voice || (connection_1.voice = {})); class ServerCommand { } connection_1.ServerCommand = ServerCommand; class AbstractCommandHandler { constructor(connection) { this.volatile_handler_boss = false; /* if true than the command handler could be registered twice to two or more handlers */ this.ignore_consumed = false; this.connection = connection; } } connection_1.AbstractCommandHandler = AbstractCommandHandler; class AbstractCommandHandlerBoss { constructor(connection) { this.command_handlers = []; /* TODO: Timeout */ this.single_command_handler = []; this.connection = connection; } destroy() { this.command_handlers = undefined; this.single_command_handler = undefined; } register_handler(handler) { if (!handler.volatile_handler_boss && handler.handler_boss) throw "handler already registered"; this.command_handlers.remove(handler); /* just to be sure */ this.command_handlers.push(handler); handler.handler_boss = this; } unregister_handler(handler) { if (!handler.volatile_handler_boss && handler.handler_boss !== this) { console.warn(_translations.Iazp8WAl || (_translations.Iazp8WAl = tr("Tried to unregister command handler which does not belong to the handler boss"))); return; } this.command_handlers.remove(handler); handler.handler_boss = undefined; } register_single_handler(handler) { this.single_command_handler.push(handler); } remove_single_handler(handler) { this.single_command_handler.remove(handler); } handlers() { return this.command_handlers; } invoke_handle(command) { let flag_consumed = false; for (const handler of this.command_handlers) { try { if (!flag_consumed || handler.ignore_consumed) flag_consumed = flag_consumed || handler.handle_command(command); } catch (error) { console.error(_translations.osT4NYsM || (_translations.osT4NYsM = tr("Failed to invoke command handler. Invocation results in an exception: %o")), error); } } for (const handler of [...this.single_command_handler]) { if (handler.command && handler.command != command.command) continue; try { if (handler.function(command)) this.single_command_handler.remove(handler); } catch (error) { console.error(_translations.kb_ARAZP || (_translations.kb_ARAZP = tr("Failed to invoke single command handler. Invocation results in an exception: %o")), error); } } return flag_consumed; } } connection_1.AbstractCommandHandlerBoss = AbstractCommandHandlerBoss; })(connection || (connection = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["37651e247358097e3a713c020f24649c058880f6fa693a9c81181c5193e5b8ef"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["37651e247358097e3a713c020f24649c058880f6fa693a9c81181c5193e5b8ef"] = "37651e247358097e3a713c020f24649c058880f6fa693a9c81181c5193e5b8ef"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "pCk7xYst", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (98,47)" }, { name: "G_WEzBlb", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (112,59)" }, { name: "y8lxS0mg", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (143,50)" }, { name: "RBhEfyBT", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (163,51)" }, { name: "N3Jb_ujY", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (165,51)" }, { name: "byMDJXBp", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (199,33)" }, { name: "kJ99wZWj", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (228,34)" }, { name: "vSKb8F5P", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (228,61)" }, { name: "z78_SMMr", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (236,45)" }, { name: "smS5MNGV", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (236,70)" }, { name: "yKYk5MrN", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (238,46)" }, { name: "T9XgymAy", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (238,99)" }, { name: "xGqliR_T", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (274,50)" }, { name: "hTYqyg0W", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (290,59)" }, { name: "LZKNb1ud", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (297,55)" }, { name: "m95mid7y", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (329,47)" }, { name: "cO7AsMbZ", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (351,46)" }, { name: "Tr8N0T8J", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (356,55)" }, { name: "tGrW50fT", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (367,46)" }, { name: "tqXi_0qx", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (372,55)" }, { name: "YwXRwg0u", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (442,38)" }, { name: "cJ2nujBf", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (498,55)" }, { name: "NTMrV0pQ", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (551,63)" }, { name: "gEcJmHRi", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (586,51)" }, { name: "rsbbZ5vo", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (591,51)" }, { name: "FUu2Z3p0", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (597,55)" }, { name: "BuZ27Ktg", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (601,25)" }, { name: "BID316jI", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (684,30)" }, { name: "fzc4kFcz", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (694,51)" }, { name: "mF6Ppr3u", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (700,51)" }, { name: "XxAerQnq", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (706,51)" }, { name: "tBW9j_7C", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (719,51)" }, { name: "_E2eMYr4", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (767,55)" }, { name: "kgIHfhjS", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (767,136)" }, { name: "ruiHzDfv", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (767,159)" }, { name: "U0exVRxM", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (871,47)" }, { name: "suQhKZ2M", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (882,51)" }, { name: "BxOvO8Ec", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (938,46)" }, { name: "_5Wlb_tM", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (990,34)" }, { name: "HMeyZ6hh", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1002,34)" }, { name: "bkMX72xe", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1016,50)" }, { name: "Pqgsw3nk", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1056,46)" }, { name: "acswhp6U", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1072,46)" }, { name: "JHeDrma5", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1094,46)" }, { name: "KYFQM8h2", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1118,46)" }, { name: "MX9isGwd", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1132,46)" }, { name: "x8tCYqXl", path: "D:/TeaSpeak/web/shared/js/connection/CommandHandler.ts (1147,46)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var connection; (function (connection_2) { class ServerConnectionCommandBoss extends connection_2.AbstractCommandHandlerBoss { constructor(connection) { super(connection); } } connection_2.ServerConnectionCommandBoss = ServerConnectionCommandBoss; class ConnectionCommandHandler extends connection_2.AbstractCommandHandler { constructor(connection) { super(connection); this.connection_handler = connection.client; this["error"] = this.handleCommandResult; this["channellist"] = this.handleCommandChannelList; this["channellistfinished"] = this.handleCommandChannelListFinished; this["notifychannelcreated"] = this.handleCommandChannelCreate; this["notifychanneldeleted"] = this.handleCommandChannelDelete; this["notifychannelhide"] = this.handleCommandChannelHide; this["notifychannelshow"] = this.handleCommandChannelShow; this["notifyserverconnectioninfo"] = this.handleNotifyServerConnectionInfo; this["notifyconnectioninfo"] = this.handleNotifyConnectionInfo; 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["notifyclientchatcomposing"] = this.notifyClientChatComposing; this["notifyclientchatclosed"] = this.handleNotifyClientChatClosed; this["notifyclientupdated"] = this.handleNotifyClientUpdated; this["notifyserveredited"] = this.handleNotifyServerEdited; this["notifyserverupdated"] = this.handleNotifyServerUpdated; this["notifyclientpoke"] = this.handleNotifyClientPoke; this["notifymusicplayerinfo"] = this.handleNotifyMusicPlayerInfo; this["notifyservergroupclientadded"] = this.handleNotifyServerGroupClientAdd; this["notifyservergroupclientdeleted"] = this.handleNotifyServerGroupClientRemove; this["notifyclientchannelgroupchanged"] = this.handleNotifyClientChannelGroupChanged; this["notifychannelsubscribed"] = this.handleNotifyChannelSubscribed; this["notifychannelunsubscribed"] = this.handleNotifyChannelUnsubscribed; this["notifyconversationhistory"] = this.handleNotifyConversationHistory; this["notifyconversationmessagedelete"] = this.handleNotifyConversationMessageDelete; this["notifymusicstatusupdate"] = this.handleNotifyMusicStatusUpdate; this["notifymusicplayersongchange"] = this.handleMusicPlayerSongChange; this["notifyplaylistsongadd"] = this.handleNotifyPlaylistSongAdd; this["notifyplaylistsongremove"] = this.handleNotifyPlaylistSongRemove; this["notifyplaylistsongreorder"] = this.handleNotifyPlaylistSongReorder; this["notifyplaylistsongloaded"] = this.handleNotifyPlaylistSongLoaded; } loggable_invoker(unique_id, client_id, name) { const id = parseInt(client_id); if (typeof (client_id) === "undefined" || Number.isNaN(id)) return undefined; if (id == 0) return { client_id: 0, client_unique_id: this.connection_handler.channelTree.server.properties.virtualserver_unique_identifier, client_name: this.connection_handler.channelTree.server.properties.virtualserver_name, }; return { client_unique_id: unique_id, client_name: name, client_id: client_id }; } proxy_command_promise(promise, options) { if (!options.process_result) return promise; return promise.catch(ex => { if (options.process_result) { if (ex instanceof CommandResult) { let res = ex; if (!res.success) { if (res.id == ErrorID.PERMISSION_ERROR) { //Permission error const permission = this.connection_handler.permissions.resolveInfo(res.json["failed_permid"]); res.message = (_translations.pCk7xYst || (_translations.pCk7xYst = tr("Insufficient client permissions. Failed on permission "))) + (permission ? permission.name : "unknown"); this.connection_handler.log.log(log.server.Type.ERROR_PERMISSION, { permission: this.connection_handler.permissions.resolveInfo(res.json["failed_permid"]) }); this.connection_handler.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } else if (res.id != ErrorID.EMPTY_RESULT) { this.connection_handler.log.log(log.server.Type.ERROR_CUSTOM, { message: res.extra_message.length == 0 ? res.message : res.extra_message }); } } } else if (typeof (ex) === "string") { this.connection_handler.log.log(log.server.Type.CONNECTION_COMMAND_ERROR, { error: ex }); } else { log.error(LogCategory.NETWORKING, _translations.G_WEzBlb || (_translations.G_WEzBlb = tr("Invalid promise result type: %s. Result: %o")), typeof (ex), ex); } } return Promise.reject(ex); }); } handle_command(command) { if (this[command.command]) { this[command.command](command.arguments); return true; } return false; } set_handler(command, handler) { this[command] = handler; } unset_handler(command, handler) { if (handler && this[command] != handler) return; this[command] = undefined; } handleCommandResult(json) { json = json[0]; //Only one bulk let code = json["return_code"]; if (!code || code.length == 0) { log.warn(LogCategory.NETWORKING, _translations.y8lxS0mg || (_translations.y8lxS0mg = tr("Invalid return code! (%o)")), json); return; } let retListeners = this.connection["_retListener"]; for (let e of retListeners) { if (e.code != code) continue; retListeners.remove(e); let result = new CommandResult(json); if (result.success) e.resolve(result); else e.reject(result); break; } } handleCommandServerInit(json) { //We could setup the voice channel if (this.connection.support_voice()) { log.debug(LogCategory.NETWORKING, _translations.RBhEfyBT || (_translations.RBhEfyBT = tr("Setting up voice"))); } else { log.debug(LogCategory.NETWORKING, _translations.N3Jb_ujY || (_translations.N3Jb_ujY = tr("Skipping voice setup (No voice bridge available)"))); } json = json[0]; //Only one bulk this.connection_handler.channelTree.registerClient(this.connection_handler.getClient()); this.connection.client.side_bar.channel_conversations().reset(); this.connection.client.clientId = parseInt(json["aclid"]); this.connection.client.getClient().updateVariables({ key: "client_nickname", value: json["acn"] }); let updates = []; for (let key in json) { if (key === "aclid") continue; if (key === "acn") continue; updates.push({ key: key, value: json[key] }); } this.connection.client.channelTree.server.updateVariables(false, ...updates); const properties = this.connection.client.channelTree.server.properties; /* host message */ if (properties.virtualserver_hostmessage_mode > 0) { if (properties.virtualserver_hostmessage_mode == 1) { /* show in log */ this.connection_handler.log.log(log.server.Type.SERVER_HOST_MESSAGE, { message: properties.virtualserver_hostmessage }); } else { /* create modal/create modal and quit */ createModal({ header: _translations.byMDJXBp || (_translations.byMDJXBp = tr("Host message")), body: MessageHelper.bbcode_chat(properties.virtualserver_hostmessage), footer: undefined }).open(); if (properties.virtualserver_hostmessage_mode == 3) { /* first let the client initialize his stuff */ setTimeout(() => { this.connection_handler.log.log(log.server.Type.SERVER_HOST_MESSAGE_DISCONNECT, { message: properties.virtualserver_welcomemessage }); this.connection.disconnect("host message disconnect"); this.connection_handler.handleDisconnect(DisconnectReason.SERVER_HOSTMESSAGE); this.connection_handler.sound.play(Sound.CONNECTION_DISCONNECTED); }, 100); } } } /* welcome message */ if (properties.virtualserver_welcomemessage) { this.connection_handler.log.log(log.server.Type.SERVER_WELCOME_MESSAGE, { message: properties.virtualserver_welcomemessage }); } /* priviledge key */ if (properties.virtualserver_ask_for_privilegekey) { createInputModal(_translations.kJ99wZWj || (_translations.kJ99wZWj = tr("Use a privilege key")), _translations.vSKb8F5P || (_translations.vSKb8F5P = tr("This is a newly created server for which administrator privileges have not yet been claimed.
Please enter the \"privilege key\" that was automatically generated when this server was created to gain administrator permissions.")), message => message.length > 0, result => { if (!result) return; const scon = server_connections.active_connection_handler(); if (scon.serverConnection.connected) scon.serverConnection.send_command("tokenuse", { token: result }).then(() => { createInfoModal(_translations.z78_SMMr || (_translations.z78_SMMr = tr("Use privilege key")), _translations.smS5MNGV || (_translations.smS5MNGV = tr("Privilege key successfully used!"))).open(); }).catch(error => { createErrorModal(_translations.yKYk5MrN || (_translations.yKYk5MrN = tr("Use privilege key")), MessageHelper.formatMessage(_translations.T9XgymAy || (_translations.T9XgymAy = tr("Failed to use privilege key: {}")), error instanceof CommandResult ? error.message : error)).open(); }); }, { field_placeholder: 'Enter Privilege Key' }).open(); } this.connection_handler.log.log(log.server.Type.CONNECTION_CONNECTED, { own_client: this.connection_handler.getClient().log_data() }); this.connection_handler.sound.play(Sound.CONNECTION_CONNECTED); this.connection.client.onConnected(); } handleNotifyServerConnectionInfo(json) { json = json[0]; /* everything is a number, so lets parse it */ for (const key of Object.keys(json)) json[key] = parseFloat(json[key]); this.connection_handler.channelTree.server.set_connection_info(json); } handleNotifyConnectionInfo(json) { json = json[0]; const object = new ClientConnectionInfo(); /* everything is a number (except ip), so lets parse it */ for (const key of Object.keys(json)) { if (key === "connection_client_ip") object[key] = json[key]; else object[key] = parseFloat(json[key]); } const client = this.connection_handler.channelTree.findClient(parseInt(json["clid"])); if (!client) { log.warn(LogCategory.NETWORKING, _translations.xGqliR_T || (_translations.xGqliR_T = tr("Received client connection info for unknown client (%o)")), json["clid"]); return; } client.set_connection_info(object); } createChannelFromJson(json, ignoreOrder = false) { let tree = this.connection.client.channelTree; let channel = new ChannelEntry(parseInt(json["cid"]), json["channel_name"], tree.findChannel(json["cpid"])); tree.insertChannel(channel); if (json["channel_order"] !== "0") { let prev = tree.findChannel(json["channel_order"]); if (!prev && json["channel_order"] != 0) { if (!ignoreOrder) { log.error(LogCategory.NETWORKING, _translations.hTYqyg0W || (_translations.hTYqyg0W = tr("Invalid channel order id!"))); return; } } let parent = tree.findChannel(json["cpid"]); if (!parent && json["cpid"] != 0) { log.error(LogCategory.NETWORKING, _translations.LZKNb1ud || (_translations.LZKNb1ud = tr("Invalid channel parent"))); return; } tree.moveChannel(channel, prev, parent); //TODO test if channel exists! } if (ignoreOrder) { for (let ch of tree.channels) { if (ch.properties.channel_order == channel.channelId) { tree.moveChannel(ch, channel, channel.parent); //Corrent the order :) } } } let updates = []; for (let key in json) { if (key === "cid") continue; if (key === "cpid") continue; if (key === "invokerid") continue; if (key === "invokername") continue; if (key === "invokeruid") continue; if (key === "reasonid") continue; updates.push({ key: key, value: json[key] }); } channel.updateVariables(...updates); } handleCommandChannelList(json) { this.connection.client.channelTree.hide_channel_tree(); /* dont perform channel inserts on the dom to prevent style recalculations */ log.debug(LogCategory.NETWORKING, _translations.m95mid7y || (_translations.m95mid7y = tr("Got %d new channels")), json.length); for (let index = 0; index < json.length; index++) this.createChannelFromJson(json[index], true); } handleCommandChannelListFinished(json) { this.connection.client.channelTree.show_channel_tree(); } handleCommandChannelCreate(json) { this.createChannelFromJson(json[0]); } handleCommandChannelShow(json) { this.createChannelFromJson(json[0]); //TODO may chat? } handleCommandChannelDelete(json) { let tree = this.connection.client.channelTree; const conversations = this.connection.client.side_bar.channel_conversations(); log.info(LogCategory.NETWORKING, _translations.cO7AsMbZ || (_translations.cO7AsMbZ = tr("Got %d channel deletions")), json.length); for (let index = 0; index < json.length; index++) { conversations.delete_conversation(parseInt(json[index]["cid"])); let channel = tree.findChannel(json[index]["cid"]); if (!channel) { log.error(LogCategory.NETWORKING, _translations.Tr8N0T8J || (_translations.Tr8N0T8J = tr("Invalid channel onDelete (Unknown channel)"))); continue; } tree.deleteChannel(channel); } } handleCommandChannelHide(json) { let tree = this.connection.client.channelTree; const conversations = this.connection.client.side_bar.channel_conversations(); log.info(LogCategory.NETWORKING, _translations.tGrW50fT || (_translations.tGrW50fT = tr("Got %d channel hides")), json.length); for (let index = 0; index < json.length; index++) { conversations.delete_conversation(parseInt(json[index]["cid"])); let channel = tree.findChannel(json[index]["cid"]); if (!channel) { log.error(LogCategory.NETWORKING, _translations.tqXi_0qx || (_translations.tqXi_0qx = tr("Invalid channel on hide (Unknown channel)"))); continue; } tree.deleteChannel(channel); } } handleCommandClientEnterView(json) { let tree = this.connection.client.channelTree; let client; let channel = undefined; let old_channel = undefined; let reason_id, reason_msg; let invokerid, invokername, invokeruid; for (const entry of json) { /* attempt to update properties if given */ channel = typeof (entry["ctid"]) !== "undefined" ? tree.findChannel(parseInt(entry["ctid"])) : channel; old_channel = typeof (entry["cfid"]) !== "undefined" ? tree.findChannel(parseInt(entry["cfid"])) : old_channel; reason_id = typeof (entry["reasonid"]) !== "undefined" ? entry["reasonid"] : reason_id; reason_msg = typeof (entry["reason_msg"]) !== "undefined" ? entry["reason_msg"] : reason_msg; invokerid = typeof (entry["invokerid"]) !== "undefined" ? parseInt(entry["invokerid"]) : invokerid; invokername = typeof (entry["invokername"]) !== "undefined" ? entry["invokername"] : invokername; invokeruid = typeof (entry["invokeruid"]) !== "undefined" ? entry["invokeruid"] : invokeruid; client = tree.findClient(parseInt(entry["clid"])); if (!client) { if (parseInt(entry["client_type_exact"]) == ClientType.CLIENT_MUSIC) { client = new MusicClientEntry(parseInt(entry["clid"]), entry["client_nickname"]); } else { client = new ClientEntry(parseInt(entry["clid"]), entry["client_nickname"]); } client.properties.client_type = parseInt(entry["client_type"]); client = tree.insertClient(client, channel); } else { tree.moveClient(client, channel); } if (this.connection_handler.client_status.queries_visible || client.properties.client_type != ClientType.CLIENT_QUERY) { const own_channel = this.connection.client.getClient().currentChannel(); this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_ENTER, { channel_from: old_channel ? old_channel.log_data() : undefined, channel_to: channel ? channel.log_data() : undefined, client: client.log_data(), invoker: this.loggable_invoker(invokeruid, invokerid, invokername), message: reason_msg, reason: parseInt(reason_id), own_channel: channel == own_channel }); if (reason_id == ViewReasonId.VREASON_USER_ACTION) { if (own_channel == channel) if (old_channel) this.connection_handler.sound.play(Sound.USER_ENTERED); else this.connection_handler.sound.play(Sound.USER_ENTERED_CONNECT); } else if (reason_id == ViewReasonId.VREASON_MOVED) { if (own_channel == channel) this.connection_handler.sound.play(Sound.USER_ENTERED_MOVED); } else if (reason_id == ViewReasonId.VREASON_CHANNEL_KICK) { if (own_channel == channel) this.connection_handler.sound.play(Sound.USER_ENTERED_KICKED); } else if (reason_id == ViewReasonId.VREASON_SYSTEM) { } else { console.warn(_translations.YwXRwg0u || (_translations.YwXRwg0u = tr("Unknown reasonid for %o")), reason_id); } } let updates = []; for (let key in entry) { if (key == "cfid") continue; if (key == "ctid") continue; if (key === "invokerid") continue; if (key === "invokername") continue; if (key === "invokeruid") continue; if (key === "reasonid") continue; updates.push({ key: key, value: entry[key] }); } client.updateVariables(...updates); /* if its a new client join, or a system reason (like we joined) */ if (!old_channel || reason_id == 2) { /* client new join */ const conversation_manager = this.connection_handler.side_bar.private_conversations(); const conversation = conversation_manager.find_conversation({ unique_id: client.properties.client_unique_identifier, client_id: client.clientId(), name: client.clientNickName() }, { create: false, attach: true }); if (conversation) client.flag_text_unread = conversation.is_unread(); } if (client instanceof LocalClientEntry) { client.initializeListener(); this.connection_handler.update_voice_status(); this.connection_handler.side_bar.info_frame().update_channel_talk(); const conversations = this.connection.client.side_bar.channel_conversations(); conversations.set_current_channel(client.currentChannel().channelId); } } } handleCommandClientLeftView(json) { let reason_id = -1; for (const entry of json) { reason_id = entry["reasonid"] || reason_id; let tree = this.connection.client.channelTree; let client = tree.findClient(entry["clid"]); if (!client) { log.error(LogCategory.NETWORKING, _translations.cJ2nujBf || (_translations.cJ2nujBf = tr("Unknown client left!"))); return 0; } if (client == this.connection.client.getClient()) { if (reason_id == ViewReasonId.VREASON_BAN) { this.connection.client.handleDisconnect(DisconnectReason.CLIENT_BANNED, entry); } else if (reason_id == ViewReasonId.VREASON_SERVER_KICK) { this.connection.client.handleDisconnect(DisconnectReason.CLIENT_KICKED, entry); } else if (reason_id == ViewReasonId.VREASON_SERVER_SHUTDOWN) { this.connection.client.handleDisconnect(DisconnectReason.SERVER_CLOSED, entry); } else if (reason_id == ViewReasonId.VREASON_SERVER_STOPPED) { this.connection.client.handleDisconnect(DisconnectReason.SERVER_CLOSED, entry); } else { this.connection.client.handleDisconnect(DisconnectReason.UNKNOWN, entry); } this.connection_handler.side_bar.info_frame().update_channel_talk(); return; } if (this.connection_handler.client_status.queries_visible || client.properties.client_type != ClientType.CLIENT_QUERY) { const own_channel = this.connection.client.getClient().currentChannel(); let channel_from = tree.findChannel(entry["cfid"]); let channel_to = tree.findChannel(entry["ctid"]); const is_own_channel = channel_from == own_channel; this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_LEAVE, { channel_from: channel_from ? channel_from.log_data() : undefined, channel_to: channel_to ? channel_to.log_data() : undefined, client: client.log_data(), invoker: this.loggable_invoker(entry["invokeruid"], entry["invokerid"], entry["invokername"]), message: entry["reasonmsg"], reason: parseInt(entry["reasonid"]), ban_time: parseInt(entry["bantime"]), own_channel: is_own_channel }); if (is_own_channel) { if (reason_id == ViewReasonId.VREASON_USER_ACTION) { this.connection_handler.sound.play(Sound.USER_LEFT); } else if (reason_id == ViewReasonId.VREASON_SERVER_LEFT) { this.connection_handler.sound.play(Sound.USER_LEFT_DISCONNECT); } else if (reason_id == ViewReasonId.VREASON_SERVER_KICK) { this.connection_handler.sound.play(Sound.USER_LEFT_KICKED_SERVER); } else if (reason_id == ViewReasonId.VREASON_CHANNEL_KICK) { this.connection_handler.sound.play(Sound.USER_LEFT_KICKED_CHANNEL); } else if (reason_id == ViewReasonId.VREASON_BAN) { this.connection_handler.sound.play(Sound.USER_LEFT_BANNED); } else if (reason_id == ViewReasonId.VREASON_TIMEOUT) { this.connection_handler.sound.play(Sound.USER_LEFT_TIMEOUT); } else if (reason_id == ViewReasonId.VREASON_MOVED) { this.connection_handler.sound.play(Sound.USER_LEFT_MOVED); } else { log.error(LogCategory.NETWORKING, _translations.NTMrV0pQ || (_translations.NTMrV0pQ = tr("Unknown client left reason %d!")), reason_id); } } if (!channel_to) { /* client left the server */ const conversation_manager = this.connection_handler.side_bar.private_conversations(); const conversation = conversation_manager.find_conversation({ unique_id: client.properties.client_unique_identifier, client_id: client.clientId(), name: client.clientNickName() }, { create: false, attach: false }); if (conversation) { conversation.set_state(chat.PrivateConversationState.DISCONNECTED); } } } tree.deleteClient(client); } } handleNotifyClientMoved(json) { json = json[0]; //Only one bulk let tree = this.connection.client.channelTree; let client = tree.findClient(json["clid"]); let self = client instanceof LocalClientEntry; let channel_to = tree.findChannel(parseInt(json["ctid"])); let channel_from = tree.findChannel(parseInt(json["cfid"])); if (!client) { log.error(LogCategory.NETWORKING, _translations.gEcJmHRi || (_translations.gEcJmHRi = tr("Unknown client move (Client)!"))); return 0; } if (!channel_to) { log.error(LogCategory.NETWORKING, _translations.rsbbZ5vo || (_translations.rsbbZ5vo = tr("Unknown client move (Channel to)!"))); return 0; } if (!self) { if (!channel_from) { log.error(LogCategory.NETWORKING, _translations.FUu2Z3p0 || (_translations.FUu2Z3p0 = tr("Unknown client move (Channel from)!"))); channel_from = client.currentChannel(); } else if (channel_from != client.currentChannel()) { log.error(LogCategory.NETWORKING, _translations.BuZ27Ktg || (_translations.BuZ27Ktg = tr("Client move from invalid source channel! Local client registered in channel %d but server send %d.")), client.currentChannel().channelId, channel_from.channelId); } } else { channel_from = client.currentChannel(); } tree.moveClient(client, channel_to); if (self) { this.connection_handler.update_voice_status(channel_to); for (const entry of client.channelTree.clientsByChannel(channel_from)) { if (entry !== client && entry.get_audio_handle()) { entry.get_audio_handle().abort_replay(); entry.speaking = false; } } const side_bar = this.connection_handler.side_bar; side_bar.info_frame().update_channel_talk(); const conversation_to = side_bar.channel_conversations().conversation(channel_to.channelId, false); if (conversation_to) conversation_to.update_private_state(); if (channel_from) { const conversation_from = side_bar.channel_conversations().conversation(channel_from.channelId, false); if (conversation_from) conversation_from.update_private_state(); } side_bar.channel_conversations().update_chat_box(); } const own_channel = this.connection.client.getClient().currentChannel(); this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_MOVE, { channel_from: channel_from ? { channel_id: channel_from.channelId, channel_name: channel_from.channelName() } : undefined, channel_from_own: channel_from == own_channel, channel_to: channel_to ? { channel_id: channel_to.channelId, channel_name: channel_to.channelName() } : undefined, channel_to_own: channel_to == own_channel, client: { client_id: client.clientId(), client_name: client.clientNickName(), client_unique_id: client.properties.client_unique_identifier }, client_own: self, invoker: this.loggable_invoker(json["invokeruid"], json["invokerid"], json["invokername"]), message: json["reasonmsg"], reason: parseInt(json["reasonid"]), }); if (json["reasonid"] == ViewReasonId.VREASON_MOVED) { if (self) this.connection_handler.sound.play(Sound.USER_MOVED_SELF); else if (own_channel == channel_to) this.connection_handler.sound.play(Sound.USER_ENTERED_MOVED); else if (own_channel == channel_from) this.connection_handler.sound.play(Sound.USER_LEFT_MOVED); } else if (json["reasonid"] == ViewReasonId.VREASON_USER_ACTION) { if (self) { } //If we do an action we wait for the error response else if (own_channel == channel_to) this.connection_handler.sound.play(Sound.USER_ENTERED); else if (own_channel == channel_from) this.connection_handler.sound.play(Sound.USER_LEFT); } else if (json["reasonid"] == ViewReasonId.VREASON_CHANNEL_KICK) { if (self) { this.connection_handler.sound.play(Sound.CHANNEL_KICKED); } else if (own_channel == channel_to) this.connection_handler.sound.play(Sound.USER_ENTERED_KICKED); else if (own_channel == channel_from) this.connection_handler.sound.play(Sound.USER_LEFT_KICKED_CHANNEL); } else { console.warn(_translations.BID316jI || (_translations.BID316jI = tr("Unknown reason id %o")), json["reasonid"]); } } handleNotifyChannelMoved(json) { json = json[0]; //Only one bulk let tree = this.connection.client.channelTree; let channel = tree.findChannel(json["cid"]); if (!channel) { log.error(LogCategory.NETWORKING, _translations.fzc4kFcz || (_translations.fzc4kFcz = tr("Unknown channel move (Channel)!"))); return 0; } let prev = tree.findChannel(json["order"]); if (!prev && json["order"] != 0) { log.error(LogCategory.NETWORKING, _translations.mF6Ppr3u || (_translations.mF6Ppr3u = tr("Unknown channel move (prev)!"))); return 0; } let parent = tree.findChannel(json["cpid"]); if (!parent && json["cpid"] != 0) { log.error(LogCategory.NETWORKING, _translations.XxAerQnq || (_translations.XxAerQnq = tr("Unknown channel move (parent)!"))); return 0; } tree.moveChannel(channel, prev, parent); } handleNotifyChannelEdited(json) { json = json[0]; //Only one bulk let tree = this.connection.client.channelTree; let channel = tree.findChannel(json["cid"]); if (!channel) { log.error(LogCategory.NETWORKING, _translations.tBW9j_7C || (_translations.tBW9j_7C = tr("Unknown channel edit (Channel)!"))); return 0; } let updates = []; for (let key in json) { if (key === "cid") continue; if (key === "invokerid") continue; if (key === "invokername") continue; if (key === "invokeruid") continue; if (key === "reasonid") continue; updates.push({ key: key, value: json[key] }); } channel.updateVariables(...updates); if (this.connection_handler.getClient().currentChannel() === channel) { //TODO: Playback sound that your channel has been edited this.connection_handler.update_voice_status(); } } handleNotifyTextMessage(json) { json = json[0]; //Only one bulk let mode = json["targetmode"]; if (mode == 1) { //json["invokerid"], json["invokername"], json["invokeruid"] const target_client_id = parseInt(json["target"]); const target_own = target_client_id === this.connection.client.getClientId(); if (target_own && target_client_id === json["invokerid"]) { log.error(LogCategory.NETWORKING, tr("Received conversation message from invalid client id. Data: %o", json)); return; } const conversation_manager = this.connection_handler.side_bar.private_conversations(); const conversation = conversation_manager.find_conversation({ client_id: target_own ? parseInt(json["invokerid"]) : target_client_id, unique_id: target_own ? json["invokeruid"] : undefined, name: target_own ? json["invokername"] : undefined }, { create: target_own, attach: target_own }); if (!conversation) { log.error(LogCategory.NETWORKING, _translations._E2eMYr4 || (_translations._E2eMYr4 = tr("Received conversation message for unknown conversation! (%s)")), target_own ? _translations.kgIHfhjS || (_translations.kgIHfhjS = tr("Remote message")) : _translations.ruiHzDfv || (_translations.ruiHzDfv = tr("Own message"))); return; } conversation.append_message(json["msg"], { type: target_own ? "partner" : "self", name: json["invokername"], unique_id: json["invokeruid"], client_id: parseInt(json["invokerid"]) }); if (target_own) { this.connection_handler.sound.play(Sound.MESSAGE_RECEIVED, { default_volume: .5 }); const client = this.connection_handler.channelTree.findClient(parseInt(json["invokerid"])); if (client) /* the client itself might be invisible */ client.flag_text_unread = conversation.is_unread(); } else { this.connection_handler.sound.play(Sound.MESSAGE_SEND, { default_volume: .5 }); } } else if (mode == 2) { const invoker = this.connection_handler.channelTree.findClient(parseInt(json["invokerid"])); const own_channel_id = this.connection.client.getClient().currentChannel().channelId; const channel_id = typeof (json["cid"]) !== "undefined" ? parseInt(json["cid"]) : own_channel_id; const channel = this.connection_handler.channelTree.findChannel(channel_id) || this.connection_handler.getClient().currentChannel(); if (json["invokerid"] == this.connection.client.clientId) this.connection_handler.sound.play(Sound.MESSAGE_SEND, { default_volume: .5 }); else if (channel_id == own_channel_id) { this.connection_handler.sound.play(Sound.MESSAGE_RECEIVED, { default_volume: .5 }); } const conversations = this.connection_handler.side_bar.channel_conversations(); const conversation = conversations.conversation(channel_id); conversation.register_new_message({ sender_database_id: invoker ? invoker.properties.client_database_id : 0, sender_name: json["invokername"], sender_unique_id: json["invokeruid"], timestamp: typeof (json["timestamp"]) === "undefined" ? Date.now() : parseInt(json["timestamp"]), message: json["msg"] }); if (conversation.is_unread() && channel) channel.flag_text_unread = true; } else if (mode == 3) { this.connection_handler.log.log(log.server.Type.GLOBAL_MESSAGE, { message: json["msg"], sender: { client_unique_id: json["invokeruid"], client_name: json["invokername"], client_id: parseInt(json["invokerid"]) } }); const invoker = this.connection_handler.channelTree.findClient(parseInt(json["invokerid"])); const conversations = this.connection_handler.side_bar.channel_conversations(); const conversation = conversations.conversation(0); conversation.register_new_message({ sender_database_id: invoker ? invoker.properties.client_database_id : 0, sender_name: json["invokername"], sender_unique_id: json["invokeruid"], timestamp: typeof (json["timestamp"]) === "undefined" ? Date.now() : parseInt(json["timestamp"]), message: json["msg"] }); this.connection_handler.channelTree.server.flag_text_unread = conversation.is_unread(); } } notifyClientChatComposing(json) { json = json[0]; const conversation_manager = this.connection_handler.side_bar.private_conversations(); const conversation = conversation_manager.find_conversation({ client_id: parseInt(json["clid"]), unique_id: json["cluid"], name: undefined }, { create: false, attach: false }); if (!conversation) return; conversation.trigger_typing(); } handleNotifyClientChatClosed(json) { json = json[0]; //Only one bulk //Chat partner has closed the conversation //clid: "6" //cluid: "YoWmG+dRGKD+Rxb7SPLAM5+B9tY=" const conversation_manager = this.connection_handler.side_bar.private_conversations(); const conversation = conversation_manager.find_conversation({ client_id: parseInt(json["clid"]), unique_id: json["cluid"], name: undefined }, { create: false, attach: false }); if (!conversation) { log.warn(LogCategory.GENERAL, _translations.U0exVRxM || (_translations.U0exVRxM = tr("Received chat close for client, but we haven't a chat open."))); return; } conversation.set_state(chat.PrivateConversationState.CLOSED); } handleNotifyClientUpdated(json) { json = json[0]; //Only one bulk let client = this.connection.client.channelTree.findClient(json["clid"]); if (!client) { log.error(LogCategory.NETWORKING, _translations.suQhKZ2M || (_translations.suQhKZ2M = tr("Tried to update an non existing client"))); return; } let updates = []; for (let key in json) { if (key == "clid") continue; updates.push({ key: key, value: json[key] }); } client.updateVariables(...updates); } handleNotifyServerEdited(json) { json = json[0]; let updates = []; for (let key in json) { if (key === "invokerid") continue; if (key === "invokername") continue; if (key === "invokeruid") continue; if (key === "reasonid") continue; updates.push({ key: key, value: json[key] }); } this.connection.client.channelTree.server.updateVariables(false, ...updates); } handleNotifyServerUpdated(json) { json = json[0]; let updates = []; for (let key in json) { if (key === "invokerid") continue; if (key === "invokername") continue; if (key === "invokeruid") continue; if (key === "reasonid") continue; updates.push({ key: key, value: json[key] }); } this.connection.client.channelTree.server.updateVariables(true, ...updates); } handleNotifyMusicPlayerInfo(json) { json = json[0]; let bot = this.connection.client.channelTree.find_client_by_dbid(json["bot_id"]); if (!bot || !(bot instanceof MusicClientEntry)) { log.warn(LogCategory.CLIENT, _translations.BxOvO8Ec || (_translations.BxOvO8Ec = tr("Got music player info for unknown or invalid bot! (ID: %i, Entry: %o)")), json["bot_id"], bot); return; } bot.handlePlayerInfo(json); } handleNotifyClientPoke(json) { json = json[0]; Modals.spawnPoke(this.connection_handler, { id: parseInt(json["invokerid"]), name: json["invokername"], unique_id: json["invokeruid"] }, json["msg"]); this.connection_handler.sound.play(Sound.USER_POKED_SELF); } //TODO server chat message handleNotifyServerGroupClientAdd(json) { json = json[0]; const self = this.connection.client.getClient(); if (json["clid"] == self.clientId()) this.connection_handler.sound.play(Sound.GROUP_SERVER_ASSIGNED_SELF); } //TODO server chat message handleNotifyServerGroupClientRemove(json) { json = json[0]; const self = this.connection.client.getClient(); if (json["clid"] == self.clientId()) { this.connection_handler.sound.play(Sound.GROUP_SERVER_REVOKED_SELF); } else { } } //TODO server chat message handleNotifyClientChannelGroupChanged(json) { json = json[0]; const self = this.connection.client.getClient(); if (json["clid"] == self.clientId()) { this.connection_handler.sound.play(Sound.GROUP_CHANNEL_CHANGED_SELF); } } handleNotifyChannelSubscribed(json) { for (const entry of json) { const channel = this.connection.client.channelTree.findChannel(entry["cid"]); if (!channel) { console.warn(_translations._5Wlb_tM || (_translations._5Wlb_tM = tr("Received channel subscribed for not visible channel (cid: %d)")), entry['cid']); continue; } channel.flag_subscribed = true; } } handleNotifyChannelUnsubscribed(json) { for (const entry of json) { const channel = this.connection.client.channelTree.findChannel(entry["cid"]); if (!channel) { console.warn(_translations.HMeyZ6hh || (_translations.HMeyZ6hh = tr("Received channel unsubscribed for not visible channel (cid: %d)")), entry['cid']); continue; } channel.flag_subscribed = false; for (const client of channel.clients(false)) this.connection.client.channelTree.deleteClient(client); } } handleNotifyConversationHistory(json) { const conversations = this.connection.client.side_bar.channel_conversations(); const conversation = conversations.conversation(parseInt(json[0]["cid"])); if (!conversation) { log.warn(LogCategory.NETWORKING, _translations.bkMX72xe || (_translations.bkMX72xe = tr("Received conversation history for invalid or unknown conversation (%o)")), json[0]["cid"]); return; } for (const entry of json) { conversation.register_new_message({ message: entry["msg"], sender_unique_id: entry["sender_unique_id"], sender_name: entry["sender_name"], timestamp: parseInt(entry["timestamp"]), sender_database_id: parseInt(entry["sender_database_id"]) }, false); } /* now update the boxes */ /* No update needed because the command which triggers this notify should update the chat box on success conversation.fix_scroll(true); conversation.handle.update_chat_box(); */ } handleNotifyConversationMessageDelete(json) { let conversation; const conversations = this.connection.client.side_bar.channel_conversations(); for (const entry of json) { if (typeof (entry["cid"]) !== "undefined") conversation = conversations.conversation(parseInt(entry["cid"]), false); if (!conversation) continue; conversation.delete_messages(parseInt(entry["timestamp_begin"]), parseInt(entry["timestamp_end"]), parseInt(entry["cldbid"]), parseInt(entry["limit"])); } } handleNotifyMusicStatusUpdate(json) { json = json[0]; const bot_id = parseInt(json["bot_id"]); const client = this.connection.client.channelTree.find_client_by_dbid(bot_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.Pqgsw3nk || (_translations.Pqgsw3nk = tr("Received music bot status update for unknown bot (%d)")), bot_id); return; } client.events.fire("music_status_update", { player_replay_index: parseInt(json["player_replay_index"]), player_buffered_index: parseInt(json["player_buffered_index"]) }); } handleMusicPlayerSongChange(json) { json = json[0]; const bot_id = parseInt(json["bot_id"]); const client = this.connection.client.channelTree.find_client_by_dbid(bot_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.acswhp6U || (_translations.acswhp6U = tr("Received music bot status update for unknown bot (%d)")), bot_id); return; } const song_id = parseInt(json["song_id"]); let song; if (song_id) { song = new SongInfo(); JSON.map_to(song, json); } client.events.fire("music_song_change", { song: song }); } handleNotifyPlaylistSongAdd(json) { json = json[0]; const playlist_id = parseInt(json["playlist_id"]); const client = this.connection.client.channelTree.clients.find(e => e instanceof MusicClientEntry && e.properties.client_playlist_id === playlist_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.JHeDrma5 || (_translations.JHeDrma5 = tr("Received playlist song add event, but we've no music bot for the playlist (%d)")), playlist_id); return; } client.events.fire("playlist_song_add", { song: { song_id: parseInt(json["song_id"]), song_invoker: json["song_invoker"], song_previous_song_id: parseInt(json["song_previous_song_id"]), song_url: json["song_url"], song_url_loader: json["song_url_loader"], song_loaded: json["song_loaded"] == true || json["song_loaded"] == "1", song_metadata: json["song_metadata"] } }); } handleNotifyPlaylistSongRemove(json) { json = json[0]; const playlist_id = parseInt(json["playlist_id"]); const client = this.connection.client.channelTree.clients.find(e => e instanceof MusicClientEntry && e.properties.client_playlist_id === playlist_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.KYFQM8h2 || (_translations.KYFQM8h2 = tr("Received playlist song remove event, but we've no music bot for the playlist (%d)")), playlist_id); return; } const song_id = parseInt(json["song_id"]); client.events.fire("playlist_song_remove", { song_id: song_id }); } handleNotifyPlaylistSongReorder(json) { json = json[0]; const playlist_id = parseInt(json["playlist_id"]); const client = this.connection.client.channelTree.clients.find(e => e instanceof MusicClientEntry && e.properties.client_playlist_id === playlist_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.MX9isGwd || (_translations.MX9isGwd = tr("Received playlist song reorder event, but we've no music bot for the playlist (%d)")), playlist_id); return; } const song_id = parseInt(json["song_id"]); const previous_song_id = parseInt(json["song_previous_song_id"]); client.events.fire("playlist_song_reorder", { song_id: song_id, previous_song_id: previous_song_id }); } handleNotifyPlaylistSongLoaded(json) { json = json[0]; const playlist_id = parseInt(json["playlist_id"]); const client = this.connection.client.channelTree.clients.find(e => e instanceof MusicClientEntry && e.properties.client_playlist_id === playlist_id); if (!client) { log.warn(LogCategory.CLIENT, _translations.x8tCYqXl || (_translations.x8tCYqXl = tr("Received playlist song loaded event, but we've no music bot for the playlist (%d)")), playlist_id); return; } const song_id = parseInt(json["song_id"]); client.events.fire("playlist_song_loaded", { song_id: song_id, success: json["success"] == 1, error_msg: json["load_error_msg"], metadata: json["song_metadata"] }); } } connection_2.ConnectionCommandHandler = ConnectionCommandHandler; })(connection || (connection = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e9e95922a16d121df1c28714498c8e3967cc4a33184c1c27b9daebcd034ed5cd"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e9e95922a16d121df1c28714498c8e3967cc4a33184c1c27b9daebcd034ed5cd"] = "e9e95922a16d121df1c28714498c8e3967cc4a33184c1c27b9daebcd034ed5cd"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "MwbGPBq7", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (248,43)" }, { name: "nF1SZku6", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (271,43)" }, { name: "Ycyq5vFI", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (545,26)" }, { name: "xjn9wuVk", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (672,47)" }, { name: "Dqn_5EM4", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (681,47)" }, { name: "yJaaczeF", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (726,43)" }, { name: "HC0JhWOd", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (772,47)" }, { name: "Zfxv8Gh8", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (881,48)" }, { name: "RpfhT5G_", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (890,48)" }, { name: "qcVDOT3t", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (928,43)" }, { name: "KjfmxVkY", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (931,48)" }, { name: "N9t94bx_", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (940,48)" }, { name: "h_SQX0Ol", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (952,55)" }, { name: "W3cTHtbm", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (997,47)" }, { name: "n7xfvxab", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (999,74)" }, { name: "N5oq_P39", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (1062,48)" }, { name: "UUEkQF5a", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (1076,48)" }, { name: "qeVWbl1T", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (1082,56)" }, { name: "yPO5jFrp", path: "D:/TeaSpeak/web/shared/js/FileManager.ts (1099,46)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// class FileEntry { } class FileListRequest { } var transfer; (function (transfer) { function spawn_download_transfer(key) { return new RequestFileDownload(key); } transfer.spawn_download_transfer = spawn_download_transfer; function spawn_upload_transfer(key) { return new RequestFileUpload(key); } transfer.spawn_upload_transfer = spawn_upload_transfer; })(transfer || (transfer = {})); class RequestFileDownload { constructor(key) { this.transfer_key = key; } request_file() { return __awaiter(this, void 0, void 0, function* () { return yield this.try_fetch("https://" + this.transfer_key.peer.hosts[0] + ":" + this.transfer_key.peer.port); }); } try_fetch(url) { return __awaiter(this, void 0, void 0, function* () { const response = yield fetch(url, { method: 'GET', cache: "no-cache", mode: 'cors', headers: { 'transfer-key': this.transfer_key.key, 'download-name': this.transfer_key.file_name, 'Access-Control-Allow-Headers': '*', 'Access-Control-Expose-Headers': '*' } }); if (!response.ok) { debugger; throw (response.type == 'opaque' || response.type == 'opaqueredirect' ? "invalid cross origin flag! May target isn't a TeaSpeak server?" : response.statusText || "response is not ok"); } return response; }); } get_key() { return this.transfer_key; } } class RequestFileUpload { constructor(key) { this.transfer_key = key; } get_key() { return this.transfer_key; } put_data(data) { return __awaiter(this, void 0, void 0, function* () { const form_data = new FormData(); if (data instanceof File) { if (data.size != this.transfer_key.total_size) throw "invalid size"; form_data.append("file", data); } else if (typeof (data) === "string") { if (data.length != this.transfer_key.total_size) throw "invalid size"; form_data.append("file", new Blob([data], { type: "application/octet-stream" })); } else { const buffer = data; if (buffer.byteLength != this.transfer_key.total_size) throw "invalid size"; form_data.append("file", new Blob([buffer], { type: "application/octet-stream" })); } yield this.try_put(form_data, "https://" + this.transfer_key.peer.hosts[0] + ":" + this.transfer_key.peer.port); }); } try_put(data, url) { return __awaiter(this, void 0, void 0, function* () { const response = yield fetch(url, { method: 'POST', cache: "no-cache", mode: 'cors', body: data, headers: { 'transfer-key': this.transfer_key.key, 'Access-Control-Allow-Headers': '*', 'Access-Control-Expose-Headers': '*' } }); if (!response.ok) throw (response.type == 'opaque' || response.type == 'opaqueredirect' ? "invalid cross origin flag! May target isn't a TeaSpeak server?" : response.statusText || "response is not ok"); }); } } class FileManager extends connection.AbstractCommandHandler { constructor(client) { super(client.serverConnection); this.listRequests = []; this.pending_download_requests = []; this.pending_upload_requests = []; this.transfer_counter = 1; this.handle = client; this.icons = new IconManager(this); this.avatars = new AvatarManager(this); this.connection.command_handler_boss().register_handler(this); } destroy() { if (this.connection) { const hboss = this.connection.command_handler_boss(); if (hboss) hboss.unregister_handler(this); } this.listRequests = undefined; this.pending_download_requests = undefined; this.pending_upload_requests = undefined; this.icons && this.icons.destroy(); this.icons = undefined; this.avatars && this.avatars.destroy(); this.avatars = undefined; } handle_command(command) { switch (command.command) { case "notifyfilelist": this.notifyFileList(command.arguments); return true; case "notifyfilelistfinished": this.notifyFileListFinished(command.arguments); return true; case "notifystartdownload": this.notifyStartDownload(command.arguments); return true; case "notifystartupload": this.notifyStartUpload(command.arguments); return true; } return false; } /******************************** File list ********************************/ //TODO multiple requests (same path) 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.send_command("ftgetfilelist", { "path": path, "cid": (channel ? channel.channelId : "0"), "cpw": (password ? password : "") }).then(() => { }).catch(reason => { _this.listRequests.remove(req); if (reason instanceof CommandResult) { if (reason.id == 0x0501) { accept([]); //Empty result return; } } reject(reason); }); }); } notifyFileList(json) { let entry = undefined; for (let e of this.listRequests) { if (e.path == json[0]["path"]) { entry = e; break; } } if (!entry) { log.error(LogCategory.CLIENT, _translations.MwbGPBq7 || (_translations.MwbGPBq7 = tr("Invalid file list entry. Path: %s")), json[0]["path"]); return; } for (let e of json) { e.datetime = parseInt(e.datetime + ""); e.size = parseInt(e.size + ""); e.type = parseInt(e.type + ""); entry.entries.push(e); } } notifyFileListFinished(json) { let entry = undefined; for (let e of this.listRequests) { if (e.path == json[0]["path"]) { entry = e; this.listRequests.remove(e); break; } } if (!entry) { log.error(LogCategory.CLIENT, _translations.nF1SZku6 || (_translations.nF1SZku6 = tr("Invalid file list entry finish. Path: ")), json[0]["path"]); return; } entry.callback(entry.entries); } /******************************** File download/upload ********************************/ download_file(path, file, channel, password) { const transfer_data = { file_name: file, file_path: path, client_transfer_id: this.transfer_counter++ }; this.pending_download_requests.push(transfer_data); return new Promise((resolve, reject) => { transfer_data["_callback"] = resolve; this.handle.serverConnection.send_command("ftinitdownload", { "path": path, "name": file, "cid": (channel ? channel.channelId : "0"), "cpw": (password ? password : ""), "clientftfid": transfer_data.client_transfer_id, "seekpos": 0, "proto": 1 }, { process_result: false }).catch(reason => { this.pending_download_requests.remove(transfer_data); reject(reason); }); }); } upload_file(options) { const transfer_data = { file_path: options.path, file_name: options.name, client_transfer_id: this.transfer_counter++, total_size: options.size }; this.pending_upload_requests.push(transfer_data); return new Promise((resolve, reject) => { transfer_data["_callback"] = resolve; this.handle.serverConnection.send_command("ftinitupload", { "path": options.path, "name": options.name, "cid": (options.channel ? options.channel.channelId : "0"), "cpw": options.channel_password || "", "clientftfid": transfer_data.client_transfer_id, "size": options.size, "overwrite": options.overwrite, "resume": false, "proto": 1 }).catch(reason => { this.pending_upload_requests.remove(transfer_data); reject(reason); }); }); } notifyStartDownload(json) { json = json[0]; let clientftfid = parseInt(json["clientftfid"]); let transfer; for (let e of this.pending_download_requests) if (e.client_transfer_id == clientftfid) { transfer = e; break; } transfer.server_transfer_id = parseInt(json["serverftfid"]); transfer.key = json["ftkey"]; transfer.total_size = json["size"]; transfer.peer = { hosts: (json["ip"] || "").split(","), port: parseInt(json["port"]) }; if (transfer.peer.hosts.length == 0) transfer.peer.hosts.push("0.0.0.0"); if (transfer.peer.hosts[0].length == 0 || transfer.peer.hosts[0] == '0.0.0.0') transfer.peer.hosts[0] = this.handle.serverConnection.remote_address().host; transfer["_callback"](transfer); this.pending_download_requests.remove(transfer); } notifyStartUpload(json) { json = json[0]; let transfer; let clientftfid = parseInt(json["clientftfid"]); for (let e of this.pending_upload_requests) if (e.client_transfer_id == clientftfid) { transfer = e; break; } transfer.server_transfer_id = parseInt(json["serverftfid"]); transfer.key = json["ftkey"]; transfer.peer = { hosts: (json["ip"] || "").split(","), port: parseInt(json["port"]) }; if (transfer.peer.hosts.length == 0) transfer.peer.hosts.push("0.0.0.0"); if (transfer.peer.hosts[0].length == 0 || transfer.peer.hosts[0] == '0.0.0.0') transfer.peer.hosts[0] = this.handle.serverConnection.remote_address().host; transfer["_callback"](transfer); this.pending_upload_requests.remove(transfer); } /** File management **/ delete_file(props) { return __awaiter(this, void 0, void 0, function* () { if (!props.name) throw "invalid name!"; try { yield this.handle.serverConnection.send_command("ftdeletefile", { cid: props.cid || 0, cpw: props.cpw, path: props.path || "", name: props.name }); } catch (error) { throw error; } }); } } class Icon { } var ImageType; (function (ImageType) { ImageType[ImageType["UNKNOWN"] = 0] = "UNKNOWN"; ImageType[ImageType["BITMAP"] = 1] = "BITMAP"; ImageType[ImageType["PNG"] = 2] = "PNG"; ImageType[ImageType["GIF"] = 3] = "GIF"; ImageType[ImageType["SVG"] = 4] = "SVG"; ImageType[ImageType["JPEG"] = 5] = "JPEG"; })(ImageType || (ImageType = {})); function media_image_type(type, file) { switch (type) { case ImageType.BITMAP: return "bmp"; case ImageType.GIF: return "gif"; case ImageType.SVG: return file ? "svg" : "svg+xml"; case ImageType.JPEG: return "jpeg"; case ImageType.UNKNOWN: case ImageType.PNG: default: return "png"; } } function image_type(encoded_data, base64_encoded) { const ab2str10 = () => { const buf = new Uint8Array(encoded_data); if (buf.byteLength < 10) return ""; let result = ""; for (let index = 0; index < 10; index++) result += String.fromCharCode(buf[index]); return result; }; const bin = typeof (encoded_data) === "string" ? ((typeof (base64_encoded) === "undefined" || base64_encoded) ? atob(encoded_data) : encoded_data) : ab2str10(); if (bin.length < 10) return ImageType.UNKNOWN; if (bin[0] == String.fromCharCode(66) && bin[1] == String.fromCharCode(77)) { return ImageType.BITMAP; } else if (bin.substr(0, 8) == "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a") { return ImageType.PNG; } else if (bin.substr(0, 4) == "\x47\x49\x46\x38" && (bin[4] == '\x37' || bin[4] == '\x39') && bin[5] == '\x61') { return ImageType.GIF; } else if (bin[0] == '\x3c') { return ImageType.SVG; } else if (bin[0] == '\xFF' && bin[1] == '\xd8') { return ImageType.JPEG; } return ImageType.UNKNOWN; } class CacheManager { constructor(name) { this.cache_name = name; } setupped() { return !!this._cache_category; } reset() { return __awaiter(this, void 0, void 0, function* () { if (!window.caches) return; try { yield caches.delete(this.cache_name); } catch (error) { throw "Failed to delete cache: " + error; } try { yield this.setup(); } catch (error) { throw "Failed to reinitialize cache!"; } }); } setup() { return __awaiter(this, void 0, void 0, function* () { if (!window.caches) throw "Missing caches!"; this._cache_category = yield caches.open(this.cache_name); }); } cleanup(max_age) { return __awaiter(this, void 0, void 0, function* () { /* FIXME: TODO */ }); } resolve_cached(key, max_age) { return __awaiter(this, void 0, void 0, function* () { max_age = typeof (max_age) === "number" ? max_age : -1; const cached_response = yield this._cache_category.match("https://_local_cache/cache_request_" + key); if (!cached_response) return undefined; /* FIXME: Max age */ return cached_response; }); } put_cache(key, value, type, headers) { return __awaiter(this, void 0, void 0, function* () { const new_headers = new Headers(); for (const key of value.headers.keys()) new_headers.set(key, value.headers.get(key)); if (type) new_headers.set("Content-type", type); for (const key of Object.keys(headers || {})) new_headers.set(key, headers[key]); yield this._cache_category.put("https://_local_cache/cache_request_" + key, new Response(value.body, { headers: new_headers })); }); } delete(key) { return __awaiter(this, void 0, void 0, function* () { const flag = yield this._cache_category.delete("https://_local_cache/cache_request_" + key, { ignoreVary: true, ignoreMethod: true, ignoreSearch: true }); if (!flag) { console.warn(_translations.Ycyq5vFI || (_translations.Ycyq5vFI = tr("Failed to delete key %s from cache!")), flag); } }); } } class IconManager { constructor(handle) { this._id_urls = {}; this._loading_promises = {}; this.handle = handle; } destroy() { if (URL.revokeObjectURL) { for (const id of Object.keys(this._id_urls)) URL.revokeObjectURL(this._id_urls[id]); } this._id_urls = undefined; this._loading_promises = undefined; } clear_cache() { return __awaiter(this, void 0, void 0, function* () { yield IconManager.cache.reset(); if (URL.revokeObjectURL) { for (const id of Object.keys(this._id_urls)) URL.revokeObjectURL(this._id_urls[id]); } this._id_urls = {}; this._loading_promises = {}; }); } delete_icon(id) { return __awaiter(this, void 0, void 0, function* () { if (id <= 1000) throw "invalid id!"; yield this.handle.delete_file({ name: '/icon_' + id }); }); } iconList() { return this.handle.requestFileList("/icons"); } create_icon_download(id) { return this.handle.download_file("", "/icon_" + id); } static _response_url(response) { return __awaiter(this, void 0, void 0, function* () { if (!response.headers.has('X-media-bytes')) throw "missing media bytes"; const type = image_type(response.headers.get('X-media-bytes')); const media = media_image_type(type); const blob = yield response.blob(); if (blob.type !== "image/" + media) return URL.createObjectURL(blob.slice(0, blob.size, "image/" + media)); else return URL.createObjectURL(blob); }); } resolved_cached(id) { return __awaiter(this, void 0, void 0, function* () { if (this._id_urls[id]) return { id: id, url: this._id_urls[id] }; if (!IconManager.cache.setupped()) yield IconManager.cache.setup(); const response = yield IconManager.cache.resolve_cached('icon_' + id); //TODO age! if (response) { const url = yield IconManager._response_url(response); if (this._id_urls[id]) URL.revokeObjectURL(this._id_urls[id]); return { id: id, url: url }; } return undefined; }); } static load_cached_icon(id, ignore_age) { if (this._static_id_url[id]) { return { id: id, url: this._static_id_url[id] }; } if (this._static_cached_promise[id]) return this._static_cached_promise[id]; return (this._static_cached_promise[id] = (() => __awaiter(this, void 0, void 0, function* () { if (!this.cache.setupped()) yield this.cache.setup(); const response = yield this.cache.resolve_cached('icon_' + id); //TODO age! if (response) { const url = yield this._response_url(response); if (this._static_id_url[id]) URL.revokeObjectURL(this._static_id_url[id]); this._static_id_url[id] = url; return { id: id, url: url }; } }))()); } _load_icon(id) { return __awaiter(this, void 0, void 0, function* () { try { let download_key; try { download_key = yield this.create_icon_download(id); } catch (error) { log.error(LogCategory.CLIENT, _translations.xjn9wuVk || (_translations.xjn9wuVk = tr("Could not request download for icon %d: %o")), id, error); throw "Failed to request icon"; } const downloader = transfer.spawn_download_transfer(download_key); let response; try { response = yield downloader.request_file(); } catch (error) { log.error(LogCategory.CLIENT, _translations.Dqn_5EM4 || (_translations.Dqn_5EM4 = tr("Could not download icon %d: %o")), id, error); throw "failed to download icon"; } const type = image_type(response.headers.get('X-media-bytes')); const media = media_image_type(type); yield IconManager.cache.put_cache('icon_' + id, response.clone(), "image/" + media); const url = yield IconManager._response_url(response.clone()); if (this._id_urls[id]) URL.revokeObjectURL(this._id_urls[id]); this._id_urls[id] = url; this._loading_promises[id] = undefined; return { id: id, url: url }; } catch (error) { setTimeout(() => { this._loading_promises[id] = undefined; }, 1000 * 60); /* try again in 60 seconds */ throw error; } }); } download_icon(id) { return this._loading_promises[id] || (this._loading_promises[id] = this._load_icon(id)); } resolve_icon(id) { return __awaiter(this, void 0, void 0, function* () { id = id >>> 0; try { const result = yield this.resolved_cached(id); if (result) return result; throw ""; } catch (error) { } try { const result = yield this.download_icon(id); if (result) return result; throw "load result is empty"; } catch (error) { log.error(LogCategory.CLIENT, _translations.yJaaczeF || (_translations.yJaaczeF = tr("Icon download failed of icon %d: %o")), id, error); } throw "icon not found"; }); } static generate_tag(icon, options) { options = options || {}; let icon_container = $.spawn("div").addClass("icon-container icon_empty"); let icon_load_image = $.spawn("div").addClass("icon_loading"); const icon_image = $.spawn("img").attr("width", 16).attr("height", 16).attr("alt", ""); const _apply = (icon) => { let id = icon ? (icon.id >>> 0) : 0; if (!icon || id == 0) { icon_load_image.remove(); icon_load_image = undefined; return; } else if (id < 1000) { icon_load_image.remove(); icon_load_image = undefined; icon_container.removeClass("icon_empty").addClass("icon_em client-group_" + id); return; } icon_image.attr("src", icon.url); icon_container.append(icon_image).removeClass("icon_empty"); if (typeof (options.animate) !== "boolean" || options.animate) { icon_image.css("opacity", 0); icon_load_image.animate({ opacity: 0 }, 50, function () { icon_load_image.remove(); icon_image.animate({ opacity: 1 }, 150); }); } else { icon_load_image.remove(); icon_load_image = undefined; } }; if (icon instanceof Promise) { icon.then(_apply).catch(error => { log.error(LogCategory.CLIENT, _translations.HC0JhWOd || (_translations.HC0JhWOd = tr("Could not load icon. Reason: %s")), error); icon_load_image.removeClass("icon_loading").addClass("icon client-warning").attr("tag", "Could not load icon"); }); } else { _apply(icon); } if (icon_load_image) icon_load_image.appendTo(icon_container); return icon_container; } generateTag(id, options) { options = options || {}; id = id >>> 0; if (id == 0 || !id) return IconManager.generate_tag({ id: id, url: "" }, options); else if (id < 1000) return IconManager.generate_tag({ id: id, url: "" }, options); if (this._id_urls[id]) { return IconManager.generate_tag({ id: id, url: this._id_urls[id] }, options); } else { return IconManager.generate_tag(this.resolve_icon(id), options); } } } IconManager.cache = new CacheManager("icons"); IconManager._static_id_url = {}; IconManager._static_cached_promise = {}; class Avatar { } class AvatarManager { constructor(handle) { this._cached_avatars = {}; this._loading_promises = {}; this.handle = handle; if (!AvatarManager.cache) AvatarManager.cache = new CacheManager("avatars"); } destroy() { this._cached_avatars = undefined; this._loading_promises = undefined; } _response_url(response, type) { return __awaiter(this, void 0, void 0, function* () { if (!response.headers.has('X-media-bytes')) throw "missing media bytes"; const media = media_image_type(type); const blob = yield response.blob(); if (blob.type !== "image/" + media) return URL.createObjectURL(blob.slice(0, blob.size, "image/" + media)); else return URL.createObjectURL(blob); }); } resolved_cached(client_avatar_id, avatar_version) { return __awaiter(this, void 0, void 0, function* () { let avatar = this._cached_avatars[avatar_version]; if (avatar) { if (typeof (avatar_version) !== "string" || avatar.avatar_id == avatar_version) return avatar; avatar = undefined; } if (!AvatarManager.cache.setupped()) yield AvatarManager.cache.setup(); const response = yield AvatarManager.cache.resolve_cached('avatar_' + client_avatar_id); //TODO age! if (!response) return undefined; let response_avatar_version = response.headers.has("X-avatar-version") ? response.headers.get("X-avatar-version") : undefined; if (typeof (avatar_version) === "string" && response_avatar_version != avatar_version) return undefined; const type = image_type(response.headers.get('X-media-bytes')); return this._cached_avatars[client_avatar_id] = { client_avatar_id: client_avatar_id, avatar_id: avatar_version || response_avatar_version, url: yield this._response_url(response, type), type: type }; }); } create_avatar_download(client_avatar_id) { log.debug(LogCategory.GENERAL, "Requesting download for avatar %s", client_avatar_id); return this.handle.download_file("", "/avatar_" + client_avatar_id); } _load_avatar(client_avatar_id, avatar_version) { return __awaiter(this, void 0, void 0, function* () { try { let download_key; try { download_key = yield this.create_avatar_download(client_avatar_id); } catch (error) { log.error(LogCategory.GENERAL, _translations.Zfxv8Gh8 || (_translations.Zfxv8Gh8 = tr("Could not request download for avatar %s: %o")), client_avatar_id, error); throw "failed to request avatar download"; } const downloader = transfer.spawn_download_transfer(download_key); let response; try { response = yield downloader.request_file(); } catch (error) { log.error(LogCategory.GENERAL, _translations.RpfhT5G_ || (_translations.RpfhT5G_ = tr("Could not download avatar %s: %o")), client_avatar_id, error); throw "failed to download avatar"; } const type = image_type(response.headers.get('X-media-bytes')); const media = media_image_type(type); yield AvatarManager.cache.put_cache('avatar_' + client_avatar_id, response.clone(), "image/" + media, { "X-avatar-version": avatar_version }); const url = yield this._response_url(response.clone(), type); return this._cached_avatars[client_avatar_id] = { client_avatar_id: client_avatar_id, avatar_id: avatar_version, url: url, type: type }; } finally { this._loading_promises[client_avatar_id] = undefined; } }); } /* loads an avatar by the avatar id and optional with the avatar version */ load_avatar(client_avatar_id, avatar_version) { return this._loading_promises[client_avatar_id] || (this._loading_promises[client_avatar_id] = this._load_avatar(client_avatar_id, avatar_version)); } generate_client_tag(client) { return this.generate_tag(client.avatarId(), client.properties.client_flag_avatar); } update_cache(client_avatar_id, avatar_id) { const _cached = this._cached_avatars[client_avatar_id]; if (_cached) { if (_cached.avatar_id === avatar_id) return; /* cache is up2date */ log.info(LogCategory.GENERAL, _translations.qcVDOT3t || (_translations.qcVDOT3t = tr("Deleting cached avatar for client %s. Cached version: %s; New version: %s")), client_avatar_id, _cached.avatar_id, avatar_id); delete this._cached_avatars[client_avatar_id]; AvatarManager.cache.delete("avatar_" + client_avatar_id).catch(error => { log.error(LogCategory.GENERAL, _translations.KjfmxVkY || (_translations.KjfmxVkY = tr("Failed to delete cached avatar for client %o: %o")), client_avatar_id, error); }); } else { this.resolved_cached(client_avatar_id).then(avatar => { if (avatar && avatar.avatar_id !== avatar_id) { /* this time we ensured that its cached */ this.update_cache(client_avatar_id, avatar_id); } }).catch(error => { log.error(LogCategory.GENERAL, _translations.N9t94bx_ || (_translations.N9t94bx_ = tr("Failed to delete cached avatar for client %o (cache lookup failed): %o")), client_avatar_id, error); }); } } generate_tag(client_avatar_id, avatar_id, options) { options = options || {}; let avatar_container = $.spawn("div"); let avatar_image = $.spawn("img").attr("alt", _translations.h_SQX0Ol || (_translations.h_SQX0Ol = tr("Client avatar"))); let cached_avatar = this._cached_avatars[client_avatar_id]; if (avatar_id === "") { avatar_container.append(this.generate_default_image()); } else if (cached_avatar && cached_avatar.avatar_id == avatar_id) { avatar_image.attr("src", cached_avatar.url); avatar_container.append(avatar_image); if (options.callback_image) options.callback_image(avatar_image); if (options.callback_avatar) options.callback_avatar(cached_avatar); } else { let loader_image = $.spawn("img"); loader_image.attr("src", "img/loading_image.svg").css("width", "75%"); avatar_container.append(loader_image); (() => __awaiter(this, void 0, void 0, function* () { let avatar; try { avatar = yield this.resolved_cached(client_avatar_id, avatar_id); } catch (error) { log.error(LogCategory.CLIENT, error); } if (!avatar) avatar = yield this.load_avatar(client_avatar_id, avatar_id); if (!avatar) throw "failed to load avatar"; if (options.callback_avatar) options.callback_avatar(avatar); avatar_image.attr("src", avatar.url); avatar_image.css("opacity", 0); avatar_container.append(avatar_image); loader_image.animate({ opacity: 0 }, 50, () => { loader_image.remove(); avatar_image.animate({ opacity: 1 }, 150, () => { if (options.callback_image) options.callback_image(avatar_image); }); }); }))().catch(reason => { log.error(LogCategory.CLIENT, _translations.W3cTHtbm || (_translations.W3cTHtbm = tr("Could not load avatar for id %s. Reason: %s")), client_avatar_id, reason); //TODO Broken image loader_image.addClass("icon client-warning").attr("tag", (_translations.n7xfvxab || (_translations.n7xfvxab = tr("Could not load avatar "))) + client_avatar_id); }); } return avatar_container; } unique_id_2_avatar_id(unique_id) { function str2ab(str) { let buf = new ArrayBuffer(str.length); // 2 bytes for each char let bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } try { let raw = atob(unique_id); let input = hex.encode(str2ab(raw)); let result = ""; for (let index = 0; index < input.length; index++) { let c = input.charAt(index); let offset = 0; if (c >= '0' && c <= '9') offset = c.charCodeAt(0) - '0'.charCodeAt(0); else if (c >= 'A' && c <= 'F') offset = c.charCodeAt(0) - 'A'.charCodeAt(0) + 0x0A; else if (c >= 'a' && c <= 'f') offset = c.charCodeAt(0) - 'a'.charCodeAt(0) + 0x0A; result += String.fromCharCode('a'.charCodeAt(0) + offset); } return result; } catch (e) { //invalid base 64 (like music bot etc) return undefined; } } generate_default_image() { return $.spawn("img").attr("src", "img/style/avatar.png").css({ width: '100%', height: '100%' }); } generate_chat_tag(client, client_unique_id, callback_loaded) { let client_handle; if (typeof (client.id) == "number") client_handle = this.handle.handle.channelTree.findClient(client.id); if (!client_handle && typeof (client.id) == "number") { client_handle = this.handle.handle.channelTree.find_client_by_dbid(client.database_id); } if (client_handle && client_handle.clientUid() !== client_unique_id) client_handle = undefined; const container = $.spawn("div").addClass("avatar"); if (client_handle && !client_handle.properties.client_flag_avatar) return container.append(this.generate_default_image()); const avatar_id = client_handle ? client_handle.avatarId() : this.unique_id_2_avatar_id(client_unique_id); if (avatar_id) { if (this._cached_avatars[avatar_id]) { /* Test if we're may able to load the client avatar sync without a loading screen */ const cache = this._cached_avatars[avatar_id]; log.debug(LogCategory.GENERAL, _translations.N5oq_P39 || (_translations.N5oq_P39 = tr("Using cached avatar. ID: %o | Version: %o (Cached: %o)")), avatar_id, client_handle ? client_handle.properties.client_flag_avatar : undefined, cache.avatar_id); if (!client_handle || client_handle.properties.client_flag_avatar == cache.avatar_id) { const image = $.spawn("img").attr("src", cache.url).css({ width: '100%', height: '100%' }); return container.append(image); } } const image_loading = $.spawn("img").attr("src", "img/loading_image.svg").css({ width: '100%', height: '100%' }); /* lets actually load the avatar */ (() => __awaiter(this, void 0, void 0, function* () { let avatar; let loaded_image = this.generate_default_image(); log.debug(LogCategory.GENERAL, _translations.UUEkQF5a || (_translations.UUEkQF5a = tr("Resolving avatar. ID: %o | Version: %o")), avatar_id, client_handle ? client_handle.properties.client_flag_avatar : undefined); try { //TODO: Cache if avatar load failed and try again in some minutes/may just even consider using the default avatar 'till restart try { avatar = yield this.resolved_cached(avatar_id, client_handle ? client_handle.properties.client_flag_avatar : undefined); } catch (error) { log.error(LogCategory.GENERAL, _translations.qeVWbl1T || (_translations.qeVWbl1T = tr("Failed to use cached avatar: %o")), error); } if (!avatar) avatar = yield this.load_avatar(avatar_id, client_handle ? client_handle.properties.client_flag_avatar : undefined); if (!avatar) throw "no avatar present!"; loaded_image = $.spawn("img").attr("src", avatar.url).css({ width: '100%', height: '100%' }); } catch (error) { throw error; } finally { container.children().remove(); container.append(loaded_image); } }))().then(() => callback_loaded && callback_loaded(true)).catch(error => { log.warn(LogCategory.CLIENT, _translations.yPO5jFrp || (_translations.yPO5jFrp = tr("Failed to load chat avatar for client %s. Error: %o")), client_unique_id, error); callback_loaded && callback_loaded(false, error); }); image_loading.appendTo(container); } else { this.generate_default_image().appendTo(container); } return container; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["455475c2b4f1106cf44d1f419a1499fbd8c48c3600ecab7876758f075e94cc7e"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["455475c2b4f1106cf44d1f419a1499fbd8c48c3600ecab7876758f075e94cc7e"] = "455475c2b4f1106cf44d1f419a1499fbd8c48c3600ecab7876758f075e94cc7e"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "FouNbgIJ", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (98,52)" }, { name: "SGTDpOXd", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (99,32)" }, { name: "WVeMm7W3", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (103,28)" }, { name: "rHWS7RQ3", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (113,17)" }, { name: "KlKrGumy", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (118,40)" }, { name: "dVNCwi_A", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (121,40)" }, { name: "T5m8C2bd", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (143,32)" }, { name: "A7HLafCo", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (192,45)" }, { name: "SPhST49p", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (201,48)" }, { name: "YDqxTCU7", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (204,48)" }, { name: "JLZp_U_5", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (226,45)" }, { name: "qarwc6lt", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (300,31)" }, { name: "PagJWgYb", path: "D:/TeaSpeak/web/shared/js/i18n/localize.ts (302,38)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } var i18n; (function (i18n) { let translations = []; let fast_translate = {}; function tr(message, key) { const sloppy = fast_translate[message]; if (sloppy) return sloppy; log.info(LogCategory.I18N, "Translating \"%s\". Default: \"%s\"", key, message); let translated = message; for (const translation of translations) { if (translation.key.message == message) { translated = translation.translated; break; } } fast_translate[message] = translated; return translated; } i18n.tr = tr; function tra(message, ...args) { message = tr(message); return MessageHelper.formatMessage(message, ...args); } i18n.tra = tra; function load_translation_file(url, path) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { $.ajax({ url: url, async: true, success: result => { try { const file = (typeof (result) === "string" ? JSON.parse(result) : result); if (!file) { reject("Invalid json"); return; } file.full_url = url; file.path = path; //TODO: Validate file resolve(file); } catch (error) { log.warn(LogCategory.I18N, _translations.FouNbgIJ || (_translations.FouNbgIJ = tr("Failed to load translation file %s. Failed to parse or process json: %o")), url, error); reject(_translations.SGTDpOXd || (_translations.SGTDpOXd = tr("Failed to process or parse json!"))); } }, error: (xhr, error) => { reject((_translations.WVeMm7W3 || (_translations.WVeMm7W3 = tr("Failed to load file: "))) + error); } }); }); }); } function load_file(url, path) { return load_translation_file(url, path).then((result) => __awaiter(this, void 0, void 0, function* () { /* TODO: Improve this test?!*/ try { _translations.rHWS7RQ3 || (_translations.rHWS7RQ3 = tr("Dummy translation test")); } catch (error) { throw "dummy test failed"; } log.info(LogCategory.I18N, _translations.KlKrGumy || (_translations.KlKrGumy = tr("Successfully initialized up translation file from %s")), url); translations = result.translations; })).catch(error => { log.warn(LogCategory.I18N, _translations.dVNCwi_A || (_translations.dVNCwi_A = tr("Failed to load translation file from \"%s\". Error: %o")), url, error); return Promise.reject(error); }); } i18n.load_file = load_file; function load_repository0(repo, reload) { return __awaiter(this, void 0, void 0, function* () { if (!repo.load_timestamp || repo.load_timestamp < 1000 || reload) { const info_json = yield new Promise((resolve, reject) => { $.ajax({ url: repo.url + "/info.json", async: true, cache: !reload, success: result => { const file = (typeof (result) === "string" ? JSON.parse(result) : result); if (!file) { reject("Invalid json"); return; } resolve(file); }, error: (xhr, error) => { reject((_translations.T5m8C2bd || (_translations.T5m8C2bd = tr("Failed to load file: "))) + error); } }); }); Object.assign(repo, info_json); } if (!repo.unique_id) repo.unique_id = guid(); repo.translations = repo.translations || []; repo.load_timestamp = Date.now(); }); } function load_repository(url) { return __awaiter(this, void 0, void 0, function* () { const result = {}; result.url = url; yield load_repository0(result, false); return result; }); } i18n.load_repository = load_repository; let config; (function (config_1) { const repository_config_key = "i18n.repository"; let _cached_repository_config; function repository_config() { if (_cached_repository_config) return _cached_repository_config; const config_string = localStorage.getItem(repository_config_key); let config; try { config = config_string ? JSON.parse(config_string) : {}; } catch (error) { log.error(LogCategory.I18N, _translations.A7HLafCo || (_translations.A7HLafCo = tr("Failed to parse repository config: %o")), error); } config.repositories = config.repositories || []; for (const repo of config.repositories) (repo.repository || { load_timestamp: 0 }).load_timestamp = 0; if (config.repositories.length == 0) { //Add the default TeaSpeak repository load_repository(StaticSettings.instance.static("i18n.default_repository", "https://web.teaspeak.de/i18n/")).then(repo => { log.info(LogCategory.I18N, _translations.SPhST49p || (_translations.SPhST49p = tr("Successfully added default repository from \"%s\".")), repo.url); register_repository(repo); }).catch(error => { log.warn(LogCategory.I18N, _translations.YDqxTCU7 || (_translations.YDqxTCU7 = tr("Failed to add default repository. Error: %o")), error); }); } return _cached_repository_config = config; } config_1.repository_config = repository_config; function save_repository_config() { localStorage.setItem(repository_config_key, JSON.stringify(_cached_repository_config)); } config_1.save_repository_config = save_repository_config; const translation_config_key = "i18n.translation"; let _cached_translation_config; function translation_config() { if (_cached_translation_config) return _cached_translation_config; const config_string = localStorage.getItem(translation_config_key); try { _cached_translation_config = config_string ? JSON.parse(config_string) : {}; } catch (error) { log.error(LogCategory.I18N, _translations.JLZp_U_5 || (_translations.JLZp_U_5 = tr("Failed to initialize translation config. Using default one. Error: %o")), error); _cached_translation_config = {}; } return _cached_translation_config; } config_1.translation_config = translation_config; function save_translation_config() { localStorage.setItem(translation_config_key, JSON.stringify(_cached_translation_config)); } config_1.save_translation_config = save_translation_config; })(config = i18n.config || (i18n.config = {})); function register_repository(repository) { if (!repository) return; for (const repo of config.repository_config().repositories) if (repo.url == repository.url) return; config.repository_config().repositories.push(repository); config.save_repository_config(); } i18n.register_repository = register_repository; function registered_repositories() { return config.repository_config().repositories.map(e => e.repository || { url: e.url, load_timestamp: 0 }); } i18n.registered_repositories = registered_repositories; function delete_repository(repository) { if (!repository) return; for (const repo of [...config.repository_config().repositories]) if (repo.url == repository.url) { config.repository_config().repositories.remove(repo); } config.save_repository_config(); } i18n.delete_repository = delete_repository; function iterate_repositories(callback_entry) { return __awaiter(this, void 0, void 0, function* () { const promises = []; for (const repository of registered_repositories()) { promises.push(load_repository0(repository, false).then(() => callback_entry(repository)).catch(error => { log.warn(LogCategory.I18N, "Failed to fetch repository %s. error: %o", repository.url, error); })); } yield Promise.all(promises); }); } i18n.iterate_repositories = iterate_repositories; function select_translation(repository, entry) { const cfg = config.translation_config(); if (entry && repository) { cfg.current_language = entry.name; cfg.current_repository_url = repository.url; cfg.current_translation_url = repository.url + entry.path; cfg.current_translation_path = entry.path; } else { cfg.current_language = undefined; cfg.current_repository_url = undefined; cfg.current_translation_url = undefined; cfg.current_translation_path = undefined; } config.save_translation_config(); } i18n.select_translation = select_translation; /* ATTENTION: This method is called before most other library inizialisations! */ function initialize() { return __awaiter(this, void 0, void 0, function* () { const rcfg = config.repository_config(); /* initialize */ const cfg = config.translation_config(); if (cfg.current_translation_url) { try { yield load_file(cfg.current_translation_url, cfg.current_translation_path); } catch (error) { console.error(_translations.qarwc6lt || (_translations.qarwc6lt = tr("Failed to initialize selected translation: %o")), error); const show_error = () => { createErrorModal(_translations.PagJWgYb || (_translations.PagJWgYb = tr("Translation System")), tra("Failed to load current selected translation file.{:br:}File: {0}{:br:}Error: {1}{:br:}{:br:}Using default fallback translations.", cfg.current_translation_url, error)).open(); }; if (loader.running()) loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { priority: 10, function: () => __awaiter(this, void 0, void 0, function* () { return show_error(); }), name: "I18N error display" }); else show_error(); } } // await load_file("http://localhost/home/TeaSpeak/TeaSpeak/Web-Client/web/environment/development/i18n/de_DE.translation"); // await load_file("http://localhost/home/TeaSpeak/TeaSpeak/Web-Client/web/environment/development/i18n/test.json"); }); } i18n.initialize = initialize; })(i18n || (i18n = {})); // @ts-ignore const tr = i18n.tr; const tra = i18n.tra; window.tr = i18n.tr; window.tra = i18n.tra; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["63756334f56b822c20cbf8616d626c6c4d92049d142c2a8274090f6c288c800a"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["63756334f56b822c20cbf8616d626c6c4d92049d142c2a8274090f6c288c800a"] = "63756334f56b822c20cbf8616d626c6c4d92049d142c2a8274090f6c288c800a"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "n_KYAaMS", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (397,13)" }, { name: "XWPfjb2K", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (399,22)" }, { name: "le2qQrVZ", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (399,38)" }, { name: "_idwzRBJ", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (400,48)" }, { name: "tzCmjh5N", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (401,44)" }, { name: "HH613O5m", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (508,16)" }, { name: "mwOSnQ5t", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (509,20)" }, { name: "biW_sg0z", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (510,20)" }, { name: "XEpW1KUu", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (511,20)" }, { name: "xQjKeR1B", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (512,20)" }, { name: "Qaqyrcb5", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (513,16)" }, { name: "VPP72Y7O", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (514,20)" }, { name: "sRQvs1pe", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (515,20)" }, { name: "MKTJCaHB", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (516,20)" }, { name: "o_mBuxpj", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (517,16)" }, { name: "Ke3sTyPP", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (518,20)" }, { name: "w1vxsh9K", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (519,20)" }, { name: "tYJyWqOO", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (520,20)" }, { name: "WZsNfPyK", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (521,20)" }, { name: "WIiqWiL4", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (522,20)" }, { name: "TOhfWBxb", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (523,16)" }, { name: "_rPytECo", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (524,20)" }, { name: "CJT92u8o", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (525,20)" }, { name: "F7lDIM5W", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (526,20)" }, { name: "p978M8l6", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (527,20)" }, { name: "nj0btL0v", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (528,16)" }, { name: "yFgZNi8s", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (529,20)" }, { name: "SiWRTYIe", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (530,20)" }, { name: "UZZVYe0I", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (531,20)" }, { name: "t7dRXZeR", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (532,20)" }, { name: "bGpv2bKN", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (534,16)" }, { name: "mPnGQldc", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (550,51)" }, { name: "xNZTALgn", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (646,75)" }, { name: "DKPKNRNP", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (655,30)" }, { name: "xRgg5id2", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (683,43)" }, { name: "zjGxpKHl", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (692,47)" }, { name: "CTD6hjuf", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (701,75)" }, { name: "bczqMhnT", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (719,55)" }, { name: "JhTXHwBa", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (740,44)" }, { name: "G5Jy9mCS", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (917,100)" }, { name: "X_wUbyDP", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (1022,44)" }, { name: "va1TCPgM", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (1025,47)" }, { name: "dpJgGcEJ", path: "D:/TeaSpeak/web/shared/js/permission/PermissionManager.ts (1047,27)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var PermissionType; (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_SELECT_GODMODE"] = "b_virtualserver_select_godmode"; 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_MUSICGROUP"] = "b_virtualserver_modify_default_musicgroup"; 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_DEFAULT_MESSAGES"] = "b_virtualserver_modify_default_messages"; 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["B_VIRTUALSERVER_MODIFY_COUNTRY_CODE"] = "b_virtualserver_modify_country_code"; 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["I_CHANNEL_CREATE_MODIFY_CONVERSATION_HISTORY_LENGTH"] = "i_channel_create_modify_conversation_history_length"; PermissionType["B_CHANNEL_CREATE_MODIFY_CONVERSATION_HISTORY_UNLIMITED"] = "b_channel_create_modify_conversation_history_unlimited"; PermissionType["B_CHANNEL_CREATE_MODIFY_CONVERSATION_PRIVATE"] = "b_channel_create_modify_conversation_private"; 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["B_CHANNEL_CONVERSATION_MESSAGE_DELETE"] = "b_channel_conversation_message_delete"; 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["B_CHANNEL_IGNORE_VIEW_POWER"] = "b_channel_ignore_view_power"; PermissionType["I_CHANNEL_JOIN_POWER"] = "i_channel_join_power"; PermissionType["I_CHANNEL_NEEDED_JOIN_POWER"] = "i_channel_needed_join_power"; PermissionType["B_CHANNEL_IGNORE_JOIN_POWER"] = "b_channel_ignore_join_power"; PermissionType["B_CHANNEL_IGNORE_DESCRIPTION_VIEW_POWER"] = "b_channel_ignore_description_view_power"; PermissionType["I_CHANNEL_VIEW_POWER"] = "i_channel_view_power"; PermissionType["I_CHANNEL_NEEDED_VIEW_POWER"] = "i_channel_needed_view_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["I_MAX_PLAYLIST_SIZE"] = "i_max_playlist_size"; PermissionType["I_MAX_PLAYLISTS"] = "i_max_playlists"; 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_CREATE"] = "b_virtualserver_servergroup_create"; 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_CREATE"] = "b_virtualserver_channelgroup_create"; 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_PLAYLIST_PERMISSION_LIST"] = "b_virtualserver_playlist_permission_list"; 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_SELF_ADD_POWER"] = "i_server_group_self_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_SELF_REMOVE_POWER"] = "i_server_group_self_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_SELF_ADD_POWER"] = "i_channel_group_self_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_SELF_REMOVE_POWER"] = "i_channel_group_self_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_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_CLONES_IP"] = "i_client_max_clones_ip"; PermissionType["I_CLIENT_MAX_CLONES_HWID"] = "i_client_max_clones_hwid"; 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["I_CLIENT_MAX_CHANNELS"] = "i_client_max_channels"; PermissionType["I_CLIENT_MAX_TEMPORARY_CHANNELS"] = "i_client_max_temporary_channels"; PermissionType["I_CLIENT_MAX_SEMI_CHANNELS"] = "i_client_max_semi_channels"; PermissionType["I_CLIENT_MAX_PERMANENT_CHANNELS"] = "i_client_max_permanent_channels"; PermissionType["B_CLIENT_USE_PRIORITY_SPEAKER"] = "b_client_use_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_VPN"] = "b_client_ignore_vpn"; PermissionType["B_CLIENT_IGNORE_ANTIFLOOD"] = "b_client_ignore_antiflood"; PermissionType["B_CLIENT_ENFORCE_VALID_HWID"] = "b_client_enforce_valid_hwid"; PermissionType["B_CLIENT_ALLOW_INVALID_PACKET"] = "b_client_allow_invalid_packet"; PermissionType["B_CLIENT_ALLOW_INVALID_BADGES"] = "b_client_allow_invalid_badges"; 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_CREATE_PERMANENT"] = "b_client_music_create_permanent"; PermissionType["B_CLIENT_MUSIC_CREATE_SEMI_PERMANENT"] = "b_client_music_create_semi_permanent"; PermissionType["B_CLIENT_MUSIC_CREATE_TEMPORARY"] = "b_client_music_create_temporary"; PermissionType["B_CLIENT_MUSIC_MODIFY_PERMANENT"] = "b_client_music_modify_permanent"; PermissionType["B_CLIENT_MUSIC_MODIFY_SEMI_PERMANENT"] = "b_client_music_modify_semi_permanent"; PermissionType["B_CLIENT_MUSIC_MODIFY_TEMPORARY"] = "b_client_music_modify_temporary"; PermissionType["I_CLIENT_MUSIC_CREATE_MODIFY_MAX_VOLUME"] = "i_client_music_create_modify_max_volume"; PermissionType["I_CLIENT_MUSIC_LIMIT"] = "i_client_music_limit"; PermissionType["I_CLIENT_MUSIC_NEEDED_DELETE_POWER"] = "i_client_music_needed_delete_power"; PermissionType["I_CLIENT_MUSIC_DELETE_POWER"] = "i_client_music_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_MODIFY_POWER"] = "i_client_music_modify_power"; PermissionType["I_CLIENT_MUSIC_NEEDED_MODIFY_POWER"] = "i_client_music_needed_modify_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_PLAYLIST_CREATE"] = "b_playlist_create"; PermissionType["I_PLAYLIST_VIEW_POWER"] = "i_playlist_view_power"; PermissionType["I_PLAYLIST_NEEDED_VIEW_POWER"] = "i_playlist_needed_view_power"; PermissionType["I_PLAYLIST_MODIFY_POWER"] = "i_playlist_modify_power"; PermissionType["I_PLAYLIST_NEEDED_MODIFY_POWER"] = "i_playlist_needed_modify_power"; PermissionType["I_PLAYLIST_PERMISSION_MODIFY_POWER"] = "i_playlist_permission_modify_power"; PermissionType["I_PLAYLIST_NEEDED_PERMISSION_MODIFY_POWER"] = "i_playlist_needed_permission_modify_power"; PermissionType["I_PLAYLIST_DELETE_POWER"] = "i_playlist_delete_power"; PermissionType["I_PLAYLIST_NEEDED_DELETE_POWER"] = "i_playlist_needed_delete_power"; PermissionType["I_PLAYLIST_SONG_ADD_POWER"] = "i_playlist_song_add_power"; PermissionType["I_PLAYLIST_SONG_NEEDED_ADD_POWER"] = "i_playlist_song_needed_add_power"; PermissionType["I_PLAYLIST_SONG_REMOVE_POWER"] = "i_playlist_song_remove_power"; PermissionType["I_PLAYLIST_SONG_NEEDED_REMOVE_POWER"] = "i_playlist_song_needed_remove_power"; 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["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["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_TRIGGER_LIST"] = "b_client_ban_trigger_list"; PermissionType["B_CLIENT_BAN_CREATE"] = "b_client_ban_create"; PermissionType["B_CLIENT_BAN_CREATE_GLOBAL"] = "b_client_ban_create_global"; PermissionType["B_CLIENT_BAN_NAME"] = "b_client_ban_name"; PermissionType["B_CLIENT_BAN_IP"] = "b_client_ban_ip"; PermissionType["B_CLIENT_BAN_HWID"] = "b_client_ban_hwid"; 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_EVEN_TEXTMESSAGE_SEND"] = "b_client_even_textmessage_send"; 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_USE_BBCODE_ANY"] = "b_client_use_bbcode_any"; PermissionType["B_CLIENT_USE_BBCODE_URL"] = "b_client_use_bbcode_url"; PermissionType["B_CLIENT_USE_BBCODE_IMAGE"] = "b_client_use_bbcode_image"; 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_QUERY_CREATE"] = "b_client_query_create"; PermissionType["B_CLIENT_QUERY_LIST"] = "b_client_query_list"; PermissionType["B_CLIENT_QUERY_LIST_OWN"] = "b_client_query_list_own"; PermissionType["B_CLIENT_QUERY_RENAME"] = "b_client_query_rename"; PermissionType["B_CLIENT_QUERY_RENAME_OWN"] = "b_client_query_rename_own"; PermissionType["B_CLIENT_QUERY_CHANGE_PASSWORD"] = "b_client_query_change_password"; PermissionType["B_CLIENT_QUERY_CHANGE_OWN_PASSWORD"] = "b_client_query_change_own_password"; PermissionType["B_CLIENT_QUERY_CHANGE_PASSWORD_GLOBAL"] = "b_client_query_change_password_global"; PermissionType["B_CLIENT_QUERY_DELETE"] = "b_client_query_delete"; PermissionType["B_CLIENT_QUERY_DELETE_OWN"] = "b_client_query_delete_own"; 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 { is_boolean() { return this.name.startsWith("b_"); } id_grant() { return this.id | (1 << 15); } } class PermissionGroup { } class GroupedPermissions { } class PermissionValue { constructor(type, value) { this.type = type; this.value = value; } granted(requiredValue, required = true) { let result; result = this.value == -1 || this.value >= requiredValue || (this.value == -2 && requiredValue == -2 && !required); log.trace(LogCategory.PERMISSIONS, _translations.n_KYAaMS || (_translations.n_KYAaMS = tr("Required permission test resulted for permission %s: %s. Required value: %s, Granted value: %s")), this.type ? this.type.name : "unknown", result ? _translations.XWPfjb2K || (_translations.XWPfjb2K = tr("granted")) : _translations.le2qQrVZ || (_translations.le2qQrVZ = tr("denied")), requiredValue + (required ? " (" + (_translations._idwzRBJ || (_translations._idwzRBJ = tr("required"))) + ")" : ""), this.hasValue() ? this.value : _translations.tzCmjh5N || (_translations.tzCmjh5N = tr("none"))); return result; } hasValue() { return typeof (this.value) !== "undefined" && this.value != -2; } hasGrant() { return typeof (this.granted_value) !== "undefined" && this.granted_value != -2; } } class NeededPermissionValue extends PermissionValue { constructor(type, value) { super(type, value); } } class PermissionManager extends connection.AbstractCommandHandler { constructor(client) { super(client.serverConnection); this.permissionList = []; this.permissionGroups = []; this.neededPermissions = []; this.needed_permission_change_listener = {}; this.requests_channel_permissions = []; this.requests_client_permissions = []; this.requests_client_channel_permissions = []; this.requests_playlist_permissions = []; this.requests_playlist_client_permissions = []; this.requests_permfind = []; this.initializedListener = []; this.criteria_equal = (a, b) => { for (const criteria of ["client_id", "channel_id", "playlist_id"]) { if ((typeof a[criteria] === "undefined") !== (typeof b[criteria] === "undefined")) return false; if (a[criteria] != b[criteria]) return false; } return true; }; //FIXME? Dont register the handler like this? this.volatile_handler_boss = true; client.serverConnection.command_handler_boss().register_handler(this); this.handle = client; } static parse_permission_bulk(json, manager) { let permissions = []; for (let perm of json) { if (perm["permid"] === undefined) continue; let perm_id = parseInt(perm["permid"]); let perm_grant = (perm_id & (1 << 15)) > 0; if (perm_grant) perm_id &= ~(1 << 15); let perm_info = manager.resolveInfo(perm_id); if (!perm_info) { log.warn(LogCategory.PERMISSIONS, _translations.mPnGQldc || (_translations.mPnGQldc = tr("Got unknown permission id (%o/%o (%o))!")), perm["permid"], perm_id, perm["permsid"]); return; } let permission; for (let ref_perm of permissions) { if (ref_perm.type == perm_info) { permission = ref_perm; break; } } if (!permission) { permission = new PermissionValue(perm_info, 0); permission.granted_value = undefined; permission.value = undefined; permissions.push(permission); } if (perm_grant) { permission.granted_value = parseInt(perm["permvalue"]); } else { permission.value = parseInt(perm["permvalue"]); permission.flag_negate = perm["permnegated"] == "1"; permission.flag_skip = perm["permskip"] == "1"; } } return permissions; } destroy() { this.handle.serverConnection && this.handle.serverConnection.command_handler_boss().unregister_handler(this); this.needed_permission_change_listener = {}; this.permissionList = undefined; this.permissionGroups = undefined; this.neededPermissions = undefined; /* delete all requests */ for (const key of Object.keys(this)) if (key.startsWith("requests")) delete this[key]; this.initializedListener = undefined; this._cacheNeededPermissions = undefined; } handle_command(command) { switch (command.command) { case "notifyclientneededpermissions": this.onNeededPermissions(command.arguments); return true; case "notifypermissionlist": this.onPermissionList(command.arguments); return true; case "notifychannelpermlist": this.onChannelPermList(command.arguments); return true; case "notifyclientpermlist": this.onClientPermList(command.arguments); return true; case "notifyclientchannelpermlist": this.onChannelClientPermList(command.arguments); return true; case "notifyplaylistpermlist": this.onPlaylistPermList(command.arguments); return true; case "notifyplaylistclientpermlist": this.onPlaylistClientPermList(command.arguments); return true; } return false; } initialized() { return this.permissionList.length > 0; } requestPermissionList() { this.handle.serverConnection.send_command("permissionlist"); } onPermissionList(json) { this.permissionList = []; this.permissionGroups = []; this._group_mapping = PermissionManager.group_mapping.slice(); let group = log.group(log.LogType.TRACE, LogCategory.PERMISSIONS, _translations.xNZTALgn || (_translations.xNZTALgn = tr("Permission mapping"))); const table_entries = []; let permission_id = 0; for (let e of json) { if (e["group_id_end"]) { let group = new PermissionGroup(); group.begin = this.permissionGroups.length ? this.permissionGroups.last().end : 0; group.end = parseInt(e["group_id_end"]); group.deep = 0; group.name = (_translations.DKPKNRNP || (_translations.DKPKNRNP = tr("Group "))) + e["group_id_end"]; let info = this._group_mapping.pop_front(); if (info) { group.name = info.name; group.deep = info.deep; } this.permissionGroups.push(group); continue; } let perm = new PermissionInfo(); permission_id++; perm.name = e["permname"]; perm.id = parseInt(e["permid"]) || permission_id; /* using permission_id as fallback if we dont have permid */ perm.description = e["permdesc"]; this.permissionList.push(perm); table_entries.push({ "id": perm.id, "name": perm.name, "description": perm.description }); } log.table(LogType.DEBUG, LogCategory.PERMISSIONS, "Permission list", table_entries); group.end(); log.info(LogCategory.PERMISSIONS, _translations.xRgg5id2 || (_translations.xRgg5id2 = tr("Got %i permissions")), this.permissionList.length); if (this._cacheNeededPermissions) this.onNeededPermissions(this._cacheNeededPermissions); for (let listener of this.initializedListener) listener(true); } onNeededPermissions(json) { if (this.permissionList.length == 0) { log.warn(LogCategory.PERMISSIONS, _translations.zjGxpKHl || (_translations.zjGxpKHl = tr("Got needed permissions but don't have a permission list!"))); this._cacheNeededPermissions = json; return; } this._cacheNeededPermissions = undefined; let copy = this.neededPermissions.slice(); let addcount = 0; let group = log.group(log.LogType.TRACE, LogCategory.PERMISSIONS, _translations.CTD6hjuf || (_translations.CTD6hjuf = tr("Got %d needed permissions.")), json.length); const table_entries = []; for (let e of json) { let entry = undefined; 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) { entry = new NeededPermissionValue(info, -2); this.neededPermissions.push(entry); } else { log.warn(LogCategory.PERMISSIONS, _translations.bczqMhnT || (_translations.bczqMhnT = tr("Could not resolve perm for id %s (%o|%o)")), e["permid"], e, info); continue; } addcount++; } if (entry.value == parseInt(e["permvalue"])) continue; entry.value = parseInt(e["permvalue"]); for (const listener of this.needed_permission_change_listener[entry.type.name] || []) listener(); table_entries.push({ "permission": entry.type.name, "value": entry.value }); } log.table(LogType.DEBUG, LogCategory.PERMISSIONS, "Needed client permissions", table_entries); group.end(); log.debug(LogCategory.PERMISSIONS, _translations.JhTXHwBa || (_translations.JhTXHwBa = tr("Dropping %o needed permissions and added %o permissions.")), copy.length, addcount); for (let e of copy) { e.value = -2; for (const listener of this.needed_permission_change_listener[e.type.name] || []) listener(); } } register_needed_permission(key, listener) { const array = this.needed_permission_change_listener[key] || []; array.push(listener); this.needed_permission_change_listener[key] = array; } unregister_needed_permission(key, listener) { const array = this.needed_permission_change_listener[key]; if (!array) return; array.remove(listener); this.needed_permission_change_listener[key] = array.length > 0 ? array : undefined; } resolveInfo(key) { for (let perm of this.permissionList) if (perm.id == key || perm.name == key) return perm; return undefined; } /* channel permission request */ onChannelPermList(json) { let channelId = parseInt(json[0]["cid"]); this.fullfill_permission_request("requests_channel_permissions", { channel_id: channelId }, "success", PermissionManager.parse_permission_bulk(json, this.handle.permissions)); } execute_channel_permission_request(request) { this.handle.serverConnection.send_command("channelpermlist", { "cid": request.channel_id }).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) this.fullfill_permission_request("requests_channel_permissions", request, "success", []); else this.fullfill_permission_request("requests_channel_permissions", request, "error", error); }); } requestChannelPermissions(channelId) { const keys = { channel_id: channelId }; return this.execute_permission_request("requests_channel_permissions", keys, this.execute_channel_permission_request.bind(this)); } /* client permission request */ onClientPermList(json) { let client = parseInt(json[0]["cldbid"]); this.fullfill_permission_request("requests_client_permissions", { client_id: client }, "success", PermissionManager.parse_permission_bulk(json, this.handle.permissions)); } execute_client_permission_request(request) { this.handle.serverConnection.send_command("clientpermlist", { cldbid: request.client_id }).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) this.fullfill_permission_request("requests_client_permissions", request, "success", []); else this.fullfill_permission_request("requests_client_permissions", request, "error", error); }); } requestClientPermissions(client_id) { const keys = { client_id: client_id }; return this.execute_permission_request("requests_client_permissions", keys, this.execute_client_permission_request.bind(this)); } /* client channel permission request */ onChannelClientPermList(json) { let client_id = parseInt(json[0]["cldbid"]); let channel_id = parseInt(json[0]["cid"]); this.fullfill_permission_request("requests_client_channel_permissions", { client_id: client_id, channel_id: channel_id }, "success", PermissionManager.parse_permission_bulk(json, this.handle.permissions)); } execute_client_channel_permission_request(request) { this.handle.serverConnection.send_command("channelclientpermlist", { cldbid: request.client_id, cid: request.channel_id }) .catch(error => { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) this.fullfill_permission_request("requests_client_channel_permissions", request, "success", []); else this.fullfill_permission_request("requests_client_channel_permissions", request, "error", error); }); } requestClientChannelPermissions(client_id, channel_id) { const keys = { client_id: client_id }; return this.execute_permission_request("requests_client_channel_permissions", keys, this.execute_client_channel_permission_request.bind(this)); } /* playlist permissions */ onPlaylistPermList(json) { let playlist_id = parseInt(json[0]["playlist_id"]); this.fullfill_permission_request("requests_playlist_permissions", { playlist_id: playlist_id }, "success", PermissionManager.parse_permission_bulk(json, this.handle.permissions)); } execute_playlist_permission_request(request) { this.handle.serverConnection.send_command("playlistpermlist", { playlist_id: request.playlist_id }) .catch(error => { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) this.fullfill_permission_request("requests_playlist_permissions", request, "success", []); else this.fullfill_permission_request("requests_playlist_permissions", request, "error", error); }); } requestPlaylistPermissions(playlist_id) { const keys = { playlist_id: playlist_id }; return this.execute_permission_request("requests_playlist_permissions", keys, this.execute_playlist_permission_request.bind(this)); } /* playlist client permissions */ onPlaylistClientPermList(json) { let playlist_id = parseInt(json[0]["playlist_id"]); let client_id = parseInt(json[0]["cldbid"]); this.fullfill_permission_request("requests_playlist_client_permissions", { playlist_id: playlist_id, client_id: client_id }, "success", PermissionManager.parse_permission_bulk(json, this.handle.permissions)); } execute_playlist_client_permission_request(request) { this.handle.serverConnection.send_command("playlistclientpermlist", { playlist_id: request.playlist_id, cldbid: request.client_id }) .catch(error => { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) this.fullfill_permission_request("requests_playlist_client_permissions", request, "success", []); else this.fullfill_permission_request("requests_playlist_client_permissions", request, "error", error); }); } requestPlaylistClientPermissions(playlist_id, client_database_id) { const keys = { playlist_id: playlist_id, client_id: client_database_id }; return this.execute_permission_request("requests_playlist_client_permissions", keys, this.execute_playlist_client_permission_request.bind(this)); } execute_permission_request(list, criteria, execute) { for (const request of this[list]) if (this.criteria_equal(request, criteria) && request.promise.time() + 1000 < Date.now()) return request.promise; const result = Object.assign({ timeout_id: setTimeout(() => this.fullfill_permission_request(list, criteria, "error", _translations.G5Jy9mCS || (_translations.G5Jy9mCS = tr("timeout"))), 5000), promise: new LaterPromise() }, criteria); this[list].push(result); execute(criteria); return result.promise; } ; fullfill_permission_request(list, criteria, status, result) { for (const request of this[list]) { if (this.criteria_equal(request, criteria)) { this[list].remove(request); clearTimeout(request.timeout_id); status === "error" ? request.promise.rejected(result) : request.promise.resolved(result); } } } find_permission(...permissions) { const permission_ids = []; for (const permission of permissions) { const info = this.resolveInfo(permission); if (!info) continue; permission_ids.push(info.id); } if (!permission_ids.length) return Promise.resolve([]); return new Promise((resolve, reject) => { const single_handler = { command: "notifypermfind", function: command => { const result = []; for (const entry of command.arguments) { const perm_id = parseInt(entry["p"]); if (permission_ids.indexOf(perm_id) === -1) return; /* not our permfind result */ const value = parseInt(entry["v"]); const type = parseInt(entry["t"]); let data; switch (type) { case 0: data = { type: "server_group", group_id: parseInt(entry["id1"]), }; break; case 1: data = { type: "client", client_id: parseInt(entry["id2"]), }; break; case 2: data = { type: "channel", channel_id: parseInt(entry["id2"]), }; break; case 3: data = { type: "channel_group", group_id: parseInt(entry["id1"]), }; break; case 4: data = { type: "client_channel", client_id: parseInt(entry["id1"]), channel_id: parseInt(entry["id1"]), }; break; default: continue; } data.id = perm_id; data.value = value; result.push(data); } resolve(result); return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("permfind", permission_ids.map(e => { return { permid: e }; })).catch(error => { this.handler_boss.remove_single_handler(single_handler); if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) { resolve([]); return; } reject(error); }); }); } 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, _translations.X_wUbyDP || (_translations.X_wUbyDP = tr("Could not resolve grant permission %o. Creating a new one.")), key); let info = key instanceof PermissionInfo ? key : this.resolveInfo(key); if (!info) { log.warn(LogCategory.PERMISSIONS, _translations.va1TCPgM || (_translations.va1TCPgM = tr("Requested needed permission with invalid key! (%o)")), key); return new NeededPermissionValue(undefined, -2); } let result = new NeededPermissionValue(info, -2); this.neededPermissions.push(result); return result; } groupedPermissions() { let result = []; let current; for (let group of this.permissionGroups) { if (group.deep == 0) { current = new GroupedPermissions(); current.group = group; current.parent = undefined; current.children = []; current.permissions = []; result.push(current); } else { if (!current) { throw _translations.dpJgGcEJ || (_translations.dpJgGcEJ = tr("invalid order!")); } else { while (group.deep <= current.group.deep) current = current.parent; let parent = current; current = new GroupedPermissions(); current.group = group; current.parent = parent; current.children = []; current.permissions = []; parent.children.push(current); } } for (let permission of this.permissionList) if (permission.id > current.group.begin && permission.id <= current.group.end) current.permissions.push(permission); } return result; } /** * Generates an enum with all know permission types, used for the enum above */ export_permission_types() { let result = ""; result = result + "enum PermissionType {\n"; for (const permission of this.permissionList) { if (!permission.name) continue; result = result + "\t" + permission.name.toUpperCase() + " = \"" + permission.name.toLowerCase() + "\", /* Permission ID: " + permission.id + " */\n"; } result = result + "}"; return result; } } /* Static info mapping until TeaSpeak implements a detailed info */ PermissionManager.group_mapping = [ { name: _translations.HH613O5m || (_translations.HH613O5m = tr("Global")), deep: 0 }, { name: _translations.mwOSnQ5t || (_translations.mwOSnQ5t = tr("Information")), deep: 1 }, { name: _translations.biW_sg0z || (_translations.biW_sg0z = tr("Virtual server management")), deep: 1 }, { name: _translations.XEpW1KUu || (_translations.XEpW1KUu = tr("Administration")), deep: 1 }, { name: _translations.xQjKeR1B || (_translations.xQjKeR1B = tr("Settings")), deep: 1 }, { name: _translations.Qaqyrcb5 || (_translations.Qaqyrcb5 = tr("Virtual Server")), deep: 0 }, { name: _translations.VPP72Y7O || (_translations.VPP72Y7O = tr("Information")), deep: 1 }, { name: _translations.sRQvs1pe || (_translations.sRQvs1pe = tr("Administration")), deep: 1 }, { name: _translations.MKTJCaHB || (_translations.MKTJCaHB = tr("Settings")), deep: 1 }, { name: _translations.o_mBuxpj || (_translations.o_mBuxpj = tr("Channel")), deep: 0 }, { name: _translations.Ke3sTyPP || (_translations.Ke3sTyPP = tr("Information")), deep: 1 }, { name: _translations.w1vxsh9K || (_translations.w1vxsh9K = tr("Create")), deep: 1 }, { name: _translations.tYJyWqOO || (_translations.tYJyWqOO = tr("Modify")), deep: 1 }, { name: _translations.WZsNfPyK || (_translations.WZsNfPyK = tr("Delete")), deep: 1 }, { name: _translations.WIiqWiL4 || (_translations.WIiqWiL4 = tr("Access")), deep: 1 }, { name: _translations.TOhfWBxb || (_translations.TOhfWBxb = tr("Group")), deep: 0 }, { name: _translations._rPytECo || (_translations._rPytECo = tr("Information")), deep: 1 }, { name: _translations.CJT92u8o || (_translations.CJT92u8o = tr("Create")), deep: 1 }, { name: _translations.F7lDIM5W || (_translations.F7lDIM5W = tr("Modify")), deep: 1 }, { name: _translations.p978M8l6 || (_translations.p978M8l6 = tr("Delete")), deep: 1 }, { name: _translations.nj0btL0v || (_translations.nj0btL0v = tr("Client")), deep: 0 }, { name: _translations.yFgZNi8s || (_translations.yFgZNi8s = tr("Information")), deep: 1 }, { name: _translations.SiWRTYIe || (_translations.SiWRTYIe = tr("Admin")), deep: 1 }, { name: _translations.UZZVYe0I || (_translations.UZZVYe0I = tr("Basics")), deep: 1 }, { name: _translations.t7dRXZeR || (_translations.t7dRXZeR = tr("Modify")), deep: 1 }, //TODO Music bot { name: _translations.bGpv2bKN || (_translations.bGpv2bKN = tr("File Transfer")), deep: 0 }, ]; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["b0ea492a6dc1c0dcbed405d36aac400c0dbb882c0f941543ac830e0a838c53e1"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["b0ea492a6dc1c0dcbed405d36aac400c0dbb882c0f941543ac830e0a838c53e1"] = "b0ea492a6dc1c0dcbed405d36aac400c0dbb882c0f941543ac830e0a838c53e1"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "m_Pwx8sY", path: "D:/TeaSpeak/web/shared/js/permission/GroupManager.ts (142,43)" }, { name: "HQc_WylI", path: "D:/TeaSpeak/web/shared/js/permission/GroupManager.ts (158,51)" }, { name: "ry6JbE1j", path: "D:/TeaSpeak/web/shared/js/permission/GroupManager.ts (207,42)" }, { name: "lM4enCzV", path: "D:/TeaSpeak/web/shared/js/permission/GroupManager.ts (216,48)" }, { name: "OlcOY9Oi", path: "D:/TeaSpeak/web/shared/js/permission/GroupManager.ts (225,47)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var GroupType; (function (GroupType) { GroupType[GroupType["QUERY"] = 0] = "QUERY"; GroupType[GroupType["TEMPLATE"] = 1] = "TEMPLATE"; GroupType[GroupType["NORMAL"] = 2] = "NORMAL"; })(GroupType || (GroupType = {})); var GroupTarget; (function (GroupTarget) { GroupTarget[GroupTarget["SERVER"] = 0] = "SERVER"; GroupTarget[GroupTarget["CHANNEL"] = 1] = "CHANNEL"; })(GroupTarget || (GroupTarget = {})); class GroupProperties { constructor() { this.iconid = 0; this.sortid = 0; this.savedb = false; this.namemode = 0; } } class GroupPermissionRequest { } class Group { constructor(handle, id, target, type, name) { this.properties = new GroupProperties(); 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 (!JSON.map_field_to(this.properties, value, key)) return; /* no updates */ if (key == "iconid") { this.properties.iconid = (new Uint32Array([this.properties.iconid]))[0]; this.handle.handle.channelTree.clientsByGroup(this).forEach(client => { client.updateGroupIcon(this); }); } else if (key == "sortid") this.handle.handle.channelTree.clientsByGroup(this).forEach(client => { client.update_group_icon_order(); }); } } class GroupManager extends connection.AbstractCommandHandler { constructor(client) { super(client.serverConnection); this.serverGroups = []; this.channelGroups = []; this.requests_group_permissions = []; client.serverConnection.command_handler_boss().register_handler(this); this.handle = client; } destroy() { this.handle.serverConnection && this.handle.serverConnection.command_handler_boss().unregister_handler(this); this.serverGroups = undefined; this.channelGroups = undefined; } handle_command(command) { switch (command.command) { case "notifyservergrouplist": case "notifychannelgrouplist": this.handle_grouplist(command.arguments); return true; case "notifyservergrouppermlist": case "notifychannelgrouppermlist": this.handle_group_permission_list(command.arguments); return true; } return false; } requestGroups() { this.handle.serverConnection.send_command("servergrouplist"); this.handle.serverConnection.send_command("channelgrouplist"); } static sorter() { return (a, b) => { if (!a) return b ? 1 : 0; if (!b) return a ? -1 : 0; if (a.properties.sortid > b.properties.sortid) return 1; if (a.properties.sortid < b.properties.sortid) return -1; if (a.id < b.id) return -1; if (a.id > b.id) return 1; return 0; }; } serverGroup(id) { for (let group of this.serverGroups) if (group.id == id) return group; return undefined; } channelGroup(id) { for (let group of this.channelGroups) if (group.id == id) return group; return undefined; } handle_grouplist(json) { let target; if (json[0]["sgid"]) target = GroupTarget.SERVER; else if (json[0]["cgid"]) target = GroupTarget.CHANNEL; else { log.error(LogCategory.CLIENT, _translations.m_Pwx8sY || (_translations.m_Pwx8sY = tr("Could not resolve group target! => %o")), json[0]); return; } if (target == GroupTarget.SERVER) this.serverGroups = []; else 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: log.error(LogCategory.CLIENT, _translations.HQc_WylI || (_translations.HQc_WylI = tr("Invalid group type: %o for group %s")), groupData["type"], groupData["name"]); continue; } let group = new Group(this, parseInt(target == GroupTarget.SERVER ? groupData["sgid"] : groupData["cgid"]), target, type, groupData["name"]); for (let key in groupData) { if (key == "sgid") continue; if (key == "cgid") continue; if (key == "type") continue; if (key == "name") continue; group.updateProperty(key, groupData[key]); } group.requiredMemberRemovePower = parseInt(groupData["n_member_removep"]); group.requiredMemberAddPower = parseInt(groupData["n_member_addp"]); group.requiredModifyPower = parseInt(groupData["n_modifyp"]); if (target == GroupTarget.SERVER) this.serverGroups.push(group); else this.channelGroups.push(group); } for (const client of this.handle.channelTree.clients) client.update_displayed_client_groups(); } request_permissions(group) { for (let request of this.requests_group_permissions) if (request.group_id == group.id && request.promise.time() + 1000 > Date.now()) return request.promise; let req = new GroupPermissionRequest(); req.group_id = group.id; req.promise = new LaterPromise(); this.requests_group_permissions.push(req); this.handle.serverConnection.send_command(group.target == GroupTarget.SERVER ? "servergrouppermlist" : "channelgrouppermlist", { cgid: group.id, sgid: group.id }).catch(error => { if (error instanceof CommandResult && error.id == 0x0501) req.promise.resolved([]); else req.promise.rejected(error); }).then(() => { //No notify handler setTimeout(() => { if (this.requests_group_permissions.remove(req)) req.promise.rejected(_translations.ry6JbE1j || (_translations.ry6JbE1j = tr("no response"))); }, 1000); }); return req.promise; } handle_group_permission_list(json) { let group = json[0]["sgid"] ? this.serverGroup(parseInt(json[0]["sgid"])) : this.channelGroup(parseInt(json[0]["cgid"])); if (!group) { log.error(LogCategory.PERMISSIONS, _translations.lM4enCzV || (_translations.lM4enCzV = tr("Got group permissions for group %o/%o, but its not a registered group!")), json[0]["sgid"], json[0]["cgid"]); return; } let requests = []; for (let req of this.requests_group_permissions) if (req.group_id == group.id) requests.push(req); if (requests.length == 0) { log.warn(LogCategory.PERMISSIONS, _translations.OlcOY9Oi || (_translations.OlcOY9Oi = tr("Got group permissions for group %o/%o, but it was never requested!")), json[0]["sgid"], json[0]["cgid"]); return; } let permissions = PermissionManager.parse_permission_bulk(json, this.handle.permissions); for (let req of requests) { this.requests_group_permissions.remove(req); req.promise.resolved(permissions); } } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["46781534c5b8744342d5e1cb470f54295d8e0415c5ff17abae7eb6ef80ec64fa"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["46781534c5b8744342d5e1cb470f54295d8e0415c5ff17abae7eb6ef80ec64fa"] = "46781534c5b8744342d5e1cb470f54295d8e0415c5ff17abae7eb6ef80ec64fa"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "DCMrKjN6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (5,21)" }, { name: "x4QFY8cw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (107,25)" }, { name: "dFGvDzKl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (125,35)" }, { name: "hmRPaeUZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (136,25)" }, { name: "PNcccgLx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (158,35)" }, { name: "R6SjfIQ9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (170,44)" }, { name: "COCcPP1_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (184,125)" }, { name: "t1qSGjoo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (185,84)" }, { name: "PerphGL8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (227,47)" }, { name: "Udn4hTMY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (227,68)" }, { name: "L2ki1Skp", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (276,34)" }, { name: "_RrVUjgX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (276,62)" }, { name: "sl496iCK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (292,71)" }, { name: "XC0NChHc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (302,34)" }, { name: "wz0RQ6W1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (302,57)" }, { name: "ySq4xxUe", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (460,43)" }, { name: "U5kKlwd8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (465,43)" }, { name: "i6XwJzrt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (466,46)" }, { name: "pwBc9du5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (466,106)" }, { name: "tYO7MhPX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (481,33)" }, { name: "TPswmcMR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (482,42)" }, { name: "P9SCZZQG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (493,35)" }, { name: "O6ifCkPV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (603,33)" }, { name: "ijGZQoJy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (659,50)" }, { name: "oPL5wq0y", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (660,75)" }, { name: "UBrvt3sv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (699,50)" }, { name: "phHj2aiZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (700,74)" }, { name: "XUo6cT78", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (710,50)" }, { name: "dCwo9upm", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (711,80)" }, { name: "AlGUCXNW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (722,50)" }, { name: "o2FZws2H", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (723,77)" }, { name: "urEnnhUv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (735,50)" }, { name: "RbO_12FB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (736,77)" }, { name: "He1Lhlei", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (748,50)" }, { name: "BsQvH7KD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (749,83)" }, { name: "dryBR96k", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (765,50)" }, { name: "NmI6OOx2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (766,83)" }, { name: "ISCwnQTE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (776,50)" }, { name: "gT4hzBi0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (777,85)" }, { name: "DaKCu_FT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (783,138)" }, { name: "D8X_oTbc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (790,85)" }, { name: "uLiVzH1c", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (797,50)" }, { name: "Zw07OLxG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (808,50)" }, { name: "NtGL5zmt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (809,88)" }, { name: "r6jWa2i3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (825,39)" }, { name: "sH3hrr8x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (826,92)" }, { name: "gtbrQF6_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (829,35)" }, { name: "DW7n4WE_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (830,88)" }, { name: "u_dYuuQh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (837,50)" }, { name: "C8qosC5x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (846,39)" }, { name: "hGsVw3C1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (861,50)" }, { name: "jvF1L94q", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (874,55)" }, { name: "ePInsAEF", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (882,50)" }, { name: "QE8mYeI3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (900,38)" }, { name: "c93vvmwR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (900,71)" }, { name: "W6aQuY5Q", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (920,104)" }, { name: "_aqNX0xB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (921,91)" }, { name: "e3VI8KGN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (924,90)" }, { name: "vjY9fepV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (951,81)" }, { name: "jedfrTq7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (985,70)" }, { name: "dJqFoWNu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1001,94)" }, { name: "QMbj98Jl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1010,83)" }, { name: "oXE3AOOj", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1010,108)" }, { name: "u3YjNURr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1010,150)" }, { name: "bdvaz2Fu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1024,54)" }, { name: "yZrWIhG1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1058,42)" }, { name: "OergtM4i", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1058,79)" }, { name: "AcQQmDNG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1058,157)" }, { name: "BIHNDdrV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1058,197)" }, { name: "LpQGcaVD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1071,36)" }, { name: "Odgcch92", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1071,57)" }, { name: "PKQe99Hv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1080,42)" }, { name: "uZOymAv8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1080,74)" }, { name: "iRIw6oQA", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1080,147)" }, { name: "uskvfZ0w", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1080,187)" }, { name: "w92k7IcM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1094,42)" }, { name: "aeeSZ1W6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1094,69)" }, { name: "x64gbqPE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1108,42)" }, { name: "f7eMoiYk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1108,74)" }, { name: "KRG7a6pk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1108,151)" }, { name: "WnIitvJ5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1108,191)" }, { name: "cgIp7Mq0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1117,74)" }, { name: "vmnyPmOT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1117,114)" }, { name: "il2IXXi7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1128,74)" }, { name: "eLGB6hfn", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1139,39)" }, { name: "rQQstdmx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1156,39)" }, { name: "JsYl7deR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1161,50)" }, { name: "V2dCo75J", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1161,87)" }, { name: "M_33FHbX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1188,115)" }, { name: "K95eJH8w", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1199,88)" }, { name: "uUD_P0G8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1227,39)" }, { name: "B2niZHis", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1232,50)" }, { name: "lglQPHRb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1232,83)" }, { name: "gjr1Hjwb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1267,82)" }, { name: "TQnO8NzW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1322,71)" }, { name: "UOYpbAz7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1323,75)" }, { name: "j_B1XMlg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1388,44)" }, { name: "LhMjT0D6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1388,64)" }, { name: "QXs1fW_l", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1400,50)" }, { name: "LvN8hZ1p", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1400,91)" }, { name: "mfkiBtNv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1405,45)" }, { name: "TgHz611r", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1405,71)" }, { name: "e35FyXnh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1413,44)" }, { name: "w9qoM29d", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1413,64)" }, { name: "hZrU5_SP", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1431,45)" }, { name: "K5k4dA5r", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1431,70)" }, { name: "pi0qV71w", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1438,46)" }, { name: "f_7UqLhu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1438,63)" }, { name: "vlf6z52a", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1488,46)" }, { name: "LbOr04qi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1501,35)" }, { name: "NFAJFMiD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1517,35)" }, { name: "TjAtodXU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1522,46)" }, { name: "hLnfEYZl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1522,75)" }, { name: "lghaKO0H", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1692,57)" }, { name: "JjcOzbzw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1723,53)" }, { name: "z4UK75Eu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1739,98)" }, { name: "am_OVcEM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1744,39)" }, { name: "pj9HuZR1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1747,53)" }, { name: "YwWBf7Xh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1776,103)" }, { name: "rqWJD5R2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1796,107)" }, { name: "w8SWxS4C", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1818,103)" }, { name: "S9WvyD7Z", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1889,46)" }, { name: "hceWH1fk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1889,109)" }, { name: "pqrGxJyU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1889,210)" }, { name: "cin0D3wS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1889,241)" }, { name: "ii2WV_Om", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1910,78)" }, { name: "zUPIX6BD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (1910,123)" }, { name: "cIzsOEm1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2022,46)" }, { name: "CPz2Dcn4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2022,106)" }, { name: "TqXWWyKK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2022,176)" }, { name: "IAvTTiJt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2022,207)" }, { name: "NZPKedF2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2124,109)" }, { name: "Fj0SrrS2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2139,45)" }, { name: "eE42rV0W", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2149,54)" }, { name: "Y9zzAYFy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2149,114)" }, { name: "EdjnX01y", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2149,184)" }, { name: "LJiFWJSt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2149,215)" }, { name: "jwSWNYxO", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2209,58)" }, { name: "UOWQDD_7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2209,126)" }, { name: "izNO4C23", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2209,204)" }, { name: "oRJMsyYz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2209,235)" }, { name: "FkXnr4XQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2267,58)" }, { name: "G2MNfANr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2267,120)" }, { name: "LUwfp1q6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2267,192)" }, { name: "Eckk8zqH", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2267,223)" }, { name: "Sz0yBwv1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2356,83)" }, { name: "nM_Detuu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2356,95)" }, { name: "tbSVCOB3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2393,35)" }, { name: "qJrtnF6R", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2409,69)" }, { name: "fMFyBIJx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2413,37)" }, { name: "m7tGEkDd", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2416,43)" }, { name: "HRWXI7ss", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2421,43)" }, { name: "_DgU0HsU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2428,69)" }, { name: "r6v8MZ09", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2431,35)" }, { name: "JslYmH78", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2432,38)" }, { name: "l0U3SilI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2432,65)" }, { name: "SCagvySD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2446,35)" }, { name: "N4jqwUqM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2447,38)" }, { name: "jeMb4g5m", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalSettings.ts (2447,93)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function spawnSettingsModal(default_page) { let modal; modal = createModal({ header: _translations.DCMrKjN6 || (_translations.DCMrKjN6 = tr("Settings")), body: () => { const tag = $("#tmpl_settings").renderTag().dividerfy(); /* general "tab" mechanic */ const left = tag.find("> .left"); const right = tag.find("> .right"); { left.find(".entry:not(.group)").on('click', event => { const entry = $(event.target); right.find("> .container").addClass("hidden"); left.find(".selected").removeClass("selected"); const target = entry.attr("container"); if (!target) return; right.find("> .container." + target).removeClass("hidden"); entry.addClass("selected"); }); } /* initialize all tabs */ /* enable one tab */ { left.find(".entry[container" + (default_page ? ("='" + default_page + "'") : "") + "]").first().trigger('click'); } return tag; }, footer: null }); modal.htmlTag.find(".modal-body").addClass("modal-settings"); settings_general_application(modal.htmlTag.find(".right .container.general-application"), modal); settings_general_language(modal.htmlTag.find(".right .container.general-language"), modal); settings_general_chat(modal.htmlTag.find(".right .container.general-chat"), modal); settings_audio_microphone(modal.htmlTag.find(".right .container.audio-microphone"), modal); settings_audio_speaker(modal.htmlTag.find(".right .container.audio-speaker"), modal); settings_audio_sounds(modal.htmlTag.find(".right .container.audio-sounds"), modal); const update_profiles = settings_identity_profiles(modal.htmlTag.find(".right .container.identity-profiles"), modal); settings_identity_forum(modal.htmlTag.find(".right .container.identity-forum"), modal, update_profiles); modal.close_listener.push(() => { if (profiles.requires_save()) profiles.save(); }); modal.open(); return modal; } Modals.spawnSettingsModal = spawnSettingsModal; function settings_general_application(container, modal) { /* hostbanner */ { const option = container.find(".option-hostbanner-background"); option.on('change', event => { settings.changeGlobal(Settings.KEY_HOSTBANNER_BACKGROUND, option[0].checked); for (const sc of server_connections.server_connection_handlers()) sc.hostbanner.update(); }).prop("checked", settings.static_global(Settings.KEY_HOSTBANNER_BACKGROUND)); } /* font size */ { const current_size = parseInt(getComputedStyle(document.body).fontSize); //settings.static_global(Settings.KEY_FONT_SIZE, 12); const select = container.find(".option-font-size"); if (select.find("option[value='" + current_size + "']").length) select.find("option[value='" + current_size + "']").prop("selected", true); else select.find("option[value='-1']").prop("selected", true); select.on('change', event => { const value = parseInt(select.val()); settings.changeGlobal(Settings.KEY_FONT_SIZE, value); console.log("Changed font size to %dpx", value); $(document.body).css("font-size", value + "px"); }); } /* all permissions */ { const option = container.find(".option-all-permissions"); option.on('change', event => { settings.changeGlobal(Settings.KEY_HOSTBANNER_BACKGROUND, option[0].checked); }).prop("checked", settings.global(Settings.KEY_PERMISSIONS_SHOW_ALL)); } } function settings_general_language(container, modal) { const container_entries = container.find(".container-list .entries"); const tag_loading = container.find(".cover-loading"); const template = $("#settings-translations-list-entry"); const restart_hint = container.find(".restart-note").hide(); const display_repository_info = (repository) => { const info_modal = createModal({ header: _translations.x4QFY8cw || (_translations.x4QFY8cw = tr("Repository info")), body: () => { return $("#settings-translations-list-entry-info").renderTag({ type: "repository", name: repository.name, url: repository.url, contact: repository.contact, translations: repository.translations || [] }); }, 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"); buttonOk.text(_translations.dFGvDzKl || (_translations.dFGvDzKl = tr("Close"))); buttonOk.click(() => info_modal.close()); footer.append(buttonOk); return footer; } }); info_modal.open(); }; const display_translation_info = (translation, repository) => { const info_modal = createModal({ header: _translations.hmRPaeUZ || (_translations.hmRPaeUZ = tr("Translation info")), body: () => { const tag = $("#settings-translations-list-entry-info").renderTag({ type: "translation", name: translation.name, url: translation.path, repository_name: repository.name, contributors: translation.contributors || [] }); tag.find(".button-info").on('click', () => display_repository_info(repository)); return tag; }, 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"); buttonOk.text(_translations.PNcccgLx || (_translations.PNcccgLx = tr("Close"))); buttonOk.click(() => info_modal.close()); footer.append(buttonOk); return footer; } }); info_modal.open(); }; const update_current_selected = () => { const container_current = container.find(".selected-language6"); container_current.empty().text(_translations.R6SjfIQ9 || (_translations.R6SjfIQ9 = tr("Loading"))); let current_translation; i18n.iterate_repositories(repository => { if (current_translation) return; for (const entry of repository.translations) if (i18n.config.translation_config().current_translation_path == entry.path) { current_translation = entry; return; } }).then(() => { container_current.empty(); const language = current_translation ? current_translation.country_code : "gb"; $.spawn("div").addClass("country flag-" + language.toLowerCase()).attr('title', i18n.country_name(language, _translations.COCcPP1_ || (_translations.COCcPP1_ = tr("Unknown language")))).appendTo(container_current); $.spawn("a").text(current_translation ? current_translation.name : _translations.t1qSGjoo || (_translations.t1qSGjoo = tr("English (Default)"))).appendTo(container_current); }).catch(error => { /* This shall never happen */ }); }; const initially_selected = i18n.config.translation_config().current_translation_url; const update_list = () => { container_entries.empty(); const currently_selected = i18n.config.translation_config().current_translation_url; //Default translation { const tag = template.renderTag({ type: "default", selected: !currently_selected || currently_selected == "default" }); tag.on('click', () => { i18n.select_translation(undefined, undefined); container_entries.find(".selected").removeClass("selected"); tag.addClass("selected"); update_current_selected(); restart_hint.toggle(initially_selected !== i18n.config.translation_config().current_translation_url); }); tag.appendTo(container_entries); } { tag_loading.show(); i18n.iterate_repositories(repo => { let repo_tag = container_entries.find("[repository=\"" + repo.unique_id + "\"]"); if (repo_tag.length == 0) { repo_tag = template.renderTag({ type: "repository", name: repo.name || repo.url, id: repo.unique_id }); repo_tag.find(".button-delete").on('click', e => { e.preventDefault(); Modals.spawnYesNo(_translations.PerphGL8 || (_translations.PerphGL8 = tr("Are you sure?")), _translations.Udn4hTMY || (_translations.Udn4hTMY = tr("Do you really want to delete this repository?")), answer => { if (answer) { i18n.delete_repository(repo); update_list(); } }); }); repo_tag.find(".button-info").on('click', e => { e.preventDefault(); display_repository_info(repo); }); container_entries.append(repo_tag); } for (const translation of repo.translations) { const tag = template.renderTag({ type: "translation", name: translation.name || translation.path, id: repo.unique_id, country_code: translation.country_code, selected: i18n.config.translation_config().current_translation_path == translation.path }); tag.find(".button-info").on('click', e => { e.preventDefault(); display_translation_info(translation, repo); }); tag.on('click', e => { if (e.isDefaultPrevented()) return; i18n.select_translation(repo, translation); container_entries.find(".selected").removeClass("selected"); tag.addClass("selected"); update_current_selected(); restart_hint.toggle(initially_selected !== i18n.config.translation_config().current_translation_url); }); tag.insertAfter(repo_tag); } }).then(() => tag_loading.hide()).catch(error => { console.error(error); /* this should NEVER happen */ }); } }; /* button add repository */ { container.find(".button-add-repository").on('click', () => { createInputModal(_translations.L2ki1Skp || (_translations.L2ki1Skp = tr("Enter repository URL")), _translations._RrVUjgX || (_translations._RrVUjgX = tr("Enter repository URL:")), text => { try { new URL(text); return true; } catch (error) { return false; } }, url => { if (!url) return; tag_loading.show(); i18n.load_repository(url).then(repository => { i18n.register_repository(repository); update_list(); }).catch(error => { tag_loading.hide(); createErrorModal("Failed to load repository", (_translations.sl496iCK || (_translations.sl496iCK = tr("Failed to query repository.
Ensure that this repository is valid and reachable.
Error: "))) + error).open(); }); }).open(); }); } container.find(".button-restart").on('click', () => { if (app.is_web()) { location.reload(); } else { createErrorModal(_translations.XC0NChHc || (_translations.XC0NChHc = tr("Not implemented")), _translations.wz0RQ6W1 || (_translations.wz0RQ6W1 = tr("Client restart isn't implemented.
Please do it manually!"))).open(); } }); update_list(); update_current_selected(); } function settings_general_chat(container, modal) { /* timestamp format */ { const option_fixed = container.find(".option-fixed-timestamps"); const option_colloquial = container.find(".option-colloquial-timestamps"); option_colloquial.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_COLLOQUIAL_TIMESTAMPS, option_colloquial[0].checked); }); option_fixed.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_FIXED_TIMESTAMPS, option_fixed[0].checked); option_colloquial .prop("disabled", option_fixed[0].checked) .parents("label").toggleClass("disabled", option_fixed[0].checked); if (option_fixed[0].checked) { option_colloquial.prop("checked", false); } else { option_colloquial.prop("checked", settings.static_global(Settings.KEY_CHAT_COLLOQUIAL_TIMESTAMPS)); } }).prop("checked", settings.static_global(Settings.KEY_CHAT_FIXED_TIMESTAMPS)).trigger('change'); } { const option = container.find(".option-instant-channel-switch"); option.on('change', event => { settings.changeGlobal(Settings.KEY_SWITCH_INSTANT_CHAT, option[0].checked); }).prop("checked", settings.static_global(Settings.KEY_SWITCH_INSTANT_CHAT)); } { const option = container.find(".option-instant-client-switch"); option.on('change', event => { settings.changeGlobal(Settings.KEY_SWITCH_INSTANT_CLIENT, option[0].checked); }).prop("checked", settings.static_global(Settings.KEY_SWITCH_INSTANT_CLIENT)); } { const option = container.find(".option-colored-emojies"); option.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_COLORED_EMOJIES, option[0].checked); }).prop("checked", settings.static_global(Settings.KEY_CHAT_COLORED_EMOJIES)); } const update_format_helper = () => server_connections.server_connection_handlers().map(e => e.side_bar).forEach(e => { e.private_conversations().update_input_format_helper(); e.channel_conversations().update_input_format_helper(); }); { const option = container.find(".option-support-markdown"); option.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_ENABLE_MARKDOWN, option[0].checked); update_format_helper(); }).prop("checked", settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN)); } { const option = container.find(".option-support-bbcode"); option.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_ENABLE_BBCODE, option[0].checked); update_format_helper(); }).prop("checked", settings.static_global(Settings.KEY_CHAT_ENABLE_BBCODE)); } { const option = container.find(".option-url-tagging"); option.on('change', event => { settings.changeGlobal(Settings.KEY_CHAT_TAG_URLS, option[0].checked); }).prop("checked", settings.static_global(Settings.KEY_CHAT_TAG_URLS)); } /* Icon size */ { const container_slider = container.find(".container-icon-size .container-slider"); const container_value = container.find(".container-icon-size .value"); sliderfy(container_slider, { unit: '%', min_value: 25, max_value: 300, step: 5, initial_value: settings.static_global(Settings.KEY_ICON_SIZE), value_field: container_value }); container_slider.on('change', event => { const value = parseInt(container_slider.attr("value")); settings.changeGlobal(Settings.KEY_ICON_SIZE, value); console.log("Changed icon size to %sem", (value / 100).toFixed(2)); MessageHelper.set_icon_size((value / 100).toFixed(2) + "em"); }); } } function settings_audio_microphone(container, modal) { const registry = new events.Registry(); registry.enable_debug("settings-microphone"); modal_settings.initialize_audio_microphone_controller(registry); modal_settings.initialize_audio_microphone_view(container, registry); modal.close_listener.push(() => registry.fire_async("deinitialize")); return; } function settings_identity_profiles(container, modal) { const registry = new events.Registry(); //registry.enable_debug("settings-identity"); modal_settings.initialize_identity_profiles_controller(registry); modal_settings.initialize_identity_profiles_view(container, registry, { forum_setuppable: true }); registry.on("setup-forum-connection", event => { modal.htmlTag.find('.entry[container="identity-forum"]').trigger('click'); }); return () => registry.fire("reload-profile"); } function settings_audio_speaker(container, modal) { /* devices */ { const container_devices = container.find(".left .container-devices"); const contianer_error = container.find(".left .container-error"); const update_devices = () => { container_devices.children().remove(); const current_selected = audio.player.current_device(); const generate_device = (device) => { const selected = device === current_selected || (typeof (current_selected) !== "undefined" && typeof (device) !== "undefined" && current_selected.device_id == device.device_id); const tag = $.spawn("div").addClass("device").toggleClass("selected", selected).append($.spawn("div").addClass("container-selected").append($.spawn("div").addClass("icon_em client-apply")), $.spawn("div").addClass("container-name").append($.spawn("div").addClass("device-driver").text(device ? (device.driver || "Unknown driver") : "No device"), $.spawn("div").addClass("device-name").text(device ? (device.name || "Unknown name") : "No device"))); tag.on('click', event => { if (tag.hasClass("selected")) return; const _old = container_devices.find(".selected"); _old.removeClass("selected"); tag.addClass("selected"); audio.player.set_device(device ? device.device_id : null).then(() => { console.debug(_translations.ySq4xxUe || (_translations.ySq4xxUe = tr("Changed default speaker device"))); }).catch((error) => { _old.addClass("selected"); tag.removeClass("selected"); console.error(_translations.U5kKlwd8 || (_translations.U5kKlwd8 = tr("Failed to change speaker to device %o: %o")), device, error); createErrorModal(_translations.i6XwJzrt || (_translations.i6XwJzrt = tr("Failed to change speaker")), MessageHelper.formatMessage(_translations.pwBc9du5 || (_translations.pwBc9du5 = tr("Failed to change the speaker device to the target speaker{:br:}{}")), error)).open(); }); }); return tag; }; generate_device(undefined).appendTo(container_devices); audio.player.available_devices().then(result => { contianer_error.text("").hide(); result.forEach(e => generate_device(e).appendTo(container_devices)); }).catch(error => { if (typeof (error) === "string") contianer_error.text(error).show(); console.log(_translations.tYO7MhPX || (_translations.tYO7MhPX = tr("Failed to query available speaker devices: %o")), error); contianer_error.text(_translations.TPswmcMR || (_translations.TPswmcMR = tr("Errors occurred (View console)"))).show(); }); }; update_devices(); const button_update = container.find(".button-update"); button_update.on('click', (event) => __awaiter(this, void 0, void 0, function* () { button_update.prop("disabled", true); try { update_devices(); } catch (error) { console.error(_translations.P9SCZZQG || (_translations.P9SCZZQG = tr("Failed to build new speaker device list: %o")), error); } button_update.prop("disabled", false); })); } /* slider */ { { const container_master = container.find(".container-volume-master"); const slider = container_master.find(".container-slider"); sliderfy(slider, { min_value: 0, max_value: 100, step: 1, initial_value: settings.static_global(Settings.KEY_SOUND_MASTER, 100), value_field: [container_master.find(".container-value")] }); slider.on('change', event => { const volume = parseInt(slider.attr('value')); if (audio.player.set_master_volume) audio.player.set_master_volume(volume / 100); settings.changeGlobal(Settings.KEY_SOUND_MASTER, volume); }); } { const container_soundpack = container.find(".container-volume-soundpack"); const slider = container_soundpack.find(".container-slider"); sliderfy(slider, { min_value: 0, max_value: 100, step: 1, initial_value: settings.static_global(Settings.KEY_SOUND_MASTER_SOUNDS, 100), value_field: [container_soundpack.find(".container-value")] }); slider.on('change', event => { const volume = parseInt(slider.attr('value')); sound.set_master_volume(volume / 100); settings.changeGlobal(Settings.KEY_SOUND_MASTER_SOUNDS, volume); }); } } /* button test sound */ { container.find(".button-test-sound").on('click', event => { sound.manager.play(Sound.SOUND_TEST, { default_volume: 1, ignore_muted: true, ignore_overlap: true }); }); } } function settings_audio_sounds(contianer, modal) { /* initialize sound list */ { const container_sounds = contianer.find(".container-sounds"); const generate_sound = (_sound) => { let tag_play_pause, tag_play, tag_pause, tag_input_muted; let tag = $.spawn("div").addClass("sound").append(tag_play_pause = $.spawn("div").addClass("container-button-play_pause").append(tag_play = $.spawn("img").attr("src", "img/icon_sound_play.svg"), tag_pause = $.spawn("img").attr("src", "img/icon_sound_pause.svg")), $.spawn("div").addClass("container-name").text(_sound), $.spawn("label").addClass("container-button-toggle").append($.spawn("div").addClass("switch").append(tag_input_muted = $.spawn("input").attr("type", "checkbox"), $.spawn("span").addClass("slider").append($.spawn("div").addClass("dot"))))); tag_play_pause.on('click', event => { if (tag_pause.is(":visible")) return; tag_play.hide(); tag_pause.show(); const _done = flag => { tag_pause.hide(); tag_play.show(); }; const _timeout = setTimeout(() => _done(false), 10 * 1000); /* the sounds are not longer than 10 seconds */ sound.manager.play(_sound, { ignore_overlap: true, ignore_muted: true, default_volume: 1, callback: flag => { clearTimeout(_timeout); _done(flag); } }); }); tag_pause.hide(); tag_input_muted.prop("checked", sound.get_sound_volume(_sound, 1) > 0); tag_input_muted.on('change', event => { const volume = tag_input_muted.prop("checked") ? 1 : 0; sound.set_sound_volume(_sound, volume); console.log(_translations.O6ifCkPV || (_translations.O6ifCkPV = tr("Changed sound volume to %o for sound %o")), volume, _sound); }); return tag; }; //container-sounds for (const sound_key in Sound) generate_sound(Sound[sound_key]).appendTo(container_sounds); /* the filter */ const input_filter = contianer.find(".input-sounds-filter"); input_filter.on('change keyup', event => { const filter = input_filter.val(); container_sounds.find(".sound").each((_, _element) => { const element = $(_element); element.toggle(filter.length == 0 || element.text().toLowerCase().indexOf(filter) !== -1); }); }); } const overlap_tag = contianer.find(".option-overlap-same"); overlap_tag.on('change', event => { const activated = event.target.checked; sound.set_overlap_activated(activated); }).prop("checked", sound.overlap_activated()); const mute_tag = contianer.find(".option-mute-output"); mute_tag.on('change', event => { const activated = event.target.checked; sound.set_ignore_output_muted(!activated); }).prop("checked", !sound.ignore_output_muted()); modal.close_listener.push(sound.save); } let modal_settings; (function (modal_settings) { function initialize_identity_profiles_controller(event_registry) { const send_error = (event, profile, text) => event_registry.fire_async(event, { status: "error", profile_id: profile, error: text }); event_registry.on("create-profile", event => { const profile = profiles.create_new_profile(event.name); profiles.mark_need_save(); event_registry.fire_async("create-profile-result", { status: "success", name: event.name, profile_id: profile.id }); }); event_registry.on("delete-profile", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.ijGZQoJy || (_translations.ijGZQoJy = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("delete-profile-result", event.profile_id, _translations.oPL5wq0y || (_translations.oPL5wq0y = tr("Unknown profile"))); return; } profiles.delete_profile(profile); event_registry.fire_async("delete-profile-result", { status: "success", profile_id: event.profile_id }); }); const build_profile_info = (profile) => { const forum_data = profile.selected_identity(profiles.identities.IdentitifyType.TEAFORO); const teamspeak_data = profile.selected_identity(profiles.identities.IdentitifyType.TEAMSPEAK); const nickname_data = profile.selected_identity(profiles.identities.IdentitifyType.NICKNAME); return { id: profile.id, name: profile.profile_name, nickname: profile.default_username, identity_type: profile.selected_identity_type, identity_forum: !forum_data ? undefined : { valid: forum_data.valid(), fallback_name: forum_data.fallback_name() }, identity_nickname: !nickname_data ? undefined : { name: nickname_data.name(), fallback_name: nickname_data.fallback_name() }, identity_teamspeak: !teamspeak_data ? undefined : { unique_id: teamspeak_data.uid(), fallback_name: teamspeak_data.fallback_name() } }; }; event_registry.on("query-profile-list", event => { event_registry.fire_async("query-profile-list-result", { status: "success", profiles: profiles.profiles().map(e => build_profile_info(e)) }); }); event_registry.on("query-profile", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.UBrvt3sv || (_translations.UBrvt3sv = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("query-profile-result", event.profile_id, _translations.phHj2aiZ || (_translations.phHj2aiZ = tr("Unknown profile"))); return; } event_registry.fire_async("query-profile-result", { status: "success", profile_id: event.profile_id, info: build_profile_info(profile) }); }); event_registry.on("set-default-profile", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.XUo6cT78 || (_translations.XUo6cT78 = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("set-default-profile-result", event.profile_id, _translations.dCwo9upm || (_translations.dCwo9upm = tr("Unknown profile"))); return; } const old = profiles.set_default_profile(profile); event_registry.fire_async("set-default-profile-result", { status: "success", old_profile_id: event.profile_id, new_profile_id: old.id }); }); event_registry.on("set-profile-name", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.AlGUCXNW || (_translations.AlGUCXNW = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("set-profile-name-result", event.profile_id, _translations.o2FZws2H || (_translations.o2FZws2H = tr("Unknown profile"))); return; } profile.profile_name = event.name; profiles.mark_need_save(); event_registry.fire_async("set-profile-name-result", { name: event.name, profile_id: event.profile_id, status: "success" }); }); event_registry.on("set-default-name", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.urEnnhUv || (_translations.urEnnhUv = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("set-default-name-result", event.profile_id, _translations.RbO_12FB || (_translations.RbO_12FB = tr("Unknown profile"))); return; } profile.default_username = event.name; profiles.mark_need_save(); event_registry.fire_async("set-default-name-result", { name: event.name, profile_id: event.profile_id, status: "success" }); }); event_registry.on("set-identity-name-name", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.He1Lhlei || (_translations.He1Lhlei = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("set-identity-name-name-result", event.profile_id, _translations.BsQvH7KD || (_translations.BsQvH7KD = tr("Unknown profile"))); return; } let identity = profile.selected_identity(profiles.identities.IdentitifyType.NICKNAME); if (!identity) profile.set_identity(profiles.identities.IdentitifyType.NICKNAME, identity = new profiles.identities.NameIdentity()); identity.set_name(event.name); profiles.mark_need_save(); event_registry.fire_async("set-identity-name-name-result", { name: event.name, profile_id: event.profile_id, status: "success" }); }); event_registry.on("query-profile-validity", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.dryBR96k || (_translations.dryBR96k = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("query-profile-validity-result", event.profile_id, _translations.NmI6OOx2 || (_translations.NmI6OOx2 = tr("Unknown profile"))); return; } event_registry.fire_async("query-profile-validity-result", { status: "success", profile_id: event.profile_id, valid: profile.valid() }); }); event_registry.on("query-identity-teamspeak", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.ISCwnQTE || (_translations.ISCwnQTE = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("query-identity-teamspeak-result", event.profile_id, _translations.gT4hzBi0 || (_translations.gT4hzBi0 = tr("Unknown profile"))); return; } const ts = profile.selected_identity(profiles.identities.IdentitifyType.TEAMSPEAK); if (!ts) { event_registry.fire_async("query-identity-teamspeak-result", { status: "error", profile_id: event.profile_id, error: _translations.DaKCu_FT || (_translations.DaKCu_FT = tr("Missing identity")) }); return; } ts.level().then(level => { event_registry.fire_async("query-identity-teamspeak-result", { status: "success", level: level, profile_id: event.profile_id }); }).catch(error => { send_error("query-identity-teamspeak-result", event.profile_id, _translations.D8X_oTbc || (_translations.D8X_oTbc = tr("failed to calculate level"))); }); }); event_registry.on("select-identity-type", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.uLiVzH1c || (_translations.uLiVzH1c = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); return; } profile.selected_identity_type = event.identity_type; profiles.mark_need_save(); }); event_registry.on("generate-identity-teamspeak", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.Zw07OLxG || (_translations.Zw07OLxG = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); send_error("generate-identity-teamspeak-result", event.profile_id, _translations.NtGL5zmt || (_translations.NtGL5zmt = tr("Unknown profile"))); return; } profiles.identities.TeaSpeakIdentity.generate_new().then(identity => { profile.set_identity(profiles.identities.IdentitifyType.TEAMSPEAK, identity); profiles.mark_need_save(); identity.level().then(level => { event_registry.fire_async("generate-identity-teamspeak-result", { status: "success", profile_id: event.profile_id, unique_id: identity.uid(), level: level }); }).catch(error => { console.error(_translations.r6jWa2i3 || (_translations.r6jWa2i3 = tr("Failed to calculate level for a new identity. Error object: %o")), error); send_error("generate-identity-teamspeak-result", event.profile_id, (_translations.sH3hrr8x || (_translations.sH3hrr8x = tr("failed to calculate level: "))) + error); }); }).catch(error => { console.error(_translations.gtbrQF6_ || (_translations.gtbrQF6_ = tr("Failed to generate a new identity. Error object: %o")), error); send_error("generate-identity-teamspeak-result", event.profile_id, (_translations.DW7n4WE_ || (_translations.DW7n4WE_ = tr("failed to generate identity: "))) + error); }); }); event_registry.on("import-identity-teamspeak", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.u_dYuuQh || (_translations.u_dYuuQh = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); return; } Modals.spawnTeamSpeakIdentityImport(identity => { profile.set_identity(profiles.identities.IdentitifyType.TEAMSPEAK, identity); profiles.mark_need_save(); identity.level().catch(error => { console.error(_translations.C8qosC5x || (_translations.C8qosC5x = tr("Failed to calculate level for a new imported identity. Error object: %o")), error); return Promise.resolve(undefined); }).then(level => { event_registry.fire_async("import-identity-teamspeak-result", { profile_id: event.profile_id, unique_id: identity.uid(), level: level }); }); }); }); event_registry.on("improve-identity-teamspeak-level", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.hGsVw3C1 || (_translations.hGsVw3C1 = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); return; } const identity = profile.selected_identity(profiles.identities.IdentitifyType.TEAMSPEAK); if (!identity) return; Modals.spawnTeamSpeakIdentityImprove(identity, profile.profile_name).close_listener.push(() => { profiles.mark_need_save(); identity.level().then(level => { event_registry.fire_async("improve-identity-teamspeak-level-update", { profile_id: event.profile_id, new_level: level }); }).catch(error => { log.error(LogCategory.CLIENT, _translations.jvF1L94q || (_translations.jvF1L94q = tr("Failed to calculate identity level after improvement (%o)")), error); }); }); }); event_registry.on("export-identity-teamspeak", event => { const profile = profiles.find_profile(event.profile_id); if (!profile) { log.warn(LogCategory.CLIENT, _translations.ePInsAEF || (_translations.ePInsAEF = tr("Received profile event with unknown profile id (event: %s, id: %s)")), event.type, event.profile_id); return; } const identity = profile.selected_identity(profiles.identities.IdentitifyType.TEAMSPEAK); if (!identity) return; identity.export_ts(true).then(data => { const element = $.spawn("a") .text("donwload") .attr("href", "data:test/plain;charset=utf-8," + encodeURIComponent(data)) .attr("download", name + ".ini") .css("display", "none") .appendTo($("body")); element[0].click(); element.remove(); }).catch(error => { console.error(error); createErrorModal(_translations.QE8mYeI3 || (_translations.QE8mYeI3 = tr("Failed to export identity")), (_translations.c93vvmwR || (_translations.c93vvmwR = tr("Failed to export and save identity.
Error: "))) + error).open(); }); }); } modal_settings.initialize_identity_profiles_controller = initialize_identity_profiles_controller; function initialize_identity_profiles_view(container, event_registry, settings) { /* profile list */ { const container_profiles = container.find(".container-profiles"); let selected_profile; const overlay_error = container_profiles.find(".overlay-error"); const overlay_timeout = container_profiles.find(".overlay-timeout"); const overlay_empty = container_profiles.find(".overlay-empty"); const build_profile = (profile, selected) => { let tag_avatar, tag_default; let tag = $.spawn("div").addClass("profile").attr("profile-id", profile.id).append(tag_avatar = $.spawn("div").addClass("container-avatar"), $.spawn("div").addClass("container-info").append($.spawn("div").addClass("container-type").append($.spawn("div").addClass("identity-type").text(profile.identity_type || (_translations.W6aQuY5Q || (_translations.W6aQuY5Q = tr("Type unset")))), tag_default = $.spawn("div").addClass("tag-default").text(_translations._aqNX0xB || (_translations._aqNX0xB = tr("(Default)"))), $.spawn("div").addClass("icon_em icon-status").hide()), $.spawn("div").addClass("profile-name").text(profile.name || (_translations.e3VI8KGN || (_translations.e3VI8KGN = tr("Unnamed")))))); tag_avatar.hide(); /* no avatars yet */ tag.on('click', event => event_registry.fire("select-profile", { profile_id: profile.id })); tag.toggleClass("selected", selected); tag_default.toggle(profile.id === "default"); event_registry.fire("query-profile-validity", { profile_id: profile.id }); return tag; }; event_registry.on("select-profile", event => { container_profiles.find(".profile").removeClass("selected"); container_profiles.find(".profile[profile-id='" + event.profile_id + "']").addClass("selected"); selected_profile = event.profile_id; }); event_registry.on("query-profile-list", event => { container_profiles.find(".profile").remove(); }); event_registry.on("query-profile-list-result", event => { container_profiles.find(".overlay").hide(); if (event.status === "error") { overlay_error.show().find(".error").text(event.error || (_translations.vjY9fepV || (_translations.vjY9fepV = tr("unknown error")))); return; } else if (event.status === "timeout") { overlay_timeout.show(); return; } if (!event.profiles.length) { overlay_empty.show(); return; } container_profiles.find(".overlay").hide(); container_profiles.find(".profile").remove(); event.profiles.forEach(e => build_profile(e, e.id == selected_profile).appendTo(container_profiles)); }); event_registry.on("delete-profile-result", event => { if (event.status !== "success") return; //TODO: Animate removal? container_profiles.find(".profile[profile-id='" + event.profile_id + "']").remove(); }); event_registry.on('create-profile-result', event => { if (event.status !== "success") return; event_registry.fire("query-profile-list"); event_registry.one("query-profile-list-result", e => event_registry.fire("select-profile", { profile_id: event.profile_id })); }); event_registry.on("set-profile-name-result", event => { if (event.status !== "success") return; const profile = container_profiles.find(".profile[profile-id='" + event.profile_id + "']"); profile.find(".profile-name").text(event.name || (_translations.jedfrTq7 || (_translations.jedfrTq7 = tr("Unnamed")))); }); event_registry.on("set-default-profile-result", event => { if (event.status !== "success") return; const old_profile = container_profiles.find(".profile[profile-id='default']"); const new_profile = container_profiles.find(".profile[profile-id='" + event.old_profile_id + "']"); old_profile.attr("profile-id", event.new_profile_id).find(".tag-default").hide(); new_profile.attr("profile-id", "default").find(".tag-default").show(); }); event_registry.on("select-identity-type", event => { if (!event.identity_type) return; const profile = container_profiles.find(".profile[profile-id='" + event.profile_id + "']"); profile.find(".identity-type").text(event.identity_type.toUpperCase() || (_translations.dJqFoWNu || (_translations.dJqFoWNu = tr("Type unset")))); }); event_registry.on("query-profile-validity-result", event => { const profile = container_profiles.find(".profile[profile-id='" + event.profile_id + "']"); profile.find(".icon-status") .show() .toggleClass("client-apply", event.status === "success" && event.valid) .toggleClass("client-delete", event.status !== "success" || !event.valid) .attr("title", event.status === "success" ? event.valid ? _translations.QMbj98Jl || (_translations.QMbj98Jl = tr("Profile is valid")) : _translations.oXE3AOOj || (_translations.oXE3AOOj = tr("Provile is invalid")) : event.error || (_translations.u3YjNURr || (_translations.u3YjNURr = tr("failed to query status")))); }); /* status indicator updaters */ event_registry.on("select-identity-type", event => { if (!event.profile_id) return; /* we need a short delay so everything could apply*/ setTimeout(() => { event_registry.fire("query-profile-validity", { profile_id: event.profile_id }); }, 100); }); event_registry.on(["set-default-name-result", "set-profile-name-result", "set-identity-name-name-result", "generate-identity-teamspeak-result"], event => { if (!('status' in event) || !('profile_id' in event)) { log.warn(LogCategory.CLIENT, _translations.bdvaz2Fu || (_translations.bdvaz2Fu = tr("Profile status watcher encountered an unuseal event!"))); return; } if (event.status !== "success") return; event_registry.fire("query-profile-validity", { profile_id: event.profile_id }); }); } /* list buttons */ { /* reload */ { const button = container.find(".button-reload-list"); button.on('click', event => event_registry.fire("query-profile-list")); event_registry.on("query-profile-list", event => button.prop("disabled", true)); event_registry.on("query-profile-list-result", event => button.prop("disabled", false)); } /* set default */ { const button = container.find(".button-set-default"); let current_profile; button.on('click', event => event_registry.fire("set-default-profile", { profile_id: current_profile })); event_registry.on("select-profile", event => { current_profile = event.profile_id; button.prop("disabled", !event.profile_id || event.profile_id === "default"); }); event_registry.on("set-default-profile-result", event => { if (event.status === "success") return; createErrorModal(_translations.yZrWIhG1 || (_translations.yZrWIhG1 = tr("Failed to set default profile")), (_translations.OergtM4i || (_translations.OergtM4i = tr("Failed to set default profile:"))) + "
" + (event.status === "timeout" ? _translations.AcQQmDNG || (_translations.AcQQmDNG = tr("request timeout")) : (event.error || (_translations.BIHNDdrV || (_translations.BIHNDdrV = tr("unknown error")))))).open(); }); button.prop("disabled", true); } /* delete button */ { const button = container.find(".button-delete"); let current_profile; button.on('click', event => { if (!current_profile || current_profile === "default") return; Modals.spawnYesNo(_translations.LpQGcaVD || (_translations.LpQGcaVD = tr("Are you sure?")), _translations.Odgcch92 || (_translations.Odgcch92 = tr("Do you really want to delete this profile?")), result => { if (result) event_registry.fire("delete-profile", { profile_id: current_profile }); }); }); event_registry.on("delete-profile-result", event => { if (event.status === "success") return; createErrorModal(_translations.PKQe99Hv || (_translations.PKQe99Hv = tr("Failed to delete profile")), (_translations.uZOymAv8 || (_translations.uZOymAv8 = tr("Failed to delete profile:"))) + "
" + (event.status === "timeout" ? _translations.iRIw6oQA || (_translations.iRIw6oQA = tr("request timeout")) : (event.error || (_translations.uskvfZ0w || (_translations.uskvfZ0w = tr("unknown error")))))).open(); }); event_registry.on("select-profile", event => { current_profile = event.profile_id; button.prop("disabled", !event.profile_id || event.profile_id === "default"); }); } /* create button */ { const button = container.find(".button-create"); button.on('click', event => { createInputModal(_translations.w92k7IcM || (_translations.w92k7IcM = tr("Please enter a name")), _translations.aeeSZ1W6 || (_translations.aeeSZ1W6 = tr("Please enter a name for the new profile:")), text => text.length >= 3 && !profiles.find_profile_by_name(text), value => { if (value) event_registry.fire("create-profile", { name: value }); }).open(); }); event_registry.on('create-profile', event => button.prop("disabled", true)); event_registry.on("create-profile-result", event => { button.prop("disabled", false); if (event.status === "success") { event_registry.fire("select-profile", { profile_id: event.profile_id }); return; } createErrorModal(_translations.x64gbqPE || (_translations.x64gbqPE = tr("Failed to create profile")), (_translations.f7eMoiYk || (_translations.f7eMoiYk = tr("Failed to create new profile:"))) + "
" + (event.status === "timeout" ? _translations.KRG7a6pk || (_translations.KRG7a6pk = tr("request timeout")) : (event.error || (_translations.WnIitvJ5 || (_translations.WnIitvJ5 = tr("unknown error")))))).open(); }); } } /* profile info */ { let current_profile; const error_text = event => event.status === "timeout" ? _translations.cgIp7Mq0 || (_translations.cgIp7Mq0 = tr("request timeout")) : (event.error || (_translations.vmnyPmOT || (_translations.vmnyPmOT = tr("unknown error")))); /* general info */ { /* profile name */ { const input = container.find(".profile-name"); let last_name; const update_name = () => input.prop("disabled", false) .val(last_name) .attr("placeholder", _translations.il2IXXi7 || (_translations.il2IXXi7 = tr("Profile name"))) .parent().removeClass("is-invalid"); const info_name = text => input.prop("disabled", true) .val(null) .attr("placeholder", text) .parent().removeClass("is-invalid"); event_registry.on("query-profile", event => { if (event.profile_id !== current_profile) return; info_name(_translations.eLGB6hfn || (_translations.eLGB6hfn = tr("loading"))); }); event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; if (event.status === "success") { last_name = event.info.name; update_name(); } else { info_name(error_text(event)); } }); event_registry.on("set-profile-name", event => { if (event.profile_id !== current_profile) return; info_name(_translations.rQQstdmx || (_translations.rQQstdmx = tr("saving"))); }); event_registry.on("set-profile-name-result", event => { if (event.status !== "success") { createErrorModal(_translations.JsYl7deR || (_translations.JsYl7deR = tr("Failed to change profile name")), (_translations.V2dCo75J || (_translations.V2dCo75J = tr("Failed to create apply new name:"))) + "
" + error_text(event)).open(); } else { last_name = event.name; } update_name(); }); input.on('keyup', event => { const text = input.val(); const profile = profiles.find_profile_by_name(text); input.parent().toggleClass("is-invalid", text.length < 3 || (profile && profile.id != current_profile)); }).on('change', event => { const text = input.val(); const profile = profiles.find_profile_by_name(text); if (text.length < 3 || (profile && profile.id != current_profile)) return; event_registry.fire("set-profile-name", { profile_id: current_profile, name: text }); }); } /* nickname name */ { const input = container.find(".profile-default-name"); let last_name = null, fallback_names = {}, current_identity_type = ""; const update_name = () => input.prop("disabled", false) .val(last_name) .attr("placeholder", fallback_names[current_identity_type] || (_translations.M_33FHbX || (_translations.M_33FHbX = tr("Another TeaSpeak user")))) .parent().removeClass("is-invalid"); const info_name = text => input.prop("disabled", true) .val(null) .attr("placeholder", text) .parent().removeClass("is-invalid"); event_registry.on("query-profile", event => { if (event.profile_id !== current_profile) return; input.prop("disabled", true).val(null).attr("placeholder", _translations.K95eJH8w || (_translations.K95eJH8w = tr("loading"))); }); event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; if (event.status === "success") { current_identity_type = event.info.identity_type; fallback_names["nickname"] = event.info.identity_nickname ? event.info.identity_nickname.fallback_name : undefined; fallback_names["teaforo"] = event.info.identity_forum ? event.info.identity_forum.fallback_name : undefined; fallback_names["teamspeak"] = event.info.identity_teamspeak ? event.info.identity_teamspeak.fallback_name : undefined; last_name = event.info.nickname; update_name(); } else { info_name(error_text(event)); } }); event_registry.on("select-identity-type", event => { if (current_identity_type === event.identity_type) return; current_identity_type = event.identity_type; update_name(); }); event_registry.on("set-default-name", event => { if (event.profile_id !== current_profile) return; info_name(_translations.uUD_P0G8 || (_translations.uUD_P0G8 = tr("saving"))); }); event_registry.on("set-default-name-result", event => { if (event.status !== "success") { createErrorModal(_translations.B2niZHis || (_translations.B2niZHis = tr("Failed to change nickname")), (_translations.lglQPHRb || (_translations.lglQPHRb = tr("Failed to create apply new nickname:"))) + "
" + error_text(event)).open(); } else { last_name = event.name; } update_name(); }); input.on('keyup', event => { const text = input.val(); input.parent().toggleClass("is-invalid", text.length != 0 && text.length < 3); }).on('change', event => { const text = input.val(); if (text.length != 0 && text.length < 3) return; event_registry.fire("set-default-name", { profile_id: current_profile, name: text }); }); } /* identity type */ { const select_identity_type = container.find(".profile-identity-type"); const show_message = (text, is_invalid) => select_identity_type .toggleClass("is-invalid", is_invalid) .prop("disabled", true) .find("option[value=error]") .text(text) .prop("selected", true); const set_type = type => select_identity_type .toggleClass("is-invalid", type === "unset") .prop("disabled", false) .find("option[value=" + type + "]") .prop("selected", true); event_registry.on("query-profile", event => show_message(_translations.gjr1Hjwb || (_translations.gjr1Hjwb = tr("loading")), false)); event_registry.on("select-identity-type", event => { if (event.profile_id !== current_profile) return; set_type(event.identity_type || "unset"); }); event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; if (event.status === "success") event_registry.fire("select-identity-type", { profile_id: event.profile_id, identity_type: event.info.identity_type }); else show_message(error_text(event), false); }); select_identity_type.on('change', event => { const type = select_identity_type.val().toLowerCase(); if (type === "error" || type == "unset") return; event_registry.fire("select-identity-type", { profile_id: current_profile, identity_type: type }); }); } /* avatar */ { container.find(".button-change-avatar").hide(); } } /* special info TeamSpeak */ { const container_settings = container.find(".container-teamspeak"); const container_valid = container_settings.find(".container-valid"); const container_invalid = container_settings.find(".container-invalid"); const input_current_level = container_settings.find(".current-level"); const input_unique_id = container_settings.find(".unique-id"); const button_new = container_settings.find(".button-new"); const button_improve = container_settings.find(".button-improve"); const button_import = container_settings.find(".button-import"); const button_export = container_settings.find(".button-export"); let is_profile_generated = false; event_registry.on("select-identity-type", event => { if (event.profile_id !== current_profile) return; container_settings.toggle(event.identity_type === "teamspeak"); }); event_registry.on("query-profile", event => { input_unique_id.val(null).attr("placeholder", _translations.TQnO8NzW || (_translations.TQnO8NzW = tr("loading"))); input_current_level.val(null).attr("placeholder", _translations.UOYpbAz7 || (_translations.UOYpbAz7 = tr("loading"))); button_new.prop("disabled", true); button_improve.prop("disabled", true); button_import.prop("disabled", true); button_export.prop("disabled", true); }); const update_identity = (state, unique_id, level) => { if (state === "not-created") { container_invalid.show(); container_valid.hide(); button_improve.prop("disabled", true); button_export.prop("disabled", true); } else { container_invalid.hide(); container_valid.show(); input_unique_id.val(unique_id).attr("placeholder", null); if (typeof level !== "number") event_registry.fire("query-identity-teamspeak", { profile_id: current_profile }); else input_current_level.val(level).attr("placeholder", null); button_improve.prop("disabled", false); button_export.prop("disabled", false); } is_profile_generated = state === "created"; button_new.toggleClass("btn-blue", !is_profile_generated).toggleClass("btn-red", is_profile_generated); button_import.toggleClass("btn-blue", !is_profile_generated).toggleClass("btn-red", is_profile_generated); button_new.prop("disabled", false); button_import.prop("disabled", false); }; event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; if (event.status !== "success") { input_unique_id.val(null).attr("placeholder", error_text(event)); return; } if (!event.info.identity_teamspeak) update_identity("not-created"); else update_identity("created", event.info.identity_teamspeak.unique_id); }); event_registry.on("query-identity-teamspeak-result", event => { if (event.profile_id !== current_profile) return; if (event.status === "success") { input_current_level.val(event.level).attr("placeholder", null); } else { input_current_level.val(null).attr("placeholder", error_text(event)); } }); /* the new button */ { button_new.on('click', event => { if (is_profile_generated) { Modals.spawnYesNo(_translations.j_B1XMlg || (_translations.j_B1XMlg = tr("Are you sure")), _translations.LhMjT0D6 || (_translations.LhMjT0D6 = tr("Do you really want to generate a new identity and override the old identity?")), result => { if (result) event_registry.fire("generate-identity-teamspeak", { profile_id: current_profile }); }); } else { event_registry.fire("generate-identity-teamspeak", { profile_id: current_profile }); } }); event_registry.on("generate-identity-teamspeak-result", event => { if (event.profile_id !== current_profile) return; if (event.status !== "success") { createErrorModal(_translations.QXs1fW_l || (_translations.QXs1fW_l = tr("Failed to generate a new identity")), (_translations.LvN8hZ1p || (_translations.LvN8hZ1p = tr("Failed to create a new identity:"))) + "
" + error_text(event)).open(); return; } update_identity("created", event.unique_id, event.level); createInfoModal(_translations.mfkiBtNv || (_translations.mfkiBtNv = tr("Identity generated")), _translations.TgHz611r || (_translations.TgHz611r = tr("A new identity had been successfully generated"))).open(); }); } /* the import identity */ { button_import.on('click', event => { if (is_profile_generated) { Modals.spawnYesNo(_translations.e35FyXnh || (_translations.e35FyXnh = tr("Are you sure")), _translations.w9qoM29d || (_translations.w9qoM29d = tr("Do you really want to import a new identity and override the old identity?")), result => { if (result) event_registry.fire("import-identity-teamspeak", { profile_id: current_profile }); }); } else { event_registry.fire("import-identity-teamspeak", { profile_id: current_profile }); } }); event_registry.on("improve-identity-teamspeak-level-update", event => { if (event.profile_id !== current_profile) return; input_current_level.val(event.new_level).attr("placeholder", null); }); event_registry.on("import-identity-teamspeak-result", event => { if (event.profile_id !== current_profile) return; event_registry.fire_async("query-profile", { profile_id: event.profile_id }); /* we do it like this so the default nickname changes as well */ createInfoModal(_translations.hZrU5_SP || (_translations.hZrU5_SP = tr("Identity imported")), _translations.K5k4dA5r || (_translations.K5k4dA5r = tr("Your identity had been successfully imported generated"))).open(); }); } /* identity export */ { button_export.on('click', event => { createInputModal(_translations.pi0qV71w || (_translations.pi0qV71w = tr("File name")), _translations.f_7UqLhu || (_translations.f_7UqLhu = tr("Please enter the file name")), text => !!text, name => { if (name) event_registry.fire("export-identity-teamspeak", { profile_id: current_profile, filename: name }); }).open(); }); } /* the improve button */ button_improve.on('click', event => event_registry.fire("improve-identity-teamspeak-level", { profile_id: current_profile })); } /* special info TeaSpeak - Forum */ { const container_settings = container.find(".container-teaforo"); const container_valid = container_settings.find(".container-valid"); const container_invalid = container_settings.find(".container-invalid"); const button_setup = container_settings.find(".button-setup"); event_registry.on("select-identity-type", event => { if (event.profile_id !== current_profile) return; container_settings.toggle(event.identity_type === "teaforo"); }); event_registry.on("query-profile", event => { container_valid.toggle(false); container_invalid.toggle(false); }); event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; const valid = event.status === "success" && event.info.identity_forum && event.info.identity_forum.valid; container_valid.toggle(!!valid); container_invalid.toggle(!valid); }); button_setup.on('click', event => event_registry.fire_async("setup-forum-connection")); button_setup.toggle(settings.forum_setuppable); } /* special info nickname */ { const container_settings = container.find(".container-nickname"); const input_nickname = container_settings.find(".nickname"); let last_name; const update_name = () => input_nickname.prop("disabled", false) .val(last_name) .attr("placeholder", _translations.vlf6z52a || (_translations.vlf6z52a = tr("Identity base name"))) .parent().removeClass("is-invalid"); const show_info = text => input_nickname.prop("disabled", true) .val(null) .attr("placeholder", text) .parent().removeClass("is-invalid"); event_registry.on("select-identity-type", event => event.profile_id === current_profile && container_settings.toggle(event.identity_type === "nickname")); event_registry.on("query-profile", event => { if (event.profile_id !== current_profile) return; show_info(_translations.LbOr04qi || (_translations.LbOr04qi = tr("loading"))); }); event_registry.on("query-profile-result", event => { if (event.profile_id !== current_profile) return; if (event.status === "success") { last_name = event.info.identity_nickname ? event.info.identity_nickname.name : null; update_name(); } else { show_info(error_text(event)); } }); event_registry.on("set-identity-name-name", event => { if (event.profile_id !== current_profile) return; show_info(_translations.NFAJFMiD || (_translations.NFAJFMiD = tr("saving"))); }); event_registry.on("set-identity-name-name-result", event => { if (event.status !== "success") { createErrorModal(_translations.TjAtodXU || (_translations.TjAtodXU = tr("Failed to change name")), (_translations.hLnfEYZl || (_translations.hLnfEYZl = tr("Failed to create new name:"))) + "
" + error_text(event)).open(); } else { last_name = event.name; } update_name(); }); input_nickname.on('keyup', event => { const text = input_nickname.val(); const profile = profiles.find_profile_by_name(text); input_nickname.parent().toggleClass("is-invalid", text.length < 3 || (profile && profile.id != current_profile)); }).on('change', event => { const text = input_nickname.val(); const profile = profiles.find_profile_by_name(text); if (text.length < 3 || (profile && profile.id != current_profile)) return; event_registry.fire("set-identity-name-name", { profile_id: current_profile, name: text }); }); } event_registry.on("select-profile", e => current_profile = e.profile_id); } /* timeouts */ { /* profile list */ { let timeout; event_registry.on("query-profile-list", event => timeout = setTimeout(() => event_registry.fire("query-profile-list-result", { status: "timeout" }), 5000)); event_registry.on("query-profile-list-result", event => { clearTimeout(timeout); timeout = undefined; }); } /* profile create */ { const timeouts = {}; event_registry.on("create-profile", event => { clearTimeout(timeouts[event.name]); timeouts[event.name] = setTimeout(() => { event_registry.fire("create-profile-result", { name: event.name, status: "timeout" }); }, 5000); }); event_registry.on("create-profile-result", event => { clearTimeout(timeouts[event.name]); delete timeouts[event.name]; }); } /* profile set default create */ { const timeouts = {}; event_registry.on("set-default-profile", event => { clearTimeout(timeouts[event.profile_id]); timeouts[event.profile_id] = setTimeout(() => { event_registry.fire("set-default-profile-result", { old_profile_id: event.profile_id, status: "timeout" }); }, 5000); }); event_registry.on("set-default-profile-result", event => { clearTimeout(timeouts[event.old_profile_id]); delete timeouts[event.old_profile_id]; }); } const create_standard_timeout = (event, response_event, key) => { const timeouts = {}; event_registry.on(event, event => { clearTimeout(timeouts[event[key]]); timeouts[event[key]] = setTimeout(() => { const timeout_event = { status: "timeout" }; timeout_event[key] = event[key]; event_registry.fire(response_event, timeout_event); }, 5000); }); event_registry.on(response_event, event => { clearTimeout(timeouts[event[key]]); delete timeouts[event[key]]; }); }; create_standard_timeout("query-profile", "query-profile-result", "profile_id"); create_standard_timeout("query-identity-teamspeak", "query-identity-teamspeak-result", "profile_id"); create_standard_timeout("delete-profile", "delete-profile-result", "profile_id"); create_standard_timeout("set-profile-name", "set-profile-name-result", "profile_id"); create_standard_timeout("set-default-name", "set-default-name-result", "profile_id"); create_standard_timeout("query-profile-validity", "query-profile-validity-result", "profile_id"); create_standard_timeout("set-identity-name-name", "set-identity-name-name-result", "profile_id"); create_standard_timeout("generate-identity-teamspeak", "generate-identity-teamspeak-result", "profile_id"); } /* some view semantics */ { let selected_profile; event_registry.on("delete-profile-result", event => { if (event.status !== "success") return; if (event.profile_id !== selected_profile) return; /* the selected profile has been deleted, so we need to select another one */ event_registry.fire("select-profile", { profile_id: "default" }); }); /* reselect the default profile or the new default profile */ event_registry.on("set-default-profile-result", event => { if (event.status !== "success") return; if (selected_profile === "default") event_registry.fire("select-profile", { profile_id: event.new_profile_id }); else if (selected_profile === event.old_profile_id) event_registry.fire("select-profile", { profile_id: "default" }); }); event_registry.on("select-profile", event => { selected_profile = event.profile_id; event_registry.fire("query-profile", { profile_id: event.profile_id }); }); event_registry.on("reload-profile", event => { event_registry.fire("query-profile-list"); event_registry.fire("select-profile", event.profile_id || selected_profile); }); } event_registry.fire("query-profile-list"); event_registry.fire("select-profile", { profile_id: "default" }); event_registry.fire("select-identity-type", { profile_id: "default", identity_type: undefined }); } modal_settings.initialize_identity_profiles_view = initialize_identity_profiles_view; function initialize_audio_microphone_controller(event_registry) { /* level meters */ { const level_meters = {}; const level_info = {}; let level_update_task; const destroy_meters = () => { Object.keys(level_meters).forEach(e => { const meter = level_meters[e]; delete level_meters[e]; meter.then(e => e.destory()); }); Object.keys(level_info).forEach(e => delete level_info[e]); }; const update_level_meter = () => { destroy_meters(); for (const device of audio.recorder.devices()) { let promise = audio.recorder.create_levelmeter(device).then(meter => { meter.set_observer(level => { if (level_meters[device.unique_id] !== promise) return; /* old level meter */ level_info[device.unique_id] = { device_id: device.unique_id, status: "success", level: level }; }); return Promise.resolve(meter); }).catch(error => { if (level_meters[device.unique_id] !== promise) return; /* old level meter */ level_info[device.unique_id] = { device_id: device.unique_id, status: "error", error: error }; log.warn(LogCategory.AUDIO, _translations.lghaKO0H || (_translations.lghaKO0H = tr("Failed to initialize a level meter for device %s (%s): %o")), device.unique_id, device.driver + ":" + device.name, error); return Promise.reject(error); }); level_meters[device.unique_id] = promise; } }; level_update_task = setInterval(() => { event_registry.fire("update-device-level", { devices: Object.keys(level_info).map(e => level_info[e]) }); }, 50); event_registry.on("query-device-result", event => { if (event.status !== "success") return; update_level_meter(); }); event_registry.on("deinitialize", event => { destroy_meters(); clearInterval(level_update_task); }); } /* device list */ { event_registry.on("query-devices", event => { Promise.resolve().then(() => { return audio.recorder.device_refresh_available() && event.refresh_list ? audio.recorder.refresh_devices() : Promise.resolve(); }).catch(error => { log.warn(LogCategory.AUDIO, _translations.JjcOzbzw || (_translations.JjcOzbzw = tr("Failed to refresh device list: %o")), error); return Promise.resolve(); }).then(() => { const devices = audio.recorder.devices(); event_registry.fire_async("query-device-result", { status: "success", active_device: default_recorder.current_device() ? default_recorder.current_device().unique_id : "none", devices: devices.map(e => { return { id: e.unique_id, name: e.name, driver: e.driver }; }) }); }); }); event_registry.on("set-device", event => { const device = audio.recorder.devices().find(e => e.unique_id === event.device_id); if (!device && event.device_id !== "none") { event_registry.fire_async("set-device-result", { status: "error", error: _translations.z4UK75Eu || (_translations.z4UK75Eu = tr("Invalid device id")), device_id: event.device_id }); return; } default_recorder.set_device(device).then(() => { console.debug(_translations.am_OVcEM || (_translations.am_OVcEM = tr("Changed default microphone device"))); event_registry.fire_async("set-device-result", { status: "success", device_id: event.device_id }); }).catch((error) => { log.warn(LogCategory.AUDIO, _translations.pj9HuZR1 || (_translations.pj9HuZR1 = tr("Failed to change microphone to device %s: %o")), device ? device.unique_id : "none", error); event_registry.fire_async("set-device-result", { status: "success", device_id: event.device_id }); }); }); } /* settings */ { event_registry.on("query-settings", event => { event_registry.fire_async("query-settings-result", { status: "success", info: { volume: default_recorder.get_volume(), vad_type: default_recorder.get_vad_type(), vad_ppt: { key: default_recorder.get_vad_ppt_key(), release_delay: Math.abs(default_recorder.get_vad_ppt_delay()), release_delay_active: default_recorder.get_vad_ppt_delay() >= 0 }, vad_threshold: { threshold: default_recorder.get_vad_threshold() } } }); }); event_registry.on("set-setting", event => { const ensure_type = (type) => { if (typeof event.value !== type) { event_registry.fire_async("set-setting-result", { status: "error", error: (_translations.YwWBf7Xh || (_translations.YwWBf7Xh = tr("Invalid value type for key"))) + " (expected: " + type + ", received: " + typeof event.value + ")", setting: event.setting }); return false; } return true; }; switch (event.setting) { case "volume": if (!ensure_type("number")) return; default_recorder.set_volume(event.value); break; case "threshold-threshold": if (!ensure_type("number")) return; default_recorder.set_vad_threshold(event.value); break; case "vad-type": if (!ensure_type("string")) return; if (!default_recorder.set_vad_type(event.value)) { event_registry.fire_async("set-setting-result", { status: "error", error: _translations.rqWJD5R2 || (_translations.rqWJD5R2 = tr("Unknown VAD type")), setting: event.setting }); return; } break; case "ppt-key": if (!ensure_type("object")) return; default_recorder.set_vad_ppt_key(event.value); break; case "ppt-release-delay": if (!ensure_type("number")) return; const sign = default_recorder.get_vad_ppt_delay() >= 0 ? 1 : -1; default_recorder.set_vad_ppt_delay(sign * event.value); break; case "ppt-release-delay-active": if (!ensure_type("boolean")) return; default_recorder.set_vad_ppt_delay(Math.abs(default_recorder.get_vad_ppt_delay()) * (event.value ? 1 : -1)); break; default: event_registry.fire_async("set-setting-result", { status: "error", error: _translations.w8SWxS4C || (_translations.w8SWxS4C = tr("Invalid setting key")), setting: event.setting }); return; } event_registry.fire_async("set-setting-result", { status: "success", setting: event.setting, value: event.value }); }); } audio.player.on_ready(() => event_registry.fire_async("audio-initialized", {})); } modal_settings.initialize_audio_microphone_controller = initialize_audio_microphone_controller; function initialize_audio_microphone_view(container, event_registry) { /* device list */ { /* actual list */ { const container_devices = container.find(".container-devices"); const volume_bar_tags = {}; let pending_changes = 0; let default_device_id; const build_device = (device, selected) => { let tag_volume, tag_volume_error; const tag = $.spawn("div").attr("device-id", device ? device.id : "none").addClass("device").toggleClass("selected", selected).append($.spawn("div").addClass("container-selected").append($.spawn("div").addClass("icon_em client-apply"), $.spawn("div").addClass("icon-loading").append($.spawn("img").attr("src", "img/icon_settings_loading.svg"))), $.spawn("div").addClass("container-name").append($.spawn("div").addClass("device-driver").text(device ? (device.driver || "Unknown driver") : "No device"), $.spawn("div").addClass("device-name").text(device ? (device.name || "Unknown name") : "No device")), $.spawn("div").addClass("container-activity").append($.spawn("div").addClass("container-activity-bar").append(tag_volume = $.spawn("div").addClass("bar-hider"), tag_volume_error = $.spawn("div").addClass("bar-error")))); tag_volume.css('width', '100%'); /* initially hide the bar */ if (device) volume_bar_tags[device.id] = { volume: tag_volume, error: tag_volume_error }; tag.on('click', event => { if (tag.hasClass("selected") || pending_changes > 0) return; event_registry.fire("set-device", { device_id: device ? device.id : "none" }); }); return tag; }; event_registry.on("set-device", event => { pending_changes++; const default_device = container_devices.find(".selected"); default_device_id = default_device.attr("device-id"); default_device.removeClass("selected"); const new_device = container_devices.find(".device[device-id='" + event.device_id + "']"); new_device.addClass("loading"); }); event_registry.on("set-device-result", event => { pending_changes--; container_devices.find(".loading").removeClass("loading"); if (event.status !== "success") { createErrorModal(_translations.S9WvyD7Z || (_translations.S9WvyD7Z = tr("Failed to change microphone")), MessageHelper.formatMessage(_translations.hceWH1fk || (_translations.hceWH1fk = tr("Failed to change the microphone to the target microphone{:br:}{}")), event.status === "timeout" ? _translations.pqrGxJyU || (_translations.pqrGxJyU = tr("Timeout")) : event.error || (_translations.cin0D3wS || (_translations.cin0D3wS = tr("Unknown error"))))).open(); } else { default_device_id = event.device_id; } container_devices.find(".device[device-id='" + default_device_id + "']").addClass("selected"); }); event_registry.on('query-devices', event => { Object.keys(volume_bar_tags).forEach(e => delete volume_bar_tags[e]); container_devices.find(".device").remove(); container_devices.find(".overlay").hide(); container_devices.find(".overlay.overlay-loading").show(); }); event_registry.on("query-device-result", event => { container_devices.find(".device").remove(); container_devices.find(".overlay").hide(); if (event.status !== "success") { const container_text = container_devices.find(".overlay.overlay-error").show().find(".error-text"); container_text.text(event.status === "timeout" ? _translations.ii2WV_Om || (_translations.ii2WV_Om = tr("Timeout while loading")) : event.error || (_translations.zUPIX6BD || (_translations.zUPIX6BD = tr("An unknown error happened")))); return; } build_device(undefined, event.active_device === "none").appendTo(container_devices); for (const device of event.devices) build_device(device, event.active_device === device.id).appendTo(container_devices); }); event_registry.on("update-device-level", event => { for (const device of event.devices) { const tags = volume_bar_tags[device.device_id]; if (!tags) continue; let level = typeof device.level === "number" ? device.level : 100; if (level > 100) level = 100; else if (level < 0) level = 0; tags.error.attr('title', device.error || null).text(device.error || null); tags.volume.css('width', (100 - level) + '%'); } }); } /* device list update button */ { const button_update = container.find(".button-update"); event_registry.on(["query-devices", "set-device"], event => button_update.prop("disabled", true)); event_registry.on(["query-device-result", "set-device-result"], event => button_update.prop("disabled", false)); button_update.on("click", event => event_registry.fire("query-devices", { refresh_list: true })); } } /* settings */ { /* TODO: Query settings error handling */ /* volume */ { const container_volume = container.find(".container-volume"); const slider_tag = container_volume.find(".container-slider"); let triggered_events = 0; let last_value = -1; const slider = sliderfy(slider_tag, { min_value: 0, max_value: 100, step: 1, initial_value: 0 }); slider_tag.on('change', event => { const value = parseInt(slider_tag.attr("value")); if (last_value === value) return; triggered_events++; event_registry.fire("set-setting", { setting: "volume", value: value }); }); event_registry.on("query-settings-result", event => { if (event.status !== "success") return; last_value = event.info.volume; slider.value(event.info.volume); }); event_registry.on("set-setting-result", event => { if (event.setting !== "volume") return; if (triggered_events > 0) { triggered_events--; return; } if (event.status !== "success") return; last_value = event.value; slider.value(event.value); }); } /* vad type */ { const container_select = container.find(".container-select-vad"); let last_value; container_select.find("input").on('change', event => { if (!event.target.checked) return; const mode = event.target.value; if (mode === last_value) return; event_registry.fire("set-setting", { setting: "vad-type", value: mode }); }); const select_vad_type = type => { let elements = container_select.find('input[value="' + type + '"]'); if (elements.length < 1) elements = container_select.find('input[value]'); elements.first().trigger('click'); }; event_registry.on("query-settings-result", event => { if (event.status !== "success") return; last_value = event.info.vad_type; select_vad_type(event.info.vad_type); }); event_registry.on("set-setting-result", event => { if (event.setting !== "vad-type") return; if (event.status !== "success") { createErrorModal(_translations.cIzsOEm1 || (_translations.cIzsOEm1 = tr("Failed to change setting")), MessageHelper.formatMessage(_translations.CPz2Dcn4 || (_translations.CPz2Dcn4 = tr("Failed to change vad type{:br:}{}")), event.status === "timeout" ? _translations.TqXWWyKK || (_translations.TqXWWyKK = tr("Timeout")) : event.error || (_translations.IAvTTiJt || (_translations.IAvTTiJt = tr("Unknown error"))))).open(); } else { last_value = event.value; } select_vad_type(last_value); }); } /* Sensitivity */ { const container_sensitivity = container.find(".container-sensitivity"); const container_bar = container_sensitivity.find(".container-activity-bar"); const bar_hider = container_bar.find(".bar-hider"); let last_value; let triggered_events = 0; let enabled; const slider = sliderfy(container_bar, { min_value: 0, max_value: 100, step: 1, initial_value: 0 }); const set_enabled = value => { if (enabled === value) return; enabled = value; container_sensitivity.toggleClass("disabled", !value); }; container_bar.on('change', event => { const value = parseInt(container_bar.attr("value")); if (last_value === value) return; triggered_events++; event_registry.fire("set-setting", { setting: "threshold-threshold", value: value }); }); event_registry.on("query-settings", event => set_enabled(false)); event_registry.on("query-settings-result", event => { if (event.status !== "success") return; last_value = event.info.vad_threshold.threshold; slider.value(event.info.vad_threshold.threshold); set_enabled(event.info.vad_type === "threshold"); }); event_registry.on("set-setting-result", event => { if (event.setting === "threshold-threshold") { if (event.status !== "success") return; if (triggered_events > 0) { triggered_events--; return; } last_value = event.value; slider.value(event.value); } else if (event.setting === "vad-type") { if (event.status !== "success") return; set_enabled(event.value === "threshold"); } }); let selected_device; event_registry.on("query-device-result", event => { if (event.status !== "success") return; selected_device = event.active_device; }); event_registry.on("set-device-result", event => { if (event.status !== "success") return; selected_device = event.device_id; }); bar_hider.css("width", "100%"); event_registry.on("update-device-level", event => { if (!enabled) return; const data = event.devices.find(e => e.device_id === selected_device); let level = data && typeof data.level === "number" ? data.level : 0; if (level > 100) level = 100; else if (level < 0) level = 0; bar_hider.css("width", (100 - level) + "%"); }); set_enabled(false); } /* ppt settings */ { /* PPT Key */ { const button_key = container.find(".container-ppt button"); event_registry.on("query-settings", event => button_key.prop("disabled", true).text(_translations.NZPKedF2 || (_translations.NZPKedF2 = tr("loading")))); let last_value; event_registry.on("query-settings-result", event => { if (event.status !== "success") return; button_key.prop('disabled', event.info.vad_type !== "push_to_talk"); button_key.text(last_value = ppt.key_description(event.info.vad_ppt.key)); }); event_registry.on("set-setting", event => { if (event.setting !== "ppt-key") return; button_key.prop("enabled", false); button_key.text(_translations.Fj0SrrS2 || (_translations.Fj0SrrS2 = tr("applying"))); }); event_registry.on("set-setting-result", event => { if (event.setting === "vad-type") { if (event.status !== "success") return; button_key.prop('disabled', event.value !== "push_to_talk"); } else if (event.setting === "ppt-key") { if (event.status !== "success") { createErrorModal(_translations.eE42rV0W || (_translations.eE42rV0W = tr("Failed to change PPT key")), MessageHelper.formatMessage(_translations.Y9zzAYFy || (_translations.Y9zzAYFy = tr("Failed to change PPT key:{:br:}{}")), event.status === "timeout" ? _translations.EdjnX01y || (_translations.EdjnX01y = tr("Timeout")) : event.error || (_translations.LJiFWJSt || (_translations.LJiFWJSt = tr("Unknown error"))))).open(); } else { last_value = ppt.key_description(event.value); } button_key.text(last_value); } }); button_key.on('click', event => { Modals.spawnKeySelect(key => { if (!key) return; event_registry.fire("set-setting", { setting: "ppt-key", value: key }); }); }); } /* delay */ { const container_delay = container.find(".container-ppt-delay"); /* toggle button */ { const input_enabled = container_delay.find("input.delay-enabled"); const update_enabled_state = () => { const value = !loading && !applying && ppt_selected; input_enabled.prop("disabled", !value).parent().toggleClass("disabled", !value); }; let last_state; let loading = true, applying = false, ppt_selected = false; event_registry.on("query-settings", event => { loading = true; update_enabled_state(); }); event_registry.on("query-settings-result", event => { if (event.status !== "success") return; loading = false; ppt_selected = event.info.vad_type === "push_to_talk"; update_enabled_state(); input_enabled.prop("checked", last_state = event.info.vad_ppt.release_delay_active); }); event_registry.on("set-setting", event => { if (event.setting !== "ppt-release-delay-active") return; applying = true; update_enabled_state(); }); event_registry.on("set-setting-result", event => { if (event.setting === "vad-type") { if (event.status !== "success") return; ppt_selected = event.value === "push_to_talk"; update_enabled_state(); } else if (event.setting === "ppt-release-delay-active") { applying = false; update_enabled_state(); if (event.status !== "success") { createErrorModal(_translations.jwSWNYxO || (_translations.jwSWNYxO = tr("Failed to change PPT delay state")), MessageHelper.formatMessage(_translations.UOWQDD_7 || (_translations.UOWQDD_7 = tr("Failed to change PPT delay state:{:br:}{}")), event.status === "timeout" ? _translations.izNO4C23 || (_translations.izNO4C23 = tr("Timeout")) : event.error || (_translations.oRJMsyYz || (_translations.oRJMsyYz = tr("Unknown error"))))).open(); } else { last_state = event.value; } input_enabled.prop("checked", last_state); } }); input_enabled.on('change', event => { event_registry.fire("set-setting", { setting: "ppt-release-delay-active", value: input_enabled.prop("checked") }); }); } /* delay input */ { const input_time = container_delay.find("input.delay-time"); const update_enabled_state = () => { const value = !loading && !applying && ppt_selected && delay_active; input_time.prop("disabled", !value).parent().toggleClass("disabled", !value); }; let last_state; let loading = true, applying = false, ppt_selected = false, delay_active = false; event_registry.on("query-settings", event => { loading = true; update_enabled_state(); }); event_registry.on("query-settings-result", event => { if (event.status !== "success") return; loading = false; ppt_selected = event.info.vad_type === "push_to_talk"; delay_active = event.info.vad_ppt.release_delay_active; update_enabled_state(); input_time.val(last_state = event.info.vad_ppt.release_delay); }); event_registry.on("set-setting", event => { if (event.setting !== "ppt-release-delay") return; applying = true; update_enabled_state(); }); event_registry.on("set-setting-result", event => { if (event.setting === "vad-type") { if (event.status !== "success") return; ppt_selected = event.value === "push_to_talk"; update_enabled_state(); } else if (event.setting === "ppt-release-delay-active") { if (event.status !== "success") return; delay_active = event.value; update_enabled_state(); } else if (event.setting === "ppt-release-delay") { applying = false; update_enabled_state(); if (event.status !== "success") { createErrorModal(_translations.FkXnr4XQ || (_translations.FkXnr4XQ = tr("Failed to change PPT delay")), MessageHelper.formatMessage(_translations.G2MNfANr || (_translations.G2MNfANr = tr("Failed to change PPT delay:{:br:}{}")), event.status === "timeout" ? _translations.LUwfp1q6 || (_translations.LUwfp1q6 = tr("Timeout")) : event.error || (_translations.Eckk8zqH || (_translations.Eckk8zqH = tr("Unknown error"))))).open(); } else { last_state = event.value; } input_time.val(last_state); } }); input_time.on('change', event => { event_registry.fire("set-setting", { setting: "ppt-release-delay", value: parseInt(input_time.val()) }); }); } } } } /* timeouts */ { /* device query */ { let timeout; event_registry.on('query-devices', event => { clearTimeout(timeout); timeout = setTimeout(() => { event_registry.fire("query-device-result", { status: "timeout" }); }, 5000); }); event_registry.on("query-device-result", event => clearTimeout(timeout)); } /* device set */ { let timeouts = {}; event_registry.on('set-device', event => { clearTimeout(timeouts[event.device_id]); timeouts[event.device_id] = setTimeout(() => { event_registry.fire("set-device-result", { status: "timeout", device_id: event.device_id }); }, 5000); }); event_registry.on("set-device-result", event => clearTimeout(timeouts[event.device_id])); } /* settings query */ { let timeout; event_registry.on('query-settings', event => { clearTimeout(timeout); timeout = setTimeout(() => { event_registry.fire("query-settings-result", { status: "timeout" }); }, 5000); }); event_registry.on("query-settings-result", event => clearTimeout(timeout)); } /* settings change */ { let timeouts = {}; event_registry.on('set-setting', event => { clearTimeout(timeouts[event.setting]); timeouts[event.setting] = setTimeout(() => { event_registry.fire("set-setting-result", { status: "timeout", setting: event.setting }); }, 5000); }); event_registry.on("set-setting-result", event => clearTimeout(timeouts[event.setting])); } } event_registry.on("audio-initialized", () => { event_registry.fire("query-settings"); event_registry.fire("query-devices", { refresh_list: false }); }); } modal_settings.initialize_audio_microphone_view = initialize_audio_microphone_view; })(modal_settings = Modals.modal_settings || (Modals.modal_settings = {})); function settings_identity_forum(container, modal, update_profiles) { const containers_connected = container.find(".show-connected"); const containers_disconnected = container.find(".show-disconnected"); const update_state = () => { const logged_in = forum.logged_in(); containers_connected.toggle(logged_in); containers_disconnected.toggle(!logged_in); if (logged_in) { container.find(".forum-username").text(forum.data().name()); container.find(".forum-premium").text(forum.data().is_premium() ? _translations.Sz0yBwv1 || (_translations.Sz0yBwv1 = tr("Yes")) : _translations.nM_Detuu || (_translations.nM_Detuu = tr("No"))); } }; /* login */ { const button_login = container.find(".button-login"); const input_username = container.find(".input-username"); const input_password = container.find(".input-password"); const container_error = container.find(".container-login .container-error"); const container_captcha_g = container.find(".g-recaptcha"); let captcha = false; const update_button_state = () => { let enabled = true; enabled = enabled && !!input_password.val(); enabled = enabled && !!input_username.val(); enabled = enabled && (typeof (captcha) === "boolean" ? !captcha : !!captcha); button_login.prop("disabled", !enabled); }; /* username */ input_username.on('change keyup', update_button_state); /* password */ input_password.on('change keyup', update_button_state); button_login.on('click', event => { input_username.prop("disabled", true); input_password.prop("disabled", true); button_login.prop("disabled", true); container_error.removeClass("shown"); forum.login(input_username.val(), input_password.val(), typeof (captcha) === "string" ? captcha : undefined).then(state => { captcha = false; console.debug(_translations.tbSVCOB3 || (_translations.tbSVCOB3 = tr("Forum login result: %o")), state); if (state.status === "success") { update_state(); update_profiles(); return; } setTimeout(() => { if (!!state.error_message) /* clear password if we have an error */ input_password.val(""); input_password.focus(); update_button_state(); }, 0); if (state.status === "captcha") { //TODO Works currently only with localhost! button_login.hide(); container_error.text(state.error_message || (_translations.qJrtnF6R || (_translations.qJrtnF6R = tr("Captcha required")))).addClass("shown"); captcha = ""; console.log(_translations.fMFyBIJx || (_translations.fMFyBIJx = tr("Showing captcha for site-key: %o")), state.captcha.data); forum.gcaptcha.spawn(container_captcha_g, state.captcha.data, token => { captcha = token; console.debug(_translations.m7tGEkDd || (_translations.m7tGEkDd = tr("Got captcha token: %o")), token); container_captcha_g.hide(); button_login.show(); update_button_state(); }).catch(error => { console.error(_translations.HRWXI7ss || (_translations.HRWXI7ss = tr("Failed to initialize forum captcha: %o")), error); container_error.text("Failed to initialize GReCaptcha! No authentication possible.").addClass("shown"); container_captcha_g.hide(); button_login.hide(); }); container_captcha_g.show(); } else { container_error.text(state.error_message || (_translations._DgU0HsU || (_translations._DgU0HsU = tr("Unknown error")))).addClass("shown"); } }).catch(error => { console.error(_translations.r6v8MZ09 || (_translations.r6v8MZ09 = tr("Failed to login within the forum. Error: %o")), error); createErrorModal(_translations.JslYmH78 || (_translations.JslYmH78 = tr("Forum login failed.")), _translations.l0U3SilI || (_translations.l0U3SilI = tr("Forum login failed. Lookup the console for more information"))).open(); }).then(() => { input_username.prop("disabled", false); input_password.prop("disabled", false); update_button_state(); }); }); update_button_state(); } /* logout */ { container.find(".button-logout").on('click', event => { forum.logout().catch(error => { console.error(_translations.SCagvySD || (_translations.SCagvySD = tr("Failed to logout from forum: %o")), error); createErrorModal(_translations.N4jqwUqM || (_translations.N4jqwUqM = tr("Forum logout failed")), MessageHelper.formatMessage(_translations.jeMb4g5m || (_translations.jeMb4g5m = tr("Failed to logout from forum account.{:br:}Error: {}")), error)).open(); }).then(() => { if (modal.shown) update_state(); update_profiles(); }); }); } update_state(); } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["92ac35d52ad1f42fa5193ac1e4f38303a97206528f82d8c2341c7735d2f8759b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["92ac35d52ad1f42fa5193ac1e4f38303a97206528f82d8c2341c7735d2f8759b"] = "92ac35d52ad1f42fa5193ac1e4f38303a97206528f82d8c2341c7735d2f8759b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "jClfZ0h9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (174,21)" }, { name: "dKMx7HBk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (243,21)" }, { name: "TaMwKYk3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (244,23)" }, { name: "jj794ggs", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (249,21)" }, { name: "PCTwVWW5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (250,23)" }, { name: "cJf25JfU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (255,21)" }, { name: "aVE1R8Ij", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (256,23)" }, { name: "FtxS8aPv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (261,21)" }, { name: "_iRssxDc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (262,23)" }, { name: "fZs9KsQ7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (306,43)" }, { name: "K_txnzdc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (316,43)" }, { name: "cqChs9Oa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (333,76)" }, { name: "CsmcENyr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (349,76)" }, { name: "LfL6QN9W", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (364,156)" }, { name: "_9iGfBfM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (392,51)" }, { name: "uxwU2nG6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (395,38)" }, { name: "lpipbMzX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (395,94)" }, { name: "Ma1zisV8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (437,63)" }, { name: "sDgA4pks", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (445,64)" }, { name: "TA3MTtDq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (449,46)" }, { name: "McoQVATK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (451,69)" }, { name: "sRJ6ujQf", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (452,67)" }, { name: "cuxjhYl0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (478,61)" }, { name: "lMroAnEz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (479,59)" }, { name: "TEivpBwN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (480,55)" }, { name: "CfdgV9De", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (481,57)" }, { name: "OZoex2JI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (511,67)" }, { name: "jwxGIkmy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (522,68)" }, { name: "jFQD0Gmp", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (527,46)" }, { name: "ozlD0jd5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (529,69)" }, { name: "vm8uLmSc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (530,71)" }, { name: "hlQqRdbg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (637,55)" }, { name: "l6HhHM6Z", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (639,55)" }, { name: "fjEVRGtV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (643,66)" }, { name: "QdbjApBs", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (644,51)" }, { name: "TFLC6YL4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (724,109)" }, { name: "mHWmn0e_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (726,56)" }, { name: "_P5v1n6D", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (727,66)" }, { name: "E92mYEjR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (781,37)" }, { name: "EEwz6h5e", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (781,68)" }, { name: "LQLYXfno", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (783,51)" }, { name: "bOiC47ix", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (786,38)" }, { name: "EcDuYmlv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (786,94)" }, { name: "u2qYFkJb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (849,37)" }, { name: "aab8fpL2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (849,67)" }, { name: "VRhtN9SF", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (851,51)" }, { name: "zu2R85Jy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (854,38)" }, { name: "iG8KyFbG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (854,91)" }, { name: "mM6I4PAT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (878,75)" }, { name: "KT1iYZJ7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanList.ts (900,79)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /// var Modals; (function (Modals) { function openBanList(client) { let modal; let _callback_bans; let _callback_triggers; const single_ban_handler = { command: "notifybanlist", function: command => { const json = command.arguments; let bans = []; for (const entry of json) { bans.push({ server_id: parseInt(entry["sid"]), banid: parseInt(entry["banid"]), ip: entry["ip"], name: entry["name"], unique_id: entry["uid"], hardware_id: entry["hwid"], timestamp_created: (parseInt(entry["created"]) * 1000), timestamp_expire: (parseInt(entry["duration"]) > 0 ? parseInt(entry["created"]) * 1000 + parseInt(entry["duration"]) * 1000 : 0), invoker_name: entry["invokername"], invoker_database_id: parseInt(entry["invokercldbid"]), invoker_unique_id: entry["invokeruid"], reason: entry["reason"], enforcements: parseInt(entry["enforcements"]), flag_own: entry["invokeruid"] == client.getClient().properties.client_unique_identifier }); } _callback_bans(bans); return false; /* do not remove me */ } }; const single_trigger_handler = { command: "notifybantriggerlist", function: command => { //TODO: Test the server id in the response? const json = command.arguments; let triggers = []; for (const entry of json) { triggers.push({ unique_id: entry["client_unique_identifier"], client_nickname: entry["client_nickname"], hardware_id: entry["client_hardware_identifier"], connection_ip: entry["connection_client_ip"], timestamp: parseInt(entry["timestamp"]) }); } _callback_triggers(triggers); return false; /* do not remove me */ } }; const controller = { request_list(_callback) { _callback_bans = _callback; return new Promise((resolve, reject) => { const timeout = setTimeout(() => { cleanup(); reject("timeout"); }, 2500); const cleanup = () => { clearTimeout(timeout); _callback_bans = undefined; }; Promise.all([ client.serverConnection.send_command("banlist", { sid: 0 }, { process_result: false }).catch(error => { //TODO: May lookup for permissions }), client.serverConnection.send_command("banlist").catch((error) => __awaiter(this, void 0, void 0, function* () { if (error instanceof CommandResult) if (error.id === ErrorID.EMPTY_RESULT) return; throw error; })) ]).then(() => { if (_callback_bans) resolve(); cleanup(); }).catch(error => { if (_callback_bans) reject(error); cleanup(); }); }); }, request_trigger_list(ban, _callback) { _callback_triggers = _callback; return new Promise((resolve, reject) => { const timeout = setTimeout(() => { cleanup(); reject("timeout"); }, 2500); const cleanup = () => { clearTimeout(timeout); _callback_triggers = undefined; }; const data = { banid: ban.ban_id }; if (typeof ban.server_id !== "undefined") data["sid"] = ban.server_id; client.serverConnection.send_command("bantriggerlist", data).catch((error) => __awaiter(this, void 0, void 0, function* () { if (error instanceof CommandResult) if (error.id === ErrorID.EMPTY_RESULT) return; throw error; })).then(() => { if (_callback_triggers) resolve(); cleanup(); }).catch(error => { if (_callback_triggers) reject(error); cleanup(); }); }); }, max_bantime() { return __awaiter(this, void 0, void 0, function* () { const value = client.permissions.neededPermission(PermissionType.I_CLIENT_BAN_MAX_BANTIME).value || 0; return value == -2 ? 0 : value; }); }, permission_add() { return __awaiter(this, void 0, void 0, function* () { return [ client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_CREATE).granted(1), client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_CREATE_GLOBAL).granted(1) ]; }); }, permission_edit() { return __awaiter(this, void 0, void 0, function* () { return [ client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_EDIT).granted(1), client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_EDIT_GLOBAL).granted(1) && false ]; }); }, add_ban(entry) { const data = {}; if (entry.ip) data["ip"] = entry.ip; if (entry.name) data["name"] = entry.name; if (entry.unique_id) data["uid"] = entry.unique_id; if (entry.hardware_id) data["hwid"] = entry.hardware_id; if (entry.reason) data["banreason"] = entry.reason; if (entry.timestamp_expire) data["time"] = Math.floor((entry.timestamp_expire - entry.timestamp_created) / 1000); if (typeof (entry.server_id) === "number") data["sid"] = entry.server_id; return client.serverConnection.send_command("banadd", data).then(e => { if (!e.success) throw e; }); }, edit_ban(data) { return client.serverConnection.send_command("banedit", data).then(e => { if (!e.success) throw e; }); }, delete_ban(entry_id, server_id) { const data = { banid: entry_id }; if (typeof (server_id) === "number") data["sid"] = server_id; return client.serverConnection.send_command("bandel", data).then(e => { if (!e.success) throw e; }); } }; modal = createModal({ header: _translations.jClfZ0h9 || (_translations.jClfZ0h9 = tr("Server Banlist")), body: () => generate_dom(controller), footer: null, width: '60em' }); client.serverConnection.command_handler_boss().register_single_handler(single_ban_handler); client.serverConnection.command_handler_boss().register_single_handler(single_trigger_handler); modal.close_listener.push(() => { client.serverConnection.command_handler_boss().remove_single_handler(single_ban_handler); client.serverConnection.command_handler_boss().remove_single_handler(single_trigger_handler); }); //TODO: Test without dividerfy! modal.htmlTag.dividerfy(); modal.htmlTag.find(".modal-body").addClass("modal-ban-list"); modal.open(); } Modals.openBanList = openBanList; //Note: This object must be sorted (from shortest to longest)! Modals.duration_data = { "sec": { "text": _translations.dKMx7HBk || (_translations.dKMx7HBk = tr("Seconds")), "1-text": _translations.TaMwKYk3 || (_translations.TaMwKYk3 = tr("Second")), scale: 1 }, "min": { "text": _translations.jj794ggs || (_translations.jj794ggs = tr("Minutes")), "1-text": _translations.PCTwVWW5 || (_translations.PCTwVWW5 = tr("Minute")), scale: 60 }, "hours": { "text": _translations.cJf25JfU || (_translations.cJf25JfU = tr("Hours")), "1-text": _translations.aVE1R8Ij || (_translations.aVE1R8Ij = tr("Hour")), scale: 3600 }, "days": { "text": _translations.FtxS8aPv || (_translations.FtxS8aPv = tr("Days")), "1-text": _translations._iRssxDc || (_translations._iRssxDc = tr("Day")), scale: 86400 }, }; function generate_dom(controller) { const template = $("#tmpl_ban_list").renderTag(); let callback_ban_filter = []; let callback_trigger_filter = []; let selected_ban; let update_edit_window; let update_ban_filter; let update_trigger_filter; const container_ban = template.find(".container-banlist"); const container_ban_entries = container_ban.find(".container-list .body"); const container_ban_entries_empty = container_ban.find(".container-list .container-empty"); const container_ban_entries_error = container_ban.find(".container-list .container-error"); const container_trigger = template.find(".container-triggerlist").hide(); const container_trigger_entries = container_trigger.find(".container-list .body"); const container_trigger_entries_empty = container_trigger.find(".container-list .container-empty"); const container_trigger_entries_error = container_trigger.find(".container-list .container-error"); const button_apply = template.find(".button-apply"); let button_apply_state = [false, false]; /* first index is add; second index is edit */ let update_category_inputs = [undefined, undefined]; let button_apply_state_index = 1; const category_add = template.find(".left .head .category-add"); const category_edit = template.find(".left .head .category-edit"); const container_add = template.find(".left .container-add"); const container_add_no_permissions = template.find(".left .container-add .container-no-permissions"); const container_edit = template.find(".left .container-edit"); const seperator_top = template.find(".container-seperator .top"); /* [local; global] */ let permission_edit = [false, false], permission_add = [false, false]; container_add_no_permissions.hide(); controller.permission_add().then(result => permission_add = result).catch(error => { log.error(LogCategory.CLIENT, _translations.fZs9KsQ7 || (_translations.fZs9KsQ7 = tr("Failed to query ban add permissions: %o")), error); }).then(() => { if (permission_add[0] !== permission_add[1]) { const input_global = container_add.find(".group-global input"); input_global.prop("checked", permission_add[1]).prop("disabled", true).firstParent(".checkbox").addClass("disabled"); } else if (!permission_add[0]) container_add_no_permissions.show(); }); controller.permission_edit().then(result => permission_edit = result).catch(error => { log.error(LogCategory.CLIENT, _translations.K_txnzdc || (_translations.K_txnzdc = tr("Failed to query ban edit permissions: %o")), error); }).then(() => { if (selected_ban) update_edit_window(false); }); /* category switch */ { category_add.on('click', event => { container_add.removeClass("hidden"); category_add.addClass("selected"); container_edit.addClass("hidden"); category_edit.removeClass("selected"); seperator_top.css({ opacity: 1 }); button_apply_state_index = 0; button_apply.prop("disabled", !button_apply_state[0]).text(_translations.cqChs9Oa || (_translations.cqChs9Oa = tr("Add ban"))); update_category_inputs[button_apply_state_index](); }); category_edit.on('click', event => { if (!selected_ban) return; container_add.addClass("hidden"); category_add.removeClass("selected"); container_edit.removeClass("hidden"); category_edit.addClass("selected"); seperator_top.css({ opacity: 0 }); button_apply_state_index = 1; button_apply.prop("disabled", !button_apply_state[1]).text(_translations.CsmcENyr || (_translations.CsmcENyr = tr("Save ban"))); update_category_inputs[button_apply_state_index](); }); } const build_ban_entry = (entry, selected) => { let button_delete; const tag = $.spawn("div").addClass("entry" + (entry.server_id > 0 ? "" : " global") + (selected ? " selected" : "")).append($.spawn("div").addClass("column column-key").append(entry.name ? $.spawn("div").append(entry.name) : undefined, entry.ip ? $.spawn("div").append(entry.ip) : undefined, entry.unique_id ? $.spawn("div").append(entry.unique_id) : undefined, entry.hardware_id ? $.spawn("div").append(entry.hardware_id) : undefined), $.spawn("div").addClass("column column-reason").text(entry.reason), $.spawn("div").addClass("column column-expires").text(entry.timestamp_expire ? moment(entry.timestamp_expire).format('DD.MM.YYYY hh:mm') : _translations.LfL6QN9W || (_translations.LfL6QN9W = tr("Never"))), $.spawn("div").addClass("column column-delete").append(button_delete = $.spawn("div").addClass("button-delete").append($.spawn("div").addClass("icon_em client-delete")))); tag.on('click', event => { if (selected_ban === entry || event.isDefaultPrevented()) return; selected_ban = entry; container_ban_entries.find(".entry.selected").removeClass("selected"); tag.addClass("selected"); update_edit_window(true); }); button_delete.on('click', event => { event.preventDefault(); controller.delete_ban(entry.banid, entry.server_id).then(() => { tag.css({ opacity: 1 }).animate({ opacity: 0 }, 250, () => tag.animate({ "max-height": 0 }, 250, () => tag.remove())); if (entry === selected_ban) { selected_ban = undefined; update_edit_window(false); } }).catch(error => { log.error(LogCategory.CLIENT, _translations._9iGfBfM || (_translations._9iGfBfM = tr("Failed to delete ban: %o")), error); if (error instanceof CommandResult) error = error.id === ErrorID.PERMISSION_ERROR ? "no permissions" : error.extra_message || error.message; createErrorModal(_translations.uxwU2nG6 || (_translations.uxwU2nG6 = tr("Failed to delete ban")), MessageHelper.formatMessage(_translations.lpipbMzX || (_translations.lpipbMzX = tr("Failed to delete ban. {:br:}Error: {}")), error)).open(); }); }); if (selected) { selected_ban = entry; update_edit_window(false); } const lower_mesh = (entry.reason || "").toLowerCase() + " " + (entry.unique_id || "").toLowerCase() + " " + (entry.name || "").toLowerCase() + " " + (entry.ip || "").toLowerCase() + " " + (entry.hardware_id || "").toLowerCase(); callback_ban_filter.push((text, flag_own, highlight_own) => { if (text && lower_mesh.indexOf(text) == -1) { tag.hide(); return false; } if (flag_own && !entry.flag_own) { tag.hide(); return false; } tag.show().toggleClass("highlight", highlight_own && entry.flag_own); return true; }); return tag; }; const update_banlist = (selected_ban) => { callback_ban_filter = []; container_ban_entries.find(".entry").remove(); container_ban_entries_error.hide(); container_ban_entries_empty.show().find("a").text(_translations.Ma1zisV8 || (_translations.Ma1zisV8 = tr("Loading..."))); let bans = []; controller.request_list(_bans => bans.push(..._bans)).then(() => { if (bans.length) { container_ban_entries.append(...bans.map(e => build_ban_entry(e, e.banid === selected_ban))); container_ban_entries_empty.hide(); } else { container_ban_entries_empty.find("a").text(_translations.sDgA4pks || (_translations.sDgA4pks = tr("No bans registered"))); } update_ban_filter(); }).catch(error => { log.info(LogCategory.CLIENT, _translations.TA3MTtDq || (_translations.TA3MTtDq = tr("Failed to update ban list: %o")), error); if (error instanceof CommandResult) error = error.id === ErrorID.PERMISSION_ERROR ? _translations.McoQVATK || (_translations.McoQVATK = tr("no permissions")) : error.extra_message || error.message; container_ban_entries_error.show().find("a").text((_translations.sRJ6ujQf || (_translations.sRJ6ujQf = tr("Failed to receive banlist: "))) + error); container_ban_entries_empty.hide(); }); }; const build_trigger_entry = (entry) => { const spawn_key_value = (key, value, reason) => { return $.spawn("div").addClass("property").toggleClass("highlighted", reason).append($.spawn("div").addClass("key").text(key + ": "), $.spawn("div").addClass("value").text(value)); }; let cause_name = !!selected_ban.name && !!entry.client_nickname.match(selected_ban.name); let cause_uid = !cause_name && !!selected_ban.unique_id && selected_ban.unique_id.toLowerCase() === (entry.unique_id || "").toLowerCase(); let cause_ip = !cause_uid && !!selected_ban.ip && selected_ban.ip.toLowerCase() === (entry.connection_ip || "").toLowerCase(); let cause_hwid = !cause_ip && !!selected_ban.hardware_id && selected_ban.hardware_id.toLowerCase() === (entry.hardware_id || "").toLowerCase(); /* we guess that IP is the cause because we dont see the IP and there is no other reason */ if (!cause_name && !cause_uid && !cause_ip && !cause_hwid && entry.connection_ip === "hidden") cause_ip = true; const time_str = moment(entry.timestamp).format('DD.MM.YYYY hh:mm'); const tag = $.spawn("div").addClass("entry").append($.spawn("div").addClass("column column-properties").append(entry.client_nickname ? spawn_key_value(_translations.cuxjhYl0 || (_translations.cuxjhYl0 = tr("Nickname")), entry.client_nickname, cause_name) : undefined, entry.connection_ip ? spawn_key_value(_translations.lMroAnEz || (_translations.lMroAnEz = tr("IP")), entry.connection_ip, cause_ip) : undefined, entry.unique_id ? spawn_key_value(_translations.TEivpBwN || (_translations.TEivpBwN = tr("Unique ID")), entry.unique_id, cause_uid) : undefined, entry.hardware_id ? spawn_key_value(_translations.CfdgV9De || (_translations.CfdgV9De = tr("Hardware ID")), entry.hardware_id, cause_hwid) : undefined), $.spawn("div").addClass("column column-timestamp").text(time_str)); const lower_mesh = (entry.unique_id || "").toLowerCase() + " " + (entry.client_nickname || "").toLowerCase() + " " + (entry.connection_ip || "").toLowerCase() + " " + (entry.hardware_id || "").toLowerCase() + " " + time_str + " " + entry.timestamp; callback_trigger_filter.push(text => { if (text && lower_mesh.indexOf(text) == -1) { tag.hide(); return false; } tag.show(); return true; }); return tag; }; const update_triggerlist = () => { callback_trigger_filter = []; container_trigger_entries.find(".entry").remove(); container_trigger_entries_error.hide(); container_trigger_entries_empty.show().find("a").text(_translations.OZoex2JI || (_translations.OZoex2JI = tr("Loading..."))); let triggers = []; controller.request_trigger_list({ ban_id: selected_ban.banid, server_id: selected_ban.server_id }, _triggers => triggers.push(..._triggers)).then(() => { if (triggers.length) { container_trigger_entries.append(...triggers.sort((a, b) => b.timestamp - a.timestamp).map(e => build_trigger_entry(e))); container_trigger_entries_empty.hide(); } else { container_trigger_entries_empty.find("a").text(_translations.jwxGIkmy || (_translations.jwxGIkmy = tr("No triggers logged"))); } update_trigger_filter(); }).catch(error => { log.info(LogCategory.CLIENT, _translations.jFQD0Gmp || (_translations.jFQD0Gmp = tr("Failed to update trigger list: %o")), error); if (error instanceof CommandResult) error = error.id === ErrorID.PERMISSION_ERROR ? _translations.ozlD0jd5 || (_translations.ozlD0jd5 = tr("no permissions")) : error.extra_message || error.message; container_trigger_entries_error.show().find("a").text((_translations.vm8uLmSc || (_translations.vm8uLmSc = tr("Failed to receive trigger list: "))) + error); container_trigger_entries_empty.hide(); }); }; const show_triggerlist = () => { container_trigger.show(); }; /* general input field rules */ const initialize_fields = (tag, index) => { const input_name = tag.find(".group-name input").on('change keyup', () => update_category_inputs[index]()); const input_ip = tag.find(".group-ip input").on('change keyup', () => update_category_inputs[index]()); const input_uid = tag.find(".group-unique-id input").on('change keyup', () => update_category_inputs[index]()); const input_hwid = tag.find(".group-hwid input").on('change keyup', () => update_category_inputs[index]()); const input_reason = tag.find(".group-reason textarea").on('change keyup', () => update_category_inputs[index]()); //const input_global = tag.find(".group-global input"); const input_duration_value = tag.find(".group-duration input").on('change keyup', () => update_category_inputs[index]()); const input_duration_type = tag.find(".group-duration select").on('change keyup', () => update_category_inputs[index]()); const tooltip_duration_max = tag.find(".tooltip-max-time a.max"); update_category_inputs[index] = () => { let _criteria_set = false; let _input_invalid = false; { //TODO: Check if in regex mode or not const value = input_name.val() || ""; if (value.length > 255) { _input_invalid = true; input_name.firstParent(".input-boxed").addClass("is-invalid"); } else { _criteria_set = _criteria_set || !!value; input_name.firstParent(".input-boxed").removeClass("is-invalid"); } } { //TODO: Check if in regex mode or not const value = input_ip.val() || ""; if (value.length > 255) { _input_invalid = true; input_ip.firstParent(".input-boxed").addClass("is-invalid"); } else { _criteria_set = _criteria_set || !!value; input_ip.firstParent(".input-boxed").removeClass("is-invalid"); } } { const value = input_uid.val() || ""; try { if (value && atob(value).length != 20) throw ""; _criteria_set = _criteria_set || !!value; input_uid.firstParent(".input-boxed").removeClass("is-invalid"); } catch (e) { _input_invalid = true; input_uid.firstParent(".input-boxed").addClass("is-invalid"); } } { const value = input_hwid.val() || ""; if (value.length > 255) { _input_invalid = true; input_hwid.firstParent(".input-boxed").addClass("is-invalid"); } else { _criteria_set = _criteria_set || !!value; input_hwid.firstParent(".input-boxed").removeClass("is-invalid"); } } { const value = input_reason.val() || ""; if (value.length > 512) { _input_invalid = true; input_reason.firstParent(".input-boxed").addClass("is-invalid"); } else { input_reason.firstParent(".input-boxed").removeClass("is-invalid"); } } { const type = input_duration_type.val(); const value = parseInt(input_duration_value.val()); const disabled = input_duration_type.prop("disabled"); input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled); if (type !== "perm") { if (input_duration_value.attr("x-saved-value")) { input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value"))); input_duration_value.attr("x-saved-value", null); } const selected_option = input_duration_type.find("option[value='" + type + "']"); const max = parseInt(selected_option.attr("duration-max")); input_duration_value.attr("max", max); if ((value > max && max != -1) || value < 1) { _input_invalid = true; input_duration_value.firstParent(".input-boxed").addClass("is-invalid"); } else { input_duration_value.firstParent(".input-boxed").removeClass("is-invalid"); } if (max != -1) tooltip_duration_max.html((_translations.hlQqRdbg || (_translations.hlQqRdbg = tr("You're allowed to ban a maximum of "))) + "" + max + " " + Modals.duration_data[type][max == 1 ? "1-text" : "text"] + ""); else tooltip_duration_max.html(_translations.l6HhHM6Z || (_translations.l6HhHM6Z = tr("You're allowed to ban permanent."))); } else { if (value && !Number.isNaN(value)) input_duration_value.attr("x-saved-value", value); input_duration_value.attr("placeholder", _translations.fjEVRGtV || (_translations.fjEVRGtV = tr("for ever"))).val(null); tooltip_duration_max.html(_translations.QdbjApBs || (_translations.QdbjApBs = tr("You're allowed to ban permanent."))); } } button_apply.prop("disabled", !(button_apply_state[button_apply_state_index] = _criteria_set && !_input_invalid)); }; /* initialize ban time */ controller.max_bantime().catch(error => { /* TODO: Error handling? */ return 0; }).then(max_time => { let unlimited = max_time == 0 || max_time == -1; if (unlimited) max_time = 0; for (const value of Object.keys(Modals.duration_data)) { input_duration_type.find("option[value='" + value + "']") .prop("disabled", !unlimited && max_time >= Modals.duration_data[value].scale) .attr("duration-scale", Modals.duration_data[value].scale) .attr("duration-max", unlimited ? -1 : Math.floor(max_time / Modals.duration_data[value].scale)); } input_duration_type.find("option[value='perm']") .prop("disabled", !unlimited) .attr("duration-scale", 0) .attr("duration-max", -1); }); }; initialize_fields(container_add, 0); initialize_fields(container_edit, 1); /* the edit "handler" */ { const tag = container_edit; const input_name = tag.find(".group-name input"); const input_ip = tag.find(".group-ip input"); const input_interpret = tag.find(".group-interpret select"); const input_uid = tag.find(".group-unique-id input"); const input_hwid = tag.find(".group-hwid input"); const input_reason = tag.find(".group-reason textarea"); const input_global = tag.find(".group-global input"); const input_duration_value = tag.find(".group-duration input"); const input_duration_type = tag.find(".group-duration select"); const tooltip_duration_detailed = tag.find(".tooltip-max-time a.detailed"); const label_enforcement_count = tag.find(".group-enforcements .value a"); const button_enforcement_list = tag.find(".button-enforcement-list"); const container_creator = tag.find(".group-creator .value"); update_edit_window = (switch_to) => { category_edit.toggleClass("disabled", !selected_ban); const editable = selected_ban && selected_ban.server_id === 0 ? permission_edit[1] : permission_edit[0]; input_name.val(selected_ban ? selected_ban.name : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_ip.val(selected_ban ? selected_ban.ip : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_uid.val(selected_ban ? selected_ban.unique_id : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_hwid.val(selected_ban ? selected_ban.hardware_id : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_reason.val(selected_ban ? selected_ban.reason : null).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_interpret.find("option").eq(selected_ban && typeof (selected_ban.name_type) === "number" ? selected_ban.name_type : 2).prop("selected", true).prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); label_enforcement_count.text((selected_ban ? selected_ban.enforcements : 0) || 0); button_enforcement_list.prop("disabled", !selected_ban || selected_ban.enforcements == 0); input_global.prop("checked", selected_ban && selected_ban.server_id == 0); input_duration_type.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); input_duration_value.prop("disabled", !editable).firstParent(".input-boxed").toggleClass("disabled", !editable); if (selected_ban) { if (selected_ban.timestamp_expire > selected_ban.timestamp_created) { const duration = Math.ceil((selected_ban.timestamp_expire - selected_ban.timestamp_created) / 1000); const periods = Object.keys(Modals.duration_data); let index; for (index = 0; index < periods.length; index++) { if (Modals.duration_data[periods[index]].scale > duration + 1 || ((duration + 1) % Modals.duration_data[periods[index]].scale) > 1.9) break; } if (index > 0) index--; input_duration_type.find("option[value='" + periods[index] + "']").prop("selected", true); input_duration_value.val(Math.ceil(duration / Modals.duration_data[periods[index]].scale)); tooltip_duration_detailed.text($.spawn("div").append(...MessageHelper.formatMessage(_translations.TFLC6YL4 || (_translations.TFLC6YL4 = tr("The ban lasts for exact {}.")), MessageHelper.format_time(duration * 1000, "never"))).text()); } else { tooltip_duration_detailed.text(_translations.mHWmn0e_ || (_translations.mHWmn0e_ = tr("The ban is forever."))); input_duration_value.attr("placeholder", _translations._P5v1n6D || (_translations._P5v1n6D = tr("for ever"))).val(null).prop('disabled', true); input_duration_type.find("option[value='perm']").prop("selected", true); } } container_creator.empty(); if (selected_ban) { container_creator.append(htmltags.generate_client_object({ client_id: 0, client_unique_id: selected_ban.invoker_unique_id, client_name: selected_ban.invoker_name, add_braces: false })); } if (switch_to) category_edit.trigger('click'); }; button_apply.on('click', event => { if (!button_apply_state[1] || button_apply_state_index != 1) return; const data = { banid: selected_ban.banid }; if (input_ip.val() != selected_ban.ip) data["ip"] = input_ip.val(); if (input_name.val() != selected_ban.name) data["name"] = input_name.val(); if (input_uid.val() != selected_ban.unique_id) data["uid"] = input_uid.val(); if (input_hwid.val() != selected_ban.hardware_id) data["hwid"] = input_hwid.val(); if (input_reason.val() != selected_ban.reason) data["banreason"] = input_reason.val(); if (input_reason.val() != selected_ban.reason) data["reason"] = input_reason.val(); const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val())); if (selected_ban.timestamp_expire > 0 ? (selected_ban.timestamp_expire - selected_ban.timestamp_created != duration) : duration != 0) data["time"] = Math.floor(duration / 1000); controller.edit_ban(data).then(() => { update_banlist(selected_ban ? selected_ban.banid : undefined); selected_ban = undefined; update_edit_window(false); createInfoModal(_translations.E92mYEjR || (_translations.E92mYEjR = tr("Ban successfully edited")), _translations.EEwz6h5e || (_translations.EEwz6h5e = tr("Your ban has been successfully edited."))).open(); }).catch(error => { log.error(LogCategory.CLIENT, _translations.LQLYXfno || (_translations.LQLYXfno = tr("Failed to edited ban: %o")), error); if (error instanceof CommandResult) error = error.id === ErrorID.PERMISSION_ERROR ? "no permissions" : error.extra_message || error.message; createErrorModal(_translations.bOiC47ix || (_translations.bOiC47ix = tr("Failed to edited ban")), MessageHelper.formatMessage(_translations.EcDuYmlv || (_translations.EcDuYmlv = tr("Failed to edited ban. {:br:}Error: {}")), error)).open(); }); }); button_enforcement_list.on('click', () => { update_triggerlist(); show_triggerlist(); }); } /* the create "handler" */ { const tag = container_add; const input_name = tag.find(".group-name input"); const input_ip = tag.find(".group-ip input"); const input_interpret = tag.find(".group-interpret select"); const input_uid = tag.find(".group-unique-id input"); const input_hwid = tag.find(".group-hwid input"); const input_reason = tag.find(".group-reason textarea"); const input_global = tag.find(".group-global input"); const input_duration_value = tag.find(".group-duration input"); const input_duration_type = tag.find(".group-duration select"); button_apply.on('click', event => { if (!button_apply_state[0] || button_apply_state_index != 0) return; const data = { banid: 0, enforcements: 0, }; if (input_global.prop('checked')) data.server_id = 0; if (input_ip.val()) data.ip = input_ip.val(); if (input_name.val()) data.name = input_name.val(); if (input_uid.val()) data.unique_id = input_uid.val(); if (input_hwid.val()) data.hardware_id = input_hwid.val(); if (input_reason.val()) data.reason = input_reason.val(); data.timestamp_created = Date.now(); data.timestamp_expire = input_duration_type.val() === "perm" ? 0 : (data.timestamp_created + 1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val())); //TODO: input_interpret (Currently not supported by TeaSpeak) controller.add_ban(data).then(() => { input_name.val(null); input_ip.val(null); input_uid.val(null); input_hwid.val(null); input_reason.val(null); input_duration_value.val(1); update_banlist(); createInfoModal(_translations.u2qYFkJb || (_translations.u2qYFkJb = tr("Ban successfully added")), _translations.aab8fpL2 || (_translations.aab8fpL2 = tr("Your ban has been successfully added."))).open(); }).catch(error => { log.error(LogCategory.CLIENT, _translations.VRhtN9SF || (_translations.VRhtN9SF = tr("Failed to add ban: %o")), error); if (error instanceof CommandResult) error = error.id === ErrorID.PERMISSION_ERROR ? "no permissions" : error.extra_message || error.message; createErrorModal(_translations.zu2R85Jy || (_translations.zu2R85Jy = tr("Failed to add ban")), MessageHelper.formatMessage(_translations.iG8KyFbG || (_translations.iG8KyFbG = tr("Failed to add ban. {:br:}Error: {}")), error)).open(); }); }); } /* the banlist filter */ { const input_filter = container_ban.find(".container-filter input").on('change keyup', () => update_ban_filter()); const option_show_own = container_ban.find(".option-show-own").on('change keyup', () => update_ban_filter()); const option_hightlight_own = container_ban.find(".option-highlight-own").on('change keyup', () => update_ban_filter()); update_ban_filter = () => { const text = (input_filter.val() || "").toLowerCase(); const flag_show_own = option_show_own.prop('checked'); const flag_hightlight_own = option_hightlight_own.prop('checked'); let count = 0; for (const entry of callback_ban_filter) if (entry(text, flag_show_own, flag_hightlight_own)) count++; if (callback_ban_filter.length != 0) { if (count > 0) container_ban_entries_empty.hide(); else container_ban_entries_empty.show().find("a").text(_translations.mM6I4PAT || (_translations.mM6I4PAT = tr("No bans found"))); } }; } /* the trigger list filter */ { const input_filter = container_trigger.find(".container-filter input").on('change keyup', () => update_trigger_filter()); const option_hightlight_cause = container_trigger.find(".option-highlight-cause").on('change keyup', () => update_trigger_filter()); const button_close = container_trigger.find(".container-close"); update_trigger_filter = () => { const text = (input_filter.val() || "").toLowerCase(); let count = 0; for (const entry of callback_trigger_filter) if (entry(text)) count++; if (callback_trigger_filter.length != 0) { if (count > 0) container_trigger_entries_empty.hide(); else container_trigger_entries_empty.show().find("a").text(_translations.KT1iYZJ7 || (_translations.KT1iYZJ7 = tr("No trigger events found"))); } container_trigger.find(".container-list").toggleClass('highlight', option_hightlight_cause.prop('checked')); }; button_close.on('click', () => container_trigger.hide()); } template.find(".button-refresh-banlist").on('click', event => update_banlist(selected_ban ? selected_ban.banid : undefined)); template.find(".button-refresh-triggerlist").on('click', event => update_triggerlist()); /* initialize */ category_add.trigger('click'); update_edit_window(false); update_banlist(); tooltip(template); return template.children(); } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["a425129a15439d8284d4458d8207b7cfbe3454239f761f5a81b6d3cfdae013e2"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["a425129a15439d8284d4458d8207b7cfbe3454239f761f5a81b6d3cfdae013e2"] = "a425129a15439d8284d4458d8207b7cfbe3454239f761f5a81b6d3cfdae013e2"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Zs_7r6YN", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (250,36)" }, { name: "nAZZvi4s", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (252,36)" }, { name: "XGdxflOT", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (254,36)" }, { name: "OLN_TF22", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (276,36)" }, { name: "WZoW8if5", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (278,36)" }, { name: "pvBk1ajE", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (302,45)" }, { name: "Y2HsuYX1", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (304,45)" }, { name: "n34NFanP", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (330,26)" }, { name: "dbxgzCQU", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (330,50)" }, { name: "Ur57HLbf", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (352,26)" }, { name: "f_X73CLe", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (352,57)" }, { name: "kgkM1V3H", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (477,26)" }, { name: "fwl0c4IH", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (477,43)" }, { name: "gTbMD5iW", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (483,37)" }, { name: "VeWm3kcQ", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (483,54)" }, { name: "K906LIA6", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (486,38)" }, { name: "vh_OTXUb", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (486,83)" }, { name: "cowCUjHx", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (492,26)" }, { name: "OJx9INaZ", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (492,49)" }, { name: "AF4Y3IBj", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (502,34)" }, { name: "vPX9C6Hk", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (502,66)" }, { name: "HHWNZCf4", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (513,30)" }, { name: "c6ki08OD", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (513,66)" }, { name: "UFVzWw9i", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (564,47)" }, { name: "FtoXJtTk", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (569,47)" }, { name: "Sqmplp9n", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (626,30)" }, { name: "e3uQNqK1", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (626,66)" }, { name: "uubmt2N7", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (635,30)" }, { name: "cHeIpZbR", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (635,62)" }, { name: "CunPp0Zv", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (643,30)" }, { name: "vHCggytV", path: "D:/TeaSpeak/web/shared/js/ui/frames/ControlBar.ts (643,62)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /* client_output_hardware Value: '1' client_output_muted Value: '0' client_outputonly_muted Value: '0' client_input_hardware Value: '1' client_input_muted Value: '0' client_away Value: '0' client_away_message Value: '' */ let control_bar; /* global variable to access the control bar */ class ControlBar { constructor(htmlTag) { this.htmlTag = htmlTag; } initialize_connection_handler_state(handler) { /* setup the state like the last displayed one */ handler.client_status.output_muted = this._button_speakers === "muted"; handler.client_status.input_muted = this._button_microphone === "muted"; handler.client_status.channel_subscribe_all = this._button_subscribe_all; handler.client_status.queries_visible = this._button_query_visible; } set_connection_handler(handler) { if (this.connection_handler == handler) return; this.connection_handler = handler; this.apply_server_state(); this.update_connection_state(); } apply_server_state() { if (!this.connection_handler) return; const flag_away = typeof (this.connection_handler.client_status.away) === "string" || this.connection_handler.client_status.away; if (!flag_away) this.button_away_active = "online"; else if (flag_away && this._button_away_active === "online") this.button_away_active = "away"; this.button_query_visible = this.connection_handler.client_status.queries_visible; this.button_subscribe_all = this.connection_handler.client_status.channel_subscribe_all; this.apply_server_hostbutton(); this.apply_server_voice_state(); } apply_server_hostbutton() { const server = this.connection_handler.channelTree.server; if (server && server.properties.virtualserver_hostbutton_gfx_url) { this._button_hostbanner .attr("title", server.properties.virtualserver_hostbutton_tooltip || server.properties.virtualserver_hostbutton_gfx_url) .attr("href", server.properties.virtualserver_hostbutton_url); this._button_hostbanner.find("img").attr("src", server.properties.virtualserver_hostbutton_gfx_url); this._button_hostbanner.each((_, e) => { e.style.display = null; }); } else { this._button_hostbanner.each((_, e) => { e.style.display = "none"; }); } } apply_server_voice_state() { if (!this.connection_handler) return; this.button_microphone = !this.connection_handler.client_status.input_hardware ? "disabled" : this.connection_handler.client_status.input_muted ? "muted" : "enabled"; this.button_speaker = this.connection_handler.client_status.output_muted ? "muted" : "enabled"; top_menu.update_state(); //TODO: Only run "small" update? } current_connection_handler() { return this.connection_handler; } initialise() { let dropdownify = (tag) => { tag.find(".dropdown-arrow").on('click', () => { tag.addClass("displayed"); }).hover(() => { tag.addClass("displayed"); }, () => { if (tag.find(".dropdown:hover").length > 0) return; tag.removeClass("displayed"); }); tag.on('mouseleave', () => { tag.removeClass("displayed"); }); }; this.htmlTag.find(".btn_connect").on('click', this.on_open_connect.bind(this)); this.htmlTag.find(".btn_connect_new_tab").on('click', this.on_open_connect_new_tab.bind(this)); this.htmlTag.find(".btn_disconnect").on('click', this.on_execute_disconnect.bind(this)); this.htmlTag.find(".btn_mute_input").on('click', this.on_toggle_microphone.bind(this)); this.htmlTag.find(".btn_mute_output").on('click', this.on_toggle_sound.bind(this)); this.htmlTag.find(".button-subscribe-mode").on('click', this.on_toggle_channel_subscribe.bind(this)); this.htmlTag.find(".btn_query_toggle").on('click', this.on_toggle_query_view.bind(this)); this.htmlTag.find(".btn_open_settings").on('click', this.on_open_settings.bind(this)); this.htmlTag.find(".btn_permissions").on('click', this.on_open_permissions.bind(this)); this.htmlTag.find(".btn_banlist").on('click', this.on_open_banslist.bind(this)); this.htmlTag.find(".button-playlist-manage").on('click', this.on_open_playlist_manage.bind(this)); this.htmlTag.find(".btn_token_use").on('click', this.on_token_use.bind(this)); this.htmlTag.find(".btn_token_list").on('click', this.on_token_list.bind(this)); (this._button_hostbanner = this.htmlTag.find(".button-hostbutton")).hide().on('click', () => { if (!this.connection_handler) return; const server = this.connection_handler.channelTree.server; if (!server || !server.properties.virtualserver_hostbutton_url) return; window.open(server.properties.virtualserver_hostbutton_url, '_blank'); }); { this.htmlTag.find(".btn_away_disable").on('click', this.on_away_disable.bind(this)); this.htmlTag.find(".btn_away_disable_global").on('click', this.on_away_disable_global.bind(this)); this.htmlTag.find(".btn_away_enable").on('click', this.on_away_enable.bind(this)); this.htmlTag.find(".btn_away_enable_global").on('click', this.on_away_enable_global.bind(this)); this.htmlTag.find(".btn_away_message").on('click', this.on_away_set_message.bind(this)); this.htmlTag.find(".btn_away_message_global").on('click', this.on_away_set_message_global.bind(this)); this.htmlTag.find(".btn_away_toggle").on('click', this.on_away_toggle.bind(this)); } dropdownify(this.htmlTag.find(".container-connect")); dropdownify(this.htmlTag.find(".container-disconnect")); dropdownify(this.htmlTag.find(".btn_token")); dropdownify(this.htmlTag.find(".btn_away")); dropdownify(this.htmlTag.find(".btn_bookmark")); dropdownify(this.htmlTag.find(".btn_query")); dropdownify(this.htmlTag.find(".dropdown-audio")); dropdownify(this.htmlTag.find(".dropdown-servertools")); { } { this.htmlTag.find(".btn_bookmark_list").on('click', this.on_bookmark_manage.bind(this)); this.htmlTag.find(".btn_bookmark_add").on('click', this.on_bookmark_server_add.bind(this)); } { /* search for query buttons not only on the large device button */ this.htmlTag.find(".btn_query_create").on('click', this.on_open_query_create.bind(this)); this.htmlTag.find(".btn_query_manage").on('click', this.on_open_query_manage.bind(this)); } this.update_bookmarks(); this.update_bookmark_status(); //Need an initialise this.button_speaker = settings.static_global(Settings.KEY_CONTROL_MUTE_OUTPUT, false) ? "muted" : "enabled"; this.button_microphone = settings.static_global(Settings.KEY_CONTROL_MUTE_INPUT, false) ? "muted" : "enabled"; this.button_subscribe_all = true; this.button_query_visible = false; } /* Update the UI */ set button_away_active(flag) { if (this._button_away_active === flag) return; this._button_away_active = flag; this.update_button_away(); } update_button_away() { const button_away_enable = this.htmlTag.find(".btn_away_enable"); const button_away_disable = this.htmlTag.find(".btn_away_disable"); const button_away_toggle = this.htmlTag.find(".btn_away_toggle"); const button_away_disable_global = this.htmlTag.find(".btn_away_disable_global"); const button_away_enable_global = this.htmlTag.find(".btn_away_enable_global"); const button_away_message_global = this.htmlTag.find(".btn_away_message_global"); button_away_toggle.toggleClass("activated", this._button_away_active !== "online"); button_away_enable.toggle(this._button_away_active === "online"); button_away_disable.toggle(this._button_away_active !== "online"); const connections = server_connections.server_connection_handlers(); if (connections.length <= 1) { button_away_disable_global.hide(); button_away_enable_global.hide(); button_away_message_global.hide(); } else { button_away_message_global.show(); button_away_enable_global.toggle(server_connections.server_connection_handlers().filter(e => !e.client_status.away).length > 0); button_away_disable_global.toggle(this._button_away_active === "away-global" || server_connections.server_connection_handlers().filter(e => typeof (e.client_status.away) === "string" || e.client_status.away).length > 0); } } set button_microphone(state) { if (this._button_microphone === state) return; this._button_microphone = state; let tag = this.htmlTag.find(".btn_mute_input"); const tag_icon = tag.find(".icon_em, .icon"); tag.toggleClass('activated', state === "muted"); /* tag_icon .toggleClass('client-input_muted', state === "muted") .toggleClass('client-capture', state === "enabled") .toggleClass('client-activate_microphone', state === "disabled"); */ tag_icon .toggleClass('client-input_muted', state !== "disabled") .toggleClass('client-capture', false) .toggleClass('client-activate_microphone', state === "disabled"); if (state === "disabled") tag_icon.attr('title', _translations.Zs_7r6YN || (_translations.Zs_7r6YN = tr("Enable your microphone on this server"))); else if (state === "enabled") tag_icon.attr('title', _translations.nAZZvi4s || (_translations.nAZZvi4s = tr("Mute microphone"))); else tag_icon.attr('title', _translations.XGdxflOT || (_translations.XGdxflOT = tr("Unmute microphone"))); } set button_speaker(state) { if (this._button_speakers === state) return; this._button_speakers = state; let tag = this.htmlTag.find(".btn_mute_output"); const tag_icon = tag.find(".icon_em, .icon"); tag.toggleClass('activated', state === "muted"); /* tag_icon .toggleClass('client-output_muted', state !== "enabled") .toggleClass('client-volume', state === "enabled"); */ tag_icon .toggleClass('client-output_muted', true) .toggleClass('client-volume', false); if (state === "enabled") tag_icon.attr('title', _translations.OLN_TF22 || (_translations.OLN_TF22 = tr("Mute sound"))); else tag_icon.attr('title', _translations.WZoW8if5 || (_translations.WZoW8if5 = tr("Unmute sound"))); } set button_subscribe_all(state) { if (this._button_subscribe_all === state) return; this._button_subscribe_all = state; this.htmlTag .find(".button-subscribe-mode") .toggleClass('activated', this._button_subscribe_all) .find('.icon_em') .toggleClass('client-unsubscribe_from_all_channels', !this._button_subscribe_all) .toggleClass('client-subscribe_to_all_channels', this._button_subscribe_all); } set button_query_visible(state) { if (this._button_query_visible === state) return; this._button_query_visible = state; const button = this.htmlTag.find(".btn_query_toggle"); button.toggleClass('activated', this._button_query_visible); if (this._button_query_visible) button.find(".query-text").text(_translations.pvBk1ajE || (_translations.pvBk1ajE = tr("Hide server queries"))); else button.find(".query-text").text(_translations.Y2HsuYX1 || (_translations.Y2HsuYX1 = tr("Show server queries"))); } /* UI listener */ on_away_toggle() { if (this._button_away_active === "away" || this._button_away_active === "away-global") this.button_away_active = "online"; else this.button_away_active = "away"; if (this.connection_handler) this.connection_handler.set_away_status(this._button_away_active !== "online"); } on_away_enable() { this.button_away_active = "away"; if (this.connection_handler) this.connection_handler.set_away_status(true); } on_away_disable() { this.button_away_active = "online"; if (this.connection_handler) this.connection_handler.set_away_status(false); } on_away_set_message() { createInputModal(_translations.n34NFanP || (_translations.n34NFanP = tr("Set away message")), _translations.dbxgzCQU || (_translations.dbxgzCQU = tr("Please enter your away message")), message => true, message => { if (typeof (message) === "string") { this.button_away_active = "away"; if (this.connection_handler) this.connection_handler.set_away_status(message); } }).open(); } on_away_enable_global() { this.button_away_active = "away-global"; for (const connection of server_connections.server_connection_handlers()) connection.set_away_status(true); } on_away_disable_global() { this.button_away_active = "online"; for (const connection of server_connections.server_connection_handlers()) connection.set_away_status(false); } on_away_set_message_global() { createInputModal(_translations.Ur57HLbf || (_translations.Ur57HLbf = tr("Set global away message")), _translations.f_X73CLe || (_translations.f_X73CLe = tr("Please enter your global away message")), message => true, message => { if (typeof (message) === "string") { this.button_away_active = "away"; for (const connection of server_connections.server_connection_handlers()) connection.set_away_status(message); } }).open(); } on_toggle_microphone() { if (this._button_microphone === "disabled" || this._button_microphone === "muted") { this.button_microphone = "enabled"; sound.manager.play(Sound.MICROPHONE_ACTIVATED); } else { this.button_microphone = "muted"; sound.manager.play(Sound.MICROPHONE_MUTED); } if (this.connection_handler) { this.connection_handler.client_status.input_muted = this._button_microphone !== "enabled"; if (!this.connection_handler.client_status.input_hardware) this.connection_handler.acquire_recorder(default_recorder, true); /* acquire_recorder already updates the voice status */ else this.connection_handler.update_voice_status(undefined); /* just update the last changed value */ settings.changeGlobal(Settings.KEY_CONTROL_MUTE_INPUT, this.connection_handler.client_status.input_muted); } } on_toggle_sound() { if (this._button_speakers === "muted") { this.button_speaker = "enabled"; sound.manager.play(Sound.SOUND_ACTIVATED); } else { this.button_speaker = "muted"; sound.manager.play(Sound.SOUND_MUTED); } if (this.connection_handler) { this.connection_handler.client_status.output_muted = this._button_speakers !== "enabled"; this.connection_handler.update_voice_status(undefined); /* just update the last changed value */ settings.changeGlobal(Settings.KEY_CONTROL_MUTE_OUTPUT, this.connection_handler.client_status.output_muted); } } on_toggle_channel_subscribe() { this.button_subscribe_all = !this._button_subscribe_all; if (this.connection_handler) { this.connection_handler.client_status.channel_subscribe_all = this._button_subscribe_all; if (this._button_subscribe_all) this.connection_handler.channelTree.subscribe_all_channels(); else this.connection_handler.channelTree.unsubscribe_all_channels(true); this.connection_handler.settings.changeServer(Settings.KEY_CONTROL_CHANNEL_SUBSCRIBE_ALL, this._button_subscribe_all); } } on_toggle_query_view() { this.button_query_visible = !this._button_query_visible; if (this.connection_handler) { this.connection_handler.client_status.queries_visible = this._button_query_visible; this.connection_handler.channelTree.toggle_server_queries(this._button_query_visible); this.connection_handler.settings.changeServer(Settings.KEY_CONTROL_SHOW_QUERIES, this._button_subscribe_all); } } on_open_settings() { Modals.spawnSettingsModal(); } on_open_connect() { if (this.connection_handler) this.connection_handler.cancel_reconnect(true); Modals.spawnConnectModal({}, { url: "ts.TeaSpeak.de", enforce: false }); } on_open_connect_new_tab() { Modals.spawnConnectModal({ default_connect_new_tab: true }, { url: "ts.TeaSpeak.de", enforce: false }); } update_connection_state() { if (this.connection_handler.serverConnection && this.connection_handler.serverConnection.connected()) { this.htmlTag.find(".container-disconnect").show(); this.htmlTag.find(".container-connect").hide(); } else { this.htmlTag.find(".container-disconnect").hide(); this.htmlTag.find(".container-connect").show(); } /* switch (this.connection_handler.serverConnection ? this.connection_handler.serverConnection.connected() : ConnectionState.UNCONNECTED) { case ConnectionState.CONNECTED: case ConnectionState.CONNECTING: case ConnectionState.INITIALISING: this.htmlTag.find(".container-disconnect").show(); this.htmlTag.find(".container-connect").hide(); break; default: this.htmlTag.find(".container-disconnect").hide(); this.htmlTag.find(".container-connect").show(); } */ } on_execute_disconnect() { this.connection_handler.cancel_reconnect(true); this.connection_handler.handleDisconnect(DisconnectReason.REQUESTED); //TODO message? this.update_connection_state(); this.connection_handler.sound.play(Sound.CONNECTION_DISCONNECTED); this.connection_handler.log.log(log.server.Type.DISCONNECTED, {}); } on_token_use() { createInputModal(_translations.kgkM1V3H || (_translations.kgkM1V3H = tr("Use token")), _translations.fwl0c4IH || (_translations.fwl0c4IH = tr("Please enter your token/privilege key")), message => message.length > 0, result => { if (!result) return; if (this.connection_handler.serverConnection.connected) this.connection_handler.serverConnection.send_command("tokenuse", { token: result }).then(() => { createInfoModal(_translations.gTbMD5iW || (_translations.gTbMD5iW = tr("Use token")), _translations.VeWm3kcQ || (_translations.VeWm3kcQ = tr("Toke successfully used!"))).open(); }).catch(error => { //TODO tr createErrorModal(_translations.K906LIA6 || (_translations.K906LIA6 = tr("Use token")), MessageHelper.formatMessage(_translations.vh_OTXUb || (_translations.vh_OTXUb = tr("Failed to use token: {}")), error instanceof CommandResult ? error.message : error)).open(); }); }).open(); } on_token_list() { createErrorModal(_translations.cowCUjHx || (_translations.cowCUjHx = tr("Not implemented")), _translations.OJx9INaZ || (_translations.OJx9INaZ = tr("Token list is not implemented yet!"))).open(); } on_open_permissions() { let button = this.htmlTag.find(".btn_permissions"); button.addClass("activated"); setTimeout(() => { if (this.connection_handler) Modals.spawnPermissionEdit(this.connection_handler).open(); else createErrorModal(_translations.AF4Y3IBj || (_translations.AF4Y3IBj = tr("You have to be connected")), _translations.vPX9C6Hk || (_translations.vPX9C6Hk = tr("You have to be connected!"))).open(); button.removeClass("activated"); }, 0); } on_open_banslist() { if (!this.connection_handler.serverConnection) return; if (this.connection_handler.permissions.neededPermission(PermissionType.B_CLIENT_BAN_LIST).granted(1)) { Modals.openBanList(this.connection_handler); } else { createErrorModal(_translations.HHWNZCf4 || (_translations.HHWNZCf4 = tr("You dont have the permission")), _translations.c6ki08OD || (_translations.c6ki08OD = tr("You dont have the permission to view the ban list"))).open(); this.connection_handler.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } } on_bookmark_server_add() { bookmarks.add_current_server(); } update_bookmark_status() { this.htmlTag.find(".btn_bookmark_add").removeClass("hidden").addClass("disabled"); this.htmlTag.find(".btn_bookmark_remove").addClass("hidden"); } update_bookmarks() { // let tag_bookmark = this.htmlTag.find(".btn_bookmark > .dropdown"); tag_bookmark.find(".bookmark, .directory").remove(); const build_entry = (bookmark) => { if (bookmark.type == bookmarks.BookmarkType.ENTRY) { const mark = bookmark; const bookmark_connect = (new_tab) => { this.htmlTag.find(".btn_bookmark").find(".dropdown").removeClass("displayed"); //FIXME Not working bookmarks.boorkmak_connect(mark, new_tab); }; return $.spawn("div") .addClass("bookmark") .append( //$.spawn("div").addClass("icon client-server") IconManager.generate_tag(IconManager.load_cached_icon(mark.last_icon_id || 0), { animate: false }) /* must be false */) .append($.spawn("div") .addClass("name") .text(bookmark.display_name) .on('click', event => { if (event.isDefaultPrevented()) return; bookmark_connect(false); }) .on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.UFVzWw9i || (_translations.UFVzWw9i = tr("Connect")), icon_class: 'client-connect', callback: () => bookmark_connect(false) }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.FtoXJtTk || (_translations.FtoXJtTk = tr("Connect in a new tab")), icon_class: 'client-connect', callback: () => bookmark_connect(true), visible: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION) }, contextmenu.Entry.CLOSE(() => { setTimeout(() => { this.htmlTag.find(".btn_bookmark.dropdown-arrow").removeClass("force-show"); }, 250); })); this.htmlTag.find(".btn_bookmark.dropdown-arrow").addClass("force-show"); })); } else { const mark = bookmark; const container = $.spawn("div").addClass("sub-menu dropdown"); const result = $.spawn("div") .addClass("directory") .append($.spawn("div").addClass("icon client-folder")) .append($.spawn("div") .addClass("name") .text(bookmark.display_name)) .append($.spawn("div").addClass("arrow right")) .append($.spawn("div").addClass("sub-container") .append(container)); /* we've to keep it this order because we're then keeping the reference of the loading icons... */ for (const member of mark.content) container.append(build_entry(member)); return result; } }; for (const bookmark of bookmarks.bookmarks().content) { const entry = build_entry(bookmark); tag_bookmark.append(entry); } } on_bookmark_manage() { Modals.spawnBookmarkModal(); } on_open_query_create() { if (this.connection_handler.permissions.neededPermission(PermissionType.B_CLIENT_CREATE_MODIFY_SERVERQUERY_LOGIN).granted(1)) { Modals.spawnQueryCreate(this.connection_handler); } else { createErrorModal(_translations.Sqmplp9n || (_translations.Sqmplp9n = tr("You dont have the permission")), _translations.e3uQNqK1 || (_translations.e3uQNqK1 = tr("You dont have the permission to create a server query login"))).open(); this.connection_handler.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } } on_open_query_manage() { if (this.connection_handler && this.connection_handler.connected) { Modals.spawnQueryManage(this.connection_handler); } else { createErrorModal(_translations.uubmt2N7 || (_translations.uubmt2N7 = tr("You have to be connected")), _translations.cHeIpZbR || (_translations.cHeIpZbR = tr("You have to be connected!"))).open(); } } on_open_playlist_manage() { if (this.connection_handler && this.connection_handler.connected) { Modals.spawnPlaylistManage(this.connection_handler); } else { createErrorModal(_translations.CunPp0Zv || (_translations.CunPp0Zv = tr("You have to be connected")), _translations.vHCggytV || (_translations.vHCggytV = tr("You have to be connected to use this function!"))).open(); } } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["197b7bafaa38d18270b5766fa93a5f6ad2093450fd9dc6608670cc211a33712d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["197b7bafaa38d18270b5766fa93a5f6ad2093450fd9dc6608670cc211a33712d"] = "197b7bafaa38d18270b5766fa93a5f6ad2093450fd9dc6608670cc211a33712d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "ZUXymrm7", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (161,31)" }, { name: "T1UFxXzN", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (173,27)" }, { name: "HS4rmli5", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (194,38)" }, { name: "kOLFxw_8", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (212,47)" }, { name: "zi0vuWHk", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (213,34)" }, { name: "slvMdYzx", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (213,70)" }, { name: "n8ME6kUb", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (280,38)" }, { name: "YBuSiAT5", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (354,39)" }, { name: "MQsgbKfE", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (377,51)" }, { name: "hTv3H6ip", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (394,51)" }, { name: "Wcp4Jl2M", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (412,27)" }, { name: "RjYBRqhz", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (425,47)" }, { name: "TTZmhO6X", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (438,51)" }, { name: "UvN4ZYoz", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (440,51)" }, { name: "yKOp1KDQ", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (444,25)" }, { name: "BAtStX1r", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (445,25)" }, { name: "EaTMLkfC", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (454,25)" }, { name: "YWdTGt0C", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (464,47)" }, { name: "os_PbxTh", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (466,21)" }, { name: "mWEfrIGh", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (467,21)" }, { name: "sKz9M0J1", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (472,21)" }, { name: "QmW2FhnQ", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (473,49)" }, { name: "c82V0qqg", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (480,21)" }, { name: "vIrDdie6", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (481,49)" }, { name: "DPauFd4a", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (488,47)" }, { name: "tPvfpJri", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (491,25)" }, { name: "yAUGk0u6", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (492,25)" }, { name: "XM3HFZtb", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (500,47)" }, { name: "SPp3hxky", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (503,21)" }, { name: "Ez6pR12l", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (504,21)" }, { name: "oeX7ep3Y", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (512,21)" }, { name: "qlxKgog8", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (523,34)" }, { name: "QTjxbWyV", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (523,57)" }, { name: "GL3SU8Zv", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (542,21)" }, { name: "L6t34lZs", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (544,40)" }, { name: "zo49e7He", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (544,100)" }, { name: "eTgdGWXl", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (575,47)" }, { name: "m_2kmrli", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (576,47)" }, { name: "gthobtoh", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (592,50)" }, { name: "OfYIEKF3", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (597,46)" }, { name: "mgD_hUkm", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (604,50)" }, { name: "E6Pxj7O_", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (667,51)" }, { name: "myFdKome", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (668,74)" }, { name: "yhxSmGy4", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (690,31)" }, { name: "FhG1RYUu", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (692,31)" }, { name: "tl9gg03_", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (694,31)" }, { name: "H8fSS_0Z", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (696,38)" }, { name: "IU0hK4NF", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (716,57)" }, { name: "Ak0MoTq5", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (719,50)" }, { name: "CdNixUn2", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (719,111)" }, { name: "ifNLFsmx", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (743,47)" }, { name: "ZAcARduu", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (744,70)" }, { name: "j356bpkL", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (763,43)" }, { name: "Hquv820o", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (764,66)" }, { name: "Nhi8Zrg7", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (778,41)" }, { name: "kwfqGPH6", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (805,46)" }, { name: "N3fwN_XS", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (811,37)" }, { name: "dWko40aF", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (811,59)" }, { name: "_o7eTDux", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (813,52)" }, { name: "q6MV9BJ6", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (817,63)" }, { name: "l2z4u5iq", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (819,63)" }, { name: "SERPbLsV", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (820,38)" }, { name: "Uwwz13se", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (824,46)" }, { name: "p6ktJjDH", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (837,56)" }, { name: "DpzOU8kx", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (843,71)" }, { name: "GSHnaSaC", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (845,71)" }, { name: "HuAordM2", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (849,67)" }, { name: "SqHGgSbh", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (850,42)" }, { name: "cCwgYPgQ", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (857,56)" }, { name: "Jkzl_W58", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (861,67)" }, { name: "HfLNjuHd", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (864,67)" }, { name: "b_WF3dmV", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (865,42)" }, { name: "PkrE3ZLe", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (873,56)" }, { name: "Yw4Xjm9C", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (877,67)" }, { name: "ZNppOyOZ", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (879,67)" }, { name: "n1Io657i", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (880,42)" }, { name: "dVyA2a02", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (884,37)" }, { name: "Wrvy2Obl", path: "D:/TeaSpeak/web/shared/js/ConnectionHandler.ts (884,73)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /// /// /// /// /// /// var DisconnectReason; (function (DisconnectReason) { DisconnectReason[DisconnectReason["HANDLER_DESTROYED"] = 0] = "HANDLER_DESTROYED"; DisconnectReason[DisconnectReason["REQUESTED"] = 1] = "REQUESTED"; DisconnectReason[DisconnectReason["DNS_FAILED"] = 2] = "DNS_FAILED"; DisconnectReason[DisconnectReason["CONNECT_FAILURE"] = 3] = "CONNECT_FAILURE"; DisconnectReason[DisconnectReason["CONNECTION_CLOSED"] = 4] = "CONNECTION_CLOSED"; DisconnectReason[DisconnectReason["CONNECTION_FATAL_ERROR"] = 5] = "CONNECTION_FATAL_ERROR"; DisconnectReason[DisconnectReason["CONNECTION_PING_TIMEOUT"] = 6] = "CONNECTION_PING_TIMEOUT"; DisconnectReason[DisconnectReason["CLIENT_KICKED"] = 7] = "CLIENT_KICKED"; DisconnectReason[DisconnectReason["CLIENT_BANNED"] = 8] = "CLIENT_BANNED"; DisconnectReason[DisconnectReason["HANDSHAKE_FAILED"] = 9] = "HANDSHAKE_FAILED"; DisconnectReason[DisconnectReason["HANDSHAKE_TEAMSPEAK_REQUIRED"] = 10] = "HANDSHAKE_TEAMSPEAK_REQUIRED"; DisconnectReason[DisconnectReason["HANDSHAKE_BANNED"] = 11] = "HANDSHAKE_BANNED"; DisconnectReason[DisconnectReason["SERVER_CLOSED"] = 12] = "SERVER_CLOSED"; DisconnectReason[DisconnectReason["SERVER_REQUIRES_PASSWORD"] = 13] = "SERVER_REQUIRES_PASSWORD"; DisconnectReason[DisconnectReason["SERVER_HOSTMESSAGE"] = 14] = "SERVER_HOSTMESSAGE"; DisconnectReason[DisconnectReason["IDENTITY_TOO_LOW"] = 15] = "IDENTITY_TOO_LOW"; DisconnectReason[DisconnectReason["UNKNOWN"] = 16] = "UNKNOWN"; })(DisconnectReason || (DisconnectReason = {})); var ConnectionState; (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 = {})); var ViewReasonId; (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 ConnectionHandler { constructor() { this._clientId = 0; this._reconnect_attempt = false; this._connect_initialize_id = 1; this.client_status = { input_hardware: false, input_muted: false, output_muted: false, away: false, channel_subscribe_all: true, queries_visible: false, sound_playback_supported: undefined, sound_record_supported: undefined, channel_codec_encoding_supported: undefined, channel_codec_decoding_supported: undefined }; this.invoke_resized_on_activate = false; this.settings = new ServerSettings(); this.log = new log.ServerLog(this); this.channelTree = new ChannelTree(this); this.side_bar = new chat.Frame(this); this.sound = new sound.SoundManager(this); this.hostbanner = new Hostbanner(this); this.serverConnection = connection.spawn_server_connection(this); this.serverConnection.onconnectionstatechanged = this.on_connection_state_changed.bind(this); this.fileManager = new FileManager(this); this.permissions = new PermissionManager(this); this.side_bar.channel_conversations().initialize_needed_listener(); this.groups = new GroupManager(this); this._local_client = new LocalClientEntry(this); /* initialize connection handler tab entry */ { this.tag_connection_handler = $.spawn("div").addClass("connection-container"); $.spawn("div").addClass("server-icon icon client-server_green").appendTo(this.tag_connection_handler); $.spawn("div").addClass("server-name").appendTo(this.tag_connection_handler); $.spawn("div").addClass("button-close icon client-tab_close_button").appendTo(this.tag_connection_handler); this.tag_connection_handler.on('click', event => { if (event.isDefaultPrevented()) return; server_connections.set_active_connection_handler(this); }); this.tag_connection_handler.find(".button-close").on('click', event => { server_connections.destroy_server_connection_handler(this); event.preventDefault(); }); this.tab_set_name(_translations.ZUXymrm7 || (_translations.ZUXymrm7 = tr("Not connected"))); } } tab_set_name(name) { this.tag_connection_handler.toggleClass('cutoff-name', name.length > 30); this.tag_connection_handler.find(".server-name").text(name); } setup() { } startConnection(addr, profile, user_action, parameters) { return __awaiter(this, void 0, void 0, function* () { this.tab_set_name(_translations.T1UFxXzN || (_translations.T1UFxXzN = tr("Connecting"))); this.cancel_reconnect(false); this._reconnect_attempt = parameters.auto_reconnect_attempt || false; if (this.serverConnection) this.handleDisconnect(DisconnectReason.REQUESTED); let server_address = { host: "", port: -1 }; { let _v6_end = addr.indexOf(']'); let idx = addr.lastIndexOf(':'); if (idx != -1 && idx > _v6_end) { server_address.port = parseInt(addr.substr(idx + 1)); server_address.host = addr.substr(0, idx); } else { server_address.host = addr; server_address.port = 9987; } } log.info(LogCategory.CLIENT, _translations.HS4rmli5 || (_translations.HS4rmli5 = tr("Start connection to %s:%d")), server_address.host, server_address.port); this.log.log(log.server.Type.CONNECTION_BEGIN, { address: { server_hostname: server_address.host, server_port: server_address.port }, client_nickname: parameters.nickname }); this.channelTree.initialiseHead(addr, server_address); if (parameters.password && !parameters.password.hashed) { try { const password = yield helpers.hashPassword(parameters.password.password); parameters.password = { hashed: true, password: password }; } catch (error) { log.error(LogCategory.CLIENT, _translations.kOLFxw_8 || (_translations.kOLFxw_8 = tr("Failed to hash connect password: %o")), error); createErrorModal(_translations.zi0vuWHk || (_translations.zi0vuWHk = tr("Error while hashing password")), (_translations.slvMdYzx || (_translations.slvMdYzx = tr("Failed to hash server password!
"))) + error).open(); } } if (parameters.password) { connection_log.update_address_password({ hostname: server_address.host, port: server_address.port }, parameters.password.password); } const original_address = { host: server_address.host, port: server_address.port }; if (dns.supported() && !server_address.host.match(Modals.Regex.IP_V4) && !server_address.host.match(Modals.Regex.IP_V6)) { const id = ++this._connect_initialize_id; this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVE, {}); try { const resolved = (yield dns.resolve_address(server_address, { timeout: 5000 })) || {}; if (id != this._connect_initialize_id) return; /* we're old */ server_address.host = typeof (resolved.target_ip) === "string" ? resolved.target_ip : server_address.host; server_address.port = typeof (resolved.target_port) === "number" ? resolved.target_port : server_address.port; this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVED, { address: { server_port: server_address.port, server_hostname: server_address.host } }); } catch (error) { if (id != this._connect_initialize_id) return; /* we're old */ this.handleDisconnect(DisconnectReason.DNS_FAILED, error); } } yield this.serverConnection.connect(server_address, new connection.HandshakeHandler(profile, parameters)); setTimeout(() => { const connected = this.serverConnection.connected(); if (user_action && connected) { connection_log.log_connect({ hostname: original_address.host, port: original_address.port }); } }, 50); }); } getClient() { return this._local_client; } getClientId() { return this._clientId; } set clientId(id) { this._clientId = id; this._local_client["_clientId"] = id; } get clientId() { return this._clientId; } getServerConnection() { return this.serverConnection; } /** * LISTENER */ onConnected() { log.info(LogCategory.CLIENT, _translations.n8ME6kUb || (_translations.n8ME6kUb = tr("Client connected"))); this.permissions.requestPermissionList(); if (this.groups.serverGroups.length == 0) this.groups.requestGroups(); this.initialize_server_settings(); /* apply the server settings */ if (this.client_status.channel_subscribe_all) this.channelTree.subscribe_all_channels(); else this.channelTree.unsubscribe_all_channels(); this.channelTree.toggle_server_queries(this.client_status.queries_visible); this.sync_status_with_server(); this.channelTree.server.updateProperties(); /* No need to update the voice stuff because as soon we see ourself we're doing it this.update_voice_status(); if(control_bar.current_connection_handler() === this) control_bar.apply_server_voice_state(); */ } initialize_server_settings() { let update_control = false; this.settings.setServer(this.channelTree.server.properties.virtualserver_unique_identifier); { const flag_subscribe = this.settings.server(Settings.KEY_CONTROL_CHANNEL_SUBSCRIBE_ALL, true); if (this.client_status.channel_subscribe_all != flag_subscribe) { this.client_status.channel_subscribe_all = flag_subscribe; update_control = true; } } { const flag_query = this.settings.server(Settings.KEY_CONTROL_SHOW_QUERIES, false); if (this.client_status.queries_visible != flag_query) { this.client_status.queries_visible = flag_query; update_control = true; } } if (update_control && server_connections.active_connection_handler() === this) { control_bar.apply_server_state(); } } get connected() { return this.serverConnection && this.serverConnection.connected(); } generate_ssl_certificate_accept() { const properties = { connect_default: true, connect_profile: this.serverConnection.handshake_handler().profile.id, connect_address: this.serverConnection.remote_address().host + (this.serverConnection.remote_address().port !== 9987 ? ":" + this.serverConnection.remote_address().port : "") }; const build_url = (base, search, props) => { const parameters = []; for (const key of Object.keys(props)) parameters.push(key + "=" + encodeURIComponent(props[key])); let callback = base + search; /* don't use document.URL because it may contains a #! */ if (!search) callback += "?" + parameters.join("&"); else callback += "&" + parameters.join("&"); return "https://" + this.serverConnection.remote_address().host + ":" + this.serverConnection.remote_address().port + "/?forward_url=" + encodeURIComponent(callback); }; /* generate the tag */ const tag = $.spawn("a").text(_translations.YBuSiAT5 || (_translations.YBuSiAT5 = tr("here"))); let pathname = document.location.pathname; if (pathname.endsWith(".php")) pathname = pathname.substring(0, pathname.lastIndexOf("/")); if (bipc.supported()) { tag.attr('href', "#"); let popup; tag.on('click', event => { const features = { status: "no", location: "no", toolbar: "no", menubar: "no", width: 600, height: 400 }; if (popup) popup.close(); properties["certificate_callback"] = bipc.get_handler().register_certificate_accept_callback(() => { log.info(LogCategory.GENERAL, _translations.MQsgbKfE || (_translations.MQsgbKfE = tr("Received notification that the certificate has been accepted! Attempting reconnect!"))); if (this._certificate_modal) this._certificate_modal.close(); popup.close(); /* no need, but nicer */ const profile = profiles.find_profile(properties.connect_profile) || profiles.default_profile(); const cprops = this.reconnect_properties(profile); this.startConnection(properties.connect_address, profile, true, cprops); }); const url = build_url(document.location.origin + pathname + "/popup/certaccept/", "", properties); const features_string = [...Object.keys(features)].map(e => e + "=" + features[e]).reduce((a, b) => a + "," + b); popup = window.open(url, "TeaWeb certificate accept", features_string); try { popup.focus(); } catch (e) { log.warn(LogCategory.GENERAL, _translations.hTv3H6ip || (_translations.hTv3H6ip = tr("Certificate accept popup has been blocked. Trying a blank page and replacing href"))); window.open(url, "TeaWeb certificate accept"); /* trying without features */ tag.attr("target", "_blank"); tag.attr("href", url); tag.unbind('click'); } }); } else { tag.attr('href', build_url(document.location.origin + pathname, document.location.search, properties)); } return tag; } handleDisconnect(type, data = {}) { this._connect_initialize_id++; this.tab_set_name(_translations.Wcp4Jl2M || (_translations.Wcp4Jl2M = tr("Not connected"))); let auto_reconnect = false; switch (type) { case DisconnectReason.REQUESTED: case DisconnectReason.SERVER_HOSTMESSAGE: /* already handled */ break; case DisconnectReason.HANDLER_DESTROYED: if (data) { this.sound.play(Sound.CONNECTION_DISCONNECTED); this.log.log(log.server.Type.DISCONNECTED, {}); } break; case DisconnectReason.DNS_FAILED: log.error(LogCategory.CLIENT, _translations.RjYBRqhz || (_translations.RjYBRqhz = tr("Failed to resolve hostname: %o")), data); this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVE_ERROR, { message: data }); this.sound.play(Sound.CONNECTION_REFUSED); break; case DisconnectReason.CONNECT_FAILURE: if (this._reconnect_attempt) { auto_reconnect = true; this.log.log(log.server.Type.CONNECTION_FAILED, {}); break; } if (data) log.error(LogCategory.CLIENT, _translations.TTZmhO6X || (_translations.TTZmhO6X = tr("Could not connect to remote host! Extra data: %o")), data); else log.error(LogCategory.CLIENT, _translations.UvN4ZYoz || (_translations.UvN4ZYoz = tr("Could not connect to remote host!")), data); if (native_client) { createErrorModal(_translations.yKOp1KDQ || (_translations.yKOp1KDQ = tr("Could not connect")), _translations.BAtStX1r || (_translations.BAtStX1r = tr("Could not connect to remote host (Connection refused)"))).open(); } else { const error_message_format = "Could not connect to remote host (Connection refused)\n" + "If you're sure that the remote host is up, than you may not allow unsigned certificates.\n" + "Click {0} to accept the remote certificate"; this._certificate_modal = createErrorModal(_translations.EaTMLkfC || (_translations.EaTMLkfC = tr("Could not connect")), MessageHelper.formatMessage(tr(error_message_format), this.generate_ssl_certificate_accept())); this._certificate_modal.close_listener.push(() => this._certificate_modal = undefined); this._certificate_modal.open(); } this.sound.play(Sound.CONNECTION_REFUSED); break; case DisconnectReason.HANDSHAKE_FAILED: //TODO sound log.error(LogCategory.CLIENT, _translations.YWdTGt0C || (_translations.YWdTGt0C = tr("Failed to process handshake: %o")), data); createErrorModal(_translations.os_PbxTh || (_translations.os_PbxTh = tr("Could not connect")), (_translations.mWEfrIGh || (_translations.mWEfrIGh = tr("Failed to process handshake: "))) + data).open(); break; case DisconnectReason.HANDSHAKE_TEAMSPEAK_REQUIRED: createErrorModal(_translations.sKz9M0J1 || (_translations.sKz9M0J1 = tr("Target server is a TeamSpeak server")), MessageHelper.formatMessage(_translations.QmW2FhnQ || (_translations.QmW2FhnQ = tr("The target server is a TeamSpeak 3 server!{:br:}Only TeamSpeak 3 based identities are able to connect.{:br:}Please select another profile or change the identify type.")))).open(); this.sound.play(Sound.CONNECTION_DISCONNECTED); auto_reconnect = false; break; case DisconnectReason.IDENTITY_TOO_LOW: createErrorModal(_translations.c82V0qqg || (_translations.c82V0qqg = tr("Identity level is too low")), MessageHelper.formatMessage(_translations.vIrDdie6 || (_translations.vIrDdie6 = tr("You've been disconnected, because your Identity level is too low.{:br:}You need at least a level of {0}")), data["extra_message"])).open(); this.sound.play(Sound.CONNECTION_DISCONNECTED); auto_reconnect = false; break; case DisconnectReason.CONNECTION_CLOSED: log.error(LogCategory.CLIENT, _translations.DPauFd4a || (_translations.DPauFd4a = tr("Lost connection to remote server!"))); if (!this._reconnect_attempt) { createErrorModal(_translations.tPvfpJri || (_translations.tPvfpJri = tr("Connection closed")), _translations.yAUGk0u6 || (_translations.yAUGk0u6 = tr("The connection was closed by remote host"))).open(); } this.sound.play(Sound.CONNECTION_DISCONNECTED); auto_reconnect = true; break; case DisconnectReason.CONNECTION_PING_TIMEOUT: log.error(LogCategory.CLIENT, _translations.XM3HFZtb || (_translations.XM3HFZtb = tr("Connection ping timeout"))); this.sound.play(Sound.CONNECTION_DISCONNECTED_TIMEOUT); createErrorModal(_translations.SPp3hxky || (_translations.SPp3hxky = tr("Connection lost")), _translations.Ez6pR12l || (_translations.Ez6pR12l = tr("Lost connection to remote host (Ping timeout)
Even possible?"))).open(); break; case DisconnectReason.SERVER_CLOSED: this.log.log(log.server.Type.SERVER_CLOSED, { message: data.reasonmsg }); createErrorModal(_translations.oeX7ep3Y || (_translations.oeX7ep3Y = tr("Server closed")), "The server is closed.
" + //TODO tr "Reason: " + data.reasonmsg).open(); this.sound.play(Sound.CONNECTION_DISCONNECTED); auto_reconnect = true; break; case DisconnectReason.SERVER_REQUIRES_PASSWORD: this.log.log(log.server.Type.SERVER_REQUIRES_PASSWORD, {}); createInputModal(_translations.qlxKgog8 || (_translations.qlxKgog8 = tr("Server password")), _translations.QTjxbWyV || (_translations.QTjxbWyV = tr("Enter server password:")), password => password.length != 0, password => { if (!(typeof password === "string")) return; const profile = this.serverConnection.handshake_handler().profile; const cprops = this.reconnect_properties(profile); cprops.password = { password: password, hashed: false }; connection_log.update_address_info({ port: this.channelTree.server.remote_address.port, hostname: this.channelTree.server.remote_address.host }, { flag_password: true }); this.startConnection(this.channelTree.server.remote_address.host + ":" + this.channelTree.server.remote_address.port, profile, false, cprops); }).open(); break; case DisconnectReason.CLIENT_KICKED: const have_invoker = typeof (data["invokerid"]) !== "undefined" && parseInt(data["invokerid"]) !== 0; const modal = createErrorModal(_translations.GL3SU8Zv || (_translations.GL3SU8Zv = tr("You've been kicked")), MessageHelper.formatMessage(have_invoker ? _translations.L6t34lZs || (_translations.L6t34lZs = tr("You've been kicked from the server by {0}:{:br:}{1}")) : _translations.zo49e7He || (_translations.zo49e7He = tr("You've been kicked from the server:{:br:}{1}")), have_invoker ? htmltags.generate_client_object({ client_id: parseInt(data["invokerid"]), client_unique_id: data["invokeruid"], client_name: data["invokername"] }) : "", data["extra_message"] || data["reasonmsg"] || "")); modal.htmlTag.find(".modal-body").addClass("modal-disconnect-kick"); modal.open(); this.sound.play(Sound.SERVER_KICKED); auto_reconnect = false; break; case DisconnectReason.HANDSHAKE_BANNED: //Reason message already printed because of the command error handling this.sound.play(Sound.CONNECTION_BANNED); break; case DisconnectReason.CLIENT_BANNED: this.log.log(log.server.Type.SERVER_BANNED, { invoker: { client_name: data["invokername"], client_id: parseInt(data["invokerid"]), client_unique_id: data["invokeruid"] }, message: data["reasonmsg"], time: parseInt(data["time"]) }); this.sound.play(Sound.CONNECTION_BANNED); break; default: log.error(LogCategory.CLIENT, _translations.eTgdGWXl || (_translations.eTgdGWXl = tr("Got uncaught disconnect!"))); log.error(LogCategory.CLIENT, _translations.m_2kmrli || (_translations.m_2kmrli = tr("Type: %o Data: %o")), type, data); break; } this.channelTree.unregisterClient(this._local_client); /* if we dont unregister our client here the client will be destroyed */ this.channelTree.reset(); if (this.serverConnection) this.serverConnection.disconnect(); if (control_bar.current_connection_handler() == this) control_bar.update_connection_state(); this.side_bar.private_conversations().clear_client_ids(); this.hostbanner.update(); if (auto_reconnect) { if (!this.serverConnection) { log.info(LogCategory.NETWORKING, _translations.gthobtoh || (_translations.gthobtoh = tr("Allowed to auto reconnect but cant reconnect because we dont have any information left..."))); return; } this.log.log(log.server.Type.RECONNECT_SCHEDULED, { timeout: 5000 }); log.info(LogCategory.NETWORKING, _translations.OfYIEKF3 || (_translations.OfYIEKF3 = tr("Allowed to auto reconnect. Reconnecting in 5000ms"))); const server_address = this.serverConnection.remote_address(); const profile = this.serverConnection.handshake_handler().profile; this._reconnect_timer = setTimeout(() => { this._reconnect_timer = undefined; this.log.log(log.server.Type.RECONNECT_EXECUTE, {}); log.info(LogCategory.NETWORKING, _translations.mgD_hUkm || (_translations.mgD_hUkm = tr("Reconnecting..."))); this.startConnection(server_address.host + ":" + server_address.port, profile, false, Object.assign(this.reconnect_properties(profile), { auto_reconnect_attempt: true })); }, 5000); } } cancel_reconnect(log_event) { if (this._reconnect_timer) { if (log_event) this.log.log(log.server.Type.RECONNECT_CANCELED, {}); clearTimeout(this._reconnect_timer); this._reconnect_timer = undefined; } } on_connection_state_changed() { if (control_bar.current_connection_handler() == this) control_bar.update_connection_state(); } update_voice_status(targetChannel) { if (!this._local_client) return; /* we've been destroyed */ targetChannel = targetChannel || this.getClient().currentChannel(); const vconnection = this.serverConnection.voice_connection(); const basic_voice_support = this.serverConnection.support_voice() && vconnection.connected() && targetChannel; const support_record = basic_voice_support && (!targetChannel || vconnection.encoding_supported(targetChannel.properties.channel_codec)); const support_playback = basic_voice_support && (!targetChannel || vconnection.decoding_supported(targetChannel.properties.channel_codec)); const property_update = { client_input_muted: this.client_status.input_muted, client_output_muted: this.client_status.output_muted }; if (support_record && basic_voice_support) vconnection.set_encoder_codec(targetChannel.properties.channel_codec); if (!this.serverConnection.support_voice() || !this.serverConnection.connected() || !vconnection.connected()) { property_update["client_input_hardware"] = false; property_update["client_output_hardware"] = false; this.client_status.input_hardware = true; /* IDK if we have input hardware or not, but it dosn't matter at all so */ /* no icons are shown so no update at all */ } else { const audio_source = vconnection.voice_recorder(); const recording_supported = typeof (audio_source) !== "undefined" && audio_source.record_supported && (!targetChannel || vconnection.encoding_supported(targetChannel.properties.channel_codec)); const playback_supported = !targetChannel || vconnection.decoding_supported(targetChannel.properties.channel_codec); property_update["client_input_hardware"] = recording_supported; property_update["client_output_hardware"] = playback_supported; this.client_status.input_hardware = recording_supported; /* update icons */ const client_properties = this.getClient().properties; for (const key of Object.keys(property_update)) { if (client_properties[key] === property_update[key]) delete property_update[key]; } if (Object.keys(property_update).length > 0) { this.serverConnection.send_command("clientupdate", property_update).catch(error => { log.warn(LogCategory.GENERAL, _translations.E6Pxj7O_ || (_translations.E6Pxj7O_ = tr("Failed to update client audio hardware properties. Error: %o")), error); this.log.log(log.server.Type.ERROR_CUSTOM, { message: _translations.myFdKome || (_translations.myFdKome = tr("Failed to update audio hardware properties.")) }); /* Update these properties anyways (for case the server fails to handle the command) */ const updates = []; for (const key of Object.keys(property_update)) updates.push({ key: key, value: (property_update[key]) + "" }); this.getClient().updateVariables(...updates); }); } } if (targetChannel && basic_voice_support) { const encoding_supported = vconnection && vconnection.encoding_supported(targetChannel.properties.channel_codec); const decoding_supported = vconnection && vconnection.decoding_supported(targetChannel.properties.channel_codec); if (this.client_status.channel_codec_decoding_supported !== decoding_supported || this.client_status.channel_codec_encoding_supported !== encoding_supported) { this.client_status.channel_codec_decoding_supported = decoding_supported; this.client_status.channel_codec_encoding_supported = encoding_supported; let message; if (!encoding_supported && !decoding_supported) message = _translations.yhxSmGy4 || (_translations.yhxSmGy4 = tr("This channel has an unsupported codec.
You cant speak or listen to anybody within this channel!")); else if (!encoding_supported) message = _translations.FhG1RYUu || (_translations.FhG1RYUu = tr("This channel has an unsupported codec.
You cant speak within this channel!")); else if (!decoding_supported) message = _translations.tl9gg03_ || (_translations.tl9gg03_ = tr("This channel has an unsupported codec.
You listen to anybody within this channel!")); /* implies speaking does not work as well */ if (message) createErrorModal(_translations.H8fSS_0Z || (_translations.H8fSS_0Z = tr("Channel codec unsupported")), message).open(); } } this.client_status = this.client_status || {}; this.client_status.sound_record_supported = support_record; this.client_status.sound_playback_supported = support_playback; if (vconnection && vconnection.voice_recorder() && vconnection.voice_recorder().record_supported) { const active = !this.client_status.input_muted && !this.client_status.output_muted; /* No need to start the microphone when we're not even connected */ const input = vconnection.voice_recorder().input; if (input) { if (active && this.serverConnection.connected()) { if (input.current_state() === audio.recorder.InputState.PAUSED) { input.start().then(result => { if (result != audio.recorder.InputStartResult.EOK) throw result; }).catch(error => { log.warn(LogCategory.VOICE, _translations.IU0hK4NF || (_translations.IU0hK4NF = tr("Failed to start microphone input (%s).")), error); if (Date.now() - (this._last_record_error_popup || 0) > 10 * 1000) { this._last_record_error_popup = Date.now(); createErrorModal(_translations.Ak0MoTq5 || (_translations.Ak0MoTq5 = tr("Failed to start recording")), MessageHelper.formatMessage(_translations.CdNixUn2 || (_translations.CdNixUn2 = tr("Microphone start failed.{:br:}Error: {}")), error)).open(); } }); } } else { input.stop(); } } } if (control_bar.current_connection_handler() === this) control_bar.apply_server_voice_state(); } sync_status_with_server() { if (this.serverConnection.connected()) this.serverConnection.send_command("clientupdate", { client_input_muted: this.client_status.input_muted, client_output_muted: this.client_status.output_muted, client_away: typeof (this.client_status.away) === "string" || this.client_status.away, client_away_message: typeof (this.client_status.away) === "string" ? this.client_status.away : "", client_input_hardware: this.client_status.sound_record_supported && this.client_status.input_hardware, client_output_hardware: this.client_status.sound_playback_supported }).catch(error => { log.warn(LogCategory.GENERAL, _translations.ifNLFsmx || (_translations.ifNLFsmx = tr("Failed to sync handler state with server. Error: %o")), error); this.log.log(log.server.Type.ERROR_CUSTOM, { message: _translations.ZAcARduu || (_translations.ZAcARduu = tr("Failed to sync handler state with server.")) }); }); } set_away_status(state) { if (this.client_status.away === state) return; if (state) { this.sound.play(Sound.AWAY_ACTIVATED); } else { this.sound.play(Sound.AWAY_DEACTIVATED); } this.client_status.away = state; this.serverConnection.send_command("clientupdate", { client_away: typeof (this.client_status.away) === "string" || this.client_status.away, client_away_message: typeof (this.client_status.away) === "string" ? this.client_status.away : "", }).catch(error => { log.warn(LogCategory.GENERAL, _translations.j356bpkL || (_translations.j356bpkL = tr("Failed to update away status. Error: %o")), error); this.log.log(log.server.Type.ERROR_CUSTOM, { message: _translations.Hquv820o || (_translations.Hquv820o = tr("Failed to update away status.")) }); }); control_bar.update_button_away(); } resize_elements() { this.channelTree.handle_resized(); this.invoke_resized_on_activate = false; } acquire_recorder(voice_recoder, update_control_bar) { const vconnection = this.serverConnection.voice_connection(); (vconnection ? vconnection.acquire_voice_recorder(voice_recoder) : Promise.resolve()).catch(error => { log.warn(LogCategory.VOICE, _translations.Nhi8Zrg7 || (_translations.Nhi8Zrg7 = tr("Failed to acquire recorder (%o)")), error); }).then(() => { this.update_voice_status(undefined); }); } reconnect_properties(profile) { const name = (this.getClient() ? this.getClient().clientNickName() : "") || (this.serverConnection && this.serverConnection.handshake_handler() ? this.serverConnection.handshake_handler().parameters.nickname : "") || settings.static_global(Settings.KEY_CONNECT_USERNAME, profile ? profile.default_username : undefined) || "Another TeaSpeak user"; const channel = (this.getClient() && this.getClient().currentChannel() ? this.getClient().currentChannel().channelId : 0) || (this.serverConnection && this.serverConnection.handshake_handler() ? (this.serverConnection.handshake_handler().parameters.channel || {}).target : ""); const channel_password = (this.getClient() && this.getClient().currentChannel() ? this.getClient().currentChannel().cached_password() : "") || (this.serverConnection && this.serverConnection.handshake_handler() ? (this.serverConnection.handshake_handler().parameters.channel || {}).password : ""); return { channel: channel ? { target: "/" + channel, password: channel_password } : undefined, nickname: name, password: this.serverConnection && this.serverConnection.handshake_handler() ? this.serverConnection.handshake_handler().parameters.password : undefined }; } update_avatar() { Modals.spawnAvatarUpload(data => { if (typeof (data) === "undefined") return; if (data === null) { log.info(LogCategory.CLIENT, _translations.kwfqGPH6 || (_translations.kwfqGPH6 = tr("Deleting existing avatar"))); this.serverConnection.send_command('ftdeletefile', { name: "/avatar_", path: "", cid: 0 }).then(() => { createInfoModal(_translations.N3fwN_XS || (_translations.N3fwN_XS = tr("Avatar deleted")), _translations.dWko40aF || (_translations.dWko40aF = tr("Avatar successfully deleted"))).open(); }).catch(error => { log.error(LogCategory.GENERAL, _translations._o7eTDux || (_translations._o7eTDux = tr("Failed to reset avatar flag: %o")), error); let message; if (error instanceof CommandResult) message = MessageHelper.formatMessage(_translations.q6MV9BJ6 || (_translations.q6MV9BJ6 = tr("Failed to delete avatar.{:br:}Error: {0}")), error.extra_message || error.message); if (!message) message = MessageHelper.formatMessage(_translations.l2z4u5iq || (_translations.l2z4u5iq = tr("Failed to delete avatar.{:br:}Lookup the console for more details"))); createErrorModal(_translations.SERPbLsV || (_translations.SERPbLsV = tr("Failed to delete avatar")), message).open(); return; }); } else { log.info(LogCategory.CLIENT, _translations.Uwwz13se || (_translations.Uwwz13se = tr("Uploading new avatar"))); (() => __awaiter(this, void 0, void 0, function* () { let key; try { key = yield this.fileManager.upload_file({ size: data.byteLength, path: '', name: '/avatar', overwrite: true, channel: undefined, channel_password: undefined }); } catch (error) { log.error(LogCategory.GENERAL, _translations.p6ktJjDH || (_translations.p6ktJjDH = tr("Failed to initialize avatar upload: %o")), error); let message; if (error instanceof CommandResult) { //TODO: Resolve permission name //i_client_max_avatar_filesize if (error.id == ErrorID.PERMISSION_ERROR) { message = MessageHelper.formatMessage(_translations.DpzOU8kx || (_translations.DpzOU8kx = tr("Failed to initialize avatar upload.{:br:}Missing permission {0}")), error["failed_permid"]); } else { message = MessageHelper.formatMessage(_translations.GSHnaSaC || (_translations.GSHnaSaC = tr("Failed to initialize avatar upload.{:br:}Error: {0}")), error.extra_message || error.message); } } if (!message) message = MessageHelper.formatMessage(_translations.HuAordM2 || (_translations.HuAordM2 = tr("Failed to initialize avatar upload.{:br:}Lookup the console for more details"))); createErrorModal(_translations.SqHGgSbh || (_translations.SqHGgSbh = tr("Failed to upload avatar")), message).open(); return; } try { yield transfer.spawn_upload_transfer(key).put_data(data); } catch (error) { log.error(LogCategory.GENERAL, _translations.cCwgYPgQ || (_translations.cCwgYPgQ = tr("Failed to upload avatar: %o")), error); let message; if (typeof (error) === "string") message = MessageHelper.formatMessage(_translations.Jkzl_W58 || (_translations.Jkzl_W58 = tr("Failed to upload avatar.{:br:}Error: {0}")), error); if (!message) message = MessageHelper.formatMessage(_translations.HfLNjuHd || (_translations.HfLNjuHd = tr("Failed to initialize avatar upload.{:br:}Lookup the console for more details"))); createErrorModal(_translations.b_WF3dmV || (_translations.b_WF3dmV = tr("Failed to upload avatar")), message).open(); return; } try { yield this.serverConnection.send_command('clientupdate', { client_flag_avatar: guid() }); } catch (error) { log.error(LogCategory.GENERAL, _translations.PkrE3ZLe || (_translations.PkrE3ZLe = tr("Failed to update avatar flag: %o")), error); let message; if (error instanceof CommandResult) message = MessageHelper.formatMessage(_translations.Yw4Xjm9C || (_translations.Yw4Xjm9C = tr("Failed to update avatar flag.{:br:}Error: {0}")), error.extra_message || error.message); if (!message) message = MessageHelper.formatMessage(_translations.ZNppOyOZ || (_translations.ZNppOyOZ = tr("Failed to update avatar flag.{:br:}Lookup the console for more details"))); createErrorModal(_translations.n1Io657i || (_translations.n1Io657i = tr("Failed to set avatar")), message).open(); return; } createInfoModal(_translations.dVyA2a02 || (_translations.dVyA2a02 = tr("Avatar successfully uploaded")), _translations.Wrvy2Obl || (_translations.Wrvy2Obl = tr("Your avatar has been uploaded successfully!"))).open(); }))(); } }); } destroy() { this.cancel_reconnect(true); this.tag_connection_handler && this.tag_connection_handler.remove(); this.tag_connection_handler = undefined; this.hostbanner && this.hostbanner.destroy(); this.hostbanner = undefined; this._local_client && this._local_client.destroy(); this._local_client = undefined; this.channelTree && this.channelTree.destroy(); this.channelTree = undefined; this.side_bar && this.side_bar.destroy(); this.side_bar = undefined; this.log && this.log.destroy(); this.log = undefined; this.permissions && this.permissions.destroy(); this.permissions = undefined; this.groups && this.groups.destroy(); this.groups = undefined; this.fileManager && this.fileManager.destroy(); this.fileManager = undefined; this.settings && this.settings.destroy(); this.settings = undefined; if (this.serverConnection) { this.serverConnection.onconnectionstatechanged = undefined; connection.destroy_server_connection(this.serverConnection); } this.serverConnection = undefined; this.sound = undefined; this._local_client = undefined; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5b0b0e729d8a6355fc16c9599bb8ac0e339c71eefff49f95cfba19ce44c9b4ae"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5b0b0e729d8a6355fc16c9599bb8ac0e339c71eefff49f95cfba19ce44c9b4ae"] = "5b0b0e729d8a6355fc16c9599bb8ac0e339c71eefff49f95cfba19ce44c9b4ae"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "SlnUPyvk", path: "D:/TeaSpeak/web/shared/js/MessageFormatter.ts (112,31)" }, { name: "nQeTIPlF", path: "D:/TeaSpeak/web/shared/js/MessageFormatter.ts (119,31)" }, { name: "tOI3DTZ8", path: "D:/TeaSpeak/web/shared/js/MessageFormatter.ts (124,31)" }, { name: "H9Jdm9OF", path: "D:/TeaSpeak/web/shared/js/MessageFormatter.ts (148,27)" }, { name: "qq3oBpng", path: "D:/TeaSpeak/web/shared/js/MessageFormatter.ts (153,27)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var messages; (function (messages) { var formatter; (function (formatter) { let bbcode; (function (bbcode) { const sanitizer_escaped = (key) => "[-- sescaped: " + key + " --]"; const sanitizer_escaped_regex = /\[-- sescaped: ([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}) --]/; const sanitizer_escaped_map = {}; const yt_url_regex = /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/; function format(message, fsettings) { fsettings = fsettings || {}; single_url_parse: if (fsettings.is_chat_message) { /* try if its only one url */ const raw_url = message.replace(/\[url(=\S+)?](\S+)\[\/url]/, "$2"); let url; try { url = new URL(raw_url); } catch (error) { break single_url_parse; } single_url_yt: { const result = raw_url.match(yt_url_regex); if (!result) break single_url_yt; return format("[yt]https://www.youtube.com/watch?v=" + result[5] + "[/yt]"); } single_url_image: { const ext_index = url.pathname.lastIndexOf("."); if (ext_index == -1) break single_url_image; const ext_name = url.pathname.substr(ext_index + 1).toLowerCase(); if ([ "jpeg", "jpg", "png", "bmp", "gif", "tiff", "pdf", "svg" ].findIndex(e => e === ext_name) == -1) break single_url_image; return format("[img]" + message + "[/img]"); } } const result = xbbcode.parse(message, { tag_whitelist: [ "b", "big", "i", "italic", "u", "underlined", "s", "strikethrough", "color", "url", "code", "i-code", "icode", "sub", "sup", "size", "hr", "br", "ul", "ol", "list", "li", "table", "tr", "td", "th", "yt", "youtube", "img" ] }); let html = result.build_html(); if (typeof (window.twemoji) !== "undefined" && settings.static_global(Settings.KEY_CHAT_COLORED_EMOJIES)) html = twemoji.parse(html); const container = $.spawn("div"); let sanitized = DOMPurify.sanitize(html, { ADD_ATTR: [ "x-highlight-type", "x-code-type", "x-image-url" ] }); sanitized = sanitized.replace(sanitizer_escaped_regex, data => { const uid = data.match(sanitizer_escaped_regex)[1]; const value = sanitizer_escaped_map[uid]; if (!value) return data; delete sanitizer_escaped_map[uid]; return value; }); container[0].innerHTML = sanitized; container.find("a") .attr('target', "_blank") .on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); const url = $(event.target).attr("href"); contextmenu.spawn_context_menu(event.pageX, event.pageY, { callback: () => { const win = window.open(url, '_blank'); win.focus(); }, name: _translations.SlnUPyvk || (_translations.SlnUPyvk = tr("Open URL")), type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-browse-addon-online" }, { callback: () => { //TODO }, name: _translations.nQeTIPlF || (_translations.nQeTIPlF = tr("Open URL in Browser")), type: contextmenu.MenuEntryType.ENTRY, visible: !app.is_web() && false // Currently not possible }, contextmenu.Entry.HR(), { callback: () => copy_to_clipboard(url), name: _translations.tOI3DTZ8 || (_translations.tOI3DTZ8 = tr("Copy URL to clipboard")), type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-copy" }); }); return [container.contents()]; //return result.root_tag.content.map(e => e.build_html()).map((entry, idx, array) => $.spawn("a").css("display", (idx == 0 ? "inline" : "") + "block").html(entry == "" && idx != 0 ? " " : entry)); } bbcode.format = format; function load_image(entry) { const url = decodeURIComponent(entry.getAttribute("x-image-url") || ""); const proxy_url = "https://images.weserv.nl/?url=" + encodeURIComponent(url); entry.onload = undefined; entry.src = proxy_url; const parent = $(entry.parentElement); parent.on('contextmenu', event => { contextmenu.spawn_context_menu(event.pageX, event.pageY, { callback: () => { const win = window.open(url, '_blank'); win.focus(); }, name: _translations.H9Jdm9OF || (_translations.H9Jdm9OF = tr("Open image in browser")), type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-browse-addon-online" }, contextmenu.Entry.HR(), { callback: () => copy_to_clipboard(url), name: _translations.qq3oBpng || (_translations.qq3oBpng = tr("Copy image URL to clipboard")), type: contextmenu.MenuEntryType.ENTRY, icon_class: "client-copy" }); }); parent.css("cursor", "pointer").on('click', event => image_preview.preview_image(proxy_url, url)); } bbcode.load_image = load_image; loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "XBBCode code tag init", function: () => __awaiter(this, void 0, void 0, function* () { /* override default parser */ xbbcode.register.register_parser({ tag: ["code", "icode", "i-code"], content_tags_whitelist: [], build_html(layer) { const klass = layer.tag_normalized != 'code' ? "tag-hljs-inline-code" : "tag-hljs-code"; const language = (layer.options || "").replace("\"", "'").toLowerCase(); /* remove heading empty lines */ let text = layer.content.map(e => e.build_text()) .reduce((a, b) => a.length == 0 && b.replace(/[ \n\r\t]+/g, "").length == 0 ? "" : a + b, "") .replace(/^([ \n\r\t]*)(?=\n)+/g, ""); if (text.startsWith("\r") || text.startsWith("\n")) text = text.substr(1); let result; if (window.hljs.getLanguage(language)) result = window.hljs.highlight(language, text, true); else result = window.hljs.highlightAuto(text); let html = '
';
                            html += '';
                            html += result.value;
                            return html + "
"; } }); /* override the yt parser */ const original_parser = xbbcode.register.find_parser("yt"); if (original_parser) xbbcode.register.register_parser({ tag: ["yt", "youtube"], build_html(layer) { const result = original_parser.build_html(layer); if (!result.startsWith(""; return sanitizer_escaped(uid); } }); /* the image parse & displayer */ xbbcode.register.register_parser({ tag: ["img", "image"], build_html(layer) { const uid = guid(); const fallback_value = "[img]" + layer.build_text() + "[/img]"; let target; let content = layer.content.map(e => e.build_text()).join(""); if (!layer.options) { target = content; } else target = layer.options; let url; try { url = new URL(target); if (!url.hostname) throw ""; } catch (error) { return fallback_value; } sanitizer_escaped_map[uid] = "
"; return sanitizer_escaped(uid); } }); }), priority: 10 }); })(bbcode = formatter.bbcode || (formatter.bbcode = {})); function sanitize_text(text) { return $(DOMPurify.sanitize("" + text + "", { ADD_ATTR: [ "x-highlight-type", "x-code-type", "x-image-url" ] })).text(); } formatter.sanitize_text = sanitize_text; })(formatter = messages.formatter || (messages.formatter = {})); })(messages || (messages = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["29ef4d07eca5d64f42ebf5dc62f9f51bdf2f1fda69c0d90abc439a47f29609ac"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["29ef4d07eca5d64f42ebf5dc62f9f51bdf2f1fda69c0d90abc439a47f29609ac"] = "29ef4d07eca5d64f42ebf5dc62f9f51bdf2f1fda69c0d90abc439a47f29609ac"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var dns; (function (dns) { dns.default_options = { timeout: 5000, allow_cache: true, max_depth: 5 }; })(dns || (dns = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["9dc0537f39bf16c58b80536db4cb74fe25af0f9cb2e1072557c5d1e08049a414"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["9dc0537f39bf16c58b80536db4cb74fe25af0f9cb2e1072557c5d1e08049a414"] = "9dc0537f39bf16c58b80536db4cb74fe25af0f9cb2e1072557c5d1e08049a414"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var events; (function (events_1) { class SingletonEvent { constructor() { this.type = "singletone-instance"; } } SingletonEvent.instance = new SingletonEvent(); events_1.SingletonEvent = SingletonEvent; class Registry { constructor() { this.handler = {}; this.connections = {}; this.debug_prefix = undefined; this.registry_uuid = "evreg_data_" + guid(); } enable_debug(prefix) { this.debug_prefix = prefix || "---"; } disable_debug() { this.debug_prefix = undefined; } on(events, handler) { if (!Array.isArray(events)) events = [events]; handler[this.registry_uuid] = { singleshot: false }; for (const event of events) { const handlers = this.handler[event] || (this.handler[event] = []); handlers.push(handler); } } one(events, handler) { if (!Array.isArray(events)) events = [events]; for (const event of events) { const handlers = this.handler[event] || (this.handler[event] = []); handler[this.registry_uuid] = { singleshot: true }; handlers.push(handler); } } off(handler_or_events, handler) { if (typeof handler_or_events === "function") { for (const key of Object.keys(this.handler)) this.handler[key].remove(handler_or_events); } else { if (!Array.isArray(handler_or_events)) handler_or_events = [handler_or_events]; for (const event of handler_or_events) { const handlers = this.handler[event]; if (handlers) handlers.remove(handler); } } } connect(event, target) { (this.connections[event] || (this.connections[event] = [])).push(target); } disconnect(event, target) { (this.connections[event] || []).remove(target); } disconnect_all(target) { for (const event of Object.keys(this.connections)) this.connections[event].remove(target); } fire(event_type, data) { if (this.debug_prefix) console.log("[%s] Trigger event: %s", this.debug_prefix, event_type); const event = Object.assign(typeof data === "undefined" ? SingletonEvent.instance : data, { type: event_type, as: function () { return this; } }); for (const handler of (this.handler[event_type] || [])) { handler(event); const reg_data = handler[this.registry_uuid]; if (typeof reg_data === "object" && reg_data.singleshot) this.handler[event_type].remove(handler); } for (const evhandler of (this.connections[event_type] || [])) evhandler.fire(event_type, event); } fire_async(event_type, data) { setTimeout(() => this.fire(event_type, data)); } destory() { this.handler = {}; } } events_1.Registry = Registry; })(events || (events = {})); const eclient = new events.Registry(); const emusic = new events.Registry(); eclient.connect("playlist_song_loaded", emusic); eclient.connect("playlist_song_loaded", emusic); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["2d91d2e2b1835bcadc3f37922502a465b7f2d371df52f15a79138ae94be7235b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["2d91d2e2b1835bcadc3f37922502a465b7f2d371df52f15a79138ae94be7235b"] = "2d91d2e2b1835bcadc3f37922502a465b7f2d371df52f15a79138ae94be7235b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "MPJIRlqs", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (81,51)" }, { name: "NDTF2Yzi", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (199,58)" }, { name: "ZI_tZyBd", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (199,72)" }, { name: "t4VTrEXu", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (205,58)" }, { name: "ybJHagZN", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (205,71)" }, { name: "LDpkmc_N", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (211,58)" }, { name: "_LzkhuHI", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (211,72)" }, { name: "cute2byM", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (217,58)" }, { name: "Yse9w1Aj", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (217,74)" }, { name: "sjq8XWYY", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (223,58)" }, { name: "LFkoylsJ", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat.ts (223,74)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var ChatType; (function (ChatType) { ChatType[ChatType["GENERAL"] = 0] = "GENERAL"; ChatType[ChatType["SERVER"] = 1] = "SERVER"; ChatType[ChatType["CHANNEL"] = 2] = "CHANNEL"; ChatType[ChatType["CLIENT"] = 3] = "CLIENT"; })(ChatType || (ChatType = {})); var MessageHelper; (function (MessageHelper) { function htmlEscape(message) { const div = document.createElement('div'); div.innerText = message; message = div.innerHTML; return message.replace(/ /g, ' ').split(/
/); } MessageHelper.htmlEscape = htmlEscape; function formatElement(object, escape_html = true) { if ($.isArray(object)) { let result = []; for (let element of object) result.push(...formatElement(element, escape_html)); return result; } else if (typeof (object) == "string") { if (object.length == 0) return []; return escape_html ? htmlEscape(object).map((entry, idx, array) => $.spawn("a").css("display", (idx == 0 || idx + 1 == array.length ? "inline" : "") + "block").html(entry == "" && idx != 0 ? " " : entry)) : [$.spawn("div").css("display", "inline-block").html(object)]; } else if (typeof (object) === "object") { if (object instanceof $) return [object]; return formatElement(""); } else if (typeof (object) === "function") return formatElement(object(), escape_html); else if (typeof (object) === "undefined") return formatElement(""); else if (typeof (object) === "number") return [$.spawn("a").text(object)]; return formatElement(""); } MessageHelper.formatElement = formatElement; function formatMessage(pattern, ...objects) { let begin = 0, found = 0; let result = []; do { found = pattern.indexOf('{', found); if (found == -1 || pattern.length <= found + 1) { result.push(...formatElement(pattern.substr(begin))); break; } if (found > 0 && pattern[found - 1] == '\\') { //TODO remove the escape! found++; continue; } result.push(...formatElement(pattern.substr(begin, found - begin))); //Append the text let offset = 0; if (pattern[found + 1] == ':') { offset++; /* the beginning : */ while (pattern[found + 1 + offset] != ':' && found + 1 + offset < pattern.length) offset++; const tag = pattern.substr(found + 2, offset - 1); offset++; /* the ending : */ if (pattern[found + offset + 1] != '}' && found + 1 + offset < pattern.length) { found++; continue; } result.push($.spawn(tag)); } else { let number; while ("0123456789".includes(pattern[found + 1 + offset])) offset++; number = parseInt(offset > 0 ? pattern.substr(found + 1, offset) : "0"); if (pattern[found + offset + 1] != '}') { found++; continue; } if (objects.length < number) log.warn(LogCategory.GENERAL, _translations.MPJIRlqs || (_translations.MPJIRlqs = tr("Message to format contains invalid index (%o)")), number); result.push(...formatElement(objects[number])); } found = found + 1 + offset; begin = found + 1; } while (found++); return result; } MessageHelper.formatMessage = formatMessage; //TODO: Remove this (only legacy) function bbcode_chat(message) { return messages.formatter.bbcode.format(message, { is_chat_message: true }); } MessageHelper.bbcode_chat = bbcode_chat; let network; (function (network) { network.KB = 1024; network.MB = 1024 * network.KB; network.GB = 1024 * network.MB; network.TB = 1024 * network.GB; function format_bytes(value, options) { options = options || {}; if (typeof options.exact !== "boolean") options.exact = true; if (typeof options.unit !== "string") options.unit = "Bytes"; let points = value.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); let v, unit; if (value > 2 * network.TB) { unit = "TB"; v = value / network.TB; } else if (value > network.GB) { unit = "GB"; v = value / network.GB; } else if (value > network.MB) { unit = "MB"; v = value / network.MB; } else if (value > network.KB) { unit = "KB"; v = value / network.KB; } else { unit = ""; v = value; } let result = ""; if (options.exact || !unit) { result += points; if (options.unit) { result += " " + options.unit; if (options.time) result += "/" + options.time; } } if (unit) { result += (result ? " / " : "") + v.toFixed(2) + " " + unit; if (options.time) result += "/" + options.time; } return result; } network.format_bytes = format_bytes; })(network = MessageHelper.network || (MessageHelper.network = {})); MessageHelper.K = 1000; MessageHelper.M = 1000 * MessageHelper.K; MessageHelper.G = 1000 * MessageHelper.M; MessageHelper.T = 1000 * MessageHelper.G; function format_number(value, options) { options = Object.assign(options || {}, {}); let points = value.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); let v, unit; if (value > 2 * MessageHelper.T) { unit = "T"; v = value / MessageHelper.T; } else if (value > MessageHelper.G) { unit = "G"; v = value / MessageHelper.G; } else if (value > MessageHelper.M) { unit = "M"; v = value / MessageHelper.M; } else if (value > MessageHelper.K) { unit = "K"; v = value / MessageHelper.K; } else { unit = ""; v = value; } if (unit && options.time) unit = unit + "/" + options.time; return points + " " + (options.unit || "") + (unit ? (" / " + v.toFixed(2) + " " + unit) : ""); } MessageHelper.format_number = format_number; MessageHelper.TIME_SECOND = 1000; MessageHelper.TIME_MINUTE = 60 * MessageHelper.TIME_SECOND; MessageHelper.TIME_HOUR = 60 * MessageHelper.TIME_MINUTE; MessageHelper.TIME_DAY = 24 * MessageHelper.TIME_HOUR; MessageHelper.TIME_WEEK = 7 * MessageHelper.TIME_DAY; function format_time(time, default_value) { let result = ""; if (time > MessageHelper.TIME_WEEK) { const amount = Math.floor(time / MessageHelper.TIME_WEEK); result += " " + amount + " " + (amount > 1 ? _translations.NDTF2Yzi || (_translations.NDTF2Yzi = tr("Weeks")) : _translations.ZI_tZyBd || (_translations.ZI_tZyBd = tr("Week"))); time -= amount * MessageHelper.TIME_WEEK; } if (time > MessageHelper.TIME_DAY) { const amount = Math.floor(time / MessageHelper.TIME_DAY); result += " " + amount + " " + (amount > 1 ? _translations.t4VTrEXu || (_translations.t4VTrEXu = tr("Days")) : _translations.ybJHagZN || (_translations.ybJHagZN = tr("Day"))); time -= amount * MessageHelper.TIME_DAY; } if (time > MessageHelper.TIME_HOUR) { const amount = Math.floor(time / MessageHelper.TIME_HOUR); result += " " + amount + " " + (amount > 1 ? _translations.LDpkmc_N || (_translations.LDpkmc_N = tr("Hours")) : _translations._LzkhuHI || (_translations._LzkhuHI = tr("Hour"))); time -= amount * MessageHelper.TIME_HOUR; } if (time > MessageHelper.TIME_MINUTE) { const amount = Math.floor(time / MessageHelper.TIME_MINUTE); result += " " + amount + " " + (amount > 1 ? _translations.cute2byM || (_translations.cute2byM = tr("Minutes")) : _translations.Yse9w1Aj || (_translations.Yse9w1Aj = tr("Minute"))); time -= amount * MessageHelper.TIME_MINUTE; } if (time > MessageHelper.TIME_SECOND) { const amount = Math.floor(time / MessageHelper.TIME_SECOND); result += " " + amount + " " + (amount > 1 ? _translations.sjq8XWYY || (_translations.sjq8XWYY = tr("Seconds")) : _translations.LFkoylsJ || (_translations.LFkoylsJ = tr("Second"))); time -= amount * MessageHelper.TIME_SECOND; } return result.length > 0 ? result.substring(1) : default_value; } MessageHelper.format_time = format_time; let _icon_size_style; function set_icon_size(size) { if (!_icon_size_style) _icon_size_style = $.spawn("style").appendTo($("#style")); _icon_size_style.text("\n" + ".message > .emoji {\n" + " height: " + size + "!important;\n" + " width: " + size + "!important;\n" + "}\n"); } MessageHelper.set_icon_size = set_icon_size; loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "icon size init", function: () => __awaiter(this, void 0, void 0, function* () { MessageHelper.set_icon_size((settings.static_global(Settings.KEY_ICON_SIZE) / 100).toFixed(2) + "em"); }), priority: 10 }); })(MessageHelper || (MessageHelper = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["94bd1d31ef570dd65f3469e82da58180cb66c5866ab7cf829a5362cb40cfd386"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["94bd1d31ef570dd65f3469e82da58180cb66c5866ab7cf829a5362cb40cfd386"] = "94bd1d31ef570dd65f3469e82da58180cb66c5866ab7cf829a5362cb40cfd386"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "IQMHO28d", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalConnect.ts (88,46)" }, { name: "kagWcYCB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalConnect.ts (107,21)" }, { name: "JfPT4VD3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalConnect.ts (288,95)" }, { name: "NJt4Js9d", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalConnect.ts (288,107)" }, { name: "iZ3MJUg4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalConnect.ts (292,80)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// //FIXME: Move this shit out of this file! var connection_log; (function (connection_log) { let _history = []; function log_connect(address) { let entry = _history.find(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port); if (!entry) { _history.push(entry = { last_timestamp: Date.now(), first_timestamp: Date.now(), address: address, clients_online: 0, clients_total: 0, country: 'unknown', name: 'Unknown', icon_id: 0, total_connection: 0, flag_password: false, password_hash: undefined }); } entry.last_timestamp = Date.now(); entry.total_connection++; _save(); } connection_log.log_connect = log_connect; function update_address_info(address, data) { _history.filter(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port).forEach(e => { for (const key of Object.keys(data)) { if (typeof (data[key]) !== "undefined") { e[key] = data[key]; } } }); _save(); } connection_log.update_address_info = update_address_info; function update_address_password(address, password_hash) { _history.filter(e => e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port).forEach(e => { e.password_hash = password_hash; }); _save(); } connection_log.update_address_password = update_address_password; function _save() { settings.changeGlobal(Settings.KEY_CONNECT_HISTORY, JSON.stringify(_history)); } function history() { return _history.sort((a, b) => b.last_timestamp - a.last_timestamp); } connection_log.history = history; function delete_entry(address) { _history = _history.filter(e => !(e.address.hostname.toLowerCase() == address.hostname.toLowerCase() && e.address.port == address.port)); _save(); } connection_log.delete_entry = delete_entry; loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: 'connection history load', priority: 1, function: () => __awaiter(this, void 0, void 0, function* () { _history = []; try { _history = JSON.parse(settings.global(Settings.KEY_CONNECT_HISTORY, "[]")); } catch (error) { log.warn(LogCategory.CLIENT, _translations.IQMHO28d || (_translations.IQMHO28d = tr("Failed to load connection history: {}")), error); } }) }); })(connection_log || (connection_log = {})); var Modals; (function (Modals) { function spawnConnectModal(options, defaultHost = { url: "ts.TeaSpeak.de", enforce: false }, connect_profile) { let selected_profile; const random_id = (() => { const array = new Uint32Array(10); window.crypto.getRandomValues(array); return array.join(""); })(); const modal = createModal({ header: _translations.kagWcYCB || (_translations.kagWcYCB = tr("Connect to a server")), body: $("#tmpl_connect").renderTag({ client: native_client, forum_path: settings.static("forum_path"), password_id: random_id, multi_tab: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION), default_connect_new_tab: typeof (options.default_connect_new_tab) === "boolean" && options.default_connect_new_tab }), footer: () => undefined, min_width: "28em" }); modal.htmlTag.find(".modal-body").addClass("modal-connect"); /* server list toggle */ { const container_last_servers = modal.htmlTag.find(".container-last-servers"); const button = modal.htmlTag.find(".button-toggle-last-servers"); const set_show = shown => { container_last_servers.toggleClass('shown', shown); button.find(".arrow").toggleClass('down', shown).toggleClass('up', !shown); settings.changeGlobal("connect_show_last_servers", shown); }; button.on('click', event => { set_show(!container_last_servers.hasClass("shown")); }); set_show(settings.static_global("connect_show_last_servers", false)); } const apply = (header, body, footer) => { const container_last_server_body = modal.htmlTag.find(".container-last-servers .table .body"); const container_empty = container_last_server_body.find(".body-empty"); let current_connect_data; const button_connect = footer.find(".button-connect"); const button_connect_tab = footer.find(".button-connect-new-tab"); const button_manage = body.find(".button-manage-profiles"); const input_profile = body.find(".container-select-profile select"); const input_address = body.find(".container-address input"); const input_nickname = body.find(".container-nickname input"); const input_password = body.find(".container-password input"); let updateFields = (reset_current_data) => { if (reset_current_data) { current_connect_data = undefined; container_last_server_body.find(".selected").removeClass("selected"); } let address = input_address.val().toString(); settings.changeGlobal(Settings.KEY_CONNECT_ADDRESS, address); let flag_address = !!address.match(Modals.Regex.IP_V4) || !!address.match(Modals.Regex.IP_V6) || !!address.match(Modals.Regex.DOMAIN); let nickname = input_nickname.val().toString(); if (nickname) settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, nickname); else nickname = input_nickname.attr("placeholder") || ""; let flag_nickname = nickname.length >= 3 && nickname.length <= 32; input_address.attr('pattern', flag_address ? null : '^[a]{1000}$').toggleClass('is-invalid', !flag_address); input_nickname.attr('pattern', flag_nickname ? null : '^[a]{1000}$').toggleClass('is-invalid', !flag_nickname); const flag_disabled = !flag_nickname || !flag_address || !selected_profile || !selected_profile.valid(); button_connect.prop("disabled", flag_disabled); button_connect_tab.prop("disabled", flag_disabled); }; input_address.val(defaultHost.enforce ? defaultHost.url : settings.static_global(Settings.KEY_CONNECT_ADDRESS, defaultHost.url)); input_address .on("keyup", () => updateFields(true)) .on('keydown', event => { if (event.keyCode == KeyCode.KEY_ENTER && !event.shiftKey) button_connect.trigger('click'); }); button_manage.on('click', event => { const modal = Modals.spawnSettingsModal("identity-profiles"); modal.close_listener.push(() => { input_profile.trigger('change'); }); return true; }); /* Connect Profiles */ { for (const profile of profiles.profiles()) { input_profile.append($.spawn("option").text(profile.profile_name).val(profile.id)); } input_profile.on('change', event => { selected_profile = profiles.find_profile(input_profile.val()) || profiles.default_profile(); { settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, undefined); input_nickname .attr('placeholder', selected_profile.connect_username() || "Another TeaSpeak user") .val(""); } settings.changeGlobal(Settings.KEY_CONNECT_PROFILE, selected_profile.id); input_profile.toggleClass("is-invalid", !selected_profile || !selected_profile.valid()); updateFields(true); }); input_profile.val(connect_profile && connect_profile.profile ? connect_profile.profile.id : settings.static_global(Settings.KEY_CONNECT_PROFILE, "default")).trigger('change'); } const last_nickname = settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined); if (last_nickname) /* restore */ settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, last_nickname); input_nickname.val(last_nickname); input_nickname.on("keyup", () => updateFields(true)); setTimeout(() => updateFields(false), 100); const server_address = () => { let address = input_address.val().toString(); if (address.match(Modals.Regex.IP_V6) && !address.startsWith("[")) return "[" + address + "]"; return address; }; button_connect.on('click', event => { modal.close(); const connection = server_connections.active_connection_handler(); if (connection) { connection.startConnection(current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(), selected_profile, true, { nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"), password: (current_connect_data && current_connect_data.password_hash) ? { password: current_connect_data.password_hash, hashed: true } : { password: input_password.val().toString(), hashed: false } }); } else { button_connect_tab.trigger('click'); } }); button_connect_tab.on('click', event => { modal.close(); const connection = server_connections.spawn_server_connection_handler(); server_connections.set_active_connection_handler(connection); connection.startConnection(current_connect_data ? current_connect_data.address.hostname + ":" + current_connect_data.address.port : server_address(), selected_profile, true, { nickname: input_nickname.val().toString() || input_nickname.attr("placeholder"), password: (current_connect_data && current_connect_data.password_hash) ? { password: current_connect_data.password_hash, hashed: true } : { password: input_password.val().toString(), hashed: false } }); }); /* connect history show */ { for (const entry of connection_log.history().slice(0, 10)) { $.spawn("div").addClass("row").append($.spawn("div").addClass("column delete").append($.spawn("div").addClass("icon_em client-delete")).on('click', event => { event.preventDefault(); const row = $(event.target).parents('.row'); row.hide(250, () => { row.detach(); }); connection_log.delete_entry(entry.address); container_empty.toggle(container_last_server_body.children().length > 1); })).append($.spawn("div").addClass("column name").append([ IconManager.generate_tag(IconManager.load_cached_icon(entry.icon_id)), $.spawn("a").text(entry.name) ])).append($.spawn("div").addClass("column address").text(entry.address.hostname + (entry.address.port != 9987 ? (":" + entry.address.port) : ""))).append($.spawn("div").addClass("column password").text(entry.flag_password ? _translations.JfPT4VD3 || (_translations.JfPT4VD3 = tr("Yes")) : _translations.NJt4Js9d || (_translations.NJt4Js9d = tr("No")))).append($.spawn("div").addClass("column country-name").append([ $.spawn("div").addClass("country flag-" + entry.country.toLowerCase()), $.spawn("a").text(i18n.country_name(entry.country, _translations.iZ3MJUg4 || (_translations.iZ3MJUg4 = tr("Global")))) ])).append($.spawn("div").addClass("column clients").text(entry.clients_online + "/" + entry.clients_total)).append($.spawn("div").addClass("column connections").text(entry.total_connection + "")).on('click', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); current_connect_data = entry; container_last_server_body.find(".selected").removeClass("selected"); $(event.target).parent('.row').addClass('selected'); input_address.val(entry.address.hostname + (entry.address.port != 9987 ? (":" + entry.address.port) : "")); input_password.val(entry.flag_password && entry.password_hash ? "WolverinDEV Yeahr!" : "").trigger('change'); }).on('dblclick', event => { current_connect_data = entry; button_connect.trigger('click'); }).appendTo(container_last_server_body); container_empty.toggle(false); } } }; apply(modal.htmlTag, modal.htmlTag, modal.htmlTag); modal.open(); return; } Modals.spawnConnectModal = spawnConnectModal; Modals.Regex = { //DOMAIN<:port> DOMAIN: /^(localhost|((([a-zA-Z0-9_-]{0,63}\.){0,253})?[a-zA-Z0-9_-]{0,63}\.[a-zA-Z]{2,64}))(|:(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,46}))$/, //IP<:port> 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 = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["49ae0724dd242660d7449bee6e4df1efdc7b9a7760c6c9229e4cf368f74fc565"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["49ae0724dd242660d7449bee6e4df1efdc7b9a7760c6c9229e4cf368f74fc565"] = "49ae0724dd242660d7449bee6e4df1efdc7b9a7760c6c9229e4cf368f74fc565"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "BL0CxyqI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (24,46)" }, { name: "_34ju4T0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (24,66)" }, { name: "eQQj5pTU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (77,59)" }, { name: "bm2Swfik", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (79,59)" }, { name: "YUZTrce_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (83,70)" }, { name: "FawXE9NI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBanClient.ts (84,55)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function spawnBanClient(client, entries, callback) { const max_ban_time = client.permissions.neededPermission(PermissionType.I_CLIENT_BAN_MAX_BANTIME).value; const permission_criteria_hwid = client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_HWID).granted(1); const permission_criteria_ip = client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_IP).granted(1); const permission_criteria_name = client.permissions.neededPermission(PermissionType.B_CLIENT_BAN_NAME).granted(1); const modal = createModal({ header: Array.isArray(entries) ? _translations.BL0CxyqI || (_translations.BL0CxyqI = tr("Ban clients")) : _translations._34ju4T0 || (_translations._34ju4T0 = tr("Ban client")), body: function () { let template = $("#tmpl_client_ban").renderTag({ entries: entries }); let update_duration; let update_button_ok; const button_ok = template.find(".button-apply"); const button_cancel = template.find(".button-cancel"); const input_duration_value = template.find(".container-duration input").on('change keyup', () => update_duration()); const input_duration_type = template.find(".container-duration select").on('change keyup', () => update_duration()); const container_reason = template.find(".container-reason"); const criteria_nickname = template.find(".criteria.nickname input") .prop('checked', permission_criteria_name).prop("disabled", !permission_criteria_name) .firstParent(".checkbox").toggleClass("disabled", !permission_criteria_name); const criteria_ip_address = template.find(".criteria.ip-address input") .prop('checked', permission_criteria_ip).prop("disabled", !permission_criteria_ip) .firstParent(".checkbox").toggleClass("disabled", !permission_criteria_ip); const criteria_hardware_id = template.find(".criteria.hardware-id input") .prop('checked', permission_criteria_hwid).prop("disabled", !permission_criteria_hwid) .firstParent(".checkbox").toggleClass("disabled", !permission_criteria_hwid); /* duration input handler */ { const tooltip_duration_max = template.find(".tooltip-max-time a.max"); update_duration = () => { const type = input_duration_type.val(); const value = parseInt(input_duration_value.val()); const disabled = input_duration_type.prop("disabled"); input_duration_value.prop("disabled", type === "perm" || disabled).firstParent(".input-boxed").toggleClass("disabled", type === "perm" || disabled); if (type !== "perm") { if (input_duration_value.attr("x-saved-value")) { input_duration_value.val(parseInt(input_duration_value.attr("x-saved-value"))); input_duration_value.attr("x-saved-value", null); } const selected_option = input_duration_type.find("option[value='" + type + "']"); const max = parseInt(selected_option.attr("duration-max")); input_duration_value.attr("max", max); if ((value > max && max != -1) || value < 1) { input_duration_value.firstParent(".input-boxed").addClass("is-invalid"); } else { input_duration_value.firstParent(".input-boxed").removeClass("is-invalid"); } if (max != -1) tooltip_duration_max.html((_translations.eQQj5pTU || (_translations.eQQj5pTU = tr("You're allowed to ban a maximum of "))) + "" + max + " " + Modals.duration_data[type][max == 1 ? "1-text" : "text"] + ""); else tooltip_duration_max.html(_translations.bm2Swfik || (_translations.bm2Swfik = tr("You're allowed to ban permanent."))); } else { if (value && !Number.isNaN(value)) input_duration_value.attr("x-saved-value", value); input_duration_value.attr("placeholder", _translations.YUZTrce_ || (_translations.YUZTrce_ = tr("for ever"))).val(null); tooltip_duration_max.html(_translations.FawXE9NI || (_translations.FawXE9NI = tr("You're allowed to ban permanent."))); } update_button_ok && update_button_ok(); }; /* initialize ban time */ Promise.resolve(max_ban_time).catch(error => { /* TODO: Error handling? */ return 0; }).then(max_time => { let unlimited = max_time == 0 || max_time == -1; if (unlimited || typeof (max_time) === "undefined") max_time = 0; for (const value of Object.keys(Modals.duration_data)) { input_duration_type.find("option[value='" + value + "']") .prop("disabled", !unlimited && max_time >= Modals.duration_data[value].scale) .attr("duration-scale", Modals.duration_data[value].scale) .attr("duration-max", unlimited ? -1 : Math.floor(max_time / Modals.duration_data[value].scale)); } input_duration_type.find("option[value='perm']") .prop("disabled", !unlimited) .attr("duration-scale", 0) .attr("duration-max", -1); update_duration(); }); update_duration(); } /* ban reason */ { const input = container_reason.find("textarea"); const insert_tag = (open, close) => { if (input.prop("disabled")) return; const node = input[0]; if (node.selectionStart || node.selectionStart == 0) { const startPos = node.selectionStart; const endPos = node.selectionEnd; node.value = node.value.substring(0, startPos) + open + node.value.substring(startPos, endPos) + close + node.value.substring(endPos); node.selectionEnd = endPos + open.length; node.selectionStart = node.selectionEnd; } else { node.value += open + close; node.selectionEnd = node.value.length - close.length; node.selectionStart = node.selectionEnd; } input.focus().trigger('change'); }; container_reason.find(".button-bold").on('click', () => insert_tag('[b]', '[/b]')); container_reason.find(".button-italic").on('click', () => insert_tag('[i]', '[/i]')); container_reason.find(".button-underline").on('click', () => insert_tag('[u]', '[/u]')); container_reason.find(".button-color input").on('change', event => { insert_tag('[color=' + event.target.value + ']', '[/color]'); }); } /* buttons */ { button_cancel.on('click', event => modal.close()); button_ok.on('click', event => { const duration = input_duration_type.val() === "perm" ? 0 : (1000 * parseInt(input_duration_type.find("option[value='" + input_duration_type.val() + "']").attr("duration-scale")) * parseInt(input_duration_value.val())); modal.close(); callback({ length: Math.floor(duration / 1000), reason: container_reason.find("textarea").val(), no_hwid: !criteria_hardware_id.find("input").prop("checked"), no_ip: !criteria_ip_address.find("input").prop("checked"), no_name: !criteria_nickname.find("input").prop("checked") }); }); const inputs = template.find(".input-boxed"); update_button_ok = () => { const invalid = [...inputs].find(e => $(e).hasClass("is-invalid")); button_ok.prop('disabled', !!invalid); }; update_button_ok(); } tooltip(template); return template.children(); }, footer: null, min_width: "10em", width: "30em" }); modal.open(); modal.htmlTag.find(".modal-body").addClass("modal-ban-client"); } Modals.spawnBanClient = spawnBanClient; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3029b469e8bd7e1fb5c0bfcd428b9adc83c2b65e721d1f06c8aacae048f4d0ed"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3029b469e8bd7e1fb5c0bfcd428b9adc83c2b65e721d1f06c8aacae048f4d0ed"] = "3029b469e8bd7e1fb5c0bfcd428b9adc83c2b65e721d1f06c8aacae048f4d0ed"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Ag35JegW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalYesNo.ts (14,69)" }, { name: "JkQ7VkSV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalYesNo.ts (15,67)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var Modals; (function (Modals) { function spawnYesNo(header, body, callback, properties) { properties = properties || {}; const props = ModalFunctions.warpProperties({}); props.template_properties || (props.template_properties = {}); props.template_properties.text_yes = properties.text_yes || (_translations.Ag35JegW || (_translations.Ag35JegW = tr("Yes"))); props.template_properties.text_no = properties.text_no || (_translations.JkQ7VkSV || (_translations.JkQ7VkSV = tr("No"))); props.template = "#tmpl_modal_yesno"; props.header = header; props.template_properties.question = ModalFunctions.jqueriefy(body); props.closeable = typeof (properties.closeable) !== "boolean" || properties.closeable; const modal = createModal(props); let submited = false; const button_yes = modal.htmlTag.find(".button-yes"); const button_no = modal.htmlTag.find(".button-no"); button_yes.on('click', event => { if (!submited) { submited = true; callback(true); } modal.close(); }); button_no.on('click', event => { if (!submited) { submited = true; callback(false); } modal.close(); }); modal.close_listener.push(() => button_no.trigger('click')); modal.open(); return modal; } Modals.spawnYesNo = spawnYesNo; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["7b2ae32fd19997df4d419a6d71100ae43c15bc27b3ea1a1523423a36e275ccd3"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["7b2ae32fd19997df4d419a6d71100ae43c15bc27b3ea1a1523423a36e275ccd3"] = "7b2ae32fd19997df4d419a6d71100ae43c15bc27b3ea1a1523423a36e275ccd3"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "IB5yR4Oy", path: "D:/TeaSpeak/web/shared/js/main.ts (46,66)" }, { name: "RDTk8by7", path: "D:/TeaSpeak/web/shared/js/main.ts (49,38)" }, { name: "m6cq39M5", path: "D:/TeaSpeak/web/shared/js/main.ts (111,44)" }, { name: "b5JhebTq", path: "D:/TeaSpeak/web/shared/js/main.ts (113,43)" }, { name: "q5H_DJQ9", path: "D:/TeaSpeak/web/shared/js/main.ts (124,23)" }, { name: "onq78WD6", path: "D:/TeaSpeak/web/shared/js/main.ts (142,31)" }, { name: "eIK8rj1V", path: "D:/TeaSpeak/web/shared/js/main.ts (149,22)" }, { name: "Eei5HLyp", path: "D:/TeaSpeak/web/shared/js/main.ts (155,43)" }, { name: "RvXdlEMk", path: "D:/TeaSpeak/web/shared/js/main.ts (162,38)" }, { name: "Lf15NSRg", path: "D:/TeaSpeak/web/shared/js/main.ts (166,37)" }, { name: "Dg9visVD", path: "D:/TeaSpeak/web/shared/js/main.ts (175,40)" }, { name: "dSUa5oYo", path: "D:/TeaSpeak/web/shared/js/main.ts (176,31)" }, { name: "QROnPXJ7", path: "D:/TeaSpeak/web/shared/js/main.ts (391,42)" }, { name: "gt6W14IK", path: "D:/TeaSpeak/web/shared/js/main.ts (496,45)" }, { name: "mihjffCP", path: "D:/TeaSpeak/web/shared/js/main.ts (498,35)" }, { name: "TFo_eVdJ", path: "D:/TeaSpeak/web/shared/js/main.ts (533,36)" }, { name: "M0D0FZJG", path: "D:/TeaSpeak/web/shared/js/main.ts (539,50)" }, { name: "wkNLjIGX", path: "D:/TeaSpeak/web/shared/js/main.ts (545,25)" }, { name: "JSLG1Ib8", path: "D:/TeaSpeak/web/shared/js/main.ts (554,50)" }, { name: "p16a70Ob", path: "D:/TeaSpeak/web/shared/js/main.ts (561,23)" }, { name: "JpTIODqT", path: "D:/TeaSpeak/web/shared/js/main.ts (585,39)" }, { name: "YhwU3o10", path: "D:/TeaSpeak/web/shared/js/main.ts (590,43)" }, { name: "HIJpRvc1", path: "D:/TeaSpeak/web/shared/js/main.ts (602,55)" }, { name: "IwzrZVZ4", path: "D:/TeaSpeak/web/shared/js/main.ts (612,21)" }, { name: "eW_bQNL1", path: "D:/TeaSpeak/web/shared/js/main.ts (621,43)" }, { name: "MWcN8CqM", path: "D:/TeaSpeak/web/shared/js/main.ts (624,39)" }, { name: "SbqJTJd5", path: "D:/TeaSpeak/web/shared/js/main.ts (639,35)" }, { name: "dWfMHleg", path: "D:/TeaSpeak/web/shared/js/main.ts (640,27)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /// /// /// /// /// /// var spawnYesNo = Modals.spawnYesNo; const js_render = window.jsrender || $; const native_client = window.require !== undefined; function getUserMediaFunctionPromise() { if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) return constraints => navigator.mediaDevices.getUserMedia(constraints); const _callbacked_function = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; if (!_callbacked_function) return undefined; return constraints => new Promise((resolve, reject) => _callbacked_function(constraints, resolve, reject)); } function setup_close() { window.onbeforeunload = event => { if (profiles.requires_save()) profiles.save(); if (!settings.static(Settings.KEY_DISABLE_UNLOAD_DIALOG, false)) { const active_connections = server_connections.server_connection_handlers().filter(e => e.connected); if (active_connections.length == 0) return; if (!native_client) { event.returnValue = "Are you really sure?
You're still connected!"; } else { const do_exit = () => { const dp = server_connections.server_connection_handlers().map(e => { if (e.serverConnection.connected()) return e.serverConnection.disconnect(_translations.IB5yR4Oy || (_translations.IB5yR4Oy = tr("client closed"))); return Promise.resolve(); }).map(e => e.catch(error => { console.warn(_translations.RDTk8by7 || (_translations.RDTk8by7 = tr("Failed to disconnect from server on client close: %o")), e); })); const exit = () => { const { remote } = require('electron'); remote.getCurrentWindow().close(); }; Promise.all(dp).then(exit); /* force exit after 2500ms */ setTimeout(exit, 2500); }; if (window.open_connected_question) { event.preventDefault(); event.returnValue = "question"; window.open_connected_question().then(result => { if (result) { /* prevent quitting because we try to disconnect */ window.onbeforeunload = e => e.preventDefault(); /* allow a force quit after 5 seconds */ setTimeout(() => window.onbeforeunload, 5000); do_exit(); } }); } else { /* we're in debugging mode */ do_exit(); } } } }; } function setup_jsrender() { if (!js_render) { loader.critical_error("Missing jsrender extension!"); return false; } if (!js_render.views) { loader.critical_error("Missing jsrender viewer extension!"); return false; } js_render.views.settings.allowCode(true); js_render.views.tags("rnd", (argument) => { let min = parseInt(argument.substr(0, argument.indexOf('~'))); let max = parseInt(argument.substr(argument.indexOf('~') + 1)); return (Math.round(Math.random() * (min + max + 1) - min)).toString(); }); js_render.views.tags("fmt_date", (...args) => { return moment(args[0]).format(args[1]); }); js_render.views.tags("tr", (...args) => { return tr(args[0]); }); $(".jsrender-template").each((idx, _entry) => { if (!js_render.templates(_entry.id, _entry.innerHTML)) { log.error(LogCategory.GENERAL, _translations.m6cq39M5 || (_translations.m6cq39M5 = tr("Failed to setup cache for js renderer template %s!")), _entry.id); } else log.info(LogCategory.GENERAL, _translations.b5JhebTq || (_translations.b5JhebTq = tr("Successfully loaded jsrender template %s")), _entry.id); }); return true; } function initialize() { return __awaiter(this, void 0, void 0, function* () { Settings.initialize(); try { yield i18n.initialize(); } catch (error) { console.error(_translations.q5H_DJQ9 || (_translations.q5H_DJQ9 = tr("Failed to initialized the translation system!\nError: %o")), error); loader.critical_error("Failed to setup the translation system"); return; } bipc.setup(); }); } function initialize_app() { return __awaiter(this, void 0, void 0, function* () { try { //Initialize main template const main = $("#tmpl_main").renderTag({ multi_session: !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION), app_version: app.ui_version() }).dividerfy(); $("body").append(main); } catch (error) { log.error(LogCategory.GENERAL, error); loader.critical_error(_translations.onq78WD6 || (_translations.onq78WD6 = tr("Failed to setup main page!"))); return; } control_bar = new ControlBar($("#control_bar")); /* setup the control bar */ if (!audio.player.initialize()) console.warn(_translations.eIK8rj1V || (_translations.eIK8rj1V = tr("Failed to initialize audio controller!"))); audio.player.on_ready(() => { if (audio.player.set_master_volume) audio.player.on_ready(() => audio.player.set_master_volume(settings.global(Settings.KEY_SOUND_MASTER) / 100)); else log.warn(LogCategory.GENERAL, _translations.Eei5HLyp || (_translations.Eei5HLyp = tr("Client does not support audio.player.set_master_volume()... May client is too old?"))); if (audio.recorder.device_refresh_available()) audio.recorder.refresh_devices(); }); default_recorder = new RecorderProfile("default"); default_recorder.initialize().catch(error => { log.error(LogCategory.AUDIO, _translations.RvXdlEMk || (_translations.RvXdlEMk = tr("Failed to initialize default recorder: %o")), error); }); sound.initialize().then(() => { log.info(LogCategory.AUDIO, _translations.Lf15NSRg || (_translations.Lf15NSRg = tr("Sounds initialized"))); }); sound.set_master_volume(settings.global(Settings.KEY_SOUND_MASTER_SOUNDS) / 100); yield profiles.load(); try { yield ppt.initialize(); } catch (error) { log.error(LogCategory.GENERAL, _translations.Dg9visVD || (_translations.Dg9visVD = tr("Failed to initialize ppt!\nError: %o")), error); loader.critical_error(_translations.dSUa5oYo || (_translations.dSUa5oYo = tr("Failed to initialize ppt!"))); return; } setup_close(); }); } function str2ab8(str) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } /* FIXME Dont use atob, because it sucks for non UTF-8 tings */ function arrayBufferBase64(base64) { base64 = atob(base64); const buf = new ArrayBuffer(base64.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = base64.length; i < strLen; i++) { bufView[i] = base64.charCodeAt(i); } return buf; } function base64_encode_ab(source) { const encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; let base64 = ""; const bytes = new Uint8Array(source); const byte_length = bytes.byteLength; const byte_reminder = byte_length % 3; const main_length = byte_length - byte_reminder; let a, b, c, d; let chunk; // Main loop deals with bytes in chunks of 3 for (let i = 0; i < main_length; i = i + 3) { // Combine the three bytes into a single integer chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; // Use bitmasks to extract 6-bit segments from the triplet a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18 b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12 c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6 d = (chunk & 63) >> 0; // 63 = (2^6 - 1) << 0 // Convert the raw binary segments to the appropriate ASCII encoding base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } // Deal with the remaining bytes and padding if (byte_reminder == 1) { chunk = bytes[main_length]; a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2 // Set the 4 least significant bits to zero b = (chunk & 3) << 4; // 3 = 2^2 - 1 base64 += encodings[a] + encodings[b] + '=='; } else if (byte_reminder == 2) { chunk = (bytes[main_length] << 8) | bytes[main_length + 1]; a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10 b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4 // Set the 2 least significant bits to zero c = (chunk & 15) << 2; // 15 = 2^4 - 1 base64 += encodings[a] + encodings[b] + encodings[c] + '='; } return base64; } /* class TestProxy extends bipc.MethodProxy { constructor(params: bipc.MethodProxyConnectParameters) { super(bipc.get_handler(), params.channel_id && params.client_id ? params : undefined); if(!this.is_slave()) { this.register_method(this.add_slave); } if(!this.is_master()) { this.register_method(this.say_hello); this.register_method(this.add_master); } } setup() { super.setup(); } protected on_connected() { log.info(LogCategory.IPC, "Test proxy connected"); } protected on_disconnected() { log.info(LogCategory.IPC, "Test proxy disconnected"); } private async say_hello() : Promise { log.info(LogCategory.IPC, "Hello World"); } private async add_slave(a: number, b: number) : Promise { return a + b; } private async add_master(a: number, b: number) : Promise { return a * b; } } interface Window { proxy_instance: TestProxy & {url: () => string}; } */ function handle_connect_request(properties, connection) { const profile_uuid = properties.profile || (profiles.default_profile() || { id: 'default' }).id; const profile = profiles.find_profile(profile_uuid) || profiles.default_profile(); const username = properties.username || profile.connect_username(); const password = properties.password ? properties.password.value : ""; const password_hashed = properties.password ? properties.password.hashed : false; if (profile && profile.valid()) { connection.startConnection(properties.address, profile, true, { nickname: username, password: password.length > 0 ? { password: password, hashed: password_hashed } : undefined }); server_connections.set_active_connection_handler(connection); } else { Modals.spawnConnectModal({}, { url: properties.address, enforce: true }, { profile: profile, enforce: true }); } } function main() { /* window.proxy_instance = new TestProxy({ client_id: settings.static_global("proxy_client_id", undefined), channel_id: settings.static_global("proxy_channel_id", undefined) }) as any; if(window.proxy_instance.is_master()) { window.proxy_instance.setup(); window.proxy_instance.url = () => { const data = window.proxy_instance.generate_connect_parameters(); return "proxy_channel_id=" + data.channel_id + "&proxy_client_id=" + data.client_id; }; } */ //http://localhost:63343/Web-Client/index.php?_ijt=omcpmt8b9hnjlfguh8ajgrgolr&default_connect_url=true&default_connect_type=teamspeak&default_connect_url=localhost%3A9987&disableUnloadDialog=1&loader_ignore_age=1 /* initialize font */ { const font = settings.static_global(Settings.KEY_FONT_SIZE, 14); //parseInt(getComputedStyle(document.body).fontSize) $(document.body).css("font-size", font + "px"); } /* context menu prevent */ $(document).on('contextmenu', event => { if (event.isDefaultPrevented()) return; if (!settings.static_global(Settings.KEY_DISABLE_GLOBAL_CONTEXT_MENU)) event.preventDefault(); }); top_menu.initialize(); server_connections = new ServerConnectionManager($("#connection-handlers")); control_bar.initialise(); /* before connection handler to allow property apply */ const initial_handler = server_connections.spawn_server_connection_handler(); initial_handler.acquire_recorder(default_recorder, false); control_bar.set_connection_handler(initial_handler); /** Setup the XF forum identity **/ profiles.identities.update_forum(); let _resize_timeout; $(window).on('resize', event => { if (event.target !== window) return; if (_resize_timeout) clearTimeout(_resize_timeout); _resize_timeout = setTimeout(() => { for (const connection of server_connections.server_connection_handlers()) connection.invoke_resized_on_activate = true; const active_connection = server_connections.active_connection_handler(); if (active_connection) active_connection.resize_elements(); $(".window-resize-listener").trigger('resize'); }, 1000); }); stats.initialize({ verbose: true, anonymize_ip_addresses: true, volatile_collection_only: false }); stats.register_user_count_listener(status => { log.info(LogCategory.STATISTICS, _translations.QROnPXJ7 || (_translations.QROnPXJ7 = tr("Received user count update: %o")), status); }); server_connections.set_active_connection_handler(server_connections.server_connection_handlers()[0]); window.test_upload = (message) => { message = message || "Hello World"; const connection = server_connections.active_connection_handler(); connection.fileManager.upload_file({ size: message.length, overwrite: true, channel: connection.getClient().currentChannel(), name: '/HelloWorld.txt', path: '' }).then(key => { const upload = new RequestFileUpload(key); const buffer = new Uint8Array(message.length); { for (let index = 0; index < message.length; index++) buffer[index] = message.charCodeAt(index); } upload.put_data(buffer).catch(error => { console.error(error); }); }); }; /* schedule it a bit later then the main because the main function is still within the loader */ setTimeout(() => { const connection = server_connections.active_connection_handler(); /* Modals.createChannelModal(connection, undefined, undefined, connection.permissions, (cb, perms) => { }); */ // Modals.openServerInfo(connection.channelTree.server); //Modals.createServerModal(connection.channelTree.server, properties => Promise.resolve()); //Modals.openClientInfo(connection.getClient()); //Modals.openServerInfoBandwidth(connection.channelTree.server); //Modals.openBanList(connection); /* Modals.spawnBanClient(connection,[ {name: "WolverinDEV", unique_id: "XXXX"}, {name: "WolverinDEV", unique_id: "XXXX"}, {name: "WolverinDEV", unique_id: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}, {name: "WolverinDEV", unique_id: "YYY"} ], () => {}); */ }, 4000); //Modals.spawnSettingsModal("identity-profiles"); //Modals.spawnKeySelect(console.log); //Modals.spawnBookmarkModal(); /* { const modal = createModal({ header: tr("Test Net Graph"), body: () => { const canvas = $.spawn("canvas") .css("position", "absolute") .css({ top: 0, bottom: 0, right: 0, left: 0 }); return $.spawn("div") .css("height", "5em") .css("width", "30em") .css("position", "relative") .append(canvas); }, footer: null }); const graph = new net.graph.Graph(modal.htmlTag.find("canvas")[0] as any); graph.initialize(); modal.close_listener.push(() => graph.terminate()); modal.open(); } */ /* for testing */ if (settings.static_global(Settings.KEY_USER_IS_NEW)) { const modal = Modals.openModalNewcomer(); modal.close_listener.push(() => settings.changeGlobal(Settings.KEY_USER_IS_NEW, false)); } } const task_teaweb_starter = { name: "voice app starter", function: () => __awaiter(this, void 0, void 0, function* () { try { yield initialize_app(); main(); if (!audio.player.initialized()) { log.info(LogCategory.VOICE, _translations.gt6W14IK || (_translations.gt6W14IK = tr("Initialize audio controller later!"))); if (!audio.player.initializeFromGesture) { console.error(_translations.mihjffCP || (_translations.mihjffCP = tr("Missing audio.player.initializeFromGesture"))); } else $(document).one('click', event => audio.player.initializeFromGesture()); } } catch (ex) { console.error(ex.stack); if (ex instanceof ReferenceError || ex instanceof TypeError) ex = ex.name + ": " + ex.message; loader.critical_error("Failed to invoke main function:
" + ex); } }), priority: 10 }; const task_connect_handler = { name: "Connect handler", function: () => __awaiter(this, void 0, void 0, function* () { const address = settings.static(Settings.KEY_CONNECT_ADDRESS, ""); const chandler = bipc.get_connect_handler(); if (settings.static(Settings.KEY_FLAG_CONNECT_DEFAULT, false) && address) { const connect_data = { address: address, profile: settings.static(Settings.KEY_CONNECT_PROFILE, ""), username: settings.static(Settings.KEY_CONNECT_USERNAME, ""), password: { value: settings.static(Settings.KEY_CONNECT_PASSWORD, ""), hashed: settings.static(Settings.KEY_FLAG_CONNECT_PASSWORD, false) } }; if (chandler) { try { yield chandler.post_connect_request(connect_data, () => new Promise((resolve, reject) => { spawnYesNo(_translations.TFo_eVdJ || (_translations.TFo_eVdJ = tr("Another TeaWeb instance is already running")), tra("Another TeaWeb instance is already running.{:br:}Would you like to connect there?"), response => { resolve(response); }, { closeable: false }).open(); })); log.info(LogCategory.CLIENT, _translations.M0D0FZJG || (_translations.M0D0FZJG = tr("Executed connect successfully in another browser window. Closing this window"))); const message = "You're connecting to {0} within the other TeaWeb instance.{:br:}" + "You could now close this page."; createInfoModal(_translations.wkNLjIGX || (_translations.wkNLjIGX = tr("Connecting successfully within other instance")), MessageHelper.formatMessage(tr(message), connect_data.address), { closeable: false, footer: undefined }).open(); return; } catch (error) { log.info(LogCategory.CLIENT, _translations.JSLG1Ib8 || (_translations.JSLG1Ib8 = tr("Failed to execute connect within other TeaWeb instance. Using this one. Error: %o")), error); } } loader.register_task(loader.Stage.LOADED, { priority: 0, function: () => __awaiter(this, void 0, void 0, function* () { return handle_connect_request(connect_data, server_connections.active_connection_handler() || server_connections.spawn_server_connection_handler()); }), name: _translations.p16a70Ob || (_translations.p16a70Ob = tr("default url connect")) }); } if (chandler) { /* no instance avail, so lets make us avail */ chandler.callback_available = data => { return !settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION); }; chandler.callback_execute = data => { handle_connect_request(data, server_connections.spawn_server_connection_handler()); return true; }; } loader.register_task(loader.Stage.LOADED, task_teaweb_starter); }), priority: 10 }; const task_certificate_callback = { name: "certificate accept tester", function: () => __awaiter(this, void 0, void 0, function* () { const certificate_accept = settings.static_global(Settings.KEY_CERTIFICATE_CALLBACK, undefined); if (certificate_accept) { log.info(LogCategory.IPC, _translations.JpTIODqT || (_translations.JpTIODqT = tr("Using this instance as certificate callback. ID: %s")), certificate_accept); try { try { yield bipc.get_handler().post_certificate_accpected(certificate_accept); } catch (e) { } //FIXME remove! log.info(LogCategory.IPC, _translations.YhwU3o10 || (_translations.YhwU3o10 = tr("Other instance has acknowledged out work. Closing this window."))); const seconds_tag = $.spawn("a"); let seconds = 5; let interval_id; interval_id = setInterval(() => { seconds--; seconds_tag.text(seconds.toString()); if (seconds <= 0) { clearTimeout(interval_id); log.info(LogCategory.GENERAL, _translations.HIJpRvc1 || (_translations.HIJpRvc1 = tr("Closing window"))); window.close(); return; } }, 1000); const message = "You've successfully accepted the certificate.{:br:}" + "This page will close in {0} seconds."; createInfoModal(_translations.IwzrZVZ4 || (_translations.IwzrZVZ4 = tr("Certificate acccepted successfully")), MessageHelper.formatMessage(tr(message), seconds_tag), { closeable: false, footer: undefined }).open(); return; } catch (error) { log.warn(LogCategory.IPC, _translations.eW_bQNL1 || (_translations.eW_bQNL1 = tr("Failed to successfully post certificate accept status: %o")), error); } } else { log.info(LogCategory.IPC, _translations.MWcN8CqM || (_translations.MWcN8CqM = tr("We're not used to accept certificated. Booting app."))); } loader.register_task(loader.Stage.LOADED, task_connect_handler); }), priority: 10 }; loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "jrendere initialize", function: () => __awaiter(this, void 0, void 0, function* () { try { if (!setup_jsrender()) throw "invalid load"; } catch (error) { loader.critical_error(_translations.SbqJTJd5 || (_translations.SbqJTJd5 = tr("Failed to setup jsrender"))); console.error(_translations.dWfMHleg || (_translations.dWfMHleg = tr("Failed to load jsrender! %o")), error); return; } }), priority: 100 }); loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "app starter", function: () => __awaiter(this, void 0, void 0, function* () { try { yield initialize(); if (app.is_web()) { loader.register_task(loader.Stage.LOADED, task_certificate_callback); } else { loader.register_task(loader.Stage.LOADED, task_teaweb_starter); } } catch (ex) { if (ex instanceof Error || typeof (ex.stack) !== "undefined") console.error((tr || (msg => msg))("Critical error stack trace: %o"), ex.stack); if (ex instanceof ReferenceError || ex instanceof TypeError) ex = ex.name + ": " + ex.message; loader.critical_error("Failed to boot app function:
" + ex); } }), priority: 1000 }); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["62df1507449bfd4cfeff0a258cbad9d01801f9ae54612fe2ef961ae958faf1c4"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["62df1507449bfd4cfeff0a258cbad9d01801f9ae54612fe2ef961ae958faf1c4"] = "62df1507449bfd4cfeff0a258cbad9d01801f9ae54612fe2ef961ae958faf1c4"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "aU106SIl", path: "D:/TeaSpeak/web/shared/js/stats.ts (76,46)" }, { name: "lDUhjdXK", path: "D:/TeaSpeak/web/shared/js/stats.ts (113,58)" }, { name: "VVoSHTqX", path: "D:/TeaSpeak/web/shared/js/stats.ts (123,58)" }, { name: "GfDLt7dd", path: "D:/TeaSpeak/web/shared/js/stats.ts (133,58)" }, { name: "xlw6v7TI", path: "D:/TeaSpeak/web/shared/js/stats.ts (144,62)" }, { name: "gFTimMhO", path: "D:/TeaSpeak/web/shared/js/stats.ts (173,50)" }, { name: "mHPFWzf_", path: "D:/TeaSpeak/web/shared/js/stats.ts (177,54)" }, { name: "ymcAaKXH", path: "D:/TeaSpeak/web/shared/js/stats.ts (215,55)" }, { name: "EIiJBDqh", path: "D:/TeaSpeak/web/shared/js/stats.ts (218,50)" }, { name: "NLURX_l7", path: "D:/TeaSpeak/web/shared/js/stats.ts (234,54)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var stats; (function (stats) { const LOG_PREFIX = "[Statistics] "; let CloseCodes; (function (CloseCodes) { CloseCodes[CloseCodes["UNSET"] = 3000] = "UNSET"; CloseCodes[CloseCodes["RECONNECT"] = 3001] = "RECONNECT"; CloseCodes[CloseCodes["INTERNAL_ERROR"] = 3002] = "INTERNAL_ERROR"; CloseCodes[CloseCodes["BANNED"] = 3100] = "BANNED"; })(CloseCodes = stats.CloseCodes || (stats.CloseCodes = {})); let ConnectionState; (function (ConnectionState) { ConnectionState[ConnectionState["CONNECTING"] = 0] = "CONNECTING"; ConnectionState[ConnectionState["INITIALIZING"] = 1] = "INITIALIZING"; ConnectionState[ConnectionState["CONNECTED"] = 2] = "CONNECTED"; ConnectionState[ConnectionState["UNSET"] = 3] = "UNSET"; })(ConnectionState || (ConnectionState = {})); class SessionConfig { } stats.SessionConfig = SessionConfig; class Config extends SessionConfig { } stats.Config = Config; let reconnect_timer; let current_config; let last_user_count_update; let user_count_listener = []; const DEFAULT_CONFIG = { verbose: true, reconnect_interval: 5000, anonymize_ip_addresses: true, volatile_collection_only: false }; function initialize_config_object(target_object, source_object) { for (const key of Object.keys(source_object)) { if (typeof (source_object[key]) === 'object') initialize_config_object(target_object[key] || (target_object[key] = {}), source_object[key]); if (typeof (target_object[key]) !== 'undefined') continue; target_object[key] = source_object[key]; } return target_object; } function initialize(config) { current_config = initialize_config_object(config || {}, DEFAULT_CONFIG); if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.aU106SIl || (_translations.aU106SIl = tr("Initializing statistics with this config: %o")), current_config); connection.start_connection(); } stats.initialize = initialize; function register_user_count_listener(listener) { user_count_listener.push(listener); } stats.register_user_count_listener = register_user_count_listener; function all_user_count_listener() { return user_count_listener; } stats.all_user_count_listener = all_user_count_listener; function deregister_user_count_listener(listener) { user_count_listener.remove(listener); } stats.deregister_user_count_listener = deregister_user_count_listener; let connection; (function (connection_3) { let connection; connection_3.connection_state = ConnectionState.UNSET; function start_connection() { cancel_reconnect(); close_connection(); connection_3.connection_state = ConnectionState.CONNECTING; connection = new WebSocket('wss://web-stats.teaspeak.de:27790'); if (!connection) connection = new WebSocket('wss://localhost:27788'); { const connection_copy = connection; connection.onclose = (event) => { if (connection_copy !== connection) return; if (current_config.verbose) log.warn(LogCategory.STATISTICS, _translations.lDUhjdXK || (_translations.lDUhjdXK = tr("Lost connection to statistics server (Connection closed). Reason: %o. Event object: %o")), CloseCodes[event.code] || event.code, event); if (event.code != CloseCodes.BANNED) invoke_reconnect(); }; connection.onopen = () => { if (connection_copy !== connection) return; if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.VVoSHTqX || (_translations.VVoSHTqX = tr("Successfully connected to server. Initializing session."))); connection_3.connection_state = ConnectionState.INITIALIZING; initialize_session(); }; connection.onerror = (event) => { if (connection_copy !== connection) return; if (current_config.verbose) log.warn(LogCategory.STATISTICS, _translations.GfDLt7dd || (_translations.GfDLt7dd = tr("Received an error. Closing connection. Object: %o")), event); connection.close(CloseCodes.INTERNAL_ERROR); invoke_reconnect(); }; connection.onmessage = (event) => { if (connection_copy !== connection) return; if (typeof (event.data) !== 'string') { if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.xlw6v7TI || (_translations.xlw6v7TI = tr("Received an message which isn't a string. Event object: %o")), event); return; } handle_message(event.data); }; } } connection_3.start_connection = start_connection; function close_connection() { if (connection) { const connection_copy = connection; connection = undefined; try { connection_copy.close(3001); } catch (_) { } } } connection_3.close_connection = close_connection; function invoke_reconnect() { close_connection(); if (reconnect_timer) { clearTimeout(reconnect_timer); reconnect_timer = undefined; } if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.gFTimMhO || (_translations.gFTimMhO = tr("Scheduled reconnect in %dms")), current_config.reconnect_interval); reconnect_timer = setTimeout(() => { if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.mHPFWzf_ || (_translations.mHPFWzf_ = tr("Reconnecting"))); start_connection(); }, current_config.reconnect_interval); } function cancel_reconnect() { if (reconnect_timer) { clearTimeout(reconnect_timer); reconnect_timer = undefined; } } connection_3.cancel_reconnect = cancel_reconnect; function send_message(type, data) { connection.send(JSON.stringify({ type: type, data: data })); } function initialize_session() { const config_object = {}; for (const key in SessionConfig) { if (SessionConfig.hasOwnProperty(key)) config_object[key] = current_config[key]; } send_message('initialize', { config: config_object }); } function handle_message(message) { const data_object = JSON.parse(message); const type = data_object.type; const data = data_object.data; if (typeof (handler[type]) === 'function') { if (current_config.verbose) log.debug(LogCategory.STATISTICS, _translations.ymcAaKXH || (_translations.ymcAaKXH = tr("Handling message of type %s")), type); handler[type](data); } else if (current_config.verbose) { log.warn(LogCategory.STATISTICS, _translations.EIiJBDqh || (_translations.EIiJBDqh = tr("Received message with an unknown type (%s). Dropping message. Full message: %o")), type, data_object); } } let handler; (function (handler) { function handle_notify_user_count(data) { last_user_count_update = Date.now(); for (const listener of [...user_count_listener]) listener(data); } function handle_notify_initialized(json) { if (current_config.verbose) log.info(LogCategory.STATISTICS, _translations.NLURX_l7 || (_translations.NLURX_l7 = tr("Session successfully initialized."))); connection_3.connection_state = ConnectionState.CONNECTED; } handler["notifyinitialized"] = handle_notify_initialized; handler["notifyusercount"] = handle_notify_user_count; })(handler || (handler = {})); })(connection || (connection = {})); })(stats || (stats = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["7b858729af48df671cca14f199f2fa867310e13498573a5e8a3960b4e45e2c01"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["7b858729af48df671cca14f199f2fa867310e13498573a5e8a3960b4e45e2c01"] = "7b858729af48df671cca14f199f2fa867310e13498573a5e8a3960b4e45e2c01"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3ece9db6d19ea2802862b96dde584af87cf367f473167d28b5019735dc5327af"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3ece9db6d19ea2802862b96dde584af87cf367f473167d28b5019735dc5327af"] = "3ece9db6d19ea2802862b96dde584af87cf367f473167d28b5019735dc5327af"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "H2OOfK3a", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (227,67)" }, { name: "qklBLtvc", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (259,63)" }, { name: "YjALhbl6", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (278,67)" }, { name: "_LVElZ8N", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (309,63)" }, { name: "iPkDE0bO", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (343,63)" }, { name: "GIgB621U", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (357,63)" }, { name: "Afd7iFYb", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (380,63)" }, { name: "kF1u3PFy", path: "D:/TeaSpeak/web/shared/js/connection/CommandHelper.ts (403,63)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var connection; (function (connection_4) { class CommandHelper extends connection_4.AbstractCommandHandler { constructor(connection) { super(connection); this._awaiters_unique_ids = {}; this._awaiters_unique_dbid = {}; this.volatile_handler_boss = false; this.ignore_consumed = true; } initialize() { this.connection.command_handler_boss().register_handler(this); } destroy() { if (this.connection) { const hboss = this.connection.command_handler_boss(); hboss && hboss.unregister_handler(this); } this._awaiters_unique_ids = undefined; } handle_command(command) { if (command.command == "notifyclientnamefromuid") this.handle_notifyclientnamefromuid(command.arguments); if (command.command == "notifyclientgetnamefromdbid") this.handle_notifyclientgetnamefromdbid(command.arguments); else return false; return true; } joinChannel(channel, password) { return this.connection.send_command("clientmove", { "clid": this.connection.client.getClientId(), "cid": channel.getChannelId(), "cpw": password || "" }); } sendMessage(message, type, target) { if (type == ChatType.SERVER) return this.connection.send_command("sendtextmessage", { "targetmode": 3, "target": 0, "msg": message }); else if (type == ChatType.CHANNEL) return this.connection.send_command("sendtextmessage", { "targetmode": 2, "target": target.getChannelId(), "msg": message }); else if (type == ChatType.CLIENT) return this.connection.send_command("sendtextmessage", { "targetmode": 1, "target": target.clientId(), "msg": message }); } updateClient(key, value) { let data = {}; data[key] = value; return this.connection.send_command("clientupdate", data); } info_from_uid(..._unique_ids) { return __awaiter(this, void 0, void 0, function* () { const response = []; const request = []; const unique_ids = new Set(_unique_ids); if (!unique_ids.size) return []; const unique_id_resolvers = {}; for (const unique_id of unique_ids) { request.push({ 'cluid': unique_id }); (this._awaiters_unique_ids[unique_id] || (this._awaiters_unique_ids[unique_id] = [])) .push(unique_id_resolvers[unique_id] = info => response.push(info)); } try { yield this.connection.send_command("clientgetnamefromuid", request); } catch (error) { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) { /* nothing */ } else { throw error; } } finally { /* cleanup */ for (const unique_id of Object.keys(unique_id_resolvers)) (this._awaiters_unique_ids[unique_id] || []).remove(unique_id_resolvers[unique_id]); } return response; }); } handle_notifyclientgetnamefromdbid(json) { for (const entry of json) { const info = { client_unique_id: entry["cluid"], client_nickname: entry["clname"], client_database_id: parseInt(entry["cldbid"]) }; const functions = this._awaiters_unique_dbid[info.client_database_id] || []; delete this._awaiters_unique_dbid[info.client_database_id]; for (const fn of functions) fn(info); } } info_from_cldbid(..._cldbid) { return __awaiter(this, void 0, void 0, function* () { const response = []; const request = []; const unique_cldbid = new Set(_cldbid); if (!unique_cldbid.size) return []; const unique_cldbid_resolvers = {}; for (const cldbid of unique_cldbid) { request.push({ 'cldbid': cldbid }); (this._awaiters_unique_dbid[cldbid] || (this._awaiters_unique_dbid[cldbid] = [])) .push(unique_cldbid_resolvers[cldbid] = info => response.push(info)); } try { yield this.connection.send_command("clientgetnamefromdbid", request); } catch (error) { if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) { /* nothing */ } else { throw error; } } finally { /* cleanup */ for (const cldbid of Object.keys(unique_cldbid_resolvers)) (this._awaiters_unique_dbid[cldbid] || []).remove(unique_cldbid_resolvers[cldbid]); } return response; }); } handle_notifyclientnamefromuid(json) { for (const entry of json) { const info = { client_unique_id: entry["cluid"], client_nickname: entry["clname"], client_database_id: parseInt(entry["cldbid"]) }; const functions = this._awaiters_unique_ids[entry["cluid"]] || []; delete this._awaiters_unique_ids[entry["cluid"]]; for (const fn of functions) fn(info); } } request_query_list(server_id = undefined) { return new Promise((resolve, reject) => { const single_handler = { command: "notifyquerylist", function: command => { const json = command.arguments; const result = {}; result.flag_all = json[0]["flag_all"]; result.flag_own = json[0]["flag_own"]; result.queries = []; for (const entry of json) { const rentry = {}; rentry.bounded_server = parseInt(entry["client_bound_server"]); rentry.username = entry["client_login_name"]; rentry.unique_id = entry["client_unique_identifier"]; result.queries.push(rentry); } resolve(result); return true; } }; this.handler_boss.register_single_handler(single_handler); let data = {}; if (server_id !== undefined) data["server_id"] = server_id; this.connection.send_command("querylist", data).catch(error => { this.handler_boss.remove_single_handler(single_handler); if (error instanceof CommandResult) { if (error.id == ErrorID.EMPTY_RESULT) { resolve(undefined); return; } } reject(error); }); }); } request_playlist_list() { return new Promise((resolve, reject) => { const single_handler = { command: "notifyplaylistlist", function: command => { const json = command.arguments; const result = []; for (const entry of json) { try { result.push({ playlist_id: parseInt(entry["playlist_id"]), playlist_bot_id: parseInt(entry["playlist_bot_id"]), playlist_title: entry["playlist_title"], playlist_type: parseInt(entry["playlist_type"]), playlist_owner_dbid: parseInt(entry["playlist_owner_dbid"]), playlist_owner_name: entry["playlist_owner_name"], needed_power_modify: parseInt(entry["needed_power_modify"]), needed_power_permission_modify: parseInt(entry["needed_power_permission_modify"]), needed_power_delete: parseInt(entry["needed_power_delete"]), needed_power_song_add: parseInt(entry["needed_power_song_add"]), needed_power_song_move: parseInt(entry["needed_power_song_move"]), needed_power_song_remove: parseInt(entry["needed_power_song_remove"]) }); } catch (error) { log.error(LogCategory.NETWORKING, _translations.H2OOfK3a || (_translations.H2OOfK3a = tr("Failed to parse playlist entry: %o")), error); } } resolve(result); return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("playlistlist").catch(error => { this.handler_boss.remove_single_handler(single_handler); if (error instanceof CommandResult) { if (error.id == ErrorID.EMPTY_RESULT) { resolve([]); return; } } reject(error); }); }); } request_playlist_songs(playlist_id) { return new Promise((resolve, reject) => { const single_handler = { command: "notifyplaylistsonglist", function: command => { const json = command.arguments; if (json[0]["playlist_id"] != playlist_id) { log.error(LogCategory.NETWORKING, _translations.qklBLtvc || (_translations.qklBLtvc = tr("Received invalid notification for playlist songs"))); return false; } const result = []; for (const entry of json) { try { result.push({ song_id: parseInt(entry["song_id"]), song_invoker: entry["song_invoker"], song_previous_song_id: parseInt(entry["song_previous_song_id"]), song_url: entry["song_url"], song_url_loader: entry["song_url_loader"], song_loaded: entry["song_loaded"] == true || entry["song_loaded"] == "1", song_metadata: entry["song_metadata"] }); } catch (error) { log.error(LogCategory.NETWORKING, _translations.YjALhbl6 || (_translations.YjALhbl6 = tr("Failed to parse playlist song entry: %o")), error); } } resolve(result); return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("playlistsonglist", { playlist_id: playlist_id }).catch(error => { this.handler_boss.remove_single_handler(single_handler); if (error instanceof CommandResult) { if (error.id == ErrorID.EMPTY_RESULT) { resolve([]); return; } } reject(error); }); }); } request_playlist_client_list(playlist_id) { return new Promise((resolve, reject) => { const single_handler = { command: "notifyplaylistclientlist", function: command => { const json = command.arguments; if (json[0]["playlist_id"] != playlist_id) { log.error(LogCategory.NETWORKING, _translations._LVElZ8N || (_translations._LVElZ8N = tr("Received invalid notification for playlist clients"))); return false; } const result = []; for (const entry of json) result.push(parseInt(entry["cldbid"])); resolve(result.filter(e => !isNaN(e))); return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("playlistclientlist", { playlist_id: playlist_id }).catch(error => { this.handler_boss.remove_single_handler(single_handler); if (error instanceof CommandResult && error.id == ErrorID.EMPTY_RESULT) { resolve([]); return; } reject(error); }); }); } request_clients_by_server_group(group_id) { return __awaiter(this, void 0, void 0, function* () { //servergroupclientlist sgid=2 //notifyservergroupclientlist sgid=6 cldbid=2 client_nickname=WolverinDEV client_unique_identifier=xxjnc14LmvTk+Lyrm8OOeo4tOqw= return new Promise((resolve, reject) => { const single_handler = { command: "notifyservergroupclientlist", function: command => { if (command.arguments[0]["sgid"] != group_id) { log.error(LogCategory.NETWORKING, _translations.iPkDE0bO || (_translations.iPkDE0bO = tr("Received invalid notification for server group client list"))); return false; } try { const result = []; for (const entry of command.arguments) result.push({ client_database_id: parseInt(entry["cldbid"]), client_nickname: entry["client_nickname"], client_unique_identifier: entry["client_unique_identifier"] }); resolve(result); } catch (error) { log.error(LogCategory.NETWORKING, _translations.GIgB621U || (_translations.GIgB621U = tr("Failed to parse server group client list: %o")), error); reject("failed to parse info"); } return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("servergroupclientlist", { sgid: group_id }).catch(error => { this.handler_boss.remove_single_handler(single_handler); reject(error); }); }); }); } request_playlist_info(playlist_id) { return new Promise((resolve, reject) => { const single_handler = { command: "notifyplaylistinfo", function: command => { const json = command.arguments[0]; if (json["playlist_id"] != playlist_id) { log.error(LogCategory.NETWORKING, _translations.Afd7iFYb || (_translations.Afd7iFYb = tr("Received invalid notification for playlist info"))); return; } try { //resolve resolve({ playlist_id: parseInt(json["playlist_id"]), playlist_title: json["playlist_title"], playlist_description: json["playlist_description"], playlist_type: parseInt(json["playlist_type"]), playlist_owner_dbid: parseInt(json["playlist_owner_dbid"]), playlist_owner_name: json["playlist_owner_name"], playlist_flag_delete_played: json["playlist_flag_delete_played"] == true || json["playlist_flag_delete_played"] == "1", playlist_flag_finished: json["playlist_flag_finished"] == true || json["playlist_flag_finished"] == "1", playlist_replay_mode: parseInt(json["playlist_replay_mode"]), playlist_current_song_id: parseInt(json["playlist_current_song_id"]), playlist_max_songs: parseInt(json["playlist_max_songs"]) }); } catch (error) { log.error(LogCategory.NETWORKING, _translations.kF1u3PFy || (_translations.kF1u3PFy = tr("Failed to parse playlist info: %o")), error); reject("failed to parse info"); } return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("playlistinfo", { playlist_id: playlist_id }).catch(error => { this.handler_boss.remove_single_handler(single_handler); reject(error); }); }); } /** * @deprecated * Its just a workaround for the query management. * There is no garante that the whoami trick will work forever */ current_virtual_server_id() { if (this._who_am_i) return Promise.resolve(parseInt(this._who_am_i["virtualserver_id"])); return new Promise((resolve, reject) => { const single_handler = { function: command => { if (command.command != "" && command.command.indexOf("=") == -1) return false; this._who_am_i = command.arguments[0]; resolve(parseInt(this._who_am_i["virtualserver_id"])); return true; } }; this.handler_boss.register_single_handler(single_handler); this.connection.send_command("whoami").catch(error => { this.handler_boss.remove_single_handler(single_handler); reject(error); }); }); } } connection_4.CommandHelper = CommandHelper; })(connection || (connection = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5231f662a327146d48f3085c7c57a8416d97bfc052e39b639f51171e8915807a"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5231f662a327146d48f3085c7c57a8416d97bfc052e39b639f51171e8915807a"] = "5231f662a327146d48f3085c7c57a8416d97bfc052e39b639f51171e8915807a"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "dXuuqi93", path: "D:/TeaSpeak/web/shared/js/connection/HandshakeHandler.ts (75,39)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var connection; (function (connection) { class HandshakeHandler { constructor(profile, parameters) { this.failed = false; this.profile = profile; this.parameters = parameters; } setConnection(con) { this.connection = con; } initialize() { this.handshake_handler = this.profile.spawn_identity_handshake_handler(this.connection); if (!this.handshake_handler) { this.handshake_failed("failed to create identity handler"); return; } this.handshake_handler.register_callback((flag, message) => { if (flag) this.handshake_finished(); else this.handshake_failed(message); }); } get_identity_handler() { return this.handshake_handler; } startHandshake() { this.handshake_handler.start_handshake(); } on_teamspeak() { const type = this.profile.selected_type(); if (type == profiles.identities.IdentitifyType.TEAMSPEAK) this.handshake_finished(); else { if (this.failed) return; this.failed = true; this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_TEAMSPEAK_REQUIRED); } } handshake_failed(message) { if (this.failed) return; this.failed = true; this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_FAILED, message); } handshake_finished(version) { const _native = window["native"]; if (native_client && _native && _native.client_version && !version) { _native.client_version() .then(this.handshake_finished.bind(this)) .catch(error => { console.error(_translations.dXuuqi93 || (_translations.dXuuqi93 = tr("Failed to get version:"))); console.error(error); this.handshake_finished("?.?.?"); }); return; } const git_version = settings.static_global("version", "unknown"); const browser_name = (navigator.browserSpecs || {})["name"] || " "; let data = { client_nickname: this.parameters.nickname || "Another TeaSpeak user", client_platform: (browser_name ? browser_name + " " : "") + navigator.platform, client_version: "TeaWeb " + git_version + " (" + navigator.userAgent + ")", client_version_sign: undefined, client_default_channel: (this.parameters.channel || {}).target, client_default_channel_password: (this.parameters.channel || {}).password, client_default_token: this.parameters.token, client_server_password: this.parameters.password ? this.parameters.password.password : undefined, client_browser_engine: navigator.product, client_input_hardware: this.connection.client.client_status.input_hardware, client_output_hardware: false, client_input_muted: this.connection.client.client_status.input_muted, client_output_muted: this.connection.client.client_status.output_muted, }; //0.0.1 [Build: 1549713549] Linux 7XvKmrk7uid2ixHFeERGqcC8vupeQqDypLtw2lY9slDNPojEv//F47UaDLG+TmVk4r6S0TseIKefzBpiRtLDAQ== if (version) { data.client_version = "TeaClient "; data.client_version += " " + version; const os = require("os"); const arch_mapping = { "x32": "32bit", "x64": "64bit" }; data.client_version += " " + (arch_mapping[os.arch()] || os.arch()); const os_mapping = { "win32": "Windows", "linux": "Linux" }; data.client_platform = (os_mapping[os.platform()] || os.platform()); } /* required to keep compatibility */ if (this.profile.selected_type() === profiles.identities.IdentitifyType.TEAMSPEAK) { data["client_key_offset"] = this.profile.selected_identity().hash_number; } this.connection.send_command("clientinit", data).catch(error => { if (error instanceof CommandResult) { if (error.id == 1028) { this.connection.client.handleDisconnect(DisconnectReason.SERVER_REQUIRES_PASSWORD); } else if (error.id == 783 || error.id == 519) { error.extra_message = isNaN(parseInt(error.extra_message)) ? "8" : error.extra_message; this.connection.client.handleDisconnect(DisconnectReason.IDENTITY_TOO_LOW, error); } else if (error.id == 3329) { this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_BANNED, error); } else { this.connection.client.handleDisconnect(DisconnectReason.CLIENT_KICKED, error); } } else this.connection.disconnect(); }); } } connection.HandshakeHandler = HandshakeHandler; })(connection || (connection = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["060051cbf8eeed8239b90b8a8a80d575412f10f065dbed5bd8be5dd5e4c9fd8b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["060051cbf8eeed8239b90b8a8a80d575412f10f065dbed5bd8be5dd5e4c9fd8b"] = "060051cbf8eeed8239b90b8a8a80d575412f10f065dbed5bd8be5dd5e4c9fd8b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var ErrorID; (function (ErrorID) { ErrorID[ErrorID["NOT_IMPLEMENTED"] = 2] = "NOT_IMPLEMENTED"; ErrorID[ErrorID["COMMAND_NOT_FOUND"] = 256] = "COMMAND_NOT_FOUND"; ErrorID[ErrorID["PERMISSION_ERROR"] = 2568] = "PERMISSION_ERROR"; ErrorID[ErrorID["EMPTY_RESULT"] = 1281] = "EMPTY_RESULT"; ErrorID[ErrorID["PLAYLIST_IS_IN_USE"] = 8451] = "PLAYLIST_IS_IN_USE"; ErrorID[ErrorID["FILE_ALREADY_EXISTS"] = 2050] = "FILE_ALREADY_EXISTS"; ErrorID[ErrorID["CLIENT_INVALID_ID"] = 512] = "CLIENT_INVALID_ID"; ErrorID[ErrorID["CONVERSATION_INVALID_ID"] = 8704] = "CONVERSATION_INVALID_ID"; ErrorID[ErrorID["CONVERSATION_MORE_DATA"] = 8705] = "CONVERSATION_MORE_DATA"; ErrorID[ErrorID["CONVERSATION_IS_PRIVATE"] = 8706] = "CONVERSATION_IS_PRIVATE"; })(ErrorID || (ErrorID = {})); class CommandResult { constructor(json) { this.json = json; this.id = parseInt(json["id"]); this.message = json["msg"]; this.extra_message = ""; if (json["extra_msg"]) this.extra_message = json["extra_msg"]; this.success = this.id == 0; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["44b39e0f81c423563b3da77145e11d4583bdaf437fa62b0b33c325db0e94385b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["44b39e0f81c423563b3da77145e11d4583bdaf437fa62b0b33c325db0e94385b"] = "44b39e0f81c423563b3da77145e11d4583bdaf437fa62b0b33c325db0e94385b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } // ASN.1 JavaScript decoder // Copyright (c) 2008-2018 Lapo Luchini // Copyright (c) 2019-2019 Markus Hadenfeldt // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. var asn1; (function (asn1) { const ellipsis = "\u2026"; function string_cut(str, len) { if (str.length > len) str = str.substring(0, len) + ellipsis; return str; } class Stream { constructor(data, position) { if (data instanceof Stream) this.data = data.data; else this.data = data; this.position = position; } length() { if (this.data instanceof ArrayBuffer) return this.data.byteLength; return this.data.length; } get(position) { if (position === undefined) position = this.position++; if (position >= this.length()) throw 'Requesting byte offset ' + this.position + ' on a stream of length ' + this.length(); return (typeof (this.data) === "string") ? this.data.charCodeAt(position) : this.data[position]; } hexByte(byte) { return Stream.HEX_DIGITS.charAt((byte >> 4) & 0xF) + Stream.HEX_DIGITS.charAt(byte & 0xF); } parseStringISO(start, end) { let s = ""; for (let i = start; i < end; ++i) s += String.fromCharCode(this.get(i)); return s; } parseStringUTF(start, end) { let s = ""; for (let i = start; i < end;) { let c = this.get(i++); if (c < 128) s += String.fromCharCode(c); else if ((c > 191) && (c < 224)) s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F)); else s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F)); } return s; } parseStringBMP(start, end) { let str = "", hi, lo; for (let i = start; i < end;) { hi = this.get(i++); lo = this.get(i++); str += String.fromCharCode((hi << 8) | lo); } return str; } parseTime(start, end, shortYear) { let s = this.parseStringISO(start, end), m = (shortYear ? Stream.reTimeS : Stream.reTimeL).exec(s); if (!m) return "Unrecognized time: " + s; if (shortYear) { // to avoid querying the timer, use the fixed range [1970, 2069] // it will conform with ITU X.400 [-10, +40] sliding window until 2030 //m[1] = +m[1]; //m[1] += (parseInt(m[1]) < 70) ? 2000 : 1900; throw "fixme!"; } s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; if (m[5]) { s += ":" + m[5]; if (m[6]) { s += ":" + m[6]; if (m[7]) s += "." + m[7]; } } if (m[8]) { s += " UTC"; if (m[8] != 'Z') { s += m[8]; if (m[9]) s += ":" + m[9]; } } return s; } ; parseInteger(start, end) { let current = this.get(start); let negative = (current > 127); let padding = negative ? 255 : 0; let length; let descriptor; // skip unuseful bits (not allowed in DER) while (current == padding && ++start < end) current = this.get(start); length = end - start; if (length === 0) return negative ? '-1' : '0'; // show bit length of huge integers if (length > 4) { descriptor = current; length <<= 3; /* calculate bit length */ while (((descriptor ^ padding) & 0x80) == 0) { descriptor <<= 1; --length; } descriptor = "(" + length + " bit)\n"; } // decode the integer if (negative) current = current - 256; let number = ""; if (typeof (Int10) !== "undefined") { let n = new Int10(current); for (let i = start + 1; i < end; ++i) n.mulAdd(256, this.get(i)); number = n.toString(); } else { let n = 0; for (let i = start + 1; i < end; ++i) { n <<= 8; n += this.get(i); } number = n.toString(); } return descriptor + number; } ; isASCII(start, end) { for (let i = start; i < end; ++i) { const c = this.get(i); if (c < 32 || c > 176) return false; } return true; } ; parseBitString(start, end, maxLength) { let unusedBit = this.get(start), lenBit = ((end - start - 1) << 3) - unusedBit, intro = "(" + lenBit + " bit)\n", s = ""; for (let i = start + 1; i < end; ++i) { let b = this.get(i), skip = (i == end - 1) ? unusedBit : 0; for (let j = 7; j >= skip; --j) s += (b >> j) & 1 ? "1" : "0"; if (s.length > maxLength) return intro + string_cut(s, maxLength); } return intro + s; } ; parseOctetString(start, end, maxLength) { if (this.isASCII(start, end)) return string_cut(this.parseStringISO(start, end), maxLength); let len = end - start, s = "(" + len + " byte)\n"; maxLength /= 2; // we work in bytes if (len > maxLength) end = start + maxLength; for (let i = start; i < end; ++i) s += this.hexByte(this.get(i)); if (len > maxLength) s += ellipsis; return s; } ; parseOID(start, end, maxLength) { let s = '', n = new Int10(), bits = 0; for (let i = start; i < end; ++i) { let v = this.get(i); n.mulAdd(128, v & 0x7F); bits += 7; if (!(v & 0x80)) { // finished if (s === '') { n = n.simplify(); if (n instanceof Int10) { n.sub(80); s = "2." + n.toString(); } else { let m = n < 80 ? n < 40 ? 0 : 1 : 2; s = m + "." + (n - m * 40); } } else s += "." + n.toString(); if (s.length > maxLength) return string_cut(s, maxLength); n = new Int10(); bits = 0; } } if (bits > 0) s += ".incomplete"; /* FIXME if (typeof oids === 'object') { let oid = oids[s]; if (oid) { if (oid.d) s += "\n" + oid.d; if (oid.c) s += "\n" + oid.c; if (oid.w) s += "\n(warning!)"; } } */ return s; } ; } Stream.HEX_DIGITS = "0123456789ABCDEF"; Stream.reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; Stream.reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; asn1.Stream = Stream; let TagClass; (function (TagClass) { TagClass[TagClass["UNIVERSAL"] = 0] = "UNIVERSAL"; TagClass[TagClass["APPLICATION"] = 1] = "APPLICATION"; TagClass[TagClass["CONTEXT"] = 2] = "CONTEXT"; TagClass[TagClass["PRIVATE"] = 3] = "PRIVATE"; })(TagClass = asn1.TagClass || (asn1.TagClass = {})); let TagType; (function (TagType) { TagType[TagType["EOC"] = 0] = "EOC"; TagType[TagType["BOOLEAN"] = 1] = "BOOLEAN"; TagType[TagType["INTEGER"] = 2] = "INTEGER"; TagType[TagType["BIT_STRING"] = 3] = "BIT_STRING"; TagType[TagType["OCTET_STRING"] = 4] = "OCTET_STRING"; TagType[TagType["NULL"] = 5] = "NULL"; TagType[TagType["OBJECT_IDENTIFIER"] = 6] = "OBJECT_IDENTIFIER"; TagType[TagType["ObjectDescriptor"] = 7] = "ObjectDescriptor"; TagType[TagType["EXTERNAL"] = 8] = "EXTERNAL"; TagType[TagType["REAL"] = 9] = "REAL"; TagType[TagType["ENUMERATED"] = 10] = "ENUMERATED"; TagType[TagType["EMBEDDED_PDV"] = 11] = "EMBEDDED_PDV"; TagType[TagType["UTF8String"] = 12] = "UTF8String"; TagType[TagType["SEQUENCE"] = 16] = "SEQUENCE"; TagType[TagType["SET"] = 17] = "SET"; TagType[TagType["NumericString"] = 18] = "NumericString"; TagType[TagType["PrintableString"] = 19] = "PrintableString"; TagType[TagType["TeletextString"] = 20] = "TeletextString"; TagType[TagType["VideotexString"] = 21] = "VideotexString"; TagType[TagType["IA5String"] = 22] = "IA5String"; TagType[TagType["UTCTime"] = 23] = "UTCTime"; TagType[TagType["GeneralizedTime"] = 24] = "GeneralizedTime"; TagType[TagType["GraphicString"] = 25] = "GraphicString"; TagType[TagType["VisibleString"] = 26] = "VisibleString"; TagType[TagType["GeneralString"] = 27] = "GeneralString"; TagType[TagType["UniversalString"] = 28] = "UniversalString"; TagType[TagType["BMPString"] = 30] = "BMPString"; })(TagType = asn1.TagType || (asn1.TagType = {})); class ASN1Tag { constructor(stream) { let buf = stream.get(); this.tagClass = buf >> 6; this.tagConstructed = ((buf & 0x20) !== 0); this.tagNumber = buf & 0x1F; if (this.tagNumber == 0x1F) { // long tag let n = new Int10(); do { buf = stream.get(); n.mulAdd(128, buf & 0x7F); } while (buf & 0x80); this.tagNumber = n.simplify(); } } isUniversal() { return this.tagClass === 0x00; } ; isEOC() { return this.tagClass === 0x00 && this.tagNumber === 0x00; } ; } class ASN1 { constructor(stream, header, length, tag, children) { this.stream = stream; this.header = header; this.length = length; this.tag = tag; this.children = children; } content(max_length, type) { if (this.tag === undefined) return null; if (max_length === undefined) max_length = Infinity; let content = this.posContent(), len = Math.abs(this.length); if (!this.tag.isUniversal()) { if (this.children !== null) return "(" + this.children.length + " elem)"; return this.stream.parseOctetString(content, content + len, max_length); } switch (type || this.tag.tagNumber) { case 0x01: // BOOLEAN return (this.stream.get(content) === 0) ? "false" : "true"; case 0x02: // INTEGER return this.stream.parseInteger(content, content + len); case 0x03: // BIT_STRING return this.children ? "(" + this.children.length + " elem)" : this.stream.parseBitString(content, content + len, max_length); case 0x04: // OCTET_STRING return this.children ? "(" + this.children.length + " elem)" : this.stream.parseOctetString(content, content + len, max_length); //case 0x05: // NULL case 0x06: // OBJECT_IDENTIFIER return this.stream.parseOID(content, content + len, max_length); //case 0x07: // ObjectDescriptor //case 0x08: // EXTERNAL //case 0x09: // REAL //case 0x0A: // ENUMERATED //case 0x0B: // EMBEDDED_PDV case 0x10: // SEQUENCE case 0x11: // SET if (this.children !== null) return "(" + this.children.length + " elem)"; else return "(no elem)"; case 0x0C: // UTF8String return string_cut(this.stream.parseStringUTF(content, content + len), max_length); case 0x12: // NumericString case 0x13: // PrintableString case 0x14: // TeletexString case 0x15: // VideotexString case 0x16: // IA5String //case 0x19: // GraphicString case 0x1A: // VisibleString //case 0x1B: // GeneralString //case 0x1C: // UniversalString return string_cut(this.stream.parseStringISO(content, content + len), max_length); case 0x1E: // BMPString return string_cut(this.stream.parseStringBMP(content, content + len), max_length); case 0x17: // UTCTime case 0x18: // GeneralizedTime return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17)); } return null; } ; typeName() { switch (this.tag.tagClass) { case 0: // universal return TagType[this.tag.tagNumber] || ("Universal_" + this.tag.tagNumber.toString()); case 1: return "Application_" + this.tag.tagNumber.toString(); case 2: return "[" + this.tag.tagNumber.toString() + "]"; // Context case 3: return "Private_" + this.tag.tagNumber.toString(); } } ; toString() { return this.typeName() + "@" + this.stream.position + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.children === null) ? 'null' : this.children.length) + "]"; } toPrettyString(indent) { if (indent === undefined) indent = ''; let s = indent + this.typeName() + " @" + this.stream.position; if (this.length >= 0) s += "+"; s += this.length; if (this.tag.tagConstructed) s += " (constructed)"; else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.children !== null)) s += " (encapsulates)"; let content = this.content(); if (content) s += ": " + content.replace(/\n/g, '|'); s += "\n"; if (this.children !== null) { indent += ' '; for (let i = 0, max = this.children.length; i < max; ++i) s += this.children[i].toPrettyString(indent); } return s; } ; posStart() { return this.stream.position; } ; posContent() { return this.stream.position + this.header; } ; posEnd() { return this.stream.position + this.header + Math.abs(this.length); } ; static decodeLength(stream) { let buf = stream.get(); const len = buf & 0x7F; if (len == buf) return len; if (len > 6) // no reason to use Int10, as it would be a huge buffer anyways throw "Length over 48 bits not supported at position " + (stream.position - 1); if (len === 0) return null; // undefined buf = 0; for (let i = 0; i < len; ++i) buf = (buf << 8) + stream.get(); return buf; } ; static encodeLength(buffer, offset, length) { if (length < 0x7F) { buffer[offset] = length; } else { buffer[offset] = 0x80; let index = 1; while (length > 0) { buffer[offset + index++] = length & 0xFF; length >>= 8; buffer[offset] += 1; } } } } asn1.ASN1 = ASN1; function decode0(stream) { const streamStart = new Stream(stream, 0); /* copy */ const tag = new ASN1Tag(stream); let len = ASN1.decodeLength(stream); const start = stream.position; const length_header = start - streamStart.position; let children = null; const query_children = () => { children = []; if (len !== null) { const end = start + len; if (end > stream.length()) throw 'Container at offset ' + start + ' has a length of ' + len + ', which is past the end of the stream'; while (stream.position < end) children[children.length] = decode0(stream); if (stream.position != end) throw 'Content size is not correct for container at offset ' + start; } else { // undefined length try { while (true) { const s = decode0(stream); if (s.tag.isEOC()) break; children[children.length] = s; } len = start - stream.position; // undefined lengths are represented as negative values } catch (e) { throw 'Exception while decoding undefined length content at offset ' + start + ': ' + e; } } }; if (tag.tagConstructed) { // must have valid content query_children(); } else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) { // sometimes BitString and OctetString are used to encapsulate ASN.1 try { if (tag.tagNumber == 0x03) if (stream.get() != 0) throw "BIT STRINGs with unused bits cannot encapsulate."; query_children(); for (let i = 0; i < children.length; ++i) if (children[i].tag.isEOC()) throw 'EOC is not supposed to be actual content.'; } catch (e) { // but silently ignore when they don't children = null; //DEBUG console.log('Could not decode structure at ' + start + ':', e); } } if (children === null) { if (len === null) throw "We can't skip over an invalid tag with undefined length at offset " + start; stream.position = start + Math.abs(len); } return new ASN1(streamStart, length_header, len, tag, children); } function decode(stream) { return decode0(new Stream(stream, 0)); } asn1.decode = decode; })(asn1 || (asn1 = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["40e158fd8e3f636d8ce20ba2e787957a9f5aee6c7612e4e69590e058bdcabe54"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["40e158fd8e3f636d8ce20ba2e787957a9f5aee6c7612e4e69590e058bdcabe54"] = "40e158fd8e3f636d8ce20ba2e787957a9f5aee6c7612e4e69590e058bdcabe54"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } class Crc32 { constructor() { this.crc = -1 >>> 0; } update(data) { const dataView = new Uint8Array(data, 0); const len = dataView.length; for (let i = 0; i < len; i++) { this.crc = (this.crc >>> 8) ^ Crc32.lookup[(this.crc ^ dataView[i]) & 0xFF]; } } ; digest(radix) { const buffer = new ArrayBuffer(4); const dv = new DataView(buffer); dv.setUint32(0, ~this.crc >>> 0, false); return dv.getUint32(0).toString(radix || 16); } ; } Crc32.lookup = [ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D ]; typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["8ba95a24447d1d808ee3655ba65ce013c1e572413ea5c442d930a3012aa144f1"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["8ba95a24447d1d808ee3655ba65ce013c1e572413ea5c442d930a3012aa144f1"] = "8ba95a24447d1d808ee3655ba65ce013c1e572413ea5c442d930a3012aa144f1"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var hex; (function (hex) { function encode(buffer) { let hexCodes = []; let view = new DataView(buffer); for (let i = 0; i < view.byteLength % 4; i++) { let value = view.getUint32(i * 4); let stringValue = value.toString(16); let padding = '00000000'; let paddedValue = (padding + stringValue).slice(-padding.length); hexCodes.push(paddedValue); } for (let i = (view.byteLength % 4) * 4; i < view.byteLength; i++) { let value = view.getUint8(i).toString(16); let padding = '00'; hexCodes.push((padding + value).slice(-padding.length)); } return hexCodes.join(""); } hex.encode = encode; })(hex || (hex = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e1d54bf625c362c99387a9e5848a1d964a10e12d46a4b54b6e6afe928d0daca3"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e1d54bf625c362c99387a9e5848a1d964a10e12d46a4b54b6e6afe928d0daca3"] = "e1d54bf625c362c99387a9e5848a1d964a10e12d46a4b54b6e6afe928d0daca3"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "flaw3JIB", path: "D:/TeaSpeak/web/shared/js/i18n/country.ts (1498,77)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var i18n; (function (i18n) { const country_infos = []; const alpha_2_map = {}; const fill_country_infos = (array) => { array.push({ name: "Afghanistan", alpha_2: "AF", alpha_3: "AFG", un_code: 4 }); array.push({ name: "Aland Islands", alpha_2: "AX", alpha_3: "ALA", un_code: 248 }); array.push({ name: "Albania", alpha_2: "AL", alpha_3: "ALB", un_code: 8 }); array.push({ name: "Algeria", alpha_2: "DZ", alpha_3: "DZA", un_code: 12 }); array.push({ name: "American Samoa", alpha_2: "AS", alpha_3: "ASM", un_code: 16 }); array.push({ name: "Andorra", alpha_2: "AD", alpha_3: "AND", un_code: 20 }); array.push({ name: "Angola", alpha_2: "AO", alpha_3: "AGO", un_code: 24 }); array.push({ name: "Anguilla", alpha_2: "AI", alpha_3: "AIA", un_code: 660 }); array.push({ name: "Antarctica", alpha_2: "AQ", alpha_3: "ATA", un_code: 10 }); array.push({ name: "Antigua and Barbuda", alpha_2: "AG", alpha_3: "ATG", un_code: 28 }); array.push({ name: "Argentina", alpha_2: "AR", alpha_3: "ARG", un_code: 32 }); array.push({ name: "Armenia", alpha_2: "AM", alpha_3: "ARM", un_code: 51 }); array.push({ name: "Aruba", alpha_2: "AW", alpha_3: "ABW", un_code: 533 }); array.push({ name: "Australia", alpha_2: "AU", alpha_3: "AUS", un_code: 36 }); array.push({ name: "Austria", alpha_2: "AT", alpha_3: "AUT", un_code: 40 }); array.push({ name: "Azerbaijan", alpha_2: "AZ", alpha_3: "AZE", un_code: 31 }); array.push({ name: "Bahamas", alpha_2: "BS", alpha_3: "BHS", un_code: 44 }); array.push({ name: "Bahrain", alpha_2: "BH", alpha_3: "BHR", un_code: 48 }); array.push({ name: "Bangladesh", alpha_2: "BD", alpha_3: "BGD", un_code: 50 }); array.push({ name: "Barbados", alpha_2: "BB", alpha_3: "BRB", un_code: 52 }); array.push({ name: "Belarus", alpha_2: "BY", alpha_3: "BLR", un_code: 112 }); array.push({ name: "Belgium", alpha_2: "BE", alpha_3: "BEL", un_code: 56 }); array.push({ name: "Belize", alpha_2: "BZ", alpha_3: "BLZ", un_code: 84 }); array.push({ name: "Benin", alpha_2: "BJ", alpha_3: "BEN", un_code: 204 }); array.push({ name: "Bermuda", alpha_2: "BM", alpha_3: "BMU", un_code: 60 }); array.push({ name: "Bhutan", alpha_2: "BT", alpha_3: "BTN", un_code: 64 }); array.push({ name: "Bolivia", alpha_2: "BO", alpha_3: "BOL", un_code: 68 }); array.push({ name: "Bosnia and Herzegovina", alpha_2: "BA", alpha_3: "BIH", un_code: 70 }); array.push({ name: "Botswana", alpha_2: "BW", alpha_3: "BWA", un_code: 72 }); array.push({ name: "Bouvet Island", alpha_2: "BV", alpha_3: "BVT", un_code: 74 }); array.push({ name: "Brazil", alpha_2: "BR", alpha_3: "BRA", un_code: 76 }); array.push({ name: "British Virgin Islands", alpha_2: "VG", alpha_3: "VGB", un_code: 92 }); array.push({ name: "British Indian Ocean Territory", alpha_2: "IO", alpha_3: "IOT", un_code: 86 }); array.push({ name: "Brunei Darussalam", alpha_2: "BN", alpha_3: "BRN", un_code: 96 }); array.push({ name: "Bulgaria", alpha_2: "BG", alpha_3: "BGR", un_code: 100 }); array.push({ name: "Burkina Faso", alpha_2: "BF", alpha_3: "BFA", un_code: 854 }); array.push({ name: "Burundi", alpha_2: "BI", alpha_3: "BDI", un_code: 108 }); array.push({ name: "Cambodia", alpha_2: "KH", alpha_3: "KHM", un_code: 116 }); array.push({ name: "Cameroon", alpha_2: "CM", alpha_3: "CMR", un_code: 120 }); array.push({ name: "Canada", alpha_2: "CA", alpha_3: "CAN", un_code: 124 }); array.push({ name: "Cape Verde", alpha_2: "CV", alpha_3: "CPV", un_code: 132 }); array.push({ name: "Cayman Islands", alpha_2: "KY", alpha_3: "CYM", un_code: 136 }); array.push({ name: "Central African Republic", alpha_2: "CF", alpha_3: "CAF", un_code: 140 }); array.push({ name: "Chad", alpha_2: "TD", alpha_3: "TCD", un_code: 148 }); array.push({ name: "Chile", alpha_2: "CL", alpha_3: "CHL", un_code: 152 }); array.push({ name: "China", alpha_2: "CN", alpha_3: "CHN", un_code: 156 }); array.push({ name: "Hong Kong, SAR China", alpha_2: "HK", alpha_3: "HKG", un_code: 344 }); array.push({ name: "Macao, SAR China", alpha_2: "MO", alpha_3: "MAC", un_code: 446 }); array.push({ name: "Christmas Island", alpha_2: "CX", alpha_3: "CXR", un_code: 162 }); array.push({ name: "Cocos (Keeling) Islands", alpha_2: "CC", alpha_3: "CCK", un_code: 166 }); array.push({ name: "Colombia", alpha_2: "CO", alpha_3: "COL", un_code: 170 }); array.push({ name: "Comoros", alpha_2: "KM", alpha_3: "COM", un_code: 174 }); array.push({ name: "Congo (Brazzaville)", alpha_2: "CG", alpha_3: "COG", un_code: 178 }); array.push({ name: "Congo, (Kinshasa)", alpha_2: "CD", alpha_3: "COD", un_code: 180 }); array.push({ name: "Cook Islands", alpha_2: "CK", alpha_3: "COK", un_code: 184 }); array.push({ name: "Costa Rica", alpha_2: "CR", alpha_3: "CRI", un_code: 188 }); array.push({ name: "Côte d'Ivoire", alpha_2: "CI", alpha_3: "CIV", un_code: 384 }); array.push({ name: "Croatia", alpha_2: "HR", alpha_3: "HRV", un_code: 191 }); array.push({ name: "Cuba", alpha_2: "CU", alpha_3: "CUB", un_code: 192 }); array.push({ name: "Cyprus", alpha_2: "CY", alpha_3: "CYP", un_code: 196 }); array.push({ name: "Czech Republic", alpha_2: "CZ", alpha_3: "CZE", un_code: 203 }); array.push({ name: "Denmark", alpha_2: "DK", alpha_3: "DNK", un_code: 208 }); array.push({ name: "Djibouti", alpha_2: "DJ", alpha_3: "DJI", un_code: 262 }); array.push({ name: "Dominica", alpha_2: "DM", alpha_3: "DMA", un_code: 212 }); array.push({ name: "Dominican Republic", alpha_2: "DO", alpha_3: "DOM", un_code: 214 }); array.push({ name: "Ecuador", alpha_2: "EC", alpha_3: "ECU", un_code: 218 }); array.push({ name: "Egypt", alpha_2: "EG", alpha_3: "EGY", un_code: 818 }); array.push({ name: "El Salvador", alpha_2: "SV", alpha_3: "SLV", un_code: 222 }); array.push({ name: "Equatorial Guinea", alpha_2: "GQ", alpha_3: "GNQ", un_code: 226 }); array.push({ name: "Eritrea", alpha_2: "ER", alpha_3: "ERI", un_code: 232 }); array.push({ name: "Estonia", alpha_2: "EE", alpha_3: "EST", un_code: 233 }); array.push({ name: "Ethiopia", alpha_2: "ET", alpha_3: "ETH", un_code: 231 }); array.push({ name: "Falkland Islands (Malvinas)", alpha_2: "FK", alpha_3: "FLK", un_code: 238 }); array.push({ name: "Faroe Islands", alpha_2: "FO", alpha_3: "FRO", un_code: 234 }); array.push({ name: "Fiji", alpha_2: "FJ", alpha_3: "FJI", un_code: 242 }); array.push({ name: "Finland", alpha_2: "FI", alpha_3: "FIN", un_code: 246 }); array.push({ name: "France", alpha_2: "FR", alpha_3: "FRA", un_code: 250 }); array.push({ name: "French Guiana", alpha_2: "GF", alpha_3: "GUF", un_code: 254 }); array.push({ name: "French Polynesia", alpha_2: "PF", alpha_3: "PYF", un_code: 258 }); array.push({ name: "French Southern Territories", alpha_2: "TF", alpha_3: "ATF", un_code: 260 }); array.push({ name: "Gabon", alpha_2: "GA", alpha_3: "GAB", un_code: 266 }); array.push({ name: "Gambia", alpha_2: "GM", alpha_3: "GMB", un_code: 270 }); array.push({ name: "Georgia", alpha_2: "GE", alpha_3: "GEO", un_code: 268 }); array.push({ name: "Germany", alpha_2: "DE", alpha_3: "DEU", un_code: 276 }); array.push({ name: "Ghana", alpha_2: "GH", alpha_3: "GHA", un_code: 288 }); array.push({ name: "Gibraltar", alpha_2: "GI", alpha_3: "GIB", un_code: 292 }); array.push({ name: "Greece", alpha_2: "GR", alpha_3: "GRC", un_code: 300 }); array.push({ name: "Greenland", alpha_2: "GL", alpha_3: "GRL", un_code: 304 }); array.push({ name: "Grenada", alpha_2: "GD", alpha_3: "GRD", un_code: 308 }); array.push({ name: "Guadeloupe", alpha_2: "GP", alpha_3: "GLP", un_code: 312 }); array.push({ name: "Guam", alpha_2: "GU", alpha_3: "GUM", un_code: 316 }); array.push({ name: "Guatemala", alpha_2: "GT", alpha_3: "GTM", un_code: 320 }); array.push({ name: "Guernsey", alpha_2: "GG", alpha_3: "GGY", un_code: 831 }); array.push({ name: "Guinea", alpha_2: "GN", alpha_3: "GIN", un_code: 324 }); array.push({ name: "Guinea-Bissau", alpha_2: "GW", alpha_3: "GNB", un_code: 624 }); array.push({ name: "Guyana", alpha_2: "GY", alpha_3: "GUY", un_code: 328 }); array.push({ name: "Haiti", alpha_2: "HT", alpha_3: "HTI", un_code: 332 }); array.push({ name: "Heard and Mcdonald Islands", alpha_2: "HM", alpha_3: "HMD", un_code: 334 }); array.push({ name: "Holy See (Vatican City State)", alpha_2: "VA", alpha_3: "VAT", un_code: 336 }); array.push({ name: "Honduras", alpha_2: "HN", alpha_3: "HND", un_code: 340 }); array.push({ name: "Hungary", alpha_2: "HU", alpha_3: "HUN", un_code: 348 }); array.push({ name: "Iceland", alpha_2: "IS", alpha_3: "ISL", un_code: 352 }); array.push({ name: "India", alpha_2: "IN", alpha_3: "IND", un_code: 356 }); array.push({ name: "Indonesia", alpha_2: "ID", alpha_3: "IDN", un_code: 360 }); array.push({ name: "Iran, Islamic Republic of", alpha_2: "IR", alpha_3: "IRN", un_code: 364 }); array.push({ name: "Iraq", alpha_2: "IQ", alpha_3: "IRQ", un_code: 368 }); array.push({ name: "Ireland", alpha_2: "IE", alpha_3: "IRL", un_code: 372 }); array.push({ name: "Isle of Man", alpha_2: "IM", alpha_3: "IMN", un_code: 833 }); array.push({ name: "Israel", alpha_2: "IL", alpha_3: "ISR", un_code: 376 }); array.push({ name: "Italy", alpha_2: "IT", alpha_3: "ITA", un_code: 380 }); array.push({ name: "Jamaica", alpha_2: "JM", alpha_3: "JAM", un_code: 388 }); array.push({ name: "Japan", alpha_2: "JP", alpha_3: "JPN", un_code: 392 }); array.push({ name: "Jersey", alpha_2: "JE", alpha_3: "JEY", un_code: 832 }); array.push({ name: "Jordan", alpha_2: "JO", alpha_3: "JOR", un_code: 400 }); array.push({ name: "Kazakhstan", alpha_2: "KZ", alpha_3: "KAZ", un_code: 398 }); array.push({ name: "Kenya", alpha_2: "KE", alpha_3: "KEN", un_code: 404 }); array.push({ name: "Kiribati", alpha_2: "KI", alpha_3: "KIR", un_code: 296 }); array.push({ name: "Korea (North)", alpha_2: "KP", alpha_3: "PRK", un_code: 408 }); array.push({ name: "Korea (South)", alpha_2: "KR", alpha_3: "KOR", un_code: 410 }); array.push({ name: "Kuwait", alpha_2: "KW", alpha_3: "KWT", un_code: 414 }); array.push({ name: "Kyrgyzstan", alpha_2: "KG", alpha_3: "KGZ", un_code: 417 }); array.push({ name: "Lao PDR", alpha_2: "LA", alpha_3: "LAO", un_code: 418 }); array.push({ name: "Latvia", alpha_2: "LV", alpha_3: "LVA", un_code: 428 }); array.push({ name: "Lebanon", alpha_2: "LB", alpha_3: "LBN", un_code: 422 }); array.push({ name: "Lesotho", alpha_2: "LS", alpha_3: "LSO", un_code: 426 }); array.push({ name: "Liberia", alpha_2: "LR", alpha_3: "LBR", un_code: 430 }); array.push({ name: "Libya", alpha_2: "LY", alpha_3: "LBY", un_code: 434 }); array.push({ name: "Liechtenstein", alpha_2: "LI", alpha_3: "LIE", un_code: 438 }); array.push({ name: "Lithuania", alpha_2: "LT", alpha_3: "LTU", un_code: 440 }); array.push({ name: "Luxembourg", alpha_2: "LU", alpha_3: "LUX", un_code: 442 }); array.push({ name: "Macedonia, Republic of", alpha_2: "MK", alpha_3: "MKD", un_code: 807 }); array.push({ name: "Madagascar", alpha_2: "MG", alpha_3: "MDG", un_code: 450 }); array.push({ name: "Malawi", alpha_2: "MW", alpha_3: "MWI", un_code: 454 }); array.push({ name: "Malaysia", alpha_2: "MY", alpha_3: "MYS", un_code: 458 }); array.push({ name: "Maldives", alpha_2: "MV", alpha_3: "MDV", un_code: 462 }); array.push({ name: "Mali", alpha_2: "ML", alpha_3: "MLI", un_code: 466 }); array.push({ name: "Malta", alpha_2: "MT", alpha_3: "MLT", un_code: 470 }); array.push({ name: "Marshall Islands", alpha_2: "MH", alpha_3: "MHL", un_code: 584 }); array.push({ name: "Martinique", alpha_2: "MQ", alpha_3: "MTQ", un_code: 474 }); array.push({ name: "Mauritania", alpha_2: "MR", alpha_3: "MRT", un_code: 478 }); array.push({ name: "Mauritius", alpha_2: "MU", alpha_3: "MUS", un_code: 480 }); array.push({ name: "Mayotte", alpha_2: "YT", alpha_3: "MYT", un_code: 175 }); array.push({ name: "Mexico", alpha_2: "MX", alpha_3: "MEX", un_code: 484 }); array.push({ name: "Micronesia, Federated States of", alpha_2: "FM", alpha_3: "FSM", un_code: 583 }); array.push({ name: "Moldova", alpha_2: "MD", alpha_3: "MDA", un_code: 498 }); array.push({ name: "Monaco", alpha_2: "MC", alpha_3: "MCO", un_code: 492 }); array.push({ name: "Mongolia", alpha_2: "MN", alpha_3: "MNG", un_code: 496 }); array.push({ name: "Montenegro", alpha_2: "ME", alpha_3: "MNE", un_code: 499 }); array.push({ name: "Montserrat", alpha_2: "MS", alpha_3: "MSR", un_code: 500 }); array.push({ name: "Morocco", alpha_2: "MA", alpha_3: "MAR", un_code: 504 }); array.push({ name: "Mozambique", alpha_2: "MZ", alpha_3: "MOZ", un_code: 508 }); array.push({ name: "Myanmar", alpha_2: "MM", alpha_3: "MMR", un_code: 104 }); array.push({ name: "Namibia", alpha_2: "NA", alpha_3: "NAM", un_code: 516 }); array.push({ name: "Nauru", alpha_2: "NR", alpha_3: "NRU", un_code: 520 }); array.push({ name: "Nepal", alpha_2: "NP", alpha_3: "NPL", un_code: 524 }); array.push({ name: "Netherlands", alpha_2: "NL", alpha_3: "NLD", un_code: 528 }); array.push({ name: "Netherlands Antilles", alpha_2: "AN", alpha_3: "ANT", un_code: 530 }); array.push({ name: "New Caledonia", alpha_2: "NC", alpha_3: "NCL", un_code: 540 }); array.push({ name: "New Zealand", alpha_2: "NZ", alpha_3: "NZL", un_code: 554 }); array.push({ name: "Nicaragua", alpha_2: "NI", alpha_3: "NIC", un_code: 558 }); array.push({ name: "Niger", alpha_2: "NE", alpha_3: "NER", un_code: 562 }); array.push({ name: "Nigeria", alpha_2: "NG", alpha_3: "NGA", un_code: 566 }); array.push({ name: "Niue", alpha_2: "NU", alpha_3: "NIU", un_code: 570 }); array.push({ name: "Norfolk Island", alpha_2: "NF", alpha_3: "NFK", un_code: 574 }); array.push({ name: "Northern Mariana Islands", alpha_2: "MP", alpha_3: "MNP", un_code: 580 }); array.push({ name: "Norway", alpha_2: "NO", alpha_3: "NOR", un_code: 578 }); array.push({ name: "Oman", alpha_2: "OM", alpha_3: "OMN", un_code: 512 }); array.push({ name: "Pakistan", alpha_2: "PK", alpha_3: "PAK", un_code: 586 }); array.push({ name: "Palau", alpha_2: "PW", alpha_3: "PLW", un_code: 585 }); array.push({ name: "Palestinian Territory", alpha_2: "PS", alpha_3: "PSE", un_code: 275 }); array.push({ name: "Panama", alpha_2: "PA", alpha_3: "PAN", un_code: 591 }); array.push({ name: "Papua New Guinea", alpha_2: "PG", alpha_3: "PNG", un_code: 598 }); array.push({ name: "Paraguay", alpha_2: "PY", alpha_3: "PRY", un_code: 600 }); array.push({ name: "Peru", alpha_2: "PE", alpha_3: "PER", un_code: 604 }); array.push({ name: "Philippines", alpha_2: "PH", alpha_3: "PHL", un_code: 608 }); array.push({ name: "Pitcairn", alpha_2: "PN", alpha_3: "PCN", un_code: 612 }); array.push({ name: "Poland", alpha_2: "PL", alpha_3: "POL", un_code: 616 }); array.push({ name: "Portugal", alpha_2: "PT", alpha_3: "PRT", un_code: 620 }); array.push({ name: "Puerto Rico", alpha_2: "PR", alpha_3: "PRI", un_code: 630 }); array.push({ name: "Qatar", alpha_2: "QA", alpha_3: "QAT", un_code: 634 }); array.push({ name: "Réunion", alpha_2: "RE", alpha_3: "REU", un_code: 638 }); array.push({ name: "Romania", alpha_2: "RO", alpha_3: "ROU", un_code: 642 }); array.push({ name: "Russian Federation", alpha_2: "RU", alpha_3: "RUS", un_code: 643 }); array.push({ name: "Rwanda", alpha_2: "RW", alpha_3: "RWA", un_code: 646 }); array.push({ name: "Saint-Barthélemy", alpha_2: "BL", alpha_3: "BLM", un_code: 652 }); array.push({ name: "Saint Helena", alpha_2: "SH", alpha_3: "SHN", un_code: 654 }); array.push({ name: "Saint Kitts and Nevis", alpha_2: "KN", alpha_3: "KNA", un_code: 659 }); array.push({ name: "Saint Lucia", alpha_2: "LC", alpha_3: "LCA", un_code: 662 }); array.push({ name: "Saint-Martin (French part)", alpha_2: "MF", alpha_3: "MAF", un_code: 663 }); array.push({ name: "Saint Pierre and Miquelon", alpha_2: "PM", alpha_3: "SPM", un_code: 666 }); array.push({ name: "Saint Vincent and Grenadines", alpha_2: "VC", alpha_3: "VCT", un_code: 670 }); array.push({ name: "Samoa", alpha_2: "WS", alpha_3: "WSM", un_code: 882 }); array.push({ name: "San Marino", alpha_2: "SM", alpha_3: "SMR", un_code: 674 }); array.push({ name: "Sao Tome and Principe", alpha_2: "ST", alpha_3: "STP", un_code: 678 }); array.push({ name: "Saudi Arabia", alpha_2: "SA", alpha_3: "SAU", un_code: 682 }); array.push({ name: "Senegal", alpha_2: "SN", alpha_3: "SEN", un_code: 686 }); array.push({ name: "Serbia", alpha_2: "RS", alpha_3: "SRB", un_code: 688 }); array.push({ name: "Seychelles", alpha_2: "SC", alpha_3: "SYC", un_code: 690 }); array.push({ name: "Sierra Leone", alpha_2: "SL", alpha_3: "SLE", un_code: 694 }); array.push({ name: "Singapore", alpha_2: "SG", alpha_3: "SGP", un_code: 702 }); array.push({ name: "Slovakia", alpha_2: "SK", alpha_3: "SVK", un_code: 703 }); array.push({ name: "Slovenia", alpha_2: "SI", alpha_3: "SVN", un_code: 705 }); array.push({ name: "Solomon Islands", alpha_2: "SB", alpha_3: "SLB", un_code: 90 }); array.push({ name: "Somalia", alpha_2: "SO", alpha_3: "SOM", un_code: 706 }); array.push({ name: "South Africa", alpha_2: "ZA", alpha_3: "ZAF", un_code: 710 }); array.push({ name: "South Georgia and the South Sandwich Islands", alpha_2: "GS", alpha_3: "SGS", un_code: 239 }); array.push({ name: "South Sudan", alpha_2: "SS", alpha_3: "SSD", un_code: 728 }); array.push({ name: "Spain", alpha_2: "ES", alpha_3: "ESP", un_code: 724 }); array.push({ name: "Sri Lanka", alpha_2: "LK", alpha_3: "LKA", un_code: 144 }); array.push({ name: "Sudan", alpha_2: "SD", alpha_3: "SDN", un_code: 736 }); array.push({ name: "Suriname", alpha_2: "SR", alpha_3: "SUR", un_code: 740 }); array.push({ name: "Svalbard and Jan Mayen Islands", alpha_2: "SJ", alpha_3: "SJM", un_code: 744 }); array.push({ name: "Swaziland", alpha_2: "SZ", alpha_3: "SWZ", un_code: 748 }); array.push({ name: "Sweden", alpha_2: "SE", alpha_3: "SWE", un_code: 752 }); array.push({ name: "Switzerland", alpha_2: "CH", alpha_3: "CHE", un_code: 756 }); array.push({ name: "Syrian Arab Republic (Syria)", alpha_2: "SY", alpha_3: "SYR", un_code: 760 }); array.push({ name: "Taiwan, Republic of China", alpha_2: "TW", alpha_3: "TWN", un_code: 158 }); array.push({ name: "Tajikistan", alpha_2: "TJ", alpha_3: "TJK", un_code: 762 }); array.push({ name: "Tanzania, United Republic of", alpha_2: "TZ", alpha_3: "TZA", un_code: 834 }); array.push({ name: "Thailand", alpha_2: "TH", alpha_3: "THA", un_code: 764 }); array.push({ name: "Timor-Leste", alpha_2: "TL", alpha_3: "TLS", un_code: 626 }); array.push({ name: "Togo", alpha_2: "TG", alpha_3: "TGO", un_code: 768 }); array.push({ name: "Tokelau", alpha_2: "TK", alpha_3: "TKL", un_code: 772 }); array.push({ name: "Tonga", alpha_2: "TO", alpha_3: "TON", un_code: 776 }); array.push({ name: "Trinidad and Tobago", alpha_2: "TT", alpha_3: "TTO", un_code: 780 }); array.push({ name: "Tunisia", alpha_2: "TN", alpha_3: "TUN", un_code: 788 }); array.push({ name: "Turkey", alpha_2: "TR", alpha_3: "TUR", un_code: 792 }); array.push({ name: "Turkmenistan", alpha_2: "TM", alpha_3: "TKM", un_code: 795 }); array.push({ name: "Turks and Caicos Islands", alpha_2: "TC", alpha_3: "TCA", un_code: 796 }); array.push({ name: "Tuvalu", alpha_2: "TV", alpha_3: "TUV", un_code: 798 }); array.push({ name: "Uganda", alpha_2: "UG", alpha_3: "UGA", un_code: 800 }); array.push({ name: "Ukraine", alpha_2: "UA", alpha_3: "UKR", un_code: 804 }); array.push({ name: "United Arab Emirates", alpha_2: "AE", alpha_3: "ARE", un_code: 784 }); array.push({ name: "United Kingdom", alpha_2: "GB", alpha_3: "GBR", un_code: 826 }); array.push({ name: "United States of America", alpha_2: "US", alpha_3: "USA", un_code: 840 }); array.push({ name: "US Minor Outlying Islands", alpha_2: "UM", alpha_3: "UMI", un_code: 581 }); array.push({ name: "Uruguay", alpha_2: "UY", alpha_3: "URY", un_code: 858 }); array.push({ name: "Uzbekistan", alpha_2: "UZ", alpha_3: "UZB", un_code: 860 }); array.push({ name: "Vanuatu", alpha_2: "VU", alpha_3: "VUT", un_code: 548 }); array.push({ name: "Venezuela (Bolivarian Republic)", alpha_2: "VE", alpha_3: "VEN", un_code: 862 }); array.push({ name: "Viet Nam", alpha_2: "VN", alpha_3: "VNM", un_code: 704 }); array.push({ name: "Virgin Islands, US", alpha_2: "VI", alpha_3: "VIR", un_code: 850 }); array.push({ name: "Wallis and Futuna Islands", alpha_2: "WF", alpha_3: "WLF", un_code: 876 }); array.push({ name: "Western Sahara", alpha_2: "EH", alpha_3: "ESH", un_code: 732 }); array.push({ name: "Yemen", alpha_2: "YE", alpha_3: "YEM", un_code: 887 }); array.push({ name: "Zambia", alpha_2: "ZM", alpha_3: "ZMB", un_code: 894 }); array.push({ name: "Zimbabwe", alpha_2: "ZW", alpha_3: "ZWE", un_code: 716 }); }; function country_name(alpha_code, fallback) { return (alpha_2_map[alpha_code.toUpperCase()] || { name: fallback || (_translations.flaw3JIB || (_translations.flaw3JIB = i18n.tr("unknown country"))) }).name; } i18n.country_name = country_name; fill_country_infos(country_infos); for (const country of country_infos) alpha_2_map[country.alpha_2] = country; })(i18n || (i18n = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["36f3b62ac78dcf997caadc844250a877529ef7cc8f67b7c34ea38cae195bdf1d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["36f3b62ac78dcf997caadc844250a877529ef7cc8f67b7c34ea38cae195bdf1d"] = "36f3b62ac78dcf997caadc844250a877529ef7cc8f67b7c34ea38cae195bdf1d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "kET_CIMv", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (124,31)" }, { name: "y0AzVS4M", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (125,34)" }, { name: "zfwYoTqI", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (125,90)" }, { name: "V5G4WXp1", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (140,35)" }, { name: "RWlYypJZ", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (165,38)" }, { name: "Y9SQ5M3h", path: "D:/TeaSpeak/web/shared/js/profiles/ConnectionProfile.ts (165,81)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var profiles; (function (profiles_1) { class ConnectionProfile { constructor(id) { this.selected_identity_type = "unset"; this.identities = {}; this.id = id; } connect_username() { if (this.default_username && this.default_username !== "Another TeaSpeak user") return this.default_username; let selected = this.selected_identity(); let name = selected ? selected.fallback_name() : undefined; return name || "Another TeaSpeak user"; } selected_identity(current_type) { if (!current_type) current_type = this.selected_type(); if (current_type === undefined) return undefined; if (current_type == profiles_1.identities.IdentitifyType.TEAFORO) { return profiles_1.identities.static_forum_identity(); } else if (current_type == profiles_1.identities.IdentitifyType.TEAMSPEAK || current_type == profiles_1.identities.IdentitifyType.NICKNAME) { return this.identities[profiles_1.identities.IdentitifyType[current_type].toLowerCase()]; } return undefined; } selected_type() { return this.selected_identity_type ? profiles_1.identities.IdentitifyType[this.selected_identity_type.toUpperCase()] : undefined; } set_identity(type, identity) { this.identities[profiles_1.identities.IdentitifyType[type].toLowerCase()] = identity; } spawn_identity_handshake_handler(connection) { const identity = this.selected_identity(); if (!identity) return undefined; return identity.spawn_identity_handshake_handler(connection); } encode() { const identity_data = {}; for (const key in this.identities) if (this.identities[key]) identity_data[key] = this.identities[key].encode(); return JSON.stringify({ version: 1, username: this.default_username, password: this.default_password, profile_name: this.profile_name, identity_type: this.selected_identity_type, identity_data: identity_data, id: this.id }); } valid() { const identity = this.selected_identity(); if (!identity || !identity.valid()) return false; return true; } } profiles_1.ConnectionProfile = ConnectionProfile; function decode_profile(data) { return __awaiter(this, void 0, void 0, function* () { data = JSON.parse(data); if (data.version !== 1) return "invalid version"; const result = new ConnectionProfile(data.id); result.default_username = data.username; result.default_password = data.password; result.profile_name = data.profile_name; result.selected_identity_type = (data.identity_type || "").toLowerCase(); if (data.identity_data) { for (const key in data.identity_data) { const type = profiles_1.identities.IdentitifyType[key.toUpperCase()]; const _data = data.identity_data[key]; if (type == undefined) continue; const identity = yield profiles_1.identities.decode_identity(type, _data); if (identity == undefined) continue; result.identities[key.toLowerCase()] = identity; } } return result; }); } let available_profiles = []; function load() { return __awaiter(this, void 0, void 0, function* () { available_profiles = []; const profiles_json = localStorage.getItem("profiles"); let profiles_data = (() => { try { return profiles_json ? JSON.parse(profiles_json) : { version: 0 }; } catch (error) { debugger; console.error(_translations.kET_CIMv || (_translations.kET_CIMv = tr("Invalid profile json! Resetting profiles :( (%o)")), profiles_json); createErrorModal(_translations.y0AzVS4M || (_translations.y0AzVS4M = tr("Profile data invalid")), MessageHelper.formatMessage(_translations.zfwYoTqI || (_translations.zfwYoTqI = tr("The profile data is invalid.{:br:}This might cause data loss.")))).open(); return { version: 0 }; } })(); if (profiles_data.version === 0) { profiles_data = { version: 1, profiles: [] }; } if (profiles_data.version == 1) { for (const profile_data of profiles_data.profiles) { const profile = yield decode_profile(profile_data); if (typeof (profile) === 'string') { console.error(_translations.V5G4WXp1 || (_translations.V5G4WXp1 = tr("Failed to load profile. Reason: %s, Profile data: %s")), profile, profiles_data); continue; } available_profiles.push(profile); } } if (!find_profile("default")) { //Create a default profile and teaforo profile { const profile = create_new_profile("default", "default"); profile.default_password = ""; profile.default_username = ""; profile.profile_name = "Default Profile"; /* generate default identity */ try { const identity = yield profiles_1.identities.TeaSpeakIdentity.generate_new(); let active = true; setTimeout(() => { active = false; }, 1000); yield identity.improve_level(8, 1, () => active); profile.set_identity(profiles_1.identities.IdentitifyType.TEAMSPEAK, identity); profile.selected_identity_type = profiles_1.identities.IdentitifyType[profiles_1.identities.IdentitifyType.TEAMSPEAK]; } catch (error) { createErrorModal(_translations.RWlYypJZ || (_translations.RWlYypJZ = tr("Failed to generate default identity")), _translations.Y9SQ5M3h || (_translations.Y9SQ5M3h = tr("Failed to generate default identity!
Please manually generate the identity within your settings => profiles"))).open(); } } { /* forum identity (works only when connected to the forum) */ const profile = create_new_profile("TeaSpeak Forum", "teaforo"); profile.default_password = ""; profile.default_username = ""; profile.profile_name = "TeaSpeak Forum profile"; profile.set_identity(profiles_1.identities.IdentitifyType.TEAFORO, profiles_1.identities.static_forum_identity()); profile.selected_identity_type = profiles_1.identities.IdentitifyType[profiles_1.identities.IdentitifyType.TEAFORO]; } save(); } }); } profiles_1.load = load; function create_new_profile(name, id) { const profile = new ConnectionProfile(id || guid()); profile.profile_name = name; profile.default_username = ""; available_profiles.push(profile); return profile; } profiles_1.create_new_profile = create_new_profile; let _requires_save = false; function save() { const profiles = []; for (const profile of available_profiles) profiles.push(profile.encode()); const data = JSON.stringify({ version: 1, profiles: profiles }); localStorage.setItem("profiles", data); } profiles_1.save = save; function mark_need_save() { _requires_save = true; } profiles_1.mark_need_save = mark_need_save; function requires_save() { return _requires_save; } profiles_1.requires_save = requires_save; function profiles() { return available_profiles; } profiles_1.profiles = profiles; function find_profile(id) { for (const profile of profiles()) if (profile.id == id) return profile; return undefined; } profiles_1.find_profile = find_profile; function find_profile_by_name(name) { name = name.toLowerCase(); for (const profile of profiles()) if ((profile.profile_name || "").toLowerCase() == name) return profile; return undefined; } profiles_1.find_profile_by_name = find_profile_by_name; function default_profile() { return find_profile("default"); } profiles_1.default_profile = default_profile; function set_default_profile(profile) { const old_default = default_profile(); if (old_default && old_default != profile) { old_default.id = guid(); } profile.id = "default"; return old_default; } profiles_1.set_default_profile = set_default_profile; function delete_profile(profile) { available_profiles.remove(profile); } profiles_1.delete_profile = delete_profile; })(profiles || (profiles = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c98187f830dc6b0f36a4ad6002bfa58f867cf63df95d93b2615674cf6e7b68e2"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c98187f830dc6b0f36a4ad6002bfa58f867cf63df95d93b2615674cf6e7b68e2"] = "c98187f830dc6b0f36a4ad6002bfa58f867cf63df95d93b2615674cf6e7b68e2"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "MP4Po9Pb", path: "D:/TeaSpeak/web/shared/js/profiles/Identity.ts (79,30)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var profiles; (function (profiles) { var identities; (function (identities) { let IdentitifyType; (function (IdentitifyType) { IdentitifyType[IdentitifyType["TEAFORO"] = 0] = "TEAFORO"; IdentitifyType[IdentitifyType["TEAMSPEAK"] = 1] = "TEAMSPEAK"; IdentitifyType[IdentitifyType["NICKNAME"] = 2] = "NICKNAME"; })(IdentitifyType = identities.IdentitifyType || (identities.IdentitifyType = {})); function decode_identity(type, data) { return __awaiter(this, void 0, void 0, function* () { let identity; switch (type) { case IdentitifyType.NICKNAME: identity = new identities.NameIdentity(); break; case IdentitifyType.TEAFORO: identity = new identities.TeaForumIdentity(undefined); break; case IdentitifyType.TEAMSPEAK: identity = new identities.TeaSpeakIdentity(undefined, undefined); break; } if (!identity) return undefined; try { yield identity.decode(data); } catch (error) { /* todo better error handling! */ console.error(error); return undefined; } return identity; }); } identities.decode_identity = decode_identity; function create_identity(type) { let identity; switch (type) { case IdentitifyType.NICKNAME: identity = new identities.NameIdentity(); break; case IdentitifyType.TEAFORO: identity = new identities.TeaForumIdentity(undefined); break; case IdentitifyType.TEAMSPEAK: identity = new identities.TeaSpeakIdentity(undefined, undefined); break; } return identity; } identities.create_identity = create_identity; class HandshakeCommandHandler extends connection.AbstractCommandHandler { constructor(connection, handle) { super(connection); this.handle = handle; } handle_command(command) { if ($.isFunction(this[command.command])) this[command.command](command.arguments); else if (command.command == "error") { return false; } else { console.warn(_translations.MP4Po9Pb || (_translations.MP4Po9Pb = tr("Received unknown command while handshaking (%o)")), command); } return true; } } identities.HandshakeCommandHandler = HandshakeCommandHandler; class AbstractHandshakeIdentityHandler { constructor(connection) { this.callbacks = []; this.connection = connection; } register_callback(callback) { this.callbacks.push(callback); } trigger_success() { for (const callback of this.callbacks) callback(true); } trigger_fail(message) { for (const callback of this.callbacks) callback(false, message); } } identities.AbstractHandshakeIdentityHandler = AbstractHandshakeIdentityHandler; })(identities = profiles.identities || (profiles.identities = {})); })(profiles || (profiles = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["4f9e18c83b3da294810607c6f8fcf9feb14743dd1dce10c97c911a3eabfa9d4b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["4f9e18c83b3da294810607c6f8fcf9feb14743dd1dce10c97c911a3eabfa9d4b"] = "4f9e18c83b3da294810607c6f8fcf9feb14743dd1dce10c97c911a3eabfa9d4b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "u5Zv5_eG", path: "D:/TeaSpeak/web/shared/js/profiles/identities/NameIdentity.ts (23,51)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var profiles; (function (profiles) { var identities; (function (identities) { class NameHandshakeHandler extends identities.AbstractHandshakeIdentityHandler { constructor(connection, identity) { super(connection); this.identity = identity; this.handler = new identities.HandshakeCommandHandler(connection, this); this.handler["handshakeidentityproof"] = () => this.trigger_fail("server requested unexpected proof"); } start_handshake() { this.connection.command_handler_boss().register_handler(this.handler); this.connection.send_command("handshakebegin", { intention: 0, authentication_method: this.identity.type(), client_nickname: this.identity.name() }).catch(error => { log.error(LogCategory.IDENTITIES, _translations.u5Zv5_eG || (_translations.u5Zv5_eG = tr("Failed to initialize name based handshake. Error: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; this.trigger_fail("failed to execute begin (" + error + ")"); }).then(() => this.trigger_success()); } trigger_fail(message) { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_fail(message); } trigger_success() { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_success(); } } class NameIdentity { constructor(name) { this._name = name; } set_name(name) { this._name = name; } name() { return this._name; } fallback_name() { return this._name; } uid() { return btoa(this._name); //FIXME hash! } type() { return identities.IdentitifyType.NICKNAME; } valid() { return this._name != undefined && this._name.length >= 5; } decode(data) { data = JSON.parse(data); if (data.version !== 1) throw "invalid version"; this._name = data["name"]; return; } encode() { return JSON.stringify({ version: 1, name: this._name }); } spawn_identity_handshake_handler(connection) { return new NameHandshakeHandler(connection, this); } } identities.NameIdentity = NameIdentity; })(identities = profiles.identities || (profiles.identities = {})); })(profiles || (profiles = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5d120c56c8577b2f19ee369d9b574360ab78471e5f9b2b2d0fb08e8ad3807ea8"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5d120c56c8577b2f19ee369d9b574360ab78471e5f9b2b2d0fb08e8ad3807ea8"] = "5d120c56c8577b2f19ee369d9b574360ab78471e5f9b2b2d0fb08e8ad3807ea8"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "W2pDcDNQ", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeaForumIdentity.ts (22,51)" }, { name: "SWcrhX8D", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeaForumIdentity.ts (35,51)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var profiles; (function (profiles) { var identities; (function (identities) { class TeaForumHandshakeHandler extends identities.AbstractHandshakeIdentityHandler { constructor(connection, identity) { super(connection); this.identity = identity; this.handler = new identities.HandshakeCommandHandler(connection, this); this.handler["handshakeidentityproof"] = this.handle_proof.bind(this); } start_handshake() { this.connection.command_handler_boss().register_handler(this.handler); this.connection.send_command("handshakebegin", { intention: 0, authentication_method: this.identity.type(), data: this.identity.data().data_json() }).catch(error => { log.error(LogCategory.IDENTITIES, _translations.W2pDcDNQ || (_translations.W2pDcDNQ = tr("Failed to initialize TeaForum based handshake. Error: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; this.trigger_fail("failed to execute begin (" + error + ")"); }); } handle_proof(json) { this.connection.send_command("handshakeindentityproof", { proof: this.identity.data().data_sign() }).catch(error => { log.error(LogCategory.IDENTITIES, _translations.SWcrhX8D || (_translations.SWcrhX8D = tr("Failed to proof the identity. Error: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; this.trigger_fail("failed to execute proof (" + error + ")"); }).then(() => this.trigger_success()); } trigger_fail(message) { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_fail(message); } trigger_success() { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_success(); } } class TeaForumIdentity { constructor(data) { this.identity_data = data; } valid() { return !!this.identity_data && !this.identity_data.is_expired(); } data() { return this.identity_data; } decode(data) { data = JSON.parse(data); if (data.version !== 1) throw "invalid version"; return; } encode() { return JSON.stringify({ version: 1 }); } spawn_identity_handshake_handler(connection) { return new TeaForumHandshakeHandler(connection, this); } fallback_name() { return this.identity_data ? this.identity_data.name() : undefined; } type() { return identities.IdentitifyType.TEAFORO; } uid() { //FIXME: Real UID! return "TeaForo#" + ((this.identity_data ? this.identity_data.name() : "Another TeaSpeak user")); } } identities.TeaForumIdentity = TeaForumIdentity; let static_identity; function set_static_identity(identity) { static_identity = identity; } identities.set_static_identity = set_static_identity; function update_forum() { if (forum.logged_in() && (!static_identity || static_identity.data() !== forum.data())) { static_identity = new TeaForumIdentity(forum.data()); } else { static_identity = undefined; } } identities.update_forum = update_forum; function valid_static_forum_identity() { return static_identity && static_identity.valid(); } identities.valid_static_forum_identity = valid_static_forum_identity; function static_forum_identity() { return static_identity; } identities.static_forum_identity = static_forum_identity; })(identities = profiles.identities || (profiles.identities = {})); })(profiles || (profiles = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["bfe72893496c223378f70914d679ecbba6151df3cd16fa95aae3f5832ef4d162"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["bfe72893496c223378f70914d679ecbba6151df3cd16fa95aae3f5832ef4d162"] = "bfe72893496c223378f70914d679ecbba6151df3cd16fa95aae3f5832ef4d162"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "l6DvuihS", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (231,51)" }, { name: "DMNxyJuG", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (247,55)" }, { name: "ekkOaQqE", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (298,55)" }, { name: "pGZABZ0J", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (411,51)" }, { name: "tOjKyP5T", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (419,46)" }, { name: "orYglH6g", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (429,51)" }, { name: "mCXt2f6G", path: "D:/TeaSpeak/web/shared/js/profiles/identities/TeamSpeakIdentity.ts (478,51)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var profiles; (function (profiles) { var identities; (function (identities) { let CryptoHelper; (function (CryptoHelper) { function base64_url_encode(str) { return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); } CryptoHelper.base64_url_encode = base64_url_encode; function base64_url_decode(str, pad) { if (typeof (pad) === 'undefined' || pad) str = (str + '===').slice(0, str.length + (str.length % 4)); return str.replace(/-/g, '+').replace(/_/g, '/'); } CryptoHelper.base64_url_decode = base64_url_decode; function arraybuffer_to_string(buf) { return String.fromCharCode.apply(null, new Uint16Array(buf)); } CryptoHelper.arraybuffer_to_string = arraybuffer_to_string; function export_ecc_key(crypto_key, public_key) { return __awaiter(this, void 0, void 0, function* () { /* Tomcrypt public key export: if (type == PK_PRIVATE) { flags[0] = 1; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_INTEGER, 1UL, key->k, LTC_ASN1_EOL, 0UL, NULL); } else { flags[0] = 0; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL); } */ const key_data = yield crypto.subtle.exportKey("jwk", crypto_key); let index = 0; const length = public_key ? 79 : 114; /* max lengths! Depends on the padding could be less */ const buffer = new Uint8Array(length); /* fixed ASN1 length */ { /* the initial sequence */ buffer[index++] = 0x30; /* type */ buffer[index++] = 0x00; /* we will set the sequence length later */ } { /* the flags bit string */ buffer[index++] = 0x03; /* type */ buffer[index++] = 0x02; /* length */ buffer[index++] = 0x07; /* data */ buffer[index++] = public_key ? 0x00 : 0x80; /* flag 1 or 0 (1 = private key)*/ } { /* key size (const 32 for P-256) */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x01; /* length */ buffer[index++] = 0x20; } try { /* Public kex X */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x20; /* length */ const raw = atob(base64_url_decode(key_data.x, false)); if (raw.charCodeAt(0) > 0x7F) { buffer[index - 1] += 1; buffer[index++] = 0; } for (let i = 0; i < 32; i++) buffer[index++] = raw.charCodeAt(i); } catch (error) { if (error instanceof DOMException) throw "failed to parse x coordinate (invalid base64)"; throw error; } try { /* Public kex Y */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x20; /* length */ const raw = atob(base64_url_decode(key_data.y, false)); if (raw.charCodeAt(0) > 0x7F) { buffer[index - 1] += 1; buffer[index++] = 0; } for (let i = 0; i < 32; i++) buffer[index++] = raw.charCodeAt(i); } catch (error) { if (error instanceof DOMException) throw "failed to parse y coordinate (invalid base64)"; throw error; } if (!public_key) { try { /* Public kex K */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x20; /* length */ const raw = atob(base64_url_decode(key_data.d, false)); if (raw.charCodeAt(0) > 0x7F) { buffer[index - 1] += 1; buffer[index++] = 0; } for (let i = 0; i < 32; i++) buffer[index++] = raw.charCodeAt(i); } catch (error) { if (error instanceof DOMException) throw "failed to parse y coordinate (invalid base64)"; throw error; } } buffer[1] = index - 2; /* set the final sequence length */ return base64_encode_ab(buffer.buffer.slice(0, index)); }); } CryptoHelper.export_ecc_key = export_ecc_key; const crypt_key = "b9dfaa7bee6ac57ac7b65f1094a1c155e747327bc2fe5d51c512023fe54a280201004e90ad1daaae1075d53b7d571c30e063b5a62a4a017bb394833aa0983e6e"; function c_strlen(buffer, offset) { let index = 0; while (index + offset < buffer.length && buffer[index + offset] != 0) index++; return index; } function decrypt_ts_identity(buffer) { return __awaiter(this, void 0, void 0, function* () { /* buffer could contains a zero! */ const hash = new Uint8Array(yield sha.sha1(buffer.buffer.slice(20, 20 + c_strlen(buffer, 20)))); for (let i = 0; i < 20; i++) buffer[i] ^= hash[i]; const length = Math.min(buffer.length, 100); for (let i = 0; i < length; i++) buffer[i] ^= crypt_key.charCodeAt(i); return arraybuffer_to_string(buffer); }); } CryptoHelper.decrypt_ts_identity = decrypt_ts_identity; function encrypt_ts_identity(buffer) { return __awaiter(this, void 0, void 0, function* () { const length = Math.min(buffer.length, 100); for (let i = 0; i < length; i++) buffer[i] ^= crypt_key.charCodeAt(i); const hash = new Uint8Array(yield sha.sha1(buffer.buffer.slice(20, 20 + c_strlen(buffer, 20)))); for (let i = 0; i < 20; i++) buffer[i] ^= hash[i]; return base64_encode_ab(buffer); }); } CryptoHelper.encrypt_ts_identity = encrypt_ts_identity; /** * @param buffer base64 encoded ASN.1 string */ function decode_tomcrypt_key(buffer) { let decoded; try { decoded = asn1.decode(atob(buffer)); } catch (error) { if (error instanceof DOMException) throw "failed to parse key buffer (invalid base64)"; throw error; } let { x, y, k } = { x: decoded.children[2].content(Infinity, asn1.TagType.VisibleString), y: decoded.children[3].content(Infinity, asn1.TagType.VisibleString), k: decoded.children[4].content(Infinity, asn1.TagType.VisibleString) }; if (x.length > 32) { if (x.charCodeAt(0) != 0) throw "Invalid X coordinate! (Too long)"; x = x.substr(1); } if (y.length > 32) { if (y.charCodeAt(0) != 0) throw "Invalid Y coordinate! (Too long)"; y = y.substr(1); } if (k.length > 32) { if (k.charCodeAt(0) != 0) throw "Invalid private coordinate! (Too long)"; k = k.substr(1); } /* console.log("Key x: %s (%d)", btoa(x), x.length); console.log("Key y: %s (%d)", btoa(y), y.length); console.log("Key k: %s (%d)", btoa(k), k.length); */ return { crv: "P-256", d: base64_url_encode(btoa(k)), x: base64_url_encode(btoa(x)), y: base64_url_encode(btoa(y)), ext: true, key_ops: ["deriveKey", "sign"], kty: "EC", }; } CryptoHelper.decode_tomcrypt_key = decode_tomcrypt_key; })(CryptoHelper = identities.CryptoHelper || (identities.CryptoHelper = {})); class TeaSpeakHandshakeHandler extends identities.AbstractHandshakeIdentityHandler { constructor(connection, identity) { super(connection); this.identity = identity; this.handler = new identities.HandshakeCommandHandler(connection, this); this.handler["handshakeidentityproof"] = this.handle_proof.bind(this); } start_handshake() { this.connection.command_handler_boss().register_handler(this.handler); this.connection.send_command("handshakebegin", { intention: 0, authentication_method: this.identity.type(), publicKey: this.identity.public_key }).catch(error => { log.error(LogCategory.IDENTITIES, _translations.l6DvuihS || (_translations.l6DvuihS = tr("Failed to initialize TeamSpeak based handshake. Error: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; this.trigger_fail("failed to execute begin (" + error + ")"); }); } handle_proof(json) { if (!json[0]["digest"]) { this.trigger_fail("server too old"); return; } this.identity.sign_message(json[0]["message"], json[0]["digest"]).then(proof => { this.connection.send_command("handshakeindentityproof", { proof: proof }).catch(error => { log.error(LogCategory.IDENTITIES, _translations.DMNxyJuG || (_translations.DMNxyJuG = tr("Failed to proof the identity. Error: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; this.trigger_fail("failed to execute proof (" + error + ")"); }).then(() => this.trigger_success()); }).catch(error => { this.trigger_fail("failed to sign message"); }); } trigger_fail(message) { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_fail(message); } trigger_success() { this.connection.command_handler_boss().unregister_handler(this.handler); super.trigger_success(); } } class IdentityPOWWorker { initialize(key) { return __awaiter(this, void 0, void 0, function* () { this._worker = new Worker(settings.static("worker_directory", "js/workers/") + "WorkerPOW.js"); /* initialize */ yield new Promise((resolve, reject) => { const timeout_id = setTimeout(() => reject("timeout"), 1000); this._worker.onmessage = event => { clearTimeout(timeout_id); if (!event.data) { reject("invalid data"); return; } if (!event.data.success) { reject("initialize failed (" + event.data.success + " | " + (event.data.message || "unknown eroror") + ")"); return; } this._worker.onmessage = event => this.handle_message(event.data); resolve(); }; this._worker.onerror = event => { log.error(LogCategory.IDENTITIES, _translations.ekkOaQqE || (_translations.ekkOaQqE = tr("POW Worker error %o")), event); clearTimeout(timeout_id); reject("Failed to load worker (" + event.message + ")"); }; }); /* set data */ yield new Promise((resolve, reject) => { this._worker.postMessage({ type: "set_data", private_key: key, code: "set_data" }); const timeout_id = setTimeout(() => reject("timeout (data)"), 1000); this._worker.onmessage = event => { clearTimeout(timeout_id); if (!event.data) { reject("invalid data"); return; } if (!event.data.success) { reject("initialize of data failed (" + event.data.success + " | " + (event.data.message || "unknown eroror") + ")"); return; } this._worker.onmessage = event => this.handle_message(event.data); resolve(); }; }); }); } mine(hash, iterations, target, timeout) { return __awaiter(this, void 0, void 0, function* () { this._current_hash = hash; if (target < this._best_level) return true; return yield new Promise((resolve, reject) => { this._worker.postMessage({ type: "mine", hash: this._current_hash, iterations: iterations, target: target, code: "mine" }); const timeout_id = setTimeout(() => reject("timeout (mine)"), timeout || 5000); this._worker.onmessage = event => { this._worker.onmessage = event => this.handle_message(event.data); clearTimeout(timeout_id); if (!event.data) { reject("invalid data"); return; } if (!event.data.success) { reject("mining failed (" + event.data.success + " | " + (event.data.message || "unknown eroror") + ")"); return; } if (event.data.result) { this._best_level = event.data.level; this._current_hash = event.data.hash; resolve(true); } else { resolve(false); /* no result */ } }; }); }); } current_hash() { return this._current_hash; } current_level() { return this._best_level; } finalize(timeout) { return __awaiter(this, void 0, void 0, function* () { try { yield new Promise((resolve, reject) => { this._worker.postMessage({ type: "finalize", code: "finalize" }); const timeout_id = setTimeout(() => reject("timeout"), timeout || 250); this._worker.onmessage = event => { this._worker.onmessage = event => this.handle_message(event.data); clearTimeout(timeout_id); if (!event.data) { reject("invalid data"); return; } if (!event.data.success) { reject("failed to finalize (" + event.data.success + " | " + (event.data.message || "unknown eroror") + ")"); return; } resolve(); }; }); } catch (error) { log.error(LogCategory.IDENTITIES, _translations.pGZABZ0J || (_translations.pGZABZ0J = tr("Failed to finalize POW worker! (%o)")), error); } this._worker.terminate(); this._worker = undefined; }); } handle_message(message) { log.info(LogCategory.IDENTITIES, _translations.tOjKyP5T || (_translations.tOjKyP5T = tr("Received message: %o")), message); } } class TeaSpeakIdentity { constructor(private_key, hash, name, initialize) { this.private_key = private_key; this.hash_number = hash || "0"; this._name = name; if (this.private_key && (typeof (initialize) === "undefined" || initialize)) { this.initialize().catch(error => { log.error(LogCategory.IDENTITIES, "Failed to initialize TeaSpeakIdentity (%s)", error); this._initialized = false; }); } } static generate_new() { return __awaiter(this, void 0, void 0, function* () { let key; try { key = yield crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ["deriveKey"]); } catch (e) { log.error(LogCategory.IDENTITIES, _translations.orYglH6g || (_translations.orYglH6g = tr("Could not generate a new key: %o")), e); throw "Failed to generate keypair"; } const private_key = yield CryptoHelper.export_ecc_key(key.privateKey, false); const identity = new TeaSpeakIdentity(private_key, "0", undefined, false); yield identity.initialize(); return identity; }); } static import_ts(ts_string, ini) { return __awaiter(this, void 0, void 0, function* () { const parse_string = string => { /* parsing without INI structure */ const V_index = string.indexOf('V'); if (V_index == -1) throw "invalid input (missing V)"; return { hash: string.substr(0, V_index), data: string.substr(V_index + 1), name: "TeaSpeak user" }; }; const { hash, data, name } = (!ini ? () => parse_string(ts_string) : () => { /* parsing with INI structure */ let identity, name; for (const line of ts_string.split("\n")) { if (line.startsWith("identity=")) identity = line.substr(9); else if (line.startsWith("nickname=")) name = line.substr(9); } if (!identity) throw "missing identity keyword"; identity = identity.match(/^"?([0-9]+V[0-9a-zA-Z+\/]+[=]+)"?$/)[1]; if (!identity) throw "invalid identity key value"; const result = parse_string(identity); result.name = name || result.name; return result; })(); if (!ts_string.match(/[0-9]+/g)) throw "invalid hash!"; let buffer; try { buffer = new Uint8Array(arrayBufferBase64(data)); } catch (error) { log.error(LogCategory.IDENTITIES, _translations.mCXt2f6G || (_translations.mCXt2f6G = tr("Failed to decode given base64 data (%s)")), data); throw "failed to base data (base64 decode failed)"; } const key64 = yield CryptoHelper.decrypt_ts_identity(new Uint8Array(arrayBufferBase64(data))); const identity = new TeaSpeakIdentity(key64, hash, name, false); yield identity.initialize(); return identity; }); } fallback_name() { return this._name; } uid() { return this._unique_id; } type() { return identities.IdentitifyType.TEAMSPEAK; } valid() { return this._initialized && !!this._crypto_key && !!this._crypto_key_sign; } decode(data) { return __awaiter(this, void 0, void 0, function* () { const json = JSON.parse(data); if (!json) throw "invalid json"; if (json.version == 2) { this.private_key = json.key; this.hash_number = json.hash; this._name = json.name; } else if (json.version == 1) { const key = json.key; this._name = json.name; const clone = yield TeaSpeakIdentity.import_ts(key, false); this.private_key = clone.private_key; this.hash_number = clone.hash_number; } else throw "invalid version"; yield this.initialize(); }); } encode() { return JSON.stringify({ key: this.private_key, hash: this.hash_number, name: this._name, version: 2 }); } level() { return __awaiter(this, void 0, void 0, function* () { if (!this._initialized || !this.public_key) throw "not initialized"; const hash = new Uint8Array(yield sha.sha1(this.public_key + this.hash_number)); let level = 0; while (level < hash.byteLength && hash[level] == 0) level++; if (level >= hash.byteLength) { level = 256; } else { let byte = hash[level]; level <<= 3; while ((byte & 0x1) == 0) { level++; byte >>= 1; } } return level; }); } /** * @param {string} a * @param {string} b * @description b must be smaller (in bytes) then a */ string_add(a, b) { const char_result = []; const char_a = [...a].reverse().map(e => e.charCodeAt(0)); const char_b = [...b].reverse().map(e => e.charCodeAt(0)); let carry = false; while (char_b.length > 0) { let result = char_b.pop_front() + char_a.pop_front() + (carry ? 1 : 0) - 48; if ((carry = result > 57)) result -= 10; char_result.push(result); } while (char_a.length > 0) { let result = char_a.pop_front() + (carry ? 1 : 0); if ((carry = result > 57)) result -= 10; char_result.push(result); } if (carry) char_result.push(49); return String.fromCharCode.apply(null, char_result.slice().reverse()); } improve_level_for(time, threads) { return __awaiter(this, void 0, void 0, function* () { let active = true; setTimeout(() => active = false, time); return yield this.improve_level(-1, threads, () => active); }); } improve_level(target, threads, active_callback, callback_level, callback_status) { return __awaiter(this, void 0, void 0, function* () { if (!this._initialized || !this.public_key) throw "not initialized"; if (target == -1) /* get the highest level possible */ target = 0; else if (target <= (yield this.level())) return true; const workers = []; const iterations = 100000; let current_hash; const next_hash = () => { if (!current_hash) return (current_hash = this.hash_number); if (current_hash.length < iterations.toString().length) { current_hash = this.string_add(iterations.toString(), current_hash); } else { current_hash = this.string_add(current_hash, iterations.toString()); } return current_hash; }; { /* init */ const initialize_promise = []; for (let index = 0; index < threads; index++) { const worker = new IdentityPOWWorker(); workers.push(worker); initialize_promise.push(worker.initialize(this.public_key)); } try { yield Promise.all(initialize_promise); } catch (error) { log.error(LogCategory.IDENTITIES, error); throw "failed to initialize"; } } let result = false; let best_level = 0; let target_level = target > 0 ? target : (yield this.level()) + 1; const worker_promise = []; const hash_timestamps = []; let last_hashrate_update = 0; const update_hashrate = () => { if (!callback_status) return; const now = Date.now(); hash_timestamps.push(now); if (last_hashrate_update + 1000 < now) { last_hashrate_update = now; const timeout = now - 10 * 1000; /* 10s */ const rounds = hash_timestamps.filter(e => e > timeout); callback_status(Math.ceil((rounds.length * iterations) / Math.ceil((now - rounds[0]) / 1000))); } }; try { result = yield new Promise((resolve, reject) => { let active = true; const exit = () => { const timeout = setTimeout(() => resolve(true), 1000); Promise.all(worker_promise).then(result => { clearTimeout(timeout); resolve(true); }).catch(error => resolve(true)); active = false; }; for (const worker of workers) { const worker_mine = () => { if (!active) return; const promise = worker.mine(next_hash(), iterations, target_level); const p = promise.then(result => { update_hashrate(); worker_promise.remove(p); if (result.valueOf()) { if (worker.current_level() > best_level) { this.hash_number = worker.current_hash(); log.info(LogCategory.IDENTITIES, "Found new best at %s (%d). Old was %d", this.hash_number, worker.current_level(), best_level); best_level = worker.current_level(); if (callback_level) callback_level(best_level); } if (active) { if (target > 0) exit(); else target_level = best_level + 1; } } if (active && (active = active_callback())) setTimeout(() => worker_mine(), 0); else { exit(); } return Promise.resolve(); }).catch(error => { worker_promise.remove(p); log.warn(LogCategory.IDENTITIES, "POW worker error %o", error); reject(error); return Promise.resolve(); }); worker_promise.push(p); }; worker_mine(); } }); } catch (error) { //error already printed before reject had been called } { /* shutdown */ const finalize_promise = []; for (const worker of workers) finalize_promise.push(worker.finalize(250)); try { yield Promise.all(finalize_promise); } catch (error) { log.error(LogCategory.IDENTITIES, error); throw "failed to finalize"; } } return result; }); } initialize() { return __awaiter(this, void 0, void 0, function* () { if (!this.private_key) throw "Invalid private key"; let jwk; try { jwk = yield CryptoHelper.decode_tomcrypt_key(this.private_key); if (!jwk) throw "result undefined"; } catch (error) { throw "failed to parse key (" + error + ")"; } try { this._crypto_key_sign = yield crypto.subtle.importKey("jwk", jwk, { name: 'ECDSA', namedCurve: 'P-256' }, false, ["sign"]); } catch (error) { log.error(LogCategory.IDENTITIES, error); throw "failed to create crypto sign key"; } try { this._crypto_key = yield crypto.subtle.importKey("jwk", jwk, { name: 'ECDH', namedCurve: 'P-256' }, true, ["deriveKey"]); } catch (error) { log.error(LogCategory.IDENTITIES, error); throw "failed to create crypto key"; } try { this.public_key = yield CryptoHelper.export_ecc_key(this._crypto_key, true); this._unique_id = base64_encode_ab(yield sha.sha1(this.public_key)); } catch (error) { log.error(LogCategory.IDENTITIES, error); throw "failed to calculate unique id"; } this._initialized = true; //const public_key = await profiles.identities.CryptoHelper.export_ecc_key(key, true); }); } export_ts(ini) { return __awaiter(this, void 0, void 0, function* () { if (!this.private_key) throw "Invalid private key"; const identity = this.hash_number + "V" + (yield CryptoHelper.encrypt_ts_identity(new Uint8Array(str2ab8(this.private_key)))); if (!ini) return identity; return "[Identity]\n" + "id=TeaWeb-Exported\n" + "identity=\"" + identity + "\"\n" + "nickname=\"" + this.fallback_name() + "\"\n" + "phonetic_nickname="; }); } sign_message(message, hash = "SHA-256") { return __awaiter(this, void 0, void 0, function* () { /* bring this to libtomcrypt format */ const sign_buffer = yield crypto.subtle.sign({ name: "ECDSA", hash: hash }, this._crypto_key_sign, str2ab8(message)); const sign = new Uint8Array(sign_buffer); /* first 32 r bits | last 32 s bits */ const buffer = new Uint8Array(72); let index = 0; { /* the initial sequence */ buffer[index++] = 0x30; /* type */ buffer[index++] = 0x00; /* we will set the sequence length later */ } { /* integer r */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x20; /* length */ if (sign[0] > 0x7F) { buffer[index - 1] += 1; buffer[index++] = 0; } for (let i = 0; i < 32; i++) buffer[index++] = sign[i]; } { /* integer s */ buffer[index++] = 0x02; /* type */ buffer[index++] = 0x20; /* length */ if (sign[32] > 0x7F) { buffer[index - 1] += 1; buffer[index++] = 0; } for (let i = 0; i < 32; i++) buffer[index++] = sign[32 + i]; } buffer[1] = index - 2; return base64_encode_ab(buffer.subarray(0, index)); }); } spawn_identity_handshake_handler(connection) { return new TeaSpeakHandshakeHandler(connection, this); } } identities.TeaSpeakIdentity = TeaSpeakIdentity; })(identities = profiles.identities || (profiles.identities = {})); })(profiles || (profiles = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["252393eff9ee9bd3314e7489a9d25e6f643f4cde49f2b32fe1c7029eb0b5daee"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["252393eff9ee9bd3314e7489a9d25e6f643f4cde49f2b32fe1c7029eb0b5daee"] = "252393eff9ee9bd3314e7489a9d25e6f643f4cde49f2b32fe1c7029eb0b5daee"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "S4Ndcg1N", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (43,35)" }, { name: "EB7cq9IQ", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (44,27)" }, { name: "ObF9UjLw", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (54,23)" }, { name: "QqP4ziMI", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (61,31)" }, { name: "CB82sp6h", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (62,23)" }, { name: "XtV0zss8", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (158,37)" }, { name: "Vy5TBBLR", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (159,32)" }, { name: "OBRgr3qI", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (166,32)" }, { name: "aQTPJDUN", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (171,27)" }, { name: "qo0mcyqP", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (174,65)" }, { name: "dySnoVdL", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (179,27)" }, { name: "saqRg2Z9", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (181,27)" }, { name: "pWWqDzP0", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (185,27)" }, { name: "q7ZPaK5Y", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (192,31)" }, { name: "B_aTnd86", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (211,27)" }, { name: "Xp60Q526", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (214,32)" }, { name: "LyfKK5vy", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (240,37)" }, { name: "LGRGmAO1", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (241,32)" }, { name: "qQhEY7WN", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (246,19)" }, { name: "LWrXMvtN", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (250,27)" }, { name: "OyRiiDGL", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (251,52)" }, { name: "mOnXkXgi", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (261,19)" }, { name: "b7eQlRLY", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (263,23)" }, { name: "NKi7YaO9", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (271,27)" }, { name: "UFFPaqTS", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (272,19)" }, { name: "bxKhuXcc", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (298,37)" }, { name: "NxOnZbz3", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (299,32)" }, { name: "zRhhTEw9", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (304,19)" }, { name: "MqQjxf4A", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (308,27)" }, { name: "hJTwy8kO", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (309,52)" }, { name: "TPtST7cV", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (334,29)" }, { name: "oACRN0w_", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (341,31)" }, { name: "W98X1kxg", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (345,30)" }, { name: "v_PzN8TK", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (348,38)" }, { name: "TudD2giw", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (350,38)" }, { name: "SIztajHh", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (356,34)" }, { name: "iv0zFIyj", path: "D:/TeaSpeak/web/shared/js/profiles/identities/teaspeak-forum.ts (362,31)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var forum; (function (forum) { let gcaptcha; (function (gcaptcha) { function initialize() { return __awaiter(this, void 0, void 0, function* () { if (typeof (window.grecaptcha) === "undefined") { let script = document.createElement("script"); script.async = true; let timeout; const callback_name = "captcha_callback_" + Math.random().toString().replace(".", ""); try { yield new Promise((resolve, reject) => { script.onerror = reject; window[callback_name] = resolve; script.src = "https://www.google.com/recaptcha/api.js?onload=" + encodeURIComponent(callback_name) + "&render=explicit"; document.body.append(script); timeout = setTimeout(() => reject("timeout"), 15000); }); } catch (error) { script.remove(); script = undefined; console.error(_translations.S4Ndcg1N || (_translations.S4Ndcg1N = tr("Failed to fetch recaptcha javascript source: %o")), error); throw _translations.EB7cq9IQ || (_translations.EB7cq9IQ = tr("failed to download source")); } finally { if (script) script.onerror = undefined; delete window[callback_name]; clearTimeout(timeout); } } if (typeof (window.grecaptcha) === "undefined") throw _translations.ObF9UjLw || (_translations.ObF9UjLw = tr("failed to load recaptcha")); }); } gcaptcha.initialize = initialize; function spawn(container, key, callback_data) { return __awaiter(this, void 0, void 0, function* () { try { yield initialize(); } catch (error) { console.error(_translations.QqP4ziMI || (_translations.QqP4ziMI = tr("Failed to initialize G-Recaptcha. Error: %o")), error); throw _translations.CB82sp6h || (_translations.CB82sp6h = tr("initialisation failed")); } if (container.attr("captcha-uuid")) window.grecaptcha.reset(container.attr("captcha-uuid")); else { container.attr("captcha-uuid", window.grecaptcha.render(container[0], { "sitekey": key, callback: callback_data })); } }); } gcaptcha.spawn = spawn; })(gcaptcha = forum.gcaptcha || (forum.gcaptcha = {})); function api_url() { return settings.static_global(Settings.KEY_TEAFORO_URL); } class Data { constructor(auth, raw, sign) { this.auth_key = auth; this.raw = raw; this.sign = sign; this.parsed = JSON.parse(raw); } data_json() { return this.raw; } data_sign() { return this.sign; } name() { return this.parsed.user_name; } user_id() { return this.parsed.user_id; } user_group() { return this.parsed.user_group_id; } is_stuff() { return this.parsed.is_staff; } is_premium() { return this.parsed.user_groups.indexOf(5) != -1; } data_age() { return new Date(this.parsed.data_age); } is_expired() { return this.parsed.data_age + 48 * 60 * 60 * 1000 < Date.now(); } should_renew() { return this.parsed.data_age + 24 * 60 * 60 * 1000 < Date.now(); } /* renew data all 24hrs */ } forum.Data = Data; let _data; function logged_in() { return !!_data && !_data.is_expired(); } forum.logged_in = logged_in; function data() { return _data; } forum.data = data; function login(username, password, captcha) { return __awaiter(this, void 0, void 0, function* () { let response; try { response = yield new Promise((resolve, reject) => { $.ajax({ url: api_url() + "?web-api/v1/login", type: "POST", cache: false, data: { username: username, password: password, remember: true, "g-recaptcha-response": captcha }, crossDomain: true, success: resolve, error: (xhr, status, error) => { console.log(_translations.XtV0zss8 || (_translations.XtV0zss8 = tr("Login request failed %o: %o")), status, error); reject(_translations.Vy5TBBLR || (_translations.Vy5TBBLR = tr("request failed"))); } }); }); } catch (error) { return { status: "error", error_message: _translations.OBRgr3qI || (_translations.OBRgr3qI = tr("failed to send login request")) }; } if (response["status"] !== "ok") { console.error(_translations.aQTPJDUN || (_translations.aQTPJDUN = tr("Response status not okey. Error happend: %o")), response); return { status: "error", error_message: (response["errors"] || [])[0] || (_translations.qo0mcyqP || (_translations.qo0mcyqP = tr("Unknown error"))) }; } if (!response["success"]) { console.error(_translations.dySnoVdL || (_translations.dySnoVdL = tr("Login failed. Response %o")), response); let message = _translations.saqRg2Z9 || (_translations.saqRg2Z9 = tr("failed to login")); let captcha; /* user/password wrong | and maybe captcha required */ if (response["code"] == 1 || response["code"] == 3) message = _translations.pWWqDzP0 || (_translations.pWWqDzP0 = tr("Invalid username or password")); if (response["code"] == 2 || response["code"] == 3) { captcha = { type: response["captcha"]["type"], data: response["captcha"]["siteKey"] //TODO: Why so static here? }; if (response["code"] == 2) message = _translations.q7ZPaK5Y || (_translations.q7ZPaK5Y = tr("captcha required")); } return { status: typeof (captcha) !== "undefined" ? "captcha" : "error", error_message: message, captcha: captcha }; } //document.cookie = "user_data=" + response["data"] + ";path=/"; //document.cookie = "user_sign=" + response["sign"] + ";path=/"; try { _data = new Data(response["auth-key"], response["data"], response["sign"]); localStorage.setItem("teaspeak-forum-data", response["data"]); localStorage.setItem("teaspeak-forum-sign", response["sign"]); localStorage.setItem("teaspeak-forum-auth", response["auth-key"]); profiles.identities.update_forum(); } catch (error) { console.error(_translations.B_aTnd86 || (_translations.B_aTnd86 = tr("Failed to parse forum given data: %o")), error); return { status: "error", error_message: _translations.Xp60Q526 || (_translations.Xp60Q526 = tr("Failed to parse response data")) }; } return { status: "success" }; }); } forum.login = login; function renew_data() { return __awaiter(this, void 0, void 0, function* () { let response; try { response = yield new Promise((resolve, reject) => { $.ajax({ url: api_url() + "?web-api/v1/renew-data", type: "GET", cache: false, crossDomain: true, data: { "auth-key": _data.auth_key }, success: resolve, error: (xhr, status, error) => { console.log(_translations.LyfKK5vy || (_translations.LyfKK5vy = tr("Renew request failed %o: %o")), status, error); reject(_translations.LGRGmAO1 || (_translations.LGRGmAO1 = tr("request failed"))); } }); }); } catch (error) { throw _translations.qQhEY7WN || (_translations.qQhEY7WN = tr("failed to send renew request")); } if (response["status"] !== "ok") { console.error(_translations.LWrXMvtN || (_translations.LWrXMvtN = tr("Response status not okey. Error happend: %o")), response); throw (response["errors"] || [])[0] || (_translations.OyRiiDGL || (_translations.OyRiiDGL = tr("Unknown error"))); } if (!response["success"]) { if (response["code"] == 1) { return "login-required"; } throw "invalid error code (" + response["code"] + ")"; } if (!response["data"] || !response["sign"]) throw _translations.mOnXkXgi || (_translations.mOnXkXgi = tr("response missing data")); console.debug(_translations.b7eQlRLY || (_translations.b7eQlRLY = tr("Renew succeeded. Parsing data."))); try { _data = new Data(_data.auth_key, response["data"], response["sign"]); localStorage.setItem("teaspeak-forum-data", response["data"]); localStorage.setItem("teaspeak-forum-sign", response["sign"]); profiles.identities.update_forum(); } catch (error) { console.error(_translations.NKi7YaO9 || (_translations.NKi7YaO9 = tr("Failed to parse forum given data: %o")), error); throw _translations.UFFPaqTS || (_translations.UFFPaqTS = tr("failed to parse data")); } return "success"; }); } forum.renew_data = renew_data; function logout() { return __awaiter(this, void 0, void 0, function* () { if (!logged_in()) return; let response; try { response = yield new Promise((resolve, reject) => { $.ajax({ url: api_url() + "?web-api/v1/logout", type: "GET", cache: false, crossDomain: true, data: { "auth-key": _data.auth_key }, success: resolve, error: (xhr, status, error) => { console.log(_translations.bxKhuXcc || (_translations.bxKhuXcc = tr("Logout request failed %o: %o")), status, error); reject(_translations.NxOnZbz3 || (_translations.NxOnZbz3 = tr("request failed"))); } }); }); } catch (error) { throw _translations.zRhhTEw9 || (_translations.zRhhTEw9 = tr("failed to send logout request")); } if (response["status"] !== "ok") { console.error(_translations.MqQjxf4A || (_translations.MqQjxf4A = tr("Response status not okey. Error happend: %o")), response); throw (response["errors"] || [])[0] || (_translations.hJTwy8kO || (_translations.hJTwy8kO = tr("Unknown error"))); } if (!response["success"]) { /* code 1 means not logged in, its an success */ if (response["code"] != 1) { throw "invalid error code (" + response["code"] + ")"; } } _data = undefined; localStorage.removeItem("teaspeak-forum-data"); localStorage.removeItem("teaspeak-forum-sign"); localStorage.removeItem("teaspeak-forum-auth"); profiles.identities.update_forum(); }); } forum.logout = logout; loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "TeaForo initialize", priority: 10, function: () => __awaiter(this, void 0, void 0, function* () { const raw_data = localStorage.getItem("teaspeak-forum-data"); const raw_sign = localStorage.getItem("teaspeak-forum-sign"); const forum_auth = localStorage.getItem("teaspeak-forum-auth"); if (!raw_data || !raw_sign || !forum_auth) { console.log(_translations.TPtST7cV || (_translations.TPtST7cV = tr("No TeaForo authentification found. TeaForo connection status: unconnected"))); return; } try { _data = new Data(forum_auth, raw_data, raw_sign); } catch (error) { console.error(_translations.oACRN0w_ || (_translations.oACRN0w_ = tr("Failed to initialize TeaForo connection from local data. Error: %o")), error); return; } if (_data.should_renew()) { console.info(_translations.W98X1kxg || (_translations.W98X1kxg = tr("TeaForo data should be renewed. Executing renew."))); renew_data().then(status => { if (status === "success") { console.info(_translations.v_PzN8TK || (_translations.v_PzN8TK = tr("TeaForo data has been successfully renewed."))); } else { console.warn(_translations.TudD2giw || (_translations.TudD2giw = tr("Failed to renew TeaForo data. New login required."))); localStorage.removeItem("teaspeak-forum-data"); localStorage.removeItem("teaspeak-forum-sign"); localStorage.removeItem("teaspeak-forum-auth"); } }).catch(error => { console.warn(_translations.SIztajHh || (_translations.SIztajHh = tr("Failed to renew TeaForo data. An error occurred: %o")), error); }); return; } if (_data && _data.is_expired()) { console.error(_translations.iv0zFIyj || (_translations.iv0zFIyj = tr("TeaForo data is expired. TeaForo connection isn't available!"))); } }) }); })(forum || (forum = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3ac4bc90640ab00e41ec66d414aef709d86113a645f77b253e52e9efeb40b68d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3ac4bc90640ab00e41ec66d414aef709d86113a645f77b253e52e9efeb40b68d"] = "3ac4bc90640ab00e41ec66d414aef709d86113a645f77b253e52e9efeb40b68d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "aSWrAHYB", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (233,25)" }, { name: "UkmzxtCM", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (252,41)" }, { name: "kN3PHhau", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (262,45)" }, { name: "qr1gpdRg", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (270,49)" }, { name: "HoO3dFkw", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (282,49)" }, { name: "jBQ2VSvY", path: "D:/TeaSpeak/web/shared/js/sound/Sounds.ts (289,45)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Sound; (function (Sound) { Sound["SOUND_TEST"] = "sound.test"; Sound["SOUND_EGG"] = "sound.egg"; Sound["AWAY_ACTIVATED"] = "away_activated"; Sound["AWAY_DEACTIVATED"] = "away_deactivated"; Sound["MICROPHONE_MUTED"] = "microphone.muted"; Sound["MICROPHONE_ACTIVATED"] = "microphone.activated"; Sound["SOUND_MUTED"] = "sound.muted"; Sound["SOUND_ACTIVATED"] = "sound.activated"; Sound["CONNECTION_CONNECTED"] = "connection.connected"; Sound["CONNECTION_DISCONNECTED"] = "connection.disconnected"; Sound["CONNECTION_BANNED"] = "connection.banned"; Sound["CONNECTION_DISCONNECTED_TIMEOUT"] = "connection.disconnected.timeout"; Sound["CONNECTION_REFUSED"] = "connection.refused"; Sound["SERVER_EDITED"] = "server.edited"; Sound["SERVER_EDITED_SELF"] = "server.edited.self"; Sound["SERVER_KICKED"] = "server.kicked"; Sound["CHANNEL_CREATED"] = "channel.created"; Sound["CHANNEL_MOVED"] = "channel.moved"; Sound["CHANNEL_EDITED"] = "channel.edited"; Sound["CHANNEL_EDITED_SELF"] = "channel.edited.self"; Sound["CHANNEL_DELETED"] = "channel.deleted"; Sound["CHANNEL_JOINED"] = "channel.joined"; Sound["CHANNEL_KICKED"] = "channel.kicked"; Sound["USER_MOVED"] = "user.moved"; Sound["USER_MOVED_SELF"] = "user.moved.self"; Sound["USER_POKED_SELF"] = "user.poked.self"; Sound["USER_BANNED"] = "user.banned"; Sound["USER_ENTERED"] = "user.joined"; Sound["USER_ENTERED_MOVED"] = "user.joined.moved"; Sound["USER_ENTERED_KICKED"] = "user.joined.kicked"; Sound["USER_ENTERED_CONNECT"] = "user.joined.connect"; Sound["USER_LEFT"] = "user.left"; Sound["USER_LEFT_MOVED"] = "user.left.moved"; Sound["USER_LEFT_KICKED_CHANNEL"] = "user.left.kicked.server"; Sound["USER_LEFT_KICKED_SERVER"] = "user.left.kicked.channel"; Sound["USER_LEFT_DISCONNECT"] = "user.left.disconnect"; Sound["USER_LEFT_BANNED"] = "user.left.banned"; Sound["USER_LEFT_TIMEOUT"] = "user.left.timeout"; Sound["ERROR_INSUFFICIENT_PERMISSIONS"] = "error.insufficient_permissions"; Sound["MESSAGE_SEND"] = "message.send"; Sound["MESSAGE_RECEIVED"] = "message.received"; Sound["GROUP_SERVER_ASSIGNED"] = "group.server.assigned"; Sound["GROUP_SERVER_REVOKED"] = "group.server.revoked"; Sound["GROUP_CHANNEL_CHANGED"] = "group.channel.changed"; Sound["GROUP_SERVER_ASSIGNED_SELF"] = "group.server.assigned.self"; Sound["GROUP_SERVER_REVOKED_SELF"] = "group.server.revoked.self"; Sound["GROUP_CHANNEL_CHANGED_SELF"] = "group.channel.changed.self"; })(Sound || (Sound = {})); var sound; (function (sound_1) { let speech_mapping = {}; let volume_require_save = false; let speech_volume = {}; let master_volume; let overlap_sounds; let ignore_muted; let master_mixed; function register_sound(key, file) { speech_mapping[key] = { key: key, filename: file }; } function get_sound_volume(sound, default_volume) { let result = speech_volume[sound]; if (typeof (result) === "undefined") { if (typeof (default_volume) !== "undefined") result = default_volume; else result = 1; } return result; } sound_1.get_sound_volume = get_sound_volume; function set_sound_volume(sound, volume) { volume_require_save = volume_require_save || speech_volume[sound] != volume; speech_volume[sound] = volume == 1 ? undefined : volume; } sound_1.set_sound_volume = set_sound_volume; function get_master_volume() { return master_volume; } sound_1.get_master_volume = get_master_volume; function set_master_volume(volume) { volume_require_save = volume_require_save || master_volume != volume; master_volume = volume; if (master_mixed) { if (master_mixed.gain.setValueAtTime) master_mixed.gain.setValueAtTime(volume, 0); else master_mixed.gain.value = volume; } } sound_1.set_master_volume = set_master_volume; function overlap_activated() { return overlap_sounds; } sound_1.overlap_activated = overlap_activated; function set_overlap_activated(flag) { volume_require_save = volume_require_save || overlap_sounds != flag; overlap_sounds = flag; } sound_1.set_overlap_activated = set_overlap_activated; function ignore_output_muted() { return ignore_muted; } sound_1.ignore_output_muted = ignore_output_muted; function set_ignore_output_muted(flag) { volume_require_save = volume_require_save || ignore_muted != flag; ignore_muted = flag; } sound_1.set_ignore_output_muted = set_ignore_output_muted; function reinitialisize_audio() { const context = audio.player.context(); const destination = audio.player.destination(); if (master_mixed) master_mixed.disconnect(); master_mixed = context.createGain(); if (master_mixed.gain.setValueAtTime) master_mixed.gain.setValueAtTime(master_volume, 0); else master_mixed.gain.value = master_volume; master_mixed.connect(destination); } sound_1.reinitialisize_audio = reinitialisize_audio; function save() { if (volume_require_save) { volume_require_save = false; const data = {}; data.version = 1; for (const key in Sound) { if (typeof (speech_volume[Sound[key]]) !== "undefined") data[Sound[key]] = speech_volume[Sound[key]]; } data.master = master_volume; data.overlap = overlap_sounds; data.ignore_muted = ignore_muted; settings.changeGlobal("sound_volume", JSON.stringify(data)); } } sound_1.save = save; function initialize() { $.ajaxSetup({ beforeSend: function (jqXHR, settings) { if (settings.dataType === 'binary') { settings.xhr().responseType = 'arraybuffer'; settings.processData = false; } } }); /* volumes */ { const data = JSON.parse(settings.static_global("sound_volume", "{}")); for (const sound_key in Sound) { if (typeof (data[Sound[sound_key]]) !== "undefined") speech_volume[Sound[sound_key]] = data[Sound[sound_key]]; } master_volume = typeof (data.master) === "number" ? data.master : 1; overlap_sounds = typeof (data.overlap) === "boolean" ? data.overlap : true; ignore_muted = typeof (data.ignore_muted) === "boolean" ? data.ignore_muted : false; } register_sound("message.received", "effects/message_received.wav"); register_sound("message.send", "effects/message_send.wav"); sound_1.manager = new SoundManager(undefined); audio.player.on_ready(reinitialisize_audio); return new Promise((resolve, reject) => { $.ajax({ url: "audio/speech/mapping.json", success: response => { if (typeof (response) === "string") response = JSON.parse(response); for (const entry of response) register_sound(entry.key, "speech/" + entry.file); resolve(); }, error: error => { log.error(LogCategory.AUDIO, "error: %o", error); reject(); }, timeout: 5000, async: true, type: 'GET' }); }); } sound_1.initialize = initialize; function resolve_sound(sound) { return __awaiter(this, void 0, void 0, function* () { const file = speech_mapping[sound]; if (!file) throw _translations.aSWrAHYB || (_translations.aSWrAHYB = tr("Missing sound handle")); return file; }); } sound_1.resolve_sound = resolve_sound; class SoundManager { constructor(handle) { this._playing_sounds = {}; this._handle = handle; } play(_sound, options) { options = options || {}; const volume = get_sound_volume(_sound, options.default_volume); log.info(LogCategory.AUDIO, _translations.UkmzxtCM || (_translations.UkmzxtCM = tr("Replaying sound %s (Sound volume: %o | Master volume %o)")), _sound, volume, master_volume); if (volume == 0 || master_volume == 0) return; if (this._handle && !options.ignore_muted && !sound.ignore_output_muted() && this._handle.client_status.output_muted) return; const context = audio.player.context(); if (!context) { log.warn(LogCategory.AUDIO, _translations.kN3PHhau || (_translations.kN3PHhau = tr("Tried to replay a sound without an audio context (Sound: %o). Dropping playback")), _sound); return; } sound.resolve_sound(_sound).then(handle => { if (!handle) return; if (!options.ignore_overlap && (this._playing_sounds[handle.filename] > 0) && !sound.overlap_activated()) { log.info(LogCategory.AUDIO, _translations.qr1gpdRg || (_translations.qr1gpdRg = tr("Dropping requested playback for sound %s because it would overlap.")), _sound); return; } this._playing_sounds[handle.filename] = (this._playing_sounds[handle.filename] || 0) + 1; audio.sounds.play_sound({ path: "audio/" + handle.filename, volume: volume * master_volume }).then(() => { if (options.callback) options.callback(true); }).catch(error => { log.warn(LogCategory.AUDIO, _translations.HoO3dFkw || (_translations.HoO3dFkw = tr("Failed to replay sound %s: %o")), handle.filename, error); if (options.callback) options.callback(false); }).then(() => { this._playing_sounds[handle.filename]--; }); }).catch(error => { log.warn(LogCategory.AUDIO, _translations.jBQ2VSvY || (_translations.jBQ2VSvY = tr("Failed to replay sound %o because it could not be resolved: %o")), sound, error); if (options.callback) options.callback(false); }); } } sound_1.SoundManager = SoundManager; })(sound || (sound = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["94fd90a83218a1cef495ffe767f26df95b1521f409477f9ee4d9e716cb205b4d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["94fd90a83218a1cef495ffe767f26df95b1521f409477f9ee4d9e716cb205b4d"] = "94fd90a83218a1cef495ffe767f26df95b1521f409477f9ee4d9e716cb205b4d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "L1w47X12", path: "D:/TeaSpeak/web/shared/js/ui/htmltags.ts (41,30)" }, { name: "tylczNSM", path: "D:/TeaSpeak/web/shared/js/ui/htmltags.ts (49,30)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var htmltags; (function (htmltags) { let mouse_coordinates = { x: 0, y: 0 }; function initialize() { document.addEventListener('mousemove', event => { mouse_coordinates.x = event.pageX; mouse_coordinates.y = event.pageY; }); } initialize(); /* required for the bbcodes */ function generate_client_open(properties) { let result = ""; /* build the opening tag:
*/ result = result + "
"; return result; } function generate_client(properties) { let result = generate_client_open(properties); /* content */ { if (properties.add_braces) result = result + "\""; result = result + MessageHelper.htmlEscape(properties.client_name || "undefined").join(" "); if (properties.add_braces) result = result + "\""; } /* close tag */ { result += "
"; } return result; } htmltags.generate_client = generate_client; function generate_client_object(properties) { return $(this.generate_client(properties)); } htmltags.generate_client_object = generate_client_object; /* required for the bbcodes */ function generate_channel_open(properties) { let result = ""; /* build the opening tag:
*/ result = result + "
"; return result; } function generate_channel(properties) { let result = generate_channel_open(properties); /* content */ { if (properties.add_braces) result = result + "\""; result = result + MessageHelper.htmlEscape(properties.channel_display_name || properties.channel_name || "undefined").join(" "); if (properties.add_braces) result = result + "\""; } /* close tag */ { result += "
"; } return result; } htmltags.generate_channel = generate_channel; function generate_channel_object(properties) { return $(this.generate_channel(properties)); } htmltags.generate_channel_object = generate_channel_object; let callbacks; (function (callbacks) { function callback_context_client(element) { const client_id = parseInt(element.attr("client-id") || "0"); const client_unique_id = decodeURIComponent(element.attr("client-unique-id") || ""); /* we ignore the name, we cant find clients by name because the name is too volatile*/ let client; const current_connection = server_connections.active_connection_handler(); if (current_connection && current_connection.channelTree) { if (!client && client_id) { client = current_connection.channelTree.findClient(client_id); if (client && (client_unique_id && client.properties.client_unique_identifier != client_unique_id)) { client = undefined; /* client id dosn't match anymore, lets search for the unique id */ } } if (!client && client_unique_id) client = current_connection.channelTree.find_client_by_unique_id(client_unique_id); if (!client) { if (current_connection.channelTree.server.properties.virtualserver_unique_identifier === client_unique_id) { current_connection.channelTree.server.spawnContextMenu(mouse_coordinates.x, mouse_coordinates.y); return; } } } if (!client) { /* we may should open a "offline" menu? */ log.debug(LogCategory.GENERAL, "Failed to resolve client from html tag. Client id: %o, Client unique id: %o, Client name: %o", client_id, client_unique_id, decodeURIComponent(element.attr("client-name"))); return false; } client.showContextMenu(mouse_coordinates.x, mouse_coordinates.y); return false; } callbacks.callback_context_client = callback_context_client; function callback_context_channel(element) { const channel_id = parseInt(element.attr("channel-id") || "0"); const current_connection = server_connections.active_connection_handler(); let channel; if (current_connection && current_connection.channelTree) { channel = current_connection.channelTree.findChannel(channel_id); } if (!channel) return false; channel.showContextMenu(mouse_coordinates.x, mouse_coordinates.y); return false; } callbacks.callback_context_channel = callback_context_channel; })(callbacks = htmltags.callbacks || (htmltags.callbacks = {})); let bbcodes; (function (bbcodes) { /* the = because we sometimes get that */ //const url_client_regex = /?client:\/\/(?[0-9]+)\/(?[a-zA-Z0-9+=#]+)~(?(?:[^%]|%[0-9A-Fa-f]{2})+)$/g; const url_client_regex = /client:\/\/([0-9]+)\/([a-zA-Z0-9+=/#]+)~((?:[^%]|%[0-9A-Fa-f]{2})+)$/g; /* IDK which browsers already support group naming */ const url_channel_regex = /channel:\/\/([0-9]+)~((?:[^%]|%[0-9A-Fa-f]{2})+)$/g; function initialize() { const origin_url = xbbcode.register.find_parser('url'); xbbcode.register.register_parser({ tag: 'url', build_html_tag_open(layer) { if (layer.options) { if (layer.options.match(url_channel_regex)) { const groups = url_channel_regex.exec(layer.options); return generate_channel_open({ add_braces: false, channel_id: parseInt(groups[1]), channel_name: decodeURIComponent(groups[2]) }); } else if (layer.options.match(url_client_regex)) { const groups = url_client_regex.exec(layer.options); return generate_client_open({ add_braces: false, client_id: parseInt(groups[1]), client_unique_id: groups[2], client_name: decodeURIComponent(groups[3]) }); } } return origin_url.build_html_tag_open(layer); }, build_html_tag_close(layer) { if (layer.options) { if (layer.options.match(url_client_regex)) return "
"; if (layer.options.match(url_channel_regex)) return "
"; } return origin_url.build_html_tag_close(layer); } }); /* "img": { openTag: function(params,content) { let myUrl; if (!params) { myUrl = content.replace(/<.*?>/g,""); } else { myUrl = params.substr(1); } urlPattern.lastIndex = 0; if ( !urlPattern.test( myUrl ) ) { myUrl = "#"; } return ''; }, closeTag: function(params,content) { return ''; } }, */ } initialize(); })(bbcodes || (bbcodes = {})); })(htmltags || (htmltags = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e015f9e59a056d21357482ef065db99f87293c0c9049bdfeb1cb3c1515932bec"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e015f9e59a056d21357482ef065db99f87293c0c9049bdfeb1cb3c1515932bec"] = "e015f9e59a056d21357482ef065db99f87293c0c9049bdfeb1cb3c1515932bec"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "sXkKn_Vj", path: "D:/TeaSpeak/web/shared/js/ui/elements/context_divider.ts (128,56)" }, { name: "yvApqoiK", path: "D:/TeaSpeak/web/shared/js/ui/elements/context_divider.ts (133,56)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } if (!$.fn.dividerfy) { $.fn.dividerfy = function () { this.find(".container-seperator").each(function () { if (!this.previousElementSibling) return; if (!this.nextElementSibling) return; const element = $(this); const parent_element = $(this.parentElement); const previous_element = $(this.previousElementSibling); const next_element = $(this.nextElementSibling); const seperator_id = element.attr("seperator-id"); const vertical = element.hasClass("vertical"); const apply_view = (property, previous, next) => { if (previous + next != 100) { //Fix values if they dont addup to 100 const diff = 100 - (previous + next); previous += diff * previous / (previous + next); next += diff * next / (previous + next); //Some minor adjustments due to roundings next += 100 - (previous + next); } const center = (vertical ? element.width() : element.height()) / 2; const value_a = "calc(" + previous + "% - " + center + "px)"; const value_b = "calc(" + next + "% - " + center + "px)"; /* dont cause a reflow here */ if (property === "height") { previous_element[0].style.height = value_a; next_element[0].style.height = value_b; } else { previous_element[0].style.width = value_a; next_element[0].style.width = value_b; } }; const listener_move = (event) => { const parent_offset = parent_element.offset(); const min = vertical ? parent_offset.left : parent_offset.top; const max = vertical ? parent_offset.left + parent_element.width() : parent_offset.top + parent_element.height(); const current = event instanceof MouseEvent ? (vertical ? event.pageX : event.pageY) : (vertical ? event.touches[event.touches.length - 1].clientX : event.touches[event.touches.length - 1].clientY); /* const previous_offset = previous_element.offset(); const next_offset = next_element.offset(); const min = vertical ? Math.min(previous_offset.left, next_offset.left) : Math.min(previous_offset.top, next_offset.top); const max = vertical ? Math.max(previous_offset.left + previous_element.width(), next_offset.left + next_element.width()) : Math.max(previous_offset.top + previous_element.height(), next_offset.top + next_element.height()); */ let previous = 0; let next = 0; if (current < min) { previous = 0; next = 1; } else if (current < max) { const x_offset = current - min; const x_offset_max = max - min; previous = x_offset / x_offset_max; next = 1 - previous; } else { previous = 1; next = 0; } //console.log(min + " - " + max + " - " + current); const property = vertical ? "width" : "height"; const previous_p = Math.ceil(previous * 100); const next_p = Math.ceil(next * 100); apply_view(property, previous_p, next_p); if (seperator_id) settings.changeGlobal("seperator-settings-" + seperator_id, JSON.stringify({ previous: previous_p, next: next_p, property: property })); }; const listener_up = (event) => { document.removeEventListener('mousemove', listener_move); document.removeEventListener('touchmove', listener_move); document.removeEventListener('mouseup', listener_up); document.removeEventListener('touchend', listener_up); document.removeEventListener('touchcancel', listener_up); $(document.documentElement).css("user-select", ""); element.removeClass("seperator-selected"); next_element.find("[x-divider-require-resize]").trigger('resize'); previous_element.find("[x-divider-require-resize]").trigger('resize'); }; element.on('mousedown', () => { document.addEventListener('mousemove', listener_move); document.addEventListener('touchmove', listener_move); document.addEventListener('mouseup', listener_up); document.addEventListener('touchend', listener_up); document.addEventListener('touchcancel', listener_up); $(document.documentElement).css("user-select", "none"); element.addClass("seperator-selected"); }); element.on('touchstart', () => { element.trigger('mousedown'); }); if (seperator_id) { try { const config = JSON.parse(settings.global("seperator-settings-" + seperator_id)); if (config) { log.debug(LogCategory.GENERAL, _translations.sXkKn_Vj || (_translations.sXkKn_Vj = tr("Applying previous changed sperator settings for %s: %o")), seperator_id, config); apply_view(config.property, config.previous, config.next); } } catch (e) { if (!(e instanceof SyntaxError)) log.error(LogCategory.GENERAL, _translations.yvApqoiK || (_translations.yvApqoiK = tr("Failed to parse seperator settings for sperator %s: %o")), seperator_id, e); } } }); return this; }; } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["419e31bbcbccf7164faea307d49009f573280d58339c5f7ec7f7d00e4dcc73d0"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["419e31bbcbccf7164faea307d49009f573280d58339c5f7ec7f7d00e4dcc73d0"] = "419e31bbcbccf7164faea307d49009f573280d58339c5f7ec7f7d00e4dcc73d0"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var net; (function (net) { var graph; (function (graph) { /* Great explanation of Bezier curves: http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_curves * * Assuming A was the last point in the line plotted and B is the new point, * we draw a curve with control points P and Q as below. * * A---P * | * | * | * Q---B * * Importantly, A and P are at the same y coordinate, as are B and Q. This is * so adjacent curves appear to flow as one. */ class Graph { constructor(canvas) { this.style = { background_color: "#28292b", //background_color: "red", separator_color: "#283036", //separator_color: 'blue', separator_count: 10, separator_width: 1, upload: { fill: "#2d3f4d", stroke: "#336e9f", strike_width: 2, }, download: { fill: "#532c26", stroke: "#a9321c", strike_width: 2, } }; this._entries = []; this._entry_max = { upload: 1, download: 1, }; this._max_space = 1.12; this._max_gap = 5; this._time_span = { origin: { begin: 0, end: 1, time: 0 }, target: { begin: 0, end: 1, time: 1 } }; this._detailed_shown = false; this.canvas = canvas; this._animate_loop = () => this.draw(); this.recalculate_cache(); /* initialize cache */ } initialize() { this._canvas_context = this.canvas.getContext("2d"); Graph._loops.push(this._animate_loop); if (Graph._loops.length == 1) { const static_loop = () => { Graph._loops.forEach(l => l()); if (Graph._loops.length > 0) requestAnimationFrame(static_loop); else console.log("STATIC terminate!"); }; static_loop(); } this.canvas.onmousemove = this.on_mouse_move.bind(this); this.canvas.onmouseleave = this.on_mouse_leave.bind(this); } terminate() { Graph._loops.remove(this._animate_loop); } max_gap_size(value) { return typeof (value) === "number" ? (this._max_gap = value) : this._max_gap; } recalculate_cache(time_span) { this._entries = this._entries.sort((a, b) => a.timestamp - b.timestamp); this._entry_max = { download: 1, upload: 1 }; if (time_span) { this._time_span = { origin: { begin: 0, end: 0, time: 0 }, target: { begin: this._entries.length > 0 ? this._entries[0].timestamp : 0, end: this._entries.length > 0 ? this._entries.last().timestamp : 0, time: 0 } }; } for (const entry of this._entries) { if (typeof (entry.upload) === "number") this._entry_max.upload = Math.max(this._entry_max.upload, entry.upload); if (typeof (entry.download) === "number") this._entry_max.download = Math.max(this._entry_max.download, entry.download); } this._entry_max.upload *= this._max_space; this._entry_max.download *= this._max_space; } insert_entry(entry) { if (this._entries.length > 0 && entry.timestamp < this._entries.last().timestamp) throw "invalid timestamp"; this._entries.push(entry); if (typeof (entry.upload) === "number") this._entry_max.upload = Math.max(this._entry_max.upload, entry.upload * this._max_space); if (typeof (entry.download) === "number") this._entry_max.download = Math.max(this._entry_max.download, entry.download * this._max_space); } insert_entries(entries) { this._entries.push(...entries); this.recalculate_cache(); this.cleanup(); } resize() { this.canvas.style.height = "100%"; this.canvas.style.width = "100%"; const cstyle = getComputedStyle(this.canvas); this.canvas.width = parseInt(cstyle.width); this.canvas.height = parseInt(cstyle.height); } cleanup() { const time = this.calculate_time_span(); let index = 0; for (; index < this._entries.length; index++) { if (this._entries[index].timestamp < time.begin) continue; if (index == 0) return; break; } /* keep the last entry as a reference point to the left */ if (index > 1) { this._entries.splice(0, index - 1); this.recalculate_cache(); } } calculate_time_span() { const time = Date.now(); if (time >= this._time_span.target.time) return this._time_span.target; if (time <= this._time_span.origin.time) return this._time_span.origin; const ob = this._time_span.origin.begin; const oe = this._time_span.origin.end; const ot = this._time_span.origin.time; const tb = this._time_span.target.begin; const te = this._time_span.target.end; const tt = this._time_span.target.time; const offset = (time - ot) / (tt - ot); return { begin: ob + (tb - ob) * offset, end: oe + (te - oe) * offset, }; } draw() { let ctx = this._canvas_context; const height = this.canvas.height; const width = this.canvas.width; //console.log("Painting on %ox%o", height, width); ctx.shadowBlur = 0; ctx.filter = ""; ctx.lineCap = "square"; ctx.fillStyle = this.style.background_color; ctx.fillRect(0, 0, width, height); /* first of all print the separators */ { const sw = this.style.separator_width; const swh = this.style.separator_width / 2; ctx.lineWidth = sw; ctx.strokeStyle = this.style.separator_color; ctx.beginPath(); /* horizontal */ { const dw = width / this.style.separator_count; let dx = dw / 2; while (dx < width) { ctx.moveTo(Math.floor(dx - swh) + .5, .5); ctx.lineTo(Math.floor(dx - swh) + .5, Math.floor(height) + .5); dx += dw; } } /* vertical */ { const dh = height / 3; //tree lines (top, center, bottom) let dy = dh / 2; while (dy < height) { ctx.moveTo(.5, Math.floor(dy - swh) + .5); ctx.lineTo(Math.floor(width) + .5, Math.floor(dy - swh) + .5); dy += dh; } } ctx.stroke(); ctx.closePath(); } /* draw the lines */ { const t = this.calculate_time_span(); const tb = t.begin; /* time begin */ const dt = t.end - t.begin; /* delta time */ const dtw = width / dt; /* delta time width */ const draw_graph = (type, direction, max) => { const hy = Math.floor(height / 2); /* half y */ const by = hy - direction * this.style[type].strike_width; /* the "base" line */ const marked_points = []; ctx.beginPath(); ctx.moveTo(0, by); let x, y, lx = 0, ly = by; /* last x, last y */ const floor = a => a; //Math.floor; for (const entry of this._entries) { x = floor((entry.timestamp - tb) * dtw); if (typeof entry[type] === "number") y = floor(hy - direction * Math.max(hy * (entry[type] / max), this.style[type].strike_width)); else y = hy - direction * this.style[type].strike_width; if (entry.timestamp < tb) { lx = x; ly = y; continue; } if (x - lx > this._max_gap && this._max_gap > 0) { ctx.lineTo(lx, by); ctx.lineTo(x, by); ctx.lineTo(x, y); lx = x; ly = y; continue; } ctx.bezierCurveTo((x + lx) / 2, ly, (x + lx) / 2, y, x, y); if (entry.highlight) marked_points.push({ x: x, y: y }); lx = x; ly = y; } ctx.strokeStyle = this.style[type].stroke; ctx.lineWidth = this.style[type].strike_width; ctx.lineJoin = "miter"; ctx.stroke(); //Close the path and fill ctx.lineTo(width, hy); ctx.lineTo(0, hy); ctx.fillStyle = this.style[type].fill; ctx.fill(); ctx.closePath(); { ctx.beginPath(); const radius = 3; for (const point of marked_points) { ctx.moveTo(point.x, point.y); ctx.ellipse(point.x, point.y, radius, radius, 0, 0, 2 * Math.PI, false); } ctx.stroke(); ctx.fill(); ctx.closePath(); } }; const shared_max = Math.max(this._entry_max.upload, this._entry_max.download); draw_graph("upload", 1, shared_max); draw_graph("download", -1, shared_max); } } on_mouse_move(event) { const offset = event.offsetX; const max_offset = this.canvas.width; if (offset < 0) return; if (offset > max_offset) return; const time_span = this.calculate_time_span(); const time = time_span.begin + (time_span.end - time_span.begin) * (offset / max_offset); let index = 0; for (; index < this._entries.length; index++) { if (this._entries[index].timestamp > time) break; } const entry_before = this._entries[index - 1]; /* In JS negative array access is allowed and returns undefined */ const entry_next = this._entries[index]; /* In JS negative array access is allowed and returns undefined */ let entry; if (!entry_before || !entry_next) { entry = entry_before || entry_next; } else { const dn = entry_next.timestamp - time; const db = time - entry_before.timestamp; if (dn > db) entry = entry_before; else entry = entry_next; } if (!entry) { this.on_mouse_leave(event); } else { this._entries.forEach(e => e.highlight = false); this._detailed_shown = true; entry.highlight = true; if (this.callback_detailed_info) this.callback_detailed_info(entry.upload, entry.download, entry.timestamp, event); } } on_mouse_leave(event) { if (!this._detailed_shown) return; this._detailed_shown = false; this._entries.forEach(e => e.highlight = false); if (this.callback_detailed_hide) this.callback_detailed_hide(); } } Graph._loops = []; graph.Graph = Graph; })(graph = net.graph || (net.graph = {})); })(net || (net = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c82d4662614adf5608bef1fd70a57019738a40114a7c07126b0c1de2799c39de"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c82d4662614adf5608bef1fd70a57019738a40114a7c07126b0c1de2799c39de"] = "c82d4662614adf5608bef1fd70a57019738a40114a7c07126b0c1de2799c39de"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } function sliderfy(slider, options) { options = Object.assign({ initial_value: 0, min_value: 0, max_value: 100, step: 1, unit: '%', value_field: [] }, options); if (!Array.isArray(options.value_field)) options.value_field = [options.value_field]; if (options.min_value >= options.max_value) throw "invalid range"; if (options.step > (options.max_value - options.min_value)) throw "invalid step size"; const tool = tooltip(slider); /* add the tooltip functionality */ const filler = slider.find(".filler"); const thumb = slider.find(".thumb"); const tooltip_text = slider.find(".tooltip a"); let _current_value; const update_value = (value, trigger_change) => { _current_value = value; const offset = Math.min(100, Math.max(0, ((value - options.min_value) * 100) / (options.max_value - options.min_value))); filler.css('width', offset + '%'); thumb.css('left', offset + '%'); tooltip_text.text(value.toFixed(0) + options.unit); slider.attr("value", value); if (trigger_change) slider.trigger('change'); for (const field of options.value_field) field.text(value + options.unit); tool.update(); }; const mouse_up_listener = () => { document.removeEventListener('mousemove', mouse_listener); document.removeEventListener('touchmove', mouse_listener); document.removeEventListener('mouseup', mouse_up_listener); document.removeEventListener('touchend', mouse_up_listener); document.removeEventListener('touchcancel', mouse_up_listener); tool.hide(); slider.removeClass("active"); console.log("Events removed"); }; const mouse_listener = (event) => { const parent_offset = slider.offset(); const min = parent_offset.left; const max = parent_offset.left + slider.width(); const current = event instanceof MouseEvent ? event.pageX : event.touches[event.touches.length - 1].clientX; const range = options.max_value - options.min_value; const offset = Math.round(((current - min) * (range / options.step)) / (max - min)) * options.step; let value = Math.min(options.max_value, Math.max(options.min_value, options.min_value + offset)); //console.log("Min: %o | Max: %o | %o (%o)", min, max, current, offset); update_value(value, true); }; slider.on('mousedown', event => { document.addEventListener('mousemove', mouse_listener); document.addEventListener('touchmove', mouse_listener); document.addEventListener('mouseup', mouse_up_listener); document.addEventListener('touchend', mouse_up_listener); document.addEventListener('touchcancel', mouse_up_listener); tool.show(); slider.addClass("active"); }); update_value(options.initial_value, false); return { value(value) { if (typeof (value) !== "undefined" && value !== _current_value) update_value(value, true); return _current_value; } }; } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["2ab9d94c857ad8d8d402323b7cdb56fdfb7a29b68fa5484661c38be7b4f6a528"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["2ab9d94c857ad8d8d402323b7cdb56fdfb7a29b68fa5484661c38be7b4f6a528"] = "2ab9d94c857ad8d8d402323b7cdb56fdfb7a29b68fa5484661c38be7b4f6a528"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "z4Yri5dV", path: "D:/TeaSpeak/web/shared/js/ui/elements/tab.ts (26,18)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// if (typeof (customElements) !== "undefined") { try { 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' }); } catch (error) { console.warn("failed to define costum elements"); } } else { console.warn(_translations.z4Yri5dV || (_translations.z4Yri5dV = tr("Could not defied tab customElements!"))); } var TabFunctions = { tabify(template, copy = true) { console.log("Tabify: copy=" + copy); 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"); content.append($.spawn("div").addClass("height-watcher")); let silentContent = $.spawn("div"); silentContent.addClass("tab-content-invisible"); /* add some kind of min height */ const update_height = () => { const height_watcher = tag.find("> .tab-content .height-watcher"); const entries = tag.find("> .tab-content-invisible x-content, > .tab-content x-content"); console.error(entries); let max_height = 0; entries.each((_, _e) => { const entry = $(_e); const height = entry.visible_height(); if (height > max_height) max_height = height; }); height_watcher.css('min-height', max_height + "px"); tag.find(".window-resize-listener").trigger('resize'); }; template.find("x-entry").each((_, _entry) => { const entry = $(_entry); const tag_header = $.spawn("div").addClass("entry"); const tag_content = copy ? entry.find("x-content").clone(true, true) : entry.find("x-content"); { const header_tag = entry.find("x-tag"); const header_data = copy ? header_tag.contents().clone(true, true) : header_tag.contents(); if (header_tag.attr("x-entry-class")) tag_header.addClass(header_tag.attr("x-entry-class")); if (header_tag.attr("x-entry-id")) tag_header.attr("x-id", header_tag.attr("x-entry-id")); tag_header.append(header_data); /* listener if the tab might got removed */ tag_header.addClass("window-resize-listener"); tag_header.on('resize', event => { if (!tag_header.is(':visible') && tag_header.hasClass('selected')) { let element = tag_header.next('.entry:visible'); if (element.length == 0) element = tag_header.prev('.entry:visible'); if (element.length == 0) { tag_header.removeClass("selected"); tag_content.hide(); } else { element.first().trigger('click'); } console.log("Next: %o", tag_header.next('.entry:visible')); console.log("prev: %o", tag_header.prev('.entry:visible')); } }); } content.append(tag_content.hide()); tag_header.on("click", () => { if (tag_header.hasClass("selected")) return; tag.find(".tab-header .selected").removeClass("selected"); tag_header.addClass("selected"); content.find("> x-content").hide(); /* don't show many nodes at once */ let entries = tag_content.find(".tab-show-partitional"); entries.hide(); const show_next = index => { console.log("Show " + index); if (index >= entries.length) return; entries.eq(index).show(); setTimeout(show_next.bind(undefined, index + 1), 0); }; show_next(0); tag_content.trigger('show'); tag_content.show(); }); console.log(this); header.append(tag_header); }); setTimeout(() => header.find(".entry").first().trigger("click"), 0); tag.append(header); tag.append(content); tag.append(silentContent); tag.on('tab.resize', update_height); return tag; } }; if (!$.fn.asTabWidget) { $.fn.asTabWidget = function (copy) { if ($(this).prop("tagName") == "X-TAB") return TabFunctions.tabify($(this), typeof (copy) === "boolean" ? copy : true); else { throw "Invalid tag! " + $(this).prop("tagName"); } }; } if (!$.fn.tabify) { $.fn.tabify = function (copy) { const wrapped_tag = $.spawn("div").append(this); wrapped_tag.find("x-tab").each((_, _element) => { const element = $(_element); element.replaceWith(element.asTabWidget(copy)); }); return wrapped_tag.children(); }; } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["faa2a3135a562096ca469b0457951b9bde59e4203f728ea2934fbf639827e1cd"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["faa2a3135a562096ca469b0457951b9bde59e4203f728ea2934fbf639827e1cd"] = "faa2a3135a562096ca469b0457951b9bde59e4203f728ea2934fbf639827e1cd"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } function tooltip(entry) { return tooltip.initialize(entry); } (function (tooltip) { let _global_tooltip; function initialize(entry, callbacks) { if (!callbacks) callbacks = {}; let _show; let _hide; let _shown; let _update; entry.find(".container-tooltip").each((index, _node) => { const node = $(_node); const node_content = node.find(".tooltip"); let _force_show = false, _flag_shown = false; const mouseenter = (event) => { const bounds = node[0].getBoundingClientRect(); if (!_global_tooltip) { _global_tooltip = $("#global-tooltip"); } _global_tooltip[0].style.left = (bounds.left + bounds.width / 2) + "px"; _global_tooltip[0].style.top = bounds.top + "px"; _global_tooltip[0].classList.add("shown"); _global_tooltip[0].innerHTML = node_content[0].innerHTML; callbacks.on_show && callbacks.on_show(_global_tooltip); _flag_shown = _flag_shown || !!event; /* if event is undefined then it has been triggered by hand */ }; const mouseexit = () => { if (_global_tooltip) { if (!_force_show) { callbacks.on_hide && callbacks.on_hide(_global_tooltip); _global_tooltip[0].classList.remove("shown"); } _flag_shown = false; } }; _node.addEventListener("mouseenter", mouseenter); _node.addEventListener("mouseleave", mouseexit); _show = () => { _force_show = true; mouseenter(); }; _hide = () => { _force_show = false; if (!_flag_shown) mouseexit(); }; _update = () => { if (_flag_shown || _force_show) mouseenter(); }; _shown = () => _flag_shown || _force_show; }); return { hide: _hide || (() => { }), show: _show || (() => { }), is_shown: _shown || (() => false), update: _update || (() => { }) }; } tooltip.initialize = initialize; })(tooltip || (tooltip = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c4e96182350831bf38d121b82c1e03618a32cef6c1c05d93fe5ce55633bb3e0e"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c4e96182350831bf38d121b82c1e03618a32cef6c1c05d93fe5ce55633bb3e0e"] = "c4e96182350831bf38d121b82c1e03618a32cef6c1c05d93fe5ce55633bb3e0e"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "YHk3QMgK", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (233,44)" }, { name: "IQurT9kP", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (238,71)" }, { name: "WLGU6bnP", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (242,76)" }, { name: "IRFS6dUE", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (311,45)" }, { name: "trzsdqss", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (312,37)" }, { name: "WzWvOBTm", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (327,37)" }, { name: "tgGIp6eC", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (336,37)" }, { name: "XMwtJTlt", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (349,41)" }, { name: "YDk3ehXm", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (359,45)" }, { name: "ZLJ7E5ad", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (364,45)" }, { name: "Dcy8u586", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (366,37)" }, { name: "SGY3uiR3", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (373,37)" }, { name: "dWnfDpjs", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (380,37)" }, { name: "Qn5Y_BQT", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (387,37)" }, { name: "JR56gU5A", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (394,37)" }, { name: "S9GOLSrc", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (402,37)" }, { name: "ZrrAICSr", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (405,34)" }, { name: "tMyCKezh", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (405,57)" }, { name: "kjIOXUWT", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (409,37)" }, { name: "wga4YG6i", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (413,34)" }, { name: "r620ua7H", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (413,51)" }, { name: "IKaKTFJ0", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (421,45)" }, { name: "bhDNOIR7", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (421,62)" }, { name: "v5LsXjCv", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (424,46)" }, { name: "mtxGQQO1", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (424,91)" }, { name: "iwtQgyN6", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (432,45)" }, { name: "GZEpQEf5", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (448,37)" }, { name: "CsIwCkwd", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (456,42)" }, { name: "DyqpEtZd", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (456,78)" }, { name: "RgaMSFmp", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (460,38)" }, { name: "LWN4R9Z1", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (460,70)" }, { name: "A8Et845b", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (465,37)" }, { name: "VQsO5xjg", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (473,42)" }, { name: "EeaoSfA3", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (473,78)" }, { name: "BamyNO0n", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (477,38)" }, { name: "hT3TIxtD", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (477,70)" }, { name: "dmjFiiJh", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (482,37)" }, { name: "zQ2y7y4l", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (490,42)" }, { name: "Jbgud9rC", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (490,78)" }, { name: "p5GLEnDz", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (494,38)" }, { name: "b17gFELJ", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (494,70)" }, { name: "mkHwLaEd", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (500,37)" }, { name: "S0zdQo8Q", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (506,45)" }, { name: "TL7JhBKN", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (509,41)" }, { name: "XRlZ6m6L", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (512,41)" }, { name: "NdyN4NkV", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (516,37)" }, { name: "Zw4iJWN_", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (519,37)" }, { name: "W4o454QI", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (524,41)" }, { name: "JJbVuuAX", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (527,41)" }, { name: "rjgt_m0J", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (532,52)" }, { name: "TZWg3Vt_", path: "D:/TeaSpeak/web/shared/js/ui/frames/MenuBar.ts (532,73)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var top_menu; (function (top_menu) { let _driver; function driver() { return _driver; } top_menu.driver = driver; function set_driver(driver) { _driver = driver; } top_menu.set_driver = set_driver; let html; (function (html) { class HTMLHrItem { constructor() { this.html_tag = $.spawn("hr"); } } class HTMLMenuItem { constructor(label, mode) { this._items = []; this._label = label; this.html_tag = $.spawn("div").addClass("container-menu-item type-" + mode); this._label_tag = $.spawn("div").addClass("menu-item"); this._label_icon_tag = $.spawn("div").addClass("container-icon").appendTo(this._label_tag); $.spawn("div").addClass("container-label").append(this._label_text_tag = $.spawn("a").text(label)).appendTo(this._label_tag); this._label_tag.on('click', event => { if (event.isDefaultPrevented()) return; const disabled = this.html_tag.hasClass("disabled"); if (this._callback_click && !disabled) { this._callback_click(); } event.preventDefault(); if (disabled) event.stopPropagation(); else HTMLMenuBarDriver.instance().close(); }); this._submenu_tag = $.spawn("div").addClass("sub-menu"); this.html_tag.append(this._label_tag); this.html_tag.append(this._submenu_tag); } append_item(label) { const item = new HTMLMenuItem(label, "side"); this._items.push(item); this._submenu_tag.append(item.html_tag); this.html_tag.addClass('sub-entries'); return item; } append_hr() { const item = new HTMLHrItem(); this._items.push(item); this._submenu_tag.append(item.html_tag); return item; } delete_item(item) { this._items.remove(item); item.html_tag.detach(); this.html_tag.toggleClass('sub-entries', this._items.length > 0); } disabled(value) { if (typeof (value) === "undefined") return this.html_tag.hasClass("disabled"); this.html_tag.toggleClass("disabled", value); return value; } items() { return this._items; } label(value) { if (typeof (value) === "undefined" || this._label === value) return this._label; return this._label; } visible(value) { if (typeof (value) === "undefined") return this.html_tag.is(':visible'); //FIXME! this.html_tag.toggle(!!value); return value; } click(callback) { this._callback_click = callback; return this; } icon(klass) { this._label_icon_tag.children().remove(); if (typeof (klass) === "string") $.spawn("div").addClass("icon_em " + klass).appendTo(this._label_icon_tag); else IconManager.generate_tag(klass).appendTo(this._label_icon_tag); return ""; } } class HTMLMenuBarDriver { constructor() { this._items = []; this.html_tag = $.spawn("div").addClass("top-menu-bar"); } static instance() { if (!this._instance) this._instance = new HTMLMenuBarDriver(); return this._instance; } append_item(label) { const item = new HTMLMenuItem(label, "down"); this._items.push(item); this.html_tag.append(item.html_tag); item._label_tag.on('click', enable_event => { enable_event.preventDefault(); this.close(); item.html_tag.addClass("active"); setTimeout(() => { $(document).one('click focusout', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); item.html_tag.removeClass("active"); }); }, 0); }); return item; } close() { this.html_tag.find(".active").removeClass("active"); } delete_item(item) { return undefined; } items() { return this._items; } flush_changes() { } initialize() { $("#top-menu-bar").replaceWith(this.html_tag); } } html.HTMLMenuBarDriver = HTMLMenuBarDriver; })(html || (html = {})); let _items_bookmark; function rebuild_bookmarks() { if (!_items_bookmark) { _items_bookmark = { root: driver().append_item(_translations.YHk3QMgK || (_translations.YHk3QMgK = tr("Favorites"))), add_current: undefined, manage: undefined }; _items_bookmark.manage = _items_bookmark.root.append_item(_translations.IQurT9kP || (_translations.IQurT9kP = tr("Manage bookmarks"))); _items_bookmark.manage.icon("client-bookmark_manager"); _items_bookmark.manage.click(() => Modals.spawnBookmarkModal()); _items_bookmark.add_current = _items_bookmark.root.append_item(_translations.WLGU6bnP || (_translations.WLGU6bnP = tr("Add current server to bookmarks"))); _items_bookmark.add_current.icon('client-bookmark_add'); _items_bookmark.add_current.click(() => bookmarks.add_current_server()); _state_updater["bookmarks.ac"] = { item: _items_bookmark.add_current, conditions: [condition_connected] }; } _items_bookmark.root.items().filter(e => e !== _items_bookmark.add_current && e !== _items_bookmark.manage).forEach(e => { _items_bookmark.root.delete_item(e); }); _items_bookmark.root.append_hr(); const build_bookmark = (root, entry) => { if (entry.type == bookmarks.BookmarkType.DIRECTORY) { const directory = entry; const item = root.append_item(directory.display_name); item.icon('client-folder'); for (const entry of directory.content) build_bookmark(item, entry); if (directory.content.length == 0) item.disabled(true); } else { const bookmark = entry; const item = root.append_item(bookmark.display_name); item.icon(IconManager.load_cached_icon(bookmark.last_icon_id || 0)); item.click(() => bookmarks.boorkmak_connect(bookmark)); } }; for (const entry of bookmarks.bookmarks().content) build_bookmark(_items_bookmark.root, entry); driver().flush_changes(); } top_menu.rebuild_bookmarks = rebuild_bookmarks; /* will be called on connection handler change or on client connect state or mic state change etc... */ let _state_updater = {}; function update_state() { for (const _key of Object.keys(_state_updater)) { const item = _state_updater[_key]; if (item.update_handler) { if (item.update_handler(item.item)) continue; } let enabled = true; for (const condition of item.conditions) if (!condition()) { enabled = false; break; } item.item.disabled(!enabled); } driver().flush_changes(); } top_menu.update_state = update_state; const condition_connected = () => { const scon = server_connections ? server_connections.active_connection_handler() : undefined; return scon && scon.connected; }; function initialize() { const driver = top_menu.driver(); driver.initialize(); /* build connection */ let item; { const menu = driver.append_item(_translations.IRFS6dUE || (_translations.IRFS6dUE = tr("Connection"))); item = menu.append_item(_translations.trzsdqss || (_translations.trzsdqss = tr("Connect to a server"))); item.icon('client-connect'); item.click(() => Modals.spawnConnectModal({})); const do_disconnect = (handlers) => { for (const handler of handlers) { handler.cancel_reconnect(true); handler.handleDisconnect(DisconnectReason.REQUESTED); //TODO message? server_connections.active_connection_handler().serverConnection.disconnect(); handler.sound.play(Sound.CONNECTION_DISCONNECTED); handler.log.log(log.server.Type.DISCONNECTED, {}); } control_bar.update_connection_state(); update_state(); }; item = menu.append_item(_translations.WzWvOBTm || (_translations.WzWvOBTm = tr("Disconnect from current server"))); item.icon('client-disconnect'); item.disabled(true); item.click(() => { const handler = server_connections.active_connection_handler(); do_disconnect([handler]); }); _state_updater["connection.dc"] = { item: item, conditions: [() => condition_connected()] }; item = menu.append_item(_translations.tgGIp6eC || (_translations.tgGIp6eC = tr("Disconnect from all servers"))); item.icon('client-disconnect'); item.click(() => { do_disconnect(server_connections.server_connection_handlers()); }); _state_updater["connection.dca"] = { item: item, conditions: [], update_handler: (item) => { item.visible(server_connections && server_connections.server_connection_handlers().length > 1); return true; } }; if (!app.is_web()) { menu.append_hr(); item = menu.append_item(_translations.XMwtJTlt || (_translations.XMwtJTlt = tr("Quit"))); item.icon('client-close_button'); item.click(() => top_menu.native_actions.quit()); } } { rebuild_bookmarks(); } if (false) { const menu = driver.append_item(_translations.YDk3ehXm || (_translations.YDk3ehXm = tr("Self"))); /* Microphone | Sound | Away */ } { const menu = driver.append_item(_translations.ZLJ7E5ad || (_translations.ZLJ7E5ad = tr("Permissions"))); item = menu.append_item(_translations.Dcy8u586 || (_translations.Dcy8u586 = tr("Server Groups"))); item.icon("client-permission_server_groups"); item.click(() => { Modals.spawnPermissionEdit(server_connections.active_connection_handler(), "sg").open(); }); _state_updater["permission.sg"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.SGY3uiR3 || (_translations.SGY3uiR3 = tr("Client Permissions"))); item.icon("client-permission_client"); item.click(() => { Modals.spawnPermissionEdit(server_connections.active_connection_handler(), "clp").open(); }); _state_updater["permission.clp"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.dWnfDpjs || (_translations.dWnfDpjs = tr("Channel Client Permissions"))); item.icon("client-permission_client"); item.click(() => { Modals.spawnPermissionEdit(server_connections.active_connection_handler(), "clchp").open(); }); _state_updater["permission.chclp"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.Qn5Y_BQT || (_translations.Qn5Y_BQT = tr("Channel Groups"))); item.icon("client-permission_channel"); item.click(() => { Modals.spawnPermissionEdit(server_connections.active_connection_handler(), "cg").open(); }); _state_updater["permission.cg"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.JR56gU5A || (_translations.JR56gU5A = tr("Channel Permissions"))); item.icon("client-permission_channel"); item.click(() => { Modals.spawnPermissionEdit(server_connections.active_connection_handler(), "chp").open(); }); _state_updater["permission.cp"] = { item: item, conditions: [condition_connected] }; menu.append_hr(); item = menu.append_item(_translations.S9GOLSrc || (_translations.S9GOLSrc = tr("List Privilege Keys"))); item.icon("client-token"); item.click(() => { createErrorModal(_translations.ZrrAICSr || (_translations.ZrrAICSr = tr("Not implemented")), _translations.tMyCKezh || (_translations.tMyCKezh = tr("Privilege key list is not implemented yet!"))).open(); }); _state_updater["permission.pk"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.kjIOXUWT || (_translations.kjIOXUWT = tr("Use Privilege Key"))); item.icon("client-token_use"); item.click(() => { //TODO: Fixeme use one method for the control bar and here! createInputModal(_translations.wga4YG6i || (_translations.wga4YG6i = tr("Use token")), _translations.r620ua7H || (_translations.r620ua7H = tr("Please enter your token/privilege key")), message => message.length > 0, result => { if (!result) return; const scon = server_connections.active_connection_handler(); if (scon.serverConnection.connected) scon.serverConnection.send_command("tokenuse", { token: result }).then(() => { createInfoModal(_translations.IKaKTFJ0 || (_translations.IKaKTFJ0 = tr("Use token")), _translations.bhDNOIR7 || (_translations.bhDNOIR7 = tr("Toke successfully used!"))).open(); }).catch(error => { //TODO tr createErrorModal(_translations.v5LsXjCv || (_translations.v5LsXjCv = tr("Use token")), MessageHelper.formatMessage(_translations.mtxGQQO1 || (_translations.mtxGQQO1 = tr("Failed to use token: {}")), error instanceof CommandResult ? error.message : error)).open(); }); }).open(); }); _state_updater["permission.upk"] = { item: item, conditions: [condition_connected] }; } { const menu = driver.append_item(_translations.iwtQgyN6 || (_translations.iwtQgyN6 = tr("Tools"))); /* item = menu.append_item(tr("Manage Playlists")); item.icon('client-music'); item.click(() => { const scon = server_connections.active_connection_handler(); if(scon && scon.connected) { Modals.spawnPlaylistManage(scon); } else { createErrorModal(tr("You have to be connected"), tr("You have to be connected to use this function!")).open(); } }); _state_updater["tools.pl"] = { item: item, conditions: [condition_connected]}; */ item = menu.append_item(_translations.GZEpQEf5 || (_translations.GZEpQEf5 = tr("Ban List"))); item.icon('client-ban_list'); item.click(() => { const scon = server_connections.active_connection_handler(); if (scon && scon.connected) { if (scon.permissions.neededPermission(PermissionType.B_CLIENT_BAN_LIST).granted(1)) { Modals.openBanList(scon); } else { createErrorModal(_translations.CsIwCkwd || (_translations.CsIwCkwd = tr("You dont have the permission")), _translations.DyqpEtZd || (_translations.DyqpEtZd = tr("You dont have the permission to view the ban list"))).open(); scon.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } } else { createErrorModal(_translations.RgaMSFmp || (_translations.RgaMSFmp = tr("You have to be connected")), _translations.LWN4R9Z1 || (_translations.LWN4R9Z1 = tr("You have to be connected to use this function!"))).open(); } }); _state_updater["tools.bl"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.A8Et845b || (_translations.A8Et845b = tr("Query List"))); item.icon('client-server_query'); item.click(() => { const scon = server_connections.active_connection_handler(); if (scon && scon.connected) { if (scon.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_LIST).granted(1) || scon.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_LIST_OWN).granted(1)) { Modals.spawnQueryManage(scon); } else { createErrorModal(_translations.VQsO5xjg || (_translations.VQsO5xjg = tr("You dont have the permission")), _translations.EeaoSfA3 || (_translations.EeaoSfA3 = tr("You dont have the permission to view the server query list"))).open(); scon.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } } else { createErrorModal(_translations.BamyNO0n || (_translations.BamyNO0n = tr("You have to be connected")), _translations.hT3TIxtD || (_translations.hT3TIxtD = tr("You have to be connected to use this function!"))).open(); } }); _state_updater["tools.ql"] = { item: item, conditions: [condition_connected] }; item = menu.append_item(_translations.dmjFiiJh || (_translations.dmjFiiJh = tr("Query Create"))); item.icon('client-server_query'); item.click(() => { const scon = server_connections.active_connection_handler(); if (scon && scon.connected) { if (scon.permissions.neededPermission(PermissionType.B_CLIENT_CREATE_MODIFY_SERVERQUERY_LOGIN).granted(1) || scon.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_CREATE).granted(1)) { Modals.spawnQueryCreate(scon); } else { createErrorModal(_translations.zQ2y7y4l || (_translations.zQ2y7y4l = tr("You dont have the permission")), _translations.Jbgud9rC || (_translations.Jbgud9rC = tr("You dont have the permission to create a server query login"))).open(); scon.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS); } } else { createErrorModal(_translations.p5GLEnDz || (_translations.p5GLEnDz = tr("You have to be connected")), _translations.b17gFELJ || (_translations.b17gFELJ = tr("You have to be connected to use this function!"))).open(); } }); _state_updater["tools.qc"] = { item: item, conditions: [condition_connected] }; menu.append_hr(); item = menu.append_item(_translations.mkHwLaEd || (_translations.mkHwLaEd = tr("Settings"))); item.icon("client-settings"); item.click(() => Modals.spawnSettingsModal()); } { const menu = driver.append_item(_translations.S0zdQo8Q || (_translations.S0zdQo8Q = tr("Help"))); if (!app.is_web()) { item = menu.append_item(_translations.TL7JhBKN || (_translations.TL7JhBKN = tr("Check for updates"))); item.click(() => top_menu.native_actions.check_native_update()); item = menu.append_item(_translations.XRlZ6m6L || (_translations.XRlZ6m6L = tr("Open changelog"))); item.click(() => top_menu.native_actions.open_change_log()); } item = menu.append_item(_translations.NdyN4NkV || (_translations.NdyN4NkV = tr("Visit TeaSpeak.de"))); item.click(() => window.open('https://teaspeak.de/', '_blank')); item = menu.append_item(_translations.Zw4iJWN_ || (_translations.Zw4iJWN_ = tr("Visit TeaSpeak forum"))); item.click(() => window.open('https://forum.teaspeak.de/', '_blank')); if (!app.is_web() && typeof (top_menu.native_actions.show_dev_tools) === "function" && top_menu.native_actions.show_dev_tools()) { menu.append_hr(); item = menu.append_item(_translations.W4o454QI || (_translations.W4o454QI = tr("Open developer tools"))); item.click(() => top_menu.native_actions.open_dev_tools()); item = menu.append_item(_translations.JJbVuuAX || (_translations.JJbVuuAX = tr("Reload UI"))); item.click(() => top_menu.native_actions.reload_page()); } menu.append_hr(); item = menu.append_item(app.is_web() ? _translations.rjgt_m0J || (_translations.rjgt_m0J = tr("About TeaWeb")) : _translations.TZWg3Vt_ || (_translations.TZWg3Vt_ = tr("About TeaClient"))); item.click(() => Modals.spawnAbout()); } update_state(); } top_menu.initialize = initialize; /* default is HTML, the client will override this */ set_driver(html.HTMLMenuBarDriver.instance()); })(top_menu || (top_menu = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["cf77d6d8a35237928a5ec1202e1c1ffbf44694d05a62e3e6fd0979af4dadf05b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["cf77d6d8a35237928a5ec1202e1c1ffbf44694d05a62e3e6fd0979af4dadf05b"] = "cf77d6d8a35237928a5ec1202e1c1ffbf44694d05a62e3e6fd0979af4dadf05b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "cSuOVkHn", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (148,33)" }, { name: "yNvFymJQ", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (160,61)" }, { name: "pqXaIVXD", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (166,37)" }, { name: "c1C0TPhH", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (184,33)" }, { name: "_9h4MR1v", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (198,91)" }, { name: "GdZEXcYF", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (202,72)" }, { name: "JEyIfN9E", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (218,36)" }, { name: "IETaAnAP", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (220,36)" }, { name: "sAdL5qG_", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (222,65)" }, { name: "DssXnAbR", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (248,59)" }, { name: "WBXUzAj5", path: "D:/TeaSpeak/web/shared/js/ui/frames/chat_frame.ts (250,59)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /* the bar on the right with the chats (Channel & Client) */ var chat; (function (chat) { let InfoFrameMode; (function (InfoFrameMode) { InfoFrameMode["NONE"] = "none"; InfoFrameMode["CHANNEL_CHAT"] = "channel_chat"; InfoFrameMode["PRIVATE_CHAT"] = "private_chat"; InfoFrameMode["CLIENT_INFO"] = "client_info"; InfoFrameMode["MUSIC_BOT"] = "music_bot"; })(InfoFrameMode = chat.InfoFrameMode || (chat.InfoFrameMode = {})); class InfoFrame { constructor(handle) { this.handle = handle; this._build_html_tag(); this.update_channel_talk(); this.update_channel_text(); this.set_mode(InfoFrameMode.CHANNEL_CHAT); this._ping_updater = setInterval(() => this.update_ping(), 2000); this.update_ping(); } html_tag() { return this._html_tag; } destroy() { clearInterval(this._ping_updater); this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._value_ping = undefined; } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_info").renderTag(); this._html_tag.find(".button-switch-chat-channel").on('click', () => this.handle.show_channel_conversations()); this._value_ping = this._html_tag.find(".value-ping"); this._html_tag.find(".chat-counter").on('click', event => this.handle.show_private_conversations()); this._button_conversation = this._html_tag.find(".button.open-conversation").on('click', event => { const selected_client = this.handle.client_info().current_client(); if (!selected_client) return; const conversation = selected_client ? this.handle.private_conversations().find_conversation({ name: selected_client.properties.client_nickname, unique_id: selected_client.properties.client_unique_identifier, client_id: selected_client.clientId() }, { create: true, attach: true }) : undefined; if (!conversation) return; this.handle.private_conversations().set_selected_conversation(conversation); this.handle.show_private_conversations(); })[0]; this._button_bot_manage = this._html_tag.find(".bot-manage").on('click', event => { const bot = this.handle.music_info().current_bot(); if (!bot) return; Modals.openMusicManage(this.handle.handle, bot); }); this._button_song_add = this._html_tag.find(".bot-add-song").on('click', event => { this.handle.music_info().events.fire("action_song_add"); }); } update_ping() { this._value_ping.removeClass("very-good good medium poor very-poor"); const connection = this.handle.handle.serverConnection; if (!this.handle.handle.connected || !connection) { this._value_ping.text("Not connected"); return; } const ping = connection.ping(); if (!ping || typeof (ping.native) !== "number") { this._value_ping.text("Not available"); return; } let value; if (typeof (ping.javascript) !== "undefined") { value = ping.javascript; this._value_ping.text(ping.javascript.toFixed(0) + "ms").attr('title', 'Native: ' + ping.native.toFixed(3) + "ms \nJavascript: " + ping.javascript.toFixed(3) + "ms"); } else { value = ping.native; this._value_ping.text(ping.native.toFixed(0) + "ms").attr('title', "Ping: " + ping.native.toFixed(3) + "ms"); } if (value <= 10) this._value_ping.addClass("very-good"); else if (value <= 30) this._value_ping.addClass("good"); else if (value <= 60) this._value_ping.addClass("medium"); else if (value <= 150) this._value_ping.addClass("poor"); else this._value_ping.addClass("very-poor"); } update_channel_talk() { const client = this.handle.handle.getClient(); const channel = client ? client.currentChannel() : undefined; this._channel_voice = channel; const html_tag = this._html_tag.find(".value-voice-channel"); const html_limit_tag = this._html_tag.find(".value-voice-limit"); html_limit_tag.text(""); html_tag.children().remove(); if (channel) { if (channel.properties.channel_icon_id != 0) client.handle.fileManager.icons.generateTag(channel.properties.channel_icon_id).appendTo(html_tag); $.spawn("div").text(channel.formattedChannelName()).appendTo(html_tag); this.update_channel_limit(channel, html_limit_tag); } else { $.spawn("div").text("Not connected").appendTo(html_tag); } } update_channel_text() { const channel_tree = this.handle.handle.connected ? this.handle.handle.channelTree : undefined; const current_channel_id = channel_tree ? this.handle.channel_conversations().current_channel() : 0; const channel = channel_tree ? channel_tree.findChannel(current_channel_id) : undefined; this._channel_text = channel; const tag_container = this._html_tag.find(".mode-channel_chat.channel"); const html_tag_title = tag_container.find(".title"); const html_tag = tag_container.find(".value-text-channel"); const html_limit_tag = tag_container.find(".value-text-limit"); /* reset */ html_tag_title.text(_translations.cSuOVkHn || (_translations.cSuOVkHn = tr("You're chatting in Channel"))); html_limit_tag.text(""); html_tag.children().detach(); /* initialize */ if (channel) { if (channel.properties.channel_icon_id != 0) this.handle.handle.fileManager.icons.generateTag(channel.properties.channel_icon_id).appendTo(html_tag); $.spawn("div").text(channel.formattedChannelName()).appendTo(html_tag); this.update_channel_limit(channel, html_limit_tag); } else if (channel_tree && current_channel_id > 0) { html_tag.append(MessageHelper.formatMessage(_translations.yNvFymJQ || (_translations.yNvFymJQ = tr("Unknown channel id {}")), current_channel_id)); } else if (channel_tree && current_channel_id == 0) { const server = this.handle.handle.channelTree.server; if (server.properties.virtualserver_icon_id != 0) this.handle.handle.fileManager.icons.generateTag(server.properties.virtualserver_icon_id).appendTo(html_tag); $.spawn("div").text(server.properties.virtualserver_name).appendTo(html_tag); html_tag_title.text(_translations.pqXaIVXD || (_translations.pqXaIVXD = tr("You're chatting in Server"))); this.update_server_limit(server, html_limit_tag); } else if (this.handle.handle.connected) { $.spawn("div").text("No channel selected").appendTo(html_tag); } else { $.spawn("div").text("Not connected").appendTo(html_tag); } } update_channel_client_count(channel) { if (channel === this._channel_text) this.update_channel_limit(channel, this._html_tag.find(".value-text-limit")); if (channel === this._channel_voice) this.update_channel_limit(channel, this._html_tag.find(".value-voice-limit")); } update_channel_limit(channel, tag) { let channel_limit = _translations.c1C0TPhH || (_translations.c1C0TPhH = tr("Unlimited")); if (!channel.properties.channel_flag_maxclients_unlimited) channel_limit = "" + channel.properties.channel_maxclients; else if (!channel.properties.channel_flag_maxfamilyclients_unlimited) { if (channel.properties.channel_maxfamilyclients >= 0) channel_limit = "" + channel.properties.channel_maxfamilyclients; } tag.text(channel.clients(false).length + " / " + channel_limit); } update_server_limit(server, tag) { const fn = () => { let text = server.properties.virtualserver_clientsonline + " / " + server.properties.virtualserver_maxclients; if (server.properties.virtualserver_reserved_slots) text += " (" + server.properties.virtualserver_reserved_slots + " " + (_translations._9h4MR1v || (_translations._9h4MR1v = tr("Reserved"))) + ")"; tag.text(text); }; server.updateProperties().then(fn).catch(error => tag.text(_translations.GdZEXcYF || (_translations.GdZEXcYF = tr("Failed to update info")))); fn(); } update_chat_counter() { const conversations = this.handle.private_conversations().conversations(); { const count = conversations.filter(e => e.is_unread()).length; const count_container = this._html_tag.find(".container-indicator"); const count_tag = count_container.find(".chat-unread-counter"); count_container.toggle(count > 0); count_tag.text(count); } { const count_tag = this._html_tag.find(".chat-counter"); if (conversations.length == 0) count_tag.text(_translations.JEyIfN9E || (_translations.JEyIfN9E = tr("No conversations"))); else if (conversations.length == 1) count_tag.text(_translations.IETaAnAP || (_translations.IETaAnAP = tr("One conversation"))); else count_tag.text(conversations.length + " " + (_translations.sAdL5qG_ || (_translations.sAdL5qG_ = tr("conversations")))); } } current_mode() { return this._mode; } set_mode(mode) { for (const mode in InfoFrameMode) this._html_tag.removeClass("mode-" + InfoFrameMode[mode]); this._html_tag.addClass("mode-" + mode); if (mode === InfoFrameMode.CLIENT_INFO && this._button_conversation) { //Will be called every time a client is shown const selected_client = this.handle.client_info().current_client(); const conversation = selected_client ? this.handle.private_conversations().find_conversation({ name: selected_client.properties.client_nickname, unique_id: selected_client.properties.client_unique_identifier, client_id: selected_client.clientId() }, { create: false, attach: false }) : undefined; const visibility = (selected_client && selected_client.clientId() !== this.handle.handle.clientId) ? "visible" : "hidden"; if (this._button_conversation.style.visibility !== visibility) this._button_conversation.style.visibility = visibility; if (conversation) { this._button_conversation.innerText = _translations.DssXnAbR || (_translations.DssXnAbR = tr("Open conversation")); } else { this._button_conversation.innerText = _translations.WBXUzAj5 || (_translations.WBXUzAj5 = tr("Start a conversation")); } } else if (mode === InfoFrameMode.MUSIC_BOT) { //TODO? } } } chat.InfoFrame = InfoFrame; let FrameContent; (function (FrameContent) { FrameContent[FrameContent["NONE"] = 0] = "NONE"; FrameContent[FrameContent["PRIVATE_CHAT"] = 1] = "PRIVATE_CHAT"; FrameContent[FrameContent["CHANNEL_CHAT"] = 2] = "CHANNEL_CHAT"; FrameContent[FrameContent["CLIENT_INFO"] = 3] = "CLIENT_INFO"; FrameContent[FrameContent["MUSIC_BOT"] = 4] = "MUSIC_BOT"; })(FrameContent = chat.FrameContent || (chat.FrameContent = {})); class Frame { constructor(handle) { this.handle = handle; this._content_type = FrameContent.NONE; this._info_frame = new InfoFrame(this); this._conversations = new chat.PrivateConverations(this); this._channel_conversations = new chat.channel.ConversationManager(this); this._client_info = new chat.ClientInfo(this); this._music_info = new chat.MusicInfo(this); this._build_html_tag(); this.show_channel_conversations(); this.info_frame().update_chat_counter(); } html_tag() { return this._html_tag; } info_frame() { return this._info_frame; } content_type() { return this._content_type; } destroy() { this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._info_frame && this._info_frame.destroy(); this._info_frame = undefined; this._conversations && this._conversations.destroy(); this._conversations = undefined; this._client_info && this._client_info.destroy(); this._client_info = undefined; this._music_info && this._music_info.destroy(); this._music_info = undefined; this._channel_conversations && this._channel_conversations.destroy(); this._channel_conversations = undefined; this._container_info && this._container_info.remove(); this._container_info = undefined; this._container_chat && this._container_chat.remove(); this._container_chat = undefined; } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat").renderTag(); this._container_info = this._html_tag.find(".container-info"); this._container_chat = this._html_tag.find(".container-chat"); this._info_frame.html_tag().appendTo(this._container_info); } private_conversations() { return this._conversations; } channel_conversations() { return this._channel_conversations; } client_info() { return this._client_info; } music_info() { return this._music_info; } _clear() { this._content_type = FrameContent.NONE; this._container_chat.children().detach(); } show_private_conversations() { if (this._content_type === FrameContent.PRIVATE_CHAT) return; this._clear(); this._content_type = FrameContent.PRIVATE_CHAT; this._container_chat.append(this._conversations.html_tag()); this._conversations.on_show(); this._info_frame.set_mode(InfoFrameMode.PRIVATE_CHAT); } show_channel_conversations() { if (this._content_type === FrameContent.CHANNEL_CHAT) return; this._clear(); this._content_type = FrameContent.CHANNEL_CHAT; this._container_chat.append(this._channel_conversations.html_tag()); this._channel_conversations.on_show(); this._info_frame.set_mode(InfoFrameMode.CHANNEL_CHAT); } show_client_info(client) { this._client_info.set_current_client(client); this._info_frame.set_mode(InfoFrameMode.CLIENT_INFO); /* specially needs an update here to update the conversation button */ if (this._content_type === FrameContent.CLIENT_INFO) return; this._client_info.previous_frame_content = this._content_type; this._clear(); this._content_type = FrameContent.CLIENT_INFO; this._container_chat.append(this._client_info.html_tag()); } show_music_player(client) { this._music_info.set_current_bot(client); if (this._content_type === FrameContent.MUSIC_BOT) return; this._info_frame.set_mode(InfoFrameMode.MUSIC_BOT); this._music_info.previous_frame_content = this._content_type; this._clear(); this._content_type = FrameContent.MUSIC_BOT; this._container_chat.append(this._music_info.html_tag()); } set_content(type) { if (this._content_type === type) return; if (type === FrameContent.CHANNEL_CHAT) this.show_channel_conversations(); else if (type === FrameContent.PRIVATE_CHAT) this.show_private_conversations(); else { this._clear(); this._content_type = FrameContent.NONE; this._info_frame.set_mode(InfoFrameMode.NONE); } } } chat.Frame = Frame; })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["f9d2d9cd4442d865648ce19099773f225ebe72215759a124bcb54cada2fd51ef"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["f9d2d9cd4442d865648ce19099773f225ebe72215759a124bcb54cada2fd51ef"] = "f9d2d9cd4442d865648ce19099773f225ebe72215759a124bcb54cada2fd51ef"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } let server_connections; class ServerConnectionManager { constructor(tag) { this.connection_handlers = []; this._tag = tag; if (settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION, false)) this._tag.hide(); this._tag_connection_entries = this._tag.find(".connection-handlers"); this._tag_buttons_scoll = this._tag.find(".container-scroll"); this._tag_button_scoll_left = this._tag_buttons_scoll.find(".button-scroll-left"); this._tag_button_scoll_right = this._tag_buttons_scoll.find(".button-scroll-right"); this._tag_button_scoll_left.on('click', this._button_scroll_left_clicked.bind(this)); this._tag_button_scoll_right.on('click', this._button_scroll_right_clicked.bind(this)); this._container_log_server = $("#server-log"); this._container_channel_tree = $("#channelTree"); this._container_hostbanner = $("#hostbanner"); this._container_chat = $("#chat"); this.set_active_connection_handler(undefined); } spawn_server_connection_handler() { const handler = new ConnectionHandler(); this.connection_handlers.push(handler); control_bar.update_button_away(); control_bar.initialize_connection_handler_state(handler); handler.tag_connection_handler.appendTo(this._tag_connection_entries); this._tag.toggleClass("shown", this.connection_handlers.length > 1); this._update_scroll(); return handler; } destroy_server_connection_handler(handler) { this.connection_handlers.remove(handler); handler.tag_connection_handler.remove(); this._update_scroll(); this._tag.toggleClass("shown", this.connection_handlers.length > 1); if (handler.serverConnection) { const connected = handler.connected; handler.serverConnection.disconnect("handler destroyed"); handler.handleDisconnect(DisconnectReason.HANDLER_DESTROYED, connected); } if (handler === this.active_handler) this.set_active_connection_handler(this.connection_handlers[0]); /* destroy all elements */ handler.destroy(); } set_active_connection_handler(handler) { if (handler && this.connection_handlers.indexOf(handler) == -1) throw "Handler hasn't been registered or is already obsolete!"; this._tag_connection_entries.find(".active").removeClass("active"); this._container_channel_tree.children().detach(); this._container_chat.children().detach(); this._container_log_server.children().detach(); this._container_hostbanner.children().detach(); if (handler) { handler.tag_connection_handler.addClass("active"); this._container_hostbanner.append(handler.hostbanner.html_tag); this._container_channel_tree.append(handler.channelTree.tag_tree()); this._container_chat.append(handler.side_bar.html_tag()); this._container_log_server.append(handler.log.html_tag()); if (handler.invoke_resized_on_activate) handler.resize_elements(); } this.active_handler = handler; control_bar.set_connection_handler(handler); top_menu.update_state(); } active_connection_handler() { return this.active_handler; } server_connection_handlers() { return this.connection_handlers; } update_ui() { this._update_scroll(); } _update_scroll() { const has_scroll = this._tag_connection_entries.hasScrollBar("width") && this._tag_connection_entries.width() + 10 >= this._tag_connection_entries.parent().width(); this._tag_buttons_scoll.toggleClass("enabled", has_scroll); this._tag.toggleClass("scrollbar", has_scroll); if (has_scroll) this._update_scroll_buttons(); } _button_scroll_right_clicked() { this._tag_connection_entries.scrollLeft((this._tag_connection_entries.scrollLeft() || 0) + 50); this._update_scroll_buttons(); } _button_scroll_left_clicked() { this._tag_connection_entries.scrollLeft((this._tag_connection_entries.scrollLeft() || 0) - 50); this._update_scroll_buttons(); } _update_scroll_buttons() { const scroll = this._tag_connection_entries.scrollLeft() || 0; this._tag_button_scoll_left.toggleClass("disabled", scroll <= 0); this._tag_button_scoll_right.toggleClass("disabled", scroll + this._tag_connection_entries.width() + 2 >= this._tag_connection_entries[0].scrollWidth); } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["aad43bc9987777ba1c29e2b3fe4eac7892a4efc3d2fe8f83a2308f49a3da326c"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["aad43bc9987777ba1c29e2b3fe4eac7892a4efc3d2fe8f83a2308f49a3da326c"] = "aad43bc9987777ba1c29e2b3fe4eac7892a4efc3d2fe8f83a2308f49a3da326c"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "eoM0uyT9", path: "D:/TeaSpeak/web/shared/js/ui/frames/hostbanner.ts (44,43)" }, { name: "WvGf45xH", path: "D:/TeaSpeak/web/shared/js/ui/frames/hostbanner.ts (64,42)" }, { name: "qS3_dAAx", path: "D:/TeaSpeak/web/shared/js/ui/frames/hostbanner.ts (84,30)" }, { name: "mLgbtjnu", path: "D:/TeaSpeak/web/shared/js/ui/frames/hostbanner.ts (97,43)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } class Hostbanner { constructor(client) { this._destryed = false; this.client = client; this.html_tag = $.spawn("div").addClass("container-hostbanner"); this.html_tag.on('click', event => { const server = this.client.channelTree.server; if (!server || !server.properties.virtualserver_hostbanner_url) return; window.open(server.properties.virtualserver_hostbanner_url, '_blank'); }); this.update(); } destroy() { if (this.updater) { clearTimeout(this.updater); this.updater = undefined; } if (this.html_tag) { this.html_tag.remove(); } this._destryed = true; } update() { if (this._destryed) return; if (this.updater) { clearTimeout(this.updater); this.updater = undefined; } this.html_tag.toggleClass("no-background", !settings.static_global(Settings.KEY_HOSTBANNER_BACKGROUND)); const tag = this.generate_tag(); tag.then(element => { log.debug(LogCategory.CLIENT, _translations.eoM0uyT9 || (_translations.eoM0uyT9 = tr("Regenerated hostbanner tag. Replacing it: %o")), element); if (!element) { this.html_tag.empty().addClass("disabled"); return; } const children = this.html_tag.children(); this.html_tag.append(element).removeClass("disabled"); /* allow the new image be loaded from cache URL */ { children .css('z-index', '2') .css('position', 'absolute') .css('height', '100%') .css('width', '100%'); setTimeout(() => { children.detach(); }, 250); } }).catch(error => { log.warn(LogCategory.CLIENT, _translations.WvGf45xH || (_translations.WvGf45xH = tr("Failed to load the hostbanner: %o")), error); this.html_tag.empty().addClass("disabled"); }); const server = this.client.channelTree.server; this.html_tag.attr('title', server ? server.properties.virtualserver_hostbanner_url : undefined); } static generate_tag(banner_url, gfx_interval, mode) { return __awaiter(this, void 0, void 0, function* () { if (!banner_url) return undefined; if (gfx_interval > 0) { const update_interval = Math.max(gfx_interval, 60); const update_timestamp = (Math.floor((Date.now() / 1000) / update_interval) * update_interval).toString(); try { const url = new URL(banner_url); if (url.search.length == 0) banner_url += "?_ts=" + update_timestamp; else banner_url += "&_ts=" + update_timestamp; } catch (error) { console.warn(_translations.qS3_dAAx || (_translations.qS3_dAAx = tr("Failed to parse banner URL: %o. Using default '&' append.")), error); banner_url += "&_ts=" + update_timestamp; } } /* first now load the image */ const image_element = document.createElement("img"); yield new Promise((resolve, reject) => { image_element.onload = resolve; image_element.onerror = reject; image_element.src = banner_url; image_element.style.display = 'none'; document.body.append(image_element); log.debug(LogCategory.CLIENT, _translations.mLgbtjnu || (_translations.mLgbtjnu = tr("Successfully loaded hostbanner image."))); }); image_element.parentNode.removeChild(image_element); image_element.style.display = 'unset'; return $.spawn("div").addClass("hostbanner-image-container hostbanner-mode-" + mode).append($(image_element)); }); } generate_tag() { return __awaiter(this, void 0, void 0, function* () { if (!this.client.connected) return undefined; const server = this.client.channelTree.server; if (!server) return undefined; if (!server.properties.virtualserver_hostbanner_gfx_url) return undefined; const timeout = server.properties.virtualserver_hostbanner_gfx_interval; const tag = Hostbanner.generate_tag(server.properties.virtualserver_hostbanner_gfx_url, server.properties.virtualserver_hostbanner_gfx_interval, server.properties.virtualserver_hostbanner_mode); if (timeout > 0) this.updater = setTimeout(() => this.update(), timeout * 1000); return tag; }); } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["956e29b868c2e9a6289cd1b992fe709ac449075b7c754e43a53fef956517a791"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["956e29b868c2e9a6289cd1b992fe709ac449075b7c754e43a53fef956517a791"] = "956e29b868c2e9a6289cd1b992fe709ac449075b7c754e43a53fef956517a791"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var image_preview; (function (image_preview) { let preview_overlay; let container_image; let button_open_in_browser; function preview_image(url, original_url) { if (!preview_overlay) return; container_image.empty(); $.spawn("img").attr({ "src": url, "title": original_url, "x-original-src": original_url }).appendTo(container_image); preview_overlay.removeClass("hidden"); button_open_in_browser.show(); } image_preview.preview_image = preview_image; function preview_image_tag(tag) { if (!preview_overlay) return; container_image.empty(); container_image.append(tag); preview_overlay.removeClass("hidden"); button_open_in_browser.hide(); } image_preview.preview_image_tag = preview_image_tag; function current_url() { const image_tag = container_image.find("img"); return image_tag.attr("x-original-src") || image_tag.attr("src") || ""; } image_preview.current_url = current_url; function close_preview() { preview_overlay.addClass("hidden"); } image_preview.close_preview = close_preview; loader.register_task(loader.Stage.LOADED, { priority: 0, name: "image preview init", function: () => __awaiter(this, void 0, void 0, function* () { preview_overlay = $("#overlay-image-preview"); container_image = preview_overlay.find(".container-image"); preview_overlay.find("img").on('click', event => event.preventDefault()); preview_overlay.on('click', event => { if (event.isDefaultPrevented()) return; close_preview(); }); preview_overlay.find(".button-close").on('click', event => { event.preventDefault(); close_preview(); }); preview_overlay.find(".button-download").on('click', event => { event.preventDefault(); const link = document.createElement('a'); link.href = current_url(); link.target = "_blank"; const findex = link.href.lastIndexOf("/") + 1; link.download = link.href.substr(findex); document.body.appendChild(link); link.click(); document.body.removeChild(link); }); button_open_in_browser = preview_overlay.find(".button-open-in-window"); button_open_in_browser.on('click', event => { event.preventDefault(); const win = window.open(current_url(), '_blank'); win.focus(); }); }) }); })(image_preview || (image_preview = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5fc74f145b59b8238703696afb5cc22ca2d480fef1ab02d2b3bcec80e04b5038"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5fc74f145b59b8238703696afb5cc22ca2d480fef1ab02d2b3bcec80e04b5038"] = "5fc74f145b59b8238703696afb5cc22ca2d480fef1ab02d2b3bcec80e04b5038"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "OtbdfpKf", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (338,49)" }, { name: "TjslEtuu", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (388,52)" }, { name: "tgKTt68B", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (391,142)" }, { name: "EwoTjp_H", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (392,144)" }, { name: "VLiF_jTd", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (393,153)" }, { name: "wQTTZBOL", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (395,121)" }, { name: "kYlrLsJh", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (396,123)" }, { name: "O27TI6gw", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (397,129)" }, { name: "DMjxS8Gy", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (400,52)" }, { name: "ekA1Jk45", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (400,155)" }, { name: "ZjRwAH8e", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (400,167)" }, { name: "BiOcwyQS", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (404,52)" }, { name: "Ds9JwNz3", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (413,79)" }, { name: "aEaFAUSl", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (413,121)" }, { name: "s3gggN2V", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (415,79)" }, { name: "LQfEHDHq", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (415,121)" }, { name: "eJVz0xy_", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (419,79)" }, { name: "rHoYTw2I", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (419,143)" }, { name: "a6eWAgVb", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (426,79)" }, { name: "za6usZnN", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (426,134)" }, { name: "GyEUhfQH", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (434,79)" }, { name: "pqtlwDzo", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (434,147)" }, { name: "ssaVXJ6s", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (442,79)" }, { name: "HloiwTjB", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (442,138)" }, { name: "T94YFRKJ", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (455,74)" }, { name: "aRnZWAxP", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (455,127)" }, { name: "mC_Bj6QF", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (462,74)" }, { name: "M3RlPff9", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (462,119)" }, { name: "OC81J6RI", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (468,74)" }, { name: "OzN4pqWV", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (468,145)" }, { name: "nI0lFUtf", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (481,75)" }, { name: "PAxjJKgM", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (481,128)" }, { name: "RX3ynvys", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (483,56)" }, { name: "KkAPpmPk", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (485,56)" }, { name: "KLX2eoxD", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (487,75)" }, { name: "mBmCZEyz", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (487,127)" }, { name: "b_y3zLOL", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (497,56)" }, { name: "Mcvtq5Rd", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (504,56)" }, { name: "owzm_mo1", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (506,75)" }, { name: "iNLIAxK4", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (506,142)" }, { name: "hQ_fh6ph", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (522,56)" }, { name: "LrNB3SF3", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (524,56)" }, { name: "NjTFIAZI", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (532,81)" }, { name: "DX3AQjzT", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (535,92)" }, { name: "H2Ej_Ul2", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (549,47)" }, { name: "BwNSE0JI", path: "D:/TeaSpeak/web/shared/js/ui/frames/server_log.ts (549,104)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var log; (function (log) { let server; (function (server) { let Type; (function (Type) { Type["CONNECTION_BEGIN"] = "connection_begin"; Type["CONNECTION_HOSTNAME_RESOLVE"] = "connection_hostname_resolve"; Type["CONNECTION_HOSTNAME_RESOLVE_ERROR"] = "connection_hostname_resolve_error"; Type["CONNECTION_HOSTNAME_RESOLVED"] = "connection_hostname_resolved"; Type["CONNECTION_LOGIN"] = "connection_login"; Type["CONNECTION_CONNECTED"] = "connection_connected"; Type["CONNECTION_FAILED"] = "connection_failed"; Type["DISCONNECTED"] = "disconnected"; Type["CONNECTION_VOICE_SETUP_FAILED"] = "connection_voice_setup_failed"; Type["CONNECTION_COMMAND_ERROR"] = "connection_command_error"; Type["GLOBAL_MESSAGE"] = "global_message"; Type["SERVER_WELCOME_MESSAGE"] = "server_welcome_message"; Type["SERVER_HOST_MESSAGE"] = "server_host_message"; Type["SERVER_HOST_MESSAGE_DISCONNECT"] = "server_host_message_disconnect"; Type["SERVER_CLOSED"] = "server_closed"; Type["SERVER_BANNED"] = "server_banned"; Type["SERVER_REQUIRES_PASSWORD"] = "server_requires_password"; Type["CLIENT_VIEW_ENTER"] = "client_view_enter"; Type["CLIENT_VIEW_LEAVE"] = "client_view_leave"; Type["CLIENT_VIEW_MOVE"] = "client_view_move"; Type["CLIENT_NICKNAME_CHANGED"] = "client_nickname_changed"; Type["CLIENT_NICKNAME_CHANGE_FAILED"] = "client_nickname_change_failed"; Type["CLIENT_SERVER_GROUP_ADD"] = "client_server_group_add"; Type["CLIENT_SERVER_GROUP_REMOVE"] = "client_server_group_remove"; Type["CLIENT_CHANNEL_GROUP_CHANGE"] = "client_channel_group_change"; Type["CHANNEL_CREATE"] = "channel_create"; Type["CHANNEL_DELETE"] = "channel_delete"; Type["ERROR_CUSTOM"] = "error_custom"; Type["ERROR_PERMISSION"] = "error_permission"; Type["RECONNECT_SCHEDULED"] = "reconnect_scheduled"; Type["RECONNECT_EXECUTE"] = "reconnect_execute"; Type["RECONNECT_CANCELED"] = "reconnect_canceled"; })(Type = server.Type || (server.Type = {})); server.MessageBuilders = { "error_custom": (data, options) => { return [$.spawn("div").addClass("log-error").text(data.message)]; } }; })(server = log.server || (log.server = {})); class ServerLog { constructor(handle) { this.history_length = 100; this._log = []; this.handle = handle; this.auto_follow = true; this._html_tag = $.spawn("div").addClass("container-log"); this._log_container = $.spawn("div").addClass("container-messages"); this._log_container.appendTo(this._html_tag); this._html_tag.on('scroll', event => { if (Date.now() - this._ignore_event < 100) { this._ignore_event = 0; return; } this.auto_follow = (this._html_tag[0].scrollTop + this._html_tag[0].clientHeight + this._html_tag[0].clientHeight * .125) > this._html_tag[0].scrollHeight; }); } log(type, data) { const event = { data: data, timestamp: Date.now(), type: type }; this._log.push(event); while (this._log.length > this.history_length) this._log.pop_front(); this.append_log(event); } html_tag() { return this._html_tag; } destroy() { this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._log_container = undefined; this._log = undefined; } append_log(message) { let container = $.spawn("div").addClass("log-message"); /* build timestamp */ { const num = number => ('00' + number).substr(-2); const date = new Date(message.timestamp); $.spawn("div") .addClass("timestamp") .text("<" + num(date.getHours()) + ":" + num(date.getMinutes()) + ":" + num(date.getSeconds()) + ">") .appendTo(container); } /* build message data */ { const builder = server.MessageBuilders[message.type]; if (!builder) { MessageHelper.formatMessage(_translations.OtbdfpKf || (_translations.OtbdfpKf = tr("missing log message builder {0}!")), message.type).forEach(e => e.addClass("log-error").appendTo(container)); } else { const elements = builder(message.data, {}); if (!elements || elements.length == 0) return; /* discard message */ container.append(...elements); } } this._ignore_event = Date.now(); this._log_container.append(container); /* max history messages! */ const messages = this._log_container.children(); let index = 0; while (messages.length - index > this.history_length) index++; const hide_elements = messages.filter(idx => idx < index); hide_elements.hide(250, () => hide_elements.remove()); if (this.auto_follow) { clearTimeout(this._scroll_task); /* do not enforce a recalculate style here */ this._scroll_task = setTimeout(() => { this._html_tag.scrollTop(this._html_tag[0].scrollHeight); this._scroll_task = 0; }, 5); } } } log.ServerLog = ServerLog; })(log || (log = {})); /* impl of the parsers */ (function (log) { let server; (function (server) { let impl; (function (impl) { const client_tag = (client, braces) => htmltags.generate_client_object({ client_unique_id: client.client_unique_id, client_id: client.client_id, client_name: client.client_name, add_braces: braces }); const channel_tag = (channel, braces) => htmltags.generate_channel_object({ channel_display_name: channel.channel_name, channel_name: channel.channel_name, channel_id: channel.channel_id, add_braces: braces }); server.MessageBuilders["connection_begin"] = (data, options) => { return MessageHelper.formatMessage(_translations.TjslEtuu || (_translations.TjslEtuu = tr("Connecting to {0}{1}")), data.address.server_hostname, data.address.server_port == 9987 ? "" : (":" + data.address.server_port)); }; server.MessageBuilders["connection_hostname_resolve"] = (data, options) => MessageHelper.formatMessage(_translations.tgKTt68B || (_translations.tgKTt68B = tr("Resolving hostname"))); server.MessageBuilders["connection_hostname_resolved"] = (data, options) => MessageHelper.formatMessage(_translations.EwoTjp_H || (_translations.EwoTjp_H = tr("Hostname resolved successfully to {0}:{1}")), data.address.server_hostname, data.address.server_port); server.MessageBuilders["connection_hostname_resolve_error"] = (data, options) => MessageHelper.formatMessage(_translations.VLiF_jTd || (_translations.VLiF_jTd = tr("Failed to resolve hostname. Connecting to given hostname. Error: {0}")), data.message); server.MessageBuilders["connection_login"] = (data, options) => MessageHelper.formatMessage(_translations.wQTTZBOL || (_translations.wQTTZBOL = tr("Logging in..."))); server.MessageBuilders["connection_failed"] = (data, options) => MessageHelper.formatMessage(_translations.kYlrLsJh || (_translations.kYlrLsJh = tr("Connect failed."))); server.MessageBuilders["connection_connected"] = (data, options) => MessageHelper.formatMessage(_translations.O27TI6gw || (_translations.O27TI6gw = tr("Connected as {0}")), client_tag(data.own_client, true)); server.MessageBuilders["connection_voice_setup_failed"] = (data, options) => { return MessageHelper.formatMessage(_translations.DMjxS8Gy || (_translations.DMjxS8Gy = tr("Failed to setup voice bridge: {0}. Allow reconnect: {1}")), data.reason, data.reconnect_delay > 0 ? _translations.ekA1Jk45 || (_translations.ekA1Jk45 = tr("yes")) : _translations.ZjRwAH8e || (_translations.ZjRwAH8e = tr("no"))); }; server.MessageBuilders["error_permission"] = (data, options) => { return MessageHelper.formatMessage(_translations.BiOcwyQS || (_translations.BiOcwyQS = tr("Insufficient client permissions. Failed on permission {0}")), data.permission ? data.permission.name : "unknown").map(e => e.addClass("log-error")); }; server.MessageBuilders["client_view_enter"] = (data, options) => { if (data.reason == ViewReasonId.VREASON_SYSTEM) { return undefined; } if (data.reason == ViewReasonId.VREASON_USER_ACTION) { /* client appeared */ if (data.channel_from) { return MessageHelper.formatMessage(data.own_channel ? _translations.Ds9JwNz3 || (_translations.Ds9JwNz3 = tr("{0} appeared from {1} to your {2}")) : _translations.aEaFAUSl || (_translations.aEaFAUSl = tr("{0} appeared from {1} to {2}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to)); } else { return MessageHelper.formatMessage(data.own_channel ? _translations.s3gggN2V || (_translations.s3gggN2V = tr("{0} connected to your channel {1}")) : _translations.LQfEHDHq || (_translations.LQfEHDHq = tr("{0} connected to channel {1}")), client_tag(data.client), channel_tag(data.channel_to)); } } else if (data.reason == ViewReasonId.VREASON_MOVED) { if (data.channel_from) { return MessageHelper.formatMessage(data.own_channel ? _translations.eJVz0xy_ || (_translations.eJVz0xy_ = tr("{0} appeared from {1} to your channel {2}, moved by {3}")) : _translations.rHoYTw2I || (_translations.rHoYTw2I = tr("{0} appeared from {1} to {2}, moved by {3}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to), client_tag(data.invoker)); } else { return MessageHelper.formatMessage(data.own_channel ? _translations.a6eWAgVb || (_translations.a6eWAgVb = tr("{0} appeared to your channel {1}, moved by {2}")) : _translations.za6usZnN || (_translations.za6usZnN = tr("{0} appeared to {1}, moved by {2}")), client_tag(data.client), channel_tag(data.channel_to), client_tag(data.invoker)); } } else if (data.reason == ViewReasonId.VREASON_CHANNEL_KICK) { if (data.channel_from) { return MessageHelper.formatMessage(data.own_channel ? _translations.GyEUhfQH || (_translations.GyEUhfQH = tr("{0} appeared from {1} to your channel {2}, kicked by {3}{4}")) : _translations.pqtlwDzo || (_translations.pqtlwDzo = tr("{0} appeared from {1} to {2}, kicked by {3}{4}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } else { return MessageHelper.formatMessage(data.own_channel ? _translations.ssaVXJ6s || (_translations.ssaVXJ6s = tr("{0} appeared to your channel {1}, kicked by {2}{3}")) : _translations.HloiwTjB || (_translations.HloiwTjB = tr("{0} appeared to {1}, kicked by {2}{3}")), client_tag(data.client), channel_tag(data.channel_to), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } } return [$.spawn("div").addClass("log-error").text("Invalid view enter reason id (" + data.message + ")")]; }; server.MessageBuilders["client_view_move"] = (data, options) => { if (data.reason == ViewReasonId.VREASON_MOVED) { return MessageHelper.formatMessage(data.client_own ? _translations.T94YFRKJ || (_translations.T94YFRKJ = tr("You was moved by {3} from channel {1} to {2}")) : _translations.aRnZWAxP || (_translations.aRnZWAxP = tr("{0} was moved from channel {1} to {2} by {3}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to), client_tag(data.invoker)); } else if (data.reason == ViewReasonId.VREASON_USER_ACTION) { return MessageHelper.formatMessage(data.client_own ? _translations.mC_Bj6QF || (_translations.mC_Bj6QF = tr("You switched from channel {1} to {2}")) : _translations.M3RlPff9 || (_translations.M3RlPff9 = tr("{0} switched from channel {1} to {2}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to)); } else if (data.reason == ViewReasonId.VREASON_CHANNEL_KICK) { return MessageHelper.formatMessage(data.client_own ? _translations.OC81J6RI || (_translations.OC81J6RI = tr("You got kicked out of the channel {1} to channel {2} by {3}{4}")) : _translations.OzN4pqWV || (_translations.OzN4pqWV = tr("{0} got kicked from channel {1} to {2} by {3}{4}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } return [$.spawn("div").addClass("log-error").text("Invalid view move reason id (" + data.reason + ")")]; }; server.MessageBuilders["client_view_leave"] = (data, options) => { if (data.reason == ViewReasonId.VREASON_USER_ACTION) { return MessageHelper.formatMessage(data.own_channel ? _translations.nI0lFUtf || (_translations.nI0lFUtf = tr("{0} disappeared from your channel {1} to {2}")) : _translations.PAxjJKgM || (_translations.PAxjJKgM = tr("{0} disappeared from {1} to {2}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to)); } else if (data.reason == ViewReasonId.VREASON_SERVER_LEFT) { return MessageHelper.formatMessage(_translations.RX3ynvys || (_translations.RX3ynvys = tr("{0} left the server{1}")), client_tag(data.client), data.message ? (" (" + data.message + ")") : ""); } else if (data.reason == ViewReasonId.VREASON_SERVER_KICK) { return MessageHelper.formatMessage(_translations.KkAPpmPk || (_translations.KkAPpmPk = tr("{0} was kicked from the server by {1}.{2}")), client_tag(data.client), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } else if (data.reason == ViewReasonId.VREASON_CHANNEL_KICK) { return MessageHelper.formatMessage(data.own_channel ? _translations.KLX2eoxD || (_translations.KLX2eoxD = tr("{0} was kicked from your channel by {2}.{3}")) : _translations.mBmCZEyz || (_translations.mBmCZEyz = tr("{0} was kicked from channel {1} by {2}.{3}")), client_tag(data.client), channel_tag(data.channel_from), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } else if (data.reason == ViewReasonId.VREASON_BAN) { let duration = "permanently"; if (data.ban_time) duration = "for " + formatDate(data.ban_time); return MessageHelper.formatMessage(_translations.b_y3zLOL || (_translations.b_y3zLOL = tr("{0} was banned {1} by {2}.{3}")), client_tag(data.client), duration, client_tag(data.invoker), data.message ? (" (" + data.message + ")") : ""); } else if (data.reason == ViewReasonId.VREASON_TIMEOUT) { return MessageHelper.formatMessage(_translations.Mcvtq5Rd || (_translations.Mcvtq5Rd = tr("{0} timed out{1}")), client_tag(data.client), data.message ? (" (" + data.message + ")") : ""); } else if (data.reason == ViewReasonId.VREASON_MOVED) { return MessageHelper.formatMessage(data.own_channel ? _translations.owzm_mo1 || (_translations.owzm_mo1 = tr("{0} disappeared from your channel {1} to {2}, moved by {3}")) : _translations.iNLIAxK4 || (_translations.iNLIAxK4 = tr("{0} disappeared from {1} to {2}, moved by {3}")), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to), client_tag(data.invoker)); } return [$.spawn("div").addClass("log-error").text("Invalid view leave reason id (" + data.reason + ")")]; }; server.MessageBuilders["server_welcome_message"] = (data, options) => { return MessageHelper.bbcode_chat("[color=green]" + data.message + "[/color]"); }; server.MessageBuilders["server_host_message"] = (data, options) => { return MessageHelper.bbcode_chat("[color=green]" + data.message + "[/color]"); }; server.MessageBuilders["client_nickname_changed"] = (data, options) => { if (data.own_client) { return MessageHelper.formatMessage(_translations.hQ_fh6ph || (_translations.hQ_fh6ph = tr("Nickname successfully changed."))); } else { return MessageHelper.formatMessage(_translations.LrNB3SF3 || (_translations.LrNB3SF3 = tr("{0} changed his nickname from \"{1}\" to \"{2}\"")), client_tag(data.client), data.old_name, data.new_name); } }; server.MessageBuilders["global_message"] = (data, options) => { return []; /* we do not show global messages within log */ }; server.MessageBuilders["disconnected"] = () => MessageHelper.formatMessage(_translations.NjTFIAZI || (_translations.NjTFIAZI = tr("Disconnected from server"))); server.MessageBuilders["reconnect_scheduled"] = (data, options) => { return tra("Reconnecting in {0}.", MessageHelper.format_time(data.timeout, _translations.DX3AQjzT || (_translations.DX3AQjzT = tr("now")))); }; server.MessageBuilders["reconnect_canceled"] = (data, options) => { return tra("Canceled reconnect."); }; server.MessageBuilders["reconnect_execute"] = (data, options) => { return tra("Reconnecting..."); }; server.MessageBuilders["server_banned"] = (data, options) => { let result; const time = data.time == 0 ? _translations.H2Ej_Ul2 || (_translations.H2Ej_Ul2 = tr("ever")) : MessageHelper.format_time(data.time * 1000, _translations.BwNSE0JI || (_translations.BwNSE0JI = tr("one second"))); if (data.invoker.client_id > 0) { if (data.message) result = tra("You've been banned from the server by {0} for {1}. Reason: {2}", client_tag(data.invoker), time, data.message); else result = tra("You've been banned from the server by {0} for {1}.", client_tag(data.invoker), time); } else { if (data.message) result = tra("You've been banned from the server for {0}. Reason: {1}", time, data.message); else result = tra("You've been banned from the server for {0}.", time); } return result.map(e => e.addClass("log-error")); }; })(impl || (impl = {})); })(server = log.server || (log.server = {})); })(log || (log = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["918f834521cd8b02e67c6b743aecf2431853a74ac702b87b960137ed0f080dd0"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["918f834521cd8b02e67c6b743aecf2431853a74ac702b87b960137ed0f080dd0"] = "918f834521cd8b02e67c6b743aecf2431853a74ac702b87b960137ed0f080dd0"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var chat; (function (chat) { class ChatBox { constructor() { this._message_history = []; this._message_history_length = 100; this._message_history_index = 0; this.typing_interval = 2000; /* update frequency */ this._enabled = true; this.__callback_key_up = this._callback_key_up.bind(this); this.__callback_key_down = this._callback_key_down.bind(this); this.__callback_text_changed = this._callback_text_changed.bind(this); this.__callback_paste = event => this._callback_paste(event); this._build_html_tag(); this._initialize_listener(); } html_tag() { return this._html_tag; } destroy() { this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._html_input = undefined; clearTimeout(this._typing_timeout); this.__callback_text_changed = undefined; this.__callback_key_down = undefined; this.__callback_paste = undefined; this.callback_text = undefined; this.callback_typing = undefined; } _initialize_listener() { this._html_input.on("cut paste drop keydown keyup", (event) => this.__callback_text_changed(event)); this._html_input.on("change", this.__callback_text_changed); this._html_input.on("keydown", this.__callback_key_down); this._html_input.on("keyup", this.__callback_key_up); this._html_input.on("paste", this.__callback_paste); } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_chatbox").renderTag({ emojy_support: settings.static_global(Settings.KEY_CHAT_COLORED_EMOJIES) }); this._html_input = this._html_tag.find(".textarea"); const tag = this._html_tag.find('.button-emoji'); tag.lsxEmojiPicker({ width: 300, height: 400, twemoji: typeof (window.twemoji) !== "undefined", onSelect: emoji => this._html_input.html(this._html_input.html() + emoji.value), closeOnSelect: false }); } _callback_text_changed(event) { if (event && event.defaultPrevented) return; /* Auto resize */ const text = this._html_input[0]; text.style.height = "1em"; text.style.height = text.scrollHeight + 'px'; if (!event || (event.type !== "keydown" && event.type !== "keyup" && event.type !== "change")) return; this._typing_last_event = Date.now(); if (this._typing_timeout) return; const _trigger_typing = (last_time) => { if (this._typing_last_event <= last_time) { this._typing_timeout = 0; return; } try { if (this.callback_typing) this.callback_typing(); } finally { this._typing_timeout = setTimeout(_trigger_typing, this.typing_interval, this._typing_last_event); } }; _trigger_typing(0); /* We def want that*/ } _text(element) { if (typeof (element) !== "object") return element; if (element instanceof HTMLImageElement) return element.alt || element.title; if (element instanceof HTMLBRElement) { return '\n'; } if (element.childNodes.length > 0) return [...element.childNodes].map(e => this._text(e)).join(""); if (element.nodeType == Node.TEXT_NODE) return element.textContent; return typeof (element.innerText) === "string" ? element.innerText : ""; } htmlEscape(message) { const div = document.createElement('div'); div.innerText = message; message = div.innerHTML; return message.replace(/ /g, ' '); } _callback_paste(event) { const _event = event.originalEvent || event; const clipboard = _event.clipboardData || window.clipboardData; if (!clipboard) return; const raw_text = clipboard.getData('text/plain'); const selection = window.getSelection(); if (!selection.rangeCount) return false; let html_xml = clipboard.getData('text/html'); if (!html_xml) html_xml = $.spawn("div").text(raw_text).html(); const parser = new DOMParser(); const nodes = parser.parseFromString(html_xml, "text/html"); let data = this._text(nodes.body); /* fix prefix & suffix new lines */ { let prefix_length = 0, suffix_length = 0; { for (let i = 0; i < raw_text.length; i++) if (raw_text.charAt(i) === '\n') prefix_length++; else if (raw_text.charAt(i) !== '\r') break; for (let i = raw_text.length - 1; i >= 0; i++) if (raw_text.charAt(i) === '\n') suffix_length++; else if (raw_text.charAt(i) !== '\r') break; } data = data.replace(/^[\n\r]+|[\n\r]+$/g, ''); data = "\n".repeat(prefix_length) + data + "\n".repeat(suffix_length); } event.preventDefault(); selection.deleteFromDocument(); document.execCommand('insertHTML', false, this.htmlEscape(data)); } test_message(message) { message = message .replace(/ /gi, "") .replace(/
/gi, "") .replace(/\n/gi, "") .replace(//gi, ""); return message.length > 0; } _callback_key_down(event) { if (event.key.toLowerCase() === "enter" && !event.shiftKey) { event.preventDefault(); /* deactivate chatbox when no callback? */ let text = this._html_input[0].innerText; if (!this.test_message(text)) return; this._message_history.push(text); this._message_history_index = this._message_history.length; if (this._message_history.length > this._message_history_length) this._message_history = this._message_history.slice(this._message_history.length - this._message_history_length); if (this.callback_text) { this.callback_text(chat.helpers.preprocess_chat_message(text)); } if (this._typing_timeout) clearTimeout(this._typing_timeout); this._typing_timeout = 1; /* enforce no typing update while sending */ this._html_input.text(""); setTimeout(() => { this.__callback_text_changed(); this._typing_timeout = 0; /* enable text change listener again */ }); } else if (event.key.toLowerCase() === "arrowdown") { //TODO: Test for at the last line within the box if (this._message_history_index < 0) return; if (this._message_history_index >= this._message_history.length) return; /* OOB, even with the empty message */ this._message_history_index++; this._html_input[0].innerText = this._message_history[this._message_history_index] || ""; /* OOB just returns "undefined" */ } else if (event.key.toLowerCase() === "arrowup") { //TODO: Test for at the first line within the box if (this._message_history_index <= 0) return; /* we cant go "down" */ this._message_history_index--; this._html_input[0].innerText = this._message_history[this._message_history_index]; } else { if (this._message_history_index >= 0) { if (this._message_history_index >= this._message_history.length) { if ("" !== this._html_input[0].innerText) this._message_history_index = -1; } else if (this._message_history[this._message_history_index] !== this._html_input[0].innerText) this._message_history_index = -1; } } } _callback_key_up(event) { if ("" === this._html_input[0].innerText) this._message_history_index = this._message_history.length; } set_enabled(flag) { if (this._enabled === flag) return; if (!this._context_task) { this._enabled = flag; /* Allow the browser to asynchronously recalculate everything */ this._context_task = setTimeout(() => { this._context_task = undefined; this._html_input.each((_, e) => { e.contentEditable = this._enabled ? "true" : "false"; }); }); this._html_tag.find('.button-emoji').toggleClass("disabled", !flag); } } is_enabled() { return this._enabled; } focus_input() { this._html_input.focus(); } } chat.ChatBox = ChatBox; })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c5be3188cf21fcbc775719d2ac72dd358cb3e8e285fbafe64efad84171587ae9"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c5be3188cf21fcbc775719d2ac72dd358cb3e8e285fbafe64efad84171587ae9"] = "c5be3188cf21fcbc775719d2ac72dd358cb3e8e285fbafe64efad84171587ae9"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "fLceMi2w", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (15,56)" }, { name: "p3JBDN23", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (176,52)" }, { name: "p_7G78re", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (179,52)" }, { name: "HIvttmjm", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (352,73)" }, { name: "yUP_LiSX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (352,94)" }, { name: "i_VB2Zg6", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (380,74)" }, { name: "dDilhGjF", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (384,45)" }, { name: "uZp2aiUD", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (386,85)" }, { name: "SLaP2Hpu", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (407,45)" }, { name: "LVc9nB1W", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (409,44)" }, { name: "hVY41Mvc", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (411,45)" }, { name: "BGNiWoVt", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (413,47)" }, { name: "dE7l9KPA", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (415,47)" }, { name: "WWKyCzCv", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/chat_helper.ts (417,30)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var chat; (function (chat) { let helpers; (function (helpers) { //https://regex101.com/r/YQbfcX/2 //static readonly URL_REGEX = /^(?([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/(?(?:[^\s?]+)?)(?:\?(?\S+))?)?$/gm; const URL_REGEX = /^(([a-zA-Z0-9-]+\.)+[a-zA-Z0-9-]{2,63})(?:\/((?:[^\s?]+)?)(?:\?(\S+))?)?$/gm; function process_urls(message) { const words = message.split(/[ \n]/); for (let index = 0; index < words.length; index++) { const flag_escaped = words[index].startsWith('!'); const unescaped = flag_escaped ? words[index].substr(1) : words[index]; _try: try { const url = new URL(unescaped); log.debug(LogCategory.GENERAL, _translations.fLceMi2w || (_translations.fLceMi2w = tr("Chat message contains URL: %o")), url); if (url.protocol !== 'http:' && url.protocol !== 'https:') break _try; if (flag_escaped) { message = undefined; words[index] = unescaped; } else { message = undefined; words[index] = "[url=" + url.toString() + "]" + url.toString() + "[/url]"; } } catch (e) { /* word isn't an url */ } if (unescaped.match(URL_REGEX)) { if (flag_escaped) { message = undefined; words[index] = unescaped; } else { message = undefined; words[index] = "[url=" + unescaped + "]" + unescaped + "[/url]"; } } } return message || words.join(" "); } let md2bbc; (function (md2bbc) { class Renderer { render(tokens, options, env) { this.last_paragraph = undefined; this._options = options; let result = ''; //TODO: Escape BB-Codes for (let index = 0; index < tokens.length; index++) { if (tokens[index].type === 'inline') { result += this.render_inline(tokens[index].children, index); } else { result += this.render_token(tokens[index], index); } } this._options = undefined; return result; } render_token(token, index) { log.debug(LogCategory.GENERAL, _translations.p3JBDN23 || (_translations.p3JBDN23 = tr("Render Markdown token: %o")), token); const renderer = Renderer.renderers[token.type]; if (typeof (renderer) === "undefined") { log.warn(LogCategory.CHAT, _translations.p_7G78re || (_translations.p_7G78re = tr("Missing markdown to bbcode renderer for token %s: %o")), token.type, token); return token.content || ""; } const result = renderer(this, token, index); if (token.type === "paragraph_open") this.last_paragraph = token; return result; } render_inline(tokens, index) { let result = ''; for (let index = 0; index < tokens.length; index++) { result += this.render_token(tokens[index], index); } return result; } options() { return this._options; } maybe_escape_bb(text) { if (this._options.escape_bb) return xbbcode.escape(text); return text; } } Renderer.renderers = { "text": (renderer, token) => renderer.options().process_url ? process_urls(renderer.maybe_escape_bb(token.content)) : renderer.maybe_escape_bb(token.content), "softbreak": () => "\n", "hardbreak": () => "\n", "paragraph_open": (renderer, token) => { const last_line = !renderer.last_paragraph || !renderer.last_paragraph.lines ? 0 : renderer.last_paragraph.lines[1]; const lines = token.lines[0] - last_line; return [...new Array(lines)].map(e => "[br]").join(""); }, "paragraph_close": () => "", "strong_open": (renderer, token) => "[b]", "strong_close": (renderer, token) => "[/b]", "em_open": (renderer, token) => "[i]", "em_close": (renderer, token) => "[/i]", "del_open": () => "[s]", "del_close": () => "[/s]", "sup": (renderer, token) => "[sup]" + renderer.maybe_escape_bb(token.content) + "[/sup]", "sub": (renderer, token) => "[sub]" + renderer.maybe_escape_bb(token.content) + "[/sub]", "bullet_list_open": () => "[ul]", "bullet_list_close": () => "[/ul]", "ordered_list_open": () => "[ol]", "ordered_list_close": () => "[/ol]", "list_item_open": () => "[li]", "list_item_close": () => "[/li]", "table_open": () => "[table]", "table_close": () => "[/table]", "thead_open": () => "", "thead_close": () => "", "tbody_open": () => "", "tbody_close": () => "", "tr_open": () => "[tr]", "tr_close": () => "[/tr]", "th_open": (renderer, token) => "[th" + (token.align ? ("=" + token.align) : "") + "]", "th_close": () => "[/th]", "td_open": () => "[td]", "td_close": () => "[/td]", "link_open": (renderer, token) => "[url" + (token.href ? ("=" + token.href) : "") + "]", "link_close": () => "[/url]", "image": (renderer, token) => "[img=" + (token.src) + "]" + (token.alt || token.src) + "[/img]", //footnote_ref //"content": "==Marked text==", //mark_open //mark_close //++Inserted text++ "ins_open": () => "[u]", "ins_close": () => "[/u]", /* ``` test [/code] test ``` */ "code": (renderer, token) => "[i-code]" + xbbcode.escape(token.content) + "[/i-code]", "fence": (renderer, token) => "[code" + (token.params ? ("=" + token.params) : "") + "]" + xbbcode.escape(token.content) + "[/code]", "heading_open": (renderer, token) => "[size=" + (9 - Math.min(4, token.hLevel)) + "]", "heading_close": (renderer, token) => "[/size][hr]", "hr": () => "[hr]", }; md2bbc.Renderer = Renderer; })(md2bbc || (md2bbc = {})); let _renderer; function process_markdown(message, options) { if (typeof (window.remarkable) === "undefined") return (options.process_url ? process_urls(message) : message); if (!_renderer) { _renderer = new window.remarkable.Remarkable('full'); _renderer.set({ typographer: true }); _renderer.renderer = new md2bbc.Renderer(); _renderer.inline.ruler.disable(['newline', 'autolink']); } _renderer.set({ process_url: !!options.process_url, escape_bb: !!options.escape_bb }); let result = _renderer.render(message); if (result.endsWith("\n")) result = result.substr(0, result.length - 1); return result; } function preprocess_chat_message(message) { const process_url = settings.static_global(Settings.KEY_CHAT_TAG_URLS); const parse_markdown = settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN); const escape_bb = !settings.static_global(Settings.KEY_CHAT_ENABLE_BBCODE); if (parse_markdown) return process_markdown(message, { process_url: process_url, escape_bb: escape_bb }); if (escape_bb) message = xbbcode.escape(message); return process_url ? process_urls(message) : message; } helpers.preprocess_chat_message = preprocess_chat_message; let history; (function (history) { let _local_cache; function get_cache() { return __awaiter(this, void 0, void 0, function* () { if (_local_cache) return _local_cache; if (!('caches' in window)) throw "missing cache extension!"; return (_local_cache = yield caches.open('chat_history')); }); } function load_history(key) { return __awaiter(this, void 0, void 0, function* () { const cache = yield get_cache(); const request = new Request("https://_local_cache/cache_request_" + key); const cached_response = yield cache.match(request); if (!cached_response) return undefined; return yield cached_response.json(); }); } history.load_history = load_history; function save_history(key, value) { return __awaiter(this, void 0, void 0, function* () { const cache = yield get_cache(); const request = new Request("https://_local_cache/cache_request_" + key); const data = JSON.stringify(value); const new_headers = new Headers(); new_headers.set("Content-type", "application/json"); new_headers.set("Content-length", data.length.toString()); yield cache.put(request, new Response(data, { headers: new_headers })); }); } history.save_history = save_history; })(history = helpers.history || (helpers.history = {})); let date; (function (date) { function same_day(a, b) { a = a instanceof Date ? a : new Date(a); b = b instanceof Date ? b : new Date(b); if (a.getDate() !== b.getDate()) return false; if (a.getMonth() !== b.getMonth()) return false; return a.getFullYear() === b.getFullYear(); } date.same_day = same_day; })(date = helpers.date || (helpers.date = {})); })(helpers = chat.helpers || (chat.helpers = {})); let format; (function (format_1) { let date; (function (date_1) { let ColloquialFormat; (function (ColloquialFormat) { ColloquialFormat[ColloquialFormat["YESTERDAY"] = 0] = "YESTERDAY"; ColloquialFormat[ColloquialFormat["TODAY"] = 1] = "TODAY"; ColloquialFormat[ColloquialFormat["GENERAL"] = 2] = "GENERAL"; })(ColloquialFormat = date_1.ColloquialFormat || (date_1.ColloquialFormat = {})); function date_format(date, now, ignore_settings) { if (!ignore_settings && !settings.static_global(Settings.KEY_CHAT_COLLOQUIAL_TIMESTAMPS)) return ColloquialFormat.GENERAL; let delta_day = now.getDate() - date.getDate(); if (delta_day < 1) /* month change? */ delta_day = date.getDate() - now.getDate(); if (delta_day == 0) return ColloquialFormat.TODAY; else if (delta_day == 1) return ColloquialFormat.YESTERDAY; return ColloquialFormat.GENERAL; } date_1.date_format = date_format; function format_date_general(date, hours) { return ('00' + date.getDate()).substr(-2) + "." + ('00' + date.getMonth()).substr(-2) + "." + date.getFullYear() + (typeof (hours) === "undefined" || hours ? " at " + ('00' + date.getHours()).substr(-2) + ":" + ('00' + date.getMinutes()).substr(-2) : ""); } date_1.format_date_general = format_date_general; function format_date_colloquial(date, current_timestamp) { const format = date_format(date, current_timestamp); if (format == ColloquialFormat.GENERAL) { return { result: format_date_general(date), format: format }; } else { let hrs = date.getHours(); let time = "AM"; if (hrs > 12) { hrs -= 12; time = "PM"; } return { result: (format == ColloquialFormat.YESTERDAY ? _translations.HIvttmjm || (_translations.HIvttmjm = tr("Yesterday at")) : _translations.yUP_LiSX || (_translations.yUP_LiSX = tr("Today at"))) + " " + hrs + ":" + date.getMinutes() + " " + time, format: format }; } } date_1.format_date_colloquial = format_date_colloquial; function format_chat_time(date) { const timestamp = date.getTime(); const current_timestamp = new Date(); const result = { result: "", next_update: 0 }; if (settings.static_global(Settings.KEY_CHAT_FIXED_TIMESTAMPS)) { const format = format_date_colloquial(date, current_timestamp); result.result = format.result; result.next_update = 0; /* TODO: Update on day change? */ } else { const delta = current_timestamp.getTime() - timestamp; if (delta < 2000) { result.result = "now"; result.next_update = 2500 - delta; /* update after two seconds */ } else if (delta < 30000) { /* 30 seconds */ result.result = Math.floor(delta / 1000) + " " + (_translations.i_VB2Zg6 || (_translations.i_VB2Zg6 = tr("seconds ago"))); result.next_update = 1000; /* update every second */ } else if (delta < 30 * 60 * 1000) { /* 30 minutes */ if (delta < 120 * 1000) result.result = _translations.dDilhGjF || (_translations.dDilhGjF = tr("one minute ago")); else result.result = Math.floor(delta / (1000 * 60)) + " " + (_translations.uZp2aiUD || (_translations.uZp2aiUD = tr("minutes ago"))); result.next_update = 60000; /* updater after a minute */ } else { result.result = format_date_colloquial(date, current_timestamp).result; result.next_update = 0; /* TODO: Update on day change? */ } } return result; } date_1.format_chat_time = format_chat_time; })(date = format_1.date || (format_1.date = {})); let time; (function (time) { function format_online_time(secs) { let years = Math.floor(secs / (60 * 60 * 24 * 365)); let days = Math.floor(secs / (60 * 60 * 24)) % 365; let hours = Math.floor(secs / (60 * 60)) % 24; let minutes = Math.floor(secs / 60) % 60; let seconds = Math.floor(secs % 60); let result = ""; if (years > 0) result += years + " " + (_translations.SLaP2Hpu || (_translations.SLaP2Hpu = tr("years"))) + " "; if (years > 0 || days > 0) result += days + " " + (_translations.LVc9nB1W || (_translations.LVc9nB1W = tr("days"))) + " "; if (years > 0 || days > 0 || hours > 0) result += hours + " " + (_translations.hVY41Mvc || (_translations.hVY41Mvc = tr("hours"))) + " "; if (years > 0 || days > 0 || hours > 0 || minutes > 0) result += minutes + " " + (_translations.BGNiWoVt || (_translations.BGNiWoVt = tr("minutes"))) + " "; if (years > 0 || days > 0 || hours > 0 || minutes > 0 || seconds > 0) result += seconds + " " + (_translations.dE7l9KPA || (_translations.dE7l9KPA = tr("seconds"))) + " "; else result = (_translations.WWKyCzCv || (_translations.WWKyCzCv = tr("now"))) + " "; return result.substr(0, result.length - 1); } time.format_online_time = format_online_time; })(time = format_1.time || (format_1.time = {})); })(format = chat.format || (chat.format = {})); })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["b95f363e0f5bc44d4fb25a34df7141f88562c49ef5fb94014debc75d5db9cb0b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["b95f363e0f5bc44d4fb25a34df7141f88562c49ef5fb94014debc75d5db9cb0b"] = "b95f363e0f5bc44d4fb25a34df7141f88562c49ef5fb94014debc75d5db9cb0b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Dp1iLhtX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (109,67)" }, { name: "D09E5x0q", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (148,40)" }, { name: "EsaodnJz", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (150,40)" }, { name: "AtQnQgBE", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (152,40)" }, { name: "vwdjmn_F", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (175,51)" }, { name: "l65uhuvX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (186,51)" }, { name: "Qdw6LANe", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (194,51)" }, { name: "iSy8yGYs", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (202,51)" }, { name: "M0LdnKoE", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (210,51)" }, { name: "Urfvx1ZJ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (218,51)" }, { name: "KNP4yV0s", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (238,73)" }, { name: "xrYdPJ1G", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (238,131)" }, { name: "rVlVp788", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (246,77)" }, { name: "NKtvfR4K", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (265,77)" }, { name: "pgVV72hD", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (269,66)" }, { name: "OyhbrRno", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/client_info.ts (269,110)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var chat; (function (chat) { class ClientInfo { constructor(handle) { this.handle = handle; this._build_html_tag(); } html_tag() { return this._html_tag; } destroy() { clearInterval(this._online_time_updater); this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._current_client = undefined; this.previous_frame_content = undefined; } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_client_info").renderTag(); this._html_tag.find(".button-close").on('click', () => { if (this.previous_frame_content === chat.FrameContent.CLIENT_INFO) this.previous_frame_content = chat.FrameContent.NONE; this.handle.set_content(this.previous_frame_content); }); this._html_tag.find(".button-more").on('click', () => { if (!this._current_client) return; Modals.openClientInfo(this._current_client); }); this._html_tag.find('.container-avatar-edit').on('click', () => this.handle.handle.update_avatar()); } current_client() { return this._current_client; } set_current_client(client, enforce) { if (client) client.updateClientVariables(); /* just to ensure */ if (client === this._current_client && (typeof (enforce) === "undefined" || !enforce)) return; this._current_client = client; /* updating the header */ { const client_name = this._html_tag.find(".client-name"); client_name.children().remove(); htmltags.generate_client_object({ add_braces: false, client_name: client ? client.clientNickName() : "undefined", client_unique_id: client ? client.clientUid() : "", client_id: client ? client.clientId() : 0 }).appendTo(client_name); const client_description = this._html_tag.find(".client-description"); client_description.text(client ? client.properties.client_description : "").toggle(!!client.properties.client_description); const is_local_entry = client instanceof LocalClientEntry; const container_avatar = this._html_tag.find(".container-avatar"); container_avatar.find(".avatar").remove(); if (client) { const avatar = this.handle.handle.fileManager.avatars.generate_chat_tag({ id: client.clientId() }, client.clientUid()); if (!is_local_entry) { avatar.css("cursor", "pointer").on('click', event => { image_preview.preview_image_tag(this.handle.handle.fileManager.avatars.generate_chat_tag({ id: client.clientId() }, client.clientUid())); }); } avatar.appendTo(container_avatar); } else this.handle.handle.fileManager.avatars.generate_chat_tag(undefined, undefined).appendTo(container_avatar); container_avatar.toggleClass("editable", is_local_entry); } /* updating the info fields */ { const online_time = this._html_tag.find(".client-online-time"); online_time.text(chat.format.time.format_online_time(client ? client.calculateOnlineTime() : 0)); if (this._online_time_updater) { clearInterval(this._online_time_updater); this._online_time_updater = 0; } if (client) { this._online_time_updater = setInterval(() => { const client = this._current_client; if (!client) { clearInterval(this._online_time_updater); this._online_time_updater = undefined; return; } if (client.currentChannel()) /* If he has no channel then he might be disconnected */ online_time.text(chat.format.time.format_online_time(client.calculateOnlineTime())); else { online_time.text(online_time.text() + (_translations.Dp1iLhtX || (_translations.Dp1iLhtX = tr(" (left view)")))); clearInterval(this._online_time_updater); } }, 1000); } const country = this._html_tag.find(".client-country"); country.children().detach(); const country_code = (client ? client.properties.client_country : undefined) || "xx"; $.spawn("div").addClass("country flag-" + country_code.toLowerCase()).appendTo(country); $.spawn("a").text(i18n.country_name(country_code.toUpperCase())).appendTo(country); const version = this._html_tag.find(".client-version"); version.children().detach(); if (client) { let platform = client.properties.client_platform; if (platform.indexOf("Win32") != 0 && (client.properties.client_version.indexOf("Win64") != -1 || client.properties.client_version.indexOf("WOW64") != -1)) platform = platform.replace("Win32", "Win64"); $.spawn("a").attr("title", client.properties.client_version).text(client.properties.client_version.split(" ")[0] + " on " + platform).appendTo(version); } const volume = this._html_tag.find(".client-local-volume"); volume.text((client && client.get_audio_handle() ? (client.get_audio_handle().get_volume() * 100) : -1).toFixed(0) + "%"); } /* teaspeak forum */ { const container_forum = this._html_tag.find(".container-teaforo"); if (client && client.properties.client_teaforo_id) { container_forum.show(); const container_data = container_forum.find(".client-teaforo-account"); container_data.children().remove(); let text = client.properties.client_teaforo_name; if ((client.properties.client_teaforo_flags & 0x01) > 0) text += " (" + (_translations.D09E5x0q || (_translations.D09E5x0q = tr("Banned"))) + ")"; if ((client.properties.client_teaforo_flags & 0x02) > 0) text += " (" + (_translations.EsaodnJz || (_translations.EsaodnJz = tr("Stuff"))) + ")"; if ((client.properties.client_teaforo_flags & 0x04) > 0) text += " (" + (_translations.AtQnQgBE || (_translations.AtQnQgBE = tr("Premium"))) + ")"; $.spawn("a") .attr("href", "https://forum.teaspeak.de/index.php?members/" + client.properties.client_teaforo_id) .attr("target", "_blank") .text(text) .appendTo(container_data); } else { container_forum.hide(); } } /* update the client status */ { //TODO Implement client status! const container_status = this._html_tag.find(".container-client-status"); const container_status_entries = container_status.find(".client-status"); container_status_entries.children().detach(); if (client) { if (client.properties.client_away) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-away"), $.spawn("a").text(_translations.vwdjmn_F || (_translations.vwdjmn_F = tr("Away"))), client.properties.client_away_message ? $.spawn("a").addClass("away-message").text("(" + client.properties.client_away_message + ")") : undefined)); } if (client.is_muted()) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-input_muted_local"), $.spawn("a").text(_translations.l65uhuvX || (_translations.l65uhuvX = tr("Client local muted"))))); } if (!client.properties.client_output_hardware) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-hardware_output_muted"), $.spawn("a").text(_translations.Qdw6LANe || (_translations.Qdw6LANe = tr("Speakers/Headphones disabled"))))); } if (!client.properties.client_input_hardware) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-hardware_input_muted"), $.spawn("a").text(_translations.iSy8yGYs || (_translations.iSy8yGYs = tr("Microphone disabled"))))); } if (client.properties.client_output_muted) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-output_muted"), $.spawn("a").text(_translations.M0LdnKoE || (_translations.M0LdnKoE = tr("Speakers/Headphones Muted"))))); } if (client.properties.client_input_muted) { container_status_entries.append($.spawn("div").addClass("status-entry").append($.spawn("div").addClass("icon_em client-input_muted"), $.spawn("a").text(_translations.Urfvx1ZJ || (_translations.Urfvx1ZJ = tr("Microphone Muted"))))); } } container_status.toggle(container_status_entries.children().length > 0); } /* update client server groups */ { const container_groups = this._html_tag.find(".client-group-server"); container_groups.children().detach(); if (client) { const invalid_groups = []; const groups = client.assignedServerGroupIds().map(group_id => { const result = this.handle.handle.groups.serverGroup(group_id); if (!result) invalid_groups.push(group_id); return result; }).filter(e => !!e).sort(GroupManager.sorter()); for (const invalid_id of invalid_groups) { container_groups.append($.spawn("a").text("{" + (_translations.KNP4yV0s || (_translations.KNP4yV0s = tr("server group "))) + invalid_groups + "}").attr("title", (_translations.xrYdPJ1G || (_translations.xrYdPJ1G = tr("Missing server group id!"))) + " (" + invalid_groups + ")")); } for (let group of groups) { container_groups.append($.spawn("div").addClass("group-container") .append(this.handle.handle.fileManager.icons.generateTag(group.properties.iconid)).append($.spawn("a").text(group.name).attr("title", (_translations.rVlVp788 || (_translations.rVlVp788 = tr("Group id: "))) + group.id))); } } } /* update client channel group */ { const container_group = this._html_tag.find(".client-group-channel"); container_group.children().detach(); if (client) { const group_id = client.assignedChannelGroup(); let group = this.handle.handle.groups.channelGroup(group_id); if (group) { container_group.append($.spawn("div").addClass("group-container") .append(this.handle.handle.fileManager.icons.generateTag(group.properties.iconid)).append($.spawn("a").text(group.name).attr("title", (_translations.NKtvfR4K || (_translations.NKtvfR4K = tr("Group id: "))) + group_id))); } else { container_group.append($.spawn("a").text(_translations.pgVV72hD || (_translations.pgVV72hD = tr("Invalid channel group!"))).attr("title", (_translations.OyhbrRno || (_translations.OyhbrRno = tr("Missing channel group id!"))) + " (" + group_id + ")")); } } } } } chat.ClientInfo = ClientInfo; })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c8d174f4cbf19f8187e08cd0cc4bb35c191fd340838f5553eaec62915ed394f9"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c8d174f4cbf19f8187e08cd0cc4bb35c191fd340838f5553eaec62915ed394f9"] = "c8d174f4cbf19f8187e08cd0cc4bb35c191fd340838f5553eaec62915ed394f9"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "hh__Ub6e", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (105,72)" }, { name: "TQ1xVaxQ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (106,81)" }, { name: "gusrL0gQ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (222,49)" }, { name: "Rghf6HNS", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (248,49)" }, { name: "lfcMsCaE", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (433,49)" }, { name: "mwRMbLH_", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (436,38)" }, { name: "keOq3AeP", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (436,98)" }, { name: "MQA1F_tv", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (438,47)" }, { name: "RbUV5nYv", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/conversations.ts (608,52)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var chat; (function (chat) { let channel; (function (channel) { class Conversation { constructor(handle, channel_id) { this._container_no_permissions_shown = false; this._container_is_private_shown = false; this._container_no_support_shown = false; this._view_max_messages = 40; /* reset to 40 again as soon we tab out :) */ this._view_entries = []; this._last_messages = []; this._last_messages_timestamp = 0; this.handle = handle; this.channel_id = channel_id; this._build_html_tag(); } html_tag() { return this._html_tag; } destroy() { this._first_unread_message_pointer.html_element.detach(); this._first_unread_message_pointer = undefined; this._view_older_messages.html_element.detach(); this._view_older_messages = undefined; for (const view_entry of this._view_entries) { view_entry.html_element.detach(); clearTimeout(view_entry.update_timer); } this._view_entries = []; } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_channel_messages").renderTag(); this._container_new_message = this._html_tag.find(".new-message"); this._container_no_permissions = this._html_tag.find(".no-permissions").hide(); this._container_is_private = this._html_tag.find(".private-conversation").hide(); this._container_no_support = this._html_tag.find(".not-supported").hide(); this._container_messages = this._html_tag.find(".container-messages"); this._container_messages.on('scroll', event => { const exact_position = this._container_messages[0].scrollTop + this._container_messages[0].clientHeight; const current_view = exact_position + this._container_messages[0].clientHeight * .125; if (current_view > this._container_messages[0].scrollHeight) { this._scroll_position = undefined; } else { this._scroll_position = this._container_messages[0].scrollTop; } const will_visible = !!this._first_unread_message && this._first_unread_message_pointer.html_element[0].offsetTop > exact_position; const is_visible = this._container_new_message[0].classList.contains("shown"); if (!is_visible && will_visible) this._container_new_message[0].classList.add("shown"); if (is_visible && !will_visible) this._container_new_message[0].classList.remove("shown"); //This causes a Layout recalc (Forced reflow) //this._container_new_message.toggleClass("shown",!!this._first_unread_message && this._first_unread_message_pointer.html_element[0].offsetTop > exact_position); }); this._view_older_messages = this._generate_view_spacer(_translations.hh__Ub6e || (_translations.hh__Ub6e = tr("Load older messages")), "old"); this._first_unread_message_pointer = this._generate_view_spacer(_translations.TQ1xVaxQ || (_translations.TQ1xVaxQ = tr("Unread messages")), "new"); this._view_older_messages.html_element.appendTo(this._container_messages).on('click', event => { this.fetch_older_messages(); }); this._container_new_message.on('click', event => { if (!this._first_unread_message) return; this._scroll_position = this._first_unread_message_pointer.html_element[0].offsetTop; this.fix_scroll(true); }); this._container_messages.on('click', event => { if (this._container_new_message.hasClass('shown')) return; /* we have clicked, but no chance to see the unread message pointer */ this._mark_read(); }); this.set_flag_private(false); } is_unread() { return !!this._first_unread_message; } mark_read() { this._mark_read(); } _mark_read() { if (this._first_unread_message) { this._first_unread_message = undefined; const ctree = this.handle.handle.handle.channelTree; if (ctree && ctree.tag_tree()) ctree.tag_tree().find(".marker-text-unread[conversation='" + this.channel_id + "']").addClass("hidden"); } this._first_unread_message_pointer.html_element.detach(); } _generate_view_message(data) { const response = data; if (response.html_element) return response; const timestamp = new Date(data.timestamp); let time = chat.format.date.format_chat_time(timestamp); response.html_element = $("#tmpl_frame_chat_channel_message").renderTag({ timestamp: time.result, client_name: htmltags.generate_client_object({ add_braces: false, client_name: data.sender_name, client_unique_id: data.sender_unique_id, client_id: 0 }), message: MessageHelper.bbcode_chat(data.message), avatar: this.handle.handle.handle.fileManager.avatars.generate_chat_tag({ database_id: data.sender_database_id }, data.sender_unique_id) }); response.html_element.find(".button-delete").on('click', () => this.delete_message(data)); if (time.next_update > 0) { const _updater = () => { time = chat.format.date.format_chat_time(timestamp); response.html_element.find(".info .timestamp").text(time.result); if (time.next_update > 0) response.update_timer = setTimeout(_updater, time.next_update); else response.update_timer = 0; }; response.update_timer = setTimeout(_updater, time.next_update); } else { response.update_timer = 0; } return response; } _generate_view_spacer(message, type) { const tag = $("#tmpl_frame_chat_private_spacer").renderTag({ message: message }).addClass("type-" + type); return { html_element: tag, update_timer: 0 }; } last_messages_timestamp() { return this._last_messages_timestamp; } fetch_last_messages() { const fetch_count = this._view_max_messages - this._last_messages.length; const fetch_timestamp_end = this._last_messages_timestamp + 1; /* we want newer messages then the last message we have */ //conversationhistory cid=1 [cpw=xxx] [timestamp_begin] [timestamp_end (0 := no end)] [message_count (default 25| max 100)] [-merge] this.handle.handle.handle.serverConnection.send_command("conversationhistory", { cid: this.channel_id, timestamp_end: fetch_timestamp_end, message_count: fetch_count }, { flagset: ["merge"], process_result: false }).catch(error => { this._view_older_messages.html_element.toggleClass('shown', false); if (error instanceof CommandResult) { if (error.id == ErrorID.CONVERSATION_MORE_DATA) { if (typeof (this._has_older_messages) === "undefined") this._has_older_messages = true; this._view_older_messages.html_element.toggleClass('shown', true); return; } else if (error.id == ErrorID.PERMISSION_ERROR) { this._container_no_permissions.show(); this._container_no_permissions_shown = true; } else if (error.id == ErrorID.CONVERSATION_IS_PRIVATE) { this.set_flag_private(true); } /* else if(error.id == ErrorID.NOT_IMPLEMENTED || error.id == ErrorID.COMMAND_NOT_FOUND) { this._container_no_support.show(); this._container_no_support_shown = true; } */ } //TODO log and handle! log.error(LogCategory.CHAT, _translations.gusrL0gQ || (_translations.gusrL0gQ = tr("Failed to fetch conversation history. %o")), error); }).then(() => { this.fix_scroll(true); this.handle.update_chat_box(); }); } fetch_older_messages() { this._view_older_messages.html_element.toggleClass('shown', false); const entry = this._view_entries.slice().reverse().find(e => 'timestamp' in e); //conversationhistory cid=1 [cpw=xxx] [timestamp_begin] [timestamp_end (0 := no end)] [message_count (default 25| max 100)] [-merge] this.handle.handle.handle.serverConnection.send_command("conversationhistory", { cid: this.channel_id, timestamp_begin: entry.timestamp - 1, message_count: this._view_max_messages }, { flagset: ["merge"] }).catch(error => { this._view_older_messages.html_element.toggleClass('shown', false); if (error instanceof CommandResult) { if (error.id == ErrorID.CONVERSATION_MORE_DATA) { this._view_older_messages.html_element.toggleClass('shown', true); this.handle.update_chat_box(); return; } } //TODO log and handle! log.error(LogCategory.CHAT, _translations.Rghf6HNS || (_translations.Rghf6HNS = tr("Failed to fetch conversation history. %o")), error); }).then(() => { this.fix_scroll(true); }); } register_new_message(message, update_view) { /* lets insert the message at the right index */ let _new_message = false; { let spliced = false; for (let index = 0; index < this._last_messages.length; index++) { if (this._last_messages[index].timestamp < message.timestamp) { this._last_messages.splice(index, 0, message); spliced = true; _new_message = index == 0; /* only set flag if this has been inserted at the front */ break; } else if (this._last_messages[index].timestamp == message.timestamp && this._last_messages[index].sender_database_id == message.sender_database_id) { return; /* we already have that message */ } } if (!spliced && this._last_messages.length < this._view_max_messages) { this._last_messages.push(message); } this._last_messages_timestamp = this._last_messages[0].timestamp; while (this._last_messages.length > this._view_max_messages) { if (this._last_messages[this._last_messages.length - 1] == this._first_unread_message) break; this._last_messages.pop(); } } /* message is within view */ { const entry = this._generate_view_message(message); let previous; for (let index = 0; index < this._view_entries.length; index++) { const current_entry = this._view_entries[index]; if (!('timestamp' in current_entry)) continue; if (current_entry.timestamp < message.timestamp) { this._view_entries.splice(index, 0, entry); previous = current_entry; break; } } if (!previous) this._view_entries.push(entry); if (previous) entry.html_element.insertAfter(previous.html_element); else entry.html_element.insertAfter(this._view_older_messages.html_element); /* last element is already the current element */ if (_new_message && (typeof (this._scroll_position) === "number" || this.handle.current_channel() !== this.channel_id || this.handle.handle.content_type() !== chat.FrameContent.CHANNEL_CHAT)) { if (typeof (this._first_unread_message) === "undefined") this._first_unread_message = entry; this._first_unread_message_pointer.html_element.insertBefore(entry.html_element); this._container_messages.trigger('scroll'); /* updates the new message stuff */ } if (typeof (update_view) !== "boolean" || update_view) this.fix_scroll(true); } /* update chat state */ this._container_no_permissions.hide(); this._container_no_permissions_shown = false; if (update_view) this.handle.update_chat_box(); } fix_scroll(animate) { if (this._scroll_fix_timer) { this._scroll_animate = this._scroll_animate && animate; return; } this._scroll_fix_timer = setTimeout(() => { this._scroll_fix_timer = undefined; let offset; if (this._first_unread_message) { offset = this._first_unread_message.html_element[0].offsetTop; } else if (typeof (this._scroll_position) !== "undefined") { offset = this._scroll_position; } else { offset = this._container_messages[0].scrollHeight; } if (this._scroll_animate) { this._container_messages.stop(true).animate({ scrollTop: offset }, 'slow'); } else { this._container_messages.stop(true).scrollTop(offset); } }, 5); } fix_view_size() { this._view_older_messages.html_element.toggleClass('shown', !!this._has_older_messages); let count = 0; for (let index = 0; index < this._view_entries.length; index++) { if ('timestamp' in this._view_entries[index]) count++; if (count > this._view_max_messages) { this._view_entries.splice(index, this._view_entries.length - index).forEach(e => { clearTimeout(e.update_timer); e.html_element.remove(); }); this._has_older_messages = true; this._view_older_messages.html_element.toggleClass('shown', true); break; } } } chat_available() { return !this._container_no_permissions_shown && !this._container_is_private_shown && !this._container_no_support_shown; } text_send_failed(error) { log.warn(LogCategory.CHAT, "Failed to send text message! (%o)", error); //TODO: Log if message send failed? if (error instanceof CommandResult) { if (error.id == ErrorID.PERMISSION_ERROR) { //TODO: Split up between channel_text_message_send permission and no view permission if (error.json["failed_permid"] == 0) { this._container_no_permissions_shown = true; this._container_no_permissions.show(); this.handle.update_chat_box(); } } } } set_flag_private(flag) { if (this._flag_private === flag) return; this._flag_private = flag; this.update_private_state(); if (!flag) this.fetch_last_messages(); } update_private_state() { if (!this._flag_private) { this._container_is_private.hide(); this._container_is_private_shown = false; } else { const client = this.handle.handle.handle.getClient(); if (client && client.currentChannel() && client.currentChannel().channelId === this.channel_id) { this._container_is_private_shown = false; this._container_is_private.hide(); } else { this._container_is_private.show(); this._container_is_private_shown = true; } } } delete_message(message) { //TODO A lot of checks! //conversationmessagedelete cid=2 timestamp_begin= timestamp_end= cldbid= limit=1 this.handle.handle.handle.serverConnection.send_command('conversationmessagedelete', { cid: this.channel_id, cldbid: message.sender_database_id, timestamp_begin: message.timestamp - 1, timestamp_end: message.timestamp + 1, limit: 1 }).then(() => { return; /* in general it gets deleted via notify */ }).catch(error => { log.error(LogCategory.CHAT, _translations.lfcMsCaE || (_translations.lfcMsCaE = tr("Failed to delete conversation message for conversation %o: %o")), this.channel_id, error); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.mwRMbLH_ || (_translations.mwRMbLH_ = tr("Failed to delete message")), MessageHelper.formatMessage(_translations.keOq3AeP || (_translations.keOq3AeP = tr("Failed to delete conversation message{:br:}Error: {}")), error)).open(); }); log.debug(LogCategory.CLIENT, _translations.MQA1F_tv || (_translations.MQA1F_tv = tr("Deleting text message %o")), message); } delete_messages(begin, end, sender, limit) { let count = 0; for (const message of this._view_entries.slice()) { if (!('sender_database_id' in message)) continue; const cmsg = message; if (end != 0 && cmsg.timestamp > end) continue; if (begin != 0 && cmsg.timestamp < begin) break; if (cmsg.sender_database_id !== sender) continue; this._delete_message(message); if (--count >= limit) return; } //TODO remove in cache? (_last_messages) } _delete_message(message) { if ('html_element' in message) { const cmessage = message; cmessage.html_element.remove(); clearTimeout(cmessage.update_timer); this._view_entries.remove(message); } this._last_messages.remove(message); } } channel.Conversation = Conversation; class ConversationManager { constructor(handle) { this._conversations = []; this._needed_listener = () => this.update_chat_box(); this.handle = handle; this._chat_box = new chat.ChatBox(); this._build_html_tag(); this._chat_box.callback_text = text => { if (!this._current_conversation) return; const conv = this._current_conversation; this.handle.handle.serverConnection.send_command("sendtextmessage", { targetmode: conv.channel_id == 0 ? 3 : 2, cid: conv.channel_id, msg: text }, { process_result: false }).catch(error => { conv.text_send_failed(error); }); }; this.update_chat_box(); } initialize_needed_listener() { this.handle.handle.permissions.register_needed_permission(PermissionType.B_CLIENT_CHANNEL_TEXTMESSAGE_SEND, this._needed_listener); this.handle.handle.permissions.register_needed_permission(PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND, this._needed_listener); } html_tag() { return this._html_tag; } destroy() { if (this.handle.handle.permissions) this.handle.handle.permissions.unregister_needed_permission(PermissionType.B_CLIENT_CHANNEL_TEXTMESSAGE_SEND, this._needed_listener); this.handle.handle.permissions.unregister_needed_permission(PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND, this._needed_listener); this._needed_listener = undefined; this._chat_box && this._chat_box.destroy(); this._chat_box = undefined; this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._container_conversation = undefined; for (const conversation of this._conversations) conversation.destroy(); this._conversations = []; this._current_conversation = undefined; } update_chat_box() { let flag = true; flag = flag && !!this._current_conversation; /* test if we have a conversation */ flag = flag && !!this.handle.handle.permissions; /* test if we got permissions to test with */ flag = flag && this.handle.handle.permissions.neededPermission(this._current_conversation.channel_id == 0 ? PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND : PermissionType.B_CLIENT_CHANNEL_TEXTMESSAGE_SEND).granted(1); flag = flag && this._current_conversation.chat_available(); this._chat_box.set_enabled(flag); } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_channel").renderTag({ chatbox: this._chat_box.html_tag() }); this._container_conversation = this._html_tag.find(".container-chat"); this._chat_box.html_tag().on('focus', event => { if (this._current_conversation) this._current_conversation.mark_read(); }); this.update_input_format_helper(); } set_current_channel(channel_id, update_info_frame) { if (this._current_conversation && this._current_conversation.channel_id === channel_id) return; let conversation = this.conversation(channel_id); this._current_conversation = conversation; if (this._current_conversation) { this._container_conversation.children().detach(); this._container_conversation.append(conversation.html_tag()); this._current_conversation.fix_view_size(); this._current_conversation.fix_scroll(false); this.update_chat_box(); } if (typeof (update_info_frame) === "undefined" || update_info_frame) this.handle.info_frame().update_channel_text(); } current_channel() { return this._current_conversation ? this._current_conversation.channel_id : 0; } /* Used by notifychanneldeleted */ delete_conversation(channel_id) { const entry = this._conversations.find(e => e.channel_id === channel_id); if (!entry) return; this._conversations.remove(entry); entry.html_tag().detach(); entry.destroy(); } reset() { while (this._conversations.length > 0) this.delete_conversation(this._conversations[0].channel_id); } conversation(channel_id, create) { let conversation = this._conversations.find(e => e.channel_id === channel_id); if (!conversation && channel_id >= 0 && (typeof (create) === "undefined" || create)) { conversation = new Conversation(this, channel_id); this._conversations.push(conversation); conversation.fetch_last_messages(); } return conversation; } on_show() { if (this._current_conversation) this._current_conversation.fix_scroll(false); } update_input_format_helper() { const tag = this._html_tag.find(".container-format-helper"); if (settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN)) { tag.removeClass("hidden").text(_translations.RbUV5nYv || (_translations.RbUV5nYv = tr("*italic*, **bold**, ~~strikethrough~~, `code`, and more..."))); } else { tag.addClass("hidden"); } } } channel.ConversationManager = ConversationManager; })(channel = chat.channel || (chat.channel = {})); })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["878e3b2427be39ef52c1cc697e3e57ad5bc79eb84ce8ccf6202267edc530f2d7"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["878e3b2427be39ef52c1cc697e3e57ad5bc79eb84ce8ccf6202267edc530f2d7"] = "878e3b2427be39ef52c1cc697e3e57ad5bc79eb84ce8ccf6202267edc530f2d7"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "E8EoU11A", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (269,54)" }, { name: "ZjhaCM4A", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (306,56)" }, { name: "CpuEwfbP", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (310,82)" }, { name: "P9gCZwQr", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (310,127)" }, { name: "cypDJ0_f", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (362,55)" }, { name: "jMSYQz4l", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (373,55)" }, { name: "dD2jftte", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (375,42)" }, { name: "XsVWXGSI", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (375,75)" }, { name: "X6UV2IrX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (392,51)" }, { name: "uGfSbNyd", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (394,38)" }, { name: "RDZR0ORC", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (394,65)" }, { name: "lFZTPJsX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (401,34)" }, { name: "cjVItg91", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (401,56)" }, { name: "NWuLJecu", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (418,55)" }, { name: "zkm5Y7oM", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (421,42)" }, { name: "iM96OH3b", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (421,71)" }, { name: "QxjOjqK0", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (438,51)" }, { name: "JcVfEfgT", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (441,38)" }, { name: "iZ6FfzUr", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (441,67)" }, { name: "gZJMtY87", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (452,50)" }, { name: "qGMVH8CP", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (517,54)" }, { name: "K933Nc0J", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (541,31)" }, { name: "tSljglBN", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (541,93)" }, { name: "h1azsSHK", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (542,57)" }, { name: "YnsxXHDT", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (542,111)" }, { name: "POFVPD93", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (635,59)" }, { name: "TLoVNGxd", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (638,46)" }, { name: "ZsiAh6Et", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (638,76)" }, { name: "hjLbCBgy", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (729,46)" }, { name: "HCGbFx4a", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (745,51)" }, { name: "vjourOhk", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (762,50)" }, { name: "HDVNAONI", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (768,50)" }, { name: "TNiqTN3i", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/music_info.ts (794,23)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var chat; (function (chat) { var PlayerState = connection.voice.PlayerState; class MusicInfo { constructor(handle) { this.update_song_info = 0; /* timestamp when we force update the info */ this.time_select = { active: false, current_select_time: 0, max_time: 0, current_player_time: 0 }; this.song_reorder = { active: false, song_id: 0, previous_entry: 0, html: undefined, indicator: $.spawn("div").addClass("reorder-indicator") }; this._playlist_subscribed = false; this.events = new events.Registry(); this.handle = handle; this.events.enable_debug("music-info"); this.initialize_listener(); this._build_html_tag(); this.set_current_bot(undefined, true); } html_tag() { return this._html_tag; } destroy() { this.set_current_bot(undefined); this.events.destory(); this._html_tag && this._html_tag.remove(); this._html_tag = undefined; this._current_bot = undefined; this.previous_frame_content = undefined; } format_time(value) { if (value == 0) return "--:--:--"; value /= 1000; let hours = 0, minutes = 0; while (value >= 60 * 60) { hours++; value -= 60 * 60; } while (value >= 60) { minutes++; value -= 60; } return ("0" + hours).substr(-2) + ":" + ("0" + minutes).substr(-2) + ":" + ("0" + value.toFixed(0)).substr(-2); } ; _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_music_info").renderTag(); this._container_playlist = this._html_tag.find(".container-playlist"); this._html_tag.find(".button-close").on('click', () => { if (this.previous_frame_content === chat.FrameContent.CLIENT_INFO) this.previous_frame_content = chat.FrameContent.NONE; this.handle.set_content(this.previous_frame_content); }); this._html_tag.find(".button-reload-playlist").on('click', () => this.events.fire("action_playlist_reload")); this._html_tag.find(".button-song-add").on('click', () => this.events.fire("action_song_add")); this._html_tag.find(".thumbnail").on('click', event => { const image = this._html_tag.find(".thumbnail img"); const url = image.attr("x-thumbnail-url"); if (!url) return; image_preview.preview_image(decodeURIComponent(url), decodeURIComponent(url)); }); { const button_play = this._html_tag.find(".control-buttons .button-play"); const button_pause = this._html_tag.find(".control-buttons .button-pause"); button_play.on('click', () => this.events.fire("action_play")); button_pause.on('click', () => this.events.fire("action_pause")); this.events.on(["bot_change", "bot_property_update"], event => { if (event.type === "bot_property_update" && event.as().properties.indexOf("player_state") == -1) return; button_play.toggleClass("hidden", this._current_bot === undefined || this._current_bot.properties.player_state < PlayerState.STOPPING); }); this.events.on(["bot_change", "bot_property_update"], event => { if (event.type === "bot_property_update" && event.as().properties.indexOf("player_state") == -1) return; button_pause.toggleClass("hidden", this._current_bot !== undefined && this._current_bot.properties.player_state >= PlayerState.STOPPING); }); this._html_tag.find(".control-buttons .button-rewind").on('click', () => this.events.fire("action_rewind")); this._html_tag.find(".control-buttons .button-forward").on('click', () => this.events.fire("action_forward")); } /* timeline updaters */ { const container = this._html_tag.find(".container-timeline"); const timeline = container.find(".timeline"); const indicator_playtime = container.find(".indicator-playtime"); const indicator_buffered = container.find(".indicator-buffered"); const thumb = container.find(".thumb"); const timestamp_current = container.find(".timestamps .current"); const timestamp_max = container.find(".timestamps .max"); thumb.on('mousedown', event => event.button === 0 && this.events.fire("playtime_move_begin")); this.events.on(["bot_change", "player_song_change", "player_time_update", "playtime_move_end"], event => { if (!this._current_bot) { this.time_select.max_time = 0; indicator_buffered.each((_, e) => { e.style.width = "0%"; }); indicator_playtime.each((_, e) => { e.style.width = "0%"; }); thumb.each((_, e) => { e.style.marginLeft = "0%"; }); timestamp_current.text("--:--:--"); timestamp_max.text("--:--:--"); return; } if (event.type === "playtime_move_end" && !event.as().canceled) return; const update_info = Date.now() > this.update_song_info; this._current_bot.requestPlayerInfo(update_info ? 1000 : 60 * 1000).then(data => { if (update_info) this.display_song_info(data); let played, buffered; if (event.type !== "player_time_update") { played = data.player_replay_index; buffered = data.player_buffered_index; } else { played = event.as().player_replay_index; buffered = event.as().player_buffered_index; } this.time_select.current_player_time = played; this.time_select.max_time = data.player_max_index; timestamp_max.text(data.player_max_index ? this.format_time(data.player_max_index) : "--:--:--"); if (this.time_select.active) return; let wplayed, wbuffered; if (data.player_max_index) { wplayed = (played * 100 / data.player_max_index).toFixed(2) + "%"; wbuffered = (buffered * 100 / data.player_max_index).toFixed(2) + "%"; timestamp_current.text(this.format_time(played)); } else { wplayed = "100%"; wbuffered = "100%"; timestamp_current.text(this.format_time(played)); } indicator_buffered.each((_, e) => { e.style.width = wbuffered; }); indicator_playtime.each((_, e) => { e.style.width = wplayed; }); thumb.each((_, e) => { e.style.marginLeft = wplayed; }); }); }); const move_callback = (event) => { const x_min = timeline.offset().left; const x_max = x_min + timeline.width(); let current = event.pageX; if (current < x_min) current = x_min; else if (current > x_max) current = x_max; const percent = (current - x_min) / (x_max - x_min); this.time_select.current_select_time = percent * this.time_select.max_time; timestamp_current.text(this.format_time(this.time_select.current_select_time)); const w = (percent * 100).toFixed(2) + "%"; indicator_playtime.each((_, e) => { e.style.width = w; }); thumb.each((_, e) => { e.style.marginLeft = w; }); }; const up_callback = (event) => { if (event.type === "mouseup") if (event.button !== 0) return; this.events.fire("playtime_move_end", { canceled: event.type !== "mouseup", target_time: this.time_select.current_select_time }); }; this.events.on("playtime_move_begin", event => { if (this.time_select.max_time <= 0) return; this.time_select.active = true; indicator_buffered.each((_, e) => { e.style.width = "0"; }); document.addEventListener("mousemove", move_callback); document.addEventListener("mouseleave", up_callback); document.addEventListener("blur", up_callback); document.addEventListener("mouseup", up_callback); document.body.style.userSelect = "none"; }); this.events.on(["bot_change", "player_song_change", "playtime_move_end"], event => { document.removeEventListener("mousemove", move_callback); document.removeEventListener("mouseleave", up_callback); document.removeEventListener("blur", up_callback); document.removeEventListener("mouseup", up_callback); document.body.style.userSelect = undefined; this.time_select.active = false; if (event.type === "playtime_move_end") { const data = event.as(); if (data.canceled) return; const offset = data.target_time - this.time_select.current_player_time; this.events.fire(offset > 0 ? "action_forward_ms" : "action_rewind_ms", { units: Math.abs(offset) }); } }); } /* song info handlers */ this.events.on(["bot_change", "player_song_change"], event => { let song; /* update the player info so we dont get old data */ if (this._current_bot) { this.update_song_info = 0; this._current_bot.requestPlayerInfo(1000).then(data => { this.display_song_info(data); }).catch(error => { log.warn(LogCategory.CLIENT, _translations.E8EoU11A || (_translations.E8EoU11A = tr("Failed to update current song for side bar: %o")), error); }); } if (event.type === "bot_change") { song = undefined; } else { song = event.as().song; } this.display_song_info(song); }); } display_song_info(song) { if (song) { if (!song.song_loaded) { console.log("Awaiting a loaded song info."); this.update_song_info = 0; } else { console.log("Song info loaded."); this.update_song_info = Date.now() + 60 * 1000; } } if (!song) song = new SongInfo(); const container_thumbnail = this._html_tag.find(".player .container-thumbnail"); const container_info = this._html_tag.find(".player .container-song-info"); container_thumbnail.find("img") .attr("src", song.song_thumbnail || "img/music/no-thumbnail.png") .attr("x-thumbnail-url", encodeURIComponent(song.song_thumbnail)) .css("cursor", song.song_thumbnail ? "pointer" : null); if (song.song_id) container_info.find(".song-name").text(song.song_title || song.song_url).attr("title", song.song_title || song.song_url); else container_info.find(".song-name").text(_translations.ZjhaCM4A || (_translations.ZjhaCM4A = tr("No song selected"))); if (song.song_description) { container_info.find(".song-description").removeClass("hidden").text(song.song_description).attr("title", song.song_description); } else { container_info.find(".song-description").addClass("hidden").text(_translations.CpuEwfbP || (_translations.CpuEwfbP = tr("Song has no description"))).attr("title", _translations.P9gCZwQr || (_translations.P9gCZwQr = tr("Song has no description"))); } } initialize_listener() { //Must come at first! this.events.on("player_song_change", event => { if (!this._current_bot) return; this._current_bot.requestPlayerInfo(0); /* enforce an info refresh */ }); /* bot property listener */ const callback_property = event => this.events.fire("bot_property_update", { properties: event.properties }); const callback_time_update = event => this.events.fire("player_time_update", event); const callback_song_change = event => this.events.fire("player_song_change", event); this.events.on("bot_change", event => { if (event.old) { event.old.events.off(callback_property); event.old.events.off(callback_time_update); event.old.events.off(callback_song_change); event.old.events.disconnect_all(this.events); } if (event.new) { event.new.events.on("property_update", callback_property); event.new.events.on("music_status_update", callback_time_update); event.new.events.on("music_song_change", callback_song_change); event.new.events.connect("playlist_song_add", this.events); event.new.events.connect("playlist_song_remove", this.events); event.new.events.connect("playlist_song_reorder", this.events); event.new.events.connect("playlist_song_loaded", this.events); } }); /* basic player actions */ { const action_map = { "action_play": 1, "action_pause": 2, "action_forward": 3, "action_rewind": 4, "action_forward_ms": 5, "action_rewind_ms": 6 }; this.events.on(Object.keys(action_map), event => { if (!this._current_bot) return; const action_id = action_map[event.type]; if (typeof action_id === "undefined") { log.warn(LogCategory.GENERAL, _translations.cypDJ0_f || (_translations.cypDJ0_f = tr("Invalid music bot action event detected: %s. This should not happen!")), event.type); return; } const data = { bot_id: this._current_bot.properties.client_database_id, action: action_id, units: event.units }; this.handle.handle.serverConnection.send_command("musicbotplayeraction", data).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; log.error(LogCategory.CLIENT, _translations.jMSYQz4l || (_translations.jMSYQz4l = tr("Failed to perform action %s on bot: %o")), event.type, error); //TODO: Better error dialog createErrorModal(_translations.dD2jftte || (_translations.dD2jftte = tr("Failed to perform action.")), _translations.XsVWXGSI || (_translations.XsVWXGSI = tr("Failed to perform action for music bot."))).open(); }); }); } this.events.on("action_song_set", event => { if (!this._current_bot) return; const connection = this.handle.handle.serverConnection; if (!connection || !connection.connected()) return; connection.send_command("playlistsongsetcurrent", { playlist_id: this._current_bot.properties.client_playlist_id, song_id: event.song_id }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; log.error(LogCategory.CLIENT, _translations.X6UV2IrX || (_translations.X6UV2IrX = tr("Failed to set current song on bot: %o")), event.type, error); //TODO: Better error dialog createErrorModal(_translations.uGfSbNyd || (_translations.uGfSbNyd = tr("Failed to set song.")), _translations.RDZR0ORC || (_translations.RDZR0ORC = tr("Failed to set current replaying song."))).open(); }); }); this.events.on("action_song_add", () => { if (!this._current_bot) return; createInputModal(_translations.lFZTPJsX || (_translations.lFZTPJsX = tr("Enter song URL")), _translations.cjVItg91 || (_translations.cjVItg91 = tr("Please enter the target song URL")), text => { try { new URL(text); return true; } catch (error) { return false; } }, result => { if (!result || !this._current_bot) return; const connection = this.handle.handle.serverConnection; connection.send_command("playlistsongadd", { playlist_id: this._current_bot.properties.client_playlist_id, url: result }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; log.error(LogCategory.CLIENT, _translations.NWuLJecu || (_translations.NWuLJecu = tr("Failed to add song to bot playlist: %o")), error); //TODO: Better error description createErrorModal(_translations.zkm5Y7oM || (_translations.zkm5Y7oM = tr("Failed to insert song")), _translations.iM96OH3b || (_translations.iM96OH3b = tr("Failed to append song to the playlist."))).open(); }); }).open(); }); this.events.on("action_song_delete", event => { if (!this._current_bot) return; const connection = this.handle.handle.serverConnection; if (!connection || !connection.connected()) return; connection.send_command("playlistsongremove", { playlist_id: this._current_bot.properties.client_playlist_id, song_id: event.song_id }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; log.error(LogCategory.CLIENT, _translations.QxjOjqK0 || (_translations.QxjOjqK0 = tr("Failed to delete song from bot playlist: %o")), error); //TODO: Better error description createErrorModal(_translations.JcVfEfgT || (_translations.JcVfEfgT = tr("Failed to delete song")), _translations.iZ6FfzUr || (_translations.iZ6FfzUr = tr("Failed to remove song from the playlist."))).open(); }); }); /* bot subscription */ this.events.on("bot_change", () => { const connection = this.handle.handle.serverConnection; if (!connection || !connection.connected()) return; const bot_id = this._current_bot ? this._current_bot.properties.client_database_id : 0; this.handle.handle.serverConnection.send_command("musicbotsetsubscription", { bot_id: bot_id }).catch(error => { log.warn(LogCategory.CLIENT, _translations.gZJMtY87 || (_translations.gZJMtY87 = tr("Failed to subscribe to displayed bot within the side bar: %o")), error); }); }); /* playlist stuff */ this.events.on(["bot_change", "action_playlist_reload"], event => { this.playlist_subscribe(true); this.update_playlist(); }); this.events.on("playlist_song_add", event => { const animation = typeof event.insert_effect === "boolean" ? event.insert_effect : true; const html_entry = this.build_playlist_entry(event.song, animation); const playlist = this._container_playlist.find(".playlist"); const previous = playlist.find(".entry[song-id=" + event.song.song_previous_song_id + "]"); if (previous.length) html_entry.insertAfter(previous); else html_entry.appendTo(playlist); if (event.song.song_loaded) this.events.fire("playlist_song_loaded", { html_entry: html_entry, metadata: event.song.song_metadata, success: true, song_id: event.song.song_id }); if (animation) setTimeout(() => html_entry.addClass("shown"), 50); }); this.events.on("playlist_song_remove", event => { const playlist = this._container_playlist.find(".playlist"); const song = playlist.find(".entry[song-id=" + event.song_id + "]"); song.addClass("deleted"); setTimeout(() => song.remove(), 5000); /* to play some animations */ }); this.events.on("playlist_song_reorder", event => { const playlist = this._container_playlist.find(".playlist"); const entry = playlist.find(".entry[song-id=" + event.song_id + "]"); if (!entry) return; console.log(event); const previous = playlist.find(".entry[song-id=" + event.previous_song_id + "]"); if (previous.length) { entry.insertAfter(previous); } else { entry.insertBefore(playlist.find(".entry")[0]); } }); this.events.on("playlist_song_loaded", event => { const entry = event.html_entry || this._container_playlist.find(".playlist .entry[song-id=" + event.song_id + "]"); const thumbnail = entry.find(".container-thumbnail img"); const name = entry.find(".name"); const description = entry.find(".description"); const length = entry.find(".length"); if (event.success) { let meta; try { meta = JSON.parse(event.metadata); } catch (error) { log.warn(LogCategory.CLIENT, _translations.qGMVH8CP || (_translations.qGMVH8CP = tr("Failed to decode song metadata"))); meta = { description: "", title: "", metadata: {}, length: 0, url: entry.attr("song-url") }; } if (!meta.title && meta.description) { meta.title = meta.description.split("\n")[0]; meta.description = meta.description.split("\n").slice(1).join("\n"); } meta.title = meta.title || meta.url; name.text(meta.title); description.text(meta.description); length.text(this.format_time(meta.length || 0)); if (meta.thumbnail) { thumbnail.attr("src", meta.thumbnail) .attr("x-thumbnail-url", encodeURIComponent(meta.thumbnail)); } } else { name.text((_translations.K933Nc0J || (_translations.K933Nc0J = tr("failed to load "))) + entry.attr("song-url")).attr("title", (_translations.tSljglBN || (_translations.tSljglBN = tr("failed to load "))) + entry.attr("song-url")); description.text(event.error_msg || (_translations.h1azsSHK || (_translations.h1azsSHK = tr("unknown error")))).attr("title", event.error_msg || (_translations.YnsxXHDT || (_translations.YnsxXHDT = tr("unknown error")))); } }); /* song reorder */ { const move_callback = (event) => { if (!this.song_reorder.html) return; this.song_reorder.html.each((_, e) => { e.style.left = (event.pageX - this.song_reorder.mouse.x) + "px"; e.style.top = (event.pageY - this.song_reorder.mouse.y) + "px"; }); const entries = this._container_playlist.find(".playlist .entry"); let before; for (const entry of entries) { const off = $(entry).offset().top; if (off > event.pageY) { this.song_reorder.indicator.insertBefore(entry); this.song_reorder.previous_entry = before ? parseInt(before.attributes.getNamedItem("song-id").value) : 0; return; } before = entry; } this.song_reorder.indicator.insertAfter(entries.last()); this.song_reorder.previous_entry = before ? parseInt(before.attributes.getNamedItem("song-id").value) : 0; }; const up_callback = (event) => { if (event.type === "mouseup") if (event.button !== 0) return; this.events.fire("reorder_end", { canceled: event.type !== "mouseup", song_id: this.song_reorder.song_id, entry: this.song_reorder.html, previous_entry: this.song_reorder.previous_entry }); }; this.events.on("reorder_begin", event => { this.song_reorder.song_id = event.song_id; this.song_reorder.html = event.entry; const width = this.song_reorder.html.width() + "px"; this.song_reorder.html.each((_, e) => { e.style.width = width; }); this.song_reorder.active = true; this.song_reorder.html.addClass("reordering"); document.addEventListener("mousemove", move_callback); document.addEventListener("mouseleave", up_callback); document.addEventListener("blur", up_callback); document.addEventListener("mouseup", up_callback); document.body.style.userSelect = "none"; }); this.events.on(["bot_change", "playlist_song_remove", "reorder_end"], event => { if (event.type === "playlist_song_remove" && event.as().song_id !== this.song_reorder.song_id) return; document.removeEventListener("mousemove", move_callback); document.removeEventListener("mouseleave", up_callback); document.removeEventListener("blur", up_callback); document.removeEventListener("mouseup", up_callback); document.body.style.userSelect = undefined; this.song_reorder.active = false; this.song_reorder.indicator.remove(); if (this.song_reorder.html) { this.song_reorder.html.each((_, e) => { e.style.width = null; e.style.left = null; e.style.top = null; }); this.song_reorder.html.removeClass("reordering"); } if (event.type === "reorder_end") { const data = event.as(); if (data.canceled) return; const connection = this.handle.handle.serverConnection; if (!connection || !connection.connected()) return; if (!this._current_bot) return; connection.send_command("playlistsongreorder", { playlist_id: this._current_bot.properties.client_playlist_id, song_id: data.song_id, song_previous_song_id: data.previous_entry }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; log.error(LogCategory.CLIENT, _translations.POFVPD93 || (_translations.POFVPD93 = tr("Failed to add song to bot playlist: %o")), error); //TODO: Better error description createErrorModal(_translations.TLoVNGxd || (_translations.TLoVNGxd = tr("Failed to reorder song")), _translations.ZsiAh6Et || (_translations.ZsiAh6Et = tr("Failed to reorder song within the playlist."))).open(); }); console.log("Reorder to %d", data.previous_entry); } }); this.events.on(["bot_change", "player_song_change"], event => { if (!this._current_bot) { this._html_tag.find(".playlist .current-song").removeClass("current-song"); return; } this._current_bot.requestPlayerInfo(1000).then(data => { const song_id = data ? data.song_id : 0; this._html_tag.find(".playlist .current-song").removeClass("current-song"); this._html_tag.find(".playlist .entry[song-id=" + song_id + "]").addClass("current-song"); }); }); } } set_current_bot(client, enforce) { if (client) client.updateClientVariables(); /* just to ensure */ if (client === this._current_bot && (typeof (enforce) === "undefined" || !enforce)) return; const old = this._current_bot; this._current_bot = client; this.events.fire("bot_change", { new: client, old: old }); } current_bot() { return this._current_bot; } sort_songs(data) { const result = []; let appendable = []; for (const song of data) { if (song.song_id == 0 || data.findIndex(e => e.song_id === song.song_previous_song_id) == -1) result.push(song); else appendable.push(song); } let iters; while (appendable.length) { do { iters = 0; const left = []; for (const song of appendable) { const index = data.findIndex(e => e.song_id === song.song_previous_song_id); if (index == -1) { left.push(song); continue; } result.splice(index + 1, 0, song); iters++; } appendable = left; } while (iters > 0); if (appendable.length) result.push(appendable.pop_front()); } return result; } /* playlist stuff */ update_playlist() { this.playlist_subscribe(true); this._container_playlist.find(".overlay").toggleClass("hidden", true); const playlist = this._container_playlist.find(".playlist"); playlist.empty(); if (!this.handle.handle.serverConnection || !this.handle.handle.serverConnection.connected() || !this._current_bot) { this._container_playlist.find(".overlay-empty").removeClass("hidden"); return; } const overlay_loading = this._container_playlist.find(".overlay-loading"); overlay_loading.removeClass("hidden"); this._current_bot.updateClientVariables(true).catch(error => { log.warn(LogCategory.CLIENT, _translations.hjLbCBgy || (_translations.hjLbCBgy = tr("Failed to update music bot variables: %o")), error); }).then(() => { this.handle.handle.serverConnection.command_helper.request_playlist_songs(this._current_bot.properties.client_playlist_id).then(songs => { this.playlist_subscribe(false); /* we're allowed to see the playlist */ if (!songs) { this._container_playlist.find(".overlay-empty").removeClass("hidden"); return; } for (const song of this.sort_songs(songs)) this.events.fire("playlist_song_add", { song: song, insert_effect: false }); }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) { this._container_playlist.find(".overlay-no-permissions").removeClass("hidden"); return; } log.error(LogCategory.CLIENT, _translations.HCGbFx4a || (_translations.HCGbFx4a = tr("Failed to load bot playlist: %o")), error); this._container_playlist.find(".overlay.overlay-error").removeClass("hidden"); }).then(() => { overlay_loading.addClass("hidden"); }); }); } playlist_subscribe(unsubscribe) { if (!this.handle.handle.serverConnection) return; if (unsubscribe || !this._current_bot) { if (!this._playlist_subscribed) return; this._playlist_subscribed = false; this.handle.handle.serverConnection.send_command("playlistsetsubscription", { playlist_id: 0 }).catch(error => { log.warn(LogCategory.CLIENT, _translations.vjourOhk || (_translations.vjourOhk = tr("Failed to unsubscribe from last playlist: %o")), error); }); } else { this.handle.handle.serverConnection.send_command("playlistsetsubscription", { playlist_id: this._current_bot.properties.client_playlist_id }).then(() => this._playlist_subscribed = true).catch(error => { log.warn(LogCategory.CLIENT, _translations.HDVNAONI || (_translations.HDVNAONI = tr("Failed to subscribe to bots playlist: %o")), error); }); } } build_playlist_entry(data, insert_effect) { const tag = $("#tmpl_frame_music_playlist_entry").renderTag(); tag.attr({ "song-id": data.song_id, "song-url": data.song_url }); const thumbnail = tag.find(".container-thumbnail img"); const name = tag.find(".name"); const description = tag.find(".description"); const length = tag.find(".length"); tag.find(".button-delete").on('click', () => this.events.fire("action_song_delete", { song_id: data.song_id })); tag.find(".container-thumbnail").on('click', event => { const target = tag.find(".container-thumbnail img"); const url = target.attr("x-thumbnail-url"); if (!url) return; image_preview.preview_image(decodeURIComponent(url), decodeURIComponent(url)); }); tag.on('dblclick', event => this.events.fire("action_song_set", { song_id: data.song_id })); name.text(_translations.TNiqTN3i || (_translations.TNiqTN3i = tr("loading..."))); description.text(data.song_url); tag.on('mousedown', event => { if (event.button !== 0) return; this.song_reorder.mouse = { x: event.pageX, y: event.pageY }; const baseOff = tag.offset(); const off = { x: event.pageX - baseOff.left, y: event.pageY - baseOff.top }; const move_listener = (event) => { const distance = Math.pow(event.pageX - this.song_reorder.mouse.x, 2) + Math.pow(event.pageY - this.song_reorder.mouse.y, 2); if (distance < 50) return; document.removeEventListener("blur", up_listener); document.removeEventListener("mouseup", up_listener); document.removeEventListener("mousemove", move_listener); this.song_reorder.mouse = off; this.events.fire("reorder_begin", { entry: tag, song_id: data.song_id }); }; const up_listener = event => { if (event.type === "mouseup" && event.button !== 0) return; document.removeEventListener("blur", up_listener); document.removeEventListener("mouseup", up_listener); document.removeEventListener("mousemove", move_listener); }; document.addEventListener("blur", up_listener); document.addEventListener("mouseup", up_listener); document.addEventListener("mousemove", move_listener); }); if (this._current_bot) { this._current_bot.requestPlayerInfo(60 * 1000).then(pdata => { if (pdata.song_id === data.song_id) tag.addClass("current-song"); }); } if (insert_effect) { tag.removeClass("shown"); tag.addClass("animation"); } return tag; } } chat.MusicInfo = MusicInfo; })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["52993fa72b08c5cb4366d0fab99788e3d4126eddfe5dfaa34a89c3679daa82be"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["52993fa72b08c5cb4366d0fab99788e3d4126eddfe5dfaa34a89c3679daa82be"] = "52993fa72b08c5cb4366d0fab99788e3d4126eddfe5dfaa34a89c3679daa82be"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "pRHnlG22", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (109,44)" }, { name: "U6OPHjhG", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (116,44)" }, { name: "IQ73bGpZ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (302,65)" }, { name: "vAvu9aXX", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (308,65)" }, { name: "Usc8Z0dA", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (417,70)" }, { name: "usbbbJmF", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (419,70)" }, { name: "YB1tzr5O", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (436,78)" }, { name: "zIQR20pQ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (438,78)" }, { name: "wcP0LRC8", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (451,61)" }, { name: "bhESUduw", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (489,28)" }, { name: "wUufMAi5", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (531,85)" }, { name: "OEugjVYr", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (558,27)" }, { name: "rQyF4uB3", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (560,87)" }, { name: "aQ79wdKI", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (560,129)" }, { name: "YpJr2VKc", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (562,27)" }, { name: "kY_eo4IV", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (564,27)" }, { name: "qCa4M1e6", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (624,44)" }, { name: "a3TO9oPJ", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (683,48)" }, { name: "oXV6BFdj", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (691,48)" }, { name: "P7dP7UKz", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (782,51)" }, { name: "HQmGkDk1", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (791,51)" }, { name: "XZu8l5EV", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (794,47)" }, { name: "WTCSSX6D", path: "D:/TeaSpeak/web/shared/js/ui/frames/side/private_conversations.ts (890,48)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /* the bar on the right with the chats (Channel & Client) */ var chat; (function (chat) { let PrivateConversationState; (function (PrivateConversationState) { PrivateConversationState[PrivateConversationState["OPEN"] = 0] = "OPEN"; PrivateConversationState[PrivateConversationState["CLOSED"] = 1] = "CLOSED"; PrivateConversationState[PrivateConversationState["DISCONNECTED"] = 2] = "DISCONNECTED"; PrivateConversationState[PrivateConversationState["DISCONNECTED_SELF"] = 3] = "DISCONNECTED_SELF"; })(PrivateConversationState = chat.PrivateConversationState || (chat.PrivateConversationState = {})); class PrivateConveration { constructor(handle, client_unique_id, client_name, client_id) { this._message_history = []; this._last_typing = 0; this._typing_timeout = 4000; this._displayed_messages = []; this._displayed_messages_length = 500; this.handle = handle; this.client_name = client_name; this.client_unique_id = client_unique_id; this.client_id = client_id; this._state = PrivateConversationState.OPEN; this._build_entry_tag(); this.set_unread_flag(false); this.load_history(); } history_key() { return this.handle.handle.handle.channelTree.server.properties.virtualserver_unique_identifier + "_" + this.client_unique_id; } load_history() { chat.helpers.history.load_history(this.history_key()).then((data) => { if (!data) return; const flag_unread = !!this._spacer_unread_message; for (const message of data.slice(data.length > this._displayed_messages_length ? data.length - this._displayed_messages_length : 0)) { this.append_message(message.message, { type: message.sender, name: message.sender_name, unique_id: message.sender_unique_id, client_id: message.sender_client_id }, new Date(message.timestamp), false); } if (!flag_unread) this.set_unread_flag(false); this.fix_scroll(false); this.save_history(); }).catch(error => { log.warn(LogCategory.CHAT, _translations.pRHnlG22 || (_translations.pRHnlG22 = tr("Failed to load private conversation history for user %s on server %s: %o")), this.client_unique_id, this.handle.handle.handle.channelTree.server.properties.virtualserver_unique_identifier, error); }); } save_history() { chat.helpers.history.save_history(this.history_key(), this._message_history).catch(error => { log.warn(LogCategory.CHAT, _translations.U6OPHjhG || (_translations.U6OPHjhG = tr("Failed to save private conversation history for user %s on server %s: %o")), this.client_unique_id, this.handle.handle.handle.channelTree.server.properties.virtualserver_unique_identifier, error); }); } entry_tag() { return this._html_entry_tag; } destroy() { this._html_message_container = undefined; /* we do not own this container */ this.clear_messages(false); this._html_entry_tag && this._html_entry_tag.remove(); this._html_entry_tag = undefined; this._message_history = undefined; if (this._typing_timeout_task) clearTimeout(this._typing_timeout_task); } _2d_flat(array) { const result = []; for (const a of array) result.push(...a.filter(e => typeof (e) !== "undefined")); return result; } messages_tags() { return this._2d_flat(this._displayed_messages.slice().reverse().map(e => [ e.tag_timepointer ? e.tag_timepointer.html_tag : undefined, e.tag_unread ? e.tag_unread.html_tag : undefined, e.tag_message ])); } append_message(message, sender, timestamp, save_history) { const message_date = timestamp || new Date(); const message_timestamp = message_date.getTime(); const packed_message = { message: message, sender: sender.type, sender_name: sender.name, sender_client_id: sender.client_id, sender_unique_id: sender.unique_id, timestamp: message_date.getTime(), message_id: 'undefined' }; /* first of all register message in message history */ { let index = 0; for (; index < this._message_history.length; index++) { if (this._message_history[index].timestamp > message_timestamp) continue; this._message_history.splice(index, 0, packed_message); break; } if (index > 100) return; /* message is too old to be displayed */ if (index >= this._message_history.length) this._message_history.push(packed_message); while (this._message_history.length > 100) this._message_history.pop(); } if (sender.type === "partner") { clearTimeout(this._typing_timeout_task); this._typing_timeout_task = 0; if (this.typing_active()) { this._last_typing = 0; this.typing_expired(); } else { this._update_message_timestamp(); } } else { this._update_message_timestamp(); } if (typeof (save_history) !== "boolean" || save_history) this.save_history(); /* insert in view */ { const basic_view_entry = this._build_message(packed_message); this._register_displayed_message({ timestamp: basic_view_entry.timestamp, message: basic_view_entry, message_type: "message", tag_message: basic_view_entry.html_tag, tag_timepointer: undefined, tag_unread: undefined }, true); } } _displayed_message_first_tag(message) { const tp = message.tag_timepointer ? message.tag_timepointer.html_tag : undefined; const tu = message.tag_unread ? message.tag_unread.html_tag : undefined; return tp || tu || message.tag_message; } _destroy_displayed_message(message, update_pointers) { if (update_pointers) { const index = this._displayed_messages.indexOf(message); if (index != -1 && index > 0) { const next = this._displayed_messages[index - 1]; if (!next.tag_timepointer && message.tag_timepointer) { next.tag_timepointer = message.tag_timepointer; message.tag_timepointer = undefined; } if (!next.tag_unread && message.tag_unread) { this._spacer_unread_message = next; next.tag_unread = message.tag_unread; message.tag_unread = undefined; } } if (message == this._spacer_unread_message) this._spacer_unread_message = undefined; } this._displayed_messages.remove(message); if (message.tag_timepointer) this._destroy_view_entry(message.tag_timepointer); if (message.tag_unread) this._destroy_view_entry(message.tag_unread); this._destroy_view_entry(message.message); } clear_messages(save) { this._message_history = []; while (this._displayed_messages.length > 0) { this._destroy_displayed_message(this._displayed_messages[0], false); } this._spacer_unread_message = undefined; this._update_message_timestamp(); if (save) this.save_history(); } fix_scroll(animate) { if (!this._html_message_container) return; let offset; if (this._spacer_unread_message) { offset = this._displayed_message_first_tag(this._spacer_unread_message)[0].offsetTop; } else if (typeof (this._scroll_position) !== "undefined") { offset = this._scroll_position; } else { offset = this._html_message_container[0].scrollHeight; } if (animate) { this._html_message_container.stop(true).animate({ scrollTop: offset }, 'slow'); } else { this._html_message_container.stop(true).scrollTop(offset); } } _update_message_timestamp() { if (this._last_message_updater_id) clearTimeout(this._last_message_updater_id); if (!this._html_entry_tag) return; /* we got deleted, not need for updates */ if (this.typing_active()) { this._html_entry_tag.find(".last-message").text(_translations.IQ73bGpZ || (_translations.IQ73bGpZ = tr("currently typing..."))); return; } const last_message = this._message_history[0]; if (!last_message) { this._html_entry_tag.find(".last-message").text(_translations.vAvu9aXX || (_translations.vAvu9aXX = tr("no history"))); return; } const timestamp = new Date(last_message.timestamp); let time = chat.format.date.format_chat_time(timestamp); this._html_entry_tag.find(".last-message").text(time.result); if (time.next_update > 0) { this._last_message_updater_id = setTimeout(() => this._update_message_timestamp(), time.next_update); } else { this._last_message_updater_id = 0; } } _destroy_message(message) { if (message.time_update_id) clearTimeout(message.time_update_id); } _build_message(message) { const result = message; if (result.html_tag) return result; const timestamp = new Date(message.timestamp); let time = chat.format.date.format_chat_time(timestamp); result.html_tag = $("#tmpl_frame_chat_private_message").renderTag({ timestamp: time.result, message_id: message.message_id, client_name: htmltags.generate_client_object({ add_braces: false, client_name: message.sender_name, client_unique_id: message.sender_unique_id, client_id: message.sender_client_id }), message: MessageHelper.bbcode_chat(message.message), avatar: this.handle.handle.handle.fileManager.avatars.generate_chat_tag({ id: message.sender_client_id }, message.sender_unique_id) }); if (time.next_update > 0) { const _updater = () => { time = chat.format.date.format_chat_time(timestamp); result.html_tag.find(".info .timestamp").text(time.result); if (time.next_update > 0) result.time_update_id = setTimeout(_updater, time.next_update); else result.time_update_id = 0; }; result.time_update_id = setTimeout(_updater, time.next_update); } else { result.time_update_id = 0; } return result; } _build_spacer(message, type) { const tag = $("#tmpl_frame_chat_private_spacer").renderTag({ message: message }).addClass("type-" + type); return { html_tag: tag }; } _register_displayed_message(message, update_new) { const message_date = new Date(message.timestamp); /* before := older message; after := newer message */ let entry_before, entry_after; let index = 0; for (; index < this._displayed_messages.length; index++) { if (this._displayed_messages[index].timestamp > message.timestamp) continue; entry_after = index > 0 ? this._displayed_messages[index - 1] : undefined; entry_before = this._displayed_messages[index]; this._displayed_messages.splice(index, 0, message); break; } if (index >= this._displayed_messages_length) { return; /* message is out of view region */ } if (index >= this._displayed_messages.length) { entry_before = undefined; entry_after = this._displayed_messages.last(); this._displayed_messages.push(message); } while (this._displayed_messages.length > this._displayed_messages_length) this._destroy_displayed_message(this._displayed_messages.last(), true); const flag_new_message = update_new && index == 0 && (message.message_type === "spacer" || message.message.sender === "partner"); /* Timeline for before - now */ { let append_pointer = false; if (entry_before) { if (!chat.helpers.date.same_day(message.timestamp, entry_before.timestamp)) { append_pointer = true; } } else { append_pointer = true; } if (append_pointer) { const diff = chat.format.date.date_format(message_date, new Date()); if (diff == chat.format.date.ColloquialFormat.YESTERDAY) message.tag_timepointer = this._build_spacer(_translations.Usc8Z0dA || (_translations.Usc8Z0dA = tr("Yesterday")), "date"); else if (diff == chat.format.date.ColloquialFormat.TODAY) message.tag_timepointer = this._build_spacer(_translations.usbbbJmF || (_translations.usbbbJmF = tr("Today")), "date"); else if (diff == chat.format.date.ColloquialFormat.GENERAL) message.tag_timepointer = this._build_spacer(chat.format.date.format_date_general(message_date, false), "date"); } } /* Timeline not and after */ { if (entry_after) { if (chat.helpers.date.same_day(message_date, entry_after.timestamp)) { if (entry_after.tag_timepointer) { this._destroy_view_entry(entry_after.tag_timepointer); entry_after.tag_timepointer = undefined; } } else if (!entry_after.tag_timepointer) { const diff = chat.format.date.date_format(new Date(entry_after.timestamp), new Date()); if (diff == chat.format.date.ColloquialFormat.YESTERDAY) entry_after.tag_timepointer = this._build_spacer(_translations.YB1tzr5O || (_translations.YB1tzr5O = tr("Yesterday")), "date"); else if (diff == chat.format.date.ColloquialFormat.TODAY) entry_after.tag_timepointer = this._build_spacer(_translations.zIQR20pQ || (_translations.zIQR20pQ = tr("Today")), "date"); else if (diff == chat.format.date.ColloquialFormat.GENERAL) entry_after.tag_timepointer = this._build_spacer(chat.format.date.format_date_general(message_date, false), "date"); entry_after.tag_timepointer.html_tag.insertBefore(entry_after.tag_message); } } } /* new message flag */ if (flag_new_message) { if (!this._spacer_unread_message) { this._spacer_unread_message = message; message.tag_unread = this._build_spacer(_translations.wcP0LRC8 || (_translations.wcP0LRC8 = tr("Unread messages")), "new"); this.set_unread_flag(true); } } if (this._html_message_container) { if (entry_before) { message.tag_message.insertAfter(entry_before.tag_message); } else if (entry_after) { message.tag_message.insertBefore(this._displayed_message_first_tag(entry_after)); } else { this._html_message_container.append(message.tag_message); } /* first time pointer */ if (message.tag_timepointer) message.tag_timepointer.html_tag.insertBefore(message.tag_message); /* the unread */ if (message.tag_unread) message.tag_unread.html_tag.insertBefore(message.tag_message); } this.fix_scroll(true); } _destroy_view_entry(entry) { if (!entry.html_tag) return; entry.html_tag.remove(); if ('sender' in entry) this._destroy_message(entry); } _build_entry_tag() { this._html_entry_tag = $("#tmpl_frame_chat_private_entry").renderTag({ client_name: this.client_name, last_time: _translations.bhESUduw || (_translations.bhESUduw = tr("error no timestamp")), avatar: this.handle.handle.handle.fileManager.avatars.generate_chat_tag({ id: this.client_id }, this.client_unique_id) }); this._html_entry_tag.on('click', event => { if (event.isDefaultPrevented()) return; this.handle.set_selected_conversation(this); }); this._html_entry_tag.find('.button-close').on('click', event => { event.preventDefault(); this.close_conversation(); }); this._update_message_timestamp(); } update_avatar() { const container = this._html_entry_tag.find(".container-avatar"); container.find(".avatar").remove(); container.append(this.handle.handle.handle.fileManager.avatars.generate_chat_tag({ id: this.client_id }, this.client_unique_id)); } close_conversation() { this.handle.delete_conversation(this, true); } set_client_name(name) { if (this.client_name === name) return; this.client_name = name; this._html_entry_tag.find(".client-name").text(name); } set_unread_flag(flag, update_chat_counter) { /* unread message pointer */ if (flag != (typeof (this._spacer_unread_message) !== "undefined")) { if (flag) { if (this._displayed_messages.length > 0) /* without messages we cant be unread */ return; if (!this._spacer_unread_message) { this._spacer_unread_message = this._displayed_messages[0]; this._spacer_unread_message.tag_unread = this._build_spacer(_translations.wUufMAi5 || (_translations.wUufMAi5 = tr("Unread messages")), "new"); this._spacer_unread_message.tag_unread.html_tag.insertBefore(this._spacer_unread_message.tag_message); } } else { const ctree = this.handle.handle.handle.channelTree; if (ctree && ctree.tag_tree() && this.client_id) ctree.tag_tree().find(".marker-text-unread[private-conversation='" + this.client_id + "']").addClass("hidden"); if (this._spacer_unread_message) { this._destroy_view_entry(this._spacer_unread_message.tag_unread); this._spacer_unread_message.tag_unread = undefined; this._spacer_unread_message = undefined; } } } /* general notify */ this._html_entry_tag.toggleClass("unread", flag); if (typeof (update_chat_counter) !== "boolean" || update_chat_counter) this.handle.handle.info_frame().update_chat_counter(); } is_unread() { return !!this._spacer_unread_message; } _append_state_change(state) { let message; if (state == "closed") message = _translations.OEugjVYr || (_translations.OEugjVYr = tr("Your chat partner has closed the conversation")); else if (state == "reconnect") message = this._state === PrivateConversationState.DISCONNECTED_SELF ? _translations.rQyF4uB3 || (_translations.rQyF4uB3 = tr("You've reconnected to the server")) : _translations.aQ79wdKI || (_translations.aQ79wdKI = tr("Your chat partner has reconnected")); else if (state === "disconnect") message = _translations.YpJr2VKc || (_translations.YpJr2VKc = tr("Your chat partner has disconnected")); else message = _translations.kY_eo4IV || (_translations.kY_eo4IV = tr("You've disconnected from the server")); const spacer = this._build_spacer(message, state); this._register_displayed_message({ timestamp: Date.now(), message: spacer, message_type: "spacer", tag_message: spacer.html_tag, tag_timepointer: undefined, tag_unread: undefined }, state === "disconnect"); } state() { return this._state; } set_state(state) { if (this._state == state) return; if (state == PrivateConversationState.DISCONNECTED) { this._append_state_change("disconnect"); this.client_id = 0; } else if (state == PrivateConversationState.OPEN && this._state != PrivateConversationState.CLOSED) this._append_state_change("reconnect"); else if (state == PrivateConversationState.CLOSED) this._append_state_change("closed"); else if (state == PrivateConversationState.DISCONNECTED_SELF) this._append_state_change("disconnect_self"); this._state = state; } set_text_callback(callback, update_enabled_state) { this._callback_message = callback; if (typeof (update_enabled_state) !== "boolean" || update_enabled_state) this.handle.update_chatbox_state(); } chat_enabled() { return typeof (this._callback_message) !== "undefined" && (this._state == PrivateConversationState.OPEN || this._state == PrivateConversationState.CLOSED); } append_error(message, date) { const spacer = this._build_spacer(message, "error"); this._register_displayed_message({ timestamp: date || Date.now(), message: spacer, message_type: "spacer", tag_message: spacer.html_tag, tag_timepointer: undefined, tag_unread: undefined }, true); } call_message(message) { if (this._callback_message) this._callback_message(message); else { log.warn(LogCategory.CHAT, _translations.qCa4M1e6 || (_translations.qCa4M1e6 = tr("Dropping conversation message for client %o because of no message callback.")), { client_name: this.client_name, client_id: this.client_id, client_unique_id: this.client_unique_id }); } } typing_expired() { this._update_message_timestamp(); if (this.handle.current_conversation() === this) this.handle.update_typing_state(); } trigger_typing() { let _new = Date.now() - this._last_typing > this._typing_timeout; this._last_typing = Date.now(); if (this._typing_timeout_task) clearTimeout(this._typing_timeout_task); if (_new) this._update_message_timestamp(); if (this.handle.current_conversation() === this) this.handle.update_typing_state(); this._typing_timeout_task = setTimeout(() => this.typing_expired(), this._typing_timeout); } typing_active() { return Date.now() - this._last_typing < this._typing_timeout; } } chat.PrivateConveration = PrivateConveration; class PrivateConverations { constructor(handle) { this._conversations = []; this._current_conversation = undefined; this.handle = handle; this._chat_box = new chat.ChatBox(); this._build_html_tag(); this.update_chatbox_state(); this.update_typing_state(); this._chat_box.callback_text = message => { if (!this._current_conversation) { log.warn(LogCategory.CHAT, _translations.a3TO9oPJ || (_translations.a3TO9oPJ = tr("Dropping conversation message because of no active conversation."))); return; } this._current_conversation.call_message(message); }; this._chat_box.callback_typing = () => { if (!this._current_conversation) { log.warn(LogCategory.CHAT, _translations.oXV6BFdj || (_translations.oXV6BFdj = tr("Dropping conversation typing action because of no active conversation."))); return; } const connection = this.handle.handle.serverConnection; if (!connection || !connection.connected()) return; connection.send_command("clientchatcomposing", { clid: this._current_conversation.client_id }); }; } clear_client_ids() { this._conversations.forEach(e => { e.client_id = 0; e.set_state(PrivateConversationState.DISCONNECTED_SELF); }); } html_tag() { return this._html_tag; } destroy() { this._chat_box && this._chat_box.destroy(); this._chat_box = undefined; for (const conversation of this._conversations) conversation.destroy(); this._conversations = []; this._current_conversation = undefined; clearTimeout(this._select_read_timer); this._html_tag && this._html_tag.remove(); this._html_tag = undefined; } current_conversation() { return this._current_conversation; } conversations() { return this._conversations; } create_conversation(client_uid, client_name, client_id) { const conv = new PrivateConveration(this, client_uid, client_name, client_id); this._conversations.push(conv); this._html_no_chats.hide(); this._container_conversation_list.append(conv.entry_tag()); this.handle.info_frame().update_chat_counter(); return conv; } delete_conversation(conv, update_chat_couner) { if (!this._conversations.remove(conv)) return; //TODO: May animate? conv.destroy(); conv.clear_messages(false); this._html_no_chats.toggle(this._conversations.length == 0); if (conv === this._current_conversation) this.set_selected_conversation(undefined); if (update_chat_couner || typeof (update_chat_couner) !== "boolean") this.handle.info_frame().update_chat_counter(); } find_conversation(partner, mode) { for (const conversation of this.conversations()) if (conversation.client_id == partner.client_id && (!partner.unique_id || conversation.client_unique_id == partner.unique_id)) { if (conversation.state() != PrivateConversationState.OPEN) conversation.set_state(PrivateConversationState.OPEN); return conversation; } let conv; if (mode.attach) { for (const conversation of this.conversations()) if (conversation.client_unique_id == partner.unique_id && conversation.state() != PrivateConversationState.OPEN) { conversation.set_state(PrivateConversationState.OPEN); conversation.client_id = partner.client_id; conversation.set_client_name(partner.name); conv = conversation; break; } } if (mode.create && !conv) { conv = this.create_conversation(partner.unique_id, partner.name, partner.client_id); conv.client_id = partner.client_id; conv.set_client_name(partner.name); } if (conv) { conv.set_text_callback(message => { log.debug(LogCategory.CLIENT, _translations.P7dP7UKz || (_translations.P7dP7UKz = tr("Sending text message %s to %o")), message, partner); this.handle.handle.serverConnection.send_command("sendtextmessage", { "targetmode": 1, "target": partner.client_id, "msg": message }).catch(error => { if (error instanceof CommandResult) { if (error.id == ErrorID.CLIENT_INVALID_ID) { conv.set_state(PrivateConversationState.DISCONNECTED); conv.set_text_callback(undefined); } else if (error.id == ErrorID.PERMISSION_ERROR) { /* may notify for no permissions? */ } else { conv.append_error((_translations.HQmGkDk1 || (_translations.HQmGkDk1 = tr("Failed to send message: "))) + (error.extra_message || error.message)); } } else { conv.append_error(_translations.XZu8l5EV || (_translations.XZu8l5EV = tr("Failed to send message. Lookup the console for more details"))); log.error(LogCategory.CHAT, tr("Failed to send conversation message: %o", error)); } }); }); } return conv; } clear_conversations() { while (this._conversations.length > 0) this.delete_conversation(this._conversations[0], false); this.handle.info_frame().update_chat_counter(); } set_selected_conversation(conv) { if (conv === this._current_conversation) return; if (this._select_read_timer) clearTimeout(this._select_read_timer); if (this._current_conversation) this._current_conversation._html_message_container = undefined; this._container_conversation_list.find(".selected").removeClass("selected"); this._container_conversation_messages.children().detach(); this._current_conversation = conv; if (!this._current_conversation) { this.update_chatbox_state(); return; } this._current_conversation._html_message_container = this._container_conversation_messages; const messages = this._current_conversation.messages_tags(); /* TODO: Check if the messages are empty and display "No messages" */ this._container_conversation_messages.append(...messages); if (this._current_conversation.is_unread() && false) { this._select_read_timer = setTimeout(() => { this._current_conversation.set_unread_flag(false, true); }, 20 * 1000); /* Lets guess you've read the new messages within 5 seconds */ } this._current_conversation.fix_scroll(false); this._current_conversation.entry_tag().addClass("selected"); this.update_chatbox_state(); } update_chatbox_state() { this._chat_box.set_enabled(!!this._current_conversation && this._current_conversation.chat_enabled()); } update_typing_state() { this._container_typing.toggleClass("hidden", !this._current_conversation || !this._current_conversation.typing_active()); } _build_html_tag() { this._html_tag = $("#tmpl_frame_chat_private").renderTag({ chatbox: this._chat_box.html_tag() }).dividerfy(); this._container_conversation = this._html_tag.find(".conversation"); this._container_conversation.on('click', event => { if (this._current_conversation) this._current_conversation.set_unread_flag(false, true); /* only updates everything if the state changes */ }); this._container_conversation_messages = this._container_conversation.find(".messages"); this._container_conversation_messages.on('scroll', event => { if (!this._current_conversation) return; const current_view = this._container_conversation_messages[0].scrollTop + this._container_conversation_messages[0].clientHeight + this._container_conversation_messages[0].clientHeight * .125; if (current_view > this._container_conversation_messages[0].scrollHeight) this._current_conversation._scroll_position = undefined; else this._current_conversation._scroll_position = this._container_conversation_messages[0].scrollTop; }); this._container_conversation_list = this._html_tag.find(".conversation-list"); this._html_no_chats = this._container_conversation_list.find(".no-chats"); this._container_typing = this._html_tag.find(".container-typing"); this.update_input_format_helper(); } try_input_focus() { this._chat_box.focus_input(); } on_show() { if (this._current_conversation) this._current_conversation.fix_scroll(false); } update_input_format_helper() { const tag = this._html_tag.find(".container-format-helper"); if (settings.static_global(Settings.KEY_CHAT_ENABLE_MARKDOWN)) { tag.removeClass("hidden").text(_translations.WTCSSX6D || (_translations.WTCSSX6D = tr("*italic*, **bold**, ~~strikethrough~~, `code`, and more..."))); } else { tag.addClass("hidden"); } } } chat.PrivateConverations = PrivateConverations; })(chat || (chat = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["cb1a8cd441d1bbbd9b2737e4c26524694bd2bd35f9024e2a99bd9a12d07cf7b0"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["cb1a8cd441d1bbbd9b2737e4c26524694bd2bd35f9024e2a99bd9a12d07cf7b0"] = "cb1a8cd441d1bbbd9b2737e4c26524694bd2bd35f9024e2a99bd9a12d07cf7b0"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "UvC90shS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAbout.ts (27,21)" }, { name: "_OdnrDIg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAbout.ts (50,48)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function format_date(date) { const d = new Date(date); return ('00' + d.getDay()).substr(-2) + "." + ('00' + d.getMonth()).substr(-2) + "." + d.getFullYear() + " - " + ('00' + d.getHours()).substr(-2) + ":" + ('00' + d.getMinutes()).substr(-2); } function spawnAbout() { const app_version = (() => { const version_node = document.getElementById("app_version"); if (!version_node) return undefined; const version = version_node.hasAttribute("value") ? version_node.getAttribute("value") : undefined; if (!version) return undefined; if (version == "unknown" || version.replace(/0+/, "").length == 0) return undefined; return version; })(); const connectModal = createModal({ header: _translations.UvC90shS || (_translations.UvC90shS = tr("About")), body: () => { let tag = $("#tmpl_about").renderTag({ client: !app.is_web(), version_client: app.is_web() ? app_version || "in-dev" : "loading...", version_ui: app_version || "in-dev", version_timestamp: !!app_version ? format_date(Date.now()) : "--" }); return tag; }, footer: null, width: "60em" }); connectModal.htmlTag.find(".modal-body").addClass("modal-about"); connectModal.open(); if (!app.is_web()) { window.native.client_version().then(version => { connectModal.htmlTag.find(".version-client").text(version); }).catch(error => { log.error(LogCategory.GENERAL, _translations._OdnrDIg || (_translations._OdnrDIg = tr("Failed to load client version: %o")), error); connectModal.htmlTag.find(".version-client").text("unknown"); }); } } Modals.spawnAbout = spawnAbout; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["ba60e7511140f62e2e02c5860bea99e474c1f09dfb5d657bb59ea95b5ca607cc"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["ba60e7511140f62e2e02c5860bea99e474c1f09dfb5d657bb59ea95b5ca607cc"] = "ba60e7511140f62e2e02c5860bea99e474c1f09dfb5d657bb59ea95b5ca607cc"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "ClTfrLVQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatar.ts (9,21)" }, { name: "bltBa8CM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatar.ts (59,35)" }, { name: "u7xCv0Fo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatar.ts (60,38)" }, { name: "ABQle2XS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatar.ts (65,29)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { //TODO: Test if we could render this image and not only the browser by knowing the type. function spawnAvatarUpload(callback_data) { const modal = createModal({ header: _translations.ClTfrLVQ || (_translations.ClTfrLVQ = tr("Avatar Upload")), footer: undefined, body: () => { return $("#tmpl_avatar_upload").renderTag({}); } }); let _data_submitted = false; let _current_avatar; modal.htmlTag.find(".button-select").on('click', event => { modal.htmlTag.find(".file-inputs").trigger('click'); }); modal.htmlTag.find(".button-delete").on('click', () => { if (_data_submitted) return; _data_submitted = true; modal.close(); callback_data(null); }); modal.htmlTag.find(".button-cancel").on('click', () => modal.close()); const button_upload = modal.htmlTag.find(".button-upload"); button_upload.on('click', event => (!_data_submitted) && (_data_submitted = true, modal.close(), true) && callback_data(_current_avatar)); const set_avatar = (data, type) => { _current_avatar = data ? arrayBufferBase64(data) : undefined; button_upload.prop("disabled", !_current_avatar); modal.htmlTag.find(".preview img").attr("src", data ? ("data:image/" + type + ";base64," + data) : "img/style/avatar.png"); }; const input_node = modal.htmlTag.find(".file-inputs")[0]; input_node.multiple = false; modal.htmlTag.find(".file-inputs").on('change', event => { console.log("Files: %o", input_node.files); const read_file = (file) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = error => reject(error); reader.readAsDataURL(file); }); (() => __awaiter(this, void 0, void 0, function* () { const data = yield read_file(input_node.files[0]); if (!data.startsWith("data:image/")) { console.error(_translations.bltBa8CM || (_translations.bltBa8CM = tr("Failed to load file %s: Invalid data media type (%o)")), input_node.files[0].name, data); createErrorModal(_translations.u7xCv0Fo || (_translations.u7xCv0Fo = tr("Icon upload failed")), tra("Failed to select avatar {}.
File is not an image", input_node.files[0].name)).open(); return; } const semi = data.indexOf(';'); const type = data.substring(11, semi); console.log(_translations.ABQle2XS || (_translations.ABQle2XS = tr("Given image has type %s")), type); set_avatar(data.substr(semi + 8 /* 8 bytes := base64, */), type); }))(); }); set_avatar(undefined); modal.close_listener.push(() => !_data_submitted && callback_data(undefined)); modal.open(); } Modals.spawnAvatarUpload = spawnAvatarUpload; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["b6161b8459fe46763e17df58843394182a9583e985503f2e71811b45b30b4ffd"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["b6161b8459fe46763e17df58843394182a9583e985503f2e71811b45b30b4ffd"] = "b6161b8459fe46763e17df58843394182a9583e985503f2e71811b45b30b4ffd"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "WyO_9diE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (25,21)" }, { name: "dDeDPqV3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (57,86)" }, { name: "rxNEagLS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (58,88)" }, { name: "YjHvCku4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (59,84)" }, { name: "JxSfQpqn", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (89,28)" }, { name: "xPENqFxw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (89,49)" }, { name: "WtQT3rEW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (91,42)" }, { name: "YQR30jMM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (91,65)" }, { name: "EAlpgDaJ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (147,52)" }, { name: "_9ZhLutC", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (148,38)" }, { name: "V5Na3lr_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (148,71)" }, { name: "yN5_Hp_F", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (152,48)" }, { name: "jrf39vdv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (153,34)" }, { name: "q3nuUEOC", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalAvatarList.ts (153,64)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { const avatar_to_uid = (id) => { const buffer = new Uint8Array(id.length / 2); for (let index = 0; index < id.length; index += 2) { const upper_nibble = id.charCodeAt(index) - 97; const lower_nibble = id.charCodeAt(index + 1) - 97; buffer[index / 2] = (upper_nibble << 4) | lower_nibble; } return base64_encode_ab(buffer); }; Modals.human_file_size = (size) => { if (size < 1000) return size + "B"; const exp = Math.floor(Math.log2(size) / 10); return (size / Math.pow(1024, exp)).toFixed(2) + 'KMGTPE'.charAt(exp - 1) + "iB"; }; function spawnAvatarList(client) { const modal = createModal({ header: _translations.WyO_9diE || (_translations.WyO_9diE = tr("Avatars")), footer: undefined, body: () => { const template = $("#tmpl_avatar_list").renderTag({}); return template; } }); let callback_download; let callback_delete; const button_download = modal.htmlTag.find(".button-download"); const button_delete = modal.htmlTag.find(".button-delete"); const container_list = modal.htmlTag.find(".container-list .list-entries-container"); const list_entries = container_list.find(".list-entries"); const container_info = modal.htmlTag.find(".container-info"); const overlay_no_user = container_info.find(".disabled-overlay").show(); const set_selected_avatar = (unique_id, avatar_id, size) => { button_download.prop("disabled", true); callback_download = undefined; if (!unique_id) { overlay_no_user.show(); return; } const tag_username = container_info.find(".property-username"); const tag_unique_id = container_info.find(".property-unique-id"); const tag_avatar_id = container_info.find(".property-avatar-id"); const container_avatar = container_info.find(".container-image"); const tag_image_bytes = container_info.find(".property-image-size"); const tag_image_width = container_info.find(".property-image-width").val(_translations.dDeDPqV3 || (_translations.dDeDPqV3 = tr("loading..."))); const tag_image_height = container_info.find(".property-image-height").val(_translations.rxNEagLS || (_translations.rxNEagLS = tr("loading..."))); const tag_image_type = container_info.find(".property-image-type").val(_translations.YjHvCku4 || (_translations.YjHvCku4 = tr("loading..."))); tag_username.val("unknown"); tag_unique_id.val(unique_id); tag_avatar_id.val(avatar_id); tag_image_bytes.val(size); container_avatar.empty().append(client.fileManager.avatars.generate_tag(avatar_id, undefined, { callback_image: image => { tag_image_width.val(image[0].naturalWidth + 'px'); tag_image_height.val(image[0].naturalHeight + 'px'); }, callback_avatar: avatar => { tag_image_type.val(media_image_type(avatar.type)); button_download.prop("disabled", false); callback_download = () => { const element = $.spawn("a") .text("download") .attr("href", avatar.url) .attr("download", "avatar-" + unique_id + "." + media_image_type(avatar.type, true)) .css("display", "none") .appendTo($("body")); element[0].click(); element.remove(); }; } })); callback_delete = () => { Modals.spawnYesNo(_translations.JxSfQpqn || (_translations.JxSfQpqn = tr("Are you sure?")), _translations.xPENqFxw || (_translations.xPENqFxw = tr("Do you really want to delete this avatar?")), result => { if (result) { createErrorModal(_translations.WtQT3rEW || (_translations.WtQT3rEW = tr("Not implemented")), _translations.YQR30jMM || (_translations.YQR30jMM = tr("Avatar delete hasn't implemented yet"))).open(); //TODO Implement avatar delete } }); }; overlay_no_user.hide(); }; set_selected_avatar(undefined, undefined, 0); const update_avatar_list = () => { const template_entry = $("#tmpl_avatar_list-list_entry"); list_entries.empty(); client.fileManager.requestFileList("/").then(files => { const username_resolve = {}; for (const entry of files) { const avatar_id = entry.name.substr('avatar_'.length); const unique_id = avatar_to_uid(avatar_id); const tag = template_entry.renderTag({ username: 'loading', unique_id: unique_id, size: Modals.human_file_size(entry.size), timestamp: moment(entry.datetime * 1000).format('YY-MM-DD HH:mm') }); (username_resolve[unique_id] || (username_resolve[unique_id] = [])).push(name => { const tag_username = tag.find(".column-username").empty(); if (name) { tag_username.append(ClientEntry.chatTag(0, name, unique_id, false)); } else { tag_username.text("unknown"); } }); list_entries.append(tag); tag.on('click', () => { list_entries.find('.selected').removeClass('selected'); tag.addClass('selected'); set_selected_avatar(unique_id, avatar_id, entry.size); }); } if (container_list.hasScrollBar()) container_list.addClass("scrollbar"); client.serverConnection.command_helper.info_from_uid(...Object.keys(username_resolve)).then(result => { for (const info of result) { username_resolve[info.client_unique_id].forEach(e => e(info.client_nickname)); delete username_resolve[info.client_unique_id]; } for (const uid of Object.keys(username_resolve)) { (username_resolve[uid] || []).forEach(e => e(undefined)); } }).catch(error => { log.error(LogCategory.GENERAL, _translations.EAlpgDaJ || (_translations.EAlpgDaJ = tr("Failed to fetch usernames from avatar names. Error: %o")), error); createErrorModal(_translations._9ZhLutC || (_translations._9ZhLutC = tr("Failed to fetch usernames")), _translations.V5Na3lr_ || (_translations.V5Na3lr_ = tr("Failed to fetch usernames related to their avatar names")), undefined).open(); }); }).catch(error => { //TODO: Display no perms error log.error(LogCategory.GENERAL, _translations.yN5_Hp_F || (_translations.yN5_Hp_F = tr("Failed to receive avatar list. Error: %o")), error); createErrorModal(_translations.jrf39vdv || (_translations.jrf39vdv = tr("Failed to list avatars")), _translations.q3nuUEOC || (_translations.q3nuUEOC = tr("Failed to receive avatar list.")), undefined).open(); }); }; button_download.on('click', () => (callback_download || (() => { }))()); button_delete.on('click', () => (callback_delete || (() => { }))()); setTimeout(() => update_avatar_list(), 250); modal.open(); } Modals.spawnAvatarList = spawnAvatarList; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["d08a8911c127b3f383f7c4a52021137598cace00cb6d24c3fcce51d3b4047aa0"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["d08a8911c127b3f383f7c4a52021137598cace00cb6d24c3fcce51d3b4047aa0"] = "d08a8911c127b3f383f7c4a52021137598cace00cb6d24c3fcce51d3b4047aa0"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "TsgDlJVp", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (9,21)" }, { name: "vheWLtP2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (51,88)" }, { name: "mBoCWnAP", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (55,64)" }, { name: "Q3EMl6hY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (58,52)" }, { name: "hwuaCgCO", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (59,62)" }, { name: "m6Nljdlg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (60,53)" }, { name: "x9AY7Kln", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (62,64)" }, { name: "nuFGAPOV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (65,46)" }, { name: "Wlsrp0ec", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (198,47)" }, { name: "fPLYDIee", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (198,67)" }, { name: "FXdq1lZN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (213,42)" }, { name: "QcWetQw3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (213,69)" }, { name: "kRMVC8Kv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (232,42)" }, { name: "rUYIwFuH", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (232,71)" }, { name: "x53hiZEu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalBookmarks.ts (305,59)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function spawnBookmarkModal() { let modal; modal = createModal({ header: _translations.TsgDlJVp || (_translations.TsgDlJVp = tr("Manage bookmarks")), body: () => { let template = $("#tmpl_manage_bookmarks").renderTag({}); let selected_bookmark; const button_delete = template.find(".button-delete"); const button_add_folder = template.find(".button-add-folder"); const button_add_bookmark = template.find(".button-add-bookmark"); const button_connect = template.find(".button-connect"); const button_connect_tab = template.find(".button-connect-tab"); const label_bookmark_name = template.find(".header .container-name"); const label_server_address = template.find(".header .container-address"); const input_bookmark_name = template.find(".input-bookmark-name"); const input_connect_profile = template.find(".input-connect-profile"); const input_server_address = template.find(".input-server-address"); const input_server_password = template.find(".input-server-password"); const label_server_name = template.find(".server-name"); const label_server_region = template.find(".server-region"); const label_last_ping = template.find(".server-ping"); const label_client_count = template.find(".server-client-count"); const label_connection_count = template.find(".server-connection-count"); const update_buttons = () => { button_delete.prop("disabled", !selected_bookmark); button_connect.prop("disabled", !selected_bookmark || selected_bookmark.type !== bookmarks.BookmarkType.ENTRY); button_connect_tab.prop("disabled", !selected_bookmark || selected_bookmark.type !== bookmarks.BookmarkType.ENTRY); }; const update_connect_info = () => { if (selected_bookmark && selected_bookmark.type === bookmarks.BookmarkType.ENTRY) { const entry = selected_bookmark; const history = connection_log.history().find(e => e.address.hostname === entry.server_properties.server_address && e.address.port === entry.server_properties.server_port); if (history) { label_server_name.text(history.name); label_server_region.empty().append($.spawn("div").addClass("country flag-" + history.country.toLowerCase()), $.spawn("div").text(i18n.country_name(history.country, _translations.vheWLtP2 || (_translations.vheWLtP2 = tr("Global"))))); label_client_count.text(history.clients_online + "/" + history.clients_total); label_connection_count.empty().append(...MessageHelper.formatMessage(_translations.mBoCWnAP || (_translations.mBoCWnAP = tr("You've connected {} times")), $.spawn("div").addClass("connect-count").text(history.total_connection))); } else { label_server_name.text(_translations.Q3EMl6hY || (_translations.Q3EMl6hY = tr("Unknown"))); label_server_region.empty().text(_translations.hwuaCgCO || (_translations.hwuaCgCO = tr("Unknown"))); label_client_count.text(_translations.m6Nljdlg || (_translations.m6Nljdlg = tr("Unknown"))); label_connection_count.empty().append(...MessageHelper.formatMessage(_translations.x9AY7Kln || (_translations.x9AY7Kln = tr("You {} connected to that server address")), $.spawn("div").addClass("connect-never").text("never"))); } label_last_ping.text(_translations.nuFGAPOV || (_translations.nuFGAPOV = tr("Average ping isn't yet supported"))); } else { label_server_name.text("--"); label_server_region.text("--"); label_last_ping.text("--"); label_client_count.text("--"); label_connection_count.text("--"); } }; const update_selected = () => { input_bookmark_name.prop("disabled", !selected_bookmark); input_connect_profile.prop("disabled", !selected_bookmark || selected_bookmark.type !== bookmarks.BookmarkType.ENTRY); input_server_address.prop("disabled", !selected_bookmark || selected_bookmark.type !== bookmarks.BookmarkType.ENTRY); input_server_password.prop("disabled", !selected_bookmark || selected_bookmark.type !== bookmarks.BookmarkType.ENTRY); if (selected_bookmark) { input_bookmark_name.val(selected_bookmark.display_name); label_bookmark_name.text(selected_bookmark.display_name); } if (selected_bookmark && selected_bookmark.type === bookmarks.BookmarkType.ENTRY) { const entry = selected_bookmark; const address = entry.server_properties.server_address + (entry.server_properties.server_port == 9987 ? "" : (" " + entry.server_properties.server_port)); label_server_address.text(address); input_server_address.val(address); let profile = input_connect_profile.find("option[value='" + entry.connect_profile + "']"); if (profile.length == 0) profile = input_connect_profile.find("option[value=default]"); profile.prop("selected", true); input_server_password.val(entry.server_properties.server_password_hash || entry.server_properties.server_password ? "WolverinDEV" : ""); } else { input_server_password.val(""); input_server_address.val(""); input_connect_profile.find("option[value='no-value']").prop('selected', true); label_server_address.text(" "); } update_connect_info(); }; const container_bookmarks = template.find(".container-bookmarks"); const update_bookmark_list = (_current_selected) => { container_bookmarks.empty(); selected_bookmark = undefined; update_selected(); const hide_links = []; const build_entry = (entry, sibling_data, index) => { let container = $.spawn("div") .addClass(entry.type === bookmarks.BookmarkType.ENTRY ? "bookmark" : "directory") .addClass(index > 0 ? "linked" : "") .addClass(sibling_data.first ? "link-start" : ""); for (let i = 0; i < index; i++) { container.append($.spawn("div") .addClass("link") .addClass(i + 1 === index ? " connected" : "") .addClass(hide_links[i + 1] ? "hidden" : "")); } if (entry.type === bookmarks.BookmarkType.ENTRY) { const bookmark = entry; container.append(bookmark.last_icon_id ? IconManager.generate_tag(IconManager.load_cached_icon(bookmark.last_icon_id || 0), { animate: false }) : $.spawn("div").addClass("icon-container icon_em")); } else { container.append($.spawn("div").addClass("icon-container icon_em client-folder")); } container.append($.spawn("div").addClass("name").attr("title", entry.display_name).text(entry.display_name)); container.appendTo(container_bookmarks); container.on('click', event => { if (selected_bookmark === entry) return; selected_bookmark = entry; container_bookmarks.find(".selected").removeClass("selected"); container.addClass("selected"); update_buttons(); update_selected(); }); if (entry.unique_id === _current_selected) container.trigger('click'); hide_links.push(sibling_data.last); let cindex = 0; const children = entry.content || []; for (const child of children) build_entry(child, { first: cindex++ == 0, last: cindex == children.length }, index + 1); hide_links.pop(); }; let cindex = 0; const children = bookmarks.bookmarks().content; for (const bookmark of children) build_entry(bookmark, { first: cindex++ == 0, last: cindex == children.length }, 0); }; /* generate profile list */ { input_connect_profile.append($.spawn("option") .attr("value", "no-value") .text("") .css("display", "none")); for (const profile of profiles.profiles()) { input_connect_profile.append($.spawn("option") .attr("value", profile.id) .text(profile.profile_name)); } } /* buttons */ { button_delete.on('click', event => { if (!selected_bookmark) return; if (selected_bookmark.type === bookmarks.BookmarkType.DIRECTORY && selected_bookmark.content.length > 0) { Modals.spawnYesNo(_translations.Wlsrp0ec || (_translations.Wlsrp0ec = tr("Are you sure")), _translations.fPLYDIee || (_translations.fPLYDIee = tr("Do you really want to delete this non empty directory?")), answer => { if (answer) { bookmarks.delete_bookmark(selected_bookmark); bookmarks.save_bookmark(selected_bookmark); update_bookmark_list(undefined); } }); } else { bookmarks.delete_bookmark(selected_bookmark); bookmarks.save_bookmark(selected_bookmark); update_bookmark_list(undefined); } }); button_add_folder.on('click', event => { createInputModal(_translations.FXdq1lZN || (_translations.FXdq1lZN = tr("Enter a folder name")), _translations.QcWetQw3 || (_translations.QcWetQw3 = tr("Enter the folder name")), text => { return true; }, result => { if (result) { const mark = bookmarks.create_bookmark_directory(selected_bookmark ? selected_bookmark.type === bookmarks.BookmarkType.DIRECTORY ? selected_bookmark : selected_bookmark.parent : bookmarks.bookmarks(), result); bookmarks.save_bookmark(mark); update_bookmark_list(mark.unique_id); } }).open(); }); button_add_bookmark.on('click', event => { createInputModal(_translations.kRMVC8Kv || (_translations.kRMVC8Kv = tr("Enter a bookmark name")), _translations.rUYIwFuH || (_translations.rUYIwFuH = tr("Enter the bookmark name")), text => { return true; }, result => { if (result) { const mark = bookmarks.create_bookmark(result, selected_bookmark ? selected_bookmark.type === bookmarks.BookmarkType.DIRECTORY ? selected_bookmark : selected_bookmark.parent : bookmarks.bookmarks(), { server_password: "", server_port: 9987, server_address: "", server_password_hash: "" }, ""); bookmarks.save_bookmark(mark); update_bookmark_list(mark.unique_id); } }).open(); }); button_connect_tab.on('click', event => { bookmarks.boorkmak_connect(selected_bookmark, true); modal.close(); }).toggle(!settings.static_global(Settings.KEY_DISABLE_MULTI_SESSION)); button_connect.on('click', event => { bookmarks.boorkmak_connect(selected_bookmark, false); modal.close(); }); } /* inputs */ { input_bookmark_name.on('change keydown', event => { const name = input_bookmark_name.val(); const valid = name.length > 3; input_bookmark_name.firstParent(".input-boxed").toggleClass("is-invalid", !valid); if (event.type === "change" && valid) { selected_bookmark.display_name = name; label_bookmark_name.text(name); } }); input_server_address.on('change keydown', event => { const address = input_server_address.val(); const valid = !!address.match(Modals.Regex.IP_V4) || !!address.match(Modals.Regex.IP_V6) || !!address.match(Modals.Regex.DOMAIN); input_server_address.firstParent(".input-boxed").toggleClass("is-invalid", !valid); if (valid) { const entry = selected_bookmark; let _v6_end = address.indexOf(']'); let idx = address.lastIndexOf(':'); if (idx != -1 && idx > _v6_end) { entry.server_properties.server_port = parseInt(address.substr(idx + 1)); entry.server_properties.server_address = address.substr(0, idx); } else { entry.server_properties.server_address = address; entry.server_properties.server_port = 9987; } label_server_address.text(entry.server_properties.server_address + (entry.server_properties.server_port == 9987 ? "" : (" " + entry.server_properties.server_port))); update_connect_info(); } }); input_connect_profile.on('change', event => { const id = input_connect_profile.val(); const profile = profiles.profiles().find(e => e.id === id); if (profile) { selected_bookmark.connect_profile = id; } else { log.warn(LogCategory.GENERAL, _translations.x53hiZEu || (_translations.x53hiZEu = tr("Failed to change connect profile for profile %s to %s")), selected_bookmark.unique_id, id); } }); } /* Arrow key navigation for the bookmark list */ { let _focused = false; let _focus_listener; let _key_listener; _focus_listener = event => { _focused = false; let element = event.target; while (element) { if (element === container_bookmarks[0]) { _focused = true; break; } element = element.parentNode; } }; _key_listener = event => { if (!_focused) return; if (event.key.toLowerCase() === "arrowdown") { container_bookmarks.find(".selected").next().trigger('click'); } else if (event.key.toLowerCase() === "arrowup") { container_bookmarks.find(".selected").prev().trigger('click'); } }; document.addEventListener('click', _focus_listener); document.addEventListener('keydown', _key_listener); modal.close_listener.push(() => { document.removeEventListener('click', _focus_listener); document.removeEventListener('keydown', _key_listener); }); } update_bookmark_list(undefined); update_buttons(); template.find(".container-bookmarks").on('keydown', event => { console.error(event.key); }); template.find(".button-close").on('click', event => modal.close()); return template.children(); }, footer: undefined, width: "40em" }); modal.htmlTag.dividerfy().find(".modal-body").addClass("modal-bookmarks"); modal.close_listener.push(() => { control_bar.update_bookmarks(); top_menu.rebuild_bookmarks(); }); modal.open(); } Modals.spawnBookmarkModal = spawnBookmarkModal; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["0e23f86b74d3179ef83d3e49bd849b2e36271d501e8e6ae0dafe6ad5bf4fc1a1"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["0e23f86b74d3179ef83d3e49bd849b2e36271d501e8e6ae0dafe6ad5bf4fc1a1"] = "0e23f86b74d3179ef83d3e49bd849b2e36271d501e8e6ae0dafe6ad5bf4fc1a1"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["9956def2660d1b3f450e99957454a2512b88c5456b04ba6ea6622103ae26fe34"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["9956def2660d1b3f450e99957454a2512b88c5456b04ba6ea6622103ae26fe34"] = "9956def2660d1b3f450e99957454a2512b88c5456b04ba6ea6622103ae26fe34"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "rnpixUHv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChangeLatency.ts (14,21)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { let modal; function spawnChangeLatency(client, current, reset, apply, callback_flush) { if (modal) modal.close(); const begin = Object.assign({}, current); current = Object.assign({}, current); modal = createModal({ header: _translations.rnpixUHv || (_translations.rnpixUHv = tr("Change playback latency")), body: function () { let tag = $("#tmpl_change_latency").renderTag({ client: htmltags.generate_client_object({ add_braces: false, client_name: client.clientNickName(), client_unique_id: client.properties.client_unique_identifier, client_id: client.clientId() }), have_flush: (typeof (callback_flush) === "function") }); const update_value = () => { const valid = current.min_buffer < current.max_buffer; modal.htmlTag.find(".modal-body").toggleClass("modal-red", !valid); modal.htmlTag.find(".modal-body").toggleClass("modal-green", valid); if (!valid) return; apply(current); }; let slider_min, slider_max; { const container = tag.find(".container-min"); const tag_value = container.find(".value"); const slider_tag = container.find(".container-slider"); slider_min = sliderfy(slider_tag, { initial_value: current.min_buffer, step: 20, max_value: 1000, min_value: 0, unit: 'ms' }); slider_tag.on('change', event => { current.min_buffer = parseInt(slider_tag.attr("value")); tag_value.text(current.min_buffer + "ms"); update_value(); }); tag_value.text(current.min_buffer + "ms"); } { const container = tag.find(".container-max"); const tag_value = container.find(".value"); const slider_tag = container.find(".container-slider"); slider_max = sliderfy(slider_tag, { initial_value: current.max_buffer, step: 20, max_value: 1020, min_value: 20, unit: 'ms' }); slider_tag.on('change', event => { current.max_buffer = parseInt(slider_tag.attr("value")); tag_value.text(current.max_buffer + "ms"); update_value(); }); tag_value.text(current.max_buffer + "ms"); } setTimeout(update_value, 0); tag.find(".button-close").on('click', event => { modal.close(); }); tag.find(".button-cancel").on('click', event => { apply(begin); modal.close(); }); tag.find(".button-reset").on('click', event => { current = Object.assign({}, reset()); slider_max.value(current.max_buffer); slider_min.value(current.min_buffer); }); tag.find(".button-flush").on('click', event => callback_flush()); return tag.children(); }, footer: null, width: 600 }); modal.close_listener.push(() => modal = undefined); modal.open(); modal.htmlTag.find(".modal-body").addClass("modal-latency"); } Modals.spawnChangeLatency = spawnChangeLatency; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["11929b66a8fc3047cb47278d16ce2fb341d4e68bf2428ef134e561ea19cce86a"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["11929b66a8fc3047cb47278d16ce2fb341d4e68bf2428ef134e561ea19cce86a"] = "11929b66a8fc3047cb47278d16ce2fb341d4e68bf2428ef134e561ea19cce86a"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "I5sxCWb1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (6,21)" }, { name: "MWhXMLY3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (18,37)" }, { name: "RE2vZk9z", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (18,63)" }, { name: "QaIxrSq4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (47,41)" }, { name: "EnZqLY5O", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (52,33)" }, { name: "LSPBpazO", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (56,9)" }, { name: "b5HSmHYG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (57,9)" }, { name: "sEjNJjwa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (58,9)" }, { name: "mpF_YaoQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (59,9)" }, { name: "rKgUkVIE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (60,9)" }, { name: "UyvxGUrS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (61,9)" }, { name: "YHbfKEbb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (69,26)" }, { name: "BR_g0fBa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (71,26)" }, { name: "MhdcoTGM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (74,26)" }, { name: "mGNRZmBq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (81,26)" }, { name: "ndprpEHA", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (84,30)" }, { name: "m3R76_Ct", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (86,30)" }, { name: "oFX6TI_6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (88,60)" }, { name: "SOznTjw5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (98,37)" }, { name: "MoxbL41x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (108,26)" }, { name: "jXz3b_jU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (115,72)" }, { name: "BM72xXA7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (124,28)" }, { name: "sAPSOS4t", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (126,28)" }, { name: "l53YQJDt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (128,73)" }, { name: "f7A9CNx_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (128,93)" }, { name: "NJeT_LZU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (135,26)" }, { name: "O6LcaNSq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalChannelInfo.ts (137,26)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function openChannelInfo(channel) { let modal; modal = createModal({ header: (_translations.I5sxCWb1 || (_translations.I5sxCWb1 = tr("Channel information: "))) + channel.channelName(), body: () => { const template = $("#tmpl_channel_info").renderTag(); const update_values = (container) => { apply_channel_description(container.find(".container-description"), channel); apply_general(container, channel); }; template.find(".button-copy").on('click', event => { copy_to_clipboard(channel.properties.channel_description); createInfoModal(_translations.MWhXMLY3 || (_translations.MWhXMLY3 = tr("Description copied")), _translations.RE2vZk9z || (_translations.RE2vZk9z = tr("The channel description has been copied to your clipboard!"))).open(); }); const button_update = template.find(".button-update"); button_update.on('click', event => update_values(modal.htmlTag)); update_values(template); tooltip(template); return template.children(); }, footer: null, width: "65em" }); modal.htmlTag.find(".button-close").on('click', event => modal.close()); modal.htmlTag.find(".modal-body").addClass("modal-channel-info"); modal.open(); } Modals.openChannelInfo = openChannelInfo; function apply_channel_description(container, channel) { const container_value = container.find(".value"); const container_no_value = container.find(".no-value"); channel.getChannelDescription().then(description => { if (description) { const result = xbbcode.parse(description, {}); container_value[0].innerHTML = result.build_html(); container_no_value.hide(); container_value.show(); } else { container_no_value.text(_translations.QaIxrSq4 || (_translations.QaIxrSq4 = tr("Channel has no description"))); } }); container_value.hide(); container_no_value.text(_translations.EnZqLY5O || (_translations.EnZqLY5O = tr("loading..."))).show(); } const codec_names = [ _translations.LSPBpazO || (_translations.LSPBpazO = tr("Speex Narrowband")), _translations.b5HSmHYG || (_translations.b5HSmHYG = tr("Speex Wideband")), _translations.sEjNJjwa || (_translations.sEjNJjwa = tr("Speex Ultra-Wideband")), _translations.mpF_YaoQ || (_translations.mpF_YaoQ = tr("CELT Mono")), _translations.rKgUkVIE || (_translations.rKgUkVIE = tr("Opus Voice")), _translations.UyvxGUrS || (_translations.UyvxGUrS = tr("Opus Music")) ]; function apply_general(container, channel) { /* channel type */ { const tag = container.find(".channel-type .value").empty(); if (channel.properties.channel_flag_permanent) tag.text(_translations.YHbfKEbb || (_translations.YHbfKEbb = tr("Permanent"))); else if (channel.properties.channel_flag_semi_permanent) tag.text(_translations.BR_g0fBa || (_translations.BR_g0fBa = tr("Semi permanent"))); else //TODO: Channel delete delay! tag.text(_translations.MhdcoTGM || (_translations.MhdcoTGM = tr("Temporary"))); } /* chat mode */ { const tag = container.find(".chat-mode .value").empty(); if (channel.properties.channel_flag_conversation_private || channel.properties.channel_flag_password) { tag.text(_translations.mGNRZmBq || (_translations.mGNRZmBq = tr("Private"))); } else { if (channel.properties.channel_conversation_history_length == -1) tag.text(_translations.ndprpEHA || (_translations.ndprpEHA = tr("Public; Semi permanent message saving"))); else if (channel.properties.channel_conversation_history_length == 0) tag.text(_translations.m3R76_Ct || (_translations.m3R76_Ct = tr("Public; Permanent message saving"))); else tag.append(MessageHelper.formatMessage(_translations.oFX6TI_6 || (_translations.oFX6TI_6 = tr("Public; Saving last {} messages")), channel.properties.channel_conversation_history_length)); } } /* current clients */ { const tag = container.find(".current-clients .value").empty(); if (channel.flag_subscribed) { const current = channel.clients().length; let channel_limit = _translations.SOznTjw5 || (_translations.SOznTjw5 = tr("Unlimited")); if (!channel.properties.channel_flag_maxclients_unlimited) channel_limit = "" + channel.properties.channel_maxclients; else if (!channel.properties.channel_flag_maxfamilyclients_unlimited) { if (channel.properties.channel_maxfamilyclients >= 0) channel_limit = "" + channel.properties.channel_maxfamilyclients; } tag.text(current + " / " + channel_limit); } else { tag.text(_translations.MoxbL41x || (_translations.MoxbL41x = tr("Channel not subscribed"))); } } /* audio codec */ { const tag = container.find(".audio-codec .value").empty(); tag.text((codec_names[channel.properties.channel_codec] || (_translations.jXz3b_jU || (_translations.jXz3b_jU = tr("Unknown")))) + " (" + channel.properties.channel_codec_quality + ")"); } /* audio encrypted */ { const tag = container.find(".audio-encrypted .value").empty(); const mode = channel.channelTree.server.properties.virtualserver_codec_encryption_mode; let appendix; if (mode == 1) appendix = _translations.BM72xXA7 || (_translations.BM72xXA7 = tr("Overridden by the server with Unencrypted!")); else if (mode == 2) appendix = _translations.sAPSOS4t || (_translations.sAPSOS4t = tr("Overridden by the server with Encrypted!")); tag.html((channel.properties.channel_codec_is_unencrypted ? _translations.l53YQJDt || (_translations.l53YQJDt = tr("Unencrypted")) : _translations.f7A9CNx_ || (_translations.f7A9CNx_ = tr("Encrypted"))) + (appendix ? "
" + appendix : "")); } /* flag password */ { const tag = container.find(".flag-password .value").empty(); if (channel.properties.channel_flag_password) tag.text(_translations.NJeT_LZU || (_translations.NJeT_LZU = tr("Yes"))); else tag.text(_translations.O6LcaNSq || (_translations.O6LcaNSq = tr("No"))); } /* topic */ { const container_tag = container.find(".topic"); const tag = container_tag.find(".value").empty(); if (channel.properties.channel_topic) { container_tag.show(); tag.text(channel.properties.channel_topic); } else { container_tag.hide(); } } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3e0d934846e6678af688be0aae682a444a3e95e9842710b8911212ab336fc824"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3e0d934846e6678af688be0aae682a444a3e95e9842710b8911212ab336fc824"] = "3e0d934846e6678af688be0aae682a444a3e95e9842710b8911212ab336fc824"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "q4nJUy60", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (8,21)" }, { name: "yHGa0IfR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (61,58)" }, { name: "fmWIsvZh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (61,72)" }, { name: "wBmsWQ1W", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (67,58)" }, { name: "xHHtl43Q", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (67,71)" }, { name: "JUA4eXwZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (73,58)" }, { name: "wXLHZg4c", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (73,72)" }, { name: "vutnPHSB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (79,58)" }, { name: "ZdTd3wyS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (79,74)" }, { name: "au_VFD3u", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (85,58)" }, { name: "gJBoJ4Ma", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (85,74)" }, { name: "GUq7Pfeo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (132,33)" }, { name: "PFTGjDJA", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (132,57)" }, { name: "oLMwSJYc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (145,36)" }, { name: "AxikKxHc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (147,36)" }, { name: "zskgIt4S", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (149,36)" }, { name: "gSwEalIF", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (157,52)" }, { name: "DvkrY7gD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (194,87)" }, { name: "Jn3_cGLt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (202,24)" }, { name: "jmL5o4nI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (206,33)" }, { name: "Tz0k6vyV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (206,57)" }, { name: "O1OHNB8l", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (210,122)" }, { name: "RTQwXVHs", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (218,45)" }, { name: "NXeVdyQD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (222,49)" }, { name: "Rcficr3s", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (230,45)" }, { name: "DRUtOKKo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (234,49)" }, { name: "fAGxWnB9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (245,87)" }, { name: "S2krnqJS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (259,77)" }, { name: "bzbgZkFM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (261,34)" }, { name: "SkjAXN3e", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (275,42)" }, { name: "FjOC00RC", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (277,42)" }, { name: "kIMQ6Lut", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (279,34)" }, { name: "SjS4iMTN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (306,92)" }, { name: "vozQRN8R", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (336,104)" }, { name: "vdSpi1jT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (338,45)" }, { name: "syz7QWKN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (343,100)" }, { name: "icJiGa8t", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (345,43)" }, { name: "a7UYf6jl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (362,53)" }, { name: "Rghh2BiN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (366,45)" }, { name: "YhgjzYlu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (376,51)" }, { name: "XAulSBWk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (380,43)" }, { name: "jstU8KwW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (397,53)" }, { name: "iizJRjxp", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (401,45)" }, { name: "hsKLHain", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (411,51)" }, { name: "NAdmQZoI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (415,43)" }, { name: "dP3HUqzO", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (432,53)" }, { name: "i2XrSfWG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (436,45)" }, { name: "KB1Gb7t_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (446,51)" }, { name: "O0s5zgie", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (450,43)" }, { name: "AkeqGziU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (467,53)" }, { name: "HWcY62Qh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (471,45)" }, { name: "s0iM_F0m", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (481,51)" }, { name: "ks4dg80v", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (485,43)" }, { name: "j8hYfOEQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (500,45)" }, { name: "Zf4MdfLy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalClientInfo.ts (508,43)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function openClientInfo(client) { let modal; let update_callbacks = []; modal = createModal({ header: (_translations.q4nJUy60 || (_translations.q4nJUy60 = tr("Profile Information: "))) + client.clientNickName(), body: () => { const template = $("#tmpl_client_info").renderTag(); /* the tab functionality */ { const container_tabs = template.find(".container-categories"); container_tabs.find(".categories .entry").on('click', event => { const entry = $(event.target); container_tabs.find(".bodies > .body").addClass("hidden"); container_tabs.find(".categories > .selected").removeClass("selected"); entry.addClass("selected"); container_tabs.find(".bodies > .body." + entry.attr("container")).removeClass("hidden"); }); container_tabs.find(".entry").first().trigger('click'); } apply_static_info(client, template, modal, update_callbacks); apply_client_status(client, template, modal, update_callbacks); apply_basic_info(client, template.find(".container-basic"), modal, update_callbacks); apply_groups(client, template.find(".container-groups"), modal, update_callbacks); apply_packets(client, template.find(".container-packets"), modal, update_callbacks); tooltip(template); return template.children(); }, footer: null, width: '60em' }); const updater = setInterval(() => { client.request_connection_info().then(info => update_callbacks.forEach(e => e(info))); }, 1000); modal.htmlTag.find(".modal-body").addClass("modal-client-info"); modal.open(); modal.close_listener.push(() => clearInterval(updater)); } Modals.openClientInfo = openClientInfo; const TIME_SECOND = 1000; const TIME_MINUTE = 60 * TIME_SECOND; const TIME_HOUR = 60 * TIME_MINUTE; const TIME_DAY = 24 * TIME_HOUR; const TIME_WEEK = 7 * TIME_DAY; function format_time(time, default_value) { let result = ""; if (time > TIME_WEEK) { const amount = Math.floor(time / TIME_WEEK); result += " " + amount + " " + (amount > 1 ? _translations.yHGa0IfR || (_translations.yHGa0IfR = tr("Weeks")) : _translations.fmWIsvZh || (_translations.fmWIsvZh = tr("Week"))); time -= amount * TIME_WEEK; } if (time > TIME_DAY) { const amount = Math.floor(time / TIME_DAY); result += " " + amount + " " + (amount > 1 ? _translations.wBmsWQ1W || (_translations.wBmsWQ1W = tr("Days")) : _translations.xHHtl43Q || (_translations.xHHtl43Q = tr("Day"))); time -= amount * TIME_DAY; } if (time > TIME_HOUR) { const amount = Math.floor(time / TIME_HOUR); result += " " + amount + " " + (amount > 1 ? _translations.JUA4eXwZ || (_translations.JUA4eXwZ = tr("Hours")) : _translations.wXLHZg4c || (_translations.wXLHZg4c = tr("Hour"))); time -= amount * TIME_HOUR; } if (time > TIME_MINUTE) { const amount = Math.floor(time / TIME_MINUTE); result += " " + amount + " " + (amount > 1 ? _translations.vutnPHSB || (_translations.vutnPHSB = tr("Minutes")) : _translations.ZdTd3wyS || (_translations.ZdTd3wyS = tr("Minute"))); time -= amount * TIME_MINUTE; } if (time > TIME_SECOND) { const amount = Math.floor(time / TIME_SECOND); result += " " + amount + " " + (amount > 1 ? _translations.au_VFD3u || (_translations.au_VFD3u = tr("Seconds")) : _translations.gJBoJ4Ma || (_translations.gJBoJ4Ma = tr("Second"))); time -= amount * TIME_SECOND; } return result.length > 0 ? result.substring(1) : default_value; } function apply_static_info(client, tag, modal, callbacks) { tag.find(".container-avatar").append(client.channelTree.client.fileManager.avatars.generate_chat_tag({ database_id: client.properties.client_database_id, id: client.clientId() }, client.properties.client_unique_identifier)); tag.find(".container-name").append(client.createChatTag()); tag.find(".client-description").text(client.properties.client_description); } function apply_client_status(client, tag, modal, callbacks) { tag.find(".status-output-disabled").toggle(!client.properties.client_output_hardware); tag.find(".status-input-disabled").toggle(!client.properties.client_input_hardware); tag.find(".status-output-muted").toggle(client.properties.client_output_muted); tag.find(".status-input-muted").toggle(client.properties.client_input_muted); tag.find(".status-away").toggle(client.properties.client_away); if (client.properties.client_away_message) { tag.find(".container-away-message").show().find("a").text(client.properties.client_away_message); } else { tag.find(".container-away-message").hide(); } } function apply_basic_info(client, tag, modal, callbacks) { /* Unique ID */ { const container = tag.find(".property-unique-id"); container.find(".value a").text(client.clientUid()); container.find(".value-dbid").text(client.properties.client_database_id); container.find(".button-copy").on('click', event => { copy_to_clipboard(client.clientUid()); createInfoModal(_translations.GUq7Pfeo || (_translations.GUq7Pfeo = tr("Unique ID copied")), _translations.PFTGjDJA || (_translations.PFTGjDJA = tr("The unique id has been copied to your clipboard!"))).open(); }); } /* TeaForo */ { const container = tag.find(".property-teaforo .value").empty(); if (client.properties.client_teaforo_id) { container.children().remove(); let text = client.properties.client_teaforo_name; if ((client.properties.client_teaforo_flags & 0x01) > 0) text += " (" + (_translations.oLMwSJYc || (_translations.oLMwSJYc = tr("Banned"))) + ")"; if ((client.properties.client_teaforo_flags & 0x02) > 0) text += " (" + (_translations.AxikKxHc || (_translations.AxikKxHc = tr("Stuff"))) + ")"; if ((client.properties.client_teaforo_flags & 0x04) > 0) text += " (" + (_translations.zskgIt4S || (_translations.zskgIt4S = tr("Premium"))) + ")"; $.spawn("a") .attr("href", "https://forum.teaspeak.de/index.php?members/" + client.properties.client_teaforo_id) .attr("target", "_blank") .text(text) .appendTo(container); } else { container.append($.spawn("a").text(_translations.gSwEalIF || (_translations.gSwEalIF = tr("Not connected")))); } } /* Version */ { const container = tag.find(".property-version"); let version_full = client.properties.client_version; let version = version_full.substring(0, version_full.indexOf(" ")); container.find(".value").empty().append($.spawn("a").attr("title", version_full).text(version), $.spawn("a").addClass("a-on").text("on"), $.spawn("a").text(client.properties.client_platform)); const container_timestamp = container.find(".container-tooltip"); let timestamp = -1; version_full.replace(/\[build: ?([0-9]+)]/gmi, (group, ts) => { timestamp = parseInt(ts); return ""; }); if (timestamp > 0) { container_timestamp.find(".value-timestamp").text(moment(timestamp * 1000).format('MMMM Do YYYY, h:mm:ss a')); container_timestamp.show(); } else { container_timestamp.hide(); } } /* Country */ { const container = tag.find(".property-country"); container.find(".value").empty().append($.spawn("div").addClass("country flag-" + client.properties.client_country.toLowerCase()), $.spawn("a").text(i18n.country_name(client.properties.client_country, _translations.DvkrY7gD || (_translations.DvkrY7gD = tr("Unknown"))))); } /* IP Address */ { const container = tag.find(".property-ip"); const value = container.find(".value a"); value.text(_translations.Jn3_cGLt || (_translations.Jn3_cGLt = tr("loading..."))); container.find(".button-copy").on('click', event => { copy_to_clipboard(value.text()); createInfoModal(_translations.jmL5o4nI || (_translations.jmL5o4nI = tr("Client IP copied")), _translations.Tz0k6vyV || (_translations.Tz0k6vyV = tr("The client IP has been copied to your clipboard!"))).open(); }); callbacks.push(info => { value.text(info.connection_client_ip ? (info.connection_client_ip + ":" + info.connection_client_port) : _translations.O1OHNB8l || (_translations.O1OHNB8l = tr("Hidden"))); }); } /* first connected */ { const container = tag.find(".property-first-connected"); container.find(".value a").text(_translations.RTQwXVHs || (_translations.RTQwXVHs = tr("loading..."))); client.updateClientVariables().then(() => { container.find(".value a").text(moment(client.properties.client_created * 1000).format('MMMM Do YYYY, h:mm:ss a')); }).catch(error => { container.find(".value a").text(_translations.NXeVdyQD || (_translations.NXeVdyQD = tr("error"))); }); } /* connect count */ { const container = tag.find(".property-connect-count"); container.find(".value a").text(_translations.Rcficr3s || (_translations.Rcficr3s = tr("loading..."))); client.updateClientVariables().then(() => { container.find(".value a").text(client.properties.client_totalconnections); }).catch(error => { container.find(".value a").text(_translations.DRUtOKKo || (_translations.DRUtOKKo = tr("error"))); }); } /* Online since */ { const container = tag.find(".property-online-since"); const node = container.find(".value a")[0]; if (node) { const update = () => { node.innerText = format_time(client.calculateOnlineTime() * 1000, _translations.fAGxWnB9 || (_translations.fAGxWnB9 = tr("0 Seconds"))); }; callbacks.push(update); /* keep it in sync with all other updates. Else it looks wired */ update(); } } /* Idle time */ { const container = tag.find(".property-idle-time"); const node = container.find(".value a")[0]; if (node) { callbacks.push(info => { node.innerText = format_time(info.connection_idle_time, _translations.S2krnqJS || (_translations.S2krnqJS = tr("Currently active"))); }); node.innerText = _translations.bzbgZkFM || (_translations.bzbgZkFM = tr("loading...")); } } /* ping */ { const container = tag.find(".property-ping"); const node = container.find(".value a")[0]; if (node) { callbacks.push(info => { if (info.connection_ping >= 0) node.innerText = info.connection_ping.toFixed(0) + "ms ± " + info.connection_ping_deviation.toFixed(2) + "ms"; else if (info.connection_ping == -1 && info.connection_ping_deviation == -1) node.innerText = _translations.SkjAXN3e || (_translations.SkjAXN3e = tr("Not calculated")); else node.innerText = _translations.FjOC00RC || (_translations.FjOC00RC = tr("loading...")); }); node.innerText = _translations.kIMQ6Lut || (_translations.kIMQ6Lut = tr("loading...")); } } } function apply_groups(client, tag, modal, callbacks) { /* server groups */ { const container_entries = tag.find(".entries"); const container_empty = tag.find(".container-default-groups"); const update_groups = () => { container_entries.empty(); container_empty.show(); for (const group_id of client.assignedServerGroupIds()) { if (group_id == client.channelTree.server.properties.virtualserver_default_server_group) continue; const group = client.channelTree.client.groups.serverGroup(group_id); if (!group) continue; //This shall never happen! container_empty.hide(); container_entries.append($.spawn("div").addClass("entry").append(client.channelTree.client.fileManager.icons.generateTag(group.properties.iconid), $.spawn("a").addClass("name").text(group.name + " (" + group.id + ")"), $.spawn("div").addClass("button-delete").append($.spawn("div").addClass("icon_em client-delete").attr("title", _translations.SjS4iMTN || (_translations.SjS4iMTN = tr("Delete group"))).on('click', event => { client.channelTree.client.serverConnection.send_command("servergroupdelclient", { sgid: group.id, cldbid: client.properties.client_database_id }).then(result => update_groups()); })).toggleClass("visible", client.channelTree.client.permissions.neededPermission(PermissionType.I_SERVER_GROUP_MEMBER_REMOVE_POWER).granted(group.requiredMemberRemovePower) || client.clientId() == client.channelTree.client.getClientId() && client.channelTree.client.permissions.neededPermission(PermissionType.I_SERVER_GROUP_SELF_REMOVE_POWER).granted(group.requiredMemberRemovePower)))); } }; tag.find(".button-group-add").on('click', () => client.open_assignment_modal()); update_groups(); } } function apply_packets(client, tag, modal, callbacks) { /* Packet Loss */ { const container = tag.find(".statistic-packet-loss"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { callbacks.push(info => { node_downstream.innerText = info.connection_server2client_packetloss_control < 0 ? _translations.vozQRN8R || (_translations.vozQRN8R = tr("Not calculated")) : (info.connection_server2client_packetloss_control || 0).toFixed(); }); node_downstream.innerText = _translations.vdSpi1jT || (_translations.vdSpi1jT = tr("loading...")); } if (node_upstream) { callbacks.push(info => { node_upstream.innerText = info.connection_client2server_packetloss_total < 0 ? _translations.syz7QWKN || (_translations.syz7QWKN = tr("Not calculated")) : (info.connection_client2server_packetloss_total || 0).toFixed(); }); node_upstream.innerText = _translations.icJiGa8t || (_translations.icJiGa8t = tr("loading...")); } } /* Packets transmitted */ { const container = tag.find(".statistic-transmitted-packets"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { callbacks.push(info => { let packets = 0; packets += info.connection_packets_received_speech > 0 ? info.connection_packets_received_speech : 0; packets += info.connection_packets_received_control > 0 ? info.connection_packets_received_control : 0; packets += info.connection_packets_received_keepalive > 0 ? info.connection_packets_received_keepalive : 0; if (packets == 0 && info.connection_packets_received_keepalive == -1) node_downstream.innerText = _translations.a7UYf6jl || (_translations.a7UYf6jl = tr("Not calculated")); else node_downstream.innerText = MessageHelper.format_number(packets, { unit: "Packets" }); }); node_downstream.innerText = _translations.Rghh2BiN || (_translations.Rghh2BiN = tr("loading...")); } if (node_upstream) { callbacks.push(info => { let packets = 0; packets += info.connection_packets_sent_speech > 0 ? info.connection_packets_sent_speech : 0; packets += info.connection_packets_sent_control > 0 ? info.connection_packets_sent_control : 0; packets += info.connection_packets_sent_keepalive > 0 ? info.connection_packets_sent_keepalive : 0; if (packets == 0 && info.connection_packets_sent_keepalive == -1) node_upstream.innerText = _translations.YhgjzYlu || (_translations.YhgjzYlu = tr("Not calculated")); else node_upstream.innerText = MessageHelper.format_number(packets, { unit: "Packets" }); }); node_upstream.innerText = _translations.XAulSBWk || (_translations.XAulSBWk = tr("loading...")); } } /* Bytes transmitted */ { const container = tag.find(".statistic-transmitted-bytes"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bytes_received_speech > 0 ? info.connection_bytes_received_speech : 0; bytes += info.connection_bytes_received_control > 0 ? info.connection_bytes_received_control : 0; bytes += info.connection_bytes_received_keepalive > 0 ? info.connection_bytes_received_keepalive : 0; if (bytes == 0 && info.connection_bytes_received_keepalive == -1) node_downstream.innerText = _translations.jstU8KwW || (_translations.jstU8KwW = tr("Not calculated")); else node_downstream.innerText = MessageHelper.network.format_bytes(bytes); }); node_downstream.innerText = _translations.iizJRjxp || (_translations.iizJRjxp = tr("loading...")); } if (node_upstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bytes_sent_speech > 0 ? info.connection_bytes_sent_speech : 0; bytes += info.connection_bytes_sent_control > 0 ? info.connection_bytes_sent_control : 0; bytes += info.connection_bytes_sent_keepalive > 0 ? info.connection_bytes_sent_keepalive : 0; if (bytes == 0 && info.connection_bytes_sent_keepalive == -1) node_upstream.innerText = _translations.hsKLHain || (_translations.hsKLHain = tr("Not calculated")); else node_upstream.innerText = MessageHelper.network.format_bytes(bytes); }); node_upstream.innerText = _translations.NAdmQZoI || (_translations.NAdmQZoI = tr("loading...")); } } /* Bandwidth second */ { const container = tag.find(".statistic-bandwidth-second"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bandwidth_received_last_second_speech > 0 ? info.connection_bandwidth_received_last_second_speech : 0; bytes += info.connection_bandwidth_received_last_second_control > 0 ? info.connection_bandwidth_received_last_second_control : 0; bytes += info.connection_bandwidth_received_last_second_keepalive > 0 ? info.connection_bandwidth_received_last_second_keepalive : 0; if (bytes == 0 && info.connection_bandwidth_received_last_second_keepalive == -1) node_downstream.innerText = _translations.dP3HUqzO || (_translations.dP3HUqzO = tr("Not calculated")); else node_downstream.innerText = MessageHelper.network.format_bytes(bytes, { time: "s" }); }); node_downstream.innerText = _translations.i2XrSfWG || (_translations.i2XrSfWG = tr("loading...")); } if (node_upstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bandwidth_sent_last_second_speech > 0 ? info.connection_bandwidth_sent_last_second_speech : 0; bytes += info.connection_bandwidth_sent_last_second_control > 0 ? info.connection_bandwidth_sent_last_second_control : 0; bytes += info.connection_bandwidth_sent_last_second_keepalive > 0 ? info.connection_bandwidth_sent_last_second_keepalive : 0; if (bytes == 0 && info.connection_bandwidth_sent_last_second_keepalive == -1) node_upstream.innerText = _translations.KB1Gb7t_ || (_translations.KB1Gb7t_ = tr("Not calculated")); else node_upstream.innerText = MessageHelper.network.format_bytes(bytes, { time: "s" }); }); node_upstream.innerText = _translations.O0s5zgie || (_translations.O0s5zgie = tr("loading...")); } } /* Bandwidth minute */ { const container = tag.find(".statistic-bandwidth-minute"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bandwidth_received_last_minute_speech > 0 ? info.connection_bandwidth_received_last_minute_speech : 0; bytes += info.connection_bandwidth_received_last_minute_control > 0 ? info.connection_bandwidth_received_last_minute_control : 0; bytes += info.connection_bandwidth_received_last_minute_keepalive > 0 ? info.connection_bandwidth_received_last_minute_keepalive : 0; if (bytes == 0 && info.connection_bandwidth_received_last_minute_keepalive == -1) node_downstream.innerText = _translations.AkeqGziU || (_translations.AkeqGziU = tr("Not calculated")); else node_downstream.innerText = MessageHelper.network.format_bytes(bytes, { time: "s" }); }); node_downstream.innerText = _translations.HWcY62Qh || (_translations.HWcY62Qh = tr("loading...")); } if (node_upstream) { callbacks.push(info => { let bytes = 0; bytes += info.connection_bandwidth_sent_last_minute_speech > 0 ? info.connection_bandwidth_sent_last_minute_speech : 0; bytes += info.connection_bandwidth_sent_last_minute_control > 0 ? info.connection_bandwidth_sent_last_minute_control : 0; bytes += info.connection_bandwidth_sent_last_minute_keepalive > 0 ? info.connection_bandwidth_sent_last_minute_keepalive : 0; if (bytes == 0 && info.connection_bandwidth_sent_last_minute_keepalive == -1) node_upstream.innerText = _translations.s0iM_F0m || (_translations.s0iM_F0m = tr("Not calculated")); else node_upstream.innerText = MessageHelper.network.format_bytes(bytes, { time: "s" }); }); node_upstream.innerText = _translations.ks4dg80v || (_translations.ks4dg80v = tr("loading...")); } } /* quota */ { const container = tag.find(".statistic-quota"); const node_downstream = container.find(".downstream .value")[0]; const node_upstream = container.find(".upstream .value")[0]; if (node_downstream) { client.updateClientVariables().then(info => { //TODO: Test for own client info and if so then show the max quota (needed permission) node_downstream.innerText = MessageHelper.network.format_bytes(client.properties.client_month_bytes_downloaded, { exact: false }); }); node_downstream.innerText = _translations.j8hYfOEQ || (_translations.j8hYfOEQ = tr("loading...")); } if (node_upstream) { client.updateClientVariables().then(info => { //TODO: Test for own client info and if so then show the max quota (needed permission) node_upstream.innerText = MessageHelper.network.format_bytes(client.properties.client_month_bytes_uploaded, { exact: false }); }); node_upstream.innerText = _translations.Zf4MdfLy || (_translations.Zf4MdfLy = tr("loading...")); } } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5bc7b026ccd4fdff697caf41b4c42b847d0401f9506454a667d610d3f97f0462"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5bc7b026ccd4fdff697caf41b4c42b847d0401f9506454a667d610d3f97f0462"] = "5bc7b026ccd4fdff697caf41b4c42b847d0401f9506454a667d610d3f97f0462"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "IhOda4YW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalGroupAssignment.ts (8,21)" }, { name: "VqL4CmtZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalGroupAssignment.ts (43,42)" }, { name: "TvHg9OzB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalGroupAssignment.ts (48,97)" }, { name: "IAFhqbSA", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalGroupAssignment.ts (64,91)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { let current_modal; function createServerGroupAssignmentModal(client, callback) { if (current_modal) current_modal.close(); current_modal = createModal({ header: _translations.IhOda4YW || (_translations.IhOda4YW = tr("Server Groups")), body: () => { let tag = {}; let groups = tag["groups"] = []; tag["client"] = client.createChatTag(); const _groups = client.channelTree.client.groups.serverGroups.sort(GroupManager.sorter()); for (let group of _groups) { if (group.type != GroupType.NORMAL) continue; let entry = {}; entry["id"] = group.id; entry["name"] = group.name; entry["disabled"] = !client.channelTree.client.permissions.neededPermission(PermissionType.I_GROUP_MEMBER_ADD_POWER).granted(group.requiredMemberRemovePower); entry["default"] = client.channelTree.server.properties.virtualserver_default_server_group == group.id; tag["icon_" + group.id] = client.channelTree.client.fileManager.icons.generateTag(group.properties.iconid); groups.push(entry); } let template = $("#tmpl_server_group_assignment").renderTag(tag); const update_groups = () => { for (let group of _groups) { template.find("input[group-id='" + group.id + "']").prop("checked", client.groupAssigned(group)); } }; template.find(".group-entry input").each((_idx, _entry) => { let entry = $(_entry); entry.on('change', event => { let group_id = parseInt(entry.attr("group-id")); let group = client.channelTree.client.groups.serverGroup(group_id); if (!group) { console.warn(_translations.VqL4CmtZ || (_translations.VqL4CmtZ = tr("Could not resolve target group!"))); return false; } let target = entry.prop("checked"); callback([group.id], target).catch(e => { log.warn(LogCategory.GENERAL, _translations.TvHg9OzB || (_translations.TvHg9OzB = tr("Failed to change group assignment: %o")), e); }).then(update_groups); }); }); template.find(".button-close").on('click', () => current_modal.close()); template.find(".button-remove-all").on('click', () => { const group_ids = []; template.find(".group-entry input").each((_idx, _entry) => { let entry = $(_entry); if (entry.attr("default") !== undefined || !entry.prop("checked")) return; group_ids.push(parseInt(entry.attr("group-id"))); }); callback(group_ids, false).catch(e => { log.warn(LogCategory.GENERAL, _translations.IAFhqbSA || (_translations.IAFhqbSA = tr("Failed to remove all group assignments: %o")), e); }).then(update_groups); }); update_groups(); return template; }, footer: null, min_width: "10em" }); current_modal.htmlTag.find(".modal-body").addClass("modal-server-group-assignments"); current_modal.close_listener.push(() => current_modal = undefined); current_modal.open(); } Modals.createServerGroupAssignmentModal = createServerGroupAssignmentModal; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["6ddbc806d1e545bfbe7cd6edfda70c9a909461095cf3c503ccf9a1e9c6e456f2"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["6ddbc806d1e545bfbe7cd6edfda70c9a909461095cf3c503ccf9a1e9c6e456f2"] = "6ddbc806d1e545bfbe7cd6edfda70c9a909461095cf3c503ccf9a1e9c6e456f2"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "CQoIZUkg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (11,21)" }, { name: "zoVj4N6w", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (98,59)" }, { name: "aGhDORx1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (136,52)" }, { name: "Ygeok_Hp", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (137,42)" }, { name: "OKoqOjb_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (149,30)" }, { name: "V9FDbgFE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (158,30)" }, { name: "_KpIpBvt", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (162,34)" }, { name: "WTCs0FZc", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (204,27)" }, { name: "OBdh35e5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (205,30)" }, { name: "weFhyRXi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (211,27)" }, { name: "slnJLUnr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (212,30)" }, { name: "ZQUb3mnr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (228,35)" }, { name: "PM2yox2o", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (229,38)" }, { name: "Hdzgrw14", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (236,35)" }, { name: "haFBfmL2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (237,38)" }, { name: "fWTWB0rC", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (246,39)" }, { name: "rXQ9XpMl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (247,42)" }, { name: "qwKMVZCa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (253,33)" }, { name: "FKg8ziMk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (255,39)" }, { name: "jbJiQdmE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (256,42)" }, { name: "Cnm0yzhD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (276,35)" }, { name: "nP_b16tY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (277,38)" }, { name: "VWE0wbL5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (282,35)" }, { name: "p7VzcfRi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (283,38)" }, { name: "LRMQF4bW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (340,37)" }, { name: "iPgGKIpi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (358,31)" }, { name: "TveVOKL0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (364,41)" }, { name: "Sdb1D0Df", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (368,39)" }, { name: "hPVhYCvy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (373,35)" }, { name: "Xqb7msAQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (381,37)" }, { name: "evYSGDAg", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (397,45)" }, { name: "gJb1dy46", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (402,39)" }, { name: "fYxv3EsZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (403,39)" }, { name: "kU_0puQM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (408,37)" }, { name: "EPY4nTY6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (414,39)" }, { name: "CqQcLAq4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (416,43)" }, { name: "NyIZkcuR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (418,43)" }, { name: "bt6ItaiX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (420,43)" }, { name: "x9YWUXAH", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (429,37)" }, { name: "wn8NJP_6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (440,21)" }, { name: "F2IChL3l", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (582,39)" }, { name: "mO_jmbzr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIconSelect.ts (586,39)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function spawnIconSelect(client, callback_icon, selected_icon) { selected_icon = selected_icon || 0; let allow_manage = client.permissions.neededPermission(PermissionType.B_ICON_MANAGE).granted(1); const modal = createModal({ header: _translations.CQoIZUkg || (_translations.CQoIZUkg = tr("Icons")), footer: undefined, body: () => { return $("#tmpl_icon_select").renderTag({ enable_select: !!callback_icon, enable_upload: allow_manage, enable_delete: allow_manage }); }, min_width: "20em" }); modal.htmlTag.find(".modal-body").addClass("modal-icon-select"); const button_select = modal.htmlTag.find(".button-select"); const button_delete = modal.htmlTag.find(".button-delete").prop("disabled", true); const button_upload = modal.htmlTag.find(".button-upload").prop("disabled", !allow_manage); const container_loading = modal.htmlTag.find(".container-loading").hide(); const container_no_permissions = modal.htmlTag.find(".container-no-permissions").hide(); const container_error = modal.htmlTag.find(".container-error").hide(); const selected_container = modal.htmlTag.find(".selected-item-container"); const container_icons = modal.htmlTag.find(".container-icons"); const container_icons_remote = container_icons.find(".container-icons-remote"); const container_icons_local = container_icons.find(".container-icons-local"); const update_local_icons = (icons) => { container_icons_local.empty(); for (const icon_id of icons) { const tag = client.fileManager.icons.generateTag(icon_id, { animate: false }).attr('title', "Icon " + icon_id); if (callback_icon) { tag.on('click', event => { container_icons.find(".selected").removeClass("selected"); tag.addClass("selected"); selected_container.empty().append(tag.clone()); selected_icon = icon_id; button_select.prop("disabled", false); }); tag.on('dblclick', event => { callback_icon(icon_id); modal.close(); }); if (icon_id == selected_icon) tag.trigger('click'); } tag.appendTo(container_icons_local); } }; const update_remote_icons = () => { container_no_permissions.hide(); container_error.hide(); container_loading.show(); const display_remote_error = (error) => { if (typeof (error) === "string") { container_error.find(".error-message").text(error); container_error.show(); } else { container_error.hide(); } }; client.fileManager.requestFileList("/icons").then(icons => { const container_icons_remote_parent = container_icons_remote.parent(); container_icons_remote.detach().empty(); const chunk_size = 50; const icon_chunks = []; let index = 0; while (icons.length > index) { icon_chunks.push(icons.slice(index, index + chunk_size)); index += chunk_size; } const process_next_chunk = () => { const chunk = icon_chunks.pop_front(); if (!chunk) return; for (const icon of chunk) { const icon_id = parseInt(icon.name.substr("icon_".length)); if (Number.isNaN(icon_id)) { log.warn(LogCategory.GENERAL, _translations.zoVj4N6w || (_translations.zoVj4N6w = tr("Received an unparsable icon within icon list (%o)")), icon); continue; } const tag = client.fileManager.icons.generateTag(icon_id, { animate: false }).attr('title', "Icon " + icon_id); if (callback_icon || allow_manage) { tag.on('click', event => { container_icons.find(".selected").removeClass("selected"); tag.addClass("selected"); selected_container.empty().append(tag.clone()); selected_icon = icon_id; button_select.prop("disabled", false); button_delete.prop("disabled", !allow_manage); }); tag.on('dblclick', event => { if (!callback_icon) return; callback_icon(icon_id); modal.close(); }); if (icon_id == selected_icon) tag.trigger('click'); } tag.appendTo(container_icons_remote); } setTimeout(process_next_chunk, 100); }; process_next_chunk(); container_icons_remote_parent.append(container_icons_remote); container_error.hide(); container_loading.hide(); container_no_permissions.hide(); }).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.PERMISSION_ERROR) { container_no_permissions.show(); } else { log.error(LogCategory.GENERAL, _translations.aGhDORx1 || (_translations.aGhDORx1 = tr("Failed to fetch icon list. Error: %o")), error); display_remote_error(_translations.Ygeok_Hp || (_translations.Ygeok_Hp = tr("Failed to fetch icon list"))); } container_loading.hide(); }); }; button_delete.on('click', event => { if (!selected_icon) return; const selected = modal.htmlTag.find(".selected"); if (selected.length != 1) console.warn(_translations.OKoqOjb_ || (_translations.OKoqOjb_ = tr("UI selected icon length does not equal with 1! (%o)")), selected.length); if (selected_icon < 1000) return; /* we cant delete local icons */ client.fileManager.icons.delete_icon(selected_icon).then(() => { selected.detach(); }).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.PERMISSION_ERROR) return; console.warn(_translations.V9FDbgFE || (_translations.V9FDbgFE = tr("Failed to delete icon %d: %o")), selected_icon, error); error = error instanceof CommandResult ? error.extra_message || error.message : error; createErrorModal(_translations._KpIpBvt || (_translations._KpIpBvt = tr("Failed to delete icon")), tra("Failed to delete icon.
Error: ", error)).open(); }); }); button_upload.on('click', event => spawnIconUpload(client)); update_local_icons([100, 200, 300, 500, 600]); update_remote_icons(); modal.htmlTag.find('.button-reload').on('click', () => update_remote_icons()); button_select.prop("disabled", true).on('click', () => { if (callback_icon) callback_icon(selected_icon); modal.close(); }); modal.htmlTag.find(".button-select-no-icon").on('click', () => { if (callback_icon) callback_icon(0); modal.close(); }); modal.open(); } Modals.spawnIconSelect = spawnIconSelect; function handle_icon_upload(file, client) { const icon = {}; icon.file = file; icon.upload_state = "unset"; const file_too_big = () => { console.error(_translations.WTCs0FZc || (_translations.WTCs0FZc = tr("Failed to load file %s: File is too big!")), file.name); createErrorModal(_translations.OBdh35e5 || (_translations.OBdh35e5 = tr("Icon upload failed")), tra("Failed to upload icon {}.
The given file is too big!", file.name)).open(); icon.state = "error"; }; if (file.size > 1024 * 1024 * 512) { file_too_big(); } else if ((file.size | 0) <= 0) { console.error(_translations.weFhyRXi || (_translations.weFhyRXi = tr("Failed to load file %s: Your browser does not support file sizes!")), file.name); createErrorModal(_translations.slnJLUnr || (_translations.slnJLUnr = tr("Icon upload failed")), tra("Failed to upload icon {}.
Your browser does not support file sizes!", file.name)).open(); icon.state = "error"; return; } else { icon.state = "loading"; icon.loader = (() => __awaiter(this, void 0, void 0, function* () { const reader = new FileReader(); try { yield new Promise((resolve, reject) => { reader.onload = resolve; reader.onerror = reject; reader.readAsDataURL(file); }); } catch (error) { console.log("Image failed to load (%o)", error); console.error(_translations.ZQUb3mnr || (_translations.ZQUb3mnr = tr("Failed to load file %s: Image failed to load")), file.name); createErrorModal(_translations.PM2yox2o || (_translations.PM2yox2o = tr("Icon upload failed")), tra("Failed to upload icon {}.
Failed to load image", file.name)).open(); icon.state = "error"; return; } const result = reader.result; if (typeof (result) !== "string") { console.error(_translations.Hdzgrw14 || (_translations.Hdzgrw14 = tr("Failed to load file %s: Result is not an media string (%o)")), file.name, result); createErrorModal(_translations.haFBfmL2 || (_translations.haFBfmL2 = tr("Icon upload failed")), tra("Failed to upload icon {}.
Result is not an media string", file.name)).open(); icon.state = "error"; return; } /* get the CRC32 sum */ { if (!result.startsWith("data:image/")) { console.error(_translations.fWTWB0rC || (_translations.fWTWB0rC = tr("Failed to load file %s: Invalid data media type (%o)")), file.name, result); createErrorModal(_translations.rXQ9XpMl || (_translations.rXQ9XpMl = tr("Icon upload failed")), tra("Failed to upload icon {}.
File is not an image", file.name)).open(); icon.state = "error"; return; } const semi = result.indexOf(';'); const type = result.substring(11, semi); console.log(_translations.qwKMVZCa || (_translations.qwKMVZCa = tr("Given image has type %s")), type); if (!result.substr(semi + 1).startsWith("base64,")) { console.error(_translations.FKg8ziMk || (_translations.FKg8ziMk = tr("Failed to load file %s: Mimetype isnt base64 encoded (%o)")), file.name, result.substr(semi + 1)); createErrorModal(_translations.jbJiQdmE || (_translations.jbJiQdmE = tr("Icon upload failed")), tra("Failed to upload icon {}.
Decoder returned unknown result", file.name)).open(); icon.state = "error"; return; } const crc = new Crc32(); crc.update(arrayBufferBase64(result.substr(semi + 8))); icon.icon_id = crc.digest(10); } const image = document.createElement("img"); try { yield new Promise((resolve, reject) => { image.onload = resolve; image.onerror = reject; image.src = result; }); } catch (error) { console.log("Image failed to load (%o)", error); console.error(_translations.Cnm0yzhD || (_translations.Cnm0yzhD = tr("Failed to load file %s: Image failed to load")), file.name); createErrorModal(_translations.nP_b16tY || (_translations.nP_b16tY = tr("Icon upload failed")), tra("Failed to upload icon {}.{:br:}Failed to load image", file.name)).open(); icon.state = "error"; } const width_error = message => { console.error(_translations.VWE0wbL5 || (_translations.VWE0wbL5 = tr("Failed to load file %s: Invalid bounds: %s")), file.name, message); createErrorModal(_translations.p7VzcfRi || (_translations.p7VzcfRi = tr("Icon upload failed")), tra("Failed to upload icon {}.{:br:}Image is too large ({})", file.name, message)).open(); icon.state = "error"; }; if (!result.startsWith("data:image/svg+xml")) { if (image.naturalWidth > 32 && image.naturalHeight > 32) { width_error("width and height (max 32px). Given: " + image.naturalWidth + "x" + image.naturalHeight); return; } if (image.naturalWidth > 32) { width_error("width (max 32px)"); return; } if (image.naturalHeight > 32) { width_error("height (max 32px)"); return; } } console.log("Image loaded (%dx%d) %s (%s)", image.naturalWidth, image.naturalHeight, image.name, icon.icon_id); icon.image_element = () => { const image = document.createElement("img"); image.src = result; return image; }; icon.state = "valid"; }))(); icon.upload_icon = () => { const create_progress_bar = () => { const html = $.spawn("div").addClass("progress"); const indicator = $.spawn("div").addClass("progress-bar bg-success progress-bar-striped progress-bar-animated"); const message = $.spawn("div").addClass("progress-message"); const set_value = value => { indicator.stop(true, false).animate({ width: value + "%" }, 250); if (value === 100) setTimeout(() => indicator.removeClass("progress-bar-striped progress-bar-animated"), 900); }; return { html_tag: html.append(indicator).append(message), set_value: set_value, set_message: msg => message.text(msg), set_error: (msg) => { let index = msg.lastIndexOf(':'); message.text(index == -1 ? msg : msg.substring(index + 1)); message.attr('title', msg); set_value(100); indicator.removeClass("bg-success").addClass("bg-danger"); } }; }; const container_image = $.spawn("div").addClass("container-icon"); const bar = create_progress_bar(); const set_error = message => { bar.set_value(100); bar.set_message((_translations.LRMQF4bW || (_translations.LRMQF4bW = tr("error: "))) + message); }; const html_tag = $.spawn("div") .addClass("upload-entry") .append(container_image) .append(bar.html_tag); icon.upload_html_tag = html_tag; let icon_added = false; if (icon.image_element) { container_image.append(icon.image_element()); icon_added = true; } bar.set_value(0); bar.set_value(_translations.iPgGKIpi || (_translations.iPgGKIpi = tr("waiting"))); return () => __awaiter(this, void 0, void 0, function* () { const time_begin = Date.now(); if (icon.state === "loading") { bar.set_message(_translations.TveVOKL0 || (_translations.TveVOKL0 = tr("Awaiting local processing"))); yield icon.loader; // @ts-ignore Could happen because the loader function updates the state if (icon.state !== "valid") { set_error(_translations.Sdb1D0Df || (_translations.Sdb1D0Df = tr("local processing failed"))); icon.upload_state = "error"; return; } } else if (icon.state === "error") { set_error(_translations.hPVhYCvy || (_translations.hPVhYCvy = tr("local processing error"))); icon.upload_state = "error"; return; } if (!icon_added) container_image.append(icon.image_element()); bar.set_value(25); bar.set_message(_translations.Xqb7msAQ || (_translations.Xqb7msAQ = tr("initializing"))); let upload_key; try { upload_key = yield client.fileManager.upload_file({ channel: undefined, channel_password: undefined, name: '/icon_' + icon.icon_id, overwrite: false, path: '', size: icon.file.size }); } catch (error) { if (error instanceof CommandResult && error.id == ErrorID.FILE_ALREADY_EXISTS) { if (!settings.static_global(Settings.KEY_DISABLE_COSMETIC_SLOWDOWN, false)) yield new Promise(resolve => setTimeout(resolve, 500 + Math.floor(Math.random() * 500))); bar.set_message(_translations.evYSGDAg || (_translations.evYSGDAg = tr("icon already exists"))); bar.set_value(100); icon.upload_state = "uploaded"; return; } console.error(_translations.gJb1dy46 || (_translations.gJb1dy46 = tr("Failed to initialize upload: %o")), error); bar.set_error(_translations.fYxv3EsZ || (_translations.fYxv3EsZ = tr("failed to initialize upload"))); icon.upload_state = "error"; return; } bar.set_value(50); bar.set_message(_translations.kU_0puQM || (_translations.kU_0puQM = tr("uploading"))); const connection = transfer.spawn_upload_transfer(upload_key); try { yield connection.put_data(icon.file); } catch (error) { console.error(_translations.EPY4nTY6 || (_translations.EPY4nTY6 = tr("Icon upload failed for icon %s: %o")), icon.file.name, error); if (typeof (error) === "string") bar.set_error((_translations.CqQcLAq4 || (_translations.CqQcLAq4 = tr("upload failed: "))) + error); else if (typeof (error.message) === "string") bar.set_error((_translations.NyIZkcuR || (_translations.NyIZkcuR = tr("upload failed: "))) + error.message); else bar.set_error(_translations.bt6ItaiX || (_translations.bt6ItaiX = tr("upload failed"))); icon.upload_state = "error"; return; } const time_end = Date.now(); if (!settings.static_global(Settings.KEY_DISABLE_COSMETIC_SLOWDOWN, false)) yield new Promise(resolve => setTimeout(resolve, Math.max(0, 1000 - (time_end - time_begin)))); bar.set_value(100); bar.set_message(_translations.x9YWUXAH || (_translations.x9YWUXAH = tr("upload completed"))); icon.upload_state = "uploaded"; }); }; } return icon; } function spawnIconUpload(client) { const modal = createModal({ header: _translations.wn8NJP_6 || (_translations.wn8NJP_6 = tr("Upload Icons")), footer: undefined, body: () => $("#tmpl_icon_upload").renderTag(), closeable: false, min_width: "20em" }); modal.htmlTag.find(".modal-body").addClass("modal-icon-upload"); const button_upload = modal.htmlTag.find(".button-upload"); const button_delete = modal.htmlTag.find(".button-remove").prop("disabled", true); const button_add = modal.htmlTag.find(".button-add"); const button_upload_abort = modal.htmlTag.find(".button-upload-abort"); const input_file = modal.htmlTag.find(".input-file-upload"); const container_icons = modal.htmlTag.find(".container-icons"); let selected_icon; let icons = []; const update_upload_button = () => { const icon_count = icons.filter(e => e.state === "valid").length; button_upload.empty(); tra("Upload icons ({})", icon_count).forEach(e => e.appendTo(button_upload)); button_upload.prop("disabled", icon_count == 0); }; update_upload_button(); const add_icon = (icon) => { icons.push(icon); icon.loader.then(e => { if (icon.state === "valid") { const image = icon.image_element(); const element = $.spawn("div") .addClass("icon-container") .append(image); container_icons.append(icon.html_tag = element); element.on('click', event => { container_icons.find(".selected").removeClass("selected"); element.addClass("selected"); selected_icon = icon; button_delete.prop("disabled", false); }); update_upload_button(); } }); }; button_delete.on('click', event => { if (!selected_icon) return; icons = icons.filter(e => e !== selected_icon); if (selected_icon.html_tag) selected_icon.html_tag.detach(); button_delete.prop("disabled", true); update_upload_button(); }); button_add.on('click', event => input_file.click()); input_file.on('change', event => { if (input_file[0].files.length > 0) { for (let index = 0; index < input_file[0].files.length; index++) { const file = input_file[0].files.item(index); { let duplicate = false; for (const icon of icons) if (icon.file.name === file.name && icon.file.lastModified === file.lastModified && icon.state !== "error") { duplicate = true; break; } if (duplicate) continue; } add_icon(handle_icon_upload(file, client)); } } }); container_icons.on('dragover', ((event) => { event.stopPropagation(); event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; })); container_icons.on('drop', ((event) => { event.stopPropagation(); event.preventDefault(); for (let index = 0; index < event.dataTransfer.files.length; index++) { const file = event.dataTransfer.files.item(index); { let duplicate = false; for (const icon of icons) if (icon.file === file && icon.state !== "error") { duplicate = true; break; } if (duplicate) continue; } add_icon(handle_icon_upload(file, client)); } })); /* upload process */ { const container_upload = modal.htmlTag.find(".container-upload"); const container_error = container_upload.find(".container-error"); const container_success = container_upload.find(".container-success"); const container_process = container_upload.find(".container-process"); const container_info = container_upload.find(".container-info"); const container_statistics = container_upload.find(".uploaded-statistics"); const show_critical_error = message => { container_error.find(".error-message").text(message); container_error.removeClass("hidden"); }; const finish_upload = () => { icons = icons.filter(e => { if (e.upload_state === "uploaded") { e.html_tag.detach(); return false; } return true; }); update_upload_button(); button_upload.prop("disabled", false); button_upload.prop("disabled", false); container_upload.hide(); container_error.addClass("hidden"); container_error.addClass("hidden"); modal.set_closeable(true); }; const execute_upload = () => __awaiter(this, void 0, void 0, function* () { if (!client || !client.fileManager) { show_critical_error(_translations.F2IChL3l || (_translations.F2IChL3l = tr("Invalid client handle"))); return; } if (!client.connected) { show_critical_error(_translations.mO_jmbzr || (_translations.mO_jmbzr = tr("Not connected"))); return; } let invoke_count = 0; let succeed_count = 0; let failed_count = 0; const uploads = icons.filter(e => e.state !== "error"); const executes = []; for (const icon of uploads) { executes.push({ icon: icon, task: icon.upload_icon() }); if (!icon.upload_html_tag) continue; /* TODO: error? */ icon.upload_html_tag.appendTo(container_process); } const update_state = () => container_statistics.text(invoke_count + " | " + succeed_count + " | " + failed_count); for (const execute of executes) { invoke_count++; update_state(); try { yield execute.task(); if (execute.icon.upload_state !== "uploaded") throw "failed"; succeed_count++; } catch (error) { failed_count++; } update_state(); } container_info.css({ opacity: 1 }).animate({ opacity: 0 }, 250, () => container_info.css({ opacity: undefined }).hide()); container_success.find(".message").html("Total icons: " + invoke_count + "
" + "Succeeded icons: " + succeed_count + "
" + "Failed icons: " + failed_count); container_success.removeClass("hidden"); }); button_upload.on('click', event => { modal.set_closeable(false); button_upload.prop("disabled", true); button_delete.prop("disabled", true); button_add.prop("disabled", true); container_process.empty(); container_upload.show(); execute_upload(); }); button_upload_abort.on('click', event => finish_upload()); container_error.addClass("hidden"); container_success.addClass("hidden"); container_upload.hide(); } modal.open(); modal.set_closeable(true); } Modals.spawnIconUpload = spawnIconUpload; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c565e1eabe89f658f183c84f4ff888d5c072e3806c50d19008c565d931f36873"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c565e1eabe89f658f183c84f4ff888d5c072e3806c50d19008c565d931f36873"] = "c565e1eabe89f658f183c84f4ff888d5c072e3806c50d19008c565d931f36873"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Q26wE6OY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (7,21)" }, { name: "HvyxPjCN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (35,40)" }, { name: "KdBchkgj", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (35,54)" }, { name: "JadIc69x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (57,46)" }, { name: "F3hRLwdH", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (57,80)" }, { name: "lvUbN5p7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (70,53)" }, { name: "Qkr0VmdR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (70,119)" }, { name: "OumC_Krz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (79,46)" }, { name: "tRwKNZyK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (79,80)" }, { name: "oZn_XbMx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (127,21)" }, { name: "XAQhUOKN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (161,32)" }, { name: "s81RoyQO", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (168,36)" }, { name: "WEuJt8JD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (177,32)" }, { name: "_ZCxkHLa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (183,39)" }, { name: "CEPpkX2y", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (184,36)" }, { name: "VA2ysnwv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalIdentity.ts (200,36)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function spawnTeamSpeakIdentityImprove(identity, name) { let modal; let elapsed_timer; modal = createModal({ header: _translations.Q26wE6OY || (_translations.Q26wE6OY = tr("Improve identity")), body: () => { let template = $("#tmpl_settings-teamspeak_improve").renderTag({ identity_name: name }); template = $.spawn("div").append(template); let active; const button_start_stop = template.find(".button-start-stop"); const button_close = template.find(".button-close"); const input_current_level = template.find(".identity-level input"); const input_target_level = template.find(".identity-target-level input"); const input_threads = template.find(".threads input"); const input_hash_rate = template.find(".hash-rate input"); const input_elapsed = template.find(".time-elapsed input"); button_close.on('click', event => { if (active) button_start_stop.trigger('click'); if (modal.shown) modal.close(); }); button_start_stop.on('click', event => { button_start_stop .toggleClass('btn-success', active) .toggleClass('btn-danger', !active) .text(active ? _translations.HvyxPjCN || (_translations.HvyxPjCN = tr("Start")) : _translations.KdBchkgj || (_translations.KdBchkgj = tr("Stop"))); input_threads.prop("disabled", !active); input_target_level.prop("disabled", !active); if (active) { input_hash_rate.val(0); clearInterval(elapsed_timer); active = false; return; } active = true; input_hash_rate.val("nan"); const threads = parseInt(input_threads.val()); const target_level = parseInt(input_target_level.val()); if (target_level == 0) { identity.improve_level(-1, threads, () => active, current_level => { input_current_level.val(current_level); }, hash_rate => { input_hash_rate.val(hash_rate); }).catch(error => { console.error(error); createErrorModal(_translations.JadIc69x || (_translations.JadIc69x = tr("Failed to improve identity")), (_translations.F3hRLwdH || (_translations.F3hRLwdH = tr("Failed to improve identity.
Error:"))) + error).open(); if (active) button_start_stop.trigger('click'); }); } else { identity.improve_level(target_level, threads, () => active, current_level => { input_current_level.val(current_level); }, hash_rate => { input_hash_rate.val(hash_rate); }).then(success => { if (success) { identity.level().then(level => { input_current_level.val(level); createInfoModal(_translations.lvUbN5p7 || (_translations.lvUbN5p7 = tr("Identity successfully improved")), MessageHelper.formatMessage(_translations.Qkr0VmdR || (_translations.Qkr0VmdR = tr("Identity successfully improved to level {}")), level)).open(); }).catch(error => { input_current_level.val("error: " + error); }); } if (active) button_start_stop.trigger('click'); }).catch(error => { console.error(error); createErrorModal(_translations.OumC_Krz || (_translations.OumC_Krz = tr("Failed to improve identity")), (_translations.tRwKNZyK || (_translations.tRwKNZyK = tr("Failed to improve identity.
Error:"))) + error).open(); if (active) button_start_stop.trigger('click'); }); } const begin = Date.now(); elapsed_timer = setInterval(() => { const time = (Date.now() - begin) / 1000; let seconds = Math.floor(time % 60).toString(); let minutes = Math.floor(time / 60).toString(); if (seconds.length < 2) seconds = "0" + seconds; if (minutes.length < 2) minutes = "0" + minutes; input_elapsed.val(minutes + ":" + seconds); }, 1000); }); template.find(".identity-unique-id input").val(identity.uid()); identity.level().then(level => { input_current_level.val(level); }).catch(error => { input_current_level.val("error: " + error); }); tooltip(template); return template.children(); }, footer: undefined, width: 750 }); modal.htmlTag.find(".modal-body").addClass("modal-identity-improve modal-green"); modal.close_listener.push(() => modal.htmlTag.find(".button-close").trigger('click')); modal.open(); return modal; } Modals.spawnTeamSpeakIdentityImprove = spawnTeamSpeakIdentityImprove; function spawnTeamSpeakIdentityImport(callback) { let modal; let selected_type; let identities = {}; modal = createModal({ header: _translations.oZn_XbMx || (_translations.oZn_XbMx = tr("Import identity")), body: () => { let template = $("#tmpl_settings-teamspeak_import").renderTag(); const button_import = template.find(".button-import"); const button_file_select = template.find(".button-load-file"); const container_status = template.find(".container-status"); const input_text = template.find(".input-identity-text"); const input_file = template.find(".file-selector"); const set_status = (message, type) => { container_status.toggleClass("hidden", !message); if (message) { container_status.toggleClass("error", type === "error"); container_status.toggleClass("loading", type === "loading"); container_status.find("a").text(message); } }; button_file_select.on('click', event => input_file.trigger('click')); template.find("input[name='type']").on('change', event => { const type = event.target.value; button_file_select.prop("disabled", type !== "file"); input_text.prop("disabled", type !== "text"); selected_type = type; button_import.prop("disabled", !identities[type]); }); template.find("input[name='type'][value='file']").prop("checked", true).trigger("change"); const import_identity = (data, ini) => { set_status(_translations.XAQhUOKN || (_translations.XAQhUOKN = tr("Parsing identity")), "loading"); profiles.identities.TeaSpeakIdentity.import_ts(data, ini).then(identity => { identities[selected_type] = identity; set_status("Identity parsed successfully.", "success"); button_import.prop("disabled", false); template.find(".success").show(); }).catch(error => { set_status((_translations.s81RoyQO || (_translations.s81RoyQO = tr("Failed to parse identity: "))) + error, "error"); }); }; /* file select button */ input_file.on('change', event => { const element = event.target; const file_reader = new FileReader(); set_status(_translations.WEuJt8JD || (_translations.WEuJt8JD = tr("Loading file")), "loading"); file_reader.onload = function () { import_identity(file_reader.result, true); }; file_reader.onerror = ev => { console.error(_translations._ZCxkHLa || (_translations._ZCxkHLa = tr("Failed to read give identity file: %o")), ev); set_status(_translations.CEPpkX2y || (_translations.CEPpkX2y = tr("Failed to read the identity file.")), "error"); return; }; if (element.files && element.files.length > 0) file_reader.readAsText(element.files[0]); }); input_text.on('change keyup', event => { const text = input_text.val(); if (!text) { set_status("", "success"); return; } if (text.indexOf('V') == -1) { set_status(_translations.VA2ysnwv || (_translations.VA2ysnwv = tr("Invalid identity string")), "error"); return; } import_identity(text, false); }); button_import.on('click', event => { modal.close(); callback(identities[selected_type]); }); set_status("", "success"); button_import.prop("disabled", true); return template.children(); }, footer: undefined, width: 750 }); modal.htmlTag.find(".modal-body").addClass("modal-identity-import modal-green"); modal.open(); return modal; } Modals.spawnTeamSpeakIdentityImport = spawnTeamSpeakIdentityImport; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c5513d1c4dddf0d8de54b0178a14b1f259bb4b79f9befed66bd8679198a54bf0"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c5513d1c4dddf0d8de54b0178a14b1f259bb4b79f9befed66bd8679198a54bf0"] = "c5513d1c4dddf0d8de54b0178a14b1f259bb4b79f9befed66bd8679198a54bf0"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "kBxmDo9P", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalInvite.ts (116,21)" }, { name: "ePBMg_5b", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalInvite.ts (170,35)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { const DefaultGeneratorSettings = { flag_direct: true, flag_resolved: false }; const build_url = (base, params) => { if (Object.keys(params).length == 0) return base; return base + "?" + Object.keys(params) .map(e => e + "=" + encodeURIComponent(params[e])) .join("&"); }; //TODO: Server password const url_generators = { "tea-web": { generate: properties => { const address = properties.resolved_address ? properties.resolved_address : properties.address; const address_str = address.host + (address.port === 9987 ? "" : address.port); const parameter = "connect_default=" + (properties.flag_direct ? 1 : 0) + "&connect_address=" + encodeURIComponent(address_str); let pathbase = ""; if (document.location.protocol !== 'https:') { /* * Seems to be a test environment or the TeaClient for localhost where we dont have to use https. */ pathbase = "https://web.teaspeak.de/"; } else if (document.location.hostname === "localhost" || document.location.host.startsWith("127.")) { pathbase = "https://web.teaspeak.de/"; } else { pathbase = document.location.origin + document.location.pathname; } return pathbase + "?" + parameter; }, setting_available: setting => { return { flag_direct: true, flag_resolved: true }[setting] || false; } }, "tea-client": { generate: properties => { const address = properties.resolved_address ? properties.resolved_address : properties.address; let parameters = { connect_default: properties.flag_direct ? 1 : 0 }; if (address.port != 9987) parameters["port"] = address.port; return build_url("teaclient://" + address.host + "/", parameters); }, setting_available: setting => { return { flag_direct: true, flag_resolved: true }[setting] || false; } }, "teamspeak": { generate: properties => { const address = properties.resolved_address ? properties.resolved_address : properties.address; let parameters = {}; if (address.port != 9987) parameters["port"] = address.port; /* ts3server://? port=9987 nickname=UserNickname password=serverPassword channel=MyDefaultChannel cid=channelID channelpassword=defaultChannelPassword token=TokenKey addbookmark=MyBookMarkLabel */ return build_url("ts3server://" + address.host + "/", parameters); }, setting_available: setting => { return { flag_direct: false, flag_resolved: true }[setting] || false; } } }; function spawnInviteEditor(connection) { let modal; modal = createModal({ header: _translations.kBxmDo9P || (_translations.kBxmDo9P = tr("Invite URL creator")), body: () => { let template = $("#tmpl_invite").renderTag(); template.find(".button-close").on('click', event => modal.close()); return template; }, footer: undefined, min_width: "20em", width: "50em" }); modal.htmlTag.find(".modal-body").addClass("modal-invite"); const button_copy = modal.htmlTag.find(".button-copy"); const input_type = modal.htmlTag.find(".property-type select"); const label_output = modal.htmlTag.find(".text-output"); const invite_settings = [ { key: "flag_direct", node: modal.htmlTag.find(".flag-direct-connect input"), value: node => node.prop('checked'), set_value: (node, value) => node.prop('checked', value == "1"), disable: (node, flag) => node.prop('disabled', flag) .firstParent('.checkbox').toggleClass('disabled', flag) }, { key: "flag_resolved", node: modal.htmlTag.find(".flag-resolved-address input"), value: node => node.prop('checked'), set_value: (node, value) => node.prop('checked', value == "1"), disable: (node, flag) => node.prop('disabled', flag) .firstParent('.checkbox').toggleClass('disabled', flag) } ]; const update_buttons = () => { const generator = url_generators[input_type.val()]; if (!generator) { for (const s of invite_settings) s.disable(s.node, true); return; } for (const s of invite_settings) s.disable(s.node, !generator.setting_available(s.key)); }; const update_link = () => { const generator = url_generators[input_type.val()]; if (!generator) { button_copy.prop('disabled', true); label_output.text(_translations.ePBMg_5b || (_translations.ePBMg_5b = tr("Missing link generator"))); return; } button_copy.prop('disabled', false); const properties = { address: connection.channelTree.server.remote_address, resolved_address: connection.channelTree.client.serverConnection.remote_address() }; for (const s of invite_settings) properties[s.key] = s.value(s.node); label_output.text(generator.generate(properties)); }; for (const s of invite_settings) { s.node.on('change keyup', () => { settings.changeGlobal(Settings.FN_INVITE_LINK_SETTING(s.key), s.value(s.node)); update_link(); }); s.set_value(s.node, settings.global(Settings.FN_INVITE_LINK_SETTING(s.key), DefaultGeneratorSettings[s.key])); } input_type.on('change', () => { settings.changeGlobal(Settings.KEY_LAST_INVITE_LINK_TYPE, input_type.val()); update_buttons(); update_link(); }).val(settings.global(Settings.KEY_LAST_INVITE_LINK_TYPE)); button_copy.on('click', event => { label_output.select(); document.execCommand('copy'); }); update_buttons(); update_link(); modal.open(); } Modals.spawnInviteEditor = spawnInviteEditor; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["8551b0f0a521938dc720e3dfc08a60a6490a3e63ba4351dc91390a4142ec3872"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["8551b0f0a521938dc720e3dfc08a60a6490a3e63ba4351dc91390a4142ec3872"] = "8551b0f0a521938dc720e3dfc08a60a6490a3e63ba4351dc91390a4142ec3872"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "MLOU8bZn", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalKeySelect.ts (4,21)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function spawnKeySelect(callback) { let modal = createModal({ header: _translations.MLOU8bZn || (_translations.MLOU8bZn = tr("Select a key")), body: () => $("#tmpl_key_select").renderTag().children(), footer: null, width: "", closeable: false }); const container_key = modal.htmlTag.find(".container-key a"); const button_save = modal.htmlTag.find(".button-save"); const button_cancel = modal.htmlTag.find(".button-cancel"); let current_key_age; let last_key; let current_key; const listener = (event) => { if (event.type === ppt.EventType.KEY_PRESS) { //console.log(tr("Key select got key press for %o"), event); last_key = current_key; current_key = event; current_key_age = Date.now(); container_key.text(ppt.key_description(event)); button_save.prop("disabled", false); } }; button_save.on('click', () => { if (!app.is_web()) { /* Because pressing the close button is also a mouse action */ if (current_key_age + 1000 > Date.now() && current_key.key_code == "MOUSE2") current_key = last_key; } callback(current_key); modal.close(); }).prop("disabled", true); button_cancel.on('click', () => modal.close()); ppt.register_key_listener(listener); modal.close_listener.push(() => ppt.unregister_key_listener(listener)); modal.htmlTag.find(".modal-body").addClass("modal-keyselect modal-green"); modal.open(); } Modals.spawnKeySelect = spawnKeySelect; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["7565364a2370e4653cf564d50e9bf0c10d91c7b074bec401591fab85bca45080"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["7565364a2370e4653cf564d50e9bf0c10d91c7b074bec401591fab85bca45080"] = "7565364a2370e4653cf564d50e9bf0c10d91c7b074bec401591fab85bca45080"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "Znbysrt7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (13,24)" }, { name: "kb1s3EbM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (35,28)" }, { name: "sJFl4SFw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (35,90)" }, { name: "UX9qUFB7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (41,24)" }, { name: "FR91na9p", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (63,51)" }, { name: "cm5CVSTu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (84,61)" }, { name: "VAfsInts", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (104,51)" }, { name: "xYJ3MH9A", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (150,57)" }, { name: "oWfb8Ffx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (169,51)" }, { name: "oxz3fXdx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (192,51)" }, { name: "YpKG3TzD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (217,51)" }, { name: "CpejOouC", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (240,51)" }, { name: "xoWTeact", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (270,51)" }, { name: "ypBEEqy0", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (294,51)" }, { name: "KMq5sCKT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (336,51)" }, { name: "P7lD9A4F", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (367,51)" }, { name: "xlYmaITB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (558,30)" }, { name: "T0lvDV9H", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (575,46)" }, { name: "c8dSeLZS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (583,69)" }, { name: "ck4GDnos", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (595,43)" }, { name: "ds03qJjo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (595,92)" }, { name: "whmoRxKI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (617,46)" }, { name: "TDfuhMFl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (640,65)" }, { name: "Wba6WIJI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (672,43)" }, { name: "KegIP_Oa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (672,96)" }, { name: "TJs6MrB8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (743,43)" }, { name: "V8NKF3zP", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (743,110)" }, { name: "NUwpilKf", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (797,43)" }, { name: "WRDVagVX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (797,109)" }, { name: "q_kBtt47", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (824,40)" }, { name: "gPVZM1r8", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (872,38)" }, { name: "lczFny7X", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (878,34)" }, { name: "Mk7tMQ1m", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (883,57)" }, { name: "uQ1yO6Yi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (894,43)" }, { name: "DJ1pfloN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (894,98)" }, { name: "pRpmtFjG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (906,34)" }, { name: "_jdzYHNZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (924,46)" }, { name: "q5PwTk4Y", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (933,69)" }, { name: "qokDUQla", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (947,43)" }, { name: "yuB8OE8e", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (947,104)" }, { name: "h2kycEoy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (975,46)" }, { name: "sTxLZaJY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1019,43)" }, { name: "WQE2CZa2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1019,99)" }, { name: "VYtn59Ga", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1073,43)" }, { name: "YUZUVDR4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1073,99)" }, { name: "xp_ufUbh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1100,40)" }, { name: "chknDAXh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1177,46)" }, { name: "n75WL7_X", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1182,46)" }, { name: "ac3ohRnJ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1217,54)" }, { name: "rRXCJPGM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1222,54)" }, { name: "H7Wzuyk5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1245,42)" }, { name: "Jl44qY0M", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1245,70)" }, { name: "dtLjMQff", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1274,48)" }, { name: "xeMEtAeJ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1300,82)" }, { name: "Q3EsnBCT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1319,44)" }, { name: "oN5z34tB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1433,51)" }, { name: "rriL0uvS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1439,55)" }, { name: "NMxty5e5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1447,74)" }, { name: "v50TMxti", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1461,46)" }, { name: "bjvee5Ts", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1472,51)" }, { name: "uaoGscii", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1535,87)" }, { name: "qZHZIWWT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1539,39)" }, { name: "WA9xLJOj", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1598,40)" }, { name: "QrA6IXLw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1733,51)" }, { name: "vXhgxTE9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1764,47)" }, { name: "qTOaE8kn", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1774,51)" }, { name: "W6NSppXR", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1782,70)" }, { name: "NRqLeDXD", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1796,47)" }, { name: "IezxIp9G", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1819,42)" }, { name: "TcN1P2qm", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalMusicManage.ts (1858,40)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function openMusicManage(client, bot) { const ev_registry = new events.Registry(); ev_registry.enable_debug("music-manage"); //dummy_controller(ev_registry); permission_controller(ev_registry, bot, client); let modal = createModal({ header: tr(_translations.Znbysrt7 || (_translations.Znbysrt7 = tr("Playlist Manage"))), body: () => build_modal(ev_registry), footer: null, min_width: "35em", closeable: true }); modal.htmlTag.find(".modal-body").addClass("modal-music-manage"); /* "controller" */ { } modal.open(); } Modals.openMusicManage = openMusicManage; function permission_controller(event_registry, bot, client) { const error_msg = error => { if (error instanceof CommandResult) { if (error.id === ErrorID.PERMISSION_ERROR) { const permission = client.permissions.resolveInfo(error.json["failed_permid"]); return (_translations.kb1s3EbM || (_translations.kb1s3EbM = tr("failed on permission "))) + (permission ? permission.name : _translations.sJFl4SFw || (_translations.sJFl4SFw = tr("unknown"))); } return error.extra_message || error.message; } else if (typeof error === "string") return error; else return _translations.UX9qUFB7 || (_translations.UX9qUFB7 = tr("command error")); }; { event_registry.on("query_playlist_status", event => { const playlist_id = bot.properties.client_playlist_id; client.serverConnection.command_helper.request_playlist_info(playlist_id).then(result => { event_registry.fire("playlist_status", { status: "success", data: { replay_mode: result.playlist_replay_mode, finished: result.playlist_flag_finished, delete_played: result.playlist_flag_delete_played, notify_song_change: bot.properties.client_flag_notify_song_change, max_size: result.playlist_max_songs } }); }).catch(error => { event_registry.fire("playlist_status", { status: "error", error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.FR91na9p || (_translations.FR91na9p = tr("Failed to query playlist info for playlist %d: %o")), playlist_id, error); }); }); event_registry.on("set_playlist_status", event => { const playlist_id = bot.properties.client_playlist_id; const property_map = { "replay_mode": "playlist_replay_mode", "finished": "playlist_flag_finished", "delete_played": "playlist_flag_delete_played", "max_size": "playlist_max_songs" }; Promise.resolve().then(() => { if (event.key === "notify_song_change") { return client.serverConnection.send_command("clientedit", { clid: bot.clientId(), client_flag_notify_song_change: event.value }); } else { const property = property_map[event.key]; if (!property) return Promise.reject(_translations.cm5CVSTu || (_translations.cm5CVSTu = tr("unknown property"))); const data = { playlist_id: playlist_id }; data[property] = event.value; return client.serverConnection.send_command("playlistedit", data); } }).then(() => { event_registry.fire("set_playlist_status_result", { status: "success", key: event.key, value: event.value }); }).catch(error => { event_registry.fire("set_playlist_status_result", { status: "error", key: event.key, error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.VAfsInts || (_translations.VAfsInts = tr("Failed to change playlist status %s for playlist %d: %o")), event.key, playlist_id, error); }); }); event_registry.on("query_bot_status", event => { setTimeout(() => { event_registry.fire("bot_status", { status: "success", data: { channel_commander: bot.properties.client_is_channel_commander, volume: bot.properties.player_volume, description: bot.properties.client_description, default_country_code: (!bot.channelTree ? undefined : !bot.channelTree.server ? undefined : bot.channelTree.server.properties.virtualserver_country_code) || "DE", country_code: bot.properties.client_country, name: bot.properties.client_nickname, priority_speaker: bot.properties.client_is_priority_speaker, bot_type: bot.properties.client_bot_type, client_platform: bot.properties.client_platform, client_version: bot.properties.client_version, uptime_mode: bot.properties.client_uptime_mode } }); }, 0); }); event_registry.on("set_bot_status", event => { const property_map = { "channel_commander": "client_is_channel_commander", "volume": "player_volume", "description": "client_description", "country_code": "client_country", "name": "client_nickname", "priority_speaker": "client_is_priority_speaker", "bot_type": "client_bot_type", "client_platform": "client_platform", "client_version": "client_version", "uptime_mode": "client_uptime_mode" }; Promise.resolve().then(() => { const property = property_map[event.key]; if (!property) return Promise.reject(_translations.xYJ3MH9A || (_translations.xYJ3MH9A = tr("unknown property"))); const data = { clid: bot.clientId() }; data[property] = event.value; return client.serverConnection.send_command("clientedit", data); }).then(() => { event_registry.fire("set_bot_status_result", { status: "success", key: event.key, value: event.value }); }).catch(error => { event_registry.fire("set_bot_status_result", { status: "error", key: event.key, error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.oWfb8Ffx || (_translations.oWfb8Ffx = tr("Failed to change bot setting %s: %o")), event.key, error); }); }); } /* permissions */ { event_registry.on("query_general_permissions", event => { const playlist_id = bot.properties.client_playlist_id; client.permissions.requestPlaylistPermissions(playlist_id).then(result => { const permissions = {}; for (const permission of result) if (permission.hasValue()) permissions[permission.type.name] = permission.value; event_registry.fire("general_permissions", { status: "success", permissions: permissions }); }).catch(error => { event_registry.fire("general_permissions", { status: "error", error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.oxz3fXdx || (_translations.oxz3fXdx = tr("Failed to query playlist general permissions for playlist %d: %o")), playlist_id, error); }); }); event_registry.on("set_general_permission", event => { const playlist_id = bot.properties.client_playlist_id; client.serverConnection.send_command("playlistaddperm", { playlist_id: playlist_id, permsid: event.key, permvalue: event.value, permskip: false, permnegated: false }).then(() => { event_registry.fire("set_general_permission_result", { key: event.key, status: "success", value: event.value }); }).catch(error => { event_registry.fire("set_general_permission_result", { status: "error", key: event.key, error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.YpKG3TzD || (_translations.YpKG3TzD = tr("Failed to set playlist general permissions for playlist %d and permission %d: %o")), playlist_id, event.key, error); }); }); event_registry.on("query_client_permissions", event => { const playlist_id = bot.properties.client_playlist_id; const client_id = event.client_database_id; client.permissions.requestPlaylistClientPermissions(playlist_id, client_id).then(result => { const permissions = {}; for (const permission of result) if (permission.hasValue()) permissions[permission.type.name] = permission.value; event_registry.fire("client_permissions", { status: "success", client_database_id: event.client_database_id, permissions: permissions }); }).catch(error => { event_registry.fire("client_permissions", { status: "error", client_database_id: event.client_database_id, error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.CpejOouC || (_translations.CpejOouC = tr("Failed to query playlist client permissions for playlist %d and client %d: %o")), playlist_id, client_id, error); }); }); event_registry.on("set_client_permission", event => { const playlist_id = bot.properties.client_playlist_id; const client_id = event.client_database_id; client.serverConnection.send_command("playlistclientaddperm", { playlist_id: playlist_id, cldbid: client_id, permsid: event.key, permvalue: event.value, permskip: false, permnegated: false }).then(() => { event_registry.fire("set_client_permission_result", { key: event.key, status: "success", client_database_id: client_id, value: event.value }); }).catch(error => { event_registry.fire("set_client_permission_result", { status: "error", key: event.key, client_database_id: client_id, error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.xoWTeact || (_translations.xoWTeact = tr("Failed to set playlist client permissions for playlist %d, permission %d and client id %d: %o")), playlist_id, event.key, client_id, error); }); }); event_registry.on("query_special_clients", event => { const playlist_id = bot.properties.client_playlist_id; client.serverConnection.command_helper.request_playlist_client_list(playlist_id).then(clients => { return client.serverConnection.command_helper.info_from_cldbid(...clients); }).then(clients => { event_registry.fire("special_client_list", { status: "success", clients: clients.map(e => { return { name: e.client_nickname, unique_id: e.client_unique_id, database_id: e.client_database_id }; }) }); }).catch(error => { event_registry.fire("special_client_list", { status: "error", error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.ypBEEqy0 || (_translations.ypBEEqy0 = tr("Failed to query special client list for playlist %d: %o")), playlist_id, error); }); }); event_registry.on("search_client", event => { if (!event.text) return; const text = event.text; Promise.resolve().then(() => { let is_uuid = false; try { is_uuid = atob(text).length === 32; } catch (e) { } if (is_uuid) { return client.serverConnection.command_helper.info_from_uid(text); } else if (text.match(/^[0-9]{1,7}$/) && !isNaN(parseInt(text))) { return client.serverConnection.command_helper.info_from_cldbid(parseInt(text)); } else { //TODO: Database name lookup? return Promise.reject("no results"); } }).then(result => { if (result.length) { const client = result[0]; event_registry.fire("search_client_result", { status: "success", client: { name: client.client_nickname, unique_id: client.client_unique_id, database_id: client.client_database_id } }); } else { event_registry.fire("search_client_result", { status: "empty" }); } }).catch(error => { event_registry.fire("search_client_result", { status: "error", error_msg: error_msg(error) }); log.error(LogCategory.CLIENT, _translations.KMq5sCKT || (_translations.KMq5sCKT = tr("Failed to lookup search text \"%s\": %o")), text, error); }); }); event_registry.on("query_group_permissions", event => { client.permissions.find_permission(event.permission_name).then(result => { let groups = []; for (const e of result) { if (e.type !== "server_group") continue; const group = client.groups.serverGroup(e.group_id); if (!group) continue; groups.push({ name: group.name, value: e.value, id: group.id }); } event_registry.fire("group_permissions", { status: "success", groups: groups, permission_name: event.permission_name }); }).catch(error => { event_registry.fire("group_permissions", { status: "error", error_msg: error_msg(error), permission_name: event.permission_name }); log.error(LogCategory.CLIENT, _translations.P7lD9A4F || (_translations.P7lD9A4F = tr("Failed to execute permfind for permission %s: %o")), event.permission_name, error); }); }); } } function dummy_controller(event_registry) { /* settings */ { event_registry.on("query_bot_status", event => { setTimeout(() => { event_registry.fire("bot_status", { status: "success", data: { name: "Another TeaSpeak bot", country_code: "DE", default_country_code: "GB", channel_commander: false, description: "Hello World", priority_speaker: true, volume: 66, uptime_mode: 0, client_version: "Version", client_platform: "Platform", bot_type: 0 } }); }); }); event_registry.on("query_playlist_status", event => { setTimeout(() => { event_registry.fire("playlist_status", { status: "success", data: { max_size: 55, notify_song_change: true, delete_played: false, finished: false, replay_mode: 2 } }); }); }); } /* permissions */ { event_registry.on("query_special_clients", event => { setTimeout(() => { event_registry.fire("special_client_list", { status: "success", clients: [{ name: "WolverinDEV", database_id: 1, unique_id: "abd" }, { name: "WolverinDEV 2", database_id: 2, unique_id: "abd1" }, { name: "WolverinDEV 3", database_id: 3, unique_id: "abd1" }] }); }, 0); }); event_registry.on("query_group_permissions", event => { setTimeout(() => { event_registry.fire("group_permissions", { status: "success", groups: [{ value: 20, name: "Server Admin p:20", id: 0 }, { value: 10, name: "Server Mod p:10", id: 0 }], permission_name: event.permission_name }); }, 0); }); event_registry.on("query_general_permissions", event => { setTimeout(() => { event_registry.fire("general_permissions", { status: "success", permissions: { i_playlist_song_needed_add_power: 77 } }); }, 0); }); event_registry.on("set_general_permission", event => { setTimeout(() => { event_registry.fire("set_general_permission_result", { key: event.key, value: event.value, status: "success" }); }); }); event_registry.on("query_client_permissions", event => { setTimeout(() => { event_registry.fire("client_permissions", { client_database_id: event.client_database_id, status: "success", permissions: { i_playlist_song_needed_add_power: 77 } }); }, 500); }); event_registry.on("set_client_permission", event => { setTimeout(() => { event_registry.fire("set_client_permission_result", { key: event.key, client_database_id: event.client_database_id, status: "success", value: event.value }); }, 500); }); } } function build_modal(event_registry) { const tag = $("#tmpl_music_manage").renderTag(); const container_settings = tag.find(".body > .category-settings"); build_settings_container(event_registry, container_settings); const container_permissions = tag.find(".body > .category-permissions"); build_permission_container(event_registry, container_permissions); /* general switch */ { let shown_container; const header = tag.find(".header"); const category_permissions = header.find(".category-permissions"); event_registry.on("show_container", data => { category_permissions.toggleClass("selected", data.container === "permissions"); container_permissions.toggleClass("hidden", data.container !== "permissions"); }); category_permissions.on('click', event => { if (shown_container === "permissions") return; event_registry.fire("show_container", { container: "permissions" }); }); const category_settings = header.find(".category-settings"); event_registry.on("show_container", data => { category_settings.toggleClass("selected", data.container === "settings"); container_settings.toggleClass("hidden", data.container !== "settings"); }); category_settings.on('click', event => { if (shown_container === "settings") return; event_registry.fire("show_container", { container: "settings" }); }); event_registry.on("show_container", data => shown_container = data.container); } /* input length fix */ tag.find("input[maxlength]").on("input", event => { const input = event.target; const max = parseInt(input.getAttribute("maxlength")); const text = input.value; if (!isNaN(max) && text && text.length > max) //input.value = text.substr(text.length - max); input.value = text.substr(0, max); }); /* initialize */ event_registry.fire("show_container", { container: "settings" }); return tag.children(); } function build_settings_container(event_registry, tag) { const show_change_error = (header, message) => { createErrorModal(_translations.xlYmaITB || (_translations.xlYmaITB = tr("Failed to change value")), header + "
" + message).open(); }; /* music bot settings */ { const container = tag.find(".settings-bot"); /* bot name */ { const input = container.find(".option-bot-name"); let last_value = undefined; event_registry.on("query_bot_status", event => { last_value = undefined; input .prop("disabled", true) .val(null) .attr("placeholder", _translations.T0lvDV9H || (_translations.T0lvDV9H = tr("loading..."))); }); event_registry.on("bot_status", event => { if (event.status === "error") input .prop("disabled", true) .val(null) .attr("placeholder", event.error_msg || (_translations.c8dSeLZS || (_translations.c8dSeLZS = tr("error while loading")))); else input .prop("disabled", false) .attr("placeholder", null) .val(last_value = event.data.name); }); event_registry.on("set_bot_status_result", event => { if (event.key !== "name") return; if (event.status !== "success") show_change_error(_translations.ck4GDnos || (_translations.ck4GDnos = tr("Failed to set bot name")), event.error_msg || (_translations.ds03qJjo || (_translations.ds03qJjo = tr("timeout")))); else last_value = event.value; input .prop("disabled", false) .attr("placeholder", null) .val(last_value); }); input.on("keyup", event => event.key === "Enter" && input.trigger("focusout")); input.on("focusout", event => { const value = input.val(); if (value === last_value) return; if (!value) { input.val(last_value); return; } input .prop("disabled", true) .val(null) .attr("placeholder", _translations.whmoRxKI || (_translations.whmoRxKI = tr("applying..."))); event_registry.fire("set_bot_status", { key: "name", value: value }); }); } /* country flag */ { const input = container.find(".option-bot-country"); const flag = container.find(".container-country .country"); let last_value = undefined, fallback_country = undefined; const update_country_code = input => { input = input || fallback_country || "ts"; flag.each((_, e) => { for (const [index, klass] of e.classList.entries()) if (klass.startsWith("flag-")) e.classList.remove(klass); }); flag.addClass("flag-" + input.toLowerCase()); flag.attr("title", i18n.country_name(input, _translations.TDfuhMFl || (_translations.TDfuhMFl = tr("Unknown country")))); }; event_registry.on("query_bot_status", event => { last_value = undefined; input .prop("disabled", true) .val(null) .attr("placeholder", "..."); update_country_code("ts"); }); event_registry.on("bot_status", event => { if (event.status === "error") input .prop("disabled", true) .val(null) .attr("placeholder", "err"); else { input .prop("disabled", false) .attr("placeholder", null) .val(last_value = event.data.country_code); fallback_country = event.data.default_country_code; } update_country_code(last_value); }); event_registry.on("set_bot_status_result", event => { if (event.key !== "country_code") return; if (event.status !== "success") show_change_error(_translations.Wba6WIJI || (_translations.Wba6WIJI = tr("Failed to set bots country")), event.error_msg || (_translations.KegIP_Oa || (_translations.KegIP_Oa = tr("timeout")))); else last_value = event.value; input .prop("disabled", false) .attr("placeholder", null) .val(last_value); update_country_code(last_value); }); input.on("input", () => { update_country_code(input.val()); input.firstParent(".input-boxed").removeClass("is-invalid"); }); input.on("keyup", event => event.key === "Enter" && input.trigger("focusout")); input.on("focusout", event => { const value = input.val(); if (value === last_value) return; if (value && value.length != 2) { input.firstParent(".input-boxed").addClass("is-invalid"); return; } input .prop("disabled", true) .val(null) .attr("placeholder", "..."); event_registry.fire("set_bot_status", { key: "country_code", value: value }); }); } /* flag channel commander */ { const input = container.find(".option-channel-commander"); const label = input.parents("label"); let last_value = undefined; event_registry.on("query_bot_status", event => { last_value = undefined; label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); }); event_registry.on("bot_status", event => { if (event.status === "error") { label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); } else { label.removeClass("disabled"); input .prop("checked", last_value = event.data.channel_commander) .prop("disabled", false); } }); event_registry.on("set_bot_status_result", event => { if (event.key !== "channel_commander") return; if (event.status !== "success") show_change_error(_translations.TJs6MrB8 || (_translations.TJs6MrB8 = tr("Failed to change channel commander state")), event.error_msg || (_translations.V8NKF3zP || (_translations.V8NKF3zP = tr("timeout")))); else last_value = event.value; label.removeClass("disabled"); input .prop("checked", last_value) .prop("disabled", false); }); input.on("change", event => { label.addClass("disabled"); input.prop("disabled", true); event_registry.fire("set_bot_status", { key: "channel_commander", value: input.prop("checked") }); }); } /* flag priority speaker */ { const input = container.find(".option-priority-speaker"); const label = input.parents("label"); let last_value = undefined; event_registry.on("query_bot_status", event => { last_value = undefined; label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); }); event_registry.on("bot_status", event => { if (event.status === "error") { label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); } else { label.removeClass("disabled"); input .prop("checked", last_value = event.data.priority_speaker) .prop("disabled", false); } }); event_registry.on("set_bot_status_result", event => { if (event.key !== "priority_speaker") return; if (event.status !== "success") show_change_error(_translations.NUwpilKf || (_translations.NUwpilKf = tr("Failed to change priority speaker state")), event.error_msg || (_translations.WRDVagVX || (_translations.WRDVagVX = tr("timeout")))); else last_value = event.value; label.removeClass("disabled"); input .prop("checked", last_value) .prop("disabled", false); }); input.on("change", event => { label.addClass("disabled"); input.prop("disabled", true); event_registry.fire("set_bot_status", { key: "priority_speaker", value: input.prop("checked") }); }); } /* status load timeout */ { let timeout; event_registry.on("query_bot_status", event => { timeout = setTimeout(() => { event_registry.fire("bot_status", { status: "error", error_msg: _translations.q_kBtt47 || (_translations.q_kBtt47 = tr("load timeout")) }); }, 5000); }); event_registry.on("bot_status", event => clearTimeout(timeout)); } /* set status timeout */ { let timeouts = {}; event_registry.on("set_bot_status", event => { clearTimeout(timeouts[event.key]); timeouts[event.key] = setTimeout(() => { event_registry.fire("set_bot_status_result", { status: "timeout", key: event.key, }); }, 5000); }); event_registry.on("set_bot_status_result", event => { clearTimeout(timeouts[event.key]); delete timeouts[event.key]; }); } } /* music bot settings */ { const container = tag.find(".settings-playlist"); /* playlist replay mode */ { const input = container.find(".option-replay-mode"); let last_value = undefined; const update_value = text => { if (text) { input.prop("disabled", true).addClass("disabled"); input.val("-1"); input.find("option[value=-1]").text(text); } else if (last_value >= 0 && last_value <= 3) { input .prop("disabled", false) .removeClass("disabled"); input.val(last_value); } else { update_value(_translations.gPVZM1r8 || (_translations.gPVZM1r8 = tr("invalid value"))); } }; event_registry.on("query_playlist_status", event => { last_value = undefined; update_value(_translations.lczFny7X || (_translations.lczFny7X = tr("loading..."))); }); event_registry.on("playlist_status", event => { if (event.status === "error") { update_value(event.error_msg || (_translations.Mk7tMQ1m || (_translations.Mk7tMQ1m = tr("error while loading")))); } else { last_value = event.data.replay_mode; update_value(undefined); } }); event_registry.on("set_playlist_status_result", event => { if (event.key !== "replay_mode") return; if (event.status !== "success") show_change_error(_translations.uQ1yO6Yi || (_translations.uQ1yO6Yi = tr("Failed to change replay mode")), event.error_msg || (_translations.DJ1pfloN || (_translations.DJ1pfloN = tr("timeout")))); else last_value = event.value; update_value(undefined); }); input.on("keyup", event => event.key === "Enter" && input.trigger("focusout")); input.on("change", event => { const value = parseInt(input.val()); console.log(value); if (isNaN(value)) return; update_value(_translations.pRpmtFjG || (_translations.pRpmtFjG = tr("applying..."))); event_registry.fire("set_playlist_status", { key: "replay_mode", value: value }); }); } /* playlist max size */ { const input = container.find(".container-max-playlist-size input"); let last_value = undefined; event_registry.on("query_playlist_status", event => { last_value = undefined; input .prop("disabled", true) .val(null) .attr("placeholder", _translations._jdzYHNZ || (_translations._jdzYHNZ = tr("loading..."))) .firstParent(".input-boxed").addClass("disabled"); }); event_registry.on("playlist_status", event => { if (event.status === "error") input .prop("disabled", true) .val(null) .attr("placeholder", event.error_msg || (_translations.q5PwTk4Y || (_translations.q5PwTk4Y = tr("error while loading")))) .firstParent(".input-boxed").addClass("disabled"); else input .prop("disabled", false) .attr("placeholder", null) .val((last_value = event.data.max_size).toString()) .firstParent(".input-boxed").removeClass("disabled"); }); event_registry.on("set_playlist_status_result", event => { if (event.key !== "max_size") return; if (event.status !== "success") show_change_error(_translations.qokDUQla || (_translations.qokDUQla = tr("Failed to change max playlist size")), event.error_msg || (_translations.yuB8OE8e || (_translations.yuB8OE8e = tr("timeout")))); else last_value = event.value; input .prop("disabled", false) .attr("placeholder", null) .val(last_value) .firstParent(".input-boxed").removeClass("disabled"); }); input.on("input", event => input.parentsUntil(".input-boxed").removeClass("is-invalid")); input.on("keyup", event => event.key === "Enter" && input.trigger("focusout")); input.on("focusout", event => { const value = input.val(); if (value === last_value) return; if (value === "") { input.val(last_value); return; } if (isNaN(parseInt(value))) { input.parentsUntil(".input-boxed").addClass("is-invalid"); return; } input .prop("disabled", true) .val(null) .attr("placeholder", _translations.h2kycEoy || (_translations.h2kycEoy = tr("applying..."))) .firstParent(".input-boxed").addClass("disabled"); event_registry.fire("set_playlist_status", { key: "max_size", value: parseInt(value) }); }); } /* flag delete played */ { const input = container.find(".option-delete-played-songs"); const label = input.parents("label"); let last_value = undefined; event_registry.on("query_playlist_status", event => { last_value = undefined; label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); }); event_registry.on("playlist_status", event => { if (event.status === "error") { label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); } else { label.removeClass("disabled"); input .prop("checked", last_value = event.data.delete_played) .prop("disabled", false); } }); event_registry.on("set_playlist_status_result", event => { if (event.key !== "delete_played") return; if (event.status !== "success") show_change_error(_translations.sTxLZaJY || (_translations.sTxLZaJY = tr("Failed to change delete state")), event.error_msg || (_translations.WQE2CZa2 || (_translations.WQE2CZa2 = tr("timeout")))); else last_value = event.value; label.removeClass("disabled"); input .prop("checked", last_value) .prop("disabled", false); }); input.on("change", event => { label.addClass("disabled"); input.prop("disabled", true); event_registry.fire("set_playlist_status", { key: "delete_played", value: input.prop("checked") }); }); } /* flag notify song change */ { const input = container.find(".option-notify-songs-change"); const label = input.parents("label"); let last_value = undefined; event_registry.on("query_playlist_status", event => { last_value = undefined; label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); }); event_registry.on("playlist_status", event => { if (event.status === "error") { label.addClass("disabled"); input .prop("checked", false) .prop("disabled", true); } else { label.removeClass("disabled"); input .prop("checked", last_value = event.data.notify_song_change) .prop("disabled", false); } }); event_registry.on("set_playlist_status_result", event => { if (event.key !== "notify_song_change") return; if (event.status !== "success") show_change_error(_translations.VYtn59Ga || (_translations.VYtn59Ga = tr("Failed to change notify state")), event.error_msg || (_translations.YUZUVDR4 || (_translations.YUZUVDR4 = tr("timeout")))); else last_value = event.value; label.removeClass("disabled"); input .prop("checked", last_value) .prop("disabled", false); }); input.on("change", event => { label.addClass("disabled"); input.prop("disabled", true); event_registry.fire("set_playlist_status", { key: "notify_song_change", value: input.prop("checked") }); }); } /* status load timeout */ { let timeout; event_registry.on("query_playlist_status", event => { timeout = setTimeout(() => { event_registry.fire("playlist_status", { status: "error", error_msg: _translations.xp_ufUbh || (_translations.xp_ufUbh = tr("load timeout")) }); }, 5000); }); event_registry.on("playlist_status", event => clearTimeout(timeout)); } /* set status timeout */ { let timeouts = {}; event_registry.on("set_playlist_status", event => { clearTimeout(timeouts[event.key]); timeouts[event.key] = setTimeout(() => { event_registry.fire("set_playlist_status_result", { status: "timeout", key: event.key, }); }, 5000); }); event_registry.on("set_playlist_status_result", event => { clearTimeout(timeouts[event.key]); delete timeouts[event.key]; }); } } /* reload button */ { const button = tag.find(".button-reload"); let timeout; event_registry.on(["query_bot_status", "query_playlist_status"], event => { button.prop("disabled", true); clearTimeout(timeout); timeout = setTimeout(() => { button.prop("disabled", false); }, 1000); }); button.on("click", event => { event_registry.fire("query_bot_status"); event_registry.fire("query_playlist_status"); }); } tooltip(tag); /* initialize on show */ { let initialized = false; event_registry.on("show_container", event => { if (event.container !== "settings" || initialized) return; initialized = true; event_registry.fire("query_bot_status"); event_registry.fire("query_playlist_status"); }); } } function build_permission_container(event_registry, tag) { /* client search mechanism */ { const container = tag.find(".table-head .column-client-specific .client-select"); let list_shown = false; /* search list show/hide */ { const button_list_clients = container.find(".button-list-clients"); button_list_clients.on('click', event => event_registry.fire(list_shown ? "hide_client_list" : "show_client_list")); event_registry.on("show_client_list", () => { list_shown = true; button_list_clients.text(_translations.chknDAXh || (_translations.chknDAXh = tr("Hide clients"))); }); event_registry.on("hide_client_list", () => { list_shown = false; button_list_clients.text(_translations.n75WL7_X || (_translations.n75WL7_X = tr("List clients"))); }); } /* the search box */ { const input_search = container.find(".input-search"); const button_search = container.find(".button-search"); let search_timeout; let last_query; input_search.on('keyup', event => { const text = input_search.val(); if (text === last_query) return; if (text) event_registry.fire("filter_client_list", { filter: text }); else event_registry.fire("filter_client_list", { filter: undefined }); input_search.toggleClass("is-invalid", !list_shown && text === last_query); if (!list_shown) { button_search.prop("disabled", !text || !!search_timeout); } else { last_query = text; } }); input_search.on('keydown', event => { if (event.key === "Enter" && !list_shown && !button_search.prop("disabled")) button_search.trigger("click"); }); event_registry.on("show_client_list", () => { button_search.prop("disabled", true); input_search.attr("placeholder", _translations.ac3ohRnJ || (_translations.ac3ohRnJ = tr("Search client list"))); }); event_registry.on("hide_client_list", () => { button_search.prop("disabled", !input_search.val() || !!search_timeout); input_search.attr("placeholder", _translations.rRXCJPGM || (_translations.rRXCJPGM = tr("Client uid or database id"))); }); button_search.on("click", event => { button_search.prop("disabled", true); input_search.blur(); const text = input_search.val(); last_query = text; event_registry.fire("search_client", { text: text }); search_timeout = setTimeout(() => event_registry.fire("search_client_result", { status: "timeout" }), 5000); }); event_registry.on("search_client_result", event => { clearTimeout(search_timeout); search_timeout = 0; button_search.prop("disabled", !input_search.val()); if (event.status === "timeout") { createErrorModal(_translations.H7Wzuyk5 || (_translations.H7Wzuyk5 = tr("Client search failed")), _translations.Jl44qY0M || (_translations.Jl44qY0M = tr("Failed to perform client search.
Search resulted in a timeout."))).open(); return; } else if (event.status === "error" || event.status === "empty") { //TODO: Display the error somehow? input_search.addClass("is-invalid"); return; } else { event_registry.fire("special_client_set", { client: event.client }); } }); } /* the client list */ { const container = tag.find(".overlay-client-list"); event_registry.on("show_client_list", () => container.removeClass("hidden")); event_registry.on("hide_client_list", () => container.addClass("hidden")); const button_refresh = container.find(".button-clientlist-refresh"); const container_entries = container.find(".container-client-list"); event_registry.on("special_client_list", data => { button_refresh.prop("disabled", false); container.find(".overlay").addClass("hidden"); if (data.status === "error-permission") { const overlay = container.find(".overlay-query-error-permissions"); overlay.find("a").text(_translations.dtLjMQff || (_translations.dtLjMQff = tr("Insufficient permissions"))); overlay.removeClass("hidden"); } else if (data.status === "success") { container_entries.find(".client").remove(); /* clear */ if (!data.clients.length) { const overlay = container.find(".overlay-empty-list"); overlay.removeClass("hidden"); } else { for (const client of data.clients) { const tag = $.spawn("div").addClass("client").append(htmltags.generate_client_object({ add_braces: false, client_id: 0, client_database_id: client.database_id, client_name: client.name, client_unique_id: client.unique_id })); tag.on('dblclick', event => event_registry.fire("special_client_set", { client: client })); tag.attr("x-filter", client.database_id + "_" + client.name + "_" + client.unique_id); container_entries.append(tag); } } } else { const overlay = container.find(".overlay-query-error"); overlay.find("a").text(data.error_msg ? data.error_msg : _translations.xeMEtAeJ || (_translations.xeMEtAeJ = tr("query failed"))); overlay.removeClass("hidden"); } }); /* refresh button */ button_refresh.on('click', event => { button_refresh.prop("disabled", true); event_registry.fire("query_special_clients"); }); /* special client list query timeout handler */ { let query_timeout; event_registry.on("query_special_clients", event => { query_timeout = setTimeout(() => { event_registry.fire("special_client_list", { status: "error", error_msg: _translations.Q3EsnBCT || (_translations.Q3EsnBCT = tr("Query timeout")) }); }, 5000); }); event_registry.on("special_client_list", event => clearTimeout(query_timeout)); } /* first time client list show */ { let shown; event_registry.on('show_client_list', event => { if (shown) return; shown = true; event_registry.fire("query_special_clients"); }); } /* the client list filter */ { let filter; const overlay = container.find(".overlay-filter-no-result"); const update_filter = () => { let shown = 0, hidden = 0; container_entries.find(".client").each(function () { const text = this.getAttribute("x-filter"); if (!filter || text.toLowerCase().indexOf(filter) != -1) { this.classList.remove("hidden"); shown++; } else { this.classList.add("hidden"); hidden++; } }); if (shown == 0 && hidden == 0) return; overlay.toggleClass("hidden", shown != 0); }; event_registry.on("special_client_list", event => update_filter()); event_registry.on("filter_client_list", event => { filter = (event.filter || "").toLowerCase(); update_filter(); }); } } event_registry.on("special_client_set", event => { container.toggleClass("hidden", !!event.client); event_registry.fire("hide_client_list"); }); } /* the client info */ { const container = tag.find(".table-head .column-client-specific .client-info"); container.find(".button-client-deselect").on("click", event => { event_registry.fire("special_client_set", { client: undefined }); }); event_registry.on("special_client_set", event => { container.toggleClass("hidden", !event.client); const client_container = container.find(".container-selected-client"); client_container.find(".htmltag-client").remove(); if (event.client) { client_container.append(htmltags.generate_client_object({ client_unique_id: event.client.unique_id, client_name: event.client.name, client_id: 0, client_database_id: event.client.database_id, add_braces: false })); } }); } const power_needed_map = { i_client_music_rename_power: "i_client_music_needed_rename_power", i_client_music_modify_power: "i_client_music_needed_modify_power", i_client_music_delete_power: "i_client_music_needed_delete_power", i_playlist_view_power: "i_playlist_needed_view_power", i_playlist_modify_power: "i_playlist_needed_modify_power", i_playlist_permission_modify_power: "i_playlist_needed_permission_modify_power", i_playlist_song_add_power: "i_playlist_song_needed_add_power", i_playlist_song_move_power: "i_playlist_song_needed_move_power", i_playlist_song_remove_power: "i_playlist_song_needed_remove_power", b_virtualserver_playlist_permission_list: "b_virtualserver_playlist_permission_list" }; const needed_power_map = Object.entries(power_needed_map).reduce((ret, entry) => { const [key, value] = entry; ret[value] = key; return ret; }, {}); /* general permissions */ { /* permission input functionality */ { tag.find(".general-permission").each((_, _e) => { const elem = $(_e); const permission_name = elem.attr("x-permission"); if (!permission_name) return; const input = elem.find("input"); input.attr("maxlength", 6); let last_sync_value = undefined; event_registry.on("query_general_permissions", event => { input.prop("disabled", true).val(null); input.attr("placeholder", _translations.oN5z34tB || (_translations.oN5z34tB = tr("loading..."))); }); event_registry.on("general_permissions", event => { input.prop("disabled", true).val(null); if (event.status === "timeout") { input.attr("placeholder", _translations.rriL0uvS || (_translations.rriL0uvS = tr("load timeout"))); } else if (event.status === "success") { input.prop("disabled", false); //TODO: Check permissions? input.attr("placeholder", null); const value = event.permissions ? event.permissions[permission_name] || 0 : 0; last_sync_value = value; input.val(value); } else { input.attr("placeholder", event.error_msg || (_translations.NMxty5e5 || (_translations.NMxty5e5 = tr("load error")))); } }); event_registry.on("set_general_permission_result", event => { if (event.key !== permission_name) return; input.prop("disabled", false); //TODO: Check permissions? input.attr("placeholder", null); if (event.status === "success") { input.val(event.value); last_sync_value = event.value; } else if (event.status === "error") { if (typeof last_sync_value === "number") input.val(last_sync_value); createErrorModal(_translations.v50TMxti || (_translations.v50TMxti = tr("Failed to change permission")), tra("Failed to change permission:{:br:}{}", event.error_msg)).open(); } }); input.on("focusout", event => { if (input.prop("disabled")) return; const value = parseInt(input.val()); if (value === last_sync_value) return; input.prop("disabled", true).val(null); input.attr("placeholder", _translations.bjvee5Ts || (_translations.bjvee5Ts = tr("applying..."))); event_registry.fire("set_general_permission", { key: permission_name, value: value || 0 }); }); input.on("keyup", event => event.key === "Enter" && input.blur()); }); } /* the tooltip functionality */ { tag.find(".general-permission").each((_, _e) => { const elem = $(_e); const permission_name = elem.attr("x-permission"); if (!permission_name) return; const required_power = needed_power_map[permission_name]; if (!required_power) return; let last_sync_value = undefined; let current_tag; let loading = false; let query_result; event_registry.on("general_permissions", event => { if (event.status === "success") last_sync_value = event.permissions ? event.permissions[permission_name] || 0 : 0; }); event_registry.on("set_general_permission_result", event => { if (event.key !== permission_name) return; if (event.status === "success") last_sync_value = event.value; }); event_registry.on("refresh_permissions", event => { query_result = undefined; /* require for the next time */ }); const show_query_result = () => { if (!current_tag) return; const container_groups = current_tag.find(".container-groups"); container_groups.children().remove(); current_tag.find(".container-status").addClass("hidden"); if (loading) { current_tag.find(".status-loading").removeClass("hidden"); } else if (!query_result || query_result.status === "error") { current_tag .find(".status-error").removeClass("hidden") .text((query_result ? query_result.error_msg : "") || (_translations.uaoGscii || (_translations.uaoGscii = tr("failed to query data")))); } else if (query_result.status === "timeout") { current_tag .find(".status-error").removeClass("hidden") .text(_translations.qZHZIWWT || (_translations.qZHZIWWT = tr("timeout while loading"))); } else { let count = 0; for (const group of (query_result.groups || [])) { if (group.value !== -1 && group.value < last_sync_value) continue; count++; container_groups.append($.spawn("div").addClass("group").text(" - " + group.name + " (" + group.id + ")")); } if (count === 0) current_tag.find(".status-no-groups").removeClass("hidden"); } }; tooltip.initialize(elem, { on_show(tag) { current_tag = tag; if (!query_result && !loading) { event_registry.fire("query_group_permissions", { permission_name: required_power }); loading = true; } show_query_result(); }, on_hide(tag) { current_tag = undefined; } }); event_registry.on("group_permissions", event => { if (event.permission_name !== required_power) return; loading = false; query_result = event; show_query_result(); }); }); /* refresh mechanism */ { event_registry.on("refresh_permissions", event => event_registry.fire("query_general_permissions")); } } /* permission set timeout */ { let permission_timers = {}; event_registry.on("set_general_permission", event => { if (permission_timers[event.key]) clearTimeout(permission_timers[event.key]); permission_timers[event.key] = setTimeout(() => { event_registry.fire("set_general_permission_result", { key: event.key, status: "error", error_msg: _translations.WA9xLJOj || (_translations.WA9xLJOj = tr("controller timeout")) }); }, 5000); }); event_registry.on("set_general_permission_result", event => { clearTimeout(permission_timers[event.key]); delete permission_timers[event.key]; }); } /* group query timeout */ { let timers = {}; event_registry.on("query_group_permissions", event => { if (timers[event.permission_name]) clearTimeout(timers[event.permission_name]); timers[event.permission_name] = setTimeout(() => { event_registry.fire("group_permissions", { permission_name: event.permission_name, status: "timeout" }); }, 5000); }); event_registry.on("group_permissions", event => { clearTimeout(timers[event.permission_name]); delete timers[event.permission_name]; }); } /* query timeout */ { let query_timeout; event_registry.on("query_general_permissions", event => { clearTimeout(query_timeout); query_timeout = setTimeout(() => { event_registry.fire("general_permissions", { status: "timeout" }); }, 5000); }); event_registry.on("general_permissions", event => clearTimeout(query_timeout)); } /* refresh button */ { const button = tag.find(".button-permission-refresh"); let refresh_timer; let loading_client_permissions = false; let loading_general_permissions = false; const update_button = () => button.prop("disabled", refresh_timer || loading_client_permissions || loading_general_permissions); event_registry.on("query_general_permissions", event => { loading_general_permissions = true; update_button(); }); event_registry.on("general_permissions", event => { loading_general_permissions = false; update_button(); }); event_registry.on("query_client_permissions", event => { loading_client_permissions = true; update_button(); }); event_registry.on("client_permissions", event => { loading_client_permissions = false; update_button(); }); button.on('click', event => { event_registry.fire("refresh_permissions"); /* allow refreshes only every second */ refresh_timer = setTimeout(() => { refresh_timer = undefined; update_button(); }, 1000); }); } } /* client specific permissions */ { const container = tag.find(".column-client-specific"); let client_database_id = 0; let needed_permissions = {}; /* needed permissions updater */ { event_registry.on("general_permissions", event => { if (event.status !== "success") return; needed_permissions = event.permissions; }); event_registry.on("set_general_permission_result", event => { if (event.status !== "success") return; needed_permissions[event.key] = event.value; }); } event_registry.on("special_client_set", event => { client_database_id = event.client ? event.client.database_id : 0; container.find(".client-permission").toggleClass("hidden", !event.client); if (client_database_id) event_registry.fire("query_client_permissions", { client_database_id: client_database_id }); }); const enabled_class = "client-apply"; const disabled_class = "client-delete"; container.find(".client-permission").each((_, _e) => { const elem = $(_e); const input = elem.find("input"); const status_indicator = elem.find(".icon_em"); const permission_name = elem.attr("x-permission"); const permission_needed_name = power_needed_map[permission_name]; let last_sync_value = undefined; let hide_indicator = false; if (typeof permission_needed_name !== "string") { log.warn(LogCategory.GENERAL, _translations.QrA6IXLw || (_translations.QrA6IXLw = tr("Missing permission needed mapping for %s")), permission_name); return; } const update_indicator = () => { const value = parseInt(input.val()); const needed = typeof needed_permissions[permission_needed_name] === "number" ? needed_permissions[permission_needed_name] : 0; const flag = value == -1 ? true : isNaN(value) || value == 0 ? false : value >= needed; status_indicator.toggle(!hide_indicator); status_indicator.toggleClass(enabled_class, flag).toggleClass(disabled_class, !flag); }; event_registry.on("special_client_set", event => { last_sync_value = undefined; }); event_registry.on("general_permissions", event => update_indicator()); event_registry.on("set_general_permission_result", event => { if (event.key !== permission_needed_name) return; if (event.status !== "success") return; update_indicator(); }); /* loading the permission */ event_registry.on("query_client_permissions", event => { if (event.client_database_id !== client_database_id) return; last_sync_value = undefined; hide_indicator = true; input.prop("disabled", true).val(null); input.attr("placeholder", _translations.vXhgxTE9 || (_translations.vXhgxTE9 = tr("loading..."))); update_indicator(); }); event_registry.on('client_permissions', event => { if (event.client_database_id !== client_database_id) return; hide_indicator = false; input.prop("disabled", true).val(null); if (event.status === "timeout") { input.attr("placeholder", _translations.qTOaE8kn || (_translations.qTOaE8kn = tr("load timeout"))); } else if (event.status === "success") { input.prop("disabled", false); //TODO: Check permissions? input.attr("placeholder", null); const value = event.permissions ? event.permissions[permission_name] || 0 : 0; last_sync_value = value; input.val(value); } else { input.attr("placeholder", event.error_msg || (_translations.W6NSppXR || (_translations.W6NSppXR = tr("load error")))); } update_indicator(); }); /* permission editing */ input.attr("maxlength", 6); input.on("focusout", event => { if (!client_database_id) return; const value = parseInt(input.val()); if (value === last_sync_value) return; input.prop("disabled", true).val(null); input.attr("placeholder", _translations.NRqLeDXD || (_translations.NRqLeDXD = tr("applying..."))); event_registry.fire("set_client_permission", { client_database_id: client_database_id, key: permission_name, value: value || 0 }); hide_indicator = true; update_indicator(); }); input.on("change", () => update_indicator()); input.on("keyup", event => event.key === "Enter" && input.blur()); event_registry.on("set_client_permission_result", event => { if (event.key !== permission_name) return; input.prop("disabled", false); //TODO: Check permissions? input.attr("placeholder", null); if (event.status === "success") { input.val(event.value); last_sync_value = event.value; } else if (event.status === "error") { if (typeof last_sync_value === "number") input.val(last_sync_value); createErrorModal(_translations.IezxIp9G || (_translations.IezxIp9G = tr("Failed to change permission")), tra("Failed to change permission:{:br:}{}", event.error_msg)).open(); } hide_indicator = false; update_indicator(); }); }); /* client permission query timeout */ { let timeout = {}; event_registry.on("query_client_permissions", event => { if (timeout[event.client_database_id]) clearTimeout(timeout[event.client_database_id]); timeout[event.client_database_id] = setTimeout(() => { event_registry.fire("client_permissions", { status: "timeout", client_database_id: event.client_database_id }); }, 5000); }); event_registry.on("client_permissions", event => { clearTimeout(timeout[event.client_database_id]); }); } /* client permission set timeout */ { let timeout = {}; event_registry.on("set_client_permission", event => { const key = event.client_database_id + "_" + event.key; if (timeout[key]) clearTimeout(timeout[key]); timeout[key] = setTimeout(() => { event_registry.fire("set_client_permission_result", { key: event.key, status: "error", client_database_id: event.client_database_id, error_msg: _translations.TcN1P2qm || (_translations.TcN1P2qm = tr("timeout")) }); }, 5000); }); event_registry.on("set_client_permission_result", event => { const key = event.client_database_id + "_" + event.key; if (timeout[key]) { clearTimeout(timeout[key]); delete timeout[key]; } }); } event_registry.on("refresh_permissions", event => { if (client_database_id) event_registry.fire("query_client_permissions", { client_database_id: client_database_id }); }); tooltip(container); } /* a title attribute for permission column */ tag.find(".table-body .column-permission a").each(function () { this.setAttribute("title", this.textContent); }); /* initialize on show */ { let initialized = false; event_registry.on("show_container", event => { if (event.container !== "permissions" || initialized) return; initialized = true; event_registry.fire("special_client_set", { client: undefined }); event_registry.fire("query_general_permissions", {}); }); } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["bb89811e744e5d317f61f537cddef6033b386003838e9d5b5605e65af1c35b7d"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["bb89811e744e5d317f61f537cddef6033b386003838e9d5b5605e65af1c35b7d"] = "bb89811e744e5d317f61f537cddef6033b386003838e9d5b5605e65af1c35b7d"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "bTUbzE93", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (46,35)" }, { name: "eXHtaUUE", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (46,56)" }, { name: "CbxHqsI9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (96,65)" }, { name: "i_CcdmUJ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (96,83)" }, { name: "MFoo4HUQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (97,65)" }, { name: "EOvfKbzY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (97,83)" }, { name: "lLkLuT23", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (386,39)" }, { name: "K0mUVYLm", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (391,65)" }, { name: "Fqmae3Ke", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (399,65)" }, { name: "TWiMcMlr", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (408,65)" }, { name: "dqF7V4bv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (409,71)" }, { name: "oqlWN8_x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalNewcomer.ts (415,39)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { const next_step = { "welcome": "microphone", //"microphone": app.is_web() ? "identity" : "speaker", /* speaker setup only for the native client! */ "microphone": "identity", "speaker": "identity", "identity": "finish" }; const last_step = (() => { const result = {}; for (const key of Object.keys(next_step)) if (!result[next_step[key]]) result[next_step[key]] = key; return result; })(); function openModalNewcomer() { let modal = createModal({ header: tra("Welcome to the {}", app.is_web() ? "TeaSpeak - Web client" : "TeaSpeak - Client"), body: () => $("#tmpl_newcomer").renderTag({ is_web: app.is_web() }).children(), footer: null, width: "", closeable: false }); const event_registry = new events.Registry(); event_registry.enable_debug("newcomer"); modal.htmlTag.find(".modal-body").addClass("modal-newcomer"); initializeBasicFunctionality(modal.htmlTag, event_registry); initializeStepWelcome(modal.htmlTag.find(".container-body .step.step-welcome"), event_registry); initializeStepIdentity(modal.htmlTag.find(".container-body .step.step-identity"), event_registry); initializeStepMicrophone(modal.htmlTag.find(".container-body .step.step-microphone"), event_registry, modal); initializeStepFinish(modal.htmlTag.find(".container-body .step.step-finish"), event_registry); event_registry.on("exit_guide", event => { if (event.ask_yesno) Modals.spawnYesNo(_translations.bTUbzE93 || (_translations.bTUbzE93 = tr("Are you sure?")), _translations.eXHtaUUE || (_translations.eXHtaUUE = tr("Do you really want to skip the basic setup guide?")), result => { if (result) event_registry.fire("exit_guide", { ask_yesno: false }); }); else modal.close(); }); event_registry.fire("show_step", { step: "welcome" }); modal.open(); event_registry.fire_async("modal-shown"); return modal; } Modals.openModalNewcomer = openModalNewcomer; function initializeBasicFunctionality(tag, event_registry) { const container_header = tag.find(".container-header"); const tag_body = tag.find(".container-body .body"); /* step navigation */ event_registry.on("show_step", event => { tag_body.find(".step").addClass("hidden"); container_header.find(".step").addClass("hidden"); tag_body.find(".step.step-" + event.step).removeClass("hidden"); container_header.find(".step.step-" + event.step).removeClass("hidden"); }); /* button controller */ { const buttons = tag.find(".buttons"); const button_last_step = buttons.find(".button-last-step"); const button_next_step = buttons.find(".button-next-step"); button_last_step.on('click', event => { if (last_step[current_step]) event_registry.fire("show_step", { step: last_step[current_step] }); else event_registry.fire("exit_guide", { ask_yesno: true }); }); let current_step; button_next_step.on('click', event => { if (next_step[current_step]) event_registry.fire("show_step", { step: next_step[current_step] }); else event_registry.fire("exit_guide", { ask_yesno: false }); }); event_registry.on("show_step", event => { current_step = event.step; button_next_step.text(next_step[current_step] ? _translations.CbxHqsI9 || (_translations.CbxHqsI9 = tr("Next step")) : _translations.i_CcdmUJ || (_translations.i_CcdmUJ = tr("Finish guide"))); button_last_step.text(last_step[current_step] ? _translations.MFoo4HUQ || (_translations.MFoo4HUQ = tr("Last step")) : _translations.EOvfKbzY || (_translations.EOvfKbzY = tr("Skip guide"))); }); event_registry.on("show_step", event => button_next_step.prop("disabled", true)); event_registry.on("show_step", event => button_last_step.prop("disabled", true)); event_registry.on("step-status", event => button_next_step.prop("disabled", !event.next_button)); event_registry.on("step-status", event => button_last_step.prop("disabled", !event.previous_button)); } } function initializeStepWelcome(tag, event_registry) { event_registry.on("show_step", e => { if (e.step !== "welcome") return; event_registry.fire_async("step-status", { next_button: true, previous_button: true }); }); } function initializeStepFinish(tag, event_registry) { event_registry.on("show_step", e => { if (e.step !== "finish") return; event_registry.fire_async("step-status", { next_button: true, previous_button: true }); }); } function initializeStepIdentity(tag, event_registry) { const profile_events = new events.Registry(); profile_events.enable_debug("settings-identity"); Modals.modal_settings.initialize_identity_profiles_controller(profile_events); Modals.modal_settings.initialize_identity_profiles_view(tag, profile_events, { forum_setuppable: false }); let step_shown = false; let help_animation_done = false; const profiles_valid = () => profiles.profiles().findIndex(e => e.valid()) !== -1; const update_step_status = () => { event_registry.fire_async("step-status", { next_button: help_animation_done && profiles_valid(), previous_button: help_animation_done }); }; profile_events.on("query-profile-validity-result", event => step_shown && event.status === "success" && event.valid && update_step_status()); event_registry.on("show_step", e => { step_shown = e.step === "identity"; if (!step_shown) return; update_step_status(); }); /* the help sequence */ { const container = tag.find(".container-settings-identity-profile"); const container_help_text = tag.find(".container-help-text"); const container_profile_list = tag.find(".highlight-profile-list"); const container_profile_settings = tag.find(".highlight-profile-settings"); const container_identity_settings = tag.find(".highlight-identity-settings"); let is_first_show = true; event_registry.on("show_step", event => { if (!is_first_show || event.step !== "identity") return; is_first_show = false; container.addClass("help-shown"); const text = tr("After you've successfully set upped your microphone,\n" + "lets setup some profiles and identities!\n" + "\n" + "Connect profiles determine, how your're authenticating yourself with the server.\n" + "So basically they're your identity.\n" + "In the following I'll guid you thru the options and GUI elements.\n" + "\n" + "To continue click anywhere on the screen."); set_help_text(text); $("body").one('mousedown', event => show_profile_list_help()); }); const set_help_text = text => { container_help_text.empty(); text.split("\n").forEach(e => container_help_text.append(e == "" ? $.spawn("br") : $.spawn("a").text(e))); }; const show_profile_list_help = () => { container.find(".highlighted").removeClass("highlighted"); container_profile_list.addClass("highlighted"); const update_position = () => { const font_size = parseFloat(getComputedStyle(container_help_text[0]).fontSize); const offset = container_profile_list.offset(); const abs = container.offset(); container_help_text.css({ top: offset.top - abs.top, left: ((offset.left - abs.left) + container_profile_list.outerWidth() + font_size) + "px", right: "1em", bottom: "1em" }); }; update_position(); container_help_text.off('resize').on('resize', update_position); const text = tr("You could have as many connect profiles as you want.\n" + "All created profiles will be listed here.\n" + "\n" + "To create a new profile just simply click the blue button \"Create profile\" and enter a profile name.\n" + "If you want to delete a profile you've to select that profile and click the delete button.\n" + "\n" + "By default we're using the \"default\" profile\n" + "to connect to any server. o change the default profile\n" + "just select the new profile and press the \"select as default\" button.\n" + "\n" + "To continue click anywhere on the screen."); set_help_text(text); $("body").one('mousedown', event => show_profile_settings_help()); }; const show_profile_settings_help = () => { container.find(".highlighted").removeClass("highlighted"); container_profile_settings.addClass("highlighted"); const update_position = () => { const font_size = parseFloat(getComputedStyle(container_help_text[0]).fontSize); const container_settings_offset = container_profile_settings.offset(); const right = container_profile_settings.outerWidth() + font_size * 2; container_help_text.css({ top: container_settings_offset.top - container.offset().top, left: "1em", right: right + "px", bottom: "1em" }); }; set_help_text(tr("In the upper left, you'll find the profile settings for the selected profile.\n" + "You could give each profile an individual name. You could also specify the default connect nickname here.\n" + "\n" + "The last option \"Identity Type\" determines on what your identity is based on.\n" + "TeaSpeak has two possibilities to identify yourself:\n" + "1. Identify yourself by your TeaSpeak forum account\n" + "2. Identify by an own generated cryptographic identity\n" + "The second methods is also known as a TeamSpeak 3 identity.\n" + "\n" + "To continue click anywhere on the screen.")); update_position(); container_help_text.off('resize').on('resize', update_position); $("body").one('mousedown', event => show_identity_settings_help()); }; const show_identity_settings_help = () => { container.find(".highlighted").removeClass("highlighted"); container_identity_settings.addClass("highlighted"); const update_position = () => { const font_size = parseFloat(getComputedStyle(container_help_text[0]).fontSize); const container_identity_offset = container_identity_settings.offset(); const right = container_profile_settings.outerWidth() + font_size * 2; container_help_text.css({ top: container_identity_offset.top - container.offset().top, left: "1em", right: right + "px", bottom: "1em" }); }; set_help_text(tr("When selecting an identify type, some corresponding will pop up in the highlighted area.\n" + "\n" + "But don't worry, we've already generated\n" + "a cryptographic identity for you!\n" + "So you don't have to change anything before you start.")); update_position(); container_help_text.off('resize').on('resize', update_position); $("body").one('mousedown', event => hide_help()); }; const hide_help = () => { container.find(".highlighted").removeClass("highlighted"); container.addClass("hide-help"); setTimeout(() => container.removeClass("help-shown"), 1000); container_help_text.off('resize'); help_animation_done = true; update_step_status(); }; } } function initializeStepMicrophone(tag, event_registry, modal) { const microphone_events = new events.Registry(); //microphone_events.enable_debug("settings-microphone"); Modals.modal_settings.initialize_audio_microphone_controller(microphone_events); Modals.modal_settings.initialize_audio_microphone_view(tag, microphone_events); modal.close_listener.push(() => microphone_events.fire_async("deinitialize")); let help_animation_done = false; const update_step_status = () => event_registry.fire_async("step-status", { next_button: help_animation_done, previous_button: help_animation_done }); event_registry.on("show_step", e => { if (e.step !== "microphone") return; update_step_status(); }); /* the help sequence */ { const container = tag.find(".container-settings-audio-microphone"); const container_help_text = tag.find(".container-help-text"); const container_profile_list = tag.find(".highlight-microphone-list"); const container_profile_settings = tag.find(".highlight-microphone-settings"); let is_first_show = true; event_registry.on("show_step", event => { if (!is_first_show || event.step !== "microphone") return; is_first_show = false; container.addClass("help-shown"); const text = tr("Firstly we need to setup a microphone.\n" + "Let me guide you thru the basic UI elements.\n" + "\n" + "To continue click anywhere on the screen."); set_help_text(text); $("body").one('mousedown', event => show_microphone_list_help()); }); const set_help_text = text => { container_help_text.empty(); text.split("\n").forEach(e => container_help_text.append(e == "" ? $.spawn("br") : $.spawn("a").text(e))); }; const show_microphone_list_help = () => { container.find(".highlighted").removeClass("highlighted"); container_profile_list.addClass("highlighted"); const update_position = () => { const font_size = parseFloat(getComputedStyle(container_help_text[0]).fontSize); const offset = container_profile_list.offset(); const abs = container.offset(); container_help_text.css({ top: offset.top - abs.top, left: ((offset.left - abs.left) + container_profile_list.outerWidth() + font_size) + "px", right: "1em", bottom: "1em" }); }; update_position(); container_help_text.off('resize').on('resize', update_position); const text = tr("All your available microphones are listed within this box.\n" + "\n" + "The currently selected microphone\n" + "is marked with a green checkmark. To change the selected microphone\n" + "just click on the new one.\n" + "\n" + "To continue click anywhere on the screen."); set_help_text(text); $("body").one('mousedown', event => show_microphone_settings_help()); }; const show_microphone_settings_help = () => { container.find(".highlighted").removeClass("highlighted"); container_profile_settings.addClass("highlighted"); const update_position = () => { const font_size = parseFloat(getComputedStyle(container_help_text[0]).fontSize); const container_settings_offset = container_profile_settings.offset(); const right = container_profile_settings.outerWidth() + font_size * 2; container_help_text.css({ top: container_settings_offset.top - container.offset().top, left: "1em", right: right + "px", bottom: "1em" }); }; container_help_text.empty(); container_help_text.append($.spawn("div").addClass("help-microphone-settings").append($.spawn("a").text(_translations.lLkLuT23 || (_translations.lLkLuT23 = tr("On the right side you'll find all microphone settings."))), $.spawn("br"), $.spawn("a").text("TeaSpeak has three voice activity detection types:"), $.spawn("ol").append($.spawn("li").addClass("vad-type").append($.spawn("a").addClass("title").text(_translations.K0mUVYLm || (_translations.K0mUVYLm = tr("Push to Talk"))), $.spawn("a").addClass("description").html(tr("To transmit audio data you'll have to
" + "press a key. The key could be selected " + "via the button right to the radio button."))), $.spawn("li").addClass("vad-type").append($.spawn("a").addClass("title").text(_translations.Fqmae3Ke || (_translations.Fqmae3Ke = tr("Voice activity detection"))), $.spawn("a").addClass("description").html(tr("In this mode, TeaSpeak will continuously analyze your microphone input. " + "If the audio level is grater than a certain threshold, " + "the audio will be transmitted. " + "The threshold is changeable via the \"Sensitivity Settings\" slider."))), $.spawn("li").addClass("vad-type").append($.spawn("a").addClass("title").html(_translations.TWiMcMlr || (_translations.TWiMcMlr = tr("Always active"))), $.spawn("a").addClass("description").text(_translations.dqF7V4bv || (_translations.dqF7V4bv = tr("Continuously transmit any audio data.\n"))))), $.spawn("br"), $.spawn("a").text(_translations.oqlWN8_x || (_translations.oqlWN8_x = tr("Now you're ready to configure your microphone. Just click anywhere on the screen."))))); update_position(); container_help_text.off('resize').on('resize', update_position); $("body").one('mousedown', event => hide_help()); }; const hide_help = () => { container.find(".highlighted").removeClass("highlighted"); container.addClass("hide-help"); setTimeout(() => container.removeClass("help-shown"), 1000); container_help_text.off('resize'); help_animation_done = true; update_step_status(); }; } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["37e3848da43122a37a986ffe0d4318d9c4892236cfecba4532909138fc47ba58"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["37e3848da43122a37a986ffe0d4318d9c4892236cfecba4532909138fc47ba58"] = "37e3848da43122a37a986ffe0d4318d9c4892236cfecba4532909138fc47ba58"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "J_SnpbWx", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (10,21)" }, { name: "odLgoCTL", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (43,21)" }, { name: "KGo6XEt2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (73,30)" }, { name: "HDvApYkd", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (73,53)" }, { name: "hLXhQgZZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (88,21)" }, { name: "LVBcNpNW", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (113,46)" }, { name: "vXw52Eni", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (113,82)" }, { name: "h1C4jc6K", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (135,46)" }, { name: "r6Y8ZEYM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (135,82)" }, { name: "O6_EO880", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (142,36)" }, { name: "UwbofYR1", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (142,57)" }, { name: "WbN1Rawl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (183,27)" }, { name: "EccIOEia", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (212,50)" }, { name: "tr0bL6Eo", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (212,80)" }, { name: "DleZumwj", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (235,31)" }, { name: "dQbnEzVb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (253,38)" }, { name: "mpjeWled", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (253,65)" }, { name: "FvJMcfQT", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (357,30)" }, { name: "DIfGV_4h", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistEdit.ts (357,67)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function spawnPlaylistSongInfo(song) { let modal; modal = createModal({ header: _translations.J_SnpbWx || (_translations.J_SnpbWx = tr("Song info")), body: () => { try { song.metadata = JSON.parse(song.song_metadata); } catch (e) { } let template = $("#tmpl_playlist_edit-song_info").renderTag(song); template = $.spawn("div").append(template); const text_area = template.find(".property-metadata-raw textarea"); template.find(".toggle-metadata").on('click', event => { if (text_area.is(":visible")) { template.find(".toggle-metadata").text("show"); } else { template.find(".toggle-metadata").text("hide"); } text_area.slideToggle({ duration: 250 }); }); text_area.hide(); return template; }, footer: undefined, width: 750 }); modal.open(); } Modals.spawnPlaylistSongInfo = spawnPlaylistSongInfo; function spawnSongAdd(playlist, callback_add) { let modal; modal = createModal({ header: _translations.odLgoCTL || (_translations.odLgoCTL = tr("Add a song")), body: () => { let template = $("#tmpl_playlist_edit-song_add").renderTag(); template = $.spawn("div").append(template); const url = template.find(".property-url .value"); const url_loader = template.find(".property-loader .value"); const button_add = template.find(".container-buttons .button-add"); const button_cancel = template.find(".container-buttons .button-cancel"); url.on('change keyup', event => { button_add.prop("disabled", url.val().toString().length == 0); }).trigger('change'); button_cancel.on('click', event => modal.close()); button_add.on('click', event => { callback_add(url.val(), url_loader.val()); modal.close(); }); return template; }, footer: undefined, width: 750 }); modal.open(); } Modals.spawnSongAdd = spawnSongAdd; function spawnPlaylistEdit(client, playlist) { { createErrorModal(_translations.KGo6XEt2 || (_translations.KGo6XEt2 = tr("Not implemented")), _translations.HDvApYkd || (_translations.HDvApYkd = tr("Playlist editing hasn't yet been implemented"))).open(); return; } let modal; let changed_properties = {}; let changed_permissions = {}; let callback_permission_update; const update_save = () => { const save_button = modal.htmlTag.find(".buttons .button-save"); save_button.prop("disabled", (Object.keys(changed_properties).length + Object.keys(changed_permissions).length) == 0); }; modal = createModal({ header: _translations.hLXhQgZZ || (_translations.hLXhQgZZ = tr("Edit playlist")), body: () => { let template = $("#tmpl_playlist_edit").renderTag().tabify(); callback_permission_update = apply_permissions(template, client, playlist, (key, value) => { console.log("Change permission %o => %o", key, value); changed_permissions[key] = value; update_save(); }); const callback_song_id = apply_songs(template, client, playlist); apply_properties(template, client, playlist, (key, value) => { console.log("Change property %o => %o", key, value); changed_properties[key] = value; update_save(); }, callback_song_id); template.find(".buttons .button-save").on('click', event => { if (Object.keys(changed_properties).length != 0) { changed_properties["playlist_id"] = playlist.playlist_id; client.serverConnection.send_command("playlistedit", changed_properties).then(() => { changed_properties = {}; update_save(); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.LVBcNpNW || (_translations.LVBcNpNW = tr("Failed to change properties.")), (_translations.vXw52Eni || (_translations.vXw52Eni = tr("Failed to change playlist properties.
Error: "))) + error).open(); }); } if (Object.keys(changed_permissions).length != 0) { const array = []; for (const permission_key of Object.keys(changed_permissions)) { array.push({ permvalue: changed_permissions[permission_key], permnegated: false, permskip: false, permsid: permission_key }); } array[0]["playlist_id"] = playlist.playlist_id; client.serverConnection.send_command("playlistaddperm", array).then(() => { changed_permissions = {}; update_save(); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.h1C4jc6K || (_translations.h1C4jc6K = tr("Failed to change permission.")), (_translations.r6Y8ZEYM || (_translations.r6Y8ZEYM = tr("Failed to change playlist permissions.
Error: "))) + error).open(); }); } }); template.find(".buttons .button-close").on('click', event => { if ((Object.keys(changed_properties).length + Object.keys(changed_permissions).length) != 0) { Modals.spawnYesNo(_translations.O6_EO880 || (_translations.O6_EO880 = tr("Are you sure?")), _translations.UwbofYR1 || (_translations.UwbofYR1 = tr("Do you really want to discard all your changes?")), result => { if (result) modal.close(); }); return; } modal.close(); }); return template; }, footer: undefined, width: 750 }); update_save(); modal.open(); return modal; } Modals.spawnPlaylistEdit = spawnPlaylistEdit; function apply_songs(tag, client, playlist) { const owns_playlist = playlist.playlist_owner_dbid == client.getClient().properties.client_database_id; const song_tag = tag.find(".container-songs"); let replaying_song_id = 0; let selected_song; const set_song_info = (text) => { const tag = song_tag.find(".info-message"); if (text && text.length > 0) { tag.text(text).show(); } else tag.hide(); }; const set_current_song = (id) => { /* this method shall enforce an update */ replaying_song_id = id; update_songs(); }; const update_songs = () => { set_song_info(_translations.WbN1Rawl || (_translations.WbN1Rawl = tr("loading song list"))); client.serverConnection.command_helper.request_playlist_songs(playlist.playlist_id).then(result => { const entries_tag = song_tag.find(".song-list-entries"); const entry_template = $("#tmpl_playlist_edit-song_entry"); entries_tag.empty(); for (const song of result) { const rendered = entry_template.renderTag(song); rendered.find(".button-info").on('click', event => { spawnPlaylistSongInfo(song); }); const button_delete = rendered.find(".button-delete"); if (!owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_SONG_REMOVE_POWER).granted(playlist.needed_power_song_remove)) button_delete.detach(); else button_delete.on('click', event => { client.serverConnection.send_command("playlistsongremove", { playlist_id: playlist.playlist_id, song_id: song.song_id }).then(() => { rendered.slideToggle({ duration: 250, done(animation, jumpedToEnd) { rendered.detach(); } }); rendered.hide(250); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.EccIOEia || (_translations.EccIOEia = tr("Failed to remove song.")), (_translations.tr0bL6Eo || (_translations.tr0bL6Eo = tr("Failed to remove song/url from the playlist.
Error: "))) + error).open(); }); }); if (song.song_id == replaying_song_id) rendered.addClass("playing"); rendered.on('click', event => { selected_song = song; entries_tag.find(".selected").removeClass("selected"); rendered.addClass("selected"); }); entries_tag.append(rendered); } const entry_container = song_tag.find(".song-list-entries-container"); if (entry_container.hasScrollBar()) entry_container.addClass("scrollbar"); set_song_info("displaying " + result.length + " songs"); }).catch(error => { console.error(error); set_song_info(_translations.DleZumwj || (_translations.DleZumwj = tr("failed to load song list"))); //TODO improve error handling! }); }; song_tag.find(".button-refresh").on('click', event => update_songs()); song_tag.find(".button-song-add").on('click', event => { spawnSongAdd(playlist, (url, loader) => { //playlist_id invoker previous url client.serverConnection.send_command("playlistsongadd", { playlist_id: playlist.playlist_id, invoker: loader, url: url }).then(() => { update_songs(); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.dQbnEzVb || (_translations.dQbnEzVb = tr("Failed to add song.")), (_translations.mpjeWled || (_translations.mpjeWled = tr("Failed to add song/url to the playlist.
Error: "))) + error).open(); }); }); }).prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_SONG_ADD_POWER).granted(playlist.needed_power_song_add)); /* setTimeout(update_songs, 100); */ /* We dont have to call that here because it will get called over set_current_song when we received the current song id */ return set_current_song; } function apply_permissions(tag, client, playlist, change_permission) { const owns_playlist = playlist.playlist_owner_dbid == client.getClient().properties.client_database_id; const permission_tag = tag.find(".container-permissions"); const nopermission_tag = tag.find(".container-no-permissions"); const update_permissions = () => { if (!client.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_PLAYLIST_PERMISSION_LIST).granted(1)) { nopermission_tag.show(); permission_tag.hide(); } else { nopermission_tag.hide(); permission_tag.show(); permission_tag.find(".permission input").prop("disabled", true); client.permissions.requestPlaylistPermissions(playlist.playlist_id).then(permissions => { permission_tag.find(".permission input") .val(0) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_PERMISSION_MODIFY_POWER).granted(playlist.needed_power_permission_modify)); for (const permission of permissions) { const tag = permission_tag.find(".permission[permission='" + permission.type.name + "']"); if (permission.value != -2) tag.find("input").val(permission.value); } }); } }; permission_tag.find(".permission").each((index, _element) => { const element = $(_element); element.find("input").on('change', event => { console.log(element.find("input").val()); change_permission(element.attr("permission"), parseInt(element.find("input").val().toString())); }); }); update_permissions(); return update_permissions; } function apply_properties(tag, client, playlist, change_property, callback_current_song) { const owns_playlist = playlist.playlist_owner_dbid == client.getClient().properties.client_database_id; client.serverConnection.command_helper.request_playlist_info(playlist.playlist_id).then(info => { tag.find(".property-owner input") .val(info.playlist_owner_name + " (" + info.playlist_owner_dbid + ")"); tag.find(".property-title input") .val(info.playlist_title) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_title", event.target.value); }); tag.find(".property-description textarea") .val(info.playlist_description) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_description", event.target.value); }); tag.find(".property-type select") .val(info.playlist_type.toString()) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_description", event.target.selectedIndex.toString()); }); tag.find(".property-replay-mode select") .val(info.playlist_replay_mode.toString()) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_replay_mode", event.target.selectedIndex.toString()); }); tag.find(".property-flag-delete-played input") .prop("checked", info.playlist_flag_delete_played) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_flag_delete_played", event.target.checked ? "1" : "0"); }); tag.find(".property-current-song input") .val(info.playlist_current_song_id); callback_current_song(info.playlist_current_song_id); tag.find(".property-flag-finished input") .prop("checked", info.playlist_flag_finished) .prop("disabled", !owns_playlist && !client.permissions.neededPermission(PermissionType.I_PLAYLIST_MODIFY_POWER).granted(playlist.needed_power_modify)) .on('change', event => { change_property("playlist_flag_finished", event.target.checked ? "1" : "0"); }); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.FvJMcfQT || (_translations.FvJMcfQT = tr("Failed to query playlist info")), (_translations.DIfGV_4h || (_translations.DIfGV_4h = tr("Failed to query playlist info.
Error:"))) + error).open(); }); } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["bb5acfe72ba10b0aa2a6519edd2b750e4a456190f2d624fe214316fd928e1f66"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["bb5acfe72ba10b0aa2a6519edd2b750e4a456190f2d624fe214316fd928e1f66"] = "bb5acfe72ba10b0aa2a6519edd2b750e4a456190f2d624fe214316fd928e1f66"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "eFc85qtL", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (9,30)" }, { name: "kG4iwbMz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (9,53)" }, { name: "o5nuh_LS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (88,21)" }, { name: "aN1mAh7m", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (106,44)" }, { name: "WBBTbFHq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (106,79)" }, { name: "xpCch8hN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (127,42)" }, { name: "sTep6Bz5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (127,75)" }, { name: "cq45GpJi", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (139,39)" }, { name: "ZOxonC98", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (139,60)" }, { name: "Bp3F9rOw", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (142,49)" }, { name: "TiqZADIK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (142,84)" }, { name: "_1mprv6P", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (150,50)" }, { name: "jNGK8sZ3", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPlaylistList.ts (150,83)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// /// var Modals; (function (Modals) { function spawnPlaylistManage(client) { { createErrorModal(_translations.eFc85qtL || (_translations.eFc85qtL = tr("Not implemented")), _translations.kG4iwbMz || (_translations.kG4iwbMz = tr("Playlist management hasn't yet been implemented"))).open(); return; } let modal; let selected_playlist; let available_playlists; let highlight_own = settings.global("playlist-list-highlight-own", true); const update_selected = () => { const buttons = modal.htmlTag.find(".header .buttons"); buttons.find(".button-playlist-edit").prop("disabled", !selected_playlist); buttons.find(".button-playlist-delete").prop("disabled", !selected_playlist || !( /* not owner or permission */client.permissions.neededPermission(PermissionType.I_PLAYLIST_DELETE_POWER).granted(selected_playlist.needed_power_delete) || /* client has permissions */ client.getClient().properties.client_database_id == selected_playlist.playlist_owner_dbid /* client is playlist owner */)); buttons.find(".button-playlist-create").prop("disabled", !client.permissions.neededPermission(PermissionType.B_PLAYLIST_CREATE).granted(1)); if (selected_playlist) { buttons.find(".button-playlist-edit").prop("disabled", false); } }; const update_list = () => __awaiter(this, void 0, void 0, function* () { const info_tag = modal.htmlTag.find(".footer .info a"); info_tag.text("loading..."); selected_playlist = undefined; update_selected(); try { available_playlists = yield client.serverConnection.command_helper.request_playlist_list(); } catch (error) { info_tag.text("failed to query playlist list."); //FIXME error handling? return; } const entries_tag = modal.htmlTag.find(".playlist-list-entries"); const entry_template = $("#tmpl_playlist_list-list_entry"); entries_tag.empty(); const owndbid = client.getClient().properties.client_database_id; for (const query of available_playlists) { const tag = entry_template.renderTag(query).on('click', event => { entries_tag.find(".entry.selected").removeClass("selected"); $(event.target).parent(".entry").addClass("selected"); selected_playlist = query; update_selected(); }); if (highlight_own && query.playlist_owner_dbid == owndbid) tag.addClass("highlighted"); entries_tag.append(tag); } const entry_container = modal.htmlTag.find(".playlist-list-entries-container"); if (entry_container.hasScrollBar()) entry_container.addClass("scrollbar"); info_tag.text("Showing " + available_playlists.length + " entries"); update_selected(); }); modal = createModal({ header: _translations.o5nuh_LS || (_translations.o5nuh_LS = tr("Manage playlists")), body: () => { let template = $("#tmpl_playlist_list").renderTag(); /* first open the modal */ setTimeout(() => { const entry_container = template.find(".playlist-list-entries-container"); if (entry_container.hasScrollBar()) entry_container.addClass("scrollbar"); }, 100); template.find(".footer .buttons .button-refresh").on('click', update_list); template.find(".button-playlist-create").on('click', event => { const single_handler = { function: command => { const json = command.arguments; update_list().then(() => { Modals.spawnYesNo(_translations.aN1mAh7m || (_translations.aN1mAh7m = tr("Playlist created successful")), _translations.WBBTbFHq || (_translations.WBBTbFHq = tr("The playlist has been successfully created.
Should we open the editor?")), result => { if (result) { for (const playlist of available_playlists) { if (playlist.playlist_id == json[0]["playlist_id"]) { Modals.spawnPlaylistEdit(client, playlist).close_listener.push(update_list); return; } } } }); }); return true; }, command: "notifyplaylistcreated" }; client.serverConnection.command_handler_boss().register_single_handler(single_handler); client.serverConnection.send_command("playlistcreate").catch(error => { client.serverConnection.command_handler_boss().remove_single_handler(single_handler); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.xpCch8hN || (_translations.xpCch8hN = tr("Unable to create playlist")), (_translations.sTep6Bz5 || (_translations.sTep6Bz5 = tr("Failed to create playlist
Message: "))) + error).open(); }); }); template.find(".button-playlist-edit").on('click', event => { if (!selected_playlist) return; Modals.spawnPlaylistEdit(client, selected_playlist).close_listener.push(update_list); }); template.find(".button-playlist-delete").on('click', () => { if (!selected_playlist) return; Modals.spawnYesNo(_translations.cq45GpJi || (_translations.cq45GpJi = tr("Are you sure?")), _translations.ZOxonC98 || (_translations.ZOxonC98 = tr("Do you really want to delete this playlist?")), result => { if (result) { client.serverConnection.send_command("playlistdelete", { playlist_id: selected_playlist.playlist_id }).then(() => { createInfoModal(_translations.Bp3F9rOw || (_translations.Bp3F9rOw = tr("Playlist deleted successful")), _translations.TiqZADIK || (_translations.TiqZADIK = tr("This playlist has been deleted successfully."))).open(); update_list(); }).catch(error => { if (error instanceof CommandResult) { /* TODO extra handling here */ //if(error.id == ErrorID.PLAYLIST_IS_IN_USE) { } error = error.extra_message || error.message; } createErrorModal(_translations._1mprv6P || (_translations._1mprv6P = tr("Unable to delete playlist")), (_translations.jNGK8sZ3 || (_translations.jNGK8sZ3 = tr("Failed to delete playlist
Message: "))) + error).open(); }); } }); }); template.find(".input-search").on('change keyup', () => { const text = (template.find(".input-search").val() || "").toLowerCase(); if (text.length == 0) { template.find(".playlist-list-entries .entry").show(); } else { template.find(".playlist-list-entries .entry").each((_, e) => { const element = $(e); if (element.text().toLowerCase().indexOf(text) == -1) element.hide(); else element.show(); }); } }); template.find(".button-highlight-own").on('change', event => { const flag = event.target.checked; settings.changeGlobal("playlist-list-highlight-own", flag); if (flag) { const owndbid = client.getClient().properties.client_database_id; template.find(".playlist-list-entries .entry").each((index, _element) => { const element = $(_element); if (parseInt(element.attr("playlist-owner-dbid")) == owndbid) element.addClass("highlighted"); }); } else { template.find(".playlist-list-entries .highlighted").removeClass("highlighted"); } }).prop("checked", highlight_own); return template; }, footer: undefined, width: 750 }); update_list(); modal.open(); } Modals.spawnPlaylistManage = spawnPlaylistManage; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["e8a999fc7a44ee2d0ddde9773f4d98a7fd17eff7fe5d5988d687dede92d8fb74"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["e8a999fc7a44ee2d0ddde9773f4d98a7fd17eff7fe5d5988d687dede92d8fb74"] = "e8a999fc7a44ee2d0ddde9773f4d98a7fd17eff7fe5d5988d687dede92d8fb74"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "UMNCZlGl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPoke.ts (19,25)" }, { name: "cfRyWTer", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPoke.ts (61,66)" }, { name: "xYlEtjJv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalPoke.ts (64,66)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { let global_modal; class PokeModal { constructor() { this.source_map = []; this._handle = createModal({ header: _translations.UMNCZlGl || (_translations.UMNCZlGl = tr("You have been poked!")), body: () => { let template = $("#tmpl_poke_popup").renderTag(); template.find(".button-close").on('click', event => this._handle_close()); return template; }, footer: undefined, width: 750 }); this._handle.close_listener.push(() => this._handle_close()); } modal() { return this._handle; } add_poke(source, invoker, message) { let handler; for (const entry of this.source_map) if (entry.source === source) { handler = entry; break; } if (!handler) { const html_tag = $.spawn("div").addClass("server"); const poke_list = $.spawn("div").addClass("poke-list"); $.spawn("div") .addClass("server-name") .text(source && source.channelTree && source.channelTree.server ? source.channelTree.server.properties.virtualserver_name : "unknown") .appendTo(html_tag); poke_list.appendTo(html_tag); this.source_map.push(handler = { source: source, add_message: (invoker, message) => { const container = $.spawn("div").addClass("entry"); $.spawn("div").addClass("date").text(moment().format("HH:mm:ss") + " - ").appendTo(container); $.spawn("div").addClass("user").append($(htmltags.generate_client({ add_braces: true, client_id: invoker.id, client_name: invoker.name, client_unique_id: invoker.unique_id }))).appendTo(container); if (message) { $.spawn("div").addClass("text").text(_translations.cfRyWTer || (_translations.cfRyWTer = tr("pokes you:"))).appendTo(container); $.spawn("div").addClass("poke-message").append(...MessageHelper.bbcode_chat(message)).appendTo(container); } else { $.spawn("div").addClass("text").text(_translations.xYlEtjJv || (_translations.xYlEtjJv = tr("pokes you."))).appendTo(container); } container.appendTo(poke_list); } }); this._handle.htmlTag.find(".container-servers").append(html_tag); } handler.add_message(invoker, message); } _handle_close() { this._handle.close(); global_modal = undefined; } } function spawnPoke(source, invoker, message) { if (!global_modal) global_modal = new PokeModal(); global_modal.add_poke(source, invoker, message); global_modal.modal().open(); } Modals.spawnPoke = spawnPoke; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["8233474cff76a05a8663c0eaec8fe99c0de8bc9b0f1e55e093cf1b4c5c5253d9"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["8233474cff76a05a8663c0eaec8fe99c0de8bc9b0f1e55e093cf1b4c5c5253d9"] = "8233474cff76a05a8663c0eaec8fe99c0de8bc9b0f1e55e093cf1b4c5c5253d9"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "oEF0dbsG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (9,21)" }, { name: "A709oy8V", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (18,42)" }, { name: "u8gNNCgy", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (18,66)" }, { name: "mgzlpOSP", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (43,42)" }, { name: "gxrVeEls", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (43,74)" }, { name: "YedBLfXN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (62,36)" }, { name: "nkmR5Lds", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQuery.ts (62,69)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { function spawnQueryCreate(connection, callback_created) { let modal; modal = createModal({ header: _translations.oEF0dbsG || (_translations.oEF0dbsG = tr("Create a server query login")), body: () => { let template = $("#tmpl_query_create").renderTag(); template = $.spawn("div").append(template); template.find(".button-close").on('click', event => modal.close()); template.find(".button-create").on('click', event => { const name = template.find(".input-name").val(); if (name.length < 3 || name.length > 64) { createErrorModal(_translations.A709oy8V || (_translations.A709oy8V = tr("Invalid username")), _translations.u8gNNCgy || (_translations.u8gNNCgy = tr("Please enter a valid name!"))).open(); return; } const single_handler = { function: command => { const json = command.arguments[0]; spawnQueryCreated({ username: name, password: json.client_login_password }, true); if (callback_created) callback_created(name, json.client_login_password); return true; }, command: "notifyquerycreated" }; connection.serverConnection.command_handler_boss().register_single_handler(single_handler); connection.serverConnection.send_command("querycreate", { client_login_name: name }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.mgzlpOSP || (_translations.mgzlpOSP = tr("Unable to create account")), (_translations.gxrVeEls || (_translations.gxrVeEls = tr("Failed to create account
Message: "))) + error).open(); }).then(() => connection.serverConnection.command_handler_boss().remove_single_handler(single_handler)); modal.close(); }); return template; }, footer: undefined, width: 750 }); modal.open(); } Modals.spawnQueryCreate = spawnQueryCreate; function spawnQueryCreated(credentials, just_created) { let modal; modal = createModal({ header: just_created ? _translations.YedBLfXN || (_translations.YedBLfXN = tr("Server query credentials")) : _translations.nkmR5Lds || (_translations.nkmR5Lds = tr("New server query credentials")), body: () => { let template = $("#tmpl_query_created").renderTag(credentials); template = $.spawn("div").append(template); template.find(".button-close").on('click', event => modal.close()); template.find(".query_name").text(credentials.username); template.find(".query_password").text(credentials.password); template.find(".btn_copy_name").on('click', () => { template.find(".query_name").select(); document.execCommand("copy"); }); template.find(".btn_copy_password").on('click', () => { template.find(".query_password").select(); document.execCommand("copy"); }); return template; }, footer: undefined, width: 750 }); modal.open(); } Modals.spawnQueryCreated = spawnQueryCreated; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["3a91b349c2467016f349cf833e9efd82314ecbcfc2ccc49a1b5acf3e418d361b"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["3a91b349c2467016f349cf833e9efd82314ecbcfc2ccc49a1b5acf3e418d361b"] = "3a91b349c2467016f349cf833e9efd82314ecbcfc2ccc49a1b5acf3e418d361b"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "QuHkt6Yk", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (169,21)" }, { name: "i_hVQpk9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (213,47)" }, { name: "vIqZZZIq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (224,59)" }, { name: "gk7HleVb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (256,43)" }, { name: "GUdKOS4n", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (259,59)" }, { name: "yZzadkPz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (260,39)" }, { name: "clwP2wmM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (264,55)" }, { name: "tSViiNga", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (265,35)" }, { name: "FnZFqOgS", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (285,54)" }, { name: "xp1swftm", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (287,54)" }, { name: "Kp_4nxoB", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (310,51)" }, { name: "iKboGUz6", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (321,41)" }, { name: "cLqUBiXb", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (321,65)" }, { name: "m9MLHYRV", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (331,43)" }, { name: "KIIc2CpG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (331,64)" }, { name: "Hf32wf2q", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (336,53)" }, { name: "qiRW7EnN", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (336,89)" }, { name: "Q_SsRGIG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (341,54)" }, { name: "rUve7dTz", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (341,114)" }, { name: "qwlCVdpq", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (350,42)" }, { name: "lFO6F9nu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (350,69)" }, { name: "NxEf3JtU", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (356,53)" }, { name: "Z2taR5dJ", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (356,89)" }, { name: "g4NSz8jG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (361,54)" }, { name: "ewpKfvcI", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (361,114)" }, { name: "uMip3QhX", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (370,42)" }, { name: "h4H98bLv", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (370,75)" }, { name: "DoHvT4u4", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (392,54)" }, { name: "wishvA6x", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalQueryManage.ts (392,115)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { /* export function spawnQueryManage(client: ConnectionHandler) { let modal: Modal; let selected_query: QueryListEntry; const update_selected = () => { const buttons = modal.htmlTag.find(".header .buttons"); //TODO gray out if no permissions (Server needs to send that... :D) buttons.find(".button-query-delete").prop("disabled", selected_query === undefined); buttons.find(".button-query-rename").prop("disabled", selected_query === undefined); buttons.find(".button-query-change-password").prop("disabled", selected_query === undefined); }; const update_list = () => { const info_tag = modal.htmlTag.find(".footer .info a"); info_tag.text("loading..."); client.serverConnection.command_helper.current_virtual_server_id().then(server_id => { client.serverConnection.command_helper.request_query_list(server_id).then(result => { selected_query = undefined; const entries_tag = modal.htmlTag.find(".query-list-entries"); const entry_template = $("#tmpl_query_manager-list_entry"); entries_tag.empty(); for(const query of result.queries || []) { entries_tag.append(entry_template.renderTag(query).on('click', event => { entries_tag.find(".entry.selected").removeClass("selected"); $(event.target).parent(".entry").addClass("selected"); selected_query = query; update_selected(); })); } const entry_container = modal.htmlTag.find(".query-list-entries-container"); if(entry_container.hasScrollBar()) entry_container.addClass("scrollbar"); if(!result || result.flag_all) { info_tag.text("Showing all server queries"); } else { info_tag.text("Showing your server queries") } update_selected(); }); }); //TODO error handling }; modal = createModal({ header: tr("Manage query accounts"), body: () => { let template = $("#tmpl_query_manager").renderTag(); template = $.spawn("div").append(template); /* first open the modal setTimeout(() => { const entry_container = template.find(".query-list-entries-container"); if(entry_container.hasScrollBar()) entry_container.addClass("scrollbar"); }, 100); template.find(".footer .buttons .button-refresh").on('click', update_list); template.find(".button-query-create").on('click', () => { Modals.spawnQueryCreate(client, (user, pass) => update_list()); }); template.find(".button-query-rename").on('click', () => { if(!selected_query) return; createInputModal(tr("Change account name"), tr("Enter the new name for the login:
"), text => text.length >= 3, result => { if(result) { client.serverConnection.send_command("queryrename", { client_login_name: selected_query.username, client_new_login_name: result }).catch(error => { if(error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(tr("Unable to rename account"), tr("Failed to rename account
Message: ") + error).open(); }).then(() => { createInfoModal(tr("Account successfully renamed"), tr("The query account has been renamed!")).open(); update_list(); }); } }).open(); }); template.find(".button-query-change-password").on('click', () => { if(!selected_query) return; createInputModal(tr("Change account's password"), tr("Enter a new password (leave blank for auto generation):
"), text => true, result => { if(result !== false) { const single_handler: connection.SingleCommandHandler = { command: "notifyquerypasswordchanges", function: command => { Modals.spawnQueryCreated({ username: command.arguments[0]["client_login_name"], password: command.arguments[0]["client_login_password"] }, false); return true; } }; client.serverConnection.command_handler_boss().register_single_handler(single_handler); client.serverConnection.send_command("querychangepassword", { client_login_name: selected_query.username, client_login_password: result }).catch(error => { client.serverConnection.command_handler_boss().remove_single_handler(single_handler); if(error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(tr("Unable to change password"), tr("Failed to change password
Message: ") + error).open(); }); } }).open(); }); template.find(".button-query-delete").on('click', () => { if(!selected_query) return; Modals.spawnYesNo(tr("Are you sure?"), tr("Do you really want to delete this account?"), result => { if(result) { client.serverConnection.send_command("querydelete", { client_login_name: selected_query.username }).catch(error => { if(error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(tr("Unable to delete account"), tr("Failed to delete account
Message: ") + error).open(); }).then(() => { createInfoModal(tr("Account successfully deleted"), tr("The query account has been successfully deleted!")).open(); update_list(); }); } }); }); template.find(".input-search").on('change keyup', () => { const text = (template.find(".input-search").val() as string || "").toLowerCase(); if(text.length == 0) { template.find(".query-list-entries .entry").show(); } else { template.find(".query-list-entries .entry").each((_, e) => { const element = $(e); if(element.text().toLowerCase().indexOf(text) == -1) element.hide(); else element.show(); }) } }); return template; }, footer: undefined, width: 750 }); update_list(); modal.open(); } */ //tmpl_query_manager function spawnQueryManage(client) { let modal; modal = createModal({ header: _translations.QuHkt6Yk || (_translations.QuHkt6Yk = tr("Manage query accounts")), body: () => { let template = $("#tmpl_query_manager").renderTag(); let current_server; let selected_query; let filter_callbacks = []; const container_list = template.find(".container-list .container-entries"); const container_list_empty = container_list.find(".container-empty"); const container_list_error = container_list.find(".container-error"); const detail_name = template.find(".detail.login-name .value"); const detail_unique_id = template.find(".detail.unique-id .value"); const detail_bound_server = template.find(".detail.bound-server .value"); const detail_unique_id_copy = template.find(".detail.unique-id .button-copy"); const input_filter = template.find(".filter-input"); const button_create = template.find(".button-create"); const button_delete = template.find(".button-delete"); const button_rename = template.find(".button-rename"); const button_change_password = template.find(".button-change-password"); const button_update = template.find(".button-update"); const permission_create = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_CREATE).granted(1); const permission_delete = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_DELETE).granted(1); const permission_delete_own = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_DELETE_OWN).granted(1); const permission_rename = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_RENAME).granted(1); const permission_rename_own = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_RENAME_OWN).granted(1); const permission_password = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_CHANGE_PASSWORD).granted(1); const permission_password_own = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_CHANGE_OWN_PASSWORD).granted(1); const permission_password_global = client.permissions.neededPermission(PermissionType.B_CLIENT_QUERY_CHANGE_PASSWORD_GLOBAL).granted(1); button_create.prop('disabled', !permission_create); const set_error = (error) => { if (typeof (error) === "string") container_list_error.text(error).show(); else container_list_error.hide(); }; const update_list = (selected_entry) => { button_update.prop('disabled', true); container_list_empty.text(_translations.i_hVQpk9 || (_translations.i_hVQpk9 = tr("loading..."))).show(); set_error(undefined); set_selected(undefined, false); filter_callbacks = []; container_list.find(".entry").remove(); client.serverConnection.command_helper.current_virtual_server_id().then(server_id => { current_server = server_id; client.serverConnection.command_helper.request_query_list(server_id).then(result => { if (!result || !result.queries.length) { container_list_empty.text(_translations.vIqZZZIq || (_translations.vIqZZZIq = tr("No queries available"))); return; } for (const entry of result.queries) { const tag = $.spawn("div").addClass("entry").text(entry.username + " (" + entry.unique_id + ")"); tag.on('click', event => { container_list.find(".selected").removeClass("selected"); tag.addClass("selected"); set_selected(entry, false); }); container_list.append(tag); if (entry.username === selected_entry) tag.trigger('click'); const text_mesh = (entry.username + " " + entry.unique_id + " " + entry.bounded_server).toLowerCase(); filter_callbacks.push(text => { if (typeof (text) === "undefined" || text_mesh.indexOf(text) != -1) { tag.show(); return true; } else { tag.hide(); return false; } }); } update_filter(); container_list_empty.hide(); button_update.prop('disabled', false); }).catch(error => { button_update.prop('disabled', false); if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) { set_error(_translations.gk7HleVb || (_translations.gk7HleVb = tr("No permissions"))); return; } log.error(LogCategory.CLIENT, _translations.GUdKOS4n || (_translations.GUdKOS4n = tr("Failed to request the query list: %o")), error); set_error(_translations.yZzadkPz || (_translations.yZzadkPz = tr("Failed to request list"))); }); }).catch(error => { button_update.prop('disabled', false); log.error(LogCategory.CLIENT, _translations.clwP2wmM || (_translations.clwP2wmM = tr("Failed to get own virtual server id: %o")), error); set_error(_translations.tSViiNga || (_translations.tSViiNga = tr("Failed to query server id"))); }); }; const set_selected = (entry, force) => { if (entry === selected_query && !force) return; selected_query = entry; if (!selected_query) { detail_name.text("-"); detail_unique_id.text("-"); detail_bound_server.text("-"); button_delete.prop('disabled', true); button_rename.prop('disabled', true); button_change_password.prop('disabled', true); } else { detail_name.text(selected_query.username); detail_unique_id.text(selected_query.unique_id); if (selected_query.bounded_server == 0) detail_bound_server.text(_translations.FnZFqOgS || (_translations.FnZFqOgS = tr("On the instance"))); else if (selected_query.bounded_server === current_server) detail_bound_server.text(_translations.xp1swftm || (_translations.xp1swftm = tr("On the current server"))); else detail_bound_server.text(selected_query.bounded_server.toString()); button_delete.prop('disabled', !permission_delete && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_delete_own)); button_rename.prop('disabled', !permission_rename && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_rename_own)); if (selected_query.bounded_server != 0) { button_change_password.prop('disabled', !permission_password && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own)); } else { button_change_password.prop('disabled', !permission_password_global && !(selected_query.unique_id === client.getClient().properties.client_unique_identifier && permission_password_own)); } } }; const update_filter = () => { let value = input_filter.val(); if (!value) value = undefined; else value = value.toLowerCase(); const shown = filter_callbacks.filter(e => e(value)).length; if (shown > 0) { container_list_empty.hide(); } else { container_list_empty.text(_translations.Kp_4nxoB || (_translations.Kp_4nxoB = tr("No accounts found"))).show(); } }; input_filter.on('change keyup', update_filter); /* all buttons */ { detail_unique_id_copy.on('click', event => { if (!selected_query) return; copy_to_clipboard(selected_query.unique_id); createInfoModal(_translations.iKboGUz6 || (_translations.iKboGUz6 = tr("Unique ID copied")), _translations.cLqUBiXb || (_translations.cLqUBiXb = tr("The unique id has been successfully copied to your clipboard."))).open(); }); button_create.on('click', event => { Modals.spawnQueryCreate(client, (user, pass) => update_list(user)); }); button_delete.on('click', event => { if (!selected_query) return; Modals.spawnYesNo(_translations.m9MLHYRV || (_translations.m9MLHYRV = tr("Are you sure?")), _translations.KIIc2CpG || (_translations.KIIc2CpG = tr("Do you really want to delete this account?")), result => { if (result) { client.serverConnection.send_command("querydelete", { client_login_name: selected_query.username }).then(() => { createInfoModal(_translations.Hf32wf2q || (_translations.Hf32wf2q = tr("Account successfully deleted")), _translations.qiRW7EnN || (_translations.qiRW7EnN = tr("The query account has been successfully deleted!"))).open(); update_list(undefined); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.Q_SsRGIG || (_translations.Q_SsRGIG = tr("Unable to delete account")), MessageHelper.formatMessage(_translations.rUve7dTz || (_translations.rUve7dTz = tr("Failed to delete account{:br:}Message: {}")), error)).open(); }); } }); }); button_rename.on('click', () => { if (!selected_query) return; createInputModal(_translations.qwlCVdpq || (_translations.qwlCVdpq = tr("Change account name")), _translations.lFO6F9nu || (_translations.lFO6F9nu = tr("Enter the new name for the login:")), text => text.length >= 3, result => { if (result) { client.serverConnection.send_command("queryrename", { client_login_name: selected_query.username, client_new_login_name: result }).then(() => { createInfoModal(_translations.NxEf3JtU || (_translations.NxEf3JtU = tr("Account successfully renamed")), _translations.Z2taR5dJ || (_translations.Z2taR5dJ = tr("The query account has been renamed!"))).open(); update_list(result); }).catch(error => { if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.g4NSz8jG || (_translations.g4NSz8jG = tr("Unable to rename account")), MessageHelper.formatMessage(_translations.ewpKfvcI || (_translations.ewpKfvcI = tr("Failed to rename account{:br:}Message: {}")), error)).open(); }); } }).open(); }); button_change_password.on('click', () => { if (!selected_query) return; createInputModal(_translations.uMip3QhX || (_translations.uMip3QhX = tr("Change account's password")), _translations.h4H98bLv || (_translations.h4H98bLv = tr("Enter a new password (leave blank for auto generation):")), text => true, result => { if (result !== false) { const single_handler = { command: "notifyquerypasswordchanges", function: command => { Modals.spawnQueryCreated({ username: command.arguments[0]["client_login_name"], password: command.arguments[0]["client_login_password"] }, false); return true; } }; client.serverConnection.command_handler_boss().register_single_handler(single_handler); client.serverConnection.send_command("querychangepassword", { client_login_name: selected_query.username, client_login_password: result }).catch(error => { client.serverConnection.command_handler_boss().remove_single_handler(single_handler); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.DoHvT4u4 || (_translations.DoHvT4u4 = tr("Unable to change password")), MessageHelper.formatMessage(_translations.wishvA6x || (_translations.wishvA6x = tr("Failed to change password{:br:}Message: {}")), error)).open(); }); } }).open(); }); button_update.on('click', event => update_list(selected_query ? selected_query.username : undefined)); } modal.close_listener.push(() => filter_callbacks = undefined); set_selected(undefined, true); update_list(undefined); template.dividerfy(); return template; }, footer: null, min_width: "25em" }); modal.htmlTag.find(".modal-body").addClass("modal-query-manage"); modal.open(); } Modals.spawnQueryManage = spawnQueryManage; })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["5331667997b364927974be0ef39bd37bedd8cf94fc7240456ded5de4f6e772d3"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["5331667997b364927974be0ef39bd37bedd8cf94fc7240456ded5de4f6e772d3"] = "5331667997b364927974be0ef39bd37bedd8cf94fc7240456ded5de4f6e772d3"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "YqHx1E4Q", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (7,21)" }, { name: "sR5xH__S", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (27,54)" }, { name: "KYruiqDh", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (30,42)" }, { name: "Jm3uN9QM", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (30,92)" }, { name: "SoMZi5vs", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (98,99)" }, { name: "wRj3c9p5", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (109,96)" }, { name: "OvjaxNtG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (110,96)" }, { name: "ukxiAAgl", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (112,87)" }, { name: "mPE1EX5O", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (124,21)" }, { name: "_IgsAh3M", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (131,108)" }, { name: "h_Cu5Dka", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (169,28)" }, { name: "SAM5Jdia", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (174,36)" }, { name: "gH3qLXyu", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (176,36)" }, { name: "tGesHS8_", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (183,28)" }, { name: "pZ9amcr9", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (188,36)" }, { name: "pgi8qIo2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (190,36)" }, { name: "Eqou3mDY", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (199,81)" }, { name: "kVOW_aDn", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (206,32)" }, { name: "awuXKKzF", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (208,32)" }, { name: "Fxejq6JG", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfo.ts (210,32)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { function openServerInfo(server) { let modal; let update_callbacks = []; modal = createModal({ header: (_translations.YqHx1E4Q || (_translations.YqHx1E4Q = tr("Server Information: "))) + server.properties.virtualserver_name, body: () => { const template = $("#tmpl_server_info").renderTag(); const children = template.children(); const top = template.find(".container-top"); const update_values = () => { apply_hostbanner(server, top); apply_category_1(server, children, update_callbacks); apply_category_2(server, children, update_callbacks); apply_category_3(server, children, update_callbacks); }; const button_update = template.find(".button-update"); button_update.on('click', event => { button_update.prop("disabled", true); server.updateProperties().then(() => { update_callbacks = []; update_values(); }).catch(error => { log.warn(LogCategory.CLIENT, _translations.sR5xH__S || (_translations.sR5xH__S = tr("Failed to refresh server properties: %o")), error); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.KYruiqDh || (_translations.KYruiqDh = tr("Refresh failed")), MessageHelper.formatMessage(_translations.Jm3uN9QM || (_translations.Jm3uN9QM = tr("Failed to refresh server properties.{:br:}Error: {}")), error)).open(); }).then(() => { button_update.prop("disabled", false); }); }).trigger('click'); update_values(); tooltip(template); return template.children(); }, footer: null, min_width: "25em" }); const updater = setInterval(() => { server.request_connection_info().then(info => update_callbacks.forEach(e => e(Modals.RequestInfoStatus.SUCCESS, info))).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.PERMISSION_ERROR) { update_callbacks.forEach(e => e(Modals.RequestInfoStatus.NO_PERMISSION)); return; } update_callbacks.forEach(e => e(Modals.RequestInfoStatus.UNKNOWN)); }); }, 1000); modal.htmlTag.find(".button-close").on('click', event => modal.close()); modal.htmlTag.find(".button-show-bandwidth").on('click', event => { const custom_callbacks = []; const custom_callback_caller = (status, info) => { custom_callbacks.forEach(e => e(status, info)); }; update_callbacks.push(custom_callback_caller); Modals.openServerInfoBandwidth(server, custom_callbacks).close_listener.push(() => { update_callbacks.remove(custom_callback_caller); }); }); modal.htmlTag.find(".modal-body").addClass("modal-server-info"); modal.open(); modal.close_listener.push(() => clearInterval(updater)); } Modals.openServerInfo = openServerInfo; function apply_hostbanner(server, tag) { let container; tag.empty().append(container = $.spawn("div").addClass("container-hostbanner")).addClass("hidden"); const htag = Hostbanner.generate_tag(server.properties.virtualserver_hostbanner_gfx_url, server.properties.virtualserver_hostbanner_gfx_interval, server.properties.virtualserver_hostbanner_mode); htag.then(t => { if (!t) return; tag.removeClass("hidden"); container.append(t); }); } function apply_category_1(server, tag, update_callbacks) { /* server name */ { const container = tag.find(".server-name"); container.text(server.properties.virtualserver_name); } /* server region */ { const container = tag.find(".server-region").empty(); container.append($.spawn("div").addClass("country flag-" + server.properties.virtualserver_country_code.toLowerCase()), $.spawn("a").text(i18n.country_name(server.properties.virtualserver_country_code, _translations.SoMZi5vs || (_translations.SoMZi5vs = tr("Global"))))); } /* slots */ { const container = tag.find(".server-slots"); let text = server.properties.virtualserver_clientsonline + "/" + server.properties.virtualserver_maxclients; if (server.properties.virtualserver_queryclientsonline) text += " +" + (server.properties.virtualserver_queryclientsonline > 1 ? server.properties.virtualserver_queryclientsonline + " " + (_translations.wRj3c9p5 || (_translations.wRj3c9p5 = tr("Queries"))) : server.properties.virtualserver_queryclientsonline + " " + (_translations.OvjaxNtG || (_translations.OvjaxNtG = tr("Query")))); if (server.properties.virtualserver_reserved_slots) text += " (" + server.properties.virtualserver_reserved_slots + " " + (_translations.ukxiAAgl || (_translations.ukxiAAgl = tr("Reserved"))) + ")"; container.text(text); } /* first run */ { const container = tag.find(".server-first-run"); container.text(server.properties.virtualserver_created > 0 ? moment(server.properties.virtualserver_created * 1000).format('MMMM Do YYYY, h:mm:ss a') : _translations.mPE1EX5O || (_translations.mPE1EX5O = tr("Unknown"))); } /* uptime */ { const container = tag.find(".server-uptime"); const update = () => container.text(MessageHelper.format_time(server.calculateUptime() * 1000, _translations._IgsAh3M || (_translations._IgsAh3M = tr("just started")))); update_callbacks.push(update); update(); } } function apply_category_2(server, tag, update_callbacks) { /* ip */ { const container = tag.find(".server-ip"); container.text(server.remote_address.host + (server.remote_address.port == 9987 ? "" : (":" + server.remote_address.port))); } /* version */ { const container = tag.find(".server-version"); let timestamp = -1; const version = (server.properties.virtualserver_version || "unknwon").replace(/ ?\[build: ?([0-9]+)]/gmi, (group, ts) => { timestamp = parseInt(ts); return ""; }); container.find("a").text(version); container.find(".container-tooltip").toggle(timestamp > 0).find(".tooltip a").text(moment(timestamp * 1000).format('[Build timestamp:] YYYY-MM-DD HH:mm Z')); } /* platform */ { const container = tag.find(".server-platform"); container.text(server.properties.virtualserver_platform); } /* ping */ { const container = tag.find(".server-ping"); container.text(_translations.h_Cu5Dka || (_translations.h_Cu5Dka = tr("calculating..."))); update_callbacks.push((status, data) => { if (status === Modals.RequestInfoStatus.SUCCESS) container.text(data.connection_ping.toFixed(0) + " " + "ms"); else if (status === Modals.RequestInfoStatus.NO_PERMISSION) container.text(_translations.SAM5Jdia || (_translations.SAM5Jdia = tr("No Permissions"))); else container.text(_translations.gH3qLXyu || (_translations.gH3qLXyu = tr("receiving..."))); }); } /* packet loss */ { const container = tag.find(".server-packet-loss"); container.text(_translations.tGesHS8_ || (_translations.tGesHS8_ = tr("receiving..."))); update_callbacks.push((status, data) => { if (status === Modals.RequestInfoStatus.SUCCESS) container.text(data.connection_packetloss_total.toFixed(2) + "%"); else if (status === Modals.RequestInfoStatus.NO_PERMISSION) container.text(_translations.pZ9amcr9 || (_translations.pZ9amcr9 = tr("No Permissions"))); else container.text(_translations.pgi8qIo2 || (_translations.pgi8qIo2 = tr("receiving..."))); }); } } function apply_category_3(server, tag, update_callbacks) { /* unique id */ { const container = tag.find(".server-unique-id"); container.text(server.properties.virtualserver_unique_identifier || (_translations.Eqou3mDY || (_translations.Eqou3mDY = tr("Unknown")))); } /* voice encryption */ { const container = tag.find(".server-voice-encryption"); if (server.properties.virtualserver_codec_encryption_mode == 0) container.text(_translations.kVOW_aDn || (_translations.kVOW_aDn = tr("Globally off"))); else if (server.properties.virtualserver_codec_encryption_mode == 1) container.text(_translations.awuXKKzF || (_translations.awuXKKzF = tr("Individually configured per channel"))); else container.text(_translations.Fxejq6JG || (_translations.Fxejq6JG = tr("Globally on"))); } /* channel count */ { const container = tag.find(".server-channel-count"); container.text(server.properties.virtualserver_channelsonline); } /* minimal security level */ { const container = tag.find(".server-min-security-level"); container.text(server.properties.virtualserver_needed_identity_security_level); } /* complains */ { const container = tag.find(".server-complains"); container.text(server.properties.virtualserver_complain_autoban_count); } } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["96c184c097607021ac37903e53735d6fda33133b10545b2f6996c468c42fb041"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["96c184c097607021ac37903e53735d6fda33133b10545b2f6996c468c42fb041"] = "96c184c097607021ac37903e53735d6fda33133b10545b2f6996c468c42fb041"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "fEMH56K2", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfoBandwidth.ts (14,21)" }, { name: "E1HApHoa", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfoBandwidth.ts (58,101)" }, { name: "Zw6Mw8Ek", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfoBandwidth.ts (58,123)" }, { name: "UZm_3vp7", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfoBandwidth.ts (153,26)" }, { name: "yZmlolTK", path: "D:/TeaSpeak/web/shared/js/ui/modal/ModalServerInfoBandwidth.ts (155,26)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var Modals; (function (Modals) { let RequestInfoStatus; (function (RequestInfoStatus) { RequestInfoStatus[RequestInfoStatus["SUCCESS"] = 0] = "SUCCESS"; RequestInfoStatus[RequestInfoStatus["UNKNOWN"] = 1] = "UNKNOWN"; RequestInfoStatus[RequestInfoStatus["NO_PERMISSION"] = 2] = "NO_PERMISSION"; })(RequestInfoStatus = Modals.RequestInfoStatus || (Modals.RequestInfoStatus = {})); function openServerInfoBandwidth(server, update_callbacks) { let modal; let own_callbacks = !update_callbacks; update_callbacks = update_callbacks || []; modal = createModal({ header: _translations.fEMH56K2 || (_translations.fEMH56K2 = tr("Server bandwidth data")), body: () => { const template = $("#tmpl_server_info_bandwidth").renderTag(); const children = template.children(); initialize_current_bandwidth(modal, children.find(".statistic-bandwidth"), update_callbacks); initialize_ft_bandwidth(modal, children.find(".statistic-ft-bandwidth"), update_callbacks); initialize_general(template.find(".top"), update_callbacks); tooltip(template); return template.children(); }, footer: null, min_width: "25em" }); if (own_callbacks) { const updater = setInterval(() => { server.request_connection_info().then(info => update_callbacks.forEach(e => e(RequestInfoStatus.SUCCESS, info))).catch(error => { if (error instanceof CommandResult && error.id == ErrorID.PERMISSION_ERROR) { update_callbacks.forEach(e => e(RequestInfoStatus.NO_PERMISSION)); return; } update_callbacks.forEach(e => e(RequestInfoStatus.UNKNOWN)); }); }, 1000); modal.close_listener.push(() => clearInterval(updater)); } modal.htmlTag.find(".button-close").on('click', event => modal.close()); modal.htmlTag.find(".modal-body").addClass("modal-server-info-bandwidth"); modal.open(); return modal; } Modals.openServerInfoBandwidth = openServerInfoBandwidth; function initialize_graph(modal, tag, callbacks, fields) { const canvas = tag.find("canvas")[0]; const label_upload = tag.find(".upload"); const label_download = tag.find(".download"); let last_info; let custom_info = false; const show_info = (upload, download) => { let fallback_text = last_info && last_info.status === RequestInfoStatus.NO_PERMISSION ? _translations.E1HApHoa || (_translations.E1HApHoa = tr("No permission")) : _translations.Zw6Mw8Ek || (_translations.Zw6Mw8Ek = tr("receiving...")); if (typeof upload !== "number") upload = last_info ? last_info[fields.uplaod] : undefined; if (typeof download !== "number") download = last_info ? last_info[fields.download] : undefined; if (typeof upload !== "number") label_upload.text(fallback_text); else label_upload.text(MessageHelper.network.format_bytes(upload, { unit: "Bytes", time: "s", exact: false })); if (typeof download !== "number") label_download.text(fallback_text); else label_download.text(MessageHelper.network.format_bytes(download, { unit: "Bytes", time: "s", exact: false })); }; show_info(undefined, undefined); const graph = new net.graph.Graph(canvas); graph.insert_entry({ timestamp: Date.now(), upload: undefined, download: undefined }); callbacks.push((status, values) => { last_info = { status: status, info: values }; if (!values) { graph.insert_entry({ timestamp: Date.now(), upload: undefined, download: undefined }); } else { graph.insert_entry({ timestamp: Date.now(), download: values[fields.download], upload: values[fields.uplaod], }); } /* set set that we want to show the entry within one second */ graph._time_span.origin = Object.assign(graph.calculate_time_span(), { time: Date.now() }); graph._time_span.target = { begin: Date.now() - 120 * 1000, end: Date.now(), time: Date.now() + 200 }; graph.cleanup(); if (!custom_info) { show_info(undefined, undefined); graph.resize(); /* just to ensure (we have to rethink this maybe; cause it causes a recalculates the style */ } }); graph.max_gap_size(0); graph.initialize(); graph.callback_detailed_hide = () => { custom_info = false; show_info(undefined, undefined); }; graph.callback_detailed_info = (upload, download, timestamp, event) => { custom_info = true; show_info(upload, download); }; modal.close_listener.push(() => graph.terminate()); modal.open_listener.push(() => graph.resize()); tag.addClass("window-resize-listener").on('resize', event => graph.resize()); } function initialize_current_bandwidth(modal, tag, callbacks) { initialize_graph(modal, tag, callbacks, { uplaod: "connection_bandwidth_sent_last_second_total", download: "connection_bandwidth_received_last_second_total" }); } function initialize_ft_bandwidth(modal, tag, callbacks) { initialize_graph(modal, tag, callbacks, { uplaod: "connection_filetransfer_bandwidth_sent", download: "connection_filetransfer_bandwidth_received" }); } function initialize_general(tag, callbacks) { const tag_packets_upload = tag.find(".statistic-packets .upload"); const tag_packets_download = tag.find(".statistic-packets .download"); const tag_bytes_upload = tag.find(".statistic-bytes .upload"); const tag_bytes_download = tag.find(".statistic-bytes .download"); const tag_ft_bytes_upload = tag.find(".statistic-ft-bytes .upload"); const tag_ft_bytes_download = tag.find(".statistic-ft-bytes .download"); const update = (tag, value) => { if (typeof value === "undefined") tag.text(_translations.UZm_3vp7 || (_translations.UZm_3vp7 = tr("receiving..."))); else if (value === null) tag.text(_translations.yZmlolTK || (_translations.yZmlolTK = tr("no permissions"))); else tag.text(MessageHelper.network.format_bytes(value, { unit: "Bytes", exact: false })); }; const props = [ { tag: tag_packets_download, property: "connection_packets_received_total" }, { tag: tag_packets_upload, property: "connection_packets_sent_total" }, { tag: tag_bytes_download, property: "connection_bytes_received_total" }, { tag: tag_bytes_upload, property: "connection_bytes_sent_total" }, { tag: tag_ft_bytes_upload, property: "connection_filetransfer_bytes_received_total" }, { tag: tag_ft_bytes_download, property: "connection_filetransfer_bytes_sent_total" }, ]; callbacks.push((status, info) => { if (status === RequestInfoStatus.SUCCESS) { for (const entry of props) update(entry.tag, info[entry.property]); } else if (status === RequestInfoStatus.NO_PERMISSION) { for (const entry of props) update(entry.tag, null); } else { for (const entry of props) update(entry.tag, undefined); } }); } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["f08e46c4af644ceb3228f5583f0b483d9ab6d5f4699e3aa67659a9474d21ffab"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["f08e46c4af644ceb3228f5583f0b483d9ab6d5f4699e3aa67659a9474d21ffab"] = "f08e46c4af644ceb3228f5583f0b483d9ab6d5f4699e3aa67659a9474d21ffab"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "jgvFVcHz", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (94,24)" }, { name: "dcBTd0ku", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (270,63)" }, { name: "JpVF5Mzm", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (281,63)" }, { name: "ViyQ3FC3", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (296,63)" }, { name: "t7rGoAdc", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (313,63)" }, { name: "eKiUcJRA", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (433,63)" }, { name: "gNpxBbWx", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (443,63)" }, { name: "Oldifku2", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (457,63)" }, { name: "JAIS9OGe", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (473,63)" }, { name: "tDmnoexV", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (575,63)" }, { name: "xDRYefpc", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (590,63)" }, { name: "cYgmPzVb", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (604,63)" }, { name: "MyTOVvJi", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (625,63)" }, { name: "eH6peQwT", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (689,63)" }, { name: "PSWt_oAu", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (703,63)" }, { name: "Z5NC2zLF", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (717,63)" }, { name: "hdpOwMqg", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (737,63)" }, { name: "uyiLQc3y", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (808,35)" }, { name: "nuh4sliq", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (814,35)" }, { name: "zyTnu_qn", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (820,35)" }, { name: "qlgoozon", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (825,35)" }, { name: "Sp05Q7cm", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (850,27)" }, { name: "BDKgOv3v", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (881,41)" }, { name: "asEzKP4X", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (881,62)" }, { name: "ZmlrpljU", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (884,38)" }, { name: "zGFSOJO8", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (888,42)" }, { name: "ZxKo1R5a", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (888,100)" }, { name: "K7C5wnF2", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (897,34)" }, { name: "q1LAQS2V", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (897,54)" }, { name: "l_zRubf8", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (904,41)" }, { name: "jZWebIbu", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (904,62)" }, { name: "wKyPu_a7", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (907,38)" }, { name: "EOkDrLst", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (911,42)" }, { name: "wJbuc7yI", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (911,100)" }, { name: "aUVlGWcp", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (917,34)" }, { name: "KsmwzQ7d", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (917,61)" }, { name: "ABUF6IGq", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (924,28)" }, { name: "y2KLYSW7", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (924,77)" }, { name: "vTy1M6TK", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (932,41)" }, { name: "LzPrH7f2", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (932,62)" }, { name: "ExJ0DQQB", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (935,38)" }, { name: "pFsB8a2X", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (939,42)" }, { name: "PIpmf1Jv", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (939,100)" }, { name: "ZKRKRFdZ", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1011,35)" }, { name: "tz_xB0DK", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1017,35)" }, { name: "shQXAD3I", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1023,35)" }, { name: "N5puAby8", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1028,35)" }, { name: "wvb9mJQm", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1055,27)" }, { name: "BNdJT1cT", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1085,41)" }, { name: "PzBumF3C", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1085,62)" }, { name: "sNlSiT7C", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1088,38)" }, { name: "usfuFq3a", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1092,42)" }, { name: "XGuZ4MEv", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1092,100)" }, { name: "u4Fvc7m6", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1101,34)" }, { name: "ORzt406c", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1101,54)" }, { name: "sGFYk3BV", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1108,41)" }, { name: "Z6K53vUj", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1108,62)" }, { name: "Nvr1sNU1", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1111,38)" }, { name: "gZuGhFeW", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1115,42)" }, { name: "RAahtMoY", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1115,100)" }, { name: "JFTntZDs", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1121,34)" }, { name: "XSwWUXyj", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1121,61)" }, { name: "BtRlLNMi", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1128,28)" }, { name: "DjQ0gUq3", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1128,77)" }, { name: "Skc29nKb", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1136,41)" }, { name: "e9uYZsgU", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1136,62)" }, { name: "p5NZb93F", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1139,38)" }, { name: "Xe4iGn25", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1143,42)" }, { name: "QzcGXAWO", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1143,100)" }, { name: "rvTpLnM3", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1175,63)" }, { name: "lNfsBK1q", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1190,63)" }, { name: "l3qUWBQ2", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1204,63)" }, { name: "mH6z0xG8", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1225,63)" }, { name: "VSkQ3V09", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1310,39)" }, { name: "z40xhzvX", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1315,39)" }, { name: "RnTroWBE", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1320,39)" }, { name: "JrlJsqem", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1330,34)" }, { name: "QYvEqWFo", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1346,33)" }, { name: "w_grwuKP", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1349,38)" }, { name: "Xqg78pAj", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1349,69)" }, { name: "vp8oLTFs", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1354,34)" }, { name: "bqhbv6gi", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1354,68)" }, { name: "IaBow48n", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1376,41)" }, { name: "qXfwiEGs", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1379,46)" }, { name: "xvC5Mz5O", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1379,102)" }, { name: "RTOwbHRq", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1384,37)" }, { name: "Fqjboqd3", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1385,42)" }, { name: "E8Wmhi8B", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1385,70)" }, { name: "kwFlKJU2", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1396,37)" }, { name: "iBC3dxeB", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1399,42)" }, { name: "HHOHRQs8", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1411,27)" }, { name: "XhSxnxAW", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1445,46)" }, { name: "SJnJGsYd", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1445,76)" }, { name: "nztvRGaW", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1446,38)" }, { name: "ouOjBgEH", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1446,68)" }, { name: "Ombfpy2D", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/ModalPermissionEdit.ts (1454,21)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /// /// var Modals; (function (Modals) { let PermissionEditorMode; (function (PermissionEditorMode) { PermissionEditorMode[PermissionEditorMode["VISIBLE"] = 0] = "VISIBLE"; PermissionEditorMode[PermissionEditorMode["NO_PERMISSION"] = 1] = "NO_PERMISSION"; PermissionEditorMode[PermissionEditorMode["UNSET"] = 2] = "UNSET"; })(PermissionEditorMode = Modals.PermissionEditorMode || (Modals.PermissionEditorMode = {})); class AbstractPermissionEditor { constructor() { this._listener_change = () => Promise.resolve(); } set_listener(listener) { this._listener_change = listener || (() => Promise.resolve()); } set_listener_update(listener) { this._listener_update = listener; } trigger_update() { if (this._listener_update) this._listener_update(); } } Modals.AbstractPermissionEditor = AbstractPermissionEditor; function _space() { const now = Date.now(); while (now + 100 > Date.now()) ; } Modals._space = _space; function spawnPermissionEdit(connection, selected_tab, options) { options = options || {}; const modal = createModal({ header: function () { return _translations.jgvFVcHz || (_translations.jgvFVcHz = tr("Server Permissions")); }, body: function () { let properties = {}; let tag = $("#tmpl_server_permissions").renderTag(properties); /* build the permission editor */ const permission_editor = (() => { const editor = new pe.HTMLPermissionEditor(); editor.initialize(connection.permissions.groupedPermissions()); editor.icon_resolver = id => connection.fileManager.icons.resolve_icon(id).then((icon) => __awaiter(this, void 0, void 0, function* () { if (!icon) return undefined; const tag = document.createElement("img"); yield new Promise((resolve, reject) => { tag.onerror = reject; tag.onload = resolve; tag.src = icon.url; }); return tag; })); editor.icon_selector = current_icon => new Promise(resolve => { Modals.spawnIconSelect(connection, id => resolve(new Int32Array([id])[0]), current_icon); }); if (editor instanceof pe.CanvasPermissionEditor) setTimeout(() => editor.update_ui(), 500); return editor; })(); const container_tab_list = tag.find(".right > .header"); { const label_current = tag.find(".left .container-selected"); const create_tab = (tab_entry, container_name, hidden_permissions) => { const target_container = tag.find(".body .container." + container_name); tab_entry.on('click', () => { /* Using a timeout here prevents unnecessary style calculations required by other click event handlers */ setTimeout(() => { container_tab_list.find(".selected").removeClass("selected"); tab_entry.addClass("selected"); label_current.text(tab_entry.find("a").text()); /* dont use show() here because it causes a style recalculation */ for (const element of tag.find(".body .container")) element.style.display = "none"; permission_editor.set_hidden_permissions(settings.static_global(Settings.KEY_PERMISSIONS_SHOW_ALL) ? undefined : hidden_permissions); permission_editor.html_tag()[0].remove(); target_container.find(".permission-editor").trigger('show'); target_container.find(".permission-editor").append(permission_editor.html_tag()); for (const element of target_container) element.style.display = null; }, 0); }); }; create_tab(container_tab_list.find(".sg"), "container-view-server-groups", permissions.senseless_server_group_permissions); create_tab(container_tab_list.find(".cg"), "container-view-channel-groups", permissions.senseless_channel_group_permissions); create_tab(container_tab_list.find(".chp"), "container-view-channel-permissions", permissions.senseless_channel_permissions); create_tab(container_tab_list.find(".clp"), "container-view-client-permissions", permissions.senseless_client_permissions); create_tab(container_tab_list.find(".clchp"), "container-view-client-channel-permissions", permissions.senseless_client_channel_permissions); } apply_server_groups(connection, permission_editor, tag.find(".left .container-view-server-groups"), tag.find(".right .container-view-server-groups")); apply_channel_groups(connection, permission_editor, tag.find(".left .container-view-channel-groups"), tag.find(".right .container-view-channel-groups")); apply_channel_permission(connection, permission_editor, tag.find(".left .container-view-channel-permissions"), tag.find(".right .container-view-channel-permissions")); apply_client_permission(connection, permission_editor, tag.find(".left .container-view-client-permissions"), tag.find(".right .container-view-client-permissions"), selected_tab == "clp" ? options : {}); apply_client_channel_permission(connection, permission_editor, tag.find(".left .container-view-client-channel-permissions"), tag.find(".right .container-view-client-channel-permissions"), selected_tab == "clchp" ? options : {}); setTimeout(() => container_tab_list.find("." + (selected_tab || "sg")).trigger('click'), 0); return tag.dividerfy(); }, footer: undefined, min_width: "30em", height: "80%", trigger_tab: false, full_size: true }); const tag = modal.htmlTag; tag.find(".modal-body").addClass("modal-permission-editor"); if (selected_tab) setTimeout(() => tag.find(".tab-header .entry[x-id=" + selected_tab + "]").first().trigger("click"), 1); tag.find(".btn_close").on('click', () => { modal.close(); }); return modal; } Modals.spawnPermissionEdit = spawnPermissionEdit; function build_channel_tree(connection, channel_list, selected_channel, select_callback) { const root = connection.channelTree.get_first_channel(); if (!root) return; const build_channel = (channel, level) => { let tag = $.spawn("div").addClass("channel").css("padding-left", "calc(0.25em + " + (level * 16) + "px)").attr("channel-id", channel.channelId); let icon_tag = connection.fileManager.icons.generateTag(channel.properties.channel_icon_id); icon_tag.appendTo(tag); const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id)); { let name = $.spawn("a").text(channel.channelName() + " (" + channel.channelId + ")").addClass("name"); name.appendTo(tag); } tag.on('click', event => { channel_list.find(".selected").removeClass("selected"); tag.addClass("selected"); select_callback(channel, _update_icon); }); return tag; }; const build_channels = (root, level) => { build_channel(root, level).appendTo(channel_list); const child_head = root.children(false).find(e => e.channel_previous === undefined); if (child_head) build_channels(child_head, level + 1); if (root.channel_next) build_channels(root.channel_next, level); }; build_channels(root, 0); let selected_channel_tag = channel_list.find(".channel[channel-id=" + selected_channel + "]"); if (!selected_channel_tag || selected_channel_tag.length < 1) selected_channel_tag = channel_list.find('.channel').first(); setTimeout(() => selected_channel_tag.trigger('click'), 0); } function apply_client_channel_permission(connection, editor, tab_left, tab_right, options) { let current_cldbid = 0; let current_channel; /* the editor */ { const pe_client = tab_right.find(".permission-editor"); tab_right.on('show', event => { editor.set_toggle_button(undefined, undefined); pe_client.append(editor.html_tag()); if (connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CLIENT_PERMISSION_LIST).granted(1)) { if (current_cldbid && current_channel) editor.set_mode(PermissionEditorMode.VISIBLE); else editor.set_mode(PermissionEditorMode.UNSET); } else { editor.set_mode(PermissionEditorMode.NO_PERMISSION); return; } editor.set_listener_update(() => { if (!current_cldbid || !current_channel) return; connection.permissions.requestClientChannelPermissions(current_cldbid, current_channel.channelId).then(result => { editor.set_permissions(result); editor.set_mode(PermissionEditorMode.VISIBLE); }).catch(error => { console.log(error); //TODO handling? }); }); /* TODO: Error handling? */ editor.set_listener((permission, value) => __awaiter(this, void 0, void 0, function* () { if (!current_cldbid) throw "unset client"; if (!current_channel) throw "unset channel"; if (value.remove) { /* remove the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.dcBTd0ku || (_translations.dcBTd0ku = tr("Removing client channel permission %s. permission.id: %o")), permission.name, permission.id); yield connection.serverConnection.send_command("channelclientdelperm", { cldbid: current_cldbid, cid: current_channel.channelId, permid: permission.id, }); } else { log.info(LogCategory.PERMISSIONS, _translations.JpVF5Mzm || (_translations.JpVF5Mzm = tr("Removing client channel grant permission %s. permission.id: %o")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channelclientdelperm", { cldbid: current_cldbid, cid: current_channel.channelId, permid: permission.id_grant(), }); } } else { /* add the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.ViyQ3FC3 || (_translations.ViyQ3FC3 = tr("Adding or updating client channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}")), permission.name, permission.id, value.value, value.flag_skip, value.flag_negate); yield connection.serverConnection.send_command("channelclientaddperm", { cldbid: current_cldbid, cid: current_channel.channelId, permid: permission.id, permvalue: value.value, permskip: value.flag_skip, permnegated: value.flag_negate }); } else { log.info(LogCategory.PERMISSIONS, _translations.t7rGoAdc || (_translations.t7rGoAdc = tr("Adding or updating client channel grant permission %s. permission.{id: %o, value: %o}")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channelclientaddperm", { cldbid: current_cldbid, cid: current_channel.channelId, permid: permission.id_grant(), permvalue: value.granted, permskip: false, permnegated: false }); } } })); /* FIXME: Use cached permissions */ editor.trigger_update(); }); } build_channel_tree(connection, tab_left.find(".list-channel .entries"), options.channel_id || 0, channel => { if (current_channel == channel) return; current_channel = channel; /* TODO: Test for visibility */ editor.trigger_update(); }); { const tag_select = tab_left.find(".client-select"); const tag_select_uid = tag_select.find("input"); const tag_select_error = tag_select.find(".invalid-feedback"); const tag_client_name = tab_left.find(".client-name"); const tag_client_uid = tab_left.find(".client-uid"); const tag_client_dbid = tab_left.find(".client-dbid"); const resolve_client = () => { let client_uid = tag_select_uid.val(); connection.serverConnection.command_helper.info_from_uid(client_uid).then(result => { if (!result || result.length == 0) return Promise.reject("invalid data"); tag_select.removeClass('is-invalid'); tag_client_name.val(result[0].client_nickname); tag_client_uid.val(result[0].client_unique_id); tag_client_dbid.val(result[0].client_database_id); current_cldbid = result[0].client_database_id; editor.trigger_update(); }).catch(error => { console.log(error); if (error instanceof CommandResult) { if (error.id == ErrorID.EMPTY_RESULT) error = "unknown client"; else error = error.extra_message || error.message; } tag_client_name.val(""); tag_client_uid.val(""); tag_client_dbid.val(""); tag_select_error.text(error); tag_select.addClass('is-invalid'); editor.set_mode(PermissionEditorMode.UNSET); }); }; tag_select_uid.on('change', event => resolve_client()); if (options.unique_id) { tag_select_uid.val(options.unique_id); setTimeout(() => resolve_client()); } } } function apply_client_permission(connection, editor, tab_left, tab_right, options) { let current_cldbid = 0; /* the editor */ { const pe_client = tab_right.find("permission-editor.client"); tab_right.on('show', event => { editor.set_toggle_button(undefined, undefined); pe_client.append(editor.html_tag()); if (connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CLIENT_PERMISSION_LIST).granted(1)) { if (current_cldbid) editor.set_mode(PermissionEditorMode.VISIBLE); else editor.set_mode(PermissionEditorMode.UNSET); } else { editor.set_mode(PermissionEditorMode.NO_PERMISSION); return; } editor.set_listener_update(() => { if (!current_cldbid) return; connection.permissions.requestClientPermissions(current_cldbid).then(result => { editor.set_permissions(result); editor.set_mode(PermissionEditorMode.VISIBLE); }).catch(error => { console.log(error); //TODO handling? }); }); /* TODO: Error handling? */ editor.set_listener((permission, value) => __awaiter(this, void 0, void 0, function* () { if (!current_cldbid) throw "unset client"; if (value.remove) { /* remove the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.eKiUcJRA || (_translations.eKiUcJRA = tr("Removing client permission %s. permission.id: %o")), permission.name, permission.id); yield connection.serverConnection.send_command("clientdelperm", { cldbid: current_cldbid, permid: permission.id, }); } else { log.info(LogCategory.PERMISSIONS, _translations.gNpxBbWx || (_translations.gNpxBbWx = tr("Removing client grant permission %s. permission.id: %o")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("clientdelperm", { cldbid: current_cldbid, permid: permission.id_grant(), }); } } else { /* add the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.Oldifku2 || (_translations.Oldifku2 = tr("Adding or updating client permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}")), permission.name, permission.id, value.value, value.flag_skip, value.flag_negate); yield connection.serverConnection.send_command("clientaddperm", { cldbid: current_cldbid, permid: permission.id, permvalue: value.value, permskip: value.flag_skip, permnegated: value.flag_negate }); } else { log.info(LogCategory.PERMISSIONS, _translations.JAIS9OGe || (_translations.JAIS9OGe = tr("Adding or updating client grant permission %s. permission.{id: %o, value: %o}")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("clientaddperm", { cldbid: current_cldbid, permid: permission.id_grant(), permvalue: value.granted, permskip: false, permnegated: false }); } } })); /* FIXME: Use cached permissions */ editor.trigger_update(); }); } const tag_select = tab_left.find(".client-select"); const tag_select_uid = tag_select.find("input"); const tag_select_error = tag_select.find(".invalid-feedback"); const tag_client_name = tab_left.find(".client-name"); const tag_client_uid = tab_left.find(".client-uid"); const tag_client_dbid = tab_left.find(".client-dbid"); const resolve_client = () => { let client_uid = tag_select_uid.val(); connection.serverConnection.command_helper.info_from_uid(client_uid).then(result => { if (!result || result.length == 0) return Promise.reject("invalid data"); tag_select.removeClass("is-invalid"); tag_client_name.val(result[0].client_nickname); tag_client_uid.val(result[0].client_unique_id); tag_client_dbid.val(result[0].client_database_id); current_cldbid = result[0].client_database_id; editor.trigger_update(); }).catch(error => { console.log(error); if (error instanceof CommandResult) { if (error.id == ErrorID.EMPTY_RESULT) error = "unknown client"; else error = error.extra_message || error.message; } tag_client_name.val(""); tag_client_uid.val(""); tag_client_dbid.val(""); tag_select_error.text(error); tag_select.addClass("is-invalid"); editor.set_mode(PermissionEditorMode.UNSET); }); }; tag_select_uid.on('change', event => resolve_client()); if (options.unique_id) { tag_select_uid.val(options.unique_id); setTimeout(() => resolve_client()); } } function apply_channel_permission(connection, editor, tab_left, tab_right) { let current_channel; let update_channel_icon; /* the editor */ { const pe_channel = tab_right.find(".permission-editor"); tab_right.on('show', event => { editor.set_toggle_button(undefined, undefined); pe_channel.append(editor.html_tag()); if (connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNEL_PERMISSION_LIST).granted(1)) editor.set_mode(PermissionEditorMode.VISIBLE); else { editor.set_mode(PermissionEditorMode.NO_PERMISSION); return; } editor.set_listener_update(() => { if (!current_channel) return; connection.permissions.requestChannelPermissions(current_channel.channelId).then(result => editor.set_permissions(result)).catch(error => { editor.set_permissions([]); console.log(error); //TODO handling? }); }); editor.set_listener((permission, value) => __awaiter(this, void 0, void 0, function* () { if (!current_channel) throw "unset channel"; if (value.remove) { /* remove the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.tDmnoexV || (_translations.tDmnoexV = tr("Removing channel permission %s. permission.id: %o")), permission.name, permission.id); yield connection.serverConnection.send_command("channeldelperm", { cid: current_channel.channelId, permid: permission.id, }).then(e => { if (permission.name === "i_icon_id" && update_channel_icon) update_channel_icon(undefined); return e; }); } else { /* TODO Remove this because its totally useless. Remove this from the UI as well */ log.info(LogCategory.PERMISSIONS, _translations.xDRYefpc || (_translations.xDRYefpc = tr("Removing channel grant permission %s. permission.id: %o")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channeldelperm", { cid: current_channel.channelId, permid: permission.id_grant(), }); } } else { /* add the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.cYgmPzVb || (_translations.cYgmPzVb = tr("Adding or updating channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}")), permission.name, permission.id, value.value, value.flag_skip, value.flag_negate); yield connection.serverConnection.send_command("channeladdperm", { cid: current_channel.channelId, permid: permission.id, permvalue: value.value, permskip: value.flag_skip, permnegated: value.flag_negate }).then(e => { if (permission.name === "i_icon_id" && update_channel_icon) update_channel_icon(value.value); return e; }); } else { /* TODO Remove this because its totally useless. Remove this from the UI as well */ log.info(LogCategory.PERMISSIONS, _translations.MyTOVvJi || (_translations.MyTOVvJi = tr("Adding or updating channel grant permission %s. permission.{id: %o, value: %o}")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channeladdperm", { cid: current_channel.channelId, permid: permission.id_grant(), permvalue: value.granted, permskip: false, permnegated: false }); } } })); /* FIXME: Use cached permissions */ editor.trigger_update(); }); } let channel_list = tab_left.find(".list-channel .entries"); build_channel_tree(connection, channel_list, 0, (channel, update) => { current_channel = channel; update_channel_icon = update; editor.trigger_update(); }); } function apply_channel_groups(connection, editor, tab_left, tab_right) { let current_group; let update_group_icon; let update_groups; let update_buttons; /* the editor */ { const pe_server = tab_right.find(".permission-editor"); tab_right.on('show', event => { editor.set_toggle_button(undefined, undefined); pe_server.append(editor.html_tag()); if (connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_PERMISSION_LIST).granted(1)) editor.set_mode(PermissionEditorMode.VISIBLE); else { editor.set_mode(PermissionEditorMode.NO_PERMISSION); return; } editor.set_listener_update(() => { if (!current_group) return; connection.groups.request_permissions(current_group).then(result => editor.set_permissions(result)).catch(error => { console.log(error); //TODO handling? }); }); editor.set_listener((permission, value) => __awaiter(this, void 0, void 0, function* () { if (!current_group) throw "unset channel group"; if (value.remove) { /* remove the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.eH6peQwT || (_translations.eH6peQwT = tr("Removing channel group permission %s. permission.id: %o")), permission.name, permission.id); yield connection.serverConnection.send_command("channelgroupdelperm", { cgid: current_group.id, permid: permission.id, }).then(e => { if (permission.name === "i_icon_id" && update_group_icon) update_group_icon(undefined); return e; }); } else { log.info(LogCategory.PERMISSIONS, _translations.PSWt_oAu || (_translations.PSWt_oAu = tr("Removing channel group grant permission %s. permission.id: %o")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channelgroupdelperm", { cgid: current_group.id, permid: permission.id_grant(), }); } } else { /* add the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.Z5NC2zLF || (_translations.Z5NC2zLF = tr("Adding or updating channel group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}")), permission.name, permission.id, value.value, value.flag_skip, value.flag_negate); yield connection.serverConnection.send_command("channelgroupaddperm", { cgid: current_group.id, permid: permission.id, permvalue: value.value, permskip: value.flag_skip, permnegated: value.flag_negate }).then(e => { if (permission.name === "i_icon_id" && update_group_icon) update_group_icon(value.value); return e; }); } else { log.info(LogCategory.PERMISSIONS, _translations.hdpOwMqg || (_translations.hdpOwMqg = tr("Adding or updating channel group grant permission %s. permission.{id: %o, value: %o}")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("channelgroupaddperm", { cgid: current_group.id, permid: permission.id_grant(), permvalue: value.granted, permskip: false, permnegated: false }); } } })); /* FIXME: Use cached permissions */ editor.trigger_update(); }); } /* list all channel groups */ { let group_list = tab_left.find(".list-groups .entries"); update_groups = (selected_group) => { group_list.children().remove(); const allow_query_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1); const allow_template_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1); for (let group of connection.groups.channelGroups.sort(GroupManager.sorter())) { if (group.type == GroupType.QUERY) { if (!allow_query_groups) continue; } else if (group.type == GroupType.TEMPLATE) { if (!allow_template_groups) continue; } let tag = $.spawn("div").addClass("group").attr("group-id", group.id); let icon_tag = connection.fileManager.icons.generateTag(group.properties.iconid); icon_tag.appendTo(tag); const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id)); { let name = $.spawn("a").text(group.name + " (" + group.id + ")").addClass("name"); if (group.properties.savedb) name.addClass("savedb"); if (connection.channelTree.server.properties.virtualserver_default_channel_group == group.id) name.addClass("default"); name.appendTo(tag); } tag.appendTo(group_list); tag.on('click', event => { current_group = group; update_group_icon = _update_icon; group_list.find(".selected").removeClass("selected"); tag.addClass("selected"); update_buttons(); //TODO trigger only if the editor is in channel group mode! editor.trigger_update(); }); tag.on('contextmenu', event => { if (event.isDefaultPrevented()) return; contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.uyiLQc3y || (_translations.uyiLQc3y = tr("Create a channel group")), icon_class: 'client-add', invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1), callback: () => tab_left.find(".button-add").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.nuh4sliq || (_translations.nuh4sliq = tr("Rename channel group")), icon_class: 'client-edit', invalidPermission: !connection.permissions.neededPermission(PermissionType.I_CHANNEL_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower), callback: () => tab_left.find(".button-rename").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.zyTnu_qn || (_translations.zyTnu_qn = tr("Duplicate channel group")), icon_class: 'client-copy', callback: () => tab_left.find(".button-duplicate").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.qlgoozon || (_translations.qlgoozon = tr("Delete channel group")), icon_class: 'client-delete', invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_DELETE).granted(1), callback: () => tab_left.find(".button-delete").trigger('click') }); event.preventDefault(); }); if (group.id === selected_group) { setTimeout(() => tag.trigger('click'), 0); selected_group = undefined; } } /* because the server menu is the first which will be shown */ if (typeof (selected_group) !== "undefined") { setTimeout(() => group_list.find('.group').first().trigger('click'), 0); } }; tab_left.find(".list-groups").on('contextmenu', event => { if (event.isDefaultPrevented()) return; contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.Sp05Q7cm || (_translations.Sp05Q7cm = tr("Create a channel group")), icon_class: 'client-add', callback: () => tab_left.find(".button-add").trigger('click') }); event.preventDefault(); }); } { const container_buttons = tab_left.find(".container-buttons"); const button_add = container_buttons.find(".button-add"); const button_rename = container_buttons.find(".button-rename"); const button_duplicate = container_buttons.find(".button-duplicate"); const button_delete = container_buttons.find(".button-delete"); button_add.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1)); button_delete.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1)); update_buttons = () => { const permission_modify = current_group && connection.permissions.neededPermission(PermissionType.I_CHANNEL_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower); button_rename.prop("disabled", !permission_modify); button_duplicate.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_CHANNELGROUP_CREATE).granted(1)); }; button_add.on('click', () => { spawnGroupAdd(false, connection.permissions, (name, type) => name.length > 0 && !connection.groups.channelGroups.find(e => e.target == GroupTarget.CHANNEL && e.name.toLowerCase() === name.toLowerCase() && e.type == type), (name, type) => { console.log("Creating channel group: %o, %o", name, type); connection.serverConnection.send_command('channelgroupadd', { name: name, type: type }).then(() => { createInfoModal(_translations.BDKgOv3v || (_translations.BDKgOv3v = tr("Group created")), _translations.asEzKP4X || (_translations.asEzKP4X = tr("The channel group has been created."))).open(); update_groups(0); //TODO: May get the created group? }).catch(error => { console.warn(_translations.ZmlrpljU || (_translations.ZmlrpljU = tr("Failed to create channel group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.zGFSOJO8 || (_translations.zGFSOJO8 = tr("Failed to create group")), MessageHelper.formatMessage(_translations.ZxKo1R5a || (_translations.ZxKo1R5a = tr("Failed to create group:{:br:}")), error)).open(); }); }); }); button_rename.on('click', () => { if (!current_group) return; createInputModal(_translations.K7C5wnF2 || (_translations.K7C5wnF2 = tr("Rename group")), _translations.q1LAQS2V || (_translations.q1LAQS2V = tr("Enter the new group name")), name => name.length > 0 && !connection.groups.channelGroups.find(e => e.target == GroupTarget.CHANNEL && e.name.toLowerCase() === name.toLowerCase() && e.type == current_group.type), result => { if (typeof (result) !== "string" || !result) return; connection.serverConnection.send_command('channelgrouprename', { cgid: current_group.id, name: result }).then(() => { createInfoModal(_translations.l_zRubf8 || (_translations.l_zRubf8 = tr("Group renamed")), _translations.jZWebIbu || (_translations.jZWebIbu = tr("The channel group has been renamed."))).open(); update_groups(current_group.id); }).catch(error => { console.warn(_translations.wKyPu_a7 || (_translations.wKyPu_a7 = tr("Failed to rename channel group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.EOkDrLst || (_translations.EOkDrLst = tr("Failed to rename group")), MessageHelper.formatMessage(_translations.wJbuc7yI || (_translations.wJbuc7yI = tr("Failed to rename group:{:br:}")), error)).open(); }); }).open(); }); button_duplicate.on('click', () => { createErrorModal(_translations.aUVlGWcp || (_translations.aUVlGWcp = tr("Not implemented yet")), _translations.KsmwzQ7d || (_translations.KsmwzQ7d = tr("This function hasn't been implemented yet!"))).open(); }); button_delete.on('click', () => { if (!current_group) return; Modals.spawnYesNo(_translations.ABUF6IGq || (_translations.ABUF6IGq = tr("Are you sure?")), MessageHelper.formatMessage(_translations.y2KLYSW7 || (_translations.y2KLYSW7 = tr("Do you really want to delete the group {}?")), current_group.name), result => { if (result !== true) return; connection.serverConnection.send_command("channelgroupdel", { cgid: current_group.id, force: true }).then(() => { createInfoModal(_translations.vTy1M6TK || (_translations.vTy1M6TK = tr("Group deleted")), _translations.LzPrH7f2 || (_translations.LzPrH7f2 = tr("The channel group has been deleted."))).open(); update_groups(0); }).catch(error => { console.warn(_translations.ExJ0DQQB || (_translations.ExJ0DQQB = tr("Failed to delete channel group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.pFsB8a2X || (_translations.pFsB8a2X = tr("Failed to delete group")), MessageHelper.formatMessage(_translations.PIpmf1Jv || (_translations.PIpmf1Jv = tr("Failed to delete group:{:br:}")), error)).open(); }); }); }); } update_groups(0); } function apply_server_groups(connection, editor, tab_left, tab_right) { let current_group; let current_group_changed = []; let update_buttons; /* list all groups */ let update_icon = []; let update_groups; { let group_list = tab_left.find(".container-group-list .list-groups .entries"); let group_list_update_icon; update_icon.push(i => group_list_update_icon(i)); update_groups = (selected_group) => { group_list.children().remove(); const allow_query_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1); const allow_template_groups = connection.permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1); for (const group of connection.groups.serverGroups.sort(GroupManager.sorter())) { if (group.type == GroupType.QUERY) { if (!allow_query_groups) continue; } else if (group.type == GroupType.TEMPLATE) { if (!allow_template_groups) continue; } let tag = $.spawn("div").addClass("group").attr("group-id", group.id); let icon_tag = connection.fileManager.icons.generateTag(group.properties.iconid); icon_tag.appendTo(tag); const _update_icon = icon_id => icon_tag.replaceWith(icon_tag = connection.fileManager.icons.generateTag(icon_id)); { let name = $.spawn("div").text(group.name + " (" + group.id + ")").addClass("name"); if (group.properties.savedb) name.addClass("savedb"); if (connection.channelTree.server.properties.virtualserver_default_server_group == group.id) name.addClass("default"); name.appendTo(tag); } tag.appendTo(group_list); tag.on('click', event => { if (current_group === group) return; current_group = group; group_list_update_icon = _update_icon; if (update_buttons) update_buttons(); for (const entry of current_group_changed) entry(); group_list.find(".selected").removeClass("selected"); tag.addClass("selected"); editor.trigger_update(); }); tag.on('contextmenu', event => { if (event.isDefaultPrevented()) return; contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.ZKRKRFdZ || (_translations.ZKRKRFdZ = tr("Create a server group")), icon_class: 'client-add', invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1), callback: () => tab_left.find(".button-add").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.tz_xB0DK || (_translations.tz_xB0DK = tr("Rename server group")), icon_class: 'client-edit', invalidPermission: !connection.permissions.neededPermission(PermissionType.I_SERVER_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower), callback: () => tab_left.find(".button-rename").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.shQXAD3I || (_translations.shQXAD3I = tr("Duplicate server group")), icon_class: 'client-copy', callback: () => tab_left.find(".button-duplicate").trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.N5puAby8 || (_translations.N5puAby8 = tr("Delete server group")), icon_class: 'client-delete', invalidPermission: !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_DELETE).granted(1), callback: () => tab_left.find(".button-delete").trigger('click') }); event.preventDefault(); }); if (group.id === selected_group) { setTimeout(() => tag.trigger('click'), 0); selected_group = undefined; } } /* because the server menu is the first which will be shown */ if (typeof (selected_group) !== "undefined") { setTimeout(() => group_list.find('.group').first().trigger('click'), 0); } }; tab_left.find(".list-groups").on('contextmenu', event => { if (event.isDefaultPrevented()) return; contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.wvb9mJQm || (_translations.wvb9mJQm = tr("Create a server group")), icon_class: 'client-add', callback: () => tab_left.find(".button-add").trigger('click') }); event.preventDefault(); }); } { const container_buttons = tab_left.find(".container-group-list .container-buttons"); const button_add = container_buttons.find(".button-add"); const button_rename = container_buttons.find(".button-rename"); const button_duplicate = container_buttons.find(".button-duplicate"); const button_delete = container_buttons.find(".button-delete"); button_add.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1)); button_delete.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_DELETE).granted(1)); update_buttons = () => { const permission_modify = current_group && connection.permissions.neededPermission(PermissionType.I_SERVER_GROUP_MODIFY_POWER).granted(current_group.requiredModifyPower); button_rename.prop("disabled", !permission_modify); button_duplicate.prop("disabled", !connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_CREATE).granted(1)); }; button_add.on('click', () => { spawnGroupAdd(true, connection.permissions, (name, type) => name.length > 0 && !connection.groups.serverGroups.find(e => e.target == GroupTarget.SERVER && e.name.toLowerCase() === name.toLowerCase() && e.type == type), (name, type) => { console.log("Creating group: %o, %o", name, type); connection.serverConnection.send_command('servergroupadd', { name: name, type: type }).then(() => { createInfoModal(_translations.BNdJT1cT || (_translations.BNdJT1cT = tr("Group created")), _translations.PzBumF3C || (_translations.PzBumF3C = tr("The server group has been created."))).open(); update_groups(0); //TODO: May get the created group? }).catch(error => { console.warn(_translations.sNlSiT7C || (_translations.sNlSiT7C = tr("Failed to create server group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.usfuFq3a || (_translations.usfuFq3a = tr("Failed to create group")), MessageHelper.formatMessage(_translations.XGuZ4MEv || (_translations.XGuZ4MEv = tr("Failed to create group:{:br:}")), error)).open(); }); }); }); button_rename.on('click', () => { if (!current_group) return; createInputModal(_translations.u4Fvc7m6 || (_translations.u4Fvc7m6 = tr("Rename group")), _translations.ORzt406c || (_translations.ORzt406c = tr("Enter the new group name")), name => name.length > 0 && !connection.groups.serverGroups.find(e => e.target == GroupTarget.SERVER && e.name.toLowerCase() === name.toLowerCase() && e.type == current_group.type), result => { if (typeof (result) !== "string" || !result) return; connection.serverConnection.send_command('servergrouprename', { sgid: current_group.id, name: result }).then(() => { createInfoModal(_translations.sGFYk3BV || (_translations.sGFYk3BV = tr("Group renamed")), _translations.Z6K53vUj || (_translations.Z6K53vUj = tr("The server group has been renamed."))).open(); update_groups(current_group.id); }).catch(error => { console.warn(_translations.Nvr1sNU1 || (_translations.Nvr1sNU1 = tr("Failed to rename server group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.gZuGhFeW || (_translations.gZuGhFeW = tr("Failed to rename group")), MessageHelper.formatMessage(_translations.RAahtMoY || (_translations.RAahtMoY = tr("Failed to rename group:{:br:}")), error)).open(); }); }).open(); }); button_duplicate.on('click', () => { createErrorModal(_translations.JFTntZDs || (_translations.JFTntZDs = tr("Not implemented yet")), _translations.XSwWUXyj || (_translations.XSwWUXyj = tr("This function hasn't been implemented yet!"))).open(); }); button_delete.on('click', () => { if (!current_group) return; Modals.spawnYesNo(_translations.BtRlLNMi || (_translations.BtRlLNMi = tr("Are you sure?")), MessageHelper.formatMessage(_translations.DjQ0gUq3 || (_translations.DjQ0gUq3 = tr("Do you really want to delete the group {}?")), current_group.name), result => { if (result !== true) return; connection.serverConnection.send_command("servergroupdel", { sgid: current_group.id, force: true }).then(() => { createInfoModal(_translations.Skc29nKb || (_translations.Skc29nKb = tr("Group deleted")), _translations.e9uYZsgU || (_translations.e9uYZsgU = tr("The server group has been deleted."))).open(); update_groups(0); }).catch(error => { console.warn(_translations.p5NZb93F || (_translations.p5NZb93F = tr("Failed to delete server group: %o")), error); if (error instanceof CommandResult) { error = error.extra_message || error.message; } createErrorModal(_translations.Xe4iGn25 || (_translations.Xe4iGn25 = tr("Failed to delete group")), MessageHelper.formatMessage(_translations.QzcGXAWO || (_translations.QzcGXAWO = tr("Failed to delete group:{:br:}")), error)).open(); }); }); }); } update_groups(0); /* the editor */ { const pe_server = tab_right.find(".permission-editor"); tab_right.on('show', event => { pe_server.append(editor.html_tag()); if (connection.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_SERVERGROUP_PERMISSION_LIST).granted(1)) editor.set_mode(PermissionEditorMode.VISIBLE); else { editor.set_mode(PermissionEditorMode.NO_PERMISSION); return; } editor.set_listener_update(() => { console.log("Updating permissions"); connection.groups.request_permissions(current_group).then(result => editor.set_permissions(result)).catch(error => { console.log(error); //TODO handling? }); }); editor.set_listener((permission, value) => __awaiter(this, void 0, void 0, function* () { if (!current_group) throw "unset server group"; if (value.remove) { /* remove the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.rvTpLnM3 || (_translations.rvTpLnM3 = tr("Removing server group permission %s. permission.id: %o")), permission.name, permission.id); yield connection.serverConnection.send_command("servergroupdelperm", { sgid: current_group.id, permid: permission.id, }).then(e => { if (permission.name === "i_icon_id") for (const c of update_icon) c(0); return e; }); } else { log.info(LogCategory.PERMISSIONS, _translations.lNfsBK1q || (_translations.lNfsBK1q = tr("Removing server group grant permission %s. permission.id: %o")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("servergroupdelperm", { sgid: current_group.id, permid: permission.id_grant(), }); } } else { /* add the permission */ if (typeof (value.value) !== "undefined") { log.info(LogCategory.PERMISSIONS, _translations.l3qUWBQ2 || (_translations.l3qUWBQ2 = tr("Adding or updating server group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}")), permission.name, permission.id, value.value, value.flag_skip, value.flag_negate); yield connection.serverConnection.send_command("servergroupaddperm", { sgid: current_group.id, permid: permission.id, permvalue: value.value, permskip: value.flag_skip, permnegated: value.flag_negate }).then(e => { if (permission.name === "i_icon_id") for (const c of update_icon) c(value.value); return e; }); } else { log.info(LogCategory.PERMISSIONS, _translations.mH6z0xG8 || (_translations.mH6z0xG8 = tr("Adding or updating server group grant permission %s. permission.{id: %o, value: %o}")), permission.name, permission.id_grant(), value.granted); yield connection.serverConnection.send_command("servergroupaddperm", { sgid: current_group.id, permid: permission.id_grant(), permvalue: value.granted, permskip: false, permnegated: false }); } } })); editor.trigger_update(); }); } /* client list */ { //container-client-list container-group-list let clients_visible = false; let selected_client; const container_client_list = tab_left.find(".container-client-list").addClass("hidden"); const container_group_list = tab_left.find(".container-group-list"); const container_selected_group = container_client_list.find(".container-current-group"); const container_clients = container_client_list.find(".list-clients .entries"); const input_filter = container_client_list.find(".filter-client-list"); const button_add = container_client_list.find(".button-add"); const button_delete = container_client_list.find(".button-delete"); const update_filter = () => { const filter_text = (input_filter.val() || "").toString().toLowerCase(); if (!filter_text) { container_clients.find(".entry").css('display', 'block'); } else { const entries = container_clients.find(".entry"); for (const _entry of entries) { const entry = $(_entry); if (entry.attr("search-string").toLowerCase().indexOf(filter_text) !== -1) entry.css('display', 'block'); else entry.css('display', 'none'); } } }; const update_client_list = () => { container_clients.empty(); button_delete.prop('disabled', true); connection.serverConnection.command_helper.request_clients_by_server_group(current_group.id).then(clients => { for (const client of clients) { const tag = $.spawn("div").addClass("client").text(client.client_nickname); tag.attr("search-string", client.client_nickname + "-" + client.client_unique_identifier + "-" + client.client_database_id); container_clients.append(tag); tag.on('click contextmenu', event => { container_clients.find(".selected").removeClass("selected"); tag.addClass("selected"); selected_client = { tag: tag, dbid: client.client_database_id }; button_delete.prop('disabled', false); }); tag.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.VSkQ3V09 || (_translations.VSkQ3V09 = tr("Add client")), icon_class: 'client-add', callback: () => button_add.trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.z40xhzvX || (_translations.z40xhzvX = tr("Remove client")), icon_class: 'client-delete', callback: () => button_delete.trigger('click') }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.RnTroWBE || (_translations.RnTroWBE = tr("Copy unique id")), icon_class: 'client-copy', callback: () => copy_to_clipboard(client.client_unique_identifier) }); }); } update_filter(); }).catch(error => { if (error instanceof CommandResult && error.id === ErrorID.PERMISSION_ERROR) return; console.warn(_translations.JrlJsqem || (_translations.JrlJsqem = tr("Failed to receive server group clients for group %d: %o")), current_group.id, error); }); }; current_group_changed.push(update_client_list); button_delete.on('click', event => { const client = selected_client; if (!client) return; connection.serverConnection.send_command("servergroupdelclient", { sgid: current_group.id, cldbid: client.dbid }).then(() => { selected_client.tag.detach(); button_delete.prop('disabled', true); /* nothing is selected */ }).catch(error => { console.log(_translations.QYvEqWFo || (_translations.QYvEqWFo = tr("Failed to delete client %o from server group %o: %o")), client.dbid, current_group.id, error); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.w_grwuKP || (_translations.w_grwuKP = tr("Failed to remove client")), _translations.Xqg78pAj || (_translations.Xqg78pAj = tr("Failed to remove client from server group"))).open(); }); }); button_add.on('click', event => { createInputModal(_translations.vp8oLTFs || (_translations.vp8oLTFs = tr("Add client to server group")), _translations.bqhbv6gi || (_translations.bqhbv6gi = tr("Enter the client unique id or database id")), text => { if (!text) return false; if (!!text.match(/^[0-9]+$/)) return true; try { return atob(text).length >= 20; } catch (error) { return false; } }, (text) => __awaiter(this, void 0, void 0, function* () { if (typeof (text) !== "string") return; let dbid; if (!!text.match(/^[0-9]+$/)) { dbid = parseInt(text); debugger; } else { try { const data = yield connection.serverConnection.command_helper.info_from_uid(text.trim()); dbid = data[0].client_database_id; } catch (error) { console.log(_translations.IaBow48n || (_translations.IaBow48n = tr("Failed to resolve client database id from unique id (%s): %o")), text, error); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.qXfwiEGs || (_translations.qXfwiEGs = tr("Failed to add client")), MessageHelper.formatMessage(_translations.xvC5Mz5O || (_translations.xvC5Mz5O = tr("Failed to add client to server group\nFailed to resolve database id: {}.")), error)).open(); return; } } if (!dbid) { console.log(_translations.RTOwbHRq || (_translations.RTOwbHRq = tr("Failed to resolve client database id from unique id (%s): Client not found"))); createErrorModal(_translations.Fqjboqd3 || (_translations.Fqjboqd3 = tr("Failed to add client")), _translations.E8Wmhi8B || (_translations.E8Wmhi8B = tr("Failed to add client to server group\nClient database id not found"))).open(); return; } connection.serverConnection.send_command("servergroupaddclient", { sgid: current_group.id, cldbid: dbid }).then(() => { update_client_list(); }).catch(error => { console.log(_translations.kwFlKJU2 || (_translations.kwFlKJU2 = tr("Failed to add client %o to server group %o: %o")), dbid, current_group.id, error); if (error instanceof CommandResult) error = error.extra_message || error.message; createErrorModal(_translations.iBC3dxeB || (_translations.iBC3dxeB = tr("Failed to add client")), tr("Failed to add client to server group\n" + error)).open(); }); })).open(); }); container_client_list.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.HHOHRQs8 || (_translations.HHOHRQs8 = tr("Add client")), icon_class: 'client-add', callback: () => button_add.trigger('click') }); }); /* icon handler and current group display */ { let update_icon_callback; update_icon.push(i => update_icon_callback(i)); input_filter.on('change keyup', event => update_filter()); current_group_changed.push(() => { container_selected_group.empty(); if (!current_group) return; let icon_container = $.spawn("div").addClass("icon-container").appendTo(container_selected_group); connection.fileManager.icons.generateTag(current_group.properties.iconid).appendTo(icon_container); update_icon_callback = icon => { icon_container.empty(); connection.fileManager.icons.generateTag(icon).appendTo(icon_container); }; $.spawn("div").addClass("name").text(current_group.name + " (" + current_group.id + ")").appendTo(container_selected_group); }); } tab_right.on('show', event => { editor.set_toggle_button(() => { clients_visible = !clients_visible; container_client_list.toggleClass("hidden", !clients_visible); container_group_list.toggleClass("hidden", clients_visible); return clients_visible ? _translations.XhSxnxAW || (_translations.XhSxnxAW = tr("Hide clients in group")) : _translations.SJnJGsYd || (_translations.SJnJGsYd = tr("Show clients in group")); }, clients_visible ? _translations.nztvRGaW || (_translations.nztvRGaW = tr("Hide clients in group")) : _translations.ouOjBgEH || (_translations.ouOjBgEH = tr("Show clients in group"))); }); } } function spawnGroupAdd(server_group, permissions, valid_name, callback) { let modal; modal = createModal({ header: _translations.Ombfpy2D || (_translations.Ombfpy2D = tr("Create a new group")), body: () => { let tag = $("#tmpl_group_add").renderTag({ server_group: server_group }); tag.find(".group-type-template").prop("disabled", !permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_TEMPLATES).granted(1)); tag.find(".group-type-query").prop("disabled", !permissions.neededPermission(PermissionType.B_SERVERINSTANCE_MODIFY_QUERYGROUP).granted(1)); const container_name = tag.find(".group-name"); const button_create = tag.find(".button-create"); const group_type = () => tag.find(".group-type")[0].selectedIndex; container_name.on('keyup change', (event) => { if (event.type === 'keyup') { const kevent = event; if (!kevent.shiftKey && kevent.key == 'Enter') { button_create.trigger('click'); return; } } const valid = valid_name(container_name.val(), group_type()); button_create.prop("disabled", !valid); container_name.parent().toggleClass("is-invalid", !valid); }).trigger('change'); tag.find(".group-type").on('change', () => container_name.trigger('change')); button_create.on('click', event => { if (button_create.prop("disabled")) return; button_create.prop("disabled", true); /* disable double clicking */ modal.close(); callback(container_name.val(), group_type()); }); return tag; }, footer: null, width: 600 }); modal.htmlTag.find(".modal-body").addClass("modal-group-add"); modal.open_listener.push(() => { modal.htmlTag.find(".group-name").focus(); }); modal.open(); } })(Modals || (Modals = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["34cd71225ad5db2a75a5d24e2b7d106cb2fb951faf9aeb6d5fcbd8cfcef9103a"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["34cd71225ad5db2a75a5d24e2b7d106cb2fb951faf9aeb6d5fcbd8cfcef9103a"] = "34cd71225ad5db2a75a5d24e2b7d106cb2fb951faf9aeb6d5fcbd8cfcef9103a"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "SNMslQQQ", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (781,46)" }, { name: "zfS9XdO_", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1406,31)" }, { name: "Tcfl6mLz", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1410,31)" }, { name: "mP58mGgk", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1448,46)" }, { name: "lZSZQS43", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1497,35)" }, { name: "Q9AfhdTW", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1503,35)" }, { name: "vFdcnsOq", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1514,35)" }, { name: "uE7PRt7i", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1520,35)" }, { name: "EPXyKw8w", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1530,31)" }, { name: "yaxyk7HH", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1535,31)" }, { name: "hwphI7MO", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1541,31)" }, { name: "pyMqO5eg", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1544,33)" }, { name: "GOZJ1o5q", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1545,33)" }, { name: "oJrVKMx7", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1551,31)" }, { name: "cBq9P5L9", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/CanvasPermissionEditor.ts (1588,42)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /* first needs the AbstractPermissionEdit */ /* Canvas Permission Editor */ var pe; (function (pe) { let ui; (function (ui) { let RepaintMode; (function (RepaintMode) { RepaintMode[RepaintMode["NONE"] = 0] = "NONE"; RepaintMode[RepaintMode["REPAINT"] = 1] = "REPAINT"; RepaintMode[RepaintMode["REPAINT_OBJECT_FULL"] = 2] = "REPAINT_OBJECT_FULL"; RepaintMode[RepaintMode["REPAINT_FULL"] = 3] = "REPAINT_FULL"; })(RepaintMode = ui.RepaintMode || (ui.RepaintMode = {})); let ClickEventType; (function (ClickEventType) { ClickEventType[ClickEventType["SIGNLE"] = 0] = "SIGNLE"; ClickEventType[ClickEventType["DOUBLE"] = 1] = "DOUBLE"; ClickEventType[ClickEventType["CONTEXT_MENU"] = 2] = "CONTEXT_MENU"; })(ClickEventType = ui.ClickEventType || (ui.ClickEventType = {})); class DrawableObject { constructor() { this._object_full_draw = false; this._width = 0; this._transforms = []; this.colors = {}; } set_width(value) { this._width = value; } request_full_draw() { this._object_full_draw = true; } pop_full_draw() { const result = this._object_full_draw; this._object_full_draw = false; return result; } width() { return this._width; } push_transform(context) { this._transforms.push(context.getTransform()); } pop_transform(context) { const transform = this._transforms.pop(); context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f); } original_x(context, x) { return context.getTransform().e + x; } original_y(context, y) { return context.getTransform().f + y; } set_color_scheme(scheme) { this.colors = scheme; } set_manager(manager) { this.manager = manager; } } class PermissionGroup extends DrawableObject { constructor(group) { super(); this._sub_elements = []; this.collapsed = false; this.group = group; this._element_permissions = new PermissionList(this.group.permissions); for (const sub of this.group.children) this._sub_elements.push(new PermissionGroup(sub)); } draw(context, full) { const _full = this.pop_full_draw() || full; this.push_transform(context); context.translate(PermissionGroup.ARROW_SIZE + 20, PermissionGroup.HEIGHT); let sum_height = 0; /* let first draw the elements, because if the sum height is zero then we could hide ourselves */ if (!this.collapsed) { /* draw the next groups */ for (const group of this._sub_elements) { group.draw(context, full); const height = group.height(); sum_height += height; context.translate(0, height); } this._element_permissions.draw(context, full); if (sum_height == 0) sum_height += this._element_permissions.height(); } else { const process_group = (group) => { for (const g of group._sub_elements) process_group(g); group._element_permissions.handle_hide(); if (sum_height == 0 && group._element_permissions.height() > 0) { sum_height = 1; } }; process_group(this); } this.pop_transform(context); if (_full && sum_height > 0) { const arrow_stretch = 2 / 3; if (!full) { context.clearRect(0, 0, this.width(), PermissionGroup.HEIGHT); } context.fillStyle = this.colors.group.name; /* arrow */ { const x1 = this.collapsed ? PermissionGroup.ARROW_SIZE * arrow_stretch / 2 : 0; const y1 = (PermissionGroup.HEIGHT - PermissionGroup.ARROW_SIZE) / 2 + (this.collapsed ? 0 : PermissionGroup.ARROW_SIZE * arrow_stretch / 2); /* center arrow */ const x2 = this.collapsed ? x1 + PermissionGroup.ARROW_SIZE * arrow_stretch : x1 + PermissionGroup.ARROW_SIZE / 2; const y2 = this.collapsed ? y1 + PermissionGroup.ARROW_SIZE / 2 : y1 + PermissionGroup.ARROW_SIZE * arrow_stretch; const x3 = this.collapsed ? x1 : x1 + PermissionGroup.ARROW_SIZE; const y3 = this.collapsed ? y1 + PermissionGroup.ARROW_SIZE : y1; context.beginPath(); context.moveTo(x1, y1); context.lineTo(x2, y2); context.lineTo(x3, y3); context.moveTo(x2, y2); context.lineTo(x3, y3); context.fill(); this._listener_colaps.region.x = this.original_x(context, 0); this._listener_colaps.region.y = this.original_y(context, y1); } /* text */ { context.font = this.colors.group.name_font; context.textBaseline = "middle"; context.textAlign = "start"; context.fillText(this.group.group.name, PermissionGroup.ARROW_SIZE + 5, PermissionGroup.HEIGHT / 2); } } } set_width(value) { super.set_width(value); for (const element of this._sub_elements) element.set_width(value - PermissionGroup.ARROW_SIZE - 20); this._element_permissions.set_width(value - PermissionGroup.ARROW_SIZE - 20); } set_color_scheme(scheme) { super.set_color_scheme(scheme); for (const child of this._sub_elements) child.set_color_scheme(scheme); this._element_permissions.set_color_scheme(scheme); } set_manager(manager) { super.set_manager(manager); for (const child of this._sub_elements) child.set_manager(manager); this._element_permissions.set_manager(manager); } height() { let result = 0; if (!this.collapsed) { for (const element of this._sub_elements) result += element.height(); result += this._element_permissions.height(); } else { //We've to figure out if we have permissions const process_group = (group) => { if (result == 0 && group._element_permissions.height() > 0) { result = 1; } else { for (const g of group._sub_elements) process_group(g); } }; process_group(this); if (result > 0) return PermissionGroup.HEIGHT; return 0; } if (result > 0) { result += PermissionGroup.HEIGHT; return result; } else { return 0; } } initialize() { for (const child of this._sub_elements) child.initialize(); this._element_permissions.initialize(); this._listener_colaps = { region: { x: 0, y: 0, height: PermissionGroup.ARROW_SIZE, width: PermissionGroup.ARROW_SIZE }, region_weight: 10, /* on_mouse_enter: () => { this.collapsed_hovered = true; return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { this.collapsed_hovered = false; return RepaintMode.REPAINT_OBJECT_FULL; }, */ on_click: () => { this.collapsed = !this.collapsed; return RepaintMode.REPAINT_FULL; }, set_full_draw: () => this.request_full_draw(), mouse_cursor: "pointer" }; this.manager.intercept_manager().register_listener(this._listener_colaps); } finalize() { for (const child of this._sub_elements) child.finalize(); this._element_permissions.finalize(); } collapse_group() { for (const child of this._sub_elements) child.collapse_group(); this.collapsed = true; } expend_group() { for (const child of this._sub_elements) child.expend_group(); this.collapsed = false; } } PermissionGroup.HEIGHT = parseFloat(getComputedStyle(document.documentElement).fontSize) * (3 / 2); /* 24 */ PermissionGroup.ARROW_SIZE = 10; /* 12 */ class PermissionList extends DrawableObject { constructor(permissions) { super(); this.permissions = []; for (const permission of permissions) this.permissions.push(new PermissionEntry(permission)); } set_width(value) { super.set_width(value); for (const entry of this.permissions) entry.set_width(value); } draw(context, full) { this.push_transform(context); for (const permission of this.permissions) { permission.draw(context, full); context.translate(0, permission.height()); } this.pop_transform(context); } height() { let height = 0; for (const permission of this.permissions) height += permission.height(); return height; } set_color_scheme(scheme) { super.set_color_scheme(scheme); for (const entry of this.permissions) entry.set_color_scheme(scheme); } set_manager(manager) { super.set_manager(manager); for (const entry of this.permissions) entry.set_manager(manager); } initialize() { for (const entry of this.permissions) entry.initialize(); } finalize() { for (const entry of this.permissions) entry.finalize(); } handle_hide() { for (const entry of this.permissions) entry.handle_hide(); } } class PermissionEntry extends DrawableObject { constructor(permission) { super(); this.granted = 22; this.flag_skip = true; this._prev_selected = false; this.flag_skip_hovered = false; this.flag_negate_hovered = false; this.flag_value_hovered = false; this.flag_grant_hovered = false; this._permission = permission; } set_icon_id_image(image) { if (this._icon_image === image) return; this._icon_image = image; if (image) { image.height = 16; image.width = 16; } } permission() { return this._permission; } draw(ctx, full) { if (!this.pop_full_draw() && !full) { /* Note: do not change this order! */ /* test for update! */ return; } if (this.hidden) { this.handle_hide(); return; } ctx.lineWidth = 1; /* debug box */ if (false) { ctx.fillStyle = "#FF0000"; ctx.fillRect(0, 0, this.width(), PermissionEntry.HEIGHT); ctx.fillStyle = "#000000"; ctx.strokeRect(0, 0, this.width(), PermissionEntry.HEIGHT); } if (!full) { const off = this.selected || this._prev_selected ? ctx.getTransform().e : 0; ctx.clearRect(-off, 0, this.width() + off, PermissionEntry.HEIGHT); } if (this.selected) ctx.fillStyle = this.colors.permission.background_selected; else ctx.fillStyle = this.colors.permission.background; const off = this.selected ? ctx.getTransform().e : 0; ctx.fillRect(-off, 0, this.width() + off, PermissionEntry.HEIGHT); this._prev_selected = this.selected; /* permission name */ { ctx.fillStyle = typeof (this.value) !== "undefined" ? this.colors.permission.name : this.colors.permission.name_unset; ctx.textBaseline = "middle"; ctx.textAlign = "start"; ctx.font = this.colors.permission.name_font; ctx.fillText(this._permission.name, 0, PermissionEntry.HALF_HEIGHT); } const original_y = this.original_y(ctx, 0); const original_x = this.original_x(ctx, 0); const width = this.width(); /* draw granted */ let w = width - PermissionEntry.COLUMN_GRANTED; if (typeof (this.granted) === "number") { this._listener_grant.region.x = original_x + w; this._listener_grant.region.y = original_y; this._draw_number_field(ctx, this.colors.permission.granted, w, 0, PermissionEntry.COLUMN_VALUE, this.granted, this.flag_grant_hovered); } else { this._listener_grant.region.y = original_y; this._listener_grant.region.x = original_x + width - PermissionEntry.COLUMN_GRANTED; } /* draw value and the skip stuff */ if (typeof (this.value) === "number") { w -= PermissionEntry.COLUMN_SKIP + PermissionEntry.COLUMN_PADDING; { const x = w + (PermissionEntry.COLUMN_SKIP - PermissionEntry.CHECKBOX_HEIGHT) / 2; const y = 1; this._listener_checkbox_skip.region.x = original_x + x; this._listener_checkbox_skip.region.y = original_y + y; this._draw_checkbox_field(ctx, this.colors.permission.skip, x, y, PermissionEntry.CHECKBOX_HEIGHT, this.flag_skip, this.flag_skip_hovered); } w -= PermissionEntry.COLUMN_NEGATE + PermissionEntry.COLUMN_PADDING; { const x = w + (PermissionEntry.COLUMN_NEGATE - PermissionEntry.CHECKBOX_HEIGHT) / 2; const y = 1; this._listener_checkbox_negate.region.x = original_x + x; this._listener_checkbox_negate.region.y = original_y + y; this._draw_checkbox_field(ctx, this.colors.permission.negate, x, y, PermissionEntry.CHECKBOX_HEIGHT, this.flag_negate, this.flag_negate_hovered); } w -= PermissionEntry.COLUMN_VALUE + PermissionEntry.COLUMN_PADDING; if (this._permission.is_boolean()) { const x = w + PermissionEntry.COLUMN_VALUE - PermissionEntry.CHECKBOX_HEIGHT; const y = 1; this._listener_value.region.width = PermissionEntry.CHECKBOX_HEIGHT; this._listener_value.region.x = original_x + x; this._listener_value.region.y = original_y + y; this._draw_checkbox_field(ctx, this.colors.permission.value_b, x, y, PermissionEntry.CHECKBOX_HEIGHT, this.value > 0, this.flag_value_hovered); } else if (this._permission.name === "i_icon_id" && this._icon_image) { this._listener_value.region.x = original_x + w; this._listener_value.region.y = original_y; this._listener_value.region.width = PermissionEntry.CHECKBOX_HEIGHT; this._draw_icon_field(ctx, this.colors.permission.value_b, w, 0, PermissionEntry.COLUMN_VALUE, this.flag_value_hovered, this._icon_image); } else { this._listener_value.region.width = PermissionEntry.COLUMN_VALUE; this._listener_value.region.x = original_x + w; this._listener_value.region.y = original_y; this._draw_number_field(ctx, this.colors.permission.value, w, 0, PermissionEntry.COLUMN_VALUE, this.value, this.flag_value_hovered); } this._listener_value.disabled = false; } else { this._listener_checkbox_skip.region.y = -1e8; this._listener_checkbox_negate.region.y = -1e8; this._listener_value.region.y = original_y; this._listener_value.region.x = original_x + width - PermissionEntry.COLUMN_GRANTED - PermissionEntry.COLUMN_NEGATE - PermissionEntry.COLUMN_VALUE - PermissionEntry.COLUMN_PADDING * 4; this._listener_value.disabled = true; } this._listener_general.region.y = original_y; this._listener_general.region.x = original_x; } handle_hide() { /* so the listener wound get triggered */ this._listener_value.region.x = -1e8; this._listener_grant.region.x = -1e8; this._listener_checkbox_negate.region.x = -1e8; this._listener_checkbox_skip.region.x = -1e8; this._listener_general.region.x = -1e8; } _draw_icon_field(ctx, scheme, x, y, width, hovered, image) { const line = ctx.lineWidth; ctx.lineWidth = 2; ctx.fillStyle = scheme.border; ctx.strokeRect(x + 1, y + 1, PermissionEntry.HEIGHT - 2, PermissionEntry.HEIGHT - 2); ctx.lineWidth = line; ctx.fillStyle = hovered ? scheme.background_hovered : scheme.background; ctx.fillRect(x + 1, y + 1, PermissionEntry.HEIGHT - 2, PermissionEntry.HEIGHT - 2); const center_y = y + PermissionEntry.HEIGHT / 2; const center_x = x + PermissionEntry.HEIGHT / 2; ctx.drawImage(image, center_x - image.width / 2, center_y - image.height / 2); } _draw_number_field(ctx, scheme, x, y, width, value, hovered) { ctx.fillStyle = hovered ? scheme.background_hovered : scheme.background; ctx.fillRect(x, y, width, PermissionEntry.HEIGHT); ctx.fillStyle = scheme.color; ctx.font = scheme.font; //Math.floor(2/3 * PermissionEntry.HEIGHT) + "px Arial"; ctx.textAlign = "start"; ctx.fillText(value + "", x, y + PermissionEntry.HALF_HEIGHT, width); ctx.strokeStyle = "#6e6e6e"; const line = ctx.lineWidth; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x, y + PermissionEntry.HEIGHT - 2); ctx.lineTo(x + width, y + PermissionEntry.HEIGHT - 2); ctx.stroke(); ctx.lineWidth = line; } _draw_checkbox_field(ctx, scheme, x, y, height, checked, hovered) { ctx.fillStyle = scheme.border; ctx.strokeRect(x, y, height, height); ctx.fillStyle = checked ? (hovered ? scheme.background_checked_hovered : scheme.background_checked) : (hovered ? scheme.background_hovered : scheme.background); ctx.fillRect(x + 1, y + 1, height - 2, height - 2); if (checked) { ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillStyle = scheme.checkmark; ctx.font = scheme.checkmark_font; //Math.floor((5/4) * PermissionEntry.HEIGHT) + "px Arial"; ctx.fillText("✓", x + height / 2, y + height / 2); } } height() { return this.hidden ? 0 : PermissionEntry.HEIGHT; } set_width(value) { super.set_width(value); this._listener_general.region.width = value; } initialize() { this._listener_checkbox_skip = { region: { x: -1e8, y: -1e8, height: PermissionEntry.CHECKBOX_HEIGHT, width: PermissionEntry.CHECKBOX_HEIGHT }, region_weight: 10, on_mouse_enter: () => { this.flag_skip_hovered = true; return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { this.flag_skip_hovered = false; return RepaintMode.REPAINT_OBJECT_FULL; }, on_click: () => { this.flag_skip = !this.flag_skip; if (this.on_change) this.on_change(); return RepaintMode.REPAINT_OBJECT_FULL; }, set_full_draw: () => this.request_full_draw(), mouse_cursor: "pointer" }; this._listener_checkbox_negate = { region: { x: -1e8, y: -1e8, height: PermissionEntry.CHECKBOX_HEIGHT, width: PermissionEntry.CHECKBOX_HEIGHT }, region_weight: 10, on_mouse_enter: () => { this.flag_negate_hovered = true; return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { this.flag_negate_hovered = false; return RepaintMode.REPAINT_OBJECT_FULL; }, on_click: () => { this.flag_negate = !this.flag_negate; if (this.on_change) this.on_change(); return RepaintMode.REPAINT_OBJECT_FULL; }, set_full_draw: () => this.request_full_draw(), mouse_cursor: "pointer" }; this._listener_value = { region: { x: -1e8, y: -1e8, height: this._permission.is_boolean() ? PermissionEntry.CHECKBOX_HEIGHT : PermissionEntry.HEIGHT, width: this._permission.is_boolean() ? PermissionEntry.CHECKBOX_HEIGHT : PermissionEntry.COLUMN_VALUE }, region_weight: 10, on_mouse_enter: () => { this.flag_value_hovered = true; return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { this.flag_value_hovered = false; return RepaintMode.REPAINT_OBJECT_FULL; }, on_click: () => { if (this._permission.is_boolean()) { this.value = this.value > 0 ? 0 : 1; if (this.on_change) this.on_change(); return RepaintMode.REPAINT_OBJECT_FULL; } else if (this._permission.name === "i_icon_id") { this.on_icon_select(this.value).then(value => { this.value = value; if (this.on_change) this.on_change(); }).catch(error => { console.warn(_translations.SNMslQQQ || (_translations.SNMslQQQ = tr("Failed to select icon: %o")), error); }); } else { this._spawn_number_edit(this._listener_value.region.x, this._listener_value.region.y, this._listener_value.region.width, this._listener_value.region.height, this.colors.permission.value, this.value || 0, value => { if (typeof (value) === "number") { this.value = value; this.request_full_draw(); this.manager.request_draw(false); if (this.on_change) this.on_change(); } }); } return RepaintMode.REPAINT_OBJECT_FULL; }, set_full_draw: () => this.request_full_draw(), mouse_cursor: "pointer" }; this._listener_grant = { region: { x: -1e8, y: -1e8, height: PermissionEntry.HEIGHT, width: PermissionEntry.COLUMN_VALUE }, region_weight: 10, on_mouse_enter: () => { this.flag_grant_hovered = true; return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { this.flag_grant_hovered = false; return RepaintMode.REPAINT_OBJECT_FULL; }, on_click: () => { this._spawn_number_edit(this._listener_grant.region.x, this._listener_grant.region.y, this._listener_grant.region.width, this._listener_grant.region.height, this.colors.permission.granted, this.granted || 0, //TODO use max assignable value? //TODO use max assignable value? //TODO use max assignable value? value => { if (typeof (value) === "number") { this.granted = value; this.request_full_draw(); this.manager.request_draw(false); if (this.on_grant_change) this.on_grant_change(); } }); return RepaintMode.REPAINT_OBJECT_FULL; }, set_full_draw: () => this.request_full_draw(), mouse_cursor: "pointer" }; this._listener_general = { region: { x: -1e8, y: -1e8, height: PermissionEntry.HEIGHT, width: 0 }, region_weight: 0, /* on_mouse_enter: () => { return RepaintMode.REPAINT_OBJECT_FULL; }, on_mouse_leave: () => { return RepaintMode.REPAINT_OBJECT_FULL; }, */ on_click: (event) => { this.manager.set_selected_entry(this); if (event.type == ClickEventType.DOUBLE && typeof (this.value) === "undefined") return this._listener_value.on_click(event); else if (event.type == ClickEventType.CONTEXT_MENU) { const mouse = this.manager.mouse; if (this.on_context_menu) { this.on_context_menu(mouse.x, mouse.y); event.consumed = true; } } return RepaintMode.NONE; }, set_full_draw: () => this.request_full_draw(), }; this.manager.intercept_manager().register_listener(this._listener_checkbox_negate); this.manager.intercept_manager().register_listener(this._listener_checkbox_skip); this.manager.intercept_manager().register_listener(this._listener_value); this.manager.intercept_manager().register_listener(this._listener_grant); this.manager.intercept_manager().register_listener(this._listener_general); } finalize() { } _spawn_number_edit(x, y, width, height, color, value, callback) { const element = $.spawn("div"); element.prop("contentEditable", true); element .css("pointer-events", "none") .css("background", color.background) .css("display", "block") .css("position", "absolute") .css("top", y) .css("left", x) .css("width", width) .css("height", height) .css("z-index", 1e6); element.text(value); element.appendTo(this.manager.canvas_container); element.focus(); element.on('focusout', event => { console.log("permission changed to " + element.text()); if (!isNaN(parseInt(element.text()))) { callback(parseInt(element.text())); } else { callback(undefined); } element.remove(); }); element.on('keypress', event => { if (event.which == KeyCode.KEY_RETURN) element.trigger('focusout'); const text = String.fromCharCode(event.which); if (isNaN(parseInt(text)) && text != "-") event.preventDefault(); if (element.text().length > 7) event.preventDefault(); }); if (window.getSelection) { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(element[0]); selection.removeAllRanges(); selection.addRange(range); } } trigger_value_assign() { this._listener_value.on_click(undefined); } trigger_grant_assign() { this._listener_grant.on_click(undefined); } } PermissionEntry.HEIGHT = PermissionGroup.HEIGHT; /* 24 */ PermissionEntry.HALF_HEIGHT = PermissionEntry.HEIGHT / 2; PermissionEntry.CHECKBOX_HEIGHT = PermissionEntry.HEIGHT - 2; PermissionEntry.COLUMN_PADDING = 2; PermissionEntry.COLUMN_VALUE = 75; PermissionEntry.COLUMN_GRANTED = 75; //public static readonly COLUMN_NEGATE = 25; //public static readonly COLUMN_SKIP = 25; PermissionEntry.COLUMN_NEGATE = 75; PermissionEntry.COLUMN_SKIP = 75; class InteractionManager { constructor() { this._listeners = []; this._entered_listeners = []; } register_listener(listener) { this._listeners.push(listener); } remove_listener(listener) { this._listeners.remove(listener); } process_mouse_move(new_x, new_y) { let _entered_listeners = []; for (const listener of this._listeners) { const aabb = listener.region; if (listener.disabled) continue; if (new_x < aabb.x || new_x > aabb.x + aabb.width) continue; if (new_y < aabb.y || new_y > aabb.y + aabb.height) continue; _entered_listeners.push(listener); } let repaint = RepaintMode.NONE; _entered_listeners.sort((a, b) => (a.region_weight || 0) - (b.region_weight || 0)); for (const listener of this._entered_listeners) { if (listener.on_mouse_leave && _entered_listeners.indexOf(listener) == -1) { let mode = listener.on_mouse_leave(); if (mode == RepaintMode.REPAINT_OBJECT_FULL) { mode = RepaintMode.REPAINT; if (listener.set_full_draw) listener.set_full_draw(); } if (mode > repaint) repaint = mode; } } for (const listener of _entered_listeners) { if (listener.on_mouse_enter && this._entered_listeners.indexOf(listener) == -1) { let mode = listener.on_mouse_enter(); if (mode == RepaintMode.REPAINT_OBJECT_FULL) { mode = RepaintMode.REPAINT; if (listener.set_full_draw) listener.set_full_draw(); } if (mode > repaint) repaint = mode; } } this._entered_listeners = _entered_listeners; let cursor; for (const listener of _entered_listeners) if (typeof (listener.mouse_cursor) === "string") { cursor = listener.mouse_cursor; } return { repaint: repaint, cursor: cursor }; } process_click_event(x, y, event) { const move_result = this.process_mouse_move(x, y); let repaint = move_result.repaint; for (const listener of this._entered_listeners) if (listener.on_click) { let mode = listener.on_click(event); if (mode == RepaintMode.REPAINT_OBJECT_FULL) { mode = RepaintMode.REPAINT; if (listener.set_full_draw) listener.set_full_draw(); } if (mode > repaint) repaint = mode; } return repaint; } process_click(x, y) { const event = { consumed: false, type: ClickEventType.SIGNLE, offset_x: x, offset_y: y }; return this.process_click_event(x, y, event); } process_dblclick(x, y) { const event = { consumed: false, type: ClickEventType.DOUBLE, offset_x: x, offset_y: y }; return this.process_click_event(x, y, event); } process_context_menu(js_event, x, y) { const event = { consumed: js_event.defaultPrevented, type: ClickEventType.CONTEXT_MENU, offset_x: x, offset_y: y }; const result = this.process_click_event(x, y, event); if (event.consumed) js_event.preventDefault(); return result; } } ui.InteractionManager = InteractionManager; class PermissionEditor { constructor(permissions) { this._max_height = 0; this._permission_count = 0; this._permission_group_count = 0; this._draw_requested = false; this._draw_requested_full = false; this._elements = []; this._permission_entry_map = {}; this.mouse = { x: 0, y: 0 }; this.grouped_permissions = permissions; this.canvas_container = $.spawn("div") .addClass("window-resize-listener") /* we want to handle resized */ .css("min-width", "750px") .css("position", "relative") .css("user-select", "none")[0]; this.canvas = $.spawn("canvas")[0]; this.canvas_container.appendChild(this.canvas); this._intersect_manager = new InteractionManager(); this.canvas_container.onmousemove = event => { this.mouse.x = event.pageX; this.mouse.y = event.pageY; const draw = this._intersect_manager.process_mouse_move(event.offsetX, event.offsetY); this.canvas_container.style.cursor = draw.cursor || ""; this._handle_repaint(draw.repaint); }; this.canvas_container.onclick = event => { this._handle_repaint(this._intersect_manager.process_click(event.offsetX, event.offsetY)); }; this.canvas_container.ondblclick = event => { this._handle_repaint(this._intersect_manager.process_dblclick(event.offsetX, event.offsetY)); }; this.canvas_container.oncontextmenu = (event) => { this._handle_repaint(this._intersect_manager.process_context_menu(event, event.offsetX, event.offsetY)); }; this.canvas_container.onresize = () => this.request_draw(true); this.initialize(); } _handle_repaint(mode) { if (mode == RepaintMode.REPAINT || mode == RepaintMode.REPAINT_FULL) this.request_draw(mode == RepaintMode.REPAINT_FULL); } request_draw(full) { this._draw_requested_full = this._draw_requested_full || full; if (this._draw_requested) return; this._draw_requested = true; requestAnimationFrame(() => { this.draw(this._draw_requested_full); }); } draw(full) { this._draw_requested = false; this._draw_requested_full = false; /* clear max height */ this.canvas_container.style.overflowY = "shown"; this.canvas_container.style.height = undefined; const max_height = this._max_height; const max_width = this.canvas_container.clientWidth; const update_width = this.canvas.width != max_width; const full_draw = typeof (full) !== "boolean" || full || update_width; if (update_width) { this.canvas.width = max_width; for (const element of this._elements) element.set_width(max_width); } console.log("Drawing%s on %dx%d", full_draw ? " full" : "", max_width, max_height); if (full_draw) this.canvas.height = max_height; const ctx = this._canvas_context; ctx.resetTransform(); if (full_draw) ctx.clearRect(0, 0, max_width, max_height); let sum_height = 0; for (const element of this._elements) { element.draw(ctx, full_draw); const height = element.height(); sum_height += height; ctx.translate(0, height); } this.canvas_container.style.overflowY = "hidden"; this.canvas_container.style.height = sum_height + "px"; } initialize() { /* setup the canvas */ { const apply_group = (group) => { for (const g of group.children || []) apply_group(g); this._permission_group_count++; this._permission_count += group.permissions.length; }; for (const group of this.grouped_permissions) apply_group(group); this._max_height = this._permission_count * PermissionEditor.PERMISSION_HEIGHT + this._permission_group_count * PermissionEditor.PERMISSION_GROUP_HEIGHT; console.log("%d permissions and %d groups required %d height", this._permission_count, this._permission_group_count, this._max_height); this.canvas.style.width = "100%"; this.canvas.style.flexShrink = "0"; this.canvas_container.style.flexShrink = "0"; this._canvas_context = this.canvas.getContext("2d"); } const font = Math.floor(2 / 3 * PermissionEntry.HEIGHT) + "px Arial"; const font_checkmark = Math.floor((5 / 4) * PermissionEntry.HEIGHT) + "px Arial"; const checkbox = { background: "#303036", background_hovered: "#CCCCCC", background_checked: "#0000AA", background_checked_hovered: "#0000AA77", border: "#000000", checkmark: "#303036", checkmark_font: font_checkmark }; const input = { color: "#000000", font: font, background_hovered: "#CCCCCCCC", background: "#30303600" }; const color_scheme = { group: { name: "#808080", name_font: font }, //#28282c permission: { name: "#808080", name_unset: "#1a1a1a", name_font: font, background: "#303036", background_selected: "#00007788", value: input, value_b: checkbox, granted: input, negate: checkbox, skip: checkbox } }; window.scheme = color_scheme; /* setup elements to draw */ { const process_group = (group) => { for (const permission of group._element_permissions.permissions) this._permission_entry_map[permission.permission().id] = permission; for (const g of group._sub_elements) process_group(g); }; for (const group of this.grouped_permissions) { const element = new PermissionGroup(group); element.set_color_scheme(color_scheme); element.set_manager(this); process_group(element); this._elements.push(element); } for (const element of this._elements) { element.initialize(); } } } intercept_manager() { return this._intersect_manager; } set_selected_entry(entry) { if (this._selected_entry === entry) return; if (this._selected_entry) { this._selected_entry.selected = false; this._selected_entry.request_full_draw(); } this._selected_entry = entry; if (this._selected_entry) { this._selected_entry.selected = true; this._selected_entry.request_full_draw(); } this.request_draw(false); } permission_entries() { return Object.keys(this._permission_entry_map).map(e => this._permission_entry_map[e]); } collapse_all() { for (const group of this._elements) group.collapse_group(); this.request_draw(true); } expend_all() { for (const group of this._elements) group.expend_group(); this.request_draw(true); } } PermissionEditor.PERMISSION_HEIGHT = PermissionEntry.HEIGHT; PermissionEditor.PERMISSION_GROUP_HEIGHT = PermissionGroup.HEIGHT; ui.PermissionEditor = PermissionEditor; })(ui || (ui = {})); class CanvasPermissionEditor extends Modals.AbstractPermissionEditor { constructor() { super(); /* references within the container tag */ this.permission_value_map = {}; } initialize(permissions) { this._permissions = permissions; this.entry_editor = new ui.PermissionEditor(permissions); this.build_tag(); } html_tag() { return this.container; } build_tag() { this.container = $("#tmpl_permission_editor_canvas").renderTag(); /* search for that as long we've not that much nodes */ this.mode_container_permissions = this.container.find(".container-mode-permissions"); this.mode_container_error_permission = this.container.find(".container-mode-no-permissions"); this.mode_container_unset = this.container.find(".container-mode-unset"); this.set_mode(Modals.PermissionEditorMode.UNSET); /* the filter */ { const tag_filter_input = this.container.find(".filter-input"); const tag_filter_granted = this.container.find(".filter-granted"); tag_filter_granted.on('change', event => tag_filter_input.trigger('change')); tag_filter_input.on('keyup change', event => { let filter_mask = tag_filter_input.val(); let req_granted = tag_filter_granted.prop("checked"); for (const entry of this.entry_editor.permission_entries()) { const permission = entry.permission(); let shown = filter_mask.length == 0 || permission.name.indexOf(filter_mask) != -1; if (shown && req_granted) { const value = this.permission_value_map[permission.id]; shown = value && (value.hasValue() || value.hasGrant()); } entry.hidden = !shown; } this.entry_editor.request_draw(true); }); } /* update button */ { this.container.find(".button-update").on('click', this.trigger_update.bind(this)); } /* global context menu listener */ { this.container.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); /* TODO allow collapse and expend all */ }); } { const tag_container = this.container.find(".entry-editor-container"); tag_container.append(this.entry_editor.canvas_container); tag_container.parent().on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); contextmenu.spawn_context_menu(event.pageX, event.pageY, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.zfS9XdO_ || (_translations.zfS9XdO_ = tr("Expend all")), callback: () => this.entry_editor.expend_all() }, { type: contextmenu.MenuEntryType.ENTRY, name: _translations.Tcfl6mLz || (_translations.Tcfl6mLz = tr("Collapse all")), callback: () => this.entry_editor.collapse_all() }); }); } /* setup the permissions */ for (const entry of this.entry_editor.permission_entries()) { const permission = entry.permission(); entry.on_change = () => { const flag_remove = typeof (entry.value) !== "number"; this._listener_change(permission, { remove: flag_remove, flag_negate: entry.flag_negate, flag_skip: entry.flag_skip, value: flag_remove ? -2 : entry.value }).then(() => { if (flag_remove) { const element = this.permission_value_map[permission.id]; if (!element) return; /* This should never happen, if so how are we displaying this permission?! */ element.value = undefined; element.flag_negate = false; element.flag_skip = false; } else { const element = this.permission_value_map[permission.id] || (this.permission_value_map[permission.id] = new PermissionValue(permission)); element.value = entry.value; element.flag_skip = entry.flag_skip; element.flag_negate = entry.flag_negate; } if (permission.name === "i_icon_id") { this.icon_resolver(entry.value).then(e => { entry.set_icon_id_image(e); entry.request_full_draw(); this.entry_editor.request_draw(false); }).catch(error => { console.warn(_translations.mP58mGgk || (_translations.mP58mGgk = tr("Failed to load icon for permission editor: %o")), error); }); } entry.request_full_draw(); this.entry_editor.request_draw(false); }).catch(() => { const element = this.permission_value_map[permission.id]; entry.value = element && element.hasValue() ? element.value : undefined; entry.flag_skip = element && element.flag_skip; entry.flag_negate = element && element.flag_negate; entry.request_full_draw(); this.entry_editor.request_draw(false); }); }; entry.on_grant_change = () => { const flag_remove = typeof (entry.granted) !== "number"; this._listener_change(permission, { remove: flag_remove, granted: flag_remove ? -2 : entry.granted, }).then(() => { if (flag_remove) { const element = this.permission_value_map[permission.id]; if (!element) return; /* This should never happen, if so how are we displaying this permission?! */ element.granted_value = undefined; } else { const element = this.permission_value_map[permission.id] || (this.permission_value_map[permission.id] = new PermissionValue(permission)); element.granted_value = entry.granted; } entry.request_full_draw(); this.entry_editor.request_draw(false); }).catch(() => { const element = this.permission_value_map[permission.id]; entry.granted = element && element.hasGrant() ? element.granted_value : undefined; entry.request_full_draw(); this.entry_editor.request_draw(false); }); }; entry.on_context_menu = (x, y) => { let entries = []; if (typeof (entry.value) === "undefined") { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.lZSZQS43 || (_translations.lZSZQS43 = tr("Add permission")), callback: () => entry.trigger_value_assign() }); } else { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.Q9AfhdTW || (_translations.Q9AfhdTW = tr("Remove permission")), callback: () => { entry.value = undefined; entry.on_change(); } }); } if (typeof (entry.granted) === "undefined") { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.vFdcnsOq || (_translations.vFdcnsOq = tr("Add grant permission")), callback: () => entry.trigger_grant_assign() }); } else { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.uE7PRt7i || (_translations.uE7PRt7i = tr("Remove grant permission")), callback: () => { entry.granted = undefined; entry.on_grant_change(); } }); } entries.push(contextmenu.Entry.HR()); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.EPXyKw8w || (_translations.EPXyKw8w = tr("Expend all")), callback: () => this.entry_editor.expend_all() }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.yaxyk7HH || (_translations.yaxyk7HH = tr("Collapse all")), callback: () => this.entry_editor.collapse_all() }); entries.push(contextmenu.Entry.HR()); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.hwphI7MO || (_translations.hwphI7MO = tr("Show permission description")), callback: () => { createInfoModal(_translations.pyMqO5eg || (_translations.pyMqO5eg = tr("Permission description")), (_translations.GOZJ1o5q || (_translations.GOZJ1o5q = tr("Permission description for permission "))) + permission.name + ":
" + permission.description).open(); } }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.oJrVKMx7 || (_translations.oJrVKMx7 = tr("Copy permission name")), callback: () => { copy_to_clipboard(permission.name); } }); contextmenu.spawn_context_menu(x, y, ...entries); }; } } set_permissions(permissions) { permissions = permissions || []; this.permission_value_map = {}; for (const permission of permissions) this.permission_value_map[permission.type.id] = permission; for (const entry of this.entry_editor.permission_entries()) { const permission = entry.permission(); const value = this.permission_value_map[permission.id]; if (permission.name === "i_icon_id") { entry.set_icon_id_image(undefined); entry.on_icon_select = this.icon_selector; } if (value && value.hasValue()) { entry.value = value.value; entry.flag_skip = value.flag_skip; entry.flag_negate = value.flag_negate; if (permission.name === "i_icon_id") { this.icon_resolver(value.value).then(e => { entry.set_icon_id_image(e); entry.request_full_draw(); this.entry_editor.request_draw(false); }).catch(error => { console.warn(_translations.cBq9P5L9 || (_translations.cBq9P5L9 = tr("Failed to load icon for permission editor: %o")), error); }); } } else { entry.value = undefined; entry.flag_skip = false; entry.flag_negate = false; } if (value && value.hasGrant()) { entry.granted = value.granted_value; } else { entry.granted = undefined; } } this.entry_editor.request_draw(true); } set_mode(mode) { this.mode_container_permissions.css('display', mode == Modals.PermissionEditorMode.VISIBLE ? 'flex' : 'none'); this.mode_container_error_permission.css('display', mode == Modals.PermissionEditorMode.NO_PERMISSION ? 'flex' : 'none'); this.mode_container_unset.css('display', mode == Modals.PermissionEditorMode.UNSET ? 'block' : 'none'); if (mode == Modals.PermissionEditorMode.VISIBLE) this.entry_editor.draw(true); } update_ui() { this.entry_editor.draw(true); } set_toggle_button(callback, initial) { throw "not implemented"; } set_hidden_permissions(permissions) { //TODO: Stuff here } } pe.CanvasPermissionEditor = CanvasPermissionEditor; })(pe || (pe = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["ff9f1f09e95203c4b91e242665e830b617f2f879056e6b6bb92b91154deb8387"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["ff9f1f09e95203c4b91e242665e830b617f2f879056e6b6bb92b91154deb8387"] = "ff9f1f09e95203c4b91e242665e830b617f2f879056e6b6bb92b91154deb8387"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "mNnKmhXi", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (127,39)" }, { name: "eIdiXluN", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (209,38)" }, { name: "pXafuMz0", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (243,35)" }, { name: "CymMMUWf", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (249,35)" }, { name: "CNnWyAfz", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (266,35)" }, { name: "h2seh3NA", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (272,35)" }, { name: "z39HymaK", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (289,35)" }, { name: "V3A7waSE", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (295,35)" }, { name: "uEA6K1Gr", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (300,31)" }, { name: "okoskUbi", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (305,31)" }, { name: "VJROSIto", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (311,31)" }, { name: "bex2YiQD", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (314,33)" }, { name: "dcxxYR_b", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (315,33)" }, { name: "n3RjiSxp", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (321,31)" }, { name: "gI5Pynkj", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (517,31)" }, { name: "dr8vqd7I", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (523,31)" }, { name: "GXXzvrDW", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (530,27)" }, { name: "q5n25a7q", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (535,27)" }, { name: "dO3GqXlP", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (703,56)" }, { name: "uqljZhQI", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (813,68)" }, { name: "DC0OXrYd", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (818,67)" }, { name: "QbNs0KSO", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (821,63)" }, { name: "bjKH7Da6", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (824,60)" }, { name: "jVdioG3L", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (837,63)" }, { name: "ZcA_dMgB", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (840,59)" }, { name: "w9vA7Svd", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (853,27)" }, { name: "ArHoLzcP", path: "D:/TeaSpeak/web/shared/js/ui/modal/permission/HTMLPermissionEditor.ts (858,27)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// /* first needs the AbstractPermissionEdit */ var pe; (function (pe) { class HTMLPermission { constructor(handle, group, permission, index) { /* the "actual" values */ this._mask = 0; /* fourth bit: hidden by filer | third bit: value type | second bit: grant shown | first bit: value shown */ this.handle = handle; this.permission = permission; this.index = index; this.group = group; this.build_tag(); } static build_checkbox() { let tag, input; tag = $.spawn("label").addClass("switch").append([ input = $.spawn("input").attr("type", "checkbox"), $.spawn("span").addClass("slider").append($.spawn("div").addClass("dot")) ]); return { tag: tag, input: input }; } build_tag() { this.tag = $.spawn("div").addClass("entry permission").css('padding-left', this.index + "em").append([ this.tag_name = $.spawn("div").addClass("column-name").text(this.permission.name), this.tag_container_value = $.spawn("div").addClass("column-value"), this.tag_container_skip = $.spawn("div").addClass("column-skip"), this.tag_container_negate = $.spawn("div").addClass("column-negate"), this.tag_container_granted = $.spawn("div").addClass("column-granted") ]); if (this.permission.is_boolean()) { let value = HTMLPermission.build_checkbox(); this._tag_value = value.tag; this._tag_value_input = value.input; this._tag_value_input.on('change', event => { const value = this._tag_value_input.prop('checked') ? 1 : 0; this.handle.trigger_change(this.permission, { remove: false, value: value, flag_skip: (this.flags & 0x01) > 0, flag_negate: (this.flags & 0x02) > 0 }).then(() => { this._value = value; }).catch(error => { this._reset_value(); }); }); this._mask |= 0x04; } else { this._tag_value = $.spawn("input").addClass("number"); this._tag_value_input = this._tag_value; this._tag_value_input.on('keydown', HTMLPermission.number_filter); this._tag_value_input.on('change', event => { const str_value = this._tag_value_input.val(); const value = parseInt(str_value); if (!HTMLPermission.number_filter_re.test(str_value) || value == NaN) { console.warn(_translations.mNnKmhXi || (_translations.mNnKmhXi = tr("Failed to parse given permission value string: %s")), this._tag_value_input.val()); this._reset_value(); return; } this.handle.trigger_change(this.permission, { remove: false, value: value, flag_skip: (this.flags & 0x01) > 0, flag_negate: (this.flags & 0x02) > 0 }).then(() => { this._value = value; this._update_active_class(); }).catch(error => { this._reset_value(); }); }); } { let skip = HTMLPermission.build_checkbox(); this._tag_skip = skip.tag; this._tag_skip_input = skip.input; this._tag_skip_input.on('change', event => { const value = this._tag_skip_input.prop('checked'); this.handle.trigger_change(this.permission, { remove: false, value: this._value, flag_skip: value, flag_negate: (this.flags & 0x02) > 0 }).then(() => { if (value) this.flags |= 0x01; else this.flags &= ~0x1; this._update_active_class(); }).catch(error => { this._reset_value(); }); }); } { let negate = HTMLPermission.build_checkbox(); this._tag_negate = negate.tag; this._tag_negate_input = negate.input; this._tag_negate_input.on('change', event => { const value = this._tag_negate_input.prop('checked'); console.log("Negate value: %o", value); this.handle.trigger_change(this.permission, { remove: false, value: this._value, flag_skip: (this.flags & 0x01) > 0, flag_negate: value }).then(() => { if (value) this.flags |= 0x02; else this.flags &= ~0x2; this._update_active_class(); }).catch(error => { this._reset_value(); }); }); } { this._tag_granted = $.spawn("input").addClass("number"); this._tag_granted_input = this._tag_granted; this._tag_granted_input.on('keydown', HTMLPermission.number_filter); this._tag_granted_input.on('change', event => { const str_value = this._tag_granted_input.val(); const value = parseInt(str_value); if (!HTMLPermission.number_filter_re.test(str_value) || Number.isNaN(value)) { console.warn(_translations.eIdiXluN || (_translations.eIdiXluN = tr("Failed to parse given permission granted value string: %s")), this._tag_granted_input.val()); this._reset_value(); return; } this.handle.trigger_change(this.permission, { remove: false, granted: value }).then(() => { this._grant = value; this._update_active_class(); }).catch(error => { this._reset_grant(); }); }); } /* double click handler */ { this.tag.on('dblclick', event => this._trigger_value_assign()); } /* context menu */ { this.tag.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); let entries = []; if (typeof (this._value) === "undefined") { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.pXafuMz0 || (_translations.pXafuMz0 = tr("Add permission")), callback: () => this._trigger_value_assign() }); } else { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.CymMMUWf || (_translations.CymMMUWf = tr("Remove permission")), callback: () => { this.handle.trigger_change(this.permission, { remove: true, value: 0 }).then(() => { this.value(undefined); }).catch(error => { //We have to do nothing }); } }); } if (typeof (this._grant) === "undefined") { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.CNnWyAfz || (_translations.CNnWyAfz = tr("Add grant permission")), callback: () => this._trigger_grant_assign() }); } else { entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.h2seh3NA || (_translations.h2seh3NA = tr("Remove grant permission")), callback: () => { this.handle.trigger_change(this.permission, { remove: true, granted: 0 }).then(() => { this.granted(undefined); }).catch(error => { //We have to do nothing }); } }); } entries.push(contextmenu.Entry.HR()); if (this.group.collapsed) entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.z39HymaK || (_translations.z39HymaK = tr("Expend group")), callback: () => this.group.expend() }); else entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.V3A7waSE || (_translations.V3A7waSE = tr("Collapse group")), callback: () => this.group.collapse() }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.uEA6K1Gr || (_translations.uEA6K1Gr = tr("Expend all")), callback: () => this.handle.expend_all() }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.okoskUbi || (_translations.okoskUbi = tr("Collapse all")), callback: () => this.handle.collapse_all() }); entries.push(contextmenu.Entry.HR()); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.VJROSIto || (_translations.VJROSIto = tr("Show permission description")), callback: () => { createInfoModal(_translations.bex2YiQD || (_translations.bex2YiQD = tr("Permission description")), (_translations.dcxxYR_b || (_translations.dcxxYR_b = tr("Permission description for permission "))) + this.permission.name + ":
" + this.permission.description).open(); } }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.n3RjiSxp || (_translations.n3RjiSxp = tr("Copy permission name")), callback: () => { copy_to_clipboard(this.permission.name); } }); contextmenu.spawn_context_menu(event.pageX, event.pageY, ...entries); }); } } _trigger_value_assign() { if (typeof (this._value) === "undefined") this.value(this._grant || 1, false, false); //TODO: Use max granted value? this._tag_value_input.focus(); if (this.permission.is_boolean()) this._tag_value_input.trigger('change'); } _trigger_grant_assign() { this.granted(1); //TODO: Use max granted value? this._tag_granted_input.focus(); } hide() { this._mask &= ~0x08; for (const element of this.tag) element.style.display = 'none'; } show() { this._mask |= 0x08; for (const element of this.tag) element.style.display = 'flex'; } is_filtered() { return (this._mask & 0x10) > 0; } set_filtered(flag) { if (flag) this._mask |= 0x10; else this._mask &= ~0x10; } is_set() { return (this._mask & 0x03) > 0; } get_value() { return this._value; } value(value, skip, negate) { if (typeof value === "undefined") { this._tag_value.detach(); this._tag_negate.detach(); this._tag_skip.detach(); this._value = undefined; this.flags = 0; this._update_active_class(); this._mask &= ~0x1; return; } if ((this._mask & 0x1) == 0) { this._tag_value.appendTo(this.tag_container_value); this._tag_negate.appendTo(this.tag_container_negate); this._tag_skip.appendTo(this.tag_container_skip); this._update_active_class(); this._mask |= 0x01; } if ((this._mask & 0x04) > 0) this._tag_value_input.prop('checked', !!value); else this._tag_value_input.val(value); this._tag_skip_input.prop('checked', !!skip); this._tag_negate_input.prop('checked', !!negate); this._value = value; this.flags = (!!skip ? 0x01 : 0) | (!!negate ? 0x2 : 0); } granted(value) { if (typeof value === "undefined") { this._tag_granted.detach(); this._update_active_class(); this._grant = undefined; this._mask &= ~0x2; return; } if ((this._mask & 0x2) == 0) { this._mask |= 0x02; this._tag_granted.appendTo(this.tag_container_granted); this._update_active_class(); } this._tag_granted_input.val(value); this._grant = value; } reset() { this._mask &= ~0x03; this._tag_value.detach(); this._tag_negate.detach(); this._tag_skip.detach(); this._tag_granted.detach(); this._value = undefined; this._grant = undefined; this.flags = 0; const tag = this.tag[0]; tag.classList.remove("active"); } _reset_value() { if (typeof (this._value) === "undefined") { if ((this._mask & 0x1) != 0) this.value(undefined); } else { this.value(this._value, (this.flags & 0x1) > 1, (this.flags & 0x2) > 1); } } _reset_grant() { if (typeof (this._grant) === "undefined") { if ((this._mask & 0x2) != 0) this.granted(undefined); } else { this.granted(this._grant); } } _update_active_class() { const value = typeof (this._value) !== "undefined" || typeof (this._grant) !== "undefined"; const tag = this.tag[0]; if (value) tag.classList.add("active"); else tag.classList.remove("active"); } } HTMLPermission.number_filter_re = /^[-+]?([0-9]{0,9})$/; HTMLPermission.number_filter = (event) => { if (event.ctrlKey) return; const target = event.target; if (event.key === "Enter") { target.blur(); return; } if ('keyCode' in event) { /* everything under 46 is a control key except 32 its space */ if (event.keyCode < 46 && event.keyCode != 32) return; if (!HTMLPermission.number_filter_re.test(target.value + String.fromCharCode(event.keyCode))) { event.preventDefault(); return; } } else { const e = event; /* for some reason typescript deducts the event type to "never" */ if (!HTMLPermission.number_filter_re.test(e.key)) { e.preventDefault(); return; } } }; class HTMLPermissionGroup { constructor(handle, group, index) { this.permissions = []; this.children = []; this.handle = handle; this.group = group; this.index = index; this._build_tag(); } _build_tag() { this.tag = $.spawn("div").addClass("entry group").css('padding-left', this.index + "em").append([ $.spawn("div").addClass("column-name").append([ this._tag_arrow = $.spawn("div").addClass("arrow down"), $.spawn("div").addClass("group-name").text(this.group.name) ]), $.spawn("div").addClass("column-value"), $.spawn("div").addClass("column-skip"), $.spawn("div").addClass("column-negate"), $.spawn("div").addClass("column-granted") ]); this.tag.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); const entries = []; if (this.collapsed) entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.gI5Pynkj || (_translations.gI5Pynkj = tr("Expend group")), callback: () => this.expend(), }); else entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.dr8vqd7I || (_translations.dr8vqd7I = tr("Collapse group")), callback: () => this.collapse(), }); entries.push(contextmenu.Entry.HR()); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.GXXzvrDW || (_translations.GXXzvrDW = tr("Expend all")), callback: () => this.handle.expend_all() }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.q5n25a7q || (_translations.q5n25a7q = tr("Collapse all")), callback: () => this.handle.collapse_all() }); contextmenu.spawn_context_menu(event.pageX, event.pageY, ...entries); }); this._tag_arrow.on('click', event => { if (this.collapsed) this.expend(); else this.collapse(); }); } update_visibility() { let flag = false; if (!flag) { for (const group of this.children) { if (group.visible) { flag = true; break; } } } if (!flag) { for (const permission of this.permissions) { if (!permission.is_filtered()) { flag = true; break; } } } this.visible = flag; flag = flag && !this.parent_collapsed; for (const element of this.tag) element.style.display = flag ? 'flex' : 'none'; const arrow_node = this._tag_arrow[0]; arrow_node.classList.remove(this.collapsed ? "down" : "right"); arrow_node.classList.add(!this.collapsed ? "down" : "right"); } collapse() { this.collapsed = true; const children = [...this.children]; while (true) { const child = children.pop(); if (!child) break; child.parent_collapsed = true; children.push(...child.children); } this.handle.update_view(); } expend() { this.collapsed = false; if (this.parent_collapsed) return; const children = [...this.children]; while (true) { const child = children.pop(); if (!child) break; child.parent_collapsed = false; if (!child.collapsed) children.push(...child.children); } this.handle.update_view(); } } class HTMLPermissionEditor extends Modals.AbstractPermissionEditor { constructor() { super(); } initialize(permissions) { this._permissions = permissions; this.build_tag(); } set_hidden_permissions(permissions) { this.hidden_permissions = permissions; this.update_filter(); } update_filter() { const value = this.filter_input.val().toLowerCase(); const grant = !!this.filter_grant.prop('checked'); const _filter = (permission) => { if (value && permission.permission.name.indexOf(value) == -1) return false; if (grant && !permission.is_set()) return false; if (this.hidden_permissions && this.hidden_permissions.find(e => e && e.toLocaleLowerCase() == permission.permission.name.toLowerCase())) return false; return true; }; for (let id = 1; id < this.permission_map.length; id++) { const permission = this.permission_map[id]; let flag = _filter(permission); permission.set_filtered(!flag); flag = flag && !permission.group.collapsed && !permission.group.parent_collapsed; /* hide when parent is filtered */ if (flag) permission.show(); else permission.hide(); } /* run in both directions, to update the parent visibility and the actiual visibility */ for (const group of this.permission_groups) group.update_visibility(); for (const group of this.permission_groups.slice().reverse()) group.update_visibility(); let index = 0; for (const entry of this.even_list) { if (!entry.visible()) continue; entry.set_even((index++ & 0x1) == 0); } } update_icon() { const permission = this.icon_shown ? this.permission_map.find(e => e && e.permission.name === "i_icon_id") : undefined; const icon_id = permission ? permission.get_value() : 0; const icon_node = this.container.find(".container-icon-select .icon-preview"); icon_node.children().remove(); let resolve; if (icon_id >= 0 && icon_id <= 1000) resolve = Promise.resolve(IconManager.generate_tag({ id: icon_id, url: "" })); else resolve = this.icon_resolver(permission ? permission.get_value() : 0).then(e => $(e)); resolve.then(tag => tag.appendTo(icon_node)) .catch(error => { log.error(LogCategory.PERMISSIONS, _translations.dO3GqXlP || (_translations.dO3GqXlP = tr("Failed to generate empty icon preview: %o")), error); }); } build_tag() { this.container = $("#tmpl_permission_editor_html").renderTag(); this.container.find("input").on('change', event => { $(event.target).parents(".form-group").toggleClass('is-filled', !!event.target.value); }); /* search for that as long we've not that much nodes */ this.mode_container_permissions = this.container.find(".container-mode-permissions"); this.mode_container_error_permission = this.container.find(".container-mode-no-permissions"); this.mode_container_unset = this.container.find(".container-mode-unset"); this.filter_input = this.container.find(".filter-input"); this.filter_input.on('change keyup', event => this.update_filter()); this.filter_grant = this.container.find(".filter-granted"); this.filter_grant.on('change', event => this.update_filter()); this.button_toggle = this.container.find(".button-toggle-clients"); this.button_toggle.on('click', () => { if (this._toggle_callback) this.button_toggle.text(this._toggle_callback()); }); this.container.find(".button-update").on('click', event => this.trigger_update()); /* allocate array space */ { let max_index = 0; let tmp = []; while (true) { const entry = tmp.pop(); if (!entry) break; for (const permission of entry.permissions) if (permission.id > max_index) max_index = permission.id; tmp.push(...entry.children); } this.permission_map = new Array(max_index + 1); } this.permission_groups = []; this.even_list = []; { const container_permission = this.mode_container_permissions.find(".container-permission-list .body"); const build_group = (pgroup, group, index) => { const hgroup = new HTMLPermissionGroup(this, group.group, index); hgroup.tag.appendTo(container_permission); this.even_list.push({ set_even(flag) { if (flag) hgroup.tag[0].classList.add('even'); else hgroup.tag[0].classList.remove('even'); }, visible() { return !hgroup.parent_collapsed && hgroup.visible; } }); if (pgroup) pgroup.children.push(hgroup); this.permission_groups.push(hgroup); index++; for (const child of group.children) build_group(hgroup, child, index); for (const permission of group.permissions) { const perm = new HTMLPermission(this, hgroup, permission, index); this.permission_map[perm.permission.id] = perm; perm.tag.appendTo(container_permission); hgroup.permissions.push(perm); this.even_list.push({ set_even(flag) { if (flag) perm.tag[0].classList.add('even'); else perm.tag[0].classList.remove('even'); }, visible() { return !perm.is_filtered() && !perm.group.collapsed && !perm.group.parent_collapsed; } }); } }; for (const group of this._permissions) build_group(undefined, group, 0); } { const container = this.container.find(".container-icon-select"); container.find(".button-select-icon").on('click', event => { const permission = this.permission_map.find(e => e && e.permission.name === "i_icon_id"); this.icon_selector(permission ? permission.get_value() : 0).then(id => { const permission = this.permission_map.find(e => e && e.permission.name === "i_icon_id"); if (permission) { this.trigger_change(permission.permission, { remove: false, value: id, flag_skip: false, flag_negate: false }, false).then(() => { log.debug(LogCategory.PERMISSIONS, _translations.uqljZhQI || (_translations.uqljZhQI = tr("Selected new icon %s")), id); permission.value(id, false, false); this.update_icon(); }).catch(error => { log.warn(LogCategory.PERMISSIONS, _translations.DC0OXrYd || (_translations.DC0OXrYd = tr("Failed to set icon permission within permission editor: %o")), error); }); } else { log.warn(LogCategory.PERMISSIONS, _translations.QbNs0KSO || (_translations.QbNs0KSO = tr("Failed to find icon permissions within permission editor"))); } }).catch(error => { log.error(LogCategory.PERMISSIONS, _translations.bjKH7Da6 || (_translations.bjKH7Da6 = tr("Failed to select an icon for the icon permission: %o")), error); }); }); container.find(".button-icon-remove").on('click', event => { const permission = this.permission_map.find(e => e && e.permission.name === "i_icon_id"); if (permission) { this.trigger_change(permission.permission, { remove: true, }, false).then(() => { permission.value(undefined); this.update_icon(); }).catch(error => { log.warn(LogCategory.PERMISSIONS, _translations.jVdioG3L || (_translations.jVdioG3L = tr("Failed to remove icon permission within permission editor: %o")), error); }); } else { log.warn(LogCategory.PERMISSIONS, _translations.ZcA_dMgB || (_translations.ZcA_dMgB = tr("Failed to find icon permission within permission editor"))); } }); } this.mode_container_permissions.on('contextmenu', event => { if (event.isDefaultPrevented()) return; event.preventDefault(); const entries = []; entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.w9vA7Svd || (_translations.w9vA7Svd = tr("Expend all")), callback: () => this.expend_all() }); entries.push({ type: contextmenu.MenuEntryType.ENTRY, name: _translations.ArHoLzcP || (_translations.ArHoLzcP = tr("Collapse all")), callback: () => this.collapse_all() }); contextmenu.spawn_context_menu(event.pageX, event.pageY, ...entries); }); this.set_mode(Modals.PermissionEditorMode.UNSET); } html_tag() { return this.container; } set_permissions(u_permissions) { const permissions = new Array(this.permission_map.length); /* initialize update array, boundary checks are already made by js */ for (const perm of u_permissions) permissions[perm.type.id] = perm; /* there is no permission with id 0 */ for (let id = 1; id < permissions.length; id++) { const new_permission = permissions[id]; const permission_handle = this.permission_map[id]; if (!new_permission) { permission_handle.reset(); continue; } permission_handle.value(new_permission.value, new_permission.flag_skip, new_permission.flag_negate); permission_handle.granted(new_permission.granted_value); } this.update_icon(); this.update_filter(); } set_mode(mode) { this.mode_container_permissions.css('display', mode == Modals.PermissionEditorMode.VISIBLE ? 'flex' : 'none'); this.mode_container_error_permission.css('display', mode == Modals.PermissionEditorMode.NO_PERMISSION ? 'flex' : 'none'); this.mode_container_unset.css('display', mode == Modals.PermissionEditorMode.UNSET ? 'block' : 'none'); if (this.icon_shown != (mode == Modals.PermissionEditorMode.VISIBLE)) { this.icon_shown = mode == Modals.PermissionEditorMode.VISIBLE; this.update_icon(); } } trigger_change(permission, value, update_icon) { if (this._listener_change) { if ((typeof (update_icon) !== "boolean" || update_icon) && permission && permission.name === "i_icon_id") return this._listener_change(permission, value).then(e => { setTimeout(() => this.update_icon(), 0); /* we need to fully handle the response and then only we're able to update the icon */ return e; }); else return this._listener_change(permission, value); } return Promise.reject(); } collapse_all() { for (const group of this.permission_groups) { group.collapsed = true; for (const child of group.children) child.parent_collapsed = true; } this.update_filter(); /* update display state of all entries */ } expend_all() { for (const group of this.permission_groups) { group.collapsed = false; group.parent_collapsed = false; } this.update_filter(); /* update display state of all entries */ } update_view() { return this.update_filter(); } set_toggle_button(callback, initial) { this._toggle_callback = callback; if (this._toggle_callback) { this.button_toggle.text(initial); this.button_toggle.show(); } else { this.button_toggle.hide(); } } } pe.HTMLPermissionEditor = HTMLPermissionEditor; })(pe || (pe = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["c3f77abe415be432cfd830b2810233936c398e3aacff06ea939745caaa7b782e"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["c3f77abe415be432cfd830b2810233936c398e3aacff06ea939745caaa7b782e"] = "c3f77abe415be432cfd830b2810233936c398e3aacff06ea939745caaa7b782e"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } /// var permissions; (function (permissions) { permissions.senseless_server_group_permissions = [ PermissionType.B_CHANNEL_GROUP_INHERITANCE_END ]; const filter = (text, ignore_type) => Object.keys(PermissionType) .filter(e => e.toLowerCase().substr(ignore_type ? 1 : 0).startsWith(text)).map(e => PermissionType[e]); permissions.senseless_channel_group_permissions = [ //Not sensefull to assign serverinstance permission to channel groups ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_serverinstance_")).map(e => PermissionType[e]), PermissionType.B_SERVERQUERY_LOGIN, //Not sensefull to assign virtual server permission to channel groups ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_virtualserver") && e.toLowerCase() === "b_virtualserver_channel_permission_list").map(e => PermissionType[e]), //Not sensefull to require some playlist permissions ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("i_playlist")).map(e => PermissionType[e]), PermissionType.B_PLAYLIST_CREATE, //Not sensefull to require some playlist permissions ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("i_client_music")).map(e => PermissionType[e]), ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_client_music")).map(e => PermissionType[e]), ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("i_server_group")).map(e => PermissionType[e]), PermissionType.I_MAX_ICON_FILESIZE, PermissionType.I_MAX_PLAYLIST_SIZE, PermissionType.I_MAX_PLAYLISTS, PermissionType.I_CLIENT_KICK_FROM_SERVER_POWER, PermissionType.I_CLIENT_NEEDED_KICK_FROM_SERVER_POWER, PermissionType.I_CLIENT_BAN_POWER, PermissionType.I_CLIENT_NEEDED_BAN_POWER, ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_client_complain")).map(e => PermissionType[e]), ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_client_ban")).map(e => PermissionType[e]), PermissionType.I_CLIENT_BAN_MAX_BANTIME, PermissionType.B_CLIENT_SERVER_TEXTMESSAGE_SEND, ...Object.keys(PermissionType).filter(e => e.toLowerCase().startsWith("b_client_query")).map(e => PermissionType[e]), PermissionType.B_CLIENT_CREATE_MODIFY_SERVERQUERY_LOGIN, PermissionType.B_CLIENT_DELETE_DBPROPERTIES, PermissionType.B_CLIENT_MODIFY_DBPROPERTIES ]; permissions.senseless_channel_permissions = [ ...permissions.senseless_channel_group_permissions, ...filter("_channel_create", true), ...filter("_client", true), ...filter("_channel_group", true), ...filter("_group", true), ...filter("b_channel_", false), ...Object.keys(PermissionType).filter(e => { e = e.toLowerCase(); return e.indexOf("_power") > 0 && e.indexOf("_needed_") == -1; }).map(e => PermissionType[e]), PermissionType.B_ICON_MANAGE, PermissionType.B_CLIENT_USE_PRIORITY_SPEAKER, PermissionType.B_CLIENT_USE_PRIORITY_SPEAKER, PermissionType.B_CHANNEL_IGNORE_DESCRIPTION_VIEW_POWER ]; permissions.senseless_client_permissions = []; permissions.senseless_client_channel_permissions = []; })(permissions || (permissions = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["27c1036c60874525f05c5900623d88fc60a288957a6b0b374d296c90f747c966"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["27c1036c60874525f05c5900623d88fc60a288957a6b0b374d296c90f747c966"] = "27c1036c60874525f05c5900623d88fc60a288957a6b0b374d296c90f747c966"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of []) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } var audio; (function (audio) { let recorder; (function (recorder) { let InputConsumerType; (function (InputConsumerType) { InputConsumerType[InputConsumerType["CALLBACK"] = 0] = "CALLBACK"; InputConsumerType[InputConsumerType["NODE"] = 1] = "NODE"; InputConsumerType[InputConsumerType["NATIVE"] = 2] = "NATIVE"; })(InputConsumerType = recorder.InputConsumerType || (recorder.InputConsumerType = {})); let filter; (function (filter) { let Type; (function (Type) { Type[Type["THRESHOLD"] = 0] = "THRESHOLD"; Type[Type["VOICE_LEVEL"] = 1] = "VOICE_LEVEL"; Type[Type["STATE"] = 2] = "STATE"; })(Type = filter.Type || (filter.Type = {})); })(filter = recorder.filter || (recorder.filter = {})); let InputState; (function (InputState) { InputState[InputState["PAUSED"] = 0] = "PAUSED"; InputState[InputState["INITIALIZING"] = 1] = "INITIALIZING"; InputState[InputState["RECORDING"] = 2] = "RECORDING"; InputState[InputState["DRY"] = 3] = "DRY"; })(InputState = recorder.InputState || (recorder.InputState = {})); let InputStartResult; (function (InputStartResult) { InputStartResult["EOK"] = "eok"; InputStartResult["EUNKNOWN"] = "eunknown"; InputStartResult["EBUSY"] = "ebusy"; InputStartResult["ENOTALLOWED"] = "enotallowed"; InputStartResult["ENOTSUPPORTED"] = "enotsupported"; })(InputStartResult = recorder.InputStartResult || (recorder.InputStartResult = {})); })(recorder = audio.recorder || (audio.recorder = {})); })(audio || (audio = {})); typeof _translations !== "undefined" || (_translations = {}); _translations["declared"] = _translations["declared"] || (_translations["declared"] = {}); _translations["declared_files"] = _translations["declared_files"] || (_translations["declared_files"] = {}); unique_translation_check: { if (_translations["declared_files"]["40c0a0ccf3b451cbca3133f589b3c49ad1383cc1a1064fb3e33f50b1892dfdfc"] !== undefined) { console.warn("This file has already been loaded!\nAre you executing scripts twice?"); break unique_translation_check; } else _translations["declared_files"]["40c0a0ccf3b451cbca3133f589b3c49ad1383cc1a1064fb3e33f50b1892dfdfc"] = "40c0a0ccf3b451cbca3133f589b3c49ad1383cc1a1064fb3e33f50b1892dfdfc"; /*Auto generated helper for testing if the translation keys are unique*/ for (var { name: _i, path: _a } of [{ name: "A6UWPV3j", path: "D:/TeaSpeak/web/shared/js/voice/RecorderProfile.ts (134,41)" }, { name: "oKaNjzJq", path: "D:/TeaSpeak/web/shared/js/voice/RecorderProfile.ts (138,46)" }, { name: "WZgGQyvw", path: "D:/TeaSpeak/web/shared/js/voice/RecorderProfile.ts (189,45)" }]) { if (_translations["declared"][_i] !== undefined) throw "Translation with generated name \"" + _i + "\" already exists!\nIt has been already defined here: " + _translations["declared"][_i] + "\nAttempted to redefine here: " + _a + "\nRegenerate and/or fix your program!"; else _translations["declared"][_i] = _a; } } let default_recorder; /* needs initialize */ class RecorderProfile { constructor(name, volatile) { this.name = name; this.volatile = typeof (volatile) === "boolean" ? volatile : false; this._ppt_hook = { callback_release: () => { if (this._ppt_timeout) clearTimeout(this._ppt_timeout); this._ppt_timeout = setTimeout(() => { const filter = this.input.get_filter(audio.recorder.filter.Type.STATE); if (filter) filter.set_state(true); }, Math.min(this.config.vad_push_to_talk.delay, 0)); }, callback_press: () => { if (this._ppt_timeout) clearTimeout(this._ppt_timeout); const filter = this.input.get_filter(audio.recorder.filter.Type.STATE); if (filter) filter.set_state(false); }, cancel: false }; this._ppt_hook_registered = false; this.record_supported = true; } initialize() { return __awaiter(this, void 0, void 0, function* () { audio.player.on_ready(() => __awaiter(this, void 0, void 0, function* () { this.initialize_input(); yield this.load(); yield this.reinitialize_filter(); })); }); } initialize_input() { this.input = audio.recorder.create_input(); this.input.callback_begin = () => { log.debug(LogCategory.VOICE, "Voice start"); if (this.callback_start) this.callback_start(); }; this.input.callback_end = () => { log.debug(LogCategory.VOICE, "Voice end"); if (this.callback_stop) this.callback_stop(); }; } load() { return __awaiter(this, void 0, void 0, function* () { const config = settings.static_global(Settings.FN_PROFILE_RECORD(this.name), {}); /* default values */ this.config = { version: 1, device_id: undefined, volume: 100, vad_threshold: { threshold: 50 }, vad_type: "threshold", vad_push_to_talk: { delay: 300, key_alt: false, key_ctrl: false, key_shift: false, key_windows: false, key_code: 't' } }; Object.assign(this.config, config || {}); this.input.set_volume(this.config.volume / 100); { const all_devices = audio.recorder.devices(); const devices = all_devices.filter(e => e.default_input || e.unique_id === this.config.device_id); const device = devices.find(e => e.unique_id === this.config.device_id) || devices[0]; log.info(LogCategory.VOICE, _translations.A6UWPV3j || (_translations.A6UWPV3j = tr("Loaded record profile device %s | %o (%o)")), this.config.device_id, device, all_devices); try { yield this.input.set_device(device); } catch (error) { log.error(LogCategory.VOICE, _translations.oKaNjzJq || (_translations.oKaNjzJq = tr("Failed to set input device (%o)")), error); } } }); } save(enforce) { if (enforce || !this.volatile) settings.changeGlobal(Settings.FN_PROFILE_RECORD(this.name), this.config); } reinitialize_filter() { return __awaiter(this, void 0, void 0, function* () { if (!this.input) return; this.input.clear_filter(); if (this._ppt_hook_registered) { ppt.unregister_key_hook(this._ppt_hook); this._ppt_hook_registered = false; } if (this.config.vad_type === "threshold") { const filter = this.input.get_filter(audio.recorder.filter.Type.THRESHOLD); yield filter.set_threshold(this.config.vad_threshold.threshold); yield filter.set_margin_frames(10); /* 500ms */ /* legacy client support */ if ('set_attack_smooth' in filter) filter.set_attack_smooth(.25); if ('set_release_smooth' in filter) filter.set_release_smooth(.9); this.input.enable_filter(audio.recorder.filter.Type.THRESHOLD); } else if (this.config.vad_type === "push_to_talk") { const filter = this.input.get_filter(audio.recorder.filter.Type.STATE); yield filter.set_state(true); for (const key of ["key_alt", "key_ctrl", "key_shift", "key_windows", "key_code"]) this._ppt_hook[key] = this.config.vad_push_to_talk[key]; ppt.register_key_hook(this._ppt_hook); this._ppt_hook_registered = true; this.input.enable_filter(audio.recorder.filter.Type.STATE); } else if (this.config.vad_type === "active") { } }); } unmount() { return __awaiter(this, void 0, void 0, function* () { if (this.callback_unmount) this.callback_unmount(); if (this.input) { try { yield this.input.set_consumer(undefined); } catch (error) { log.warn(LogCategory.VOICE, _translations.WZgGQyvw || (_translations.WZgGQyvw = tr("Failed to unmount input consumer for profile (%o)")), error); } } this.callback_start = undefined; this.callback_stop = undefined; this.callback_unmount = undefined; this.current_handler = undefined; }); } get_vad_type() { return this.config.vad_type; } set_vad_type(type) { if (this.config.vad_type === type) return true; if (["push_to_talk", "threshold", "active"].findIndex(e => e === type) == -1) return false; this.config.vad_type = type; this.reinitialize_filter(); this.save(); return true; } get_vad_threshold() { return parseInt(this.config.vad_threshold.threshold); } /* for some reason it might be a string... */ set_vad_threshold(value) { if (this.config.vad_threshold.threshold === value) return; this.config.vad_threshold.threshold = value; this.reinitialize_filter(); this.save(); } get_vad_ppt_key() { return this.config.vad_push_to_talk; } set_vad_ppt_key(key) { for (const _key of ["key_alt", "key_ctrl", "key_shift", "key_windows", "key_code"]) this.config.vad_push_to_talk[_key] = key[_key]; this.reinitialize_filter(); this.save(); } get_vad_ppt_delay() { return this.config.vad_push_to_talk.delay; } set_vad_ppt_delay(value) { if (this.config.vad_push_to_talk.delay === value) return; this.config.vad_push_to_talk.delay = value; this.reinitialize_filter(); this.save(); } current_device() { return this.input.current_device(); } set_device(device) { this.config.device_id = device ? device.unique_id : undefined; this.save(); return this.input.set_device(device); } get_volume() { return this.input ? (this.input.get_volume() * 100) : this.config.volume; } set_volume(volume) { if (this.config.volume === volume) return; this.config.volume = volume; this.input && this.input.set_volume(volume / 100); this.save(); } } //# sourceMappingURL=shared.js.map //# sourceMappingURL=client.js.map