-
-
-
\ No newline at end of file
diff --git a/html/js/authentication.js b/html/js/authentication.js
deleted file mode 100644
index 581700b..0000000
--- a/html/js/authentication.js
+++ /dev/null
@@ -1,42 +0,0 @@
-function createFirstAccount(elm) {
- var err = false;
- var div = document.getElementById(elm);
- console.log(div);
-
- var form = document.getElementById('authentication');
-
- const username = document.getElementById('username');
- const password = document.getElementById('password');
- const confirm = document.getElementById('confirm');
-
- var inputs = div.getElementsByTagName('INPUT')
- console.log(confirm);
-
- switch(confirm) {
- case null: break;
-
- default:
- for (var i = 0; i < inputs.length; i++) {
- if (inputs[i].value.length == 0) {
- inputs[i].style.borderColor = 'red';
- err = true
- }
- }
-
- switch(err) {
- case true: return; break;
- case false:
- if (password.value != confirm.value) {
- confirm.style.borderColor = 'red';
- return;
- }
- break;
- }
- }
-
-
-
-
- form.submit();
- return;
-}
\ No newline at end of file
diff --git a/html/js/authentication_ts.js b/html/js/authentication_ts.js
deleted file mode 100644
index f708119..0000000
--- a/html/js/authentication_ts.js
+++ /dev/null
@@ -1,32 +0,0 @@
-function login() {
- var err = false;
- var data = new Object();
- var div = document.getElementById("content");
- var form = document.getElementById("authentication");
- var inputs = div.getElementsByTagName("INPUT");
- console.log(inputs);
- for (var i = inputs.length - 1; i >= 0; i--) {
- var key = inputs[i].name;
- var value = inputs[i].value;
- if (value.length == 0) {
- inputs[i].style.borderColor = "red";
- err = true;
- }
- data[key] = value;
- }
- if (err == true) {
- data = new Object();
- return;
- }
- if (data.hasOwnProperty("confirm")) {
- if (data["confirm"] != data["password"]) {
- alert("sdafsd");
- document.getElementById('password').style.borderColor = "red";
- document.getElementById('confirm').style.borderColor = "red";
- document.getElementById("err").innerHTML = "{{.account.failed}}";
- return;
- }
- }
- console.log(data);
- form.submit();
-}
diff --git a/html/js/base.js b/html/js/base.js
deleted file mode 100644
index ebc2f66..0000000
--- a/html/js/base.js
+++ /dev/null
@@ -1,331 +0,0 @@
-var config = new Object();
-var menu = new Object();
-var subMenu = new Object();
-var activeStreams = new Object();
-var xEPG = new Object();
-var users = new Object();
-var log = new Object();
-var undo = new Object();
-var webSockets = true;
-var closeLog, version, activeMenu;
-var columnToSort = 0
-
-
-if (window.WebSocket === undefined) {
- alert("Your browser does not support WebSockets");
- webSockets = false;
-}
-
-function pageReady() {
- var data = new Object();
- data["cmd"] = "getServerConfig";
- xTeVe(data);
- //showLoadingScreen(false);
-
- var resizeHandle = document.getElementById("openStreams");
- var box = document.getElementById("myStreamsBox");
- resizeHandle.addEventListener("mousedown", initialiseResize, false);
-
- function initialiseResize(e) {
- window.addEventListener("mousemove", startResizing, false);
- window.addEventListener("mouseup", stopResizing, false);
- }
-
- function startResizing(e) {
- box.style.height = (e.clientY - box.offsetTop) + "px";
-
- var elm = document.getElementById("allStreams");
- if (e.clientY > 120) {
- elm.className = "visible";
- } else {
- elm.className = "notVisible";
- }
-
- calculateWrapperHeight();
-
- }
- function stopResizing(e) {
- window.removeEventListener('mousemove', startResizing, false);
- window.removeEventListener('mouseup', stopResizing, false);
- calculateWrapperHeight();
- }
-
- window.addEventListener("resize", function(){
- calculateWrapperHeight();
- }, true);
-}
-
-
-function getObjKeys(obj) {
- var keys = new Array();
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- keys.push(i);
- }
- }
-
- return keys;
-}
-
-
-function createElement(item) {
- //console.log(item);
- var element = document.createElement(item["_element"]);
- if (item.hasOwnProperty("_text")) {
- //element.innerHTML = "
" + item["_text"] + "
";
- element.innerHTML = item["_text"];
- }
-
- var keys = getObjKeys(item);
- for (var i = 0; i < keys.length; i++) {
- if (keys[i].charAt(0) != "_") {
- //console.log(keys[i], item[keys[i]]);
- element.setAttribute(keys[i], item[keys[i]]);
- }
- }
-
- //console.log(element);
- return element;
-}
-
-function modifyOption(id, options, values) {
- var select = document.getElementById(id);
- select.innerHTML = "";
-
- for (var i = 0; i < options.length; i++) {
-
- var element = document.createElement("OPTION")
-
- element.value = values[i];
- element.innerHTML = options[i];
-
- document.getElementById(id).appendChild(element);
-
- }
-
-}
-
-
-function startWebSocket() {
- if (webSockets == false) {
- return;
- }
-
- //ws.send('{"cmd": "getServerConfig1"}');
-
-}
-
-function checkErr(obj) {
- //alert(obj["err"])
- //screenLog(obj["err"], "error")
- console.log(obj);
- var newObj = new Object();
- var newErr = new Object();
- newErr["key"] = "Error";
- newErr["value"] = obj["err"];
- newErr["type"] = "error";
-
- newObj[0] = newErr
- showLog(newObj);
- return
-}
-
-function screenLog(msg, msgType, show) {
- return
- clearTimeout(closeLog)
- var div = document.getElementById("screenLog");
- var newMsg = new Object();
-
- newMsg["_element"] = "P";
-
- switch(msgType) {
- case "error": newMsg["class"] = "errorMsg"; break;
- case "warning": newMsg["class"] = "warningMsg"; break;
- //default: newMsg["class"] = "infoMsg"
- }
-
- newMsg["_text"] = msg;
-
- div.appendChild(createElement(newMsg));
-
- div.scrollTop = div.scrollHeight;
-
- if (show == false) {
- return;
- }
-
- div.className = ""
- closeLog = setTimeout(closeScreenLog, 10000);
-}
-
-
-function closeScreenLog() {
- var div = document.getElementById("screenLog");
- div.className = "screenLogHidden"
-}
-
-function showScreenLog() {
- clearTimeout(closeLog)
- var div = document.getElementById("screenLog");
- var currentClass = div.className;
- div.className = "screenLogHidden"
-
- switch(currentClass) {
- case "screenLogHidden": div.className = ""; break;
- case "": div.className = "screenLogHidden"; break;
- }
-}
-
-function showLoadingScreen(elm) {
- var div = document.getElementById("loading");
- switch(elm) {
- case true: div.className = "block"; break;
- case false: div.className = "none"; break;
-
- /*
- case true: div.style.display = "block"; break;
- case false: div.style.display = "none"; break;
- */
- }
-}
-
-function createClintInfo(obj) {
- //console.log(obj);
- var keys = getObjKeys(obj);
- for (var i = 0; i < keys.length; i++) {
- if(document.getElementById(keys[i])){
- document.getElementById(keys[i]).innerHTML = obj[keys[i]];
- }
- }
- //document.getElementById("clientInfo").className = "visible";
-}
-
-function showElement(elmID, type) {
- switch(type) {
- case true: cssClass = "block"; break;
- case false: cssClass = "none"; break;
- }
-
- document.getElementById(elmID).className = cssClass;
-}
-
-function showPopUpElement(elm) {
- var allElements = new Array("deleteUserDetail", "mapping-detail", "user-detail", "file-detail");
-
- for (var i = 0; i < allElements.length; i++) {
- showElement(allElements[i], false)
- }
-
- showElement(elm, true)
-
- setTimeout(function(){
- showElement("popup", true);
- }, 10);
-}
-
- // body...
-
-function showStreams(force) {
-
- var elmBox = document.getElementById("myStreamsBox");
- var elm = document.getElementById("allStreams");
- //console.log(elm);
- show = elm.className;
-
- switch(force) {
- case true: show = "notVisible"; break;
- case false: show = "visible"; break;
- }
-
- switch(show) {
- case "notVisible":
- elm.className = "visible";
- elmBox.style.height = "100px";
- break;
-
- default:
- elm.className = "notVisible";
- elmBox.style.height = "20px";
- break;
- }
-
- var show = elm.style.display; {
- //console.log(elm.style.display);
- }
-
- calculateWrapperHeight();
-}
-
-function xteveBackup() {
- console.log("xteveBackup");
- var data = new Object();
- data["cmd"] = "xteveBackup";
-
- xTeVe(data);
-}
-
-function xteveRestore(elm) {
- var restore = document.createElement("INPUT");
- restore.setAttribute("type", "file");
- restore.setAttribute("class", "notVisible");
- restore.setAttribute("name", "");
- restore.id = "upload";
-
- document.body.appendChild(restore);
- restore.click();
-
- restore.onchange = function() {
- var filename = restore.files[0].name
- //console.log(restore.srcElement.files[0]);
- var check = confirm("File: " + filename + "\nAll data will be replaced with those from the backup.\nShould the files be restored?");
- if (check == true) {
- var reader = new FileReader();
- var file = document.querySelector('input[type=file]').files[0];
- if (file) {
- reader.readAsDataURL(file);
- reader.onload = function() {
- console.log(reader.result);
- var data = new Object();
- data["cmd"] = "xteveRestore"
- data["base64"] = reader.result
-
- xTeVe(data);
- return
- };
- } else {
- alert("File could not be loaded")
- }
- }
- };
-}
-
-function getBase64(file) {
- var reader = new FileReader();
- reader.readAsDataURL(file);
- reader.onload = function() {
- console.log(reader.result);
- };
- reader.onerror = function(error) {
- console.log('Error: ', error);
- };
-}
-
-function logout() {
- document.cookie.split(';').forEach(function(c) {
- document.cookie = c.trim().split('=')[0] + '=;' + 'expires=Thu, 01 Jan 1970 00:00:00 UTC;';
- });
- location.reload();
-}
-
-function getCookie(name) {
- var value = "; " + document.cookie;
- var parts = value.split("; " + name + "=");
- if (parts.length == 2) return parts.pop().split(";").shift();
-}
-
-function setCookie(token) {
- //console.log(token);
- document.cookie = "Token=" + token
-}
-
diff --git a/html/js/base_ts.js b/html/js/base_ts.js
deleted file mode 100644
index 17ea2ac..0000000
--- a/html/js/base_ts.js
+++ /dev/null
@@ -1,481 +0,0 @@
-var SERVER = new Object();
-var BULK_EDIT = false;
-var COLUMN_TO_SORT;
-var SEARCH_MAPPING = new Object();
-var UNDO = new Object();
-var SERVER_CONNECTION = false;
-var WS_AVAILABLE = false;
-// Menü
-var menuItems = new Array();
-menuItems.push(new MainMenuItem("playlist", "{{.mainMenu.item.playlist}}", "m3u.png", "{{.mainMenu.headline.playlist}}"));
-//menuItems.push(new MainMenuItem("pmsID", "{{.mainMenu.item.pmsID}}", "number.png", "{{.mainMenu.headline.pmsID}}"))
-menuItems.push(new MainMenuItem("filter", "{{.mainMenu.item.filter}}", "filter.png", "{{.mainMenu.headline.filter}}"));
-menuItems.push(new MainMenuItem("xmltv", "{{.mainMenu.item.xmltv}}", "xmltv.png", "{{.mainMenu.headline.xmltv}}"));
-menuItems.push(new MainMenuItem("mapping", "{{.mainMenu.item.mapping}}", "mapping.png", "{{.mainMenu.headline.mapping}}"));
-menuItems.push(new MainMenuItem("users", "{{.mainMenu.item.users}}", "users.png", "{{.mainMenu.headline.users}}"));
-menuItems.push(new MainMenuItem("settings", "{{.mainMenu.item.settings}}", "settings.png", "{{.mainMenu.headline.settings}}"));
-menuItems.push(new MainMenuItem("log", "{{.mainMenu.item.log}}", "log.png", "{{.mainMenu.headline.log}}"));
-menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}"));
-// Kategorien für die Einstellungen
-var settingsCategory = new Array();
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"));
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"));
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"));
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"));
-function showPopUpElement(elm) {
- var allElements = new Array("popup-custom");
- for (var i = 0; i < allElements.length; i++) {
- showElement(allElements[i], false);
- }
- showElement(elm, true);
- setTimeout(function () {
- showElement("popup", true);
- }, 10);
- return;
-}
-function showElement(elmID, type) {
- var cssClass;
- switch (type) {
- case true:
- cssClass = "block";
- break;
- case false:
- cssClass = "none";
- break;
- }
- document.getElementById(elmID).className = cssClass;
-}
-function changeButtonAction(element, buttonID, attribute) {
- var value = element.options[element.selectedIndex].value;
- document.getElementById(buttonID).setAttribute(attribute, value);
-}
-function getLocalData(dataType, id) {
- var data = new Object();
- switch (dataType) {
- case "m3u":
- data = SERVER["settings"]["files"][dataType][id];
- break;
- case "hdhr":
- data = SERVER["settings"]["files"][dataType][id];
- break;
- case "filter":
- case "custom-filter":
- case "group-title":
- if (id == -1) {
- data["active"] = true;
- data["caseSensitive"] = false;
- data["description"] = "";
- data["exclude"] = "";
- data["filter"] = "";
- data["include"] = "";
- data["name"] = "";
- data["type"] = "group-title";
- SERVER["settings"]["filter"][id] = data;
- }
- data = SERVER["settings"]["filter"][id];
- break;
- case "xmltv":
- data = SERVER["settings"]["files"][dataType][id];
- break;
- case "users":
- data = SERVER["users"][id]["data"];
- break;
- case "mapping":
- data = SERVER["xepg"]["epgMapping"][id];
- break;
- case "m3uGroups":
- data = SERVER["data"]["playlist"]["m3u"]["groups"];
- break;
- }
- return data;
-}
-function getObjKeys(obj) {
- var keys = new Array();
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- keys.push(i);
- }
- }
- return keys;
-}
-function getAllSelectedChannels() {
- var channels = new Array();
- if (BULK_EDIT == false) {
- return channels;
- }
- var trs = document.getElementById("content_table").getElementsByTagName("TR");
- for (var i = 1; i < trs.length; i++) {
- if (trs[i].style.display != "none") {
- if (trs[i].firstChild.firstChild.checked == true) {
- channels.push(trs[i].id);
- }
- }
- }
- return channels;
-}
-function selectAllChannels() {
- var bulk = false;
- var trs = document.getElementById("content_table").getElementsByTagName("TR");
- if (trs[0].firstChild.firstChild.checked == true) {
- bulk = true;
- }
- for (var i = 1; i < trs.length; i++) {
- if (trs[i].style.display != "none") {
- switch (bulk) {
- case true:
- trs[i].firstChild.firstChild.checked = true;
- break;
- case false:
- trs[i].firstChild.firstChild.checked = false;
- break;
- }
- }
- }
- return;
-}
-function bulkEdit() {
- BULK_EDIT = !BULK_EDIT;
- var className;
- var rows = document.getElementsByClassName("bulk");
- switch (BULK_EDIT) {
- case true:
- className = "bulk showBulk";
- break;
- case false:
- className = "bulk hideBulk";
- break;
- }
- for (var i = 0; i < rows.length; i++) {
- rows[i].className = className;
- rows[i].checked = false;
- }
- return;
-}
-function sortTable(column) {
- //console.log(columm);
- if (column == COLUMN_TO_SORT) {
- return;
- }
- var table = document.getElementById("content_table");
- var tableHead = table.getElementsByTagName("TR")[0];
- var tableItems = tableHead.getElementsByTagName("TD");
- var sortObj = new Object();
- var x, xValue;
- var tableHeader;
- var sortByString = false;
- if (column > 0 && COLUMN_TO_SORT > 0) {
- tableItems[COLUMN_TO_SORT].className = "pointer";
- tableItems[column].className = "sortThis";
- }
- COLUMN_TO_SORT = column;
- var rows = table.rows;
- if (rows[1] != undefined) {
- tableHeader = rows[0];
- x = rows[1].getElementsByTagName("TD")[column];
- for (i = 1; i < rows.length; i++) {
- x = rows[i].getElementsByTagName("TD")[column];
- switch (x.childNodes[0].tagName.toLowerCase()) {
- case "input":
- xValue = x.getElementsByTagName("INPUT")[0].value.toLowerCase();
- break;
- case "p":
- xValue = x.getElementsByTagName("P")[0].innerText.toLowerCase();
- break;
- default: console.log(x.childNodes[0].tagName);
- }
- if (xValue == "" || xValue == NaN) {
- xValue = i;
- sortObj[i] = rows[i];
- }
- else {
- switch (isNaN(xValue)) {
- case false:
- xValue = parseFloat(xValue);
- sortObj[xValue] = rows[i];
- break;
- case true:
- sortByString = true;
- sortObj[xValue.toLowerCase() + i] = rows[i];
- break;
- }
- }
- }
- while (table.firstChild) {
- table.removeChild(table.firstChild);
- }
- var sortValues = getObjKeys(sortObj);
- if (sortByString == true) {
- sortValues.sort();
- console.log(sortValues);
- }
- else {
- function sortFloat(a, b) {
- return a - b;
- }
- sortValues.sort(sortFloat);
- }
- table.appendChild(tableHeader);
- for (var i = 0; i < sortValues.length; i++) {
- table.appendChild(sortObj[sortValues[i]]);
- }
- }
- return;
-}
-function createSearchObj() {
- SEARCH_MAPPING = new Object();
- var data = SERVER["xepg"]["epgMapping"];
- var channels = getObjKeys(data);
- var channelKeys = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"];
- channels.forEach(function (id) {
- channelKeys.forEach(function (key) {
- if (key == "x-active") {
- switch (data[id][key]) {
- case true:
- SEARCH_MAPPING[id] = "online ";
- break;
- case false:
- SEARCH_MAPPING[id] = "offline ";
- break;
- }
- }
- else {
- if (key == "x-xmltv-file") {
- var xmltvFile = getValueFromProviderFile(data[id][key], "xmltv", "name");
- if (xmltvFile != undefined) {
- SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + xmltvFile + " ";
- }
- }
- else {
- SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " ";
- }
- }
- });
- });
- return;
-}
-function searchInMapping() {
- var searchValue = document.getElementById("searchMapping").value;
- var trs = document.getElementById("content_table").getElementsByTagName("TR");
- for (var i = 1; i < trs.length; ++i) {
- var id = trs[i].getAttribute("id");
- var element = SEARCH_MAPPING[id];
- switch (element.toLowerCase().includes(searchValue.toLowerCase())) {
- case true:
- document.getElementById(id).style.display = "";
- break;
- case false:
- document.getElementById(id).style.display = "none";
- break;
- }
- }
- return;
-}
-function calculateWrapperHeight() {
- if (document.getElementById("box-wrapper")) {
- var elm = document.getElementById("box-wrapper");
- var divs = new Array("myStreamsBox", "clientInfo", "content");
- var elementsHeight = 0 - elm.offsetHeight;
- for (var i = 0; i < divs.length; i++) {
- elementsHeight = elementsHeight + document.getElementById(divs[i]).offsetHeight;
- }
- elm.style.height = window.innerHeight - elementsHeight + "px";
- }
- return;
-}
-function changeChannelNumber(element) {
- var dbID = element.parentNode.parentNode.id;
- var newNumber = parseFloat(element.value);
- var channelNumbers = [];
- var data = SERVER["xepg"]["epgMapping"];
- var channels = getObjKeys(data);
- if (isNaN(newNumber)) {
- alert("{{.alert.invalidChannelNumber}}");
- return;
- }
- channels.forEach(function (id) {
- var channelNumber = parseFloat(data[id]["x-channelID"]);
- channelNumbers.push(channelNumber);
- });
- for (var i = 0; i < channelNumbers.length; i++) {
- if (channelNumbers.indexOf(newNumber) == -1) {
- break;
- }
- if (Math.floor(newNumber) == newNumber) {
- newNumber = newNumber + 1;
- }
- else {
- newNumber = newNumber + 0.1;
- newNumber.toFixed(1);
- newNumber = Math.round(newNumber * 10) / 10;
- }
- }
- data[dbID]["x-channelID"] = newNumber.toString();
- element.value = newNumber;
- console.log(data[dbID]["x-channelID"]);
- if (COLUMN_TO_SORT == 1) {
- COLUMN_TO_SORT = -1;
- sortTable(1);
- }
- return;
-}
-function backup() {
- var data = new Object();
- console.log("Backup data");
- var cmd = "xteveBackup";
- console.log("SEND TO SERVER");
- console.log(data);
- var server = new Server(cmd);
- server.request(data);
- return;
-}
-function toggleChannelStatus(id) {
- var element;
- var status;
- if (document.getElementById("active")) {
- var checkbox = document.getElementById("active");
- status = (checkbox).checked;
- }
- var ids = getAllSelectedChannels();
- if (ids.length == 0) {
- ids.push(id);
- }
- ids.forEach(function (id) {
- var channel = SERVER["xepg"]["epgMapping"][id];
- channel["x-active"] = status;
- switch (channel["x-active"]) {
- case true:
- if (channel["x-xmltv-file"] == "-" || channel["x-mapping"] == "-") {
- if (BULK_EDIT == false) {
- alert(channel["x-name"] + ": Missing XMLTV file / channel");
- checkbox.checked = false;
- }
- channel["x-active"] = false;
- }
- break;
- case false:
- // code...
- break;
- }
- if (channel["x-active"] == false) {
- document.getElementById(id).className = "notActiveEPG";
- }
- else {
- document.getElementById(id).className = "activeEPG";
- }
- });
-}
-function restore() {
- if (document.getElementById('upload')) {
- document.getElementById('upload').remove();
- }
- var restore = document.createElement("INPUT");
- restore.setAttribute("type", "file");
- restore.setAttribute("class", "notVisible");
- restore.setAttribute("name", "");
- restore.id = "upload";
- document.body.appendChild(restore);
- restore.click();
- restore.onchange = function () {
- var filename = restore.files[0].name;
- var check = confirm("File: " + filename + "\n{{.confirm.restore}}");
- if (check == true) {
- var reader = new FileReader();
- var file = document.querySelector('input[type=file]').files[0];
- if (file) {
- reader.readAsDataURL(file);
- reader.onload = function () {
- console.log(reader.result);
- var data = new Object();
- var cmd = "xteveRestore";
- data["base64"] = reader.result;
- var server = new Server(cmd);
- server.request(data);
- };
- }
- else {
- alert("File could not be loaded");
- }
- restore.remove();
- return;
- }
- };
- return;
-}
-function uploadLogo() {
- if (document.getElementById('upload')) {
- document.getElementById('upload').remove();
- }
- var upload = document.createElement("INPUT");
- upload.setAttribute("type", "file");
- upload.setAttribute("class", "notVisible");
- upload.setAttribute("name", "");
- upload.id = "upload";
- document.body.appendChild(upload);
- upload.click();
- upload.onblur = function () {
- alert();
- };
- upload.onchange = function () {
- var filename = upload.files[0].name;
- var reader = new FileReader();
- var file = document.querySelector('input[type=file]').files[0];
- if (file) {
- reader.readAsDataURL(file);
- reader.onload = function () {
- console.log(reader.result);
- var data = new Object();
- var cmd = "uploadLogo";
- data["base64"] = reader.result;
- data["filename"] = file.name;
- var server = new Server(cmd);
- server.request(data);
- var updateLogo = document.getElementById('update-icon');
- updateLogo.checked = false;
- updateLogo.className = "changed";
- };
- }
- else {
- alert("File could not be loaded");
- }
- upload.remove();
- return;
- };
-}
-function checkUndo(key) {
- switch (key) {
- case "epgMapping":
- if (UNDO.hasOwnProperty(key)) {
- SERVER["xepg"][key] = JSON.parse(JSON.stringify(UNDO[key]));
- }
- else {
- UNDO[key] = JSON.parse(JSON.stringify(SERVER["xepg"][key]));
- }
- break;
- default:
- break;
- }
- return;
-}
-function sortSelect(elem) {
- var tmpAry = [];
- var selectedValue = elem[elem.selectedIndex].value;
- for (var i = 0; i < elem.options.length; i++)
- tmpAry.push(elem.options[i]);
- tmpAry.sort(function (a, b) { return (a.text < b.text) ? -1 : 1; });
- while (elem.options.length > 0)
- elem.options[0] = null;
- var newSelectedIndex = 0;
- for (var i = 0; i < tmpAry.length; i++) {
- elem.options[i] = tmpAry[i];
- if (elem.options[i].value == selectedValue)
- newSelectedIndex = i;
- }
- elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
- return;
-}
-function updateLog() {
- console.log("TOKEN");
- var server = new Server("updateLog");
- server.request(new Object());
-}
diff --git a/html/js/classes_ts.js b/html/js/classes_ts.js
deleted file mode 100644
index 80c168b..0000000
--- a/html/js/classes_ts.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-})();
-var MainMenu = /** @class */ (function () {
- function MainMenu() {
- this.DocumentID = "main-menu";
- this.HTMLTag = "LI";
- }
- MainMenu.prototype.create = function () {
- console.log(this.DocumentID);
- };
- return MainMenu;
-}());
-var MainMenuItem = /** @class */ (function (_super) {
- __extends(MainMenuItem, _super);
- function MainMenuItem() {
- return _super !== null && _super.apply(this, arguments) || this;
- }
- MainMenuItem.prototype.create2 = function () {
- var element = document.createElement(this.HTMLTag);
- element.innerText = this.Value;
- console.log(element);
- };
- return MainMenuItem;
-}(MainMenu));
-function pageReady() {
- var item = new MainMenuItem();
- item.Value = "Test";
- item.create2();
-}
diff --git a/html/js/configuaration.js b/html/js/configuaration.js
deleted file mode 100644
index 0b1105b..0000000
--- a/html/js/configuaration.js
+++ /dev/null
@@ -1,294 +0,0 @@
-var configMenu = new Object();
-var wizard = new Array("key", "tuner", "epgSource", "m3u", "complete");
-var activeWizard;
-var dvrIP
-
-var configMenu_tuner = new Object();
-configMenu_tuner["_element"] = "SELECT";
-configMenu_tuner["_menuType"] = "singleInput";
-configMenu_tuner["_configKey"] = "tuner";
-configMenu_tuner["_label"] = "Available tuners";
-configMenu_tuner["name"] = "tuner";
-configMenu_tuner["id"] = "Tuner";
-configMenu_tuner["placeholder"] = "Tuner";
-configMenu_tuner["_usage"] = "This setting is only used by Plex and Emby. The number of concurrent streams allowed by the IPTV provider."
-
-
-var optionValues = new Array();
-for (var i = 1; i <= 100; i++) {
- optionValues.push(i)
-}
-configMenu_tuner["_optionValues"] = optionValues;
-
-var configMenu_epg = new Object();
-configMenu_epg["_element"] = "SELECT";
-configMenu_epg["_menuType"] = "singleInput";
-configMenu_epg["_configKey"] = "epgSource";
-configMenu_epg["_label"] = "Selection of the EPG source";
-configMenu_epg["name"] = "epgSource";
-configMenu_epg["id"] = "EPG source";
-configMenu_epg["placeholder"] = "EPG source";
-configMenu_epg["_optionValues"] = new Array("PMS", "XEPG");
-configMenu_epg["_usage"] = "PMS: Use EPG data from Plex or Emby XEPG: Use of external EPG data (XMLTV) Several XMLTV sources possible Allows editing and order channels M3U / XMLTV export (HTTP link for IPTV apps)"
-
-var configMenu_m3u = new Object();
-configMenu_m3u["_element"] = "INPUT";
-configMenu_m3u["_menuType"] = "inputArray";
-configMenu_m3u["_configKey"] = "file";
-configMenu_m3u["_label"] = "M3U File: local or remote";
-configMenu_m3u["name"] = "file";
-configMenu_m3u["id"] = "m3u";
-configMenu_m3u["type"] = "text";
-configMenu_m3u["placeholder"] = "M3U File";
-configMenu_m3u["_usage"] = "Remote playlist: http://your.provider.com/file.m3u Local playlist: /path/to/file.m3u"
-
-
-configMenu_m3u["value"] = "http://websrv.local:8080/kabel.m3u";
-
-var configMenu_complete = new Object();
-configMenu_complete["_element"] = "H2";
-configMenu_complete["_menuType"] = "inputArray";
-configMenu_complete["_configKey"] = "file";
-configMenu_complete["_text"] = "xTeVe was successfully set up";
-configMenu_complete["name"] = "complete";
-configMenu_complete["id"] = "complete";
-configMenu_complete["type"] = "text";
-configMenu_complete["class"] = "center";
-
-configMenu["tuner"] = configMenu_tuner;
-configMenu["epgSource"] = configMenu_epg;
-configMenu["m3u"] = configMenu_m3u;
-configMenu["complete"] = configMenu_complete;
-
-function readyForConfiguration() {
- var data = new Object();
- data["cmd"] = "getServerConfig";
- xTeVe(data);
- showLoadingScreen(false);
-}
-
-function createConfiguration(elm) {
-
- activeWizard = elm;
- var item = configMenu[elm];
-
- var div = document.getElementById("content");
- div.innerHTML = "";
- div.setAttribute("data-configKey", item["_configKey"]);
- div.setAttribute("data-menuType", item["_menuType"]);
-
- switch(item.hasOwnProperty("_label")) {
- case true:
- var newItem = new Object();
- newItem["_element"] = "LABEL";
- newItem["_text"] = item["_label"];
- newItem["for"] = item["id"];
- div.appendChild(createElement(newItem));
- break
- }
-
- switch(item["_element"]) {
- case "SELECT":
- div.appendChild(createElement(item));
- var selectElement = div.getElementsByTagName("SELECT")[0];
- var values = item["_optionValues"];
- for (var i = 0; i < values.length; i++) {
- var newEntry = new Object;
- newEntry["_element"] = "OPTION";
- newEntry["_text"] = item["id"] + ": " + values[i];
- newEntry["value"] = values[i];
- selectElement.appendChild(createElement(newEntry));
- }
- //return
- break;
-
- default:
- div.appendChild(createElement(item));
- break;
-
-
- }
- //alert()
-
- switch(item.hasOwnProperty("_usage")) {
- case true:
- var usageItem = new Object();
- usageItem["_element"] = "PRE"
- usageItem["_text"] = item["_usage"];
- div.appendChild(createElement(usageItem));
- }
-
- if (activeWizard == "complete") {
- document.getElementById("next").value = "Finished"
- //document.getElementById("next").setAttribute("onclick", "javascript: location.reload();")
- }
-
- //div.appendChild(createElement(item));
-}
-
-function saveData() {
-
- var div = document.getElementById("content");
- var inputs = div.getElementsByTagName("INPUT");
- var selects = div.getElementsByTagName("SELECT");
- var value;
- var data = new Object();
- var valueArr = new Array();
- var newData = false;
-
- if (activeWizard == "complete") {
- data["cmd"] = "wizardCompleted";
- showLoadingScreen(true)
- xTeVe(data);
- return
- }
-
- for (var i = 0; i < inputs.length; i++) {
- var menuType = inputs[i].parentElement.getAttribute("data-menutype");
- if (inputs[i].value != undefined && inputs[i].value != "" ) {
- newData = true;
-
- console.log(inputs[i].id)
- switch(inputs[i].id) {
- case "m3u":
- var newPlaylist = new Object();
- newPlaylist["file.source"] = inputs[i].value;
- //newPlaylist["name"] = inputs[i].value;
- newPlaylist["type"] = "m3u";
- newPlaylist["new"] = true;
-
- data["files"] = new Object();
- data["files"]["m3u"] = new Object();
- data["files"]["m3u"]["-"] = newPlaylist;
-
- data["cmd"] = "saveFilesM3U";
- xTeVe(data)
- return
- }
- /*
- switch(menuType) {
- case "singleInput":
- data[inputs[i].name] = inputs[i].value; break;
- case "inputArray":
- valueArr.push(inputs[i].value);
- data[inputs[i].name] = valueArr; break
-
- }
- */
- } else {
- inputs[i].style.borderBottomColor = "red";
- return;
- }
- }
-
-
- for (var i = 0; i < selects.length; i++) {
- var value = selects[i].options[selects[i].selectedIndex].value;
- if (isNaN(value) == false) {
- value = parseInt(value);
- data[selects[i].name] = value;
- newData = true;
- break;
- }
- data[selects[i].name] = value;
- newData = true;
- }
-
-
- //console.log(data, newData);
- if (newData == true) {
- config = data
- data["cmd"] = "saveConfig";
- xTeVe(data);
- }
-}
-
-function xTeVe(data) {
-
- if (webSockets == false) {
- alert("Your browser does not support WebSockets");
- return;
- }
-
- if (activeWizard == "m3u" || activeWizard == "epgSource") {
- showLoadingScreen(true);
- }
-
- var protocolWS
- switch(window.location.protocol) {
- case "http:": protocolWS = "ws://"; break;
- case "https:": protocolWS = "wss://"; break;
- }
-
- var ws = new WebSocket(protocolWS + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token"));
-
- ws.onopen = function() {
- ws.send(JSON.stringify(data));
- }
-
- ws.onmessage = function (e) {
-
- var response = JSON.parse(e.data);
-
- if (response.hasOwnProperty("clientInfo")) {
- createClintInfo(response["clientInfo"]);
- }
-
- if (response.hasOwnProperty("status")) {
- if (response["status"] == false) {
- document.getElementById("headline").style.borderColor = "red";
- showErr(response["err"]);
- showLoadingScreen(false)
- return
- } else {
- document.getElementById("err").innerHTML = "";
- document.getElementById("headline").style.borderColor = "lawngreen";
- }
-
- dvrIP = response["DVR"]
- switch(response["configurationWizard"]) {
- case true:
- if (activeWizard == undefined) {
- activeWizard = wizard[0]
- }
- var n = wizard.indexOf(activeWizard);
- n++;
- activeWizard = wizard[n]
-
- if (activeWizard == undefined) {
- data["cmd"] = "wizardCompleted";
- xTeVe(data)
- } else {
- //console.log(activeWizard);
- createConfiguration(activeWizard);
- }
-
- break;
- }
-
- switch(response["reload"]) {
-
-
- case true:
-
- setTimeout(function(){
- location.reload();
- }, 100);
-
- //location.reload();
-
- break;
-
- }
-
-
- }
-
- setTimeout(function(){ showLoadingScreen(false); }, 300);
- }
-
-}
-
-function showErr(elm) {
- document.getElementById("err").innerHTML = elm;
-}
\ No newline at end of file
diff --git a/html/js/configuration_ts.js b/html/js/configuration_ts.js
deleted file mode 100644
index 8aa4ee3..0000000
--- a/html/js/configuration_ts.js
+++ /dev/null
@@ -1,147 +0,0 @@
-var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-})();
-var WizardCategory = /** @class */ (function () {
- function WizardCategory() {
- this.DocumentID = "content";
- }
- WizardCategory.prototype.createCategoryHeadline = function (value) {
- var element = document.createElement("H4");
- element.innerHTML = value;
- return element;
- };
- return WizardCategory;
-}());
-var WizardItem = /** @class */ (function (_super) {
- __extends(WizardItem, _super);
- function WizardItem(key, headline) {
- var _this = _super.call(this) || this;
- _this.headline = headline;
- _this.key = key;
- return _this;
- }
- WizardItem.prototype.createWizard = function () {
- var headline = this.createCategoryHeadline(this.headline);
- var key = this.key;
- var content = new PopupContent();
- var description;
- var doc = document.getElementById(this.DocumentID);
- doc.innerHTML = "";
- doc.appendChild(headline);
- switch (key) {
- case "tuner":
- var text = new Array();
- var values = new Array();
- for (var i = 1; i <= 100; i++) {
- text.push(i);
- values.push(i);
- }
- var select = content.createSelect(text, values, "1", key);
- select.setAttribute("class", "wizard");
- select.id = key;
- doc.appendChild(select);
- description = "{{.wizard.tuner.description}}";
- break;
- case "epgSource":
- var text = ["PMS", "XEPG"];
- var values = ["PMS", "XEPG"];
- var select = content.createSelect(text, values, "XEPG", key);
- select.setAttribute("class", "wizard");
- select.id = key;
- doc.appendChild(select);
- description = "{{.wizard.epgSource.description}}";
- break;
- case "m3u":
- var input = content.createInput("text", key, "");
- input.setAttribute("placeholder", "{{.wizard.m3u.placeholder}}");
- input.setAttribute("class", "wizard");
- input.id = key;
- doc.appendChild(input);
- description = "{{.wizard.m3u.description}}";
- break;
- case "xmltv":
- var input = content.createInput("text", key, "");
- input.setAttribute("placeholder", "{{.wizard.xmltv.placeholder}}");
- input.setAttribute("class", "wizard");
- input.id = key;
- doc.appendChild(input);
- description = "{{.wizard.xmltv.description}}";
- break;
- default:
- console.log(key);
- break;
- }
- var pre = document.createElement("PRE");
- pre.innerHTML = description;
- doc.appendChild(pre);
- console.log(headline, key);
- };
- return WizardItem;
-}(WizardCategory));
-function readyForConfiguration(wizard) {
- var server = new Server("getServerConfig");
- server.request(new Object());
- showElement("loading", false);
- configurationWizard[wizard].createWizard();
-}
-function saveWizard() {
- var cmd = "saveWizard";
- var div = document.getElementById("content");
- var config = div.getElementsByClassName("wizard");
- var wizard = new Object();
- for (var i = 0; i < config.length; i++) {
- var name;
- var value;
- switch (config[i].tagName) {
- case "SELECT":
- name = config[i].name;
- value = config[i].value;
- // Wenn der Wert eine Zahl ist, wird dieser als Zahl gespeichert
- if (isNaN(value)) {
- wizard[name] = value;
- }
- else {
- wizard[name] = parseInt(value);
- }
- break;
- case "INPUT":
- switch (config[i].type) {
- case "text":
- name = config[i].name;
- value = config[i].value;
- if (value.length == 0) {
- var msg = name.toUpperCase() + ": " + "{{.alert.missingInput}}";
- alert(msg);
- return;
- }
- wizard[name] = value;
- break;
- }
- break;
- default:
- // code...
- break;
- }
- }
- var data = new Object();
- data["wizard"] = wizard;
- var server = new Server(cmd);
- server.request(data);
- console.log(data);
-}
-// Wizard
-var configurationWizard = new Array();
-configurationWizard.push(new WizardItem("tuner", "{{.wizard.tuner.title}}"));
-configurationWizard.push(new WizardItem("epgSource", "{{.wizard.epgSource.title}}"));
-configurationWizard.push(new WizardItem("m3u", "{{.wizard.m3u.title}}"));
-configurationWizard.push(new WizardItem("xmltv", "{{.wizard.xmltv.title}}"));
diff --git a/html/js/data.js b/html/js/data.js
deleted file mode 100644
index 688733a..0000000
--- a/html/js/data.js
+++ /dev/null
@@ -1,329 +0,0 @@
-function showConfig(obj) {
- config = obj;
- //setMenuItem();
- createMenu();
- //document.getElementById("page").className = "";
-}
-
-showMyStreams
-
-function showMyStreams(allStreamsObj) {
-
- var streamTypeKeys = getObjKeys(allStreamsObj)
-
- for (var s = 0; s < streamTypeKeys.length; s++) {
- var streamType = streamTypeKeys[s];
- var obj = new Object();
- obj = allStreamsObj[streamType];
- switch(streamType) {
- case "activeStreams": activeStreams = obj; break;
- }
-
- document.getElementById(streamType).innerHTML = "";
-
- var streamsObj = new Object();
- var streamsNames = new Array();
-
- var keys = getObjKeys(obj)
-
- // Create Object (streamsObj) for the streams and sort by name (streamsNames)
- for (var i = 0; i < keys.length; i++) {
- var name = obj[keys[i]]["name"];
- var tmp = new Object();
- var streamKey = getObjKeys(obj[keys[i]]);
-
- for (var j = 0; j < streamKey.length; j++) {
- tmp[streamKey[j]] = obj[keys[i]][streamKey[j]];
- }
-
- streamsObj[name] = tmp;
- streamsNames.push(name)
- }
-
- streamsNames.sort();
-
- // Create Table for activeStreams
- var table = document.getElementById(streamType);
-
- for (var i = 0; i < streamsNames.length; i++) {
- var newEntry = new Object();
- newEntry["_element"] = "TR";
- table.appendChild(createElement(newEntry));
- var line = table.lastChild;
-
- var tmp = streamsObj[streamsNames[i]]
- var keys = getObjKeys(tmp)
-
- var newKey = new Object()
- newKey["_element"] = "TD";
- //newKey["_text"] = streamsNames[i];
- switch(streamType) {
- case "activeStreams": newKey["_text"] = "Channel (+):"; break;
- case "inactiveStreams": newKey["_text"] = "Channel (-):"; break;
- }
-
- newKey["class"] = "tdKey";
- console.log();
-
-
- var newVal = new Object()
- newVal["_element"] = "TD";
- newVal["_text"] = streamsNames[i];
- newVal["class"] = "tdVal";
- //newVal["_text"] = value;
-
- line.appendChild(createElement(newKey));
- line.appendChild(createElement(newVal));
-
- }
-
- }
-
- return
-}
-
-function showActiveStreams(obj) {
- document.getElementById("activeStreams").innerHTML = "";
- activeStreams = obj;
- var streamsObj = new Object();
- var streamsNames = new Array();
-
- var keys = getObjKeys(obj)
-
- // Create Object (streamsObj) for the streams and sort by name (streamsNames)
- for (var i = 0; i < keys.length; i++) {
- var name = obj[keys[i]]["name"];
- var tmp = new Object();
- var streamKey = getObjKeys(obj[keys[i]]);
-
- for (var j = 0; j < streamKey.length; j++) {
- tmp[streamKey[j]] = obj[keys[i]][streamKey[j]];
- }
-
- streamsObj[name] = tmp;
- streamsNames.push(name)
- }
-
- streamsNames.sort();
-
- // Create Table for activeStreams
- var table = document.getElementById("activeStreams");
-
- for (var i = 0; i < streamsNames.length; i++) {
- var newEntry = new Object();
- newEntry["_element"] = "TR";
- table.appendChild(createElement(newEntry));
- var line = table.lastChild;
-
- var tmp = streamsObj[streamsNames[i]]
- var keys = getObjKeys(tmp)
-
- var newKey = new Object()
- newKey["_element"] = "TD";
- //newKey["_text"] = streamsNames[i];
- newKey["_text"] = "Channel:";
- newKey["class"] = "tdKey";
- console.log();
-
-
- var newVal = new Object()
- newVal["_element"] = "TD";
- newVal["_text"] = streamsNames[i];
- newVal["class"] = "tdVal";
- //newVal["_text"] = value;
-
- line.appendChild(createElement(newKey));
- line.appendChild(createElement(newVal));
-
- }
-
-}
-
-function parseLogs(obj) {
- log = obj
- var keys = getObjKeys(obj)
-
- var msgType;
- for (var i = 0; i < keys.length; i++) {
- switch(keys[i]) {
- case "warnings": msgType = "warningMsg"; break;
- case "errors": msgType = "errorMsg"; break;
- }
-
- switch(obj[keys[i]]) {
- case 0: msgType = "tdVal"; break;
- default: break;
- }
-
- if(document.getElementById(keys[i])){
- document.getElementById(keys[i]).className = msgType;
- }
-
-
- }
- return
-}
-
-
-function cancelData(element) {
- createMenu();
-}
-
-function saveData(element) {
- var data = new Object();
- var div = element.parentNode.parentNode;
- var inputs = div.getElementsByTagName("INPUT");
-
- var configKey = div.getAttribute("data-configkey");
- var menuType = div.getAttribute("data-menutype");
- var value;
- var valueArr = new Array();
-
- for (var i = 0; i < inputs.length; i++) {
- if (inputs[i].type == "text" && inputs[i].value != undefined && inputs[i].value != "" ) {
- console.log(inputs[i].value, menuType)
- switch(menuType) {
- case "inputArray": valueArr.push(inputs[i].value); break;
- case "singleInput": value = inputs[i].value; break;
- }
- }
- }
-
- switch(menuType) {
- case "inputArray": data[configKey] = valueArr; break;
- case "singleInput":
- if (isNaN(value) == false) {
- value = parseInt(value);
- data[configKey] = value;
- break;
- }
-
- if (value == undefined) {
- data["delete"] = configKey;
- } else {
- data[configKey] = value
- }
-
- break;
- }
-
- data["cmd"] = "saveConfig";
- console.log(data);
- xTeVe(data)
-}
-
-function xTeVe(data) {
- if (webSockets == false) {
- alert("Your browser does not support WebSockets");
- return;
- } else {
- if (data["cmd"] != "getLog") {
- showLoadingScreen(true)
- }
- }
- delete undo["epgMapping"];
-
- var protocolWS
- switch(window.location.protocol) {
- case "http:": protocolWS = "ws://"; break;
- case "https:": protocolWS = "wss://"; break;
- }
-
-
- var ws = new WebSocket(protocolWS + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token"));
- ws.onopen = function() {
- console.log(data)
- ws.send(JSON.stringify(data));
- }
-
- ws.onmessage = function (e) {
- var response = JSON.parse(e.data);
- console.log(response);
-
- if (response.hasOwnProperty("clientInfo")) {
- createClintInfo(response["clientInfo"]);
- }
-
- if (response.hasOwnProperty("log")) {
- createClintInfo(response["log"]);
- }
-
- if (response.hasOwnProperty("status")) {
- if (response["status"] == false) {
- alert(response["err"])
- if(response.hasOwnProperty("reload")) {
- location.reload();
- }
- //checkErr(response)
- console.log(response);
- updateXteveStatus(response);
- setTimeout(function(){ showLoadingScreen(false); }, 300);
-
- return
- }
-
- updateXteveStatus(response)
-
- //console.log(data["cmd"]);
- switch(data["cmd"]) {
- case "saveUserData": createMenu(); break;
- case "saveNewUser": createMenu(); break;
- case "saveFilesXMLTV": //createMenu(); break;
- case "saveFilesM3U": //createMenu(); return; break;
- case "saveConfig":
- data = new Object();
- data["cmd"] = "checkToken";
- xTeVe(data);
- break;
-
- case "emptyLog": writeLogInDiv(); break;
- case "getLog": return; break;
- }
-
-
- }
-
- if (config["files"] == undefined || config["files"].length == 0) {
- createMenu();
- document.getElementById(10).click()
- }
-
- setTimeout(function(){ showLoadingScreen(false); }, 0);
- }
-
-}
-
-function updateXteveStatus(response) {
- var keys = getObjKeys(response);
- //console.log(keys);
-
- for (var i = 0; i < keys.length; i++) {
- switch(keys[i]) {
- case "alert": alert(response[keys[i]]); break;
- case "config": showConfig(response[keys[i]]); break;
- case "log": parseLogs(response[keys[i]]); break;
- case "myStreams": showMyStreams(response[keys[i]]); break;
- case "xEPG": xEPG = response[keys[i]]; break;
- case "users": users = response[keys[i]]; break;
- case "token": document.cookie = "Token=" + response[keys[i]]; break;
- case "reload": location.reload(); break;
- case "openLink": window.location = response["openLink"]; break;
- //case "version": version = response[keys[i]]; break;
- }
- }
-}
-
-function getValueFromProviderFile(xXmltvFile, fileType, key) {
-
- var fileID = xXmltvFile.substring(0, xXmltvFile.lastIndexOf('.'))
-
- if (config["files"][fileType].hasOwnProperty(fileID) == true) {
- var data = config["files"][fileType][fileID];
- return data[key]
- }
-
-}
-
-
-
-
diff --git a/html/js/files.js b/html/js/files.js
deleted file mode 100644
index a8b63f2..0000000
--- a/html/js/files.js
+++ /dev/null
@@ -1,379 +0,0 @@
-function openFiles(elm, fileType) {
- //document.getElementById("settings").innerHTML = "Test";
-
- columnToSort = 0;
- var newDiv = document.getElementById("settings");
-
- var newEntry = new Object();
- newEntry["_element"] = "HR";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "New";
- newEntry["onclick"] = 'fileDetail("-", "' + fileType + '")';
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "Update";
- newEntry["onclick"] = "fileDetail(0)";
- //newDiv.appendChild(createElement(newEntry));
-
- var div = document.getElementById("settings");
-
- // Build table
- var newTable = new Object();
- newTable["_element"] = "TABLE";
- newTable["id"] = "id_mapping";
- newTable["class"] = "table-mapping";
- div.appendChild(createElement(newTable));
-
- setTimeout(function(){
- createFilesTable(fileType);
- }, 10);
-
-}
-
-function createFilesTable(fileType) {
- var table = document.getElementById("id_mapping");
- var availableFileTypes = new Array();
-
- table.innerHTML = "";
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "table-mapping-header";
- table.appendChild(createElement(newTR));
-
- var tr = table.lastChild;
-
- switch(fileType) {
- case "xmltv":
- availableFileTypes = new Array("xmltv");
- var trHeadlines = new Array("Guide", "Last Update", "Availability %", "Channels", "Programs")
- var compatibilityKeys = new Array("xmltv.channels", "xmltv.programs")
- break;
-
- case "m3u":
- availableFileTypes = new Array("m3u", "hdhr");
- var trHeadlines = new Array("Playlist", "Last Update", "Availability %", "Type", "Streams", "group-title %", "tvg-id %", "Unique ID %");
- var compatibilityKeys = new Array("streams", "group.title", "tvg.id", "stream.id");
- break;
- }
-
- for (var i = 0; i < trHeadlines.length; i++) {
- var newTD = new Object();
- newTD["_element"] = "TD";
- newTD["_text"] = trHeadlines[i];
- tr.appendChild(createElement(newTD));
- }
-
- for (var i = 0; i < availableFileTypes.length; i++) {
-
- var fileType = availableFileTypes[i]
-
- var data = config["files"][fileType];
-
- var allFiles = getObjKeys(data)
-
- for (var f = 0; f < allFiles.length; f++) {
- var elm = data[allFiles[f]];
- var table = document.getElementById("id_mapping");
- var fileID = elm["id.provider"];
- var name = elm["name"];
- var lastUpdate = elm["last.update"];
- var availability = elm["provider.availability"];
- var type = elm["type"].toUpperCase();
- var compatibility = elm["compatibility"];
-
- // Create TR
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "";
- newTR["id"] = fileID;
- newTR["onclick"] = 'javascript: fileDetail("' + fileID + '","' + fileType + '");';
- table.appendChild(createElement(newTR));
-
- var tr = table.lastChild;
-
- // Create file name TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = name;
- createNewTD(newTD, tr);
-
- // Create last update TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = lastUpdate;
- createNewTD(newTD, tr);
-
- // Create availability TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = availability;
- createNewTD(newTD, tr);
-
- if (fileType == "m3u" || fileType == "hdhr") {
-
- // Create Type TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = type;
- createNewTD(newTD, tr);
-
- }
-
- // Create all compatibility TDs
-
- for (var j = 0; j < compatibilityKeys.length; j++) {
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = compatibility[compatibilityKeys[j]];
- createNewTD(newTD, tr);
- }
-
- }
-
- }
-
-
- sortTable(0)
-
- // usage Info
- var div = document.getElementById("settings");
- switch(menu[activeMenu.id].hasOwnProperty("_usage")) {
- case true:
- var usageItem = new Object();
- usageItem["_element"] = "PRE"
- usageItem["_text"] = menu[activeMenu.id]["_usage"];
-
- var newHR = new Object();
- newHR["_element"] = "HR"
- div.appendChild(createElement(newHR));
- div.appendChild(createElement(usageItem));
- break;
- }
-
- calculateWrapperHeight();
- return;
-}
-
-
-function fileDetail(fileID, fileType) {
-
- optionsText = new Array("M3U", "HDHomeRun - [Experimental]")
- optionsValue = new Array("m3u", "hdhr")
-
- switch (fileType) {
-
- case "m3u":
- document.getElementById("name").setAttribute("placeholder", "Playlist name");
- document.getElementById("description").setAttribute("placeholder", "Description of this playlist");
- document.getElementById("file-detail-headline").innerHTML = "M3U Playlist";
- document.getElementById("file-path").innerHTML = "M3U File:";
- document.getElementById("file.source").setAttribute("placeholder", "Local or remote");
- break;
-
- case "hdhr":
- document.getElementById("name").setAttribute("placeholder", "HDHomeRun name");
- document.getElementById("description").setAttribute("placeholder", "Description of this HDHomeRun tuner");
- document.getElementById("file-detail-headline").innerHTML = "HDHomeRun";
- document.getElementById("file-path").innerHTML = "HDHomeRun IP:";
- document.getElementById("file.source").setAttribute("placeholder", "IP address and port of the tuner (192.168.1.10:5004)");
- break;
-
- case "xmltv":
- document.getElementById("name").setAttribute("placeholder", "XMLTV name");
- document.getElementById("description").setAttribute("placeholder", "Description of this XMLTV file");
- document.getElementById("file-detail-headline").innerHTML = "XMLTV File";
- document.getElementById("file-path").innerHTML = "XMLTV File:";
- document.getElementById("file.source").setAttribute("placeholder", "Local or remote");
-
- optionsText = new Array("XMLTV")
- optionsValue = new Array("xmltv")
- break;
- }
-
- modifyOption("type", optionsText, optionsValue)
-
- showPopUpElement('file-detail');
-
- document.getElementById("saveFileDetail").setAttribute("onclick", 'javascript: saveFileDetail("' + fileID + '","' + fileType + '", false)');
- document.getElementById("updateFileDetail").setAttribute("onclick", 'javascript: updateFile("' + fileID + '","' + fileType + '", false)');
- document.getElementById("deleteFileDetail").setAttribute("onclick", 'javascript: saveFileDetail("' + fileID + '","' + fileType + '", true)');
-
- var data = new Object();
-
- switch(fileID) {
-
- case "-": // New file
- data["name"] = "";
- data["description"] = "";
- data["file.source"] = "";
- data["type"] = fileType;
-
- document.getElementById("deleteFileDetail").className = "delete";
- document.getElementById("type").setAttribute("onchange", "changeFileType(this);")
- document.getElementById("type").setAttribute("data-id", fileID)
-
- showElement("deleteFileDetail", false);
- showElement("updateFileDetail", false);
-
- if (fileType == "xmltv") {
- showElement("type", false);
- showElement("file-type", false);
- } else {
- showElement("type", true);
- showElement("file-type", true);
- }
-
- break;
-
- default:
- data = config["files"][fileType][fileID];
- document.getElementById("deleteFileDetail").className = "delete";
-
- showElement("updateFileDetail", true);
- showElement("type", false);
- showElement("file-type", false);
-
- break;
-
- }
-
- var keys = getObjKeys(data);
-
- for (var i = 0; i < keys.length; i++) {
-
- if(document.getElementById(keys[i])){
- document.getElementById(keys[i]).value = data[keys[i]];
- }
-
-
- }
-
-}
-
-function changeFileType(elm) {
-
- var fileID = elm.getAttribute("data-id");
- var fileType = elm.options[elm.selectedIndex].value;
-
- fileDetail(fileID, fileType)
-
-}
-
-
-function saveFileDetail(fileID, fileType, deleteFile) {
-
- if (fileID == undefined) {
- alert("ID is missing!!!");
- return
- }
-
- var inputs = document.getElementById("file-detail").getElementsByTagName("INPUT");
- var selects = document.getElementById("file-detail").getElementsByTagName("SELECT");
- var newFileData = new Object();
- var data = new Object();
-
- for (var i = 0; i < inputs.length; i++) {
- switch(inputs[i].type) {
- case "text": newFileData[inputs[i].name] = inputs[i].value; break;
- }
- }
-
- for (var i = 0; i < selects.length; i++) {
- newFileData[selects[i].id] = selects[i].options[selects[i].selectedIndex].value;
- }
-
- if (deleteFile == true) {
- switch(fileType) {
- case "m3u": var alertText = "Delete this playlist?"; break;
- case "hdhr": var alertText = "Delete this HDHomeRun tuner?"; break;
- case "xmltv": var alertText = "Delete this XMLTV file?"; break;
- }
-
- if (confirm(alertText)) {
- newFileData["delete"] = true
- data = buildFilesObj(fileType, fileID, newFileData);
- console.log(data);
-
- } else {
- showElement("popup", false);
- return
-
- }
-
- } else {
-
- switch(config["files"][fileType].hasOwnProperty(fileID)) {
-
- case true:
- data = config["files"][fileType][fileID];
- if (data["file.source"] != newFileData["file.source"]) {
- data["update"] = true
- } else {
- data["updatePlaylistName"] = true;
- }
- break;
-
- case false:
- newFileData["new"] = true;
- data = buildFilesObj(fileType, fileID, newFileData);
- break
-
- }
-
- }
-
- switch(fileType) {
-
- case "m3u": data["cmd"] = "saveFilesM3U"; break;
- case "hdhr": data["cmd"] = "saveFilesHDHR"; break;
- case "xmltv": data["cmd"] = "saveFilesXMLTV"; break;
-
- }
- //console.log(data);
- xTeVe(data);
- return
-}
-
-function updateFile(fileID, fileType, allFiles) {
-
- switch(config["files"][fileType].hasOwnProperty(fileID)) {
-
- case true:
-
- var data = new Object();
- var data = buildFilesObj(fileType, fileID, config["files"][fileType][fileID])
- data["new"] = true
-
- switch(fileType) {
-
- case "m3u": data["cmd"] = "updateFileM3U"; break;
- case "hdhr": data["cmd"] = "updateFileHDHR"; break;
- case "xmltv": data["cmd"] = "updateFileXMLTV"; break;
-
- }
-
- xTeVe(data);
-
- break;
- }
-
-}
-
-function buildFilesObj(fileType, fileID, obj) {
-
- var data = new Object();
- data["files"] = new Object();
- data["files"][fileType] = new Object();
- data["files"][fileType][fileID] = obj
- return data
-
-}
\ No newline at end of file
diff --git a/html/js/log.js b/html/js/log.js
deleted file mode 100644
index 378d42f..0000000
--- a/html/js/log.js
+++ /dev/null
@@ -1,114 +0,0 @@
-var logInterval
-
-
-function updateLog() {
- var data = new Object();
- data["cmd"] = "getLog";
- xTeVe(data);
- writeLogInDiv();
- return
-}
-
-function writeLogInDiv() {
- var logs = log["log"];
- var div = document.getElementById("settings").lastChild.lastChild;
- div.innerHTML = "";
-
- var max = 50;
-
-
- for (var i = 0; i < logs.length; i++) {
- var newEntry = new Object();
- newEntry["_element"] = "P";
-
- if (logs[i].includes("ERROR")) {
-// case "warnings": msgType = "warningMsg"; break;
- newEntry["class"] = "errorMsg";
- }
-
- if (logs[i].includes("WARNING")) {
-// case "warnings": msgType = "warningMsg"; break;
- newEntry["class"] = "warningMsg";
- }
-
- newEntry["_text"] = logs[i];
-
- div.appendChild(createElement(newEntry));
- }
-
- calculateWrapperHeight();
- var scrollDiv = document.getElementById("box-wrapper");
- scrollDiv.scrollTop = scrollDiv.scrollHeight;
-}
-
-function showLog(obj) {
- //logInterval = setInterval(updateLog, 5000);
-
- var logs = log["log"];
-
- var div = document.getElementById("settings");
-
- var newEntry = new Object();
- newEntry["_element"] = "HR";
- div.appendChild(createElement(newEntry));
- //div = div.lastChild;
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "Empty Log";
- newEntry["onclick"] = "emptyLog()";
- div.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "code";
- newEntry["_text"] = "Update Log: ";
- div.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "checkbox";
- //newEntry["checked"] = "checkbox";
- newEntry["onclick"] = "logUpdates(this)";
- div.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "HR";
- div.appendChild(createElement(newEntry));
-
-
-
-
-
- var newWrapper = new Object();
- newWrapper["_element"] = "DIV";
- newWrapper["id"] = "box-wrapper";
- div.appendChild(createElement(newWrapper));
- div = div.lastChild;
-
- var newPre = new Object();
- newPre["_element"] = "PRE";
- newPre["id"] = "logScreen";
- div.appendChild(createElement(newPre));
-
- div = div.lastChild;
-
- writeLogInDiv()
- return
-}
-
-function emptyLog() {
- var data = new Object();
- data["cmd"] = "emptyLog";
- xTeVe(data);
- return
-}
-
-function logUpdates(elm) {
- switch(elm.checked) {
- case false: clearInterval(logInterval); break;
- case true: logInterval = setInterval(updateLog, 5000); break;
-
- }
-}
\ No newline at end of file
diff --git a/html/js/logs_ts.js b/html/js/logs_ts.js
deleted file mode 100644
index ab2f812..0000000
--- a/html/js/logs_ts.js
+++ /dev/null
@@ -1,42 +0,0 @@
-var Log = /** @class */ (function () {
- function Log() {
- }
- Log.prototype.createLog = function (entry) {
- var element = document.createElement("PRE");
- if (entry.indexOf("WARNING") != -1) {
- element.className = "warningMsg";
- }
- if (entry.indexOf("ERROR") != -1) {
- element.className = "errorMsg";
- }
- if (entry.indexOf("DEBUG") != -1) {
- element.className = "debugMsg";
- }
- element.innerHTML = entry;
- return element;
- };
- return Log;
-}());
-function showLogs(bottom) {
- var log = new Log();
- var logs = SERVER["log"]["log"];
- var div = document.getElementById("content_log");
- div.innerHTML = "";
- var keys = getObjKeys(logs);
- keys.forEach(function (logID) {
- var entry = log.createLog(logs[logID]);
- div.append(entry);
- });
- setTimeout(function () {
- if (bottom == true) {
- var wrapper = document.getElementById("box-wrapper");
- wrapper.scrollTop = wrapper.scrollHeight;
- }
- }, 10);
-}
-function resetLogs() {
- var cmd = "resetLogs";
- var data = new Object();
- var server = new Server(cmd);
- server.request(data);
-}
diff --git a/html/js/mapping-editor.js b/html/js/mapping-editor.js
deleted file mode 100644
index 471dfe3..0000000
--- a/html/js/mapping-editor.js
+++ /dev/null
@@ -1,1466 +0,0 @@
-var mappingError = false;
-var bulk = false;
-var bulkEditAll = false;
-var selectObj = new Object();
-var searchObj = new Object();
-
-var bulkIDs = new Array();
-var bulkChangeObj = new Object();
-
-function checkUndo(key, elm) {
- var tmp = new Object();
- tmp = elm
- console.log("--");
- if (undo.hasOwnProperty("epgMapping")) {
- xEPG["epgMapping"] = JSON.parse(JSON.stringify(undo["epgMapping"]));;
- } else {
- undo["epgMapping"] = JSON.parse(JSON.stringify(elm));
- }
-}
-
-//var plexCategories = new Array("-", "Action sports", "Action", "Adults only", "Adventure", "Aerobics", "Animals", "Animated", "Anime", "Anthology", "Archery", "Art", "Arts/crafts", "Auction", "Auto racing", "Auto", "Aviation", "Awards", "Ballet", "Baseball", "Basketball", "Bicycle racing", "Bicycle", "Billiards", "Biography", "Boat racing", "Boat", "Bowling", "Boxing", "Bus./financial", "Children", "Collectibles", "Comedy drama", "Comedy", "Community", "Computers", "Consumer", "Cooking", "Crime drama", "Crime", "Dance", "Dark comedy", "Debate", "Diving", "Docudrama", "Documentary", "Drama", "Educational", "Entertainment", "Environment", "Equestrian", "Erotic", "Event", "Fantasy", "Fashion", "Feature Film", "Fishing", "Football", "Game show", "Gaming", "Gay/lesbian", "Golf", "Handball", "Health", "Historical drama", "History", "Hockey", "Holiday", "Home improvement", "Horror", "Horse", "House/garden", "How-to", "Interview", "Intl soccer", "Law", "Martial arts", "Medical", "Military", "Miniseries", "Mixed martial arts", "Motorcycle racing", "Motorcycle", "Motorsports", "Mountain biking", "Music", "Musical comedy", "Musical", "Mystery", "Nature", "News", "Newsmagazine", "Olympics", "Opera", "Outdoors", "Parade", "Paranormal", "Parenting", "Performing arts", "Playoff sports", "Poker", "Politics", "Pro wrestling", "Public affairs", "Reality", "Religious", "Rodeo", "Roller derby", "Romance", "Romantic comedy", "Rugby", "Running", "Sailing", "Science fiction", "Science", "Self improvement", "Series", "Shooting", "Shopping", "Short Film", "Sitcom", "Skiing", "Snooker", "Soap", "Soccer", "Special", "Sports", "sports", "Sports event", "Sports non-event", "Sports talk", "Standup", "Surfing", "Suspense", "TV Movie", "Talk", "Technology", "Tennis", "Theater", "Thriller", "Track/field", "Travel", "Triathlon", "Variety", "Volleyball", "War", "Watersports", "Weather", "Western", "Wrestling", "Yacht racing", "movie", "series", "sports", "tvshow");
-var plexCategoriesValues = new Array("-", "Kids", "News", "Movie", "Series", "Sports")
-var plexCategoriesOption = new Array("-", "Kids (Emby only)", "News", "Movie", "Series", "Sports")
-
-
-function openMappingEditor(elm) {
- var columnToSort = 1
-
- checkUndo("epgMapping", xEPG["epgMapping"])
-
- var newDiv = document.getElementById("settings");
-
- var newEntry = new Object();
- newEntry["_element"] = "HR";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "Save";
- newEntry["onclick"] = "saveXEPG()";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "Bulk Edit";
- newEntry["onclick"] = "bulkEdit()";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "Show XEPG";
- newEntry["onclick"] = "showXEPG()";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["class"] = "search";
- newEntry["id"] = "searchMapping";
- newEntry["type"] = "search";
- newEntry["placeholder"] = "Search";
- newEntry["onchange"] = "searchInMapping()";
- newDiv.appendChild(createElement(newEntry));
-
- var div = document.getElementById("settings");
- //screenLog("Duplicate ID", "error", true)
-
-
- // Build table
-
- var newWrapper = new Object();
- newWrapper["_element"] = "DIV";
- newWrapper["id"] = "box-wrapper";
- div.appendChild(createElement(newWrapper));
-
-
- var newTable = new Object();
- newTable["_element"] = "TABLE";
- newTable["id"] = "id_mapping";
- newTable["class"] = "table-mapping";
- div.lastChild.appendChild(createElement(newTable));
- showLoadingScreen(true);
-
- setTimeout(function(){
- createMappingTable();
- }, 10);
-
-}
-
-function createSearchObj() {
- searchObj = new Object();
- var IDs = getObjKeys(xEPG["epgMapping"])
- for (var i = IDs.length - 1; i >= 0; i--) {
- var item = xEPG["epgMapping"][IDs[i]];
- var searchID = item["x-epg"];
- var searchValue = "";
- searchValue = searchValue + item["x-channelID"] + " ";
- searchValue = searchValue + item["x-category"] + " ";
- searchValue = searchValue + item["x-name"] + " ";
- searchValue = searchValue + item["x-group-title"] + " ";
- searchValue = searchValue + item["x-xmltv-file"] + " ";
- searchValue = searchValue + item["_file.m3u.name"] + " ";
-
- switch(item["x-active"]) {
- case true: searchValue = searchValue + "online"; break;
- case false: searchValue = searchValue + "offline"; break;
- }
-
- searchObj[searchValue] = searchID;
-
- }
-}
-
-
-function calculateWrapperHeight() {
-
- if (document.getElementById("box-wrapper")){
-
- var elm = document.getElementById("box-wrapper");
-
- var divs = new Array("myStreamsBox", "clientInfo", "settings");
- var elementsHeight = 0 - elm.offsetHeight;
- for (var i = 0; i < divs.length; i++) {
- elementsHeight = elementsHeight + document.getElementById(divs[i]).offsetHeight;
- }
-
- elm.style.height = window.innerHeight - elementsHeight + "px";
-
- }
-
- if (document.getElementById("menu-wrapper")){
-
- var elm = document.getElementById("menu-wrapper");
-
- var offest = document.getElementById("settings").offsetHeight + document.getElementById("myStreamsBox").offsetHeight + document.getElementById("clientInfo").offsetHeight;
-
- if (window.innerHeight > offest) {
- elm.style.height = window.innerHeight + "px"
- } else {
- elm.style.height = offest + "px"
- }
-
-
- }
-
-
-}
-
-function createMappingTable() {
- columnToSort = 1;
- createSearchObj();
-
- // Create table (Header)
- var table = document.getElementById("id_mapping");
- table.innerHTML = "";
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "table-mapping-header";
- table.appendChild(createElement(newTR));
-
- var tr = document.getElementById("id_mapping").lastChild;
- var trHeadlines = new Array("Bulk", "Ch. No.", "Logo", "Channel Name", "Playlist", "Group Title", "XMLTV File", "XMLTV ID")
-
- for (var i = 0; i < trHeadlines.length; i++) {
- var newTD = new Object();
-
- newTD["_element"] = "TD";
- newTD["_text"] = trHeadlines[i];
-
-
-
- var width = "";
- switch(trHeadlines[i]) {
-
- case "Bulk":
-
- maxWidth = "32px";
- minWidth = "32px";
-
- // Create bulk TD
- var newCheckbox = new Object();
- newCheckbox["_element"] = "INPUT";
- newCheckbox["type"] = "checkbox";
- newCheckbox["class"] = "bulk hideBulk";
- newCheckbox["onmouseout"] = "javascript: this.blur()"
- newCheckbox["onclick"] = "javascript: bulkEditAllChannels()"
-
-
- //newTD.appendChild(createElement(newCheckbox));
-
- break;
-
- case "Ch. No.":
- maxWidth = "80px";
- minWidth = "70px";
- newTD["onclick"] = "javscript: sortTable(" + i + ");";
- newTD["class"] = "pointer";
- break;
-
- case "Logo": maxWidth = "120px"; minWidth = "60px"; break;
-
- case "Channel Name":
- maxWidth = "50%";
- minWidth = "200px";
- newTD["onclick"] = "javscript: sortTable(" + i + ");";
- newTD["class"] = "pointer";
- break;
-
- case "Playlist":
- maxWidth = "150px";
- minWidth = "100px";
- newTD["onclick"] = "javscript: sortTable(" + i + ");";
- newTD["class"] = "pointer";
- break;
-
- case "Group Title":
- maxWidth = "150px";
- minWidth = "100px";
- newTD["onclick"] = "javscript: sortTable(" + i + ");";
- newTD["class"] = "pointer";
- break;
-
- case "XMLTV File":
- maxWidth = "150px";
- minWidth = "100px";
- //newTD["onclick"] = "javscript: sortTable(" + i + ");";
- newTD["class"] = "";
- break;
-
-
- case "XMLTV ID": maxWidth = "150px"; minWidth = "100px"; break;
-
- default:
- newTD["class"] = "";
- break;
- }
-
- tr.appendChild(createElement(newTD));
- if (trHeadlines[i] == "Bulk") {
- tr.lastChild.innerHTML = "";
- tr.lastChild.appendChild(createElement(newCheckbox));
-
- }
-
- var elm = tr.lastChild;
- elm.style.width = maxWidth;
- elm.style.maxWidth = maxWidth;
- elm.style.minWidth = minWidth;
-
- }
- calculateWrapperHeight();
- var IDs = getObjKeys(xEPG["epgMapping"])
-
- var allXmltvFiles = getObjKeys(xEPG["xmltvMap"]);
-
- if (allXmltvFiles == 0) {
- showLoadingScreen(false);
- return;
- }
-
- // Sort IDs
- var posObj = new Object();
- for (var i = 0; i < IDs.length; i++) {
- var item = xEPG["epgMapping"][IDs[i]];
- var pos
- switch(isNaN(xEPG["epgMapping"][IDs[i]]["x-channelID"])) {
- case false: pos = parseFloat(xEPG["epgMapping"][IDs[i]]["x-channelID"]) ; break;
- }
- posObj[pos] = item;
- }
- posFloat = getObjKeys(posObj)
- function sortFloat(a,b) { return a - b; }
- posFloat.sort(sortFloat)
-
- //console.log(posFloat);
-
- // ---
-
- if (IDs.length > 200) {
- setTimeout(function(){
- showLoadingScreen(true);
- }, 1);
-
- }
-
-
- // table for int channel ID's
- for (var i = 0; i < posFloat.length; i++) {
-
- var table = document.getElementById("id_mapping");
- var item = posObj[posFloat[i]];
- //var item = xEPG["epgMapping"][IDs[i]];
- //console.log(item);
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "";
- newTR["id"] = item["x-epg"];
- newTR["oncontextmenu"] = 'javascript: switchChannelStatus("' + item["x-epg"] + '"); return false;';
- table.appendChild(createElement(newTR));
-
- var tr = document.getElementById("id_mapping").lastChild;
-
- // Create bulk TD
- var newTD = new Object();
- newTD["_element"] = "INPUT";
- newTD["type"] = "checkbox";
- newTD["class"] = "bulk hideBulk";
- newTD["onmouseout"] = "javascript: this.blur()"
-
- createNewTD(newTD, tr);
-
-
- // Create ID TD
- var newTD = new Object();
- newTD["_element"] = "INPUT";
- newTD["type"] = "text"
- newTD["class"] = "w40px";
- newTD["value"] = item["x-channelID"];
- newTD["onfocusout"] = "javascript: arrangeTable(this);"
- createNewTD(newTD, tr);
-
- // Create IMG TD
- var newTD = new Object();
- newTD["_element"] = "IMG";
- newTD["onclick"] = 'javascript: mappingDetail("' + item["x-epg"] + '");';
- if (item["tvg-logo"] != undefined) {
- newTD["src"] = item["tvg-logo"];
- } else {
- item["tvg-logo"] = "";
- newTD["src"] = "";
- }
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
-
- // Create P TD (channel name)
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = item["x-name"];
- newTD["class"] = item["x-category"];
-
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
- tr.lastChild.lastChild.style.padding = "5px 10px";
-
- // Create P TD (Playlist Name)
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = item["_file.m3u.name"];
- newTD["class"] = item["tableEllipsis"];
-
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
-
- // Create P TD (Group Title)
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = item["x-group-title"];
- newTD["class"] = item["tableEllipsis"];
-
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
-
-
- // Create P TD (XMLTV file)
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["class"] = "tableEllipsis";
- newTD["_text"] = "-"
-
- if (allXmltvFiles.indexOf(item["x-xmltv-file"]) != -1) {
- var xXmltvFile = item["x-xmltv-file"];
- switch(xXmltvFile) {
- case "-": newTD["_text"] = xXmltvFile; break;
- case "xTeVe Dummy": newTD["_text"] = xXmltvFile; break;
- default: newTD["_text"] = getValueFromProviderFile(xXmltvFile, "xmltv", "name"); break;
-
- }
- //console.log(newTD);
-
- //newTD["_text"] = item["x-xmltv-file"];
- } else {
- //newTD["_text"] = "-"
- }
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
-
- // Creatr P TD (XMLTV channel ID)
- newTD["_element"] = "P";
- newTD["class"] = "tableEllipsis";
-
- if (item["x-mapping"] != undefined) {
- newTD["_text"] = item["x-mapping"];
- }
-
- createNewTD(newTD, tr);
- tr.lastChild.setAttribute("onclick", 'javascript: mappingDetail("' + item["x-epg"] + '");')
-
-
- var xXmltvFile = item["x-xmltv-file"];
- var xMapping = item["x-mapping"];
- var tvgID = item["tvg-id"];
-
- //console.log(item["x-epg"]);
- //console.log(item);
-
- if (item["x-active"] == true) {
- tr.className = "activeEPG";
- } else {
- tr.className = "notActiveEPG";
- }
-
- }
-
- sortTable(1);
-
- setTimeout(function(){
- showLoadingScreen(false);
- }, 5);
-}
-
-function searchInMapping(elm) {
-
- var search = document.getElementById("searchMapping").value;
- var values = getObjKeys(searchObj)
-
- for (var i = values.length - 1; i >= 0; i--) {
- var id = searchObj[values[i]];
- var bool = values[i].toLowerCase().includes(search.toLowerCase());
- switch(bool) {
- case true: document.getElementById(id).style.display = ""; break;
- case false: document.getElementById(id).style.display = "none"; break;
- }
- }
-
-}
-
-function mappingDetail(xepg) {
-
- bulkIDs = new Array();
- var activeElement = document.activeElement;
- // If input id, return
- if (activeElement.tagName == "INPUT") {
- return
- }
-
- if (bulk == true) {
- var elm = document.getElementsByClassName("bulk");
- for (var i = 1; i < elm.length; i++) {
- if (elm[i].checked == true) {
- var id = elm[i].parentElement.parentElement.id;
- bulkIDs.push(id)
- }
-
- }
-
- if (bulkIDs.length == 0) {
- showElement('popup', false)
- alert("No channels selected for editing")
- return
- }
-
- xepg = bulkIDs[0]
- }
-
-
- createSearchObj();
-
- showPopUpElement('mapping-detail');
-
- var thisChannel = xEPG["epgMapping"][xepg];
- //console.log(thisChannel);
- var xXmltvFile = thisChannel["x-xmltv-file"];
- var xMapping = thisChannel["x-mapping"];
- var xCategory = thisChannel["x-category"];
-
- if (xXmltvFile == undefined) {
- thisChannel["x-xmltv-file"] = "-";
- xXmltvFile = "-";
- }
-
- if (xMapping == undefined) {
- thisChannel["x-mapping"] = "-";
- xMapping = "-";
- }
-
- /*
- console.log("ID:", xepg);
- console.log("XMLTV File:", xXmltvFile);
- console.log("Mapping:", xMapping);
- */
-
- var keys = getObjKeys(thisChannel);
- for (var i = 0; i < keys.length; i++) {
- if(document.getElementById(keys[i])){
- var td = document.getElementById(keys[i])
- } else {
- var td = undefined;
- }
-
- var newItem = new Object();
- var values, text = new Array();
- switch(keys[i]) {
- case "x-xmltv-file":
- var fileIDs = getObjKeys(xEPG["xmltvMap"]);
- var value = new Array("-");
- var text = new Array("-");
-
- for (var j = fileIDs.length - 1; j >= 0; j--) {
- if (fileIDs[j] != "xTeVe Dummy") {
- value.push(getValueFromProviderFile(fileIDs[j], "xmltv", "file.xteve"))
- text.push(getValueFromProviderFile(fileIDs[j], "xmltv", "name"))
- } else {
- value.push(fileIDs[j])
- text.push(fileIDs[j])
- }
-
- }
-
- newItem["_element"] = "SELECT";
- newItem["_optionValues"] = value;
- newItem["_optionText"] = text
- newItem["value"] = xXmltvFile;
- newItem["onchange"] = 'javascript: changeXmltvFile("' + xepg + '",this);';
-
- break;
-
- case "x-mapping":
-
- var values = getObjKeys(xEPG["xmltvMap"][xXmltvFile]);
-
- for (var j = 0; j < values.length; j++) {
-
- if (xEPG["xmltvMap"][xXmltvFile][values[j]].hasOwnProperty('display-name') == true) {
- var displayName = xEPG["xmltvMap"][xXmltvFile][values[j]]["display-name"];
- } else {
- var displayName = "-"
- }
-
- //text[j] = values[j] + " (" + displayName + ")";
- text[j] = displayName + " (" + values[j] + ")";
- }
-
- text.unshift("-");
- values.unshift("-");
- newItem["_element"] = "SELECT";
- newItem["_optionValues"] = values;
- newItem["_optionText"] = text
- newItem["value"] = xMapping;
- newItem["onchange"] = 'javascript: mappingChannel("' + xepg + '",this);';
- break;
-
- case "x-category":
- //var values = plexCategoriesValues
- newItem["_element"] = "SELECT";
- newItem["_optionValues"] = plexCategoriesValues;
- newItem["_optionText"] = plexCategoriesOption;
- newItem["value"] = xCategory;
- newItem["onchange"] = 'saveCategory("' + xepg + '")';
- break;
-
- case "tvg-logo":
- document.getElementById("channel-logo").setAttribute("src", thisChannel["tvg-logo"]);
- newItem["_element"] = "INPUT";
- newItem["type"] = "text";
- newItem["value"] = thisChannel["tvg-logo"];
- newItem["onfocusout"] = 'saveChannelLogo("' + xepg + '")';
- newItem["placeholder"] = 'Image URL';
- break;
-
- case "x-update-channel-icon":
- newItem["_element"] = "INPUT";
- newItem["type"] = "checkbox";
- switch(JSON.parse(thisChannel["x-update-channel-icon"])) {
- case true: newItem["checked"] = thisChannel["x-update-channel-icon"];
- break
- }
- newItem["onchange"] = 'saveChannelIconUpdate("' + xepg + '")';
- break;
-
- case "x-name":
- newItem["_element"] = "INPUT";
- newItem["type"] = "text";
- newItem["value"] = thisChannel["x-name"];
- newItem["onfocusout"] = 'saveChannelName("' + xepg + '")';
- newItem["placeholder"] = 'Channel Name';
- break;
-
- case "x-update-channel-name":
- if (thisChannel.hasOwnProperty("_uuid.key") == true) {
- newItem["_element"] = "INPUT";
- newItem["type"] = "checkbox";
- switch(JSON.parse(thisChannel["x-update-channel-name"])) {
- case true: newItem["checked"] = thisChannel["x-update-channel-name"];
- break
- }
- newItem["onchange"] = 'saveChannelNameUpdate("' + xepg + '")';
- showElement("streamHasCUID", true)
-
- break;
- } else {
- //streamHasCUID
- showElement("streamHasCUID", false)
- break;
- }
-
- case "x-active":
- newItem["_element"] = "INPUT";
- newItem["type"] = "checkbox";
- switch(JSON.parse(thisChannel["x-active"])) {
- case true: newItem["checked"] = thisChannel["x-active"];
- break
- }
- newItem["onchange"] = 'saveChannelStatus("' + xepg + '")';
- break;
-
- case "x-group-title":
- newItem["_element"] = "INPUT";
- newItem["type"] = "text";
- newItem["value"] = thisChannel["x-group-title"];
- newItem["onfocusout"] = 'saveGroupTitle("' + xepg + '")';
- newItem["placeholder"] = 'Group Title';
- break;
-
- default:
- newItem["_element"] = "P";
- newItem["_text"] = thisChannel[keys[i]];
- break;
-
- }
-
- if (td != undefined) {
- td.innerHTML = "";
- var element = createNewElement(newItem)
- //console.log(element);
- td.appendChild(element);
- }
-
- }
-
- if (bulk == true) {
-
- var elm = document.getElementsByClassName("noBulk");
- for (var i = 0; i < elm.length; i++) {
- elm[i].lastChild.setAttribute("readonly", true)
- elm[i].lastChild.style.borderColor = "red";
- }
-
- xepg = bulkIDs[0]
- }
-
- sortSelect(document.getElementById("x-xmltv-file").lastChild);
- sortSelect(document.getElementById("x-mapping").lastChild);
-
-}
-
-function sortSelect(elem) {
-
- var tmpAry = [];
- // Retain selected value before sorting
- var selectedValue = elem[elem.selectedIndex].value;
- // Grab all existing entries
- for (var i=0;i 0) elem.options[0] = null;
- // Restore sorted elements
- var newSelectedIndex = 0;
- for (var i=0;i 0 && xMapping != "-" && xMapping.length > 0) {
- if (xEPG["xmltvMap"][xXmltvFile][xMapping].hasOwnProperty("icon")) {
- var logoURL = xEPG["xmltvMap"][xXmltvFile][xMapping]["icon"];
- thisChannel["tvg-logo"] = logoURL;
- document.getElementById(xepg).childNodes[2].lastChild.setAttribute("src", logoURL);
- document.getElementById("channel-logo").setAttribute("src", logoURL);
- } else {
- alert("No logo URL in the XMLTV file available")
- }
-
- }
-
- /*
- if (xEPG["xmltvMap"][xXmltvFile][xMapping]["icon"] != undefined) {
-
-
- }
- */
-
- }
-}
-
-function saveChannelLogo(xepg) {
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel["tvg-logo"] = document.getElementById("tvg-logo").lastChild.value;
- document.getElementById(xepg).childNodes[2].lastChild.setAttribute("src", thisChannel["tvg-logo"]);
- mappingDetail(xepg);
- return
- }
-
- if (bulk == true) {
- var key = "tvg-logo";
- var value = document.getElementById("tvg-logo").lastChild.value;
- saveBulk(key, value);
-
- mappingDetail(xepg);
- return
- }
-}
-
-function saveChannelIconUpdate(xepg) {
-
- var key = "x-update-channel-icon";
- var value = JSON.parse(document.getElementById("x-update-channel-icon").lastChild.checked);
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel[key] = value
- updateChannelLogo(xepg)
-
- mappingDetail(xepg);
- searchInMapping();
- return
- }
-
- if (bulk == true) {
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
-}
-
-function saveChannelName(xepg) {
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel["x-name"] = document.getElementById("x-name").lastChild.value;
- document.getElementById(xepg).childNodes[3].lastChild.innerHTML = thisChannel["x-name"];
- mappingDetail(xepg);
- searchInMapping();
- }
-
-}
-
-function saveChannelNameUpdate(xepg) {
- var key = "x-update-channel-name";
- var value = JSON.parse(document.getElementById("x-update-channel-name").lastChild.checked);
-
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel[key] = value
- mappingDetail(xepg);
- searchInMapping();
- return
- }
-
- if (bulk == true) {
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
-}
-
-function saveChannelStatus(xepg) {
- var thisChannel = xEPG["epgMapping"][xepg];
- var xXmltvFile = thisChannel["x-xmltv-file"];
-
- var key = "x-active";
- var value = JSON.parse(document.getElementById("x-active").lastChild.checked);
-
- if (xEPG["xmltvMap"].hasOwnProperty(xXmltvFile) == true) {
- if (thisChannel["x-mapping"] != "-" && thisChannel["x-mapping"] != undefined) {
- thisChannel["x-active"] = !thisChannel["x-active"];
- var tr = document.getElementById(xepg);
- switch(thisChannel["x-active"]) {
- case true: tr.className = "activeEPG"; break;
- case false: tr.className = "notActiveEPG"; break;
- }
-
- } else {
- var err = "XMLTV Channel is not selected"
- alert(err)
- value = false
- }
-
- } else {
- if (value == true) {
- var err = "XMLTV File is not selecte"
- alert(err)
- value = false
- }
- }
-
-
-
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel[key] = value
- mappingDetail(xepg);
- searchInMapping();
-
- var tr = document.getElementById(xepg);
- switch(thisChannel["x-active"]) {
- case true: tr.className = "activeEPG"; break;
- case false: tr.className = "notActiveEPG"; break;
- }
-
- return
- }
-
- if (bulk == true) {
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
-}
-
-function saveGroupTitle(xepg) {
- var key = "x-group-title";
- var value = document.getElementById("x-group-title").lastChild.value;
-
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- document.getElementById(xepg).childNodes[5].lastChild.innerHTML = value;
- thisChannel[key] = value;
- mappingDetail(xepg);
- searchInMapping();
- }
-
- if (bulk == true) {
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
-}
-
-function saveCategory(xepg) {
- var key = "x-category";
- var value = document.getElementById("x-category").lastChild.value;
-
- if (bulk == false) {
- var thisChannel = xEPG["epgMapping"][xepg];
- thisChannel[key] = value
- document.getElementById(xepg).childNodes[3].lastChild.className = value
- mappingDetail(xepg);
- searchInMapping();
- }
-
- if (bulk == true) {
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
-}
-
-function arrangeTable(elm) {
- var tr = elm.parentElement.parentElement;
- var newPosition = elm.value;
- var x_channelID = tr.id;
-
- switch(isNaN(newPosition)) {
- case true:
- alert("Ch. No. must be a number");
- mappingError = true;
- break;
- }
-
-
- //var item = xEPG["epgMapping"][id];
- var keys = getObjKeys(xEPG["epgMapping"])
- for (var i = 0; i < keys.length; i++) {
- var item = xEPG["epgMapping"][keys[i]];
- if (item["x-epg"] == x_channelID) {
-
- // Check if position exist
- var oldPosition = item["x-channelID"];
-
- if (oldPosition != newPosition) {
-
- console.log(newPosition, newPosition.length);
- if (newPosition.length == 0) {
- mappingError = true
- newPosition = oldPosition;
-
- }
-
- if (mappingError == true) {
- elm.value = oldPosition;
- return;
- }
-
- for (var j = keys.length - 1; j >= 0; j--) {
- var channel = xEPG["epgMapping"][keys[j]];
- if (keys[j] != x_channelID) {
- if (newPosition == channel["x-channelID"]) { // If position exist, set next free position.
- newPosition++;
- elm.value = newPosition;
- arrangeTable(elm);
- return;
- /*
- var newError = new Object();
- newError["err"] = "Duplicate ID";
- checkErr(newError);
- sortTable();
- mappingError = true;
- document.getElementById(x_channelID).getElementsByTagName("INPUT")[0].focus();
- return;
- */
- }
- }
- }
-
- }
-
- //console.log(oldPosition, newPosition);
- if (keys[i] == x_channelID && oldPosition != newPosition) {
- item["x-channelID"] = newPosition;
- }
-
- document.getElementById("logInfo").className = "notVisible";
- if (columnToSort == 1) {
- sortTable(columnToSort);
- }
- mappingError = false;
-
- }
- }
-}
-
-function changeXmltvFile(xepg, elm) {
-
- var thisChannel = xEPG["epgMapping"][xepg];
-
- var xXmltvFile = elm.value;
- var channelID = thisChannel["tvg-id"];
- thisChannel["x-xmltv-file"] = xXmltvFile;
-
- if (bulk == false) {
-
- setTimeout(function(){
-
- var xMapping = "-"
-
- // Automap
- if (xXmltvFile != "-") {
- if (xEPG["xmltvMap"][xXmltvFile].hasOwnProperty(channelID) == true) {
- thisChannel["x-mapping"] = channelID;
- xMapping = channelID
- } else {
- thisChannel["x-mapping"] = xMapping
- }
- } else {
- thisChannel["x-mapping"] = xMapping
-
- }
-
- var tr = document.getElementById(xepg);
-
- if (xMapping == "-") {
- thisChannel["x-active"] = false;
- tr.className = "notActiveEPG"
- } else {
- thisChannel["x-active"] = true;
- tr.className = "activeEPG"
- }
-
- // Show data in table
- var td = tr.getElementsByTagName("TD");
- var dataFile = td[td.length - 2].lastChild;
- switch(xXmltvFile) {
- case "-": dataFile.innerHTML = xXmltvFile; break;
- case "xTeVe Dummy": dataFile.innerHTML = xXmltvFile; break;
- default: dataFile.innerHTML = getValueFromProviderFile(xXmltvFile, "xmltv", "name"); break;
- }
-
- //xXmltvFile.replace(/^.*[\\\/]/, '');
-
- var dataXmltvID = td[td.length - 1].lastChild;
- dataXmltvID.innerHTML = xMapping;
-
- mappingDetail(xepg);
-
- }, 10);
- }
-
- if (bulk == true) {
- var key = "x-xmltv-file"
- var value = xXmltvFile
- saveBulk(key, value);
-
- var key = "x-mapping"
- var value = "-"
- saveBulk(key, value);
- mappingDetail(xepg);
- return
- }
-
- return
-}
-
-function mappingChannel(xepg, elm) {
- var thisChannel = xEPG["epgMapping"][xepg];
- //var xMapping = elm.value;
- var xMapping = elm.options[elm.selectedIndex].value
-
- if (bulk == false) {
-
- thisChannel["x-mapping"] = xMapping;
-
- var tr = document.getElementById(xepg);
-
- if (xMapping == "-") {
- thisChannel["x-active"] = false;
- tr.className = "notActiveEPG"
- } else {
- thisChannel["x-active"] = true;
- tr.className = "activeEPG"
- }
-
- // Show data in table
- var td = tr.getElementsByTagName("TD");
- var dataXmltvID = td[td.length - 1].lastChild;
- dataXmltvID.innerHTML = xMapping;
- //console.log(td[td.length - 1]);
- //console.log(xMapping, elm);
-
- createSearchObj();
- searchInMapping();
- updateChannelLogo(xepg)
- mappingDetail(xepg);
- return
- }
-
- if (bulk == true) {
-
- var key = "x-mapping"
- var value = xMapping
- saveBulk(key, value);
-
- mappingDetail(xepg);
- return
- }
-
- return
-}
-
-
-function createNewTD(newItem, elm) {
- var newTD = new Object();
- newTD["_element"] = "TD";
-
- elm.appendChild(createElement(newTD));
- var td = elm.lastChild;
-
- switch(newItem["_element"]) {
- case "SELECT":
- td.appendChild(createElement(newItem));
- var td = elm.lastChild.lastChild;
- var values = newItem["_optionValues"];
- for (var i = 0; i < values.length; i++) {
- //console.log(item);
- var newEntry = new Object;
- newEntry["_element"] = "OPTION";
- newEntry["_text"] = values[i];
- newEntry["value"] = values[i];
- td.appendChild(createElement(newEntry));
- }
- td.value = newItem["value"];
-
- break;
-
- default:
-
- td.appendChild(createElement(newItem));
- break;
- }
-
-}
-
-function saveXEPG() {
- if (mappingError == true) {
- alert("Data could not be saved, errors in the XEPG data.");
- return;
- }
- showLoadingScreen(true);
-
- var data = new Object();
- data["epgMapping"] = xEPG["epgMapping"];
- data["cmd"] = "saveEpgMapping";
- //console.log(data);
- xTeVe(data);
-}
-
-function bulkEdit() {
- bulk = !bulk;
- var className;
-
- var elm = document.getElementsByClassName("bulk");
-
- switch(bulk) {
- case true:
- className = "bulk showBulk";
- break;
-
- case false:
- className = "bulk hideBulk";
- bulkEditAll = false;
- break;
- }
-
- for (var i = 0; i < elm.length; i++) {
- elm[i].className = className;
- elm[i].checked = false;
- }
-
-}
-
-function bulkEditAllChannels() {
-
- var allTR = document.getElementById("id_mapping").getElementsByTagName("TR");
-
- for (var i = 1; i < allTR.length; i++) {
- if (allTR[i].style.display != "none") {
- switch(bulkEditAll) {
- case false: allTR[i].firstChild.firstChild.checked = true; break;
- case true: allTR[i].firstChild.firstChild.checked = false; break;
- }
-
- }
-
- }
-
- bulkEditAll = !bulkEditAll;
-}
-
-function sortTable(columm) {
- //console.log(columm);
- if (columm == columnToSort) {
- //return;
- }
-
- var table = document.getElementById("id_mapping");
- var tableHead = table.getElementsByTagName("TR")[0];
- var tableItems = tableHead.getElementsByTagName("TD");
-
- var sortObj = new Object();
- var x, xValue;
- var tableHeader
- var sortByString = false
-
- if (columm > 0 && columnToSort > 0) {
- tableItems[columnToSort].className = "pointer";
- tableItems[columm].className = "sortThis";
- }
-
- columnToSort = columm;
-
- var rows = table.rows;
-
- if (rows[1] != undefined) {
- tableHeader = rows[0]
-
- x = rows[1].getElementsByTagName("TD")[columm];
-
- for (i = 1; i < rows.length; i++) {
-
- x = rows[i].getElementsByTagName("TD")[columm];
-
- switch(x.childNodes[0].tagName.toLowerCase()) {
- case "input":
- xValue = x.getElementsByTagName("INPUT")[0].value.toLowerCase();
- break;
-
- case "p":
- xValue = x.getElementsByTagName("P")[0].innerText.toLowerCase();
- break;
-
- default: console.log(x.childNodes[0].tagName);
- }
-
- if (xValue == "" || xValue == NaN) {
- xValue = i
- sortObj[i] = rows[i];
-
- } else {
-
- switch(isNaN(xValue)) {
- case false:
-
- xValue = parseFloat(xValue);
- sortObj[xValue] = rows[i]
- break;
-
- case true:
-
- sortByString = true
- sortObj[xValue.toLowerCase() + i] = rows[i]
- break;
-
- }
-
- }
-
- }
-
- while (table.firstChild) {
- table.removeChild(table.firstChild);
- }
-
- var sortValues = getObjKeys(sortObj)
- if (sortByString == true) {
- sortValues.sort()
- } else {
- function sortFloat(a, b) {
- return a - b;
- }
- sortValues.sort(sortFloat);
- }
-
- table.appendChild(tableHeader)
-
- for (var i = 0; i < sortValues.length; i++) {
-
- table.appendChild(sortObj[sortValues[i]])
-
- }
-
- }
-
-}
-
-
-function sortTable_old(columm) {
- showLoadingScreen(true);
-
- setTimeout(function(){
-
- var table, rows, switching, i, x, y, shouldSwitch;
- table = document.getElementById("id_mapping");
-
- var tableHead = table.getElementsByTagName("TR")[0];
- var tableItems = tableHead.getElementsByTagName("TD");
-
- if (columm > 0) {
- tableItems[columnToSort].className = "pointer";
- tableItems[columm].className = "sortThis";
- }
-
- columnToSort = columm;
-
- /*
- for (var i = 0; i < tableItems.length; i++) {
- if (tableItems[i].className != undefined) {
- tableItems[i].className = "pointer"
- }
-
- }
- */
-
-
-
- console.log(tableItems);
-
- switching = true;
- while (switching) {
- switching = false;
- rows = table.rows;
- for (i = 1; i < (rows.length - 1); i++) {
- shouldSwitch = false;
-
- x = rows[i].getElementsByTagName("TD")[columm];
- y = rows[i + 1].getElementsByTagName("TD")[columm];
-
- switch(x.childNodes[0].tagName.toLowerCase()) {
- case "input":
- xValue = x.getElementsByTagName("INPUT")[0].value.toLowerCase();
- yValue = y.getElementsByTagName("INPUT")[0].value.toLowerCase();
- break;
-
- case "p":
- xValue = x.getElementsByTagName("P")[0].innerText.toLowerCase();
- yValue = y.getElementsByTagName("P")[0].innerText.toLowerCase();
- break;
-
- default: console.log(x.childNodes[0].tagName);
- }
-
-
- switch(isNaN(xValue)) {
- case false: xValue = parseFloat(xValue) ; break;
- }
-
- switch(isNaN(yValue)) {
- case false: yValue = parseFloat(yValue) ; break;
- }
-
-
- if (xValue > yValue) {
- shouldSwitch = true;
- break;
- }
-
- }
- if (shouldSwitch) {
- rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
- switching = true;
- }
- }
- createSearchObj()
-
- showLoadingScreen(false);
- }, 20);
-
-}
-
-function showXEPG() {
- var url = location.protocol + "//" + location.hostname + ":" + location.port + "/xmltv/xteve.xml"
- var win = window.open(url, '_blank');
- win.focus();
-}
\ No newline at end of file
diff --git a/html/js/menu.js b/html/js/menu.js
deleted file mode 100644
index 962e921..0000000
--- a/html/js/menu.js
+++ /dev/null
@@ -1,754 +0,0 @@
-
-function setMenuItem() {
-
- menu = new Object();
- subMenu = new Object();
-
- var menu_m3u = new Object();
- menu_m3u["_menuType"] = "inputArray";
- menu_m3u["_element"] = "LI";
- menu_m3u["_configKey"] = "files.m3u";
- menu_m3u["_text"] = "Playlist";
- menu_m3u["_icon"] = "img/m3u.png";
- menu_m3u["_headline"] = "Playlists: Local or remote";
- menu_m3u["_usage"] = "Info Availability: File availability in percent Streams: Number of streams in the file. group-title: Streams that are assigned to a group. Simplifies filtering streams tvg-id: This ID is used for automatic mapping, must match with the channel ID in the XMLTV file. Unique ID: Streams with a unique ID to identify them. Allows channel name changes in the M3U without losing the XMLTV mapping (PPV / live events).
Usage M3U: Remote playlist: http://your.iptv.provider.com/file.m3u Local playlist: /path/to/file.m3u
Usage HDHomeRun: IP: 192.168.1.10:5004 "
- menu_m3u["name"] = "file";
- menu_m3u["id"] = "file";
- menu_m3u["value"] = menu_m3u["name"];
- menu_m3u["placeholder"] = "Playlist: local or remote";
- menu_m3u["onclick"] = "javascript: toggleMenu(this);";
- menu_m3u["class"] = "menu-notActive";
-
-
- var menu_filter = new Object();
- menu_filter["_menuType"] = "inputArray";
- menu_filter["_element"] = "LI";
- menu_filter["_configKey"] = "filter";
- menu_filter["_text"] = "Filter";
- menu_filter["_icon"] = "img/filter.png";
- menu_filter["_headline"] = "Filter by M3U parameters, e.g. group-title";
- menu_filter["_usage"] = "Usage: Sport - All sports channels Sport {HD} - All HD sports channels Sport {HD} !{ES,DE} - All HD sports channels, but no Spanish and German
To filter the streams of a HDHomeRun, the playlist name can be entered: My tuner {HD}"
- //menu_filter["_usage"] = "Usage: All sports channels: Sport All HD sports channels: Sport {HD} All HD sports channels, but no Spanish and German: Sport {HD} !{ES,DE}"
- menu_filter["name"] = "filter";
- menu_filter["id"] = "M3U";
- menu_filter["value"] = menu_filter["name"];
- menu_filter["placeholder"] = "Filter streams: Sport";
- menu_filter["onclick"] = "javascript: toggleMenu(this);";
- menu_filter["class"] = "menu-notActive";
-
- var menu_id = new Object();
- menu_id["_menuType"] = "inputArray";
- menu_id["_element"] = "LI";
- menu_id["_configKey"] = "id";
- menu_id["_text"] = "PMS ID";
- menu_id["_icon"] = "img/number.png";
- menu_id["_headline"] = "Setup PMS guide number";
- menu_id["_usage"] = 'Some playlists have unique channel IDs. Enter the keyword of the ID. The channel assignment in PMS will change as a result.
e.g. channelID #EXTINF:0 type="stream" channelId="81", My Streaming Channel HD
Only enter here if you know what you are doing!'
- menu_id["name"] = "id";
- menu_id["id"] = "id";
- menu_id["value"] = menu_id["name"];
- menu_id["placeholder"] = "Unique ID from the M3U file";
- menu_id["onclick"] = "javascript: toggleMenu(this);";
- menu_id["class"] = "menu-notActive";
-
-
- var menu_xmltv = new Object();
- menu_xmltv["_menuType"] = "inputArray";
- menu_xmltv["_element"] = "LI";
- menu_xmltv["_configKey"] = "files.xmltv";
- menu_xmltv["_text"] = "XMLTV";
- menu_xmltv["_icon"] = "img/xmltv.png";
- menu_xmltv["_headline"] = "XMLTV files: Local or remote";
- menu_xmltv["_usage"] = "Info: Availability: File availability in percent Channels: Number of channels in the file Programs: Number of EPG data
Usage: Remote XMLTV file: http://your.epg.provider.com/guide.xml Local XMLTV file: /path/to/guide.xml"
- menu_xmltv["name"] = "xmltv";
- menu_xmltv["id"] = "xmltv";
- menu_xmltv["value"] = menu_xmltv["name"];
- menu_xmltv["placeholder"] = "XMLTV File: local or remote";
- menu_xmltv["onclick"] = "javascript: toggleMenu(this);";
- menu_xmltv["class"] = "menu-notActive";
-
- menu_mapping = new Object();
- menu_mapping["_element"] = "LI";
- menu_mapping["_text"] = "Mapping";
- menu_mapping["_icon"] = "img/mapping.png";
- menu_mapping["_configKey"] = "mapping";
- menu_mapping["_headline"] = "XMLTV assignment and sorting of channels";
- menu_mapping["id"] = "mapping";
- menu_mapping["onclick"] = "javascript: toggleMenu(this);";
- menu_mapping["class"] = "menu-notActive phone";
-
- menu_users = new Object();
- menu_users["_element"] = "LI";
- menu_users["_text"] = "Users";
- menu_users["_icon"] = "img/users.png";
- menu_users["_configKey"] = "users";
- menu_users["_headline"] = "Administration of users and permissions";
- menu_users["id"] = "users";
- menu_users["onclick"] = "javascript: toggleMenu(this);";
- menu_users["class"] = "menu-notActive";
- menu_users["_usage"] = "Authorization groups: WEB: Users can log in to the web interface PMS: Programs like Plex can access the channel list. Login via DVR IP: username:password@xteve.ip:port M3U: Allows clients to download the M3U playlist. XML: Allows clients to download the XMLTV file. API: Allows clients to use the API interface.
!!! For PMS authentication, only the following special characters are valid: !$()=.,-:;
The individual authentication groups can be activated / deactivated in the settings menu."
-
- menu_settings = new Object();
- menu_settings["_element"] = "LI";
- menu_settings["_text"] = "Settings";
- menu_settings["_icon"] = "img/settings.png";
- menu_settings["_configKey"] = "settings";
- menu_settings["_headline"] = "Settings";
- menu_settings["_subMenu"] = "701,702,703,704,705,706,707,708,799,710,711,712,713,714";
- menu_settings["id"] = "settings";
- menu_settings["onclick"] = "javascript: toggleMenu(this);";
- menu_settings["class"] = "menu-notActive";
-
- menu_log = new Object();
- menu_log["_element"] = "LI";
- menu_log["_text"] = "Log";
- menu_log["_icon"] = "img/log.png";
- menu_log["_headline"] = "Log";
- menu_log["_configKey"] = "log";
- menu_log["id"] = "log";
- menu_log["onclick"] = "javascript: toggleMenu(this);";
- menu_log["class"] = "menu-notActive";
-
- menu_logout = new Object();
- menu_logout["_element"] = "LI";
- menu_logout["_text"] = "Logout";
- menu_logout["_icon"] = "img/logout.png";
- menu_logout["id"] = "logout";
- menu_logout["onclick"] = "javascript: logout();";
- menu_logout["class"] = "menu-notActive";
-
- var menu_schedule = new Object();
- menu_schedule["_menuType"] = "inputArray";
- menu_schedule["_element"] = "LI";
- menu_schedule["_configKey"] = "update";
- menu_schedule["_text"] = "Schedule";
- menu_schedule["_icon"] = "img/schedule.png";
- menu_schedule["_headline"] = "Schedule for updating M3U, XMLTV files and creating a local backup";
- menu_schedule["_usage"] = "Usage: 0815 = 8:15 am 1930 = 7:30 pm"
- menu_schedule["name"] = "update";
- menu_schedule["id"] = "update";
- menu_schedule["value"] = menu_id["name"];
- menu_schedule["placeholder"]= "time of day (24-hour clock)";
- menu_schedule["onclick"] = "javascript: toggleMenu(this);";
- menu_schedule["class"] = "menu-notActive";
-
- var menu_filesUpdate = new Object();
- menu_filesUpdate["_element"] = "LI";
- menu_filesUpdate["_menuType"] = "checkbox";
- menu_filesUpdate["_configKey"] = "files.update";
- menu_filesUpdate["_label"] = "Update the provider files at system startup";
- menu_filesUpdate["_headline"] = "Update the provider files at system startup";
- menu_filesUpdate["_usage"] = "Playlists and XMLTV files are updated by xTeVe at system startup."
- menu_filesUpdate["name"] = "files.update";
- menu_filesUpdate["id"] = "files.update";
- menu_filesUpdate["value"] = menu_filesUpdate["name"];
- menu_filesUpdate["onclick"] = "javascript: toggleMenu(this);";
- menu_filesUpdate["class"] = "menu-notActive";
-
- var menu_tuner = new Object();
- menu_tuner["_element"] = "LI";
- menu_tuner["_menuType"] = "select";
- menu_tuner["_configKey"] = "tuner";
- menu_tuner["_label"] = "Available tuners";
- menu_tuner["_text"] = "Tuner";
- menu_tuner["_icon"] = "img/tuner.png";
- menu_tuner["_headline"] = "Number of tuners";
- menu_tuner["_usage"] = "This setting is only used by Plex and Emby. The number of concurrent streams allowed by the IPTV provider. After a change, xTeVe must be delete in the PMS DVR settings and set up again."
- menu_tuner["name"] = "tuner";
- menu_tuner["id"] = "tuner";
- menu_tuner["value"] = menu_tuner["name"];
- menu_tuner["placeholder"] = "Number of tuners";
- menu_tuner["onclick"] = "javascript: toggleMenu(this);";
- menu_tuner["class"] = "menu-notActive";
-
- var optionValues = new Array();
- for (var i = 1; i <= 100; i++) {
- optionValues.push(i)
- }
- menu_tuner["_optionValues"] = optionValues;
-
- var menu_epg = new Object();
- menu_epg["_element"] = "LI";
- menu_epg["_menuType"] = "select";
- menu_epg["_configKey"] = "epgSource";
- menu_epg["_label"] = "Selection of the EPG source";
- menu_epg["_text"] = "EPG source";
- menu_epg["_headline"] = "Selection of the EPG source";
- menu_epg["_usage"] = "PMS: Use EPG data from Plex or Emby. XEPG: Use of external EPG data (XMLTV). Several XMLTV sources possible. Allows editing and order channels. M3U / XMLTV export (HTTP link for IPTV apps)."
- menu_epg["name"] = "epgSource";
- menu_epg["id"] = "epgSource";
- menu_epg["value"] = menu_epg["name"];
- menu_epg["placeholder"] = "EPG source";
- menu_epg["onclick"] = "javascript: toggleMenu(this);";
- menu_epg["class"] = "menu-notActive";
- menu_epg["_optionValues"] = new Array("PMS", "XEPG");
-
- var menu_xepg = new Object();
- menu_xepg["_element"] = "LI";
- menu_xepg["_menuType"] = "checkbox";
- menu_xepg["_configKey"] = "xteveAutoUpdate";
- menu_xepg["_label"] = "Automatic update of xTeVe";
- menu_xepg["_headline"] = "Automatic update of xTeVe";
- menu_xepg["_usage"] = "If a new version of xTeVe is available, it will be automatically installed."
- menu_xepg["name"] = "xteveAutoUpdate";
- menu_xepg["id"] = "xteveAutoUpdate";
- menu_xepg["value"] = menu_xepg["name"];
- menu_xepg["onclick"] = "javascript: toggleMenu(this);";
- menu_xepg["class"] = "menu-notActive";
-
- var menu_autoBackupPath = new Object();
- menu_autoBackupPath["_element"] = "LI";
- menu_autoBackupPath["_menuType"] = "singleInput";
- menu_autoBackupPath["_configKey"] = "backup.path";
- menu_autoBackupPath["_label"] = "Location for automatic backups";
- menu_autoBackupPath["_headline"] = "Location for automatic backups";
- menu_autoBackupPath["_usage"] = "Before any update of the provider data by the schedule, xTeVe creates a backup. The path for the automatic backups can be changed. xTeVe requires write permission for this folder."
- menu_autoBackupPath["name"] = "backup.path";
- menu_autoBackupPath["id"] = "backup.path";
- menu_autoBackupPath["value"] = menu_autoBackupPath["name"];
- menu_autoBackupPath["onclick"] = "javascript: toggleMenu(this);";
- menu_autoBackupPath["class"] = "menu-notActive";
-
- var menu_autoBackupKeep = new Object();
- menu_autoBackupKeep["_element"] = "LI";
- menu_autoBackupKeep["_menuType"] = "select";
- menu_autoBackupKeep["_configKey"] = "backup.keep";
- menu_autoBackupKeep["_text"] = "Keep";
- menu_autoBackupKeep["_label"] = "Number of backups to keep";
- menu_autoBackupKeep["_headline"] = "Number of backups to keep";
- menu_autoBackupKeep["_usage"] = ""
- menu_autoBackupKeep["name"] = "backup.keep";
- menu_autoBackupKeep["id"] = "backup.keep";
- menu_autoBackupKeep["value"] = menu_autoBackupKeep["name"];
- menu_autoBackupKeep["onclick"] = "javascript: toggleMenu(this);";
- menu_autoBackupKeep["class"] = "menu-notActive";
-
- var optionValues = new Array(5, 10, 20, 30, 40, 50);
- menu_autoBackupKeep["_optionValues"] = optionValues;
-
-
- var menu_buffer = new Object();
- menu_buffer["_element"] = "LI";
- menu_buffer["_menuType"] = "checkbox";
- menu_buffer["_configKey"] = "buffer";
- menu_buffer["_label"] = "Stream buffering [Experimental]";
- menu_buffer["_headline"] = "Stream buffering [Experimental]";
- menu_buffer["_usage"] = "With activated buffer, streams can be played and recorded more fluently. The stream is passed from xTeVe to Plex / Emby"
- menu_buffer["name"] = "buffer";
- menu_buffer["id"] = "buffer";
- menu_buffer["value"] = menu_buffer["name"];
- menu_buffer["onclick"] = "javascript: toggleMenu(this);";
- menu_buffer["class"] = "menu-notActive";
-
- var menu_api = new Object();
- menu_api["_element"] = "LI";
- menu_api["_menuType"] = "checkbox";
- menu_api["_configKey"] = "api";
- menu_api["_label"] = "API interface";
- menu_api["_headline"] = "API interface";
- menu_api["_usage"] = 'Via API interface it is possible to send commands to xTeVe. API documentation is available here '
- //menu_api["_usage"] = 'Via API interface it is possible to send commands to xTeVe. API documentation is available here '
- menu_api["name"] = "api";
- menu_api["id"] = "api";
- menu_api["value"] = menu_api["name"];
- menu_api["onclick"] = "javascript: toggleMenu(this);";
- menu_api["class"] = "menu-notActive";
-
- var menu_authenticationWeb = new Object();
- menu_authenticationWeb["_element"] = "LI";
- menu_authenticationWeb["_menuType"] = "checkbox";
- menu_authenticationWeb["_configKey"] = "authentication.web";
- menu_authenticationWeb["_label"] = "User authentication";
- menu_authenticationWeb["_headline"] = "User authentication";
- menu_authenticationWeb["_usage"] = "Access to xTeVe requires authentication."
- menu_authenticationWeb["name"] = "authentication.web";
- menu_authenticationWeb["id"] = "authentication.web";
- menu_authenticationWeb["value"] = menu_authenticationWeb["name"];
- menu_authenticationWeb["onclick"] = "javascript: toggleMenu(this);";
- menu_authenticationWeb["class"] = "menu-notActive";
-
- var menu_authenticationPms = new Object();
- menu_authenticationPms["_element"] = "LI";
- menu_authenticationPms["_menuType"] = "checkbox";
- menu_authenticationPms["_configKey"] = "authentication.pms";
- menu_authenticationPms["_label"] = "Plex authentication.";
- menu_authenticationPms["_headline"] = "Plex authentication.";
- menu_authenticationPms["_usage"] = "Plex requests are only possible with authentication. Warning!!! After activating this function xTeVe must be delete in the PMS DVR settings and set up again."
- menu_authenticationPms["name"] = "authentication.pms";
- menu_authenticationPms["id"] = "authentication.pms";
- menu_authenticationPms["value"] = menu_authenticationPms["name"];
- menu_authenticationPms["onclick"] = "javascript: toggleMenu(this);";
- menu_authenticationPms["class"] = "menu-notActive";
-
- var menu_authenticationM3u = new Object();
- menu_authenticationM3u["_element"] = "LI";
- menu_authenticationM3u["_menuType"] = "checkbox";
- menu_authenticationM3u["_configKey"] = "authentication.m3u";
- menu_authenticationM3u["_label"] = "M3U authentication.";
- menu_authenticationM3u["_headline"] = "M3U authentication.";
- menu_authenticationM3u["_usage"] = "Downloading the M3U file via an HTTP request is only possible with authentication."
- menu_authenticationM3u["name"] = "authentication.m3u";
- menu_authenticationM3u["id"] = "authentication.m3u";
- menu_authenticationM3u["value"] = menu_authenticationM3u["name"];
- menu_authenticationM3u["onclick"] = "javascript: toggleMenu(this);";
- menu_authenticationM3u["class"] = "menu-notActive";
-
-
- var menu_authenticationXml = new Object();
- menu_authenticationXml["_element"] = "LI";
- menu_authenticationXml["_menuType"] = "checkbox";
- menu_authenticationXml["_configKey"] = "authentication.xml";
- menu_authenticationXml["_label"] = "XEPG authentication";
- menu_authenticationXml["_headline"] = "XEPG authentication";
- menu_authenticationXml["_usage"] = "Downloading the XEPG (XMLTV) file via an HTTP request is only possible with authentication."
- menu_authenticationXml["name"] = "authentication.xml";
- menu_authenticationXml["id"] = "authentication.xml";
- menu_authenticationXml["value"] = menu_authenticationXml["name"];
- menu_authenticationXml["onclick"] = "javascript: toggleMenu(this);";
- menu_authenticationXml["class"] = "menu-notActive";
-
- var menu_authenticationApi = new Object();
- menu_authenticationApi["_element"] = "LI";
- menu_authenticationApi["_menuType"] = "checkbox";
- menu_authenticationApi["_configKey"] = "authentication.api";
- menu_authenticationApi["_label"] = "API authentication";
- menu_authenticationApi["_headline"] = "API authentication";
- menu_authenticationApi["_usage"] = "Access to the API interface is only possible with authentication."
- menu_authenticationApi["name"] = "authentication.api";
- menu_authenticationApi["id"] = "authentication.api";
- menu_authenticationApi["value"] = menu_authenticationApi["name"];
- menu_authenticationApi["onclick"] = "javascript: toggleMenu(this);";
- menu_authenticationApi["class"] = "menu-notActive";
-
-
- // Main menu
- menu[10] = menu_m3u;
-
- switch(config["epgSource"]) {
- case "PMS":
- menu[20] = menu_id;
- break;
-
- case "XMLTV":
- menu[40] = menu_xmltv;
- break;
-
- case "XEPG":
- menu[40] = menu_xmltv;
- menu[50] = menu_mapping;
- break;
- }
-
- menu[30] = menu_filter;
-
- if (config["authentication.web"] == true) {
- menu[60] = menu_users;
- }
-
- menu[70] = menu_settings;
- menu[80] = menu_log;
- if (config["authentication.web"] == true) {
- menu[100] = menu_logout;
- }
-
-
- // Sub-Menu
-
- subMenu[701] = menu_schedule;
- subMenu[702] = menu_filesUpdate;
- subMenu[703] = menu_tuner;
- subMenu[704] = menu_epg;
- subMenu[705] = menu_xepg;
- subMenu[706] = menu_autoBackupPath;
- subMenu[707] = menu_autoBackupKeep;
- subMenu[708] = menu_buffer;
-
- subMenu[710] = menu_authenticationWeb;
-
- if (config["authentication.web"] == true) {
- subMenu[711] = menu_authenticationPms;
- subMenu[712] = menu_authenticationM3u;
- subMenu[713] = menu_authenticationXml;
- subMenu[714] = menu_authenticationApi;
- }
-
- subMenu[799] = menu_api;
-
-
-
- return
-}
-
-function createMenu() {
-
- showElement("popup", false);
-
- //console.log(config);
- setMenuItem();
- var menuItems = getObjKeys(menu)
- var nav = document.getElementsByTagName("NAV")[0];
- nav.innerHTML = "";
- var newItem = new Object();
-
- for (var i = 0; i < menuItems.length; i++) {
-
-
- var newItem = menu[menuItems[i]];
- newItem["id"] = menuItems[i];
-
-
- switch(newItem.hasOwnProperty("_icon")) {
- case true:
- var itemText = newItem["_text"];
- delete newItem["_text"]
- nav.appendChild(createElement(newItem));
- newItem["_text"] = itemText;
- var newIcon = new Object();
- newIcon["_element"] = "IMG";
- newIcon["src"] = newItem["_icon"];
-
- var currentElement = document.getElementById(menuItems[i]);
- currentElement.appendChild(createElement(newIcon));
-
-
- var text = new Object();
- text["_element"] = "P"
- text["_text"] = itemText;
- text["class"] = "nav-text"
- currentElement.appendChild(createElement(text));
- break;
-
- default:
- nav.appendChild(createElement(newIcon));
- break;
- }
-
- }
- if (activeMenu != undefined) {
- //console.log(activeMenu);
- toggleMenu(activeMenu);
- }
-
- return
-}
-
-function toggleMenu(elm) {
- //showStreams(false);
- clearInterval(logInterval)
- activeMenu = elm;
- var item = menu[elm.id]
- var div = document.getElementById("settings");
- div.innerHTML = "";
-
- // Set Headline
- var headline = new Object();
- headline["_element"] = "H4";
- headline["_text"] = item["_headline"];
- div.appendChild(createElement(headline));
-
- // Sub-Menu
- if (item.hasOwnProperty("_subMenu") == true) {
- openSubMenu(item);
- return
- }
-
- // Mapping, Users, Log, Files
- switch(item["_configKey"]) {
- case "mapping": openMappingEditor(item); return; break;
- case "users": openUsers(item); return; break;
- case "log": showLog(item); return; break;
- case "files.m3u": openFiles(item, "m3u"); return; break;
- case "files.xmltv": openFiles(item, "xmltv"); return; break;
-
- case "filter": showStreams(true); break;
- }
-
-
-
- var newHR = new Object();
- newHR["_element"] = "HR"
- div.appendChild(createElement(newHR));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- //newEntry["class"] = "save";
- newEntry["value"] = "Save";
- newEntry["onclick"] = "saveData2('settings')"
- div.appendChild(createElement(newEntry));
-
-
- var newWrapper = new Object();
- newWrapper["_element"] = "DIV";
- newWrapper["id"] = "box-wrapper";
- div.appendChild(createElement(newWrapper));
-
- div = div.lastChild;
-
- div.appendChild(createMenuItem(item))
-
- // usage Info
- switch(menu[activeMenu.id].hasOwnProperty("_usage")) {
- case true:
- var usageItem = new Object();
- usageItem["_element"] = "PRE"
- usageItem["_text"] = menu[activeMenu.id]["_usage"];
- div.appendChild(createElement(usageItem));
- }
-
- calculateWrapperHeight();
-
-}
-
-function createMenuItem(item) {
- var element = document.createElement("DIV");
- switch(item["_menuType"]) {
- case "inputArray":
- if (config.hasOwnProperty(item["_configKey"]) == true) {
- var value = config[item["_configKey"]];
- } else {
- var value = new Array();
- }
-
- for (var i = 0; i < value.length; i++) {
- var newEntry = new Object();
- newEntry = item
- delete newEntry["onclick"];
- newEntry["_element"] = "INPUT";
- newEntry["value"] = value[i];
- newEntry["type"] = "search";
- newEntry["data-menutype"] = item["_menuType"];
- newEntry["data-menukey"] = item["_configKey"];
- element.appendChild(createElement(newEntry));
-
- }
- // New entry for array
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "search";
- newEntry["name"] = item["name"];
- newEntry["placeholder"] = item["placeholder"];
- newEntry["value"] = "";
- newEntry["data-menutype"] = item["_menuType"];
- newEntry["data-menukey"] = item["_configKey"];
- element.appendChild(createElement(newEntry));
- break;
-
- case "singleInput":
- var value = config[item["_configKey"]];
- if (value == undefined) {
- value = "";
- }
- var newEntry = new Object();
- newEntry = item;
- delete newEntry["onclick"];
- newEntry["_element"] = "INPUT";
- newEntry["value"] = value;
- newEntry["type"] = "search";
- newEntry["data-menutype"] = item["_menuType"];
- newEntry["data-menukey"] = item["_configKey"];
- element.appendChild(createElement(newEntry));
- break;
-
- case "checkbox":
- var value = config[item["_configKey"]];
- if (value == undefined) {
- value = false;
- }
- var newEntry = new Object();
- newEntry = item;
- delete newEntry["onclick"];
- newEntry["_element"] = "INPUT";
- newEntry["value"] = value;
- newEntry["type"] = "checkbox";
- newEntry["data-menutype"] = item["_menuType"];
- newEntry["data-menukey"] = item["_configKey"];
- element.appendChild(createElement(newEntry));
- element.getElementsByTagName("INPUT")[0].checked = value;
- break;
-
- case "select":
- var value = config[item["_configKey"]];
- var newEntry = new Object();
- newEntry = item;
- delete newEntry["onclick"]
- newEntry["_element"] = "SELECT";
- element.appendChild(createElement(newEntry));
- var selectElement = element.getElementsByTagName("SELECT")[0];
- var values = item["_optionValues"];
- for (var i = 0; i < values.length; i++) {
- var newEntry = new Object;
- newEntry["_element"] = "OPTION";
- newEntry["_text"] = item["_text"] + ": " + values[i];
- newEntry["value"] = values[i];
- selectElement.appendChild(createElement(newEntry));
- }
- selectElement.value = value;
- break;
-
- }
- return element;
-}
-
-function openSubMenu(item) {
- var entrys = item["_subMenu"].split(",");
- var div = document.getElementById("settings");
-
- var newHR = new Object();
- newHR["_element"] = "HR"
- div.appendChild(createElement(newHR));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- //newEntry["class"] = "save";
- newEntry["value"] = "Save";
- newEntry["onclick"] = "saveData2('settings')"
- div.appendChild(createElement(newEntry));
-
- if (item["_configKey"] == "settings") {
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- //newEntry["class"] = "save";
- newEntry["value"] = "Backup";
- newEntry["onclick"] = "xteveBackup()"
- div.appendChild(createElement(newEntry));
- }
-
- if (item["_configKey"] == "settings") {
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- //newEntry["class"] = "save";
- newEntry["value"] = "Restore";
- newEntry["onclick"] = "xteveRestore(this)"
- div.appendChild(createElement(newEntry));
- }
-
-
- var newWrapper = new Object();
- newWrapper["_element"] = "DIV";
- newWrapper["id"] = "box-wrapper";
- div.appendChild(createElement(newWrapper));
-
- div = div.lastChild;
-
-
- for (var i = 0; i < entrys.length; i++) {
- var item = subMenu[entrys[i]];
- if (item == undefined) {
- break;
- }
-
- var container = new Object();
- container["_element"] = "DIV";
- div.appendChild(createElement(container));
-
- var divContainer = div.lastChild;
-
- var headline = new Object();
- headline["_element"] = "H5";
- headline["_text"] = item["_headline"];
- divContainer.appendChild(createElement(headline));
-
- divContainer.appendChild(createMenuItem(item))
-
- switch(item.hasOwnProperty("_usage")) {
- case true:
- var usageItem = new Object();
- usageItem["_element"] = "PRE"
- usageItem["_text"] = item["_usage"];
- divContainer.appendChild(createElement(usageItem));
- }
-
- var hr = new Object();
- hr["_element"] = "HR";
- divContainer.appendChild(createElement(hr));
-
- }
-
- calculateWrapperHeight();
- return
-}
-
-function saveData2(elm) {
- var div = document.getElementById(elm);
- var inputs = div.getElementsByTagName("INPUT");
- var selects = div.getElementsByTagName("SELECT");
- var value, configKey;
- var data = new Object();
- var valueArr = new Array();
- var newData = false;
-
- for (var i = 0; i < inputs.length; i++) {
- if (inputs[i].type != "button") {
- var menuType = inputs[i].getAttribute("data-menutype");
-
- //console.log(menuType);
- switch(menuType) {
- case "singleInput":
- value = inputs[i].value;
- if (value == "" || value == undefined) {
- data = new Object();
- data["delete"] = inputs[i].name
- newData = true;
- } else {
- newData = true;
- data[inputs[i].name] = value;
- console.log(data);
- }
- break;
- case "inputArray":
- value = inputs[i].value;
- if (value != "" && value != undefined) {
- newData = true;
- valueArr.push(value)
- data[inputs[i].name] = valueArr;
- configKey = inputs[i].name;
- }
-
- break;
-
- case "checkbox":
- value = inputs[i].checked
- data[inputs[i].name] = value;
- }
-
- }
-
- }
-
-
- // Delete config key
- if (valueArr.length == 0 && newData == false) {
- newData = true;
- data = new Object();
- data["delete"] = configKey;
- }
-
-
- for (var i = 0; i < selects.length; i++) {
- var value = selects[i].options[selects[i].selectedIndex].value;
- switch(isNaN(value)) {
- case false: value = parseInt(value); break;
- }
-
- data[selects[i].name] = value;
- newData = true;
- }
-
- //console.log(data, newData);
-
- if (newData == true) {
- data["cmd"] = "saveConfig";
- if (!data.hasOwnProperty('filter')) {
- data["filter"] = config["filter"]
- }
- var settings = new Object();
- settings["cmd"] = data["cmd"];
- settings["settings"] = data;
- console.log(settings);
- xTeVe(settings);
- }
-}
diff --git a/html/js/menu_ts.js b/html/js/menu_ts.js
deleted file mode 100644
index 8cb5a78..0000000
--- a/html/js/menu_ts.js
+++ /dev/null
@@ -1,1757 +0,0 @@
-var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-})();
-var MainMenu = /** @class */ (function () {
- function MainMenu() {
- this.DocumentID = "main-menu";
- this.HTMLTag = "LI";
- this.ImagePath = "img/";
- }
- MainMenu.prototype.createIMG = function (src) {
- var element = document.createElement("IMG");
- element.setAttribute("src", this.ImagePath + src);
- return element;
- };
- MainMenu.prototype.createValue = function (value) {
- var element = document.createElement("P");
- element.innerHTML = value;
- return element;
- };
- return MainMenu;
-}());
-var MainMenuItem = /** @class */ (function (_super) {
- __extends(MainMenuItem, _super);
- function MainMenuItem(menuKey, value, image, headline) {
- var _this = _super.call(this) || this;
- _this.menuKey = menuKey;
- _this.value = value;
- _this.imgSrc = image;
- _this.headline = headline;
- return _this;
- }
- MainMenuItem.prototype.createItem = function () {
- var item = document.createElement("LI");
- item.setAttribute("onclick", "javascript: openThisMenu(this)");
- item.setAttribute("id", this.id);
- var img = this.createIMG(this.imgSrc);
- var value = this.createValue(this.value);
- item.appendChild(img);
- item.appendChild(value);
- var doc = document.getElementById(this.DocumentID);
- doc.appendChild(item);
- switch (this.menuKey) {
- case "playlist":
- this.tableHeader = ["{{.playlist.table.playlist}}", "{{.playlist.table.tuner}}", "{{.playlist.table.lastUpdate}}", "{{.playlist.table.availability}} %", "{{.playlist.table.type}}", "{{.playlist.table.streams}}", "{{.playlist.table.groupTitle}} %", "{{.playlist.table.tvgID}} %", "{{.playlist.table.uniqueID}} %"];
- break;
- case "xmltv":
- this.tableHeader = ["{{.xmltv.table.guide}}", "{{.xmltv.table.lastUpdate}}", "{{.xmltv.table.availability}} %", "{{.xmltv.table.channels}}", "{{.xmltv.table.programs}}"];
- break;
- case "filter":
- this.tableHeader = ["{{.filter.table.name}}", "{{.filter.table.type}}", "{{.filter.table.filter}}"];
- break;
- case "users":
- this.tableHeader = ["{{.users.table.username}}", "{{.users.table.password}}", "{{.users.table.web}}", "{{.users.table.pms}}", "{{.users.table.m3u}}", "{{.users.table.xml}}", "{{.users.table.api}}"];
- break;
- case "mapping":
- this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}"];
- break;
- }
- //console.log(this.menuKey, this.tableHeader);
- };
- return MainMenuItem;
-}(MainMenu));
-var Content = /** @class */ (function () {
- function Content() {
- this.DocumentID = "content";
- this.TableID = "content_table";
- this.headerClass = "content_table_header";
- this.interactionID = "content-interaction";
- }
- Content.prototype.createHeadline = function (value) {
- var element = document.createElement("H3");
- element.innerHTML = value;
- return element;
- };
- Content.prototype.createHR = function () {
- var element = document.createElement("HR");
- return element;
- };
- Content.prototype.createInteraction = function () {
- var element = document.createElement("DIV");
- element.setAttribute("id", this.interactionID);
- return element;
- };
- Content.prototype.createDIV = function () {
- var element = document.createElement("DIV");
- element.id = this.DivID;
- return element;
- };
- Content.prototype.createTABLE = function () {
- var element = document.createElement("TABLE");
- element.id = this.TableID;
- return element;
- };
- Content.prototype.createTableRow = function () {
- var element = document.createElement("TR");
- element.className = this.headerClass;
- return element;
- };
- Content.prototype.createTableContent = function (menuKey) {
- var data = new Object();
- var rows = new Array();
- switch (menuKey) {
- case "playlist":
- var fileTypes = new Array("m3u", "hdhr");
- fileTypes.forEach(function (fileType) {
- data = SERVER["settings"]["files"][fileType];
- var keys = getObjKeys(data);
- keys.forEach(function (key) {
- var tr = document.createElement("TR");
- tr.id = key;
- tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)');
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["name"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (SERVER["settings"]["buffer"] != "-") {
- cell.value = data[key]["tuner"];
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["last.update"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["provider.availability"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["type"].toUpperCase();
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["streams"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["group.title"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["tvg.id"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["stream.id"];
- tr.appendChild(cell.createCell());
- rows.push(tr);
- });
- });
- break;
- case "filter":
- delete SERVER["settings"]["filter"][-1];
- data = SERVER["settings"]["filter"];
- var keys = getObjKeys(data);
- keys.forEach(function (key) {
- var tr = document.createElement("TR");
- tr.id = key;
- tr.setAttribute('onclick', 'javascript: openPopUp("' + data[key]["type"] + '", this)');
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["name"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- switch (data[key]["type"]) {
- case "custom-filter":
- cell.value = "{{.filter.custom}}";
- break;
- case "group-title":
- cell.value = "{{.filter.group}}";
- break;
- default:
- break;
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["filter"];
- tr.appendChild(cell.createCell());
- rows.push(tr);
- });
- break;
- case "xmltv":
- var fileTypes = new Array("xmltv");
- fileTypes.forEach(function (fileType) {
- data = SERVER["settings"]["files"][fileType];
- var keys = getObjKeys(data);
- keys.forEach(function (key) {
- var tr = document.createElement("TR");
- tr.id = key;
- tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)');
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["name"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["last.update"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["provider.availability"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["xmltv.channels"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["compatibility"]["xmltv.programs"];
- tr.appendChild(cell.createCell());
- rows.push(tr);
- });
- });
- break;
- case "users":
- var fileTypes = new Array("users");
- fileTypes.forEach(function (fileType) {
- data = SERVER[fileType];
- var keys = getObjKeys(data);
- keys.forEach(function (key) {
- var tr = document.createElement("TR");
- tr.id = key;
- tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)');
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["data"]["username"];
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = "******";
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["data"]["authentication.web"] == true) {
- cell.value = "✓";
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["data"]["authentication.pms"] == true) {
- cell.value = "✓";
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["data"]["authentication.m3u"] == true) {
- cell.value = "✓";
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["data"]["authentication.xml"] == true) {
- cell.value = "✓";
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["data"]["authentication.api"] == true) {
- cell.value = "✓";
- }
- else {
- cell.value = "-";
- }
- tr.appendChild(cell.createCell());
- rows.push(tr);
- });
- });
- break;
- case "mapping":
- BULK_EDIT = false;
- createSearchObj();
- checkUndo("epgMapping");
- console.log("MAPPING");
- data = SERVER["xepg"]["epgMapping"];
- var keys = getObjKeys(data);
- keys.forEach(function (key) {
- var tr = document.createElement("TR");
- tr.id = key;
- //tr.setAttribute('oncontextmenu', 'javascript: rightClick(this)')
- switch (data[key]["x-active"]) {
- case true:
- tr.className = "activeEPG";
- break;
- case false:
- tr.className = "notActiveEPG";
- break;
- }
- // Bulk
- var cell = new Cell();
- cell.child = true;
- cell.childType = "BULK";
- cell.value = false;
- tr.appendChild(cell.createCell());
- // Kanalnummer
- var cell = new Cell();
- cell.child = true;
- cell.childType = "INPUTCHANNEL";
- cell.value = data[key]["x-channelID"];
- //td.setAttribute('onclick', 'javascript: changeChannelNumber("' + key + '", this)')
- tr.appendChild(cell.createCell());
- // Logo
- var cell = new Cell();
- cell.child = true;
- cell.childType = "IMG";
- cell.imageURL = data[key]["tvg-logo"];
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- // Kanalname
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.className = data[key]["x-category"];
- cell.value = data[key]["x-name"];
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- // Playlist
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- //cell.value = data[key]["_file.m3u.name"]
- cell.value = getValueFromProviderFile(data[key]["_file.m3u.id"], "m3u", "name");
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- // Gruppe (group-title)
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = data[key]["x-group-title"];
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- // XMLTV Datei
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- if (data[key]["x-xmltv-file"] != "-") {
- cell.value = getValueFromProviderFile(data[key]["x-xmltv-file"], "xmltv", "name");
- }
- else {
- cell.value = data[key]["x-xmltv-file"];
- }
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- // XMLTV Kanal
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- //var value = str.substring(1, 4);
- var value = data[key]["x-mapping"];
- if (value.length > 20) {
- value = data[key]["x-mapping"].substring(0, 20) + "...";
- }
- cell.value = value;
- var td = cell.createCell();
- td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)');
- td.id = key;
- tr.appendChild(td);
- rows.push(tr);
- });
- break;
- case "settings":
- alert();
- break;
- default:
- console.log("Table content (menuKey):", menuKey);
- break;
- }
- return rows;
- };
- return Content;
-}());
-var Cell = /** @class */ (function () {
- function Cell() {
- }
- Cell.prototype.createCell = function () {
- var td = document.createElement("TD");
- if (this.child == true) {
- var element;
- switch (this.childType) {
- case "P":
- element = document.createElement(this.childType);
- element.innerHTML = this.value;
- element.className = this.className;
- break;
- case "INPUT":
- element = document.createElement(this.childType);
- element.value = this.value;
- element.type = "text";
- break;
- case "INPUTCHANNEL":
- element = document.createElement("INPUT");
- element.setAttribute("onchange", "javscript: changeChannelNumber(this)");
- element.value = this.value;
- element.type = "text";
- break;
- case "BULK":
- element = document.createElement("INPUT");
- element.checked = this.value;
- element.type = "checkbox";
- element.className = "bulk hideBulk";
- break;
- case "BULK_HEAD":
- element = document.createElement("INPUT");
- element.checked = this.value;
- element.type = "checkbox";
- element.className = "bulk hideBulk";
- element.setAttribute("onclick", "javascript: selectAllChannels()");
- break;
- case "IMG":
- element = document.createElement(this.childType);
- element.setAttribute("src", this.imageURL);
- if (this.imageURL != "") {
- element.setAttribute("onerror", "javascript: this.onerror=null;this.src=''");
- //onerror="this.onerror=null;this.src='missing.gif';"
- }
- }
- td.appendChild(element);
- }
- else {
- td.innerHTML = this.value;
- }
- if (this.onclick == true) {
- td.setAttribute("onclick", this.onclickFunktion);
- td.className = "pointer";
- }
- if (this.tdClassName != undefined) {
- td.className = this.tdClassName;
- }
- return td;
- };
- return Cell;
-}());
-var ShowContent = /** @class */ (function (_super) {
- __extends(ShowContent, _super);
- function ShowContent(menuID) {
- var _this = _super.call(this) || this;
- _this.menuID = menuID;
- return _this;
- }
- ShowContent.prototype.createInput = function (type, name, value) {
- var input = document.createElement("INPUT");
- input.setAttribute("type", type);
- input.setAttribute("name", name);
- input.setAttribute("value", value);
- return input;
- };
- ShowContent.prototype.show = function () {
- COLUMN_TO_SORT = -1;
- // Alten Inhalt löschen
- var doc = document.getElementById(this.DocumentID);
- doc.innerHTML = "";
- showPreview(false);
- // Überschrift
- var headline = menuItems[this.menuID].headline;
- var menuKey = menuItems[this.menuID].menuKey;
- var h = this.createHeadline(headline);
- doc.appendChild(h);
- var hr = this.createHR();
- doc.appendChild(hr);
- // Interaktion
- var div = this.createInteraction();
- doc.appendChild(div);
- var interaction = document.getElementById(this.interactionID);
- switch (menuKey) {
- case "playlist":
- var input = this.createInput("button", menuKey, "{{.button.new}}");
- input.setAttribute("id", "-");
- input.setAttribute("onclick", 'javascript: openPopUp("playlist")');
- interaction.appendChild(input);
- break;
- case "filter":
- var input = this.createInput("button", menuKey, "{{.button.new}}");
- input.setAttribute("id", -1);
- input.setAttribute("onclick", 'javascript: openPopUp("filter", this)');
- interaction.appendChild(input);
- break;
- case "xmltv":
- var input = this.createInput("button", menuKey, "{{.button.new}}");
- input.setAttribute("id", "xmltv");
- input.setAttribute("onclick", 'javascript: openPopUp("xmltv")');
- interaction.appendChild(input);
- break;
- case "users":
- var input = this.createInput("button", menuKey, "{{.button.new}}");
- input.setAttribute("id", "users");
- input.setAttribute("onclick", 'javascript: openPopUp("users")');
- interaction.appendChild(input);
- break;
- case "mapping":
- showElement("loading", true);
- var input = this.createInput("button", menuKey, "{{.button.save}}");
- input.setAttribute("onclick", 'javascript: savePopupData("mapping", "", "")');
- interaction.appendChild(input);
- var input = this.createInput("button", menuKey, "{{.button.bulkEdit}}");
- input.setAttribute("onclick", 'javascript: bulkEdit()');
- interaction.appendChild(input);
- var input = this.createInput("search", "search", "");
- input.setAttribute("id", "searchMapping");
- input.setAttribute("placeholder", "{{.button.search}}");
- input.className = "search";
- input.setAttribute("onchange", 'javascript: searchInMapping()');
- interaction.appendChild(input);
- break;
- case "settings":
- var input = this.createInput("button", menuKey, "{{.button.save}}");
- input.setAttribute("onclick", 'javascript: saveSettings();');
- interaction.appendChild(input);
- var input = this.createInput("button", menuKey, "{{.button.backup}}");
- input.setAttribute("onclick", 'javascript: backup();');
- interaction.appendChild(input);
- var input = this.createInput("button", menuKey, "{{.button.restore}}");
- input.setAttribute("onclick", 'javascript: restore();');
- interaction.appendChild(input);
- var wrapper = document.createElement("DIV");
- wrapper.setAttribute("id", "box-wrapper");
- doc.appendChild(wrapper);
- this.DivID = "content_settings";
- var settings = this.createDIV();
- wrapper.appendChild(settings);
- showSettings();
- return;
- break;
- case "log":
- var input = this.createInput("button", menuKey, "{{.button.resetLogs}}");
- input.setAttribute("onclick", 'javascript: resetLogs();');
- interaction.appendChild(input);
- var wrapper = document.createElement("DIV");
- wrapper.setAttribute("id", "box-wrapper");
- doc.appendChild(wrapper);
- this.DivID = "content_log";
- var logs = this.createDIV();
- wrapper.appendChild(logs);
- showLogs(true);
- return;
- break;
- case "logout":
- location.reload();
- document.cookie = "Token= ; expires = Thu, 01 Jan 1970 00:00:00 GMT";
- break;
- default:
- console.log("Show content (menuKey):", menuKey);
- break;
- }
- // Tabelle erstellen (falls benötigt)
- var tableHeader = menuItems[this.menuID].tableHeader;
- if (tableHeader.length > 0) {
- var wrapper = document.createElement("DIV");
- doc.appendChild(wrapper);
- wrapper.setAttribute("id", "box-wrapper");
- var table = this.createTABLE();
- wrapper.appendChild(table);
- var header = this.createTableRow();
- table.appendChild(header);
- // Kopfzeile der Tablle
- tableHeader.forEach(function (element) {
- var cell = new Cell();
- cell.child = true;
- cell.childType = "P";
- cell.value = element;
- if (element == "BULK") {
- cell.childType = "BULK_HEAD";
- cell.value = false;
- }
- if (menuKey == "mapping") {
- if (element == "{{.mapping.table.chNo}}") {
- cell.onclick = true;
- cell.onclickFunktion = "javascript: sortTable(1);";
- cell.tdClassName = "sortThis";
- }
- if (element == "{{.mapping.table.channelName}}") {
- cell.onclick = true;
- cell.onclickFunktion = "javascript: sortTable(3);";
- }
- if (element == "{{.mapping.table.playlist}}") {
- cell.onclick = true;
- cell.onclickFunktion = "javascript: sortTable(4);";
- }
- if (element == "{{.mapping.table.groupTitle}}") {
- cell.onclick = true;
- cell.onclickFunktion = "javascript: sortTable(5);";
- }
- }
- header.appendChild(cell.createCell());
- });
- table.appendChild(header);
- // Inhalt der Tabelle
- var rows = this.createTableContent(menuKey);
- rows.forEach(function (tr) {
- table.appendChild(tr);
- });
- }
- switch (menuKey) {
- case "mapping":
- sortTable(1);
- break;
- case "filter":
- showPreview(true);
- sortTable(0);
- break;
- default:
- COLUMN_TO_SORT = -1;
- sortTable(0);
- break;
- }
- showElement("loading", false);
- };
- return ShowContent;
-}(Content));
-function PageReady() {
- var server = new Server("getServerConfig");
- server.request(new Object());
- window.addEventListener("resize", function () {
- calculateWrapperHeight();
- }, true);
- setInterval(function () {
- updateLog();
- }, 10000);
- return;
-}
-function createLayout() {
- // Client Info
- var obj = SERVER["clientInfo"];
- var keys = getObjKeys(obj);
- for (var i = 0; i < keys.length; i++) {
- if (document.getElementById(keys[i])) {
- document.getElementById(keys[i]).innerHTML = obj[keys[i]];
- }
- }
- if (!document.getElementById("main-menu")) {
- return;
- }
- // Menü erstellen
- document.getElementById("main-menu").innerHTML = "";
- for (var i_1 = 0; i_1 < menuItems.length; i_1++) {
- menuItems[i_1].id = i_1;
- switch (menuItems[i_1]["menuKey"]) {
- case "users":
- case "logout":
- if (SERVER["settings"]["authentication.web"] == true) {
- menuItems[i_1].createItem();
- }
- break;
- case "mapping":
- case "xmltv":
- if (SERVER["clientInfo"]["epgSource"] == "XEPG") {
- menuItems[i_1].createItem();
- }
- break;
- default:
- menuItems[i_1].createItem();
- break;
- }
- }
- return;
-}
-function openThisMenu(element) {
- var id = element.id;
- var content = new ShowContent(id);
- content.show();
- calculateWrapperHeight();
- return;
-}
-var PopupWindow = /** @class */ (function () {
- function PopupWindow() {
- this.DocumentID = "popup-custom";
- this.InteractionID = "interaction";
- this.doc = document.getElementById(this.DocumentID);
- }
- PopupWindow.prototype.createTitle = function (title) {
- var td = document.createElement("TD");
- td.className = "left";
- td.innerHTML = title + ":";
- return td;
- };
- PopupWindow.prototype.createContent = function (element) {
- var td = document.createElement("TD");
- td.appendChild(element);
- return td;
- };
- PopupWindow.prototype.createInteraction = function () {
- var div = document.createElement("div");
- div.setAttribute("id", "popup-interaction");
- div.className = "interaction";
- this.doc.appendChild(div);
- };
- return PopupWindow;
-}());
-var PopupContent = /** @class */ (function (_super) {
- __extends(PopupContent, _super);
- function PopupContent() {
- var _this = _super !== null && _super.apply(this, arguments) || this;
- _this.table = document.createElement("TABLE");
- return _this;
- }
- PopupContent.prototype.createHeadline = function (headline) {
- this.doc.innerHTML = "";
- var element = document.createElement("H3");
- element.innerHTML = headline.toUpperCase();
- this.doc.appendChild(element);
- // Tabelle erstellen
- this.table = document.createElement("TABLE");
- this.doc.appendChild(this.table);
- };
- PopupContent.prototype.appendRow = function (title, element) {
- var tr = document.createElement("TR");
- // Bezeichnung
- if (title.length != 0) {
- tr.appendChild(this.createTitle(title));
- }
- // Content
- tr.appendChild(this.createContent(element));
- this.table.appendChild(tr);
- };
- PopupContent.prototype.createInput = function (type, name, value) {
- var input = document.createElement("INPUT");
- if (value == undefined) {
- value = "";
- }
- input.setAttribute("type", type);
- input.setAttribute("name", name);
- input.setAttribute("value", value);
- return input;
- };
- PopupContent.prototype.createCheckbox = function (name) {
- var input = document.createElement("INPUT");
- input.setAttribute("type", "checkbox");
- input.setAttribute("name", name);
- return input;
- };
- PopupContent.prototype.createSelect = function (text, values, set, dbKey) {
- var select = document.createElement("SELECT");
- select.setAttribute("name", dbKey);
- for (var i = 0; i < text.length; i++) {
- var option = document.createElement("OPTION");
- option.setAttribute("value", values[i]);
- option.innerText = text[i];
- select.appendChild(option);
- }
- if (set != "") {
- select.value = set;
- }
- if (set == undefined) {
- select.value = values[0];
- }
- return select;
- };
- PopupContent.prototype.selectOption = function (select, value) {
- //select.selectedOptions = value
- var s = select;
- s.options[s.selectedIndex].value = value;
- return select;
- };
- PopupContent.prototype.description = function (value) {
- var tr = document.createElement("TR");
- var td = document.createElement("TD");
- var span = document.createElement("PRE");
- span.innerHTML = value;
- tr.appendChild(td);
- tr.appendChild(this.createContent(span));
- this.table.appendChild(tr);
- };
- // Interaktion
- PopupContent.prototype.addInteraction = function (element) {
- var interaction = document.getElementById("popup-interaction");
- interaction.appendChild(element);
- };
- return PopupContent;
-}(PopupWindow));
-function openPopUp(dataType, element) {
- var data = new Object();
- var id;
- switch (element) {
- case undefined:
- switch (dataType) {
- case "group-title":
- if (id == undefined) {
- id = -1;
- }
- data = getLocalData("filter", id);
- data["type"] = "group-title";
- break;
- case "custom-filter":
- if (id == undefined) {
- id = -1;
- }
- data = getLocalData("filter", id);
- data["type"] = "custom-filter";
- break;
- default:
- data["id.provider"] = "-";
- data["type"] = dataType;
- id = "-";
- break;
- }
- break;
- default:
- id = element.id;
- data = getLocalData(dataType, id);
- break;
- }
- var content = new PopupContent();
- switch (dataType) {
- case "playlist":
- content.createHeadline("{{.playlist.playlistType.title}}");
- // Type
- var text = ["M3U", "HDHomeRun"];
- var values = ["javascript: openPopUp('m3u')", "javascript: openPopUp('hdhr')"];
- var select = content.createSelect(text, values, "", "type");
- select.setAttribute("id", "type");
- select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick")'); // changeButtonAction
- content.appendRow("{{.playlist.type.title}}", select);
- // Interaktion
- content.createInteraction();
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Weiter
- var input = content.createInput("button", "next", "{{.button.next}}");
- input.setAttribute("onclick", 'javascript: openPopUp("m3u")');
- input.setAttribute("id", 'next');
- content.addInteraction(input);
- break;
- case "m3u":
- content.createHeadline(dataType);
- // Name
- var dbKey = "name";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.name.placeholder}}");
- content.appendRow("{{.playlist.name.title}}", input);
- // Beschreibung
- var dbKey = "description";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.description.placeholder}}");
- content.appendRow("{{.playlist.description.title}}", input);
- // URL
- var dbKey = "file.source";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.fileM3U.placeholder}}");
- content.appendRow("{{.playlist.fileM3U.title}}", input);
- // Tuner
- if (SERVER["settings"]["buffer"] != "-") {
- var text = new Array();
- var values = new Array();
- for (var i = 1; i <= 100; i++) {
- text.push(i.toString());
- values.push(i.toString());
- }
- var dbKey = "tuner";
- var select = content.createSelect(text, values, data[dbKey], dbKey);
- select.setAttribute("onfocus", "javascript: return;");
- content.appendRow("{{.playlist.tuner.title}}", select);
- }
- else {
- var dbKey = "tuner";
- if (data[dbKey] == undefined) {
- data[dbKey] = 1;
- }
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("readonly", "true");
- input.className = "notAvailable";
- content.appendRow("{{.playlist.tuner.title}}", input);
- }
- content.description("{{.playlist.tuner.description}}");
- // Interaktion
- content.createInteraction();
- // Löschen
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "delete", "{{.button.delete}}");
- input.className = "delete";
- input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", true, 0)');
- content.addInteraction(input);
- }
- else {
- var input = content.createInput("button", "back", "{{.button.back}}");
- input.setAttribute("onclick", 'javascript: openPopUp("playlist")');
- content.addInteraction(input);
- }
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Aktualisieren
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "update", "{{.button.update}}");
- input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 1)');
- content.addInteraction(input);
- }
- // Speichern
- var input = content.createInput("button", "save", "{{.button.save}}");
- input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 0)');
- content.addInteraction(input);
- break;
- case "hdhr":
- content.createHeadline(dataType);
- // Name
- var dbKey = "name";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.name.placeholder}}");
- content.appendRow("{{.playlist.name.title}}", input);
- // Beschreibung
- var dbKey = "description";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.description.placeholder}}");
- content.appendRow("{{.playlist.description.placeholder}}", input);
- // URL
- var dbKey = "file.source";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.playlist.fileHDHR.placeholder}}");
- content.appendRow("{{.playlist.fileHDHR.title}}", input);
- // Tuner
- if (SERVER["settings"]["buffer"] != "-") {
- var text = new Array();
- var values = new Array();
- for (var i = 1; i <= 100; i++) {
- text.push(i.toString());
- values.push(i.toString());
- }
- var dbKey = "tuner";
- var select = content.createSelect(text, values, data[dbKey], dbKey);
- select.setAttribute("onfocus", "javascript: return;");
- content.appendRow("{{.playlist.tuner.title}}", select);
- }
- else {
- var dbKey = "tuner";
- if (data[dbKey] == undefined) {
- data[dbKey] = 1;
- }
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("readonly", "true");
- input.className = "notAvailable";
- content.appendRow("{{.playlist.tuner.title}}", input);
- }
- content.description("{{.playlist.tuner.description}}");
- // Interaktion
- content.createInteraction();
- // Löschen
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "delete", "{{.button.delete}}");
- input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", true, 0)');
- input.className = "delete";
- content.addInteraction(input);
- }
- else {
- var input = content.createInput("button", "back", "{{.button.back}}");
- input.setAttribute("onclick", 'javascript: openPopUp("playlist")');
- content.addInteraction(input);
- }
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Aktualisieren
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "update", "{{.button.update}}");
- input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 1)');
- content.addInteraction(input);
- }
- // Speichern
- var input = content.createInput("button", "save", "{{.button.save}}");
- input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 0)');
- content.addInteraction(input);
- break;
- case "filter":
- content.createHeadline(dataType);
- // Type
- var dbKey = "type";
- var text = ["M3U: " + "{{.filter.type.groupTitle}}", "xTeVe: " + "{{.filter.type.customFilter}}"];
- var values = ["javascript: openPopUp('group-title')", "javascript: openPopUp('custom-filter')"];
- var select = content.createSelect(text, values, "javascript: openPopUp('group-title')", dbKey);
- select.setAttribute("id", id);
- select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick");'); // changeButtonAction
- content.appendRow("{{.filter.type.title}}", select);
- // Interaktion
- content.createInteraction();
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Weiter
- var input = content.createInput("button", "next", "{{.button.next}}");
- input.setAttribute("onclick", 'javascript: openPopUp("group-title")');
- input.setAttribute("id", 'next');
- content.addInteraction(input);
- break;
- case "custom-filter":
- case "group-title":
- switch (dataType) {
- case "custom-filter":
- content.createHeadline("{{.filter.custom}}");
- break;
- case "group-title":
- content.createHeadline("{{.filter.group}}");
- break;
- }
- // Name
- var dbKey = "name";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.filter.name.placeholder}}");
- content.appendRow("{{.filter.name.title}}", input);
- // Beschreibung
- var dbKey = "description";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.filter.description.placeholder}}");
- content.appendRow("{{.filter.description.title}}", input);
- // Typ
- var dbKey = "type";
- var input = content.createInput("hidden", dbKey, data[dbKey]);
- content.appendRow("", input);
- var filterType = data[dbKey];
- switch (filterType) {
- case "custom-filter":
- // Groß- Kleinschreibung beachten
- var dbKey = "caseSensitive";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.filter.caseSensitive.title}}", input);
- // Filterregel (Benutzerdefiniert)
- var dbKey = "filter";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.filter.filterRule.placeholder}}");
- content.appendRow("{{.filter.filterRule.title}}", input);
- break;
- case "group-title":
- //alert(dbKey + " " + filterType)
- // Filter basierend auf den Gruppen in der M3U
- var dbKey = "filter";
- var groupsM3U = getLocalData("m3uGroups", "");
- var text = groupsM3U["text"];
- var values = groupsM3U["value"];
- var select = content.createSelect(text, values, data[dbKey], dbKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- content.appendRow("{{.filter.filterGroup.title}}", select);
- content.description("{{.filter.filterGroup.description}}");
- // Groß- Kleinschreibung beachten
- var dbKey = "caseSensitive";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.filter.caseSensitive.title}}", input);
- var dbKey = "include";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.filter.include.placeholder}}");
- content.appendRow("{{.filter.include.title}}", input);
- content.description("{{.filter.include.description}}");
- var dbKey = "exclude";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.filter.exclude.placeholder}}");
- content.appendRow("{{.filter.exclude.title}}", input);
- content.description("{{.filter.exclude.description}}");
- break;
- default:
- break;
- }
- // Interaktion
- content.createInteraction();
- // Löschen
- var input = content.createInput("button", "delete", "{{.button.delete}}");
- input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", true, 0)');
- input.className = "delete";
- content.addInteraction(input);
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Speichern
- var input = content.createInput("button", "save", "{{.button.save}}");
- input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", false, 0)');
- content.addInteraction(input);
- break;
- case "xmltv":
- content.createHeadline(dataType);
- // Name
- var dbKey = "name";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.xmltv.name.placeholder}}");
- content.appendRow("{{.xmltv.name.title}}", input);
- // Beschreibung
- var dbKey = "description";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.xmltv.description.placeholder}}");
- content.appendRow("{{.xmltv.description.title}}", input);
- // URL
- var dbKey = "file.source";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.xmltv.fileXMLTV.placeholder}}");
- content.appendRow("{{.xmltv.fileXMLTV.title}}", input);
- // Interaktion
- content.createInteraction();
- // Löschen
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "delete", "{{.button.delete}}");
- input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", true, 0)');
- input.className = "delete";
- content.addInteraction(input);
- }
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Aktualisieren
- if (data["id.provider"] != "-") {
- var input = content.createInput("button", "update", "{{.button.update}}");
- input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 1)');
- content.addInteraction(input);
- }
- // Speichern
- var input = content.createInput("button", "save", "{{.button.save}}");
- input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 0)');
- content.addInteraction(input);
- break;
- case "users":
- content.createHeadline("{{.mainMenu.item.users}}");
- // Benutzername
- var dbKey = "username";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.users.username.placeholder}}");
- content.appendRow("{{.users.username.title}}", input);
- // Neues Passwort
- var dbKey = "password";
- var input = content.createInput("password", dbKey, "");
- input.setAttribute("placeholder", "{{.users.password.placeholder}}");
- content.appendRow("{{.users.password.title}}", input);
- // Bestätigung
- var dbKey = "confirm";
- var input = content.createInput("password", dbKey, "");
- input.setAttribute("placeholder", "{{.users.confirm.placeholder}}");
- content.appendRow("{{.users.confirm.title}}", input);
- // Berechtigung WEB
- var dbKey = "authentication.web";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- if (data["defaultUser"] == true) {
- input.setAttribute("onclick", "javascript: return false");
- }
- content.appendRow("{{.users.web.title}}", input);
- // Berechtigung PMS
- var dbKey = "authentication.pms";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.users.pms.title}}", input);
- // Berechtigung M3U
- var dbKey = "authentication.m3u";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.users.m3u.title}}", input);
- // Berechtigung XML
- var dbKey = "authentication.xml";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.users.xml.title}}", input);
- // Berechtigung API
- var dbKey = "authentication.api";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- content.appendRow("{{.users.api.title}}", input);
- // Interaktion
- content.createInteraction();
- // Löschen
- if (data["defaultUser"] != true && id != "-") {
- var input = content.createInput("button", "delete", "{{.button.delete}}");
- input.className = "delete";
- input.setAttribute('onclick', 'javascript: savePopupData("' + dataType + '", "' + id + '", true, 0)');
- content.addInteraction(input);
- }
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Speichern
- var input = content.createInput("button", "save", "{{.button.save}}");
- input.setAttribute("onclick", 'javascript: savePopupData("' + dataType + '", "' + id + '", "false");');
- content.addInteraction(input);
- break;
- case "mapping":
- content.createHeadline("{{.mainMenu.item.mapping}}");
- // Aktiv
- var dbKey = "x-active";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- input.id = "active";
- //input.setAttribute("onchange", "javascript: this.className = 'changed'")
- input.setAttribute("onchange", "javascript: toggleChannelStatus('" + id + "', this)");
- content.appendRow("{{.mapping.active.title}}", input);
- // Kanalname
- var dbKey = "x-name";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- if (BULK_EDIT == true) {
- input.style.border = "solid 1px red";
- input.setAttribute("readonly", "true");
- }
- content.appendRow("{{.mapping.channelName.title}}", input);
- content.description(data["name"]);
- // Beschreibung
- var dbKey = "x-description";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("placeholder", "{{.mapping.description.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- content.appendRow("{{.mapping.description.title}}", input);
- // Aktualisierung des Kanalnamens
- if (data.hasOwnProperty("_uuid.key")) {
- if (data["_uuid.key"] != "") {
- var dbKey = "x-update-channel-name";
- var input = content.createCheckbox(dbKey);
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- input.checked = data[dbKey];
- content.appendRow("{{.mapping.updateChannelName.title}}", input);
- }
- }
- // Logo URL (Kanal)
- var dbKey = "tvg-logo";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- input.setAttribute("id", "channel-icon");
- content.appendRow("{{.mapping.channelLogo.title}}", input);
- // Aktualisierung des Kanallogos
- var dbKey = "x-update-channel-icon";
- var input = content.createCheckbox(dbKey);
- input.checked = data[dbKey];
- input.setAttribute("id", "update-icon");
- input.setAttribute("onchange", "javascript: this.className = 'changed'; changeChannelLogo('" + id + "');");
- content.appendRow("{{.mapping.updateChannelLogo.title}}", input);
- // Erweitern der EPG Kategorie
- var dbKey = "x-category";
- var text = ["-", "Kids (Emby only)", "News", "Movie", "Series", "Sports"];
- var values = ["", "Kids", "News", "Movie", "Series", "Sports"];
- var select = content.createSelect(text, values, data[dbKey], dbKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- content.appendRow("{{.mapping.epgCategory.title}}", select);
- // M3U Gruppentitel
- var dbKey = "x-group-title";
- var input = content.createInput("text", dbKey, data[dbKey]);
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- content.appendRow("{{.mapping.m3uGroupTitle.title}}", input);
- if (data["group-title"] != undefined) {
- content.description(data["group-title"]);
- }
- // XMLTV Datei
- var dbKey = "x-xmltv-file";
- var xmlFile = data[dbKey];
- var xmltv = new XMLTVFile();
- var select = xmltv.getFiles(data[dbKey]);
- select.setAttribute("name", dbKey);
- select.setAttribute("id", "popup-xmltv");
- select.setAttribute("onchange", "javascript: this.className = 'changed'; setXmltvChannel('" + id + "',this);");
- content.appendRow("{{.mapping.xmltvFile.title}}", select);
- var file = data[dbKey];
- // XMLTV Mapping
- var dbKey = "x-mapping";
- var xmltv = new XMLTVFile();
- var select = xmltv.getPrograms(file, data[dbKey]);
- select.setAttribute("name", dbKey);
- select.setAttribute("id", "popup-mapping");
- select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');");
- sortSelect(select);
- content.appendRow("{{.mapping.xmltvChannel.title}}", select);
- // Interaktion
- content.createInteraction();
- // Logo hochladen
- var input = content.createInput("button", "cancel", "{{.button.uploadLogo}}");
- input.setAttribute("onclick", 'javascript: uploadLogo();');
- content.addInteraction(input);
- // Abbrechen
- var input = content.createInput("button", "cancel", "{{.button.cancel}}");
- input.setAttribute("onclick", 'javascript: showElement("popup", false);');
- content.addInteraction(input);
- // Fertig
- var ids = new Array();
- ids = getAllSelectedChannels();
- if (ids.length == 0) {
- ids.push(id);
- }
- var input = content.createInput("button", "save", "{{.button.done}}");
- input.setAttribute("onclick", 'javascript: donePopupData("' + dataType + '", "' + ids + '", "false");');
- content.addInteraction(input);
- break;
- default:
- break;
- }
- showPopUpElement('popup-custom');
-}
-var XMLTVFile = /** @class */ (function () {
- function XMLTVFile() {
- }
- XMLTVFile.prototype.getFiles = function (set) {
- var fileIDs = getObjKeys(SERVER["xepg"]["xmltvMap"]);
- var values = new Array("-");
- var text = new Array("-");
- for (var i = 0; i < fileIDs.length; i++) {
- if (fileIDs[i] != "xTeVe Dummy") {
- values.push(getValueFromProviderFile(fileIDs[i], "xmltv", "file.xteve"));
- text.push(getValueFromProviderFile(fileIDs[i], "xmltv", "name"));
- }
- else {
- values.push(fileIDs[i]);
- text.push(fileIDs[i]);
- }
- }
- var select = document.createElement("SELECT");
- for (var i = 0; i < text.length; i++) {
- var option = document.createElement("OPTION");
- option.setAttribute("value", values[i]);
- option.innerText = text[i];
- select.appendChild(option);
- }
- if (set != "") {
- select.value = set;
- }
- return select;
- };
- XMLTVFile.prototype.getPrograms = function (file, set) {
- //var fileIDs:string[] = getObjKeys(SERVER["xepg"]["xmltvMap"])
- var values = getObjKeys(SERVER["xepg"]["xmltvMap"][file]);
- var text = new Array();
- var displayName;
- for (var i = 0; i < values.length; i++) {
- if (SERVER["xepg"]["xmltvMap"][file][values[i]].hasOwnProperty('display-name') == true) {
- displayName = SERVER["xepg"]["xmltvMap"][file][values[i]]["display-name"];
- }
- else {
- displayName = "-";
- }
- text[i] = displayName + " (" + values[i] + ")";
- }
- text.unshift("-");
- values.unshift("-");
- var select = document.createElement("SELECT");
- for (var i = 0; i < text.length; i++) {
- var option = document.createElement("OPTION");
- option.setAttribute("value", values[i]);
- option.innerText = text[i];
- select.appendChild(option);
- }
- if (set != "") {
- select.value = set;
- }
- if (select.value != set) {
- select.value = "-";
- }
- return select;
- };
- return XMLTVFile;
-}());
-function getValueFromProviderFile(file, fileType, key) {
- if (file == "xTeVe Dummy") {
- return file;
- }
- var fileID;
- var indicator = file.charAt(0);
- switch (indicator) {
- case "M":
- fileType = "m3u";
- fileID = file;
- break;
- case "H":
- fileType = "hdhr";
- fileID = file;
- break;
- case "X":
- fileType = "xmltv";
- fileID = file.substring(0, file.lastIndexOf('.'));
- break;
- }
- if (SERVER["settings"]["files"][fileType].hasOwnProperty(fileID) == true) {
- var data = SERVER["settings"]["files"][fileType][fileID];
- return data[key];
- }
- return;
-}
-function setXmltvChannel(id, element) {
- var xmltv = new XMLTVFile();
- var xmlFile = element.value;
- var tvgId = SERVER["xepg"]["epgMapping"][id]["tvg-id"];
- var td = document.getElementById("popup-mapping").parentElement;
- td.innerHTML = "";
- var select = xmltv.getPrograms(element.value, tvgId);
- select.setAttribute("name", "x-mapping");
- select.setAttribute("id", "popup-mapping");
- select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');");
- select.className = "changed";
- sortSelect(select);
- td.appendChild(select);
- checkXmltvChannel(id, select, xmlFile);
-}
-function checkXmltvChannel(id, element, xmlFile) {
- var value = element.value;
- var bool;
- var checkbox = document.getElementById('active');
- var channel = SERVER["xepg"]["epgMapping"][id];
- var updateLogo;
- if (value == "-") {
- bool = false;
- }
- else {
- bool = true;
- }
- checkbox.checked = bool;
- checkbox.className = "changed";
- console.log(xmlFile);
- // Kanallogo aktualisieren
- /*
- updateLogo = (document.getElementById("update-icon") as HTMLInputElement).checked
- console.log(updateLogo);
- */
- if (xmlFile != "xTeVe Dummy" && bool == true) {
- //(document.getElementById("update-icon") as HTMLInputElement).checked = true;
- //(document.getElementById("update-icon") as HTMLInputElement).className = "changed";
- console.log("ID", id);
- changeChannelLogo(id);
- return;
- }
- if (xmlFile == "xTeVe Dummy") {
- document.getElementById("update-icon").checked = false;
- document.getElementById("update-icon").className = "changed";
- }
- return;
-}
-function changeChannelLogo(id) {
- var updateLogo;
- var channel = SERVER["xepg"]["epgMapping"][id];
- var f = document.getElementById("popup-xmltv");
- var xmltvFile = f.options[f.selectedIndex].value;
- var m = document.getElementById("popup-mapping");
- var xMapping = m.options[m.selectedIndex].value;
- var xmltvLogo = SERVER["xepg"]["xmltvMap"][xmltvFile][xMapping]["icon"];
- updateLogo = document.getElementById("update-icon").checked;
- if (updateLogo == true && xmltvFile != "xTeVe Dummy") {
- if (SERVER["xepg"]["xmltvMap"][xmltvFile].hasOwnProperty(xMapping)) {
- var logo = xmltvLogo;
- }
- else {
- logo = channel["tvg-logo"];
- }
- var logoInput = document.getElementById("channel-icon");
- logoInput.value = logo;
- if (BULK_EDIT == false) {
- logoInput.className = "changed";
- }
- }
-}
-function savePopupData(dataType, id, remove, option) {
- if (dataType == "mapping") {
- var data = new Object();
- console.log("Save mapping data");
- cmd = "saveEpgMapping";
- data["epgMapping"] = SERVER["xepg"]["epgMapping"];
- console.log("SEND TO SERVER");
- var server = new Server(cmd);
- server.request(data);
- delete UNDO["epgMapping"];
- return;
- }
- console.log("Save popup data");
- var div = document.getElementById("popup-custom");
- var inputs = div.getElementsByTagName("TABLE")[0].getElementsByTagName("INPUT");
- var selects = div.getElementsByTagName("TABLE")[0].getElementsByTagName("SELECT");
- var input = new Object();
- var confirmMsg;
- for (var i = 0; i < selects.length; i++) {
- var name;
- name = selects[i].name;
- var value = selects[i].value;
- switch (name) {
- case "tuner":
- input[name] = parseInt(value);
- break;
- default:
- input[name] = value;
- break;
- }
- }
- for (var i = 0; i < inputs.length; i++) {
- switch (inputs[i].type) {
- case "checkbox":
- name = inputs[i].name;
- input[name] = inputs[i].checked;
- break;
- case "text":
- case "hidden":
- case "password":
- name = inputs[i].name;
- switch (name) {
- case "tuner":
- input[name] = parseInt(inputs[i].value);
- break;
- default:
- input[name] = inputs[i].value;
- break;
- }
- break;
- }
- }
- var data = new Object();
- var cmd;
- if (remove == true) {
- input["delete"] = true;
- }
- switch (dataType) {
- case "users":
- confirmMsg = "Delete this user?";
- if (id == "-") {
- cmd = "saveNewUser";
- data["userData"] = input;
- }
- else {
- cmd = "saveUserData";
- var d = new Object();
- d[id] = input;
- data["userData"] = d;
- }
- break;
- case "m3u":
- confirmMsg = "Delete this playlist?";
- switch (option) {
- // Popup: Save
- case 0:
- cmd = "saveFilesM3U";
- break;
- // Popup: Update
- case 1:
- cmd = "updateFileM3U";
- break;
- }
- data["files"] = new Object;
- data["files"][dataType] = new Object;
- data["files"][dataType][id] = input;
- break;
- case "hdhr":
- confirmMsg = "Delete this HDHomeRun tuner?";
- switch (option) {
- // Popup: Save
- case 0:
- cmd = "saveFilesHDHR";
- break;
- // Popup: Update
- case 1:
- cmd = "updateFileHDHR";
- break;
- }
- data["files"] = new Object;
- data["files"][dataType] = new Object;
- data["files"][dataType][id] = input;
- break;
- case "xmltv":
- confirmMsg = "Delete this XMLTV file?";
- switch (option) {
- // Popup: Save
- case 0:
- cmd = "saveFilesXMLTV";
- break;
- // Popup: Update
- case 1:
- cmd = "updateFileXMLTV";
- break;
- }
- data["files"] = new Object;
- data["files"][dataType] = new Object;
- data["files"][dataType][id] = input;
- break;
- case "filter":
- confirmMsg = "Delete this filter?";
- cmd = "saveFilter";
- data["filter"] = new Object;
- data["filter"][id] = input;
- break;
- default:
- console.log(dataType, id);
- return;
- break;
- }
- if (remove == true) {
- if (!confirm(confirmMsg)) {
- showElement("popup", false);
- return;
- }
- }
- console.log("SEND TO SERVER");
- console.log(data);
- var server = new Server(cmd);
- server.request(data);
-}
-function donePopupData(dataType, idsStr) {
- var ids = idsStr.split(',');
- var div = document.getElementById("popup-custom");
- var inputs = div.getElementsByClassName("changed");
- ids.forEach(function (id) {
- var input = new Object();
- input = SERVER["xepg"]["epgMapping"][id];
- console.log(input);
- for (var i = 0; i < inputs.length; i++) {
- var name;
- var value;
- switch (inputs[i].tagName) {
- case "INPUT":
- switch (inputs[i].type) {
- case "checkbox":
- name = inputs[i].name;
- value = inputs[i].checked;
- input[name] = value;
- break;
- case "text":
- name = inputs[i].name;
- value = inputs[i].value;
- input[name] = value;
- break;
- }
- break;
- case "SELECT":
- name = inputs[i].name;
- value = inputs[i].value;
- input[name] = value;
- break;
- }
- switch (name) {
- case "tvg-logo":
- //(document.getElementById(id).childNodes[2].firstChild as HTMLElement).setAttribute("src", value)
- break;
- case "x-name":
- document.getElementById(id).childNodes[3].firstChild.innerHTML = value;
- break;
- case "x-category":
- document.getElementById(id).childNodes[3].firstChild.className = value;
- break;
- case "x-group-title":
- document.getElementById(id).childNodes[5].firstChild.innerHTML = value;
- break;
- case "x-xmltv-file":
- if (value != "xTeVe Dummy" && value != "-") {
- value = getValueFromProviderFile(value, "xmltv", "name");
- }
- if (value == "-") {
- input["x-active"] = false;
- }
- document.getElementById(id).childNodes[6].firstChild.innerHTML = value;
- break;
- case "x-mapping":
- if (value == "-") {
- input["x-active"] = false;
- }
- document.getElementById(id).childNodes[7].firstChild.innerHTML = value;
- break;
- default:
- }
- createSearchObj();
- searchInMapping();
- }
- if (input["x-active"] == false) {
- document.getElementById(id).className = "notActiveEPG";
- }
- else {
- document.getElementById(id).className = "activeEPG";
- }
- console.log(input["tvg-logo"]);
- document.getElementById(id).childNodes[2].firstChild.setAttribute("src", input["tvg-logo"]);
- });
- showElement("popup", false);
- return;
-}
-function showPreview(element) {
- var div = document.getElementById("myStreamsBox");
- switch (element) {
- case false:
- div.className = "notVisible";
- return;
- break;
- }
- var streams = ["activeStreams", "inactiveStreams"];
- streams.forEach(function (preview) {
- var table = document.getElementById(preview);
- table.innerHTML = "";
- var obj = SERVER["data"]["StreamPreviewUI"][preview];
- obj.forEach(function (channel) {
- var tr = document.createElement("TR");
- var tdKey = document.createElement("TD");
- var tdVal = document.createElement("TD");
- tdKey.className = "tdKey";
- tdVal.className = "tdVal";
- switch (preview) {
- case "activeStreams":
- tdKey.innerText = "Channel: (+)";
- break;
- case "inactiveStreams":
- tdKey.innerText = "Channel: (-)";
- break;
- }
- tdVal.innerText = channel;
- tr.appendChild(tdKey);
- tr.appendChild(tdVal);
- table.appendChild(tr);
- });
- });
- showElement("loading", false);
- div.className = "visible";
- return;
-}
diff --git a/html/js/network_ts.js b/html/js/network_ts.js
deleted file mode 100644
index 916e819..0000000
--- a/html/js/network_ts.js
+++ /dev/null
@@ -1,105 +0,0 @@
-var Server = /** @class */ (function () {
- function Server(cmd) {
- this.cmd = cmd;
- }
- Server.prototype.request = function (data) {
- if (SERVER_CONNECTION == true) {
- return;
- }
- SERVER_CONNECTION = true;
- console.log(data);
- if (this.cmd != "updateLog") {
- showElement("loading", true);
- UNDO = new Object();
- }
- switch (window.location.protocol) {
- case "http:":
- this.protocol = "ws://";
- break;
- case "https:":
- this.protocol = "wss://";
- break;
- }
- var url = this.protocol + window.location.hostname + ":" + window.location.port + "/data/" + "?Token=" + getCookie("Token");
- data["cmd"] = this.cmd;
- var ws = new WebSocket(url);
- ws.onopen = function () {
- WS_AVAILABLE = true;
- console.log("REQUEST (JS):");
- console.log(data);
- console.log("REQUEST: (JSON)");
- console.log(JSON.stringify(data));
- this.send(JSON.stringify(data));
- };
- ws.onerror = function (e) {
- console.log("No websocket connection to xTeVe could be established. Check your network configuration.");
- SERVER_CONNECTION = false;
- if (WS_AVAILABLE == false) {
- alert("No websocket connection to xTeVe could be established. Check your network configuration.");
- }
- };
- ws.onmessage = function (e) {
- SERVER_CONNECTION = false;
- showElement("loading", false);
- console.log("RESPONSE:");
- var response = JSON.parse(e.data);
- console.log(response);
- if (response.hasOwnProperty("token")) {
- document.cookie = "Token=" + response["token"];
- }
- if (response["status"] == false) {
- alert(response["err"]);
- if (response.hasOwnProperty("reload")) {
- location.reload();
- }
- return;
- }
- if (response.hasOwnProperty("logoURL")) {
- var div = document.getElementById("channel-icon");
- div.value = response["logoURL"];
- div.className = "changed";
- return;
- }
- switch (data["cmd"]) {
- case "updateLog":
- SERVER["log"] = response["log"];
- if (document.getElementById("content_log")) {
- showLogs(false);
- }
- return;
- break;
- default:
- SERVER = new Object();
- SERVER = response;
- break;
- }
- if (response.hasOwnProperty("openMenu")) {
- var menu = document.getElementById(response["openMenu"]);
- menu.click();
- showElement("popup", false);
- }
- if (response.hasOwnProperty("openLink")) {
- window.location = response["openLink"];
- }
- if (response.hasOwnProperty("alert")) {
- alert(response["alert"]);
- }
- if (response.hasOwnProperty("reload")) {
- location.reload();
- }
- if (response.hasOwnProperty("wizard")) {
- createLayout();
- configurationWizard[response["wizard"]].createWizard();
- return;
- }
- createLayout();
- };
- };
- return Server;
-}());
-function getCookie(name) {
- var value = "; " + document.cookie;
- var parts = value.split("; " + name + "=");
- if (parts.length == 2)
- return parts.pop().split(";").shift();
-}
diff --git a/html/js/settings_ts.js b/html/js/settings_ts.js
deleted file mode 100644
index f0f1fdb..0000000
--- a/html/js/settings_ts.js
+++ /dev/null
@@ -1,513 +0,0 @@
-var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-})();
-var SettingsCategory = /** @class */ (function () {
- function SettingsCategory() {
- this.DocumentID = "content_settings";
- }
- SettingsCategory.prototype.createCategoryHeadline = function (value) {
- var element = document.createElement("H4");
- element.innerHTML = value;
- return element;
- };
- SettingsCategory.prototype.createHR = function () {
- var element = document.createElement("HR");
- return element;
- };
- SettingsCategory.prototype.createSettings = function (settingsKey) {
- var setting = document.createElement("TR");
- var content = new PopupContent();
- var data = SERVER["settings"][settingsKey];
- switch (settingsKey) {
- // Texteingaben
- case "update":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.update.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "update", data.toString());
- input.setAttribute("placeholder", "{{.settings.update.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "backup.path":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.backupPath.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "backup.path", data);
- input.setAttribute("placeholder", "{{.settings.backupPath.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "temp.path":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.tempPath.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "temp.path", data);
- input.setAttribute("placeholder", "{{.settings.tmpPath.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "user.agent":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.userAgent.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "user.agent", data);
- input.setAttribute("placeholder", "{{.settings.userAgent.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "buffer.timeout":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.bufferTimeout.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "buffer.timeout", data);
- input.setAttribute("placeholder", "{{.settings.bufferTimeout.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "ffmpeg.path":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.ffmpegPath.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "ffmpeg.path", data);
- input.setAttribute("placeholder", "{{.settings.ffmpegPath.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "ffmpeg.options":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.ffmpegOptions.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "ffmpeg.options", data);
- input.setAttribute("placeholder", "{{.settings.ffmpegOptions.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "vlc.path":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.vlcPath.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "vlc.path", data);
- input.setAttribute("placeholder", "{{.settings.vlcPath.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "vlc.options":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.vlcOptions.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "vlc.options", data);
- input.setAttribute("placeholder", "{{.settings.vlcOptions.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- // Checkboxen
- case "authentication.web":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.authenticationWEB.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "authentication.pms":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.authenticationPMS.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "authentication.m3u":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.authenticationM3U.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "authentication.xml":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.authenticationXML.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "authentication.api":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.authenticationAPI.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "files.update":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.filesUpdate.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "cache.images":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.cacheImages.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "xepg.replace.missing.images":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.replaceEmptyImages.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "xteveAutoUpdate":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.xteveAutoUpdate.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "api":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.api.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createCheckbox(settingsKey);
- input.checked = data;
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- // Select
- case "tuner":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.tuner.title}}" + ":";
- var tdRight = document.createElement("TD");
- var text = new Array();
- var values = new Array();
- for (var i = 1; i <= 100; i++) {
- text.push(i);
- values.push(i);
- }
- var select = content.createSelect(text, values, data, settingsKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(select);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "epgSource":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.epgSource.title}}" + ":";
- var tdRight = document.createElement("TD");
- var text = ["PMS", "XEPG"];
- var values = ["PMS", "XEPG"];
- var select = content.createSelect(text, values, data, settingsKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(select);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "backup.keep":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.backupKeep.title}}" + ":";
- var tdRight = document.createElement("TD");
- var text = ["5", "10", "20", "30", "40", "50"];
- var values = ["5", "10", "20", "30", "40", "50"];
- var select = content.createSelect(text, values, data, settingsKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(select);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "buffer.size.kb":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.bufferSize.title}}" + ":";
- var tdRight = document.createElement("TD");
- var text = ["0.5 MB", "1 MB", "2 MB", "3 MB", "4 MB", "5 MB", "6 MB", "7 MB", "8 MB"];
- var values = ["512", "1024", "2048", "3072", "4096", "5120", "6144", "7168", "8192"];
- var select = content.createSelect(text, values, data, settingsKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(select);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "buffer":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.streamBuffering.title}}" + ":";
- var tdRight = document.createElement("TD");
- var text = ["{{.settings.streamBuffering.info_false}}", "xTeVe: ({{.settings.streamBuffering.info_xteve}})", "FFmpeg: ({{.settings.streamBuffering.info_ffmpeg}})", "VLC: ({{.settings.streamBuffering.info_vlc}})"];
- var values = ["-", "xteve", "ffmpeg", "vlc"];
- var select = content.createSelect(text, values, data, settingsKey);
- select.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(select);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- case "udpxy":
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "{{.settings.udpxy.title}}" + ":";
- var tdRight = document.createElement("TD");
- var input = content.createInput("text", "udpxy", data);
- input.setAttribute("placeholder", "{{.settings.udpxy.placeholder}}");
- input.setAttribute("onchange", "javascript: this.className = 'changed'");
- tdRight.appendChild(input);
- setting.appendChild(tdLeft);
- setting.appendChild(tdRight);
- break;
- }
- return setting;
- };
- SettingsCategory.prototype.createDescription = function (settingsKey) {
- var description = document.createElement("TR");
- var text;
- switch (settingsKey) {
- case "authentication.web":
- text = "{{.settings.authenticationWEB.description}}";
- break;
- case "authentication.m3u":
- text = "{{.settings.authenticationM3U.description}}";
- break;
- case "authentication.pms":
- text = "{{.settings.authenticationPMS.description}}";
- break;
- case "authentication.xml":
- text = "{{.settings.authenticationXML.description}}";
- break;
- case "authentication.api":
- if (SERVER["settings"]["authentication.web"] == true) {
- text = "{{.settings.authenticationAPI.description}}";
- }
- break;
- case "xteveAutoUpdate":
- text = "{{.settings.xteveAutoUpdate.description}}";
- break;
- case "backup.keep":
- text = "{{.settings.backupKeep.description}}";
- break;
- case "backup.path":
- text = "{{.settings.backupPath.description}}";
- break;
- case "temp.path":
- text = "{{.settings.tempPath.description}}";
- break;
- case "buffer":
- text = "{{.settings.streamBuffering.description}}";
- break;
- case "buffer.size.kb":
- text = "{{.settings.bufferSize.description}}";
- break;
- case "buffer.timeout":
- text = "{{.settings.bufferTimeout.description}}";
- break;
- case "user.agent":
- text = "{{.settings.userAgent.description}}";
- break;
- case "ffmpeg.path":
- text = "{{.settings.ffmpegPath.description}}";
- break;
- case "ffmpeg.options":
- text = "{{.settings.ffmpegOptions.description}}";
- break;
- case "vlc.path":
- text = "{{.settings.vlcPath.description}}";
- break;
- case "vlc.options":
- text = "{{.settings.vlcOptions.description}}";
- break;
- case "epgSource":
- text = "{{.settings.epgSource.description}}";
- break;
- case "tuner":
- text = "{{.settings.tuner.description}}";
- break;
- case "update":
- text = "{{.settings.update.description}}";
- break;
- case "api":
- text = "{{.settings.api.description}}";
- break;
- case "files.update":
- text = "{{.settings.filesUpdate.description}}";
- break;
- case "cache.images":
- text = "{{.settings.cacheImages.description}}";
- break;
- case "xepg.replace.missing.images":
- text = "{{.settings.replaceEmptyImages.description}}";
- break;
- case "udpxy":
- text = "{{.settings.udpxy.description}}";
- break;
- default:
- text = "";
- break;
- }
- var tdLeft = document.createElement("TD");
- tdLeft.innerHTML = "";
- var tdRight = document.createElement("TD");
- var pre = document.createElement("PRE");
- pre.innerHTML = text;
- tdRight.appendChild(pre);
- description.appendChild(tdLeft);
- description.appendChild(tdRight);
- return description;
- };
- return SettingsCategory;
-}());
-var SettingsCategoryItem = /** @class */ (function (_super) {
- __extends(SettingsCategoryItem, _super);
- function SettingsCategoryItem(headline, settingsKeys) {
- var _this = _super.call(this) || this;
- _this.headline = headline;
- _this.settingsKeys = settingsKeys;
- return _this;
- }
- SettingsCategoryItem.prototype.createCategory = function () {
- var _this = this;
- var headline = this.createCategoryHeadline(this.headline);
- var settingsKeys = this.settingsKeys;
- var doc = document.getElementById(this.DocumentID);
- doc.appendChild(headline);
- // Tabelle für die Kategorie erstellen
- var table = document.createElement("TABLE");
- var keys = settingsKeys.split(",");
- keys.forEach(function (settingsKey) {
- switch (settingsKey) {
- case "authentication.pms":
- case "authentication.m3u":
- case "authentication.xml":
- case "authentication.api":
- if (SERVER["settings"]["authentication.web"] == false) {
- break;
- }
- default:
- var item = _this.createSettings(settingsKey);
- var description = _this.createDescription(settingsKey);
- table.appendChild(item);
- table.appendChild(description);
- break;
- }
- });
- doc.appendChild(table);
- doc.appendChild(this.createHR());
- };
- return SettingsCategoryItem;
-}(SettingsCategory));
-function showSettings() {
- console.log("SETTINGS");
- for (var i = 0; i < settingsCategory.length; i++) {
- settingsCategory[i].createCategory();
- }
-}
-function saveSettings() {
- console.log("Save Settings");
- var cmd = "saveSettings";
- var div = document.getElementById("content_settings");
- var settings = div.getElementsByClassName("changed");
- var newSettings = new Object();
- for (var i = 0; i < settings.length; i++) {
- var name;
- var value;
- switch (settings[i].tagName) {
- case "INPUT":
- switch (settings[i].type) {
- case "checkbox":
- name = settings[i].name;
- value = settings[i].checked;
- newSettings[name] = value;
- break;
- case "text":
- name = settings[i].name;
- value = settings[i].value;
- switch (name) {
- case "update":
- value = value.split(",");
- value = value.filter(function (e) { return e; });
- break;
- case "buffer.timeout":
- value = parseFloat(value);
- }
- newSettings[name] = value;
- break;
- }
- break;
- case "SELECT":
- name = settings[i].name;
- value = settings[i].value;
- // Wenn der Wert eine Zahl ist, wird dieser als Zahl gespeichert
- if (isNaN(value)) {
- newSettings[name] = value;
- }
- else {
- newSettings[name] = parseInt(value);
- }
- break;
- }
- }
- var data = new Object();
- data["settings"] = newSettings;
- var server = new Server(cmd);
- server.request(data);
-}
diff --git a/html/js/users.js b/html/js/users.js
deleted file mode 100644
index 8cf9414..0000000
--- a/html/js/users.js
+++ /dev/null
@@ -1,341 +0,0 @@
-function openUsers(elm) {
- colomnSort = 0;
-
- var newDiv = document.getElementById("settings");
-
- var newEntry = new Object();
- newEntry["_element"] = "HR";
- newDiv.appendChild(createElement(newEntry));
-
- var newEntry = new Object();
- newEntry["_element"] = "INPUT";
- newEntry["type"] = "button";
- newEntry["class"] = "button";
- newEntry["value"] = "New";
- newEntry["onclick"] = "userDetail(0)";
- newDiv.appendChild(createElement(newEntry));
-
- var div = document.getElementById("settings");
-
- // Build table
- var newTable = new Object();
- newTable["_element"] = "TABLE";
- newTable["id"] = "id_mapping";
- newTable["class"] = "table-mapping";
- div.appendChild(createElement(newTable));
-
- setTimeout(function(){
- createUsersTable();
- }, 10);
-}
-
-function createUsersTable() {
- var table = document.getElementById("id_mapping");
- table.innerHTML = "";
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "table-mapping-header";
- table.appendChild(createElement(newTR));
-
- var tr = table.lastChild;
- var trHeadlines = new Array("Username", "Password", "WEB", "PMS", "M3U", "XML", "API")
-
- for (var i = 0; i < trHeadlines.length; i++) {
- var newTD = new Object();
- newTD["_element"] = "TD";
- newTD["_text"] = trHeadlines[i];
- tr.appendChild(createElement(newTD));
- }
-
-
- // Sort users
- var userIds = getObjKeys(users);
-
- var userObj = new Object();
-
- for (var i = 0; i < userIds.length; i++) {
- var username = users[userIds[i]]["data"]["username"];
- userObj[username] = userIds[i];
- }
-
- var allUsers = getObjKeys(userObj);
- allUsers.sort();
- // --
-
- for (var i = 0; i < allUsers.length; i++) {
- var table = document.getElementById("id_mapping");
- var userID = userObj[allUsers[i]];
- var username = allUsers[i];
- var item = users[userID]["data"];
-
- // Create TR
- var newTR = new Object();
- newTR["_element"] = "TR";
- newTR["class"] = "";
- newTR["id"] = userID;
- newTR["onclick"] = 'javascript: userDetail("' + userID + '");';
- table.appendChild(createElement(newTR));
-
- var tr = table.lastChild;
-
- // Create username TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = username;
- createNewTD(newTD, tr);
-
- // Create password TD
- var newTD = new Object();
- newTD["_element"] = "P";
- newTD["_text"] = ".....";
- createNewTD(newTD, tr);
-
- // Create web access
- var newTD = new Object();
- newTD["_element"] = "P";
- switch(item["authentication.web"]){
- case true: newTD["_text"] = "✓"; break;
- default: newTD["_text"] = "-"; break;
- }
- createNewTD(newTD, tr);
-
- // Create PMS access
- var newTD = new Object();
- newTD["_element"] = "P";
- switch(item["authentication.pms"]){
- case true: newTD["_text"] = "✓"; break;
- default: newTD["_text"] = "-"; break;
- }
- createNewTD(newTD, tr);
-
- // Create M3U access
- var newTD = new Object();
- newTD["_element"] = "P";
- switch(item["authentication.m3u"]){
- case true: newTD["_text"] = "✓"; break;
- default: newTD["_text"] = "-"; break;
- }
- createNewTD(newTD, tr);
-
- // Create XMLTV access
- var newTD = new Object();
- newTD["_element"] = "P";
- switch(item["authentication.xml"]){
- case true: newTD["_text"] = "✓"; break;
- default: newTD["_text"] = "-"; break;
- }
- createNewTD(newTD, tr);
-
- // Create API access
- var newTD = new Object();
- newTD["_element"] = "P";
-
- switch(item["authentication.api"]){
- case true: newTD["_text"] = "✓"; break;
- default: newTD["_text"] = "-"; break;
- }
- createNewTD(newTD, tr);
-
- }
-
- // usage Info
- var div = document.getElementById("settings");
- switch(menu[activeMenu.id].hasOwnProperty("_usage")) {
- case true:
- var usageItem = new Object();
- usageItem["_element"] = "PRE"
- usageItem["_text"] = menu[activeMenu.id]["_usage"];
-
- var newHR = new Object();
- newHR["_element"] = "HR"
- div.appendChild(createElement(newHR));
- div.appendChild(createElement(usageItem));
- }
-
- sortTable(0);
-}
-
-function userDetail(userID) {
- showPopUpElement('user-detail');
- setTimeout(function(){
- showElement("popup", true);
- }, 10);
- var defaultUser;
-
- document.getElementById("saveUserDetail").setAttribute("onclick", 'javascript: saveUserDetail("' + userID + '", false)');
- document.getElementById("deleteUserDetail").setAttribute("onclick", 'javascript: saveUserDetail("' + userID + '", true)');
-
- var data = new Object();
-
- switch(userID) {
- case 0: // New User
- data["username"] = "";
- data["authentication.web"] = false;
- data["authentication.pms"] = true;
- data["authentication.xml"] = true;
- data["authentication.m3u"] = false;
- data["authentication.api"] = false;
- data["defaultUser"] = false;
- setTimeout(function(){
- showElement("deleteUserDetail", false)
- }, 1);
-
- break;
-
- default:
- data = users[userID]["data"];
- showElement("deleteUserDetail", true)
- document.getElementById("deleteUserDetail").className = "delete";
-
- break
- }
-
-
- var username = data["username"];
- data["password"] = "";
- data["confirm"] = "";
-
- var keys = getObjKeys(data);
- defaultUser = data["defaultUser"];
- if (data.hasOwnProperty("defaultUser")) {
- defaultUser = JSON.parse(data["defaultUser"]);
- }
-
- for (var i = 0; i < keys.length; i++) {
-
- if(document.getElementById(keys[i])){
- var td = document.getElementById(keys[i])
- } else {
- var td = undefined;
- }
-
- var newItem = new Object();
-
- newItem["_element"] = "INPUT";
-
- newItem["value"] = data[keys[i]];
- newItem["name"] = keys[i];
-
-
-
-
-
- switch(keys[i].indexOf("authentication")) {
- case -1:
- if (keys[i] == "password" || keys[i] == "confirm") {
- newItem["type"] = "password";
- } else {
- newItem["type"] = "text";
- }
- break;
-
- default:
- newItem["type"] = "checkbox";
-
- if (keys[i] == "authentication.web" && defaultUser == true) {
- newItem["onclick"] = "return false";
- }
-
- if (data[keys[i]] == true) {
- newItem["checked"] = data[keys[i]];
- }
-
- break;
- }
-
- switch(keys[i]) {
- case "defaultUser":
- //if (data[keys[i]] == true) {
- newItem["type"] = "hidden";
- //}
- }
-
-
- if (td != undefined) {
- td.innerHTML = "";
- var element = createNewElement(newItem)
- //console.log(element);
- td.appendChild(element);
- }
-
-
- }
-
-
- if (defaultUser == true) {
- showElement("deleteUserDetail", false)
- } else {
- showElement("deleteUserDetail", true)
- document.getElementById("deleteUserDetail").className = "delete";
- }
-
-}
-
-function saveUserDetail(userID, deleteUser) {
-
- var inputs = document.getElementById("user-detail-table").getElementsByTagName("INPUT");
-
- var newUserData = new Object();
- for (var i = 0; i < inputs.length; i++) {
- switch(inputs[i].type) {
- case "checkbox": newUserData[inputs[i].name] = inputs[i].checked; break;
- default: newUserData[inputs[i].name] = inputs[i].value; break;
- }
-
- if (inputs["username"].value.length == 0) {
- inputs["username"].style.border = "solid 1px red";
- return;
- }
-
- switch(userID) {
- case "0":
- if (inputs["password"].value.length == 0) {
- console.log(inputs["password"].value.length);
- inputs["password"].style.border = "solid 1px red";
- return
- }
- break;
- }
-
- if (inputs["password"].value.length > 0) {
- if (inputs["password"].value != inputs["confirm"].value) {
- inputs["password"].style.border = "solid 1px red";
- inputs["confirm"].style.border = "solid 1px red";
- return;
- }
- }
-
- }
-
- var data = new Object();
-
- switch(userID) {
- case "0":
- //data = newUserData
- data["userData"] = newUserData
- data["cmd"] = "saveNewUser"; break;
-
- default:
- var thisUser = new Object();
-
- if (deleteUser == true) {
- if (confirm('Delete the selected user?')) {
- data["deleteUser"] = true;
- } else {
- showElement("popup", false);
- return
- }
- }
-
- thisUser[userID] = newUserData;
-
- data["userData"] = thisUser;
- data["cmd"] = "saveUserData"; break;
- }
-
- xTeVe(data);
- //createUsersTable()
- showElement("popup", false);
-}
-
-
diff --git a/html/lang/en.json b/html/lang/en.json
index 73c3d14..1a4756a 100644
--- a/html/lang/en.json
+++ b/html/lang/en.json
@@ -1,8 +1,6 @@
{
- "mainMenu":
- {
- "item":
- {
+ "mainMenu": {
+ "item": {
"playlist": "Playlist",
"pmsID": "PMS ID",
"filter": "Filter",
@@ -13,8 +11,7 @@
"log": "Log",
"logout": "Logout"
},
- "headline":
- {
+ "headline": {
"playlist": "Local or remote playlists",
"filter": "Filter playlist",
"xmltv": "Local or remote XMLTV files",
@@ -25,18 +22,15 @@
"logout": "Logout"
}
},
- "confirm":
- {
+ "confirm": {
"restore": "All data will be replaced with those from the backup. Should the files be restored?"
},
- "alert":
- {
+ "alert": {
"fileLoadingError": "File couldn't be loaded",
"invalidChannelNumber": "Invalid channel number",
"missingInput": "Missing input"
},
- "button":
- {
+ "button": {
"back": "Back",
"backup": "Backup",
"bulkEdit": "Bulk Edit",
@@ -54,70 +48,68 @@
"resetLogs": "Reset Logs",
"uploadLogo": "Upload Logo"
},
- "filter":
- {
- "table":
- {
+ "filter": {
+ "table": {
+ "startingChannel": "Starting Ch. No.",
"name": "Filter Name",
"type": "Filter Type",
"filter": "Filter"
},
"custom": "Custom",
- "group": "Group",
- "name":
- {
+ "group": "M3U Group",
+ "name": {
"title": "Filter Name",
"placeholder": "Filter name",
"description": ""
},
- "description":
- {
+ "description": {
"title": "Description",
"placeholder": "Description",
"description": ""
},
- "type":
- {
+ "type": {
"title": "Type",
"groupTitle": "Group Title",
"customFilter": "Custom Filter"
},
- "caseSensitive":
- {
+ "caseSensitive": {
"title": "Case Sensitive",
"placeholder": "",
"description": ""
},
- "filterRule":
- {
+ "filterRule": {
"title": "Filter Rule",
"placeholder": "Sport {HD} !{ES,IT}",
"description": ""
},
- "filterGroup":
- {
+ "filterGroup": {
"title": "Group Title",
"placeholder": "",
"description": "Select a M3U group. (Counter) Changing the group title in the M3U invalidates the filter."
},
- "include":
- {
+ "include": {
"title": "Include",
"placeholder": "FHD,UHD",
"description": "Channel name must include. (Comma separated) Comma means or"
},
- "exclude":
- {
+ "exclude": {
"title": "Exclude",
"placeholder": "ES,IT",
"description": "Channel name must not contain. (Comma separated) Comma means or"
+ },
+ "preserveMapping": {
+ "title": "Preserve Existing M3U Channel Numbers",
+ "palceholder": "",
+ "description": "Preserve existing M3U playlist channel numbers?"
+ },
+ "startingChannel": {
+ "title": "Starting Channel Number",
+ "placeholder": "",
+ "description": ""
}
-
},
- "playlist":
- {
- "table":
- {
+ "playlist": {
+ "table": {
"playlist": "Playlist",
"tuner": "Tuner",
"lastUpdate": "Last Update",
@@ -128,155 +120,151 @@
"tvgID": "tvg-id",
"uniqueID": "Unique ID"
},
- "playlistType":
- {
+ "playlistType": {
"title": "Playlist type",
"placeholder": "",
"description": ""
},
- "type":
- {
+ "type": {
"title": "Type",
"placeholder": "",
"description": ""
},
- "name":
- {
+ "name": {
"title": "Name",
"placeholder": "Playlist name",
"description": ""
},
- "description":
- {
+ "description": {
"title": "Description",
"placeholder": "Description",
"description": ""
},
- "fileM3U":
- {
+ "fileM3U": {
"title": "M3U File",
"placeholder": "File path or URL of the M3U",
"description": ""
},
- "fileHDHR":
- {
+ "fileHDHR": {
"title": "HDHomeRun IP",
"placeholder": "IP address and port (192.168.1.10:5004)",
"description": ""
},
- "tuner":
- {
+ "tuner": {
"title": "Tuner / Streams",
"placeholder": "",
"description": "Number of parallel connections that can be established to the provider. Only available with activated buffer. New settings will only be applied after quitting all streams."
}
},
- "xmltv":
- {
- "table":
- {
+ "xmltv": {
+ "table": {
"guide": "Guide",
"lastUpdate": "Last Update",
"availability": "Availability",
"channels": "Channels",
"programs": "Programs"
},
- "name":
- {
+ "name": {
"title": "Name",
"placeholder": "Guide name",
"description": ""
},
- "description":
- {
+ "description": {
"title": "Description",
"placeholder": "Description",
"description": ""
},
- "fileXMLTV":
- {
+ "fileXMLTV": {
"title": "XMLTV File",
"placeholder": "File path or URL of the XMLTV",
"description": ""
}
},
- "mapping":
- {
- "table":
- {
+ "mapping": {
+ "table": {
"chNo": "Ch. No.",
"logo": "Logo",
"channelName": "Channel Name",
+ "updateChannelNameRegex": "Upd. Rx.",
"playlist": "Playlist",
"groupTitle": "Group Title",
"xmltvFile": "XMLTV File",
- "xmltvID": "XMLTV ID"
+ "xmltvID": "XMLTV ID",
+ "timeshift": "Timeshift"
},
- "active":
- {
+ "active": {
"title": "Active",
"placeholder": "",
"description": ""
},
- "channelName":
- {
+ "channelName": {
"title": "Channel Name",
"placeholder": "",
"description": ""
},
- "description":
- {
+ "description": {
"title": "Channel Description",
"placeholder": "Used by the Dummy as an XML description",
"description": ""
},
- "updateChannelName":
- {
+ "updateChannelName": {
"title": "Update Channel Name",
"placeholder": "",
"description": ""
},
- "channelLogo":
- {
+ "updateChannelNameRegex": {
+ "title": "Channel name update regex",
+ "placeholder": "For example ^PPV[ \\\\-_]?1.*",
+ "description": "On update, if any new channel name matches this regex, rename current channel to the first matching name"
+ },
+ "updateChannelNameByGroupRegex": {
+ "title": "Only by group regex",
+ "placeholder": "",
+ "description": "Rename this channel only if current user-defined group matches this regex"
+ },
+ "updateChannelGroup": {
+ "title": "Update Channel Group",
+ "placeholder": "",
+ "description": "If checked, use group from the database"
+ },
+ "channelLogo": {
"title": "Logo URL",
"placeholder": "",
"description": ""
},
- "updateChannelLogo":
- {
- "title": "Update Channel Logo",
+ "updateChannelLogo": {
+ "title": "Use logo from M3U",
"placeholder": "",
"description": ""
},
- "epgCategory":
- {
+ "epgCategory": {
"title": "EPG Category",
"placeholder": "",
"description": ""
},
- "m3uGroupTitle":
- {
+ "m3uGroupTitle": {
"title": "Group Title (xteve.m3u)",
"placeholder": "",
"description": ""
},
- "xmltvFile":
- {
+ "xmltvFile": {
"title": "XMLTV File",
"placeholder": "",
"description": ""
},
- "xmltvChannel":
- {
+ "xmltvChannel": {
"title": "XMLTV Channel",
"placeholder": "",
"description": ""
+ },
+ "timeshift": {
+ "title": "Timeshift",
+ "placeholder": "0",
+ "description": ""
}
},
- "users":
- {
- "table":
- {
+ "users": {
+ "table": {
"username": "Username",
"password": "Password",
"web": "WEB",
@@ -285,262 +273,247 @@
"xml": "XML",
"api": "API"
},
- "username":
- {
+ "username": {
"title": "Username",
"placeholder": "Username",
"description": ""
},
- "password":
- {
+ "password": {
"title": "Password",
"placeholder": "Password",
"description": ""
},
- "confirm":
- {
+ "confirm": {
"title": "Confirm",
"placeholder": "Password confirm",
"description": ""
},
- "web":
- {
+ "web": {
"title": "Web Access",
"placeholder": "",
"description": ""
},
- "pms":
- {
+ "pms": {
"title": "PMS Access",
"placeholder": "",
"description": ""
},
- "m3u":
- {
+ "m3u": {
"title": "M3U Access",
"placeholder": "",
"description": ""
},
- "xml":
- {
+ "xml": {
"title": "XML Access",
"placeholder": "",
"description": ""
},
- "api":
- {
+ "api": {
"title": "API Access",
"placeholder": "",
"description": ""
}
},
- "settings":
- {
- "category":
- {
+ "settings": {
+ "category": {
"general": "General",
+ "mapping": "Mapping",
"files": "Files",
"streaming": "Streaming",
"backup": "Backup",
"authentication": "Authentication"
},
- "update":
- {
+ "update": {
"title": "Schedule for updating (Playlist, XMLTV, Backup)",
"placeholder": "0000,1000,2000",
"description": "Time in 24 hour format (0800 = 8:00 am). More times can be entered comma separated. Leave this field empty if no updates are to be carried out."
},
- "api":
- {
+ "api": {
"title": "API Interface",
"description": "Via API interface it is possible to send commands to xTeVe. API documentation is here"
},
- "epgSource":
- {
+ "clearXMLTVCache": {
+ "title": "Clear XMLTV cache",
+ "description": "If checked, do not keep XMLTV cache in memory. Significally reduces RAM usage in idle mode, but significally slowing down every subsequent update in XEPG database."
+ },
+ "defaultMissingEPG": {
+ "title": "Fill Missing EPG Data",
+ "description": "When there is no matching EPG data for channel, autofill with xTeVe dummy EPG data?"
+ },
+ "enableMappedChannels": {
+ "title": "Enable mapped channels",
+ "description": "Automatically enable channels with assigned EPG data"
+ },
+ "disallowURLDuplicates": {
+ "title": "Disallow URL duplicates",
+ "description": "If checked, do not add a new channel from playlist if channel with such URL already exists"
+ },
+ "epgSource": {
"title": "EPG Source",
"description": "PMS: - Use EPG data from Plex or Emby
XEPG: - Use of one or more XMLTV files - Channel management - M3U / XMLTV export (HTTP link for IPTV apps)"
},
- "tuner":
- {
+ "tuner": {
"title": "Number of Tuners",
"description": "Number of parallel connections that can be established to the provider. Available for: Plex, Emby (HDHR), M3U (with active buffer). After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again."
},
- "filesUpdate":
- {
+ "hostIP": {
+ "title": "Host IP",
+ "description": "IP address xTeVe will use to form M3U and XMLTV files"
+ },
+ "hostName": {
+ "title": "Host Name Override",
+ "description": "Hostname xTeVe will use to form M3U and XMLTV files. This will override Host IP if set"
+ },
+ "tlsMode": {
+ "title": "TLS (HTTPS) mode",
+ "description": "Changes web server protocol to HTTPS. For details, see https://github.com/SenexCrenshaw/xTeVe#tls-mode"
+ },
+ "filesUpdate": {
"title": "Updates all files at startup",
"description": "Updates all playlists, tuner and XMLTV files at startup."
},
- "cacheImages":
- {
+ "cacheImages": {
"title": "Image Caching",
"description": "All images from the XMLTV file are cached, allowing faster rendering of the grid in the client. Downloading the images may take a while and will be done in the background."
},
- "replaceEmptyImages":
- {
+ "replaceEmptyImages": {
"title": "Replace missing program images",
"description": "If the poster in the XMLTV program is missing, the channel logo will be used."
},
- "xteveAutoUpdate":
- {
+ "xteveAutoUpdate": {
"title": "Automatic update of xTeVe",
"description": "If a new version of xTeVe is available, it will be automatically installed. The updates are downloaded from GitHub."
},
- "streamBuffering":
- {
+ "streamBuffering": {
"title": "Stream Buffer",
"description": "Functions of the buffer: - The stream is passed from xTeVe, FFmpeg or VLC to Plex, Emby or M3U Player - Small jerking of the streams can be compensated - HLS / M3U8 support - RTP / RTPS support (only FFmpeg or VLC) - Re-streaming - Separate tuner limit for each playlist",
"info_false": "No Buffer (Client connects to the streaming server)",
"info_xteve": "xTeVe connects to the streaming server",
"info_ffmpeg": "FFmpeg connects to the streaming server",
"info_vlc": "VLC connects to the streaming server"
-
},
- "udpxy":
- {
+ "udpxy": {
"title": "UDPxy address",
"description": "The address of your UDPxy server. If set, and the channel URLs in the m3u is multicast, xTeVe will rewrite it so that it is accessed via the UDPxy service.",
"placeholder": "host:port"
},
- "ffmpegPath":
- {
+ "ffmpegPath": {
"title": "FFmpeg Binary Path",
"description": "Path to FFmpeg binary.",
"placeholder": "/path/to/ffmpeg"
},
- "ffmpegOptions":
- {
+ "ffmpegOptions": {
"title": "FFmpeg Options",
"description": "FFmpeg options. Only change if you know what you are doing. Leave blank to set default settings.",
"placeholder": "Leave blank to set default settings"
},
- "vlcPath":
- {
+ "vlcPath": {
"title": "VLC / CVLC Binary Path",
"description": "Path to VLC / CVLC binary.",
"placeholder": "/path/to/cvlc"
},
- "vlcOptions":
- {
+ "vlcOptions": {
"title": "VLC / CVLC Options",
"description": "VLC / CVLC options. Only change if you know what you are doing. Leave blank to set default settings.",
"placeholder": "Leave blank to set default settings"
},
- "bufferSize":
- {
+ "bufferSize": {
"title": "Buffer Size",
"description": "Buffer size in MB. M3U8: If the TS segment smaller then the buffer size, the file size of the segment is used."
},
- "bufferTimeout":
- {
+ "storeBufferInRAM": {
+ "title": "Store buffer in RAM",
+ "description": "If checked, write buffer to RAM instead of writing to disk"
+ },
+ "bufferTimeout": {
"title": "Timeout for new client connections",
"description": "The xTeVe buffer waits until new client connections are established. Helpful for fast channel switching. Value in milliseconds.",
"placeholder": "100"
},
- "userAgent":
- {
+ "userAgent": {
"title": "User Agent",
"description": "User Agent for HTTP requests. For every HTTP connection, this value is used for the user agent. Should only be changed if xTeVe is blocked.",
"placeholder": "xTeVe"
},
- "backupPath":
- {
+ "backupPath": {
"title": "Location for automatic backups",
"placeholder": "/mnt/data/backup/xteve/",
"description": "Before any update of the provider data by the schedule, xTeVe creates a backup. The path for the automatic backups can be changed. xTeVe requires write permission for this folder."
},
- "tempPath":
- {
+ "tempPath": {
"title": "Location for the temporary files",
"placeholder": "/tmp/xteve/",
"description": "Location for the buffer files."
},
- "backupKeep":
- {
+ "backupKeep": {
"title": "Number of backups to keep",
"description": "Number of backups to keep. Older backups are automatically deleted."
},
- "authenticationWEB":
- {
+ "authenticationWEB": {
"title": "WEB Authentication",
"description": "Access to the web interface only possible with credentials."
},
- "authenticationPMS":
- {
+ "authenticationPMS": {
"title": "PMS Authentication",
"description": "Plex requests are only possible with authentication. Warning!!! After activating this function xTeVe must be delete in the PMS DVR settings and set up again."
},
- "authenticationM3U":
- {
+ "authenticationM3U": {
"title": "M3U Authentication",
"description": "Downloading the xteve.m3u file via an HTTP request is only possible with authentication."
},
- "authenticationXML":
- {
+ "authenticationXML": {
"title": "XML Authentication",
"description": "Downloading the xteve.xml file via an HTTP request is only possible with authentication"
},
- "authenticationAPI":
- {
+ "authenticationAPI": {
"title": "API Authentication",
"description": "Access to the API interface is only possible with authentication."
}
},
- "wizard":
- {
- "epgSource":
- {
+ "wizard": {
+ "epgSource": {
"title": "EPG Source",
"description": "PMS: - Use EPG data from Plex or Emby
XEPG: - Use of one or more XMLTV files - Channel management - M3U / XMLTV export (HTTP link for IPTV apps)"
},
- "tuner":
- {
+ "tuner": {
"title": "Number of tuners",
"description": "Number of parallel connections that can be established to the provider. Available for: Plex, Emby (HDHR), M3U (with active buffer). After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again."
},
- "m3u":
- {
+ "m3u": {
"title": "M3U Playlist",
"placeholder": "File path or URL of the M3U",
"description": "Local or remote playlists"
},
- "xmltv":
- {
+ "xmltv": {
"title": "XMLTV File",
"placeholder": "File path or URL of the XMLTV",
"description": "Local or remote XMLTV file"
}
},
- "login":
- {
+ "login": {
"failed": "User authentication failed",
"headline": "Login",
- "username":
- {
+ "username": {
"title": "Username",
"placeholder": "Username"
},
- "password":
- {
+ "password": {
"title": "Password",
"placeholder": "Password"
}
},
- "account":
- {
+ "account": {
"failed": "Password does not match",
"headline": "Create user account",
- "username":
- {
+ "username": {
"title": "Username",
"placeholder": "Username"
},
- "password":
- {
+ "password": {
"title": "Password",
"placeholder": "Password"
},
- "confirm":
- {
+ "confirm": {
"title": "Confirm",
"placeholder": "Confirm"
}
diff --git a/html/login.html b/html/login.html
index a3e7042..9c1521f 100644
--- a/html/login.html
+++ b/html/login.html
@@ -1,46 +1,47 @@
-
-
-
-
- xTeVe
-
-
-
-
-
+
-
-
-
+
+
+
+ xTeVe
+
+
+
+
+
-
+
-
-
{{.login.headline}}
-
+
-
{{.authenticationErr}}
+
-
+
+
{{.login.headline}}
+
-
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
diff --git a/html/maintenance.html b/html/maintenance.html
index b1ba141..c55f54d 100644
--- a/html/maintenance.html
+++ b/html/maintenance.html
@@ -1,30 +1,32 @@
-
-
-
-
- xTeVe
-
-
-
-
-
-
-
-
-
-
-
-
Maintenance
-
-
-
- xTeVe is updating the database, please try again later.
-
-
-
-
-
-
-
+
+
+
+
+
+ xTeVe
+
+
+
+
+
+
+
+
+
+
+
+
Maintenance
+
+
+
+ xTeVe is updating the database, please try again later.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/release.json b/release.json
new file mode 100644
index 0000000..79426e8
--- /dev/null
+++ b/release.json
@@ -0,0 +1,4 @@
+{
+ "version": "2.5.1",
+ "go_version": "1.19.0"
+}
diff --git a/snap/hooks/pre-refresh b/snap/hooks/pre-refresh
new file mode 100755
index 0000000..bd6da56
--- /dev/null
+++ b/snap/hooks/pre-refresh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -ex
+
+# Check to see if the service is running
+SERVICE_STATUS=`snapctl services xteve.xteve | tail -1 | cut -d " " -f 5`
+if [ "$SERVICE_STATUS" != "active" ]; then
+ exit 0
+fi
+
+# Check to see if it is doing anything
+exec $SNAP/bin/xteve-inactive -port 8080
diff --git a/snap/local/scripts/restart-if-inactive b/snap/local/scripts/restart-if-inactive
new file mode 100755
index 0000000..ee8d4f4
--- /dev/null
+++ b/snap/local/scripts/restart-if-inactive
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+${SNAP}/bin/xteve-inactive -port 8080 && snapctl restart xteve.xteve
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
new file mode 100644
index 0000000..8e07259
--- /dev/null
+++ b/snap/snapcraft.yaml
@@ -0,0 +1,62 @@
+name: xteve
+base: core22
+summary: M3U Proxy for Plex DVR and Emby Live TV.
+adopt-info: xteve
+description: |
+ xTeVe emulates a DVR tuner for Plex and Emby. It takes an M3U files and
+ emulates a network tuner that can be discovered by those services. Provides
+ multiple tuners and caching proxy of streams. Can also take XMLTV files an
+ handle them internally for program guides.
+
+grade: stable
+confinement: strict
+
+parts:
+ xteve:
+ plugin: go
+ source: .
+ build-snaps:
+ - go
+ override-stage: |
+ snapcraftctl stage
+ snapcraftctl set-version `$SNAPCRAFT_STAGE/bin/xteve -version`
+ snap-scripts:
+ plugin: dump
+ source: snap/local/scripts
+ organize:
+ '*': bin/
+# vlc:
+# plugin: nil
+# stage-packages: [ "vlc-bin" ]
+ ffmpeg:
+ plugin: nil
+ stage-packages: [ "ffmpeg" ]
+
+apps:
+ xteve:
+ daemon: simple
+ command: bin/xteve -port 8080 -config $SNAP_COMMON/config -no-updates -debug 3
+ environment:
+ LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}:${SNAP}/usr/lib:${SNAP}/usr/lib/${SNAP_LAUNCHER_ARCH_TRIPLET}/pulseaudio/
+ plugs:
+ - network
+ - network-bind
+# restart:
+# daemon: oneshot
+# command: bin/restart-if-inactive
+# timer: 00:10-23:10/24
+# plugs:
+# - network
+ inactive:
+ command: bin/xteve-inactive -port 8080
+ plugs:
+ - network
+ status:
+ command: bin/xteve-status -port 8080
+ plugs:
+ - network
+
+hooks:
+ pre-refresh:
+ plugs:
+ - network
diff --git a/src/authentication.go b/src/authentication.go
index 1b15876..aae2e31 100644
--- a/src/authentication.go
+++ b/src/authentication.go
@@ -63,7 +63,7 @@ func createFirstUserForAuthentication(username, password string) (token string,
func tokenAuthentication(token string) (newToken string, err error) {
- if System.ConfigurationWizard == true {
+ if System.ConfigurationWizard {
return
}
@@ -74,7 +74,7 @@ func tokenAuthentication(token string) (newToken string, err error) {
func basicAuth(r *http.Request, level string) (username string, err error) {
- err = errors.New("User authentication failed")
+ err = errors.New("user authentication failed")
auth := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
@@ -109,7 +109,7 @@ func urlAuth(r *http.Request, requestType string) (err error) {
case "m3u":
level = "authentication.m3u"
- if Settings.AuthenticationM3U == true {
+ if Settings.AuthenticationM3U {
token, err = authentication.UserAuthentication(username, password)
if err != nil {
return
@@ -119,7 +119,7 @@ func urlAuth(r *http.Request, requestType string) (err error) {
case "xml":
level = "authentication.xml"
- if Settings.AuthenticationXML == true {
+ if Settings.AuthenticationXML {
token, err = authentication.UserAuthentication(username, password)
if err != nil {
return
@@ -150,19 +150,19 @@ func checkAuthorizationLevel(token, level string) (err error) {
if v, ok := userData[level].(bool); ok {
- if v == false {
- err = errors.New("No authorization")
+ if !v {
+ err = errors.New("no authorization")
}
} else {
userData[level] = false
- err = authentication.WriteUserData(userID, userData)
- err = errors.New("No authorization")
+ authentication.WriteUserData(userID, userData)
+ //err = errors.New("No authorization")
}
} else {
- err = authentication.WriteUserData(userID, userData)
- err = errors.New("No authorization")
+ authentication.WriteUserData(userID, userData)
+ //err = errors.New("No authorization")
}
return
diff --git a/src/backup.go b/src/backup.go
index 437fbcb..4899fa1 100644
--- a/src/backup.go
+++ b/src/backup.go
@@ -1,274 +1,285 @@
package src
import (
- b64 "encoding/base64"
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
+ b64 "encoding/base64"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
)
func xTeVeAutoBackup() (err error) {
- var archiv = "xteve_auto_backup_" + time.Now().Format("20060102_1504") + ".zip"
- var target string
- var sourceFiles = make([]string, 0)
- var oldBackupFiles = make([]string, 0)
- var debug string
+ var archive = "xteve_auto_backup_" + time.Now().Format("20060102_1504") + ".zip"
+ var target string
+ var sourceFiles = make([]string, 0)
+ var oldBackupFiles = make([]string, 0)
+ var debug string
- if len(Settings.BackupPath) > 0 {
- System.Folder.Backup = Settings.BackupPath
- }
+ if len(Settings.BackupPath) > 0 {
+ System.Folder.Backup = Settings.BackupPath
+ }
- showInfo("Backup Path:" + System.Folder.Backup)
+ showInfo("Backup Path:" + System.Folder.Backup)
- err = checkFolder(System.Folder.Backup)
- if err != nil {
- ShowError(err, 1070)
- return
- }
+ err = checkFolder(System.Folder.Backup)
+ if err != nil {
+ ShowError(err, 1070)
+ return
+ }
- // Alte Backups löschen
- files, err := ioutil.ReadDir(System.Folder.Backup)
+ // Delete Old Backups
+ files, err := ioutil.ReadDir(System.Folder.Backup)
- if err == nil {
+ if err == nil {
- for _, file := range files {
+ for _, file := range files {
- if filepath.Ext(file.Name()) == ".zip" && strings.Contains(file.Name(), "xteve_auto_backup") {
- oldBackupFiles = append(oldBackupFiles, file.Name())
- }
+ if filepath.Ext(file.Name()) == ".zip" && strings.Contains(file.Name(), "xteve_auto_backup") {
+ oldBackupFiles = append(oldBackupFiles, file.Name())
+ }
- }
+ }
- // Alle Backups löschen
- var end int
- switch Settings.BackupKeep {
- case 0:
- end = 0
- default:
- end = Settings.BackupKeep - 1
- }
+ // Delete All Backups
+ var end int
+ switch Settings.BackupKeep {
+ case 0:
+ end = 0
+ default:
+ end = Settings.BackupKeep - 1
+ }
- for i := 0; i < len(oldBackupFiles)-end; i++ {
+ for i := 0; i < len(oldBackupFiles)-end; i++ {
- os.RemoveAll(System.Folder.Backup + oldBackupFiles[i])
- debug = fmt.Sprintf("Delete backup file:%s", oldBackupFiles[i])
- showDebug(debug, 1)
+ os.RemoveAll(System.Folder.Backup + oldBackupFiles[i])
+ debug = fmt.Sprintf("Delete backup file:%s", oldBackupFiles[i])
+ showDebug(debug, 1)
- }
+ }
- if Settings.BackupKeep == 0 {
- return
- }
+ if Settings.BackupKeep == 0 {
+ return
+ }
- } else {
+ } else {
- return
+ return
- }
+ }
- // Backup erstellen
- if err == nil {
+ // Create a Backup
+ if err == nil {
- target = System.Folder.Backup + archiv
+ target = System.Folder.Backup + archive
- for _, i := range SystemFiles {
- sourceFiles = append(sourceFiles, System.Folder.Config+i)
- }
+ for _, i := range SystemFiles {
+ sourceFiles = append(sourceFiles, System.Folder.Config+i)
+ }
- sourceFiles = append(sourceFiles, System.Folder.ImagesUpload)
+ sourceFiles = append(sourceFiles, System.Folder.ImagesUpload)
+ if Settings.TLSMode {
+ sourceFiles = append(sourceFiles, System.Folder.Certificates)
+ }
- err = zipFiles(sourceFiles, target)
+ err = zipFiles(sourceFiles, target)
- if err == nil {
+ if err == nil {
- debug = fmt.Sprintf("Create backup file:%s", target)
- showDebug(debug, 1)
+ debug = fmt.Sprintf("Create backup file:%s", target)
+ showDebug(debug, 1)
- showInfo("Backup file:" + target)
+ showInfo("Backup file:" + target)
- }
+ }
- }
+ }
- return
+ return
}
-func xteveBackup() (archiv string, err error) {
+func xteveBackup() (archive string, err error) {
- err = checkFolder(System.Folder.Temp)
- if err != nil {
- return
- }
+ err = checkFolder(System.Folder.Temp)
+ if err != nil {
+ return
+ }
- archiv = "xteve_backup_" + time.Now().Format("20060102_1504") + ".zip"
+ archive = "xteve_backup_" + time.Now().Format("20060102_1504") + ".zip"
- var target = System.Folder.Temp + archiv
- var sourceFiles = make([]string, 0)
+ var target = System.Folder.Temp + archive
+ var sourceFiles = make([]string, 0)
- for _, i := range SystemFiles {
- sourceFiles = append(sourceFiles, System.Folder.Config+i)
- }
+ for _, i := range SystemFiles {
+ sourceFiles = append(sourceFiles, System.Folder.Config+i)
+ }
- sourceFiles = append(sourceFiles, System.Folder.Data)
+ sourceFiles = append(sourceFiles, System.Folder.Data)
+ if Settings.TLSMode {
+ sourceFiles = append(sourceFiles, System.Folder.Certificates)
+ }
- err = zipFiles(sourceFiles, target)
- if err != nil {
- ShowError(err, 0)
- return
- }
+ err = zipFiles(sourceFiles, target)
+ if err != nil {
+ ShowError(err, 0)
+ return
+ }
- return
+ return
}
func xteveRestore(archive string) (newWebURL string, err error) {
- var newPort, oldPort, backupVersion, tmpRestore string
+ var newPort, oldPort, backupVersion, tmpRestore string
- tmpRestore = System.Folder.Temp + "restore" + string(os.PathSeparator)
+ tmpRestore = System.Folder.Temp + "restore" + string(os.PathSeparator)
- err = checkFolder(tmpRestore)
- if err != nil {
- return
- }
+ defer os.RemoveAll(tmpRestore)
+ defer os.Remove(archive)
- // Zip Archiv in tmp entpacken
- err = extractZIP(archive, tmpRestore)
- if err != nil {
- return
- }
+ err = checkFolder(tmpRestore)
+ if err != nil {
+ return
+ }
- // Neue Config laden um den Port und die Version zu überprüfen
- newConfig, err := loadJSONFileToMap(tmpRestore + "settings.json")
- if err != nil {
- ShowError(err, 0)
- return
- }
+ // Unpack the ZIP Archive in tmp
+ err = extractZIP(archive, tmpRestore)
+ if err != nil {
+ return
+ }
- backupVersion = newConfig["version"].(string)
- if backupVersion < System.Compatibility {
- err = errors.New(getErrMsg(1013))
- return
- }
+ // Load a new Config to check the Port and Version
+ newConfig, err := loadJSONFileToMap(tmpRestore + "settings.json")
+ if err != nil {
+ ShowError(err, 0)
+ return
+ }
- // Zip Archiv in den Config Ordner entpacken
- err = extractZIP(archive, System.Folder.Config)
- if err != nil {
- return
- }
+ backupVersion = newConfig["version"].(string)
+ if backupVersion < System.Compatibility {
+ err = errors.New(getErrMsg(1013))
+ return
+ }
- // Neue Config laden um den Port und die Version zu überprüfen
- newConfig, err = loadJSONFileToMap(System.Folder.Config + "settings.json")
- if err != nil {
- ShowError(err, 0)
- return
- }
+ if err = removeChildItems(getPlatformPath(System.Folder.Config)); err != nil {
+ ShowError(err, 1073)
+ }
- newPort = newConfig["port"].(string)
- oldPort = Settings.Port
+ // Extract the ZIP Archive into the Config Folder
+ err = extractZIP(archive, System.Folder.Config)
+ if err != nil {
+ return
+ }
- if newPort == oldPort {
+ // Load a new Config to check the Port and Version
+ newConfig, err = loadJSONFileToMap(System.Folder.Config + "settings.json")
+ if err != nil {
+ ShowError(err, 0)
+ return
+ }
- if err != nil {
- ShowError(err, 0)
- }
+ newPort = newConfig["port"].(string)
+ oldPort = Settings.Port
- loadSettings()
+ if newPort == oldPort {
- err := Init()
- if err != nil {
- ShowError(err, 0)
- return "", err
- }
+ if err != nil {
+ ShowError(err, 0)
+ }
- err = StartSystem(true)
- if err != nil {
- ShowError(err, 0)
- return "", err
- }
+ loadSettings()
- return "", err
- }
+ err := Init()
+ if err != nil {
+ ShowError(err, 0)
+ return "", err
+ }
- var url = System.URLBase + "/web/"
- newWebURL = strings.Replace(url, ":"+oldPort, ":"+newPort, 1)
+ err = StartSystem(true)
+ if err != nil {
+ ShowError(err, 0)
+ return "", err
+ }
- os.RemoveAll(tmpRestore)
+ return "", err
+ }
- return
+ var url = System.URLBase + "/web/"
+ newWebURL = strings.Replace(url, ":"+oldPort, ":"+newPort, 1)
+
+ return
}
func xteveRestoreFromWeb(input string) (newWebURL string, err error) {
- // Base64 Json String in base64 umwandeln
- b64data := input[strings.IndexByte(input, ',')+1:]
+ // Convert base64 JSON string to base64
+ b64data := input[strings.IndexByte(input, ',')+1:]
- // Base64 in bytes umwandeln und speichern
- sDec, err := b64.StdEncoding.DecodeString(b64data)
+ // Convert Base64 into bytes and save
+ sDec, err := b64.StdEncoding.DecodeString(b64data)
- if err != nil {
- return
- }
+ if err != nil {
+ return
+ }
- var archive = System.Folder.Temp + "restore.zip"
+ var archive = System.Folder.Temp + "restore.zip"
- err = writeByteToFile(archive, sDec)
- if err != nil {
- return
- }
+ err = writeByteToFile(archive, sDec)
+ if err != nil {
+ return
+ }
- newWebURL, err = xteveRestore(archive)
+ newWebURL, err = xteveRestore(archive)
- return
+ return
}
-// XteveRestoreFromCLI : Wiederherstellung über die Kommandozeile
+// XteveRestoreFromCLI : Recovery from the Command Line
func XteveRestoreFromCLI(archive string) (err error) {
- var confirm string
+ var confirm string
- println()
- showInfo(fmt.Sprintf("Version:%s Build: %s", System.Version, System.Build))
- showInfo(fmt.Sprintf("Backup File:%s", archive))
- showInfo(fmt.Sprintf("System Folder:%s", getPlatformPath(System.Folder.Config)))
- println()
+ println()
+ showInfo(fmt.Sprintf("Version:%s Build: %s", System.Version, System.Build))
+ showInfo(fmt.Sprintf("Backup File:%s", archive))
+ showInfo(fmt.Sprintf("System Folder:%s", getPlatformPath(System.Folder.Config)))
+ println()
- fmt.Print("All data will be replaced with those from the backup. Should the files be restored? [yes|no]:")
+ fmt.Print("All data will be replaced with those from the backup. Should the files be restored? [yes|no]:")
- fmt.Scanln(&confirm)
+ fmt.Scanln(&confirm)
- switch strings.ToLower(confirm) {
+ switch strings.ToLower(confirm) {
- case "yes":
- break
+ case "yes":
+ break
- case "no":
- return
+ case "no":
+ return
- default:
- fmt.Println("Invalid input")
- return
+ default:
+ fmt.Println("Invalid input")
+ return
- }
+ }
- if len(System.Folder.Config) > 0 {
+ if len(System.Folder.Config) > 0 {
- err = checkFilePermission(System.Folder.Config)
- if err != nil {
- return
- }
+ err = checkFilePermission(System.Folder.Config)
+ if err != nil {
+ return
+ }
- _, err = xteveRestore(archive)
- if err != nil {
- return
- }
+ _, err = xteveRestore(archive)
+ if err != nil {
+ return
+ }
- showHighlight(fmt.Sprintf("Restor:Backup was successfully restored. %s can now be started normally", System.Name))
+ showHighlight(fmt.Sprintf("Restor:Backup was successfully restored. %s can now be started normally", System.Name))
- }
- return
+ }
+ return
}
diff --git a/src/buffer.go b/src/buffer.go
index 7af38e7..66fe6a1 100644
--- a/src/buffer.go
+++ b/src/buffer.go
@@ -1,7 +1,7 @@
package src
/*
- Tuner-Limit Bild als Video rendern [ffmpeg]
+ Render Tuner Stream-Limit image as Video [ffmpeg]
-loop 1 -i stream-limit.jpg -c:v libx264 -t 1 -pix_fmt yuv420p -vf scale=1920:1080 stream-limit.ts
*/
@@ -21,6 +21,10 @@ import (
"strconv"
"strings"
"time"
+
+ "github.com/avfs/avfs/vfs/memfs"
+ "github.com/avfs/avfs/vfs/osfs"
+ "github.com/samber/lo"
)
func createStreamID(stream map[int]ThisStream) (streamID int) {
@@ -59,17 +63,17 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
//w.Header().Set("Connection", "keep-alive")
w.Header().Set("Connection", "close")
- // Überprüfen ob die Playlist schon verwendet wird
+ // Check whether the Playlist is already in use
if p, ok := BufferInformation.Load(playlistID); !ok {
var playlistType string
- // Playlist wird noch nicht verwendet, Default-Werte für die Playlist erstellen
+ // Playlist is not yet used, create Default Values for the Playlist
playlist.Folder = System.Folder.Temp + playlistID + string(os.PathSeparator)
playlist.PlaylistID = playlistID
playlist.Streams = make(map[int]ThisStream)
playlist.Clients = make(map[int]ThisClient)
- err := checkFolder(playlist.Folder)
+ err := checkVFSFolder(playlist.Folder, bufferVFS)
if err != nil {
ShowError(err, 000)
httpStatusError(w, r, 404)
@@ -90,7 +94,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
playlist.PlaylistName = getProviderParameter(playlist.PlaylistID, playlistType, "name")
- // Default-Werte für den Stream erstellen
+ // Create Default Values for the Stream
streamID = createStreamID(playlist.Streams)
client.Connection = 1
@@ -105,8 +109,8 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
} else {
- // Playlist wird bereits zum streamen verwendet
- // Überprüfen ob die URL bereit von einem anderen Client gestreamt wird.
+ // Playlist is already being used for streaming
+ // Check if the URL is already being streamed by another Client
playlist = p.(Playlist)
@@ -145,18 +149,17 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
}
- // Neuer Stream bei einer bereits aktiven Playlist
- if newStream == true {
+ // New Stream for an already active Playlist
+ if newStream {
- // Prüfen ob die Playlist noch einen weiteren Stream erlaubt (Tuner)
+ // Check whether the Playlist allows another Stream (Tuner)
if len(playlist.Streams) >= playlist.Tuner {
showInfo(fmt.Sprintf("Streaming Status:Playlist: %s - No new connections available. Tuner = %d", playlist.PlaylistName, playlist.Tuner))
if value, ok := webUI["html/video/stream-limit.ts"]; ok {
- var content string
- content = GetHTMLString(value.(string))
+ var content string = GetHTMLString(value.(string))
w.WriteHeader(200)
w.Header().Set("Content-type", "video/mpeg")
@@ -174,8 +177,8 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
return
}
- // Playlist erlaubt einen weiterern Stream (Das Limit des Tuners ist noch nicht erreicht)
- // Default-Werte für den Stream erstellen
+ // Playlist allows another Stream (The Tuner limit has not yet been reached)
+ // Create Default Values for the Stream
stream = ThisStream{}
client = ThisClient{}
@@ -195,10 +198,10 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
}
- // Überprüfen ob der Stream breits von einem anderen Client abgespielt wird
- if playlist.Streams[streamID].Status == false && newStream == true {
+ // Check whether the Stream is already being played by another Client
+ if !playlist.Streams[streamID].Status && newStream {
- // Neuer Buffer wird benötigt
+ // New buffer is required
stream = playlist.Streams[streamID]
stream.MD5 = getMD5(streamingURL)
stream.Folder = playlist.Folder + stream.MD5 + string(os.PathSeparator)
@@ -230,7 +233,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
w.WriteHeader(200)
- for { // Loop 1: Warten bis das erste Segment durch den Buffer heruntergeladen wurde
+ for { // Loop 1: Wait until the first Segment has been downloaded by the Buffer
if p, ok := BufferInformation.Load(playlistID); ok {
@@ -238,7 +241,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
if stream, ok := playlist.Streams[streamID]; ok {
- if stream.Status == false {
+ if !stream.Status {
timeOut++
@@ -260,16 +263,17 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
var oldSegments []string
- for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden
+ for { // Loop 2: Temporary files are available, Data can be sent to the Client
- // HTTP Clientverbindung überwachen
+ // Monitor HTTP Client connection
- cn, ok := w.(http.CloseNotifier)
+ //cn, ok := w.(http.CloseNotifier)
+ ctx := r.Context()
if ok {
select {
- case <-cn.CloseNotify():
+ case <-ctx.Done(): // cn.CloseNotify():
killClientConnection(streamID, playlistID, false)
return
@@ -293,17 +297,17 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
}
- if _, err := os.Stat(stream.Folder); os.IsNotExist(err) {
+ if _, err := bufferVFS.Stat(stream.Folder); fsIsNotExistErr(err) {
killClientConnection(streamID, playlistID, false)
return
}
- var tmpFiles = getTmpFiles(&stream)
+ var tmpFiles = getBufTmpFiles(&stream)
//fmt.Println("Buffer Loop:", stream.Connection)
for _, f := range tmpFiles {
- if _, err := os.Stat(stream.Folder); os.IsNotExist(err) {
+ if _, err := bufferVFS.Stat(stream.Folder); fsIsNotExistErr(err) {
killClientConnection(streamID, playlistID, false)
return
}
@@ -312,7 +316,13 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
var fileName = stream.Folder + f
- file, err := os.Open(fileName)
+ file, err := bufferVFS.Open(fileName)
+ if err != nil {
+ debug = fmt.Sprintf("Buffer Open (%s)", fileName)
+ showDebug(debug, 2)
+ return
+ }
+
defer file.Close()
if err == nil {
@@ -330,7 +340,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
file.Seek(0, 0)
- if streaming == false {
+ if !streaming {
contentType := http.DetectContentType(buffer)
_ = contentType
@@ -365,12 +375,14 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
}
- var n = indexOfString(f, oldSegments)
+ var n = lo.IndexOf(oldSegments, f)
if n > 20 {
var fileToRemove = stream.Folder + oldSegments[0]
- os.RemoveAll(getPlatformFile(fileToRemove))
+ if err = bufferVFS.RemoveAll(getPlatformFile(fileToRemove)); err != nil {
+ ShowError(err, 4007)
+ }
oldSegments = append(oldSegments[:0], oldSegments[0+1:]...)
}
@@ -385,31 +397,31 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
time.Sleep(time.Duration(100) * time.Millisecond)
}
- } // Ende Loop 2
+ } // End of Loop 2
} else {
- // Stream nicht vorhanden
+ // Stream not available
killClientConnection(streamID, stream.PlaylistID, false)
showInfo(fmt.Sprintf("Streaming Status:Playlist: %s - Tuner: %d / %d", playlist.PlaylistName, len(playlist.Streams), playlist.Tuner))
return
}
- } // Ende BufferInformation
+ } // End of Buffer Information
- } // Ende Loop 1
+ } // End of Loop 1
}
-func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
+func getBufTmpFiles(stream *ThisStream) (tmpFiles []string) {
var tmpFolder = stream.Folder
var fileIDs []float64
- if _, err := os.Stat(tmpFolder); !os.IsNotExist(err) {
+ if _, err := bufferVFS.Stat(tmpFolder); !fsIsNotExistErr(err) {
- files, err := ioutil.ReadDir(getPlatformPath(tmpFolder))
+ files, err := bufferVFS.ReadDir(getPlatformPath(tmpFolder))
if err != nil {
ShowError(err, 000)
return
@@ -435,7 +447,7 @@ func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
var fileName = fmt.Sprintf("%d.ts", int64(file))
- if indexOfString(fileName, stream.OldSegments) == -1 {
+ if lo.IndexOf(stream.OldSegments, fileName) == -1 {
tmpFiles = append(tmpFiles, fileName)
stream.OldSegments = append(stream.OldSegments, fileName)
}
@@ -458,7 +470,7 @@ func killClientConnection(streamID int, playlistID string, force bool) {
var playlist = p.(Playlist)
- if force == true {
+ if force {
delete(playlist.Streams, streamID)
showInfo(fmt.Sprintf("Streaming Status:Playlist: %s - Tuner: %d / %d", playlist.PlaylistName, len(playlist.Streams), playlist.Tuner))
return
@@ -511,7 +523,9 @@ func clientConnection(stream ThisStream) (status bool) {
debug = fmt.Sprintf("Remove tmp folder:%s", stream.Folder)
showDebug(debug, 1)
- os.RemoveAll(stream.Folder)
+ if err := bufferVFS.RemoveAll(stream.Folder); err != nil {
+ ShowError(err, 4005)
+ }
if p, ok := BufferInformation.Load(stream.PlaylistID); ok {
@@ -547,7 +561,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
var m3u8Segments []string
var bandwidth BandwidthCalculation
var networkBandwidth = Settings.M3U8AdaptiveBandwidthMBPS * 1e+6
- // Größe des Buffers
+ // Size of the Buffer
var bufferSize = Settings.BufferSize
var buffer = make([]byte, 1024*bufferSize*2)
@@ -592,16 +606,18 @@ func connectToStreamingServer(streamID int, playlistID string) {
}
- os.RemoveAll(getPlatformPath(tmpFolder))
+ if err := bufferVFS.RemoveAll(getPlatformPath(tmpFolder)); err != nil {
+ ShowError(err, 4005)
+ }
- err := checkFolder(tmpFolder)
+ err := checkVFSFolder(tmpFolder, bufferVFS)
if err != nil {
ShowError(err, 0)
addErrorToStream(err)
return
}
- // M3U8 Segmente
+ // M3U8 Segments
InitBuffer:
defaultSegment()
@@ -614,9 +630,9 @@ func connectToStreamingServer(streamID int, playlistID string) {
var stream ThisStream = playlist.Streams[streamID]
- if stream.Status == false {
+ if !stream.Status {
- if strings.Index(stream.URL, ".m3u8") != -1 {
+ if strings.Contains(stream.URL, ".m3u8") {
showInfo("Streaming Type:" + "[HLS / M3U8]")
} else {
showInfo("Streaming Type:" + "[TS]")
@@ -634,7 +650,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
for {
- if clientConnection(stream) == false {
+ if !clientConnection(stream) {
return
}
@@ -653,10 +669,10 @@ func connectToStreamingServer(streamID int, playlistID string) {
debug = fmt.Sprintf("Connection to:%s", currentURL)
showDebug(debug, 2)
- // Sprung für Redirect (301 <---> 308)
+ // Jump for redirect (301 <---> 308)
Redirect:
- req, err := http.NewRequest("GET", currentURL, nil)
+ req, _ := http.NewRequest("GET", currentURL, nil)
req.Header.Set("User-Agent", Settings.UserAgent)
req.Header.Set("Connection", "close")
//req.Header.Set("Range", "bytes=0-")
@@ -678,7 +694,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
if resp == nil {
- err = errors.New("No response from streaming server")
+ err = errors.New("no response from streaming server")
fmt.Println("Current URL:", currentURL)
ShowError(err, 0)
@@ -709,7 +725,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
} else {
- err = errors.New("Streaming server")
+ err = errors.New("streaming server")
ShowError(err, 4002)
addErrorToStream(err)
@@ -730,13 +746,11 @@ func connectToStreamingServer(streamID int, playlistID string) {
}
- defer resp.Body.Close()
-
}
defer resp.Body.Close()
- // HTTP Status überprüfen, bei Fehlern wird der Stream beendet
+ // Check HTTP Status, in case of errors the stream is terminated
var contentType = resp.Header.Get("Content-Type")
var httpStatusCode = resp.StatusCode
var httpStatusInfo = fmt.Sprintf("HTTP Response Status [%d] %s", httpStatusCode, http.StatusText(resp.StatusCode))
@@ -763,8 +777,8 @@ func connectToStreamingServer(streamID int, playlistID string) {
return
}
- // Informationen über den Streamingserver auslesen
- if stream.Status == false {
+ // Read out information about the streaming server
+ if !stream.Status {
if len(stream.URLStreamingServer) == 0 {
@@ -797,7 +811,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
}
- // Content Type bereinigen
+ // Clean up Content Type
if len(contentType) > 0 {
var ct = strings.SplitN(contentType, ";", 2)
contentType = strings.ToLower(ct[0])
@@ -828,7 +842,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
var fileSize int
- // Größe des Buffers
+ // Size of the Buffer
buffer = make([]byte, 1024*bufferSize*2)
var tmpFileSize = 1024 * bufferSize * 1
@@ -840,12 +854,12 @@ func connectToStreamingServer(streamID int, playlistID string) {
var tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
- if clientConnection(stream) == false {
+ if !clientConnection(stream) {
resp.Body.Close()
return
}
- bufferFile, err := os.Create(tmpFile)
+ bufferFile, err := bufferVFS.Create(tmpFile)
if err != nil {
addErrorToStream(err)
@@ -865,7 +879,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
}
timeOut = 0
- // Buffer mit Daten vom Server füllen
+ // Fill the Buffer with data from the Server
n, err := resp.Body.Read(buffer)
if err != nil && err != io.EOF {
@@ -892,20 +906,19 @@ func connectToStreamingServer(streamID int, playlistID string) {
fileSize = fileSize + n
- if clientConnection(stream) == false {
+ if !clientConnection(stream) {
resp.Body.Close()
bufferFile.Close()
- err = os.RemoveAll(stream.Folder)
- if err != nil {
+ if err = bufferVFS.RemoveAll(stream.Folder); err != nil {
ShowError(err, 4005)
}
return
}
- // Buffer auf die Festplatte speichern
+ // Save the buffer to the Hard Disk
if fileSize >= tmpFileSize/2 || n == 0 {
Lock.Lock()
@@ -934,20 +947,19 @@ func connectToStreamingServer(streamID int, playlistID string) {
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
- if clientConnection(stream) == false {
+ if !clientConnection(stream) {
bufferFile.Close()
resp.Body.Close()
- err = os.RemoveAll(stream.Folder)
- if err != nil {
+ if err = bufferVFS.RemoveAll(stream.Folder); err != nil {
ShowError(err, 4005)
}
return
}
- bufferFile, err = os.Create(tmpFile)
+ bufferFile, err = bufferVFS.Create(tmpFile)
if err != nil {
addErrorToStream(err)
resp.Body.Close()
@@ -969,10 +981,10 @@ func connectToStreamingServer(streamID int, playlistID string) {
//--
- // Umbekanntes Format
+ // Unknown Format
default:
showInfo("Content Type:" + resp.Header.Get("Content-Type"))
- err = errors.New("Streaming error")
+ err = errors.New("streaming error")
ShowError(err, 4003)
addErrorToStream(err)
@@ -982,8 +994,8 @@ func connectToStreamingServer(streamID int, playlistID string) {
s++
- // Wartezeit für den Download das nächste Segments berechnen
- if stream.HLS == true {
+ // Calculate the waiting time for the Download of the next Segment
+ if stream.HLS {
var sleep float64
@@ -1008,7 +1020,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
_ = i
time.Sleep(time.Duration(100) * time.Millisecond)
- if _, err := os.Stat(stream.Folder); os.IsNotExist(err) {
+ if _, err := bufferVFS.Stat(stream.Folder); fsIsNotExistErr(err) {
break
}
@@ -1024,9 +1036,9 @@ func connectToStreamingServer(streamID int, playlistID string) {
resp.Body.Close()
- } // Ende for loop
+ } // End for loop
- } // Ende BufferInformation
+ } // End of BufferInformation
}
@@ -1125,7 +1137,7 @@ func parseM3U8(stream *ThisStream) (err error) {
var parseURL = func(line string, segment *Segment) {
- // Prüfen ob die Adresse eine gültige URL ist (http://... oder /path/to/stream)
+ // Check if the address is a valid URL (http://... or /path/to/stream)
_, err := url.ParseRequestURI(line)
if err == nil {
@@ -1133,33 +1145,32 @@ func parseM3U8(stream *ThisStream) (err error) {
u, _ := url.Parse(line)
if len(u.Host) == 0 {
- // Adresse enthällt nicht die Domain, Redirect wird der Adresse hinzugefügt
+ // Check whether the domain is included in the address
segment.URL = stream.URLStreamingServer + line
} else {
- // Domain in der Adresse enthalten
+ // Domain included in the address
segment.URL = line
}
} else {
- // keine URL, sondern ein Dateipfad (media/file-01.ts)
+ // not URL, but a file path (media/file-01.ts)
var serverURLPath = strings.Replace(stream.M3U8URL, path.Base(stream.M3U8URL), line, -1)
segment.URL = serverURLPath
}
- return
}
if strings.Contains(stream.Body, "#EXTM3U") {
var lines = strings.Split(strings.Replace(stream.Body, "\r\n", "\n", -1), "\n")
- if stream.DynamicBandwidth == false {
+ if !stream.DynamicBandwidth {
stream.DynamicStream = make(map[int]DynamicStream)
}
- // Parameter parsen
+ // Parse Parameters
for i, line := range lines {
_ = i
@@ -1177,8 +1188,8 @@ func parseM3U8(stream *ThisStream) (err error) {
}
- // M3U8 enthällt mehrere Links zu weiteren M3U8 Wiedergabelisten (Bandbreitenoption)
- if segment.Info == true && len(line) > 0 && line[0:1] != "#" {
+ // M3U8 contains several links to additional M3U8 Playlists (Bandwidth option)
+ if segment.Info && len(line) > 0 && line[0:1] != "#" {
var dynamicStream DynamicStream
@@ -1195,7 +1206,7 @@ func parseM3U8(stream *ThisStream) (err error) {
}
- // Segment mit TS Stream
+ // Segment with TS Stream
if segment.Duration > 0 && line[0:1] != "#" {
parseURL(line, &segment)
@@ -1222,7 +1233,7 @@ func parseM3U8(stream *ThisStream) (err error) {
noNewSegment = true
- if stream.Status == false {
+ if !stream.Status {
if len(m3u8Segments) >= 2 {
m3u8Segments = m3u8Segments[0 : len(m3u8Segments)-1]
@@ -1234,12 +1245,12 @@ func parseM3U8(stream *ThisStream) (err error) {
segment = s
- if stream.Status == false {
+ if !stream.Status {
noNewSegment = false
stream.LastSequence = segment.Sequence
- // Stream ist vom Typ VOD. Es muss das erste Segment der M3U8 Playlist verwendet werden.
+ // Stream is of type VOD. The first segment of the M3U8 playlist must be used.
if strings.ToUpper(segment.PlaylistType) == "VOD" {
break
}
@@ -1260,9 +1271,9 @@ func parseM3U8(stream *ThisStream) (err error) {
}
- if noNewSegment == false {
+ if !noNewSegment {
- if stream.DynamicBandwidth == true {
+ if stream.DynamicBandwidth {
switchBandwidth(stream)
} else {
stream.Segment = append(stream.Segment, segment)
@@ -1270,7 +1281,7 @@ func parseM3U8(stream *ThisStream) (err error) {
}
- if noNewSegment == true {
+ if noNewSegment {
var sleep = lastSegmentDuration * 0.5
@@ -1279,7 +1290,7 @@ func parseM3U8(stream *ThisStream) (err error) {
_ = i
time.Sleep(time.Duration(100) * time.Millisecond)
- if _, err := os.Stat(stream.Folder); os.IsNotExist(err) {
+ if _, err := bufferVFS.Stat(stream.Folder); fsIsNotExistErr(err) {
break
}
@@ -1341,7 +1352,7 @@ func switchBandwidth(stream *ThisStream) (err error) {
return
}
-// Buffer mit FFMPEG
+// Buffer with FFMPEG
func thirdPartyBuffer(streamID int, playlistID string) {
if p, ok := BufferInformation.Load(playlistID); ok {
@@ -1354,7 +1365,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
var buf bytes.Buffer
var fileSize = 0
var streamStatus = make(chan bool)
-
+ //var dir_file_mode os.FileMode = fs.ModeDir
var tmpFolder = playlist.Streams[streamID].Folder
var url = playlist.Streams[streamID].URL
@@ -1390,9 +1401,11 @@ func thirdPartyBuffer(streamID int, playlistID string) {
}
- os.RemoveAll(getPlatformPath(tmpFolder))
+ if err := bufferVFS.RemoveAll(getPlatformPath(tmpFolder)); err != nil {
+ ShowError(err, 4005)
+ }
- err := checkFolder(tmpFolder)
+ err := checkVFSFolder(tmpFolder, bufferVFS)
if err != nil {
ShowError(err, 0)
addErrorToStream(err)
@@ -1411,7 +1424,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
var tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)
- f, err := os.Create(tmpFile)
+ f, err := bufferVFS.Create(tmpFile)
f.Close()
if err != nil {
addErrorToStream(err)
@@ -1420,7 +1433,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
//args = strings.Replace(args, "[USER-AGENT]", Settings.UserAgent, -1)
- // User-Agent setzen
+ // Set User-Agent
var args []string
for i, a := range strings.Split(options, " ") {
@@ -1458,7 +1471,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
debug = fmt.Sprintf("%s:%s %s", bufferType, path, args)
showDebug(debug, 1)
- // Byte-Daten vom Prozess
+ // Byte-Data from the Process
stdOut, err := cmd.StdoutPipe()
if err != nil {
ShowError(err, 0)
@@ -1468,7 +1481,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
return
}
- // Log-Daten vom Prozess
+ // Log-Data from the Process
logOut, err := cmd.StderrPipe()
if err != nil {
ShowError(err, 0)
@@ -1478,7 +1491,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
return
}
- if len(buf.Bytes()) == 0 && stream.Status == false {
+ if len(buf.Bytes()) == 0 && !stream.Status {
showInfo(bufferType + ":Processing data")
}
@@ -1487,7 +1500,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
go func() {
- // Log Daten vom Prozess im Dubug Mode 1 anzeigen.
+ // Show Log Data from the Process in Debug Mode 1.
scanner := bufio.NewScanner(logOut)
scanner.Split(bufio.ScanLines)
@@ -1508,7 +1521,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
}()
- f, err = os.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
+ f, err = bufferVFS.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
panic(err)
}
@@ -1556,11 +1569,11 @@ func thirdPartyBuffer(streamID int, playlistID string) {
}
- if fileSize == 0 && stream.Status == false {
+ if fileSize == 0 && !stream.Status {
showInfo("Streaming Status:Receive data from " + bufferType)
}
- if clientConnection(stream) == false {
+ if !clientConnection(stream) {
cmd.Process.Kill()
f.Close()
cmd.Wait()
@@ -1585,7 +1598,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
if fileSize >= bufferSize/2 {
- if tmpSegment == 1 && stream.Status == false {
+ if tmpSegment == 1 && !stream.Status {
close(t)
close(streamStatus)
showInfo(fmt.Sprintf("Streaming Status:Buffering data from %s", bufferType))
@@ -1594,7 +1607,7 @@ func thirdPartyBuffer(streamID int, playlistID string) {
f.Close()
tmpSegment++
- if stream.Status == false {
+ if !stream.Status {
Lock.Lock()
stream.Status = true
playlist.Streams[streamID] = stream
@@ -1607,8 +1620,8 @@ func thirdPartyBuffer(streamID int, playlistID string) {
fileSize = 0
var errCreate, errOpen error
- f, errCreate = os.Create(tmpFile)
- f, errOpen = os.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
+ _, errCreate = bufferVFS.Create(tmpFile)
+ f, errOpen = bufferVFS.OpenFile(tmpFile, os.O_APPEND|os.O_WRONLY, 0600)
if errCreate != nil || errOpen != nil {
cmd.Process.Kill()
ShowError(err, 0)
@@ -1660,6 +1673,16 @@ func getTuner(id, playlistType string) (tuner int) {
return
}
+func initBufferVFS(virtual bool) {
+
+ if virtual {
+ bufferVFS = memfs.New(memfs.WithMainDirs())
+ } else {
+ bufferVFS = osfs.New()
+ }
+
+}
+
func debugRequest(req *http.Request) {
var debugLevel = 3
@@ -1696,8 +1719,6 @@ func debugRequest(req *http.Request) {
debug = "Request:* * * * * * END HTTP(S) REQUEST * * * * * *"
showDebug(debug, debugLevel)
-
- return
}
func debugResponse(resp *http.Response) {
@@ -1741,6 +1762,4 @@ func debugResponse(resp *http.Response) {
debug = "Pesponse:* * * * * * END RESPONSE * * * * * * "
showDebug(debug, debugLevel)
-
- return
}
diff --git a/src/cert.go b/src/cert.go
new file mode 100644
index 0000000..3725b60
--- /dev/null
+++ b/src/cert.go
@@ -0,0 +1,79 @@
+package src
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
+ "math/big"
+ "net"
+ "os"
+ "time"
+)
+
+// genCertFiles creates a self-signed certificate and it's private key in config/certificates directory.
+//
+// Inspired by https://gist.github.com/shaneutt/5e1995295cff6721c89a71d13a71c251
+func genCertFiles() (err error) {
+ showInfo("Web server:" + "Generating certificate")
+
+ subject := pkix.Name{
+ CommonName: "xTeVe",
+ Country: []string{"US"},
+ Locality: []string{"San Francisco"},
+ Organization: []string{"xTeVe, Inc."},
+ PostalCode: []string{"94016"},
+ Province: []string{""},
+ StreetAddress: []string{"Golden Gate Bridge"},
+ }
+
+ serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
+ serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
+ if err != nil {
+ return
+ }
+
+ certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
+ if err != nil {
+ return
+ }
+
+ certPrivKeyPEM := pem.EncodeToMemory(&pem.Block{
+ Type: "RSA PRIVATE KEY",
+ Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
+ })
+
+ cert := &x509.Certificate{
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+ IPAddresses: append(System.IPAddressesV4Raw, net.IPv6loopback),
+ KeyUsage: x509.KeyUsageDigitalSignature,
+ NotAfter: time.Now().AddDate(10, 0, 0),
+ NotBefore: time.Now(),
+ SerialNumber: serialNumber,
+ Subject: subject,
+ SubjectKeyId: []byte{1, 2, 3, 4, 6},
+ }
+
+ certBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &certPrivKey.PublicKey, certPrivKey)
+ if err != nil {
+ return
+ }
+
+ certPEM := pem.EncodeToMemory(&pem.Block{
+ Type: "CERTIFICATE",
+ Bytes: certBytes,
+ })
+
+ err = os.WriteFile(System.File.ServerCertPrivKey, certPrivKeyPEM, 0644)
+ if err != nil {
+ return
+ }
+
+ err = os.WriteFile(System.File.ServerCert, certPEM, 0644)
+ if err != nil {
+ return
+ }
+
+ return
+}
diff --git a/src/compression.go b/src/compression.go
index ba76626..67fbc89 100644
--- a/src/compression.go
+++ b/src/compression.go
@@ -86,6 +86,7 @@ func extractZIP(archive, target string) (err error) {
if err != nil {
return err
}
+ defer reader.Close()
if err := os.MkdirAll(target, 0755); err != nil {
return err
@@ -127,7 +128,7 @@ func extractGZIP(gzipBody []byte, fileSource string) (body []byte, err error) {
var r io.Reader
r, err = gzip.NewReader(b)
if err != nil {
- // Keine gzip Datei
+ // Not a gzip file
body = gzipBody
err = nil
return
diff --git a/src/config.go b/src/config.go
index 3584168..1f3ab1b 100644
--- a/src/config.go
+++ b/src/config.go
@@ -6,38 +6,43 @@ import (
"runtime"
"strings"
"sync"
+
+ "github.com/avfs/avfs"
)
-// System : Beinhaltet alle Systeminformationen
+// System : Contains all System Information
var System SystemStruct
-// WebScreenLog : Logs werden im RAM gespeichert und für das Webinterface bereitgestellt
+// WebScreenLog : Logs are saved in RAM and made available for the Web interface
var WebScreenLog WebScreenLogStruct
-// Settings : Inhalt der settings.json
+// Settings : Content of settings.json
var Settings SettingsStruct
-// Data : Alle Daten werden hier abgelegt. (Lineup, XMLTV)
+// Data : All data is stored here. (Lineup, XMLTV)
var Data DataStruct
-// SystemFiles : Alle Systemdateien
+// SystemFiles : All System Files
var SystemFiles = []string{"authentication.json", "pms.json", "settings.json", "xepg.json", "urls.json"}
-// BufferInformation : Informationen über den Buffer (aktive Streams, maximale Streams)
+// BufferInformation : Information about the Buffer (active Streams, maximum Streams)
var BufferInformation sync.Map
-// BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen
+// BufferClients : Number of Clients playing a Stream over the Buffer
var BufferClients sync.Map
+// bufferVFS : Filesystem to use for the Buffer
+var bufferVFS avfs.VFS
+
// Lock : Lock Map
var Lock = sync.RWMutex{}
-// Init : Systeminitialisierung
+// Init : System Initialization
func Init() (err error) {
var debug string
- // System Einstellungen
+ // System Settings
System.AppName = strings.ToLower(System.Name)
System.ARCH = runtime.GOARCH
System.OS = runtime.GOOS
@@ -47,25 +52,21 @@ func Init() (err error) {
System.ServerProtocol.WEB = "http"
System.ServerProtocol.XML = "http"
System.PlexChannelLimit = 480
- System.UnfilteredChannelLimit = 480
System.Compatibility = "1.4.4"
- // FFmpeg Default Einstellungen
- System.FFmpeg.DefaultOptions = "-hide_banner -loglevel error -i [URL] -c copy -f mpegts pipe:1"
+ // FFmpeg Default Settings
+ System.FFmpeg.DefaultOptions = "-hide_banner -err_detect ignore_err -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 20 -loglevel error -i [URL] -c copy -f mpegts pipe:1"
System.VLC.DefaultOptions = "-I dummy [URL] --sout #std{mux=ts,access=file,dst=-}"
- // Default Logeinträge, wird später von denen aus der settings.json überschrieben. Muss gemacht werden, damit die ersten Einträge auch im Log (webUI aangezeigt werden)
+ // Default Log Entries, which will later be overwritten by those from settings.json. Needed so that the first entries are also displayed in the Log (webUI are displayed)
Settings.LogEntriesRAM = 500
- // Variablen für den Update Prozess
+ // Variables for the Update Process
//System.Update.Git = "https://github.com/xteve-project/xTeVe-Downloads/blob"
System.Update.Git = fmt.Sprintf("https://github.com/%s/%s/blob", System.GitHub.User, System.GitHub.Repo)
System.Update.Name = "xteve_2"
- // Ordnerpfade festlegen
- var tempFolder = os.TempDir() + string(os.PathSeparator) + System.AppName + string(os.PathSeparator)
- tempFolder = getPlatformPath(strings.Replace(tempFolder, "//", "/", -1))
-
+ // Define folder paths
if len(System.Folder.Config) == 0 {
System.Folder.Config = GetUserHomeDirectory() + string(os.PathSeparator) + "." + System.AppName + string(os.PathSeparator)
} else {
@@ -77,14 +78,15 @@ func Init() (err error) {
System.Folder.Backup = System.Folder.Config + "backup" + string(os.PathSeparator)
System.Folder.Data = System.Folder.Config + "data" + string(os.PathSeparator)
System.Folder.Cache = System.Folder.Config + "cache" + string(os.PathSeparator)
+ System.Folder.Certificates = System.Folder.Config + "certificates" + string(os.PathSeparator)
System.Folder.ImagesCache = System.Folder.Cache + "images" + string(os.PathSeparator)
System.Folder.ImagesUpload = System.Folder.Data + "images" + string(os.PathSeparator)
- System.Folder.Temp = tempFolder
+ System.Folder.Temp = getDefaultTempDir()
// Dev Info
showDevInfo()
- // System Ordner erstellen
+ // Create System Folder
err = createSystemFolders()
if err != nil {
ShowError(err, 1070)
@@ -92,10 +94,12 @@ func Init() (err error) {
}
if len(System.Flag.Restore) > 0 {
- // Einstellungen werden über CLI wiederhergestellt. Weitere Initialisierung ist nicht notwendig.
+ // Settings are restored via CLI. No further Initialization is necessary.
return
}
+ System.File.ServerCert = getPlatformFile(fmt.Sprintf("%sxteve.crt", System.Folder.Certificates))
+ System.File.ServerCertPrivKey = getPlatformFile(fmt.Sprintf("%sxteve.key", System.Folder.Certificates))
System.File.XML = getPlatformFile(fmt.Sprintf("%s%s.xml", System.Folder.Data, System.AppName))
System.File.M3U = getPlatformFile(fmt.Sprintf("%s%s.m3u", System.Folder.Data, System.AppName))
@@ -106,18 +110,13 @@ func Init() (err error) {
return
}
- err = resolveHostIP()
- if err != nil {
- ShowError(err, 1002)
- }
-
- // Menü für das Webinterface
+ // Menu for the Web interface
System.WEB.Menu = []string{"playlist", "filter", "xmltv", "mapping", "users", "settings", "log", "logout"}
fmt.Println("For help run: " + getPlatformFile(os.Args[0]) + " -h")
fmt.Println()
- // Überprüfen ob xTeVe als root läuft
+ // Check whether xTeVe is running as root
if os.Geteuid() == 0 {
showWarning(2110)
}
@@ -129,24 +128,22 @@ func Init() (err error) {
showInfo(fmt.Sprintf("Version:%s Build: %s", System.Version, System.Build))
showInfo(fmt.Sprintf("Database Version:%s", System.DBVersion))
- showInfo(fmt.Sprintf("System IP Addresses:IPv4: %d | IPv6: %d", len(System.IPAddressesV4), len(System.IPAddressesV6)))
- showInfo("Hostname:" + System.Hostname)
showInfo(fmt.Sprintf("System Folder:%s", getPlatformPath(System.Folder.Config)))
- // Systemdateien erstellen (Falls nicht vorhanden)
+ // Create System Files (If not available)
err = createSystemFiles()
if err != nil {
ShowError(err, 1071)
return
}
- // Bedingte Update Änderungen durchführen
+ // Perform conditional Update Changes
err = conditionalUpdateChanges()
if err != nil {
return
}
- // Einstellungen laden (settings.json)
+ // Load Settings (settings.json)
showInfo(fmt.Sprintf("Load Settings:%s", System.File.Settings))
_, err = loadSettings()
@@ -155,14 +152,22 @@ func Init() (err error) {
return
}
- // Berechtigung aller Ordner überprüfen
+ err = resolveHostIP()
+ if err != nil {
+ ShowError(err, 1002)
+ }
+
+ showInfo(fmt.Sprintf("System IP Addresses:IPv4: %d | IPv6: %d", len(System.IPAddressesV4), len(System.IPAddressesV6)))
+ showInfo("Hostname:" + System.Hostname)
+
+ // Check the permissions on all Folders
err = checkFilePermission(System.Folder.Config)
if err == nil {
- err = checkFilePermission(System.Folder.Temp)
+ checkFilePermission(System.Folder.Temp)
}
- // Separaten tmp Ordner für jede Instanz
- //System.Folder.Temp = System.Folder.Temp + Settings.UUID + string(os.PathSeparator)
+ // Separate tmp Folder for each Instance
+ // System.Folder.Temp = System.Folder.Temp + Settings.UUID + string(os.PathSeparator)
showInfo(fmt.Sprintf("Temporary Folder:%s", getPlatformPath(System.Folder.Temp)))
err = checkFolder(System.Folder.Temp)
@@ -175,10 +180,10 @@ func Init() (err error) {
return
}
- // Branch festlegen
+ // Set Branch
System.Branch = Settings.Branch
- if System.Dev == true {
+ if System.Dev {
System.Branch = "Development"
}
@@ -189,13 +194,17 @@ func Init() (err error) {
showInfo(fmt.Sprintf("GitHub:https://github.com/%s", System.GitHub.User))
showInfo(fmt.Sprintf("Git Branch:%s [%s]", System.Branch, System.GitHub.User))
- // Domainnamen setzten
- setGlobalDomain(fmt.Sprintf("%s:%s", System.IPAddress, Settings.Port))
+ if len(strings.TrimSpace(Settings.HostName)) > 0 {
+ Settings.HostIP = strings.TrimSpace(Settings.HostName)
+ }
- System.URLBase = fmt.Sprintf("%s://%s:%s", System.ServerProtocol.WEB, System.IPAddress, Settings.Port)
+ // Set Domain Names
+ setGlobalDomain(fmt.Sprintf("%s:%s", Settings.HostIP, Settings.Port))
- // HTML Dateien erstellen, mit dev == true werden die lokalen HTML Dateien verwendet
- if System.Dev == true {
+ System.URLBase = fmt.Sprintf("%s://%s:%s", System.ServerProtocol.WEB, Settings.HostIP, Settings.Port)
+
+ // Create HTML Files, with dev the local HTML Files are used
+ if System.Dev {
HTMLInit("webUI", "src", "html"+string(os.PathSeparator), "src"+string(os.PathSeparator)+"webUI.go")
err = BuildGoFile()
@@ -205,19 +214,19 @@ func Init() (err error) {
}
- // DLNA Server starten
+ // Start the DLNA Server
err = SSDP()
if err != nil {
return
}
- // HTML Datein laden
+ // Load HTML Files
loadHTMLMap()
return
}
-// StartSystem : System wird gestartet
+// StartSystem : System is starting up
func StartSystem(updateProviderFiles bool) (err error) {
setDeviceID()
@@ -226,15 +235,14 @@ func StartSystem(updateProviderFiles bool) (err error) {
return
}
- // Systeminformationen in der Konsole ausgeben
+ // Output System Information in the Console
showInfo(fmt.Sprintf("UUID:%s", Settings.UUID))
showInfo(fmt.Sprintf("Tuner (Plex / Emby):%d", Settings.Tuner))
showInfo(fmt.Sprintf("EPG Source:%s", Settings.EpgSource))
showInfo(fmt.Sprintf("Plex Channel Limit:%d", System.PlexChannelLimit))
- showInfo(fmt.Sprintf("Unfiltered Chan. Limit:%d", System.UnfilteredChannelLimit))
- // Providerdaten aktualisieren
- if len(Settings.Files.M3U) > 0 && Settings.FilesUpdate == true || updateProviderFiles == true {
+ // Update Provider Data
+ if len(Settings.Files.M3U) > 0 && Settings.FilesUpdate || updateProviderFiles {
err = xTeVeAutoBackup()
if err != nil {
@@ -260,3 +268,16 @@ func StartSystem(updateProviderFiles bool) (err error) {
return
}
+
+// reinitialize : Initialize and start up the system, updating provider files
+func reinitialize() {
+ err := Init()
+ if err != nil {
+ ShowError(err, 0)
+ }
+
+ err = StartSystem(true)
+ if err != nil {
+ ShowError(err, 0)
+ }
+}
diff --git a/src/data.go b/src/data.go
index 3ea9bdc..77db7ed 100644
--- a/src/data.go
+++ b/src/data.go
@@ -15,7 +15,7 @@ import (
"xteve/src/internal/imgcache"
)
-// Einstellungen ändern (WebUI)
+// Change Settings (WebUI)
func updateServerSettings(request RequestStruct) (settings SettingsStruct, err error) {
var oldSettings = jsonToMap(mapToJSON(Settings))
@@ -25,8 +25,6 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
var createXEPGFiles = false
var debug string
- // -vvv [URL] --sout '#transcode{vcodec=mp4v, acodec=mpga} :standard{access=http, mux=ogg}'
-
for key, value := range newSettings {
if _, ok := oldSettings[key]; ok {
@@ -40,7 +38,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
reloadData = true
case "update":
- // Leerzeichen aus den Werten entfernen und Formatierung der Uhrzeit überprüfen (0000 - 2359)
+ // Remove spaces from the Values and check the formatting of the Time (0000 - 2359)
var newUpdateTimes = make([]string, 0)
for _, v := range value.([]interface{}) {
@@ -57,9 +55,9 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
- if len(newUpdateTimes) == 0 {
- //newUpdateTimes = append(newUpdateTimes, "0000")
- }
+ // if len(newUpdateTimes) == 0 {
+ // //newUpdateTimes = append(newUpdateTimes, "0000")
+ // }
value = newUpdateTimes
@@ -86,20 +84,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
case "temp.path":
- value = strings.TrimRight(value.(string), string(os.PathSeparator)) + string(os.PathSeparator)
- err = checkFolder(value.(string))
- if err == nil {
-
- err = checkFilePermission(value.(string))
- if err != nil {
- return
- }
-
- }
-
- if err != nil {
- return
- }
+ value = getValidTempDir(value.(string))
case "ffmpeg.path", "vlc.path":
var path = value.(string)
@@ -115,6 +100,18 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
case "scheme.m3u", "scheme.xml":
createXEPGFiles = true
+ case "defaultMissingEPG":
+ // If DefaultMissingEPG was set, rebuild DVR and XEPG database
+ if newSettings["defaultMissingEPG"] != "-" && oldSettings["defaultMissingEPG"] == "-" {
+ reloadData = true
+ }
+
+ case "enableMappedChannels":
+ // If EnableMappedChannels was turned on, rebuild DVR and XEPG database
+ if newSettings["enableMappedChannels"] == true && oldSettings["enableMappedChannels"] == false {
+ reloadData = true
+ }
+
}
oldSettings[key] = value
@@ -143,13 +140,13 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
- // Einstellungen aktualisieren
+ // Update Settings
err = json.Unmarshal([]byte(mapToJSON(oldSettings)), &Settings)
if err != nil {
return
}
- if Settings.AuthenticationWEB == false {
+ if !Settings.AuthenticationWEB {
Settings.AuthenticationAPI = false
Settings.AuthenticationM3U = false
@@ -159,7 +156,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
- // Buffer Einstellungen überprüfen
+ // Check Buffer Settings
if len(Settings.FFmpegOptions) == 0 {
Settings.FFmpegOptions = System.FFmpeg.DefaultOptions
}
@@ -191,7 +188,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
settings = Settings
- if reloadData == true {
+ if reloadData {
err = buildDatabaseDVR()
if err != nil {
@@ -202,7 +199,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
- if cacheImages == true {
+ if cacheImages {
if Settings.EpgSource == "XEPG" && System.ImageCachingInProgress == 0 {
@@ -241,7 +238,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
}
- if createXEPGFiles == true {
+ if createXEPGFiles {
go func() {
createXMLTVFile()
@@ -255,7 +252,7 @@ func updateServerSettings(request RequestStruct) (settings SettingsStruct, err e
return
}
-// Providerdaten speichern (WebUI)
+// Save Provider Data (WebUI)
func saveFiles(request RequestStruct, fileType string) (err error) {
var filesMap = make(map[string]interface{})
@@ -288,14 +285,14 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
if dataID == "-" {
- // Neue Providerdatei
+ // New Provider File
dataID = indicator + randomString(19)
data.(map[string]interface{})["new"] = true
filesMap[dataID] = data
} else {
- // Bereits vorhandene Providerdatei
+ // Existing Provider File
for key, value := range data.(map[string]interface{}) {
var oldData = filesMap[dataID].(map[string]interface{})
@@ -318,7 +315,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
}
- // Neue Providerdatei
+ // New Provider File
if _, ok := data.(map[string]interface{})["new"]; ok {
reloadData = true
@@ -344,7 +341,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
return
}
- if reloadData == true {
+ if reloadData {
err = buildDatabaseDVR()
if err != nil {
@@ -362,7 +359,7 @@ func saveFiles(request RequestStruct, fileType string) (err error) {
return
}
-// Providerdaten manuell aktualisieren (WebUI)
+// Update Provider Data manually (WebUI)
func updateFile(request RequestStruct, fileType string) (err error) {
var updateData = make(map[string]interface{})
@@ -392,7 +389,7 @@ func updateFile(request RequestStruct, fileType string) (err error) {
return
}
-// Providerdaten löschen (WebUI)
+// Delete Provider Data (WebUI)
func deleteLocalProviderFiles(dataID, fileType string) {
var removeData = make(map[string]interface{})
@@ -418,10 +415,9 @@ func deleteLocalProviderFiles(dataID, fileType string) {
os.RemoveAll(System.Folder.Data + dataID + fileExtension)
}
- return
}
-// Filtereinstellungen speichern (WebUI)
+// Save Filter Settings (WebUI)
func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
var filterMap = make(map[int64]interface{})
@@ -431,6 +427,8 @@ func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
defaultFilter.Active = true
defaultFilter.CaseSensitive = false
+ defaultFilter.PreserveMapping = true
+ defaultFilter.StartingChannel = strconv.FormatFloat(Settings.MappingFirstChannel, 'f', -1, 64) // 1000
filterMap = Settings.Filter
newData = request.Filter
@@ -450,17 +448,17 @@ func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
if dataID == -1 {
- // Neuer Filter
+ // New Filter
newFilter = true
dataID = createNewID()
filterMap[dataID] = jsonToMap(mapToJSON(defaultFilter))
}
- // Filter aktualisieren / löschen
+ // Update / delete filters
for key, value := range data.(map[string]interface{}) {
- // Filter löschen
+ // Clear Filters
if _, ok := data.(map[string]interface{})["delete"]; ok {
delete(filterMap, dataID)
break
@@ -471,7 +469,7 @@ func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
if len(filter) == 0 {
err = errors.New(getErrMsg(1014))
- if newFilter == true {
+ if newFilter {
delete(filterMap, dataID)
}
@@ -505,7 +503,7 @@ func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
return
}
-// XEPG Mapping speichern
+// Save XEPG Mapping
func saveXEpgMapping(request RequestStruct) (err error) {
var tmp = Data.XEPG
@@ -536,10 +534,10 @@ func saveXEpgMapping(request RequestStruct) (err error) {
} else {
- // Wenn während des erstellen der Datanbank das Mapping erneut gespeichert wird, wird die Datenbank erst später erneut aktualisiert.
+ // If the Mapping is saved again while the Database is being created, the Database will not be updated again until later.
go func() {
- if System.BackgroundProcess == true {
+ if System.BackgroundProcess {
return
}
@@ -557,7 +555,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
cleanupXEPG()
System.ScanInProgress = 0
buildXEPG(false)
- showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
+ showInfo("XEPG:" + "Ready to use")
System.BackgroundProcess = false
@@ -568,7 +566,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
return
}
-// Benutzerdaten speichern (WebUI)
+// Save User Data (WebUI)
func saveUserData(request RequestStruct) (err error) {
var userData = request.UserData
@@ -598,7 +596,7 @@ func saveUserData(request RequestStruct) (err error) {
return
}
- if request.DeleteUser == true {
+ if request.DeleteUser {
err = authentication.RemoveUser(userID)
return
}
@@ -624,7 +622,7 @@ func saveUserData(request RequestStruct) (err error) {
return
}
-// Neuen Benutzer anlegen (WebUI)
+// Create New User (WebUI)
func saveNewUser(request RequestStruct) (err error) {
var data = request.UserData
@@ -745,7 +743,7 @@ func saveWizard(request RequestStruct) (nextStep int, err error) {
return
}
-// Filterregeln erstellen
+// Create Filter Rules
func createFilterRules() (err error) {
Data.Filter = nil
@@ -781,6 +779,8 @@ func createFilterRules() (err error) {
}
dataFilter.CaseSensitive = filter.CaseSensitive
+ dataFilter.PreserveMapping = filter.PreserveMapping
+ dataFilter.StartingChannel = filter.StartingChannel
dataFilter.Rule = fmt.Sprintf("%s%s%s", filter.Filter, include, exclude)
dataFilter.Type = filter.Type
@@ -792,14 +792,14 @@ func createFilterRules() (err error) {
return
}
-// Datenbank für das DVR System erstellen
+// Create a Database for the DVR System
func buildDatabaseDVR() (err error) {
System.ScanInProgress = 1
- Data.Streams.All = make([]interface{}, 0, System.UnfilteredChannelLimit)
- Data.Streams.Active = make([]interface{}, 0, System.UnfilteredChannelLimit)
- Data.Streams.Inactive = make([]interface{}, 0, System.UnfilteredChannelLimit)
+ Data.Streams.All = make([]interface{}, 0)
+ Data.Streams.Active = make([]interface{}, 0)
+ Data.Streams.Inactive = make([]interface{}, 0)
Data.Playlist.M3U.Groups.Text = []string{}
Data.Playlist.M3U.Groups.Value = []string{}
Data.StreamPreviewUI.Active = []string{}
@@ -807,6 +807,7 @@ func buildDatabaseDVR() (err error) {
var availableFileTypes = []string{"m3u", "hdhr"}
+ var urlValuesMap = make(map[string]string)
var tmpGroupsM3U = make(map[string]int64)
err = createFilterRules()
@@ -844,7 +845,7 @@ func buildDatabaseDVR() (err error) {
playlistFile = append(playlistFile[:n], playlistFile[n+1:]...)
}
- // Streams analysieren
+ // Analyze Streams
for _, stream := range channels {
var s = stream.(map[string]string)
@@ -852,7 +853,16 @@ func buildDatabaseDVR() (err error) {
s["_file.m3u.name"] = playlistName
s["_file.m3u.id"] = id
- // Kompatibilität berechnen
+ if Settings.DisallowURLDuplicates {
+ if _, haveURL := urlValuesMap[s["url"]]; haveURL {
+ showInfo("Streams:" + fmt.Sprintf("Found duplicated URL %v, ignoring the channel %v", s["url"], s["name"]))
+ continue
+ } else {
+ urlValuesMap[s["url"]] = s["_values"]
+ }
+ }
+
+ // Calculate Compatibility
for _, key := range keys {
switch key {
@@ -867,12 +877,12 @@ func buildDatabaseDVR() (err error) {
if value, ok := s[key]; ok {
if len(value) > 0 {
- if _, ok := tmpGroupsM3U[value]; ok {
- tmpGroupsM3U[value]++
- } else {
- tmpGroupsM3U[value] = 1
- }
-
+ // if _, ok := tmpGroupsM3U[value]; ok {
+ // tmpGroupsM3U[value]++
+ // } else {
+ // tmpGroupsM3U[value] = 1
+ // }
+ tmpGroupsM3U[value]++
groupTitle++
}
}
@@ -890,7 +900,7 @@ func buildDatabaseDVR() (err error) {
Data.Streams.All = append(Data.Streams.All, stream)
- // Neuer Filter ab Version 1.3.0
+ // New Filter from Version 1.3.0
var preview string
var status = filterThisStream(stream)
@@ -947,7 +957,7 @@ func buildDatabaseDVR() (err error) {
for group, count := range tmpGroupsM3U {
var text = fmt.Sprintf("%s (%d)", group, count)
- var value = fmt.Sprintf("%s", group)
+ var value = group
Data.Playlist.M3U.Groups.Text = append(Data.Playlist.M3U.Groups.Text, text)
Data.Playlist.M3U.Groups.Value = append(Data.Playlist.M3U.Groups.Value, value)
}
@@ -955,7 +965,7 @@ func buildDatabaseDVR() (err error) {
sort.Strings(Data.Playlist.M3U.Groups.Text)
sort.Strings(Data.Playlist.M3U.Groups.Value)
- if len(Data.Streams.Active) == 0 && len(Data.Streams.All) <= System.UnfilteredChannelLimit && len(Settings.Filter) == 0 {
+ if len(Data.Streams.Active) == 0 && len(Settings.Filter) == 0 {
Data.Streams.Active = Data.Streams.All
Data.Streams.Inactive = make([]interface{}, 0)
@@ -968,10 +978,6 @@ func buildDatabaseDVR() (err error) {
showWarning(2000)
}
- if len(Settings.Filter) == 0 && len(Data.Streams.All) > System.UnfilteredChannelLimit {
- showWarning(2001)
- }
-
System.ScanInProgress = 0
showInfo(fmt.Sprintf("All streams:%d", len(Data.Streams.All)))
showInfo(fmt.Sprintf("Active streams:%d", len(Data.Streams.Active)))
@@ -983,7 +989,7 @@ func buildDatabaseDVR() (err error) {
return
}
-// Speicherort aller lokalen Providerdateien laden, immer für eine Dateityp (M3U, XMLTV usw.)
+// Load Storage Location of all local Provider Files, always for one File Type (M3U, XMLTV etc.)
func getLocalProviderFiles(fileType string) (localFiles []string) {
var fileExtension string
@@ -1012,7 +1018,7 @@ func getLocalProviderFiles(fileType string) (localFiles []string) {
return
}
-// Providerparameter anhand von dem Key ausgeben
+// Output Provider Parameters based on the Key
func getProviderParameter(id, fileType, key string) (s string) {
var dataMap = make(map[string]interface{})
@@ -1043,7 +1049,7 @@ func getProviderParameter(id, fileType, key string) (s string) {
return
}
-// Provider Statistiken Kompatibilität aktualisieren
+// Update Provider Statistics Compatibility
func setProviderCompatibility(id, fileType string, compatibility map[string]int) {
var dataMap = make(map[string]interface{})
diff --git a/src/hdhr.go b/src/hdhr.go
index 830401a..490486d 100644
--- a/src/hdhr.go
+++ b/src/hdhr.go
@@ -5,6 +5,10 @@ import (
"encoding/json"
"encoding/xml"
"fmt"
+ "sort"
+ "strconv"
+
+ "github.com/samber/lo"
)
func makeInteraceFromHDHR(content []byte, playlistName, id string) (channels []interface{}, err error) {
@@ -154,7 +158,7 @@ func getLineup() (jsonContent []byte, err error) {
return
}
- if xepgChannel.XActive == true {
+ if xepgChannel.XActive {
var stream LineupStream
stream.GuideName = xepgChannel.XName
stream.GuideNumber = xepgChannel.XChannelID
@@ -169,9 +173,17 @@ func getLineup() (jsonContent []byte, err error) {
}
}
-
}
+ // Sort the lineup
+ // Have to use type assertions (https://golang.org/ref/spec#Type_assertions) to cast generic interface{} into LineupStream
+ sort.Slice(lineup, func(i, j int) bool {
+ var chanA, chanB float64
+ chanA, _ = strconv.ParseFloat(lineup[i].(LineupStream).GuideNumber, 64)
+ chanB, _ = strconv.ParseFloat(lineup[j].(LineupStream).GuideNumber, 64)
+ return chanA < chanB
+ })
+
jsonContent, err = json.MarshalIndent(lineup, "", " ")
Data.Cache.PMS = nil
@@ -212,7 +224,7 @@ func getGuideNumberPMS(channelName string) (pmsID string, err error) {
ids = append(ids, v)
}
- if indexOfString(id, ids) != -1 {
+ if lo.IndexOf(ids, id) != -1 {
i++
goto newID
}
diff --git a/src/html-build.go b/src/html-build.go
index 2b7ba10..1c54172 100644
--- a/src/html-build.go
+++ b/src/html-build.go
@@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"runtime"
+ "sort"
)
var htmlFolder string
@@ -18,10 +19,10 @@ var packageName string
var blankMap = make(map[string]interface{})
-// HTMLInit : Dateipfade festlegen
-// mapName = Name der zu erstellenden map
-// htmlFolder: Ordner der HTML Dateien
-// packageName: Name des package
+// HTMLInit : Define file paths
+// mapName = Name of the map to be created
+// htmlFolder: HTML Files Folder
+// packageName: Name of the package
func HTMLInit(name, pkg, folder, file string) {
htmlFolder = folder
@@ -31,7 +32,7 @@ func HTMLInit(name, pkg, folder, file string) {
}
-// BuildGoFile : Erstellt das GO Dokument
+// BuildGoFile : Creates the GO Document
func BuildGoFile() error {
var err = checkHTMLFile(htmlFolder)
@@ -70,7 +71,14 @@ func createMapFromFiles(folder string) string {
var content string
- for key := range blankMap {
+ // Sort map keys before writing to file to prevent git mark webUI.go as modified when no real changes has been made
+ keys := make([]string, 0, len(blankMap))
+ for k := range blankMap {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+
+ for _, key := range keys {
var newKey = key
content += ` ` + mapName + `["` + newKey + `"` + `] = "` + blankMap[key].(string) + `"` + "\n"
}
@@ -80,9 +88,9 @@ func createMapFromFiles(folder string) string {
func readFilesToMap(path string, info os.FileInfo, err error) error {
- if info.IsDir() == false {
+ if !info.IsDir() {
var base64Str = fileToBase64(getLocalPath(path))
- blankMap[path] = base64Str
+ blankMap[filepath.ToSlash(path)] = base64Str
}
return nil
@@ -110,7 +118,7 @@ func fileToBase64(file string) string {
func getLocalPath(filename string) string {
path, file := filepath.Split(filename)
- var newPath = filepath.Dir(path)
+ var newPath = filepath.ToSlash(filepath.Dir(path))
var newFileName = newPath + "/" + file
diff --git a/src/images.go b/src/images.go
index 04dd256..9e891af 100644
--- a/src/images.go
+++ b/src/images.go
@@ -1,30 +1,30 @@
package src
import (
- b64 "encoding/base64"
- "fmt"
- "strings"
+ b64 "encoding/base64"
+ "fmt"
+ "strings"
)
func uploadLogo(input, filename string) (logoURL string, err error) {
- b64data := input[strings.IndexByte(input, ',')+1:]
+ b64data := input[strings.IndexByte(input, ',')+1:]
- // BAse64 in bytes umwandeln un speichern
- sDec, err := b64.StdEncoding.DecodeString(b64data)
- if err != nil {
- return
- }
+ // Convert Base64 into bytes and save
+ sDec, err := b64.StdEncoding.DecodeString(b64data)
+ if err != nil {
+ return
+ }
- var file = fmt.Sprintf("%s%s", System.Folder.ImagesUpload, filename)
+ var file = fmt.Sprintf("%s%s", System.Folder.ImagesUpload, filename)
- err = writeByteToFile(file, sDec)
- if err != nil {
- return
- }
+ err = writeByteToFile(file, sDec)
+ if err != nil {
+ return
+ }
- logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.XML, System.Domain, filename)
+ logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.XML, System.Domain, filename)
- return
+ return
}
diff --git a/src/info.go b/src/info.go
index 26c5605..e837e1d 100644
--- a/src/info.go
+++ b/src/info.go
@@ -1,100 +1,100 @@
package src
import (
- "fmt"
- "strings"
+ "fmt"
+ "strings"
)
-// ShowSystemInfo : Systeminformationen anzeigen
-func ShowSystemInfo() {
+// ShowSystemVersion basic version info
+func ShowSystemVersion() {
+ fmt.Println(fmt.Sprintf("%s.%s", System.Version, System.Build))
+}
- fmt.Print("Creating the information takes a moment...")
- err := buildDatabaseDVR()
- if err != nil {
- ShowError(err, 0)
- return
- }
+// ShowSystemInfo : View System Information
+func ShowSystemInfo() {
- buildXEPG(false)
+ fmt.Print("Creating the information takes a moment...")
+ err := buildDatabaseDVR()
+ if err != nil {
+ ShowError(err, 0)
+ return
+ }
- fmt.Println("OK")
- println()
+ buildXEPG(false)
- fmt.Println(fmt.Sprintf("Version: %s %s.%s", System.Name, System.Version, System.Build))
- fmt.Println(fmt.Sprintf("Branch: %s", System.Branch))
- fmt.Println(fmt.Sprintf("GitHub: %s/%s | Git update = %t", System.GitHub.User, System.GitHub.Repo, System.GitHub.Update))
- fmt.Println(fmt.Sprintf("Folder (config): %s", System.Folder.Config))
+ fmt.Println("OK")
+ println()
- fmt.Println(fmt.Sprintf("Streams: %d / %d", len(Data.Streams.Active), len(Data.Streams.All)))
- fmt.Println(fmt.Sprintf("Filter: %d", len(Data.Filter)))
- fmt.Println(fmt.Sprintf("XEPG Chanels: %d", int(Data.XEPG.XEPGCount)))
+ fmt.Printf("Version: %s %s.%s\n", System.Name, System.Version, System.Build)
+ fmt.Printf("Branch: %s\n", System.Branch)
+ fmt.Printf("GitHub: %s/%s | Git update = %t\n", System.GitHub.User, System.GitHub.Repo, System.GitHub.Update)
+ fmt.Printf("Folder (config): %s\n", System.Folder.Config)
- println()
- fmt.Println(fmt.Sprintf("IPv4 Addresses:"))
+ fmt.Printf("Streams: %d / %d\n", len(Data.Streams.Active), len(Data.Streams.All))
+ fmt.Printf("Filter: %d\n", len(Data.Filter))
+ fmt.Printf("XEPG Chanels: %d\n", int(Data.XEPG.XEPGCount))
- for i, ipv4 := range System.IPAddressesV4 {
+ println()
+ fmt.Println("IPv4 Addresses:")
- switch count := i; {
+ for i, ipv4 := range System.IPAddressesV4 {
- case count < 10:
- fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
- break
- case count < 100:
- fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
- break
+ switch count := i; {
- }
+ case count < 10:
+ fmt.Printf(" %d. %s\n", count, ipv4)
+ case count < 100:
+ fmt.Printf(" %d. %s\n", count, ipv4)
- }
+ }
- println()
- fmt.Println(fmt.Sprintf("IPv6 Addresses:"))
+ }
- for i, ipv4 := range System.IPAddressesV6 {
+ println()
+ fmt.Println("IPv6 Addresses:")
- switch count := i; {
+ for i, ipv4 := range System.IPAddressesV6 {
- case count < 10:
- fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
- break
- case count < 100:
- fmt.Println(fmt.Sprintf(" %d. %s", count, ipv4))
- break
+ switch count := i; {
- }
+ case count < 10:
+ fmt.Printf(" %d. %s\n", count, ipv4)
+ case count < 100:
+ fmt.Printf(" %d. %s\n", count, ipv4)
+ }
- }
+ }
- println("---")
+ println("---")
- fmt.Println("Settings [General]")
- fmt.Println(fmt.Sprintf("xTeVe Update: %t", Settings.XteveAutoUpdate))
- fmt.Println(fmt.Sprintf("UUID: %s", Settings.UUID))
- fmt.Println(fmt.Sprintf("Tuner (Plex / Emby): %d", Settings.Tuner))
- fmt.Println(fmt.Sprintf("EPG Source: %s", Settings.EpgSource))
+ fmt.Println("Settings [General]")
+ fmt.Printf("xTeVe Update: %t\n", Settings.XteveAutoUpdate)
+ fmt.Printf("UUID: %s\n", Settings.UUID)
+ fmt.Printf("Tuner (Plex / Emby): %d\n", Settings.Tuner)
+ fmt.Printf("EPG Source: %s\n", Settings.EpgSource)
- println("---")
+ println("---")
- fmt.Println("Settings [Files]")
- fmt.Println(fmt.Sprintf("Schedule: %s", strings.Join(Settings.Update, ",")))
- fmt.Println(fmt.Sprintf("Files Update: %t", Settings.FilesUpdate))
- fmt.Println(fmt.Sprintf("Folder (tmp): %s", Settings.TempPath))
- fmt.Println(fmt.Sprintf("Image Chaching: %t", Settings.CacheImages))
- fmt.Println(fmt.Sprintf("Replace EPG Image: %t", Settings.XepgReplaceMissingImages))
+ fmt.Println("Settings [Files]")
+ fmt.Printf("Schedule: %s\n", strings.Join(Settings.Update, ","))
+ fmt.Printf("Files Update: %t\n", Settings.FilesUpdate)
+ fmt.Printf("Folder (tmp): %s\n", Settings.TempPath)
+ fmt.Printf("Image Chaching: %t\n", Settings.CacheImages)
+ fmt.Printf("Replace EPG Image: %t\n", Settings.XepgReplaceMissingImages)
- println("---")
+ println("---")
- fmt.Println("Settings [Streaming]")
- fmt.Println(fmt.Sprintf("Buffer: %s", Settings.Buffer))
- fmt.Println(fmt.Sprintf("UDPxy: %s", Settings.UDPxy))
- fmt.Println(fmt.Sprintf("Buffer Size: %d KB", Settings.BufferSize))
- fmt.Println(fmt.Sprintf("Timeout: %d ms", int(Settings.BufferTimeout)))
- fmt.Println(fmt.Sprintf("User Agent: %s", Settings.UserAgent))
+ fmt.Println("Settings [Streaming]")
+ fmt.Printf("Buffer: %s\n", Settings.Buffer)
+ fmt.Printf("UDPxy: %s\n", Settings.UDPxy)
+ fmt.Printf("Buffer Size: %d KB\n", Settings.BufferSize)
+ fmt.Printf("Timeout: %d ms\n", int(Settings.BufferTimeout))
+ fmt.Printf("User Agent: %s\n", Settings.UserAgent)
- println("---")
+ println("---")
- fmt.Println("Settings [Backup]")
- fmt.Println(fmt.Sprintf("Folder (backup): %s", Settings.BackupPath))
- fmt.Println(fmt.Sprintf("Backup Keep: %d", Settings.BackupKeep))
+ fmt.Println("Settings [Backup]")
+ fmt.Printf("Folder (backup): %s\n", Settings.BackupPath)
+ fmt.Printf("Backup Keep: %d\n", Settings.BackupKeep)
}
diff --git a/src/internal/authentication/authentication.go b/src/internal/authentication/authentication.go
index 0f6bae4..4aa68cb 100755
--- a/src/internal/authentication/authentication.go
+++ b/src/internal/authentication/authentication.go
@@ -1,21 +1,21 @@
package authentication
import (
- "encoding/json"
- "errors"
- "io/ioutil"
- "net/http"
- "os"
- "path/filepath"
-
- "crypto/hmac"
- "crypto/rand"
- "crypto/sha256"
- "encoding/base64"
-
- "time"
- //"fmt"
- //"log"
+ "encoding/json"
+ "errors"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "path/filepath"
+
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/sha256"
+ "encoding/base64"
+
+ "time"
+ //"fmt"
+ //"log"
)
const tokenLength = 40
@@ -34,12 +34,12 @@ var initAuthentication = false
// Cookie : cookie
type Cookie struct {
- Name string
- Value string
- Path string
- Domain string
- Expires time.Time
- RawExpires string
+ Name string
+ Value string
+ Path string
+ Domain string
+ Expires time.Time
+ RawExpires string
}
// Framework examples
@@ -128,465 +128,457 @@ func main() {
// Init : databasePath = Path to authentication.json
func Init(databasePath string, validity int) (err error) {
- database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
-
- // Check if the database already exists
- if _, err = os.Stat(database); os.IsNotExist(err) {
- // Create an empty database
- var defaults = make(map[string]interface{})
- defaults["dbVersion"] = "1.0"
- defaults["hash"] = "sha256"
- defaults["users"] = make(map[string]interface{})
-
- if saveDatabase(defaults) != nil {
- return
- }
- }
-
- // Loading the database
- err = loadDatabase()
-
- // Set Token Validity
- tokenValidity = validity
- initAuthentication = true
- return
+ database = filepath.Dir(databasePath) + string(os.PathSeparator) + databaseFile
+
+ // Check if the database already exists
+ if _, err = os.Stat(database); os.IsNotExist(err) {
+ // Create an empty database
+ var defaults = make(map[string]interface{})
+ defaults["dbVersion"] = "1.0"
+ defaults["hash"] = "sha256"
+ defaults["users"] = make(map[string]interface{})
+
+ if saveDatabase(defaults) != nil {
+ return
+ }
+ }
+
+ // Loading the database
+ err = loadDatabase()
+
+ // Set Token Validity
+ tokenValidity = validity
+ initAuthentication = true
+ return
}
// CreateDefaultUser = created efault user
func CreateDefaultUser(username, password string) (err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- var users = data["users"].(map[string]interface{})
- // Check if the default user exists
- if len(users) > 0 {
- err = createError(001)
- return
- }
+ var users = data["users"].(map[string]interface{})
+ // Check if the default user exists
+ if len(users) > 0 {
+ err = createError(001)
+ return
+ }
- var defaults = defaultsForNewUser(username, password)
- users[defaults["_id"].(string)] = defaults
- saveDatabase(data)
+ var defaults = defaultsForNewUser(username, password)
+ users[defaults["_id"].(string)] = defaults
+ saveDatabase(data)
- return
+ return
}
// CreateNewUser : create new user
func CreateNewUser(username, password string) (userID string, err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- var checkIfTheUserAlreadyExists = func(username string, userData map[string]interface{}) (err error) {
- var salt = userData["_salt"].(string)
- var loginUsername = userData["_username"].(string)
+ var checkIfTheUserAlreadyExists = func(username string, userData map[string]interface{}) (err error) {
+ var salt = userData["_salt"].(string)
+ var loginUsername = userData["_username"].(string)
- if SHA256(username, salt) == loginUsername {
- err = createError(020)
- }
+ if SHA256(username, salt) == loginUsername {
+ err = createError(020)
+ }
- return
- }
+ return
+ }
- var users = data["users"].(map[string]interface{})
- for _, userData := range users {
- err = checkIfTheUserAlreadyExists(username, userData.(map[string]interface{}))
- if err != nil {
- return
- }
- }
+ var users = data["users"].(map[string]interface{})
+ for _, userData := range users {
+ err = checkIfTheUserAlreadyExists(username, userData.(map[string]interface{}))
+ if err != nil {
+ return
+ }
+ }
- var defaults = defaultsForNewUser(username, password)
- userID = defaults["_id"].(string)
- users[userID] = defaults
+ var defaults = defaultsForNewUser(username, password)
+ userID = defaults["_id"].(string)
+ users[userID] = defaults
- saveDatabase(data)
+ saveDatabase(data)
- return
+ return
}
// UserAuthentication : user authentication
func UserAuthentication(username, password string) (token string, err error) {
- err = checkInit()
- if err != nil {
- return
- }
-
- var login = func(username, password string, loginData map[string]interface{}) (err error) {
- err = createError(010)
-
- var salt = loginData["_salt"].(string)
- var loginUsername = loginData["_username"].(string)
- var loginPassword = loginData["_password"].(string)
-
- if SHA256(username, salt) == loginUsername {
- if SHA256(password, salt) == loginPassword {
- err = nil
- }
- }
-
- return
- }
-
- var users = data["users"].(map[string]interface{})
- for id, loginData := range users {
- err = login(username, password, loginData.(map[string]interface{}))
- if err == nil {
- token = setToken(id, "-")
- return
- }
- }
-
- return
+ err = checkInit()
+ if err != nil {
+ return
+ }
+
+ var login = func(username, password string, loginData map[string]interface{}) (err error) {
+ err = createError(010)
+
+ var salt = loginData["_salt"].(string)
+ var loginUsername = loginData["_username"].(string)
+ var loginPassword = loginData["_password"].(string)
+
+ if SHA256(username, salt) == loginUsername {
+ if SHA256(password, salt) == loginPassword {
+ err = nil
+ }
+ }
+
+ return
+ }
+
+ var users = data["users"].(map[string]interface{})
+ for id, loginData := range users {
+ err = login(username, password, loginData.(map[string]interface{}))
+ if err == nil {
+ token = setToken(id, "-")
+ return
+ }
+ }
+
+ return
}
// CheckTheValidityOfTheToken : check token
func CheckTheValidityOfTheToken(token string) (newToken string, err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(011)
+ err = createError(011)
- if v, ok := tokens[token]; ok {
- var expires = v.(map[string]interface{})["expires"].(time.Time)
- var userID = v.(map[string]interface{})["id"].(string)
+ if v, ok := tokens[token]; ok {
+ var expires = v.(map[string]interface{})["expires"].(time.Time)
+ var userID = v.(map[string]interface{})["id"].(string)
- if expires.Sub(time.Now().Local()) < 0 {
- return
- }
+ if expires.Sub(time.Now().Local()) < 0 {
+ return
+ }
- newToken = setToken(userID, token)
+ newToken = setToken(userID, token)
- err = nil
+ err = nil
- } else {
- return
- }
+ } else {
+ return
+ }
- return
+ return
}
// GetUserID : get user ID
func GetUserID(token string) (userID string, err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(002)
+ err = createError(002)
- if v, ok := tokens[token]; ok {
- var expires = v.(map[string]interface{})["expires"].(time.Time)
- userID = v.(map[string]interface{})["id"].(string)
+ if v, ok := tokens[token]; ok {
+ var expires = v.(map[string]interface{})["expires"].(time.Time)
+ userID = v.(map[string]interface{})["id"].(string)
- if expires.Sub(time.Now().Local()) < 0 {
- return
- }
+ if expires.Sub(time.Now().Local()) < 0 {
+ return
+ }
- err = nil
- }
+ err = nil
+ }
- return
+ return
}
// WriteUserData : save user date
func WriteUserData(userID string, userData map[string]interface{}) (err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(030)
+ err = createError(030)
- if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
+ if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
- v["data"] = userData
- err = saveDatabase(data)
+ v["data"] = userData
+ err = saveDatabase(data)
- } else {
- return
- }
+ } else {
+ return
+ }
- return
+ return
}
// ReadUserData : load user date
func ReadUserData(userID string) (userData map[string]interface{}, err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(031)
+ err = createError(031)
- if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
- userData = v["data"].(map[string]interface{})
- err = nil
+ if v, ok := data["users"].(map[string]interface{})[userID].(map[string]interface{}); ok {
+ userData = v["data"].(map[string]interface{})
+ err = nil
- return
- }
+ return
+ }
- return
+ return
}
// RemoveUser : remove user
func RemoveUser(userID string) (err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(032)
+ err = createError(032)
- if _, ok := data["users"].(map[string]interface{})[userID]; ok {
+ if _, ok := data["users"].(map[string]interface{})[userID]; ok {
- delete(data["users"].(map[string]interface{}), userID)
- err = saveDatabase(data)
+ delete(data["users"].(map[string]interface{}), userID)
+ err = saveDatabase(data)
- return
- }
+ return
+ }
- return
+ return
}
// SetDefaultUserData : set default user data
func SetDefaultUserData(defaults map[string]interface{}) (err error) {
- allUserData, err := GetAllUserData()
-
- for _, d := range allUserData {
- var data = d.(map[string]interface{})["data"].(map[string]interface{})
- var userID = d.(map[string]interface{})["_id"].(string)
-
- for k, v := range defaults {
- if _, ok := data[k]; ok {
- // Key exist
- } else {
- data[k] = v
- }
- }
- err = WriteUserData(userID, data)
- }
- return
+ allUserData, err := GetAllUserData()
+
+ for _, d := range allUserData {
+ var data = d.(map[string]interface{})["data"].(map[string]interface{})
+ var userID = d.(map[string]interface{})["_id"].(string)
+
+ for k, v := range defaults {
+ if _, ok := data[k]; ok {
+ // Key exist
+ } else {
+ data[k] = v
+ }
+ }
+ err = WriteUserData(userID, data)
+ }
+ return
}
// ChangeCredentials : change credentials
func ChangeCredentials(userID, username, password string) (err error) {
- err = checkInit()
- if err != nil {
- return
- }
+ err = checkInit()
+ if err != nil {
+ return
+ }
- err = createError(032)
+ err = createError(032)
- if userData, ok := data["users"].(map[string]interface{})[userID]; ok {
- //var userData = tmp.(map[string]interface{})
- var salt = userData.(map[string]interface{})["_salt"].(string)
+ if userData, ok := data["users"].(map[string]interface{})[userID]; ok {
+ //var userData = tmp.(map[string]interface{})
+ var salt = userData.(map[string]interface{})["_salt"].(string)
- if len(username) > 0 {
- userData.(map[string]interface{})["_username"] = SHA256(username, salt)
- }
+ if len(username) > 0 {
+ userData.(map[string]interface{})["_username"] = SHA256(username, salt)
+ }
- if len(password) > 0 {
- userData.(map[string]interface{})["_password"] = SHA256(password, salt)
- }
+ if len(password) > 0 {
+ userData.(map[string]interface{})["_password"] = SHA256(password, salt)
+ }
- err = saveDatabase(data)
- }
+ err = saveDatabase(data)
+ }
- return
+ return
}
// GetAllUserData : get all user data
func GetAllUserData() (allUserData map[string]interface{}, err error) {
- err = checkInit()
- if err != nil {
- return
- }
-
- if len(data) == 0 {
- var defaults = make(map[string]interface{})
- defaults["dbVersion"] = "1.0"
- defaults["hash"] = "sha256"
- defaults["users"] = make(map[string]interface{})
- saveDatabase(defaults)
- data = defaults
- }
-
- allUserData = data["users"].(map[string]interface{})
- return
+ err = checkInit()
+ if err != nil {
+ return
+ }
+
+ if len(data) == 0 {
+ var defaults = make(map[string]interface{})
+ defaults["dbVersion"] = "1.0"
+ defaults["hash"] = "sha256"
+ defaults["users"] = make(map[string]interface{})
+ saveDatabase(defaults)
+ data = defaults
+ }
+
+ allUserData = data["users"].(map[string]interface{})
+ return
}
// CheckTheValidityOfTheTokenFromHTTPHeader : get token from HTTP header
func CheckTheValidityOfTheTokenFromHTTPHeader(w http.ResponseWriter, r *http.Request) (writer http.ResponseWriter, newToken string, err error) {
- err = createError(011)
- for _, cookie := range r.Cookies() {
- if cookie.Name == "Token" {
- var token string
- token, err = CheckTheValidityOfTheToken(cookie.Value)
- //fmt.Println("T", token, err)
- writer = SetCookieToken(w, token)
- newToken = token
- }
- }
- //fmt.Println(err)
- return
+ err = createError(011)
+ for _, cookie := range r.Cookies() {
+ if cookie.Name == "Token" {
+ var token string
+ token, err = CheckTheValidityOfTheToken(cookie.Value)
+ //fmt.Println("T", token, err)
+ writer = SetCookieToken(w, token)
+ newToken = token
+ }
+ }
+ //fmt.Println(err)
+ return
}
// Framework tools
func checkInit() (err error) {
- if initAuthentication == false {
- err = createError(000)
- }
+ if !initAuthentication {
+ err = createError(000)
+ }
- return
+ return
}
func saveDatabase(tmpMap interface{}) (err error) {
- jsonString, err := json.MarshalIndent(tmpMap, "", " ")
+ jsonString, err := json.MarshalIndent(tmpMap, "", " ")
- if err != nil {
- return
- }
+ if err != nil {
+ return
+ }
- err = ioutil.WriteFile(database, []byte(jsonString), 0600)
- if err != nil {
- return
- }
+ err = ioutil.WriteFile(database, []byte(jsonString), 0600)
+ if err != nil {
+ return
+ }
- return
+ return
}
func loadDatabase() (err error) {
- jsonString, err := ioutil.ReadFile(database)
- if err != nil {
- return
- }
+ jsonString, err := ioutil.ReadFile(database)
+ if err != nil {
+ return
+ }
- err = json.Unmarshal([]byte(jsonString), &data)
- if err != nil {
- return
- }
+ err = json.Unmarshal([]byte(jsonString), &data)
+ if err != nil {
+ return
+ }
- return
+ return
}
// SHA256 : password + salt = sha256 string
func SHA256(secret, salt string) string {
- key := []byte(secret)
- h := hmac.New(sha256.New, key)
- h.Write([]byte("_remote_db"))
- return base64.StdEncoding.EncodeToString(h.Sum(nil))
+ key := []byte(secret)
+ h := hmac.New(sha256.New, key)
+ h.Write([]byte("_remote_db"))
+ return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func randomString(n int) string {
- const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
-
- var bytes = make([]byte, n)
- rand.Read(bytes)
- for i, b := range bytes {
- bytes[i] = alphanum[b%byte(len(alphanum))]
- }
- return string(bytes)
+ const alphanum = "-AbCdEfGhIjKlMnOpQrStUvWxYz0123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ_"
+
+ var bytes = make([]byte, n)
+ rand.Read(bytes)
+ for i, b := range bytes {
+ bytes[i] = alphanum[b%byte(len(alphanum))]
+ }
+ return string(bytes)
}
func randomID(n int) string {
- const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
-
- var bytes = make([]byte, n)
- rand.Read(bytes)
- for i, b := range bytes {
- bytes[i] = alphanum[b%byte(len(alphanum))]
- }
- return string(bytes)
+ const alphanum = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789"
+
+ var bytes = make([]byte, n)
+ rand.Read(bytes)
+ for i, b := range bytes {
+ bytes[i] = alphanum[b%byte(len(alphanum))]
+ }
+ return string(bytes)
}
func createError(errCode int) (err error) {
- var errMsg string
- switch errCode {
- case 000:
- errMsg = "Authentication has not yet been initialized"
- case 001:
- errMsg = "Default user already exists"
- case 002:
- errMsg = "No user id found for this token"
- case 010:
- errMsg = "User authentication failed"
- case 011:
- errMsg = "Session has expired"
- case 020:
- errMsg = "User already exists"
- case 030:
- errMsg = "User data could not be saved"
- case 031:
- errMsg = "User data could not be read"
- case 032:
- errMsg = "User ID was not found"
- }
-
- err = errors.New(errMsg)
- return
+ var errMsg string
+ switch errCode {
+ case 000:
+ errMsg = "Authentication has not yet been initialized"
+ case 001:
+ errMsg = "Default user already exists"
+ case 002:
+ errMsg = "No user id found for this token"
+ case 010:
+ errMsg = "User authentication failed"
+ case 011:
+ errMsg = "Session has expired"
+ case 020:
+ errMsg = "User already exists"
+ case 030:
+ errMsg = "User data could not be saved"
+ case 031:
+ errMsg = "User data could not be read"
+ case 032:
+ errMsg = "User ID was not found"
+ }
+
+ err = errors.New(errMsg)
+ return
}
func defaultsForNewUser(username, password string) map[string]interface{} {
- var defaults = make(map[string]interface{})
- var salt = randomString(saltLength)
- defaults["_username"] = SHA256(username, salt)
- defaults["_password"] = SHA256(password, salt)
- defaults["_salt"] = salt
- defaults["_id"] = "id-" + randomID(idLength)
- //defaults["_one.time.token"] = randomString(tokenLength)
- defaults["data"] = make(map[string]interface{})
-
- return defaults
+ var defaults = make(map[string]interface{})
+ var salt = randomString(saltLength)
+ defaults["_username"] = SHA256(username, salt)
+ defaults["_password"] = SHA256(password, salt)
+ defaults["_salt"] = salt
+ defaults["_id"] = "id-" + randomID(idLength)
+ //defaults["_one.time.token"] = randomString(tokenLength)
+ defaults["data"] = make(map[string]interface{})
+
+ return defaults
}
func setToken(id, oldToken string) (newToken string) {
- delete(tokens, oldToken)
+ delete(tokens, oldToken)
loopToken:
- newToken = randomString(tokenLength)
- if _, ok := tokens[newToken]; ok {
- goto loopToken
- }
+ newToken = randomString(tokenLength)
+ if _, ok := tokens[newToken]; ok {
+ goto loopToken
+ }
- var tmp = make(map[string]interface{})
- tmp["id"] = id
- tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
+ var tmp = make(map[string]interface{})
+ tmp["id"] = id
+ tmp["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
- tokens[newToken] = tmp
+ tokens[newToken] = tmp
- return
-}
-
-func mapToJSON(tmpMap interface{}) string {
- jsonString, err := json.MarshalIndent(tmpMap, "", " ")
- if err != nil {
- return "{}"
- }
- return string(jsonString)
+ return
}
// SetCookieToken : set cookie
func SetCookieToken(w http.ResponseWriter, token string) http.ResponseWriter {
- expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
- cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
- http.SetCookie(w, &cookie)
- return w
+ expiration := time.Now().Add(time.Minute * time.Duration(tokenValidity))
+ cookie := http.Cookie{Name: "Token", Value: token, Expires: expiration}
+ http.SetCookie(w, &cookie)
+ return w
}
diff --git a/src/internal/imgcache/cache.go b/src/internal/imgcache/cache.go
index 0337dcc..9a2f3ce 100644
--- a/src/internal/imgcache/cache.go
+++ b/src/internal/imgcache/cache.go
@@ -30,7 +30,7 @@ type imageFunc struct {
Remove func()
}
-// New : New cahce
+// New : New cache
func New(path, chacheURL string, caching bool) (c *Cache, err error) {
c = &Cache{}
diff --git a/src/internal/m3u-parser/m3u-parser_test.go b/src/internal/m3u-parser/m3u-parser_test.go
deleted file mode 100644
index ca3e73d..0000000
--- a/src/internal/m3u-parser/m3u-parser_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package m3u
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log"
- "testing"
-)
-
-type M3UStream struct {
- GroupTitle string `json:"group-title,required"`
- Name string `json:"name,required"`
- TvgID string `json:"tvg-id,required"`
- TvgLogo string `json:"tvg-logo,required"`
- TvgName string `json:"tvg-name,required"`
- URL string `json:"url,required"`
- UUIDKey string `json:"_uuid.key,omitempty"`
- UUIDValue string `json:"_uuid.value,omitempty"`
-}
-
-func TestStream1(t *testing.T) {
-
- var file = "test_list_1.m3u"
- var content, err = ioutil.ReadFile(file)
- if err != nil {
- t.Error(err)
- return
- }
-
- streams, err := MakeInterfaceFromM3U(content)
-
- if err != nil {
- t.Error(err)
- }
-
- err = checkStream(streams)
- if err != nil {
- t.Error(err)
- }
-
- fmt.Println("Streams:", len(streams))
- t.Log(streams)
-
-}
-
-func checkStream(streamInterface []interface{}) (err error) {
-
- for i, s := range streamInterface {
-
- var stream = s.(map[string]string)
- var m3uStream M3UStream
-
- jsonString, err := json.MarshalIndent(stream, "", " ")
-
- if err == nil {
-
- err = json.Unmarshal(jsonString, &m3uStream)
- if err == nil {
-
- log.Print(fmt.Sprintf("Stream: %d", i))
- log.Print(fmt.Sprintf("Name*: %s", m3uStream.Name))
- log.Print(fmt.Sprintf("URL*: %s", m3uStream.URL))
- log.Print(fmt.Sprintf("tvg-name: %s", m3uStream.TvgName))
- log.Print(fmt.Sprintf("tvg-id**: %s", m3uStream.TvgID))
- log.Print(fmt.Sprintf("tvg-logo: %s", m3uStream.TvgLogo))
- log.Print(fmt.Sprintf("group-title**: %s", m3uStream.GroupTitle))
-
- if len(m3uStream.UUIDKey) > 0 {
- log.Print(fmt.Sprintf("UUID key***: %s", m3uStream.UUIDKey))
- log.Print(fmt.Sprintf("UUID value: %s", m3uStream.UUIDValue))
- } else {
- log.Print(fmt.Sprintf("UUID key: false"))
- }
-
- }
-
- }
-
- log.Println(fmt.Sprintf("- - - - - (*: Required) | (**: Nice to have) | (***: Love it) - - - - -"))
- }
-
- return
-}
diff --git a/src/internal/m3u-parser/test_list_1.m3u b/src/internal/m3u-parser/test_playlist_1.m3u
similarity index 58%
rename from src/internal/m3u-parser/test_list_1.m3u
rename to src/internal/m3u-parser/test_playlist_1.m3u
index 478c95d..4ba02c0 100644
--- a/src/internal/m3u-parser/test_list_1.m3u
+++ b/src/internal/m3u-parser/test_playlist_1.m3u
@@ -2,12 +2,14 @@
#EXTINF:0 channelID="1" tvg-chno="1" tvg-name="Channel.1" tvg-id="tvg.id.1" tvg-logo="https://example/logo.png" group-title="Group 1", Channel 1
http://example.com/stream/1
-#EXTINF:0 channelID="2" tvg-chno="2" tvg-name="Channel.2" tvg-id="tvg.id.2" tvg-logo="https://example/logo.png" group-title="Group 2",Channel 2
+#EXTINF:0 channelID="2" tvg-chno="2" tvg-name="Channel.2" tvg-id="tvg.id.2" tvg-logo="https://example/logo/2.png",Channel 2
+#EXTGRP: Group 2
#123
http://example.com/stream/2
-#EXTINF:123, Sample artist - Sample title
+#EXTINF:123,,:It's - a difficult name |
http://example.com/stream/3
-#EXTINF:321,Example Artist - Example title
+#EXTINF:-1 tvg-id="tvg.id.4" tvg-name="Channel.4" tvg-logo="https://example/logo/4.png" tvg-chno="4" channel-id="4" tvg-shift="-5" group-title="Group 4",Channel 4
+#EXTGRP:Group 99
http://example.com/stream/4
diff --git a/src/internal/m3u-parser/xteve_m3uParser.go b/src/internal/m3u-parser/xteve_m3uParser.go
deleted file mode 100755
index 79641b3..0000000
--- a/src/internal/m3u-parser/xteve_m3uParser.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package m3u
-
-import (
- "errors"
- "fmt"
- "log"
- "net/url"
- "regexp"
- "strings"
-)
-
-// MakeInterfaceFromM3U :
-func MakeInterfaceFromM3U(byteStream []byte) (allChannels []interface{}, err error) {
-
- var content = string(byteStream)
- var channelName string
- var uuids []string
-
- var parseMetaData = func(channel string) (stream map[string]string) {
-
- stream = make(map[string]string)
- var exceptForParameter = `[a-z-A-Z=]*(".*?")`
- var exceptForChannelName = `,([^\n]*|,[^\r]*)`
-
- var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
-
- // Zeilen mit # und leerer Zeilen entfernen
- for i := len(lines) - 1; i >= 0; i-- {
-
- if len(lines[i]) == 0 || lines[i][0:1] == "#" {
- lines = append(lines[:i], lines[i+1:]...)
- }
-
- }
-
- if len(lines) >= 2 {
-
- for _, line := range lines {
-
- _, err := url.ParseRequestURI(line)
-
- switch err {
-
- case nil:
- stream["url"] = strings.Trim(line, "\r\n")
-
- default:
-
- var value string
- // Alle Parameter parsen
- var p = regexp.MustCompile(exceptForParameter)
- var streamParameter = p.FindAllString(line, -1)
-
- for _, p := range streamParameter {
-
- line = strings.Replace(line, p, "", 1)
-
- p = strings.Replace(p, `"`, "", -1)
- var parameter = strings.SplitN(p, "=", 2)
-
- if len(parameter) == 2 {
-
- // TVG Key als Kleinbuchstaben speichern
- switch strings.Contains(parameter[0], "tvg") {
-
- case true:
- stream[strings.ToLower(parameter[0])] = parameter[1]
- case false:
- stream[parameter[0]] = parameter[1]
-
- }
-
- // URL's nicht an die Filterfunktion übergeben
- if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
- value = value + parameter[1] + " "
- }
-
- }
-
- }
-
- // Kanalnamen parsen
- n := regexp.MustCompile(exceptForChannelName)
- var name = n.FindAllString(line, 1)
-
- if len(name) > 0 {
- channelName = name[0]
- channelName = strings.Replace(channelName, `,`, "", 1)
- channelName = strings.TrimRight(channelName, "\r\n")
- channelName = strings.TrimRight(channelName, " ")
- }
-
- if len(channelName) == 0 {
-
- if v, ok := stream["tvg-name"]; ok {
- channelName = v
- }
-
- }
-
- channelName = strings.TrimRight(channelName, " ")
-
- // Kanäle ohne Namen werden augelassen
- if len(channelName) == 0 {
- return
- }
-
- stream["name"] = channelName
- value = value + channelName
-
- stream["_values"] = value
-
- }
-
- }
-
- }
-
- // Nach eindeutiger ID im Stream suchen
- for key, value := range stream {
-
- if !strings.Contains(strings.ToLower(key), "tvg-id") {
-
- if strings.Contains(strings.ToLower(key), "id") {
-
- if indexOfString(value, uuids) != -1 {
- log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
- break
- }
-
- uuids = append(uuids, value)
-
- stream["_uuid.key"] = key
- stream["_uuid.value"] = value
- break
-
- }
-
- }
-
- }
-
- return
- }
-
- //fmt.Println(content)
- if strings.Contains(content, "#EXT-X-TARGETDURATION") || strings.Contains(content, "#EXT-X-MEDIA-SEQUENCE") {
- err = errors.New("Invalid M3U file, an extended M3U file is required.")
- return
- }
-
- if strings.Contains(content, "#EXTM3U") {
-
- var channels = strings.Split(content, "#EXTINF")
-
- channels = append(channels[:0], channels[1:]...)
-
- for _, channel := range channels {
-
- var stream = parseMetaData(channel)
-
- if len(stream) > 0 && stream != nil {
- allChannels = append(allChannels, stream)
- }
-
- }
-
- } else {
-
- err = errors.New("Invalid M3U file, an extended M3U file is required.")
-
- }
-
- return
-}
-
-func indexOfString(element string, data []string) int {
-
- for k, v := range data {
- if element == v {
- return k
- }
- }
-
- return -1
-}
diff --git a/src/internal/m3u-parser/xteve_m3u_parser.go b/src/internal/m3u-parser/xteve_m3u_parser.go
new file mode 100644
index 0000000..31b0654
--- /dev/null
+++ b/src/internal/m3u-parser/xteve_m3u_parser.go
@@ -0,0 +1,188 @@
+package m3u
+
+import (
+ "errors"
+ "fmt"
+ "log"
+ "net/url"
+ "regexp"
+ "strings"
+
+ "github.com/samber/lo"
+)
+
+var exceptForParameterRx = regexp.MustCompile(`[a-z-A-Z=]*(".*?")`)
+var exceptForChannelNameRx = regexp.MustCompile(`,([^\n]*|,[^\r]*)`)
+var extGrpRx = regexp.MustCompile(`#EXTGRP: *(.*)`)
+
+// MakeInterfaceFromM3U :
+func MakeInterfaceFromM3U(byteStream []byte) (allChannels []interface{}, err error) {
+
+ var content = string(byteStream)
+ var channelName string
+ var uuids []string
+
+ var parseMetaData = func(channel string) (stream map[string]string) {
+
+ stream = make(map[string]string)
+
+ var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
+
+ // Remove lines with # and blank lines
+ for i := len(lines) - 1; i >= 0; i-- {
+
+ if len(lines[i]) == 0 || lines[i][0:1] == "#" {
+ lines = append(lines[:i], lines[i+1:]...)
+ }
+
+ }
+
+ if len(lines) >= 2 {
+
+ for _, line := range lines {
+
+ _, err := url.ParseRequestURI(line)
+
+ switch err {
+
+ case nil:
+ stream["url"] = strings.Trim(line, "\r\n")
+
+ default:
+
+ var value string
+ // Parse all parameters
+ var streamParameter = exceptForParameterRx.FindAllString(line, -1)
+
+ for _, p := range streamParameter {
+
+ line = strings.Replace(line, p, "", 1)
+
+ p = strings.Replace(p, `"`, "", -1)
+ var parameter = strings.SplitN(p, "=", 2)
+
+ if len(parameter) == 2 {
+
+ // Set TVG Key as lowercase
+ switch strings.Contains(parameter[0], "tvg") {
+
+ case true:
+ stream[strings.ToLower(parameter[0])] = parameter[1]
+ case false:
+ stream[parameter[0]] = parameter[1]
+
+ }
+
+ // URL's are not passed to the filter function
+ if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
+ value = value + parameter[1] + " "
+ }
+
+ }
+
+ }
+
+ // Parse channel names
+ var name = exceptForChannelNameRx.FindAllString(line, 1)
+
+ if len(name) > 0 {
+ channelName = name[0]
+ channelName = strings.Replace(channelName, `,`, "", 1)
+ channelName = strings.TrimRight(channelName, "\r\n")
+ channelName = strings.Trim(channelName, " ")
+ }
+
+ if len(channelName) == 0 {
+
+ if v, ok := stream["tvg-name"]; ok {
+ channelName = v
+ }
+
+ }
+
+ channelName = strings.Trim(channelName, " ")
+
+ // Channels without names are skipped
+ if len(channelName) == 0 {
+ return
+ }
+
+ stream["name"] = channelName
+ value = value + channelName
+
+ stream["_values"] = value
+
+ }
+
+ }
+
+ }
+
+ // Search for a unique ID in the stream
+ for key, value := range stream {
+
+ if !strings.Contains(strings.ToLower(key), "tvg-id") {
+
+ if strings.Contains(strings.ToLower(key), "id") {
+
+ if lo.IndexOf(uuids, value) != -1 {
+ log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
+ break
+ }
+
+ uuids = append(uuids, value)
+
+ stream["_uuid.key"] = key
+ stream["_uuid.value"] = value
+ break
+
+ }
+
+ }
+
+ }
+
+ return
+ }
+
+ if strings.Contains(content, "#EXT-X-TARGETDURATION") || strings.Contains(content, "#EXT-X-MEDIA-SEQUENCE") {
+ err = errors.New("Invalid M3U file, an extended M3U file is required.")
+ return
+ }
+
+ if strings.Contains(content, "#EXTM3U") {
+
+ var channels = strings.Split(content, "#EXTINF")
+
+ channels = append(channels[:0], channels[1:]...)
+
+ var lastExtGrp string
+
+ for _, channel := range channels {
+
+ var stream = parseMetaData(channel)
+
+ if extGrp := extGrpRx.FindStringSubmatch(channel); len(extGrp) > 1 {
+ // EXTGRP applies to all subseqent channels until overriden
+ lastExtGrp = strings.Trim(extGrp[1], "\r\n")
+ }
+
+ // group-title has priority over EXTGRP
+ if stream["group-title"] == "" && lastExtGrp != "" {
+ stream["group-title"] = lastExtGrp
+ }
+
+ if len(stream) > 0 && stream != nil {
+ allChannels = append(allChannels, stream)
+ }
+
+ }
+
+ } else {
+
+ err = errors.New("Invalid M3U file, an extended M3U file is required.")
+
+ }
+
+ return
+}
diff --git a/src/internal/m3u-parser/xteve_m3u_parser_test.go b/src/internal/m3u-parser/xteve_m3u_parser_test.go
new file mode 100644
index 0000000..8ec353f
--- /dev/null
+++ b/src/internal/m3u-parser/xteve_m3u_parser_test.go
@@ -0,0 +1,85 @@
+package m3u
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+type M3UStream struct {
+ GroupTitle string `json:"group-title,required"`
+ Name string `json:"name,required"`
+ TvgID string `json:"tvg-id,required"`
+ TvgLogo string `json:"tvg-logo,required"`
+ TvgName string `json:"tvg-name,required"`
+ TvgShift string `json:"tvg-shift,omitempty"`
+ URL string `json:"url,required"`
+ UUIDKey string `json:"_uuid.key,omitempty"`
+ UUIDValue string `json:"_uuid.value,omitempty"`
+}
+
+func TestMakeInterfaceFromM3U(t *testing.T) {
+
+ // Read playlist
+ file := "test_playlist_1.m3u"
+ content, err := ioutil.ReadFile(file)
+ assert.NoError(t, err, "Should read playlist")
+
+ // Parse playlist into []interface{}
+ rawStreams, err := MakeInterfaceFromM3U(content)
+ assert.NoError(t, err, "Should parse playlist")
+
+ // Build []M3UStream from []interface{}
+ streams := []M3UStream{}
+
+ for _, rawStream := range rawStreams {
+ jsonString, err := json.MarshalIndent(rawStream, "", " ")
+ assert.NoError(t, err, "Should convert from interface")
+
+ stream := M3UStream{}
+ err = json.Unmarshal(jsonString, &stream)
+ assert.NoError(t, err, "Should convert from interface")
+
+ streams = append(streams, stream)
+ }
+
+ assert.Len(t, streams, 4, "Should be 4 streams in total")
+
+ // Test stream 1
+ assert.Equal(t, "Channel 1", streams[0].Name, "Names should match")
+ assert.Equal(t, "Group 1", streams[0].GroupTitle, "Groups should match")
+ assert.Equal(t, "http://example.com/stream/1", streams[0].URL, "URL's should match")
+ assert.Equal(t, "Channel.1", streams[0].TvgName, "TVG names should match")
+ assert.Equal(t, "tvg.id.1", streams[0].TvgID, "TVG ID's should match")
+ assert.Equal(t, "https://example/logo.png", streams[0].TvgLogo, "TVG logos should match")
+ assert.Empty(t, streams[0].TvgShift, "Should not have tvg-shift tag")
+
+ // Test stream 2
+ assert.Equal(t, "Channel 2", streams[1].Name, "Names should match")
+ assert.Equal(t, "Group 2", streams[1].GroupTitle, "Should have a GroupTitle set from EXTGRP")
+ assert.Equal(t, "http://example.com/stream/2", streams[1].URL, "URL's should match")
+ assert.Equal(t, "Channel.2", streams[1].TvgName, "TVG names should match")
+ assert.Equal(t, "tvg.id.2", streams[1].TvgID, "TVG ID's should match")
+ assert.Equal(t, "https://example/logo/2.png", streams[1].TvgLogo, "TVG logos should match")
+ assert.Empty(t, streams[1].TvgShift, "Should not have tvg-shift tag")
+
+ // Test stream 3
+ assert.Equal(t, ",:It's - a difficult name |", streams[2].Name, "Names should match")
+ assert.Equal(t, "Group 2", streams[2].GroupTitle, "Should have a GroupTitle set from previous EXTGRP")
+ assert.Equal(t, "http://example.com/stream/3", streams[2].URL, "URL's should match")
+ assert.Empty(t, streams[2].TvgName, "Should not have tvg-name tag")
+ assert.Empty(t, streams[2].TvgID, "Should not have tvg-id tag")
+ assert.Empty(t, streams[2].TvgLogo, "Should not have tvg-logo tag")
+ assert.Empty(t, streams[2].TvgShift, "Should not have tvg-shift tag")
+
+ // Test stream 4
+ assert.Equal(t, "Channel 4", streams[3].Name, "Names should match")
+ assert.Equal(t, "Group 4", streams[3].GroupTitle, "Should have a GroupTitle set from group-title, over EXTGRP")
+ assert.Equal(t, "http://example.com/stream/4", streams[3].URL, "URL's should match")
+ assert.Equal(t, "Channel.4", streams[3].TvgName, "TVG names should match")
+ assert.Equal(t, "tvg.id.4", streams[3].TvgID, "TVG ID's should match")
+ assert.Equal(t, "https://example/logo/4.png", streams[3].TvgLogo, "TVG logos should match")
+ assert.Equal(t, "-5", streams[3].TvgShift, "TVG shifts should match")
+}
diff --git a/src/internal/up2date/client/client.go b/src/internal/up2date/client/client.go
index 13eeccc..433db84 100755
--- a/src/internal/up2date/client/client.go
+++ b/src/internal/up2date/client/client.go
@@ -61,7 +61,7 @@ func serverRequest() (err error) {
jsonByte, err := json.MarshalIndent(Updater, "", " ")
if err == nil {
- // Serververbindung prüfen
+ // Check server connection
u, err := url.Parse(Updater.URL)
if err != nil {
return err
diff --git a/src/internal/up2date/client/update.go b/src/internal/up2date/client/update.go
index 7b3b15b..0418ecc 100755
--- a/src/internal/up2date/client/update.go
+++ b/src/internal/up2date/client/update.go
@@ -187,15 +187,6 @@ func restorOldBinary(oldBinary, newBinary string) {
os.Rename(oldBinary, newBinary)
}
-func getPlatformFile(filename string) string {
-
- path, file := filepath.Split(filename)
- var newPath = filepath.Dir(path)
- var newFileName = newPath + string(os.PathSeparator) + file
-
- return newFileName
-}
-
func getFilenameFromPath(path string) string {
file := filepath.Base(path)
diff --git a/src/m3u.go b/src/m3u.go
index efb5231..033093f 100644
--- a/src/m3u.go
+++ b/src/m3u.go
@@ -10,9 +10,11 @@ import (
"strings"
m3u "xteve/src/internal/m3u-parser"
+
+ "github.com/samber/lo"
)
-// Playlisten parsen
+// Parse Playlists
func parsePlaylist(filename, fileType string) (channels []interface{}, err error) {
content, err := readByteFromFile(filename)
@@ -33,7 +35,7 @@ func parsePlaylist(filename, fileType string) (channels []interface{}, err error
return
}
-// Streams filtern
+// Filter Streams
func filterThisStream(s interface{}) (status bool) {
status = false
@@ -61,7 +63,7 @@ func filterThisStream(s interface{}) (status bool) {
name = v
}
- // Unerwünschte Streams !{DEU}
+ // Unwanted Streams !{DEU}
r := regexp.MustCompile(regexpNO)
val := r.FindStringSubmatch(filter.Rule)
@@ -73,7 +75,7 @@ func filterThisStream(s interface{}) (status bool) {
}
- // Muss zusätzlich erfüllt sein {DEU}
+ // Required Streams {DEU}
r = regexp.MustCompile(regexpYES)
val = r.FindStringSubmatch(filter.Rule)
@@ -105,6 +107,8 @@ func filterThisStream(s interface{}) (status bool) {
if group == filter.Rule {
match = true
+ stream["_preserve-mapping"] = strconv.FormatBool(filter.PreserveMapping)
+ stream["_starting-channel"] = filter.StartingChannel
}
case "custom-filter":
@@ -114,18 +118,18 @@ func filterThisStream(s interface{}) (status bool) {
}
}
- if match == true {
+ if match {
if len(exclude) > 0 {
var status = checkConditions(search, exclude, "exclude")
- if status == false {
+ if !status {
return false
}
}
if len(include) > 0 {
var status = checkConditions(search, include, "include")
- if status == false {
+ if !status {
return false
}
}
@@ -139,7 +143,7 @@ func filterThisStream(s interface{}) (status bool) {
return false
}
-// Bedingungen für den Filter
+// Conditions for the Filter
func checkConditions(streamValues, conditions, coType string) (status bool) {
switch coType {
@@ -178,7 +182,7 @@ func checkConditions(streamValues, conditions, coType string) (status bool) {
return
}
-// xTeVe M3U Datei erstellen
+// Create xTeVe M3U file
func buildM3U(groups []string) (m3u string, err error) {
var imgc = Data.Cache.Images
@@ -191,11 +195,11 @@ func buildM3U(groups []string) (m3u string, err error) {
err := json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
if err == nil {
- if xepgChannel.XActive == true {
+ if xepgChannel.XActive {
if len(groups) > 0 {
- if indexOfString(xepgChannel.XGroupTitle, groups) == -1 {
+ if lo.IndexOf(groups, xepgChannel.XGroupTitle) == -1 {
goto Done
}
@@ -215,7 +219,7 @@ func buildM3U(groups []string) (m3u string, err error) {
Done:
}
- // M3U Inhalt erstellen
+ // Create M3U Content
sort.Float64s(channelNumbers)
var xmltvURL = fmt.Sprintf("%s://%s/xmltv/xteve.xml", System.ServerProtocol.XML, System.Domain)
diff --git a/src/maintenance.go b/src/maintenance.go
index 76c499c..4698cda 100644
--- a/src/maintenance.go
+++ b/src/maintenance.go
@@ -6,7 +6,7 @@ import (
"time"
)
-// InitMaintenance : Wartungsprozess initialisieren
+// InitMaintenance : Initialize maintenance process
func InitMaintenance() (err error) {
rand.Seed(time.Now().Unix())
@@ -23,7 +23,7 @@ func maintenance() {
var t = time.Now()
- // Aktualisierung der Playlist und XMLTV Dateien
+ // Update the playlist and XMLTV files
if System.ScanInProgress == 0 {
for _, schedule := range Settings.Update {
@@ -32,13 +32,13 @@ func maintenance() {
showInfo("Update:" + schedule)
- // Backup erstellen
+ // Create a backup
err := xTeVeAutoBackup()
if err != nil {
ShowError(err, 000)
}
- // Playlist und XMLTV Dateien aktualisieren
+ // Update Playlist and XMLTV Files
getProviderData("m3u", "")
getProviderData("hdhr", "")
@@ -46,17 +46,17 @@ func maintenance() {
getProviderData("xmltv", "")
}
- // Datenbank für DVR erstellen
+ // Create database for DVR
err = buildDatabaseDVR()
if err != nil {
ShowError(err, 000)
}
- if Settings.CacheImages == false && System.ImageCachingInProgress == 0 {
+ if !Settings.CacheImages && System.ImageCachingInProgress == 0 {
removeChildItems(System.Folder.ImagesCache)
}
- // XEPG Dateien erstellen
+ // Create XEPG Files
Data.Cache.XMLTV = make(map[string]XMLTV)
buildXEPG(false)
@@ -75,7 +75,6 @@ func maintenance() {
}
- return
}
func randomTime(min, max int) int {
diff --git a/src/provider.go b/src/provider.go
index f376b3a..5da3bb2 100644
--- a/src/provider.go
+++ b/src/provider.go
@@ -11,7 +11,7 @@ import (
m3u "xteve/src/internal/m3u-parser"
)
-// fileType: Welcher Dateityp soll aktualisiert werden (m3u, hdhr, xml) | fileID: Update einer bestimmten Datei (Provider ID)
+// fileType: Which File Type should be updated (m3u, hdhr, xml) | fileID: Update a specific File (Provider ID)
func getProviderData(fileType, fileID string) (err error) {
var fileExtension, serverFileName string
@@ -30,7 +30,7 @@ func getProviderData(fileType, fileID string) (err error) {
dataMap[id] = data
}
- // Default keys für die Providerdaten
+ // Default keys for the Provider Data
var keys = []string{"name", "description", "type", "file." + System.AppName, "file.source", "tuner", "last.update", "compatibility", "counter.error", "counter.download", "provider.availability"}
for _, key := range keys {
@@ -85,14 +85,14 @@ func getProviderData(fileType, fileID string) (err error) {
data["id.provider"] = id
}
- // Datei extrahieren
+ // Extract File
body, err = extractGZIP(body, fileSource)
if err != nil {
ShowError(err, 000)
return
}
- // Daten überprüfen
+ // Check Data
showInfo("Check File:" + fileSource)
switch fileType {
@@ -151,8 +151,8 @@ func getProviderData(fileType, fileID string) (err error) {
delete(data, "new")
}
- // Wenn eine ID vorhanden ist und nicht mit der aus der Datanbank übereinstimmt, wird die Aktualisierung übersprungen (goto)
- if len(fileID) > 0 && newProvider == false {
+ // If an ID is available and does not match the one from the Database, the Update is skipped (goto)
+ if len(fileID) > 0 && !newProvider {
if dataID != fileID {
goto Done
}
@@ -162,7 +162,7 @@ func getProviderData(fileType, fileID string) (err error) {
case "hdhr":
- // Laden vom HDHomeRun Tuner
+ // Load from the HDHomeRun Tuner
showInfo("Tuner:" + fileSource)
var tunerURL = "http://" + fileSource + "/lineup.json"
serverFileName, body, err = downloadFileFromServer(tunerURL)
@@ -171,13 +171,13 @@ func getProviderData(fileType, fileID string) (err error) {
if strings.Contains(fileSource, "http://") || strings.Contains(fileSource, "https://") {
- // Laden vom Remote Server
+ // Load from the Remote Server
showInfo("Download:" + fileSource)
serverFileName, body, err = downloadFileFromServer(fileSource)
} else {
- // Laden einer lokalen Datei
+ // Load a local File
showInfo("Open:" + fileSource)
err = checkFile(fileSource)
@@ -204,9 +204,9 @@ func getProviderData(fileType, fileID string) (err error) {
ShowError(err, 000)
var downloadErr = err
- if newProvider == false {
+ if !newProvider {
- // Prüfen ob ältere Datei vorhanden ist
+ // Check whether there is an older File
var file = System.Folder.Data + dataID + fileExtension
err = checkFile(file)
@@ -219,7 +219,7 @@ func getProviderData(fileType, fileID string) (err error) {
err = downloadErr
}
- // Fehler Counter um 1 erhöhen
+ // Increase Error Counter by 1
var data = make(map[string]interface{})
if value, ok := dataMap[dataID].(map[string]interface{}); ok {
@@ -235,8 +235,8 @@ func getProviderData(fileType, fileID string) (err error) {
}
- // Berechnen der Fehlerquote
- if newProvider == false {
+ // Calculate the Margin of Error
+ if !newProvider {
if value, ok := dataMap[dataID].(map[string]interface{}); ok {
@@ -294,7 +294,7 @@ func downloadFileFromServer(providerURL string) (filename string, body []byte, e
return
}
- // Dateiname aus dem Header holen
+ // Get the File Mame from the Header
var index = strings.Index(resp.Header.Get("Content-Disposition"), "filename")
if index > -1 {
diff --git a/src/screen.go b/src/screen.go
index b3ac4df..45a60d4 100644
--- a/src/screen.go
+++ b/src/screen.go
@@ -3,6 +3,7 @@ package src
import (
"fmt"
"log"
+ "os"
"runtime"
"strconv"
"strings"
@@ -12,7 +13,7 @@ import (
func showInfo(str string) {
- if System.Flag.Info == true {
+ if System.Flag.Info {
return
}
@@ -39,7 +40,6 @@ func showInfo(str string) {
}
- return
}
func showDebug(str string, level int) {
@@ -73,7 +73,6 @@ func showDebug(str string, level int) {
}
- return
}
func showHighlight(str string) {
@@ -105,7 +104,6 @@ func showHighlight(str string) {
addNotification(notification)
- return
}
func showWarning(errCode int) {
@@ -121,10 +119,9 @@ func showWarning(errCode int) {
WebScreenLog.Warnings++
mutex.Unlock()
- return
}
-// ShowError : Zeigt die Fehlermeldungen in der Konsole
+// ShowError : Shows the Error Messages in the Console
func ShowError(err error, errCode int) {
var mutex = sync.RWMutex{}
@@ -139,7 +136,6 @@ func ShowError(err error, errCode int) {
WebScreenLog.Errors++
mutex.Unlock()
- return
}
func printLogOnScreen(logMsg string, logType string) {
@@ -211,10 +207,9 @@ func logCleanUp() {
WebScreenLog.Log = logs
- return
}
-// Fehlercodes
+// Return Error Message from numeric Error Codes
func getErrMsg(errCode int) (errMsg string) {
switch errCode {
@@ -224,166 +219,186 @@ func getErrMsg(errCode int) (errMsg string) {
// Errors
case 1001:
- errMsg = fmt.Sprintf("Web server could not be started.")
+ errMsg = "Web server could not be started."
case 1002:
- errMsg = fmt.Sprintf("No local IP address found.")
+ errMsg = "No local IP address found."
case 1003:
- errMsg = fmt.Sprintf("Invalid xml")
+ errMsg = "Invalid xml"
case 1004:
- errMsg = fmt.Sprintf("File not found")
+ errMsg = "File not found"
case 1005:
- errMsg = fmt.Sprintf("Invalid M3U file, an extended M3U file is required.")
+ errMsg = "Invalid M3U file, an extended M3U file is required."
case 1006:
- errMsg = fmt.Sprintf("No playlist!")
+ errMsg = "No playlist!"
case 1007:
- errMsg = fmt.Sprintf("XEPG requires an XMLTV file.")
+ errMsg = "XEPG requires an XMLTV file."
case 1010:
- errMsg = fmt.Sprintf("Invalid file compression")
+ errMsg = "Invalid file compression"
case 1011:
errMsg = fmt.Sprintf("Data is corrupt or unavailable, %s now uses an older version of this file", System.Name)
case 1012:
- errMsg = fmt.Sprintf("Invalid formatting of the time")
+ errMsg = "Invalid formatting of the time"
case 1013:
errMsg = fmt.Sprintf("Invalid settings file (settings.json), file must be at least version %s", System.Compatibility)
case 1014:
- errMsg = fmt.Sprintf("Invalid filter rule")
+ errMsg = "Invalid filter rule"
+ case 1015:
+ errMsg = fmt.Sprintf("Specified temp folder path is invalid, fallback to %s", os.TempDir())
+ case 1016:
+ errMsg = "Web server could not be stopped."
+ case 1017:
+ errMsg = "Web server could not be started in TLS mode, fallback to default."
+ case 1018:
+ errMsg = "Failed to compile channel name update regex"
case 1020:
- errMsg = fmt.Sprintf("Data could not be saved, invalid keyword")
+ errMsg = "Data could not be saved, invalid keyword"
- // Datenbank Update
+ // Database Update
case 1030:
errMsg = fmt.Sprintf("Invalid settings file (%s)", System.File.Settings)
case 1031:
- errMsg = fmt.Sprintf("Database error. The database version of your settings is not compatible with this version.")
+ errMsg = "Database error. The database version of your settings is not compatible with this version."
// M3U Parser
case 1050:
- errMsg = fmt.Sprintf("Invalid duration specification in the M3U8 playlist.")
+ errMsg = "Invalid duration specification in the M3U8 playlist."
case 1060:
- errMsg = fmt.Sprintf("Invalid characters found in the tvg parameters, streams with invalid parameters were skipped.")
+ errMsg = "Invalid characters found in the tvg parameters, streams with invalid parameters were skipped."
- // Dateisystem
+ // Filesystem
case 1070:
- errMsg = fmt.Sprintf("Folder could not be created.")
+ errMsg = "Folder could not be created."
case 1071:
- errMsg = fmt.Sprintf("File could not be created")
+ errMsg = "File could not be created"
case 1072:
- errMsg = fmt.Sprintf("File not found")
+ errMsg = "File not found"
+ case 1073:
+ errMsg = "Can not remove old config folder contents before recover"
// Backup
case 1090:
- errMsg = fmt.Sprintf("Automatic backup failed")
+ errMsg = "Automatic backup failed"
// Websockets
case 1100:
- errMsg = fmt.Sprintf("WebUI build error")
+ errMsg = "WebUI build error"
case 1101:
- errMsg = fmt.Sprintf("WebUI request error")
+ errMsg = "WebUI request error"
case 1102:
- errMsg = fmt.Sprintf("WebUI response error")
+ errMsg = "WebUI response error"
// PMS Guide Numbers
case 1200:
- errMsg = fmt.Sprintf("Could not create file")
+ errMsg = "Could not create file"
- // Stream URL Fehler
+ // Stream URL Error
case 1201:
- errMsg = fmt.Sprintf("Plex stream error")
+ errMsg = "Plex stream error"
case 1202:
- errMsg = fmt.Sprintf("Steaming URL could not be found in any playlist")
+ errMsg = "Steaming URL could not be found in any playlist"
case 1203:
- errMsg = fmt.Sprintf("Steaming URL could not be found in any playlist")
+ errMsg = "Steaming URL could not be found in any playlist"
case 1204:
- errMsg = fmt.Sprintf("Streaming was stopped by third party transcoder (FFmpeg / VLC)")
+ errMsg = "Streaming was stopped by third party transcoder (FFmpeg / VLC)"
// Warnings
case 2000:
- errMsg = fmt.Sprintf("Plex can not handle more than %d streams. If you do not use Plex, you can ignore this warning.", System.PlexChannelLimit)
+ errMsg = fmt.Sprintf("Plex can not handle more than %d streams. Use filter to reduce the number of streams. "+
+ "If you do not use Plex, ignore this warning.", System.PlexChannelLimit)
case 2001:
- errMsg = fmt.Sprintf("%s has loaded more than %d streams. Use the filter to reduce the number of streams.", System.Name, System.UnfilteredChannelLimit)
+ // Free slot
+ return
case 2002:
- errMsg = fmt.Sprintf("PMS can not play m3u8 streams")
+ errMsg = "PMS can not play m3u8 streams"
case 2003:
- errMsg = fmt.Sprintf("PMS can not play streams over RTSP.")
+ errMsg = "PMS can not play streams over RTSP."
case 2004:
- errMsg = fmt.Sprintf("Buffer is disabled for this stream.")
+ errMsg = "Buffer is disabled for this stream."
case 2005:
- errMsg = fmt.Sprintf("There are no channels mapped, use the mapping menu to assign EPG data to the channels.")
+ errMsg = "There are no channels mapped, use the mapping menu to assign EPG data to the channels."
case 2010:
- errMsg = fmt.Sprintf("No valid streaming URL")
+ errMsg = "No valid streaming URL"
case 2020:
- errMsg = fmt.Sprintf("FFmpeg binary was not found. Check the FFmpeg binary path in the xTeVe settings.")
+ errMsg = "FFmpeg binary was not found. Check the FFmpeg binary path in the xTeVe settings."
case 2021:
- errMsg = fmt.Sprintf("VLC binary was not found. Check the VLC path binary in the xTeVe settings.")
+ errMsg = "VLC binary was not found. Check the VLC path binary in the xTeVe settings."
+ case 2022:
+ errMsg = "Loaded database had broken XEPG mapping (version <= 2.1.1). It was cleared."
case 2099:
- errMsg = fmt.Sprintf("Updates have been disabled by the developer")
+ errMsg = "Updates have been disabled by the developer"
// Tuner
case 2105:
errMsg = fmt.Sprintf("The number of tuners has changed, you have to delete " + System.Name + " in Plex / Emby HDHR and set it up again.")
case 2106:
- errMsg = fmt.Sprintf("This function is only available with XEPG as EPG source")
+ errMsg = "This function is only available with XEPG as EPG source"
case 2110:
- errMsg = fmt.Sprintf("Don't run this as Root!")
+ errMsg = "Don't run this as Root!"
case 2300:
- errMsg = fmt.Sprintf("No channel logo found in the XMLTV or M3U file.")
+ errMsg = "No channel logo found in the XMLTV or M3U file."
case 2301:
- errMsg = fmt.Sprintf("XMLTV file no longer available, channel has been deactivated.")
+ errMsg = "XMLTV file no longer available, channel has been deactivated."
case 2302:
- errMsg = fmt.Sprintf("Channel ID in the XMLTV file has changed. Channel has been deactivated.")
+ errMsg = "Channel ID in the XMLTV file has changed. Channel has been deactivated."
- // Benutzerauthentifizierung
+ // User Authentication
case 3000:
- errMsg = fmt.Sprintf("Database for user authentication could not be initialized.")
+ errMsg = "Database for user authentication could not be initialized."
case 3001:
- errMsg = fmt.Sprintf("The user has no authorization to load the channels.")
+ errMsg = "The user has no authorization to load the channels."
// Buffer
case 4000:
- errMsg = fmt.Sprintf("Connection to streaming source was interrupted.")
+ errMsg = "Connection to streaming source was interrupted."
case 4001:
- errMsg = fmt.Sprintf("Too many errors connecting to the provider. Streaming is canceled.")
+ errMsg = "Too many errors connecting to the provider. Streaming is canceled."
case 4002:
- errMsg = fmt.Sprintf("New URL for the redirect to the streaming server is missing")
+ errMsg = "New URL for the redirect to the streaming server is missing"
case 4003:
- errMsg = fmt.Sprintf("Server sends an incompatible content-type")
+ errMsg = "Server sends an incompatible content-type"
case 4004:
- errMsg = fmt.Sprintf("This error message comes from the provider")
+ errMsg = "This error message comes from the provider"
case 4005:
- errMsg = fmt.Sprintf("Temporary buffer files could not be deleted")
+ errMsg = "Temporary buffer files could not be deleted"
case 4006:
- errMsg = fmt.Sprintf("Server connection timeout")
+ errMsg = "Server connection timeout"
+ case 4007:
+ errMsg = "Old temporary buffer file could not be deleted"
- // Buffer (M3U8)
+ // Buffer (M3U8
case 4050:
- errMsg = fmt.Sprintf("Invalid M3U8 file")
+ errMsg = "Invalid M3U8 file"
case 4051:
- errMsg = fmt.Sprintf("#EXTM3U header is missing")
+ errMsg = "#EXTM3U header is missing"
// Caching
case 4100:
- errMsg = fmt.Sprintf("Unknown content type for downloaded image")
+ errMsg = "Unknown content type for downloaded image"
case 4101:
- errMsg = fmt.Sprintf("Invalid URL, original URL is used for this image")
+ errMsg = "Invalid URL, original URL is used for this image"
// API
case 5000:
- errMsg = fmt.Sprintf("Invalid API command")
+ errMsg = "Invalid API command"
// Update Server
case 6001:
- errMsg = fmt.Sprintf("Ivalid key")
+ errMsg = "Ivalid key"
case 6002:
- errMsg = fmt.Sprintf("Update failed")
+ errMsg = "Update failed"
case 6003:
- errMsg = fmt.Sprintf("Update server not available")
+ errMsg = "Update server not available"
case 6004:
- errMsg = fmt.Sprintf("xTeVe update available")
+ errMsg = "xTeVe update available"
+
+ // Certificates
+ case 7000:
+ errMsg = "Can not generate a certificate"
default:
errMsg = fmt.Sprintf("Unknown error / warning (%d)", errCode)
@@ -392,6 +407,17 @@ func getErrMsg(errCode int) (errMsg string) {
return errMsg
}
+func sendAlert(text string) {
+
+ select {
+ case webAlerts <- text:
+ //
+ default:
+ err := fmt.Errorf("client alert buffer is full, dropping the message: %v", text)
+ ShowError(err, 0)
+ }
+}
+
func addNotification(notification Notification) (err error) {
var i int
diff --git a/src/ssdp.go b/src/ssdp.go
index 63ce77c..9fc6074 100644
--- a/src/ssdp.go
+++ b/src/ssdp.go
@@ -1,72 +1,72 @@
package src
import (
- "fmt"
- "log"
- "os"
- "os/signal"
- "time"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "time"
- "github.com/koron/go-ssdp"
+ "github.com/koron/go-ssdp"
)
// SSDP : SSPD / DLNA Server
func SSDP() (err error) {
- if Settings.SSDP == false || System.Flag.Info == true {
- return
- }
+ if !Settings.SSDP || System.Flag.Info {
+ return
+ }
- showInfo(fmt.Sprintf("SSDP / DLNA:%t", Settings.SSDP))
+ showInfo(fmt.Sprintf("SSDP / DLNA:%t", Settings.SSDP))
- quit := make(chan os.Signal, 1)
- signal.Notify(quit, os.Interrupt)
+ quit := make(chan os.Signal, 1)
+ signal.Notify(quit, os.Interrupt)
- ad, err := ssdp.Advertise(
- fmt.Sprintf("upnp:rootdevice"), // send as "ST"
- fmt.Sprintf("uuid:%s::upnp:rootdevice", System.DeviceID), // send as "USN"
- fmt.Sprintf("%s/device.xml", System.URLBase), // send as "LOCATION"
- System.AppName, // send as "SERVER"
- 1800) // send as "maxAge" in "CACHE-CONTROL"
+ ad, err := ssdp.Advertise(
+ "upnp:rootdevice", // send as "ST"
+ fmt.Sprintf("uuid:%s::upnp:rootdevice", System.DeviceID), // send as "USN"
+ fmt.Sprintf("%s/device.xml", System.URLBase), // send as "LOCATION"
+ System.AppName, // send as "SERVER"
+ 1800) // send as "maxAge" in "CACHE-CONTROL"
- if err != nil {
- return
- }
+ if err != nil {
+ return
+ }
- // Debug SSDP
- if System.Flag.Debug == 3 {
- ssdp.Logger = log.New(os.Stderr, "[SSDP] ", log.LstdFlags)
- }
+ // Debug SSDP
+ if System.Flag.Debug == 3 {
+ ssdp.Logger = log.New(os.Stderr, "[SSDP] ", log.LstdFlags)
+ }
- go func(adv *ssdp.Advertiser) {
+ go func(adv *ssdp.Advertiser) {
- aliveTick := time.Tick(300 * time.Second)
+ aliveTick := time.NewTicker(300 * time.Second)
- loop:
- for {
+ loop:
+ for {
- select {
+ select {
- case <-aliveTick:
- err = adv.Alive()
- if err != nil {
- ShowError(err, 0)
- adv.Bye()
- adv.Close()
- break loop
- }
+ case <-aliveTick.C:
+ err = adv.Alive()
+ if err != nil {
+ ShowError(err, 0)
+ adv.Bye()
+ adv.Close()
+ break loop
+ }
- case <-quit:
- adv.Bye()
- adv.Close()
- os.Exit(0)
- break loop
+ case <-quit:
+ adv.Bye()
+ adv.Close()
+ os.Exit(0)
+ break loop
- }
+ }
- }
+ }
- }(ad)
+ }(ad)
- return
+ return
}
diff --git a/src/struct-buffer.go b/src/struct-buffer.go
index b56e2d5..6c4cf5f 100644
--- a/src/struct-buffer.go
+++ b/src/struct-buffer.go
@@ -2,7 +2,7 @@ package src
import "time"
-// Playlist : Enthält allen Playlistinformationen, die der Buffer benötigr
+// Playlist : Contains all Playlist Information that the Buffer needs
type Playlist struct {
Folder string
PlaylistID string
@@ -13,12 +13,12 @@ type Playlist struct {
Streams map[int]ThisStream
}
-// ThisClient : Clientinfos
+// ThisClient : Client Information
type ThisClient struct {
Connection int
}
-// ThisStream : Enthält Informationen zu dem abzuspielenden Stream einer Playlist
+// ThisStream : Contains Information about the Playlist Stream to be played
type ThisStream struct {
ChannelName string
Error string
@@ -32,7 +32,7 @@ type ThisStream struct {
Segment []Segment
- // Serverinformationen
+ // Server information
Location string
URLFile string
URLHost string
@@ -41,7 +41,7 @@ type ThisStream struct {
URLScheme string
URLStreamingServer string
- // Wird nur für HLS / M3U8 verwendet
+ // Is only used for HLS / M3U8
Body string
Difference float64
Duration float64
@@ -62,11 +62,11 @@ type ThisStream struct {
DynamicStream map[int]DynamicStream
- // Lokale Temp Datein
+ // Local Temp Files
OldSegments []string
}
-// Segment : URL Segmente (HLS / M3U8)
+// Segment : URL Segments (HLS / M3U8)
type Segment struct {
Duration float64
Info bool
@@ -85,7 +85,7 @@ type Segment struct {
}
}
-// DynamicStream : Streaminformationen bei dynamischer Bandbreite
+// DynamicStream : Stream Information with dynamic Bandwidth
type DynamicStream struct {
AverageBandwidth int
Bandwidth int
@@ -94,13 +94,13 @@ type DynamicStream struct {
URL string
}
-// ClientConnection : Client Verbindungen
+// ClientConnection : Client Connections
type ClientConnection struct {
Connection int
Error error
}
-// BandwidthCalculation : Bandbreitenberechnung für den Stream
+// BandwidthCalculation : Bandwidth Calculation for the Stream
type BandwidthCalculation struct {
NetworkBandwidth int
Size int
diff --git a/src/struct-hdhr.go b/src/struct-hdhr.go
index f0376ce..7a361fe 100644
--- a/src/struct-hdhr.go
+++ b/src/struct-hdhr.go
@@ -53,7 +53,7 @@ type Lineup []interface {
//URL string `json:"URL"`
}
-// LineupStream : HDHR einzelner Stream im Lineup
+// LineupStream : HDHR single Stream in the Lineup
type LineupStream struct {
GuideName string `json:"GuideName"`
GuideNumber string `json:"GuideNumber"`
diff --git a/src/struct-system.go b/src/struct-system.go
index 595f4d2..630dd4c 100644
--- a/src/struct-system.go
+++ b/src/struct-system.go
@@ -1,8 +1,11 @@
package src
-import "xteve/src/internal/imgcache"
+import (
+ "net"
+ "xteve/src/internal/imgcache"
+)
-// SystemStruct : Beinhaltet alle Systeminformationen
+// SystemStruct : Contains all System Information
type SystemStruct struct {
Addresses struct {
DVR string
@@ -10,20 +13,19 @@ type SystemStruct struct {
XML string
}
- APIVersion string
- AppName string
- ARCH string
- BackgroundProcess bool
- Branch string
- Build string
- Compatibility string
- ConfigurationWizard bool
- DBVersion string
- Dev bool
- DeviceID string
- Domain string
- PlexChannelLimit int
- UnfilteredChannelLimit int
+ APIVersion string
+ AppName string
+ ARCH string
+ BackgroundProcess bool
+ Branch string
+ Build string
+ Compatibility string
+ ConfigurationWizard bool
+ DBVersion string
+ Dev bool
+ DeviceID string
+ Domain string
+ PlexChannelLimit int
FFmpeg struct {
DefaultOptions string
@@ -36,13 +38,15 @@ type SystemStruct struct {
}
File struct {
- Authentication string
- M3U string
- PMS string
- Settings string
- URLS string
- XEPG string
- XML string
+ Authentication string
+ M3U string
+ PMS string
+ ServerCert string
+ ServerCertPrivKey string
+ Settings string
+ URLS string
+ XEPG string
+ XML string
}
Compressed struct {
@@ -61,6 +65,7 @@ type SystemStruct struct {
Folder struct {
Backup string
Cache string
+ Certificates string
Config string
Data string
ImagesCache string
@@ -70,10 +75,11 @@ type SystemStruct struct {
Hostname string
ImageCachingInProgress int
- IPAddress string
- IPAddressesList []string
- IPAddressesV4 []string
- IPAddressesV6 []string
+ IPAddressesList []string // Every IP address available (IPv4 + IPv6)
+ IPAddressesV4 []string // Every IPv4 address available in string format
+ IPAddressesV4Host []string // Every IPv4 address available except loopback and link-local
+ IPAddressesV4Raw []net.IP // Every IPv4 address available in net.IP format
+ IPAddressesV6 []string // Every IPv6 address available
Name string
OS string
ScanInProgress int
@@ -109,13 +115,13 @@ type SystemStruct struct {
}
}
-// GitStruct : Updateinformationen von GitHub
+// GitStruct : Update information from GitHub
type GitStruct struct {
Filename string `json:"filename"`
Version string `json:"version"`
}
-// DataStruct : Alle Daten werden hier abgelegt. (Lineup, XMLTV)
+// DataStruct : All Data is stored here. (Lineup, XMLTV)
type DataStruct struct {
Cache struct {
Images *imgcache.Cache
@@ -165,114 +171,130 @@ type DataStruct struct {
}
}
-// Filter : Wird für die Filterregeln verwendet
+// Filter : Used for the Filter Rules
type Filter struct {
- CaseSensitive bool
- Rule string
- Type string
+ CaseSensitive bool
+ PreserveMapping bool
+ Rule string
+ Type string
+ StartingChannel string
}
-// XEPGChannelStruct : XEPG Struktur
+// XEPGChannelStruct : XEPG Structure
type XEPGChannelStruct struct {
- FileM3UID string `json:"_file.m3u.id,required"`
- FileM3UName string `json:"_file.m3u.name,required"`
- FileM3UPath string `json:"_file.m3u.path,required"`
- GroupTitle string `json:"group-title,required"`
- Name string `json:"name,required"`
- TvgID string `json:"tvg-id,required"`
- TvgLogo string `json:"tvg-logo,required"`
- TvgName string `json:"tvg-name,required"`
- URL string `json:"url,required"`
- UUIDKey string `json:"_uuid.key,required"`
- UUIDValue string `json:"_uuid.value,omitempty"`
- Values string `json:"_values,required"`
- XActive bool `json:"x-active,required"`
- XCategory string `json:"x-category,required"`
- XChannelID string `json:"x-channelID,required"`
- XEPG string `json:"x-epg,required"`
- XGroupTitle string `json:"x-group-title,required"`
- XMapping string `json:"x-mapping,required"`
- XmltvFile string `json:"x-xmltv-file,required"`
- XName string `json:"x-name,required"`
- XUpdateChannelIcon bool `json:"x-update-channel-icon,required"`
- XUpdateChannelName bool `json:"x-update-channel-name,required"`
- XDescription string `json:"x-description,required"`
+ FileM3UID string `json:"_file.m3u.id"`
+ FileM3UName string `json:"_file.m3u.name"`
+ FileM3UPath string `json:"_file.m3u.path"`
+ GroupTitle string `json:"group-title"`
+ Name string `json:"name"`
+ TvgID string `json:"tvg-id"`
+ TvgLogo string `json:"tvg-logo"`
+ TvgName string `json:"tvg-name"`
+ TvgShift string `json:"tvg-shift"`
+ UpdateChannelNameRegex string `json:"update-channel-name-regex"`
+ UpdateChannelNameByGroupRegex string `json:"update-channel-name-by-group-regex"`
+ URL string `json:"url"`
+ UUIDKey string `json:"_uuid.key"`
+ UUIDValue string `json:"_uuid.value,omitempty"`
+ Values string `json:"_values"`
+ XActive bool `json:"x-active"`
+ XCategory string `json:"x-category"`
+ XChannelID string `json:"x-channelID"`
+ XEPG string `json:"x-epg"`
+ XGroupTitle string `json:"x-group-title"`
+ XMapping string `json:"x-mapping"`
+ XmltvFile string `json:"x-xmltv-file"`
+ XName string `json:"x-name"`
+ XUpdateChannelIcon bool `json:"x-update-channel-icon"`
+ XUpdateChannelName bool `json:"x-update-channel-name"`
+ XUpdateChannelGroup bool `json:"x-update-channel-group"`
+ XDescription string `json:"x-description"`
+ XTimeshift string `json:"x-timeshift"`
}
-// M3UChannelStructXEPG : M3U Struktur für XEPG
+// M3UChannelStructXEPG : M3U Structure for XEPG
type M3UChannelStructXEPG struct {
- FileM3UID string `json:"_file.m3u.id,required"`
- FileM3UName string `json:"_file.m3u.name,required"`
- FileM3UPath string `json:"_file.m3u.path,required"`
- GroupTitle string `json:"group-title,required"`
- Name string `json:"name,required"`
- TvgID string `json:"tvg-id,required"`
- TvgLogo string `json:"tvg-logo,required"`
- TvgName string `json:"tvg-name,required"`
- URL string `json:"url,required"`
- UUIDKey string `json:"_uuid.key,required"`
- UUIDValue string `json:"_uuid.value,required"`
- Values string `json:"_values,required"`
+ FileM3UID string `json:"_file.m3u.id"`
+ FileM3UName string `json:"_file.m3u.name"`
+ FileM3UPath string `json:"_file.m3u.path"`
+ GroupTitle string `json:"group-title"`
+ Name string `json:"name"`
+ TvgID string `json:"tvg-id"`
+ TvgLogo string `json:"tvg-logo"`
+ TvgName string `json:"tvg-name"`
+ TvgShift string `json:"tvg-shift"`
+ URL string `json:"url"`
+ UUIDKey string `json:"_uuid.key"`
+ UUIDValue string `json:"_uuid.value"`
+ Values string `json:"_values"`
+ PreserveMapping string `json:"_preserve-mapping"`
+ StartingChannel string `json:"_starting-channel"`
}
-// FilterStruct : Filter Struktur
+// FilterStruct : Filter Structure
type FilterStruct struct {
- Active bool `json:"active,required"`
- CaseSensitive bool `json:"caseSensitive,required"`
- Description string `json:"description,required"`
- Exclude string `json:"exclude,required"`
- Filter string `json:"filter,required"`
- Include string `json:"include,required"`
- Name string `json:"name,required"`
- Rule string `json:"rule,omitempty"`
- Type string `json:"type,required"`
+ Active bool `json:"active"`
+ CaseSensitive bool `json:"caseSensitive"`
+ PreserveMapping bool `json:"preserveMapping"`
+ Description string `json:"description"`
+ Exclude string `json:"exclude"`
+ Filter string `json:"filter"`
+ Include string `json:"include"`
+ Name string `json:"name"`
+ Rule string `json:"rule,omitempty"`
+ Type string `json:"type"`
+ StartingChannel string `json:"startingChannel"`
}
-// StreamingURLS : Informationen zu allen streaming URL's
+// StreamingURLS : Information on all Streaming URL's
type StreamingURLS struct {
- Streams map[string]StreamInfo `json:"channels,required"`
+ Streams map[string]StreamInfo `json:"channels"`
}
-// StreamInfo : Informationen zum Kanal für die streaming URL
+// StreamInfo : Information about the Channel for the Streaming URL
type StreamInfo struct {
- ChannelNumber string `json:"channelNumber,required"`
- Name string `json:"name,required"`
- PlaylistID string `json:"playlistID,required"`
- URL string `json:"url,required"`
- URLid string `json:"urlID,required"`
+ ChannelNumber string `json:"channelNumber"`
+ Name string `json:"name"`
+ PlaylistID string `json:"playlistID"`
+ URL string `json:"url"`
+ URLid string `json:"urlID"`
}
-// Notification : Notifikationen im Webinterface
+// Notification : Notifications in the Web Interface
type Notification struct {
- Headline string `json:"headline,required"`
- Message string `json:"message,required"`
- New bool `json:"new,required"`
- Time string `json:"time,required"`
- Type string `json:"type,required"`
+ Headline string `json:"headline"`
+ Message string `json:"message"`
+ New bool `json:"new"`
+ Time string `json:"time"`
+ Type string `json:"type"`
}
-// SettingsStruct : Inhalt der settings.json
+// SettingsStruct : Content of settings.json
type SettingsStruct struct {
- API bool `json:"api"`
- AuthenticationAPI bool `json:"authentication.api"`
- AuthenticationM3U bool `json:"authentication.m3u"`
- AuthenticationPMS bool `json:"authentication.pms"`
- AuthenticationWEB bool `json:"authentication.web"`
- AuthenticationXML bool `json:"authentication.xml"`
- BackupKeep int `json:"backup.keep"`
- BackupPath string `json:"backup.path"`
- Branch string `json:"git.branch,omitempty"`
- Buffer string `json:"buffer"`
- BufferSize int `json:"buffer.size.kb"`
- BufferTimeout float64 `json:"buffer.timeout"`
- CacheImages bool `json:"cache.images"`
- EpgSource string `json:"epgSource"`
- FFmpegOptions string `json:"ffmpeg.options"`
- FFmpegPath string `json:"ffmpeg.path"`
- VLCOptions string `json:"vlc.options"`
- VLCPath string `json:"vlc.path"`
- FileM3U []string `json:"file,omitempty"` // Beim Wizard wird die M3U in ein Slice gespeichert
- FileXMLTV []string `json:"xmltv,omitempty"` // Altes Speichersystem der Provider XML Datei Slice (Wird für die Umwandlung auf das neue benötigt)
+ API bool `json:"api"`
+ AuthenticationAPI bool `json:"authentication.api"`
+ AuthenticationM3U bool `json:"authentication.m3u"`
+ AuthenticationPMS bool `json:"authentication.pms"`
+ AuthenticationWEB bool `json:"authentication.web"`
+ AuthenticationXML bool `json:"authentication.xml"`
+ BackupKeep int `json:"backup.keep"`
+ BackupPath string `json:"backup.path"`
+ Branch string `json:"git.branch,omitempty"`
+ Buffer string `json:"buffer"`
+ BufferSize int `json:"buffer.size.kb"`
+ BufferTimeout float64 `json:"buffer.timeout"`
+ CacheImages bool `json:"cache.images"`
+ ClearXMLTVCache bool `json:"clearXMLTVCache"`
+ DefaultMissingEPG string `json:"defaultMissingEPG"`
+ DisallowURLDuplicates bool `json:"disallowURLDuplicates"`
+ EnableMappedChannels bool `json:"enableMappedChannels"`
+ EpgSource string `json:"epgSource"`
+ FFmpegOptions string `json:"ffmpeg.options"`
+ FFmpegPath string `json:"ffmpeg.path"`
+ VLCOptions string `json:"vlc.options"`
+ VLCPath string `json:"vlc.path"`
+ FileM3U []string `json:"file,omitempty"` // In the Wizard, the M3U is saved in a Slice
+ FileXMLTV []string `json:"xmltv,omitempty"` // Old Storage System of the provider XML File Slice (Required for the conversion to the new one)
Files struct {
HDHR map[string]interface{} `json:"hdhr"`
@@ -282,6 +304,8 @@ type SettingsStruct struct {
FilesUpdate bool `json:"files.update"`
Filter map[int64]interface{} `json:"filter"`
+ HostIP string `json:"hostIP"` // IP chosen in web client. Used to form m3u and xml files.
+ HostName string `json:"hostName"` // Hostname chosen in web client. Used to form m3u and xml files.
Key string `json:"key,omitempty"`
Language string `json:"language"`
LogEntriesRAM int `json:"log.entries.ram"`
@@ -289,7 +313,9 @@ type SettingsStruct struct {
MappingFirstChannel float64 `json:"mapping.first.channel"`
Port string `json:"port"`
SSDP bool `json:"ssdp"`
+ StoreBufferInRAM bool `json:"storeBufferInRAM"`
TempPath string `json:"temp.path"`
+ TLSMode bool `json:"tlsMode"`
Tuner int `json:"tuner"`
Update []string `json:"update"`
UpdateURL string `json:"update.url,omitempty"`
@@ -301,7 +327,7 @@ type SettingsStruct struct {
XteveAutoUpdate bool `json:"xteveAutoUpdate"`
}
-// LanguageUI : Sprache für das WebUI
+// LanguageUI : Language for the WebUI
type LanguageUI struct {
Login struct {
Failed string
diff --git a/src/struct-webserver.go b/src/struct-webserver.go
index e87abcb..0640563 100644
--- a/src/struct-webserver.go
+++ b/src/struct-webserver.go
@@ -1,11 +1,11 @@
package src
-// RequestStruct : Anfragen über die Websocket Schnittstelle
+// RequestStruct : Requests via the Websocket Interface
type RequestStruct struct {
- // Befehle an xTeVe
- Cmd string `json:"cmd,required"`
+ // Commands to xTeVe
+ Cmd string `json:"cmd"`
- // Benutzer
+ // User
DeleteUser bool `json:"deleteUser,omitempty"`
UserData map[string]interface{} `json:"userData,omitempty"`
@@ -15,7 +15,7 @@ type RequestStruct struct {
// Restore
Base64 string `json:"base64,omitempty"`
- // Neue Werte für die Einstellungen (settings.json)
+ // New Values for the Settings (settings.json)
Settings struct {
API *bool `json:"api,omitempty"`
AuthenticationAPI *bool `json:"authentication.api,omitempty"`
@@ -26,16 +26,23 @@ type RequestStruct struct {
BackupKeep *int `json:"backup.keep,omitempty"`
BackupPath *string `json:"backup.path,omitempty"`
Buffer *string `json:"buffer,omitempty"`
- BufferSize *int `json:"buffer.size.kb, omitempty"`
+ BufferSize *int `json:"buffer.size.kb,omitempty"`
BufferTimeout *float64 `json:"buffer.timeout,omitempty"`
CacheImages *bool `json:"cache.images,omitempty"`
+ ClearXMLTVCache *bool `json:"clearXMLTVCache,omitempty"`
+ DefaultMissingEPG *string `json:"defaultMissingEPG,omitempty"`
+ DisallowURLDuplicates *bool `json:"disallowURLDuplicates,omitempty"`
+ EnableMappedChannels *bool `json:"enableMappedChannels,omitempty"`
EpgSource *string `json:"epgSource,omitempty"`
FFmpegOptions *string `json:"ffmpeg.options,omitempty"`
FFmpegPath *string `json:"ffmpeg.path,omitempty"`
VLCOptions *string `json:"vlc.options,omitempty"`
VLCPath *string `json:"vlc.path,omitempty"`
FilesUpdate *bool `json:"files.update,omitempty"`
+ HostIP *string `json:"hostIP,omitempty"` // IP chosen in web client. Used to form m3u and xml files.
+ HostName *string `json:"hostName"` // Hostname chosen in web client. Used to form m3u and xml files.
TempPath *string `json:"temp.path,omitempty"`
+ TLSMode *bool `json:"tlsMode,omitempty"`
Tuner *int `json:"tuner,omitempty"`
UDPxy *string `json:"udpxy,omitempty"`
Update *[]string `json:"update,omitempty"`
@@ -44,6 +51,7 @@ type RequestStruct struct {
XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"`
SchemeM3U *string `json:"scheme.m3u,omitempty"`
SchemeXML *string `json:"scheme.xml,omitempty"`
+ StoreBufferInRAM *bool `json:"storeBufferInRAM,omitempty"`
} `json:"settings,omitempty"`
// Upload Logo
@@ -52,7 +60,7 @@ type RequestStruct struct {
// Filter
Filter map[int64]interface{} `json:"filter,omitempty"`
- // Dateien (M3U, HDHR, XMLTV)
+ // Files (M3U, HDHR, XMLTV)
Files struct {
HDHR map[string]interface{} `json:"hdhr,omitempty"`
M3U map[string]interface{} `json:"m3u,omitempty"`
@@ -68,7 +76,7 @@ type RequestStruct struct {
} `json:"wizard,omitempty"`
}
-// ResponseStruct : Antworten an den Client (WEB)
+// ResponseStruct : Responses to the Client (WEB)
type ResponseStruct struct {
ClientInfo struct {
ARCH string `json:"arch"`
@@ -76,51 +84,52 @@ type ResponseStruct struct {
DVR string `json:"DVR"`
EpgSource string `json:"epgSource"`
Errors int `json:"errors"`
- M3U string `json:"m3u-url,required"`
+ M3U string `json:"m3u-url"`
OS string `json:"os"`
Streams string `json:"streams"`
UUID string `json:"uuid"`
Version string `json:"version"`
Warnings int `json:"warnings"`
XEPGCount int64 `json:"xepg"`
- XML string `json:"xepg-url,required"`
+ XML string `json:"xepg-url"`
} `json:"clientInfo,omitempty"`
Data struct {
Playlist struct {
M3U struct {
Groups struct {
- Text []string `json:"text,required"`
- Value []string `json:"value,required"`
- } `json:"groups,required"`
- } `json:"m3u,required"`
- } `json:"playlist,required"`
+ Text []string `json:"text"`
+ Value []string `json:"value"`
+ } `json:"groups"`
+ } `json:"m3u"`
+ } `json:"playlist"`
StreamPreviewUI struct {
- Active []string `json:"activeStreams,required"`
- Inactive []string `json:"inactiveStreams,required"`
+ Active []string `json:"activeStreams"`
+ Inactive []string `json:"inactiveStreams"`
}
- } `json:"data,required"`
+ } `json:"data"`
Alert string `json:"alert,omitempty"`
- ConfigurationWizard bool `json:"configurationWizard,required"`
+ ConfigurationWizard bool `json:"configurationWizard"`
Error string `json:"err,omitempty"`
- Log WebScreenLogStruct `json:"log,required"`
+ IPAddressesV4Host []string `json:"ipAddressesV4Host"` // Every IPv4 address to display in web client
+ Log WebScreenLogStruct `json:"log"`
LogoURL string `json:"logoURL,omitempty"`
OpenLink string `json:"openLink,omitempty"`
OpenMenu string `json:"openMenu,omitempty"`
Reload bool `json:"reload,omitempty"`
- Settings SettingsStruct `json:"settings,required"`
- Status bool `json:"status,required"`
+ Settings SettingsStruct `json:"settings"`
+ Status bool `json:"status"`
Token string `json:"token,omitempty"`
Users map[string]interface{} `json:"users,omitempty"`
Wizard int `json:"wizard,omitempty"`
- XEPG map[string]interface{} `json:"xepg,required"`
+ XEPG map[string]interface{} `json:"xepg"`
Notification map[string]Notification `json:"notification,omitempty"`
}
-// APIRequestStruct : Anfrage über die API Schnittstelle
+// APIRequestStruct : Request via the API interface
type APIRequestStruct struct {
Cmd string `json:"cmd"`
Password string `json:"password"`
@@ -128,15 +137,17 @@ type APIRequestStruct struct {
Username string `json:"username"`
}
-// APIResponseStruct : Antwort an den Client (API)
+// APIResponseStruct : Response to the Client (API)
type APIResponseStruct struct {
EpgSource string `json:"epg.source,omitempty"`
Error string `json:"err,omitempty"`
- Status bool `json:"status,required"`
+ Status bool `json:"status"`
StreamsActive int64 `json:"streams.active,omitempty"`
StreamsAll int64 `json:"streams.all,omitempty"`
StreamsXepg int64 `json:"streams.xepg,omitempty"`
Token string `json:"token,omitempty"`
+ TunerActive int64 `json:"tuners.active,omitempty"`
+ TunerAll int64 `json:"tuners.all,omitempty"`
URLDvr string `json:"url.dvr,omitempty"`
URLM3U string `json:"url.m3u,omitempty"`
URLXepg string `json:"url.xepg,omitempty"`
@@ -144,9 +155,9 @@ type APIResponseStruct struct {
VersionXteve string `json:"version.xteve,omitempty"`
}
-// WebScreenLogStruct : Logs werden im RAM gespeichert und für das Webinterface bereitgestellt
+// WebScreenLogStruct : Logs are saved in RAM and made available for the Web Interface
type WebScreenLogStruct struct {
- Errors int `json:"errors,required"`
- Log []string `json:"log,required"`
- Warnings int `json:"warnings,required"`
+ Errors int `json:"errors"`
+ Log []string `json:"log"`
+ Warnings int `json:"warnings"`
}
diff --git a/src/struct-xml.go b/src/struct-xml.go
index c79f385..da9faa9 100644
--- a/src/struct-xml.go
+++ b/src/struct-xml.go
@@ -2,7 +2,7 @@ package src
import "encoding/xml"
-// XMLTV : XMLTV Datei
+// XMLTV : XMLTV File
type XMLTV struct {
Generator string `xml:"generator-info-name,attr"`
Source string `xml:"source-info-name,attr"`
@@ -12,24 +12,24 @@ type XMLTV struct {
Program []*Program `xml:"programme"`
}
-// Channel : Kanäle
+// Channel : Channels
type Channel struct {
- ID string `xml:"id,attr"`
- DisplayName []DisplayName `xml:"display-name"`
- Icon Icon `xml:"icon"`
+ ID string `xml:"id,attr"`
+ DisplayNames []DisplayName `xml:"display-name"`
+ Icon Icon `xml:"icon"`
}
-// DisplayName : Kanalname
+// DisplayName : Channel Name
type DisplayName struct {
Value string `xml:",chardata"`
}
-// Icon : Senderlogo
+// Icon : Station Logo
type Icon struct {
Src string `xml:"src,attr"`
}
-// Program : Programme
+// Program : Programs
type Program struct {
Channel string `xml:"channel,attr"`
Start string `xml:"start,attr"`
@@ -54,61 +54,61 @@ type Program struct {
Premiere *Live `xml:"premiere"`
}
-// Title : Programmtitel
+// Title : Program Title
type Title struct {
Lang string `xml:"lang,attr"`
Value string `xml:",chardata"`
}
-// SubTitle : Kurzbeschreibung
+// SubTitle : Brief Description
type SubTitle struct {
Lang string `xml:"lang,attr"`
Value string `xml:",chardata"`
}
-//Desc : Programmbeschreibung
+//Desc : Program Description
type Desc struct {
Lang string `xml:"lang,attr"`
Value string `xml:",chardata"`
}
-// Category : Kategorien
+// Category : Categories
type Category struct {
Lang string `xml:"lang,attr"`
Value string `xml:",chardata"`
}
-// Rating : Bewertung
+// Rating : Rating
type Rating struct {
System string `xml:"system,attr"`
Value string `xml:"value"`
Icon []Icon `xml:"icon"`
}
-// StarRating : Bewertung / Kritiken
+// StarRating : Rating / Reviews
type StarRating struct {
Value string `xml:"value"`
System string `xml:"system,attr"`
}
-// Language : Sprachen
+// Language : Langueages
type Language struct {
Value string `xml:",chardata"`
}
-// Country : Länder
+// Country : Countries
type Country struct {
Lang string `xml:"lang,attr"`
Value string `xml:",chardata"`
}
-// EpisodeNum : Episodennummerierung
+// EpisodeNum : Episode Numbering
type EpisodeNum struct {
System string `xml:"system,attr"`
Value string `xml:",chardata"`
}
-// Poster : Programmposter / Cover
+// Poster : Program Poster / Cover
type Poster struct {
Height string `xml:"height,attr"`
Src string `xml:"src,attr"`
@@ -151,7 +151,7 @@ type Producer struct {
Value string `xml:",chardata"`
}
-// Video : Video Metadaten
+// Video : Video Metadata
type Video struct {
Aspect string `xml:"aspect,omitempty"`
Colour string `xml:"colour,omitempty"`
@@ -159,17 +159,17 @@ type Video struct {
Quality string `xml:"quality,omitempty"`
}
-// PreviouslyShown : Widerholung bzw. Erstausstrahlung
+// PreviouslyShown : Repetition or first Broadcast
type PreviouslyShown struct {
Start string `xml:"start,attr"`
}
-// New : Sendung als neu deklarieren
+// New : Declare the Broadcast as new
type New struct {
Value string `xml:",chardata"`
}
-// Live : Sendung als Liveübertragung deklarieren
+// Live : Declare the Broadcast as a Live Broadcast
type Live struct {
Value string `xml:",chardata"`
}
diff --git a/src/system.go b/src/system.go
index 82be0e1..f8b6c37 100644
--- a/src/system.go
+++ b/src/system.go
@@ -4,16 +4,15 @@ import (
"encoding/json"
"errors"
"fmt"
- "os"
"reflect"
"strings"
"time"
)
-// Entwicklerinfos anzeigen
+// Show Developer Information
func showDevInfo() {
- if System.Dev == true {
+ if System.Dev {
fmt.Print("\033[31m")
fmt.Println("* * * * * D E V M O D E * * * * *")
@@ -25,10 +24,9 @@ func showDevInfo() {
}
- return
}
-// Alle Systemordner erstellen
+// Create all System Folders
func createSystemFolders() (err error) {
e := reflect.ValueOf(&System.Folder).Elem()
@@ -48,7 +46,7 @@ func createSystemFolders() (err error) {
return
}
-// Alle Systemdateien erstellen
+// Create all System Files
func createSystemFiles() (err error) {
var debug string
@@ -58,7 +56,7 @@ func createSystemFiles() (err error) {
err = checkFile(filename)
if err != nil {
- // Datei existiert nicht, wird jetzt erstellt
+ // File does not exist, will be created now
err = saveMapToJSONFile(filename, make(map[string]interface{}))
if err != nil {
return
@@ -89,7 +87,7 @@ func createSystemFiles() (err error) {
return
}
-// Einstellungen laden und default Werte setzen (xTeVe)
+// Load Settings and set Default Values (xTeVe)
func loadSettings() (settings SettingsStruct, err error) {
settingsMap, err := loadJSONFileToMap(System.File.Settings)
@@ -97,7 +95,7 @@ func loadSettings() (settings SettingsStruct, err error) {
return
}
- // Deafult Werte setzten
+ // Set Deafult Values
var defaults = make(map[string]interface{})
var dataMap = make(map[string]interface{})
@@ -113,34 +111,42 @@ func loadSettings() (settings SettingsStruct, err error) {
defaults["authentication.xml"] = false
defaults["backup.keep"] = 10
defaults["backup.path"] = System.Folder.Backup
- defaults["buffer"] = "-"
defaults["buffer.size.kb"] = 1024
defaults["buffer.timeout"] = 500
+ defaults["buffer"] = "-"
defaults["cache.images"] = false
+ defaults["clearXMLTVCache"] = false
+ defaults["defaultMissingEPG"] = "-"
+ defaults["disallowURLDuplicates"] = false
+ defaults["enableMappedChannels"] = false
defaults["epgSource"] = "PMS"
defaults["ffmpeg.options"] = System.FFmpeg.DefaultOptions
- defaults["vlc.options"] = System.VLC.DefaultOptions
- defaults["files"] = dataMap
defaults["files.update"] = true
+ defaults["files"] = dataMap
defaults["filter"] = make(map[string]interface{})
defaults["git.branch"] = System.Branch
+ defaults["hostIP"] = "" // Will be set in resolveHostIP()
+ defaults["hostName"] = ""
defaults["language"] = "en"
defaults["log.entries.ram"] = 500
- defaults["mapping.first.channel"] = 1000
- defaults["xepg.replace.missing.images"] = true
defaults["m3u8.adaptive.bandwidth.mbps"] = 10
+ defaults["mapping.first.channel"] = 1000
defaults["port"] = "34400"
defaults["ssdp"] = true
+ defaults["storeBufferInRAM"] = false
+ defaults["temp.path"] = System.Folder.Temp
+ defaults["tlsMode"] = false
defaults["tuner"] = 1
+ defaults["udpxy"] = ""
defaults["update"] = []string{"0000"}
defaults["user.agent"] = System.Name
defaults["uuid"] = createUUID()
- defaults["udpxy"] = ""
defaults["version"] = System.DBVersion
+ defaults["vlc.options"] = System.VLC.DefaultOptions
+ defaults["xepg.replace.missing.images"] = true
defaults["xteveAutoUpdate"] = true
- defaults["temp.path"] = System.Folder.Temp
- // Default Werte setzen
+ // Set Default Values
for key, value := range defaults {
if _, ok := settingsMap[key]; !ok {
settingsMap[key] = value
@@ -152,7 +158,7 @@ func loadSettings() (settings SettingsStruct, err error) {
return
}
- // Einstellungen von den Flags übernehmen
+ // Adopt the settings from the Flags
if len(System.Flag.Port) > 0 {
settings.Port = System.Flag.Port
}
@@ -170,11 +176,14 @@ func loadSettings() (settings SettingsStruct, err error) {
settings.VLCPath = searchFileInOS("cvlc")
}
- settings.Version = System.DBVersion
+ // Initialze virutal filesystem for the Buffer
+ initBufferVFS(settings.StoreBufferInRAM)
+
+ settings.TempPath = getValidTempDir(settings.TempPath)
err = saveSettings(settings)
- // Warung wenn FFmpeg nicht gefunden wurde
+ // Warning if FFmpeg was not found
if len(Settings.FFmpegPath) == 0 && Settings.Buffer == "ffmpeg" {
showWarning(2020)
}
@@ -186,7 +195,7 @@ func loadSettings() (settings SettingsStruct, err error) {
return
}
-// Einstellungen speichern (xTeVe)
+// Save Settings (xTeVe)
func saveSettings(settings SettingsStruct) (err error) {
if settings.BackupKeep == 0 {
@@ -201,7 +210,11 @@ func saveSettings(settings SettingsStruct) (err error) {
settings.BufferTimeout = 0
}
- System.Folder.Temp = settings.TempPath + settings.UUID + string(os.PathSeparator)
+ if System.Dev {
+ Settings.UUID = "2019-01-DEV-xTeVe!"
+ }
+
+ System.Folder.Temp = getValidTempDir(settings.TempPath + settings.UUID)
err = writeByteToFile(System.File.Settings, []byte(mapToJSON(settings)))
if err != nil {
@@ -210,20 +223,24 @@ func saveSettings(settings SettingsStruct) (err error) {
Settings = settings
- if System.Dev == true {
- Settings.UUID = "2019-01-DEV-xTeVe!"
- }
-
setDeviceID()
return
}
-// Zugriff über die Domain ermöglichen
+// Enable access via the Domain
func setGlobalDomain(domain string) {
System.Domain = domain
+ if Settings.TLSMode {
+ System.ServerProtocol.API = "https"
+ System.ServerProtocol.DVR = "https"
+ System.ServerProtocol.M3U = "https"
+ System.ServerProtocol.WEB = "https"
+ System.ServerProtocol.XML = "https"
+ }
+
switch Settings.AuthenticationPMS {
case true:
System.Addresses.DVR = "username:password@" + System.Domain
@@ -250,16 +267,15 @@ func setGlobalDomain(domain string) {
System.Addresses.XML = getErrMsg(2106)
}
- return
}
-// UUID generieren
+// Generate UUID
func createUUID() (uuid string) {
uuid = time.Now().Format("2006-01") + "-" + randomString(4) + "-" + randomString(6)
return
}
-// Eindeutige Geräte ID für Plex generieren
+// Generate Unique Device ID for Plex
func setDeviceID() {
var id = Settings.UUID
@@ -272,10 +288,9 @@ func setDeviceID() {
System.DeviceID = fmt.Sprintf("%s:%d", id, Settings.Tuner)
}
- return
}
-// Provider Streaming-URL zu xTeVe Streaming-URL konvertieren
+// Convert Provider Streaming URL to xTeVe Streaming URL
func createStreamingURL(streamingType, playlistID, channelNumber, channelName, url string) (streamingURL string, err error) {
var streamInfo StreamInfo
@@ -338,7 +353,7 @@ func getStreamInfo(urlID string) (streamInfo StreamInfo, err error) {
streamInfo = s
streamInfo.URL = strings.Trim(streamInfo.URL, "\r\n")
} else {
- err = errors.New("Streaming error")
+ err = errors.New("streaming error")
}
return
diff --git a/src/toolchain.go b/src/toolchain.go
index 19e7f3c..1750561 100644
--- a/src/toolchain.go
+++ b/src/toolchain.go
@@ -6,7 +6,9 @@ import (
"crypto/rand"
"encoding/hex"
"encoding/json"
+ "errors"
"fmt"
+ "io/fs"
"io/ioutil"
"net"
"os"
@@ -16,18 +18,21 @@ import (
"runtime"
"strings"
"text/template"
+
+ "github.com/avfs/avfs"
+ "github.com/samber/lo"
)
// --- System Tools ---
-// Prüft ob der Ordner existiert, falls nicht, wir der Ordner erstellt
+// Checks whether the Folder exists, if not, the Folder is created
func checkFolder(path string) (err error) {
var debug string
_, err = os.Stat(filepath.Dir(path))
if os.IsNotExist(err) {
- // Ordner existiert nicht, wird jetzt erstellt
+ // Folder does not exist, will now be created
err = os.MkdirAll(getPlatformPath(path), 0755)
if err == nil {
@@ -45,7 +50,45 @@ func checkFolder(path string) (err error) {
return nil
}
-// Prüft ob die Datei im Dateisystem existiert
+// checkVFSFolder : Checks whether the Folder exists in provided virtual filesystem, if not, the Folder is created
+func checkVFSFolder(path string, vfs avfs.VFS) (err error) {
+
+ var debug string
+ _, err = vfs.Stat(filepath.Dir(path))
+
+ if fsIsNotExistErr(err) {
+ // Folder does not exist, will now be created
+
+ err = vfs.MkdirAll(getPlatformPath(path), 0755)
+ if err == nil {
+
+ debug = fmt.Sprintf("Create virtual filesystem Folder:%s", path)
+ showDebug(debug, 1)
+
+ } else {
+ return err
+ }
+
+ return nil
+ }
+
+ return nil
+}
+
+// fsIsNotExistErr : Returns true whether the is known to report that a file or directory does not exist,
+// including virtual file system errors
+func fsIsNotExistErr(err error) bool {
+ if errors.Is(err, fs.ErrNotExist) ||
+ errors.Is(err, avfs.ErrWinPathNotFound) ||
+ errors.Is(err, avfs.ErrNoSuchFileOrDir) ||
+ errors.Is(err, avfs.ErrWinFileNotFound) {
+ return true
+ }
+
+ return false
+}
+
+// Checks whether the File exists in the Filesystem
func checkFile(filename string) (err error) {
var file = getPlatformFile(filename)
@@ -62,14 +105,23 @@ func checkFile(filename string) (err error) {
switch mode := fi.Mode(); {
case mode.IsDir():
err = fmt.Errorf("%s: %s", file, getErrMsg(1072))
- case mode.IsRegular():
- break
+ // case mode.IsRegular():
+ // break
}
return
}
-// GetUserHomeDirectory : Benutzer Homer Verzeichnis
+func allFilesExist(list ...string) bool {
+ for _, f := range list {
+ if err := checkFile(f); err != nil {
+ return false
+ }
+ }
+ return true
+}
+
+// GetUserHomeDirectory : User Home Directory
func GetUserHomeDirectory() (userHomeDirectory string) {
usr, err := user.Current()
@@ -92,7 +144,7 @@ func GetUserHomeDirectory() (userHomeDirectory string) {
return
}
-// Prüft Dateiberechtigung
+// Checks File Permissions
func checkFilePermission(dir string) (err error) {
var filename = dir + "permission.test"
@@ -105,12 +157,46 @@ func checkFilePermission(dir string) (err error) {
return
}
-// Ordnerpfad für das laufende OS generieren
+// Generate folder path for the running OS
func getPlatformPath(path string) string {
return filepath.Dir(path) + string(os.PathSeparator)
}
-// Dateipfad für das laufende OS generieren
+// getDefaultTempDir returns default temporary folder path + application name, e.g.: "/tmp/xteve/" or %Tmp%\xteve.
+//
+// Function assumes default OS temporary folder exists and writable.
+func getDefaultTempDir() string {
+ return os.TempDir() + string(os.PathSeparator) + System.AppName + string(os.PathSeparator)
+}
+
+// getValidTempDir returns standartized temporary folder with trailing path separator:
+//
+// Slashes will be replaced with OS specific ones and duplicated slashes removed.
+//
+// On Windows, "/tmp" will be replaced with expanded system environment variable %Tmp%.
+func getValidTempDir(path string) string {
+ if runtime.GOOS == "windows" {
+ if strings.HasPrefix(path, "/tmp") {
+ path = strings.Replace(path, "/tmp", os.TempDir(), 1)
+ }
+ }
+ path = filepath.Clean(path)
+ path = path + string(os.PathSeparator)
+
+ err := checkFolder(path)
+ if err == nil {
+ err = checkFilePermission(path)
+ }
+
+ if err != nil {
+ ShowError(err, 1015)
+ path = getDefaultTempDir()
+ }
+
+ return path
+}
+
+// Generate File Path for the running OS
func getPlatformFile(filename string) (osFilePath string) {
path, file := filepath.Split(filename)
@@ -120,18 +206,12 @@ func getPlatformFile(filename string) (osFilePath string) {
return
}
-// Dateinamen aus dem Dateipfad ausgeben
+// Output Filenames from the File Path
func getFilenameFromPath(path string) (file string) {
return filepath.Base(path)
}
-// Nicht mehr verwendete Systemdaten löschen
-func removeOldSystemData() {
- // Temporären Ordner löschen
- os.RemoveAll(System.Folder.Temp)
-}
-
-// Sucht eine Datei im OS
+// Searches for a File in the OS
func searchFileInOS(file string) (path string) {
switch runtime.GOOS {
@@ -198,14 +278,6 @@ func jsonToMap(content string) map[string]interface{} {
return (tmpMap)
}
-func jsonToMapInt64(content string) map[int64]interface{} {
-
- var tmpMap = make(map[int64]interface{})
- json.Unmarshal([]byte(content), &tmpMap)
-
- return (tmpMap)
-}
-
func jsonToInterface(content string) (tmpMap interface{}, err error) {
err = json.Unmarshal([]byte(content), &tmpMap)
@@ -233,6 +305,9 @@ func saveMapToJSONFile(file string, tmpMap interface{}) error {
func loadJSONFileToMap(file string) (tmpMap map[string]interface{}, err error) {
f, err := os.Open(getPlatformFile(file))
+ if err != nil {
+ panic(err)
+ }
defer f.Close()
content, err := ioutil.ReadAll(f)
@@ -250,6 +325,9 @@ func loadJSONFileToMap(file string) (tmpMap map[string]interface{}, err error) {
func readByteFromFile(file string) (content []byte, err error) {
f, err := os.Open(getPlatformFile(file))
+ if err != nil {
+ panic(err)
+ }
defer f.Close()
content, err = ioutil.ReadAll(f)
@@ -287,7 +365,7 @@ func readStringFromFile(file string) (str string, err error) {
return
}
-// Netzwerk
+// Network
func resolveHostIP() (err error) {
netInterfaceAddresses, err := net.InterfaceAddrs()
@@ -307,9 +385,10 @@ func resolveHostIP() (err error) {
if networkIP.IP.To4() != nil {
System.IPAddressesV4 = append(System.IPAddressesV4, ip)
+ System.IPAddressesV4Raw = append(System.IPAddressesV4Raw, networkIP.IP)
if !networkIP.IP.IsLoopback() && ip[0:7] != "169.254" {
- System.IPAddress = ip
+ System.IPAddressesV4Host = append(System.IPAddressesV4Host, ip)
}
} else {
@@ -320,17 +399,22 @@ func resolveHostIP() (err error) {
}
- if len(System.IPAddress) == 0 {
+ // If IP previously set in settings (including the default, empty) is not available anymore
+ if !lo.Contains(System.IPAddressesV4Host, Settings.HostIP) {
+ Settings.HostIP = System.IPAddressesV4Host[0]
+ }
+
+ if len(Settings.HostIP) == 0 {
switch len(System.IPAddressesV4) {
case 0:
if len(System.IPAddressesV6) > 0 {
- System.IPAddress = System.IPAddressesV6[0]
+ Settings.HostIP = System.IPAddressesV6[0]
}
default:
- System.IPAddress = System.IPAddressesV4[0]
+ Settings.HostIP = System.IPAddressesV4[0]
}
@@ -344,7 +428,7 @@ func resolveHostIP() (err error) {
return
}
-// Sonstiges
+// Miscellaneous
func randomString(n int) string {
const alphanum = "AB1CD2EF3GH4IJ5KL6MN7OP8QR9ST0UVWXYZ"
@@ -374,39 +458,6 @@ func parseTemplate(content string, tmpMap map[string]interface{}) (result string
return
}
-func indexOfString(element string, data []string) int {
-
- for k, v := range data {
- if element == v {
- return k
- }
- }
-
- return -1
-}
-
-func indexOfFloat64(element float64, data []float64) int {
-
- for k, v := range data {
- if element == v {
- return (k)
- }
- }
-
- return -1
-}
-
-func indexOfInt(element int, data []int) int {
-
- for k, v := range data {
- if element == v {
- return (k)
- }
- }
-
- return -1
-}
-
func getMD5(str string) string {
md5Hasher := md5.New()
diff --git a/src/update.go b/src/update.go
index 2c13d92..cc72a31 100644
--- a/src/update.go
+++ b/src/update.go
@@ -12,10 +12,10 @@ import (
"reflect"
)
-// BinaryUpdate : Binary Update Prozess. Git Branch master und beta wird von GitHub geladen.
+// BinaryUpdate : Binary update process. Git Branch master and beta is loaded from GitHub.
func BinaryUpdate() (err error) {
- if System.GitHub.Update == false {
+ if !System.GitHub.Update {
showWarning(2099)
return
}
@@ -30,7 +30,7 @@ func BinaryUpdate() (err error) {
switch System.Branch {
- // Update von GitHub
+ // Update from GitHub
case "master", "beta":
var gitInfo = fmt.Sprintf("%s/%s/info.json?raw=true", System.Update.Git, System.Branch)
@@ -58,7 +58,7 @@ func BinaryUpdate() (err error) {
return err
}
- body, err = ioutil.ReadAll(resp.Body)
+ body, _ = ioutil.ReadAll(resp.Body)
err = json.Unmarshal(body, &git)
if err != nil {
@@ -70,7 +70,7 @@ func BinaryUpdate() (err error) {
updater.Response.Version = git.Version
updater.Response.Filename = git.Filename
- // Update vom eigenen Server
+ // Update from your own Server
default:
updater.URL = Settings.UpdateURL
@@ -83,11 +83,11 @@ func BinaryUpdate() (err error) {
showInfo("Update URL:" + updater.URL)
fmt.Println("-----------------")
- // Versionsinformationen vom Server laden
+ // Load version information from the Server
err = up2date.GetVersion()
if err != nil {
- debug = fmt.Sprintf(err.Error())
+ debug = err.Error()
showDebug(debug, 1)
return nil
@@ -105,22 +105,22 @@ func BinaryUpdate() (err error) {
var currentVersion = System.Version + "." + System.Build
- // Versionsnummer überprüfen
- if updater.Response.Version > currentVersion && updater.Response.Status == true {
+ // Check Version Number
+ if updater.Response.Version > currentVersion && updater.Response.Status {
- if Settings.XteveAutoUpdate == true {
- // Update durchführen
+ if Settings.XteveAutoUpdate {
+ // Perform update
var fileType, url string
showInfo(fmt.Sprintf("Update Available:Version: %s", updater.Response.Version))
switch System.Branch {
- // Update von GitHub
+ // Update from GitHub
case "master", "beta":
- showInfo(fmt.Sprintf("Update Server:GitHub"))
+ showInfo("Update Server:GitHub")
- // Update vom eigenen Server
+ // Update from your own Server
default:
showInfo(fmt.Sprintf("Update Server:%s", Settings.UpdateURL))
@@ -128,13 +128,13 @@ func BinaryUpdate() (err error) {
showInfo(fmt.Sprintf("Start Update:Branch: %s", updater.Branch))
- // Neue Version als BIN Datei herunterladen
+ // Download the new version as a BIN File
if len(updater.Response.UpdateBIN) > 0 {
url = updater.Response.UpdateBIN
fileType = "bin"
}
- // Neue Version als ZIP Datei herunterladen
+ // Download the new version as a ZIP File
if len(updater.Response.UpdateZIP) > 0 {
url = updater.Response.UpdateZIP
fileType = "zip"
@@ -150,7 +150,7 @@ func BinaryUpdate() (err error) {
}
} else {
- // Hinweis ausgeben
+ // Display update exception
showWarning(6004)
}
@@ -176,7 +176,7 @@ checkVersion:
return
}
- // Letzte Kompatible Version (1.4.4)
+ // Latest Compatible Version (1.4.4)
if settingsVersion < System.Compatibility {
err = errors.New(getErrMsg(1013))
return
@@ -185,13 +185,13 @@ checkVersion:
switch settingsVersion {
case "1.4.4":
- // UUID Wert in xepg.json setzen
+ // Set UUID Value in xepg.json
err = setValueForUUID()
if err != nil {
return
}
- // Neuer Filter (WebUI). Alte Filtereinstellungen werden konvertiert
+ // New filter (WebUI). Old Filter Settings are converted
if oldFilter, ok := settingsMap["filter"].([]interface{}); ok {
var newFilterMap = convertToNewFilter(oldFilter)
settingsMap["filter"] = newFilterMap
@@ -238,14 +238,42 @@ checkVersion:
return
}
- case "2.1.0":
- // Falls es in einem späteren Update Änderungen an der Datenbank gibt, geht es hier weiter
+ case "2.1.0", "2.1.1":
+ // Database verison <= 2.1.1 has broken XEPG mapping
+
+ // Clear XEPG mapping
+ Data.XEPG.Channels = make(map[string]interface{})
+ Data.XEPG.XEPGCount = 0
+ Data.Cache.Streams = struct{ Active []string }{}
+
+ err = saveMapToJSONFile(System.File.XEPG, Data.XEPG.Channels)
+ if err != nil {
+ ShowError(err, 000)
+ return err
+ }
+
+ // Notify user
+ showWarning(2022)
+ sendAlert(getErrMsg(2022))
+
+ // Update database version
+ settingsMap["version"] = "2.2.0"
+
+ err = saveMapToJSONFile(System.File.Settings, settingsMap)
+ if err != nil {
+ return
+ }
+
+ goto checkVersion
+
+ case "2.2.0", "2.2.1", "2.2.2", "2.2.3", "2.3.0":
+ // If there are changes to the Database in a later update, continue here
break
}
} else {
- // settings.json ist zu alt (älter als Version 1.4.4)
+ // settings.json is too old (older than Version 1.4.4)
err = errors.New(getErrMsg(1013))
}
@@ -281,7 +309,7 @@ func convertToNewFilter(oldFilter []interface{}) (newFilterMap map[int]interface
func setValueForUUID() (err error) {
- xepg, err := loadJSONFileToMap(System.File.XEPG)
+ xepg, _ := loadJSONFileToMap(System.File.XEPG)
for _, c := range xepg {
diff --git a/src/version.go b/src/version.go
new file mode 100644
index 0000000..4acf3aa
--- /dev/null
+++ b/src/version.go
@@ -0,0 +1,4 @@
+package src
+
+// Version : Version, the Build Number is parsed in the main func
+const Version = "2.5.1"
diff --git a/src/webUI.go b/src/webUI.go
index dc7a75a..447ea28 100644
--- a/src/webUI.go
+++ b/src/webUI.go
@@ -4,48 +4,37 @@ var webUI = make(map[string]interface{})
func loadHTMLMap() {
- webUI["html/img/x_ transparent.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTo3NjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI1NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoeXQb1AAAaJElEQVR4Ae2dCZhcVZXHz+1KSFiGkISkqyIoOgI68EkgOBNkEcQRlIFRZDGABAQEhInGbxw+RUZRNhWRLawDYR0GHAaHUVkGvwGURUcgwIiAOGxjV3UHAslHQrbuM/9TlQ6d7qruWt527/u/7+uuqvvucu7vvnveuffde54IDxIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARLwiIDzQtayHi0q23shaydCOnlISu7nnWThRdrFOkPWyCleyNqJkF1yjhTd8k6yiDvtuLgLiCR/lVnIZ14keWU7k2Xyuu4oU92r2RazQ+nWypXI4W86zCXbyZ28KBvJ97MtpEhX1gWsyleS08TJU17I2omQKpvLarmqkywyn7ZHPw9rLvTOvwbX6xEyxS3Nenv4oQCcWwmQc/D3dtaBdiyfyv5S1mM7zieLGSzWEsS6KIuiRSzTGTD9H404z1iy80MBWNVL7hn8nx8LhaxlqnKBvKbvyppYHctTM/0nd5xPljNwcrcUs2/6DyL0RwGYxDOcjR3vGBQ+4M8tMElmdQ3n6NGjYPofGE6F6tTESRmm/1xxTuuczWSQH08BhqJbqlNkuTyJoK2GBgf53S6mkrvB+7qZ6b9Gfod6hHv3dzKAGbX9pNvd51N7+WUBGNlJbgm07FH4G/AJdFuyqlwotXFzW8kzk2itXAFZwu38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"
- webUI["html/js/authentication_ts.js"] = "ZnVuY3Rpb24gbG9naW4oKSB7CiAgICB2YXIgZXJyID0gZmFsc2U7CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudCIpOwogICAgdmFyIGZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYXV0aGVudGljYXRpb24iKTsKICAgIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIik7CiAgICBjb25zb2xlLmxvZyhpbnB1dHMpOwogICAgZm9yICh2YXIgaSA9IGlucHV0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICAgIHZhciBrZXkgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICB2YXIgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICJyZWQiOwogICAgICAgICAgICBlcnIgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTsKICAgIH0KICAgIGlmIChlcnIgPT0gdHJ1ZSkgewogICAgICAgIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoImNvbmZpcm0iKSkgewogICAgICAgIGlmIChkYXRhWyJjb25maXJtIl0gIT0gZGF0YVsicGFzc3dvcmQiXSkgewogICAgICAgICAgICBhbGVydCgic2RhZnNkIik7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpLnN0eWxlLmJvcmRlckNvbG9yID0gInJlZCI7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJykuc3R5bGUuYm9yZGVyQ29sb3IgPSAicmVkIjsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImVyciIpLmlubmVySFRNTCA9ICJ7ey5hY2NvdW50LmZhaWxlZH19IjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIGNvbnNvbGUubG9nKGRhdGEpOwogICAgZm9ybS5zdWJtaXQoKTsKfQo="
- webUI["html/js/configuration_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIFdpemFyZENhdGVnb3J5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gV2l6YXJkQ2F0ZWdvcnkoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gImNvbnRlbnQiOwogICAgfQogICAgV2l6YXJkQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkg0Iik7CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICByZXR1cm4gV2l6YXJkQ2F0ZWdvcnk7Cn0oKSk7CnZhciBXaXphcmRJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKFdpemFyZEl0ZW0sIF9zdXBlcik7CiAgICBmdW5jdGlvbiBXaXphcmRJdGVtKGtleSwgaGVhZGxpbmUpIHsKICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzOwogICAgICAgIF90aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgX3RoaXMua2V5ID0ga2V5OwogICAgICAgIHJldHVybiBfdGhpczsKICAgIH0KICAgIFdpemFyZEl0ZW0ucHJvdG90eXBlLmNyZWF0ZVdpemFyZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgaGVhZGxpbmUgPSB0aGlzLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUodGhpcy5oZWFkbGluZSk7CiAgICAgICAgdmFyIGtleSA9IHRoaXMua2V5OwogICAgICAgIHZhciBjb250ZW50ID0gbmV3IFBvcHVwQ29udGVudCgpOwogICAgICAgIHZhciBkZXNjcmlwdGlvbjsKICAgICAgICB2YXIgZG9jID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5Eb2N1bWVudElEKTsKICAgICAgICBkb2MuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgZG9jLmFwcGVuZENoaWxkKGhlYWRsaW5lKTsKICAgICAgICBzd2l0Y2ggKGtleSkgewogICAgICAgICAgICBjYXNlICJ0dW5lciI6CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnB1c2goaSk7CiAgICAgICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCAiMSIsIGtleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJjbGFzcyIsICJ3aXphcmQiKTsKICAgICAgICAgICAgICAgIHNlbGVjdC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLnR1bmVyLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImVwZ1NvdXJjZSI6CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFsiUE1TIiwgIlhFUEciXTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbIlBNUyIsICJYRVBHIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCAiWEVQRyIsIGtleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJjbGFzcyIsICJ3aXphcmQiKTsKICAgICAgICAgICAgICAgIHNlbGVjdC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLmVwZ1NvdXJjZS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtM3UiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGtleSwgIiIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey53aXphcmQubTN1LnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBpbnB1dC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJ7ey53aXphcmQubTN1LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBrZXksICIiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sud2l6YXJkLnhtbHR2LnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBpbnB1dC5pZCA9IGtleTsKICAgICAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJ7ey53aXphcmQueG1sdHYuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGtleSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHByZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlBSRSIpOwogICAgICAgIHByZS5pbm5lckhUTUwgPSBkZXNjcmlwdGlvbjsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQocHJlKTsKICAgICAgICBjb25zb2xlLmxvZyhoZWFkbGluZSwga2V5KTsKICAgIH07CiAgICByZXR1cm4gV2l6YXJkSXRlbTsKfShXaXphcmRDYXRlZ29yeSkpOwpmdW5jdGlvbiByZWFkeUZvckNvbmZpZ3VyYXRpb24od2l6YXJkKSB7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcigiZ2V0U2VydmVyQ29uZmlnIik7CiAgICBzZXJ2ZXIucmVxdWVzdChuZXcgT2JqZWN0KCkpOwogICAgc2hvd0VsZW1lbnQoImxvYWRpbmciLCBmYWxzZSk7CiAgICBjb25maWd1cmF0aW9uV2l6YXJkW3dpemFyZF0uY3JlYXRlV2l6YXJkKCk7Cn0KZnVuY3Rpb24gc2F2ZVdpemFyZCgpIHsKICAgIHZhciBjbWQgPSAic2F2ZVdpemFyZCI7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKTsKICAgIHZhciBjb25maWcgPSBkaXYuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgid2l6YXJkIik7CiAgICB2YXIgd2l6YXJkID0gbmV3IE9iamVjdCgpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb25maWcubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgbmFtZTsKICAgICAgICB2YXIgdmFsdWU7CiAgICAgICAgc3dpdGNoIChjb25maWdbaV0udGFnTmFtZSkgewogICAgICAgICAgICBjYXNlICJTRUxFQ1QiOgogICAgICAgICAgICAgICAgbmFtZSA9IGNvbmZpZ1tpXS5uYW1lOwogICAgICAgICAgICAgICAgdmFsdWUgPSBjb25maWdbaV0udmFsdWU7CiAgICAgICAgICAgICAgICAvLyBXZW5uIGRlciBXZXJ0IGVpbmUgWmFobCBpc3QsIHdpcmQgZGllc2VyIGFscyBaYWhsIGdlc3BlaWNoZXJ0CiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgd2l6YXJkW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB3aXphcmRbbmFtZV0gPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSU5QVVQiOgogICAgICAgICAgICAgICAgc3dpdGNoIChjb25maWdbaV0udHlwZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gY29uZmlnW2ldLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gY29uZmlnW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc2cgPSBuYW1lLnRvVXBwZXJDYXNlKCkgKyAiOiAiICsgInt7LmFsZXJ0Lm1pc3NpbmdJbnB1dH19IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KG1zZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBjb2RlLi4uCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIGRhdGFbIndpemFyZCJdID0gd2l6YXJkOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwogICAgY29uc29sZS5sb2coZGF0YSk7Cn0KLy8gV2l6YXJkCnZhciBjb25maWd1cmF0aW9uV2l6YXJkID0gbmV3IEFycmF5KCk7CmNvbmZpZ3VyYXRpb25XaXphcmQucHVzaChuZXcgV2l6YXJkSXRlbSgidHVuZXIiLCAie3sud2l6YXJkLnR1bmVyLnRpdGxlfX0iKSk7CmNvbmZpZ3VyYXRpb25XaXphcmQucHVzaChuZXcgV2l6YXJkSXRlbSgiZXBnU291cmNlIiwgInt7LndpemFyZC5lcGdTb3VyY2UudGl0bGV9fSIpKTsKY29uZmlndXJhdGlvbldpemFyZC5wdXNoKG5ldyBXaXphcmRJdGVtKCJtM3UiLCAie3sud2l6YXJkLm0zdS50aXRsZX19IikpOwpjb25maWd1cmF0aW9uV2l6YXJkLnB1c2gobmV3IFdpemFyZEl0ZW0oInhtbHR2IiwgInt7LndpemFyZC54bWx0di50aXRsZX19IikpOwo="
- webUI["html/js/menu_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIE1haW5NZW51ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gTWFpbk1lbnUoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gIm1haW4tbWVudSI7CiAgICAgICAgdGhpcy5IVE1MVGFnID0gIkxJIjsKICAgICAgICB0aGlzLkltYWdlUGF0aCA9ICJpbWcvIjsKICAgIH0KICAgIE1haW5NZW51LnByb3RvdHlwZS5jcmVhdGVJTUcgPSBmdW5jdGlvbiAoc3JjKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTUciKTsKICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgic3JjIiwgdGhpcy5JbWFnZVBhdGggKyBzcmMpOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICAgIE1haW5NZW51LnByb3RvdHlwZS5jcmVhdGVWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51Owp9KCkpOwp2YXIgTWFpbk1lbnVJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKE1haW5NZW51SXRlbSwgX3N1cGVyKTsKICAgIGZ1bmN0aW9uIE1haW5NZW51SXRlbShtZW51S2V5LCB2YWx1ZSwgaW1hZ2UsIGhlYWRsaW5lKSB7CiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpczsKICAgICAgICBfdGhpcy5tZW51S2V5ID0gbWVudUtleTsKICAgICAgICBfdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIF90aGlzLmltZ1NyYyA9IGltYWdlOwogICAgICAgIF90aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgcmV0dXJuIF90aGlzOwogICAgfQogICAgTWFpbk1lbnVJdGVtLnByb3RvdHlwZS5jcmVhdGVJdGVtID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBpdGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiTEkiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgib25jbGljayIsICJqYXZhc2NyaXB0OiBvcGVuVGhpc01lbnUodGhpcykiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgiaWQiLCB0aGlzLmlkKTsKICAgICAgICB2YXIgaW1nID0gdGhpcy5jcmVhdGVJTUcodGhpcy5pbWdTcmMpOwogICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuY3JlYXRlVmFsdWUodGhpcy52YWx1ZSk7CiAgICAgICAgaXRlbS5hcHBlbmRDaGlsZChpbWcpOwogICAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQodmFsdWUpOwogICAgICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChpdGVtKTsKICAgICAgICBzd2l0Y2ggKHRoaXMubWVudUtleSkgewogICAgICAgICAgICBjYXNlICJwbGF5bGlzdCI6CiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlSGVhZGVyID0gWyJ7ey5wbGF5bGlzdC50YWJsZS5wbGF5bGlzdH19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnR1bmVyfX0iLCAie3sucGxheWxpc3QudGFibGUubGFzdFVwZGF0ZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLmF2YWlsYWJpbGl0eX19ICUiLCAie3sucGxheWxpc3QudGFibGUudHlwZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnN0cmVhbXN9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS5ncm91cFRpdGxlfX0gJSIsICJ7ey5wbGF5bGlzdC50YWJsZS50dmdJRH19ICUiLCAie3sucGxheWxpc3QudGFibGUudW5pcXVlSUR9fSAlIl07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3sueG1sdHYudGFibGUuZ3VpZGV9fSIsICJ7ey54bWx0di50YWJsZS5sYXN0VXBkYXRlfX0iLCAie3sueG1sdHYudGFibGUuYXZhaWxhYmlsaXR5fX0gJSIsICJ7ey54bWx0di50YWJsZS5jaGFubmVsc319IiwgInt7LnhtbHR2LnRhYmxlLnByb2dyYW1zfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3suZmlsdGVyLnRhYmxlLm5hbWV9fSIsICJ7ey5maWx0ZXIudGFibGUudHlwZX19IiwgInt7LmZpbHRlci50YWJsZS5maWx0ZXJ9fSJdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbInt7LnVzZXJzLnRhYmxlLnVzZXJuYW1lfX0iLCAie3sudXNlcnMudGFibGUucGFzc3dvcmR9fSIsICJ7ey51c2Vycy50YWJsZS53ZWJ9fSIsICJ7ey51c2Vycy50YWJsZS5wbXN9fSIsICJ7ey51c2Vycy50YWJsZS5tM3V9fSIsICJ7ey51c2Vycy50YWJsZS54bWx9fSIsICJ7ey51c2Vycy50YWJsZS5hcGl9fSJdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIm1hcHBpbmciOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsiQlVMSyIsICJ7ey5tYXBwaW5nLnRhYmxlLmNoTm99fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmxvZ299fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmNoYW5uZWxOYW1lfX0iLCAie3subWFwcGluZy50YWJsZS5wbGF5bGlzdH19IiwgInt7Lm1hcHBpbmcudGFibGUuZ3JvdXBUaXRsZX19IiwgInt7Lm1hcHBpbmcudGFibGUueG1sdHZGaWxlfX0iLCAie3subWFwcGluZy50YWJsZS54bWx0dklEfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvL2NvbnNvbGUubG9nKHRoaXMubWVudUtleSwgdGhpcy50YWJsZUhlYWRlcik7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51SXRlbTsKfShNYWluTWVudSkpOwp2YXIgQ29udGVudCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIENvbnRlbnQoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gImNvbnRlbnQiOwogICAgICAgIHRoaXMuVGFibGVJRCA9ICJjb250ZW50X3RhYmxlIjsKICAgICAgICB0aGlzLmhlYWRlckNsYXNzID0gImNvbnRlbnRfdGFibGVfaGVhZGVyIjsKICAgICAgICB0aGlzLmludGVyYWN0aW9uSUQgPSAiY29udGVudC1pbnRlcmFjdGlvbiI7CiAgICB9CiAgICBDb250ZW50LnByb3RvdHlwZS5jcmVhdGVIZWFkbGluZSA9IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSDMiKTsKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICAgIENvbnRlbnQucHJvdG90eXBlLmNyZWF0ZUhSID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSFIiKTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICBDb250ZW50LnByb3RvdHlwZS5jcmVhdGVJbnRlcmFjdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkRJViIpOwogICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCJpZCIsIHRoaXMuaW50ZXJhY3Rpb25JRCk7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgQ29udGVudC5wcm90b3R5cGUuY3JlYXRlRElWID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiRElWIik7CiAgICAgICAgZWxlbWVudC5pZCA9IHRoaXMuRGl2SUQ7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgQ29udGVudC5wcm90b3R5cGUuY3JlYXRlVEFCTEUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUQUJMRSIpOwogICAgICAgIGVsZW1lbnQuaWQgPSB0aGlzLlRhYmxlSUQ7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgQ29udGVudC5wcm90b3R5cGUuY3JlYXRlVGFibGVSb3cgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gdGhpcy5oZWFkZXJDbGFzczsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICBDb250ZW50LnByb3RvdHlwZS5jcmVhdGVUYWJsZUNvbnRlbnQgPSBmdW5jdGlvbiAobWVudUtleSkgewogICAgICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgICAgIHZhciByb3dzID0gbmV3IEFycmF5KCk7CiAgICAgICAgc3dpdGNoIChtZW51S2V5KSB7CiAgICAgICAgICAgIGNhc2UgInBsYXlsaXN0IjoKICAgICAgICAgICAgICAgIHZhciBmaWxlVHlwZXMgPSBuZXcgQXJyYXkoIm0zdSIsICJoZGhyIik7CiAgICAgICAgICAgICAgICBmaWxlVHlwZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWxlcyJdW2ZpbGVUeXBlXTsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE9iaktleXMoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIicgKyBmaWxlVHlwZSArICciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsibmFtZSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoU0VSVkVSWyJzZXR0aW5ncyJdWyJidWZmZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bInR1bmVyIl07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIi0iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bImxhc3QudXBkYXRlIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bInByb3ZpZGVyLmF2YWlsYWJpbGl0eSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJ0eXBlIl0udG9VcHBlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiY29tcGF0aWJpbGl0eSJdWyJzdHJlYW1zIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bImNvbXBhdGliaWxpdHkiXVsiZ3JvdXAudGl0bGUiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiY29tcGF0aWJpbGl0eSJdWyJ0dmcuaWQiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiY29tcGF0aWJpbGl0eSJdWyJzdHJlYW0uaWQiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICByb3dzLnB1c2godHIpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmlsdGVyIjoKICAgICAgICAgICAgICAgIGRlbGV0ZSBTRVJWRVJbInNldHRpbmdzIl1bImZpbHRlciJdWy0xXTsKICAgICAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbHRlciJdOwogICAgICAgICAgICAgICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGRhdGEpOwogICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgICAgICAgICAgICAgIHRyLmlkID0ga2V5OwogICAgICAgICAgICAgICAgICAgIHRyLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIicgKyBkYXRhW2tleV1bInR5cGUiXSArICciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJuYW1lIl07CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGFba2V5XVsidHlwZSJdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICJ7ey5maWx0ZXIuY3VzdG9tfX0iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImdyb3VwLXRpdGxlIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAie3suZmlsdGVyLmdyb3VwfX0iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJmaWx0ZXIiXTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgcm93cy5wdXNoKHRyKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIHZhciBmaWxlVHlwZXMgPSBuZXcgQXJyYXkoInhtbHR2Iik7CiAgICAgICAgICAgICAgICBmaWxlVHlwZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWxlcyJdW2ZpbGVUeXBlXTsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE9iaktleXMoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIicgKyBmaWxlVHlwZSArICciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsibmFtZSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJsYXN0LnVwZGF0ZSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJwcm92aWRlci5hdmFpbGFiaWxpdHkiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiY29tcGF0aWJpbGl0eSJdWyJ4bWx0di5jaGFubmVscyJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJjb21wYXRpYmlsaXR5Il1bInhtbHR2LnByb2dyYW1zIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcm93cy5wdXNoKHRyKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgICAgIHZhciBmaWxlVHlwZXMgPSBuZXcgQXJyYXkoInVzZXJzIik7CiAgICAgICAgICAgICAgICBmaWxlVHlwZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gU0VSVkVSW2ZpbGVUeXBlXTsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE9iaktleXMoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIicgKyBmaWxlVHlwZSArICciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiZGF0YSJdWyJ1c2VybmFtZSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIioqKioqKiI7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV1bImRhdGEiXVsiYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICLinJMiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICItIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVtrZXldWyJkYXRhIl1bImF1dGhlbnRpY2F0aW9uLnBtcyJdID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAi4pyTIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XVsiZGF0YSJdWyJhdXRoZW50aWNhdGlvbi5tM3UiXSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIuKckyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIi0iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV1bImRhdGEiXVsiYXV0aGVudGljYXRpb24ueG1sIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICLinJMiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICItIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVtrZXldWyJkYXRhIl1bImF1dGhlbnRpY2F0aW9uLmFwaSJdID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAi4pyTIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICByb3dzLnB1c2godHIpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgICAgICBCVUxLX0VESVQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGNyZWF0ZVNlYXJjaE9iaigpOwogICAgICAgICAgICAgICAgY2hlY2tVbmRvKCJlcGdNYXBwaW5nIik7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygiTUFQUElORyIpOwogICAgICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl07CiAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE9iaktleXMoZGF0YSk7CiAgICAgICAgICAgICAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24gKGtleSkgewogICAgICAgICAgICAgICAgICAgIHZhciB0ciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgICAgICAgICAgICAgdHIuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgLy90ci5zZXRBdHRyaWJ1dGUoJ29uY29udGV4dG1lbnUnLCAnamF2YXNjcmlwdDogcmlnaHRDbGljayh0aGlzKScpCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChkYXRhW2tleV1bIngtYWN0aXZlIl0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHIuY2xhc3NOYW1lID0gImFjdGl2ZUVQRyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyLmNsYXNzTmFtZSA9ICJub3RBY3RpdmVFUEciOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIEJ1bGsKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiQlVMSyI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAvLyBLYW5hbG51bW1lcgogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJJTlBVVENIQU5ORUwiOwogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bIngtY2hhbm5lbElEIl07CiAgICAgICAgICAgICAgICAgICAgLy90ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogY2hhbmdlQ2hhbm5lbE51bWJlcigiJyArIGtleSArICciLCB0aGlzKScpCiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIC8vIExvZ28KICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiSU1HIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLmltYWdlVVJMID0gZGF0YVtrZXldWyJ0dmctbG9nbyJdOwogICAgICAgICAgICAgICAgICAgIHZhciB0ZCA9IGNlbGwuY3JlYXRlQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIHRkLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIm1hcHBpbmciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgIHRkLmlkID0ga2V5OwogICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKHRkKTsKICAgICAgICAgICAgICAgICAgICAvLyBLYW5hbG5hbWUKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jbGFzc05hbWUgPSBkYXRhW2tleV1bIngtY2F0ZWdvcnkiXTsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJ4LW5hbWUiXTsKICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gUGxheWxpc3QKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgLy9jZWxsLnZhbHVlID0gZGF0YVtrZXldWyJfZmlsZS5tM3UubmFtZSJdIAogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZGF0YVtrZXldWyJfZmlsZS5tM3UuaWQiXSwgIm0zdSIsICJuYW1lIik7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRkID0gY2VsbC5jcmVhdGVDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgdGQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgibWFwcGluZyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgdGQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGQpOwogICAgICAgICAgICAgICAgICAgIC8vIEdydXBwZSAoZ3JvdXAtdGl0bGUpCiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bIngtZ3JvdXAtdGl0bGUiXTsKICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gWE1MVFYgRGF0ZWkKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XVsieC14bWx0di1maWxlIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZGF0YVtrZXldWyJ4LXhtbHR2LWZpbGUiXSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bIngteG1sdHYtZmlsZSJdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gWE1MVFYgS2FuYWwKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgLy92YXIgdmFsdWUgPSBzdHIuc3Vic3RyaW5nKDEsIDQpOwogICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGRhdGFba2V5XVsieC1tYXBwaW5nIl07CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IDIwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZGF0YVtrZXldWyJ4LW1hcHBpbmciXS5zdWJzdHJpbmcoMCwgMjApICsgIi4uLiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgcm93cy5wdXNoKHRyKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInNldHRpbmdzIjoKICAgICAgICAgICAgICAgIGFsZXJ0KCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJUYWJsZSBjb250ZW50IChtZW51S2V5KToiLCBtZW51S2V5KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcm93czsKICAgIH07CiAgICByZXR1cm4gQ29udGVudDsKfSgpKTsKdmFyIENlbGwgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBDZWxsKCkgewogICAgfQogICAgQ2VsbC5wcm90b3R5cGUuY3JlYXRlQ2VsbCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgIGlmICh0aGlzLmNoaWxkID09IHRydWUpIHsKICAgICAgICAgICAgdmFyIGVsZW1lbnQ7CiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5jaGlsZFR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgIlAiOgogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY2hpbGRUeXBlKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSB0aGlzLmNsYXNzTmFtZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIklOUFVUIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNoaWxkVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiSU5QVVRDSEFOTkVMIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2c2NyaXB0OiBjaGFuZ2VDaGFubmVsTnVtYmVyKHRoaXMpIik7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiQlVMSyI6CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklOUFVUIik7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gdGhpcy52YWx1ZTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnR5cGUgPSAiY2hlY2tib3giOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImJ1bGsgaGlkZUJ1bGsiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiQlVMS19IRUFEIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNoZWNrZWQgPSB0aGlzLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQudHlwZSA9ICJjaGVja2JveCI7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSAiYnVsayBoaWRlQnVsayI7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAiamF2YXNjcmlwdDogc2VsZWN0QWxsQ2hhbm5lbHMoKSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiSU1HIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNoaWxkVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoInNyYyIsIHRoaXMuaW1hZ2VVUkwpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmltYWdlVVJMICE9ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCJvbmVycm9yIiwgImphdmFzY3JpcHQ6IHRoaXMub25lcnJvcj1udWxsO3RoaXMuc3JjPScnIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vb25lcnJvcj0idGhpcy5vbmVycm9yPW51bGw7dGhpcy5zcmM9J21pc3NpbmcuZ2lmJzsiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdGQuaW5uZXJIVE1MID0gdGhpcy52YWx1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMub25jbGljayA9PSB0cnVlKSB7CiAgICAgICAgICAgIHRkLnNldEF0dHJpYnV0ZSgib25jbGljayIsIHRoaXMub25jbGlja0Z1bmt0aW9uKTsKICAgICAgICAgICAgdGQuY2xhc3NOYW1lID0gInBvaW50ZXIiOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy50ZENsYXNzTmFtZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdGQuY2xhc3NOYW1lID0gdGhpcy50ZENsYXNzTmFtZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRkOwogICAgfTsKICAgIHJldHVybiBDZWxsOwp9KCkpOwp2YXIgU2hvd0NvbnRlbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7CiAgICBfX2V4dGVuZHMoU2hvd0NvbnRlbnQsIF9zdXBlcik7CiAgICBmdW5jdGlvbiBTaG93Q29udGVudChtZW51SUQpIHsKICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzOwogICAgICAgIF90aGlzLm1lbnVJRCA9IG1lbnVJRDsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CiAgICBTaG93Q29udGVudC5wcm90b3R5cGUuY3JlYXRlSW5wdXQgPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHsKICAgICAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTlBVVCIpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidHlwZSIsIHR5cGUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgibmFtZSIsIG5hbWUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIGlucHV0OwogICAgfTsKICAgIFNob3dDb250ZW50LnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkgewogICAgICAgIENPTFVNTl9UT19TT1JUID0gLTE7CiAgICAgICAgLy8gQWx0ZW4gSW5oYWx0IGzDtnNjaGVuCiAgICAgICAgdmFyIGRvYyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuRG9jdW1lbnRJRCk7CiAgICAgICAgZG9jLmlubmVySFRNTCA9ICIiOwogICAgICAgIHNob3dQcmV2aWV3KGZhbHNlKTsKICAgICAgICAvLyDDnGJlcnNjaHJpZnQKICAgICAgICB2YXIgaGVhZGxpbmUgPSBtZW51SXRlbXNbdGhpcy5tZW51SURdLmhlYWRsaW5lOwogICAgICAgIHZhciBtZW51S2V5ID0gbWVudUl0ZW1zW3RoaXMubWVudUlEXS5tZW51S2V5OwogICAgICAgIHZhciBoID0gdGhpcy5jcmVhdGVIZWFkbGluZShoZWFkbGluZSk7CiAgICAgICAgZG9jLmFwcGVuZENoaWxkKGgpOwogICAgICAgIHZhciBociA9IHRoaXMuY3JlYXRlSFIoKTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaHIpOwogICAgICAgIC8vIEludGVyYWt0aW9uCiAgICAgICAgdmFyIGRpdiA9IHRoaXMuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoZGl2KTsKICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmludGVyYWN0aW9uSUQpOwogICAgICAgIHN3aXRjaCAobWVudUtleSkgewogICAgICAgICAgICBjYXNlICJwbGF5bGlzdCI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLm5ld319Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImlkIiwgIi0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInBsYXlsaXN0IiknKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5uZXd9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsIC0xKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoImZpbHRlciIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5uZXd9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJ4bWx0diIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgieG1sdHYiKScpOwogICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24ubmV3fX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiaWQiLCAidXNlcnMiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInVzZXJzIiknKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoIm1hcHBpbmciLCAiIiwgIiIpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLmJ1bGtFZGl0fX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBidWxrRWRpdCgpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJzZWFyY2giLCAic2VhcmNoIiwgIiIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJzZWFyY2hNYXBwaW5nIik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmJ1dHRvbi5zZWFyY2h9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gInNlYXJjaCI7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgJ2phdmFzY3JpcHQ6IHNlYXJjaEluTWFwcGluZygpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAic2V0dGluZ3MiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5zYXZlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzYXZlU2V0dGluZ3MoKTsnKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24uYmFja3VwfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBiYWNrdXAoKTsnKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24ucmVzdG9yZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogcmVzdG9yZSgpOycpOwogICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTsKICAgICAgICAgICAgICAgIHdyYXBwZXIuc2V0QXR0cmlidXRlKCJpZCIsICJib3gtd3JhcHBlciIpOwogICAgICAgICAgICAgICAgZG9jLmFwcGVuZENoaWxkKHdyYXBwZXIpOwogICAgICAgICAgICAgICAgdGhpcy5EaXZJRCA9ICJjb250ZW50X3NldHRpbmdzIjsKICAgICAgICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHRoaXMuY3JlYXRlRElWKCk7CiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHNldHRpbmdzKTsKICAgICAgICAgICAgICAgIHNob3dTZXR0aW5ncygpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImxvZyI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLnJlc2V0TG9nc319Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogcmVzZXRMb2dzKCk7Jyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB2YXIgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkRJViIpOwogICAgICAgICAgICAgICAgd3JhcHBlci5zZXRBdHRyaWJ1dGUoImlkIiwgImJveC13cmFwcGVyIik7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQod3JhcHBlcik7CiAgICAgICAgICAgICAgICB0aGlzLkRpdklEID0gImNvbnRlbnRfbG9nIjsKICAgICAgICAgICAgICAgIHZhciBsb2dzID0gdGhpcy5jcmVhdGVESVYoKTsKICAgICAgICAgICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQobG9ncyk7CiAgICAgICAgICAgICAgICBzaG93TG9ncyh0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJsb2dvdXQiOgogICAgICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5jb29raWUgPSAiVG9rZW49IDsgZXhwaXJlcyA9IFRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgR01UIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgY29uc29sZS5sb2coIlNob3cgY29udGVudCAobWVudUtleSk6IiwgbWVudUtleSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLy8gVGFiZWxsZSBlcnN0ZWxsZW4gKGZhbGxzIGJlbsO2dGlndCkKICAgICAgICB2YXIgdGFibGVIZWFkZXIgPSBtZW51SXRlbXNbdGhpcy5tZW51SURdLnRhYmxlSGVhZGVyOwogICAgICAgIGlmICh0YWJsZUhlYWRlci5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHZhciB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiRElWIik7CiAgICAgICAgICAgIGRvYy5hcHBlbmRDaGlsZCh3cmFwcGVyKTsKICAgICAgICAgICAgd3JhcHBlci5zZXRBdHRyaWJ1dGUoImlkIiwgImJveC13cmFwcGVyIik7CiAgICAgICAgICAgIHZhciB0YWJsZSA9IHRoaXMuY3JlYXRlVEFCTEUoKTsKICAgICAgICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZCh0YWJsZSk7CiAgICAgICAgICAgIHZhciBoZWFkZXIgPSB0aGlzLmNyZWF0ZVRhYmxlUm93KCk7CiAgICAgICAgICAgIHRhYmxlLmFwcGVuZENoaWxkKGhlYWRlcik7CiAgICAgICAgICAgIC8vIEtvcGZ6ZWlsZSBkZXIgVGFibGxlCiAgICAgICAgICAgIHRhYmxlSGVhZGVyLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZWxlbWVudDsKICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09ICJCVUxLIikgewogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIkJVTEtfSEVBRCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG1lbnVLZXkgPT0gIm1hcHBpbmciKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7Lm1hcHBpbmcudGFibGUuY2hOb319IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5rdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoMSk7IjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC50ZENsYXNzTmFtZSA9ICJzb3J0VGhpcyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09ICJ7ey5tYXBwaW5nLnRhYmxlLmNoYW5uZWxOYW1lfX0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGljayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGlja0Z1bmt0aW9uID0gImphdmFzY3JpcHQ6IHNvcnRUYWJsZSgzKTsiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSAie3subWFwcGluZy50YWJsZS5wbGF5bGlzdH19IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5rdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoNCk7IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7Lm1hcHBpbmcudGFibGUuZ3JvdXBUaXRsZX19IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5rdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoNSk7IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBoZWFkZXIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGFibGUuYXBwZW5kQ2hpbGQoaGVhZGVyKTsKICAgICAgICAgICAgLy8gSW5oYWx0IGRlciBUYWJlbGxlCiAgICAgICAgICAgIHZhciByb3dzID0gdGhpcy5jcmVhdGVUYWJsZUNvbnRlbnQobWVudUtleSk7CiAgICAgICAgICAgIHJvd3MuZm9yRWFjaChmdW5jdGlvbiAodHIpIHsKICAgICAgICAgICAgICAgIHRhYmxlLmFwcGVuZENoaWxkKHRyKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAobWVudUtleSkgewogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgICAgIHNvcnRUYWJsZSgxKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgc2hvd1ByZXZpZXcodHJ1ZSk7CiAgICAgICAgICAgICAgICBzb3J0VGFibGUoMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIENPTFVNTl9UT19TT1JUID0gLTE7CiAgICAgICAgICAgICAgICBzb3J0VGFibGUoMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgc2hvd0VsZW1lbnQoImxvYWRpbmciLCBmYWxzZSk7CiAgICB9OwogICAgcmV0dXJuIFNob3dDb250ZW50Owp9KENvbnRlbnQpKTsKZnVuY3Rpb24gUGFnZVJlYWR5KCkgewogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoImdldFNlcnZlckNvbmZpZyIpOwogICAgc2VydmVyLnJlcXVlc3QobmV3IE9iamVjdCgpKTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJyZXNpemUiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogICAgfSwgdHJ1ZSk7CiAgICBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgdXBkYXRlTG9nKCk7CiAgICB9LCAxMDAwMCk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gY3JlYXRlTGF5b3V0KCkgewogICAgLy8gQ2xpZW50IEluZm8KICAgIHZhciBvYmogPSBTRVJWRVJbImNsaWVudEluZm8iXTsKICAgIHZhciBrZXlzID0gZ2V0T2JqS2V5cyhvYmopOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pLmlubmVySFRNTCA9IG9ialtrZXlzW2ldXTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJtYWluLW1lbnUiKSkgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIE1lbsO8IGVyc3RlbGxlbgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm1haW4tbWVudSIpLmlubmVySFRNTCA9ICIiOwogICAgZm9yICh2YXIgaV8xID0gMDsgaV8xIDwgbWVudUl0ZW1zLmxlbmd0aDsgaV8xKyspIHsKICAgICAgICBtZW51SXRlbXNbaV8xXS5pZCA9IGlfMTsKICAgICAgICBzd2l0Y2ggKG1lbnVJdGVtc1tpXzFdWyJtZW51S2V5Il0pIHsKICAgICAgICAgICAgY2FzZSAidXNlcnMiOgogICAgICAgICAgICBjYXNlICJsb2dvdXQiOgogICAgICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtc1tpXzFdLmNyZWF0ZUl0ZW0oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgaWYgKFNFUlZFUlsiY2xpZW50SW5mbyJdWyJlcGdTb3VyY2UiXSA9PSAiWEVQRyIpIHsKICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXNbaV8xXS5jcmVhdGVJdGVtKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIG1lbnVJdGVtc1tpXzFdLmNyZWF0ZUl0ZW0oKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBvcGVuVGhpc01lbnUoZWxlbWVudCkgewogICAgdmFyIGlkID0gZWxlbWVudC5pZDsKICAgIHZhciBjb250ZW50ID0gbmV3IFNob3dDb250ZW50KGlkKTsKICAgIGNvbnRlbnQuc2hvdygpOwogICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogICAgcmV0dXJuOwp9CnZhciBQb3B1cFdpbmRvdyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFBvcHVwV2luZG93KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJwb3B1cC1jdXN0b20iOwogICAgICAgIHRoaXMuSW50ZXJhY3Rpb25JRCA9ICJpbnRlcmFjdGlvbiI7CiAgICAgICAgdGhpcy5kb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgfQogICAgUG9wdXBXaW5kb3cucHJvdG90eXBlLmNyZWF0ZVRpdGxlID0gZnVuY3Rpb24gKHRpdGxlKSB7CiAgICAgICAgdmFyIHRkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICB0ZC5jbGFzc05hbWUgPSAibGVmdCI7CiAgICAgICAgdGQuaW5uZXJIVE1MID0gdGl0bGUgKyAiOiI7CiAgICAgICAgcmV0dXJuIHRkOwogICAgfTsKICAgIFBvcHVwV2luZG93LnByb3RvdHlwZS5jcmVhdGVDb250ZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICB2YXIgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgIHRkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgICAgIHJldHVybiB0ZDsKICAgIH07CiAgICBQb3B1cFdpbmRvdy5wcm90b3R5cGUuY3JlYXRlSW50ZXJhY3Rpb24gPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgIGRpdi5zZXRBdHRyaWJ1dGUoImlkIiwgInBvcHVwLWludGVyYWN0aW9uIik7CiAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICJpbnRlcmFjdGlvbiI7CiAgICAgICAgdGhpcy5kb2MuYXBwZW5kQ2hpbGQoZGl2KTsKICAgIH07CiAgICByZXR1cm4gUG9wdXBXaW5kb3c7Cn0oKSk7CnZhciBQb3B1cENvbnRlbnQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7CiAgICBfX2V4dGVuZHMoUG9wdXBDb250ZW50LCBfc3VwZXIpOwogICAgZnVuY3Rpb24gUG9wdXBDb250ZW50KCkgewogICAgICAgIHZhciBfdGhpcyA9IF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzOwogICAgICAgIF90aGlzLnRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEFCTEUiKTsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CiAgICBQb3B1cENvbnRlbnQucHJvdG90eXBlLmNyZWF0ZUhlYWRsaW5lID0gZnVuY3Rpb24gKGhlYWRsaW5lKSB7CiAgICAgICAgdGhpcy5kb2MuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJIMyIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gaGVhZGxpbmUudG9VcHBlckNhc2UoKTsKICAgICAgICB0aGlzLmRvYy5hcHBlbmRDaGlsZChlbGVtZW50KTsKICAgICAgICAvLyBUYWJlbGxlIGVyc3RlbGxlbgogICAgICAgIHRoaXMudGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUQUJMRSIpOwogICAgICAgIHRoaXMuZG9jLmFwcGVuZENoaWxkKHRoaXMudGFibGUpOwogICAgfTsKICAgIFBvcHVwQ29udGVudC5wcm90b3R5cGUuYXBwZW5kUm93ID0gZnVuY3Rpb24gKHRpdGxlLCBlbGVtZW50KSB7CiAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAvLyBCZXplaWNobnVuZwogICAgICAgIGlmICh0aXRsZS5sZW5ndGggIT0gMCkgewogICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZVRpdGxlKHRpdGxlKSk7CiAgICAgICAgfQogICAgICAgIC8vIENvbnRlbnQKICAgICAgICB0ci5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUNvbnRlbnQoZWxlbWVudCkpOwogICAgICAgIHRoaXMudGFibGUuYXBwZW5kQ2hpbGQodHIpOwogICAgfTsKICAgIFBvcHVwQ29udGVudC5wcm90b3R5cGUuY3JlYXRlSW5wdXQgPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHsKICAgICAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTlBVVCIpOwogICAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdmFsdWUgPSAiIjsKICAgICAgICB9CiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ0eXBlIiwgdHlwZSk7CiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIHZhbHVlKTsKICAgICAgICByZXR1cm4gaW5wdXQ7CiAgICB9OwogICAgUG9wdXBDb250ZW50LnByb3RvdHlwZS5jcmVhdGVDaGVja2JveCA9IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInR5cGUiLCAiY2hlY2tib3giKTsKICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm5hbWUiLCBuYW1lKTsKICAgICAgICByZXR1cm4gaW5wdXQ7CiAgICB9OwogICAgUG9wdXBDb250ZW50LnByb3RvdHlwZS5jcmVhdGVTZWxlY3QgPSBmdW5jdGlvbiAodGV4dCwgdmFsdWVzLCBzZXQsIGRiS2V5KSB7CiAgICAgICAgdmFyIHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlNFTEVDVCIpOwogICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm5hbWUiLCBkYktleSk7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKTsKICAgICAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZXNbaV0pOwogICAgICAgICAgICBvcHRpb24uaW5uZXJUZXh0ID0gdGV4dFtpXTsKICAgICAgICAgICAgc2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7CiAgICAgICAgfQogICAgICAgIGlmIChzZXQgIT0gIiIpIHsKICAgICAgICAgICAgc2VsZWN0LnZhbHVlID0gc2V0OwogICAgICAgIH0KICAgICAgICBpZiAoc2V0ID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBzZWxlY3QudmFsdWUgPSB2YWx1ZXNbMF07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxlY3Q7CiAgICB9OwogICAgUG9wdXBDb250ZW50LnByb3RvdHlwZS5zZWxlY3RPcHRpb24gPSBmdW5jdGlvbiAoc2VsZWN0LCB2YWx1ZSkgewogICAgICAgIC8vc2VsZWN0LnNlbGVjdGVkT3B0aW9ucyA9IHZhbHVlCiAgICAgICAgdmFyIHMgPSBzZWxlY3Q7CiAgICAgICAgcy5vcHRpb25zW3Muc2VsZWN0ZWRJbmRleF0udmFsdWUgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gc2VsZWN0OwogICAgfTsKICAgIFBvcHVwQ29udGVudC5wcm90b3R5cGUuZGVzY3JpcHRpb24gPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgIHZhciB0ZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgdmFyIHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBzcGFuLmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgIHRyLmFwcGVuZENoaWxkKHRkKTsKICAgICAgICB0ci5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUNvbnRlbnQoc3BhbikpOwogICAgICAgIHRoaXMudGFibGUuYXBwZW5kQ2hpbGQodHIpOwogICAgfTsKICAgIC8vIEludGVyYWt0aW9uCiAgICBQb3B1cENvbnRlbnQucHJvdG90eXBlLmFkZEludGVyYWN0aW9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtaW50ZXJhY3Rpb24iKTsKICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChlbGVtZW50KTsKICAgIH07CiAgICByZXR1cm4gUG9wdXBDb250ZW50Owp9KFBvcHVwV2luZG93KSk7CmZ1bmN0aW9uIG9wZW5Qb3BVcChkYXRhVHlwZSwgZWxlbWVudCkgewogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgaWQ7CiAgICBzd2l0Y2ggKGVsZW1lbnQpIHsKICAgICAgICBjYXNlIHVuZGVmaW5lZDoKICAgICAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAiZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGlmIChpZCA9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSAtMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGdldExvY2FsRGF0YSgiZmlsdGVyIiwgaWQpOwogICAgICAgICAgICAgICAgICAgIGRhdGFbInR5cGUiXSA9ICJncm91cC10aXRsZSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJjdXN0b20tZmlsdGVyIjoKICAgICAgICAgICAgICAgICAgICBpZiAoaWQgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gLTE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBnZXRMb2NhbERhdGEoImZpbHRlciIsIGlkKTsKICAgICAgICAgICAgICAgICAgICBkYXRhWyJ0eXBlIl0gPSAiY3VzdG9tLWZpbHRlciI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGRhdGFbImlkLnByb3ZpZGVyIl0gPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgZGF0YVsidHlwZSJdID0gZGF0YVR5cGU7CiAgICAgICAgICAgICAgICAgICAgaWQgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWQgPSBlbGVtZW50LmlkOwogICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxEYXRhKGRhdGFUeXBlLCBpZCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgdmFyIGNvbnRlbnQgPSBuZXcgUG9wdXBDb250ZW50KCk7CiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CiAgICAgICAgY2FzZSAicGxheWxpc3QiOgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUhlYWRsaW5lKCJ7ey5wbGF5bGlzdC5wbGF5bGlzdFR5cGUudGl0bGV9fSIpOwogICAgICAgICAgICAvLyBUeXBlCiAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJNM1UiLCAiSERIb21lUnVuIl07CiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbImphdmFzY3JpcHQ6IG9wZW5Qb3BVcCgnbTN1JykiLCAiamF2YXNjcmlwdDogb3BlblBvcFVwKCdoZGhyJykiXTsKICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIiIsICJ0eXBlIik7CiAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoImlkIiwgInR5cGUiKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAnamF2YXNjcmlwdDogY2hhbmdlQnV0dG9uQWN0aW9uKHRoaXMsICJuZXh0IiwgIm9uY2xpY2siKScpOyAvLyBjaGFuZ2VCdXR0b25BY3Rpb24KICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LnR5cGUudGl0bGV9fSIsIHNlbGVjdCk7CiAgICAgICAgICAgIC8vIEludGVyYWt0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gQWJicmVjaGVuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLmNhbmNlbH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICAvLyBXZWl0ZXIKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgIm5leHQiLCAie3suYnV0dG9uLm5leHR9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtM3UiKScpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImlkIiwgJ25leHQnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoZGF0YVR5cGUpOwogICAgICAgICAgICAvLyBOYW1lCiAgICAgICAgICAgIHZhciBkYktleSA9ICJuYW1lIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QubmFtZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5uYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEJlc2NocmVpYnVuZwogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBVUkwKICAgICAgICAgICAgdmFyIGRiS2V5ID0gImZpbGUuc291cmNlIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QuZmlsZU0zVS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5maWxlTTNVLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIFR1bmVyCiAgICAgICAgICAgIGlmIChTRVJWRVJbInNldHRpbmdzIl1bImJ1ZmZlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IDEwMDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dC5wdXNoKGkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goaS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJ0dW5lciI7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhW2RiS2V5XSwgZGJLZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25mb2N1cyIsICJqYXZhc2NyaXB0OiByZXR1cm47Iik7CiAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sucGxheWxpc3QudHVuZXIudGl0bGV9fSIsIHNlbGVjdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAidHVuZXIiOwogICAgICAgICAgICAgICAgaWYgKGRhdGFbZGJLZXldID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIGRhdGFbZGJLZXldID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJyZWFkb25seSIsICJ0cnVlIik7CiAgICAgICAgICAgICAgICBpbnB1dC5jbGFzc05hbWUgPSAibm90QXZhaWxhYmxlIjsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC50dW5lci50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnQuZGVzY3JpcHRpb24oInt7LnBsYXlsaXN0LnR1bmVyLmRlc2NyaXB0aW9ufX0iKTsKICAgICAgICAgICAgLy8gSW50ZXJha3Rpb24KICAgICAgICAgICAgY29udGVudC5jcmVhdGVJbnRlcmFjdGlvbigpOwogICAgICAgICAgICAvLyBMw7ZzY2hlbgogICAgICAgICAgICBpZiAoZGF0YVsiaWQucHJvdmlkZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJkZWxldGUiLCAie3suYnV0dG9uLmRlbGV0ZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5jbGFzc05hbWUgPSAiZGVsZXRlIjsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJtM3UiLCAiJyArIGlkICsgJyIsIHRydWUsIDApJyk7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJiYWNrIiwgInt7LmJ1dHRvbi5iYWNrfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInBsYXlsaXN0IiknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFiYnJlY2hlbgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gQWt0dWFsaXNpZXJlbgogICAgICAgICAgICBpZiAoZGF0YVsiaWQucHJvdmlkZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJ1cGRhdGUiLCAie3suYnV0dG9uLnVwZGF0ZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgibTN1IiwgIicgKyBpZCArICciLCBmYWxzZSwgMSknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNwZWljaGVybgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAic2F2ZSIsICJ7ey5idXR0b24uc2F2ZX19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJtM3UiLCAiJyArIGlkICsgJyIsIGZhbHNlLCAwKScpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAiaGRociI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoZGF0YVR5cGUpOwogICAgICAgICAgICAvLyBOYW1lCiAgICAgICAgICAgIHZhciBkYktleSA9ICJuYW1lIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QubmFtZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5uYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEJlc2NocmVpYnVuZwogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBVUkwKICAgICAgICAgICAgdmFyIGRiS2V5ID0gImZpbGUuc291cmNlIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QuZmlsZUhESFIucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sucGxheWxpc3QuZmlsZUhESFIudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gVHVuZXIKICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYnVmZmVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnB1c2goaS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gInR1bmVyIjsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmZvY3VzIiwgImphdmFzY3JpcHQ6IHJldHVybjsiKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC50dW5lci50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJ0dW5lciI7CiAgICAgICAgICAgICAgICBpZiAoZGF0YVtkYktleV0gPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YVtkYktleV0gPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJub3RBdmFpbGFibGUiOwogICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LnR1bmVyLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3sucGxheWxpc3QudHVuZXIuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAvLyBJbnRlcmFrdGlvbgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUludGVyYWN0aW9uKCk7CiAgICAgICAgICAgIC8vIEzDtnNjaGVuCiAgICAgICAgICAgIGlmIChkYXRhWyJpZC5wcm92aWRlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImRlbGV0ZSIsICJ7ey5idXR0b24uZGVsZXRlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJoZGhyIiwgIicgKyBpZCArICciLCB0cnVlLCAwKScpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJiYWNrIiwgInt7LmJ1dHRvbi5iYWNrfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInBsYXlsaXN0IiknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFiYnJlY2hlbgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gQWt0dWFsaXNpZXJlbgogICAgICAgICAgICBpZiAoZGF0YVsiaWQucHJvdmlkZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJ1cGRhdGUiLCAie3suYnV0dG9uLnVwZGF0ZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiaGRociIsICInICsgaWQgKyAnIiwgZmFsc2UsIDEpJyk7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBTcGVpY2hlcm4KICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInNhdmUiLCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiaGRociIsICInICsgaWQgKyAnIiwgZmFsc2UsIDApJyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUhlYWRsaW5lKGRhdGFUeXBlKTsKICAgICAgICAgICAgLy8gVHlwZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAidHlwZSI7CiAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJNM1U6ICIgKyAie3suZmlsdGVyLnR5cGUuZ3JvdXBUaXRsZX19IiwgInhUZVZlOiAiICsgInt7LmZpbHRlci50eXBlLmN1c3RvbUZpbHRlcn19Il07CiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbImphdmFzY3JpcHQ6IG9wZW5Qb3BVcCgnZ3JvdXAtdGl0bGUnKSIsICJqYXZhc2NyaXB0OiBvcGVuUG9wVXAoJ2N1c3RvbS1maWx0ZXInKSJdOwogICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCAiamF2YXNjcmlwdDogb3BlblBvcFVwKCdncm91cC10aXRsZScpIiwgZGJLZXkpOwogICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJpZCIsIGlkKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAnamF2YXNjcmlwdDogY2hhbmdlQnV0dG9uQWN0aW9uKHRoaXMsICJuZXh0IiwgIm9uY2xpY2siKTsnKTsgLy8gY2hhbmdlQnV0dG9uQWN0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIudHlwZS50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgLy8gSW50ZXJha3Rpb24KICAgICAgICAgICAgY29udGVudC5jcmVhdGVJbnRlcmFjdGlvbigpOwogICAgICAgICAgICAvLyBBYmJyZWNoZW4KICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImNhbmNlbCIsICJ7ey5idXR0b24uY2FuY2VsfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIFdlaXRlcgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAibmV4dCIsICJ7ey5idXR0b24ubmV4dH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoImdyb3VwLXRpdGxlIiknKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICduZXh0Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJjdXN0b20tZmlsdGVyIjoKICAgICAgICBjYXNlICJncm91cC10aXRsZSI6CiAgICAgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7LmZpbHRlci5jdXN0b219fSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7LmZpbHRlci5ncm91cH19Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gTmFtZSAgICAgIAogICAgICAgICAgICB2YXIgZGJLZXkgPSAibmFtZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmZpbHRlci5uYW1lLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5uYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEJlc2NocmVpYnVuZwogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5maWx0ZXIuZGVzY3JpcHRpb24ucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3suZmlsdGVyLmRlc2NyaXB0aW9uLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIFR5cAogICAgICAgICAgICB2YXIgZGJLZXkgPSAidHlwZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImhpZGRlbiIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCIiLCBpbnB1dCk7CiAgICAgICAgICAgIHZhciBmaWx0ZXJUeXBlID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIHN3aXRjaCAoZmlsdGVyVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAiY3VzdG9tLWZpbHRlciI6CiAgICAgICAgICAgICAgICAgICAgLy8gR3Jvw58tIEtsZWluc2NocmVpYnVuZyBiZWFjaHRlbgogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJjYXNlU2Vuc2l0aXZlIjsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5jYXNlU2Vuc2l0aXZlLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgLy8gRmlsdGVycmVnZWwgKEJlbnV0emVyZGVmaW5pZXJ0KQogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJmaWx0ZXIiOwogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suZmlsdGVyLmZpbHRlclJ1bGUucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIuZmlsdGVyUnVsZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIC8vYWxlcnQoZGJLZXkgKyAiICIgKyBmaWx0ZXJUeXBlKQogICAgICAgICAgICAgICAgICAgIC8vIEZpbHRlciBiYXNpZXJlbmQgYXVmIGRlbiBHcnVwcGVuIGluIGRlciBNM1UKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAiZmlsdGVyIjsKICAgICAgICAgICAgICAgICAgICB2YXIgZ3JvdXBzTTNVID0gZ2V0TG9jYWxEYXRhKCJtM3VHcm91cHMiLCAiIik7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBncm91cHNNM1VbInRleHQiXTsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gZ3JvdXBzTTNVWyJ2YWx1ZSJdOwogICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3suZmlsdGVyLmZpbHRlckdyb3VwLnRpdGxlfX0iLCBzZWxlY3QpOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuZGVzY3JpcHRpb24oInt7LmZpbHRlci5maWx0ZXJHcm91cC5kZXNjcmlwdGlvbn19Iik7CiAgICAgICAgICAgICAgICAgICAgLy8gR3Jvw58tIEtsZWluc2NocmVpYnVuZyBiZWFjaHRlbgogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJjYXNlU2Vuc2l0aXZlIjsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5jYXNlU2Vuc2l0aXZlLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gImluY2x1ZGUiOwogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suZmlsdGVyLmluY2x1ZGUucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIuaW5jbHVkZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuZGVzY3JpcHRpb24oInt7LmZpbHRlci5pbmNsdWRlLmRlc2NyaXB0aW9ufX0iKTsKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAiZXhjbHVkZSI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5maWx0ZXIuZXhjbHVkZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5leGNsdWRlLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3suZmlsdGVyLmV4Y2x1ZGUuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBJbnRlcmFrdGlvbgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUludGVyYWN0aW9uKCk7CiAgICAgICAgICAgIC8vIEzDtnNjaGVuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJkZWxldGUiLCAie3suYnV0dG9uLmRlbGV0ZX19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJmaWx0ZXIiLCAiJyArIGlkICsgJyIsIHRydWUsIDApJyk7CiAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJkZWxldGUiOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gQWJicmVjaGVuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLmNhbmNlbH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICAvLyBTcGVpY2hlcm4KICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInNhdmUiLCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiZmlsdGVyIiwgIicgKyBpZCArICciLCBmYWxzZSwgMCknKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgY29udGVudC5jcmVhdGVIZWFkbGluZShkYXRhVHlwZSk7CiAgICAgICAgICAgIC8vIE5hbWUKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIm5hbWUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey54bWx0di5uYW1lLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnhtbHR2Lm5hbWUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQmVzY2hyZWlidW5nCiAgICAgICAgICAgIHZhciBkYktleSA9ICJkZXNjcmlwdGlvbiI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnhtbHR2LmRlc2NyaXB0aW9uLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnhtbHR2LmRlc2NyaXB0aW9uLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIFVSTAogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZmlsZS5zb3VyY2UiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey54bWx0di5maWxlWE1MVFYucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sueG1sdHYuZmlsZVhNTFRWLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEludGVyYWt0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gTMO2c2NoZW4KICAgICAgICAgICAgaWYgKGRhdGFbImlkLnByb3ZpZGVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiZGVsZXRlIiwgInt7LmJ1dHRvbi5kZWxldGV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoInhtbHR2IiwgIicgKyBpZCArICciLCB0cnVlLCAwKScpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBBYmJyZWNoZW4KICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImNhbmNlbCIsICJ7ey5idXR0b24uY2FuY2VsfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIEFrdHVhbGlzaWVyZW4KICAgICAgICAgICAgaWYgKGRhdGFbImlkLnByb3ZpZGVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAidXBkYXRlIiwgInt7LmJ1dHRvbi51cGRhdGV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoInhtbHR2IiwgIicgKyBpZCArICciLCBmYWxzZSwgMSknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNwZWljaGVybgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAic2F2ZSIsICJ7ey5idXR0b24uc2F2ZX19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJ4bWx0diIsICInICsgaWQgKyAnIiwgZmFsc2UsIDApJyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJ1c2VycyI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7Lm1haW5NZW51Lml0ZW0udXNlcnN9fSIpOwogICAgICAgICAgICAvLyBCZW51dHplcm5hbWUgCiAgICAgICAgICAgIHZhciBkYktleSA9ICJ1c2VybmFtZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnVzZXJzLnVzZXJuYW1lLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnVzZXJzLnVzZXJuYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIE5ldWVzIFBhc3N3b3J0IAogICAgICAgICAgICB2YXIgZGJLZXkgPSAicGFzc3dvcmQiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJwYXNzd29yZCIsIGRiS2V5LCAiIik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sudXNlcnMucGFzc3dvcmQucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sudXNlcnMucGFzc3dvcmQudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQmVzdMOkdGlndW5nIAogICAgICAgICAgICB2YXIgZGJLZXkgPSAiY29uZmlybSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInBhc3N3b3JkIiwgZGJLZXksICIiKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey51c2Vycy5jb25maXJtLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnVzZXJzLmNvbmZpcm0udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQmVyZWNodGlndW5nIFdFQgogICAgICAgICAgICB2YXIgZGJLZXkgPSAiYXV0aGVudGljYXRpb24ud2ViIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgaWYgKGRhdGFbImRlZmF1bHRVc2VyIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgImphdmFzY3JpcHQ6IHJldHVybiBmYWxzZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy53ZWIudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQmVyZWNodGlndW5nIFBNUwogICAgICAgICAgICB2YXIgZGJLZXkgPSAiYXV0aGVudGljYXRpb24ucG1zIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnVzZXJzLnBtcy50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBCZXJlY2h0aWd1bmcgTTNVCiAgICAgICAgICAgIHZhciBkYktleSA9ICJhdXRoZW50aWNhdGlvbi5tM3UiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sudXNlcnMubTN1LnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEJlcmVjaHRpZ3VuZyBYTUwKICAgICAgICAgICAgdmFyIGRiS2V5ID0gImF1dGhlbnRpY2F0aW9uLnhtbCI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goZGJLZXkpOwogICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy54bWwudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQmVyZWNodGlndW5nIEFQSQogICAgICAgICAgICB2YXIgZGJLZXkgPSAiYXV0aGVudGljYXRpb24uYXBpIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnVzZXJzLmFwaS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBJbnRlcmFrdGlvbgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUludGVyYWN0aW9uKCk7CiAgICAgICAgICAgIC8vIEzDtnNjaGVuCiAgICAgICAgICAgIGlmIChkYXRhWyJkZWZhdWx0VXNlciJdICE9IHRydWUgJiYgaWQgIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiZGVsZXRlIiwgInt7LmJ1dHRvbi5kZWxldGV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiJyArIGRhdGFUeXBlICsgJyIsICInICsgaWQgKyAnIiwgdHJ1ZSwgMCknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFiYnJlY2hlbgogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gU3BlaWNoZXJuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJzYXZlIiwgInt7LmJ1dHRvbi5zYXZlfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoIicgKyBkYXRhVHlwZSArICciLCAiJyArIGlkICsgJyIsICJmYWxzZSIpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7Lm1haW5NZW51Lml0ZW0ubWFwcGluZ319Iik7CiAgICAgICAgICAgIC8vIEFrdGl2IAogICAgICAgICAgICB2YXIgZGJLZXkgPSAieC1hY3RpdmUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICBpbnB1dC5pZCA9ICJhY3RpdmUiOwogICAgICAgICAgICAvL2lucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKQogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRvZ2dsZUNoYW5uZWxTdGF0dXMoJyIgKyBpZCArICInLCB0aGlzKSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy5hY3RpdmUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gS2FuYWxuYW1lIAogICAgICAgICAgICB2YXIgZGJLZXkgPSAieC1uYW1lIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgaWYgKEJVTEtfRURJVCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICBpbnB1dC5zdHlsZS5ib3JkZXIgPSAic29saWQgMXB4IHJlZCI7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy5jaGFubmVsTmFtZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKGRhdGFbIm5hbWUiXSk7CiAgICAgICAgICAgIC8vIEJlc2NocmVpYnVuZyAKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngtZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5tYXBwaW5nLmRlc2NyaXB0aW9uLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy5kZXNjcmlwdGlvbi50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBBa3R1YWxpc2llcnVuZyBkZXMgS2FuYWxuYW1lbnMKICAgICAgICAgICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoIl91dWlkLmtleSIpKSB7CiAgICAgICAgICAgICAgICBpZiAoZGF0YVsiX3V1aWQua2V5Il0gIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAieC11cGRhdGUtY2hhbm5lbC1uYW1lIjsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLnVwZGF0ZUNoYW5uZWxOYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gTG9nbyBVUkwgKEthbmFsKSAKICAgICAgICAgICAgdmFyIGRiS2V5ID0gInR2Zy1sb2dvIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJjaGFubmVsLWljb24iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcuY2hhbm5lbExvZ28udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQWt0dWFsaXNpZXJ1bmcgZGVzIEthbmFsbG9nb3MKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngtdXBkYXRlLWNoYW5uZWwtaWNvbiI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goZGJLZXkpOwogICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiaWQiLCAidXBkYXRlLWljb24iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJzsgY2hhbmdlQ2hhbm5lbExvZ28oJyIgKyBpZCArICInKTsiKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcudXBkYXRlQ2hhbm5lbExvZ28udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gRXJ3ZWl0ZXJuIGRlciBFUEcgS2F0ZWdvcmllCiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LWNhdGVnb3J5IjsKICAgICAgICAgICAgdmFyIHRleHQgPSBbIi0iLCAiS2lkcyAoRW1ieSBvbmx5KSIsICJOZXdzIiwgIk1vdmllIiwgIlNlcmllcyIsICJTcG9ydHMiXTsKICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFsiIiwgIktpZHMiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIl07CiAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLmVwZ0NhdGVnb3J5LnRpdGxlfX0iLCBzZWxlY3QpOwogICAgICAgICAgICAvLyBNM1UgR3J1cHBlbnRpdGVsCiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LWdyb3VwLXRpdGxlIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcubTN1R3JvdXBUaXRsZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICBpZiAoZGF0YVsiZ3JvdXAtdGl0bGUiXSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIGNvbnRlbnQuZGVzY3JpcHRpb24oZGF0YVsiZ3JvdXAtdGl0bGUiXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gWE1MVFYgRGF0ZWkKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngteG1sdHYtZmlsZSI7CiAgICAgICAgICAgIHZhciB4bWxGaWxlID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIHZhciB4bWx0diA9IG5ldyBYTUxUVkZpbGUoKTsKICAgICAgICAgICAgdmFyIHNlbGVjdCA9IHhtbHR2LmdldEZpbGVzKGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgibmFtZSIsIGRiS2V5KTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiaWQiLCAicG9wdXAteG1sdHYiKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCc7IHNldFhtbHR2Q2hhbm5lbCgnIiArIGlkICsgIicsdGhpcyk7Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLnhtbHR2RmlsZS50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgdmFyIGZpbGUgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgLy8gWE1MVFYgTWFwcGluZwogICAgICAgICAgICB2YXIgZGJLZXkgPSAieC1tYXBwaW5nIjsKICAgICAgICAgICAgdmFyIHhtbHR2ID0gbmV3IFhNTFRWRmlsZSgpOwogICAgICAgICAgICB2YXIgc2VsZWN0ID0geG1sdHYuZ2V0UHJvZ3JhbXMoZmlsZSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJuYW1lIiwgZGJLZXkpOwogICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJpZCIsICJwb3B1cC1tYXBwaW5nIik7CiAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnOyBjaGVja1htbHR2Q2hhbm5lbCgnIiArIGlkICsgIicsdGhpcywnIiArIHhtbEZpbGUgKyAiJyk7Iik7CiAgICAgICAgICAgIHNvcnRTZWxlY3Qoc2VsZWN0KTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcueG1sdHZDaGFubmVsLnRpdGxlfX0iLCBzZWxlY3QpOwogICAgICAgICAgICAvLyBJbnRlcmFrdGlvbgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUludGVyYWN0aW9uKCk7CiAgICAgICAgICAgIC8vIExvZ28gaG9jaGxhZGVuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLnVwbG9hZExvZ299fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogdXBsb2FkTG9nbygpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gQWJicmVjaGVuCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLmNhbmNlbH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICAvLyBGZXJ0aWcKICAgICAgICAgICAgdmFyIGlkcyA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICBpZHMgPSBnZXRBbGxTZWxlY3RlZENoYW5uZWxzKCk7CiAgICAgICAgICAgIGlmIChpZHMubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgIGlkcy5wdXNoKGlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAic2F2ZSIsICJ7ey5idXR0b24uZG9uZX19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBkb25lUG9wdXBEYXRhKCInICsgZGF0YVR5cGUgKyAnIiwgIicgKyBpZHMgKyAnIiwgImZhbHNlIik7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHNob3dQb3BVcEVsZW1lbnQoJ3BvcHVwLWN1c3RvbScpOwp9CnZhciBYTUxUVkZpbGUgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBYTUxUVkZpbGUoKSB7CiAgICB9CiAgICBYTUxUVkZpbGUucHJvdG90eXBlLmdldEZpbGVzID0gZnVuY3Rpb24gKHNldCkgewogICAgICAgIHZhciBmaWxlSURzID0gZ2V0T2JqS2V5cyhTRVJWRVJbInhlcGciXVsieG1sdHZNYXAiXSk7CiAgICAgICAgdmFyIHZhbHVlcyA9IG5ldyBBcnJheSgiLSIpOwogICAgICAgIHZhciB0ZXh0ID0gbmV3IEFycmF5KCItIik7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlSURzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChmaWxlSURzW2ldICE9ICJ4VGVWZSBEdW1teSIpIHsKICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZShmaWxlSURzW2ldLCAieG1sdHYiLCAiZmlsZS54dGV2ZSIpKTsKICAgICAgICAgICAgICAgIHRleHQucHVzaChnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZmlsZUlEc1tpXSwgInhtbHR2IiwgIm5hbWUiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChmaWxlSURzW2ldKTsKICAgICAgICAgICAgICAgIHRleHQucHVzaChmaWxlSURzW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2YXIgc2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiU0VMRUNUIik7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKTsKICAgICAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZXNbaV0pOwogICAgICAgICAgICBvcHRpb24uaW5uZXJUZXh0ID0gdGV4dFtpXTsKICAgICAgICAgICAgc2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7CiAgICAgICAgfQogICAgICAgIGlmIChzZXQgIT0gIiIpIHsKICAgICAgICAgICAgc2VsZWN0LnZhbHVlID0gc2V0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZWN0OwogICAgfTsKICAgIFhNTFRWRmlsZS5wcm90b3R5cGUuZ2V0UHJvZ3JhbXMgPSBmdW5jdGlvbiAoZmlsZSwgc2V0KSB7CiAgICAgICAgLy92YXIgZmlsZUlEczpzdHJpbmdbXSA9IGdldE9iaktleXMoU0VSVkVSWyJ4ZXBnIl1bInhtbHR2TWFwIl0pCiAgICAgICAgdmFyIHZhbHVlcyA9IGdldE9iaktleXMoU0VSVkVSWyJ4ZXBnIl1bInhtbHR2TWFwIl1bZmlsZV0pOwogICAgICAgIHZhciB0ZXh0ID0gbmV3IEFycmF5KCk7CiAgICAgICAgdmFyIGRpc3BsYXlOYW1lOwogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChTRVJWRVJbInhlcGciXVsieG1sdHZNYXAiXVtmaWxlXVt2YWx1ZXNbaV1dLmhhc093blByb3BlcnR5KCdkaXNwbGF5LW5hbWUnKSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICBkaXNwbGF5TmFtZSA9IFNFUlZFUlsieGVwZyJdWyJ4bWx0dk1hcCJdW2ZpbGVdW3ZhbHVlc1tpXV1bImRpc3BsYXktbmFtZSJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgZGlzcGxheU5hbWUgPSAiLSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGV4dFtpXSA9IGRpc3BsYXlOYW1lICsgIiAoIiArIHZhbHVlc1tpXSArICIpIjsKICAgICAgICB9CiAgICAgICAgdGV4dC51bnNoaWZ0KCItIik7CiAgICAgICAgdmFsdWVzLnVuc2hpZnQoIi0iKTsKICAgICAgICB2YXIgc2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiU0VMRUNUIik7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKTsKICAgICAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZXNbaV0pOwogICAgICAgICAgICBvcHRpb24uaW5uZXJUZXh0ID0gdGV4dFtpXTsKICAgICAgICAgICAgc2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7CiAgICAgICAgfQogICAgICAgIGlmIChzZXQgIT0gIiIpIHsKICAgICAgICAgICAgc2VsZWN0LnZhbHVlID0gc2V0OwogICAgICAgIH0KICAgICAgICBpZiAoc2VsZWN0LnZhbHVlICE9IHNldCkgewogICAgICAgICAgICBzZWxlY3QudmFsdWUgPSAiLSI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxlY3Q7CiAgICB9OwogICAgcmV0dXJuIFhNTFRWRmlsZTsKfSgpKTsKZnVuY3Rpb24gZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKGZpbGUsIGZpbGVUeXBlLCBrZXkpIHsKICAgIGlmIChmaWxlID09ICJ4VGVWZSBEdW1teSIpIHsKICAgICAgICByZXR1cm4gZmlsZTsKICAgIH0KICAgIHZhciBmaWxlSUQ7CiAgICB2YXIgaW5kaWNhdG9yID0gZmlsZS5jaGFyQXQoMCk7CiAgICBzd2l0Y2ggKGluZGljYXRvcikgewogICAgICAgIGNhc2UgIk0iOgogICAgICAgICAgICBmaWxlVHlwZSA9ICJtM3UiOwogICAgICAgICAgICBmaWxlSUQgPSBmaWxlOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJIIjoKICAgICAgICAgICAgZmlsZVR5cGUgPSAiaGRociI7CiAgICAgICAgICAgIGZpbGVJRCA9IGZpbGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIlgiOgogICAgICAgICAgICBmaWxlVHlwZSA9ICJ4bWx0diI7CiAgICAgICAgICAgIGZpbGVJRCA9IGZpbGUuc3Vic3RyaW5nKDAsIGZpbGUubGFzdEluZGV4T2YoJy4nKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtmaWxlVHlwZV0uaGFzT3duUHJvcGVydHkoZmlsZUlEKSA9PSB0cnVlKSB7CiAgICAgICAgdmFyIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbGVzIl1bZmlsZVR5cGVdW2ZpbGVJRF07CiAgICAgICAgcmV0dXJuIGRhdGFba2V5XTsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBzZXRYbWx0dkNoYW5uZWwoaWQsIGVsZW1lbnQpIHsKICAgIHZhciB4bWx0diA9IG5ldyBYTUxUVkZpbGUoKTsKICAgIHZhciB4bWxGaWxlID0gZWxlbWVudC52YWx1ZTsKICAgIHZhciB0dmdJZCA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl1baWRdWyJ0dmctaWQiXTsKICAgIHZhciB0ZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwb3B1cC1tYXBwaW5nIikucGFyZW50RWxlbWVudDsKICAgIHRkLmlubmVySFRNTCA9ICIiOwogICAgdmFyIHNlbGVjdCA9IHhtbHR2LmdldFByb2dyYW1zKGVsZW1lbnQudmFsdWUsIHR2Z0lkKTsKICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm5hbWUiLCAieC1tYXBwaW5nIik7CiAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJpZCIsICJwb3B1cC1tYXBwaW5nIik7CiAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJzsgY2hlY2tYbWx0dkNoYW5uZWwoJyIgKyBpZCArICInLHRoaXMsJyIgKyB4bWxGaWxlICsgIicpOyIpOwogICAgc2VsZWN0LmNsYXNzTmFtZSA9ICJjaGFuZ2VkIjsKICAgIHNvcnRTZWxlY3Qoc2VsZWN0KTsKICAgIHRkLmFwcGVuZENoaWxkKHNlbGVjdCk7CiAgICBjaGVja1htbHR2Q2hhbm5lbChpZCwgc2VsZWN0LCB4bWxGaWxlKTsKfQpmdW5jdGlvbiBjaGVja1htbHR2Q2hhbm5lbChpZCwgZWxlbWVudCwgeG1sRmlsZSkgewogICAgdmFyIHZhbHVlID0gZWxlbWVudC52YWx1ZTsKICAgIHZhciBib29sOwogICAgdmFyIGNoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FjdGl2ZScpOwogICAgdmFyIGNoYW5uZWwgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdW2lkXTsKICAgIHZhciB1cGRhdGVMb2dvOwogICAgaWYgKHZhbHVlID09ICItIikgewogICAgICAgIGJvb2wgPSBmYWxzZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGJvb2wgPSB0cnVlOwogICAgfQogICAgY2hlY2tib3guY2hlY2tlZCA9IGJvb2w7CiAgICBjaGVja2JveC5jbGFzc05hbWUgPSAiY2hhbmdlZCI7CiAgICBjb25zb2xlLmxvZyh4bWxGaWxlKTsKICAgIC8vIEthbmFsbG9nbyBha3R1YWxpc2llcmVuCiAgICAvKgogICAgdXBkYXRlTG9nbyA9IChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXBkYXRlLWljb24iKSBhcyBIVE1MSW5wdXRFbGVtZW50KS5jaGVja2VkCiAgICBjb25zb2xlLmxvZyh1cGRhdGVMb2dvKTsKICAgICovCiAgICBpZiAoeG1sRmlsZSAhPSAieFRlVmUgRHVtbXkiICYmIGJvb2wgPT0gdHJ1ZSkgewogICAgICAgIC8vKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1cGRhdGUtaWNvbiIpIGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQgPSB0cnVlOwogICAgICAgIC8vKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1cGRhdGUtaWNvbiIpIGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNsYXNzTmFtZSA9ICJjaGFuZ2VkIjsKICAgICAgICBjb25zb2xlLmxvZygiSUQiLCBpZCk7CiAgICAgICAgY2hhbmdlQ2hhbm5lbExvZ28oaWQpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICh4bWxGaWxlID09ICJ4VGVWZSBEdW1teSIpIHsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXBkYXRlLWljb24iKS5jaGVja2VkID0gZmFsc2U7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInVwZGF0ZS1pY29uIikuY2xhc3NOYW1lID0gImNoYW5nZWQiOwogICAgfQogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIGNoYW5nZUNoYW5uZWxMb2dvKGlkKSB7CiAgICB2YXIgdXBkYXRlTG9nbzsKICAgIHZhciBjaGFubmVsID0gU0VSVkVSWyJ4ZXBnIl1bImVwZ01hcHBpbmciXVtpZF07CiAgICB2YXIgZiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwb3B1cC14bWx0diIpOwogICAgdmFyIHhtbHR2RmlsZSA9IGYub3B0aW9uc1tmLnNlbGVjdGVkSW5kZXhdLnZhbHVlOwogICAgdmFyIG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtbWFwcGluZyIpOwogICAgdmFyIHhNYXBwaW5nID0gbS5vcHRpb25zW20uc2VsZWN0ZWRJbmRleF0udmFsdWU7CiAgICB2YXIgeG1sdHZMb2dvID0gU0VSVkVSWyJ4ZXBnIl1bInhtbHR2TWFwIl1beG1sdHZGaWxlXVt4TWFwcGluZ11bImljb24iXTsKICAgIHVwZGF0ZUxvZ28gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXBkYXRlLWljb24iKS5jaGVja2VkOwogICAgaWYgKHVwZGF0ZUxvZ28gPT0gdHJ1ZSAmJiB4bWx0dkZpbGUgIT0gInhUZVZlIER1bW15IikgewogICAgICAgIGlmIChTRVJWRVJbInhlcGciXVsieG1sdHZNYXAiXVt4bWx0dkZpbGVdLmhhc093blByb3BlcnR5KHhNYXBwaW5nKSkgewogICAgICAgICAgICB2YXIgbG9nbyA9IHhtbHR2TG9nbzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxvZ28gPSBjaGFubmVsWyJ0dmctbG9nbyJdOwogICAgICAgIH0KICAgICAgICB2YXIgbG9nb0lucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNoYW5uZWwtaWNvbiIpOwogICAgICAgIGxvZ29JbnB1dC52YWx1ZSA9IGxvZ287CiAgICAgICAgaWYgKEJVTEtfRURJVCA9PSBmYWxzZSkgewogICAgICAgICAgICBsb2dvSW5wdXQuY2xhc3NOYW1lID0gImNoYW5nZWQiOwogICAgICAgIH0KICAgIH0KfQpmdW5jdGlvbiBzYXZlUG9wdXBEYXRhKGRhdGFUeXBlLCBpZCwgcmVtb3ZlLCBvcHRpb24pIHsKICAgIGlmIChkYXRhVHlwZSA9PSAibWFwcGluZyIpIHsKICAgICAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgICAgICBjb25zb2xlLmxvZygiU2F2ZSBtYXBwaW5nIGRhdGEiKTsKICAgICAgICBjbWQgPSAic2F2ZUVwZ01hcHBpbmciOwogICAgICAgIGRhdGFbImVwZ01hcHBpbmciXSA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl07CiAgICAgICAgY29uc29sZS5sb2coIlNFTkQgVE8gU0VSVkVSIik7CiAgICAgICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgICAgICBzZXJ2ZXIucmVxdWVzdChkYXRhKTsKICAgICAgICBkZWxldGUgVU5ET1siZXBnTWFwcGluZyJdOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnNvbGUubG9nKCJTYXZlIHBvcHVwIGRhdGEiKTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtY3VzdG9tIik7CiAgICB2YXIgaW5wdXRzID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUQUJMRSIpWzBdLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTlBVVCIpOwogICAgdmFyIHNlbGVjdHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRBQkxFIilbMF0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlNFTEVDVCIpOwogICAgdmFyIGlucHV0ID0gbmV3IE9iamVjdCgpOwogICAgdmFyIGNvbmZpcm1Nc2c7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdHMubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgbmFtZTsKICAgICAgICBuYW1lID0gc2VsZWN0c1tpXS5uYW1lOwogICAgICAgIHZhciB2YWx1ZSA9IHNlbGVjdHNbaV0udmFsdWU7CiAgICAgICAgc3dpdGNoIChuYW1lKSB7CiAgICAgICAgICAgIGNhc2UgInR1bmVyIjoKICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gcGFyc2VJbnQodmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICBzd2l0Y2ggKGlucHV0c1tpXS50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgImNoZWNrYm94IjoKICAgICAgICAgICAgICAgIG5hbWUgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gaW5wdXRzW2ldLmNoZWNrZWQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgIGNhc2UgImhpZGRlbiI6CiAgICAgICAgICAgIGNhc2UgInBhc3N3b3JkIjoKICAgICAgICAgICAgICAgIG5hbWUgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICAgICAgICAgIHN3aXRjaCAobmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgInR1bmVyIjoKICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRbbmFtZV0gPSBwYXJzZUludChpbnB1dHNbaV0udmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIHZhciBjbWQ7CiAgICBpZiAocmVtb3ZlID09IHRydWUpIHsKICAgICAgICBpbnB1dFsiZGVsZXRlIl0gPSB0cnVlOwogICAgfQogICAgc3dpdGNoIChkYXRhVHlwZSkgewogICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgY29uZmlybU1zZyA9ICJEZWxldGUgdGhpcyB1c2VyPyI7CiAgICAgICAgICAgIGlmIChpZCA9PSAiLSIpIHsKICAgICAgICAgICAgICAgIGNtZCA9ICJzYXZlTmV3VXNlciI7CiAgICAgICAgICAgICAgICBkYXRhWyJ1c2VyRGF0YSJdID0gaW5wdXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjbWQgPSAic2F2ZVVzZXJEYXRhIjsKICAgICAgICAgICAgICAgIHZhciBkID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgICAgICAgZFtpZF0gPSBpbnB1dDsKICAgICAgICAgICAgICAgIGRhdGFbInVzZXJEYXRhIl0gPSBkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgcGxheWxpc3Q/IjsKICAgICAgICAgICAgc3dpdGNoIChvcHRpb24pIHsKICAgICAgICAgICAgICAgIC8vIFBvcHVwOiBTYXZlCiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInNhdmVGaWxlc00zVSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvLyBQb3B1cDogVXBkYXRlCiAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInVwZGF0ZUZpbGVNM1UiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl0gPSBuZXcgT2JqZWN0OwogICAgICAgICAgICBkYXRhWyJmaWxlcyJdW2RhdGFUeXBlXSA9IG5ldyBPYmplY3Q7CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl1bZGF0YVR5cGVdW2lkXSA9IGlucHV0OwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJoZGhyIjoKICAgICAgICAgICAgY29uZmlybU1zZyA9ICJEZWxldGUgdGhpcyBIREhvbWVSdW4gdHVuZXI/IjsKICAgICAgICAgICAgc3dpdGNoIChvcHRpb24pIHsKICAgICAgICAgICAgICAgIC8vIFBvcHVwOiBTYXZlCiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInNhdmVGaWxlc0hESFIiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgLy8gUG9wdXA6IFVwZGF0ZQogICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgIGNtZCA9ICJ1cGRhdGVGaWxlSERIUiI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YVsiZmlsZXMiXSA9IG5ldyBPYmplY3Q7CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl1bZGF0YVR5cGVdID0gbmV3IE9iamVjdDsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdID0gaW5wdXQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgY29uZmlybU1zZyA9ICJEZWxldGUgdGhpcyBYTUxUViBmaWxlPyI7CiAgICAgICAgICAgIHN3aXRjaCAob3B0aW9uKSB7CiAgICAgICAgICAgICAgICAvLyBQb3B1cDogU2F2ZQogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGNtZCA9ICJzYXZlRmlsZXNYTUxUViI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvLyBQb3B1cDogVXBkYXRlCiAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInVwZGF0ZUZpbGVYTUxUViI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YVsiZmlsZXMiXSA9IG5ldyBPYmplY3Q7CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl1bZGF0YVR5cGVdID0gbmV3IE9iamVjdDsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdID0gaW5wdXQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgImZpbHRlciI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgZmlsdGVyPyI7CiAgICAgICAgICAgIGNtZCA9ICJzYXZlRmlsdGVyIjsKICAgICAgICAgICAgZGF0YVsiZmlsdGVyIl0gPSBuZXcgT2JqZWN0OwogICAgICAgICAgICBkYXRhWyJmaWx0ZXIiXVtpZF0gPSBpbnB1dDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YVR5cGUsIGlkKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGlmIChyZW1vdmUgPT0gdHJ1ZSkgewogICAgICAgIGlmICghY29uZmlybShjb25maXJtTXNnKSkgewogICAgICAgICAgICBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBjb25zb2xlLmxvZygiU0VORCBUTyBTRVJWRVIiKTsKICAgIGNvbnNvbGUubG9nKGRhdGEpOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9CmZ1bmN0aW9uIGRvbmVQb3B1cERhdGEoZGF0YVR5cGUsIGlkc1N0cikgewogICAgdmFyIGlkcyA9IGlkc1N0ci5zcGxpdCgnLCcpOwogICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwb3B1cC1jdXN0b20iKTsKICAgIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgiY2hhbmdlZCIpOwogICAgaWRzLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7CiAgICAgICAgdmFyIGlucHV0ID0gbmV3IE9iamVjdCgpOwogICAgICAgIGlucHV0ID0gU0VSVkVSWyJ4ZXBnIl1bImVwZ01hcHBpbmciXVtpZF07CiAgICAgICAgY29uc29sZS5sb2coaW5wdXQpOwogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBuYW1lOwogICAgICAgICAgICB2YXIgdmFsdWU7CiAgICAgICAgICAgIHN3aXRjaCAoaW5wdXRzW2ldLnRhZ05hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgIklOUFVUIjoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGlucHV0c1tpXS50eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImNoZWNrYm94IjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gaW5wdXRzW2ldLmNoZWNrZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiU0VMRUNUIjoKICAgICAgICAgICAgICAgICAgICBuYW1lID0gaW5wdXRzW2ldLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaW5wdXRbbmFtZV0gPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKG5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgInR2Zy1sb2dvIjoKICAgICAgICAgICAgICAgICAgICAvLyhkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1syXS5maXJzdENoaWxkIGFzIEhUTUxFbGVtZW50KS5zZXRBdHRyaWJ1dGUoInNyYyIsIHZhbHVlKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieC1uYW1lIjoKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1szXS5maXJzdENoaWxkLmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieC1jYXRlZ29yeSI6CiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNoaWxkTm9kZXNbM10uZmlyc3RDaGlsZC5jbGFzc05hbWUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIngtZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzVdLmZpcnN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ4LXhtbHR2LWZpbGUiOgogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSAieFRlVmUgRHVtbXkiICYmIHZhbHVlICE9ICItIikgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZSh2YWx1ZSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09ICItIikgewogICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFsieC1hY3RpdmUiXSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1s2XS5maXJzdENoaWxkLmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieC1tYXBwaW5nIjoKICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gIi0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0WyJ4LWFjdGl2ZSJdID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzddLmZpcnN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB9CiAgICAgICAgICAgIGNyZWF0ZVNlYXJjaE9iaigpOwogICAgICAgICAgICBzZWFyY2hJbk1hcHBpbmcoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGlucHV0WyJ4LWFjdGl2ZSJdID09IGZhbHNlKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jbGFzc05hbWUgPSAiYWN0aXZlRVBHIjsKICAgICAgICB9CiAgICAgICAgY29uc29sZS5sb2coaW5wdXRbInR2Zy1sb2dvIl0pOwogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzJdLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCJzcmMiLCBpbnB1dFsidHZnLWxvZ28iXSk7CiAgICB9KTsKICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsKICAgIHJldHVybjsKfQpmdW5jdGlvbiBzaG93UHJldmlldyhlbGVtZW50KSB7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpOwogICAgc3dpdGNoIChlbGVtZW50KSB7CiAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICJub3RWaXNpYmxlIjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHZhciBzdHJlYW1zID0gWyJhY3RpdmVTdHJlYW1zIiwgImluYWN0aXZlU3RyZWFtcyJdOwogICAgc3RyZWFtcy5mb3JFYWNoKGZ1bmN0aW9uIChwcmV2aWV3KSB7CiAgICAgICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocHJldmlldyk7CiAgICAgICAgdGFibGUuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgdmFyIG9iaiA9IFNFUlZFUlsiZGF0YSJdWyJTdHJlYW1QcmV2aWV3VUkiXVtwcmV2aWV3XTsKICAgICAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAoY2hhbm5lbCkgewogICAgICAgICAgICB2YXIgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgICAgICB2YXIgdGRLZXkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICB2YXIgdGRWYWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICB0ZEtleS5jbGFzc05hbWUgPSAidGRLZXkiOwogICAgICAgICAgICB0ZFZhbC5jbGFzc05hbWUgPSAidGRWYWwiOwogICAgICAgICAgICBzd2l0Y2ggKHByZXZpZXcpIHsKICAgICAgICAgICAgICAgIGNhc2UgImFjdGl2ZVN0cmVhbXMiOgogICAgICAgICAgICAgICAgICAgIHRkS2V5LmlubmVyVGV4dCA9ICJDaGFubmVsOiAoKykiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiaW5hY3RpdmVTdHJlYW1zIjoKICAgICAgICAgICAgICAgICAgICB0ZEtleS5pbm5lclRleHQgPSAiQ2hhbm5lbDogKC0pIjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZFZhbC5pbm5lclRleHQgPSBjaGFubmVsOwogICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZEtleSk7CiAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKHRkVmFsKTsKICAgICAgICAgICAgdGFibGUuYXBwZW5kQ2hpbGQodHIpOwogICAgICAgIH0pOwogICAgfSk7CiAgICBzaG93RWxlbWVudCgibG9hZGluZyIsIGZhbHNlKTsKICAgIGRpdi5jbGFzc05hbWUgPSAidmlzaWJsZSI7CiAgICByZXR1cm47Cn0K"
- webUI["html/css/screen.css"] = "bmF2IGltZyB7CiAgZGlzcGxheTogYmxvY2s7CiAgbWF4LWhlaWdodDogMjBweDsKICBtYXgtd2lkdGg6IDIwcHg7CiAgZmxvYXQ6IGxlZnQ7Cn0KCm5hdiBwIHsKICB0ZXh0LWFsaWduOiBsZWZ0OwogIHBhZGRpbmc6IDBweCAzMHB4Owp9CgojbGF5b3V0IHsKICBkaXNwbGF5OiBibG9jazsKICBoZWlnaHQ6IDEwMCU7Cn0KCgoubGF5b3V0LWxlZnQgewogIGRpc3BsYXk6IGJsb2NrOwogIG1pbi13aWR0aDogMTUwcHg7CiAgbWF4LXdpZHRoOiAyMCU7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBoZWlnaHQ6IGluaGVyaXQ7CiAgZmxvYXQ6IGxlZnQ7Cn0KCi5sYXlvdXQtcmlnaHQgewogIGRpc3BsYXk6IGJsb2NrOwogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7Cn0KCiNtZW51LXdyYXBwZXIgewogIGhlaWdodDogMTAwJTsKfQoKCiNsb2dvIHsKICBkaXNwbGF5OiBibG9jazsKICBtaW4td2lkdGg6IDE4MHB4OwogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvbG9nb193XzYwMHgyMDAucG5nIik7CiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7IAogIGJhY2tncm91bmQtc2l6ZTogMTAwJTsKfQoKCiNwYWdlIHsKICBtYXgtd2lkdGg6IDk1MHB4OwogIG1hcmdpbjogYXV0bzsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwoKICAvKgogIGhlaWdodDogLXdlYmtpdC1jYWxjKDEwMCUgLSAxMzBweCk7CiAgaGVpZ2h0OiAtbW96LWNhbGMoMTAwJSAtIDEzMHB4KTsKICBoZWlnaHQ6IGNhbGMoMTAwJSAtIDEzMHB4KTsKICAqLwogIAogIG1pbi1oZWlnaHQ6IC13ZWJraXQtY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IC1tb3otY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IGNhbGMoMTAwJSAtIDEyMHB4KTsKICAKICAKICBib3gtc2hhZG93OiAwcHggNXB4IDVweCAjMjIyOwogIAp9CgojdWlTZXR0aW5nIHsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luLXJpZ2h0OiAyNXB4Owp9CgojYm94IGlucHV0W3R5cGU9dGV4dF0sICNib3ggaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiAtbW96LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiBjYWxjKDEwMCUgLSAyMHB4KTsKfQoKI2JveCBpbnB1dFt0eXBlPXN1Ym1pdF17CiAgbWFyZ2luOiA1MHB4IGF1dG87Cn0KCiNzZXR0aW5ncyB7CiAgZGlzcGxheTogYmxvY2s7CiAgcGFkZGluZzogMTBweCAxMHB4Owp9Cgojc2V0dGluZ3MgaDUgewogIG1hcmdpbjogNTBweCAwcHggMTBweCAwcHg7Cn0KCiNjb250ZW50LWludGVyYWN0aW9uIC5zZWFyY2ggewogIHdpZHRoOiAyMDBweDsKICBib3JkZXI6IDFweCBzb2xpZCAjMDAwOwogIHBhZGRpbmc6IDlweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzMzOwogIG1hcmdpbjogMTBweDsKICBmbG9hdDogcmlnaHQ7CiAgYm9yZGVyLXJhZGl1czogM3B4OwoKfQoKI215U3RyZWFtcyB7CiAgcG9zaXRpb246IGZpeGVkOwogIGJvdHRvbTogMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMxMTE7CiAgd2lkdGg6IDEwMCU7CiAgbWF4LXdpZHRoOiA5NTBweDsKCiAgLyoKICBtYXgtaGVpZ2h0OiAxMDBweDsKICAqLwogIG1hcmdpbi1ib3R0b206IDBweDsKfQoKI215U3RyZWFtcyBpbWcgewogIHdpZHRoOiA0JTsKICBwYWRkaW5nOiAycHggNXB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBmbG9hdDogcmlnaHQ7Cn0KCiNzZXR0aW5ncy1mb290ZXIgewoKfQoKCi8qIFdpemFyZCovCiNib3ggewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7CiAgbWluLWhlaWdodDogNDAwcHg7CiAgCiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsKfQoKI2JveCBwewogIHBhZGRpbmc6IDEwcHggMHB4Owp9CgojYm94LWZvb3RlciB7CiAgbWFyZ2luLXRvcDogYXV0bzsKfQoKI2JveC1mb290ZXIgewogIG1hcmdpbjogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgojaGVhZGxpbmUgewogIGJhY2tncm91bmQtY29sb3I6ICMyMjI7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMnB4ICMyMjI7CiAgdHJhbnNpdGlvbjogYWxsIDAuNXM7CiAgcGFkZGluZzogMTBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7Cn0KCiNjb250ZW50IHsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdzogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgovKiAtLS0gKi8KCgojY2xpZW50SW5mbywgI2FjdGl2ZVN0cmVhbXMsICNpbmFjdGl2ZVN0cmVhbXMgewogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgZGlzcGxheTogYmxvY2s7CiAgZm9udC1zaXplOiA5cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBjb2xvcjogIzAwRTZGRjsKICBib3JkZXItYm90dG9tOiBzb2xpZCAwcHg7OwogIHBhZGRpbmc6IDBweDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIG92ZXJmbG93LXg6IGhpZGRlbjsKICBib3JkZXItc3BhY2luZzogNHB4IDRweDsKICBib3JkZXItYm90dG9tOiBzb2xpZCAxcHggIzQ0NDsKfQoKI215U3RyZWFtc0JveCB7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHBhZGRpbmc6IDBweDsKICAvKmhlaWdodDogMTAwcHg7Ki8KICBtYXgtaGVpZ2h0OiAxNTBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwogIGNvbG9yOiB3aGl0ZTsKICBkaXNwbGF5OmZsZXg7CiAganVzdGlmeS1jb250ZW50OmNlbnRlcjsKICBhbGlnbi1pdGVtczpjZW50ZXI7Cn0KCiNvcGVuU3RyZWFtcyB7CiAgd2lkdGg6IDIwcHg7CiAgaGVpZ2h0OiAyMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBmbG9hdDogcmlnaHQ7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHJpZ2h0OiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvdG91Y2gucG5nIik7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICAKICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gcmlnaHQ7ICAKfQoKI2FsbFN0cmVhbXMgewogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwJTsKICBwYWRkaW5nOiAycHg7ICAgICAKfQoKI2FjdGl2ZVN0cmVhbXMsICNpbmFjdGl2ZVN0cmVhbXMgewogIG92ZXJmbG93LXk6IHNjcm9sbDsKICB3aWR0aDogNTAlOwogIG1heC1oZWlnaHQ6IDEwMHB4OwogIGZsb2F0OiBsZWZ0Owp9CgojYWN0aXZlU3RyZWFtcyAudGRLZXksICNpbmFjdGl2ZVN0cmVhbXMgLnRkS2V5IHsKICB3aWR0aDogNzVweDsKfQoKCgoKI2luYWN0aXZlU3RyZWFtcyAudGRLZXkgewogIGNvbG9yOiByZWQ7Cn0KCiNjbGllbnRJbmZvIC50ZFZhbCwgI2xvZ0luZm8gLnRkVmFsLCAjYWN0aXZlU3RyZWFtcyAudGRWYWwsICNpbmFjdGl2ZVN0cmVhbXMgLnRkVmFsLCAjbWFwcGluZ0luZm8gLnRkVmFsewogIGNvbG9yOiAjYWFhOwogIHdoaXRlLXNwYWNlOiBpbmhlcml0Owp9CgojYm94LXdyYXBwZXIgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICB3aWR0aDogMTAwJTsKICAKICBvdmVyZmxvdy15OiBzY3JvbGw7Cn0KCiNjb250ZW50X3RhYmxlLCAjbWFwcGluZy1kZXRhaWwtdGFibGUsICNjb250ZW50X3RhYmxlIHsKICBkaXNwbGF5OiB0YWJsZTsKICAKICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOwogIG92ZXJmbG93LXk6IHNjcm9sbDsKICB3aWR0aDogMTAwJTsKfQoKCiNjb250ZW50X3RhYmxlIC5jb250ZW50X3RhYmxlX2hlYWRlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBoZWlnaHQ6IDUwcHg7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMXB4ICMxMTE7CiAgYm9yZGVyLWxlZnQ6IHNvbGlkIDNweCAjMzMzOwogIGN1cnNvcjogYXV0bzsKCn0KCgp0Ym9keSB7CiAgd2lkdGg6IDEwMCU7Cn0KCgoudGFibGVFbGxpcHNpcyB7CiAgd2lkdGg6IDE1MHB4OwogIG92ZXJmbG93OiBoaWRkZW47CiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQoKI2NvbnRlbnRfdGFibGUgaW1nIHsKICBkaXNwbGF5OiBibG9jazsKICBtYXgtaGVpZ2h0OiAyOHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKICBtYXgtd2lkdGg6IDMwcHg7Cn0KCiNjb250ZW50X3RhYmxlIHRyewogIGJvcmRlci1sZWZ0OiBzb2xpZCAzcHggNDQ0OwogIGJvcmRlci1ib3R0b206IHNvbGlkIDFweCAjMzMzOwogIGN1cnNvcjogcG9pbnRlcjsKfQoKI2NvbnRlbnRfdGFibGUgdHI6aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMzMzM7Cn0KCiNjb250ZW50X3RhYmxlIHRkIHsKCiAgcGFkZGluZzogMHB4IDJweDsKfQoKI2NvbnRlbnRfdGFibGUgaW5wdXRbdHlwZT10ZXh0XXsKICB3aWR0aDogODAlOwogIG1pbi13aWR0aDogMzVweDsKICBtYXgtd2lkdGg6IDYwcHg7CiAgYm9yZGVyOiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBtYXJnaW4tbGVmdDogNXB4OwogIHRleHQtYWxpZ246IGxlZnQ7Cn0KCiNjb250ZW50X3RhYmxlIGlucHV0W3R5cGU9Y2hlY2tib3hdewogIG1heC13aWR0aDogMjVweDsKICBtYXJnaW46IGF1dG87Cn0KCgouc2hvd0J1bGsgewogIGRpc3BsYXk6IGJsb2NrOwp9CgouaGlkZUJ1bGsgewogIGRpc3BsYXk6IG5vbmU7Cn0KCi5ub0J1bGsgewoKfQoKI2NvbnRlbnRfdGFibGUgdHIuYWN0aXZlRVBHewogIGJvcmRlci1sZWZ0OiBzb2xpZCAzcHggbGF3bmdyZWVuOwp9CgojY29udGVudF90YWJsZSB0ci5ub3RBY3RpdmVFUEd7CiAgYm9yZGVyLWxlZnQ6IHNvbGlkIDNweCByZWQ7Cn0KCgojbG9nU2NyZWVuIHB7CiAgd2hpdGUtc3BhY2U6IHByZTsKICBmb250LXNpemU6IDEwcHg7CiAgLyoKICBsaW5lLWhlaWdodDogMS42ZW07CiAgZm9udC1mYW1pbHk6ICJBcmlhbCIsIHNhbnMtc2VyaWY7CiAgKi8KICBsZXR0ZXItc3BhY2luZzogMXB4OwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7IAogIGZvbnQtc2l6ZTogMTJweDsgCiAgZm9udC1zdHlsZTogbm9ybWFsOyAKICBmb250LXZhcmlhbnQ6IG5vcm1hbDsgCiAgbGluZS1oZWlnaHQ6IDEuNmVtOyAKfQoKI3BvcHVwIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNCk7CiAgcG9zaXRpb246IGZpeGVkOwogIGxlZnQ6IDBweDsKICB3aWR0aDogMTAwJTsKICB6LWluZGV4OiAxMDA7CiAgaGVpZ2h0OiAxMDAlOwp9CgojbWFwcGluZy1kZXRhaWwsICN1c2VyLWRldGFpbCwgI2ZpbGUtZGV0YWlsLCAjcG9wdXAtY3VzdG9tIHsKICBib3gtc2hhZG93OiAwcHggNXB4IDQwcHggIzAwMDsKICBtYXJnaW4tdG9wOiAyMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKICAKICBtYXgtd2lkdGg6IDYwMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMyMjI7CiAgcGFkZGluZzogMTBweDsKICBvdmVyZmxvdzphdXRvOwp9CgojcG9wdXAtY3VzdG9tIGgzIHsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCiNmaWxlLWRldGFpbCBpbnB1dFt0eXBlPXRleHRdIHsKICB3aWR0aDogLXdlYmtpdC1jYWxjKDEwMCUgLSAyMHB4KTsKICB3aWR0aDogLW1vei1jYWxjKDEwMCUgLSAyMHB4KTsKICB3aWR0aDogY2FsYygxMDAlIC0gMjBweCk7Cn0KCiNtYXBwaW5nLWRldGFpbCBpbWcgewogIGRpc3BsYXk6IGJsb2NrOwogIG1heC1oZWlnaHQ6IDMwcHg7CiAgbWFyZ2luLWJvdHRvbTogMjBweDsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87Cn0KCiNwb3B1cC1jdXN0b20gaW5wdXRbdHlwZT10ZXh0XSwgI3BvcHVwLWN1c3RvbSBpbnB1dFt0eXBlPXBhc3N3b3JkXSwgI21hcHBpbmctZGV0YWlsIGlucHV0W3R5cGU9dGV4dF0sICNjb250ZW50X3NldHRpbmdzIGlucHV0W3R5cGU9dGV4dF0sICNjb250ZW50X3NldHRpbmdzIGlucHV0W3R5cGU9cGFzc3dvcmRdewogIGJvcmRlcjogc29saWQgMXB4OwogIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICB0ZXh0LWFsaWduOiBsZWZ0OwogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiAgICAtbW96LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiAgICAgICAgIGNhbGMoMTAwJSAtIDIwcHgpOwp9CgojcG9wdXAtY3VzdG9tIGlucHV0W3R5cGU9dGV4dF0ubm90QXZhaWxhYmxlIHsKICBib3JkZXItY29sb3I6IHJlZDsKICBjb2xvcjogIzY2NjsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9CgojbWFwcGluZy1kZXRhaWwtdGFibGUsICN1c2VyLWRldGFpbC10YWJsZSB7CiAgZGlzcGxheTogaW5saW5lLXRhYmxlOwogIHdpZHRoOiAxMDAlOwp9CgojcG9wdXAtY3VzdG9tIHRhYmxlLCAjY29udGVudF9zZXR0aW5ncyB0YWJsZSB7CiAgZGlzcGxheTogaW5saW5lLXRhYmxlOwogIHRhYmxlLWxheW91dDogZml4ZWQ7CiAgd2lkdGg6IDEwMCU7Cn0KCgojbWFwcGluZy1kZXRhaWwtdGFibGUgdGQsICN1c2VyLWRldGFpbC10YWJsZSB0ZCB7CiAgcGFkZGluZzogMTBweCAwcHg7Cgp9CgojbWFwcGluZy1kZXRhaWwtdGFibGUgdGQubGVmdCwgI3VzZXItZGV0YWlsLXRhYmxlIHRkLmxlZnQsICNwb3B1cC1jdXN0b20gdGQubGVmdCB7CiAgd2lkdGg6IDM4JTsKfQoKLmludGVyYWN0aW9uLCAjaW50ZXJhY3Rpb24gewogIG1hcmdpbi10b3A6IDIwcHg7CiAgZGlzcGxheTogaW5saW5lLWZsZXg7CiAgZmxvYXQ6IHJpZ2h0Owp9CgouaW50ZXJhY3Rpb24gaW5wdXRbdHlwZT1idXR0b25dLCAuaW50ZXJhY3Rpb24gaW5wdXRbdHlwZT1zdWJtaXRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIG1pbi13aWR0aDogMTAwcHg7CiAgbWFyZ2luOiAwcHggMTBweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCiNub3RpZmljYXRpb24gewogIGRpc3BsYXk6IGJsb2NrOwogIHBvc2l0aW9uOiBmaXhlZDsKICByaWdodDogMHB4OwogIGhlaWdodDogMTAwJTsKICB3aWR0aDogMjUwcHg7CiAgCiAgYmFja2dyb3VuZC1jb2xvcjogIzIyMjsKICBib3gtc2hhZG93OiAwcHggMHB4IDIwcHggIzAwMDsKfQoKI25vdGlmaWNhdGlvbiBoNSB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMTIxMjsKICBwYWRkaW5nOiA1cHggMTBweCA1cHggMTBweDsKfQoKI25vdGlmaWNhdGlvbiBwcmUgewogIHBhZGRpbmc6IDBweCAxMHB4IDBweCAxMHB4Owp9Cgojbm90aWZpY2F0aW9uIHAgewogIGZvbnQtc2l6ZTogMTAgcHg7CiAgbWFyZ2luOiAwcHg7CiAgcGFkZGluZzogMHB4IDEwcHggNXB4IDEwcHg7Cn0KCiNub3RpZmljYXRpb24gLmVsZW1lbnQgewogIC8qcGFkZGluZzogMHB4IDVweDsqLwogIG1hcmdpbjogNXB4IDVweDsKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzE4MTgxODsKICBib3JkZXItbGVmdDogMTBweCBzb2xpZCBncmVlbjsKfQoKCkBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjIwcHgpewogIGJvZHkgewogICAgd2lkdGg6IDEwMCU7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwogIH0KCiAgaDEgewogICAgZm9udC1zaXplOiAyNnB4OwogICAgbGV0dGVyLXNwYWNpbmc6IDNweDsKICB9CgogIG5hdiBwIHsKICAgIGRpc3BsYXk6IGJsb2NrOwogIH0KCgoKICAjaGVhZGVyX2NvbmZpZyB7CiAgICBkaXNwbGF5OiBibG9jazsKICAgIGhlaWdodDogMTAwcHg7CiAgICBiYWNrZ3JvdW5kOiB1cmwoIi4uL2ltZy9sb2dvX3dfNjAweDIwMC5wbmciKTsKICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CiAgICAKICAgIGJhY2tncm91bmQtc2l6ZTogMzAwcHggMTAwcHg7CiAgfQoKICAjc2NyZWVuTG9nIHsKICAgIG1hcmdpbi1sZWZ0OiAzMDBweDsKCiAgICB0cmFuc2l0aW9uOiBub25lOwogICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7CiAgICBib3JkZXItYm90dG9tOiBzb2xpZCAxcHggdHJhbnNwYXJlbnQ7CiAgICBib3gtc2hhZG93OiAwcHggMHB4IDBweCAjMjIyOwogIH0KCiAgI3NldHRpbmdzIHsKICAgIC8qCiAgICBoZWlnaHQ6IC13ZWJraXQtY2FsYygxMDAlIC0gMTAwcHgpOwogICAgaGVpZ2h0OiAtbW96LWNhbGMoMTAwJSAtIDEwMHB4KTsKICAgIGhlaWdodDogY2FsYygxMDAlIC0gMTAwcHgpOwogICAgKi8KICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgIG92ZXJmbG93OiBhdXRvOwogIH0KCgogIC5zY3JlZW5Mb2dIaWRkZW4gewogICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMHB4LCAwcHgpOwogIH0KCgogICNib3ggewogICAgZGlzcGxheTogYmxvY2s7CiAgICBtaW4taGVpZ2h0OiA1MDBweDsKICAgIG1heC13aWR0aDogNTAwcHg7CiAgICBtYXJnaW46IDEwcHggYXV0bzsKICAgIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7CiAgICBib3gtc2hhZG93OiAwcHggNXB4IDVweCAjMjIyOwoKICAgIGRpc3BsYXk6IGZsZXg7CiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIH0KCiAgI3NldHRpbmdzLCAjc2V0dGluZ3MtZm9vdGVyIHsKICAgIAogIH0KfQo="
- webUI["html/js/authentication.js"] = "ZnVuY3Rpb24gY3JlYXRlRmlyc3RBY2NvdW50KGVsbSkgewogIHZhciBlcnIgPSBmYWxzZTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtKTsKICBjb25zb2xlLmxvZyhkaXYpOwoKICB2YXIgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdXRoZW50aWNhdGlvbicpOwogIAogIGNvbnN0IHVzZXJuYW1lICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1c2VybmFtZScpOwogIGNvbnN0IHBhc3N3b3JkICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzd29yZCcpOwogIGNvbnN0IGNvbmZpcm0gICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb25maXJtJyk7CgogIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ0lOUFVUJykKICBjb25zb2xlLmxvZyhjb25maXJtKTsKCiAgc3dpdGNoKGNvbmZpcm0pIHsKICAgIGNhc2UgbnVsbDogYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6IAogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChpbnB1dHNbaV0udmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgIGlucHV0c1tpXS5zdHlsZS5ib3JkZXJDb2xvciA9ICdyZWQnOwogICAgICAgICAgZXJyID0gdHJ1ZQogICAgICAgIH0KICAgICAgfQoKICAgICAgc3dpdGNoKGVycikgewogICAgICAgIGNhc2UgdHJ1ZTogcmV0dXJuOyBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOiAKICAgICAgICAgIGlmIChwYXNzd29yZC52YWx1ZSAhPSBjb25maXJtLnZhbHVlKSB7CiAgICAgICAgICAgIGNvbmZpcm0uc3R5bGUuYm9yZGVyQ29sb3IgPSAncmVkJzsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICB9CgoKICAKCiAgZm9ybS5zdWJtaXQoKTsKICByZXR1cm47Cn0="
- webUI["html/js/configuaration.js"] = "dmFyIGNvbmZpZ01lbnUgPSBuZXcgT2JqZWN0KCk7CnZhciB3aXphcmQgPSBuZXcgQXJyYXkoImtleSIsICJ0dW5lciIsICJlcGdTb3VyY2UiLCAibTN1IiwgImNvbXBsZXRlIik7CnZhciBhY3RpdmVXaXphcmQ7CnZhciBkdnJJUAoKdmFyIGNvbmZpZ01lbnVfdHVuZXIgPSBuZXcgT2JqZWN0KCk7CmNvbmZpZ01lbnVfdHVuZXJbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X3R1bmVyWyJfbWVudVR5cGUiXSAgICAgPSAic2luZ2xlSW5wdXQiOwpjb25maWdNZW51X3R1bmVyWyJfY29uZmlnS2V5Il0gICAgPSAidHVuZXIiOwpjb25maWdNZW51X3R1bmVyWyJfbGFiZWwiXSAgICAgICAgPSAiQXZhaWxhYmxlIHR1bmVycyI7CmNvbmZpZ01lbnVfdHVuZXJbIm5hbWUiXSAgICAgICAgICA9ICJ0dW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbImlkIl0gICAgICAgICAgICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbInBsYWNlaG9sZGVyIl0gICA9ICJUdW5lciI7CmNvbmZpZ01lbnVfdHVuZXJbIl91c2FnZSJdICAgICAgICA9ICJUaGlzIHNldHRpbmcgaXMgb25seSB1c2VkIGJ5IFBsZXggYW5kIEVtYnkuPGJyPlRoZSBudW1iZXIgb2YgY29uY3VycmVudCBzdHJlYW1zIGFsbG93ZWQgYnkgdGhlIElQVFYgcHJvdmlkZXIuIgoKCnZhciBvcHRpb25WYWx1ZXMgPSBuZXcgQXJyYXkoKTsKZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICBvcHRpb25WYWx1ZXMucHVzaChpKQp9CmNvbmZpZ01lbnVfdHVuZXJbIl9vcHRpb25WYWx1ZXMiXSA9IG9wdGlvblZhbHVlczsKCnZhciBjb25maWdNZW51X2VwZyA9IG5ldyBPYmplY3QoKTsKY29uZmlnTWVudV9lcGdbIl9lbGVtZW50Il0gICAgICA9ICJTRUxFQ1QiOwpjb25maWdNZW51X2VwZ1siX21lbnVUeXBlIl0gICAgID0gInNpbmdsZUlucHV0IjsKY29uZmlnTWVudV9lcGdbIl9jb25maWdLZXkiXSAgICA9ICJlcGdTb3VyY2UiOwpjb25maWdNZW51X2VwZ1siX2xhYmVsIl0gICAgICAgID0gIlNlbGVjdGlvbiBvZiB0aGUgRVBHIHNvdXJjZSI7CmNvbmZpZ01lbnVfZXBnWyJuYW1lIl0gICAgICAgICAgPSAiZXBnU291cmNlIjsKY29uZmlnTWVudV9lcGdbImlkIl0gICAgICAgICAgICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbInBsYWNlaG9sZGVyIl0gICA9ICJFUEcgc291cmNlIjsKY29uZmlnTWVudV9lcGdbIl9vcHRpb25WYWx1ZXMiXSA9IG5ldyBBcnJheSgiUE1TIiwgIlhFUEciKTsKY29uZmlnTWVudV9lcGdbIl91c2FnZSJdICAgICAgICA9ICJQTVM6ICAgVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5PGJyPlhFUEc6ICBVc2Ugb2YgZXh0ZXJuYWwgRVBHIGRhdGEgKFhNTFRWKTxicj4gICAgICAgU2V2ZXJhbCBYTUxUViBzb3VyY2VzIHBvc3NpYmxlPGJyPiAgICAgICBBbGxvd3MgZWRpdGluZyBhbmQgb3JkZXIgY2hhbm5lbHM8YnI+ICAgICAgIE0zVSAvIFhNTFRWIGV4cG9ydCAoSFRUUCBsaW5rIGZvciBJUFRWIGFwcHMpIgoKdmFyIGNvbmZpZ01lbnVfbTN1ID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X20zdVsiX2VsZW1lbnQiXSAgICAgICAgPSAiSU5QVVQiOwpjb25maWdNZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CmNvbmZpZ01lbnVfbTN1WyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9tM3VbIl9sYWJlbCJdICAgICAgICAgID0gIk0zVSBGaWxlOiBsb2NhbCBvciByZW1vdGUiOwpjb25maWdNZW51X20zdVsibmFtZSJdICAgICAgICAgICAgPSAiZmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJpZCJdICAgICAgICAgICAgICA9ICJtM3UiOwpjb25maWdNZW51X20zdVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfbTN1WyJwbGFjZWhvbGRlciJdICAgICA9ICJNM1UgRmlsZSI7CmNvbmZpZ01lbnVfbTN1WyJfdXNhZ2UiXSAgICAgICAgICA9ICJSZW1vdGUgcGxheWxpc3Q6IGh0dHA6Ly95b3VyLnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1IgoKCmNvbmZpZ01lbnVfbTN1WyJ2YWx1ZSJdICAgICAgICAgICA9ICJodHRwOi8vd2Vic3J2LmxvY2FsOjgwODAva2FiZWwubTN1IjsKCnZhciBjb25maWdNZW51X2NvbXBsZXRlID0gbmV3IE9iamVjdCgpOwpjb25maWdNZW51X2NvbXBsZXRlWyJfZWxlbWVudCJdICAgICAgICA9ICJIMiI7CmNvbmZpZ01lbnVfY29tcGxldGVbIl9tZW51VHlwZSJdICAgICAgID0gImlucHV0QXJyYXkiOwpjb25maWdNZW51X2NvbXBsZXRlWyJfY29uZmlnS2V5Il0gICAgICA9ICJmaWxlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsiX3RleHQiXSAgICAgICAgICAgPSAieFRlVmUgd2FzIHN1Y2Nlc3NmdWxseSBzZXQgdXAiOwpjb25maWdNZW51X2NvbXBsZXRlWyJuYW1lIl0gICAgICAgICAgICA9ICJjb21wbGV0ZSI7CmNvbmZpZ01lbnVfY29tcGxldGVbImlkIl0gICAgICAgICAgICAgID0gImNvbXBsZXRlIjsKY29uZmlnTWVudV9jb21wbGV0ZVsidHlwZSJdICAgICAgICAgICAgPSAidGV4dCI7CmNvbmZpZ01lbnVfY29tcGxldGVbImNsYXNzIl0gICAgICAgICAgID0gImNlbnRlciI7Cgpjb25maWdNZW51WyJ0dW5lciJdICAgICA9IGNvbmZpZ01lbnVfdHVuZXI7CmNvbmZpZ01lbnVbImVwZ1NvdXJjZSJdID0gY29uZmlnTWVudV9lcGc7CmNvbmZpZ01lbnVbIm0zdSJdICAgICAgID0gY29uZmlnTWVudV9tM3U7CmNvbmZpZ01lbnVbImNvbXBsZXRlIl0gID0gY29uZmlnTWVudV9jb21wbGV0ZTsKCmZ1bmN0aW9uIHJlYWR5Rm9yQ29uZmlndXJhdGlvbigpIHsKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICBkYXRhWyJjbWQiXSA9ICJnZXRTZXJ2ZXJDb25maWciOwogIHhUZVZlKGRhdGEpOwogIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsKfQoKZnVuY3Rpb24gY3JlYXRlQ29uZmlndXJhdGlvbihlbG0pIHsKCiAgYWN0aXZlV2l6YXJkID0gZWxtOwogIHZhciBpdGVtICA9IGNvbmZpZ01lbnVbZWxtXTsKCiAgdmFyIGRpdiAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKTsKICBkaXYuaW5uZXJIVE1MID0gIiI7CiAgZGl2LnNldEF0dHJpYnV0ZSgiZGF0YS1jb25maWdLZXkiLCBpdGVtWyJfY29uZmlnS2V5Il0pOwogIGRpdi5zZXRBdHRyaWJ1dGUoImRhdGEtbWVudVR5cGUiLCBpdGVtWyJfbWVudVR5cGUiXSk7CiAgCiAgc3dpdGNoKGl0ZW0uaGFzT3duUHJvcGVydHkoIl9sYWJlbCIpKSB7CiAgICBjYXNlIHRydWU6CiAgICAgIHZhciBuZXdJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdJdGVtWyJfZWxlbWVudCJdID0gIkxBQkVMIjsKICAgICAgbmV3SXRlbVsiX3RleHQiXSAgICA9IGl0ZW1bIl9sYWJlbCJdOyAKICAgICAgbmV3SXRlbVsiZm9yIl0gICAgICA9IGl0ZW1bImlkIl07CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0l0ZW0pKTsKICAgICAgYnJlYWsKICB9CgogIHN3aXRjaChpdGVtWyJfZWxlbWVudCJdKSB7CiAgICBjYXNlICJTRUxFQ1QiOgogICAgICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChpdGVtKSk7CiAgICAgIHZhciBzZWxlY3RFbGVtZW50ID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJTRUxFQ1QiKVswXTsKICAgICAgdmFyIHZhbHVlcyA9IGl0ZW1bIl9vcHRpb25WYWx1ZXMiXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0OwogICAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJPUFRJT04iOwogICAgICAgIG5ld0VudHJ5WyJfdGV4dCJdICAgICA9IGl0ZW1bImlkIl0gKyAiOiAiICsgdmFsdWVzW2ldOwogICAgICAgIG5ld0VudHJ5WyJ2YWx1ZSJdICAgICA9IHZhbHVlc1tpXTsKICAgICAgICBzZWxlY3RFbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICAgICAgfQogICAgICAvL3JldHVybgogICAgICBicmVhazsKCiAgICBkZWZhdWx0OiAKICAgICAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoaXRlbSkpOwogICAgICBicmVhazsKCgogIH0KICAvL2FsZXJ0KCkKCiAgc3dpdGNoKGl0ZW0uaGFzT3duUHJvcGVydHkoIl91c2FnZSIpKSB7CiAgICBjYXNlIHRydWU6IAogICAgICB2YXIgdXNhZ2VJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICB1c2FnZUl0ZW1bIl9lbGVtZW50Il0gPSAiUFJFIgogICAgICB1c2FnZUl0ZW1bIl90ZXh0Il0gICAgPSBpdGVtWyJfdXNhZ2UiXTsKICAgICAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQodXNhZ2VJdGVtKSk7CiAgfQoKICBpZiAoYWN0aXZlV2l6YXJkID09ICJjb21wbGV0ZSIpIHsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJuZXh0IikudmFsdWUgPSAiRmluaXNoZWQiCiAgICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJuZXh0Iikuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgImphdmFzY3JpcHQ6IGxvY2F0aW9uLnJlbG9hZCgpOyIpCiAgfQoKICAvL2Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KGl0ZW0pKTsKfQoKZnVuY3Rpb24gc2F2ZURhdGEoKSB7CgogIHZhciBkaXYgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50Iik7CiAgdmFyIGlucHV0cyA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKTsKICB2YXIgc2VsZWN0cyA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiU0VMRUNUIik7CiAgdmFyIHZhbHVlOwogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIHZhciB2YWx1ZUFyciA9IG5ldyBBcnJheSgpOwogIHZhciBuZXdEYXRhID0gZmFsc2U7CgogIGlmIChhY3RpdmVXaXphcmQgPT0gImNvbXBsZXRlIikgewogICAgZGF0YVsiY21kIl0gPSAid2l6YXJkQ29tcGxldGVkIjsKICAgIHNob3dMb2FkaW5nU2NyZWVuKHRydWUpCiAgICB4VGVWZShkYXRhKTsKICAgIHJldHVybgogIH0KICAKICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykgewogICAgdmFyIG1lbnVUeXBlID0gaW5wdXRzW2ldLnBhcmVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCJkYXRhLW1lbnV0eXBlIik7CiAgICBpZiAoaW5wdXRzW2ldLnZhbHVlICE9IHVuZGVmaW5lZCAmJiBpbnB1dHNbaV0udmFsdWUgIT0gIiIgKSB7CiAgICAgIG5ld0RhdGEgPSB0cnVlOwoKICAgICAgY29uc29sZS5sb2coaW5wdXRzW2ldLmlkKQogICAgICBzd2l0Y2goaW5wdXRzW2ldLmlkKSB7CiAgICAgICAgY2FzZSAibTN1IjogCiAgICAgICAgICB2YXIgbmV3UGxheWxpc3QgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICBuZXdQbGF5bGlzdFsiZmlsZS5zb3VyY2UiXSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgIC8vbmV3UGxheWxpc3RbIm5hbWUiXSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgIG5ld1BsYXlsaXN0WyJ0eXBlIl0gPSAibTN1IjsKICAgICAgICAgIG5ld1BsYXlsaXN0WyJuZXciXSA9IHRydWU7CgogICAgICAgICAgZGF0YVsiZmlsZXMiXSA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgIGRhdGFbImZpbGVzIl1bIm0zdSJdID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgZGF0YVsiZmlsZXMiXVsibTN1Il1bIi0iXSA9IG5ld1BsYXlsaXN0OwogICAgICAgICAgCiAgICAgICAgICBkYXRhWyJjbWQiXSA9ICJzYXZlRmlsZXNNM1UiOwogICAgICAgICAgeFRlVmUoZGF0YSkKICAgICAgICAgIHJldHVybgogICAgICB9CiAgICAgIC8qCiAgICAgIHN3aXRjaChtZW51VHlwZSkgewogICAgICAgIGNhc2UgInNpbmdsZUlucHV0IjoKICAgICAgICAgIGRhdGFbaW5wdXRzW2ldLm5hbWVdID0gaW5wdXRzW2ldLnZhbHVlOyBicmVhazsKICAgICAgICBjYXNlICJpbnB1dEFycmF5IjogCiAgICAgICAgICB2YWx1ZUFyci5wdXNoKGlucHV0c1tpXS52YWx1ZSk7CiAgICAgICAgICBkYXRhW2lucHV0c1tpXS5uYW1lXSA9IHZhbHVlQXJyOyBicmVhawoKICAgICAgfQogICAgICAqLwogICAgfSBlbHNlIHsKICAgICAgaW5wdXRzW2ldLnN0eWxlLmJvcmRlckJvdHRvbUNvbG9yID0gInJlZCI7CiAgICAgIHJldHVybjsKICAgIH0KICB9CgoKICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdHMubGVuZ3RoOyBpKyspIHsKICAgIHZhciB2YWx1ZSA9IHNlbGVjdHNbaV0ub3B0aW9uc1tzZWxlY3RzW2ldLnNlbGVjdGVkSW5kZXhdLnZhbHVlOwogICAgaWYgKGlzTmFOKHZhbHVlKSA9PSBmYWxzZSkgewogICAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlKTsKICAgICAgZGF0YVtzZWxlY3RzW2ldLm5hbWVdID0gdmFsdWU7CiAgICAgIG5ld0RhdGEgPSB0cnVlOwogICAgICBicmVhazsKICAgIH0KICAgIGRhdGFbc2VsZWN0c1tpXS5uYW1lXSA9IHZhbHVlOwogICAgbmV3RGF0YSA9IHRydWU7CiAgfQoKCiAgLy9jb25zb2xlLmxvZyhkYXRhLCBuZXdEYXRhKTsKICBpZiAobmV3RGF0YSA9PSB0cnVlKSB7CiAgICBjb25maWcgPSBkYXRhCiAgICBkYXRhWyJjbWQiXSA9ICJzYXZlQ29uZmlnIjsKICAgIHhUZVZlKGRhdGEpOwogIH0KfQoKZnVuY3Rpb24geFRlVmUoZGF0YSkgewoKICBpZiAod2ViU29ja2V0cyA9PSBmYWxzZSkgewogICAgYWxlcnQoIllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IFdlYlNvY2tldHMiKTsKICAgIHJldHVybjsKICB9CgogIGlmIChhY3RpdmVXaXphcmQgPT0gIm0zdSIgfHwgYWN0aXZlV2l6YXJkID09ICJlcGdTb3VyY2UiKSB7CiAgICBzaG93TG9hZGluZ1NjcmVlbih0cnVlKTsKICB9CgogIHZhciBwcm90b2NvbFdTCiAgc3dpdGNoKHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCkgewogICAgY2FzZSAiaHR0cDoiOiAgIHByb3RvY29sV1MgPSAid3M6Ly8iOyBicmVhazsKICAgIGNhc2UgImh0dHBzOiI6ICBwcm90b2NvbFdTID0gIndzczovLyI7IGJyZWFrOwogIH0KCiAgdmFyIHdzID0gbmV3IFdlYlNvY2tldChwcm90b2NvbFdTICsgd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lICsgIjoiICsgd2luZG93LmxvY2F0aW9uLnBvcnQgKyAiL2RhdGEvIiArICI/VG9rZW49IiArIGdldENvb2tpZSgiVG9rZW4iKSk7CiAgCiAgd3Mub25vcGVuID0gZnVuY3Rpb24oKSB7CiAgICB3cy5zZW5kKEpTT04uc3RyaW5naWZ5KGRhdGEpKTsKICB9CgogIHdzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7CiAgICAKICAgIHZhciByZXNwb25zZSA9IEpTT04ucGFyc2UoZS5kYXRhKTsKICAgIAogICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJjbGllbnRJbmZvIikpIHsKICAgICAgY3JlYXRlQ2xpbnRJbmZvKHJlc3BvbnNlWyJjbGllbnRJbmZvIl0pOwogICAgfQoKICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgic3RhdHVzIikpIHsKICAgICAgaWYgKHJlc3BvbnNlWyJzdGF0dXMiXSA9PSBmYWxzZSkgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJoZWFkbGluZSIpLnN0eWxlLmJvcmRlckNvbG9yID0gInJlZCI7CiAgICAgICAgc2hvd0VycihyZXNwb25zZVsiZXJyIl0pOwogICAgICAgIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKQogICAgICAgIHJldHVybgogICAgICB9IGVsc2UgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJlcnIiKS5pbm5lckhUTUwgPSAiIjsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaGVhZGxpbmUiKS5zdHlsZS5ib3JkZXJDb2xvciA9ICJsYXduZ3JlZW4iOwogICAgICB9CgogICAgICBkdnJJUCA9IHJlc3BvbnNlWyJEVlIiXQogICAgICBzd2l0Y2gocmVzcG9uc2VbImNvbmZpZ3VyYXRpb25XaXphcmQiXSkgewogICAgICAgIGNhc2UgdHJ1ZTogCiAgICAgICAgICBpZiAoYWN0aXZlV2l6YXJkID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBhY3RpdmVXaXphcmQgPSB3aXphcmRbMF0KICAgICAgICAgIH0KICAgICAgICAgIHZhciBuID0gd2l6YXJkLmluZGV4T2YoYWN0aXZlV2l6YXJkKTsKICAgICAgICAgIG4rKzsKICAgICAgICAgIGFjdGl2ZVdpemFyZCA9IHdpemFyZFtuXQoKICAgICAgICAgIGlmIChhY3RpdmVXaXphcmQgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIGRhdGFbImNtZCJdID0gIndpemFyZENvbXBsZXRlZCI7CiAgICAgICAgICAgIHhUZVZlKGRhdGEpCiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL2NvbnNvbGUubG9nKGFjdGl2ZVdpemFyZCk7CiAgICAgICAgICAgIGNyZWF0ZUNvbmZpZ3VyYXRpb24oYWN0aXZlV2l6YXJkKTsgCiAgICAgICAgICB9CiAgICAgICAgICAKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgc3dpdGNoKHJlc3BvbnNlWyJyZWxvYWQiXSkgewogICAgICAgIAogICAgICAgIAogICAgICAgIGNhc2UgdHJ1ZTogCiAgICAKICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXsgCiAgICAgICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpOwogICAgICAgICAgfSwgMTAwKTsKICAgICAgICAgIAogICAgICAgICAgLy9sb2NhdGlvbi5yZWxvYWQoKTsKICAgICAgICAgIAogICAgICAgICAgYnJlYWs7CiAgICAgICAgCiAgICAgIH0KCiAgICAgIAogICAgfQoKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXsgc2hvd0xvYWRpbmdTY3JlZW4oZmFsc2UpOyB9LCAzMDApOwogIH0KICAKfQoKZnVuY3Rpb24gc2hvd0VycihlbG0pIHsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZXJyIikuaW5uZXJIVE1MID0gZWxtOwp9"
- webUI["html/js/files.js"] = "ZnVuY3Rpb24gb3BlbkZpbGVzKGVsbSwgZmlsZVR5cGUpIHsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpLmlubmVySFRNTCA9ICJUZXN0IjsKICAKICBjb2x1bW5Ub1NvcnQgPSAwOyAKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gJ2ZpbGVEZXRhaWwoIi0iLCAiJyArIGZpbGVUeXBlICsgJyIpJzsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSA9ICJVcGRhdGUiOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gPSAiZmlsZURldGFpbCgwKSI7CiAgLy9uZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CgogICAvLyBCdWlsZCB0YWJsZQogIHZhciBuZXdUYWJsZSA9IG5ldyBPYmplY3QoKTsKICBuZXdUYWJsZVsiX2VsZW1lbnQiXSAgPSAiVEFCTEUiOwogIG5ld1RhYmxlWyJpZCJdICAgICAgICA9ICJpZF9tYXBwaW5nIjsKICBuZXdUYWJsZVsiY2xhc3MiXSAgICAgPSAidGFibGUtbWFwcGluZyI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VGFibGUpKTsKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIGNyZWF0ZUZpbGVzVGFibGUoZmlsZVR5cGUpOyAKICB9LCAxMCk7Cgp9CgpmdW5jdGlvbiBjcmVhdGVGaWxlc1RhYmxlKGZpbGVUeXBlKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB2YXIgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCk7CiAgCiAgdGFibGUuaW5uZXJIVE1MID0gIiI7CiAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogIG5ld1RSWyJfZWxlbWVudCJdID0gIlRSIjsKICBuZXdUUlsiY2xhc3MiXSAgICA9ICJ0YWJsZS1tYXBwaW5nLWhlYWRlciI7CiAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICB2YXIgdHIgPSB0YWJsZS5sYXN0Q2hpbGQ7CgogIHN3aXRjaChmaWxlVHlwZSkgewogICAgY2FzZSAieG1sdHYiOiAKICAgICAgYXZhaWxhYmxlRmlsZVR5cGVzID0gbmV3IEFycmF5KCJ4bWx0diIpOyAKICAgICAgdmFyIHRySGVhZGxpbmVzID0gbmV3IEFycmF5KCJHdWlkZSIsICJMYXN0IFVwZGF0ZSIsICJBdmFpbGFiaWxpdHkgJSIsICJDaGFubmVscyIsICJQcm9ncmFtcyIpCiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgieG1sdHYuY2hhbm5lbHMiLCAieG1sdHYucHJvZ3JhbXMiKQogICAgICBicmVhazsKCiAgICBjYXNlICJtM3UiOgogICAgICBhdmFpbGFibGVGaWxlVHlwZXMgPSBuZXcgQXJyYXkoIm0zdSIsICJoZGhyIik7IAogICAgICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlBsYXlsaXN0IiwgIkxhc3QgVXBkYXRlIiwgIkF2YWlsYWJpbGl0eSAlIiwgIlR5cGUiLCAiU3RyZWFtcyIsICJncm91cC10aXRsZSAlIiwgInR2Zy1pZCAlIiwgIlVuaXF1ZSBJRCAlIik7CiAgICAgIHZhciBjb21wYXRpYmlsaXR5S2V5cyA9IG5ldyBBcnJheSgic3RyZWFtcyIsICJncm91cC50aXRsZSIsICJ0dmcuaWQiLCAic3RyZWFtLmlkIik7CiAgICAgIGJyZWFrOwogIH0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ckhlYWRsaW5lcy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiVEQiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB0ckhlYWRsaW5lc1tpXTsKICAgIHRyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VEQpKTsKICB9CiAgCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdmFpbGFibGVGaWxlVHlwZXMubGVuZ3RoOyBpKyspIHsKICAgIAogICAgdmFyIGZpbGVUeXBlID0gYXZhaWxhYmxlRmlsZVR5cGVzW2ldCgogICAgdmFyIGRhdGEgPSBjb25maWdbImZpbGVzIl1bZmlsZVR5cGVdOwogICAgCiAgICB2YXIgYWxsRmlsZXMgPSBnZXRPYmpLZXlzKGRhdGEpCiAgCiAgICBmb3IgKHZhciBmID0gMDsgZiA8IGFsbEZpbGVzLmxlbmd0aDsgZisrKSB7CiAgICAgIHZhciBlbG0gICAgICAgICAgID0gZGF0YVthbGxGaWxlc1tmXV07CiAgICAgIHZhciB0YWJsZSAgICAgICAgID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICAgICAgdmFyIGZpbGVJRCAgICAgICAgPSBlbG1bImlkLnByb3ZpZGVyIl07CiAgICAgIHZhciBuYW1lICAgICAgICAgID0gZWxtWyJuYW1lIl07CiAgICAgIHZhciBsYXN0VXBkYXRlICAgID0gZWxtWyJsYXN0LnVwZGF0ZSJdOwogICAgICB2YXIgYXZhaWxhYmlsaXR5ICA9IGVsbVsicHJvdmlkZXIuYXZhaWxhYmlsaXR5Il07CiAgICAgIHZhciB0eXBlICAgICAgICAgID0gZWxtWyJ0eXBlIl0udG9VcHBlckNhc2UoKTsKICAgICAgdmFyIGNvbXBhdGliaWxpdHkgPSBlbG1bImNvbXBhdGliaWxpdHkiXTsKCiAgICAgIC8vIENyZWF0ZSBUUgogICAgICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld1RSWyJfZWxlbWVudCJdICAgICAgID0gIlRSIjsKICAgICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgICAgbmV3VFJbImlkIl0gICAgICAgICAgICAgPSBmaWxlSUQ7CiAgICAgIG5ld1RSWyJvbmNsaWNrIl0gICAgICAgID0gJ2phdmFzY3JpcHQ6IGZpbGVEZXRhaWwoIicgKyBmaWxlSUQgKyAnIiwiJyArIGZpbGVUeXBlICsgJyIpOyc7CiAgICAgIHRhYmxlLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VFIpKTsKCiAgICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIC8vIENyZWF0ZSBmaWxlIG5hbWUgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBuYW1lOwogICAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgICAgLy8gQ3JlYXRlIGxhc3QgdXBkYXRlIFRECiAgICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICAgIG5ld1REWyJfdGV4dCJdICAgID0gbGFzdFVwZGF0ZTsKICAgICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAgIC8vIENyZWF0ZSBhdmFpbGFiaWxpdHkgVEQKICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBhdmFpbGFiaWxpdHk7CiAgICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgICBpZiAoZmlsZVR5cGUgPT0gIm0zdSIgfHwgZmlsZVR5cGUgPT0gImhkaHIiKSB7CgogICAgICAgIC8vIENyZWF0ZSBUeXBlIFRECiAgICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgICAgIG5ld1REWyJfdGV4dCJdICAgID0gdHlwZTsKICAgICAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwogIAogICAgICB9CiAgICAgIAogICAgICAvLyBDcmVhdGUgYWxsIGNvbXBhdGliaWxpdHkgVERzCgogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNvbXBhdGliaWxpdHlLZXlzLmxlbmd0aDsgaisrKSB7CiAgICAgICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgICAgIG5ld1REWyJfdGV4dCJdICAgID0gY29tcGF0aWJpbGl0eVtjb21wYXRpYmlsaXR5S2V5c1tqXV07CiAgICAgICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKICAgICAgfQoKICAgIH0KCiAgfQogIAogIAogIHNvcnRUYWJsZSgwKQoKICAvLyB1c2FnZSBJbmZvICAKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgc3dpdGNoKG1lbnVbYWN0aXZlTWVudS5pZF0uaGFzT3duUHJvcGVydHkoIl91c2FnZSIpKSB7CiAgICBjYXNlIHRydWU6IAogICAgICB2YXIgdXNhZ2VJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICB1c2FnZUl0ZW1bIl9lbGVtZW50Il0gPSAiUFJFIgogICAgICB1c2FnZUl0ZW1bIl90ZXh0Il0gICAgPSBtZW51W2FjdGl2ZU1lbnUuaWRdWyJfdXNhZ2UiXTsKCiAgICAgIHZhciBuZXdIUiA9IG5ldyBPYmplY3QoKTsKICAgICAgbmV3SFJbIl9lbGVtZW50Il0gPSAiSFIiCiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0hSKSk7CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KHVzYWdlSXRlbSkpOwogICAgICBicmVhazsKICB9CgogIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICByZXR1cm47Cn0KCgpmdW5jdGlvbiBmaWxlRGV0YWlsKGZpbGVJRCwgZmlsZVR5cGUpIHsKCiAgb3B0aW9uc1RleHQgID0gbmV3IEFycmF5KCJNM1UiLCAiSERIb21lUnVuIC0gW0V4cGVyaW1lbnRhbF0iKQogIG9wdGlvbnNWYWx1ZSA9IG5ldyBBcnJheSgibTN1IiwgImhkaHIiKQoKICBzd2l0Y2ggKGZpbGVUeXBlKSB7CiAgICAKICAgIGNhc2UgIm0zdSI6IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibmFtZSIpLnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAiUGxheWxpc3QgbmFtZSIpOyAKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImRlc2NyaXB0aW9uIikuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJEZXNjcmlwdGlvbiBvZiB0aGlzIHBsYXlsaXN0Iik7IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZmlsZS1kZXRhaWwtaGVhZGxpbmUiKS5pbm5lckhUTUwgPSAiTTNVIFBsYXlsaXN0IjsgCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmaWxlLXBhdGgiKS5pbm5lckhUTUwgPSAiTTNVIEZpbGU6IjsgCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmaWxlLnNvdXJjZSIpLnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAiTG9jYWwgb3IgcmVtb3RlIik7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgImhkaHIiOiAKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm5hbWUiKS5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgIkhESG9tZVJ1biBuYW1lIik7IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZGVzY3JpcHRpb24iKS5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgIkRlc2NyaXB0aW9uIG9mIHRoaXMgSERIb21lUnVuIHR1bmVyIik7IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZmlsZS1kZXRhaWwtaGVhZGxpbmUiKS5pbm5lckhUTUwgPSAiSERIb21lUnVuIjsgCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmaWxlLXBhdGgiKS5pbm5lckhUTUwgPSAiSERIb21lUnVuIElQOiI7IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZmlsZS5zb3VyY2UiKS5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgIklQIGFkZHJlc3MgYW5kIHBvcnQgb2YgdGhlIHR1bmVyICgxOTIuMTY4LjEuMTA6NTAwNCkiKTsKICAgICAgYnJlYWs7CiAgICAKICAgIGNhc2UgInhtbHR2IjogCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJuYW1lIikuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJYTUxUViBuYW1lIik7IAogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZGVzY3JpcHRpb24iKS5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgIkRlc2NyaXB0aW9uIG9mIHRoaXMgWE1MVFYgZmlsZSIpOyAKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZpbGUtZGV0YWlsLWhlYWRsaW5lIikuaW5uZXJIVE1MID0gIlhNTFRWIEZpbGUiOyAKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZpbGUtcGF0aCIpLmlubmVySFRNTCA9ICJYTUxUViBGaWxlOiI7CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmaWxlLnNvdXJjZSIpLnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAiTG9jYWwgb3IgcmVtb3RlIik7CgogICAgICBvcHRpb25zVGV4dCAgPSBuZXcgQXJyYXkoIlhNTFRWIikKICAgICAgb3B0aW9uc1ZhbHVlID0gbmV3IEFycmF5KCJ4bWx0diIpCiAgICAgIGJyZWFrOwogIH0KCiAgbW9kaWZ5T3B0aW9uKCJ0eXBlIiwgb3B0aW9uc1RleHQsIG9wdGlvbnNWYWx1ZSkKICAKICBzaG93UG9wVXBFbGVtZW50KCdmaWxlLWRldGFpbCcpOwoKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2F2ZUZpbGVEZXRhaWwiKS5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2F2ZUZpbGVEZXRhaWwoIicgKyBmaWxlSUQgKyAnIiwiJyArIGZpbGVUeXBlICsgJyIsIGZhbHNlKScpOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1cGRhdGVGaWxlRGV0YWlsIikuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHVwZGF0ZUZpbGUoIicgKyBmaWxlSUQgKyAnIiwiJyArIGZpbGVUeXBlICsgJyIsIGZhbHNlKScpOwogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWxldGVGaWxlRGV0YWlsIikuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNhdmVGaWxlRGV0YWlsKCInICsgZmlsZUlEICsgJyIsIicgKyBmaWxlVHlwZSArICciLCB0cnVlKScpOwoKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKCiAgc3dpdGNoKGZpbGVJRCkgewoKICAgIGNhc2UgIi0iOiAvLyBOZXcgZmlsZQogICAgICBkYXRhWyJuYW1lIl0gICAgICAgID0gIiI7CiAgICAgIGRhdGFbImRlc2NyaXB0aW9uIl0gPSAiIjsKICAgICAgZGF0YVsiZmlsZS5zb3VyY2UiXSA9ICIiOwogICAgICBkYXRhWyJ0eXBlIl0gPSBmaWxlVHlwZTsKICAgICAgCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWxldGVGaWxlRGV0YWlsIikuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0eXBlIikuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJjaGFuZ2VGaWxlVHlwZSh0aGlzKTsiKQogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidHlwZSIpLnNldEF0dHJpYnV0ZSgiZGF0YS1pZCIsIGZpbGVJRCkKICAgICAgCiAgICAgIHNob3dFbGVtZW50KCJkZWxldGVGaWxlRGV0YWlsIiwgZmFsc2UpOwogICAgICBzaG93RWxlbWVudCgidXBkYXRlRmlsZURldGFpbCIsIGZhbHNlKTsKICAgICAgCiAgICAgIGlmIChmaWxlVHlwZSA9PSAieG1sdHYiKSB7CiAgICAgICAgc2hvd0VsZW1lbnQoInR5cGUiLCBmYWxzZSk7CiAgICAgICAgc2hvd0VsZW1lbnQoImZpbGUtdHlwZSIsIGZhbHNlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzaG93RWxlbWVudCgidHlwZSIsIHRydWUpOwogICAgICAgIHNob3dFbGVtZW50KCJmaWxlLXR5cGUiLCB0cnVlKTsKICAgICAgfQogICAgICAKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDogCiAgICAgIGRhdGEgPSBjb25maWdbImZpbGVzIl1bZmlsZVR5cGVdW2ZpbGVJRF07CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWxldGVGaWxlRGV0YWlsIikuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgIAogICAgICBzaG93RWxlbWVudCgidXBkYXRlRmlsZURldGFpbCIsIHRydWUpOwogICAgICBzaG93RWxlbWVudCgidHlwZSIsIGZhbHNlKTsKICAgICAgc2hvd0VsZW1lbnQoImZpbGUtdHlwZSIsIGZhbHNlKTsKICAgICAgCiAgICAgIGJyZWFrOwoKICB9CgogIHZhciBrZXlzID0gZ2V0T2JqS2V5cyhkYXRhKTsKICAKICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKCiAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChrZXlzW2ldKSl7CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pLnZhbHVlID0gZGF0YVtrZXlzW2ldXTsKICAgIH0gCgoKICB9Cgp9CgpmdW5jdGlvbiBjaGFuZ2VGaWxlVHlwZShlbG0pIHsKCiAgdmFyIGZpbGVJRCA9IGVsbS5nZXRBdHRyaWJ1dGUoImRhdGEtaWQiKTsKICB2YXIgZmlsZVR5cGUgPSBlbG0ub3B0aW9uc1tlbG0uc2VsZWN0ZWRJbmRleF0udmFsdWU7CiAgCiAgZmlsZURldGFpbChmaWxlSUQsIGZpbGVUeXBlKQoKfQoKCmZ1bmN0aW9uIHNhdmVGaWxlRGV0YWlsKGZpbGVJRCwgZmlsZVR5cGUsIGRlbGV0ZUZpbGUpIHsKCiAgaWYgKGZpbGVJRCA9PSB1bmRlZmluZWQpIHsKICAgIGFsZXJ0KCJJRCBpcyBtaXNzaW5nISEhIik7CiAgICByZXR1cm4gCiAgfQoKICB2YXIgaW5wdXRzICAgICAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZmlsZS1kZXRhaWwiKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKTsKICB2YXIgc2VsZWN0cyAgICAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZmlsZS1kZXRhaWwiKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiU0VMRUNUIik7CiAgdmFyIG5ld0ZpbGVEYXRhID0gbmV3IE9iamVjdCgpOwogIHZhciBkYXRhICAgICAgICA9IG5ldyBPYmplY3QoKTsKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgIHN3aXRjaChpbnB1dHNbaV0udHlwZSkgewogICAgICBjYXNlICJ0ZXh0IjogbmV3RmlsZURhdGFbaW5wdXRzW2ldLm5hbWVdID0gaW5wdXRzW2ldLnZhbHVlOyBicmVhazsKICAgIH0KICB9CgogIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0cy5sZW5ndGg7IGkrKykgewogICAgbmV3RmlsZURhdGFbc2VsZWN0c1tpXS5pZF0gPSBzZWxlY3RzW2ldLm9wdGlvbnNbc2VsZWN0c1tpXS5zZWxlY3RlZEluZGV4XS52YWx1ZTsKICB9CgogIGlmIChkZWxldGVGaWxlID09IHRydWUpIHsKICAgIHN3aXRjaChmaWxlVHlwZSkgewogICAgICBjYXNlICJtM3UiOiAgIHZhciBhbGVydFRleHQgPSAiRGVsZXRlIHRoaXMgcGxheWxpc3Q/IjsgYnJlYWs7CiAgICAgIGNhc2UgImhkaHIiOiB2YXIgYWxlcnRUZXh0ID0gIkRlbGV0ZSB0aGlzIEhESG9tZVJ1biB0dW5lcj8iOyBicmVhazsKICAgICAgY2FzZSAieG1sdHYiOiB2YXIgYWxlcnRUZXh0ID0gIkRlbGV0ZSB0aGlzIFhNTFRWIGZpbGU/IjsgYnJlYWs7CiAgICB9CgogICAgaWYgKGNvbmZpcm0oYWxlcnRUZXh0KSkgewogICAgICBuZXdGaWxlRGF0YVsiZGVsZXRlIl0gPSB0cnVlCiAgICAgIGRhdGEgPSBidWlsZEZpbGVzT2JqKGZpbGVUeXBlLCBmaWxlSUQsIG5ld0ZpbGVEYXRhKTsKICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgIAogICAgfSBlbHNlIHsKICAgICAgc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOwogICAgICByZXR1cm4KICAgIAogICAgfQoKICB9IGVsc2UgewogIAogICAgc3dpdGNoKGNvbmZpZ1siZmlsZXMiXVtmaWxlVHlwZV0uaGFzT3duUHJvcGVydHkoZmlsZUlEKSkgewoKICAgICAgY2FzZSB0cnVlOiAKICAgICAgICBkYXRhID0gY29uZmlnWyJmaWxlcyJdW2ZpbGVUeXBlXVtmaWxlSURdOyAKICAgICAgICBpZiAoZGF0YVsiZmlsZS5zb3VyY2UiXSAhPSBuZXdGaWxlRGF0YVsiZmlsZS5zb3VyY2UiXSkgewogICAgICAgICAgZGF0YVsidXBkYXRlIl0gPSB0cnVlCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRhdGFbInVwZGF0ZVBsYXlsaXN0TmFtZSJdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIAogICAgICBjYXNlIGZhbHNlOiAKICAgICAgICBuZXdGaWxlRGF0YVsibmV3Il0gPSB0cnVlOwogICAgICAgIGRhdGEgPSBidWlsZEZpbGVzT2JqKGZpbGVUeXBlLCBmaWxlSUQsIG5ld0ZpbGVEYXRhKTsKICAgICAgICBicmVhawoKICAgIH0KICAKICB9ICAKICAKICBzd2l0Y2goZmlsZVR5cGUpIHsKCiAgICBjYXNlICJtM3UiOiAgIGRhdGFbImNtZCJdID0gInNhdmVGaWxlc00zVSI7IGJyZWFrOwogICAgY2FzZSAiaGRociI6ICBkYXRhWyJjbWQiXSA9ICJzYXZlRmlsZXNIREhSIjsgYnJlYWs7CiAgICBjYXNlICJ4bWx0diI6IGRhdGFbImNtZCJdID0gInNhdmVGaWxlc1hNTFRWIjsgYnJlYWs7CgogIH0KICAvL2NvbnNvbGUubG9nKGRhdGEpOwogIHhUZVZlKGRhdGEpOwogIHJldHVybgp9CgpmdW5jdGlvbiB1cGRhdGVGaWxlKGZpbGVJRCwgZmlsZVR5cGUsIGFsbEZpbGVzKSB7CiAgCiAgc3dpdGNoKGNvbmZpZ1siZmlsZXMiXVtmaWxlVHlwZV0uaGFzT3duUHJvcGVydHkoZmlsZUlEKSkgewoKICAgIGNhc2UgdHJ1ZTogCiAgICAKICAgICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICAgIHZhciBkYXRhID0gYnVpbGRGaWxlc09iaihmaWxlVHlwZSwgZmlsZUlELCBjb25maWdbImZpbGVzIl1bZmlsZVR5cGVdW2ZpbGVJRF0pCiAgICAgIGRhdGFbIm5ldyJdID0gdHJ1ZQoKICAgICAgc3dpdGNoKGZpbGVUeXBlKSB7CgogICAgICAgIGNhc2UgIm0zdSI6ICAgZGF0YVsiY21kIl0gPSAidXBkYXRlRmlsZU0zVSI7IGJyZWFrOwogICAgICAgIGNhc2UgImhkaHIiOiAgZGF0YVsiY21kIl0gPSAidXBkYXRlRmlsZUhESFIiOyBicmVhazsKICAgICAgICBjYXNlICJ4bWx0diI6IGRhdGFbImNtZCJdID0gInVwZGF0ZUZpbGVYTUxUViI7IGJyZWFrOwoKICAgICAgfQogICAgICAKICAgICAgeFRlVmUoZGF0YSk7CiAgICAgIAogICAgICBicmVhazsKICB9Cgp9CgpmdW5jdGlvbiBidWlsZEZpbGVzT2JqKGZpbGVUeXBlLCBmaWxlSUQsIG9iaikgewoKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICBkYXRhWyJmaWxlcyJdID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImZpbGVzIl1bZmlsZVR5cGVdID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImZpbGVzIl1bZmlsZVR5cGVdW2ZpbGVJRF0gPSBvYmoKICByZXR1cm4gZGF0YQoKfQ=="
- webUI["html/js/mapping-editor.js"] = "dmFyIG1hcHBpbmdFcnJvciAgPSBmYWxzZTsKdmFyIGJ1bGsgICAgICAgICAgPSBmYWxzZTsKdmFyIGJ1bGtFZGl0QWxsICAgPSBmYWxzZTsgCnZhciBzZWxlY3RPYmogICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc2VhcmNoT2JqICAgICA9IG5ldyBPYmplY3QoKTsKCnZhciBidWxrSURzICAgICAgID0gbmV3IEFycmF5KCk7CnZhciBidWxrQ2hhbmdlT2JqID0gbmV3IE9iamVjdCgpOwoKZnVuY3Rpb24gY2hlY2tVbmRvKGtleSwgZWxtKSB7CiAgdmFyIHRtcCA9IG5ldyBPYmplY3QoKTsKICB0bXAgPSBlbG0KICBjb25zb2xlLmxvZygiLS0iKTsKICBpZiAodW5kby5oYXNPd25Qcm9wZXJ0eSgiZXBnTWFwcGluZyIpKSB7CiAgICB4RVBHWyJlcGdNYXBwaW5nIl0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHVuZG9bImVwZ01hcHBpbmciXSkpOzsKICB9IGVsc2UgewogICAgdW5kb1siZXBnTWFwcGluZyJdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlbG0pKTsKICB9Cn0KCi8vdmFyIHBsZXhDYXRlZ29yaWVzID0gbmV3IEFycmF5KCItIiwgIkFjdGlvbiBzcG9ydHMiLCAiQWN0aW9uIiwgIkFkdWx0cyBvbmx5IiwgIkFkdmVudHVyZSIsICJBZXJvYmljcyIsICJBbmltYWxzIiwgIkFuaW1hdGVkIiwgIkFuaW1lIiwgIkFudGhvbG9neSIsICJBcmNoZXJ5IiwgIkFydCIsICJBcnRzL2NyYWZ0cyIsICJBdWN0aW9uIiwgIkF1dG8gcmFjaW5nIiwgIkF1dG8iLCAiQXZpYXRpb24iLCAiQXdhcmRzIiwgIkJhbGxldCIsICJCYXNlYmFsbCIsICJCYXNrZXRiYWxsIiwgIkJpY3ljbGUgcmFjaW5nIiwgIkJpY3ljbGUiLCAiQmlsbGlhcmRzIiwgIkJpb2dyYXBoeSIsICJCb2F0IHJhY2luZyIsICJCb2F0IiwgIkJvd2xpbmciLCAiQm94aW5nIiwgIkJ1cy4vZmluYW5jaWFsIiwgIkNoaWxkcmVuIiwgIkNvbGxlY3RpYmxlcyIsICJDb21lZHkgZHJhbWEiLCAiQ29tZWR5IiwgIkNvbW11bml0eSIsICJDb21wdXRlcnMiLCAiQ29uc3VtZXIiLCAiQ29va2luZyIsICJDcmltZSBkcmFtYSIsICJDcmltZSIsICJEYW5jZSIsICJEYXJrIGNvbWVkeSIsICJEZWJhdGUiLCAiRGl2aW5nIiwgIkRvY3VkcmFtYSIsICJEb2N1bWVudGFyeSIsICJEcmFtYSIsICJFZHVjYXRpb25hbCIsICJFbnRlcnRhaW5tZW50IiwgIkVudmlyb25tZW50IiwgIkVxdWVzdHJpYW4iLCAiRXJvdGljIiwgIkV2ZW50IiwgIkZhbnRhc3kiLCAiRmFzaGlvbiIsICJGZWF0dXJlIEZpbG0iLCAiRmlzaGluZyIsICJGb290YmFsbCIsICJHYW1lIHNob3ciLCAiR2FtaW5nIiwgIkdheS9sZXNiaWFuIiwgIkdvbGYiLCAiSGFuZGJhbGwiLCAiSGVhbHRoIiwgIkhpc3RvcmljYWwgZHJhbWEiLCAiSGlzdG9yeSIsICJIb2NrZXkiLCAiSG9saWRheSIsICJIb21lIGltcHJvdmVtZW50IiwgIkhvcnJvciIsICJIb3JzZSIsICJIb3VzZS9nYXJkZW4iLCAiSG93LXRvIiwgIkludGVydmlldyIsICJJbnRsIHNvY2NlciIsICJMYXciLCAiTWFydGlhbCBhcnRzIiwgIk1lZGljYWwiLCAiTWlsaXRhcnkiLCAiTWluaXNlcmllcyIsICJNaXhlZCBtYXJ0aWFsIGFydHMiLCAiTW90b3JjeWNsZSByYWNpbmciLCAiTW90b3JjeWNsZSIsICJNb3RvcnNwb3J0cyIsICJNb3VudGFpbiBiaWtpbmciLCAiTXVzaWMiLCAiTXVzaWNhbCBjb21lZHkiLCAiTXVzaWNhbCIsICJNeXN0ZXJ5IiwgIk5hdHVyZSIsICJOZXdzIiwgIk5ld3NtYWdhemluZSIsICJPbHltcGljcyIsICJPcGVyYSIsICJPdXRkb29ycyIsICJQYXJhZGUiLCAiUGFyYW5vcm1hbCIsICJQYXJlbnRpbmciLCAiUGVyZm9ybWluZyBhcnRzIiwgIlBsYXlvZmYgc3BvcnRzIiwgIlBva2VyIiwgIlBvbGl0aWNzIiwgIlBybyB3cmVzdGxpbmciLCAiUHVibGljIGFmZmFpcnMiLCAiUmVhbGl0eSIsICJSZWxpZ2lvdXMiLCAiUm9kZW8iLCAiUm9sbGVyIGRlcmJ5IiwgIlJvbWFuY2UiLCAiUm9tYW50aWMgY29tZWR5IiwgIlJ1Z2J5IiwgIlJ1bm5pbmciLCAiU2FpbGluZyIsICJTY2llbmNlIGZpY3Rpb24iLCAiU2NpZW5jZSIsICJTZWxmIGltcHJvdmVtZW50IiwgIlNlcmllcyIsICJTaG9vdGluZyIsICJTaG9wcGluZyIsICJTaG9ydCBGaWxtIiwgIlNpdGNvbSIsICJTa2lpbmciLCAiU25vb2tlciIsICJTb2FwIiwgIlNvY2NlciIsICJTcGVjaWFsIiwgIlNwb3J0cyIsICJzcG9ydHMiLCAiU3BvcnRzIGV2ZW50IiwgIlNwb3J0cyBub24tZXZlbnQiLCAiU3BvcnRzIHRhbGsiLCAiU3RhbmR1cCIsICJTdXJmaW5nIiwgIlN1c3BlbnNlIiwgIlRWIE1vdmllIiwgIlRhbGsiLCAiVGVjaG5vbG9neSIsICJUZW5uaXMiLCAiVGhlYXRlciIsICJUaHJpbGxlciIsICJUcmFjay9maWVsZCIsICJUcmF2ZWwiLCAiVHJpYXRobG9uIiwgIlZhcmlldHkiLCAiVm9sbGV5YmFsbCIsICJXYXIiLCAiV2F0ZXJzcG9ydHMiLCAiV2VhdGhlciIsICJXZXN0ZXJuIiwgIldyZXN0bGluZyIsICJZYWNodCByYWNpbmciLCAibW92aWUiLCAic2VyaWVzIiwgInNwb3J0cyIsICJ0dnNob3ciKTsKdmFyIHBsZXhDYXRlZ29yaWVzVmFsdWVzID0gbmV3IEFycmF5KCItIiwgIktpZHMiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKdmFyIHBsZXhDYXRlZ29yaWVzT3B0aW9uID0gbmV3IEFycmF5KCItIiwgIktpZHMgKEVtYnkgb25seSkiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIikKCgpmdW5jdGlvbiBvcGVuTWFwcGluZ0VkaXRvcihlbG0pIHsKICB2YXIgY29sdW1uVG9Tb3J0ICA9IDEKCiAgY2hlY2tVbmRvKCJlcGdNYXBwaW5nIiwgeEVQR1siZXBnTWFwcGluZyJdKQoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiU2F2ZSI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAic2F2ZVhFUEcoKSI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiQnVsayBFZGl0IjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJidWxrRWRpdCgpIjsKICBuZXdEaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiSU5QVVQiOwogIG5ld0VudHJ5WyJ0eXBlIl0gICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbImNsYXNzIl0gICAgICAgPSAiYnV0dG9uIjsKICBuZXdFbnRyeVsidmFsdWUiXSAgICAgICA9ICJTaG93IFhFUEciOwogIG5ld0VudHJ5WyJvbmNsaWNrIl0gICAgID0gInNob3dYRVBHKCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CgogIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3QoKTsKICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbImNsYXNzIl0gICAgICAgPSAic2VhcmNoIjsKICBuZXdFbnRyeVsiaWQiXSAgICAgICAgICA9ICJzZWFyY2hNYXBwaW5nIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJzZWFyY2giOwogIG5ld0VudHJ5WyJwbGFjZWhvbGRlciJdID0gIlNlYXJjaCI7CiAgbmV3RW50cnlbIm9uY2hhbmdlIl0gICAgPSAic2VhcmNoSW5NYXBwaW5nKCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CgogIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2V0dGluZ3MiKTsKICAvL3NjcmVlbkxvZygiRHVwbGljYXRlIElEIiwgImVycm9yIiwgdHJ1ZSkKICAKCiAgLy8gQnVpbGQgdGFibGUKCiAgdmFyIG5ld1dyYXBwZXIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3V3JhcHBlclsiX2VsZW1lbnQiXSAgPSAiRElWIjsKICBuZXdXcmFwcGVyWyJpZCJdICAgICAgICA9ICJib3gtd3JhcHBlciI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3V3JhcHBlcikpOwoKCiAgdmFyIG5ld1RhYmxlID0gbmV3IE9iamVjdCgpOwogIG5ld1RhYmxlWyJfZWxlbWVudCJdICA9ICJUQUJMRSI7CiAgbmV3VGFibGVbImlkIl0gICAgICAgID0gImlkX21hcHBpbmciOwogIG5ld1RhYmxlWyJjbGFzcyJdICAgICA9ICJ0YWJsZS1tYXBwaW5nIjsKICBkaXYubGFzdENoaWxkLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VGFibGUpKTsKICBzaG93TG9hZGluZ1NjcmVlbih0cnVlKTsKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIGNyZWF0ZU1hcHBpbmdUYWJsZSgpOyAKICB9LCAxMCk7Cgp9CgpmdW5jdGlvbiBjcmVhdGVTZWFyY2hPYmooKSB7CiAgc2VhcmNoT2JqID0gbmV3IE9iamVjdCgpOwogIHZhciBJRHMgPSBnZXRPYmpLZXlzKHhFUEdbImVwZ01hcHBpbmciXSkKICBmb3IgKHZhciBpID0gSURzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICB2YXIgaXRlbSA9IHhFUEdbImVwZ01hcHBpbmciXVtJRHNbaV1dOwogICAgdmFyIHNlYXJjaElEID0gaXRlbVsieC1lcGciXTsKICAgIHZhciBzZWFyY2hWYWx1ZSA9ICIiOyAKICAgIHNlYXJjaFZhbHVlID0gc2VhcmNoVmFsdWUgKyBpdGVtWyJ4LWNoYW5uZWxJRCJdICsgIiAiOwogICAgc2VhcmNoVmFsdWUgPSBzZWFyY2hWYWx1ZSArIGl0ZW1bIngtY2F0ZWdvcnkiXSArICIgIjsKICAgIHNlYXJjaFZhbHVlID0gc2VhcmNoVmFsdWUgKyBpdGVtWyJ4LW5hbWUiXSArICIgIjsKICAgIHNlYXJjaFZhbHVlID0gc2VhcmNoVmFsdWUgKyBpdGVtWyJ4LWdyb3VwLXRpdGxlIl0gKyAiICI7CiAgICBzZWFyY2hWYWx1ZSA9IHNlYXJjaFZhbHVlICsgaXRlbVsieC14bWx0di1maWxlIl0gKyAiICI7CiAgICBzZWFyY2hWYWx1ZSA9IHNlYXJjaFZhbHVlICsgaXRlbVsiX2ZpbGUubTN1Lm5hbWUiXSArICIgIjsKCiAgICBzd2l0Y2goaXRlbVsieC1hY3RpdmUiXSkgewogICAgICBjYXNlIHRydWU6ICBzZWFyY2hWYWx1ZSA9IHNlYXJjaFZhbHVlICsgIm9ubGluZSI7IGJyZWFrOwogICAgICBjYXNlIGZhbHNlOiBzZWFyY2hWYWx1ZSA9IHNlYXJjaFZhbHVlICsgIm9mZmxpbmUiOyBicmVhazsKICAgIH0KCiAgICBzZWFyY2hPYmpbc2VhcmNoVmFsdWVdID0gc2VhcmNoSUQ7CgogIH0KfQoKCmZ1bmN0aW9uIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKSB7CgogIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYm94LXdyYXBwZXIiKSl7CgogICAgdmFyIGVsbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJib3gtd3JhcHBlciIpOwogICAgCiAgICB2YXIgZGl2cyA9IG5ldyBBcnJheSgibXlTdHJlYW1zQm94IiwgImNsaWVudEluZm8iLCAic2V0dGluZ3MiKTsKICAgIHZhciBlbGVtZW50c0hlaWdodCA9IDAgLSBlbG0ub2Zmc2V0SGVpZ2h0OwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaXZzLmxlbmd0aDsgaSsrKSB7CiAgICAgIGVsZW1lbnRzSGVpZ2h0ID0gZWxlbWVudHNIZWlnaHQgKyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkaXZzW2ldKS5vZmZzZXRIZWlnaHQ7CiAgICB9CgogICAgZWxtLnN0eWxlLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGVsZW1lbnRzSGVpZ2h0ICsgInB4IjsKCiAgfQoKICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm1lbnUtd3JhcHBlciIpKXsKCiAgICB2YXIgZWxtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm1lbnUtd3JhcHBlciIpOwogICAgCiAgICB2YXIgb2ZmZXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIikub2Zmc2V0SGVpZ2h0ICsgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpLm9mZnNldEhlaWdodCArIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjbGllbnRJbmZvIikub2Zmc2V0SGVpZ2h0OwogICAgCiAgICBpZiAod2luZG93LmlubmVySGVpZ2h0ID4gb2ZmZXN0KSB7CiAgICAgIGVsbS5zdHlsZS5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgKyAicHgiCiAgICB9IGVsc2UgewogICAgICBlbG0uc3R5bGUuaGVpZ2h0ID0gb2ZmZXN0ICsgInB4IgogICAgfQogICAgCgogIH0KCgp9CgpmdW5jdGlvbiBjcmVhdGVNYXBwaW5nVGFibGUoKSB7CiAgY29sdW1uVG9Tb3J0ID0gMTsKICBjcmVhdGVTZWFyY2hPYmooKTsKCiAgLy8gQ3JlYXRlIHRhYmxlIChIZWFkZXIpCiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB0YWJsZS5pbm5lckhUTUwgPSAiIjsKICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3VFJbIl9lbGVtZW50Il0gPSAiVFIiOwogIG5ld1RSWyJjbGFzcyJdICAgID0gInRhYmxlLW1hcHBpbmctaGVhZGVyIjsKICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1RSKSk7CgogIHZhciB0ciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpZF9tYXBwaW5nIikubGFzdENoaWxkOwogIHZhciB0ckhlYWRsaW5lcyA9IG5ldyBBcnJheSgiQnVsayIsICJDaC4gTm8uIiwgIkxvZ28iLCAiQ2hhbm5lbCBOYW1lIiwgIlBsYXlsaXN0IiwgIkdyb3VwIFRpdGxlIiwgIlhNTFRWIEZpbGUiLCAiWE1MVFYgSUQiKQoKICBmb3IgKHZhciBpID0gMDsgaSA8IHRySGVhZGxpbmVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CgogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiVEQiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB0ckhlYWRsaW5lc1tpXTsKCiAgICAKCiAgICB2YXIgd2lkdGggPSAiIjsKICAgIHN3aXRjaCh0ckhlYWRsaW5lc1tpXSkgewoKICAgICAgY2FzZSAiQnVsayI6ICAKICAgICAgICAKICAgICAgICBtYXhXaWR0aCA9ICIzMnB4IjsgCiAgICAgICAgbWluV2lkdGggPSAiMzJweCI7IAogICAgCiAgICAgICAgLy8gQ3JlYXRlIGJ1bGsgVEQKICAgICAgICB2YXIgbmV3Q2hlY2tib3ggPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgbmV3Q2hlY2tib3hbIl9lbGVtZW50Il0gPSAiSU5QVVQiOwogICAgICAgIG5ld0NoZWNrYm94WyJ0eXBlIl0gICAgID0gImNoZWNrYm94IjsKICAgICAgICBuZXdDaGVja2JveFsiY2xhc3MiXSAgICA9ICJidWxrIGhpZGVCdWxrIjsKICAgICAgICBuZXdDaGVja2JveFsib25tb3VzZW91dCJdID0gImphdmFzY3JpcHQ6IHRoaXMuYmx1cigpIgogICAgICAgIG5ld0NoZWNrYm94WyJvbmNsaWNrIl0gICAgPSAiamF2YXNjcmlwdDogYnVsa0VkaXRBbGxDaGFubmVscygpIgoKICAgIAogICAgICAgIC8vbmV3VEQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdDaGVja2JveCkpOwoKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgIkNoLiBOby4iOiAKICAgICAgICBtYXhXaWR0aCA9ICI4MHB4IjsgCiAgICAgICAgbWluV2lkdGggPSAiNzBweCI7IAogICAgICAgIG5ld1REWyJvbmNsaWNrIl0gID0gImphdnNjcmlwdDogc29ydFRhYmxlKCIgKyBpICsgIik7IjsKICAgICAgICBuZXdURFsiY2xhc3MiXSAgICA9ICJwb2ludGVyIjsKICAgICAgICBicmVhazsKICAgICAgCiAgICAgIGNhc2UgIkxvZ28iOiAgbWF4V2lkdGggPSAiMTIwcHgiOyBtaW5XaWR0aCA9ICI2MHB4IjsgYnJlYWs7CiAgICAgIAogICAgICBjYXNlICJDaGFubmVsIE5hbWUiOiAgCiAgICAgICAgbWF4V2lkdGggPSAiNTAlIjsgCiAgICAgICAgbWluV2lkdGggPSAiMjAwcHgiOyAKICAgICAgICBuZXdURFsib25jbGljayJdICA9ICJqYXZzY3JpcHQ6IHNvcnRUYWJsZSgiICsgaSArICIpOyI7CiAgICAgICAgbmV3VERbImNsYXNzIl0gPSAicG9pbnRlciI7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlICJQbGF5bGlzdCI6ICAgICAgCiAgICAgICAgbWF4V2lkdGggPSAiMTUwcHgiOyAKICAgICAgICBtaW5XaWR0aCA9ICIxMDBweCI7IAogICAgICAgIG5ld1REWyJvbmNsaWNrIl0gID0gImphdnNjcmlwdDogc29ydFRhYmxlKCIgKyBpICsgIik7IjsKICAgICAgICBuZXdURFsiY2xhc3MiXSAgICA9ICJwb2ludGVyIjsKICAgICAgICBicmVhazsKICAgICAgCiAgICAgIGNhc2UgIkdyb3VwIFRpdGxlIjogICAKICAgICAgICBtYXhXaWR0aCA9ICIxNTBweCI7IAogICAgICAgIG1pbldpZHRoID0gIjEwMHB4IjsgCiAgICAgICAgbmV3VERbIm9uY2xpY2siXSAgPSAiamF2c2NyaXB0OiBzb3J0VGFibGUoIiArIGkgKyAiKTsiOwogICAgICAgIG5ld1REWyJjbGFzcyJdICAgID0gInBvaW50ZXIiOwogICAgICAgIGJyZWFrOwogICAgICAKICAgICAgY2FzZSAiWE1MVFYgRmlsZSI6ICAgIAogICAgICAgIG1heFdpZHRoID0gIjE1MHB4IjsgCiAgICAgICAgbWluV2lkdGggPSAiMTAwcHgiOyAKICAgICAgICAvL25ld1REWyJvbmNsaWNrIl0gID0gImphdnNjcmlwdDogc29ydFRhYmxlKCIgKyBpICsgIik7IjsKICAgICAgICBuZXdURFsiY2xhc3MiXSAgICA9ICIiOwogICAgICAgIGJyZWFrOwogICAgICAKCiAgICAgIGNhc2UgIlhNTFRWIElEIjogICAgICBtYXhXaWR0aCA9ICIxNTBweCI7IG1pbldpZHRoID0gIjEwMHB4IjsgYnJlYWs7CgogICAgICBkZWZhdWx0OiAKICAgICAgICBuZXdURFsiY2xhc3MiXSAgICA9ICIiOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIHRyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VEQpKTsKICAgIGlmICh0ckhlYWRsaW5lc1tpXSA9PSAiQnVsayIpIHsKICAgICAgdHIubGFzdENoaWxkLmlubmVySFRNTCA9ICIiOwogICAgICB0ci5sYXN0Q2hpbGQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdDaGVja2JveCkpOwogICAgICAKICAgIH0KICAgIAogICAgdmFyIGVsbSA9IHRyLmxhc3RDaGlsZDsKICAgIGVsbS5zdHlsZS53aWR0aCA9IG1heFdpZHRoOwogICAgZWxtLnN0eWxlLm1heFdpZHRoID0gbWF4V2lkdGg7CiAgICBlbG0uc3R5bGUubWluV2lkdGggPSBtaW5XaWR0aDsKCiAgfQogIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB2YXIgSURzID0gZ2V0T2JqS2V5cyh4RVBHWyJlcGdNYXBwaW5nIl0pCgogIHZhciBhbGxYbWx0dkZpbGVzID0gZ2V0T2JqS2V5cyh4RVBHWyJ4bWx0dk1hcCJdKTsKCiAgaWYgKGFsbFhtbHR2RmlsZXMgPT0gMCkgewogICAgc2hvd0xvYWRpbmdTY3JlZW4oZmFsc2UpOwogICAgcmV0dXJuOwogIH0KCiAgLy8gU29ydCBJRHMKICB2YXIgcG9zT2JqID0gbmV3IE9iamVjdCgpOwogIGZvciAodmFyIGkgPSAwOyBpIDwgSURzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgaXRlbSAgPSB4RVBHWyJlcGdNYXBwaW5nIl1bSURzW2ldXTsKICAgIHZhciBwb3MKICAgIHN3aXRjaChpc05hTih4RVBHWyJlcGdNYXBwaW5nIl1bSURzW2ldXVsieC1jaGFubmVsSUQiXSkpIHsKICAgICAgY2FzZSBmYWxzZTogcG9zID0gcGFyc2VGbG9hdCh4RVBHWyJlcGdNYXBwaW5nIl1bSURzW2ldXVsieC1jaGFubmVsSUQiXSkgOyBicmVhazsKICAgIH0KICAgIHBvc09ialtwb3NdID0gaXRlbTsKICB9CiAgcG9zRmxvYXQgPSBnZXRPYmpLZXlzKHBvc09iaikKICBmdW5jdGlvbiBzb3J0RmxvYXQoYSxiKSB7IHJldHVybiBhIC0gYjsgfQogIHBvc0Zsb2F0LnNvcnQoc29ydEZsb2F0KQoKICAvL2NvbnNvbGUubG9nKHBvc0Zsb2F0KTsKCiAgLy8gLS0tCgogIGlmIChJRHMubGVuZ3RoID4gMjAwKSB7CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IAogICAgICBzaG93TG9hZGluZ1NjcmVlbih0cnVlKTsKICAgIH0sIDEpOwoKICB9CgoKICAvLyB0YWJsZSBmb3IgaW50IGNoYW5uZWwgSUQncwogIGZvciAodmFyIGkgPSAwOyBpIDwgcG9zRmxvYXQubGVuZ3RoOyBpKyspIHsKCiAgICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaWRfbWFwcGluZyIpOwogICAgdmFyIGl0ZW0gID0gcG9zT2JqW3Bvc0Zsb2F0W2ldXTsKICAgIC8vdmFyIGl0ZW0gID0geEVQR1siZXBnTWFwcGluZyJdW0lEc1tpXV07CiAgICAvL2NvbnNvbGUubG9nKGl0ZW0pOwogICAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogICAgbmV3VFJbIl9lbGVtZW50Il0gICAgICAgPSAiVFIiOwogICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgIG5ld1RSWyJpZCJdICAgICAgICAgICAgID0gaXRlbVsieC1lcGciXTsKICAgIG5ld1RSWyJvbmNvbnRleHRtZW51Il0gID0gJ2phdmFzY3JpcHQ6IHN3aXRjaENoYW5uZWxTdGF0dXMoIicgKyBpdGVtWyJ4LWVwZyJdICsgJyIpOyByZXR1cm4gZmFsc2U7JzsKICAgIHRhYmxlLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VFIpKTsKCiAgICB2YXIgdHIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaWRfbWFwcGluZyIpLmxhc3RDaGlsZDsKICAgIAogICAgLy8gQ3JlYXRlIGJ1bGsgVEQKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdICAgPSAiSU5QVVQiOwogICAgbmV3VERbInR5cGUiXSAgICAgICA9ICJjaGVja2JveCI7CiAgICBuZXdURFsiY2xhc3MiXSAgICAgID0gImJ1bGsgaGlkZUJ1bGsiOwogICAgbmV3VERbIm9ubW91c2VvdXQiXSA9ICJqYXZhc2NyaXB0OiB0aGlzLmJsdXIoKSIKICAgIAogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKICAgIAoKICAgIC8vIENyZWF0ZSBJRCBURAogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiSU5QVVQiOwogICAgbmV3VERbInR5cGUiXSAgICAgPSAidGV4dCIKICAgIG5ld1REWyJjbGFzcyJdICAgID0gInc0MHB4IjsKICAgIG5ld1REWyJ2YWx1ZSJdICAgID0gaXRlbVsieC1jaGFubmVsSUQiXTsKICAgIG5ld1REWyJvbmZvY3Vzb3V0Il0gPSAiamF2YXNjcmlwdDogYXJyYW5nZVRhYmxlKHRoaXMpOyIKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIElNRyBURAogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiSU1HIjsKICAgIG5ld1REWyJvbmNsaWNrIl0gID0gJ2phdmFzY3JpcHQ6IG1hcHBpbmdEZXRhaWwoIicgKyBpdGVtWyJ4LWVwZyJdICsgJyIpOyc7CiAgICBpZiAoaXRlbVsidHZnLWxvZ28iXSAhPSB1bmRlZmluZWQpIHsKICAgICAgbmV3VERbInNyYyJdICAgICAgPSBpdGVtWyJ0dmctbG9nbyJdOwogICAgfSBlbHNlIHsKICAgICAgaXRlbVsidHZnLWxvZ28iXSA9ICIiOwogICAgICBuZXdURFsic3JjIl0gPSAiIjsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CiAgICB0ci5sYXN0Q2hpbGQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IG1hcHBpbmdEZXRhaWwoIicgKyBpdGVtWyJ4LWVwZyJdICsgJyIpOycpCgogICAgLy8gQ3JlYXRlIFAgVEQgKGNoYW5uZWwgbmFtZSkKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSBpdGVtWyJ4LW5hbWUiXTsKICAgIG5ld1REWyJjbGFzcyJdICAgICA9IGl0ZW1bIngtY2F0ZWdvcnkiXTsKCiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwogICAgdHIubGFzdENoaWxkLnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBtYXBwaW5nRGV0YWlsKCInICsgaXRlbVsieC1lcGciXSArICciKTsnKQogICAgdHIubGFzdENoaWxkLmxhc3RDaGlsZC5zdHlsZS5wYWRkaW5nID0gIjVweCAxMHB4IjsKCiAgICAvLyBDcmVhdGUgUCBURCAoUGxheWxpc3QgTmFtZSkKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSBpdGVtWyJfZmlsZS5tM3UubmFtZSJdOwogICAgbmV3VERbImNsYXNzIl0gICAgID0gaXRlbVsidGFibGVFbGxpcHNpcyJdOwogICAgCiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwogICAgdHIubGFzdENoaWxkLnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBtYXBwaW5nRGV0YWlsKCInICsgaXRlbVsieC1lcGciXSArICciKTsnKQogICAgCiAgICAvLyBDcmVhdGUgUCBURCAoR3JvdXAgVGl0bGUpCiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIG5ld1REWyJfdGV4dCJdICAgID0gaXRlbVsieC1ncm91cC10aXRsZSJdOwogICAgbmV3VERbImNsYXNzIl0gICAgID0gaXRlbVsidGFibGVFbGxpcHNpcyJdOwogICAgCiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwogICAgdHIubGFzdENoaWxkLnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBtYXBwaW5nRGV0YWlsKCInICsgaXRlbVsieC1lcGciXSArICciKTsnKQoKICAgIAogICAgLy8gQ3JlYXRlIFAgVEQgKFhNTFRWIGZpbGUpCiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSAgICAgICA9ICJQIjsKICAgIG5ld1REWyJjbGFzcyJdICAgID0gInRhYmxlRWxsaXBzaXMiOwogICAgbmV3VERbIl90ZXh0Il0gPSAiLSIKCiAgICBpZiAoYWxsWG1sdHZGaWxlcy5pbmRleE9mKGl0ZW1bIngteG1sdHYtZmlsZSJdKSAhPSAtMSkgewogICAgICB2YXIgeFhtbHR2RmlsZSA9IGl0ZW1bIngteG1sdHYtZmlsZSJdOwogICAgICBzd2l0Y2goeFhtbHR2RmlsZSkgewogICAgICAgIGNhc2UgIi0iOiAgICAgICAgICAgbmV3VERbIl90ZXh0Il0gID0geFhtbHR2RmlsZTsgYnJlYWs7CiAgICAgICAgY2FzZSAieFRlVmUgRHVtbXkiOiBuZXdURFsiX3RleHQiXSAgPSB4WG1sdHZGaWxlOyBicmVhazsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgIG5ld1REWyJfdGV4dCJdICA9IGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZSh4WG1sdHZGaWxlLCAieG1sdHYiLCAibmFtZSIpOyBicmVhazsKICAgICAgICAKICAgICAgfQogICAgICAvL2NvbnNvbGUubG9nKG5ld1REKTsKCiAgICAgIC8vbmV3VERbIl90ZXh0Il0gICAgPSBpdGVtWyJ4LXhtbHR2LWZpbGUiXTsKICAgIH0gZWxzZSB7CiAgICAgIC8vbmV3VERbIl90ZXh0Il0gPSAiLSIKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CiAgICB0ci5sYXN0Q2hpbGQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IG1hcHBpbmdEZXRhaWwoIicgKyBpdGVtWyJ4LWVwZyJdICsgJyIpOycpCgogICAgLy8gQ3JlYXRyIFAgVEQgKFhNTFRWIGNoYW5uZWwgSUQpCiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIG5ld1REWyJjbGFzcyJdICAgID0gInRhYmxlRWxsaXBzaXMiOwoKICAgIGlmIChpdGVtWyJ4LW1hcHBpbmciXSAhPSB1bmRlZmluZWQpIHsKICAgICAgbmV3VERbIl90ZXh0Il0gICAgPSBpdGVtWyJ4LW1hcHBpbmciXTsKICAgIH0KICAgIAogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKICAgIHRyLmxhc3RDaGlsZC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogbWFwcGluZ0RldGFpbCgiJyArIGl0ZW1bIngtZXBnIl0gKyAnIik7JykKCgogICAgdmFyIHhYbWx0dkZpbGUgID0gaXRlbVsieC14bWx0di1maWxlIl07CiAgICB2YXIgeE1hcHBpbmcgICAgPSBpdGVtWyJ4LW1hcHBpbmciXTsKICAgIHZhciB0dmdJRCAgICAgICA9IGl0ZW1bInR2Zy1pZCJdOwogICAgCiAgICAvL2NvbnNvbGUubG9nKGl0ZW1bIngtZXBnIl0pOwogICAgLy9jb25zb2xlLmxvZyhpdGVtKTsKCiAgICBpZiAoaXRlbVsieC1hY3RpdmUiXSA9PSB0cnVlKSB7CiAgICAgIHRyLmNsYXNzTmFtZSA9ICJhY3RpdmVFUEciOwogICAgfSBlbHNlIHsKICAgICAgdHIuY2xhc3NOYW1lID0gIm5vdEFjdGl2ZUVQRyI7CiAgICB9CiAgICAKICB9CgogIHNvcnRUYWJsZSgxKTsKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsKICB9LCA1KTsKfQoKZnVuY3Rpb24gc2VhcmNoSW5NYXBwaW5nKGVsbSkgewoKICB2YXIgc2VhcmNoID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNlYXJjaE1hcHBpbmciKS52YWx1ZTsKICB2YXIgdmFsdWVzID0gZ2V0T2JqS2V5cyhzZWFyY2hPYmopCiAgCiAgZm9yICh2YXIgaSA9IHZhbHVlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgdmFyIGlkID0gc2VhcmNoT2JqW3ZhbHVlc1tpXV07CiAgICB2YXIgYm9vbCA9IHZhbHVlc1tpXS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaC50b0xvd2VyQ2FzZSgpKTsKICAgIHN3aXRjaChib29sKSB7CiAgICAgIGNhc2UgdHJ1ZTogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gIiI7IGJyZWFrOwogICAgICBjYXNlIGZhbHNlOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSA9ICJub25lIjsgYnJlYWs7CiAgICB9CiAgfQoKfQoKZnVuY3Rpb24gbWFwcGluZ0RldGFpbCh4ZXBnKSB7CiAgCiAgYnVsa0lEcyAgID0gbmV3IEFycmF5KCk7CiAgdmFyIGFjdGl2ZUVsZW1lbnQgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50OwogIC8vIElmIGlucHV0IGlkLCByZXR1cm4KICBpZiAoYWN0aXZlRWxlbWVudC50YWdOYW1lID09ICJJTlBVVCIpIHsKICAgIHJldHVybgogIH0KCiAgaWYgKGJ1bGsgPT0gdHJ1ZSkgewogICAgdmFyIGVsbSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImJ1bGsiKTsKICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZWxtLmxlbmd0aDsgaSsrKSB7CiAgICAgIGlmIChlbG1baV0uY2hlY2tlZCA9PSB0cnVlKSB7CiAgICAgICAgdmFyIGlkID0gZWxtW2ldLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5pZDsKICAgICAgICBidWxrSURzLnB1c2goaWQpCiAgICAgIH0KICAgICAgCiAgICB9CgogICAgaWYgKGJ1bGtJRHMubGVuZ3RoID09IDApIHsKICAgICAgc2hvd0VsZW1lbnQoJ3BvcHVwJywgZmFsc2UpCiAgICAgIGFsZXJ0KCJObyBjaGFubmVscyBzZWxlY3RlZCBmb3IgZWRpdGluZyIpCiAgICAgIHJldHVybgogICAgfQoKICAgIHhlcGcgPSBidWxrSURzWzBdCiAgfQoKCiAgY3JlYXRlU2VhcmNoT2JqKCk7CiAgCiAgc2hvd1BvcFVwRWxlbWVudCgnbWFwcGluZy1kZXRhaWwnKTsKCiAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogIC8vY29uc29sZS5sb2codGhpc0NoYW5uZWwpOwogIHZhciB4WG1sdHZGaWxlICA9IHRoaXNDaGFubmVsWyJ4LXhtbHR2LWZpbGUiXTsKICB2YXIgeE1hcHBpbmcgICAgPSB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl07CiAgdmFyIHhDYXRlZ29yeSAgID0gdGhpc0NoYW5uZWxbIngtY2F0ZWdvcnkiXTsKCiAgaWYgKHhYbWx0dkZpbGUgPT0gdW5kZWZpbmVkKSB7CiAgICB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl0gPSAiLSI7CiAgICB4WG1sdHZGaWxlID0gIi0iOwogIH0KCiAgaWYgKHhNYXBwaW5nID09IHVuZGVmaW5lZCkgewogICAgdGhpc0NoYW5uZWxbIngtbWFwcGluZyJdID0gIi0iOwogICAgeE1hcHBpbmcgPSAiLSI7CiAgfQoKICAvKgogIGNvbnNvbGUubG9nKCJJRDoiLCB4ZXBnKTsKICBjb25zb2xlLmxvZygiWE1MVFYgRmlsZToiLCB4WG1sdHZGaWxlKTsKICBjb25zb2xlLmxvZygiTWFwcGluZzoiLCB4TWFwcGluZyk7CiAgKi8KCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKHRoaXNDaGFubmVsKTsKICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pKXsKICAgICAgdmFyIHRkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoa2V5c1tpXSkKICAgIH0gZWxzZSB7CiAgICAgIHZhciB0ZCA9IHVuZGVmaW5lZDsKICAgIH0KICAgIAogICAgdmFyIG5ld0l0ZW0gPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgdmFsdWVzLCB0ZXh0ID0gbmV3IEFycmF5KCk7CiAgICBzd2l0Y2goa2V5c1tpXSkgewogICAgICBjYXNlICJ4LXhtbHR2LWZpbGUiOiAKICAgICAgICB2YXIgZmlsZUlEcyA9IGdldE9iaktleXMoeEVQR1sieG1sdHZNYXAiXSk7CiAgICAgICAgdmFyIHZhbHVlID0gbmV3IEFycmF5KCItIik7CiAgICAgICAgdmFyIHRleHQgID0gbmV3IEFycmF5KCItIik7CgogICAgICAgIGZvciAodmFyIGogPSBmaWxlSURzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7CiAgICAgICAgICBpZiAoZmlsZUlEc1tqXSAhPSAieFRlVmUgRHVtbXkiKSB7CiAgICAgICAgICAgIHZhbHVlLnB1c2goZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKGZpbGVJRHNbal0sICJ4bWx0diIsICJmaWxlLnh0ZXZlIikpCiAgICAgICAgICAgIHRleHQucHVzaChnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZmlsZUlEc1tqXSwgInhtbHR2IiwgIm5hbWUiKSkKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhbHVlLnB1c2goZmlsZUlEc1tqXSkKICAgICAgICAgICAgdGV4dC5wdXNoKGZpbGVJRHNbal0pCiAgICAgICAgICB9CiAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbmV3SXRlbVsiX2VsZW1lbnQiXSAgICAgICA9ICJTRUxFQ1QiOwogICAgICAgIG5ld0l0ZW1bIl9vcHRpb25WYWx1ZXMiXSAgPSB2YWx1ZTsKICAgICAgICBuZXdJdGVtWyJfb3B0aW9uVGV4dCJdICAgID0gdGV4dAogICAgICAgIG5ld0l0ZW1bInZhbHVlIl0gICAgICAgICAgPSB4WG1sdHZGaWxlOwogICAgICAgIG5ld0l0ZW1bIm9uY2hhbmdlIl0gICAgICAgPSAnamF2YXNjcmlwdDogY2hhbmdlWG1sdHZGaWxlKCInICsgeGVwZyArICciLHRoaXMpOyc7CgogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSAieC1tYXBwaW5nIjogCgogICAgICAgIHZhciB2YWx1ZXMgPSBnZXRPYmpLZXlzKHhFUEdbInhtbHR2TWFwIl1beFhtbHR2RmlsZV0pOwoKICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbHVlcy5sZW5ndGg7IGorKykgewogICAgICAgICAgCiAgICAgICAgICBpZiAoeEVQR1sieG1sdHZNYXAiXVt4WG1sdHZGaWxlXVt2YWx1ZXNbal1dLmhhc093blByb3BlcnR5KCdkaXNwbGF5LW5hbWUnKSA9PSB0cnVlKSB7CiAgICAgICAgICAgIHZhciBkaXNwbGF5TmFtZSA9IHhFUEdbInhtbHR2TWFwIl1beFhtbHR2RmlsZV1bdmFsdWVzW2pdXVsiZGlzcGxheS1uYW1lIl07CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB2YXIgZGlzcGxheU5hbWUgPSAiLSIKICAgICAgICAgIH0KICAgICAgICAgIAogICAgICAgICAgLy90ZXh0W2pdID0gdmFsdWVzW2pdICsgIiAoIiArIGRpc3BsYXlOYW1lICsgIikiOwogICAgICAgICAgdGV4dFtqXSA9IGRpc3BsYXlOYW1lICsgIiAoIiArIHZhbHVlc1tqXSAgKyAiKSI7CiAgICAgICAgfQoKICAgICAgICB0ZXh0LnVuc2hpZnQoIi0iKTsKICAgICAgICB2YWx1ZXMudW5zaGlmdCgiLSIpOwogICAgICAgIG5ld0l0ZW1bIl9lbGVtZW50Il0gICAgICAgPSAiU0VMRUNUIjsKICAgICAgICBuZXdJdGVtWyJfb3B0aW9uVmFsdWVzIl0gID0gdmFsdWVzOwogICAgICAgIG5ld0l0ZW1bIl9vcHRpb25UZXh0Il0gICAgPSB0ZXh0CiAgICAgICAgbmV3SXRlbVsidmFsdWUiXSAgICAgICAgICA9IHhNYXBwaW5nOwogICAgICAgIG5ld0l0ZW1bIm9uY2hhbmdlIl0gICAgICAgPSAnamF2YXNjcmlwdDogbWFwcGluZ0NoYW5uZWwoIicgKyB4ZXBnICsgJyIsdGhpcyk7JzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgIngtY2F0ZWdvcnkiOgogICAgICAgIC8vdmFyIHZhbHVlcyA9IHBsZXhDYXRlZ29yaWVzVmFsdWVzCiAgICAgICAgbmV3SXRlbVsiX2VsZW1lbnQiXSAgICAgICA9ICJTRUxFQ1QiOwogICAgICAgIG5ld0l0ZW1bIl9vcHRpb25WYWx1ZXMiXSAgPSBwbGV4Q2F0ZWdvcmllc1ZhbHVlczsKICAgICAgICBuZXdJdGVtWyJfb3B0aW9uVGV4dCJdICAgID0gcGxleENhdGVnb3JpZXNPcHRpb247CiAgICAgICAgbmV3SXRlbVsidmFsdWUiXSAgICAgICAgICA9IHhDYXRlZ29yeTsKICAgICAgICBuZXdJdGVtWyJvbmNoYW5nZSJdICAgICAgID0gJ3NhdmVDYXRlZ29yeSgiJyArIHhlcGcgKyAnIiknOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSAidHZnLWxvZ28iOgogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjaGFubmVsLWxvZ28iKS5zZXRBdHRyaWJ1dGUoInNyYyIsIHRoaXNDaGFubmVsWyJ0dmctbG9nbyJdKTsKICAgICAgICBuZXdJdGVtWyJfZWxlbWVudCJdICAgICAgID0gIklOUFVUIjsKICAgICAgICBuZXdJdGVtWyJ0eXBlIl0gICAgICAgICAgID0gInRleHQiOwogICAgICAgIG5ld0l0ZW1bInZhbHVlIl0gICAgICAgICAgPSB0aGlzQ2hhbm5lbFsidHZnLWxvZ28iXTsKICAgICAgICBuZXdJdGVtWyJvbmZvY3Vzb3V0Il0gICAgID0gJ3NhdmVDaGFubmVsTG9nbygiJyArIHhlcGcgKyAnIiknOwogICAgICAgIG5ld0l0ZW1bInBsYWNlaG9sZGVyIl0gICAgPSAnSW1hZ2UgVVJMJzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgIngtdXBkYXRlLWNoYW5uZWwtaWNvbiI6CiAgICAgICAgbmV3SXRlbVsiX2VsZW1lbnQiXSAgICAgICA9ICJJTlBVVCI7CiAgICAgICAgbmV3SXRlbVsidHlwZSJdICAgICAgICAgICA9ICJjaGVja2JveCI7CiAgICAgICAgc3dpdGNoKEpTT04ucGFyc2UodGhpc0NoYW5uZWxbIngtdXBkYXRlLWNoYW5uZWwtaWNvbiJdKSkgewogICAgICAgICAgY2FzZSB0cnVlOiBuZXdJdGVtWyJjaGVja2VkIl0gICAgICAgID0gdGhpc0NoYW5uZWxbIngtdXBkYXRlLWNoYW5uZWwtaWNvbiJdOwogICAgICAgICAgICBicmVhawogICAgICAgIH0KICAgICAgICBuZXdJdGVtWyJvbmNoYW5nZSJdICAgICA9ICdzYXZlQ2hhbm5lbEljb25VcGRhdGUoIicgKyB4ZXBnICsgJyIpJzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgIngtbmFtZSI6CiAgICAgICAgbmV3SXRlbVsiX2VsZW1lbnQiXSAgICAgICA9ICJJTlBVVCI7CiAgICAgICAgbmV3SXRlbVsidHlwZSJdICAgICAgICAgICA9ICJ0ZXh0IjsKICAgICAgICBuZXdJdGVtWyJ2YWx1ZSJdICAgICAgICAgID0gdGhpc0NoYW5uZWxbIngtbmFtZSJdOwogICAgICAgIG5ld0l0ZW1bIm9uZm9jdXNvdXQiXSAgICAgPSAnc2F2ZUNoYW5uZWxOYW1lKCInICsgeGVwZyArICciKSc7CiAgICAgICAgbmV3SXRlbVsicGxhY2Vob2xkZXIiXSAgICA9ICdDaGFubmVsIE5hbWUnOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSAieC11cGRhdGUtY2hhbm5lbC1uYW1lIjoKICAgICAgICBpZiAodGhpc0NoYW5uZWwuaGFzT3duUHJvcGVydHkoIl91dWlkLmtleSIpID09IHRydWUpIHsKICAgICAgICAgIG5ld0l0ZW1bIl9lbGVtZW50Il0gICAgICAgPSAiSU5QVVQiOwogICAgICAgICAgbmV3SXRlbVsidHlwZSJdICAgICAgICAgICA9ICJjaGVja2JveCI7CiAgICAgICAgICBzd2l0Y2goSlNPTi5wYXJzZSh0aGlzQ2hhbm5lbFsieC11cGRhdGUtY2hhbm5lbC1uYW1lIl0pKSB7CiAgICAgICAgICAgIGNhc2UgdHJ1ZTogbmV3SXRlbVsiY2hlY2tlZCJdICAgICAgICA9IHRoaXNDaGFubmVsWyJ4LXVwZGF0ZS1jaGFubmVsLW5hbWUiXTsKICAgICAgICAgICAgICBicmVhawogICAgICAgICAgfQogICAgICAgICAgbmV3SXRlbVsib25jaGFuZ2UiXSAgICAgPSAnc2F2ZUNoYW5uZWxOYW1lVXBkYXRlKCInICsgeGVwZyArICciKSc7CiAgICAgICAgICBzaG93RWxlbWVudCgic3RyZWFtSGFzQ1VJRCIsIHRydWUpCgogICAgICAgICAgYnJlYWs7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vc3RyZWFtSGFzQ1VJRAogICAgICAgICAgc2hvd0VsZW1lbnQoInN0cmVhbUhhc0NVSUQiLCBmYWxzZSkKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgY2FzZSAieC1hY3RpdmUiOgogICAgICAgIG5ld0l0ZW1bIl9lbGVtZW50Il0gICAgICAgPSAiSU5QVVQiOwogICAgICAgIG5ld0l0ZW1bInR5cGUiXSAgICAgICAgICAgPSAiY2hlY2tib3giOwogICAgICAgIHN3aXRjaChKU09OLnBhcnNlKHRoaXNDaGFubmVsWyJ4LWFjdGl2ZSJdKSkgewogICAgICAgICAgY2FzZSB0cnVlOiBuZXdJdGVtWyJjaGVja2VkIl0gICAgICAgID0gdGhpc0NoYW5uZWxbIngtYWN0aXZlIl07CiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgfQogICAgICAgIG5ld0l0ZW1bIm9uY2hhbmdlIl0gICAgID0gJ3NhdmVDaGFubmVsU3RhdHVzKCInICsgeGVwZyArICciKSc7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlICJ4LWdyb3VwLXRpdGxlIjoKICAgICAgICBuZXdJdGVtWyJfZWxlbWVudCJdICAgICAgID0gIklOUFVUIjsKICAgICAgICBuZXdJdGVtWyJ0eXBlIl0gICAgICAgICAgID0gInRleHQiOwogICAgICAgIG5ld0l0ZW1bInZhbHVlIl0gICAgICAgICAgPSB0aGlzQ2hhbm5lbFsieC1ncm91cC10aXRsZSJdOwogICAgICAgIG5ld0l0ZW1bIm9uZm9jdXNvdXQiXSAgICAgPSAnc2F2ZUdyb3VwVGl0bGUoIicgKyB4ZXBnICsgJyIpJzsKICAgICAgICBuZXdJdGVtWyJwbGFjZWhvbGRlciJdICAgID0gJ0dyb3VwIFRpdGxlJzsKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgbmV3SXRlbVsiX2VsZW1lbnQiXSAgICAgICA9ICJQIjsKICAgICAgICBuZXdJdGVtWyJfdGV4dCJdICAgICAgICAgID0gdGhpc0NoYW5uZWxba2V5c1tpXV07CiAgICAgICAgYnJlYWs7CiAgICAgIAogICAgfQogICAgCiAgICBpZiAodGQgIT0gdW5kZWZpbmVkKSB7CiAgICAgIHRkLmlubmVySFRNTCA9ICIiOwogICAgICB2YXIgZWxlbWVudCA9IGNyZWF0ZU5ld0VsZW1lbnQobmV3SXRlbSkKICAgICAgLy9jb25zb2xlLmxvZyhlbGVtZW50KTsKICAgICAgdGQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgICB9CgogIH0KCiAgaWYgKGJ1bGsgPT0gdHJ1ZSkgewoKICAgIHZhciBlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJub0J1bGsiKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxtLmxlbmd0aDsgaSsrKSB7CiAgICAgIGVsbVtpXS5sYXN0Q2hpbGQuc2V0QXR0cmlidXRlKCJyZWFkb25seSIsIHRydWUpCiAgICAgIGVsbVtpXS5sYXN0Q2hpbGQuc3R5bGUuYm9yZGVyQ29sb3IgPSAicmVkIjsKICAgIH0KCiAgICB4ZXBnID0gYnVsa0lEc1swXQogIH0KCiAgc29ydFNlbGVjdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgieC14bWx0di1maWxlIikubGFzdENoaWxkKTsKICBzb3J0U2VsZWN0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ4LW1hcHBpbmciKS5sYXN0Q2hpbGQpOwogIAp9CgpmdW5jdGlvbiBzb3J0U2VsZWN0KGVsZW0pIHsKCiAgdmFyIHRtcEFyeSA9IFtdOwogIC8vIFJldGFpbiBzZWxlY3RlZCB2YWx1ZSBiZWZvcmUgc29ydGluZwogIHZhciBzZWxlY3RlZFZhbHVlID0gZWxlbVtlbGVtLnNlbGVjdGVkSW5kZXhdLnZhbHVlOwogIC8vIEdyYWIgYWxsIGV4aXN0aW5nIGVudHJpZXMKICBmb3IgKHZhciBpPTA7aTxlbGVtLm9wdGlvbnMubGVuZ3RoO2krKykgdG1wQXJ5LnB1c2goZWxlbS5vcHRpb25zW2ldKTsKICAvLyBTb3J0IGFycmF5IGJ5IHRleHQgYXR0cmlidXRlCiAgdG1wQXJ5LnNvcnQoZnVuY3Rpb24oYSxiKXsgcmV0dXJuIChhLnRleHQgPCBiLnRleHQpPy0xOjE7IH0pOwogIC8vIFdpcGUgb3V0IGV4aXN0aW5nIGVsZW1lbnRzCiAgd2hpbGUgKGVsZW0ub3B0aW9ucy5sZW5ndGggPiAwKSBlbGVtLm9wdGlvbnNbMF0gPSBudWxsOwogIC8vIFJlc3RvcmUgc29ydGVkIGVsZW1lbnRzCiAgdmFyIG5ld1NlbGVjdGVkSW5kZXggPSAwOwogIGZvciAodmFyIGk9MDtpPHRtcEFyeS5sZW5ndGg7aSsrKSB7CiAgICAgIGVsZW0ub3B0aW9uc1tpXSA9IHRtcEFyeVtpXTsKICAgICAgaWYoZWxlbS5vcHRpb25zW2ldLnZhbHVlID09IHNlbGVjdGVkVmFsdWUpIG5ld1NlbGVjdGVkSW5kZXggPSBpOwogIH0KICBlbGVtLnNlbGVjdGVkSW5kZXggPSBuZXdTZWxlY3RlZEluZGV4OyAvLyBTZXQgbmV3IHNlbGVjdGVkIGluZGV4IGFmdGVyIHNvcnRpbmcKICByZXR1cm47Cn0KCgpmdW5jdGlvbiBzd2l0Y2hDaGFubmVsU3RhdHVzKHhlcGcpIHsKICB2YXIgdGhpc0NoYW5uZWwgPSB4RVBHWyJlcGdNYXBwaW5nIl1beGVwZ107CiAgdmFyIHhYbWx0dkZpbGUgPSB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl07CgogIGlmICh4RVBHWyJ4bWx0dk1hcCJdLmhhc093blByb3BlcnR5KHhYbWx0dkZpbGUpID09IHRydWUpIHsKICAgIGlmICh0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gIT0gIi0iICYmIHRoaXNDaGFubmVsWyJ4LW1hcHBpbmciXSAhPSB1bmRlZmluZWQpIHsKICAgICAgdGhpc0NoYW5uZWxbIngtYWN0aXZlIl0gPSAhdGhpc0NoYW5uZWxbIngtYWN0aXZlIl07CiAgICAgIHZhciB0ciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHhlcGcpOwogICAgICBzd2l0Y2godGhpc0NoYW5uZWxbIngtYWN0aXZlIl0pIHsKICAgICAgICBjYXNlIHRydWU6IHRyLmNsYXNzTmFtZSA9ICJhY3RpdmVFUEciOyBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOiB0ci5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIjsgYnJlYWs7CiAgICAgIH0KICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxvZ0luZm8iKS5jbGFzc05hbWUgPSAibm90VmlzaWJsZSI7CgogICAgfSBlbHNlIHsKICAgICAgdmFyIGVyciA9ICJYTUxUViBDaGFubmVsIGlzIG5vdCBzZWxlY3RlZCIKICAgICAgYWxlcnQoZXJyKQogICAgICAvKgogICAgICB2YXIgbmV3RXJyb3IgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0Vycm9yWyJlcnIiXSA9ICJDaGFubmVsIGlzIG5vdCBzZWxlY3RlZCI7CiAgICAgIGNoZWNrRXJyKG5ld0Vycm9yKTsKICAgICAgKi8KICAgIH0KCiAgfSBlbHNlIHsKICAgIHZhciBlcnIgPSAiWE1MVFYgRmlsZSBpcyBub3Qgc2VsZWN0ZWQiCiAgICBhbGVydChlcnIpCiAgICAvKgogICAgdmFyIG5ld0Vycm9yID0gbmV3IE9iamVjdCgpOwogICAgbmV3RXJyb3JbImVyciJdID0gIlhNTFRWIGZpbGUgaXMgbm90IHNlbGVjdGVkIjsKICAgIGNoZWNrRXJyKG5ld0Vycm9yKTsKICAgICovCiAgfQoKICBzZWFyY2hJbk1hcHBpbmcoKTsKCn0KCmZ1bmN0aW9uIGNyZWF0ZU5ld0VsZW1lbnQobmV3SXRlbSkgewoKICB2YXIgZWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQobmV3SXRlbSk7CiAgCiAgc3dpdGNoKG5ld0l0ZW1bIl9lbGVtZW50Il0pIHsKICAgIGNhc2UgIlNFTEVDVCI6CiAgICAgIC8vZWxlbWVudFtdCiAgICAgIHZhciB2YWx1ZXMgID0gbmV3SXRlbVsiX29wdGlvblZhbHVlcyJdOwogICAgICB2YXIgdGV4dCAgICA9IG5ld0l0ZW1bIl9vcHRpb25UZXh0Il07CgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgIC8vY29uc29sZS5sb2coaXRlbSk7CiAgICAgICAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdDsKICAgICAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgPSAiT1BUSU9OIjsKICAgICAgICBuZXdFbnRyeVsiX3RleHQiXSAgICAgPSB0ZXh0W2ldOwogICAgICAgIG5ld0VudHJ5WyJ2YWx1ZSJdICAgICA9IHZhbHVlc1tpXTsKICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICAgICAgfQogICAgICBlbGVtZW50LnZhbHVlID0gbmV3SXRlbVsidmFsdWUiXTsKICAgICAgYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6IAogICAgICAKICAgICAgLy9lbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3SXRlbSkpOwogICAgICBicmVhazsKICB9CiAgCiAgcmV0dXJuIGVsZW1lbnQ7Cn0KCmZ1bmN0aW9uIHNhdmVCdWxrKGtleSwgdmFsdWUpIHsKICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1bGtJRHMubGVuZ3RoOyBpKyspIHsKICAgIHZhciBpZCA9IGJ1bGtJRHNbaV0KICAgIHZhciB0aGlzQ2hhbm5lbCA9IHhFUEdbImVwZ01hcHBpbmciXVtpZF07CiAgICB0aGlzQ2hhbm5lbFtrZXldID0gdmFsdWU7CgogICAgc3dpdGNoKGtleSkgewogICAgICBjYXNlICJ0dmctbG9nbyI6ICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNoaWxkTm9kZXNbMl0ubGFzdENoaWxkLnNldEF0dHJpYnV0ZSgic3JjIiwgdmFsdWUpOyBicmVhazsKICAgICAgCiAgICAgIGNhc2UgIngtY2F0ZWdvcnkiOiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1szXS5sYXN0Q2hpbGQuY2xhc3NOYW1lID0gdmFsdWU7IGJyZWFrOwoKICAgICAgY2FzZSAieC14bWx0di1maWxlIjoKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzZdLmxhc3RDaGlsZDsKICAgICAgICBzd2l0Y2godmFsdWUpIHsKICAgICAgICAgIGNhc2UgIi0iOiAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsgYnJlYWs7CiAgICAgICAgICBjYXNlICJ4VGVWZSBEdW1teSI6IGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7IGJyZWFrOwogICAgICAgICAgZGVmYXVsdDogICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZSh2YWx1ZSwgInhtbHR2IiwgIm5hbWUiKTsgYnJlYWs7CiAgICAgICAgfQoKCgogICAgICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzVdLmxhc3RDaGlsZC5pbm5lckhUTUwgPSB2YWx1ZS5yZXBsYWNlKC9eLipbXFxcL10vLCAnJyk7IGJyZWFrOwogICAgICBjYXNlICJ4LW1hcHBpbmciOiAgIAogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzddLmxhc3RDaGlsZC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICBpZiAodmFsdWUgPT0gIi0iKSB7CiAgICAgICAgICB0aGlzQ2hhbm5lbFsieC1hY3RpdmUiXSA9IGZhbHNlOwogICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsYXNzTmFtZSA9ICJub3RBY3RpdmVFUEciOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzQ2hhbm5lbFsieC1hY3RpdmUiXSA9IHRydWU7CiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2xhc3NOYW1lID0gImFjdGl2ZUVQRyI7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSAieC1ncm91cC10aXRsZSI6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzVdLmxhc3RDaGlsZC5pbm5lckhUTUwgPSB2YWx1ZTsgYnJlYWs7CgogICAgICBjYXNlICJ4LWFjdGl2ZSI6CiAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwogICAgICAgIAogICAgICAgIGlmICh0aGlzQ2hhbm5lbC5oYXNPd25Qcm9wZXJ0eSgieC14bWx0di1maWxlIikgPT0gdHJ1ZSkgewogICAgICAgICAgaWYgKHRoaXNDaGFubmVsWyJ4LW1hcHBpbmciXSAhPSAiLSIgJiYgdGhpc0NoYW5uZWxbIngtbWFwcGluZyJdICE9IHVuZGVmaW5lZCAmJiB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl0gIT0gIi0iICYmIHRoaXNDaGFubmVsWyJ4LXhtbHR2LWZpbGUiXSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgc3dpdGNoKHRoaXNDaGFubmVsWyJ4LWFjdGl2ZSJdKSB7CiAgICAgICAgICAgICAgY2FzZSB0cnVlOiB0ci5jbGFzc05hbWUgPSAiYWN0aXZlRVBHIjsgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSBmYWxzZTogdHIuY2xhc3NOYW1lID0gIm5vdEFjdGl2ZUVQRyI7IGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICB9CgogICAgdXBkYXRlQ2hhbm5lbExvZ28oaWQpCgogIH0KCn0KCmZ1bmN0aW9uIHVwZGF0ZUNoYW5uZWxMb2dvKHhlcGcpIHsKICB2YXIgdGhpc0NoYW5uZWwgPSB4RVBHWyJlcGdNYXBwaW5nIl1beGVwZ107CiAgaWYgKHRoaXNDaGFubmVsWyJ4LXVwZGF0ZS1jaGFubmVsLWljb24iXSA9PSB0cnVlKSB7CiAgICB2YXIgeFhtbHR2RmlsZSAgPSB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl07CiAgICB2YXIgeE1hcHBpbmcgICAgPSB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl07CgogICAgaWYgKHhYbWx0dkZpbGUgIT0gIi0iICYmIHhYbWx0dkZpbGUubGVuZ3RoID4gMCAmJiB4TWFwcGluZyAhPSAiLSIgJiYgeE1hcHBpbmcubGVuZ3RoID4gMCkgewogICAgICBpZiAoeEVQR1sieG1sdHZNYXAiXVt4WG1sdHZGaWxlXVt4TWFwcGluZ10uaGFzT3duUHJvcGVydHkoImljb24iKSkgewogICAgICAgIHZhciBsb2dvVVJMID0geEVQR1sieG1sdHZNYXAiXVt4WG1sdHZGaWxlXVt4TWFwcGluZ11bImljb24iXTsKICAgICAgICB0aGlzQ2hhbm5lbFsidHZnLWxvZ28iXSA9IGxvZ29VUkw7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeGVwZykuY2hpbGROb2Rlc1syXS5sYXN0Q2hpbGQuc2V0QXR0cmlidXRlKCJzcmMiLCBsb2dvVVJMKTsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY2hhbm5lbC1sb2dvIikuc2V0QXR0cmlidXRlKCJzcmMiLCBsb2dvVVJMKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhbGVydCgiTm8gbG9nbyBVUkwgaW4gdGhlIFhNTFRWIGZpbGUgYXZhaWxhYmxlIikKICAgICAgfQogICAgICAKICAgIH0KICAgIAogICAgLyoKICAgIGlmICh4RVBHWyJ4bWx0dk1hcCJdW3hYbWx0dkZpbGVdW3hNYXBwaW5nXVsiaWNvbiJdICE9IHVuZGVmaW5lZCkgewoKICAgICAgCiAgICB9CiAgICAqLwogICAgCiAgfQp9CgpmdW5jdGlvbiBzYXZlQ2hhbm5lbExvZ28oeGVwZykgewogIGlmIChidWxrID09IGZhbHNlKSB7CiAgICB2YXIgdGhpc0NoYW5uZWwgPSB4RVBHWyJlcGdNYXBwaW5nIl1beGVwZ107CiAgICB0aGlzQ2hhbm5lbFsidHZnLWxvZ28iXSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0dmctbG9nbyIpLmxhc3RDaGlsZC52YWx1ZTsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHhlcGcpLmNoaWxkTm9kZXNbMl0ubGFzdENoaWxkLnNldEF0dHJpYnV0ZSgic3JjIiwgdGhpc0NoYW5uZWxbInR2Zy1sb2dvIl0pOwogICAgbWFwcGluZ0RldGFpbCh4ZXBnKTsKICAgIHJldHVybgogIH0KCiAgaWYgKGJ1bGsgPT0gdHJ1ZSkgewogICAgdmFyIGtleSAgID0gInR2Zy1sb2dvIjsKICAgIHZhciB2YWx1ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0dmctbG9nbyIpLmxhc3RDaGlsZC52YWx1ZTsKICAgIHNhdmVCdWxrKGtleSwgdmFsdWUpOwoKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICByZXR1cm4KICB9Cn0KCmZ1bmN0aW9uIHNhdmVDaGFubmVsSWNvblVwZGF0ZSh4ZXBnKSB7CgogIHZhciBrZXkgICA9ICJ4LXVwZGF0ZS1jaGFubmVsLWljb24iOwogIHZhciB2YWx1ZSA9IEpTT04ucGFyc2UoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIngtdXBkYXRlLWNoYW5uZWwtaWNvbiIpLmxhc3RDaGlsZC5jaGVja2VkKTsKICBpZiAoYnVsayA9PSBmYWxzZSkgewogICAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogICAgdGhpc0NoYW5uZWxba2V5XSA9IHZhbHVlCiAgICB1cGRhdGVDaGFubmVsTG9nbyh4ZXBnKQogICAgCiAgICBtYXBwaW5nRGV0YWlsKHhlcGcpOwogICAgc2VhcmNoSW5NYXBwaW5nKCk7CiAgICByZXR1cm4KICB9CgogIGlmIChidWxrID09IHRydWUpIHsKICAgIHNhdmVCdWxrKGtleSwgdmFsdWUpOwogICAgbWFwcGluZ0RldGFpbCh4ZXBnKTsKICAgIHJldHVybgogIH0KICAKfQoKZnVuY3Rpb24gc2F2ZUNoYW5uZWxOYW1lKHhlcGcpIHsKICBpZiAoYnVsayA9PSBmYWxzZSkgewogICAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogICAgdGhpc0NoYW5uZWxbIngtbmFtZSJdID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIngtbmFtZSIpLmxhc3RDaGlsZC52YWx1ZTsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHhlcGcpLmNoaWxkTm9kZXNbM10ubGFzdENoaWxkLmlubmVySFRNTCA9IHRoaXNDaGFubmVsWyJ4LW5hbWUiXTsKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICBzZWFyY2hJbk1hcHBpbmcoKTsKICB9CiAgCn0KCmZ1bmN0aW9uIHNhdmVDaGFubmVsTmFtZVVwZGF0ZSh4ZXBnKSB7CiAgdmFyIGtleSAgID0gIngtdXBkYXRlLWNoYW5uZWwtbmFtZSI7CiAgdmFyIHZhbHVlID0gSlNPTi5wYXJzZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgieC11cGRhdGUtY2hhbm5lbC1uYW1lIikubGFzdENoaWxkLmNoZWNrZWQpOwoKICBpZiAoYnVsayA9PSBmYWxzZSkgewogICAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogICAgdGhpc0NoYW5uZWxba2V5XSA9IHZhbHVlCiAgICBtYXBwaW5nRGV0YWlsKHhlcGcpOwogICAgc2VhcmNoSW5NYXBwaW5nKCk7CiAgICByZXR1cm4KICB9CgogIGlmIChidWxrID09IHRydWUpIHsKICAgIHNhdmVCdWxrKGtleSwgdmFsdWUpOwogICAgbWFwcGluZ0RldGFpbCh4ZXBnKTsKICAgIHJldHVybgogIH0KCn0KCmZ1bmN0aW9uIHNhdmVDaGFubmVsU3RhdHVzKHhlcGcpIHsKICB2YXIgdGhpc0NoYW5uZWwgPSB4RVBHWyJlcGdNYXBwaW5nIl1beGVwZ107CiAgdmFyIHhYbWx0dkZpbGUgPSB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl07CgogIHZhciBrZXkgICA9ICJ4LWFjdGl2ZSI7CiAgdmFyIHZhbHVlID0gSlNPTi5wYXJzZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgieC1hY3RpdmUiKS5sYXN0Q2hpbGQuY2hlY2tlZCk7CgogIGlmICh4RVBHWyJ4bWx0dk1hcCJdLmhhc093blByb3BlcnR5KHhYbWx0dkZpbGUpID09IHRydWUpIHsKICAgIGlmICh0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gIT0gIi0iICYmIHRoaXNDaGFubmVsWyJ4LW1hcHBpbmciXSAhPSB1bmRlZmluZWQpIHsKICAgICAgdGhpc0NoYW5uZWxbIngtYWN0aXZlIl0gPSAhdGhpc0NoYW5uZWxbIngtYWN0aXZlIl07CiAgICAgIHZhciB0ciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHhlcGcpOwogICAgICBzd2l0Y2godGhpc0NoYW5uZWxbIngtYWN0aXZlIl0pIHsKICAgICAgICBjYXNlIHRydWU6IHRyLmNsYXNzTmFtZSA9ICJhY3RpdmVFUEciOyBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOiB0ci5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIjsgYnJlYWs7CiAgICAgIH0KICAgICAgCiAgICB9IGVsc2UgewogICAgICB2YXIgZXJyID0gIlhNTFRWIENoYW5uZWwgaXMgbm90IHNlbGVjdGVkIgogICAgICBhbGVydChlcnIpCiAgICAgIHZhbHVlID0gZmFsc2UKICAgIH0KCiAgfSBlbHNlIHsKICAgIGlmICh2YWx1ZSA9PSB0cnVlKSB7CiAgICAgIHZhciBlcnIgPSAiWE1MVFYgRmlsZSBpcyBub3Qgc2VsZWN0ZSIKICAgICAgYWxlcnQoZXJyKQogICAgICB2YWx1ZSA9IGZhbHNlCiAgICB9CiAgfQoKICAKCiAgaWYgKGJ1bGsgPT0gZmFsc2UpIHsKICAgIHZhciB0aGlzQ2hhbm5lbCA9IHhFUEdbImVwZ01hcHBpbmciXVt4ZXBnXTsKICAgIHRoaXNDaGFubmVsW2tleV0gPSB2YWx1ZQogICAgbWFwcGluZ0RldGFpbCh4ZXBnKTsKICAgIHNlYXJjaEluTWFwcGluZygpOwoKICAgIHZhciB0ciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHhlcGcpOwogICAgc3dpdGNoKHRoaXNDaGFubmVsWyJ4LWFjdGl2ZSJdKSB7CiAgICAgIGNhc2UgdHJ1ZTogdHIuY2xhc3NOYW1lID0gImFjdGl2ZUVQRyI7IGJyZWFrOwogICAgICBjYXNlIGZhbHNlOiB0ci5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIjsgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuCiAgfQoKICBpZiAoYnVsayA9PSB0cnVlKSB7CiAgICBzYXZlQnVsayhrZXksIHZhbHVlKTsKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICByZXR1cm4KICB9Cgp9CgpmdW5jdGlvbiBzYXZlR3JvdXBUaXRsZSh4ZXBnKSB7CiAgdmFyIGtleSAgID0gIngtZ3JvdXAtdGl0bGUiOwogIHZhciB2YWx1ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ4LWdyb3VwLXRpdGxlIikubGFzdENoaWxkLnZhbHVlOwoKICBpZiAoYnVsayA9PSBmYWxzZSkgewogICAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeGVwZykuY2hpbGROb2Rlc1s1XS5sYXN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICB0aGlzQ2hhbm5lbFtrZXldID0gdmFsdWU7CiAgICBtYXBwaW5nRGV0YWlsKHhlcGcpOwogICAgc2VhcmNoSW5NYXBwaW5nKCk7CiAgfQoKICBpZiAoYnVsayA9PSB0cnVlKSB7CiAgICBzYXZlQnVsayhrZXksIHZhbHVlKTsKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICByZXR1cm4KICB9Cgp9CgpmdW5jdGlvbiBzYXZlQ2F0ZWdvcnkoeGVwZykgewogIHZhciBrZXkgICA9ICJ4LWNhdGVnb3J5IjsKICB2YXIgdmFsdWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgieC1jYXRlZ29yeSIpLmxhc3RDaGlsZC52YWx1ZTsKCiAgaWYgKGJ1bGsgPT0gZmFsc2UpIHsKICAgIHZhciB0aGlzQ2hhbm5lbCA9IHhFUEdbImVwZ01hcHBpbmciXVt4ZXBnXTsKICAgIHRoaXNDaGFubmVsW2tleV0gPSB2YWx1ZQogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeGVwZykuY2hpbGROb2Rlc1szXS5sYXN0Q2hpbGQuY2xhc3NOYW1lID0gdmFsdWUKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICBzZWFyY2hJbk1hcHBpbmcoKTsKICB9CgogIGlmIChidWxrID09IHRydWUpIHsKICAgIHNhdmVCdWxrKGtleSwgdmFsdWUpOwogICAgbWFwcGluZ0RldGFpbCh4ZXBnKTsKICAgIHJldHVybgogIH0KCn0KCmZ1bmN0aW9uIGFycmFuZ2VUYWJsZShlbG0pIHsKICB2YXIgdHIgPSBlbG0ucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50OwogIHZhciBuZXdQb3NpdGlvbiA9IGVsbS52YWx1ZTsKICB2YXIgeF9jaGFubmVsSUQgPSB0ci5pZDsKCiAgc3dpdGNoKGlzTmFOKG5ld1Bvc2l0aW9uKSkgewogICAgY2FzZSB0cnVlOiAKICAgICAgYWxlcnQoIkNoLiBOby4gbXVzdCBiZSBhIG51bWJlciIpOwogICAgICBtYXBwaW5nRXJyb3IgPSB0cnVlOwogICAgICBicmVhazsKICB9CgoKICAvL3ZhciBpdGVtID0geEVQR1siZXBnTWFwcGluZyJdW2lkXTsKICB2YXIga2V5cyA9IGdldE9iaktleXMoeEVQR1siZXBnTWFwcGluZyJdKQogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgdmFyIGl0ZW0gPSB4RVBHWyJlcGdNYXBwaW5nIl1ba2V5c1tpXV07CiAgICBpZiAoaXRlbVsieC1lcGciXSA9PSB4X2NoYW5uZWxJRCkgewoKICAgICAgLy8gQ2hlY2sgaWYgcG9zaXRpb24gZXhpc3QKICAgICAgdmFyIG9sZFBvc2l0aW9uID0gaXRlbVsieC1jaGFubmVsSUQiXTsKCiAgICAgIGlmIChvbGRQb3NpdGlvbiAhPSBuZXdQb3NpdGlvbikgewoKICAgICAgICBjb25zb2xlLmxvZyhuZXdQb3NpdGlvbiwgbmV3UG9zaXRpb24ubGVuZ3RoKTsKICAgICAgICBpZiAobmV3UG9zaXRpb24ubGVuZ3RoID09IDApIHsKICAgICAgICAgIG1hcHBpbmdFcnJvciA9IHRydWUKICAgICAgICAgIG5ld1Bvc2l0aW9uID0gb2xkUG9zaXRpb247CiAgICAgICAgICAKICAgICAgICB9CgogICAgICAgIGlmIChtYXBwaW5nRXJyb3IgPT0gdHJ1ZSkgewogICAgICAgICAgZWxtLnZhbHVlID0gb2xkUG9zaXRpb247CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmb3IgKHZhciBqID0ga2V5cy5sZW5ndGggLSAxOyBqID49IDA7IGotLSkgewogICAgICAgICAgdmFyIGNoYW5uZWwgPSB4RVBHWyJlcGdNYXBwaW5nIl1ba2V5c1tqXV07CiAgICAgICAgICBpZiAoa2V5c1tqXSAhPSB4X2NoYW5uZWxJRCkgewogICAgICAgICAgICBpZiAobmV3UG9zaXRpb24gPT0gY2hhbm5lbFsieC1jaGFubmVsSUQiXSkgeyAvLyBJZiBwb3NpdGlvbiBleGlzdCwgc2V0IG5leHQgZnJlZSBwb3NpdGlvbi4KICAgICAgICAgICAgICBuZXdQb3NpdGlvbisrOwogICAgICAgICAgICAgIGVsbS52YWx1ZSA9IG5ld1Bvc2l0aW9uOwogICAgICAgICAgICAgIGFycmFuZ2VUYWJsZShlbG0pOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgIHZhciBuZXdFcnJvciA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICBuZXdFcnJvclsiZXJyIl0gPSAiRHVwbGljYXRlIElEIjsKICAgICAgICAgICAgICBjaGVja0VycihuZXdFcnJvcik7CiAgICAgICAgICAgICAgc29ydFRhYmxlKCk7CiAgICAgICAgICAgICAgbWFwcGluZ0Vycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh4X2NoYW5uZWxJRCkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIilbMF0uZm9jdXMoKTsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgIH0KCiAgICAgIC8vY29uc29sZS5sb2cob2xkUG9zaXRpb24sIG5ld1Bvc2l0aW9uKTsKICAgICAgaWYgKGtleXNbaV0gPT0geF9jaGFubmVsSUQgJiYgb2xkUG9zaXRpb24gIT0gbmV3UG9zaXRpb24pIHsgIAogICAgICAgIGl0ZW1bIngtY2hhbm5lbElEIl0gPSBuZXdQb3NpdGlvbjsKICAgICAgfSAKCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJsb2dJbmZvIikuY2xhc3NOYW1lID0gIm5vdFZpc2libGUiOwogICAgICBpZiAoY29sdW1uVG9Tb3J0ID09IDEpIHsKICAgICAgICBzb3J0VGFibGUoY29sdW1uVG9Tb3J0KTsKICAgICAgfQogICAgICBtYXBwaW5nRXJyb3IgPSBmYWxzZTsKCiAgICB9CiAgfQp9CgpmdW5jdGlvbiBjaGFuZ2VYbWx0dkZpbGUoeGVwZywgZWxtKSB7CgogIHZhciB0aGlzQ2hhbm5lbCA9IHhFUEdbImVwZ01hcHBpbmciXVt4ZXBnXTsKICAKICB2YXIgeFhtbHR2RmlsZSAgICA9IGVsbS52YWx1ZTsKICB2YXIgY2hhbm5lbElEICAgICA9IHRoaXNDaGFubmVsWyJ0dmctaWQiXTsKICB0aGlzQ2hhbm5lbFsieC14bWx0di1maWxlIl0gPSB4WG1sdHZGaWxlOwoKICBpZiAoYnVsayA9PSBmYWxzZSkgewoKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXsgCgogICAgICB2YXIgeE1hcHBpbmcgPSAiLSIKCiAgICAgIC8vIEF1dG9tYXAKICAgICAgaWYgKHhYbWx0dkZpbGUgIT0gIi0iKSB7CiAgICAgICAgaWYgKHhFUEdbInhtbHR2TWFwIl1beFhtbHR2RmlsZV0uaGFzT3duUHJvcGVydHkoY2hhbm5lbElEKSA9PSB0cnVlKSB7CiAgICAgICAgICB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gPSBjaGFubmVsSUQ7CiAgICAgICAgICB4TWFwcGluZyA9IGNoYW5uZWxJRAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gPSB4TWFwcGluZwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gPSB4TWFwcGluZwoKICAgICAgfQogICAgICAKICAgICAgdmFyIHRyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeGVwZyk7CgogICAgICBpZiAoeE1hcHBpbmcgPT0gIi0iKSB7CiAgICAgICAgdGhpc0NoYW5uZWxbIngtYWN0aXZlIl0gPSBmYWxzZTsKICAgICAgICB0ci5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIgogICAgICB9IGVsc2UgewogICAgICAgIHRoaXNDaGFubmVsWyJ4LWFjdGl2ZSJdICA9IHRydWU7CiAgICAgICAgdHIuY2xhc3NOYW1lID0gImFjdGl2ZUVQRyIKICAgICAgfQoKICAgICAgLy8gU2hvdyBkYXRhIGluIHRhYmxlCiAgICAgIHZhciB0ZCA9IHRyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJURCIpOwogICAgICB2YXIgZGF0YUZpbGUgPSB0ZFt0ZC5sZW5ndGggLSAyXS5sYXN0Q2hpbGQ7CiAgICAgIHN3aXRjaCh4WG1sdHZGaWxlKSB7CiAgICAgICAgY2FzZSAiLSI6ICAgICAgICAgICBkYXRhRmlsZS5pbm5lckhUTUwgPSB4WG1sdHZGaWxlOyBicmVhazsKICAgICAgICBjYXNlICJ4VGVWZSBEdW1teSI6IGRhdGFGaWxlLmlubmVySFRNTCA9IHhYbWx0dkZpbGU7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgZGF0YUZpbGUuaW5uZXJIVE1MID0gZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKHhYbWx0dkZpbGUsICJ4bWx0diIsICJuYW1lIik7IGJyZWFrOwogICAgICB9CgogICAgICAvL3hYbWx0dkZpbGUucmVwbGFjZSgvXi4qW1xcXC9dLywgJycpOwoKICAgICAgdmFyIGRhdGFYbWx0dklEID0gdGRbdGQubGVuZ3RoIC0gMV0ubGFzdENoaWxkOwogICAgICBkYXRhWG1sdHZJRC5pbm5lckhUTUwgPSB4TWFwcGluZzsKICAgICAgCiAgICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CgogICAgfSwgMTApOwogIH0KCiAgaWYgKGJ1bGsgPT0gdHJ1ZSkgewogICAgdmFyIGtleSA9ICJ4LXhtbHR2LWZpbGUiCiAgICB2YXIgdmFsdWUgPSB4WG1sdHZGaWxlCiAgICBzYXZlQnVsayhrZXksIHZhbHVlKTsKCiAgICB2YXIga2V5ID0gIngtbWFwcGluZyIKICAgIHZhciB2YWx1ZSA9ICItIgogICAgc2F2ZUJ1bGsoa2V5LCB2YWx1ZSk7CiAgICBtYXBwaW5nRGV0YWlsKHhlcGcpOwogICAgcmV0dXJuCiAgfQoKICByZXR1cm4KfQoKZnVuY3Rpb24gbWFwcGluZ0NoYW5uZWwoeGVwZywgZWxtKSB7CiAgdmFyIHRoaXNDaGFubmVsID0geEVQR1siZXBnTWFwcGluZyJdW3hlcGddOwogIC8vdmFyIHhNYXBwaW5nICAgICAgPSBlbG0udmFsdWU7CiAgdmFyIHhNYXBwaW5nICAgICAgPSBlbG0ub3B0aW9uc1tlbG0uc2VsZWN0ZWRJbmRleF0udmFsdWUKICAKICBpZiAoYnVsayA9PSBmYWxzZSkgewogICAgCiAgICB0aGlzQ2hhbm5lbFsieC1tYXBwaW5nIl0gPSB4TWFwcGluZzsKCiAgICB2YXIgdHIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh4ZXBnKTsKCiAgICBpZiAoeE1hcHBpbmcgPT0gIi0iKSB7CiAgICAgIHRoaXNDaGFubmVsWyJ4LWFjdGl2ZSJdID0gZmFsc2U7CiAgICAgIHRyLmNsYXNzTmFtZSA9ICJub3RBY3RpdmVFUEciCiAgICB9IGVsc2UgewogICAgICB0aGlzQ2hhbm5lbFsieC1hY3RpdmUiXSAgPSB0cnVlOwogICAgICB0ci5jbGFzc05hbWUgPSAiYWN0aXZlRVBHIgogICAgfQoKICAgIC8vIFNob3cgZGF0YSBpbiB0YWJsZQogICAgdmFyIHRkID0gdHIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlREIik7CiAgICB2YXIgZGF0YVhtbHR2SUQgPSB0ZFt0ZC5sZW5ndGggLSAxXS5sYXN0Q2hpbGQ7CiAgICBkYXRhWG1sdHZJRC5pbm5lckhUTUwgPSB4TWFwcGluZzsKICAgIC8vY29uc29sZS5sb2codGRbdGQubGVuZ3RoIC0gMV0pOwogICAgLy9jb25zb2xlLmxvZyh4TWFwcGluZywgZWxtKTsKCiAgICBjcmVhdGVTZWFyY2hPYmooKTsKICAgIHNlYXJjaEluTWFwcGluZygpOwogICAgdXBkYXRlQ2hhbm5lbExvZ28oeGVwZykKICAgIG1hcHBpbmdEZXRhaWwoeGVwZyk7CiAgICByZXR1cm4KICB9CgogIGlmIChidWxrID09IHRydWUpIHsKCiAgICB2YXIga2V5ID0gIngtbWFwcGluZyIKICAgIHZhciB2YWx1ZSA9IHhNYXBwaW5nCiAgICBzYXZlQnVsayhrZXksIHZhbHVlKTsKCiAgICBtYXBwaW5nRGV0YWlsKHhlcGcpOwogICAgcmV0dXJuCiAgfQoKICByZXR1cm4KfQoKCmZ1bmN0aW9uIGNyZWF0ZU5ld1REKG5ld0l0ZW0sIGVsbSkgewogIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICBuZXdURFsiX2VsZW1lbnQiXSA9ICJURCI7CiAgCiAgZWxtLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VEQpKTsKICB2YXIgdGQgPSBlbG0ubGFzdENoaWxkOyAKICAKICBzd2l0Y2gobmV3SXRlbVsiX2VsZW1lbnQiXSkgewogICAgY2FzZSAiU0VMRUNUIjoKICAgICAgdGQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdJdGVtKSk7CiAgICAgIHZhciB0ZCA9IGVsbS5sYXN0Q2hpbGQubGFzdENoaWxkOyAKICAgICAgdmFyIHZhbHVlcyA9IG5ld0l0ZW1bIl9vcHRpb25WYWx1ZXMiXTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAvL2NvbnNvbGUubG9nKGl0ZW0pOwogICAgICAgIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3Q7CiAgICAgICAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIk9QVElPTiI7CiAgICAgICAgbmV3RW50cnlbIl90ZXh0Il0gICAgID0gdmFsdWVzW2ldOwogICAgICAgIG5ld0VudHJ5WyJ2YWx1ZSJdICAgICA9IHZhbHVlc1tpXTsKICAgICAgICB0ZC5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CiAgICAgIH0KICAgICAgdGQudmFsdWUgPSBuZXdJdGVtWyJ2YWx1ZSJdOwoKICAgICAgYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6IAogICAgICAKICAgICAgdGQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdJdGVtKSk7CiAgICAgIGJyZWFrOwogIH0KICAKfQoKZnVuY3Rpb24gc2F2ZVhFUEcoKSB7CiAgaWYgKG1hcHBpbmdFcnJvciA9PSB0cnVlKSB7CiAgICBhbGVydCgiRGF0YSBjb3VsZCBub3QgYmUgc2F2ZWQsIGVycm9ycyBpbiB0aGUgWEVQRyBkYXRhLiIpOwogICAgcmV0dXJuOwogIH0KICBzaG93TG9hZGluZ1NjcmVlbih0cnVlKTsKCiAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgZGF0YVsiZXBnTWFwcGluZyJdID0geEVQR1siZXBnTWFwcGluZyJdOwogIGRhdGFbImNtZCJdID0gInNhdmVFcGdNYXBwaW5nIjsKICAvL2NvbnNvbGUubG9nKGRhdGEpOwogIHhUZVZlKGRhdGEpOwp9CgpmdW5jdGlvbiBidWxrRWRpdCgpIHsKICBidWxrID0gIWJ1bGs7CiAgdmFyIGNsYXNzTmFtZTsKCiAgdmFyIGVsbSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImJ1bGsiKTsKCiAgc3dpdGNoKGJ1bGspIHsKICAgIGNhc2UgdHJ1ZTogCiAgICAgIGNsYXNzTmFtZSA9ICJidWxrIHNob3dCdWxrIjsKICAgICAgYnJlYWs7CgogICAgY2FzZSBmYWxzZTogCiAgICAgIGNsYXNzTmFtZSA9ICJidWxrIGhpZGVCdWxrIjsKICAgICAgYnVsa0VkaXRBbGwgPSBmYWxzZTsKICAgICAgYnJlYWs7CiAgfQoKICBmb3IgKHZhciBpID0gMDsgaSA8IGVsbS5sZW5ndGg7IGkrKykgewogICAgZWxtW2ldLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKICAgIGVsbVtpXS5jaGVja2VkID0gZmFsc2U7CiAgfQoKfQoKZnVuY3Rpb24gYnVsa0VkaXRBbGxDaGFubmVscygpIHsKCiAgdmFyIGFsbFRSID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVFIiKTsKCiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhbGxUUi5sZW5ndGg7IGkrKykgewogICAgaWYgKGFsbFRSW2ldLnN0eWxlLmRpc3BsYXkgIT0gIm5vbmUiKSB7CiAgICAgIHN3aXRjaChidWxrRWRpdEFsbCkgewogICAgICAgIGNhc2UgZmFsc2U6IGFsbFRSW2ldLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZC5jaGVja2VkID0gdHJ1ZTsgYnJlYWs7CiAgICAgICAgY2FzZSB0cnVlOiBhbGxUUltpXS5maXJzdENoaWxkLmZpcnN0Q2hpbGQuY2hlY2tlZCA9IGZhbHNlOyBicmVhazsgCiAgICAgIH0KCiAgICB9CiAgICAKICB9CgogIGJ1bGtFZGl0QWxsID0gIWJ1bGtFZGl0QWxsOwp9CgpmdW5jdGlvbiBzb3J0VGFibGUoY29sdW1tKSB7CiAgLy9jb25zb2xlLmxvZyhjb2x1bW0pOwogIGlmIChjb2x1bW0gPT0gY29sdW1uVG9Tb3J0KSB7CiAgICAvL3JldHVybjsKICB9CgogIHZhciB0YWJsZSAgICAgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpZF9tYXBwaW5nIik7CiAgdmFyIHRhYmxlSGVhZCAgID0gdGFibGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRSIilbMF07CiAgdmFyIHRhYmxlSXRlbXMgID0gdGFibGVIZWFkLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJURCIpOwogIAogIHZhciBzb3J0T2JqID0gbmV3IE9iamVjdCgpOwogIHZhciB4LCB4VmFsdWU7CiAgdmFyIHRhYmxlSGVhZGVyCiAgdmFyIHNvcnRCeVN0cmluZyA9IGZhbHNlCgogIGlmIChjb2x1bW0gPiAwICYmIGNvbHVtblRvU29ydCA+IDApICB7CiAgICB0YWJsZUl0ZW1zW2NvbHVtblRvU29ydF0uY2xhc3NOYW1lID0gInBvaW50ZXIiOwogICAgdGFibGVJdGVtc1tjb2x1bW1dLmNsYXNzTmFtZSA9ICJzb3J0VGhpcyI7CiAgfQoKICBjb2x1bW5Ub1NvcnQgPSBjb2x1bW07CgogIHZhciByb3dzID0gdGFibGUucm93czsKCiAgaWYgKHJvd3NbMV0gIT0gdW5kZWZpbmVkKSB7CiAgICB0YWJsZUhlYWRlciA9IHJvd3NbMF0KCiAgICB4ID0gcm93c1sxXS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKVtjb2x1bW1dOwogICAgCiAgICBmb3IgKGkgPSAxOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgewoKICAgICAgeCA9IHJvd3NbaV0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlREIilbY29sdW1tXTsKCiAgICAgIHN3aXRjaCh4LmNoaWxkTm9kZXNbMF0udGFnTmFtZS50b0xvd2VyQ2FzZSgpKSB7CiAgICAgICAgY2FzZSAiaW5wdXQiOgogICAgICAgICAgeFZhbHVlID0geC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKVswXS52YWx1ZS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgInAiOgogICAgICAgICAgeFZhbHVlID0geC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiUCIpWzBdLmlubmVyVGV4dC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgCiAgICAgICAgZGVmYXVsdDogY29uc29sZS5sb2coeC5jaGlsZE5vZGVzWzBdLnRhZ05hbWUpOwogICAgICB9CgogICAgICBpZiAoeFZhbHVlID09ICIiIHx8IHhWYWx1ZSA9PSBOYU4pIHsKICAgICAgICB4VmFsdWUgPSBpCiAgICAgICAgc29ydE9ialtpXSA9IHJvd3NbaV07CiAgICAgIAogICAgICB9IGVsc2UgewoKICAgICAgICBzd2l0Y2goaXNOYU4oeFZhbHVlKSkgewogICAgICAgICAgY2FzZSBmYWxzZTogCgogICAgICAgICAgICB4VmFsdWUgPSBwYXJzZUZsb2F0KHhWYWx1ZSk7CiAgICAgICAgICAgIHNvcnRPYmpbeFZhbHVlXSA9IHJvd3NbaV0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSB0cnVlOgoKICAgICAgICAgICAgc29ydEJ5U3RyaW5nID0gdHJ1ZQogICAgICAgICAgICBzb3J0T2JqW3hWYWx1ZS50b0xvd2VyQ2FzZSgpICsgaV0gPSByb3dzW2ldCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICB9CgogICAgICB9CiAgICAKICAgIH0KCiAgICB3aGlsZSAodGFibGUuZmlyc3RDaGlsZCkgewogICAgICB0YWJsZS5yZW1vdmVDaGlsZCh0YWJsZS5maXJzdENoaWxkKTsKICAgIH0KICAgIAogICAgdmFyIHNvcnRWYWx1ZXMgPSBnZXRPYmpLZXlzKHNvcnRPYmopCiAgICBpZiAoc29ydEJ5U3RyaW5nID09IHRydWUpIHsKICAgICAgc29ydFZhbHVlcy5zb3J0KCkKICAgIH0gZWxzZSB7CiAgICAgIGZ1bmN0aW9uIHNvcnRGbG9hdChhLCBiKSB7IAogICAgICAgIHJldHVybiBhIC0gYjsgCiAgICAgIH0KICAgICAgc29ydFZhbHVlcy5zb3J0KHNvcnRGbG9hdCk7CiAgICB9CgogICAgdGFibGUuYXBwZW5kQ2hpbGQodGFibGVIZWFkZXIpCiAgICAKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc29ydFZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgIAogICAgICB0YWJsZS5hcHBlbmRDaGlsZChzb3J0T2JqW3NvcnRWYWx1ZXNbaV1dKQoKICAgIH0KICAgIAogIH0KCn0KCgpmdW5jdGlvbiBzb3J0VGFibGVfb2xkKGNvbHVtbSkgewogIHNob3dMb2FkaW5nU2NyZWVuKHRydWUpOwogIAogIHNldFRpbWVvdXQoZnVuY3Rpb24oKXsgCgogICAgdmFyIHRhYmxlLCByb3dzLCBzd2l0Y2hpbmcsIGksIHgsIHksIHNob3VsZFN3aXRjaDsKICAgIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKCiAgICB2YXIgdGFibGVIZWFkID0gdGFibGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRSIilbMF07CiAgICB2YXIgdGFibGVJdGVtcyA9IHRhYmxlSGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKTsKCiAgICBpZiAoY29sdW1tID4gMCkgIHsKICAgICAgdGFibGVJdGVtc1tjb2x1bW5Ub1NvcnRdLmNsYXNzTmFtZSA9ICJwb2ludGVyIjsKICAgICAgdGFibGVJdGVtc1tjb2x1bW1dLmNsYXNzTmFtZSA9ICJzb3J0VGhpcyI7CiAgICB9CiAgICAKICAgIGNvbHVtblRvU29ydCA9IGNvbHVtbTsKCiAgICAvKgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZUl0ZW1zLmxlbmd0aDsgaSsrKSB7CiAgICAgIGlmICh0YWJsZUl0ZW1zW2ldLmNsYXNzTmFtZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICB0YWJsZUl0ZW1zW2ldLmNsYXNzTmFtZSA9ICJwb2ludGVyIgogICAgICB9CgogICAgfQogICAgKi8KCiAgICAKCiAgICBjb25zb2xlLmxvZyh0YWJsZUl0ZW1zKTsgCgogICAgc3dpdGNoaW5nID0gdHJ1ZTsKICAgIHdoaWxlIChzd2l0Y2hpbmcpIHsKICAgICAgc3dpdGNoaW5nID0gZmFsc2U7CiAgICAgIHJvd3MgPSB0YWJsZS5yb3dzOwogICAgICBmb3IgKGkgPSAxOyBpIDwgKHJvd3MubGVuZ3RoIC0gMSk7IGkrKykgewogICAgICAgIHNob3VsZFN3aXRjaCA9IGZhbHNlOwoKICAgICAgICB4ID0gcm93c1tpXS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKVtjb2x1bW1dOwogICAgICAgIHkgPSByb3dzW2kgKyAxXS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKVtjb2x1bW1dOwoKICAgICAgICBzd2l0Y2goeC5jaGlsZE5vZGVzWzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgY2FzZSAiaW5wdXQiOgogICAgICAgICAgICB4VmFsdWUgPSB4LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTlBVVCIpWzBdLnZhbHVlLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgIHlWYWx1ZSA9IHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIilbMF0udmFsdWUudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSAicCI6CiAgICAgICAgICAgIHhWYWx1ZSA9IHguZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlAiKVswXS5pbm5lclRleHQudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgeVZhbHVlID0geS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiUCIpWzBdLmlubmVyVGV4dC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIAogICAgICAgICAgZGVmYXVsdDogY29uc29sZS5sb2coeC5jaGlsZE5vZGVzWzBdLnRhZ05hbWUpOwogICAgICAgIH0KCiAgICAgICAgCiAgICAgICAgc3dpdGNoKGlzTmFOKHhWYWx1ZSkpIHsKICAgICAgICAgIGNhc2UgZmFsc2U6IHhWYWx1ZSA9IHBhcnNlRmxvYXQoeFZhbHVlKSA7IGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoKGlzTmFOKHlWYWx1ZSkpIHsKICAgICAgICAgIGNhc2UgZmFsc2U6IHlWYWx1ZSA9IHBhcnNlRmxvYXQoeVZhbHVlKSA7IGJyZWFrOwogICAgICAgIH0KICAgICAgICAKCiAgICAgICAgaWYgKHhWYWx1ZSA+IHlWYWx1ZSkgewogICAgICAgICAgc2hvdWxkU3dpdGNoID0gdHJ1ZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgIH0KICAgICAgaWYgKHNob3VsZFN3aXRjaCkgewogICAgICAgIHJvd3NbaV0ucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUocm93c1tpICsgMV0sIHJvd3NbaV0pOwogICAgICAgIHN3aXRjaGluZyA9IHRydWU7CiAgICAgIH0KICAgIH0KICAgIGNyZWF0ZVNlYXJjaE9iaigpCiAgICAKICAgIHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsKICB9LCAyMCk7Cgp9CgpmdW5jdGlvbiBzaG93WEVQRygpIHsKICB2YXIgdXJsID0gbG9jYXRpb24ucHJvdG9jb2wgKyAiLy8iICsgbG9jYXRpb24uaG9zdG5hbWUgKyAiOiIgKyBsb2NhdGlvbi5wb3J0ICsgIi94bWx0di94dGV2ZS54bWwiCiAgdmFyIHdpbiA9IHdpbmRvdy5vcGVuKHVybCwgJ19ibGFuaycpOwogIHdpbi5mb2N1cygpOwp9"
- webUI["html/index.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPCEtLS0KICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIiAvPiAKICAgIC0tPgogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL25ldHdvcmtfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL21lbnVfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL3NldHRpbmdzX3RzLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9sb2dzX3RzLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9iYXNlX3RzLmpzIj48L3NjcmlwdD4KCiAgPC9oZWFkPgoKICAgIDxib2R5IG9ubG9hZD0iamF2YXNjcmlwdDogUGFnZVJlYWR5KCk7Ij4KCiAgICAgIDxkaXYgaWQ9ImxvYWRpbmciIGNsYXNzPSJub25lIj4KICAgICAgICA8ZGl2IGNsYXNzPSJsb2FkZXIiPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgaWQ9InBvcHVwIiBjbGFzcz0ibm9uZSI+CiAgICAgICAgPGRpdiBpZD0icG9wdXAtY3VzdG9tIj48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJsYXlvdXQiPgoKICAgICAgICA8IS0tCiAgICAgICAgPGRpdiBpZD0ibm90aWZpY2F0aW9uIj4KICAgICAgICAgIDxkaXYgY2xhc3M9ImVsZW1lbnQiPgogICAgICAgICAgICA8aDU+WEVQRzwvaDU+CiAgICAgICAgICAgIDxwcmU+MTEuMDUuMjAxOSAtIDIwOjIxPC9wcmU+CiAgICAgICAgICAgIDxocj4KICAgICAgICAgICAgPHA+SGFsbG8gZGFzIGlzdCBlaW4gVGVzdC4gVW5kIG5vY2ggbWVociBUZXh0LjwvcD4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAtLT4KCiAgICAgICAgPGRpdiBpZD0ibWVudS13cmFwcGVyIiBjbGFzcz0ibGF5b3V0LWxlZnQiPgogICAgICAgICAgPGRpdiBpZD0gImJyYW5jaCI+PC9kaXY+CiAgICAgICAgICA8ZGl2IGlkPSJsb2dvIj48L2Rpdj4KICAgICAgICAgIDxuYXYgaWQ9Im1haW4tbWVudSI+PC9uYXY+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxkaXYgY2xhc3M9ImxheW91dC1yaWdodCI+CgogICAgICAgICAgPHRhYmxlIGlkPSJjbGllbnRJbmZvIiBjbGFzcz0iIj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij54VGVWZTo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPk9TOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJvcyIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkgcGhvbmUiPkRWUiBJUDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0iRFZSIiBjbGFzcz0idGRWYWwgcGhvbmUiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgIDwvdHI+CgogICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VVVJRDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0idXVpZCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkFyY2g6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9ImFyY2giIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5IHBob25lIj5NM1UgVVJMOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJtM3UtdXJsIiBjbGFzcz0idGRWYWwgcGhvbmUiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgIDwvdHI+CgogICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+QXZhaWxhYmxlIFN0cmVhbXM6PC90ZD4KICAgICAgICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5FUEcgU291cmNlOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJlcGdTb3VyY2UiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5IHBob25lIj5YRVBHIFVSTDo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0ieGVwZy11cmwiIGNsYXNzPSJ0ZFZhbCBwaG9uZSI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPC90cj4KCiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5YRVBHIENoYW5uZWxzOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJ4ZXBnIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+RXJyb3JzOjwvdGQ+CiAgICAgICAgICAgICAgPHRkIGlkPSJlcnJvcnMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5XYXJuaW5nczo8L3RkPgogICAgICAgICAgICAgIDx0ZCBpZD0id2FybmluZ3MiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPC90cj4KCiAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAKICAgICAgICAgIDxkaXYgaWQ9Im15U3RyZWFtc0JveCIgY2xhc3M9Im5vdFZpc2libGUiPgoKICAgICAgICAgICAgPGRpdiBpZD0iYWxsU3RyZWFtcyI+CiAgICAgICAgICAgICAgPHRhYmxlIGlkPSJhY3RpdmVTdHJlYW1zIj48L3RhYmxlPgogICAgICAgICAgICAgIDx0YWJsZSBpZD0iaW5hY3RpdmVTdHJlYW1zIj48L3RhYmxlPgogICAgICAgICAgICA8L2Rpdj4KCiAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIAogICAgICAgICAgPGRpdiBpZD0iY29udGVudCIgY2xhc3M9IiI+PC9kaXY+CiAgICAgICAgICAgIAogICAgICAgIDwvZGl2PgoKICAgICAgPC9kaXY+CiAgICAgIAogICAgPC9ib2R5PgogICAgCjwvaHRtbD4="
+ webUI["html/configuration.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImNzcy9iYXNlLmNzcyIgdHlwZT0idGV4dC9jc3MiPgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9jb25maWd1cmF0aW9uX3RzLmpzIj48L3NjcmlwdD4KICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL21lbnVfdHMuanMiPjwvc2NyaXB0PgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9zZXR0aW5nc190cy5qcyI+PC9zY3JpcHQ+CiAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2Jhc2VfdHMuanMiPjwvc2NyaXB0Pgo8L2hlYWQ+Cgo8Ym9keSBvbmxvYWQ9ImphdmFzY3JpcHQ6IHJlYWR5Rm9yQ29uZmlndXJhdGlvbigwKTsiPgoKICA8ZGl2IGlkPSJsb2FkaW5nIiBjbGFzcz0iYmxvY2siPgogICAgPGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj4KICA8L2Rpdj4KCiAgPGRpdiBpZD0iaGVhZGVyIiBjbGFzcz0iaW1nQ2VudGVyIj48L2Rpdj4KICA8ZGl2IGlkPSJib3giPgoKICAgIDx0YWJsZSBpZD0iY2xpZW50SW5mbyIgY2xhc3M9InZpc2libGUiPgogICAgICA8dHI+CiAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VmVyc2lvbjo8L3RkPgogICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPk9TOjwvdGQ+CiAgICAgICAgPHRkIGlkPSJvcyIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICA8L3RyPgogICAgICA8dHI+CiAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+VVVJRDo8L3RkPgogICAgICAgIDx0ZCBpZD0idXVpZCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkFyY2g6PC90ZD4KICAgICAgICA8dGQgaWQ9ImFyY2giIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgPC90cj4KICAgICAgPHRyPgogICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPlN0cmVhbXM6PC90ZD4KICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5EVlI6PC90ZD4KICAgICAgICA8dGQgaWQ9IkRWUiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICA8L3RyPgogICAgPC90YWJsZT4KCiAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj5Db25maWd1cmF0aW9uPC9oMT4KICAgIDwvZGl2PgogICAgPHAgaWQ9ImVyciIgY2xhc3M9ImVycm9yTXNnIGNlbnRlciI+PC9wPgogICAgPGRpdiBpZD0iY29udGVudCI+CgogICAgPC9kaXY+CiAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj4KICAgICAgPGlucHV0IGlkPSJuZXh0IiBjbGFzcz0iIiB0eXBlPSJidXR0b24iIG5hbWU9Im5leHQiIHZhbHVlPSJOZXh0IiBvbmNsaWNrPSJqYXZhc2NyaXB0OiBzYXZlV2l6YXJkKCk7Ij4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2JvZHk+Cgo8L2h0bWw+"
+ webUI["html/create-first-user.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImNzcy9iYXNlLmNzcyIgdHlwZT0idGV4dC9jc3MiPgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9uZXR3b3JrX3RzLmpzIj48L3NjcmlwdD4KICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0Pgo8L2hlYWQ+Cgo8Ym9keT4KCiAgPGRpdiBpZD0iaGVhZGVyIiBjbGFzcz0iaW1nQ2VudGVyIj48L2Rpdj4KCiAgPGRpdiBpZD0iYm94Ij4KCiAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj57ey5hY2NvdW50LmhlYWRsaW5lfX08L2gxPgogICAgPC9kaXY+CgogICAgPHAgaWQ9ImVyciIgY2xhc3M9ImVycm9yTXNnIGNlbnRlciI+PC9wPgoKICAgIDxkaXYgaWQ9ImNvbnRlbnQiPgoKICAgICAgPGZvcm0gaWQ9ImF1dGhlbnRpY2F0aW9uIiBhY3Rpb249IiIgbWV0aG9kPSJwb3N0Ij4KCiAgICAgICAgPGg1Pnt7LmFjY291bnQudXNlcm5hbWUudGl0bGV9fTo8L2g1PgogICAgICAgIDxpbnB1dCBpZD0idXNlcm5hbWUiIHR5cGU9InRleHQiIG5hbWU9InVzZXJuYW1lIiBwbGFjZWhvbGRlcj0iVXNlcm5hbWUiIHZhbHVlPSIiPgogICAgICAgIDxoNT57ey5hY2NvdW50LnBhc3N3b3JkLnRpdGxlfX06PC9oNT4KICAgICAgICA8aW5wdXQgaWQ9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgbmFtZT0icGFzc3dvcmQiIHBsYWNlaG9sZGVyPSJQYXNzd29yZCIgdmFsdWU9IiI+CiAgICAgICAgPGg1Pnt7LmFjY291bnQuY29uZmlybS50aXRsZX19OjwvaDU+CiAgICAgICAgPGlucHV0IGlkPSJjb25maXJtIiB0eXBlPSJwYXNzd29yZCIgbmFtZT0iY29uZmlybSIgcGxhY2Vob2xkZXI9IkNvbmZpcm0iIHZhbHVlPSIiPgoKICAgICAgPC9mb3JtPgoKICAgIDwvZGl2PgoKICAgIDxkaXYgaWQ9ImJveC1mb290ZXIiPgogICAgICA8aW5wdXQgaWQ9InN1Ym1pdCIgY2xhc3M9IiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0ie3suYnV0dG9uLmNyYWV0ZUFjY291bnR9fSIgb25jbGljaz0iamF2YXNjcmlwdDogbG9naW4oKTsiPgogICAgPC9kaXY+CgoKICA8L2Rpdj4KPC9ib2R5PgoKPC9odG1sPg=="
+ webUI["html/css/base.css"] = "KiB7CiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lOwogIC1tb3otYXBwZWFyYW5jZTogbm9uZTsKICAtbXMtYXBwZWFyYW5jZTogbm9uZTsKICBmb250LWZhbWlseTogIkFyaWFsIiwgc2Fucy1zZXJpZjsKICBsZXR0ZXItc3BhY2luZzogMnB4Owp9CgovKgo6Oi13ZWJraXQtc2Nyb2xsYmFyIHsgCiAgICBkaXNwbGF5OiBub25lOyAKfQoqLwoKOjotd2Via2l0LXNjcm9sbGJhciB7CiAgd2lkdGg6IDEycHg7CiAgaGVpZ2h0OiAxMnB4Owp9CgoKOjotd2Via2l0LXNjcm9sbGJhci10cmFjayB7CiAgLXdlYmtpdC1ib3gtc2hhZG93OiBpbnNldCAwIDAgNnB4IHJnYmEoMCwgMCwgMCwgMC4zKTsKICBib3gtc2hhZG93OiBpbnNldCAwIDAgNnB4IHJnYmEoMCwgMCwgMCwgMC4zKTsKICBib3JkZXItcmFkaXVzOiA1cHg7Cgp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHsKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgLXdlYmtpdC1ib3gtc2hhZG93OiBpbnNldCAwIDAgNnB4IHJnYmEoMCwgMCwgMCwgMC42KTsKICBib3gtc2hhZG93OiBpbnNldCAwIDAgNnB4IHJnYmEoMCwgMCwgMCwgMC42KTsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0Owp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iOmhvdmVyIHsKICBiYWNrZ3JvdW5kOiAjMzMzOwp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLWNvcm5lciB7CiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7Cn0KCmEgewogIGNvbG9yOiAjMDBFNkZGOwp9CgpodG1sLApib2R5IHsKICBjb2xvcjogI2ZmZjsKICBtYXJnaW46IDBweCBhdXRvOwogIGhlaWdodDogMTAwJTsKICBmb250LXNpemU6IDE0cHg7Cn0KCmgyIHsKICBmb250LXNpemU6IDI0cHg7CiAgbGV0dGVyLXNwYWNpbmc6IDJweDsKfQoKaDMgewogIGZvbnQtc2l6ZTogMjJweDsKICBsZXR0ZXItc3BhY2luZzogMXB4Owp9CgpoNCB7CiAgZm9udC1zaXplOiAyMHB4OwogIGxldHRlci1zcGFjaW5nOiAxcHg7CiAgbGluZS1oZWlnaHQ6IDEuNWVtOwoKfQoKaDUgewogIGZvbnQtc2l6ZTogMTZweDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIGxpbmUtaGVpZ2h0OiAxLjJlbTsKICBtYXJnaW46IDI1cHggMHB4IDEwcHggMHB4Owp9CgpociB7CiAgYm9yZGVyOiAwOwogIGhlaWdodDogMXB4OwogIGJhY2tncm91bmQ6ICMzMzM7CiAgbWFyZ2luOiAxMHB4IDBweDsKfQoKcCB7CiAgbWFyZ2luOiAycHg7CiAgcGFkZGluZzogMnB4IDVweDsKfQoKcHJlIHsKICBtYXJnaW46IDBweCAwcHggNXB4IDBweDsKICBmb250LXNpemU6IDEycHg7CiAgY29sb3I6ICNkZGQ7CiAgbGV0dGVyLXNwYWNpbmc6IDFweDsKICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXNpemU6IDEycHg7CiAgZm9udC1zdHlsZTogbm9ybWFsOwogIGZvbnQtdmFyaWFudDogbm9ybWFsOwogIGxpbmUtaGVpZ2h0OiAxLjZlbTsKfQoKbGFiZWwgewogIG1hcmdpbi1ib3R0b206IDIwcHg7CiAgZGlzcGxheTogYmxvY2s7Cn0KCmxpIHsKICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBwYWRkaW5nOiAxMHB4IDIwcHg7CiAgY3Vyc29yOiBwb2ludGVyOwogIGJvcmRlci1sZWZ0OiBzb2xpZCAycHggIzExMTsKICB0cmFuc2l0aW9uOiBhbGwgMC4zOwp9CgpsaTpob3ZlciB7CiAgYm9yZGVyLWNvbG9yOiAjMDBFNkZGCn0KCnNlbGVjdCB7CiAgY3Vyc29yOiBwb2ludGVyOwogIHdpZHRoOiBjYWxjKDEwMCUgKyAycHgpOwogIGJvcmRlcjogc29saWQgMHB4ICMwMEU2RkY7CiAgYm9yZGVyLXJhZGl1czogMHB4OwogIG91dGxpbmU6IG5vbmU7CiAgY29sb3I6ICNmZmY7CiAgcGFkZGluZzogOXB4IDEwcHg7CiAgZGlzcGxheTogYmxvY2s7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBmb250LXNpemU6IDE0cHg7CiAgbWFyZ2luOiA1cHggMHB4IDVweCAwcHg7Cn0KCnNlbGVjdDpmb2N1cyB7CiAgb3V0bGluZTogbm9uZTsKfQoKaW5wdXQgewogIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTsKICBtYXJnaW46IDVweCAwcHg7CiAgcGFkZGluZzogMi41cHggMTBweDsKICBvdXRsaW5lOiBub25lOwogIGZvbnQtc2l6ZTogMTRweDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLAppbnB1dFt0eXBlPXN1Ym1pdF0gewogIGN1cnNvcjogcG9pbnRlcjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIG1hcmdpbjogMTBweCAxMHB4OwogIHBhZGRpbmc6IDEwcHggMjVweDsKICBib3JkZXI6IHNvbGlkIDBweDsKICBib3JkZXItY29sb3I6ICMwMDA7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIG91dGxpbmU6IG5vbmU7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXTpmb2N1cyB7CiAgb3V0bGluZTogbm9uZTsKfQoKaW5wdXRbdHlwZT1idXR0b25dOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDBFNkZGOwogIGNvbG9yOiAjMDAwOwp9CgppbnB1dFt0eXBlPWJ1dHRvbl06aG92ZXIuZGVsZXRlIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9dGV4dF0sCmlucHV0W3R5cGU9c2VhcmNoXSwKaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIGNvbG9yOiAjZmZmOwogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDBweCk7CiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMHB4KTsKICB3aWR0aDogY2FsYygxMDAlIC0gMHB4KTsKICBvdXRsaW5lOiBub25lOwogIGJvcmRlcjogc29saWQgMXB4IHRyYW5zcGFyZW50OwogIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OwogIGJvcmRlci1ib3R0b20tY29sb3I6ICM1NTU7CiAgYm9yZGVyLXJhZGl1czogMHB4OwogIHBhZGRpbmc6IDhweCAxMHB4Owp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdIHsKICBib3JkZXI6IHNvbGlkIDFweCAjMDBFNkZGOwogIGJhY2tncm91bmQtY29sb3I6ICMzMzM7CiAgaGVpZ2h0OiAyNXB4OwogIHdpZHRoOiAyNXB4OwogIGN1cnNvcjogcG9pbnRlcjsKICAvKgogIC13ZWJraXQtYXBwZWFyYW5jZTogY2hlY2tib3g7CiAgKi8KfQoKaW5wdXRbdHlwZT0iY2hlY2tib3giXTpjaGVja2VkIHsKICBjb2xvcjogI2ZmZjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDBFNkZGOwogIC8qZGlzcGxheTogaW5saW5lLWJsb2NrOyovCn0KCmlucHV0W3R5cGU9ImNoZWNrYm94Il06YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC00cHg7CiAgY29udGVudDogIiAiOwp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdOmNoZWNrZWQ6YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC0zcHg7CiAgY29udGVudDogIuKckyI7CiAgY29sb3I6ICMwMDA7Cn0KCgppbnB1dFt0eXBlPWJ1dHRvbl0uY2FuY2VsIHsKCiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7CiAgYm9yZGVyLWNvbG9yOiByZWQ7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXS5zYXZlIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwogIGZsb2F0OiByaWdodDsKfQoKCmlucHV0W3R5cGU9YnV0dG9uXS5ibGFjaywKaW5wdXRbdHlwZT1zdWJtaXRdLmJsYWNrIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIGJvcmRlci1jb2xvcjogIzAwMDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLmNlbnRlciB7CiAgbWFyZ2luLXJpZ2h0OiBhdXRvOwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIGJhY2tncm91bmQtY29sb3I6ICMwMDA7CiAgYm9yZGVyLWNvbG9yOiAjMDAwOwp9CgoucG9pbnRlciB7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgoucG9pbnRlcjpob3ZlciB7CiAgY29sb3I6ICMwMEU2RkY7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgouc29ydFRoaXMgewogIGNvbG9yOiAjMDBFNkZGOwp9CgoudzQwcHggewogIG1heC13aWR0aDogNDBweDsKfQoKLnc1MHB4IHsKICBtYXgtd2lkdGg6IDUwcHg7Cn0KCi53ODBweCB7CiAgbWF4LXdpZHRoOiA4MHB4Owp9CgoudzE1MHB4IHsKICBtYXgtd2lkdGg6IDE1MHB4Owp9CgoudzIwMHB4IHsKICBtYXgtd2lkdGg6IDIwMHB4OwogIG1pbi13aWR0aDogMTAwcHg7CiAgd2lkdGg6IDIwMHB4OwogIG92ZXJmbG93LXg6IGhpZGRlbjsKICB3aGl0ZS1zcGFjZTogbm93cmFwOwogIG92ZXJmbG93OiBoaWRkZW47CiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7Cn0KCi53MzAwcHggewogIG1heC13aWR0aDogMzAwcHg7Cn0KCi53MjIwcHggewogIG1heC13aWR0aDogMjIwcHg7CiAgY3Vyc29yOiBhbGlhczsKfQoKLmZvb3RlciB7CiAgZm9udC1zaXplOiAxMHB4Owp9CgouY2VudGVyIHsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5zY3JlZW5Mb2dIaWRkZW4gewogIHRyYW5zZm9ybTogdHJhbnNsYXRlKDBweCwgLTExMHB4KTsKfQoKLmJvcmRlclNwYWNlIHsKICBtYXJnaW4tYm90dG9tOiAzMHB4Owp9Cgoubm9uZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKLm5vdFZpc2libGUgewogIGhlaWdodDogMHB4OwogIGRpc3BsYXk6IG5vbmU7CiAgb3BhY2l0eTogMDsKICBib3JkZXItYm90dG9tOiAjMDAwIHNvbGlkIDBweDsKCn0KCi52aXNpYmxlIHsKICBvcGFjaXR5OiAxOwogIGRpc3BsYXk6IGJsb2NrOwogIGJvcmRlci1ib3R0b206ICM0NDQgc29saWQgMXB4OwogIHBhZGRpbmc6IDEwcHg7Cn0KCi5mbG9hdFJpZ2h0IHsKICBmbG9hdDogcmlnaHQ7Cn0KCi5mbG9hdExlZnQgewogIGZsb2F0OiBsZWZ0Owp9CgoubWVudS1hY3RpdmUgewogIGJhY2tncm91bmQtY29sb3I6ICMwMEU2RkY7Cn0KCiNicmFuY2ggewogIGRpc3BsYXk6IHRhYmxlOwogIG1hcmdpbjogYXV0bzsKICBjb2xvcjogcmVkOwp9CgojaW50ZXJhY3Rpb24gewogIG1hcmdpbi1ib3R0b206IDEwMHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBib3JkZXItYm90dG9tOiBzb2xpZCAwcHggIzc3NzsKfQoKCi5oYWxmIHsKICBkaXNwbGF5OiBibG9jazsKICB3aWR0aDogNDUlOwp9CgoubWVudSB7CiAgYm9yZGVyOiBzb2xpZCAxcHggIzAwRTZGRjsKfQoKLmluZm9Nc2cgewogIGNvbG9yOiAjYWFhOwp9CgouZXJyb3JNc2cgewogIGNvbG9yOiByZWQ7Cn0KCi53YXJuaW5nTXNnIHsKICBjb2xvcjogeWVsbG93Owp9CgouZGVidWdNc2cgewogIGNvbG9yOiBtYWdlbnRhOwp9CgouTmV3cywKLk1vdmllLAouU2VyaWVzLAouU3BvcnRzLAouS2lkcyB7CiAgYm9yZGVyLWxlZnQ6IHNvbGlkIDJweAp9CgouTmV3cyB7CiAgYm9yZGVyLWNvbG9yOiB0b21hdG8KfQoKLk1vdmllIHsKICBib3JkZXItY29sb3I6IHJveWFsYmx1ZTsKfQoKLlNlcmllcyB7CiAgYm9yZGVyLWNvbG9yOiBnb2xkOwp9CgouU3BvcnRzIHsKICBib3JkZXItY29sb3I6IHllbGxvd2dyZWVuOwp9CgouS2lkcyB7CiAgYm9yZGVyLWNvbG9yOiBtZWRpdW1wdXJwbGU7Cn0KCi8qIExvYWRpbmcgKi8KI2xvYWRpbmcgewogIGxlZnQ6IDBweDsKICB0b3A6IDBweDsKICB6LWluZGV4OiAxMDAwMDsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjgpOwogIG1hcmdpbjogYXV0bzsKICB3aWR0aDogMTAwJTsKICBoZWlnaHQ6IDEwMCU7Cn0KCgoubG9hZGVyIHsKICBib3JkZXI6IDVweCBzb2xpZCB0cmFuc3BhcmVudDsKICBib3JkZXItcmFkaXVzOiA1MCU7CiAgYm9yZGVyLXRvcDogNXB4IHNvbGlkICMwMEU2RkY7CiAgYm9yZGVyLWJvdHRvbTogNXB4IHNvbGlkICMwMEU2RkY7CiAgd2lkdGg6IDUwcHg7CiAgaGVpZ2h0OiA1MHB4OwogIC13ZWJraXQtYW5pbWF0aW9uOiBzcGluIDEuMnMgbGluZWFyIGluZmluaXRlOwogIGFuaW1hdGlvbjogc3BpbiAxLjJzIGxpbmVhciBpbmZpbml0ZTsKCiAgcG9zaXRpb246IGZpeGVkOwogIG1hcmdpbjogYXV0bzsKCiAgdG9wOiAwOwogIHJpZ2h0OiAwOwogIGJvdHRvbTogMDsKICBsZWZ0OiAwOwoKfQoKQC13ZWJraXQta2V5ZnJhbWVzIHNwaW4gewogIDAlIHsKICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7CiAgfQoKICAxMDAlIHsKICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTsKICB9Cn0KCkBrZXlmcmFtZXMgc3BpbiB7CiAgMCUgewogICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7CiAgfQoKICAxMDAlIHsKICAgIHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7CiAgfQp9"
+ webUI["html/css/screen.css"] = "bmF2IGltZyB7CiAgZGlzcGxheTogYmxvY2s7CiAgbWF4LWhlaWdodDogMjBweDsKICBtYXgtd2lkdGg6IDIwcHg7CiAgZmxvYXQ6IGxlZnQ7Cn0KCm5hdiBwIHsKICB0ZXh0LWFsaWduOiBsZWZ0OwogIHBhZGRpbmc6IDBweCAzMHB4Owp9CgojbGF5b3V0IHsKICBkaXNwbGF5OiBibG9jazsKICBoZWlnaHQ6IDEwMCU7Cn0KCgoubGF5b3V0LWxlZnQgewogIGRpc3BsYXk6IGJsb2NrOwogIG1pbi13aWR0aDogMTUwcHg7CiAgbWF4LXdpZHRoOiAyMCU7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBoZWlnaHQ6IGluaGVyaXQ7CiAgZmxvYXQ6IGxlZnQ7Cn0KCi5sYXlvdXQtcmlnaHQgewogIGRpc3BsYXk6IGJsb2NrOwogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7Cn0KCiNtZW51LXdyYXBwZXIgewogIGhlaWdodDogMTAwJTsKfQoKCiNsb2dvIHsKICBkaXNwbGF5OiBibG9jazsKICBtaW4td2lkdGg6IDE4MHB4OwogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvbG9nb193XzYwMHgyMDAucG5nIik7CiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7CiAgYmFja2dyb3VuZC1zaXplOiAxMDAlOwp9CgoKI3BhZ2UgewogIG1heC13aWR0aDogOTUwcHg7CiAgbWFyZ2luOiBhdXRvOwogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7CgogIC8qCiAgaGVpZ2h0OiAtd2Via2l0LWNhbGMoMTAwJSAtIDEzMHB4KTsKICBoZWlnaHQ6IC1tb3otY2FsYygxMDAlIC0gMTMwcHgpOwogIGhlaWdodDogY2FsYygxMDAlIC0gMTMwcHgpOwogICovCgogIG1pbi1oZWlnaHQ6IC13ZWJraXQtY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IC1tb3otY2FsYygxMDAlIC0gMTIwcHgpOwogIG1pbi1oZWlnaHQ6IGNhbGMoMTAwJSAtIDEyMHB4KTsKCgogIGJveC1zaGFkb3c6IDBweCA1cHggNXB4ICMyMjI7Cgp9CgojdWlTZXR0aW5nIHsKICBmbG9hdDogcmlnaHQ7CiAgbWFyZ2luLXJpZ2h0OiAyNXB4Owp9CgojYm94IGlucHV0W3R5cGU9dGV4dF0sCiNib3ggaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiAtbW96LWNhbGMoMTAwJSAtIDIwcHgpOwogIHdpZHRoOiBjYWxjKDEwMCUgLSAyMHB4KTsKfQoKI2JveCBpbnB1dFt0eXBlPXN1Ym1pdF0gewogIG1hcmdpbjogNTBweCBhdXRvOwp9Cgojc2V0dGluZ3MgewogIGRpc3BsYXk6IGJsb2NrOwogIHBhZGRpbmc6IDEwcHggMTBweDsKfQoKI3NldHRpbmdzIGg1IHsKICBtYXJnaW46IDUwcHggMHB4IDEwcHggMHB4Owp9CgojY29udGVudC1pbnRlcmFjdGlvbiAuc2VhcmNoIHsKICB3aWR0aDogMjAwcHg7CiAgYm9yZGVyOiAxcHggc29saWQgIzAwMDsKICBwYWRkaW5nOiA5cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBtYXJnaW46IDEwcHg7CiAgZmxvYXQ6IHJpZ2h0OwogIGJvcmRlci1yYWRpdXM6IDNweDsKCn0KCiNteVN0cmVhbXMgewogIHBvc2l0aW9uOiBmaXhlZDsKICBib3R0b206IDBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwogIHdpZHRoOiAxMDAlOwogIG1heC13aWR0aDogOTUwcHg7CgogIC8qCiAgbWF4LWhlaWdodDogMTAwcHg7CiAgKi8KICBtYXJnaW4tYm90dG9tOiAwcHg7Cn0KCiNteVN0cmVhbXMgaW1nIHsKICB3aWR0aDogNCU7CiAgcGFkZGluZzogMnB4IDVweDsKICBjdXJzb3I6IHBvaW50ZXI7CiAgZmxvYXQ6IHJpZ2h0Owp9CgovKiBXaXphcmQqLwojYm94IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwogIG1pbi1oZWlnaHQ6IDQwMHB4OwoKICBkaXNwbGF5OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOwp9CgojYm94IHAgewogIHBhZGRpbmc6IDEwcHggMHB4Owp9CgojYm94LWZvb3RlciB7CiAgbWFyZ2luLXRvcDogYXV0bzsKfQoKI2JveC1mb290ZXIgewogIG1hcmdpbjogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgojaGVhZGxpbmUgewogIGJhY2tncm91bmQtY29sb3I6ICMyMjI7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMnB4ICMyMjI7CiAgdHJhbnNpdGlvbjogYWxsIDAuNXM7CiAgcGFkZGluZzogMTBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7Cn0KCiNjb250ZW50IHsKICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdzogYXV0bzsKICBwYWRkaW5nOiAxMHB4Owp9CgovKiAtLS0gKi8KCgojY2xpZW50SW5mbywKI2FjdGl2ZVN0cmVhbXMsCiNpbmFjdGl2ZVN0cmVhbXMgewogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgZGlzcGxheTogYmxvY2s7CiAgZm9udC1zaXplOiA5cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBjb2xvcjogIzAwRTZGRjsKICBib3JkZXItYm90dG9tOiBzb2xpZCAwcHg7CiAgOwogIHBhZGRpbmc6IDBweDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIG92ZXJmbG93LXg6IGhpZGRlbjsKICBib3JkZXItc3BhY2luZzogNHB4IDRweDsKICBib3JkZXItYm90dG9tOiBzb2xpZCAxcHggIzQ0NDsKfQoKI215U3RyZWFtc0JveCB7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHBhZGRpbmc6IDBweDsKICAvKmhlaWdodDogMTAwcHg7Ki8KICBtYXgtaGVpZ2h0OiAxNTBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTExOwogIGNvbG9yOiB3aGl0ZTsKICBkaXNwbGF5OiBmbGV4OwogIGp1c3RpZnktY29udGVudDogY2VudGVyOwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7Cn0KCiNvcGVuU3RyZWFtcyB7CiAgd2lkdGg6IDIwcHg7CiAgaGVpZ2h0OiAyMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBmbG9hdDogcmlnaHQ7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHJpZ2h0OiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvdG91Y2gucG5nIik7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKCiAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0Owp9CgojYWxsU3RyZWFtcyB7CiAgd2lkdGg6IDEwMCU7CiAgaGVpZ2h0OiAxMDAlOwogIHBhZGRpbmc6IDJweDsKfQoKI2FjdGl2ZVN0cmVhbXMsCiNpbmFjdGl2ZVN0cmVhbXMgewogIG92ZXJmbG93LXk6IHNjcm9sbDsKICB3aWR0aDogNTAlOwogIG1heC1oZWlnaHQ6IDEwMHB4OwogIGZsb2F0OiBsZWZ0Owp9CgojYWN0aXZlU3RyZWFtcyAudGRLZXksCiNpbmFjdGl2ZVN0cmVhbXMgLnRkS2V5IHsKICB3aWR0aDogNzVweDsKfQoKCgoKI2luYWN0aXZlU3RyZWFtcyAudGRLZXkgewogIGNvbG9yOiByZWQ7Cn0KCiNjbGllbnRJbmZvIC50ZFZhbCwKI2xvZ0luZm8gLnRkVmFsLAojYWN0aXZlU3RyZWFtcyAudGRWYWwsCiNpbmFjdGl2ZVN0cmVhbXMgLnRkVmFsLAojbWFwcGluZ0luZm8gLnRkVmFsIHsKICBjb2xvcjogI2FhYTsKICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsKfQoKI2NsaWVudEluZm8gLnRkVmFsTGluaywKI2xvZ0luZm8gLnRkVmFsTGluaywKI2FjdGl2ZVN0cmVhbXMgLnRkVmFsTGluaywKI2luYWN0aXZlU3RyZWFtcyAudGRWYWxMaW5rLAojbWFwcGluZ0luZm8gLnRkVmFsTGluayB7CiAgY29sb3I6IGxpbWU7CiAgd2hpdGUtc3BhY2U6IGluaGVyaXQ7Cn0KCiNib3gtd3JhcHBlciB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIHdpZHRoOiAxMDAlOwoKICBvdmVyZmxvdy15OiBzY3JvbGw7Cn0KCiNjb250ZW50X3RhYmxlLAojbWFwcGluZy1kZXRhaWwtdGFibGUsCiNjb250ZW50X3RhYmxlIHsKICBkaXNwbGF5OiB0YWJsZTsKCiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKICBvdmVyZmxvdy15OiBzY3JvbGw7CiAgd2lkdGg6IDEwMCU7Cn0KCgojY29udGVudF90YWJsZSAuY29udGVudF90YWJsZV9oZWFkZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMzMzM7CiAgaGVpZ2h0OiA1MHB4OwogIGJvcmRlci1ib3R0b206IHNvbGlkIDFweCAjMTExOwogIGJvcmRlci1sZWZ0OiBzb2xpZCAzcHggIzMzMzsKICBjdXJzb3I6IGF1dG87Cgp9CgoKdGJvZHkgewogIHdpZHRoOiAxMDAlOwp9CgoKLnRhYmxlRWxsaXBzaXMgewogIHdpZHRoOiAxNTBweDsKICBvdmVyZmxvdzogaGlkZGVuOwogIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzOwogIHdoaXRlLXNwYWNlOiBub3dyYXA7Cn0KCiNjb250ZW50X3RhYmxlIGltZyB7CiAgZGlzcGxheTogYmxvY2s7CiAgbWF4LWhlaWdodDogMjhweDsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87CiAgbWF4LXdpZHRoOiAzMHB4Owp9CgojY29udGVudF90YWJsZSB0ciB7CiAgYm9yZGVyLWxlZnQ6IHNvbGlkIDNweCA0NDQ7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMXB4ICMzMzM7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgojY29udGVudF90YWJsZSB0cjpob3ZlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKfQoKI2NvbnRlbnRfdGFibGUgdGQgewoKICBwYWRkaW5nOiAwcHggMnB4Owp9CgojY29udGVudF90YWJsZSBpbnB1dFt0eXBlPXRleHRdIHsKICB3aWR0aDogODAlOwogIG1pbi13aWR0aDogMzVweDsKICBtYXgtd2lkdGg6IDYwcHg7CiAgYm9yZGVyOiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBtYXJnaW4tbGVmdDogNXB4OwogIHRleHQtYWxpZ246IGxlZnQ7Cn0KCiNjb250ZW50X3RhYmxlIGlucHV0W3R5cGU9Y2hlY2tib3hdIHsKICBtYXgtd2lkdGg6IDI1cHg7CiAgbWFyZ2luOiBhdXRvOwp9CgoKLnNob3dCdWxrIHsKICBkaXNwbGF5OiBibG9jazsKfQoKLmhpZGVCdWxrIHsKICBkaXNwbGF5OiBub25lOwp9CgojY29udGVudF90YWJsZSB0ci5hY3RpdmVFUEcgewogIGJvcmRlci1sZWZ0OiBzb2xpZCAzcHggbGF3bmdyZWVuOwp9CgojY29udGVudF90YWJsZSB0ci5ub3RBY3RpdmVFUEcgewogIGJvcmRlci1sZWZ0OiBzb2xpZCAzcHggcmVkOwp9CgoKI2xvZ1NjcmVlbiBwIHsKICB3aGl0ZS1zcGFjZTogcHJlOwogIGZvbnQtc2l6ZTogMTBweDsKICAvKgogIGxpbmUtaGVpZ2h0OiAxLjZlbTsKICBmb250LWZhbWlseTogIkFyaWFsIiwgc2Fucy1zZXJpZjsKICAqLwogIGxldHRlci1zcGFjaW5nOiAxcHg7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXNpemU6IDEycHg7CiAgZm9udC1zdHlsZTogbm9ybWFsOwogIGZvbnQtdmFyaWFudDogbm9ybWFsOwogIGxpbmUtaGVpZ2h0OiAxLjZlbTsKfQoKI3BvcHVwIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNCk7CiAgcG9zaXRpb246IGZpeGVkOwogIGxlZnQ6IDBweDsKICB3aWR0aDogMTAwJTsKICB6LWluZGV4OiAxMDA7CiAgaGVpZ2h0OiAxMDAlOwogIG92ZXJmbG93OiBzY3JvbGw7Cn0KCiNtYXBwaW5nLWRldGFpbCwKI3VzZXItZGV0YWlsLAojZmlsZS1kZXRhaWwsCiNwb3B1cC1jdXN0b20gewogIGJveC1zaGFkb3c6IDBweCA1cHggNDBweCAjMDAwOwogIG1hcmdpbi10b3A6IDIwcHg7CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgbWFyZ2luLXJpZ2h0OiBhdXRvOwoKICBtYXgtd2lkdGg6IDgwMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMyMjI7CiAgcGFkZGluZzogMTBweDsKICBvdmVyZmxvdzogYXV0bzsKfQoKI3BvcHVwLWN1c3RvbSBoMyB7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgojZmlsZS1kZXRhaWwgaW5wdXRbdHlwZT10ZXh0XSB7CiAgd2lkdGg6IC13ZWJraXQtY2FsYygxMDAlIC0gMjBweCk7CiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMjBweCk7CiAgd2lkdGg6IGNhbGMoMTAwJSAtIDIwcHgpOwp9CgojbWFwcGluZy1kZXRhaWwgaW1nIHsKICBkaXNwbGF5OiBibG9jazsKICBtYXgtaGVpZ2h0OiAzMHB4OwogIG1hcmdpbi1ib3R0b206IDIwcHg7CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgbWFyZ2luLXJpZ2h0OiBhdXRvOwp9CgojcG9wdXAtY3VzdG9tIGlucHV0W3R5cGU9dGV4dF0sCiNwb3B1cC1jdXN0b20gaW5wdXRbdHlwZT1wYXNzd29yZF0sCiNtYXBwaW5nLWRldGFpbCBpbnB1dFt0eXBlPXRleHRdLAojY29udGVudF9zZXR0aW5ncyBpbnB1dFt0eXBlPXRleHRdLAojY29udGVudF9zZXR0aW5ncyBpbnB1dFt0eXBlPXBhc3N3b3JkXSB7CiAgYm9yZGVyOiBzb2xpZCAxcHg7CiAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzMzOwogIHRleHQtYWxpZ246IGxlZnQ7CiAgd2lkdGg6IC13ZWJraXQtY2FsYygxMDAlIC0gMjBweCk7CiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMjBweCk7CiAgd2lkdGg6IGNhbGMoMTAwJSAtIDIwcHgpOwp9CgojcG9wdXAtY3VzdG9tIGlucHV0W3R5cGU9dGV4dF0ubm90QXZhaWxhYmxlIHsKICBib3JkZXItY29sb3I6IHJlZDsKICBjb2xvcjogIzY2NjsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9CgojcG9wdXAtY3VzdG9tIGlucHV0W3R5cGU9dGV4dF06ZGlzYWJsZWQgewogIGNvbG9yOiAjNjY2OwogIGN1cnNvcjogbm90LWFsbG93ZWQ7Cn0KCiNtYXBwaW5nLWRldGFpbC10YWJsZSwKI3VzZXItZGV0YWlsLXRhYmxlIHsKICBkaXNwbGF5OiBpbmxpbmUtdGFibGU7CiAgd2lkdGg6IDEwMCU7Cn0KCiNwb3B1cC1jdXN0b20gdGFibGUsCiNjb250ZW50X3NldHRpbmdzIHRhYmxlIHsKICBkaXNwbGF5OiBpbmxpbmUtdGFibGU7CiAgdGFibGUtbGF5b3V0OiBmaXhlZDsKICB3aWR0aDogMTAwJTsKfQoKCiNtYXBwaW5nLWRldGFpbC10YWJsZSB0ZCwKI3VzZXItZGV0YWlsLXRhYmxlIHRkIHsKICBwYWRkaW5nOiAxMHB4IDBweDsKCn0KCiNtYXBwaW5nLWRldGFpbC10YWJsZSB0ZC5sZWZ0LAojdXNlci1kZXRhaWwtdGFibGUgdGQubGVmdCwKI3BvcHVwLWN1c3RvbSB0ZC5sZWZ0IHsKICB3aWR0aDogMzglOwp9CgouaW50ZXJhY3Rpb24sCiNpbnRlcmFjdGlvbiB7CiAgbWFyZ2luLXRvcDogMjBweDsKICBkaXNwbGF5OiBpbmxpbmUtZmxleDsKICBmbG9hdDogcmlnaHQ7Cn0KCi5pbnRlcmFjdGlvbiBpbnB1dFt0eXBlPWJ1dHRvbl0sCi5pbnRlcmFjdGlvbiBpbnB1dFt0eXBlPXN1Ym1pdF0gewogIGJhY2tncm91bmQtY29sb3I6ICMwMDA7CiAgbWluLXdpZHRoOiAxMDBweDsKICBtYXJnaW46IDBweCAxMHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKI25vdGlmaWNhdGlvbiB7CiAgZGlzcGxheTogYmxvY2s7CiAgcG9zaXRpb246IGZpeGVkOwogIHJpZ2h0OiAwcHg7CiAgaGVpZ2h0OiAxMDAlOwogIHdpZHRoOiAyNTBweDsKCiAgYmFja2dyb3VuZC1jb2xvcjogIzIyMjsKICBib3gtc2hhZG93OiAwcHggMHB4IDIwcHggIzAwMDsKfQoKI25vdGlmaWNhdGlvbiBoNSB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMTIxMjsKICBwYWRkaW5nOiA1cHggMTBweCA1cHggMTBweDsKfQoKI25vdGlmaWNhdGlvbiBwcmUgewogIHBhZGRpbmc6IDBweCAxMHB4IDBweCAxMHB4Owp9Cgojbm90aWZpY2F0aW9uIHAgewogIGZvbnQtc2l6ZTogMTAgcHg7CiAgbWFyZ2luOiAwcHg7CiAgcGFkZGluZzogMHB4IDEwcHggNXB4IDEwcHg7Cn0KCiNub3RpZmljYXRpb24gLmVsZW1lbnQgewogIC8qcGFkZGluZzogMHB4IDVweDsqLwogIG1hcmdpbjogNXB4IDVweDsKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzE4MTgxODsKICBib3JkZXItbGVmdDogMTBweCBzb2xpZCBncmVlbjsKfQoKCkBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjIwcHgpIHsKICBib2R5IHsKICAgIHdpZHRoOiAxMDAlOwogICAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICB9CgogIGgxIHsKICAgIGZvbnQtc2l6ZTogMjZweDsKICAgIGxldHRlci1zcGFjaW5nOiAzcHg7CiAgfQoKICBuYXYgcCB7CiAgICBkaXNwbGF5OiBibG9jazsKICB9CgoKCiAgI2hlYWRlcl9jb25maWcgewogICAgZGlzcGxheTogYmxvY2s7CiAgICBoZWlnaHQ6IDEwMHB4OwogICAgYmFja2dyb3VuZDogdXJsKCIuLi9pbWcvbG9nb193XzYwMHgyMDAucG5nIik7CiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0OwoKICAgIGJhY2tncm91bmQtc2l6ZTogMzAwcHggMTAwcHg7CiAgfQoKICAjc2NyZWVuTG9nIHsKICAgIG1hcmdpbi1sZWZ0OiAzMDBweDsKCiAgICB0cmFuc2l0aW9uOiBub25lOwogICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7CiAgICBib3JkZXItYm90dG9tOiBzb2xpZCAxcHggdHJhbnNwYXJlbnQ7CiAgICBib3gtc2hhZG93OiAwcHggMHB4IDBweCAjMjIyOwogIH0KCiAgI3NldHRpbmdzIHsKICAgIC8qCiAgICBoZWlnaHQ6IC13ZWJraXQtY2FsYygxMDAlIC0gMTAwcHgpOwogICAgaGVpZ2h0OiAtbW96LWNhbGMoMTAwJSAtIDEwMHB4KTsKICAgIGhlaWdodDogY2FsYygxMDAlIC0gMTAwcHgpOwogICAgKi8KICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgIG92ZXJmbG93OiBhdXRvOwogIH0KCgogIC5zY3JlZW5Mb2dIaWRkZW4gewogICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMHB4LCAwcHgpOwogIH0KCgogICNib3ggewogICAgZGlzcGxheTogYmxvY2s7CiAgICBtaW4taGVpZ2h0OiA1MDBweDsKICAgIG1heC13aWR0aDogNTAwcHg7CiAgICBtYXJnaW46IDEwcHggYXV0bzsKICAgIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7CiAgICBib3gtc2hhZG93OiAwcHggNXB4IDVweCAjMjIyOwoKICAgIGRpc3BsYXk6IGZsZXg7CiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIH0KCn0="
+ webUI["html/favicon.ico"] = "AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAKBEAAJ4EAAAwMAAAAQAgAGgmAADGFQAAKAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO2cIH7unCD57pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg+e2cIH7unCD57pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD57pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unSP/7p0k/+6cIP/voSz/7pwg/+6fJv/unSP/7p4k/+6cIP/unCD/7pwh/+6eJP/unCD/7pwg/+6cIP/unSP/+Nmr//vpzv/zumT/++nO/++hK//87tr/99Se//rkwv/30JX/9s2P//zt1//41qL/9ceC/+6cIP/unCD/7p0i//nds//30Zj/7qAo//rmx//unib/++vS//bMjP/54Lv/9suK//TAcf/758n/8Kg6/++gKv/unCD/7pwg/+6cIf/1xn//8rJS/++iLf/30Zn/8Kk+//GuSf/0wnX/9MBx//GsRP/xr0z/+d20//fTnP/wpjj/7pwg/+6cIP/unCD/7pwg/+6cIP/yt13/+d62//ndsv/0v3D/7pwg/+6cIP/unCD/7pwg//ncsP/53rb/9cmF/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unSP/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg+e6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg+e2cIH7unCD57pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg+e2cIH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAALsmiF87pwg5u6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg5uyaIXz/gAAC7JwhfO6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+ycIXzunCDm7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg5u6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/76Es/+6cIP/uoCn/7p4m/+6cIP/unCD/8KxE/++iLf/unCD/7pwg/+6cIf/wpzj/76It/+6cIP/unCD/76Qy/+6cIP/unCD/7pwg/+6cIP/unCD/7p0j/++iL//unSL/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/++hLf/99ej/9MBy//747//++fL/871r/+6cIP/88d//+eC5/+6cIP/uniT/++nO/////////v7/+uPA//CrQv/++vT/+uC5/+6fJv/wq0L/76Mv//fRl//++/X///////769P/31aD/7p8n/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//K0WP///fv///36//K3Xf/87NT/76Qy//zt1//758r/7pwg//GtR///////99Kb//CnOf/1x4L//fXo//316f/30pr//O/b//3y4v/99ur///////vq0P/xsE7/8a5J//jZqv/30Zj/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwh//3z5v/76tD/7pwg/++lNP/voi3/+d+2//zy4v/unCD/76Qy///+/f/88d7/9s2P/++iLf/3057/+uXF/+6dI//++PD/875s//O3Xv//////9suL/+6cIP/unCD/7pwg//GuSf/unCD/7pwg/+6cIP/unCD/7pwg/++gKf/65sb///////3y4//2zY7/7pwg/+6cIP/2y4r///78/+6eJv/unCD/+d62//netv/537b/+uK9//jarP/88N7/7pwg//779//87tj/7p0j//rkw//87db/9L1r//CqP//unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7p4m//3z5P/76Mv/76Iv//zu2f/ys1X/7pwg//KzU///////8a5I/+6cIP/voi//+d+3//769P/41qL/9s6Q//748P/unCD/+dyx//vpz//unCD/8a1H//78+f/64r3/871q/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/76Aq/+6dJP/unCD/7pwg/+6cIP/unCD/7p0j//337v/0v2//7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7p4k/+6cIP/unCD/7pwg/+6cIP/20JX//v37//bNj//54Lv/9cZ//+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/8K1F//vpzv/30Zj/++rQ//nftv/1xHr/9cV8/+6fJ//unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//XGf///////+uK+//O8aP///v7/8KtB/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/8KtD//jXpv/76Mz/++nN//vozP/658n/8rNT/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/+d60//bNj//76c7//fPj//ndsv/uniX/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/voSv/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCDm7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg5uyaIXzunCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/smiF8/4AAAuycIXzunCDm7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCDm7JwhfP+AAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADumSIP7JseXO6cIMbunSD27pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unSD27pwgxuybHlztpCQOAAAAAO6ZIg/unCGV7pwg9+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6bIPjunCGV7aQkDuybHlzunCD37pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD47JseXO6cIMbunCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwgxu6dIPbunCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7p0g9u6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/++lNP/uoCr/7pwg/+6eJv/wpzn/7p0j/+6cIP/unCD/7pwg//GwT//zt17/758o/+6cIP/unCD/7pwg/+6cIf/vpTT/8a9M//CqP//uniT/7pwg/+6cIP/voCn/8K1G/+6cIf/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/758o//CnOP/vozH/7p0h/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/8atD//758f/41qT/8Kk9//zs0////////O/b//K2Wv/uniT/7pwg//vnyP//////9cmF/+6cIP/unCD/7p0i//bLiv/++/b//////////v/98uH/9cR5/++iLf/2yIL///z5//riv//wqTz/7pwh/++gKf/voSz/7p0i//GvTP/64Lv///35/////////////fLi//bKiP/vpTX/7pwh/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//bJhf/99ej/++rQ///////99Oj/++bH//316f/yuGD/7pwh//voyv//////99Kb/+6cIP/unCD/8K1G///9+v///v7/++nN//jXp//64r7//vrz//ncr//65cX///79//zv2//64bv/87pk//jaq//53rX/9smG//zy4v////////36//vlxv/527D/+uK///747//64r3/76U0/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/++hK//416b///79///+/P/30Jb/76U0//fTnP/42Kn/76Ap//netf//////+dqt/+6cIP/unCD/87tl///////99ej/8bBM/++fKP/voy//87lh//337f///fr/+uTE//GvS//769L//vjw//305v/65ML//vrz////////////9cmF/++kMv/voSv/76Mw//K1WP/87db/9L9w/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/0vmz//vrz//747//zuGD/7pwg/++hLP/ytVn/758o//bOkP//////+ubI/+6cIP/unCD/8q9N/////v/+/fv/+uG6//O6ZP/vpDP/7p0h//K4Yf//////99Wg/+6dIf/2yoj///37//XIhP/unSH/99Ka///////+/Pj/8axE/+6cIP/unCD/7pwg/+6cIP/xsE7/8rNU/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//GvS//53LH///79//789//3zpL/76Ao/+6cIP/unCD/7pwg//O6ZP///////fXo/+6cIP/unCD/7p4l//zu2v///v3/+Nin//zv2//65sf/8a9M//K6ZP//////+Nmp/+6cIP/1x4L///37//zt1v/wqDv/8a5K//769f///v3/87pk/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/8KY4//305//+/Pn///////rjwf/99ur/986S/+6cIP/unCD/7pwg//GrQv/++PD///79/++jMP/unCD/7pwg//O9av///Pr/99Od//O5Yv///v7/+Nmq//XEev///////OzV/+6cIP/2yof///78//779//0wnb/7p0i//XDef/++fL//fHh//fRmf/3zpL/76U1/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/76Mx//747v///v7//O7Y/++jMf/2z5P//vz4//TDef/unCD/7pwg/++lNf/76c3///////K1WP/unCD/7pwg/++gKP/2z5P//fft//779f/+/Pj/99Kb//O9af///fv//vfu/+6cIP/zu2X//fXp//768//1xHv/7pwg/+6fJv/30pn///78//737f/98eD/8rde/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//O7Z//30pr/8a5I/+6cIP/wpjj/9cZ///GvS//unCD/7pwg/+6fJ//41qT///////XIg//unCD/7pwg/+6cIP/unyj/8rdd//bJhf/1xXz/76U1/++jMP/2yYX/9ceA/+6cIP/unyj/87xo//TCdv/vpTX/7pwg//CqQP/99ej///78//O5Yv/ytFf/8bBN/++iLv/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIf/uniX/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/0wnX//vv2//narv/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCH/7pwh/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//G0V/////7//vz5//rft//98+X//fXo//vq0P/ys1P/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/++kM//43LD/+Nmq//O6Zf/zuWH//fXp//zs1f/wqT3/8Ko///CqQP/vpDH/7pwh/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//GtR//++/b///////zv2v/0vm7/87xn///+/f/52q3/76Aq/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6dIv/ytVf/+uTD///9+//++fL///38///9+//99Ob//fbq//337v/42qv/76It/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//K1Wf/99ej//v36//758//64r7/+uO////+/f/41qT/76Ao/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCH/76Qy//K2W//30Zf/+Nqs//jarP/42qv/+Nmq//fYpv/2zI3/76Iv/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//jbrf/2y4n/8rVX//jVoP/758r/++rQ//fVoP/wqkD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg//CnOv/unSL/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6dIPbunCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7p0g9u6cIMbunCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwgxuybHlzumyD47pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD37JseXO2kJA7unCGV7pwg+O6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIPfunCGV7pkiDwAAAADtpCQO7JseXO6cIMbunSD27pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unCD/7pwg/+6cIP/unSD27pwgxuybHlzumSIPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
+ webUI["html/img/filter.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzo2OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cs038OQAAAOISURBVGgF5ZpLSBVRGMfvvfmqCKKiKCqKtE3SQ8haJJm1ctPCZYHrFhXtohcUBLVsU1BRBJKLXpsSKs1aCL1oUUhvMgIloodZKmLZ72+OzNVx7jzOXGfqg/89Z875zv/7f35n7px7vanUP2JptzyGhoYKmK8GW0EZmA/mgW7wHrwDN0BTOp0epPVtxBBnLdgIVoE5YBboBR2gDTTA/5DWn0FeDPaBz8CLdeF0EBR5jYRvKbgABoAXa8Opwit/CudK8NoLs4PPM8ZyBsNnB/jpsD7X0C8cjgDXnaQkqkEPCGMSuGWivxxzx8OQj6xtpHWuPhPloHfEMWzTD0HN2GQY2xuW2Lb+/Fh+VaIQPLE5meh+gmSxFYz+BjBogtjGscfiH26Z2GmbNNltVQAIpwDdP6ZNO2iRYqTpZGhfgWUaiMC2w1kCzkbALcqLvDVvUyK6MW9HFES0b8BvsFwXEZi4F+iBtykCcjtlqf0igr52VJ1eqiIgzzdlrRIZfWfJd3SD8ZbqHvkB4XSDpJNB9V0VcX/cT4Ys/zEzSuSj/3WxW9GpRD7ETpZ/QcOJ6LyfdHugitxNehbob9G7lo4PXWBmQhPqQ/fsDOeUfjqNCU1Csi+TQ5+2luzc3yaRr6elevQZwhZr4bomYam0U41yabYqov5hvSTMjlp6RyuiAarSTLPZmox5246+lVREx/isiuh6NxhUJwF2yEpCWu1bK8WEsjyRgCSa0XrVrjNra2mC7TWD5ilYAuJoA4jSlnppF5dVEU3g0ENTD4b3nsZiZsfGJuGqj8qY+CINGqP2GLZCJ+HjtpblxAJ9k3cPrLfGJrnVUaSCarxw0jFua1lOLNBerANx+byya6IkLM2uLZWpAl6/Mcc1EjvjKtLrJNLqI5HnjfQ+bsVeteb0g2y/t7hGvd7CNjenOL8OkJ40KtOdTF+Cl/nV6Mkf4gxocI9vZPYLLKs9iQrqRIACcM2IXGeSboYrg+rztY5ARaDJWUeo0W+sXudLTFhnApaAW6FkZy/+yuXasLoCrSfwVHAnW0+gK93YawKJMLUIAdNAKwhqnSxcYUpPKB6EBE2mg7VR///EX24jybTQerXnOC70FyVP3gjTPXPTQyaP8NFPNeJrCNTPP667JKOq6VNo/A2hes5ccUjmEmPmDoD5+FMgWCcA+3FG57QJP//kQ1PgGBIOToEDgUn+t4V/AJeGknwARIKLAAAAAElFTkSuQmCC"
+ webUI["html/img/log.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xNFQxMToxMDo0MjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CkP32mEAAANASURBVGgF7ZlPiE1RHMffw1AYhiL5k1HEijJiYaFZiHoyFspW2RFRkkSZGgtFWJIwi9FYmo0VOywkKTbKgjSlWcifRCPX51dv6s2d33md77vvXjfmV9859/7u93x/v98959x73p1KRbAkSargAhgDH0E/qIYkuHYEvAPGvwbmNOEerXM/0Q6BRSFuZj/ix0DaDnvCkGppIucDAe4OhzvkcUO+GaELAf8ux7/b8Zlrr+Pvc3zm6nX8NccXdKmFLHaUPJ/Ruhyu5zNap8Nd6PiCLrUQTyi0Rjy/5/M0Zd+smB7M32XwtgBr07aC6yfSTs7XO77OALfH4VbgHsD/HLytVquJx4nyIdQFBsHftscksK5Z0sGhpuN8Or4Aa5sJFHjtO7G2MjKvvZjN1sglOpSlCMt9LrDZ4S4Hd0Qg24vrK+gAZbPtjMqTdFKhEdkIsYxFWP720JlioUK6pzDL41jtpRIqxOOWxecuB3fhRGT8E85YBK8VygI6GSRTCxlH3TaJgyw4O2678aCxO94LbNPovYDdmOrUukIBN/MqwjJEOwGPOHR31W4VONVCLEBR9lAJpBbSrYhn5K5R+quFnGUOr1ICtMIlxjz6XVb6qot9JeKvCPSAdlQJJHDtd8hOIN0wtRDLxx6Ntr0ulalTq1TJNyYzXUjj3SjD8X87Iva7uR8s5+2bi6FtX1oOgi8g2tSn1g2yPx+t3gIR/c90s1+C1vuO/YkxdWrdjxFtE2dE0VELWaqIZ+QuUfqrhZxmyKUvgEoyE1xizOR4YOI8plXXyAZEbYsyTJvXFsUW+x6wGUSbWogJ237rZHSEgojq1CooLT3MdCH6Pcu3xz8zIq0s9lvc2+sgz6dWH/rnQPB/jlybZGoh99hCHJqk0P6TD0jaI/4b7dVYeXVq2bemokyKpRZiHwWKMimWWshxhryjoEpOKXHUNbIN8WcUc5s2r8Vue7l9oAaiTS3EhDeB6EUYnUlGojq1MobLr3uokB/5hcys7OYWKuRl5nD5Cbi5uYXw0ntPHoay2S8Seuol5RZSJ0r/n/DEc/BdrN9kTZrH7BkwDspgwyQxW6uggU3nHnAXvAG/QZE2SrARsL8hJffwDxM0mNDPvT8IAAAAAElFTkSuQmCC"
+ webUI["html/img/logo_b_880x200.jpg"] = "/9j/4AAQSkZJRgABAQABLAEsAAD/4QDIRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAPAAAAcgEyAAIAAAAUAAAAgodpAAQAAAABAAAAlgAAAAAAAAEsAAAAAQAAASwAAAABUGl4ZWxtYXRvciAzLjMAADIwMTk6MDg6MDIgMjA6MDg6MTQAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAA3CgAwAEAAAAAQAAAMgAAAAA/+EJkGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iUGl4ZWxtYXRvciAzLjMiIHhtcDpNb2RpZnlEYXRlPSIyMDE5LTA4LTAyVDIwOjA4OjE0Ii8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAyANwAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/dAAQAbv/aAAwDAQACEQMRAD8A/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9D+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//0f4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//S/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9P+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//1P4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDvPDXws+J3jPT31bwf8OfHnivSo7mSyfU/DXhDxBrunpeQpFLNaPe6Xp11bLcxRzwSSQNL5saTROyhZUNAHQf8M//AB4/6In8XP8Aw23jL/5TUAH/AAz/APHj/oifxc/8Nt4y/wDl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f/E3xn4o+IPjnxDLaafp8mveMPGet33iPxNrMlhpNpYaVZPqmtale3z2mmWNlp9s05hsrS2tkjhQA4ygAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//S/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAczu+N7M2BgbmLYHoM9BnJxx1/FgBtABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAOLuwVWZiq/dUsSFz12joM4HQduc4FADaACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//0/4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//U/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9X+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//1v4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//X/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9k="
+ webUI["html/img/logo_w_600x200.png"] = "iVBORw0KGgoAAAANSUhEUgAAAlgAAADICAYAAAA0n5+2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAuIwAALiMBeKU/dgAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MzAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjAwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAg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"
webUI["html/img/logout.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xM1QxMToxMDoxODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cg27QeEAAANQSURBVGgF7Zk9aBRBGIZzSRSN8YdoCpEkghCCqK1o4g9IsBCCNmIniCAiWAhqI8G02qiIoqCCWggSEcFKEFPYpVAU8QdFUyiKRpRokBjP55OdZDLZvZnZ7N3Ngh887M7sN/O9797t7c5eTc3/8D8DxWKxGS5Ai//oAEYgvB4OwleQaAtAlp8ERG+Bp6Jei/wYQfRy6NfE67vhG0FtA/TBqK7c2A/bCGJ3wpAhOq4ZphGUroEHcYoT+sIygsgmOAu/EwQndYdhBHV1sB8+Jym19Lf6/faVIRuBG+GRRajtcPWMoKwFbtgUOh6vvBGEzYFj8MNRpEtaZY2gaAe8cVHmmXOc/K3QXIZv/+SUFFgJ96AS8ZwiZ6Ab6iZVzGCPiRbCKRiDasQHip6EdD/PDKyFvfAJQgg5kVfB/VoieT0MQojxE1G9UG/7otWS0A7pPkrb7DM/Ppcp+mAAM/bFGEmL4RL8gVDjI8JWOZ0bEjvhSahO0CXXsLMZWZYegREIMV4jaoHTJyNJJLfC7RCdoOm6sxGVyKAeeBegoU6l0XmLiXlwAqp1o4w7j3d1AwW9YdtnNrnQzkOXLddyfAPHv8Ey6ABpd8N88In2QqHwymfARC5mCrAH0i6qGDr9jk3fbNgFz8A1DkwIS7tDpSVwGdLcexIfPZhPHpf2wS+wRX9a/dPGUakLzBdwNgGJRlQBJtgMw5aJ3qr8TLYUmwVHwXXxZTUiwphvHYxDUnzPxIA5CdXa4E5SVa3fyUhkRtYqpSKbNYxpJiq+ncpDJar7GGlknvcl5mqM05BZH4Xl3iOLpLh7j7OR6MScSzAykplg20QIWA0PDSG+RuTdQVy8sNXP9DgK5N4jK9AvkRpfI4sYF/c2836mQl0nQ4zce66AfZFkTMqYl2DGaSMt/CYOHpsuaPco5bLUzUuMGkLHaQ+ovjwZUZrVdpAHRnnw/Bd5MrJCiY62t4x2+E2uBfkfRg95TdSkK8/LJ7JWF83+Nb5Ww0Zf+E3OviwXVMgT8dLwVRsKEd0A+uP8biMlH01MHAYVF/Oh2lCJenkDqpbUN9nPyzU91QnCRbyEPEXn1sQhxMv7tG1T7cW3rK/r44eVtxfxm6gwBh38zJqPJuUtXu3Z/wLwuBaBLgMkKwAAAABJRU5ErkJggg=="
+ webUI["html/img/m3u.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CumjVbcAAAGWSURBVGgF7VoxTgJRFGTFaGKBFnbEcABjb0fiBego7D2ABYmn8ARKRWFNQ6gx4QRQGWJJoY2VhXGdl7Dkh7Dsx3ns3yXvJ5P97L6d92bmhwYqlcWK43gK5L2enP51NP8F7pN721wPnOITZx9qG6HxI8QIZO+9XCHeL+VQKKm8QMyxb6+iCpH528AQYs58xIQWknV8mhDxCjEXWWJCC8maT55fAmOIudpUXAYhMn8dGEHMTZqYsgiR+U+BAcTcrhNTJiEy/xHQg5jOqpjD1RsBP3+id8u3P8TUoij6SuoLIwRDfWOofjLYtteyHa1UfcvvcUT1jqpGauVuHnyAdragjv/TAkley3uhj9Y5ZhDQa2+Olgmhz4IygSWibChNZ4nQFioTWCLKhtJ0lghtoTKBJaJsKE1nidAWKhNYIsqG0nSWCG2hMoElomwoTWeJ0BYqE1giyobSdJYIbaEygSWibChNZ4nQFioTWCLKhtJ0biJzmi1/guXMrpDn/OegO3bXMuAH0TtgAvwARV3y57Q34AGoJkL+AErKZ9cqbH7AAAAAAElFTkSuQmCC"
+ webUI["html/img/mapping.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0wMlQxMjowODo5NzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CpRxQsEAAAJLSURBVGgF7VoxTgMxEMwBHWlAaeABVCEtBcoD+EBewCdCyQsQtLyAPCBvCBSRIBUPCF1ogqBJjlkrezGr6HTrO98lhy1Z9trr2VmvnbMNjUadUhzHLeQB8hw5LS3QOUbubvIf7X3kKXIZibgS51bCZdWgMT6D8nECgArkngagQN0B8dhbkblalVmLIyheCGUthhjuLBq77MihA0xTjHHBEBBOorHLjjghbNOg4Mg2RYO4hIiEiHiaAV5aSwf8hRgjZdHtTTTc2ZFXpZkY+hMx5k3IZYlr7jgudJHp2JElLaF0K1mirYn8nAWgQB3ibM59ERNCA52d6Nghv9isQiUtn0kURe92I9eBcYA6YZxym8dyDuwRuMw82gjQYQbsPdLDdNCROO0US3uEfp3usTZpjf5J2CNtNFwjl7FHvmBnCB5PCQkQoJudJtGvE23sJEFuI39rQArS7dskXK6nlwkAKiB1VxAxLcyUePAH8cQmlbEul4+UM8LkVjPc2ZHcaFUDBEeqjoC0HyIiZ6RqOUSk6ghI+xyRD9mRQTYfIktPylaX16rhzo48KE29QH8kxjxC/hFtZYiGe70OjWVMW7Dx32bA3iO7//iAC8DOPweZFQhH6O+CmkRvW2f28oV8owEoUHdMPPg70rFJZajTkqT7uZ3ObaHEuuHOjnCpsb8vlKUsur2JhruLA94Y5QEOjuSZPR9jQ0R8zGoezNpFhN5RtUm+/bpgaG1u0jd2OSLDTRopbZ/okxcrLUYKvKprbRfHhXr8m5PK/y1V/gWRKLfiNSmxEAAAAABJRU5ErkJggg=="
+ webUI["html/img/settings.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0xMFQxODowODo4OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Ckxt87EAAAS7SURBVGgFzZpdiFVVGIbn5N+IMgVhaRLqWI7mQIJoIVRgOhQZNDAhWcbcVuPV3BRE6I14440iQQSaN0p6kz8zI0k5inUhZSSaYOVYODMo5eiMOOPf+LzH2cPMPmvttdbe53jOBy9rr2+938/ae51vr733qaoqgQwPD68B/wDJfXAP3AE94JMShCy+SxJ9CvSDJFlU7MiPFdsh/hrBdIffBsd48HApJjLPI4tnPThBlFJMZI5HBuWZCIt9AmgEzeAJR6JzHeMadnKI8wbYCz4Fkz18JlNwMgf8BCL5j4O3bVaMdUfEhPZqgv1U7HbEbDvoT7HZOPUYNwAlHheV09a4A3RTgMqtj9QY7JdgeM5i3I4+fDIYrQeq/UnyNYOTlBDtS+BwEjk2doz+KyO2OY5bwVCME+/qylTHT4C1D3k+uB33Yul3ov/eMuajlu1RH+II5wtT4hNNSnQ6U/kzbRkfq351bCfF8apAm7kmvq38njWRK0S305SHcSK5XO4U5O9MBmXWbSe3E6YccialdKzH2TTnQEF10XgZ5DdivsxEhkyxjVdERAwu03xmMiqD7hYx19km4cyHq6KyeHKkWpSz+ciVrHVpRYZk/wLHp0H2bULkNKzt4Eq86TKxLq3IECf6nXwV9QPbAfjHQSfoD7SN6L63gYhvbrkiTwKf/dPYpbdPVxKMnigdg0VAG8FQye8AzBl6aIk2A+wPiNoHd63LNZx3wbUAvz/CfTzJb/43AmkGpLfAi0DPE/NALQgtve+xFPdi5xRiNkHa5ySOJ/TR7RrBJdqL4AAxL+p+8ToYAFklNCnF3pM1KPba2L6v8vons5oPsko9ZyZoa0PsOoKezxoY+y5N5DYHWSvDTXzUMJH7IUkRW0tbyyV0CcfDDKmqDMe1KfqnQyehGNgo9q8p4hWYFGsiBY4fsSK/BRkkaPgj5PhMy720BnVFesfnlKo3Das0bw8XYJf196GEuzWRLSDoRypLg2w06FyqTS6Cx7iK1eeqGqrnugmuBgvB8+A5UAuqQYiU+oZ4h2T+BV3gAlDp/pai0U1rFpVGMAv8AHzFd4vShMOQLcoB+DNB/sSbM3ZoMV4BQsW0adSJSbNp1Hu1mY40/YZxpPdJaUSfFzrBMXAjjQNsdvll6cHCWVvKJIphdhcny11pqmolCk5aIDif0BKdZBucgPlO8kh/r8O4HtwClSCbk86HtQqQuUrvKVCf5OARjt0lll4H/WKKmbS0tmJQKZNQ7nq9+w0n2LhTN04E8jKMPpZ1hcli8tGTZYEYJwJrZQGzchTGz3a2ifwdkHc73LYAfpx6DcWXQK1LeiDsdpFGx7UOwUGQJKpmGyIjjvWh50iSQWzsZ/ofgvx+jnYp+B/YpJcB7QXDBKPJ4JDF6+/oCwoBuhoL36R+Jp4RJH16u2IgaxJpHhMehsBY3wTjV2YbOuuumLHrwCW6msbSj74O/DHGgV4Ohl8Jw1nSMmsB+tL6Wnw83odzBrhEr2GtgvFE8A74ADxtJZZygMC25cjQqBwqdg62qpUlziUP45Cq6OGuqqoUE/FJ8i+v7MpJYvEsHl1A5gNty2vLmaN3bBLdAvqB3svqXxLRvyEuc9zs7SiA+ACpw05pJx8SoAAAAABJRU5ErkJggg=="
+ webUI["html/img/stream-limit.jpg"] = "/9j/4AAQSkZJRgABAQAAAQABAAD/4gJoSUNDX1BST0ZJTEUAAQEAAAJYbGNtcwQwAABtbnRyUkdCIFhZWiAH4wAFABcAFgAuAAphY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAAEBjcHJ0AAABSAAAAE53dHB0AAABmAAAABRjaGFkAAABrAAAACxyWFlaAAAB2AAAABRiWFlaAAAB7AAAABRnWFlaAAACAAAAABRyVFJDAAACFAAAACBnVFJDAAACFAAAACBiVFJDAAACFAAAACBjaHJtAAACNAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACQAAAAcAHMAUgBHAEIAIABJAEUAQwA2ADEAOQA2ADYALQAyAC4AMQAAbWx1YwAAAAAAAAABAAAADGVuVVMAAAAyAAAAHABOAG8AIABjAG8AcAB5AHIAaQBnAGgAdAAsACAAdQBzAGUAIABmAHIAZQBlAGwAeQAAAABYWVogAAAAAAAA9tYAAQAAAADTLXNmMzIAAAAAAAEMSgAABeP///MqAAAHmwAA/Yf///ui///9owAAA9gAAMCUWFlaIAAAAAAAAG+UAAA47gAAA5BYWVogAAAAAAAAJJ0AAA+DAAC2vlhZWiAAAAAAAABipQAAt5AAABjecGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltjaHJtAAAAAAADAAAAAKPXAABUewAATM0AAJmaAAAmZgAAD1z/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAQ4B4ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD/AD/6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD9PvBf/AARa/wCCrXxF8HeE/iD4G/YM/aL8UeCfHfhrQvGXg/xNpHgia50nxF4W8T6Xa634f13TLkTgXGn6vpN9aahZTgAS21xFIAN1dL/w4o/4LB/9I7/2m/8AwgZ//kiv9b3/AIJp/wDKOX9gH/syf9lX/wBUV4Dr7YoA/wAWr/hxR/wWD/6R3/tN/wDhAz//ACRR/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Ir/AGlaKAP8Wr/hxR/wWD/6R3/tN/8AhAz/APyRR/w4o/4LB/8ASO/9pv8A8IGf/wCSK/2laKAP8Wr/AIcUf8Fg/wDpHf8AtN/+EDP/APJFH/Dij/gsH/0jv/ab/wDCBn/+SK/2laKAP8Wr/hxR/wAFg/8ApHf+03/4QM//AMkUf8OKP+Cwf/SO/wDab/8ACBn/APkiv9pWigD/ABav+HFH/BYP/pHf+03/AOEDP/8AJFH/AA4o/wCCwf8A0jv/AGm//CBn/wDkiv8AaVooA/xav+HFH/BYP/pHf+03/wCEDP8A/JFH/Dij/gsH/wBI7/2m/wDwgZ//AJIr/aVooA/xav8AhxR/wWD/AOkd/wC03/4QM/8A8kUf8OKP+Cwf/SO/9pv/AMIGf/5Ir/aVooA/xav+HFH/AAWD/wCkd/7Tf/hAz/8AyRR/w4o/4LB/9I7/ANpv/wAIGf8A+SK/2laKAP8AFq/4cUf8Fg/+kd/7Tf8A4QM//wAkUf8ADij/AILB/wDSO/8Aab/8IGf/AOSK/wBpWigD/Fq/4cUf8Fg/+kd/7Tf/AIQM/wD8kUf8OKP+Cwf/AEjv/ab/APCBn/8Akiv9pWigD/Fq/wCHFH/BYP8A6R3/ALTf/hAz/wDyRR/w4o/4LB/9I7/2m/8AwgZ//kiv9pWigD/E88f/APBGT/gqj8K/AnjT4nfEX9hL9ofwf8P/AIdeFPEPjnxz4t1zwTNaaL4X8IeE9Ju9d8SeIdXujORbaZo2j2F5qN9OQRDa20shB24r8yq/28f+Ctf/ACit/wCClX/ZhH7Xv/rP/wAQK/xDqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA+j/ANmj9kL9pr9snxbrvgL9lr4K+Ovjn408M+HH8X6/4Y+H2ljWdZ0vwvFqen6NLr1zYrNHMNMh1XVtL0+a7RWihu9RsoZSj3MIf7U/4cUf8Fg/+kd/7Tf/AIQM/wD8kV2v/BAD9sj/AIYi/wCCrf7K/wATNW1X+yvh98QPFw+AHxWklm+z6f8A8IJ8aWg8HjU9Xl3Ls0rwd4wufCPxAuz82B4RQlJACjf7MFAH+LV/w4o/4LB/9I7/ANpv/wAIGf8A+SKP+HFH/BYP/pHf+03/AOEDP/8AJFf7StFAH+LV/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Io/4cUf8Fg/+kd/7Tf/AIQM/wD8kV/tK0UAf4tX/Dij/gsH/wBI7/2m/wDwgZ//AJIo/wCHFH/BYP8A6R3/ALTf/hAz/wDyRX+0rRQB/gx/HT4CfGb9mT4n+Ivgt+0B8NfFnwj+K3hJNHl8SeA/G2lzaP4i0iLxBomneI9Emu7KbJWLU9C1bTtTs5UZ45rW7idWySB5HX9yX/B69+yL/wAIr8eP2V/22/D2meXpfxb8Da18BfiPd2sOy3i8afDG9k8U+BdR1OXbiXVPFHg/xZrukWzB2P8AZnw0jjZIxEjS/wANtABRRRQAUUUUAFFFFABRRRQAUUUUAPRHldIokeSSR1SONFLu7uQqIiKCzOzEKqqCWJAAJNfq8n/BCv8A4LBSIki/8E7/ANp3a6q67vh/dI21gGG5HnV0bB5V1VlPDAEEVv8A/BBj9kX/AIbU/wCCrf7Ivwo1PTP7T8DeGPiFb/Gz4nRTQ+fpzeAvgpE3xDv9L1hQrEaZ4w1nRdD8BSkAFp/FdvH5kO/zo/8AZ4oA/wAWr/hxR/wWD/6R3/tN/wDhAz//ACRR/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Ir/AGlaKAP8Wr/hxR/wWD/6R3/tN/8AhAz/APyRR/w4o/4LB/8ASO/9pv8A8IGf/wCSK/2laKAP8Wr/AIcUf8Fg/wDpHf8AtN/+EDP/APJFH/Dij/gsH/0jv/ab/wDCBn/+SK/2laKAP8Kz9p39iX9rL9i7UfCOkftV/AT4ifAfVPHtlq+o+DtO+IejjRb3xDp+gz2Ntq97p1s00k0lrY3GpWUEs7IkbSz+XGztHKI/lqv6F/8Ag5+/bI/4a5/4K2/HDTNF1X+0fh7+y5aaZ+y74KEU261GofDq61K8+KVz5UbG3N0fi9r3jnSTexl5bzSdE0USybLeCGD+eigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/cg/4Jp/8o5f2Af+zJ/2Vf8A1RXgOvtivif/AIJp/wDKOX9gH/syf9lX/wBUV4Dr7YoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD8+P8AgrX/AMorf+ClX/ZhH7Xv/rP/AMQK/wAQ6v8Abx/4K1/8orf+ClX/AGYR+17/AOs//ECv8Q6gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAHI7xOkkbtHJGyvHIjFHR0IZXRlIZWVgGVlIIIBBBFf7Z//BIH9sRP28f+Cbv7J37St5qS6n4x8VfC/TPDXxTmMqvc/wDC3PhxNcfD/wCJdxdQ5Mtp/bPi7w3qfiLT7e4zK2jazplyHnhuIrib/Eur/QW/4Mm/2yPteh/tZfsE+JNV3T6PeaT+1D8KNPml3yNp2pDRvht8YrW381t0NrYahB8JtRtLK33Rtda5r980cUjzyzgH98VFFFABRRRQAUUUUAfhR/wcifsif8Ngf8Eif2ndD0vTP7T8dfAvSbH9p74ehYvPuINW+DCXur+MUs4FUzXF/qvwjvfiRoFhb25E819q9skazn/R5v8AHer/AH6NW0rTdd0rU9D1mxtdU0fWdPvNK1bTL6FLmy1HTdRtpLS+sby3kDRz2t3azS29xDIrJLFI6OCrEV/hv/8ABQv9lrUv2J/23/2ov2V9Riuo4Pgv8Y/GHhbwzPe7/tWqeAJdQbWfhrr83mfPu8R/D7VPDOvjcWO3Uh88n32APjeiiigAooooAKKKKACiiigAooooA/0D/wDgyU/ZE+z6T+19+3Xr+mYl1G70D9lz4Y6lJFtdbSwTSfif8YfKaRd0lvd3Vz8HreC4g2xifS9VtneSRHSD++mvyl/4Ih/sif8ADEf/AAS3/ZB+B2o6X/ZXjV/hhYfE/wCKEEsPlahH8S/jDNN8SfFmmaq21WnvfCl14ki8EpKw+Ww8M2MCExQxmv1aoAKKKKACiiigAr5A/b+/ao0X9iP9iv8AaZ/as1xrRk+Cfwi8V+LdCsr5gtrrfjk2R0j4c+GZWLKF/wCEq8f6n4a8NodwxJqqdeh+v6/ib/4PTP2yP+EA/Za/Z5/Yk8N6r5WvftCfEG7+LPxGtLWb98nww+Dogh8OaVqtvuA+weKviT4g03W9Nk2uWvvhfdrujEZEoB/nB+IfEGteLPEGueKvEup3eteIvE2san4g1/WL+Uz32ra1rN7PqOq6nezNzNd399cz3VzKeZJpXc8mseiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/cg/4Jp/8AKOX9gH/syf8AZV/9UV4Dr7Yr4n/4Jp/8o5f2Af8Asyf9lX/1RXgOvtigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPz4/4K1/8orf+ClX/AGYR+17/AOs//ECv8Q6v9vH/AIK1/wDKK3/gpV/2YR+17/6z/wDECv8AEOoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr9V/+CJP7ZH/DCn/BT39k348anqv9leA2+Itp8Mvi1NNN5Onp8LPi3FJ8P/F+qaou5RPaeEbfXYPHcMLMB/aXhXT5R80Sg/lRRQB/v8UV+TP/AAQ5/bI/4bo/4JdfsnfG7VNV/tXx9p/w+tfhN8WpZZvO1Fvid8IJG8A+JNV1f5m8u/8AGUWi6d8QFjDECx8W2TgRh/LT9ZqACiiigAooooAK/wA07/g9I/ZE/wCFcftj/AD9sXQNM8jQP2lfhZdfD7xtd28O5H+KPwOnsbO31HUp1A8q41z4a+KvBmkaXDN808HgPUnhZ1tplh/0sa/nd/4Oi/2RP+Gq/wDgkT8cNZ0fS/7R8dfsuapoP7T/AITMUO64TS/ACahpXxSVp0Bnjsbf4ReJvHOuz26hoLi+0HS2nQG3iuLcA/yKaKKKACiiigAooooAKKKKACv02/4I3fsi/wDDcf8AwUy/ZC/Z3vtM/tXwfr3xX0nxh8TrWSLfaS/Cr4XQ3PxJ+IlleyMGhto9d8L+FtQ8NWk04MbaprWn2yxzz3EUEv5k1/eL/wAGTH7In9reP/2uf259f0zdZ+D9A0H9mf4Z6hND5sEmveK7jTviL8VprV3Gy21LQ9E0b4YWSTwlp207xnqVsWhgnkS5AP8AQzooooAKKKKACiiigAr/AB3f+DkD9sj/AIbN/wCCtf7SWvaRqv8Aanw9+BGpWv7MPw1aOf7RaJovwcudR0zxfd2E6MYLnT9d+LV/8RfEWm3dsPJuNM1axZJJ1VbiX/Ux/wCCnv7XVn+wl+wF+1T+1TLdW1trXws+E2vXHgJbsRtBe/FTxOYPBnwo02aKQMJbe/8AiN4h8MW16qxysti9zN5UixMp/wAQK+vr3U7281LUru5v9R1C6uL6/vryaS5u729u5XuLq7uriZnlnubieR5p5pXaSWV2d2ZmJIBVooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/sa/Z9/4PGv2mv2ffgJ8EPgJo37HXwJ8QaP8EPhD8NfhDpOv6n43+IFtqWt6b8NfBmi+DLHV9Qt7QfZbe+1K10WK9u4bb/R4riaSOH92q169/xG8ftWf9GRfs9/+F98R/8ACv4h6KAP7eP+I3j9qz/oyL9nv/wvviP/AIUf8RvH7Vn/AEZF+z3/AOF98R/8K/iHooA/t4/4jeP2rP8AoyL9nv8A8L74j/4Uf8RvH7Vn/RkX7Pf/AIX3xH/wr+IeigD+3j/iN4/as/6Mi/Z7/wDC++I/+FH/ABG8ftWf9GRfs9/+F98R/wDCv4h6KAP9GT/gmX/wdhftE/t2/t3fs3/skeLv2T/gt4E8N/G/xpf+F9W8XeHPGPjnUNb0O3tPCviHxCt1p9lqY+wXEzzaNFbslz8gimkYfOq1/cpX+NT/AMG73/KaX9gD/srmtf8AqtPHVf7K1ABRRRQAUUUUAFFFFAH8KH/BRT/g7X/aN/Yq/bf/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WOj6BoOn3Gq6xql5Jg+Xaafp1pcXdw+DshhdsHGKAP8AN2/4PR/2yP8AhY37XHwD/Yq8N6r53h/9m34dT/Er4g2dtNiP/hanxqFlcaTpmqW4Yh7rw38MdB8M6zpUzhWitviTqKICJmJ/itr6y/bt/ah179tX9sf9pP8Aaq8RG6juvjh8XfF/jbS7C9fzLjQfCN1qUln4D8LF98m6Lwl4IsvD/hm2Jkc/ZtJiBdj8x+TaACiiigAooooAK/2Hv+DZvSf7G/4Id/sIWe3Z53hv40atjGM/29+0r8Ztc3f8D/tHfnvuzzmv8eGv9kD/AINw7+HUv+CJ37A1xAqqkfw58c2DBOhm0r40fEvTLhj/ALb3FnKz/wC2WoA/biiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr/JJ/4Ow/+U2X7Q//AGTv9nj/ANUr4Nr/AFtq/wAkn/g7D/5TZftD/wDZO/2eP/VK+DaAP5vaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK6vwJ4G8W/E3xn4X+HngLQdQ8UeNPGmu6b4a8L+HtLi86/1fWtXuo7OwsrdCVRTLPKoeaZ47e3iD3FzLFBFJIt06dSrUhSpQnUq1Zwp06dOMp1KlSpOMKdOEIKUpznOcIQhGMpSlKMYpuST58Xi8LgMJisfjsTh8FgcDhsRjcbjcXXpYXCYPB4OhWxWLxeKxOIqUaGHw2Fw2GxGIxGIr1aVGhQoVq1WpTp0pzj9Y/sAfsT+O/27/wBofw38HvC32vSfCtqY/EXxU8cx2/nWvgfwDZ3MMep6gDIpgm13VHkTR/C2myZ+361dwPcCLSrTVL2z/wBHr4T/AAs8CfBD4beC/hL8MtAtPDHgPwBoNl4c8NaJZj5LWwskOZriZv3t7qV/cvPqOr6ndNJe6rqt3eal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gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr+z7/ggp/wTT/4VH4Psf20vjV4f8r4n/ELRXX4K+HtVtsXPgT4d6zbFJvGk8E6brXxN8QbCXZpbIqz6X4Hn/17P4t1GysPyI/4Ip/8E13/AGxfjB/wuX4r6G837N3wa1q0m1S1voD9h+KPxAtlg1HSvAMXmL5V3oOmRyWmt+O8ear6bNpfh14h/wAJK95p/wDedHGkSJFEiRxxoscccahEjRAFRERQFVFUBVVQAoAAAAr+o/AXw29vUpcdZ3h/3FGclw3ha0NK1eDlTq5zOE1rTw8lOjlzaaniFXxkbxw+Hkf4Nfta/psf2Tg8d9FLwvzi2aZlh6E/GrPctxHv5dleIhRxeC8NsPiKFS8Mbm1KWFzPjSMKkZ4bKJZTw5VUKub5vRT6KKK/rU/55AooooAKKKr3d3a2Frc319c29lY2VvNd3l5dzR21raWttG01xc3NxMyQwW8EKPLNNK6RxRozuyqpIG0k22kkm220kkk2222kkkm220kk22km04xlOUYQjKc5yjCEIRlOc5zlGMIQhGMpSnKUoxjGMZSlKUYxjKUoxlYoqlpuo6frGn2Gr6TfWeqaVqlla6jpmp6fcw3un6jp99AlzZX1jeWzyW93Z3dtLHcW1zBJJDPDIksTsjqxu0k1JKUWnFpNNNNNNJppptNNNNNNpppptNNucJ0pzp1ITp1Kc506lOpCdOpTqU5zp1KdSnUjCpTqU6lOdOpTqQhOE4ThOEJwnCBRRRTJCiiigD8if+Cvv/BOiw/bq+A0ms+CNNtIv2i/hFZalrXwv1HENtN4u00p9q1z4X6pdvsRrXxCIRc+Gp7yRIdI8Vw2j/arDS9W8QPcf59Ooaff6Tf32larZXem6npl5c6fqWnX9vNZ31hf2Uz215ZXtpcJHPa3drcRyQXNvPGk0E0bxSIrqyj/AFjK/kJ/4L+/8E2P+Ed1S/8A27PgroG3QtdvbW3/AGivDmlWxCaR4gvZorLTPixb20K7EsfEN1Jb6R43ZFjMXiGXTPEMqXUuv6/e2f8AM3j14cfX8NPjjJcPfG4KlGPEGGow97F4GlFQp5pGEVeWIwEOWnjGk5VcCoV5c0sFNn+5H7JX6an+qWdYX6LPibm/JwvxNj61XwgzrMcRalw/xVj6s6+M4ErYivU5aGUcV4h1cbw3GVSFHAcVPFZXSVKhxNhqa/ldooor+QD/AKOAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP2i/4N3v8AlNL+wB/2VzWv/VaeOq/2Vq/xqf8Ag3e/5TS/sAf9lc1r/wBVp46r/ZWoAKKKKACiiigAooooA/xef+C9P/KYv/goZ/2cZ4p/9I9Lr8ja/XL/AIL0/wDKYv8A4KGf9nGeKf8A0j0uvyNoAKKKKACiiigAooooAKKKKAP9gz/g2Z/aA/4aB/4Iy/sk3N5ffbfEXwd03xl+z/4jTzPM+w/8Kr8YavpXgux3Elhs+F1z4CnEbBfKFwI4wYljdv3sr/Py/wCDJb9r8Qal+13+wh4g1PCahb6H+1J8LtOlmCJ9rsjo/wAMPjEkKyHEtzdWs3weura2t8SC30vWbt45I45JIf8AQNoAKKKKACiiigAr/IT/AODmr9h/U/2M/wDgq18b9YsNJ+x/C39qq8n/AGnPhrfW8BjsJLr4hajeS/FPQwYx9kt77Q/itb+LZhpcDB7Tw3rHhe8eC3i1O2jr/Xsr8Kv+DgD/AIJMWn/BVj9i2+8M+BbLSbf9qT4GXOqfEX9nLXtQkgsl1XVJbOGPxh8JtS1ScpFY6H8UdJ0+ys4bi5mtbHTvGuieCtb1O6i0jS9SjnAP8dyit7xV4W8S+BvE/iLwX4y0HV/C3i/wjrmq+GfFPhnX9PudK13w94h0K+n0zWdE1nS72OG807VNL1G1uLG/sbqKK4tbqCWCaNJEZRg0AFFFFABRRRQAUUUUAFFFFABRRXU+CPA3jT4meLvDvgD4c+EvEvjzx14u1W10Lwr4N8HaHqXiTxR4k1q+kEVnpWhaDo9teapquo3Uh2wWdlazzyHO1Dg0ActRX97P/BJf/gz5vPEel6R8a/8AgqrqeqeHbPUrEXnh79kz4deJRY+I40vICLe6+MvxJ0CeU6Jcwo5uI/A3w9v5NRhmNlLrfjbTrm21Xwk/z5/wc8f8EZv2AP8Agmj+zF+zp8S/2Q/hZ4k8A+L/AIh/Hi/8C+Kb/W/if8QvHcF94bg+H3iLX47OGw8Y+IdZs7KVdT061mN3aQxXJRGhMpid1IB/FTRRRQAUUUUAFFFFABXonwh+KPjD4H/Ff4ZfGj4fagdJ8efCP4geDviZ4L1Qb/8AiX+KvAviHTvE/h+8IjeN2S31XTLWV0V0LorJuG7Ned0UAf7xX7NPx38IftQ/s8/BH9o3wDKH8HfHH4WeBvil4fj85LiaxsfGvhzT9eGk3roFC6nost7JpOqwMkctrqVldW08UU0Mka+3V/Iv/wAGc/7ZH/C8f+CdnjX9lzxBqv2vxl+xx8T7zTNHtZpvNuV+D3xmn1jx34Lmd5G8+X7L46t/ito0Ufzw2Gk6bolpE6ReTBF/XRQAUUUUAFFFFABRRRQAUUUUAFFFFAHGfEfx/wCFfhP8PfHnxT8d6pFongj4aeDPFHj/AMZa1PjydI8K+DdDvvEXiHVJslR5Wn6Rp15dyZZRsiOSOtf4YP7W37RPir9rf9p74+/tN+NTKniT46fFnxx8S72ykmM66Nb+KdevdR0nw5ayEn/iXeGNHlsPD2lxg7YdN0y1hX5YxX+oP/wdh/tkf8Mw/wDBKbxn8L9B1X7D8Qf2wvGOifAXR47eby9Rg8BASeMvi3qiRblEulXfhTQI/h9q+d+wfEWzAjy/mxf5ONABRRRQAUUUUAFFFFABX9zX/BkV+0B/Yvx8/bZ/Zdvr3918Q/hP8P8A45eHrKaTbHDe/CbxZd+BvEzWKEhWutTs/i94be8RQ0slt4fglUCK0mYfwy1+vP8AwQh/a/H7Ev8AwVU/ZI+L2qamNM8CeIfiDb/Bj4pSzTeTpyfD340RN8PtU1XV2ypOneDtT1rRvH0gUlvtHhO2bZMFMMgB/s/0UUUAFFFFABRRRQB/EL/wekfsP6p8Q/2fP2fP28vBukfarz9nrX9Q+D/xjntbdnu0+GnxU1LTrjwD4h1Cfbti0fwj8SbW58OIu4O+p/Fq2YI0ccrxf5wNf7z3x5+B/wANP2lvgx8T/gB8Y/Dlv4s+F/xe8F694D8baDcbVN5ofiCxlsp5rK5KO+naxpzvHqWh6vbBb3RtZs7DVbCSG9s4JU/xdv8AgqP/AME4PjJ/wS6/a28dfs0/Fa2udT0WCWXxL8HviUllJbaL8WfhRqV7dReGfGGmHBhg1JFt5tF8X6JHLM3h3xbpur6Us95Zw2OpXwB+dVFFFABRRRQAUUUUAFFFFABRRRQAUUV/Sh/wSF/4Npf2vf8AgpK/hr4v/FeLVf2Wv2Qr97XUY/iZ4s0ST/hYfxT0dikxj+DHgPUfss99p2owFI7f4j+Jxp/gqKK5/tDQF8c3Gn3mhUAfzX0V/qEftmf8GwX/AASD+AP7Cv7V3xW8EfBb4j3PxL+Cv7Jvx1+IXhDxl4g+OvxQv7yfxz8OPg/4p8SeH/Eut6LZ+INN8J3txJr2jWmp6jplt4esfD9zIZrWLR7bTnWzT/L3oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr6s/Yv/AGSPiN+2x8f/AAd8Cvh1C9vJrEx1Txj4qltpLnS/AfgXTpoP+Ei8XasEaNWjsYZ4rTS7J57c6zr99pOiQzwz6jHInzX4e8P654s17RPC3hjSdQ1/xJ4k1bTtC0DQ9JtZr7VNY1rVruGw0zS9OsrdXnu76/vZ4bW1t4UaSaeVI0UswFf6HP8AwSm/4J56H+wP8ALbTtdttP1D49/EuHTfEPxk8S2/k3Is72OF5NJ+H2i3se9ZPD3guO6ubc3EUjx61r9zrOthls7rTbLT/wBO8LPD6vx5n8adeNSnkGWSpYnOsVHmhz03Lmo5bQqJaYrHuEotxblh8JHEYlpSWH5v4W+nv9MDKvomeEVfG5XXwWM8W+OKWPyXwyyKv7Kv9XxcaPssy41zXByk3LIuE4YqlXjTrQjRzfiCrk2SRlUpvN1R+5vgD8Cvhz+zT8IPAvwR+FGjLongfwBosOkaXA3lvfahcFnuNU17WrqOOIX2veINUmu9Z1q+8qMXWpXtxJHFDEY4Y/YaKK/0Ew+HoYTD0MLhaNPD4bDUaWHw9CjCNOlRoUacKVKlThFKMIU6cIQjFLRLdtylL/j5zjOM14hzfNM/z3Mcbm+d53mOOzfOM2zHEVcXmGZ5pmWKr47MMfjcVWlKriMVi8Xiq+Ir1ZyvKpUdlCEadOkUUUVsecFFFFABX8zf/BwB/wAFFf8AhWHgmT9ib4R675XxB+JWjQ3vxv1fTbnFx4S+Gupx+ZZeB/Ogbfba18Q4f3+swO6S2/gUfZ7i2mtPGlrcW/7Ift+ftneC/wBhb9nDxd8afEv2TU/EhQ+HPhf4NnnMUvjb4ianbXDaJpJEbpOukWKwXGueJryFlks/D+mag9sZNQksbW5/zdPiZ8SPGnxg+IPjH4o/EXXbvxN448e+IdS8T+J9cvWBmv8AVtVuHuLhkjUCK1tIdy21hYWyRWenWMNtY2UMNpbwxJ/Pfjt4h/2Dlb4Tymvy5znWHbzGrSnapl2T1eaEoc0XzU8VmiVShT1jOngViqyt9YpN/wCxP7J76G//ABFrjyP0hPEHKfbeG3hjnEI8HZfj8PzYTjLxIwDoYqhiHSrU3TxeR8CSlhM0xj5auHxfFNTIcul7RZTjqcf66P8Ag31/4KHf8J/4P/4Ye+LGueZ40+H2l3Wq/AjVdSuAZ/Enw+sVa51f4fiadvMuNU8BqZNS8P26vNLL4Ke6sreC10/wWGm/p3r/ACn/AIZ/Ejxn8H/iD4O+KPw71y78N+OPAXiHTPFHhjW7Nh51hq2k3KXNs7xtmK6tZiht7+xuUktNQsZrixvIZrW4mif/AElP2Cv2xvBn7cn7N3gz43+F/smna7PF/wAI98S/CEE5ll8E/EbSbe2PiDQm3u8zadcfaLbW/Dl1M3nXvhvVdKubgQ3j3VtAvAfxB/t3Kv8AVLNa/Nm+SYdPLqtWd6mYZNT5YQheT5qmIyu9OhPWU54GWFqu/wBXqNV+1l+h7/xCjj//AImF4Byr2Ph14o5vOHGWBwOH5cJwh4lYz22Kr4r2dGmqeEybj1U8VmuFfLSoYfiqjn+Ai4PNsJTl9mUUUV/Qp/joFFFFABWH4m8NeH/GfhzXvCHizR9P8Q+F/FGj6l4e8RaDq1tHeaZrOiaxZzafqml6haSho7izvrK4mtrmFwVkikdT1rcoqZRjOMoTjGcJxlCcJxjKE4TjKE4TjJSjKM4ylGUZRlGUZSjKLjJp60K9fC16GKw1athsThq1HE4bE4erUoYjD4jD1aWIw+Iw9ejUpVqFehXoUK9CtRq0qtGtRo1aVSnVpU6kP85f/gqV/wAE/vEH7A37Q9/4Z0+HUNR+CPxBfUfE3wU8VXfmTtLoS3Cf2j4L1e9IKS+J/A893badqDlvM1PSrjQ/ELRWx1lrK0/M+v8ATU/bq/Y38Afty/s8+Lfgl41WDTtVuEOu/DrxmbYXF74D+IGnW9wuheIbZRiSaxczzaV4h06N421Xw9qGp2Mc1tdSWt5a/wCbv8ZPhB4/+AfxR8b/AAc+KOhT+HPHnw+1678PeItKmyyLc2xV7e+sLjaqX+j6tZS22raJqkANrqmkXtlqNq729zE5/grxh8OpcE559dy6jL/VvOatWrl7im4ZfineriMpqS15Y01J1sA5O9TBS9leVTBzv/1tfs3/AKZtD6UHhYuF+Msxovxs8M8BgcBxdTqzp08RxhkCVPA5N4gYSivZ+1q410aeWcWwoU+XB8S0/rrhRwnEmG9n5nRRRX48f6QhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB+0X/Bu9/wAppf2AP+yua1/6rTx1X+ytX+NT/wAG73/KaX9gD/srmtf+q08dV/srUAFFFFABRRRQAUUUUAf4vP8AwXp/5TF/8FDP+zjPFP8A6R6XX5G1+uX/AAXp/wCUxf8AwUM/7OM8U/8ApHpdfkbQAUUUUAFFFFABRRRQAUUUUAfod/wSn/bi1j/gnV+3z+zp+1dZm7n8NeBfGcWk/FLR7NWml1/4QeNLabwn8TNMhtR8l3qUXhTVtQ1fw7HMrRweKdK0O9277RCP9tHw54i0Lxf4e0Hxb4X1ax1/wz4o0bS/EXh3XdLuI7vTNa0LW7GDU9I1bTruItFdWOo6fc295aXEbGOa3mjkQlWBr/Agr/Tu/wCDSL/gqvb/ALTv7L9z+wF8Wtfjk+Of7I/hy1f4XT39wPt3j79mpbuDS9Eht1Zi1xqPwZ1O8sPBF8iJBHF4M1T4diBLu6t9cuowD+wqiiigAooooAKKKKAP5av+C73/AAbffDX/AIKYf2x+0v8As133hz4NftsWGkKmrSahANP+G/7RFvpdssOm6Z8RpbC2lufD3j2ztIYtN0D4l2trfG5sYrXw94x0/UdMg0XW/CX+Zr+1X+xt+1B+xD8Tb34QftV/BTxx8FvHdqbiSzsPFemBdI8SWFtKIJNa8FeK9PlvvCvjjw+Zj5Ka/wCEdZ1nR2mDW/2zz45Ik/3X68D/AGj/ANlr9nb9r74a6l8H/wBpv4OeA/jX8OdUYzSeGvHeh2+qx2F95bwx6x4e1IeVrPhbxBbRySLZeI/DWo6TrtgHc2WowFmJAP8ACDor/TP/AGuf+DMH9hv4o/2prv7I3xs+LX7LHiK486ay8JeJxH8d/hRbsuXgsbO08Qal4d+J2nJMx8ibUtR+JnipreIxzx6XcSRSRXX4I/F7/gzO/wCCo/gf7Vd/DL4ifsq/G3T03mzstG+IPjHwN4ruAuSvn6Z47+H2k+F7V5BgIE8b3ShtwkeNQrsAfyPUV+6/ib/g2h/4LeeFbi5gvP2FfE+ppbyMq3Xhn4tfs++KLe5QfdmthoPxYv7hkkXDKkkEU652SwxyhkXyO4/4IF/8FkLa+TT5P+Cev7QbTuSFkt9D0e7sQR136na63NpsY54aS7VW/hJwaAPyEor9y/DH/Btd/wAFuPFk1vFp/wCwf4z09bh0XzvE/wATfgP4RhhVyMyXB8T/ABU0mSNIxlnHlmTAIWNnwp/RH4Of8GaX/BUrx59ku/ih49/Za+BenPsN7Za78Q/FXjvxZbB8bhb6X8PvAut+Frt4xnesnjmzQttEckgJZQD+SOtrw54b8ReMNd0rwv4R0DWvFPibXbyHTtE8O+HNKvtb13WNQuG2wWOlaRpkF1qGoXk7fLDa2lvNPI3CIxr/AEkP2X/+DKr9jfwJ/Z+r/tX/ALS/xn/aD1iDyp7nwx8ONK0P4GeAJ5DtabT9RMk3xF8dapaR/NFHfaT4u8HXdxgXBgtdxtU/p2/ZD/4Jx/sOfsG6Guifsmfsz/C/4PTPaCxv/FmkaI2s/EnXbTC5t/EnxS8Uz658RfEdvuUulrrXie+tYXeQ28EQkYEA/wA57/gmt/waXft0ftbtoPxE/a0ln/Yk+CF4be9Ol+MtFOqftEeKdOYiQw6R8Kpp7JfAIuVSazm1D4oahoeuaTK9vqFv4C8R2TbX/wBAD/gnv/wR+/YH/wCCZfh+G1/Zj+CumW3xBm07+zvEXx28etb+Nfjf4qikjEd4l745vbOA+H9N1ALG194X8B6d4R8HzyxRXDeHvtKmZv05ooAK/iq/4Pbv+TJf2Pv+zp9U/wDVS+MK/tVr+Kr/AIPbv+TJf2Pv+zp9U/8AVS+MKAP81yiiigAooooAKKKKACiiigD+lP8A4NT/ANsj/hln/grD8OfAGvar9g+H37XnhnWf2ddfjnm22MfjPVpLbxP8ItQEBZVl1a78f+H9N8C6bJy8MHj3UgisJmB/1pa/wMfAnjbxN8NPG/g34jeCtVuNC8ZeAPFXh7xt4S1u0O260bxN4V1ez13QdVtm7XGn6rYWl3Ce0kKmv9zn9jb9pLwx+2F+yn+z1+1D4Q+zx6J8dPhJ4J+Io0+2lM66Dq+v6Ja3HiTwtNIWcm98J+JP7W8M6iu+TZf6Tcp5km3ewB9K0UUUAFFFFABRRRQAUUUUAFFFeY/Gv4t+D/gF8HPit8cviFe/2d4E+Dnw58a/FDxjfAoHtvDPgTw5qPifW5IRIyI9x/Z2mXC20RYGacxxLlnAIB/mTf8AB4X+2R/wvr/gpH4c/Zq8P6r9s8E/sZ/DLT/DF9bQz+fZj4vfFqDSvH/xBvLeSM+SXg8Jj4W+GL6EB5rLWPDOq2s8glWS3t/5Lq9i/aG+NvjD9pT48/GX9oT4g3H2jxt8bfif44+KfihlkeWGHWfHPiPUfEd5ZWZcAx6fp8moGw023VUitbC2traGOKGJI18doAKKKKACiiigAooooAKVWZWDKSrKQyspIZWByCCOQQeQRyDyKSigD/Z4/wCCFf8AwUCg/wCCj/8AwTc+Bfxt1nVotS+L3g/TT8Fvj/EZVkvU+Lvw3sdOsNV12+VSRFL8QfD114a+JccUY8q2i8YrYod9nKqfsBX+UF/wa4/8FV7f9gT9tX/hQvxZ1+LTP2Zv2xtQ8NeBfE+o6lcLDpnw5+MFpPc2Hwq+Ics9wwt9N0W/vdYuvAvje5Z7O0i0nXtJ8Uaxdm08DwQN/q+0AFFFFABRRRQAV+c3/BTX/gmB+zR/wVS/Z8vPgZ+0Hos1jquky3etfCf4u+HLeyX4hfCDxhPBHEdb8M3t3FJHeaPqqQW1n4v8IagTovirTIYEuBZ6zpuga7ov6M0UAf4y/wDwU7/4IZ/t3f8ABLnxJrmofFX4d3/xG/Z8i1V7Xwr+058NNNvNZ+Geq2FxOI9JHjGO3N3qfwq8SXavFby+HvG6WVvcaot1a+Ftc8V2FumrXH431/v0arpOl69peo6Jrmm6frOi6xY3WmatpGq2dvqOl6ppt9A9tfafqOn3kc1pe2N5bSyW91aXMUtvcQSPFNG8bsp/m3/bH/4NSf8AglB+1Pea74p8B+A/GX7I/wAQtanu9Rk1n9nnX4dO8DzarcM7q938I/Ftl4l8C6XpCM/zaJ8PLL4ewlVUQ3Fuxd3AP8l+iv7V/jn/AMGTX7Z/hvUNTn/Z2/ay/Zz+LGgQSPLpsHxS0v4hfBnxXd233ktjY6BoXxf8Om+QnyvMn8S2FpOFM5e03i2T8u/iH/wa0/8ABbfwFfy21j+yZpXxG05C4TXvh58c/gVqNhPsOP3WneIfiH4Z8UKGGGQ3Hh6DcDj74ZAAfz2UV+xWuf8ABvz/AMFmfDxYX/8AwT6+OlwVOD/YcHhPxMD2+VvDfifVg491JB6g4rZ8Pf8ABu5/wWm8TbP7N/YA+Ldt5mNv/CQ638M/CWM/3/8AhK/Hei+V7+Zsx3xQB+LlFf05/B7/AINGP+CyfxNa2PjH4f8AwN/Z/gnKlpvi78cvDeqtBExB8yW1+CFr8Y7pW2Hd5DRLOp/dzJE4ZV/ZL9mn/gyItI7m01T9sP8AbcuLq0V4xfeCP2a/AUdlcSxja0rW3xS+J5vkgY/NEkcvwgnAGJjNnMAAP8/qv2S/4J4f8EHf+Cjn/BSLUtH1P4T/AAW1P4b/AAZv2t57v9oX432mr/D/AOFS6ZMQTeeFrm80yfxF8SpSgZYoPh3oXiS3huTDHrF9o1tL9sT/AEx/2NP+Dfr/AIJSfsPX2neJfhh+y74b8ffEfTDBLa/FP4+XU3xm8ZWt7bEG31TRbXxak/gnwdq8TbmXVPA3g/wxffvHVpzHtRf2eACgKoAAAAAGAAOAABwABwAOlAH8z3/BNP8A4NbP+CfH7Cv9gfED4waOn7Z/7QemfZr4eNPjBoFivwt8L6vDtkE/gH4KPcav4che2nSKez1jx7fePdfsr63j1LQ77w/I5tY/6YERI0SONFjjjVUREUKiIoCqiKoCqqqAFUAAAAAYp1FAHw5/wU7/AOUa3/BQv/sxz9rL/wBUJ4/r/Dqr/cV/4Kd/8o1v+Chf/Zjn7WX/AKoTx/X+HVQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFfsD/AMEff+CcV/8At0fHNfEvjzTLuL9m/wCEOoafqvxJvmEttD411rK3mi/C7S7tNkjTayEW98V3Fm6zaR4VSVPtOn6prvh6ab18hyPMeJM3wGSZVQdfHZhXjRpR1VOnH4q2IrzSl7LDYaiqlfEVWrQp03bmnOlCp+deLXipwZ4J+HXFfij4gZnDKuFuEMrrZlj6q5JYvG19aOXZNlWHnUpvHZ1neYzwuVZTgacufEY3Fwc3SwuGx2Jwn63f8EBv+CaX9h6fpv7dnxu8P41jV7W4j/Zz8MatbYfTNGu4pLTUPi3d2k6blvNbt5J9L8BmUIItFk1HxPFFcLrHhrUbT+qmqmn6fYaTYWWl6XZWmm6Zptpbafp2nWFtDZ2NhYWcKW9pZWVpbpHb2tpa28ccFtbQRpDBDGkUSKiqot1/oxwZwll3BWQYPIsuipKjH2uNxbgo1swx9WMfrOMrWu1zzXJQpuUlh8LToUIv3akqn/GB9Jf6QnGf0nPF3iXxV4yqToPMazwHDPD1PETr5fwhwjga1dZHw3l3NywksLh6jxWZ42NGlUzfPMbmua143r4SlgyiiivqT8DCiiigArN1nWNJ8O6RqviDXtSsdG0PQtNvtY1rV9TuYbLTdK0nTLWW91HUtQvLh47e0sbGzgmuru5ndIYIIpJZXVEYjSr+V3/g4L/4KLf8I/pMn7CXwh13brev2lhq/wC0PremXG2XSvD1ykOo+H/has8Lb47vxFE1r4i8YRKYmXw+dD0d5Lq08Q63ZQ/LcZ8V4Dgvh7HZ7j2p+wh7LBYTnUKmPzCtGccJg6W7XtKi561SMZewwtLEVmvdgp/vn0Z/o/cW/Sb8YuFfCfhONTD/ANq4j69xNn7w8q+D4T4Py6ph6nEHEeNXu05fVMJUWFyzC1KtJ5pnuYZRllOX7/FTw/4kf8FW/wBv7Vv28/2j9Q1zQ7u+t/gZ8NH1Lwn8FtBn86BZ9INzGNY8eahZShDDrvju6s7a/kjlhiuNO0G08P6HcB7jSri5ufzAoor/ADjznOMfn+a4/Oc0rvEY/McTUxOIqO6ipTdoUqUW5KnQoUlToYelF8tKjRpwV7SlP/tL8M/DnhLwi4B4T8NOBMrp5RwpwbkuEyTJ8HDllVlSw0ObEY7HV406csZmua42pjM1zbH1Y+1x2Z5hjMRPlUqFLDlfq1/wSM/4KAXv7Cv7SNlL4q1G6PwD+LUumeEvjBpoMssGjRC4kj8O/Ee1tY97Nf8Agm7vbmW/WGKee+8LX/iCxt7abUZNMktvyloqsjznH8PZtgM6yus6GOy7E08TQnryS5XapRrRTj7TD4ijKrh8RTbtUo1px0koShl4peGnCPjH4e8XeGPHeWxzThXjPJcXk2aYf3I4igq8efB5nl9adOp9UzbJ8wpYHN8pxsI8+EzHL8NVXNSniqOI/wBY6xvrLU7Kz1LTby11DTtQtbe+sL+xuIruyvrK7iSe1vLS6geSC5tbmCSOa3uIXeKaJ0kjdkYE2q/ma/4N+v8Agod/ws3wL/wxN8WNc83x/wDDLR59R+COqalcZuPFXwz09d+oeCBNO2+51f4eK3n6Nbo8ks/gaT7NbW0Fl4Lup5v6Za/0e4Q4owHGPD+X59l7UaeLp8uJwzkpVMDjqSjDGYKtaz56FZvkk4x9th6mHrxXLVaj/wAVn0i/Aji76Nvi/wAXeEvGNOVTFZBjfbZLnMaE6GD4p4VzCVbEcOcT5cpc0fq+a5dGH1mhCrVeXZthM4yqtP2uXxdcooor6U/EAooooAK/n6/4Lof8E2P+GmvhdJ+018H9A+0fHn4OaDOfEuj6Xbbr/wCKPwu04TXt5pyQQr5l/wCLPBSvd6x4cCZvNV0l9Y8Oxx6het4btbX+gWivA4n4by3izI8fkOaU+fDY2k1GrGMXWwmJheWFxuGck1Gvha3LUg7pTj7WjUvSr1EfrngV41ca/R78U+E/FjgLGewzzhjHxqV8DVqVoZdxDkeKdOhnvDOc06Mk6+U57lvtsHiVyzqYWusBmeEUMflWEqP/ACZ6K/oG/wCC6H/BNj/hmX4ov+018H9A+z/AX4x69MfEuj6XbbLD4XfFHUTPe3mnR28KiOw8JeNSl1q/hwRhbPStXTWPDqR6fZJ4btrv+fmv85eJ+G8y4TzzH5DmlPlxOCqtQqxUlRxeGneWFxuHcleVDFUeWpDVuEva0alqtCoj/tH8CvGrgr6QnhZwn4scBYz2+R8T4BVK+BrVKM8x4ezzCqnQz3hnOadGTjQzbIsy9tg8QuWFPFUHgMzwingM1wlRFFFFeAfroUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB+0X/Bu9/wAppf2AP+yua1/6rTx1X+ytX+NT/wAG73/KaX9gD/srmtf+q08dV/srUAFFFFABRRRQAUUUUAf4vP8AwXp/5TF/8FDP+zjPFP8A6R6XX5G1+uX/AAXp/wCUxf8AwUM/7OM8U/8ApHpdfkbQAUUUUAFFFFABRRRQAUUUUAFfTP7Hf7Wvxm/YZ/aR+Ff7UvwD19dB+Jfwo8QprGmC6WWfRfEOk3UE2m+JfBviexilgfUfC3jDw/eaj4e1+yjnt7l9O1CaWwu7HUYbO+tvmaigD/cC/wCCa/8AwUL+Cf8AwU3/AGUPAP7UPwVu1tItbi/sL4j+ALu+gvPEXwn+KGlWto/iv4feIjEkLSTadLd29/oWrNa2cXiXwrqWh+JbW1trfVktofvav8Vj/gkx/wAFZf2hf+CTH7RNp8WvhRdTeK/hh4rl0zSfjt8C9U1Oe08J/FbwjaTyMnziO5j8P+O/DqXV7d+BvG9tZ3F5oV7cXVjfW2r+F9Y8Q+HtY/16v2H/ANuf9m//AIKGfADwp+0Z+zJ47svGHgvxDbwwa1o00lrbeM/hz4qW2hn1XwF8RvDsN1dXHhnxfojzKtzZzSTWOpWj2mu+HtQ1nw5qelaxfAH17RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfxVf8Ht3/Jkv7H3/AGdPqn/qpfGFf2q1/FV/we3f8mS/sff9nT6p/wCql8YUAf5rlFFFABRRRQAUUUUAFFFFABX+mh/wZkftkf8AC1/2IPjF+x34i1X7R4n/AGUviafE3guznnw6fCD45S6r4it7OwgkYyTpovxR0f4jXupzQEw2ieLtDgljheeF7n/Mvr+hL/g2G/bI/wCGRP8Agrd8DLDWtV/s74e/tQW2pfsu+NhLNttje/Ei6025+F9yY5GFutwnxf0LwJppvZCklnpOr6yI5AlxNFMAf681FFFABRRRQAUUUUAFFFFABX8q3/B3j+2R/wAM7/8ABMRPgHoGq/YvHn7ZvxG0n4bJBBN5GoJ8KvAMtj8QPihqdswYM9rPeWXgTwNq0IVln0zx9cxOQrkN/VTX+Uv/AMHcH7ZH/DSP/BUjUvgr4f1X7d4A/Y18AaL8IbSK3m87TpviZ4mSHx78VtVhBYmPULa61fw18PtYjCoEvPh1sCsVMsoB/LfRRRQAUUUUAFFFFABRRRQAUUUUAFf6lH/BsR/wW/h/bw+Ddn+xj+0n4qib9sH4C+E7ePwt4i1m7Vb/APaF+D2gQwWFp4kW4nYPqXxM8BWv2TS/H9u5k1LxFpA03x8kmp3U3jWXRP8ALXr0j4P/ABg+J3wA+J/gf4z/AAY8b6/8OPil8N/EFl4o8E+NvDF61jrWg61YMTFcW8oDxT288TzWWpabew3OmavplzeaVqtneabeXVrMAf72FFfzsf8ABCH/AIL2fCb/AIKr/DKw+GXxPvvDPwy/bk8CaKg8e/DJbqLTdK+K+nadbZuvil8HrW8nM9/pc8cL3fi7wbBJeav4DvTKZvtnhqfStbu/6J6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA+HP8Agp3/AMo1v+Chf/Zjn7WX/qhPH9f4dVf7iv8AwU7/AOUa3/BQv/sxz9rL/wBUJ4/r/DqoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKtWNje6ne2em6bZ3WoajqF1b2NhYWNvLd3t9e3cqQWtnaWsCST3N1czyRw29vCjyzSukcaM7AFpNtJJttpJJNtttJJJJtttpJJNttJJtpOZzhThKpUlGEIRlOc5yjCEIQjKc5znOUIQhCEJznOc4QhCE5znGMZSj7x+y5+zX8Sf2t/jj4G+BHwr0/7V4l8ZaksdzqVxHK2keFPDtpifxB4v8AEM0SsbbRPD+nCW8uiM3F5MLbStOjudV1CxtLj/SQ/ZX/AGZ/ht+yJ8DPA/wH+Flh9n8O+D9PAvtWniiTV/F3iW8CzeIfGHiGWIYuNZ1+/wB9zMNxgsLUWej6ctvpWm2FrB+fv/BHj/gnDZfs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FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF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FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z"
webUI["html/img/users.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0zMFQxNzowODozODwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CjU01MMAAANJSURBVGgF1ZnLaxNRFMYz2rpoFbW+SCsihaJQRMT6rPhAXAq6c+HChSguRFd1oRtd+A/oWhQ3oiiWFB91UbqRqlXXgoIIQhFbQTTQao2/GzLDZEjIPefO7SQHPjJz55zzfd/MZCa5N8h5ilKptJvWp8FekAed4Bv4Cj6Dh2A4CIJZPpszMHEV2MQ0SZdB0DROENMHjoEzQBoFCpZnbgYR58E/qfpE/kv2F2dmBvJ94G9ClHb3SiZGUBuASa3qGnVzjG3RmFmkKYrVHGB7e2zfdbOdBhc1TVyNnNSQNqg5wVURf/FdjRxpIEpzuIOio9JCtRHO2hrINkgJLfPFt6vaCII2WYrSpPVJi1RGuBrmTbxeSibIX5j3CUauAfOo9BXzNH4nMJ5TXREI1gHzqPQVRtc2zCyxJdAaGbclcMj7zi/jOdt6rZFhCH7akijznknqVEY4U78heSAhUuTekNSojFQIChIiYe57TtZrSY2LkecQzUjIBLljglz3VJ4qg+AXSDNGabbWXZ2wA6Qjabqg136hhHK6y60V8o2EGyl8/qHHpKZPGkYeQzyvIa9RM86XvFhjvOGQsxGIp2B50ZDJLuG2XZqnLO5rM3viGh9o0OZJon1bRLxxdHLcns1jJiYOAu2U0D2P0uStMXJdcVU+UdMlZ/NYgaA28ERg5ge5/R4l6VsjrANMWJiZJWeXnqm60vnxW90ul6u8ByaS4zX2i+S+qjGuGkrdSEWFzT1vlhlSC19Gui0UtnNriSfi6vX1ZWRjPcLEeGrzYqkb4SyvQGxvQnC93cF6BzIfx8gpYBsfSdycuei4AAR1ggugCCRh1lbugIF4vwXbhtisjfSDc+ARSOOf4lv6mNWv1VIj1ouQNF9K851gDzArtWbV1uYxS5o4zB+sp+AuKPC+cVv5RXwPuATMmUpreY1Wopgh+ybYKj4dFHWB+8DMwTZTjCHmsJUhEgfAF9DMcQtx9V8dHMyDqWZ2ENM2FL8yVV92kkY56GM5Lc6Z1vY0jbp5EJQnuqPLg4kdLWTCnIxVIJoDi4wweNYcbbGIfuLEjRxqMRNGbvTvsmyE22oZg70taKQn1BxekXw40GKfK0O9oZHsJ8ZCRbLPaI3xP7YzeQoHxWckAAAAAElFTkSuQmCC"
- webUI["html/img/logo_b_880x200.jpg"] = "/9j/4AAQSkZJRgABAQABLAEsAAD/4QDIRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAPAAAAcgEyAAIAAAAUAAAAgodpAAQAAAABAAAAlgAAAAAAAAEsAAAAAQAAASwAAAABUGl4ZWxtYXRvciAzLjMAADIwMTk6MDg6MDIgMjA6MDg6MTQAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAA3CgAwAEAAAAAQAAAMgAAAAA/+EJkGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iUGl4ZWxtYXRvciAzLjMiIHhtcDpNb2RpZnlEYXRlPSIyMDE5LTA4LTAyVDIwOjA4OjE0Ii8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAyANwAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/dAAQAbv/aAAwDAQACEQMRAD8A/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9D+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//0f4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//S/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9P+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//1P4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDvPDXws+J3jPT31bwf8OfHnivSo7mSyfU/DXhDxBrunpeQpFLNaPe6Xp11bLcxRzwSSQNL5saTROyhZUNAHQf8M//AB4/6In8XP8Aw23jL/5TUAH/AAz/APHj/oifxc/8Nt4y/wDl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f/E3xn4o+IPjnxDLaafp8mveMPGet33iPxNrMlhpNpYaVZPqmtale3z2mmWNlp9s05hsrS2tkjhQA4ygAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//S/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAczu+N7M2BgbmLYHoM9BnJxx1/FgBtABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAOLuwVWZiq/dUsSFz12joM4HQduc4FADaACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//0/4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//U/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9X+IegAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//1v4h6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//X/iHoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAP/9k="
- webUI["html/img/filter.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzo2OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cs038OQAAAOISURBVGgF5ZpLSBVRGMfvvfmqCKKiKCqKtE3SQ8haJJm1ctPCZYHrFhXtohcUBLVsU1BRBJKLXpsSKs1aCL1oUUhvMgIloodZKmLZ72+OzNVx7jzOXGfqg/89Z875zv/7f35n7px7vanUP2JptzyGhoYKmK8GW0EZmA/mgW7wHrwDN0BTOp0epPVtxBBnLdgIVoE5YBboBR2gDTTA/5DWn0FeDPaBz8CLdeF0EBR5jYRvKbgABoAXa8Opwit/CudK8NoLs4PPM8ZyBsNnB/jpsD7X0C8cjgDXnaQkqkEPCGMSuGWivxxzx8OQj6xtpHWuPhPloHfEMWzTD0HN2GQY2xuW2Lb+/Fh+VaIQPLE5meh+gmSxFYz+BjBogtjGscfiH26Z2GmbNNltVQAIpwDdP6ZNO2iRYqTpZGhfgWUaiMC2w1kCzkbALcqLvDVvUyK6MW9HFES0b8BvsFwXEZi4F+iBtykCcjtlqf0igr52VJ1eqiIgzzdlrRIZfWfJd3SD8ZbqHvkB4XSDpJNB9V0VcX/cT4Ys/zEzSuSj/3WxW9GpRD7ETpZ/QcOJ6LyfdHugitxNehbob9G7lo4PXWBmQhPqQ/fsDOeUfjqNCU1Csi+TQ5+2luzc3yaRr6elevQZwhZr4bomYam0U41yabYqov5hvSTMjlp6RyuiAarSTLPZmox5246+lVREx/isiuh6NxhUJwF2yEpCWu1bK8WEsjyRgCSa0XrVrjNra2mC7TWD5ilYAuJoA4jSlnppF5dVEU3g0ENTD4b3nsZiZsfGJuGqj8qY+CINGqP2GLZCJ+HjtpblxAJ9k3cPrLfGJrnVUaSCarxw0jFua1lOLNBerANx+byya6IkLM2uLZWpAl6/Mcc1EjvjKtLrJNLqI5HnjfQ+bsVeteb0g2y/t7hGvd7CNjenOL8OkJ40KtOdTF+Cl/nV6Mkf4gxocI9vZPYLLKs9iQrqRIACcM2IXGeSboYrg+rztY5ARaDJWUeo0W+sXudLTFhnApaAW6FkZy/+yuXasLoCrSfwVHAnW0+gK93YawKJMLUIAdNAKwhqnSxcYUpPKB6EBE2mg7VR///EX24jybTQerXnOC70FyVP3gjTPXPTQyaP8NFPNeJrCNTPP667JKOq6VNo/A2hes5ccUjmEmPmDoD5+FMgWCcA+3FG57QJP//kQ1PgGBIOToEDgUn+t4V/AJeGknwARIKLAAAAAElFTkSuQmCC"
+ webUI["html/img/x_ transparent.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTo3NjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjI1NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoeXQb1AAAaJElEQVR4Ae2dCZhcVZXHz+1KSFiGkISkqyIoOgI68EkgOBNkEcQRlIFRZDGABAQEhInGbxw+RUZRNhWRLawDYR0GHAaHUVkGvwGURUcgwIiAOGxjV3UHAslHQrbuM/9TlQ6d7qruWt527/u/7+uuqvvucu7vvnveuffde54IDxIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARLwiIDzQtayHi0q23shaydCOnlISu7nnWThRdrFOkPWyCleyNqJkF1yjhTd8k6yiDvtuLgLiCR/lVnIZ14keWU7k2Xyuu4oU92r2RazQ+nWypXI4W86zCXbyZ28KBvJ97MtpEhX1gWsyleS08TJU17I2omQKpvLarmqkywyn7ZHPw9rLvTOvwbX6xEyxS3Nenv4oQCcWwmQc/D3dtaBdiyfyv5S1mM7zieLGSzWEsS6KIuiRSzTGTD9H404z1iy80MBWNVL7hn8nx8LhaxlqnKBvKbvyppYHctTM/0nd5xPljNwcrcUs2/6DyL0RwGYxDOcjR3vGBQ+4M8tMElmdQ3n6NGjYPofGE6F6tTESRmm/1xxTuuczWSQH08BhqJbqlNkuTyJoK2GBgf53S6mkrvB+7qZ6b9Gfod6hHv3dzKAGbX9pNvd51N7+WUBGNlJbgm07FH4G/AJdFuyqlwotXFzW8kzk2itXAFZwu38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"
webUI["html/img/x_black.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMTozNzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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a1jSekqmtA1rrGsx7JYkDuvrVahwRdgVXD1xcwri6mmYRULLe4CuPc2wfrGo4U+7Y/3S9ZHD+GcflbnfiCJbr77whoaS6ucCXVkVkuLKgORQwNJFygRDJnqwb9i3b0HxkqjT0L4erGy5Rh1IRnhXrpaZq6GZCyRLf6cvhoTY6V9koX8bGdEUlyWVm6W5q1GuostihNm97L/dpm5k+QHCbDna0zRzgSS/lRHWL7iHPOa+9YsYkpttoCwSMcQRkrWioz5Qsc7aFJ1coHY3QyJ9jSjfJEOCfTUpWzehVBnUbqCJOCHEkB1xsmXDwq9DnObUz9q4QOUqYPaPKFzUKcVj6Eeu461q67Vhlqy6+Xo11G52JhRZNNW1FRbN00FWPVwguSa+8YEZ1i+D9vQjelm/iHTwAB69Vwd7CkuGLOcWtxfR4o+dHhNg4DNmhDvJ8M6ehknvhTXMDp8kQQgT33W4z+i7k/2gho+Jvrp1NTVwgW5opV76yl8F/cufe9CyJiRllZ6lYCHMXWPAXmNp9CRb8Pi30r658sHtCSCPsZNXQDYdMaLIek/No13V/rBfGMFSCXnsKNo1dDelnKt/dyUH8uvjjLH+zyfpbv1iUl/NVBt4mVJy58HoDyFZLt0rrj4G7TfIjARvMjy7d6JnR/UXS/+yeD5kLYkETxpRZL2jZJVzb7cl9yZA/cYqh4z+20AEzOj+BKxbZYRFqXQssvLs5gQzpBUp616rNsX55WdXBHbPBRrwlBm5v2VYJo1FsjmOtQg8ezo+fd8Ve4qy04HPRlmR1UiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABGwg8D8UnyVeZFwGAQAAAABJRU5ErkJggg=="
- webUI["html/js/base_ts.js"] = "dmFyIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKdmFyIEJVTEtfRURJVCA9IGZhbHNlOwp2YXIgQ09MVU1OX1RPX1NPUlQ7CnZhciBTRUFSQ0hfTUFQUElORyA9IG5ldyBPYmplY3QoKTsKdmFyIFVORE8gPSBuZXcgT2JqZWN0KCk7CnZhciBTRVJWRVJfQ09OTkVDVElPTiA9IGZhbHNlOwp2YXIgV1NfQVZBSUxBQkxFID0gZmFsc2U7Ci8vIE1lbsO8CnZhciBtZW51SXRlbXMgPSBuZXcgQXJyYXkoKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgicGxheWxpc3QiLCAie3subWFpbk1lbnUuaXRlbS5wbGF5bGlzdH19IiwgIm0zdS5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUucGxheWxpc3R9fSIpKTsKLy9tZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJwbXNJRCIsICJ7ey5tYWluTWVudS5pdGVtLnBtc0lEfX0iLCAibnVtYmVyLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5wbXNJRH19IikpCm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oImZpbHRlciIsICJ7ey5tYWluTWVudS5pdGVtLmZpbHRlcn19IiwgImZpbHRlci5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUuZmlsdGVyfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInhtbHR2IiwgInt7Lm1haW5NZW51Lml0ZW0ueG1sdHZ9fSIsICJ4bWx0di5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUueG1sdHZ9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibWFwcGluZyIsICJ7ey5tYWluTWVudS5pdGVtLm1hcHBpbmd9fSIsICJtYXBwaW5nLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5tYXBwaW5nfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInVzZXJzIiwgInt7Lm1haW5NZW51Lml0ZW0udXNlcnN9fSIsICJ1c2Vycy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUudXNlcnN9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgic2V0dGluZ3MiLCAie3subWFpbk1lbnUuaXRlbS5zZXR0aW5nc319IiwgInNldHRpbmdzLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5zZXR0aW5nc319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJsb2ciLCAie3subWFpbk1lbnUuaXRlbS5sb2d9fSIsICJsb2cucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmxvZ319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJsb2dvdXQiLCAie3subWFpbk1lbnUuaXRlbS5sb2dvdXR9fSIsICJsb2dvdXQucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmxvZ291dH19IikpOwovLyBLYXRlZ29yaWVuIGbDvHIgZGllIEVpbnN0ZWxsdW5nZW4KdmFyIHNldHRpbmdzQ2F0ZWdvcnkgPSBuZXcgQXJyYXkoKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkuZ2VuZXJhbH19IiwgInh0ZXZlQXV0b1VwZGF0ZSx0dW5lcixlcGdTb3VyY2UsYXBpIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5maWxlc319IiwgInVwZGF0ZSxmaWxlcy51cGRhdGUsdGVtcC5wYXRoLGNhY2hlLmltYWdlcyx4ZXBnLnJlcGxhY2UubWlzc2luZy5pbWFnZXMiKSk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LnN0cmVhbWluZ319IiwgImJ1ZmZlcix1ZHB4eSxidWZmZXIuc2l6ZS5rYixidWZmZXIudGltZW91dCx1c2VyLmFnZW50LGZmbXBlZy5wYXRoLGZmbXBlZy5vcHRpb25zLHZsYy5wYXRoLHZsYy5vcHRpb25zIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5iYWNrdXB9fSIsICJiYWNrdXAucGF0aCxiYWNrdXAua2VlcCIpKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkuYXV0aGVudGljYXRpb259fSIsICJhdXRoZW50aWNhdGlvbi53ZWIsYXV0aGVudGljYXRpb24ucG1zLGF1dGhlbnRpY2F0aW9uLm0zdSxhdXRoZW50aWNhdGlvbi54bWwsYXV0aGVudGljYXRpb24uYXBpIikpOwpmdW5jdGlvbiBzaG93UG9wVXBFbGVtZW50KGVsbSkgewogICAgdmFyIGFsbEVsZW1lbnRzID0gbmV3IEFycmF5KCJwb3B1cC1jdXN0b20iKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKICAgICAgICBzaG93RWxlbWVudChhbGxFbGVtZW50c1tpXSwgZmFsc2UpOwogICAgfQogICAgc2hvd0VsZW1lbnQoZWxtLCB0cnVlKTsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIHRydWUpOwogICAgfSwgMTApOwogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIHNob3dFbGVtZW50KGVsbUlELCB0eXBlKSB7CiAgICB2YXIgY3NzQ2xhc3M7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIHRydWU6CiAgICAgICAgICAgIGNzc0NsYXNzID0gImJsb2NrIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgY3NzQ2xhc3MgPSAibm9uZSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtSUQpLmNsYXNzTmFtZSA9IGNzc0NsYXNzOwp9CmZ1bmN0aW9uIGNoYW5nZUJ1dHRvbkFjdGlvbihlbGVtZW50LCBidXR0b25JRCwgYXR0cmlidXRlKSB7CiAgICB2YXIgdmFsdWUgPSBlbGVtZW50Lm9wdGlvbnNbZWxlbWVudC5zZWxlY3RlZEluZGV4XS52YWx1ZTsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbklEKS5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7Cn0KZnVuY3Rpb24gZ2V0TG9jYWxEYXRhKGRhdGFUeXBlLCBpZCkgewogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CiAgICAgICAgY2FzZSAibTN1IjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJoZGhyIjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgIGNhc2UgImdyb3VwLXRpdGxlIjoKICAgICAgICAgICAgaWYgKGlkID09IC0xKSB7CiAgICAgICAgICAgICAgICBkYXRhWyJhY3RpdmUiXSA9IHRydWU7CiAgICAgICAgICAgICAgICBkYXRhWyJjYXNlU2Vuc2l0aXZlIl0gPSBmYWxzZTsKICAgICAgICAgICAgICAgIGRhdGFbImRlc2NyaXB0aW9uIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbImV4Y2x1ZGUiXSA9ICIiOwogICAgICAgICAgICAgICAgZGF0YVsiZmlsdGVyIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbImluY2x1ZGUiXSA9ICIiOwogICAgICAgICAgICAgICAgZGF0YVsibmFtZSJdID0gIiI7CiAgICAgICAgICAgICAgICBkYXRhWyJ0eXBlIl0gPSAiZ3JvdXAtdGl0bGUiOwogICAgICAgICAgICAgICAgU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWx0ZXIiXVtpZF0gPSBkYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbHRlciJdW2lkXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWxlcyJdW2RhdGFUeXBlXVtpZF07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsidXNlcnMiXVtpZF1bImRhdGEiXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdW2lkXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAibTN1R3JvdXBzIjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsiZGF0YSJdWyJwbGF5bGlzdCJdWyJtM3UiXVsiZ3JvdXBzIl07CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIGRhdGE7Cn0KZnVuY3Rpb24gZ2V0T2JqS2V5cyhvYmopIHsKICAgIHZhciBrZXlzID0gbmV3IEFycmF5KCk7CiAgICBmb3IgKHZhciBpIGluIG9iaikgewogICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHsKICAgICAgICAgICAga2V5cy5wdXNoKGkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBrZXlzOwp9CmZ1bmN0aW9uIGdldEFsbFNlbGVjdGVkQ2hhbm5lbHMoKSB7CiAgICB2YXIgY2hhbm5lbHMgPSBuZXcgQXJyYXkoKTsKICAgIGlmIChCVUxLX0VESVQgPT0gZmFsc2UpIHsKICAgICAgICByZXR1cm4gY2hhbm5lbHM7CiAgICB9CiAgICB2YXIgdHJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfdGFibGUiKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVFIiKTsKICAgIGZvciAodmFyIGkgPSAxOyBpIDwgdHJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKHRyc1tpXS5zdHlsZS5kaXNwbGF5ICE9ICJub25lIikgewogICAgICAgICAgICBpZiAodHJzW2ldLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZC5jaGVja2VkID09IHRydWUpIHsKICAgICAgICAgICAgICAgIGNoYW5uZWxzLnB1c2godHJzW2ldLmlkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBjaGFubmVsczsKfQpmdW5jdGlvbiBzZWxlY3RBbGxDaGFubmVscygpIHsKICAgIHZhciBidWxrID0gZmFsc2U7CiAgICB2YXIgdHJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfdGFibGUiKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVFIiKTsKICAgIGlmICh0cnNbMF0uZmlyc3RDaGlsZC5maXJzdENoaWxkLmNoZWNrZWQgPT0gdHJ1ZSkgewogICAgICAgIGJ1bGsgPSB0cnVlOwogICAgfQogICAgZm9yICh2YXIgaSA9IDE7IGkgPCB0cnMubGVuZ3RoOyBpKyspIHsKICAgICAgICBpZiAodHJzW2ldLnN0eWxlLmRpc3BsYXkgIT0gIm5vbmUiKSB7CiAgICAgICAgICAgIHN3aXRjaCAoYnVsaykgewogICAgICAgICAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICAgICAgICAgIHRyc1tpXS5maXJzdENoaWxkLmZpcnN0Q2hpbGQuY2hlY2tlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICAgICAgICAgIHRyc1tpXS5maXJzdENoaWxkLmZpcnN0Q2hpbGQuY2hlY2tlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIGJ1bGtFZGl0KCkgewogICAgQlVMS19FRElUID0gIUJVTEtfRURJVDsKICAgIHZhciBjbGFzc05hbWU7CiAgICB2YXIgcm93cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImJ1bGsiKTsKICAgIHN3aXRjaCAoQlVMS19FRElUKSB7CiAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICBjbGFzc05hbWUgPSAiYnVsayBzaG93QnVsayI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgIGNsYXNzTmFtZSA9ICJidWxrIGhpZGVCdWxrIjsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspIHsKICAgICAgICByb3dzW2ldLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKICAgICAgICByb3dzW2ldLmNoZWNrZWQgPSBmYWxzZTsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBzb3J0VGFibGUoY29sdW1uKSB7CiAgICAvL2NvbnNvbGUubG9nKGNvbHVtbSk7CiAgICBpZiAoY29sdW1uID09IENPTFVNTl9UT19TT1JUKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfdGFibGUiKTsKICAgIHZhciB0YWJsZUhlYWQgPSB0YWJsZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVFIiKVswXTsKICAgIHZhciB0YWJsZUl0ZW1zID0gdGFibGVIZWFkLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJURCIpOwogICAgdmFyIHNvcnRPYmogPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgeCwgeFZhbHVlOwogICAgdmFyIHRhYmxlSGVhZGVyOwogICAgdmFyIHNvcnRCeVN0cmluZyA9IGZhbHNlOwogICAgaWYgKGNvbHVtbiA+IDAgJiYgQ09MVU1OX1RPX1NPUlQgPiAwKSB7CiAgICAgICAgdGFibGVJdGVtc1tDT0xVTU5fVE9fU09SVF0uY2xhc3NOYW1lID0gInBvaW50ZXIiOwogICAgICAgIHRhYmxlSXRlbXNbY29sdW1uXS5jbGFzc05hbWUgPSAic29ydFRoaXMiOwogICAgfQogICAgQ09MVU1OX1RPX1NPUlQgPSBjb2x1bW47CiAgICB2YXIgcm93cyA9IHRhYmxlLnJvd3M7CiAgICBpZiAocm93c1sxXSAhPSB1bmRlZmluZWQpIHsKICAgICAgICB0YWJsZUhlYWRlciA9IHJvd3NbMF07CiAgICAgICAgeCA9IHJvd3NbMV0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlREIilbY29sdW1uXTsKICAgICAgICBmb3IgKGkgPSAxOyBpIDwgcm93cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB4ID0gcm93c1tpXS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKVtjb2x1bW5dOwogICAgICAgICAgICBzd2l0Y2ggKHguY2hpbGROb2Rlc1swXS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgImlucHV0IjoKICAgICAgICAgICAgICAgICAgICB4VmFsdWUgPSB4LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTlBVVCIpWzBdLnZhbHVlLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJwIjoKICAgICAgICAgICAgICAgICAgICB4VmFsdWUgPSB4LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJQIilbMF0uaW5uZXJUZXh0LnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OiBjb25zb2xlLmxvZyh4LmNoaWxkTm9kZXNbMF0udGFnTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHhWYWx1ZSA9PSAiIiB8fCB4VmFsdWUgPT0gTmFOKSB7CiAgICAgICAgICAgICAgICB4VmFsdWUgPSBpOwogICAgICAgICAgICAgICAgc29ydE9ialtpXSA9IHJvd3NbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGlzTmFOKHhWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICAgICAgICAgICAgICB4VmFsdWUgPSBwYXJzZUZsb2F0KHhWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRPYmpbeFZhbHVlXSA9IHJvd3NbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgICAgICAgICAgc29ydEJ5U3RyaW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgc29ydE9ialt4VmFsdWUudG9Mb3dlckNhc2UoKSArIGldID0gcm93c1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd2hpbGUgKHRhYmxlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgdGFibGUucmVtb3ZlQ2hpbGQodGFibGUuZmlyc3RDaGlsZCk7CiAgICAgICAgfQogICAgICAgIHZhciBzb3J0VmFsdWVzID0gZ2V0T2JqS2V5cyhzb3J0T2JqKTsKICAgICAgICBpZiAoc29ydEJ5U3RyaW5nID09IHRydWUpIHsKICAgICAgICAgICAgc29ydFZhbHVlcy5zb3J0KCk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKHNvcnRWYWx1ZXMpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZnVuY3Rpb24gc29ydEZsb2F0KGEsIGIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhIC0gYjsKICAgICAgICAgICAgfQogICAgICAgICAgICBzb3J0VmFsdWVzLnNvcnQoc29ydEZsb2F0KTsKICAgICAgICB9CiAgICAgICAgdGFibGUuYXBwZW5kQ2hpbGQodGFibGVIZWFkZXIpOwogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc29ydFZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChzb3J0T2JqW3NvcnRWYWx1ZXNbaV1dKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gY3JlYXRlU2VhcmNoT2JqKCkgewogICAgU0VBUkNIX01BUFBJTkcgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgZGF0YSA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl07CiAgICB2YXIgY2hhbm5lbHMgPSBnZXRPYmpLZXlzKGRhdGEpOwogICAgdmFyIGNoYW5uZWxLZXlzID0gWyJ4LWFjdGl2ZSIsICJ4LWNoYW5uZWxJRCIsICJ4LW5hbWUiLCAiX2ZpbGUubTN1Lm5hbWUiLCAieC1ncm91cC10aXRsZSIsICJ4LXhtbHR2LWZpbGUiXTsKICAgIGNoYW5uZWxzLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7CiAgICAgICAgY2hhbm5lbEtleXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgICAgIGlmIChrZXkgPT0gIngtYWN0aXZlIikgewogICAgICAgICAgICAgICAgc3dpdGNoIChkYXRhW2lkXVtrZXldKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICAgICAgICAgICAgICBTRUFSQ0hfTUFQUElOR1tpZF0gPSAib25saW5lICI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIFNFQVJDSF9NQVBQSU5HW2lkXSA9ICJvZmZsaW5lICI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGtleSA9PSAieC14bWx0di1maWxlIikgewogICAgICAgICAgICAgICAgICAgIHZhciB4bWx0dkZpbGUgPSBnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZGF0YVtpZF1ba2V5XSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeG1sdHZGaWxlICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICBTRUFSQ0hfTUFQUElOR1tpZF0gPSBTRUFSQ0hfTUFQUElOR1tpZF0gKyB4bWx0dkZpbGUgKyAiICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgU0VBUkNIX01BUFBJTkdbaWRdID0gU0VBUkNIX01BUFBJTkdbaWRdICsgZGF0YVtpZF1ba2V5XSArICIgIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfSk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc2VhcmNoSW5NYXBwaW5nKCkgewogICAgdmFyIHNlYXJjaFZhbHVlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNlYXJjaE1hcHBpbmciKS52YWx1ZTsKICAgIHZhciB0cnMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudF90YWJsZSIpLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUUiIpOwogICAgZm9yICh2YXIgaSA9IDE7IGkgPCB0cnMubGVuZ3RoOyArK2kpIHsKICAgICAgICB2YXIgaWQgPSB0cnNbaV0uZ2V0QXR0cmlidXRlKCJpZCIpOwogICAgICAgIHZhciBlbGVtZW50ID0gU0VBUkNIX01BUFBJTkdbaWRdOwogICAgICAgIHN3aXRjaCAoZWxlbWVudC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFZhbHVlLnRvTG93ZXJDYXNlKCkpKSB7CiAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKSB7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIikpIHsKICAgICAgICB2YXIgZWxtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgICAgICAgdmFyIGRpdnMgPSBuZXcgQXJyYXkoIm15U3RyZWFtc0JveCIsICJjbGllbnRJbmZvIiwgImNvbnRlbnQiKTsKICAgICAgICB2YXIgZWxlbWVudHNIZWlnaHQgPSAwIC0gZWxtLm9mZnNldEhlaWdodDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpdnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgZWxlbWVudHNIZWlnaHQgPSBlbGVtZW50c0hlaWdodCArIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRpdnNbaV0pLm9mZnNldEhlaWdodDsKICAgICAgICB9CiAgICAgICAgZWxtLnN0eWxlLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGVsZW1lbnRzSGVpZ2h0ICsgInB4IjsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBjaGFuZ2VDaGFubmVsTnVtYmVyKGVsZW1lbnQpIHsKICAgIHZhciBkYklEID0gZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUuaWQ7CiAgICB2YXIgbmV3TnVtYmVyID0gcGFyc2VGbG9hdChlbGVtZW50LnZhbHVlKTsKICAgIHZhciBjaGFubmVsTnVtYmVycyA9IFtdOwogICAgdmFyIGRhdGEgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdOwogICAgdmFyIGNoYW5uZWxzID0gZ2V0T2JqS2V5cyhkYXRhKTsKICAgIGlmIChpc05hTihuZXdOdW1iZXIpKSB7CiAgICAgICAgYWxlcnQoInt7LmFsZXJ0LmludmFsaWRDaGFubmVsTnVtYmVyfX0iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjaGFubmVscy5mb3JFYWNoKGZ1bmN0aW9uIChpZCkgewogICAgICAgIHZhciBjaGFubmVsTnVtYmVyID0gcGFyc2VGbG9hdChkYXRhW2lkXVsieC1jaGFubmVsSUQiXSk7CiAgICAgICAgY2hhbm5lbE51bWJlcnMucHVzaChjaGFubmVsTnVtYmVyKTsKICAgIH0pOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFubmVsTnVtYmVycy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChjaGFubmVsTnVtYmVycy5pbmRleE9mKG5ld051bWJlcikgPT0gLTEpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChNYXRoLmZsb29yKG5ld051bWJlcikgPT0gbmV3TnVtYmVyKSB7CiAgICAgICAgICAgIG5ld051bWJlciA9IG5ld051bWJlciArIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBuZXdOdW1iZXIgPSBuZXdOdW1iZXIgKyAwLjE7CiAgICAgICAgICAgIG5ld051bWJlci50b0ZpeGVkKDEpOwogICAgICAgICAgICBuZXdOdW1iZXIgPSBNYXRoLnJvdW5kKG5ld051bWJlciAqIDEwKSAvIDEwOwogICAgICAgIH0KICAgIH0KICAgIGRhdGFbZGJJRF1bIngtY2hhbm5lbElEIl0gPSBuZXdOdW1iZXIudG9TdHJpbmcoKTsKICAgIGVsZW1lbnQudmFsdWUgPSBuZXdOdW1iZXI7CiAgICBjb25zb2xlLmxvZyhkYXRhW2RiSURdWyJ4LWNoYW5uZWxJRCJdKTsKICAgIGlmIChDT0xVTU5fVE9fU09SVCA9PSAxKSB7CiAgICAgICAgQ09MVU1OX1RPX1NPUlQgPSAtMTsKICAgICAgICBzb3J0VGFibGUoMSk7CiAgICB9CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gYmFja3VwKCkgewogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICBjb25zb2xlLmxvZygiQmFja3VwIGRhdGEiKTsKICAgIHZhciBjbWQgPSAieHRldmVCYWNrdXAiOwogICAgY29uc29sZS5sb2coIlNFTkQgVE8gU0VSVkVSIik7CiAgICBjb25zb2xlLmxvZyhkYXRhKTsKICAgIHZhciBzZXJ2ZXIgPSBuZXcgU2VydmVyKGNtZCk7CiAgICBzZXJ2ZXIucmVxdWVzdChkYXRhKTsKICAgIHJldHVybjsKfQpmdW5jdGlvbiB0b2dnbGVDaGFubmVsU3RhdHVzKGlkKSB7CiAgICB2YXIgZWxlbWVudDsKICAgIHZhciBzdGF0dXM7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImFjdGl2ZSIpKSB7CiAgICAgICAgdmFyIGNoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImFjdGl2ZSIpOwogICAgICAgIHN0YXR1cyA9IChjaGVja2JveCkuY2hlY2tlZDsKICAgIH0KICAgIHZhciBpZHMgPSBnZXRBbGxTZWxlY3RlZENoYW5uZWxzKCk7CiAgICBpZiAoaWRzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgaWRzLnB1c2goaWQpOwogICAgfQogICAgaWRzLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7CiAgICAgICAgdmFyIGNoYW5uZWwgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdW2lkXTsKICAgICAgICBjaGFubmVsWyJ4LWFjdGl2ZSJdID0gc3RhdHVzOwogICAgICAgIHN3aXRjaCAoY2hhbm5lbFsieC1hY3RpdmUiXSkgewogICAgICAgICAgICBjYXNlIHRydWU6CiAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbFsieC14bWx0di1maWxlIl0gPT0gIi0iIHx8IGNoYW5uZWxbIngtbWFwcGluZyJdID09ICItIikgewogICAgICAgICAgICAgICAgICAgIGlmIChCVUxLX0VESVQgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoY2hhbm5lbFsieC1uYW1lIl0gKyAiOiBNaXNzaW5nIFhNTFRWIGZpbGUgLyBjaGFubmVsIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFsieC1hY3RpdmUiXSA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgICAgICAvLyBjb2RlLi4uCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGNoYW5uZWxbIngtYWN0aXZlIl0gPT0gZmFsc2UpIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsYXNzTmFtZSA9ICJub3RBY3RpdmVFUEciOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsYXNzTmFtZSA9ICJhY3RpdmVFUEciOwogICAgICAgIH0KICAgIH0pOwp9CmZ1bmN0aW9uIHJlc3RvcmUoKSB7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZCcpKSB7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZCcpLnJlbW92ZSgpOwogICAgfQogICAgdmFyIHJlc3RvcmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTlBVVCIpOwogICAgcmVzdG9yZS5zZXRBdHRyaWJ1dGUoInR5cGUiLCAiZmlsZSIpOwogICAgcmVzdG9yZS5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIm5vdFZpc2libGUiKTsKICAgIHJlc3RvcmUuc2V0QXR0cmlidXRlKCJuYW1lIiwgIiIpOwogICAgcmVzdG9yZS5pZCA9ICJ1cGxvYWQiOwogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyZXN0b3JlKTsKICAgIHJlc3RvcmUuY2xpY2soKTsKICAgIHJlc3RvcmUub25jaGFuZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGZpbGVuYW1lID0gcmVzdG9yZS5maWxlc1swXS5uYW1lOwogICAgICAgIHZhciBjaGVjayA9IGNvbmZpcm0oIkZpbGU6ICIgKyBmaWxlbmFtZSArICJcbnt7LmNvbmZpcm0ucmVzdG9yZX19Iik7CiAgICAgICAgaWYgKGNoZWNrID09IHRydWUpIHsKICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgICAgICAgICAgIHZhciBmaWxlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1maWxlXScpLmZpbGVzWzBdOwogICAgICAgICAgICBpZiAoZmlsZSkgewogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7CiAgICAgICAgICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlYWRlci5yZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgICAgICAgICAgIHZhciBjbWQgPSAieHRldmVSZXN0b3JlIjsKICAgICAgICAgICAgICAgICAgICBkYXRhWyJiYXNlNjQiXSA9IHJlYWRlci5yZXN1bHQ7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIucmVxdWVzdChkYXRhKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBhbGVydCgiRmlsZSBjb3VsZCBub3QgYmUgbG9hZGVkIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdG9yZS5yZW1vdmUoKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH07CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gdXBsb2FkTG9nbygpIHsKICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBsb2FkJykpIHsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBsb2FkJykucmVtb3ZlKCk7CiAgICB9CiAgICB2YXIgdXBsb2FkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgIHVwbG9hZC5zZXRBdHRyaWJ1dGUoInR5cGUiLCAiZmlsZSIpOwogICAgdXBsb2FkLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAibm90VmlzaWJsZSIpOwogICAgdXBsb2FkLnNldEF0dHJpYnV0ZSgibmFtZSIsICIiKTsKICAgIHVwbG9hZC5pZCA9ICJ1cGxvYWQiOwogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh1cGxvYWQpOwogICAgdXBsb2FkLmNsaWNrKCk7CiAgICB1cGxvYWQub25ibHVyID0gZnVuY3Rpb24gKCkgewogICAgICAgIGFsZXJ0KCk7CiAgICB9OwogICAgdXBsb2FkLm9uY2hhbmdlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBmaWxlbmFtZSA9IHVwbG9hZC5maWxlc1swXS5uYW1lOwogICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOwogICAgICAgIHZhciBmaWxlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT1maWxlXScpLmZpbGVzWzBdOwogICAgICAgIGlmIChmaWxlKSB7CiAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpOwogICAgICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgY29uc29sZS5sb2cocmVhZGVyLnJlc3VsdCk7CiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgIHZhciBjbWQgPSAidXBsb2FkTG9nbyI7CiAgICAgICAgICAgICAgICBkYXRhWyJiYXNlNjQiXSA9IHJlYWRlci5yZXN1bHQ7CiAgICAgICAgICAgICAgICBkYXRhWyJmaWxlbmFtZSJdID0gZmlsZS5uYW1lOwogICAgICAgICAgICAgICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgICAgICAgICAgICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwogICAgICAgICAgICAgICAgdmFyIHVwZGF0ZUxvZ28gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlLWljb24nKTsKICAgICAgICAgICAgICAgIHVwZGF0ZUxvZ28uY2hlY2tlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgdXBkYXRlTG9nby5jbGFzc05hbWUgPSAiY2hhbmdlZCI7CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBhbGVydCgiRmlsZSBjb3VsZCBub3QgYmUgbG9hZGVkIik7CiAgICAgICAgfQogICAgICAgIHVwbG9hZC5yZW1vdmUoKTsKICAgICAgICByZXR1cm47CiAgICB9Owp9CmZ1bmN0aW9uIGNoZWNrVW5kbyhrZXkpIHsKICAgIHN3aXRjaCAoa2V5KSB7CiAgICAgICAgY2FzZSAiZXBnTWFwcGluZyI6CiAgICAgICAgICAgIGlmIChVTkRPLmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgICAgIFNFUlZFUlsieGVwZyJdW2tleV0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KFVORE9ba2V5XSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgVU5ET1trZXldID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShTRVJWRVJbInhlcGciXVtrZXldKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc29ydFNlbGVjdChlbGVtKSB7CiAgICB2YXIgdG1wQXJ5ID0gW107CiAgICB2YXIgc2VsZWN0ZWRWYWx1ZSA9IGVsZW1bZWxlbS5zZWxlY3RlZEluZGV4XS52YWx1ZTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbS5vcHRpb25zLmxlbmd0aDsgaSsrKQogICAgICAgIHRtcEFyeS5wdXNoKGVsZW0ub3B0aW9uc1tpXSk7CiAgICB0bXBBcnkuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gKGEudGV4dCA8IGIudGV4dCkgPyAtMSA6IDE7IH0pOwogICAgd2hpbGUgKGVsZW0ub3B0aW9ucy5sZW5ndGggPiAwKQogICAgICAgIGVsZW0ub3B0aW9uc1swXSA9IG51bGw7CiAgICB2YXIgbmV3U2VsZWN0ZWRJbmRleCA9IDA7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRtcEFyeS5sZW5ndGg7IGkrKykgewogICAgICAgIGVsZW0ub3B0aW9uc1tpXSA9IHRtcEFyeVtpXTsKICAgICAgICBpZiAoZWxlbS5vcHRpb25zW2ldLnZhbHVlID09IHNlbGVjdGVkVmFsdWUpCiAgICAgICAgICAgIG5ld1NlbGVjdGVkSW5kZXggPSBpOwogICAgfQogICAgZWxlbS5zZWxlY3RlZEluZGV4ID0gbmV3U2VsZWN0ZWRJbmRleDsgLy8gU2V0IG5ldyBzZWxlY3RlZCBpbmRleCBhZnRlciBzb3J0aW5nCiAgICByZXR1cm47Cn0KZnVuY3Rpb24gdXBkYXRlTG9nKCkgewogICAgY29uc29sZS5sb2coIlRPS0VOIik7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcigidXBkYXRlTG9nIik7CiAgICBzZXJ2ZXIucmVxdWVzdChuZXcgT2JqZWN0KCkpOwp9Cg=="
- webUI["html/js/menu.js"] = "CmZ1bmN0aW9uIHNldE1lbnVJdGVtKCkgewoKICBtZW51ID0gbmV3IE9iamVjdCgpOwogIHN1Yk1lbnUgPSBuZXcgT2JqZWN0KCk7CgogIHZhciBtZW51X20zdSA9IG5ldyBPYmplY3QoKTsKICBtZW51X20zdVsiX21lbnVUeXBlIl0gICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9tM3VbIl9lbGVtZW50Il0gICAgICAgID0gIkxJIjsKICBtZW51X20zdVsiX2NvbmZpZ0tleSJdICAgICAgPSAiZmlsZXMubTN1IjsKICBtZW51X20zdVsiX3RleHQiXSAgICAgICAgICAgPSAiUGxheWxpc3QiOwogIG1lbnVfbTN1WyJfaWNvbiJdICAgICAgICAgICA9ICJpbWcvbTN1LnBuZyI7CiAgbWVudV9tM3VbIl9oZWFkbGluZSJdICAgICAgID0gIlBsYXlsaXN0czogTG9jYWwgb3IgcmVtb3RlIjsKICBtZW51X20zdVsiX3VzYWdlIl0gICAgICAgICAgPSAiPGI+SW5mbzwvYj48YnI+QXZhaWxhYmlsaXR5OiBGaWxlIGF2YWlsYWJpbGl0eSBpbiBwZXJjZW50PGJyPlN0cmVhbXM6ICAgICAgTnVtYmVyIG9mIHN0cmVhbXMgaW4gdGhlIGZpbGUuPGJyPmdyb3VwLXRpdGxlOiAgU3RyZWFtcyB0aGF0IGFyZSBhc3NpZ25lZCB0byBhIGdyb3VwLiBTaW1wbGlmaWVzIGZpbHRlcmluZyBzdHJlYW1zPGJyPnR2Zy1pZDogICAgICAgVGhpcyBJRCBpcyB1c2VkIGZvciBhdXRvbWF0aWMgbWFwcGluZywgbXVzdCBtYXRjaCB3aXRoIHRoZSBjaGFubmVsIElEIGluIHRoZSBYTUxUViBmaWxlLjxicj5VbmlxdWUgSUQ6ICAgIFN0cmVhbXMgd2l0aCBhIHVuaXF1ZSBJRCB0byBpZGVudGlmeSB0aGVtLiBBbGxvd3MgY2hhbm5lbCBuYW1lIGNoYW5nZXMgaW4gdGhlIE0zVSB3aXRob3V0IGxvc2luZyB0aGUgWE1MVFYgbWFwcGluZyAoUFBWIC8gbGl2ZSBldmVudHMpLjxicj48YnI+PGI+VXNhZ2UgTTNVOjwvYj48YnI+UmVtb3RlIHBsYXlsaXN0OiBodHRwOi8veW91ci5pcHR2LnByb3ZpZGVyLmNvbS9maWxlLm0zdTxicj5Mb2NhbCAgcGxheWxpc3Q6IC9wYXRoL3RvL2ZpbGUubTN1PGJyPjxicj48Yj5Vc2FnZSBIREhvbWVSdW46PC9iPjxicj5JUDogMTkyLjE2OC4xLjEwOjUwMDQ8YnI+IgogIG1lbnVfbTN1WyJuYW1lIl0gICAgICAgICAgICA9ICJmaWxlIjsKICBtZW51X20zdVsiaWQiXSAgICAgICAgICAgICAgPSAiZmlsZSI7CiAgbWVudV9tM3VbInZhbHVlIl0gICAgICAgICAgID0gbWVudV9tM3VbIm5hbWUiXTsKICBtZW51X20zdVsicGxhY2Vob2xkZXIiXSAgICAgPSAiUGxheWxpc3Q6IGxvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV9tM3VbIm9uY2xpY2siXSAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X20zdVsiY2xhc3MiXSAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfZmlsdGVyID0gbmV3IE9iamVjdCgpOwogIG1lbnVfZmlsdGVyWyJfbWVudVR5cGUiXSAgICA9ICJpbnB1dEFycmF5IjsKICBtZW51X2ZpbHRlclsiX2VsZW1lbnQiXSAgICAgPSAiTEkiOwogIG1lbnVfZmlsdGVyWyJfY29uZmlnS2V5Il0gICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfdGV4dCJdICAgICAgICA9ICJGaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJfaWNvbiJdICAgICAgICA9ICJpbWcvZmlsdGVyLnBuZyI7CiAgbWVudV9maWx0ZXJbIl9oZWFkbGluZSJdICAgID0gIkZpbHRlciBieSBNM1UgcGFyYW1ldGVycywgZS5nLiBncm91cC10aXRsZSI7CiAgbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+U3BvcnQgLSBBbGwgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzPGJyPlNwb3J0IHtIRH0gIXtFUyxERX0gLSBBbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuPGJyPjxicj5UbyBmaWx0ZXIgdGhlIHN0cmVhbXMgb2YgYSBIREhvbWVSdW4sIHRoZSBwbGF5bGlzdCBuYW1lIGNhbiBiZSBlbnRlcmVkOjxicj5NeSB0dW5lciB7SER9IgogIC8vbWVudV9maWx0ZXJbIl91c2FnZSJdICAgICAgID0gIjxiPlVzYWdlOjwvYj48YnI+QWxsIHNwb3J0cyBjaGFubmVsczogU3BvcnQ8YnI+QWxsIEhEIHNwb3J0cyBjaGFubmVsczogU3BvcnQge0hEfTxicj5BbGwgSEQgc3BvcnRzIGNoYW5uZWxzLCBidXQgbm8gU3BhbmlzaCBhbmQgR2VybWFuOiBTcG9ydCB7SER9ICF7RVMsREV9IgogIG1lbnVfZmlsdGVyWyJuYW1lIl0gICAgICAgICA9ICJmaWx0ZXIiOwogIG1lbnVfZmlsdGVyWyJpZCJdICAgICAgICAgICA9ICJNM1UiOwogIG1lbnVfZmlsdGVyWyJ2YWx1ZSJdICAgICAgICA9IG1lbnVfZmlsdGVyWyJuYW1lIl07CiAgbWVudV9maWx0ZXJbInBsYWNlaG9sZGVyIl0gID0gIkZpbHRlciBzdHJlYW1zOiBTcG9ydCI7CiAgbWVudV9maWx0ZXJbIm9uY2xpY2siXSAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2ZpbHRlclsiY2xhc3MiXSAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICB2YXIgbWVudV9pZCA9IG5ldyBPYmplY3QoKTsKICBtZW51X2lkWyJfbWVudVR5cGUiXSAgICAgICAgPSAiaW5wdXRBcnJheSI7CiAgbWVudV9pZFsiX2VsZW1lbnQiXSAgICAgICAgID0gIkxJIjsKICBtZW51X2lkWyJfY29uZmlnS2V5Il0gICAgICAgPSAiaWQiOwogIG1lbnVfaWRbIl90ZXh0Il0gICAgICAgICAgICA9ICJQTVMgSUQiOwogIG1lbnVfaWRbIl9pY29uIl0gICAgICAgICAgICA9ICJpbWcvbnVtYmVyLnBuZyI7CiAgbWVudV9pZFsiX2hlYWRsaW5lIl0gICAgICAgID0gIlNldHVwIFBNUyBndWlkZSBudW1iZXIiOwogIG1lbnVfaWRbIl91c2FnZSJdICAgICAgICAgICA9ICdTb21lIHBsYXlsaXN0cyBoYXZlIHVuaXF1ZSBjaGFubmVsIElEcy48YnI+RW50ZXIgdGhlIGtleXdvcmQgb2YgdGhlIElELiBUaGUgY2hhbm5lbCBhc3NpZ25tZW50IGluIFBNUyB3aWxsIGNoYW5nZSBhcyBhIHJlc3VsdC48YnI+PGJyPmUuZy4gY2hhbm5lbElEPGJyPiNFWFRJTkY6MCB0eXBlPSJzdHJlYW0iIDxiPmNoYW5uZWxJZDwvYj49IjgxIiwgTXkgU3RyZWFtaW5nIENoYW5uZWwgSEQ8YnI+PGJyPk9ubHkgZW50ZXIgaGVyZSBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmchJwogIG1lbnVfaWRbIm5hbWUiXSAgICAgICAgICAgICA9ICJpZCI7CiAgbWVudV9pZFsiaWQiXSAgICAgICAgICAgICAgID0gImlkIjsKICBtZW51X2lkWyJ2YWx1ZSJdICAgICAgICAgICAgPSBtZW51X2lkWyJuYW1lIl07CiAgbWVudV9pZFsicGxhY2Vob2xkZXIiXSAgICAgID0gIlVuaXF1ZSBJRCBmcm9tIHRoZSBNM1UgZmlsZSI7CiAgbWVudV9pZFsib25jbGljayJdICAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2lkWyJjbGFzcyJdICAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKCiAgdmFyIG1lbnVfeG1sdHYgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV94bWx0dlsiX21lbnVUeXBlIl0gICAgID0gImlucHV0QXJyYXkiOwogIG1lbnVfeG1sdHZbIl9lbGVtZW50Il0gICAgICA9ICJMSSI7CiAgbWVudV94bWx0dlsiX2NvbmZpZ0tleSJdICAgID0gImZpbGVzLnhtbHR2IjsKICBtZW51X3htbHR2WyJfdGV4dCJdICAgICAgICAgPSAiWE1MVFYiOwogIG1lbnVfeG1sdHZbIl9pY29uIl0gICAgICAgICA9ICJpbWcveG1sdHYucG5nIjsKICBtZW51X3htbHR2WyJfaGVhZGxpbmUiXSAgICAgPSAiWE1MVFYgZmlsZXM6IExvY2FsIG9yIHJlbW90ZSI7CiAgbWVudV94bWx0dlsiX3VzYWdlIl0gICAgICAgID0gIjxiPkluZm86PC9iPjxicj5BdmFpbGFiaWxpdHk6IEZpbGUgYXZhaWxhYmlsaXR5IGluIHBlcmNlbnQ8YnI+Q2hhbm5lbHM6ICAgICBOdW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIGZpbGU8YnI+UHJvZ3JhbXM6ICAgICBOdW1iZXIgb2YgRVBHIGRhdGE8YnI+PGJyPjxiPlVzYWdlOjwvYj48YnI+UmVtb3RlIFhNTFRWIGZpbGU6IGh0dHA6Ly95b3VyLmVwZy5wcm92aWRlci5jb20vZ3VpZGUueG1sPGJyPkxvY2FsICBYTUxUViBmaWxlOiAvcGF0aC90by9ndWlkZS54bWwiCiAgbWVudV94bWx0dlsibmFtZSJdICAgICAgICAgID0gInhtbHR2IjsKICBtZW51X3htbHR2WyJpZCJdICAgICAgICAgICAgPSAieG1sdHYiOwogIG1lbnVfeG1sdHZbInZhbHVlIl0gICAgICAgICA9IG1lbnVfeG1sdHZbIm5hbWUiXTsKICBtZW51X3htbHR2WyJwbGFjZWhvbGRlciJdICAgPSAiWE1MVFYgRmlsZTogbG9jYWwgb3IgcmVtb3RlIjsKICBtZW51X3htbHR2WyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfeG1sdHZbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CgogIG1lbnVfbWFwcGluZyA9IG5ldyBPYmplY3QoKTsKICBtZW51X21hcHBpbmdbIl9lbGVtZW50Il0gICA9ICJMSSI7CiAgbWVudV9tYXBwaW5nWyJfdGV4dCJdICAgICAgPSAiTWFwcGluZyI7CiAgbWVudV9tYXBwaW5nWyJfaWNvbiJdICAgICAgPSAiaW1nL21hcHBpbmcucG5nIjsKICBtZW51X21hcHBpbmdbIl9jb25maWdLZXkiXSA9ICJtYXBwaW5nIjsKICBtZW51X21hcHBpbmdbIl9oZWFkbGluZSJdICA9ICJYTUxUViBhc3NpZ25tZW50IGFuZCBzb3J0aW5nIG9mIGNoYW5uZWxzIjsKICBtZW51X21hcHBpbmdbImlkIl0gICAgICAgICA9ICJtYXBwaW5nIjsKICBtZW51X21hcHBpbmdbIm9uY2xpY2siXSAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9tYXBwaW5nWyJjbGFzcyJdICAgICAgPSAibWVudS1ub3RBY3RpdmUgcGhvbmUiOwoKICBtZW51X3VzZXJzID0gbmV3IE9iamVjdCgpOwogIG1lbnVfdXNlcnNbIl9lbGVtZW50Il0gICA9ICJMSSI7CiAgbWVudV91c2Vyc1siX3RleHQiXSAgICAgID0gIlVzZXJzIjsKICBtZW51X3VzZXJzWyJfaWNvbiJdICAgICAgPSAiaW1nL3VzZXJzLnBuZyI7CiAgbWVudV91c2Vyc1siX2NvbmZpZ0tleSJdID0gInVzZXJzIjsKICBtZW51X3VzZXJzWyJfaGVhZGxpbmUiXSAgPSAiQWRtaW5pc3RyYXRpb24gb2YgdXNlcnMgYW5kIHBlcm1pc3Npb25zIjsKICBtZW51X3VzZXJzWyJpZCJdICAgICAgICAgPSAidXNlcnMiOwogIG1lbnVfdXNlcnNbIm9uY2xpY2siXSAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV91c2Vyc1siY2xhc3MiXSAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKICBtZW51X3VzZXJzWyJfdXNhZ2UiXSAgICAgPSAiPGI+QXV0aG9yaXphdGlvbiBncm91cHM6PC9iPjxicj5XRUI6IFVzZXJzIGNhbiBsb2cgaW4gdG8gdGhlIHdlYiBpbnRlcmZhY2U8YnI+UE1TOiBQcm9ncmFtcyBsaWtlIFBsZXggY2FuIGFjY2VzcyB0aGUgY2hhbm5lbCBsaXN0LiBMb2dpbiB2aWEgRFZSIElQOiB1c2VybmFtZTpwYXNzd29yZEB4dGV2ZS5pcDpwb3J0PGJyPk0zVTogQWxsb3dzIGNsaWVudHMgdG8gZG93bmxvYWQgdGhlIE0zVSBwbGF5bGlzdC48YnI+WE1MOiBBbGxvd3MgY2xpZW50cyB0byBkb3dubG9hZCB0aGUgWE1MVFYgZmlsZS48YnI+QVBJOiBBbGxvd3MgY2xpZW50cyB0byB1c2UgdGhlIEFQSSBpbnRlcmZhY2UuPGJyPjxicj4hISEgRm9yIFBNUyBhdXRoZW50aWNhdGlvbiwgb25seSB0aGUgZm9sbG93aW5nIHNwZWNpYWwgY2hhcmFjdGVycyBhcmUgdmFsaWQ6ICEkKCk9LiwtOjs8YnI+PGJyPlRoZSBpbmRpdmlkdWFsIGF1dGhlbnRpY2F0aW9uIGdyb3VwcyBjYW4gYmUgYWN0aXZhdGVkIC8gZGVhY3RpdmF0ZWQgaW4gdGhlIHNldHRpbmdzIG1lbnUuIgogIAogIG1lbnVfc2V0dGluZ3MgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9zZXR0aW5nc1siX2VsZW1lbnQiXSAgID0gIkxJIjsKICBtZW51X3NldHRpbmdzWyJfdGV4dCJdICAgICAgPSAiU2V0dGluZ3MiOwogIG1lbnVfc2V0dGluZ3NbIl9pY29uIl0gICAgICA9ICJpbWcvc2V0dGluZ3MucG5nIjsKICBtZW51X3NldHRpbmdzWyJfY29uZmlnS2V5Il0gPSAic2V0dGluZ3MiOwogIG1lbnVfc2V0dGluZ3NbIl9oZWFkbGluZSJdICA9ICJTZXR0aW5ncyI7CiAgbWVudV9zZXR0aW5nc1siX3N1Yk1lbnUiXSAgID0gIjcwMSw3MDIsNzAzLDcwNCw3MDUsNzA2LDcwNyw3MDgsNzk5LDcxMCw3MTEsNzEyLDcxMyw3MTQiOwogIG1lbnVfc2V0dGluZ3NbImlkIl0gICAgICAgICA9ICJzZXR0aW5ncyI7CiAgbWVudV9zZXR0aW5nc1sib25jbGljayJdICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X3NldHRpbmdzWyJjbGFzcyJdICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICBtZW51X2xvZyA9IG5ldyBPYmplY3QoKTsKICBtZW51X2xvZ1siX2VsZW1lbnQiXSAgICAgICAgPSAiTEkiOwogIG1lbnVfbG9nWyJfdGV4dCJdICAgICAgICAgICA9ICJMb2ciOwogIG1lbnVfbG9nWyJfaWNvbiJdICAgICAgICAgICA9ICJpbWcvbG9nLnBuZyI7CiAgbWVudV9sb2dbIl9oZWFkbGluZSJdICAgICAgID0gIkxvZyI7CiAgbWVudV9sb2dbIl9jb25maWdLZXkiXSAgICAgID0gImxvZyI7CiAgbWVudV9sb2dbImlkIl0gICAgICAgICAgICAgID0gImxvZyI7CiAgbWVudV9sb2dbIm9uY2xpY2siXSAgICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2xvZ1siY2xhc3MiXSAgICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICBtZW51X2xvZ291dCA9IG5ldyBPYmplY3QoKTsKICBtZW51X2xvZ291dFsiX2VsZW1lbnQiXSAgID0gIkxJIjsKICBtZW51X2xvZ291dFsiX3RleHQiXSAgICAgID0gIkxvZ291dCI7CiAgbWVudV9sb2dvdXRbIl9pY29uIl0gICAgICA9ICJpbWcvbG9nb3V0LnBuZyI7CiAgbWVudV9sb2dvdXRbImlkIl0gICAgICAgICA9ICJsb2dvdXQiOwogIG1lbnVfbG9nb3V0WyJvbmNsaWNrIl0gICAgPSAiamF2YXNjcmlwdDogbG9nb3V0KCk7IjsKICBtZW51X2xvZ291dFsiY2xhc3MiXSAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKCiAgdmFyIG1lbnVfc2NoZWR1bGUgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9zY2hlZHVsZVsiX21lbnVUeXBlIl0gID0gImlucHV0QXJyYXkiOwogIG1lbnVfc2NoZWR1bGVbIl9lbGVtZW50Il0gICA9ICJMSSI7CiAgbWVudV9zY2hlZHVsZVsiX2NvbmZpZ0tleSJdID0gInVwZGF0ZSI7CiAgbWVudV9zY2hlZHVsZVsiX3RleHQiXSAgICAgID0gIlNjaGVkdWxlIjsKICBtZW51X3NjaGVkdWxlWyJfaWNvbiJdICAgICAgPSAiaW1nL3NjaGVkdWxlLnBuZyI7CiAgbWVudV9zY2hlZHVsZVsiX2hlYWRsaW5lIl0gID0gIlNjaGVkdWxlIGZvciB1cGRhdGluZyBNM1UsIFhNTFRWIGZpbGVzIGFuZCBjcmVhdGluZyBhIGxvY2FsIGJhY2t1cCI7CiAgbWVudV9zY2hlZHVsZVsiX3VzYWdlIl0gICAgID0gIjxiPlVzYWdlOjwvYj48YnI+MDgxNSA9IDg6MTUgYW08YnI+MTkzMCA9IDc6MzAgcG0iCiAgbWVudV9zY2hlZHVsZVsibmFtZSJdICAgICAgID0gInVwZGF0ZSI7CiAgbWVudV9zY2hlZHVsZVsiaWQiXSAgICAgICAgID0gInVwZGF0ZSI7CiAgbWVudV9zY2hlZHVsZVsidmFsdWUiXSAgICAgID0gbWVudV9pZFsibmFtZSJdOwogIG1lbnVfc2NoZWR1bGVbInBsYWNlaG9sZGVyIl09ICJ0aW1lIG9mIGRheSAoMjQtaG91ciBjbG9jaykiOwogIG1lbnVfc2NoZWR1bGVbIm9uY2xpY2siXSAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9zY2hlZHVsZVsiY2xhc3MiXSAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKCiAgdmFyIG1lbnVfZmlsZXNVcGRhdGUgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9maWxlc1VwZGF0ZVsiX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9maWxlc1VwZGF0ZVsiX21lbnVUeXBlIl0gICAgID0gImNoZWNrYm94IjsKICBtZW51X2ZpbGVzVXBkYXRlWyJfY29uZmlnS2V5Il0gICAgPSAiZmlsZXMudXBkYXRlIjsKICBtZW51X2ZpbGVzVXBkYXRlWyJfbGFiZWwiXSAgICAgICAgPSAiVXBkYXRlIHRoZSBwcm92aWRlciBmaWxlcyBhdCBzeXN0ZW0gc3RhcnR1cCI7CiAgbWVudV9maWxlc1VwZGF0ZVsiX2hlYWRsaW5lIl0gICAgID0gIlVwZGF0ZSB0aGUgcHJvdmlkZXIgZmlsZXMgYXQgc3lzdGVtIHN0YXJ0dXAiOwogIG1lbnVfZmlsZXNVcGRhdGVbIl91c2FnZSJdICAgICAgICA9ICJQbGF5bGlzdHMgYW5kIFhNTFRWIGZpbGVzIGFyZSB1cGRhdGVkIGJ5IHhUZVZlIGF0IHN5c3RlbSBzdGFydHVwLiIKICBtZW51X2ZpbGVzVXBkYXRlWyJuYW1lIl0gICAgICAgICAgPSAiZmlsZXMudXBkYXRlIjsKICBtZW51X2ZpbGVzVXBkYXRlWyJpZCJdICAgICAgICAgICAgPSAiZmlsZXMudXBkYXRlIjsKICBtZW51X2ZpbGVzVXBkYXRlWyJ2YWx1ZSJdICAgICAgICAgPSBtZW51X2ZpbGVzVXBkYXRlWyJuYW1lIl07CiAgbWVudV9maWxlc1VwZGF0ZVsib25jbGljayJdICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2ZpbGVzVXBkYXRlWyJjbGFzcyJdICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwogIAogIHZhciBtZW51X3R1bmVyID0gbmV3IE9iamVjdCgpOwogIG1lbnVfdHVuZXJbIl9lbGVtZW50Il0gICAgICA9ICJMSSI7CiAgbWVudV90dW5lclsiX21lbnVUeXBlIl0gICAgID0gInNlbGVjdCI7CiAgbWVudV90dW5lclsiX2NvbmZpZ0tleSJdICAgID0gInR1bmVyIjsKICBtZW51X3R1bmVyWyJfbGFiZWwiXSAgICAgICAgPSAiQXZhaWxhYmxlIHR1bmVycyI7CiAgbWVudV90dW5lclsiX3RleHQiXSAgICAgICAgID0gIlR1bmVyIjsKICBtZW51X3R1bmVyWyJfaWNvbiJdICAgICAgICAgPSAiaW1nL3R1bmVyLnBuZyI7CiAgbWVudV90dW5lclsiX2hlYWRsaW5lIl0gICAgID0gIk51bWJlciBvZiB0dW5lcnMiOwogIG1lbnVfdHVuZXJbIl91c2FnZSJdICAgICAgICA9ICJUaGlzIHNldHRpbmcgaXMgb25seSB1c2VkIGJ5IFBsZXggYW5kIEVtYnkuPGJyPlRoZSBudW1iZXIgb2YgY29uY3VycmVudCBzdHJlYW1zIGFsbG93ZWQgYnkgdGhlIElQVFYgcHJvdmlkZXIuPGJyPkFmdGVyIGEgY2hhbmdlLCB4VGVWZSBtdXN0IGJlIGRlbGV0ZSBpbiB0aGUgUE1TIERWUiBzZXR0aW5ncyBhbmQgc2V0IHVwIGFnYWluLiIKICBtZW51X3R1bmVyWyJuYW1lIl0gICAgICAgICAgPSAidHVuZXIiOwogIG1lbnVfdHVuZXJbImlkIl0gICAgICAgICAgICA9ICJ0dW5lciI7CiAgbWVudV90dW5lclsidmFsdWUiXSAgICAgICAgID0gbWVudV90dW5lclsibmFtZSJdOwogIG1lbnVfdHVuZXJbInBsYWNlaG9sZGVyIl0gICA9ICJOdW1iZXIgb2YgdHVuZXJzIjsKICBtZW51X3R1bmVyWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfdHVuZXJbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CgogIHZhciBvcHRpb25WYWx1ZXMgPSBuZXcgQXJyYXkoKTsKICBmb3IgKHZhciBpID0gMTsgaSA8PSAxMDA7IGkrKykgewogICAgb3B0aW9uVmFsdWVzLnB1c2goaSkKICB9CiAgbWVudV90dW5lclsiX29wdGlvblZhbHVlcyJdID0gb3B0aW9uVmFsdWVzOwogIAogIHZhciBtZW51X2VwZyA9IG5ldyBPYmplY3QoKTsKICBtZW51X2VwZ1siX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9lcGdbIl9tZW51VHlwZSJdICAgICA9ICJzZWxlY3QiOwogIG1lbnVfZXBnWyJfY29uZmlnS2V5Il0gICAgPSAiZXBnU291cmNlIjsKICBtZW51X2VwZ1siX2xhYmVsIl0gICAgICAgID0gIlNlbGVjdGlvbiBvZiB0aGUgRVBHIHNvdXJjZSI7CiAgbWVudV9lcGdbIl90ZXh0Il0gICAgICAgICA9ICJFUEcgc291cmNlIjsKICBtZW51X2VwZ1siX2hlYWRsaW5lIl0gICAgID0gIlNlbGVjdGlvbiBvZiB0aGUgRVBHIHNvdXJjZSI7CiAgbWVudV9lcGdbIl91c2FnZSJdICAgICAgICA9ICJQTVM6ICAgVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5Ljxicj5YRVBHOiAgVXNlIG9mIGV4dGVybmFsIEVQRyBkYXRhIChYTUxUVikuPGJyPiAgICAgICBTZXZlcmFsIFhNTFRWIHNvdXJjZXMgcG9zc2libGUuPGJyPiAgICAgICBBbGxvd3MgZWRpdGluZyBhbmQgb3JkZXIgY2hhbm5lbHMuPGJyPiAgICAgICBNM1UgLyBYTUxUViBleHBvcnQgKEhUVFAgbGluayBmb3IgSVBUViBhcHBzKS4iCiAgbWVudV9lcGdbIm5hbWUiXSAgICAgICAgICA9ICJlcGdTb3VyY2UiOwogIG1lbnVfZXBnWyJpZCJdICAgICAgICAgICAgPSAiZXBnU291cmNlIjsKICBtZW51X2VwZ1sidmFsdWUiXSAgICAgICAgID0gbWVudV9lcGdbIm5hbWUiXTsKICBtZW51X2VwZ1sicGxhY2Vob2xkZXIiXSAgID0gIkVQRyBzb3VyY2UiOwogIG1lbnVfZXBnWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfZXBnWyJjbGFzcyJdICAgICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwogIG1lbnVfZXBnWyJfb3B0aW9uVmFsdWVzIl0gPSBuZXcgQXJyYXkoIlBNUyIsICJYRVBHIik7CgogIHZhciBtZW51X3hlcGcgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV94ZXBnWyJfZWxlbWVudCJdID0gIkxJIjsKICBtZW51X3hlcGdbIl9tZW51VHlwZSJdICAgICA9ICJjaGVja2JveCI7CiAgbWVudV94ZXBnWyJfY29uZmlnS2V5Il0gICAgPSAieHRldmVBdXRvVXBkYXRlIjsKICBtZW51X3hlcGdbIl9sYWJlbCJdICAgICAgICA9ICJBdXRvbWF0aWMgdXBkYXRlIG9mIHhUZVZlIjsKICBtZW51X3hlcGdbIl9oZWFkbGluZSJdICAgICA9ICJBdXRvbWF0aWMgdXBkYXRlIG9mIHhUZVZlIjsKICBtZW51X3hlcGdbIl91c2FnZSJdICAgICAgICA9ICJJZiBhIG5ldyB2ZXJzaW9uIG9mIHhUZVZlIGlzIGF2YWlsYWJsZSwgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGluc3RhbGxlZC4iCiAgbWVudV94ZXBnWyJuYW1lIl0gICAgICAgICAgPSAieHRldmVBdXRvVXBkYXRlIjsKICBtZW51X3hlcGdbImlkIl0gICAgICAgICAgICA9ICJ4dGV2ZUF1dG9VcGRhdGUiOwogIG1lbnVfeGVwZ1sidmFsdWUiXSAgICAgICAgID0gbWVudV94ZXBnWyJuYW1lIl07CiAgbWVudV94ZXBnWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfeGVwZ1siY2xhc3MiXSAgICAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKCiAgdmFyIG1lbnVfYXV0b0JhY2t1cFBhdGggPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9hdXRvQmFja3VwUGF0aFsiX2VsZW1lbnQiXSAgID0gIkxJIjsKICBtZW51X2F1dG9CYWNrdXBQYXRoWyJfbWVudVR5cGUiXSAgPSAic2luZ2xlSW5wdXQiOwogIG1lbnVfYXV0b0JhY2t1cFBhdGhbIl9jb25maWdLZXkiXSA9ICJiYWNrdXAucGF0aCI7CiAgbWVudV9hdXRvQmFja3VwUGF0aFsiX2xhYmVsIl0gICAgID0gIkxvY2F0aW9uIGZvciBhdXRvbWF0aWMgYmFja3VwcyI7CiAgbWVudV9hdXRvQmFja3VwUGF0aFsiX2hlYWRsaW5lIl0gID0gIkxvY2F0aW9uIGZvciBhdXRvbWF0aWMgYmFja3VwcyI7CiAgbWVudV9hdXRvQmFja3VwUGF0aFsiX3VzYWdlIl0gICAgID0gIkJlZm9yZSBhbnkgdXBkYXRlIG9mIHRoZSBwcm92aWRlciBkYXRhIGJ5IHRoZSBzY2hlZHVsZSwgeFRlVmUgY3JlYXRlcyBhIGJhY2t1cC4gVGhlIHBhdGggZm9yIHRoZSBhdXRvbWF0aWMgYmFja3VwcyBjYW4gYmUgY2hhbmdlZC4geFRlVmUgcmVxdWlyZXMgd3JpdGUgcGVybWlzc2lvbiBmb3IgdGhpcyBmb2xkZXIuIgogIG1lbnVfYXV0b0JhY2t1cFBhdGhbIm5hbWUiXSAgICAgICA9ICJiYWNrdXAucGF0aCI7CiAgbWVudV9hdXRvQmFja3VwUGF0aFsiaWQiXSAgICAgICAgID0gImJhY2t1cC5wYXRoIjsKICBtZW51X2F1dG9CYWNrdXBQYXRoWyJ2YWx1ZSJdICAgICAgPSBtZW51X2F1dG9CYWNrdXBQYXRoWyJuYW1lIl07CiAgbWVudV9hdXRvQmFja3VwUGF0aFsib25jbGljayJdICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2F1dG9CYWNrdXBQYXRoWyJjbGFzcyJdICAgICAgPSAibWVudS1ub3RBY3RpdmUiOwoKICB2YXIgbWVudV9hdXRvQmFja3VwS2VlcCA9IG5ldyBPYmplY3QoKTsKICBtZW51X2F1dG9CYWNrdXBLZWVwWyJfZWxlbWVudCJdICAgPSAiTEkiOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbIl9tZW51VHlwZSJdICA9ICJzZWxlY3QiOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbIl9jb25maWdLZXkiXSA9ICJiYWNrdXAua2VlcCI7CiAgbWVudV9hdXRvQmFja3VwS2VlcFsiX3RleHQiXSAgICAgID0gIktlZXAiOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbIl9sYWJlbCJdICAgICA9ICJOdW1iZXIgb2YgYmFja3VwcyB0byBrZWVwIjsKICBtZW51X2F1dG9CYWNrdXBLZWVwWyJfaGVhZGxpbmUiXSAgPSAiTnVtYmVyIG9mIGJhY2t1cHMgdG8ga2VlcCI7CiAgbWVudV9hdXRvQmFja3VwS2VlcFsiX3VzYWdlIl0gICAgID0gIiIKICBtZW51X2F1dG9CYWNrdXBLZWVwWyJuYW1lIl0gICAgICAgPSAiYmFja3VwLmtlZXAiOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbImlkIl0gICAgICAgICA9ICJiYWNrdXAua2VlcCI7CiAgbWVudV9hdXRvQmFja3VwS2VlcFsidmFsdWUiXSAgICAgID0gbWVudV9hdXRvQmFja3VwS2VlcFsibmFtZSJdOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbIm9uY2xpY2siXSAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9hdXRvQmFja3VwS2VlcFsiY2xhc3MiXSAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKCiAgdmFyIG9wdGlvblZhbHVlcyA9IG5ldyBBcnJheSg1LCAxMCwgMjAsIDMwLCA0MCwgNTApOwogIG1lbnVfYXV0b0JhY2t1cEtlZXBbIl9vcHRpb25WYWx1ZXMiXSA9IG9wdGlvblZhbHVlczsKCgogIHZhciBtZW51X2J1ZmZlciA9IG5ldyBPYmplY3QoKTsKICBtZW51X2J1ZmZlclsiX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9idWZmZXJbIl9tZW51VHlwZSJdICAgICA9ICJjaGVja2JveCI7CiAgbWVudV9idWZmZXJbIl9jb25maWdLZXkiXSAgICA9ICJidWZmZXIiOwogIG1lbnVfYnVmZmVyWyJfbGFiZWwiXSAgICAgICAgPSAiU3RyZWFtIGJ1ZmZlcmluZyBbRXhwZXJpbWVudGFsXSI7CiAgbWVudV9idWZmZXJbIl9oZWFkbGluZSJdICAgICA9ICJTdHJlYW0gYnVmZmVyaW5nIFtFeHBlcmltZW50YWxdIjsKICBtZW51X2J1ZmZlclsiX3VzYWdlIl0gICAgICAgID0gIldpdGggYWN0aXZhdGVkIGJ1ZmZlciwgc3RyZWFtcyBjYW4gYmUgcGxheWVkIGFuZCByZWNvcmRlZCBtb3JlIGZsdWVudGx5Ljxicj5UaGUgc3RyZWFtIGlzIHBhc3NlZCBmcm9tIHhUZVZlIHRvIFBsZXggLyBFbWJ5IgogIG1lbnVfYnVmZmVyWyJuYW1lIl0gICAgICAgICAgPSAiYnVmZmVyIjsKICBtZW51X2J1ZmZlclsiaWQiXSAgICAgICAgICAgID0gImJ1ZmZlciI7CiAgbWVudV9idWZmZXJbInZhbHVlIl0gICAgICAgICA9IG1lbnVfYnVmZmVyWyJuYW1lIl07CiAgbWVudV9idWZmZXJbIm9uY2xpY2siXSAgICAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9idWZmZXJbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CgogIHZhciBtZW51X2FwaSA9IG5ldyBPYmplY3QoKTsKICBtZW51X2FwaVsiX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9hcGlbIl9tZW51VHlwZSJdICAgICA9ICJjaGVja2JveCI7CiAgbWVudV9hcGlbIl9jb25maWdLZXkiXSAgICA9ICJhcGkiOwogIG1lbnVfYXBpWyJfbGFiZWwiXSAgICAgICAgPSAiQVBJIGludGVyZmFjZSI7CiAgbWVudV9hcGlbIl9oZWFkbGluZSJdICAgICA9ICJBUEkgaW50ZXJmYWNlIjsKICBtZW51X2FwaVsiX3VzYWdlIl0gICAgICAgID0gJ1ZpYSBBUEkgaW50ZXJmYWNlIGl0IGlzIHBvc3NpYmxlIHRvIHNlbmQgY29tbWFuZHMgdG8geFRlVmUuIEFQSSBkb2N1bWVudGF0aW9uIGlzIGF2YWlsYWJsZSA8YSBocmVmPSJodHRwczovL3h0ZXZlLmRlP3Njcm9sbD1hcGkiPmhlcmU8L2E+ICcKICAvL21lbnVfYXBpWyJfdXNhZ2UiXSAgICAgICAgPSAnVmlhIEFQSSBpbnRlcmZhY2UgaXQgaXMgcG9zc2libGUgdG8gc2VuZCBjb21tYW5kcyB0byB4VGVWZS4gQVBJIGRvY3VtZW50YXRpb24gaXMgYXZhaWxhYmxlIDxhIGhyZWY9Imh0dHA6Ly9sb2NhbGhvc3Q6MTMxMz9zY3JvbGw9YXBpIj5oZXJlPC9hPiAnCiAgbWVudV9hcGlbIm5hbWUiXSAgICAgICAgICA9ICJhcGkiOwogIG1lbnVfYXBpWyJpZCJdICAgICAgICAgICAgPSAiYXBpIjsKICBtZW51X2FwaVsidmFsdWUiXSAgICAgICAgID0gbWVudV9hcGlbIm5hbWUiXTsKICBtZW51X2FwaVsib25jbGljayJdICAgICAgID0gImphdmFzY3JpcHQ6IHRvZ2dsZU1lbnUodGhpcyk7IjsKICBtZW51X2FwaVsiY2xhc3MiXSAgICAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKCiAgdmFyIG1lbnVfYXV0aGVudGljYXRpb25XZWIgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9hdXRoZW50aWNhdGlvbldlYlsiX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9hdXRoZW50aWNhdGlvbldlYlsiX21lbnVUeXBlIl0gICAgID0gImNoZWNrYm94IjsKICBtZW51X2F1dGhlbnRpY2F0aW9uV2ViWyJfY29uZmlnS2V5Il0gICAgPSAiYXV0aGVudGljYXRpb24ud2ViIjsKICBtZW51X2F1dGhlbnRpY2F0aW9uV2ViWyJfbGFiZWwiXSAgICAgICAgPSAiVXNlciBhdXRoZW50aWNhdGlvbiI7CiAgbWVudV9hdXRoZW50aWNhdGlvbldlYlsiX2hlYWRsaW5lIl0gICAgID0gIlVzZXIgYXV0aGVudGljYXRpb24iOwogIG1lbnVfYXV0aGVudGljYXRpb25XZWJbIl91c2FnZSJdICAgICAgICA9ICJBY2Nlc3MgdG8geFRlVmUgcmVxdWlyZXMgYXV0aGVudGljYXRpb24uIgogIG1lbnVfYXV0aGVudGljYXRpb25XZWJbIm5hbWUiXSAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi53ZWIiOwogIG1lbnVfYXV0aGVudGljYXRpb25XZWJbImlkIl0gICAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi53ZWIiOwogIG1lbnVfYXV0aGVudGljYXRpb25XZWJbInZhbHVlIl0gICAgICAgICA9IG1lbnVfYXV0aGVudGljYXRpb25XZWJbIm5hbWUiXTsKICBtZW51X2F1dGhlbnRpY2F0aW9uV2ViWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfYXV0aGVudGljYXRpb25XZWJbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CiAgCiAgdmFyIG1lbnVfYXV0aGVudGljYXRpb25QbXMgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1siX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1siX21lbnVUeXBlIl0gICAgID0gImNoZWNrYm94IjsKICBtZW51X2F1dGhlbnRpY2F0aW9uUG1zWyJfY29uZmlnS2V5Il0gICAgPSAiYXV0aGVudGljYXRpb24ucG1zIjsKICBtZW51X2F1dGhlbnRpY2F0aW9uUG1zWyJfbGFiZWwiXSAgICAgICAgPSAiUGxleCBhdXRoZW50aWNhdGlvbi4iOwogIG1lbnVfYXV0aGVudGljYXRpb25QbXNbIl9oZWFkbGluZSJdICAgICA9ICJQbGV4IGF1dGhlbnRpY2F0aW9uLiI7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1siX3VzYWdlIl0gICAgICAgID0gIlBsZXggcmVxdWVzdHMgYXJlIG9ubHkgcG9zc2libGUgd2l0aCBhdXRoZW50aWNhdGlvbi48YnI+V2FybmluZyEhISBBZnRlciBhY3RpdmF0aW5nIHRoaXMgZnVuY3Rpb24geFRlVmUgbXVzdCBiZSBkZWxldGUgaW4gdGhlIFBNUyBEVlIgc2V0dGluZ3MgYW5kIHNldCB1cCBhZ2Fpbi4iCiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1sibmFtZSJdICAgICAgICAgID0gImF1dGhlbnRpY2F0aW9uLnBtcyI7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1siaWQiXSAgICAgICAgICAgID0gImF1dGhlbnRpY2F0aW9uLnBtcyI7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1sidmFsdWUiXSAgICAgICAgID0gbWVudV9hdXRoZW50aWNhdGlvblBtc1sibmFtZSJdOwogIG1lbnVfYXV0aGVudGljYXRpb25QbXNbIm9uY2xpY2siXSAgICAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9hdXRoZW50aWNhdGlvblBtc1siY2xhc3MiXSAgICAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKICAKICB2YXIgbWVudV9hdXRoZW50aWNhdGlvbk0zdSA9IG5ldyBPYmplY3QoKTsKICBtZW51X2F1dGhlbnRpY2F0aW9uTTN1WyJfZWxlbWVudCJdID0gIkxJIjsKICBtZW51X2F1dGhlbnRpY2F0aW9uTTN1WyJfbWVudVR5cGUiXSAgICAgPSAiY2hlY2tib3giOwogIG1lbnVfYXV0aGVudGljYXRpb25NM3VbIl9jb25maWdLZXkiXSAgICA9ICJhdXRoZW50aWNhdGlvbi5tM3UiOwogIG1lbnVfYXV0aGVudGljYXRpb25NM3VbIl9sYWJlbCJdICAgICAgICA9ICJNM1UgYXV0aGVudGljYXRpb24uIjsKICBtZW51X2F1dGhlbnRpY2F0aW9uTTN1WyJfaGVhZGxpbmUiXSAgICAgPSAiTTNVIGF1dGhlbnRpY2F0aW9uLiI7CiAgbWVudV9hdXRoZW50aWNhdGlvbk0zdVsiX3VzYWdlIl0gICAgICAgID0gIkRvd25sb2FkaW5nIHRoZSBNM1UgZmlsZSB2aWEgYW4gSFRUUCByZXF1ZXN0IGlzIG9ubHkgcG9zc2libGUgd2l0aCBhdXRoZW50aWNhdGlvbi4iCiAgbWVudV9hdXRoZW50aWNhdGlvbk0zdVsibmFtZSJdICAgICAgICAgID0gImF1dGhlbnRpY2F0aW9uLm0zdSI7CiAgbWVudV9hdXRoZW50aWNhdGlvbk0zdVsiaWQiXSAgICAgICAgICAgID0gImF1dGhlbnRpY2F0aW9uLm0zdSI7CiAgbWVudV9hdXRoZW50aWNhdGlvbk0zdVsidmFsdWUiXSAgICAgICAgID0gbWVudV9hdXRoZW50aWNhdGlvbk0zdVsibmFtZSJdOwogIG1lbnVfYXV0aGVudGljYXRpb25NM3VbIm9uY2xpY2siXSAgICAgICA9ICJqYXZhc2NyaXB0OiB0b2dnbGVNZW51KHRoaXMpOyI7CiAgbWVudV9hdXRoZW50aWNhdGlvbk0zdVsiY2xhc3MiXSAgICAgICAgID0gIm1lbnUtbm90QWN0aXZlIjsKICAKCiAgdmFyIG1lbnVfYXV0aGVudGljYXRpb25YbWwgPSBuZXcgT2JqZWN0KCk7CiAgbWVudV9hdXRoZW50aWNhdGlvblhtbFsiX2VsZW1lbnQiXSA9ICJMSSI7CiAgbWVudV9hdXRoZW50aWNhdGlvblhtbFsiX21lbnVUeXBlIl0gICAgID0gImNoZWNrYm94IjsKICBtZW51X2F1dGhlbnRpY2F0aW9uWG1sWyJfY29uZmlnS2V5Il0gICAgPSAiYXV0aGVudGljYXRpb24ueG1sIjsKICBtZW51X2F1dGhlbnRpY2F0aW9uWG1sWyJfbGFiZWwiXSAgICAgICAgPSAiWEVQRyBhdXRoZW50aWNhdGlvbiI7CiAgbWVudV9hdXRoZW50aWNhdGlvblhtbFsiX2hlYWRsaW5lIl0gICAgID0gIlhFUEcgYXV0aGVudGljYXRpb24iOwogIG1lbnVfYXV0aGVudGljYXRpb25YbWxbIl91c2FnZSJdICAgICAgICA9ICJEb3dubG9hZGluZyB0aGUgWEVQRyAoWE1MVFYpIGZpbGUgdmlhIGFuIEhUVFAgcmVxdWVzdCBpcyBvbmx5IHBvc3NpYmxlIHdpdGggYXV0aGVudGljYXRpb24uIgogIG1lbnVfYXV0aGVudGljYXRpb25YbWxbIm5hbWUiXSAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi54bWwiOwogIG1lbnVfYXV0aGVudGljYXRpb25YbWxbImlkIl0gICAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi54bWwiOwogIG1lbnVfYXV0aGVudGljYXRpb25YbWxbInZhbHVlIl0gICAgICAgICA9IG1lbnVfYXV0aGVudGljYXRpb25YbWxbIm5hbWUiXTsKICBtZW51X2F1dGhlbnRpY2F0aW9uWG1sWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfYXV0aGVudGljYXRpb25YbWxbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CgogIHZhciBtZW51X2F1dGhlbnRpY2F0aW9uQXBpID0gbmV3IE9iamVjdCgpOwogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbIl9lbGVtZW50Il0gPSAiTEkiOwogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbIl9tZW51VHlwZSJdICAgICA9ICJjaGVja2JveCI7CiAgbWVudV9hdXRoZW50aWNhdGlvbkFwaVsiX2NvbmZpZ0tleSJdICAgID0gImF1dGhlbnRpY2F0aW9uLmFwaSI7CiAgbWVudV9hdXRoZW50aWNhdGlvbkFwaVsiX2xhYmVsIl0gICAgICAgID0gIkFQSSBhdXRoZW50aWNhdGlvbiI7CiAgbWVudV9hdXRoZW50aWNhdGlvbkFwaVsiX2hlYWRsaW5lIl0gICAgID0gIkFQSSBhdXRoZW50aWNhdGlvbiI7CiAgbWVudV9hdXRoZW50aWNhdGlvbkFwaVsiX3VzYWdlIl0gICAgICAgID0gIkFjY2VzcyB0byB0aGUgQVBJIGludGVyZmFjZSBpcyBvbmx5IHBvc3NpYmxlIHdpdGggYXV0aGVudGljYXRpb24uIgogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbIm5hbWUiXSAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi5hcGkiOwogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbImlkIl0gICAgICAgICAgICA9ICJhdXRoZW50aWNhdGlvbi5hcGkiOwogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbInZhbHVlIl0gICAgICAgICA9IG1lbnVfYXV0aGVudGljYXRpb25BcGlbIm5hbWUiXTsKICBtZW51X2F1dGhlbnRpY2F0aW9uQXBpWyJvbmNsaWNrIl0gICAgICAgPSAiamF2YXNjcmlwdDogdG9nZ2xlTWVudSh0aGlzKTsiOwogIG1lbnVfYXV0aGVudGljYXRpb25BcGlbImNsYXNzIl0gICAgICAgICA9ICJtZW51LW5vdEFjdGl2ZSI7CiAgCiAgCiAgLy8gTWFpbiBtZW51CiAgbWVudVsxMF0gPSBtZW51X20zdTsKCiAgc3dpdGNoKGNvbmZpZ1siZXBnU291cmNlIl0pIHsKICAgIGNhc2UgIlBNUyI6CiAgICAgIG1lbnVbMjBdID0gbWVudV9pZDsKICAgICAgYnJlYWs7CiAgICAKICAgIGNhc2UgIlhNTFRWIjoKICAgICAgbWVudVs0MF0gPSBtZW51X3htbHR2OwogICAgICBicmVhazsKCiAgICBjYXNlICJYRVBHIjoKICAgICAgbWVudVs0MF0gPSBtZW51X3htbHR2OwogICAgICBtZW51WzUwXSA9IG1lbnVfbWFwcGluZzsKICAgICAgYnJlYWs7CiAgfQogIAogIG1lbnVbMzBdID0gbWVudV9maWx0ZXI7CiAgCiAgaWYgKGNvbmZpZ1siYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgbWVudVs2MF0gPSBtZW51X3VzZXJzOwogIH0KCiAgbWVudVs3MF0gPSBtZW51X3NldHRpbmdzOwogIG1lbnVbODBdID0gbWVudV9sb2c7CiAgaWYgKGNvbmZpZ1siYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgbWVudVsxMDBdID0gbWVudV9sb2dvdXQ7CiAgfSAKICAKCiAgLy8gU3ViLU1lbnUKCiAgc3ViTWVudVs3MDFdID0gbWVudV9zY2hlZHVsZTsKICBzdWJNZW51WzcwMl0gPSBtZW51X2ZpbGVzVXBkYXRlOwogIHN1Yk1lbnVbNzAzXSA9IG1lbnVfdHVuZXI7CiAgc3ViTWVudVs3MDRdID0gbWVudV9lcGc7CiAgc3ViTWVudVs3MDVdID0gbWVudV94ZXBnOwogIHN1Yk1lbnVbNzA2XSA9IG1lbnVfYXV0b0JhY2t1cFBhdGg7CiAgc3ViTWVudVs3MDddID0gbWVudV9hdXRvQmFja3VwS2VlcDsKICBzdWJNZW51WzcwOF0gPSBtZW51X2J1ZmZlcjsKICAKICBzdWJNZW51WzcxMF0gPSBtZW51X2F1dGhlbnRpY2F0aW9uV2ViOwogIAogIGlmIChjb25maWdbImF1dGhlbnRpY2F0aW9uLndlYiJdID09IHRydWUpIHsKICAgIHN1Yk1lbnVbNzExXSA9IG1lbnVfYXV0aGVudGljYXRpb25QbXM7CiAgICBzdWJNZW51WzcxMl0gPSBtZW51X2F1dGhlbnRpY2F0aW9uTTN1OwogICAgc3ViTWVudVs3MTNdID0gbWVudV9hdXRoZW50aWNhdGlvblhtbDsKICAgIHN1Yk1lbnVbNzE0XSA9IG1lbnVfYXV0aGVudGljYXRpb25BcGk7CiAgfQoKICBzdWJNZW51Wzc5OV0gPSBtZW51X2FwaTsKCiAgCgogIHJldHVybgp9CgpmdW5jdGlvbiBjcmVhdGVNZW51KCkgewoKICBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7CgogIC8vY29uc29sZS5sb2coY29uZmlnKTsKICBzZXRNZW51SXRlbSgpOwogIHZhciBtZW51SXRlbXMgPSBnZXRPYmpLZXlzKG1lbnUpCiAgdmFyIG5hdiA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJOQVYiKVswXTsKICBuYXYuaW5uZXJIVE1MID0gIiI7CiAgdmFyIG5ld0l0ZW0gPSBuZXcgT2JqZWN0KCk7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgbWVudUl0ZW1zLmxlbmd0aDsgaSsrKSB7CgogICAgCiAgICB2YXIgbmV3SXRlbSA9IG1lbnVbbWVudUl0ZW1zW2ldXTsKICAgIG5ld0l0ZW1bImlkIl0gPSBtZW51SXRlbXNbaV07CgogICAgCiAgICBzd2l0Y2gobmV3SXRlbS5oYXNPd25Qcm9wZXJ0eSgiX2ljb24iKSkgewogICAgICBjYXNlIHRydWU6IAogICAgICAgIHZhciBpdGVtVGV4dCA9IG5ld0l0ZW1bIl90ZXh0Il07CiAgICAgICAgZGVsZXRlIG5ld0l0ZW1bIl90ZXh0Il0KICAgICAgICBuYXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdJdGVtKSk7CiAgICAgICAgbmV3SXRlbVsiX3RleHQiXSA9IGl0ZW1UZXh0OwogICAgICAgIHZhciBuZXdJY29uID0gbmV3IE9iamVjdCgpOwogICAgICAgIG5ld0ljb25bIl9lbGVtZW50Il0gPSAiSU1HIjsKICAgICAgICBuZXdJY29uWyJzcmMiXSA9IG5ld0l0ZW1bIl9pY29uIl07CgogICAgICAgIHZhciBjdXJyZW50RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG1lbnVJdGVtc1tpXSk7CiAgICAgICAgY3VycmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdJY29uKSk7CgoKICAgICAgICB2YXIgdGV4dCA9IG5ldyBPYmplY3QoKTsKICAgICAgICB0ZXh0WyJfZWxlbWVudCJdID0gIlAiCiAgICAgICAgdGV4dFsiX3RleHQiXSA9IGl0ZW1UZXh0OwogICAgICAgIHRleHRbImNsYXNzIl0gPSAibmF2LXRleHQiCiAgICAgICAgY3VycmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudCh0ZXh0KSk7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIG5hdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0ljb24pKTsKICAgICAgICBicmVhazsKICAgIH0KCiAgfQogIGlmIChhY3RpdmVNZW51ICE9IHVuZGVmaW5lZCkgewogICAgLy9jb25zb2xlLmxvZyhhY3RpdmVNZW51KTsKICAgIHRvZ2dsZU1lbnUoYWN0aXZlTWVudSk7CiAgfQoKICByZXR1cm4KfQoKZnVuY3Rpb24gdG9nZ2xlTWVudShlbG0pIHsKICAvL3Nob3dTdHJlYW1zKGZhbHNlKTsKICBjbGVhckludGVydmFsKGxvZ0ludGVydmFsKQogIGFjdGl2ZU1lbnUgPSBlbG07CiAgdmFyIGl0ZW0gPSBtZW51W2VsbS5pZF0KICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgZGl2LmlubmVySFRNTCA9ICIiOwogIAogIC8vIFNldCBIZWFkbGluZQogIHZhciBoZWFkbGluZSA9IG5ldyBPYmplY3QoKTsKICBoZWFkbGluZVsiX2VsZW1lbnQiXSA9ICJINCI7CiAgaGVhZGxpbmVbIl90ZXh0Il0gPSBpdGVtWyJfaGVhZGxpbmUiXTsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChoZWFkbGluZSkpOwoKICAvLyBTdWItTWVudQogIGlmIChpdGVtLmhhc093blByb3BlcnR5KCJfc3ViTWVudSIpID09IHRydWUpIHsKICAgIG9wZW5TdWJNZW51KGl0ZW0pOwogICAgcmV0dXJuCiAgfQoKICAvLyBNYXBwaW5nLCBVc2VycywgTG9nLCBGaWxlcwogIHN3aXRjaChpdGVtWyJfY29uZmlnS2V5Il0pIHsKICAgIGNhc2UgIm1hcHBpbmciOiAgICAgb3Blbk1hcHBpbmdFZGl0b3IoaXRlbSk7IHJldHVybjsgYnJlYWs7CiAgICBjYXNlICJ1c2VycyI6ICAgICAgIG9wZW5Vc2VycyhpdGVtKTsgcmV0dXJuOyBicmVhazsKICAgIGNhc2UgImxvZyI6ICAgICAgICAgc2hvd0xvZyhpdGVtKTsgcmV0dXJuOyBicmVhazsKICAgIGNhc2UgImZpbGVzLm0zdSI6ICAgb3BlbkZpbGVzKGl0ZW0sICJtM3UiKTsgcmV0dXJuOyBicmVhazsKICAgIGNhc2UgImZpbGVzLnhtbHR2Ijogb3BlbkZpbGVzKGl0ZW0sICJ4bWx0diIpOyByZXR1cm47IGJyZWFrOwoKICAgIGNhc2UgImZpbHRlciI6ICAgICAgc2hvd1N0cmVhbXModHJ1ZSk7IGJyZWFrOwogIH0KCiAKCiAgdmFyIG5ld0hSID0gbmV3IE9iamVjdCgpOwogIG5ld0hSWyJfZWxlbWVudCJdID0gIkhSIgogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0hSKSk7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIC8vbmV3RW50cnlbImNsYXNzIl0gPSAic2F2ZSI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiU2F2ZSI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSA9ICJzYXZlRGF0YTIoJ3NldHRpbmdzJykiCiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCgogIHZhciBuZXdXcmFwcGVyID0gbmV3IE9iamVjdCgpOwogIG5ld1dyYXBwZXJbIl9lbGVtZW50Il0gID0gIkRJViI7CiAgbmV3V3JhcHBlclsiaWQiXSAgICAgICAgPSAiYm94LXdyYXBwZXIiOwogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1dyYXBwZXIpKTsKCiAgZGl2ID0gZGl2Lmxhc3RDaGlsZDsKICAKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlTWVudUl0ZW0oaXRlbSkpCgogIC8vIHVzYWdlIEluZm8gIAogIHN3aXRjaChtZW51W2FjdGl2ZU1lbnUuaWRdLmhhc093blByb3BlcnR5KCJfdXNhZ2UiKSkgewogICAgY2FzZSB0cnVlOiAKICAgICAgdmFyIHVzYWdlSXRlbSA9IG5ldyBPYmplY3QoKTsKICAgICAgdXNhZ2VJdGVtWyJfZWxlbWVudCJdID0gIlBSRSIKICAgICAgdXNhZ2VJdGVtWyJfdGV4dCJdICAgID0gbWVudVthY3RpdmVNZW51LmlkXVsiX3VzYWdlIl07CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KHVzYWdlSXRlbSkpOwogIH0KICAKICBjYWxjdWxhdGVXcmFwcGVySGVpZ2h0KCk7Cgp9CgpmdW5jdGlvbiBjcmVhdGVNZW51SXRlbShpdGVtKSB7CiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTsKICBzd2l0Y2goaXRlbVsiX21lbnVUeXBlIl0pIHsKICAgIGNhc2UgImlucHV0QXJyYXkiOgogICAgICBpZiAoY29uZmlnLmhhc093blByb3BlcnR5KGl0ZW1bIl9jb25maWdLZXkiXSkgPT0gdHJ1ZSkgewogICAgICAgIHZhciB2YWx1ZSA9IGNvbmZpZ1tpdGVtWyJfY29uZmlnS2V5Il1dOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciB2YWx1ZSA9IG5ldyBBcnJheSgpOwogICAgICB9CiAgICAgIAogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogICAgICAgIG5ld0VudHJ5ID0gaXRlbQogICAgICAgIGRlbGV0ZSBuZXdFbnRyeVsib25jbGljayJdOwogICAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgICAgICAgbmV3RW50cnlbInZhbHVlIl0gICAgID0gdmFsdWVbaV07CiAgICAgICAgbmV3RW50cnlbInR5cGUiXSAgICAgID0gInNlYXJjaCI7CiAgICAgICAgbmV3RW50cnlbImRhdGEtbWVudXR5cGUiXSA9IGl0ZW1bIl9tZW51VHlwZSJdOwogICAgICAgIG5ld0VudHJ5WyJkYXRhLW1lbnVrZXkiXSA9IGl0ZW1bIl9jb25maWdLZXkiXTsKICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgICAgIH0KICAgICAgLy8gTmV3IGVudHJ5IGZvciBhcnJheQogICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgICAgPSAiSU5QVVQiOwogICAgICBuZXdFbnRyeVsidHlwZSJdICAgICAgICAgID0gInNlYXJjaCI7CiAgICAgIG5ld0VudHJ5WyJuYW1lIl0gICAgICAgICAgPSBpdGVtWyJuYW1lIl07CiAgICAgIG5ld0VudHJ5WyJwbGFjZWhvbGRlciJdICAgPSBpdGVtWyJwbGFjZWhvbGRlciJdOwogICAgICBuZXdFbnRyeVsidmFsdWUiXSAgICAgICAgID0gIiI7CiAgICAgIG5ld0VudHJ5WyJkYXRhLW1lbnV0eXBlIl0gPSBpdGVtWyJfbWVudVR5cGUiXTsKICAgICAgbmV3RW50cnlbImRhdGEtbWVudWtleSJdICA9IGl0ZW1bIl9jb25maWdLZXkiXTsKICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CiAgICAgIGJyZWFrOwogIAogICAgY2FzZSAic2luZ2xlSW5wdXQiOgogICAgICB2YXIgdmFsdWUgPSBjb25maWdbaXRlbVsiX2NvbmZpZ0tleSJdXTsKICAgICAgaWYgKHZhbHVlID09IHVuZGVmaW5lZCkgewogICAgICAgIHZhbHVlID0gIiI7CiAgICAgIH0KICAgICAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdFbnRyeSA9IGl0ZW07CiAgICAgIGRlbGV0ZSBuZXdFbnRyeVsib25jbGljayJdOwogICAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgPSAiSU5QVVQiOwogICAgICBuZXdFbnRyeVsidmFsdWUiXSAgICAgPSB2YWx1ZTsKICAgICAgbmV3RW50cnlbInR5cGUiXSAgICAgID0gInNlYXJjaCI7CiAgICAgIG5ld0VudHJ5WyJkYXRhLW1lbnV0eXBlIl0gPSBpdGVtWyJfbWVudVR5cGUiXTsKICAgICAgbmV3RW50cnlbImRhdGEtbWVudWtleSJdID0gaXRlbVsiX2NvbmZpZ0tleSJdOwogICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAiY2hlY2tib3giOgogICAgICB2YXIgdmFsdWUgPSBjb25maWdbaXRlbVsiX2NvbmZpZ0tleSJdXTsKICAgICAgaWYgKHZhbHVlID09IHVuZGVmaW5lZCkgewogICAgICAgIHZhbHVlID0gZmFsc2U7CiAgICAgIH0KICAgICAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogICAgICBuZXdFbnRyeSA9IGl0ZW07CiAgICAgIGRlbGV0ZSBuZXdFbnRyeVsib25jbGljayJdOwogICAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgPSAiSU5QVVQiOwogICAgICBuZXdFbnRyeVsidmFsdWUiXSAgICAgPSB2YWx1ZTsKICAgICAgbmV3RW50cnlbInR5cGUiXSAgICAgID0gImNoZWNrYm94IjsKICAgICAgbmV3RW50cnlbImRhdGEtbWVudXR5cGUiXSA9IGl0ZW1bIl9tZW51VHlwZSJdOwogICAgICBuZXdFbnRyeVsiZGF0YS1tZW51a2V5Il0gPSBpdGVtWyJfY29uZmlnS2V5Il07CiAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTlBVVCIpWzBdLmNoZWNrZWQgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICAKICAgIGNhc2UgInNlbGVjdCI6CiAgICAgIHZhciB2YWx1ZSA9IGNvbmZpZ1tpdGVtWyJfY29uZmlnS2V5Il1dOwogICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0VudHJ5ID0gaXRlbTsKICAgICAgZGVsZXRlIG5ld0VudHJ5WyJvbmNsaWNrIl0KICAgICAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIlNFTEVDVCI7CiAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICB2YXIgc2VsZWN0RWxlbWVudCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlNFTEVDVCIpWzBdOwogICAgICB2YXIgdmFsdWVzID0gaXRlbVsiX29wdGlvblZhbHVlcyJdOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3Q7CiAgICAgICAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIk9QVElPTiI7CiAgICAgICAgbmV3RW50cnlbIl90ZXh0Il0gICAgID0gaXRlbVsiX3RleHQiXSArICI6ICIgKyB2YWx1ZXNbaV07CiAgICAgICAgbmV3RW50cnlbInZhbHVlIl0gICAgID0gdmFsdWVzW2ldOwogICAgICAgIHNlbGVjdEVsZW1lbnQuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICB9CiAgICAgIHNlbGVjdEVsZW1lbnQudmFsdWUgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICAKICB9CiAgcmV0dXJuIGVsZW1lbnQ7Cn0KCmZ1bmN0aW9uIG9wZW5TdWJNZW51KGl0ZW0pIHsKICB2YXIgZW50cnlzID0gaXRlbVsiX3N1Yk1lbnUiXS5zcGxpdCgiLCIpOwogIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2V0dGluZ3MiKTsKCiAgdmFyIG5ld0hSID0gbmV3IE9iamVjdCgpOwogIG5ld0hSWyJfZWxlbWVudCJdID0gIkhSIgogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0hSKSk7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIC8vbmV3RW50cnlbImNsYXNzIl0gPSAic2F2ZSI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiU2F2ZSI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSA9ICJzYXZlRGF0YTIoJ3NldHRpbmdzJykiCiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgaWYgKGl0ZW1bIl9jb25maWdLZXkiXSA9PSAic2V0dGluZ3MiKSB7CiAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgPSAiSU5QVVQiOwogICAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogICAgLy9uZXdFbnRyeVsiY2xhc3MiXSA9ICJzYXZlIjsKICAgIG5ld0VudHJ5WyJ2YWx1ZSJdID0gIkJhY2t1cCI7CiAgICBuZXdFbnRyeVsib25jbGljayJdID0gInh0ZXZlQmFja3VwKCkiCiAgICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogIH0KCiAgaWYgKGl0ZW1bIl9jb25maWdLZXkiXSA9PSAic2V0dGluZ3MiKSB7CiAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSAgPSAiSU5QVVQiOwogICAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogICAgLy9uZXdFbnRyeVsiY2xhc3MiXSA9ICJzYXZlIjsKICAgIG5ld0VudHJ5WyJ2YWx1ZSJdID0gIlJlc3RvcmUiOwogICAgbmV3RW50cnlbIm9uY2xpY2siXSA9ICJ4dGV2ZVJlc3RvcmUodGhpcykiCiAgICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogIH0KCgogIHZhciBuZXdXcmFwcGVyID0gbmV3IE9iamVjdCgpOwogIG5ld1dyYXBwZXJbIl9lbGVtZW50Il0gID0gIkRJViI7CiAgbmV3V3JhcHBlclsiaWQiXSAgICAgICAgPSAiYm94LXdyYXBwZXIiOwogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1dyYXBwZXIpKTsKICAKICBkaXYgPSBkaXYubGFzdENoaWxkOwogIAoKICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJ5cy5sZW5ndGg7IGkrKykgewogICAgdmFyIGl0ZW0gPSBzdWJNZW51W2VudHJ5c1tpXV07CiAgICBpZiAoaXRlbSA9PSB1bmRlZmluZWQpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgICAKICAgIHZhciBjb250YWluZXIgPSBuZXcgT2JqZWN0KCk7CiAgICBjb250YWluZXJbIl9lbGVtZW50Il0gPSAiRElWIjsKICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KGNvbnRhaW5lcikpOwoKICAgIHZhciBkaXZDb250YWluZXIgPSBkaXYubGFzdENoaWxkOwogICAgCiAgICB2YXIgaGVhZGxpbmUgPSBuZXcgT2JqZWN0KCk7CiAgICBoZWFkbGluZVsiX2VsZW1lbnQiXSA9ICJINSI7CiAgICBoZWFkbGluZVsiX3RleHQiXSA9IGl0ZW1bIl9oZWFkbGluZSJdOwogICAgZGl2Q29udGFpbmVyLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoaGVhZGxpbmUpKTsKCiAgICBkaXZDb250YWluZXIuYXBwZW5kQ2hpbGQoY3JlYXRlTWVudUl0ZW0oaXRlbSkpCgogICAgc3dpdGNoKGl0ZW0uaGFzT3duUHJvcGVydHkoIl91c2FnZSIpKSB7CiAgICAgIGNhc2UgdHJ1ZTogCiAgICAgICAgdmFyIHVzYWdlSXRlbSA9IG5ldyBPYmplY3QoKTsKICAgICAgICB1c2FnZUl0ZW1bIl9lbGVtZW50Il0gPSAiUFJFIgogICAgICAgIHVzYWdlSXRlbVsiX3RleHQiXSAgICA9IGl0ZW1bIl91c2FnZSJdOwogICAgICAgIGRpdkNvbnRhaW5lci5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KHVzYWdlSXRlbSkpOwogICAgfQoKICAgIHZhciBociA9IG5ldyBPYmplY3QoKTsKICAgIGhyWyJfZWxlbWVudCJdID0gIkhSIjsKICAgIGRpdkNvbnRhaW5lci5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KGhyKSk7CiAgCiAgfQoKICBjYWxjdWxhdGVXcmFwcGVySGVpZ2h0KCk7CiAgcmV0dXJuCn0KCmZ1bmN0aW9uIHNhdmVEYXRhMihlbG0pIHsKICB2YXIgZGl2ICAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbG0pOwogIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIik7CiAgdmFyIHNlbGVjdHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlNFTEVDVCIpOwogIHZhciB2YWx1ZSwgY29uZmlnS2V5OwogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIHZhciB2YWx1ZUFyciA9IG5ldyBBcnJheSgpOwogIHZhciBuZXdEYXRhID0gZmFsc2U7CiAgCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgIGlmIChpbnB1dHNbaV0udHlwZSAhPSAiYnV0dG9uIikgewogICAgICB2YXIgbWVudVR5cGUgPSBpbnB1dHNbaV0uZ2V0QXR0cmlidXRlKCJkYXRhLW1lbnV0eXBlIik7CiAgICAgIAogICAgICAvL2NvbnNvbGUubG9nKG1lbnVUeXBlKTsKICAgICAgc3dpdGNoKG1lbnVUeXBlKSB7CiAgICAgICAgY2FzZSAic2luZ2xlSW5wdXQiOgogICAgICAgICAgdmFsdWUgPSBpbnB1dHNbaV0udmFsdWU7CiAgICAgICAgICBpZiAodmFsdWUgPT0gIiIgfHwgdmFsdWUgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICAgIGRhdGFbImRlbGV0ZSJdID0gaW5wdXRzW2ldLm5hbWUKICAgICAgICAgICAgbmV3RGF0YSA9IHRydWU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuZXdEYXRhID0gdHJ1ZTsKICAgICAgICAgICAgZGF0YVtpbnB1dHNbaV0ubmFtZV0gPSB2YWx1ZTsKICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJpbnB1dEFycmF5IjogCiAgICAgICAgICB2YWx1ZSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgIGlmICh2YWx1ZSAhPSAiIiAmJiB2YWx1ZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgbmV3RGF0YSA9IHRydWU7CiAgICAgICAgICAgIHZhbHVlQXJyLnB1c2godmFsdWUpCiAgICAgICAgICAgIGRhdGFbaW5wdXRzW2ldLm5hbWVdID0gdmFsdWVBcnI7CiAgICAgICAgICAgIGNvbmZpZ0tleSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgICAgfSAKICAgICAgICAgIAogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgImNoZWNrYm94IjoKICAgICAgICAgIHZhbHVlID0gaW5wdXRzW2ldLmNoZWNrZWQKICAgICAgICAgIGRhdGFbaW5wdXRzW2ldLm5hbWVdID0gdmFsdWU7CiAgICAgIH0KICAgICAgCiAgICB9CiAgICAKICB9CgoKICAvLyBEZWxldGUgY29uZmlnIGtleQogIGlmICh2YWx1ZUFyci5sZW5ndGggPT0gMCAmJiBuZXdEYXRhID09IGZhbHNlKSB7CiAgICBuZXdEYXRhID0gdHJ1ZTsKICAgIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICBkYXRhWyJkZWxldGUiXSA9IGNvbmZpZ0tleTsKICB9IAoKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxlY3RzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgdmFsdWUgPSBzZWxlY3RzW2ldLm9wdGlvbnNbc2VsZWN0c1tpXS5zZWxlY3RlZEluZGV4XS52YWx1ZTsKICAgIHN3aXRjaChpc05hTih2YWx1ZSkpIHsKICAgICAgY2FzZSBmYWxzZTogdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7IGJyZWFrOwogICAgfQoKICAgIGRhdGFbc2VsZWN0c1tpXS5uYW1lXSA9IHZhbHVlOwogICAgbmV3RGF0YSA9IHRydWU7CiAgfQoKICAvL2NvbnNvbGUubG9nKGRhdGEsIG5ld0RhdGEpOwoKICBpZiAobmV3RGF0YSA9PSB0cnVlKSB7CiAgICBkYXRhWyJjbWQiXSA9ICJzYXZlQ29uZmlnIjsKICAgIGlmICghZGF0YS5oYXNPd25Qcm9wZXJ0eSgnZmlsdGVyJykpIHsKICAgICAgZGF0YVsiZmlsdGVyIl0gPSBjb25maWdbImZpbHRlciJdCiAgICB9CiAgICB2YXIgc2V0dGluZ3MgPSBuZXcgT2JqZWN0KCk7CiAgICBzZXR0aW5nc1siY21kIl0gPSBkYXRhWyJjbWQiXTsKICAgIHNldHRpbmdzWyJzZXR0aW5ncyJdID0gZGF0YTsKICAgIGNvbnNvbGUubG9nKHNldHRpbmdzKTsKICAgIHhUZVZlKHNldHRpbmdzKTsKICB9Cn0K"
- webUI["html/img/BC-QR.jpg"] = "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"
- webUI["html/css/base.css"] = "KiB7CiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lOwogIC1tb3otYXBwZWFyYW5jZTogbm9uZTsKICAtbXMtYXBwZWFyYW5jZTogbm9uZTsKICBmb250LWZhbWlseTogIkFyaWFsIiwgc2Fucy1zZXJpZjsKICBsZXR0ZXItc3BhY2luZzogMnB4OyAKfQoKLyoKOjotd2Via2l0LXNjcm9sbGJhciB7IAogICAgZGlzcGxheTogbm9uZTsgCn0KKi8KCjo6LXdlYmtpdC1zY3JvbGxiYXIgewogIHdpZHRoOiAxMnB4OwogIGhlaWdodDogMTJweDsKfQoKIAo6Oi13ZWJraXQtc2Nyb2xsYmFyLXRyYWNrIHsKICAtd2Via2l0LWJveC1zaGFkb3c6IGluc2V0IDAgMCA2cHggcmdiYSgwLDAsMCwwLjMpOyAKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgICAKfQogCjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIgewogIGJvcmRlci1yYWRpdXM6IDVweDsKICAtd2Via2l0LWJveC1zaGFkb3c6IGluc2V0IDAgMCA2cHggcmdiYSgwLCAwLCAwLDAuNik7IAogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ7Cn0KCjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXIgewogIGJhY2tncm91bmQ6ICMzMzM7IAp9Cgo6Oi13ZWJraXQtc2Nyb2xsYmFyLWNvcm5lciB7IAogIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyAKfQoKYSB7CiAgY29sb3I6ICMwMEU2RkY7Cn0KCmh0bWwsIGJvZHkgewogIGNvbG9yOiAjZmZmOwogIG1hcmdpbjogMHB4IGF1dG87CiAgaGVpZ2h0OiAxMDAlOwogIGZvbnQtc2l6ZTogMTRweDsKfQoKaDIgewogIGZvbnQtc2l6ZTogMjRweDsKICBsZXR0ZXItc3BhY2luZzogMnB4Owp9CgpoMyB7CiAgZm9udC1zaXplOiAyMnB4OwogIGxldHRlci1zcGFjaW5nOiAxcHg7Cn0KCmg0IHsKICBmb250LXNpemU6IDIwcHg7CiAgbGV0dGVyLXNwYWNpbmc6IDFweDsKICBsaW5lLWhlaWdodDogMS41ZW07Cgp9CgpoNSB7CiAgZm9udC1zaXplOiAxNnB4OwogIGxldHRlci1zcGFjaW5nOiAxcHg7CiAgbGluZS1oZWlnaHQ6IDEuMmVtOwogIG1hcmdpbjogMjVweCAwcHggMTBweCAwcHg7Cn0KCmhyIHsKICBib3JkZXI6IDA7CiAgaGVpZ2h0OiAxcHg7CiAgYmFja2dyb3VuZDogIzMzMzsKICBtYXJnaW46IDEwcHggMHB4Owp9CgpwIHsKICBtYXJnaW46IDJweDsKICBwYWRkaW5nOiAycHggNXB4Owp9CgpwcmUgewogIG1hcmdpbjogMHB4IDBweCA1cHggMHB4OwogIGZvbnQtc2l6ZTogMTJweDsKICBjb2xvcjogI2RkZDsKICBsZXR0ZXItc3BhY2luZzogMXB4OwogIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOyAKICBmb250LXNpemU6IDEycHg7IAogIGZvbnQtc3R5bGU6IG5vcm1hbDsgCiAgZm9udC12YXJpYW50OiBub3JtYWw7IAogIGxpbmUtaGVpZ2h0OiAxLjZlbTsgCn0KCmxhYmVsIHsKICBtYXJnaW4tYm90dG9tOiAyMHB4OwogIGRpc3BsYXk6IGJsb2NrOwp9CgpsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIGJhY2tncm91bmQtY29sb3I6ICMxMTE7CiAgcGFkZGluZzogMTBweCAyMHB4OwogIGN1cnNvcjogcG9pbnRlcjsKICBib3JkZXItbGVmdDogc29saWQgMnB4ICMxMTE7CiAgdHJhbnNpdGlvbjogYWxsIDAuMzsKfQoKbGk6aG92ZXIgewogIGJvcmRlci1jb2xvcjogIzAwRTZGRgp9CgpzZWxlY3QgewogIGN1cnNvcjogcG9pbnRlcjsKICB3aWR0aDogY2FsYygxMDAlICsgMnB4KTsKICBib3JkZXI6IHNvbGlkIDBweCAjMDBFNkZGOwogIGJvcmRlci1yYWRpdXM6IDBweDsKICBvdXRsaW5lOiBub25lOwogIGNvbG9yOiAjZmZmOwogIHBhZGRpbmc6IDlweCAxMHB4OwogIGRpc3BsYXk6YmxvY2s7CiAgYmFja2dyb3VuZC1jb2xvcjogIzMzMzsKICBmb250LXNpemU6IDE0cHg7CiAgbWFyZ2luOiA1cHggMHB4IDVweCAwcHg7Cn0KCnNlbGVjdDpmb2N1cyB7CiAgb3V0bGluZTogbm9uZTsKfQoKaW5wdXQgewogIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTsKICBtYXJnaW46IDVweCAwcHg7CiAgcGFkZGluZzogMi41cHggMTBweDsKICBvdXRsaW5lOiBub25lOwogIGZvbnQtc2l6ZTogMTRweDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLCBpbnB1dFt0eXBlPXN1Ym1pdF0gewogIGN1cnNvcjogcG9pbnRlcjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIG1hcmdpbjogMTBweCAxMHB4OwogIHBhZGRpbmc6IDEwcHggMjVweDsKICBib3JkZXI6IHNvbGlkIDBweDsKICBib3JkZXItY29sb3I6ICMwMDA7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIG91dGxpbmU6IG5vbmU7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXTpmb2N1cyB7IAogICBvdXRsaW5lOiBub25lOwp9CgppbnB1dFt0eXBlPWJ1dHRvbl06aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICMwMEU2RkY7CiAgY29sb3I6ICMwMDA7Cn0KCmlucHV0W3R5cGU9YnV0dG9uXTpob3Zlci5kZWxldGUgIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7CiAgY29sb3I6ICNmZmY7Cn0KCmlucHV0W3R5cGU9dGV4dF0sIGlucHV0W3R5cGU9c2VhcmNoXSwgaW5wdXRbdHlwZT1wYXNzd29yZF0gewogIGNvbG9yOiAjZmZmOwogIHdpZHRoOiAtd2Via2l0LWNhbGMoMTAwJSAtIDBweCk7CiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMHB4KTsKICB3aWR0aDogY2FsYygxMDAlIC0gMHB4KTsKICBvdXRsaW5lOiBub25lOwogIGJvcmRlcjogc29saWQgMXB4IHRyYW5zcGFyZW50OwogIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OwogIGJvcmRlci1ib3R0b20tY29sb3I6ICM1NTU7CiAgYm9yZGVyLXJhZGl1czogMHB4OwogIHBhZGRpbmc6IDhweCAxMHB4Owp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdIHsKICBib3JkZXI6IHNvbGlkIDFweCAjMDBFNkZGOwogIGJhY2tncm91bmQtY29sb3I6ICMzMzM7CiAgaGVpZ2h0OiAyNXB4OwogIHdpZHRoOiAyNXB4OwogIGN1cnNvcjogcG9pbnRlcjsKICAvKgogIC13ZWJraXQtYXBwZWFyYW5jZTogY2hlY2tib3g7CiAgKi8KfQoKaW5wdXRbdHlwZT0iY2hlY2tib3giXTpjaGVja2VkIHsKICBjb2xvcjogI2ZmZjsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDBFNkZGOwogIC8qZGlzcGxheTogaW5saW5lLWJsb2NrOyovCn0KCmlucHV0W3R5cGU9ImNoZWNrYm94Il06YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC00cHg7CiAgY29udGVudDogIiAiOwp9CgppbnB1dFt0eXBlPSJjaGVja2JveCJdOmNoZWNrZWQ6YmVmb3JlIHsKICBwb3NpdGlvbjogaW5pdGlhbDsKICBsZWZ0OiAwcHg7CiAgbWFyZ2luLWxlZnQ6IC0zcHg7CiAgY29udGVudDogIuKckyI7CiAgY29sb3I6ICMwMDA7Cn0KCgppbnB1dFt0eXBlPWJ1dHRvbl0uY2FuY2VsIHsKICAKICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKICBib3JkZXItY29sb3I6IHJlZDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLnNhdmV7CiAgYmFja2dyb3VuZC1jb2xvcjogIzExMTsKICBmbG9hdDogcmlnaHQ7Cn0KCgppbnB1dFt0eXBlPWJ1dHRvbl0uYmxhY2ssIGlucHV0W3R5cGU9c3VibWl0XS5ibGFja3sKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOwogIGJvcmRlci1jb2xvcjogIzAwMDsKfQoKaW5wdXRbdHlwZT1idXR0b25dLmNlbnRlcnsKICBtYXJnaW4tcmlnaHQ6IGF1dG87CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsKICBib3JkZXItY29sb3I6ICMwMDA7Cn0KCi5wb2ludGVyIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5wb2ludGVyOmhvdmVyIHsKICBjb2xvcjogIzAwRTZGRjsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5zb3J0VGhpcyB7CiAgY29sb3I6ICMwMEU2RkY7Cn0KCi53NDBweCB7CiAgbWF4LXdpZHRoOiA0MHB4Owp9CgoudzUwcHggewogIG1heC13aWR0aDogNTBweDsKfQoKLnc4MHB4IHsKICBtYXgtd2lkdGg6IDgwcHg7Cn0KCi53MTUwcHggewogIG1heC13aWR0aDogMTUwcHg7Cn0KCi53MjAwcHggewogIG1heC13aWR0aDogMjAwcHg7CiAgbWluLXdpZHRoOiAxMDBweDsKICB3aWR0aDogMjAwcHg7CiAgb3ZlcmZsb3cteDogaGlkZGVuOwogIHdoaXRlLXNwYWNlOiBub3dyYXA7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpczsKfQoKLnczMDBweCB7CiAgbWF4LXdpZHRoOiAzMDBweDsKfQoKLncyMjBweCB7CiAgbWF4LXdpZHRoOiAyMjBweDsKICBjdXJzb3I6IGFsaWFzOwp9CgouZm9vdGVyIHsKICBmb250LXNpemU6IDEwcHg7Cn0KCi5jZW50ZXIgewogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKLnNjcmVlbkxvZ0hpZGRlbiB7CiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMHB4LCAtMTEwcHgpOwp9CgouYm9yZGVyU3BhY2UgewogIG1hcmdpbi1ib3R0b206IDMwcHg7Cn0KCi5ibG9jayB7Cgp9Cgoubm9uZSB7CiAgZGlzcGxheTogbm9uZTsKfQoKCi5ub3RWaXNpYmxlIHsKICBoZWlnaHQ6IDBweDsKICBkaXNwbGF5OiBub25lOwogIG9wYWNpdHk6IDA7CiAgYm9yZGVyLWJvdHRvbTogIzAwMCBzb2xpZCAwcHg7CiAgCn0KCi52aXNpYmxlIHsKICBvcGFjaXR5OiAxOwogIGRpc3BsYXk6IGJsb2NrOwogIGJvcmRlci1ib3R0b206ICM0NDQgc29saWQgMXB4OyAKICBwYWRkaW5nOiAxMHB4Owp9CgouZmxvYXRSaWdodCB7CiAgZmxvYXQ6IHJpZ2h0Owp9CgouZmxvYXRMZWZ0IHsKICBmbG9hdDogbGVmdDsKfQoKLm1lbnUtYWN0aXZlIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDBFNkZGOwp9CgoubWVudS1ub3RBY3RpdmUgewogIAp9CgojYnJhbmNoIHsKICBkaXNwbGF5OiB0YWJsZTsKICBtYXJnaW46IGF1dG87CiAgY29sb3I6IHJlZDsKfQoKI2ludGVyYWN0aW9uIHsKICBtYXJnaW4tYm90dG9tOiAxMDBweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgYm9yZGVyLWJvdHRvbTogc29saWQgMHB4ICM3Nzc7Cn0KCgouaGFsZiB7CiAgZGlzcGxheTogYmxvY2s7CiAgd2lkdGg6IDQ1JTsKfQoKLm1lbnUgewogIGJvcmRlcjogc29saWQgMXB4ICMwMEU2RkY7Cn0KCi5pbmZvTXNnIHsKICBjb2xvcjogI2FhYTsKfQoKLmVycm9yTXNnIHsKICBjb2xvcjogcmVkOwp9Cgoud2FybmluZ01zZyB7CiAgY29sb3I6IHllbGxvdzsKfQoKLmRlYnVnTXNnIHsKICBjb2xvcjogbWFnZW50YTsKfQoKLk5ld3MsIC5Nb3ZpZSwgLlNlcmllcywgLlNwb3J0cywgLktpZHMgewogIGJvcmRlci1sZWZ0OiBzb2xpZCAycHgKfQoKLk5ld3MgewogIGJvcmRlci1jb2xvcjogdG9tYXRvCn0KCi5Nb3ZpZSB7CiAgYm9yZGVyLWNvbG9yOiByb3lhbGJsdWU7Cn0KCi5TZXJpZXMgewogIGJvcmRlci1jb2xvcjogZ29sZDsKfQoKLlNwb3J0cyB7CiAgYm9yZGVyLWNvbG9yOiB5ZWxsb3dncmVlbjsKfQoKLktpZHMgewogIGJvcmRlci1jb2xvcjogbWVkaXVtcHVycGxlOwp9CgovKiBMb2FkaW5nICovCiNsb2FkaW5nIHsKICBsZWZ0OiAwcHg7CiAgdG9wOiAwcHg7CiAgei1pbmRleDogMTAwMDA7CiAgcG9zaXRpb246IGFic29sdXRlOwogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwwLDAsIDAuOCk7CiAgbWFyZ2luOiBhdXRvOwogIHdpZHRoOiAxMDAlOwogIGhlaWdodDogMTAwJTsKfQoKCi5sb2FkZXIgewogIGJvcmRlcjogNXB4IHNvbGlkIHRyYW5zcGFyZW50OwogIGJvcmRlci1yYWRpdXM6IDUwJTsKICBib3JkZXItdG9wOiA1cHggc29saWQgIzAwRTZGRjsKICBib3JkZXItYm90dG9tOiA1cHggc29saWQgIzAwRTZGRjsKICB3aWR0aDogNTBweDsKICBoZWlnaHQ6IDUwcHg7CiAgLXdlYmtpdC1hbmltYXRpb246IHNwaW4gMS4ycyBsaW5lYXIgaW5maW5pdGU7CiAgYW5pbWF0aW9uOiBzcGluIDEuMnMgbGluZWFyIGluZmluaXRlOwoKICBwb3NpdGlvbjogZml4ZWQ7CiAgbWFyZ2luOiBhdXRvOwoKICB0b3A6IDA7CiAgcmlnaHQ6IDA7CiAgYm90dG9tOiAwOwogIGxlZnQ6IDA7CiAgCn0KCkAtd2Via2l0LWtleWZyYW1lcyBzcGluIHsKICAwJSB7IC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7IH0KICAxMDAlIHsgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyB9Cn0KCkBrZXlmcmFtZXMgc3BpbiB7CiAgMCUgeyB0cmFuc2Zvcm06IHJvdGF0ZSgwZGVnKTsgfQogIDEwMCUgeyB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyB9Cn0K"
- webUI["html/img/settings.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0xMFQxODowODo4OTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Ckxt87EAAAS7SURBVGgFzZpdiFVVGIbn5N+IMgVhaRLqWI7mQIJoIVRgOhQZNDAhWcbcVuPV3BRE6I14440iQQSaN0p6kz8zI0k5inUhZSSaYOVYODMo5eiMOOPf+LzH2cPMPmvttdbe53jOBy9rr2+938/ae51vr733qaoqgQwPD68B/wDJfXAP3AE94JMShCy+SxJ9CvSDJFlU7MiPFdsh/hrBdIffBsd48HApJjLPI4tnPThBlFJMZI5HBuWZCIt9AmgEzeAJR6JzHeMadnKI8wbYCz4Fkz18JlNwMgf8BCL5j4O3bVaMdUfEhPZqgv1U7HbEbDvoT7HZOPUYNwAlHheV09a4A3RTgMqtj9QY7JdgeM5i3I4+fDIYrQeq/UnyNYOTlBDtS+BwEjk2doz+KyO2OY5bwVCME+/qylTHT4C1D3k+uB33Yul3ov/eMuajlu1RH+II5wtT4hNNSnQ6U/kzbRkfq351bCfF8apAm7kmvq38njWRK0S305SHcSK5XO4U5O9MBmXWbSe3E6YccialdKzH2TTnQEF10XgZ5DdivsxEhkyxjVdERAwu03xmMiqD7hYx19km4cyHq6KyeHKkWpSz+ciVrHVpRYZk/wLHp0H2bULkNKzt4Eq86TKxLq3IECf6nXwV9QPbAfjHQSfoD7SN6L63gYhvbrkiTwKf/dPYpbdPVxKMnigdg0VAG8FQye8AzBl6aIk2A+wPiNoHd63LNZx3wbUAvz/CfTzJb/43AmkGpLfAi0DPE/NALQgtve+xFPdi5xRiNkHa5ySOJ/TR7RrBJdqL4AAxL+p+8ToYAFklNCnF3pM1KPba2L6v8vons5oPsko9ZyZoa0PsOoKezxoY+y5N5DYHWSvDTXzUMJH7IUkRW0tbyyV0CcfDDKmqDMe1KfqnQyehGNgo9q8p4hWYFGsiBY4fsSK/BRkkaPgj5PhMy720BnVFesfnlKo3Das0bw8XYJf196GEuzWRLSDoRypLg2w06FyqTS6Cx7iK1eeqGqrnugmuBgvB8+A5UAuqQYiU+oZ4h2T+BV3gAlDp/pai0U1rFpVGMAv8AHzFd4vShMOQLcoB+DNB/sSbM3ZoMV4BQsW0adSJSbNp1Hu1mY40/YZxpPdJaUSfFzrBMXAjjQNsdvll6cHCWVvKJIphdhcny11pqmolCk5aIDif0BKdZBucgPlO8kh/r8O4HtwClSCbk86HtQqQuUrvKVCf5OARjt0lll4H/WKKmbS0tmJQKZNQ7nq9+w0n2LhTN04E8jKMPpZ1hcli8tGTZYEYJwJrZQGzchTGz3a2ifwdkHc73LYAfpx6DcWXQK1LeiDsdpFGx7UOwUGQJKpmGyIjjvWh50iSQWzsZ/ofgvx+jnYp+B/YpJcB7QXDBKPJ4JDF6+/oCwoBuhoL36R+Jp4RJH16u2IgaxJpHhMehsBY3wTjV2YbOuuumLHrwCW6msbSj74O/DHGgV4Ohl8Jw1nSMmsB+tL6Wnw83odzBrhEr2GtgvFE8A74ADxtJZZygMC25cjQqBwqdg62qpUlziUP45Cq6OGuqqoUE/FJ8i+v7MpJYvEsHl1A5gNty2vLmaN3bBLdAvqB3svqXxLRvyEuc9zs7SiA+ACpw05pJx8SoAAAAABJRU5ErkJggg=="
- webUI["html/js/classes_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTsKICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKICAgIH07CiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHsKICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfQogICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKICAgIH07Cn0pKCk7CnZhciBNYWluTWVudSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIE1haW5NZW51KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJtYWluLW1lbnUiOwogICAgICAgIHRoaXMuSFRNTFRhZyA9ICJMSSI7CiAgICB9CiAgICBNYWluTWVudS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgIGNvbnNvbGUubG9nKHRoaXMuRG9jdW1lbnRJRCk7CiAgICB9OwogICAgcmV0dXJuIE1haW5NZW51Owp9KCkpOwp2YXIgTWFpbk1lbnVJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikgewogICAgX19leHRlbmRzKE1haW5NZW51SXRlbSwgX3N1cGVyKTsKICAgIGZ1bmN0aW9uIE1haW5NZW51SXRlbSgpIHsKICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7CiAgICB9CiAgICBNYWluTWVudUl0ZW0ucHJvdG90eXBlLmNyZWF0ZTIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuSFRNTFRhZyk7CiAgICAgICAgZWxlbWVudC5pbm5lclRleHQgPSB0aGlzLlZhbHVlOwogICAgICAgIGNvbnNvbGUubG9nKGVsZW1lbnQpOwogICAgfTsKICAgIHJldHVybiBNYWluTWVudUl0ZW07Cn0oTWFpbk1lbnUpKTsKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogICAgdmFyIGl0ZW0gPSBuZXcgTWFpbk1lbnVJdGVtKCk7CiAgICBpdGVtLlZhbHVlID0gIlRlc3QiOwogICAgaXRlbS5jcmVhdGUyKCk7Cn0K"
- webUI["html/js/data.js"] = "ZnVuY3Rpb24gc2hvd0NvbmZpZyhvYmopIHsKICBjb25maWcgPSBvYmo7CiAgLy9zZXRNZW51SXRlbSgpOwogIGNyZWF0ZU1lbnUoKTsKICAvL2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwYWdlIikuY2xhc3NOYW1lID0gIiI7Cn0KCnNob3dNeVN0cmVhbXMKCmZ1bmN0aW9uIHNob3dNeVN0cmVhbXMoYWxsU3RyZWFtc09iaikgewoKICB2YXIgc3RyZWFtVHlwZUtleXMgPSBnZXRPYmpLZXlzKGFsbFN0cmVhbXNPYmopCgogIGZvciAodmFyIHMgPSAwOyBzIDwgc3RyZWFtVHlwZUtleXMubGVuZ3RoOyBzKyspIHsKICAgIHZhciBzdHJlYW1UeXBlID0gc3RyZWFtVHlwZUtleXNbc107CiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOwogICAgb2JqID0gYWxsU3RyZWFtc09ialtzdHJlYW1UeXBlXTsKICAgIHN3aXRjaChzdHJlYW1UeXBlKSB7CiAgICAgIGNhc2UgImFjdGl2ZVN0cmVhbXMiOiBhY3RpdmVTdHJlYW1zICAgICA9IG9iajsgYnJlYWs7CiAgICB9CgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3RyZWFtVHlwZSkuaW5uZXJIVE1MID0gIiI7CgogICAgdmFyIHN0cmVhbXNPYmogICAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtc05hbWVzICA9IG5ldyBBcnJheSgpOwogICAgCiAgICB2YXIga2V5cyA9IGdldE9iaktleXMob2JqKQogICAgCiAgICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBuYW1lICAgID0gb2JqW2tleXNbaV1dWyJuYW1lIl07CiAgICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICAgIHZhciBzdHJlYW1LZXkgPSBnZXRPYmpLZXlzKG9ialtrZXlzW2ldXSk7CgogICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmVhbUtleS5sZW5ndGg7IGorKykgewogICAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICAgIH0KCiAgICAgIHN0cmVhbXNPYmpbbmFtZV0gPSB0bXA7CiAgICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgICB9CgogICAgc3RyZWFtc05hbWVzLnNvcnQoKTsKICAgIAogICAgLy8gQ3JlYXRlIFRhYmxlIGZvciBhY3RpdmVTdHJlYW1zCiAgICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzdHJlYW1UeXBlKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmVhbXNOYW1lcy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdID0gIlRSIjsKICAgICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogICAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAgIHZhciB0bXAgPSBzdHJlYW1zT2JqW3N0cmVhbXNOYW1lc1tpXV0KICAgICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKHRtcCkKCiAgICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgICAgbmV3S2V5WyJfZWxlbWVudCJdICA9ICJURCI7CiAgICAgIC8vbmV3S2V5WyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgc3dpdGNoKHN0cmVhbVR5cGUpIHsKICAgICAgICBjYXNlICJhY3RpdmVTdHJlYW1zIjogbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsICgrKToiOyBicmVhazsKICAgICAgICBjYXNlICJpbmFjdGl2ZVN0cmVhbXMiOiBuZXdLZXlbIl90ZXh0Il0gICA9ICJDaGFubmVsICgtKToiOyBicmVhazsKICAgICAgfQogICAgICAKICAgICAgbmV3S2V5WyJjbGFzcyJdICAgICA9ICJ0ZEtleSI7CiAgICAgIGNvbnNvbGUubG9nKCk7CgoKICAgICAgdmFyIG5ld1ZhbCA9IG5ldyBPYmplY3QoKQogICAgICBuZXdWYWxbIl9lbGVtZW50Il0gID0gIlREIjsKICAgICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgICAgbmV3VmFsWyJjbGFzcyJdICAgICA9ICJ0ZFZhbCI7CiAgICAgIC8vbmV3VmFsWyJfdGV4dCJdICAgICA9IHZhbHVlOwogICAgICAKICAgICAgbGluZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0tleSkpOwogICAgICBsaW5lLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3VmFsKSk7CiAgICAgIAogICAgfQoKICB9CgogIHJldHVybgp9CgpmdW5jdGlvbiBzaG93QWN0aXZlU3RyZWFtcyhvYmopIHsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWN0aXZlU3RyZWFtcyIpLmlubmVySFRNTCA9ICIiOwogIGFjdGl2ZVN0cmVhbXMgICAgID0gb2JqOwogIHZhciBzdHJlYW1zT2JqICAgID0gbmV3IE9iamVjdCgpOwogIHZhciBzdHJlYW1zTmFtZXMgID0gbmV3IEFycmF5KCk7CiAgCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKG9iaikKICAKICAvLyBDcmVhdGUgT2JqZWN0IChzdHJlYW1zT2JqKSBmb3IgdGhlIHN0cmVhbXMgYW5kIHNvcnQgYnkgbmFtZSAoc3RyZWFtc05hbWVzKQogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgdmFyIG5hbWUgICAgPSBvYmpba2V5c1tpXV1bIm5hbWUiXTsKICAgIHZhciB0bXAgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc3RyZWFtS2V5ID0gZ2V0T2JqS2V5cyhvYmpba2V5c1tpXV0pOwoKICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyZWFtS2V5Lmxlbmd0aDsgaisrKSB7CiAgICAgIHRtcFtzdHJlYW1LZXlbal1dID0gb2JqW2tleXNbaV1dW3N0cmVhbUtleVtqXV07ICAgICAgCiAgICB9CgogICAgc3RyZWFtc09ialtuYW1lXSA9IHRtcDsKICAgIHN0cmVhbXNOYW1lcy5wdXNoKG5hbWUpCiAgfQoKICBzdHJlYW1zTmFtZXMuc29ydCgpOwogIAogIC8vIENyZWF0ZSBUYWJsZSBmb3IgYWN0aXZlU3RyZWFtcwogIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJhY3RpdmVTdHJlYW1zIik7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyZWFtc05hbWVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdFbnRyeVsiX2VsZW1lbnQiXSA9ICJUUiI7CiAgICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CiAgICB2YXIgbGluZSA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICB2YXIgdG1wID0gc3RyZWFtc09ialtzdHJlYW1zTmFtZXNbaV1dCiAgICB2YXIga2V5cyA9IGdldE9iaktleXModG1wKQoKICAgIHZhciBuZXdLZXkgPSBuZXcgT2JqZWN0KCkKICAgIG5ld0tleVsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgLy9uZXdLZXlbIl90ZXh0Il0gICAgID0gc3RyZWFtc05hbWVzW2ldOwogICAgbmV3S2V5WyJfdGV4dCJdICAgICA9ICJDaGFubmVsOiI7CiAgICBuZXdLZXlbImNsYXNzIl0gICAgID0gInRkS2V5IjsKICAgIGNvbnNvbGUubG9nKCk7CgoKICAgIHZhciBuZXdWYWwgPSBuZXcgT2JqZWN0KCkKICAgIG5ld1ZhbFsiX2VsZW1lbnQiXSAgPSAiVEQiOwogICAgbmV3VmFsWyJfdGV4dCJdICAgICA9IHN0cmVhbXNOYW1lc1tpXTsKICAgIG5ld1ZhbFsiY2xhc3MiXSAgICAgPSAidGRWYWwiOwogICAgLy9uZXdWYWxbIl90ZXh0Il0gICAgID0gdmFsdWU7CiAgICAKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdLZXkpKTsKICAgIGxpbmUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdWYWwpKTsKICAgIAogIH0KCn0KCmZ1bmN0aW9uIHBhcnNlTG9ncyhvYmopIHsKICBsb2cgPSBvYmoKICB2YXIga2V5cyA9IGdldE9iaktleXMob2JqKQoKICB2YXIgbXNnVHlwZTsKICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKICAgIHN3aXRjaChrZXlzW2ldKSB7CiAgICAgIGNhc2UgIndhcm5pbmdzIjogIG1zZ1R5cGUgPSAid2FybmluZ01zZyI7IGJyZWFrOwogICAgICBjYXNlICJlcnJvcnMiOiAgICBtc2dUeXBlID0gImVycm9yTXNnIjsgYnJlYWs7CiAgICB9CgogICAgc3dpdGNoKG9ialtrZXlzW2ldXSkgewogICAgICBjYXNlIDA6IG1zZ1R5cGUgPSAidGRWYWwiOyBicmVhazsKICAgICAgZGVmYXVsdDogYnJlYWs7CiAgICB9CgogICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoa2V5c1tpXSkpewogICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChrZXlzW2ldKS5jbGFzc05hbWUgPSBtc2dUeXBlOwogICAgfQogICAgCiAgICAKICB9CiAgcmV0dXJuCn0KCgpmdW5jdGlvbiBjYW5jZWxEYXRhKGVsZW1lbnQpIHsKICBjcmVhdGVNZW51KCk7Cn0KCmZ1bmN0aW9uIHNhdmVEYXRhKGVsZW1lbnQpIHsKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICB2YXIgZGl2ID0gZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGU7CiAgdmFyIGlucHV0cyA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKTsKICAKICB2YXIgY29uZmlnS2V5ID0gZGl2LmdldEF0dHJpYnV0ZSgiZGF0YS1jb25maWdrZXkiKTsKICB2YXIgbWVudVR5cGUgPSBkaXYuZ2V0QXR0cmlidXRlKCJkYXRhLW1lbnV0eXBlIik7CiAgdmFyIHZhbHVlOwogIHZhciB2YWx1ZUFyciA9IG5ldyBBcnJheSgpOwogIAogIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7CiAgICBpZiAoaW5wdXRzW2ldLnR5cGUgPT0gInRleHQiICYmIGlucHV0c1tpXS52YWx1ZSAhPSB1bmRlZmluZWQgJiYgaW5wdXRzW2ldLnZhbHVlICE9ICIiICkgewogICAgICBjb25zb2xlLmxvZyhpbnB1dHNbaV0udmFsdWUsIG1lbnVUeXBlKQogICAgICBzd2l0Y2gobWVudVR5cGUpIHsKICAgICAgICBjYXNlICJpbnB1dEFycmF5IjogdmFsdWVBcnIucHVzaChpbnB1dHNbaV0udmFsdWUpOyBicmVhazsKICAgICAgICBjYXNlICJzaW5nbGVJbnB1dCI6IHZhbHVlID0gaW5wdXRzW2ldLnZhbHVlOyBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgc3dpdGNoKG1lbnVUeXBlKSB7CiAgICBjYXNlICJpbnB1dEFycmF5IjogIGRhdGFbY29uZmlnS2V5XSA9IHZhbHVlQXJyOyBicmVhazsKICAgIGNhc2UgInNpbmdsZUlucHV0IjogIAogICAgICBpZiAoaXNOYU4odmFsdWUpID09IGZhbHNlKSB7CiAgICAgICAgdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgZGF0YVtjb25maWdLZXldID0gdmFsdWU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHsKICAgICAgICBkYXRhWyJkZWxldGUiXSA9IGNvbmZpZ0tleTsgCiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGF0YVtjb25maWdLZXldID0gdmFsdWUKICAgICAgfQoKICAgICAgYnJlYWs7CiAgfQoKICBkYXRhWyJjbWQiXSA9ICJzYXZlQ29uZmlnIjsKICBjb25zb2xlLmxvZyhkYXRhKTsKICB4VGVWZShkYXRhKQp9CgpmdW5jdGlvbiB4VGVWZShkYXRhKSB7CiAgaWYgKHdlYlNvY2tldHMgPT0gZmFsc2UpIHsKICAgIGFsZXJ0KCJZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJTb2NrZXRzIik7CiAgICByZXR1cm47CiAgfSBlbHNlIHsKICAgIGlmIChkYXRhWyJjbWQiXSAhPSAiZ2V0TG9nIikgewogICAgICBzaG93TG9hZGluZ1NjcmVlbih0cnVlKQogICAgfQogIH0KICBkZWxldGUgdW5kb1siZXBnTWFwcGluZyJdOwogIAogIHZhciBwcm90b2NvbFdTCiAgc3dpdGNoKHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCkgewogICAgY2FzZSAiaHR0cDoiOiAgIHByb3RvY29sV1MgPSAid3M6Ly8iOyBicmVhazsKICAgIGNhc2UgImh0dHBzOiI6ICBwcm90b2NvbFdTID0gIndzczovLyI7IGJyZWFrOwogIH0KCgogIHZhciB3cyA9IG5ldyBXZWJTb2NrZXQocHJvdG9jb2xXUyArIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSArICI6IiArIHdpbmRvdy5sb2NhdGlvbi5wb3J0ICsgIi9kYXRhLyIgKyAiP1Rva2VuPSIgKyBnZXRDb29raWUoIlRva2VuIikpOwogIHdzLm9ub3BlbiA9IGZ1bmN0aW9uKCkgewogICAgY29uc29sZS5sb2coZGF0YSkKICAgIHdzLnNlbmQoSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogIH0KCiAgd3Mub25tZXNzYWdlID0gZnVuY3Rpb24gKGUpIHsKICAgIHZhciByZXNwb25zZSA9IEpTT04ucGFyc2UoZS5kYXRhKTsKICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTsKICAgIAogICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJjbGllbnRJbmZvIikpIHsKICAgICAgY3JlYXRlQ2xpbnRJbmZvKHJlc3BvbnNlWyJjbGllbnRJbmZvIl0pOwogICAgfQoKICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgibG9nIikpIHsKICAgICAgY3JlYXRlQ2xpbnRJbmZvKHJlc3BvbnNlWyJsb2ciXSk7CiAgICB9CgogICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJzdGF0dXMiKSkgewogICAgICBpZiAocmVzcG9uc2VbInN0YXR1cyJdID09IGZhbHNlKSB7CiAgICAgICAgYWxlcnQocmVzcG9uc2VbImVyciJdKQogICAgICAgIGlmKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJyZWxvYWQiKSkgewogICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgICAgICAgfQogICAgICAgIC8vY2hlY2tFcnIocmVzcG9uc2UpCiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpOwogICAgICAgIHVwZGF0ZVh0ZXZlU3RhdHVzKHJlc3BvbnNlKTsKICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IHNob3dMb2FkaW5nU2NyZWVuKGZhbHNlKTsgfSwgMzAwKTsKICAgICAgICAKICAgICAgICByZXR1cm4KICAgICAgfQoKICAgICAgdXBkYXRlWHRldmVTdGF0dXMocmVzcG9uc2UpCgogICAgICAvL2NvbnNvbGUubG9nKGRhdGFbImNtZCJdKTsKICAgICAgc3dpdGNoKGRhdGFbImNtZCJdKSB7CiAgICAgICAgY2FzZSAic2F2ZVVzZXJEYXRhIjogICAgY3JlYXRlTWVudSgpOyBicmVhazsKICAgICAgICBjYXNlICJzYXZlTmV3VXNlciI6ICAgICBjcmVhdGVNZW51KCk7IGJyZWFrOwogICAgICAgIGNhc2UgInNhdmVGaWxlc1hNTFRWIjogIC8vY3JlYXRlTWVudSgpOyBicmVhazsKICAgICAgICBjYXNlICJzYXZlRmlsZXNNM1UiOiAgICAvL2NyZWF0ZU1lbnUoKTsgcmV0dXJuOyBicmVhazsKICAgICAgICBjYXNlICJzYXZlQ29uZmlnIjogICAgCiAgICAgICAgICBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgZGF0YVsiY21kIl0gPSAiY2hlY2tUb2tlbiI7CiAgICAgICAgICB4VGVWZShkYXRhKTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICJlbXB0eUxvZyI6IHdyaXRlTG9nSW5EaXYoKTsgYnJlYWs7CiAgICAgICAgY2FzZSAiZ2V0TG9nIjogIHJldHVybjsgYnJlYWs7CiAgICAgIH0KCgogICAgfQoKICAgIGlmIChjb25maWdbImZpbGVzIl0gPT0gdW5kZWZpbmVkIHx8IGNvbmZpZ1siZmlsZXMiXS5sZW5ndGggPT0gMCkgewogICAgICBjcmVhdGVNZW51KCk7CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKDEwKS5jbGljaygpCiAgICB9CgogICAgc2V0VGltZW91dChmdW5jdGlvbigpeyBzaG93TG9hZGluZ1NjcmVlbihmYWxzZSk7IH0sIDApOwogIH0KICAKfQoKZnVuY3Rpb24gdXBkYXRlWHRldmVTdGF0dXMocmVzcG9uc2UpIHsKICB2YXIga2V5cyA9IGdldE9iaktleXMocmVzcG9uc2UpOwogIC8vY29uc29sZS5sb2coa2V5cyk7CgogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgc3dpdGNoKGtleXNbaV0pIHsKICAgICAgY2FzZSAiYWxlcnQiOiAgICAgICAgIGFsZXJ0KHJlc3BvbnNlW2tleXNbaV1dKTsgYnJlYWs7CiAgICAgIGNhc2UgImNvbmZpZyI6ICAgICAgICBzaG93Q29uZmlnKHJlc3BvbnNlW2tleXNbaV1dKTsgYnJlYWs7CiAgICAgIGNhc2UgImxvZyI6ICAgICAgICAgICBwYXJzZUxvZ3MocmVzcG9uc2Vba2V5c1tpXV0pOyBicmVhazsKICAgICAgY2FzZSAibXlTdHJlYW1zIjogICAgIHNob3dNeVN0cmVhbXMocmVzcG9uc2Vba2V5c1tpXV0pOyBicmVhazsKICAgICAgY2FzZSAieEVQRyI6ICAgICAgICAgIHhFUEcgPSByZXNwb25zZVtrZXlzW2ldXTsgYnJlYWs7CiAgICAgIGNhc2UgInVzZXJzIjogICAgICAgICB1c2VycyA9IHJlc3BvbnNlW2tleXNbaV1dOyBicmVhazsKICAgICAgY2FzZSAidG9rZW4iOiAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9ICJUb2tlbj0iICsgcmVzcG9uc2Vba2V5c1tpXV07IGJyZWFrOwogICAgICBjYXNlICJyZWxvYWQiOiAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7IGJyZWFrOwogICAgICBjYXNlICJvcGVuTGluayI6ICAgICAgd2luZG93LmxvY2F0aW9uID0gcmVzcG9uc2VbIm9wZW5MaW5rIl07IGJyZWFrOwogICAgICAvL2Nhc2UgInZlcnNpb24iOiB2ZXJzaW9uID0gcmVzcG9uc2Vba2V5c1tpXV07IGJyZWFrOwogICAgfQogIH0KfQoKZnVuY3Rpb24gZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKHhYbWx0dkZpbGUsIGZpbGVUeXBlLCBrZXkpIHsKCiAgdmFyIGZpbGVJRCA9IHhYbWx0dkZpbGUuc3Vic3RyaW5nKDAsIHhYbWx0dkZpbGUubGFzdEluZGV4T2YoJy4nKSkKCiAgaWYgKGNvbmZpZ1siZmlsZXMiXVtmaWxlVHlwZV0uaGFzT3duUHJvcGVydHkoZmlsZUlEKSA9PSB0cnVlKSB7CiAgICB2YXIgZGF0YSA9IGNvbmZpZ1siZmlsZXMiXVtmaWxlVHlwZV1bZmlsZUlEXTsKICAgIHJldHVybiBkYXRhW2tleV0KICB9Cgp9CgoKCgo="
- webUI["html/js/log.js"] = "dmFyIGxvZ0ludGVydmFsCgoKZnVuY3Rpb24gdXBkYXRlTG9nKCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldExvZyI7CiAgeFRlVmUoZGF0YSk7CiAgd3JpdGVMb2dJbkRpdigpOwogIHJldHVybgp9CgpmdW5jdGlvbiB3cml0ZUxvZ0luRGl2KCkgewogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIikubGFzdENoaWxkLmxhc3RDaGlsZDsKICBkaXYuaW5uZXJIVE1MID0gIiI7CgogIHZhciBtYXggPSA1MDsKICAKICAKICBmb3IgKHZhciBpID0gMDsgaSA8IGxvZ3MubGVuZ3RoOyBpKyspIHsKICAgIHZhciBuZXdFbnRyeSA9IG5ldyBPYmplY3QoKTsKICAgIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJQIjsKCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiRVJST1IiKSkgewovLyAgICAgIGNhc2UgIndhcm5pbmdzIjogIG1zZ1R5cGUgPSAid2FybmluZ01zZyI7IGJyZWFrOwogICAgICBuZXdFbnRyeVsiY2xhc3MiXSAgID0gImVycm9yTXNnIjsKICAgIH0KCiAgICBpZiAobG9nc1tpXS5pbmNsdWRlcygiV0FSTklORyIpKSB7Ci8vICAgICAgY2FzZSAid2FybmluZ3MiOiAgbXNnVHlwZSA9ICJ3YXJuaW5nTXNnIjsgYnJlYWs7CiAgICAgIG5ld0VudHJ5WyJjbGFzcyJdICAgPSAid2FybmluZ01zZyI7CiAgICB9CgogICAgbmV3RW50cnlbIl90ZXh0Il0gICAgID0gbG9nc1tpXTsKICAgIAogICAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKICB9CgogIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB2YXIgc2Nyb2xsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgc2Nyb2xsRGl2LnNjcm9sbFRvcCA9IHNjcm9sbERpdi5zY3JvbGxIZWlnaHQ7Cn0KCmZ1bmN0aW9uIHNob3dMb2cob2JqKSB7CiAgLy9sb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7CgogIHZhciBsb2dzID0gbG9nWyJsb2ciXTsKCiAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZXR0aW5ncyIpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gID0gIkhSIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwogIC8vZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdICAgICAgID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gICAgICAgPSAiRW1wdHkgTG9nIjsKICBuZXdFbnRyeVsib25jbGljayJdICAgICA9ICJlbXB0eUxvZygpIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdFbnRyeSkpOwoKICB2YXIgbmV3RW50cnkgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RW50cnlbIl9lbGVtZW50Il0gICAgPSAiY29kZSI7CiAgbmV3RW50cnlbIl90ZXh0Il0gICAgICAgID0gIlVwZGF0ZSBMb2c6ICI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICAgID0gIklOUFVUIjsKICBuZXdFbnRyeVsidHlwZSJdICAgICAgICA9ICJjaGVja2JveCI7CiAgLy9uZXdFbnRyeVsiY2hlY2tlZCJdICAgICA9ICJjaGVja2JveCI7CiAgbmV3RW50cnlbIm9uY2xpY2siXSAgICAgPSAibG9nVXBkYXRlcyh0aGlzKSI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgCgoKICAKICB2YXIgbmV3V3JhcHBlciA9IG5ldyBPYmplY3QoKTsKICBuZXdXcmFwcGVyWyJfZWxlbWVudCJdICA9ICJESVYiOwogIG5ld1dyYXBwZXJbImlkIl0gICAgICAgID0gImJveC13cmFwcGVyIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdXcmFwcGVyKSk7CiAgZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCiAgdmFyIG5ld1ByZSA9IG5ldyBPYmplY3QoKTsKICBuZXdQcmVbIl9lbGVtZW50Il0gID0gIlBSRSI7CiAgbmV3UHJlWyJpZCJdICAgICAgICA9ICJsb2dTY3JlZW4iOwogIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1ByZSkpOwoKICBkaXYgPSBkaXYubGFzdENoaWxkOwoKICB3cml0ZUxvZ0luRGl2KCkKICByZXR1cm4KfQoKZnVuY3Rpb24gZW1wdHlMb2coKSB7CiAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgZGF0YVsiY21kIl0gPSAiZW1wdHlMb2ciOwogIHhUZVZlKGRhdGEpOwogIHJldHVybgp9CgpmdW5jdGlvbiBsb2dVcGRhdGVzKGVsbSkgewogIHN3aXRjaChlbG0uY2hlY2tlZCkgewogICAgY2FzZSBmYWxzZTogY2xlYXJJbnRlcnZhbChsb2dJbnRlcnZhbCk7IGJyZWFrOwogICAgY2FzZSB0cnVlOiBsb2dJbnRlcnZhbCA9IHNldEludGVydmFsKHVwZGF0ZUxvZywgNTAwMCk7IGJyZWFrOwogICAgCiAgfQp9"
- webUI["html/js/settings_ts.js"] = "dmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkgewogICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwKICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fAogICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9OwogICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpOwogICAgfTsKICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikgewogICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7CiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9CiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpOwogICAgfTsKfSkoKTsKdmFyIFNldHRpbmdzQ2F0ZWdvcnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7CiAgICBmdW5jdGlvbiBTZXR0aW5nc0NhdGVnb3J5KCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJjb250ZW50X3NldHRpbmdzIjsKICAgIH0KICAgIFNldHRpbmdzQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkg0Iik7CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICBTZXR0aW5nc0NhdGVnb3J5LnByb3RvdHlwZS5jcmVhdGVIUiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkhSIik7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogICAgU2V0dGluZ3NDYXRlZ29yeS5wcm90b3R5cGUuY3JlYXRlU2V0dGluZ3MgPSBmdW5jdGlvbiAoc2V0dGluZ3NLZXkpIHsKICAgICAgICB2YXIgc2V0dGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgdmFyIGNvbnRlbnQgPSBuZXcgUG9wdXBDb250ZW50KCk7CiAgICAgICAgdmFyIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bc2V0dGluZ3NLZXldOwogICAgICAgIHN3aXRjaCAoc2V0dGluZ3NLZXkpIHsKICAgICAgICAgICAgLy8gVGV4dGVpbmdhYmVuCiAgICAgICAgICAgIGNhc2UgInVwZGF0ZSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudXBkYXRlLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ1cGRhdGUiLCBkYXRhLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy51cGRhdGUucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJhY2t1cC5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5iYWNrdXBQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJiYWNrdXAucGF0aCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy5iYWNrdXBQYXRoLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ0ZW1wLnBhdGgiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnRlbXBQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ0ZW1wLnBhdGgiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudG1wUGF0aC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidXNlci5hZ2VudCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudXNlckFnZW50LnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ1c2VyLmFnZW50IiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnVzZXJBZ2VudC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYnVmZmVyLnRpbWVvdXQiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmJ1ZmZlclRpbWVvdXQudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgImJ1ZmZlci50aW1lb3V0IiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLmJ1ZmZlclRpbWVvdXQucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImZmbXBlZy5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5mZm1wZWdQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJmZm1wZWcucGF0aCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy5mZm1wZWdQYXRoLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmZm1wZWcub3B0aW9ucyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuZmZtcGVnT3B0aW9ucy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAiZmZtcGVnLm9wdGlvbnMiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MuZmZtcGVnT3B0aW9ucy5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidmxjLnBhdGgiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnZsY1BhdGgudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgInZsYy5wYXRoIiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnZsY1BhdGgucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInZsYy5vcHRpb25zIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy52bGNPcHRpb25zLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ2bGMub3B0aW9ucyIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy52bGNPcHRpb25zLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAvLyBDaGVja2JveGVuCiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLndlYiI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25XRUIudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLnBtcyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25QTVMudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLm0zdSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25NM1UudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLnhtbCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25YTUwudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLmFwaSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25BUEkudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImZpbGVzLnVwZGF0ZSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuZmlsZXNVcGRhdGUudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImNhY2hlLmltYWdlcyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuY2FjaGVJbWFnZXMudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhlcGcucmVwbGFjZS5taXNzaW5nLmltYWdlcyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MucmVwbGFjZUVtcHR5SW1hZ2VzLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ4dGV2ZUF1dG9VcGRhdGUiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnh0ZXZlQXV0b1VwZGF0ZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXBpIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hcGkudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIC8vIFNlbGVjdAogICAgICAgICAgICBjYXNlICJ0dW5lciI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudHVuZXIudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnB1c2goaSk7CiAgICAgICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJlcGdTb3VyY2UiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmVwZ1NvdXJjZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJQTVMiLCAiWEVQRyJdOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFsiUE1TIiwgIlhFUEciXTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGEsIHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKHNlbGVjdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJhY2t1cC5rZWVwIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5iYWNrdXBLZWVwLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBbIjUiLCAiMTAiLCAiMjAiLCAiMzAiLCAiNDAiLCAiNTAiXTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbIjUiLCAiMTAiLCAiMjAiLCAiMzAiLCAiNDAiLCAiNTAiXTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGEsIHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKHNlbGVjdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJ1ZmZlci5zaXplLmtiIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5idWZmZXJTaXplLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBbIjAuNSBNQiIsICIxIE1CIiwgIjIgTUIiLCAiMyBNQiIsICI0IE1CIiwgIjUgTUIiLCAiNiBNQiIsICI3IE1CIiwgIjggTUIiXTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbIjUxMiIsICIxMDI0IiwgIjIwNDgiLCAiMzA3MiIsICI0MDk2IiwgIjUxMjAiLCAiNjE0NCIsICI3MTY4IiwgIjgxOTIiXTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGEsIHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKHNlbGVjdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJ1ZmZlciI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3Muc3RyZWFtQnVmZmVyaW5nLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBbInt7LnNldHRpbmdzLnN0cmVhbUJ1ZmZlcmluZy5pbmZvX2ZhbHNlfX0iLCAieFRlVmU6ICh7ey5zZXR0aW5ncy5zdHJlYW1CdWZmZXJpbmcuaW5mb194dGV2ZX19KSIsICJGRm1wZWc6ICh7ey5zZXR0aW5ncy5zdHJlYW1CdWZmZXJpbmcuaW5mb19mZm1wZWd9fSkiLCAiVkxDOiAoe3suc2V0dGluZ3Muc3RyZWFtQnVmZmVyaW5nLmluZm9fdmxjfX0pIl07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gWyItIiwgInh0ZXZlIiwgImZmbXBlZyIsICJ2bGMiXTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGEsIHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKHNlbGVjdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVkcHh5IjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy51ZHB4eS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidWRweHkiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudWRweHkucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXR0aW5nOwogICAgfTsKICAgIFNldHRpbmdzQ2F0ZWdvcnkucHJvdG90eXBlLmNyZWF0ZURlc2NyaXB0aW9uID0gZnVuY3Rpb24gKHNldHRpbmdzS2V5KSB7CiAgICAgICAgdmFyIGRlc2NyaXB0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICB2YXIgdGV4dDsKICAgICAgICBzd2l0Y2ggKHNldHRpbmdzS2V5KSB7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLndlYiI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmF1dGhlbnRpY2F0aW9uV0VCLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLm0zdSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmF1dGhlbnRpY2F0aW9uTTNVLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLnBtcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmF1dGhlbnRpY2F0aW9uUE1TLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLnhtbCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmF1dGhlbnRpY2F0aW9uWE1MLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLmFwaSI6CiAgICAgICAgICAgICAgICBpZiAoU0VSVkVSWyJzZXR0aW5ncyJdWyJhdXRoZW50aWNhdGlvbi53ZWIiXSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbkFQSS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ4dGV2ZUF1dG9VcGRhdGUiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy54dGV2ZUF1dG9VcGRhdGUuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYmFja3VwLmtlZXAiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5iYWNrdXBLZWVwLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJhY2t1cC5wYXRoIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYmFja3VwUGF0aC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ0ZW1wLnBhdGgiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy50ZW1wUGF0aC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJidWZmZXIiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5zdHJlYW1CdWZmZXJpbmcuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYnVmZmVyLnNpemUua2IiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5idWZmZXJTaXplLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJ1ZmZlci50aW1lb3V0IjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYnVmZmVyVGltZW91dC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1c2VyLmFnZW50IjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudXNlckFnZW50LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImZmbXBlZy5wYXRoIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuZmZtcGVnUGF0aC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmZm1wZWcub3B0aW9ucyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmZmbXBlZ09wdGlvbnMuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidmxjLnBhdGgiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy52bGNQYXRoLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInZsYy5vcHRpb25zIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudmxjT3B0aW9ucy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJlcGdTb3VyY2UiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5lcGdTb3VyY2UuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy50dW5lci5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1cGRhdGUiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy51cGRhdGUuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXBpIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYXBpLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImZpbGVzLnVwZGF0ZSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmZpbGVzVXBkYXRlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImNhY2hlLmltYWdlcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmNhY2hlSW1hZ2VzLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhlcGcucmVwbGFjZS5taXNzaW5nLmltYWdlcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnJlcGxhY2VFbXB0eUltYWdlcy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1ZHB4eSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnVkcHh5LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0ZXh0ID0gIiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICIiOwogICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICB2YXIgcHJlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUFJFIik7CiAgICAgICAgcHJlLmlubmVySFRNTCA9IHRleHQ7CiAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChwcmUpOwogICAgICAgIGRlc2NyaXB0aW9uLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgZGVzY3JpcHRpb24uYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgfTsKICAgIHJldHVybiBTZXR0aW5nc0NhdGVnb3J5Owp9KCkpOwp2YXIgU2V0dGluZ3NDYXRlZ29yeUl0ZW0gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7CiAgICBfX2V4dGVuZHMoU2V0dGluZ3NDYXRlZ29yeUl0ZW0sIF9zdXBlcik7CiAgICBmdW5jdGlvbiBTZXR0aW5nc0NhdGVnb3J5SXRlbShoZWFkbGluZSwgc2V0dGluZ3NLZXlzKSB7CiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpczsKICAgICAgICBfdGhpcy5oZWFkbGluZSA9IGhlYWRsaW5lOwogICAgICAgIF90aGlzLnNldHRpbmdzS2V5cyA9IHNldHRpbmdzS2V5czsKICAgICAgICByZXR1cm4gX3RoaXM7CiAgICB9CiAgICBTZXR0aW5nc0NhdGVnb3J5SXRlbS5wcm90b3R5cGUuY3JlYXRlQ2F0ZWdvcnkgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgICB2YXIgaGVhZGxpbmUgPSB0aGlzLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUodGhpcy5oZWFkbGluZSk7CiAgICAgICAgdmFyIHNldHRpbmdzS2V5cyA9IHRoaXMuc2V0dGluZ3NLZXlzOwogICAgICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChoZWFkbGluZSk7CiAgICAgICAgLy8gVGFiZWxsZSBmw7xyIGRpZSBLYXRlZ29yaWUgZXJzdGVsbGVuCiAgICAgICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEFCTEUiKTsKICAgICAgICB2YXIga2V5cyA9IHNldHRpbmdzS2V5cy5zcGxpdCgiLCIpOwogICAgICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAoc2V0dGluZ3NLZXkpIHsKICAgICAgICAgICAgc3dpdGNoIChzZXR0aW5nc0tleSkgewogICAgICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ucG1zIjoKICAgICAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLm0zdSI6CiAgICAgICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi54bWwiOgogICAgICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24uYXBpIjoKICAgICAgICAgICAgICAgICAgICBpZiAoU0VSVkVSWyJzZXR0aW5ncyJdWyJhdXRoZW50aWNhdGlvbi53ZWIiXSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHZhciBpdGVtID0gX3RoaXMuY3JlYXRlU2V0dGluZ3Moc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjcmlwdGlvbiA9IF90aGlzLmNyZWF0ZURlc2NyaXB0aW9uKHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChpdGVtKTsKICAgICAgICAgICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQodGFibGUpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUhSKCkpOwogICAgfTsKICAgIHJldHVybiBTZXR0aW5nc0NhdGVnb3J5SXRlbTsKfShTZXR0aW5nc0NhdGVnb3J5KSk7CmZ1bmN0aW9uIHNob3dTZXR0aW5ncygpIHsKICAgIGNvbnNvbGUubG9nKCJTRVRUSU5HUyIpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXR0aW5nc0NhdGVnb3J5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgc2V0dGluZ3NDYXRlZ29yeVtpXS5jcmVhdGVDYXRlZ29yeSgpOwogICAgfQp9CmZ1bmN0aW9uIHNhdmVTZXR0aW5ncygpIHsKICAgIGNvbnNvbGUubG9nKCJTYXZlIFNldHRpbmdzIik7CiAgICB2YXIgY21kID0gInNhdmVTZXR0aW5ncyI7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfc2V0dGluZ3MiKTsKICAgIHZhciBzZXR0aW5ncyA9IGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJjaGFuZ2VkIik7CiAgICB2YXIgbmV3U2V0dGluZ3MgPSBuZXcgT2JqZWN0KCk7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIG5hbWU7CiAgICAgICAgdmFyIHZhbHVlOwogICAgICAgIHN3aXRjaCAoc2V0dGluZ3NbaV0udGFnTmFtZSkgewogICAgICAgICAgICBjYXNlICJJTlBVVCI6CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHNldHRpbmdzW2ldLnR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjaGVja2JveCI6CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBzZXR0aW5nc1tpXS5uYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNldHRpbmdzW2ldLmNoZWNrZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NldHRpbmdzW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gc2V0dGluZ3NbaV0ubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBzZXR0aW5nc1tpXS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJ1cGRhdGUiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoIiwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmZpbHRlcihmdW5jdGlvbiAoZSkgeyByZXR1cm4gZTsgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJidWZmZXIudGltZW91dCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUZsb2F0KHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBuZXdTZXR0aW5nc1tuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJTRUxFQ1QiOgogICAgICAgICAgICAgICAgbmFtZSA9IHNldHRpbmdzW2ldLm5hbWU7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHNldHRpbmdzW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgLy8gV2VubiBkZXIgV2VydCBlaW5lIFphaGwgaXN0LCB3aXJkIGRpZXNlciBhbHMgWmFobCBnZXNwZWljaGVydAogICAgICAgICAgICAgICAgaWYgKGlzTmFOKHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgIG5ld1NldHRpbmdzW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBuZXdTZXR0aW5nc1tuYW1lXSA9IHBhcnNlSW50KHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgZGF0YVsic2V0dGluZ3MiXSA9IG5ld1NldHRpbmdzOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9Cg=="
- webUI["html/js/users.js"] = "ZnVuY3Rpb24gb3BlblVzZXJzKGVsbSkgewogIGNvbG9tblNvcnQgPSAwOwoKICB2YXIgbmV3RGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJIUiI7CiAgbmV3RGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3RW50cnkpKTsKCiAgdmFyIG5ld0VudHJ5ID0gbmV3IE9iamVjdCgpOwogIG5ld0VudHJ5WyJfZWxlbWVudCJdICA9ICJJTlBVVCI7CiAgbmV3RW50cnlbInR5cGUiXSA9ICJidXR0b24iOwogIG5ld0VudHJ5WyJjbGFzcyJdID0gImJ1dHRvbiI7CiAgbmV3RW50cnlbInZhbHVlIl0gPSAiTmV3IjsKICBuZXdFbnRyeVsib25jbGljayJdID0gInVzZXJEZXRhaWwoMCkiOwogIG5ld0Rpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0VudHJ5KSk7CgogIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2V0dGluZ3MiKTsKCiAgIC8vIEJ1aWxkIHRhYmxlCiAgdmFyIG5ld1RhYmxlID0gbmV3IE9iamVjdCgpOwogIG5ld1RhYmxlWyJfZWxlbWVudCJdICA9ICJUQUJMRSI7CiAgbmV3VGFibGVbImlkIl0gICAgICAgID0gImlkX21hcHBpbmciOwogIG5ld1RhYmxlWyJjbGFzcyJdICAgICA9ICJ0YWJsZS1tYXBwaW5nIjsKICBkaXYuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUYWJsZSkpOwoKICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IAogICAgY3JlYXRlVXNlcnNUYWJsZSgpOyAKICB9LCAxMCk7Cn0KCmZ1bmN0aW9uIGNyZWF0ZVVzZXJzVGFibGUoKSB7CiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlkX21hcHBpbmciKTsKICB0YWJsZS5pbm5lckhUTUwgPSAiIjsKICB2YXIgbmV3VFIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3VFJbIl9lbGVtZW50Il0gPSAiVFIiOwogIG5ld1RSWyJjbGFzcyJdICAgID0gInRhYmxlLW1hcHBpbmctaGVhZGVyIjsKICB0YWJsZS5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld1RSKSk7CgogIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKICB2YXIgdHJIZWFkbGluZXMgPSBuZXcgQXJyYXkoIlVzZXJuYW1lIiwgIlBhc3N3b3JkIiwgIldFQiIsICJQTVMiLCAiTTNVIiwgIlhNTCIsICJBUEkiKQoKICBmb3IgKHZhciBpID0gMDsgaSA8IHRySGVhZGxpbmVzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJURCI7CiAgICBuZXdURFsiX3RleHQiXSAgICA9IHRySGVhZGxpbmVzW2ldOwogICAgdHIuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdURCkpOwogIH0KCgogIC8vIFNvcnQgdXNlcnMKICB2YXIgdXNlcklkcyA9IGdldE9iaktleXModXNlcnMpOwoKICB2YXIgdXNlck9iaiA9IG5ldyBPYmplY3QoKTsKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCB1c2VySWRzLmxlbmd0aDsgaSsrKSB7CiAgICB2YXIgdXNlcm5hbWUgPSB1c2Vyc1t1c2VySWRzW2ldXVsiZGF0YSJdWyJ1c2VybmFtZSJdOwogICAgdXNlck9ialt1c2VybmFtZV0gPSB1c2VySWRzW2ldOwogIH0KCiAgdmFyIGFsbFVzZXJzID0gZ2V0T2JqS2V5cyh1c2VyT2JqKTsKICBhbGxVc2Vycy5zb3J0KCk7CiAgLy8gLS0KCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGxVc2Vycy5sZW5ndGg7IGkrKykgewogICAgdmFyIHRhYmxlICAgICA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpZF9tYXBwaW5nIik7CiAgICB2YXIgdXNlcklEICAgID0gdXNlck9ialthbGxVc2Vyc1tpXV07CiAgICB2YXIgdXNlcm5hbWUgID0gYWxsVXNlcnNbaV07CiAgICB2YXIgaXRlbSAgICAgID0gdXNlcnNbdXNlcklEXVsiZGF0YSJdOwoKICAgIC8vIENyZWF0ZSBUUgogICAgdmFyIG5ld1RSID0gbmV3IE9iamVjdCgpOwogICAgbmV3VFJbIl9lbGVtZW50Il0gICAgICAgPSAiVFIiOwogICAgbmV3VFJbImNsYXNzIl0gICAgICAgICAgPSAiIjsKICAgIG5ld1RSWyJpZCJdICAgICAgICAgICAgID0gdXNlcklEOwogICAgbmV3VFJbIm9uY2xpY2siXSAgICAgICAgPSAnamF2YXNjcmlwdDogdXNlckRldGFpbCgiJyArIHVzZXJJRCArICciKTsnOwogICAgdGFibGUuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudChuZXdUUikpOwoKICAgIHZhciB0ciA9IHRhYmxlLmxhc3RDaGlsZDsKCiAgICAvLyBDcmVhdGUgdXNlcm5hbWUgVEQKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgbmV3VERbIl90ZXh0Il0gICAgPSB1c2VybmFtZTsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHBhc3N3b3JkIFRECiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIG5ld1REWyJfdGV4dCJdICAgID0gIi4uLi4uIjsKICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIHdlYiBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwogICAgc3dpdGNoKGl0ZW1bImF1dGhlbnRpY2F0aW9uLndlYiJdKXsKICAgICAgY2FzZSB0cnVlOiBuZXdURFsiX3RleHQiXSAgICA9ICLinJMiOyBicmVhazsKICAgICAgZGVmYXVsdDogICBuZXdURFsiX3RleHQiXSAgICA9ICItIjsgYnJlYWs7CiAgICB9CiAgICBjcmVhdGVOZXdURChuZXdURCwgdHIpOwoKICAgIC8vIENyZWF0ZSBQTVMgYWNjZXNzCiAgICB2YXIgbmV3VEQgPSBuZXcgT2JqZWN0KCk7CiAgICBuZXdURFsiX2VsZW1lbnQiXSA9ICJQIjsKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5wbXMiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7IGJyZWFrOwogICAgfQogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgICAvLyBDcmVhdGUgTTNVIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ubTN1Il0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIFhNTFRWIGFjY2VzcwogICAgdmFyIG5ld1REID0gbmV3IE9iamVjdCgpOwogICAgbmV3VERbIl9lbGVtZW50Il0gPSAiUCI7CiAgICBzd2l0Y2goaXRlbVsiYXV0aGVudGljYXRpb24ueG1sIl0pewogICAgICBjYXNlIHRydWU6IG5ld1REWyJfdGV4dCJdICAgID0gIuKckyI7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgIG5ld1REWyJfdGV4dCJdICAgID0gIi0iOyBicmVhazsKICAgIH0KICAgIGNyZWF0ZU5ld1REKG5ld1RELCB0cik7CgogICAgLy8gQ3JlYXRlIEFQSSBhY2Nlc3MKICAgIHZhciBuZXdURCA9IG5ldyBPYmplY3QoKTsKICAgIG5ld1REWyJfZWxlbWVudCJdID0gIlAiOwoKICAgIHN3aXRjaChpdGVtWyJhdXRoZW50aWNhdGlvbi5hcGkiXSl7CiAgICAgIGNhc2UgdHJ1ZTogbmV3VERbIl90ZXh0Il0gICAgPSAi4pyTIjsgYnJlYWs7CiAgICAgIGRlZmF1bHQ6ICAgbmV3VERbIl90ZXh0Il0gICAgPSAiLSI7IGJyZWFrOwogICAgfQogICAgY3JlYXRlTmV3VEQobmV3VEQsIHRyKTsKCiAgfQoKICAvLyB1c2FnZSBJbmZvICAKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNldHRpbmdzIik7CiAgc3dpdGNoKG1lbnVbYWN0aXZlTWVudS5pZF0uaGFzT3duUHJvcGVydHkoIl91c2FnZSIpKSB7CiAgICBjYXNlIHRydWU6IAogICAgICB2YXIgdXNhZ2VJdGVtID0gbmV3IE9iamVjdCgpOwogICAgICB1c2FnZUl0ZW1bIl9lbGVtZW50Il0gPSAiUFJFIgogICAgICB1c2FnZUl0ZW1bIl90ZXh0Il0gICAgPSBtZW51W2FjdGl2ZU1lbnUuaWRdWyJfdXNhZ2UiXTsKCiAgICAgIHZhciBuZXdIUiA9IG5ldyBPYmplY3QoKTsKICAgICAgbmV3SFJbIl9lbGVtZW50Il0gPSAiSFIiCiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KG5ld0hSKSk7CiAgICAgIGRpdi5hcHBlbmRDaGlsZChjcmVhdGVFbGVtZW50KHVzYWdlSXRlbSkpOwogIH0KCiAgc29ydFRhYmxlKDApOwp9CgpmdW5jdGlvbiB1c2VyRGV0YWlsKHVzZXJJRCkgewogIHNob3dQb3BVcEVsZW1lbnQoJ3VzZXItZGV0YWlsJyk7CiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIHRydWUpOwogIH0sIDEwKTsKICB2YXIgZGVmYXVsdFVzZXI7CgogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzYXZlVXNlckRldGFpbCIpLnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzYXZlVXNlckRldGFpbCgiJyArIHVzZXJJRCArICciLCBmYWxzZSknKTsKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZGVsZXRlVXNlckRldGFpbCIpLnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzYXZlVXNlckRldGFpbCgiJyArIHVzZXJJRCArICciLCB0cnVlKScpOwoKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAKICBzd2l0Y2godXNlcklEKSB7CiAgICBjYXNlIDA6ICAgLy8gTmV3IFVzZXIKICAgICAgZGF0YVsidXNlcm5hbWUiXSA9ICIiOwogICAgICBkYXRhWyJhdXRoZW50aWNhdGlvbi53ZWIiXSA9IGZhbHNlOwogICAgICBkYXRhWyJhdXRoZW50aWNhdGlvbi5wbXMiXSA9IHRydWU7CiAgICAgIGRhdGFbImF1dGhlbnRpY2F0aW9uLnhtbCJdID0gdHJ1ZTsKICAgICAgZGF0YVsiYXV0aGVudGljYXRpb24ubTN1Il0gPSBmYWxzZTsKICAgICAgZGF0YVsiYXV0aGVudGljYXRpb24uYXBpIl0gPSBmYWxzZTsKICAgICAgZGF0YVsiZGVmYXVsdFVzZXIiXSAgICAgICAgPSBmYWxzZTsKICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgICAgICBzaG93RWxlbWVudCgiZGVsZXRlVXNlckRldGFpbCIsIGZhbHNlKQogICAgICB9LCAxKTsKCiAgICAgIGJyZWFrOyAKICAgIAogICAgZGVmYXVsdDogCiAgICAgIGRhdGEgPSB1c2Vyc1t1c2VySURdWyJkYXRhIl07IAogICAgICBzaG93RWxlbWVudCgiZGVsZXRlVXNlckRldGFpbCIsIHRydWUpICAgCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWxldGVVc2VyRGV0YWlsIikuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgIAogICAgICBicmVhawogIH0KICAKCiAgdmFyIHVzZXJuYW1lID0gZGF0YVsidXNlcm5hbWUiXTsKICBkYXRhWyJwYXNzd29yZCJdID0gIiI7CiAgZGF0YVsiY29uZmlybSJdID0gIiI7CgogIHZhciBrZXlzID0gZ2V0T2JqS2V5cyhkYXRhKTsKICBkZWZhdWx0VXNlciA9IGRhdGFbImRlZmF1bHRVc2VyIl07CiAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoImRlZmF1bHRVc2VyIikpIHsKICAgIGRlZmF1bHRVc2VyID0gSlNPTi5wYXJzZShkYXRhWyJkZWZhdWx0VXNlciJdKTsKICB9CgogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewoKICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pKXsKICAgICAgdmFyIHRkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoa2V5c1tpXSkKICAgIH0gZWxzZSB7CiAgICAgIHZhciB0ZCA9IHVuZGVmaW5lZDsKICAgIH0KCiAgICB2YXIgbmV3SXRlbSA9IG5ldyBPYmplY3QoKTsKCiAgICBuZXdJdGVtWyJfZWxlbWVudCJdID0gIklOUFVUIjsKICAgIAogICAgbmV3SXRlbVsidmFsdWUiXSAgICA9IGRhdGFba2V5c1tpXV07CiAgICBuZXdJdGVtWyJuYW1lIl0gICAgID0ga2V5c1tpXTsKCgoKCgogICAgc3dpdGNoKGtleXNbaV0uaW5kZXhPZigiYXV0aGVudGljYXRpb24iKSkgewogICAgICBjYXNlIC0xOiAKICAgICAgICBpZiAoa2V5c1tpXSA9PSAicGFzc3dvcmQiIHx8IGtleXNbaV0gPT0gImNvbmZpcm0iKSB7CiAgICAgICAgICBuZXdJdGVtWyJ0eXBlIl0gICAgID0gInBhc3N3b3JkIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmV3SXRlbVsidHlwZSJdICAgICA9ICJ0ZXh0IjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OiAKICAgICAgICBuZXdJdGVtWyJ0eXBlIl0gICAgID0gImNoZWNrYm94IjsKICAgICAgICAKICAgICAgICBpZiAoa2V5c1tpXSA9PSAiYXV0aGVudGljYXRpb24ud2ViIiAmJiBkZWZhdWx0VXNlciA9PSB0cnVlKSB7CiAgICAgICAgICBuZXdJdGVtWyJvbmNsaWNrIl0gPSAicmV0dXJuIGZhbHNlIjsgCiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChkYXRhW2tleXNbaV1dID09IHRydWUpIHsgICAgICAgICAgCiAgICAgICAgICBuZXdJdGVtWyJjaGVja2VkIl0gID0gZGF0YVtrZXlzW2ldXTsgIAogICAgICAgIH0KICAgICAgICAKICAgICAgICBicmVhazsKICAgIH0KCiAgICBzd2l0Y2goa2V5c1tpXSkgewogICAgICBjYXNlICJkZWZhdWx0VXNlciI6IAogICAgICAgIC8vaWYgKGRhdGFba2V5c1tpXV0gPT0gdHJ1ZSkgewogICAgICAgIG5ld0l0ZW1bInR5cGUiXSAgICAgPSAiaGlkZGVuIjsKICAgICAgICAvL30KICAgIH0KCgogICAgaWYgKHRkICE9IHVuZGVmaW5lZCkgewogICAgICB0ZC5pbm5lckhUTUwgPSAiIjsKICAgICAgdmFyIGVsZW1lbnQgPSBjcmVhdGVOZXdFbGVtZW50KG5ld0l0ZW0pCiAgICAgIC8vY29uc29sZS5sb2coZWxlbWVudCk7CiAgICAgIHRkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgfQoKCiAgfQoKCiAgaWYgKGRlZmF1bHRVc2VyID09IHRydWUpIHsKICAgIHNob3dFbGVtZW50KCJkZWxldGVVc2VyRGV0YWlsIiwgZmFsc2UpCiAgfSBlbHNlIHsKICAgIHNob3dFbGVtZW50KCJkZWxldGVVc2VyRGV0YWlsIiwgdHJ1ZSkKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWxldGVVc2VyRGV0YWlsIikuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgfQoKfQoKZnVuY3Rpb24gc2F2ZVVzZXJEZXRhaWwodXNlcklELCBkZWxldGVVc2VyKSB7CgogIHZhciBpbnB1dHMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidXNlci1kZXRhaWwtdGFibGUiKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiSU5QVVQiKTsKCiAgdmFyIG5ld1VzZXJEYXRhID0gbmV3IE9iamVjdCgpOwogIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7CiAgICBzd2l0Y2goaW5wdXRzW2ldLnR5cGUpIHsKICAgICAgY2FzZSAiY2hlY2tib3giOiAgbmV3VXNlckRhdGFbaW5wdXRzW2ldLm5hbWVdID0gaW5wdXRzW2ldLmNoZWNrZWQ7IGJyZWFrOwogICAgICBkZWZhdWx0OiAgICAgICAgICBuZXdVc2VyRGF0YVtpbnB1dHNbaV0ubmFtZV0gPSBpbnB1dHNbaV0udmFsdWU7IGJyZWFrOwogICAgfQogICAgCiAgICBpZiAoaW5wdXRzWyJ1c2VybmFtZSJdLnZhbHVlLmxlbmd0aCA9PSAwKSB7CiAgICAgIGlucHV0c1sidXNlcm5hbWUiXS5zdHlsZS5ib3JkZXIgPSAic29saWQgMXB4IHJlZCI7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBzd2l0Y2godXNlcklEKSB7CiAgICAgIGNhc2UgIjAiOiAKICAgICAgICBpZiAoaW5wdXRzWyJwYXNzd29yZCJdLnZhbHVlLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICBjb25zb2xlLmxvZyhpbnB1dHNbInBhc3N3b3JkIl0udmFsdWUubGVuZ3RoKTsKICAgICAgICAgIGlucHV0c1sicGFzc3dvcmQiXS5zdHlsZS5ib3JkZXIgPSAic29saWQgMXB4IHJlZCI7CiAgICAgICAgICByZXR1cm4KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGlucHV0c1sicGFzc3dvcmQiXS52YWx1ZS5sZW5ndGggPiAwKSB7CiAgICAgIGlmIChpbnB1dHNbInBhc3N3b3JkIl0udmFsdWUgIT0gaW5wdXRzWyJjb25maXJtIl0udmFsdWUpIHsKICAgICAgICBpbnB1dHNbInBhc3N3b3JkIl0uc3R5bGUuYm9yZGVyID0gInNvbGlkIDFweCByZWQiOwogICAgICAgIGlucHV0c1siY29uZmlybSJdLnN0eWxlLmJvcmRlciA9ICJzb2xpZCAxcHggcmVkIjsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0KICAgIAogIH0KCiAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgCiAgc3dpdGNoKHVzZXJJRCkgewogICAgY2FzZSAiMCI6CiAgICAgIC8vZGF0YSA9IG5ld1VzZXJEYXRhCiAgICAgIGRhdGFbInVzZXJEYXRhIl0gID0gbmV3VXNlckRhdGEKICAgICAgZGF0YVsiY21kIl0gICAgICAgPSAic2F2ZU5ld1VzZXIiOyBicmVhazsKICAgIAogICAgZGVmYXVsdDogIAogICAgICB2YXIgdGhpc1VzZXIgICAgICA9IG5ldyBPYmplY3QoKTsKICAgICAgCiAgICAgIGlmIChkZWxldGVVc2VyID09IHRydWUpIHsKICAgICAgICBpZiAoY29uZmlybSgnRGVsZXRlIHRoZSBzZWxlY3RlZCB1c2VyPycpKSB7CiAgICAgICAgICBkYXRhWyJkZWxldGVVc2VyIl0gPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7CiAgICAgICAgICByZXR1cm4KICAgICAgICB9CiAgICAgIH0KICAgICAgCiAgICAgIHRoaXNVc2VyW3VzZXJJRF0gID0gbmV3VXNlckRhdGE7CgogICAgICBkYXRhWyJ1c2VyRGF0YSJdID0gdGhpc1VzZXI7CiAgICAgIGRhdGFbImNtZCJdID0gInNhdmVVc2VyRGF0YSI7IGJyZWFrOwogIH0KICAKICB4VGVWZShkYXRhKTsKICAvL2NyZWF0ZVVzZXJzVGFibGUoKQogIHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsKfQoKCg=="
- webUI["html/.DS_Store"] = "AAAAAUJ1ZDEAABgAAAAIAAAAGAAAABALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAQAAAABAAAQAHNwYmxvYgAAAMticAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAgLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAABAAAAQAAAAAEAAACAAAAAAQAAAQAAAAABAAACAAAAAAEAAAQAAAAAAAAAAAEAABAAAAAAAQAAIAAAAAABAABAAAAAAAEAAIAAAAAAAQABAAAAAAABAAIAAAAAAAEABAAAAAAAAQAIAAAAAAABABAAAAAAAAEAIAAAAAAAAQBAAAAAAAABAIAAAAAAAAEBAAAAAAAAAQIAAAAAAAABBAAAAAAAAAEIAAAAAAAAARAAAAAAAAABIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEERFNEQgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAgAAAAYAAAAAAAAAABAAAAgAAAAAEAAAEAAAAAAQAAAgAAAAABAAAEAAAAAAEAAAgAAAAAAAAAAAEAACAAAAAAAQAAQAAAAAABAACAAAAAAAEAAQAAAAAAAQACAAAAAAABAAQAAAAAAAEACAAAAAAAAQAQAAAAAAABACAAAAAAAAEAQAAAAAAAAQCAAAAAAAABAQAAAAAAAAECAAAAAAAAAQQAAAAAAAABCAAAAAAAAAEQAAAAAAAAASAAAAAAAAABQAAAAAAAAABpZWTUGRobHB0MHw1VaW5kZXhZYXNjZW5kaW5nVXdpZHRoV3Zpc2libGUQBwkRASwI1BkaGxwiDSQNEAgIEMgI1BkaGxwnDSkNEAIIELUI1BkaGxwsDS4MEAMIEGEJ1BkaGxwxDDMNEAUJEGQI1BkaGxw2DDgMEAQJEHMJ1BkaGxw7DD0NEAYJEEsI1BkaGxxADEIMEAAJEQK+CdQZGhscCw0pDAgJIwAAAAAAAAAAI0AoAAAAAAAAVG5hbWUjQDAAAAAAAAAJAAgAHQAyAEQAWABgAHIAewCNAJgAoQC0ALYAtwC4AMsA1ADjAO8A9AD6AP8BBwEMARkBIgEoATIBOAFAAUIBQwFGAUcBUAFSAVMBVQFWAV8BYQFiAWQBZQFuAXABcQFzAXQBfQF/AYABggGDAYwBjgGPAZEBkgGbAZ0BngGgAaEBqgGsAa0BsAGxAboBuwG8AcUBzgHTAdwAAAAAAAACAQAAAAAAAABMAAAAAAAAAAAAAAAAAAAB3QAAAAMAaQBtAGd2U3JubG9uZwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ webUI["html/img/x_white.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMToyNTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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"
webUI["html/img/xmltv.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQyMDowNzozMzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Co6j9bsAAAGgSURBVGgF7VqxTsNADL0gYGEon8DOwsbAAH8BYmJn6cYIn8DC3h0+oixISFRiYYCJL0AwMMBAeK5w2rpV6uikxHfYknW98+vds18TK21DWGBlWR7CH+BfcEv2AzLP8HP42gLqkyUATuEp2PWEdQjF9ATs1zF/g29Mrxt+vVcUxR3xWxEktzFPJQmivsv8ZSI9DiQyVnxlIonwn6fpiczXpNuVVXH8O+a3Ys3y9NUyuf/NTTbEHZTjUlGSRzSiPhroUIENwB4AS/vS/susDwDhTpYBER9g7wHh5DWyibV9CiitCZbIafDEYUuJHQI3Nr/9ciWsjK6IFSWYhyvClbAyZqOIlYJG84jq7E1Ot97Zm+TinV1TrWwudk9EI3ebGFekzWprzspGEU2ySWCiOrs/s9dr7M/s9fVJJJrNXcsTsfaJc0WsKZINH+/sf1Jqvl1n1f2ZnStRN/pdq646XcSkIh9dkIg4s+IrE3nCpp8RG7f91ns+cCYR/LD4jcAZB42PN+A7/mcQ8ZxJhBYQvMJwBB/BKTFLVoLMC/wCfgyv7BesTKUC2LKM3wAAAABJRU5ErkJggg=="
- webUI["html/js/network_ts.js"] = "dmFyIFNlcnZlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIFNlcnZlcihjbWQpIHsKICAgICAgICB0aGlzLmNtZCA9IGNtZDsKICAgIH0KICAgIFNlcnZlci5wcm90b3R5cGUucmVxdWVzdCA9IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgaWYgKFNFUlZFUl9DT05ORUNUSU9OID09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfQ09OTkVDVElPTiA9IHRydWU7CiAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgaWYgKHRoaXMuY21kICE9ICJ1cGRhdGVMb2ciKSB7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgIFVORE8gPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAod2luZG93LmxvY2F0aW9uLnByb3RvY29sKSB7CiAgICAgICAgICAgIGNhc2UgImh0dHA6IjoKICAgICAgICAgICAgICAgIHRoaXMucHJvdG9jb2wgPSAid3M6Ly8iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImh0dHBzOiI6CiAgICAgICAgICAgICAgICB0aGlzLnByb3RvY29sID0gIndzczovLyI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHVybCA9IHRoaXMucHJvdG9jb2wgKyB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgKyAiOiIgKyB3aW5kb3cubG9jYXRpb24ucG9ydCArICIvZGF0YS8iICsgIj9Ub2tlbj0iICsgZ2V0Q29va2llKCJUb2tlbiIpOwogICAgICAgIGRhdGFbImNtZCJdID0gdGhpcy5jbWQ7CiAgICAgICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh1cmwpOwogICAgICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgV1NfQVZBSUxBQkxFID0gdHJ1ZTsKICAgICAgICAgICAgY29uc29sZS5sb2coIlJFUVVFU1QgKEpTKToiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSRVFVRVNUOiAoSlNPTikiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgICAgICB0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoZGF0YSkpOwogICAgICAgIH07CiAgICAgICAgd3Mub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJObyB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byB4VGVWZSBjb3VsZCBiZSBlc3RhYmxpc2hlZC4gQ2hlY2sgeW91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIFNFUlZFUl9DT05ORUNUSU9OID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChXU19BVkFJTEFCTEUgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGFsZXJ0KCJObyB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byB4VGVWZSBjb3VsZCBiZSBlc3RhYmxpc2hlZC4gQ2hlY2sgeW91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHdzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIFNFUlZFUl9DT05ORUNUSU9OID0gZmFsc2U7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgZmFsc2UpOwogICAgICAgICAgICBjb25zb2xlLmxvZygiUkVTUE9OU0U6Iik7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IEpTT04ucGFyc2UoZS5kYXRhKTsKICAgICAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UpOwogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoInRva2VuIikpIHsKICAgICAgICAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9ICJUb2tlbj0iICsgcmVzcG9uc2VbInRva2VuIl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlWyJzdGF0dXMiXSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYWxlcnQocmVzcG9uc2VbImVyciJdKTsKICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgicmVsb2FkIikpIHsKICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoImxvZ29VUkwiKSkgewogICAgICAgICAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjaGFubmVsLWljb24iKTsKICAgICAgICAgICAgICAgIGRpdi52YWx1ZSA9IHJlc3BvbnNlWyJsb2dvVVJMIl07CiAgICAgICAgICAgICAgICBkaXYuY2xhc3NOYW1lID0gImNoYW5nZWQiOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAoZGF0YVsiY21kIl0pIHsKICAgICAgICAgICAgICAgIGNhc2UgInVwZGF0ZUxvZyI6CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSWyJsb2ciXSA9IHJlc3BvbnNlWyJsb2ciXTsKICAgICAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfbG9nIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0xvZ3MoZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICBTRVJWRVIgPSByZXNwb25zZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoIm9wZW5NZW51IikpIHsKICAgICAgICAgICAgICAgIHZhciBtZW51ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocmVzcG9uc2VbIm9wZW5NZW51Il0pOwogICAgICAgICAgICAgICAgbWVudS5jbGljaygpOwogICAgICAgICAgICAgICAgc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eSgib3BlbkxpbmsiKSkgewogICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcmVzcG9uc2VbIm9wZW5MaW5rIl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJhbGVydCIpKSB7CiAgICAgICAgICAgICAgICBhbGVydChyZXNwb25zZVsiYWxlcnQiXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJyZWxvYWQiKSkgewogICAgICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJ3aXphcmQiKSkgewogICAgICAgICAgICAgICAgY3JlYXRlTGF5b3V0KCk7CiAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uV2l6YXJkW3Jlc3BvbnNlWyJ3aXphcmQiXV0uY3JlYXRlV2l6YXJkKCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3JlYXRlTGF5b3V0KCk7CiAgICAgICAgfTsKICAgIH07CiAgICByZXR1cm4gU2VydmVyOwp9KCkpOwpmdW5jdGlvbiBnZXRDb29raWUobmFtZSkgewogICAgdmFyIHZhbHVlID0gIjsgIiArIGRvY3VtZW50LmNvb2tpZTsKICAgIHZhciBwYXJ0cyA9IHZhbHVlLnNwbGl0KCI7ICIgKyBuYW1lICsgIj0iKTsKICAgIGlmIChwYXJ0cy5sZW5ndGggPT0gMikKICAgICAgICByZXR1cm4gcGFydHMucG9wKCkuc3BsaXQoIjsiKS5zaGlmdCgpOwp9Cg=="
- webUI["html/login.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keT4KICAgICAgICAgIAogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgoKICAgICAgPGRpdiBpZD0iYm94Ij4KCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPnt7LmxvZ2luLmhlYWRsaW5lfX08L2gxPgogICAgICAgIDwvZGl2PgoKICAgICAgICA8cCBpZD0iZXJyIiBjbGFzcz0iZXJyb3JNc2cgY2VudGVyIj57ey5hdXRoZW50aWNhdGlvbkVycn19PC9wPgoKICAgICAgICA8ZGl2IGlkPSJjb250ZW50Ij4KCiAgICAgICAgICAgIDxmb3JtIGlkPSJhdXRoZW50aWNhdGlvbiIgYWN0aW9uPSIiIG1ldGhvZD0icG9zdCI+CgogICAgICAgICAgICAgIDxoNT57ey5sb2dpbi51c2VybmFtZS50aXRsZX19OjwvaDU+CiAgICAgICAgICAgICAgPGlucHV0IGlkPSJ1c2VybmFtZSIgdHlwZT0idGV4dCIgbmFtZT0idXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJVc2VybmFtZSIgdmFsdWU9IiI+CiAgICAgICAgICAgICAgPGg1Pnt7LmxvZ2luLnBhc3N3b3JkLnRpdGxlfX06PC9oNT4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgbmFtZT0icGFzc3dvcmQiIHBsYWNlaG9sZGVyPSJQYXNzd29yZCIgdmFsdWU9IiI+CgogICAgICAgICAgICA8L2Zvcm0+CgogICAgICAgIDwvZGl2PgoKICAgICAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj4KICAgICAgICAgIDxpbnB1dCBpZD0ic3VibWl0IiBjbGFzcz0iIiB0eXBlPSJidXR0b24iIHZhbHVlPSJ7ey5idXR0b24ubG9naW59fSIgb25jbGljaz0iamF2YXNjcmlwdDogbG9naW4oKTsiPgogICAgICAgIDwvZGl2PgogICAgICAgIAogICAgICA8L2Rpdj4KCiAgICA8L2JvZHk+CiAgICAKPC9odG1sPg=="
- webUI["html/img/mapping.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wOC0wMlQxMjowODo5NzwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CpRxQsEAAAJLSURBVGgF7VoxTgMxEMwBHWlAaeABVCEtBcoD+EBewCdCyQsQtLyAPCBvCBSRIBUPCF1ogqBJjlkrezGr6HTrO98lhy1Z9trr2VmvnbMNjUadUhzHLeQB8hw5LS3QOUbubvIf7X3kKXIZibgS51bCZdWgMT6D8nECgArkngagQN0B8dhbkblalVmLIyheCGUthhjuLBq77MihA0xTjHHBEBBOorHLjjghbNOg4Mg2RYO4hIiEiHiaAV5aSwf8hRgjZdHtTTTc2ZFXpZkY+hMx5k3IZYlr7jgudJHp2JElLaF0K1mirYn8nAWgQB3ibM59ERNCA52d6Nghv9isQiUtn0kURe92I9eBcYA6YZxym8dyDuwRuMw82gjQYQbsPdLDdNCROO0US3uEfp3usTZpjf5J2CNtNFwjl7FHvmBnCB5PCQkQoJudJtGvE23sJEFuI39rQArS7dskXK6nlwkAKiB1VxAxLcyUePAH8cQmlbEul4+UM8LkVjPc2ZHcaFUDBEeqjoC0HyIiZ6RqOUSk6ghI+xyRD9mRQTYfIktPylaX16rhzo48KE29QH8kxjxC/hFtZYiGe70OjWVMW7Dx32bA3iO7//iAC8DOPweZFQhH6O+CmkRvW2f28oV8owEoUHdMPPg70rFJZajTkqT7uZ3ObaHEuuHOjnCpsb8vlKUsur2JhruLA94Y5QEOjuSZPR9jQ0R8zGoezNpFhN5RtUm+/bpgaG1u0jd2OSLDTRopbZ/okxcrLUYKvKprbRfHhXr8m5PK/y1V/gWRKLfiNSmxEAAAAABJRU5ErkJggg=="
- webUI["html/img/logo_w_600x200.png"] = "iVBORw0KGgoAAAANSUhEUgAAAlgAAADICAYAAAA0n5+2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAuIwAALiMBeKU/dgAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MzAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjAwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAg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"
- webUI["html/img/stream-limit.jpg"] = "/9j/4AAQSkZJRgABAQAAAQABAAD/4gJoSUNDX1BST0ZJTEUAAQEAAAJYbGNtcwQwAABtbnRyUkdCIFhZWiAH4wAFABcAFgAuAAphY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAAEBjcHJ0AAABSAAAAE53dHB0AAABmAAAABRjaGFkAAABrAAAACxyWFlaAAAB2AAAABRiWFlaAAAB7AAAABRnWFlaAAACAAAAABRyVFJDAAACFAAAACBnVFJDAAACFAAAACBiVFJDAAACFAAAACBjaHJtAAACNAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACQAAAAcAHMAUgBHAEIAIABJAEUAQwA2ADEAOQA2ADYALQAyAC4AMQAAbWx1YwAAAAAAAAABAAAADGVuVVMAAAAyAAAAHABOAG8AIABjAG8AcAB5AHIAaQBnAGgAdAAsACAAdQBzAGUAIABmAHIAZQBlAGwAeQAAAABYWVogAAAAAAAA9tYAAQAAAADTLXNmMzIAAAAAAAEMSgAABeP///MqAAAHmwAA/Yf///ui///9owAAA9gAAMCUWFlaIAAAAAAAAG+UAAA47gAAA5BYWVogAAAAAAAAJJ0AAA+DAAC2vlhZWiAAAAAAAABipQAAt5AAABjecGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltjaHJtAAAAAAADAAAAAKPXAABUewAATM0AAJmaAAAmZgAAD1z/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAQ4B4ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD/AD/6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD9PvBf/AARa/wCCrXxF8HeE/iD4G/YM/aL8UeCfHfhrQvGXg/xNpHgia50nxF4W8T6Xa634f13TLkTgXGn6vpN9aahZTgAS21xFIAN1dL/w4o/4LB/9I7/2m/8AwgZ//kiv9b3/AIJp/wDKOX9gH/syf9lX/wBUV4Dr7YoA/wAWr/hxR/wWD/6R3/tN/wDhAz//ACRR/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Ir/AGlaKAP8Wr/hxR/wWD/6R3/tN/8AhAz/APyRR/w4o/4LB/8ASO/9pv8A8IGf/wCSK/2laKAP8Wr/AIcUf8Fg/wDpHf8AtN/+EDP/APJFH/Dij/gsH/0jv/ab/wDCBn/+SK/2laKAP8Wr/hxR/wAFg/8ApHf+03/4QM//AMkUf8OKP+Cwf/SO/wDab/8ACBn/APkiv9pWigD/ABav+HFH/BYP/pHf+03/AOEDP/8AJFH/AA4o/wCCwf8A0jv/AGm//CBn/wDkiv8AaVooA/xav+HFH/BYP/pHf+03/wCEDP8A/JFH/Dij/gsH/wBI7/2m/wDwgZ//AJIr/aVooA/xav8AhxR/wWD/AOkd/wC03/4QM/8A8kUf8OKP+Cwf/SO/9pv/AMIGf/5Ir/aVooA/xav+HFH/AAWD/wCkd/7Tf/hAz/8AyRR/w4o/4LB/9I7/ANpv/wAIGf8A+SK/2laKAP8AFq/4cUf8Fg/+kd/7Tf8A4QM//wAkUf8ADij/AILB/wDSO/8Aab/8IGf/AOSK/wBpWigD/Fq/4cUf8Fg/+kd/7Tf/AIQM/wD8kUf8OKP+Cwf/AEjv/ab/APCBn/8Akiv9pWigD/Fq/wCHFH/BYP8A6R3/ALTf/hAz/wDyRR/w4o/4LB/9I7/2m/8AwgZ//kiv9pWigD/E88f/APBGT/gqj8K/AnjT4nfEX9hL9ofwf8P/AIdeFPEPjnxz4t1zwTNaaL4X8IeE9Ju9d8SeIdXujORbaZo2j2F5qN9OQRDa20shB24r8yq/28f+Ctf/ACit/wCClX/ZhH7Xv/rP/wAQK/xDqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA+j/ANmj9kL9pr9snxbrvgL9lr4K+Ovjn408M+HH8X6/4Y+H2ljWdZ0vwvFqen6NLr1zYrNHMNMh1XVtL0+a7RWihu9RsoZSj3MIf7U/4cUf8Fg/+kd/7Tf/AIQM/wD8kV2v/BAD9sj/AIYi/wCCrf7K/wATNW1X+yvh98QPFw+AHxWklm+z6f8A8IJ8aWg8HjU9Xl3Ls0rwd4wufCPxAuz82B4RQlJACjf7MFAH+LV/w4o/4LB/9I7/ANpv/wAIGf8A+SKP+HFH/BYP/pHf+03/AOEDP/8AJFf7StFAH+LV/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Io/4cUf8Fg/+kd/7Tf/AIQM/wD8kV/tK0UAf4tX/Dij/gsH/wBI7/2m/wDwgZ//AJIo/wCHFH/BYP8A6R3/ALTf/hAz/wDyRX+0rRQB/gx/HT4CfGb9mT4n+Ivgt+0B8NfFnwj+K3hJNHl8SeA/G2lzaP4i0iLxBomneI9Emu7KbJWLU9C1bTtTs5UZ45rW7idWySB5HX9yX/B69+yL/wAIr8eP2V/22/D2meXpfxb8Da18BfiPd2sOy3i8afDG9k8U+BdR1OXbiXVPFHg/xZrukWzB2P8AZnw0jjZIxEjS/wANtABRRRQAUUUUAFFFFABRRRQAUUUUAPRHldIokeSSR1SONFLu7uQqIiKCzOzEKqqCWJAAJNfq8n/BCv8A4LBSIki/8E7/ANp3a6q67vh/dI21gGG5HnV0bB5V1VlPDAEEVv8A/BBj9kX/AIbU/wCCrf7Ivwo1PTP7T8DeGPiFb/Gz4nRTQ+fpzeAvgpE3xDv9L1hQrEaZ4w1nRdD8BSkAFp/FdvH5kO/zo/8AZ4oA/wAWr/hxR/wWD/6R3/tN/wDhAz//ACRR/wAOKP8AgsH/ANI7/wBpv/wgZ/8A5Ir/AGlaKAP8Wr/hxR/wWD/6R3/tN/8AhAz/APyRR/w4o/4LB/8ASO/9pv8A8IGf/wCSK/2laKAP8Wr/AIcUf8Fg/wDpHf8AtN/+EDP/APJFH/Dij/gsH/0jv/ab/wDCBn/+SK/2laKAP8Kz9p39iX9rL9i7UfCOkftV/AT4ifAfVPHtlq+o+DtO+IejjRb3xDp+gz2Ntq97p1s00k0lrY3GpWUEs7IkbSz+XGztHKI/lqv6F/8Ag5+/bI/4a5/4K2/HDTNF1X+0fh7+y5aaZ+y74KEU261GofDq61K8+KVz5UbG3N0fi9r3jnSTexl5bzSdE0USybLeCGD+eigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/cg/4Jp/8o5f2Af+zJ/2Vf8A1RXgOvtivif/AIJp/wDKOX9gH/syf9lX/wBUV4Dr7YoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD8+P8AgrX/AMorf+ClX/ZhH7Xv/rP/AMQK/wAQ6v8Abx/4K1/8orf+ClX/AGYR+17/AOs//ECv8Q6gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAHI7xOkkbtHJGyvHIjFHR0IZXRlIZWVgGVlIIIBBBFf7Z//BIH9sRP28f+Cbv7J37St5qS6n4x8VfC/TPDXxTmMqvc/wDC3PhxNcfD/wCJdxdQ5Mtp/bPi7w3qfiLT7e4zK2jazplyHnhuIrib/Eur/QW/4Mm/2yPteh/tZfsE+JNV3T6PeaT+1D8KNPml3yNp2pDRvht8YrW381t0NrYahB8JtRtLK33Rtda5r980cUjzyzgH98VFFFABRRRQAUUUUAfhR/wcifsif8Ngf8Eif2ndD0vTP7T8dfAvSbH9p74ehYvPuINW+DCXur+MUs4FUzXF/qvwjvfiRoFhb25E819q9skazn/R5v8AHer/AH6NW0rTdd0rU9D1mxtdU0fWdPvNK1bTL6FLmy1HTdRtpLS+sby3kDRz2t3azS29xDIrJLFI6OCrEV/hv/8ABQv9lrUv2J/23/2ov2V9Riuo4Pgv8Y/GHhbwzPe7/tWqeAJdQbWfhrr83mfPu8R/D7VPDOvjcWO3Uh88n32APjeiiigAooooAKKKKACiiigAooooA/0D/wDgyU/ZE+z6T+19+3Xr+mYl1G70D9lz4Y6lJFtdbSwTSfif8YfKaRd0lvd3Vz8HreC4g2xifS9VtneSRHSD++mvyl/4Ih/sif8ADEf/AAS3/ZB+B2o6X/ZXjV/hhYfE/wCKEEsPlahH8S/jDNN8SfFmmaq21WnvfCl14ki8EpKw+Ww8M2MCExQxmv1aoAKKKKACiiigAr5A/b+/ao0X9iP9iv8AaZ/as1xrRk+Cfwi8V+LdCsr5gtrrfjk2R0j4c+GZWLKF/wCEq8f6n4a8NodwxJqqdeh+v6/ib/4PTP2yP+EA/Za/Z5/Yk8N6r5WvftCfEG7+LPxGtLWb98nww+Dogh8OaVqtvuA+weKviT4g03W9Nk2uWvvhfdrujEZEoB/nB+IfEGteLPEGueKvEup3eteIvE2san4g1/WL+Uz32ra1rN7PqOq6nezNzNd399cz3VzKeZJpXc8mseiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/cg/4Jp/8AKOX9gH/syf8AZV/9UV4Dr7Yr4n/4Jp/8o5f2Af8Asyf9lX/1RXgOvtigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPz4/4K1/8orf+ClX/AGYR+17/AOs//ECv8Q6v9vH/AIK1/wDKK3/gpV/2YR+17/6z/wDECv8AEOoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr9V/+CJP7ZH/DCn/BT39k348anqv9leA2+Itp8Mvi1NNN5Onp8LPi3FJ8P/F+qaou5RPaeEbfXYPHcMLMB/aXhXT5R80Sg/lRRQB/v8UV+TP/AAQ5/bI/4bo/4JdfsnfG7VNV/tXx9p/w+tfhN8WpZZvO1Fvid8IJG8A+JNV1f5m8u/8AGUWi6d8QFjDECx8W2TgRh/LT9ZqACiiigAooooAK/wA07/g9I/ZE/wCFcftj/AD9sXQNM8jQP2lfhZdfD7xtd28O5H+KPwOnsbO31HUp1A8q41z4a+KvBmkaXDN808HgPUnhZ1tplh/0sa/nd/4Oi/2RP+Gq/wDgkT8cNZ0fS/7R8dfsuapoP7T/AITMUO64TS/ACahpXxSVp0Bnjsbf4ReJvHOuz26hoLi+0HS2nQG3iuLcA/yKaKKKACiiigAooooAKKKKACv02/4I3fsi/wDDcf8AwUy/ZC/Z3vtM/tXwfr3xX0nxh8TrWSLfaS/Cr4XQ3PxJ+IlleyMGhto9d8L+FtQ8NWk04MbaprWn2yxzz3EUEv5k1/eL/wAGTH7In9reP/2uf259f0zdZ+D9A0H9mf4Z6hND5sEmveK7jTviL8VprV3Gy21LQ9E0b4YWSTwlp207xnqVsWhgnkS5AP8AQzooooAKKKKACiiigAr/AB3f+DkD9sj/AIbN/wCCtf7SWvaRqv8Aanw9+BGpWv7MPw1aOf7RaJovwcudR0zxfd2E6MYLnT9d+LV/8RfEWm3dsPJuNM1axZJJ1VbiX/Ux/wCCnv7XVn+wl+wF+1T+1TLdW1trXws+E2vXHgJbsRtBe/FTxOYPBnwo02aKQMJbe/8AiN4h8MW16qxysti9zN5UixMp/wAQK+vr3U7281LUru5v9R1C6uL6/vryaS5u729u5XuLq7uriZnlnubieR5p5pXaSWV2d2ZmJIBVooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/sa/Z9/4PGv2mv2ffgJ8EPgJo37HXwJ8QaP8EPhD8NfhDpOv6n43+IFtqWt6b8NfBmi+DLHV9Qt7QfZbe+1K10WK9u4bb/R4riaSOH92q169/xG8ftWf9GRfs9/+F98R/8ACv4h6KAP7eP+I3j9qz/oyL9nv/wvviP/AIUf8RvH7Vn/AEZF+z3/AOF98R/8K/iHooA/t4/4jeP2rP8AoyL9nv8A8L74j/4Uf8RvH7Vn/RkX7Pf/AIX3xH/wr+IeigD+3j/iN4/as/6Mi/Z7/wDC++I/+FH/ABG8ftWf9GRfs9/+F98R/wDCv4h6KAP9GT/gmX/wdhftE/t2/t3fs3/skeLv2T/gt4E8N/G/xpf+F9W8XeHPGPjnUNb0O3tPCviHxCt1p9lqY+wXEzzaNFbslz8gimkYfOq1/cpX+NT/AMG73/KaX9gD/srmtf8AqtPHVf7K1ABRRRQAUUUUAFFFFAH8KH/BRT/g7X/aN/Yq/bf/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WOj6BoOn3Gq6xql5Jg+Xaafp1pcXdw+DshhdsHGKAP8AN2/4PR/2yP8AhY37XHwD/Yq8N6r53h/9m34dT/Er4g2dtNiP/hanxqFlcaTpmqW4Yh7rw38MdB8M6zpUzhWitviTqKICJmJ/itr6y/bt/ah179tX9sf9pP8Aaq8RG6juvjh8XfF/jbS7C9fzLjQfCN1qUln4D8LF98m6Lwl4IsvD/hm2Jkc/ZtJiBdj8x+TaACiiigAooooAK/2Hv+DZvSf7G/4Id/sIWe3Z53hv40atjGM/29+0r8Ztc3f8D/tHfnvuzzmv8eGv9kD/AINw7+HUv+CJ37A1xAqqkfw58c2DBOhm0r40fEvTLhj/ALb3FnKz/wC2WoA/biiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr/JJ/4Ow/+U2X7Q//AGTv9nj/ANUr4Nr/AFtq/wAkn/g7D/5TZftD/wDZO/2eP/VK+DaAP5vaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK6vwJ4G8W/E3xn4X+HngLQdQ8UeNPGmu6b4a8L+HtLi86/1fWtXuo7OwsrdCVRTLPKoeaZ47e3iD3FzLFBFJIt06dSrUhSpQnUq1Zwp06dOMp1KlSpOMKdOEIKUpznOcIQhGMpSlKMYpuST58Xi8LgMJisfjsTh8FgcDhsRjcbjcXXpYXCYPB4OhWxWLxeKxOIqUaGHw2Fw2GxGIxGIr1aVGhQoVq1WpTp0pzj9Y/sAfsT+O/27/wBofw38HvC32vSfCtqY/EXxU8cx2/nWvgfwDZ3MMep6gDIpgm13VHkTR/C2myZ+361dwPcCLSrTVL2z/wBHr4T/AAs8CfBD4beC/hL8MtAtPDHgPwBoNl4c8NaJZj5LWwskOZriZv3t7qV/cvPqOr6ndNJe6rqt3eal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gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr+z7/ggp/wTT/4VH4Psf20vjV4f8r4n/ELRXX4K+HtVtsXPgT4d6zbFJvGk8E6brXxN8QbCXZpbIqz6X4Hn/17P4t1GysPyI/4Ip/8E13/AGxfjB/wuX4r6G837N3wa1q0m1S1voD9h+KPxAtlg1HSvAMXmL5V3oOmRyWmt+O8ear6bNpfh14h/wAJK95p/wDedHGkSJFEiRxxoscccahEjRAFRERQFVFUBVVQAoAAAAr+o/AXw29vUpcdZ3h/3FGclw3ha0NK1eDlTq5zOE1rTw8lOjlzaaniFXxkbxw+Hkf4Nfta/psf2Tg8d9FLwvzi2aZlh6E/GrPctxHv5dleIhRxeC8NsPiKFS8Mbm1KWFzPjSMKkZ4bKJZTw5VUKub5vRT6KKK/rU/55AooooAKKKr3d3a2Frc319c29lY2VvNd3l5dzR21raWttG01xc3NxMyQwW8EKPLNNK6RxRozuyqpIG0k22kkm220kkk2222kkkm220kk22km04xlOUYQjKc5yjCEIRlOc5zlGMIQhGMpSnKUoxjGMZSlKUYxjKUoxlYoqlpuo6frGn2Gr6TfWeqaVqlla6jpmp6fcw3un6jp99AlzZX1jeWzyW93Z3dtLHcW1zBJJDPDIksTsjqxu0k1JKUWnFpNNNNNNJppptNNNNNNpppptNNucJ0pzp1ITp1Kc506lOpCdOpTqU5zp1KdSnUjCpTqU6lOdOpTqQhOE4ThOEJwnCBRRRTJCiiigD8if+Cvv/BOiw/bq+A0ms+CNNtIv2i/hFZalrXwv1HENtN4u00p9q1z4X6pdvsRrXxCIRc+Gp7yRIdI8Vw2j/arDS9W8QPcf59Ooaff6Tf32larZXem6npl5c6fqWnX9vNZ31hf2Uz215ZXtpcJHPa3drcRyQXNvPGk0E0bxSIrqyj/AFjK/kJ/4L+/8E2P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/DSP/BUjUvgr4f1X7d4A/Y18AaL8IbSK3m87TpviZ4mSHx78VtVhBYmPULa61fw18PtYjCoEvPh1sCsVMsoB/LfRRRQAUUUUAFFFFABRRRQAUUUUAFf6lH/BsR/wW/h/bw+Ddn+xj+0n4qib9sH4C+E7ePwt4i1m7Vb/APaF+D2gQwWFp4kW4nYPqXxM8BWv2TS/H9u5k1LxFpA03x8kmp3U3jWXRP8ALXr0j4P/ABg+J3wA+J/gf4z/AAY8b6/8OPil8N/EFl4o8E+NvDF61jrWg61YMTFcW8oDxT288TzWWpabew3OmavplzeaVqtneabeXVrMAf72FFfzsf8ABCH/AIL2fCb/AIKr/DKw+GXxPvvDPwy/bk8CaKg8e/DJbqLTdK+K+nadbZuvil8HrW8nM9/pc8cL3fi7wbBJeav4DvTKZvtnhqfStbu/6J6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA+HP8Agp3/AMo1v+Chf/Zjn7WX/qhPH9f4dVf7iv8AwU7/AOUa3/BQv/sxz9rL/wBUJ4/r/DqoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKtWNje6ne2em6bZ3WoajqF1b2NhYWNvLd3t9e3cqQWtnaWsCST3N1czyRw29vCjyzSukcaM7AFpNtJJttpJJNtttJJJJtttpJJNttJJtpOZzhThKpUlGEIRlOc5yjCEIQjKc5znOUIQhCEJznOc4QhCE5znGMZSj7x+y5+zX8Sf2t/jj4G+BHwr0/7V4l8ZaksdzqVxHK2keFPDtpifxB4v8AEM0SsbbRPD+nCW8uiM3F5MLbStOjudV1CxtLj/SQ/ZX/AGZ/ht+yJ8DPA/wH+Flh9n8O+D9PAvtWniiTV/F3iW8CzeIfGHiGWIYuNZ1+/wB9zMNxgsLUWej6ctvpWm2FrB+fv/BHj/gnDZfs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FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF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FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z"
- webUI["html/lang/en.json"] = "ewogICJtYWluTWVudSI6CiAgewogICAgIml0ZW0iOgogICAgewogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAicG1zSUQiOiAiUE1TIElEIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIiLAogICAgICAieG1sdHYiOiAiWE1MVFYiLAogICAgICAibWFwcGluZyI6ICJNYXBwaW5nIiwKICAgICAgInVzZXJzIjogIlVzZXJzIiwKICAgICAgInNldHRpbmdzIjogIlNldHRpbmdzIiwKICAgICAgImxvZyI6ICJMb2ciLAogICAgICAibG9nb3V0IjogIkxvZ291dCIKICAgIH0sCiAgICAiaGVhZGxpbmUiOgogICAgewogICAgICAicGxheWxpc3QiOiAiTG9jYWwgb3IgcmVtb3RlIHBsYXlsaXN0cyIsCiAgICAgICJmaWx0ZXIiOiAiRmlsdGVyIHBsYXlsaXN0IiwKICAgICAgInhtbHR2IjogIkxvY2FsIG9yIHJlbW90ZSBYTUxUViBmaWxlcyIsCiAgICAgICJtYXBwaW5nIjogIk1hcCBwbGF5bGlzdCBjaGFubmVscyB0byBFUEcgY2hhbm5lbHMiLAogICAgICAidXNlcnMiOiAiVXNlciBtYW5hZ2VtZW50IiwKICAgICAgInNldHRpbmdzIjogIlNldHRpbmdzIiwKICAgICAgImxvZyI6ICJMb2ciLAogICAgICAibG9nb3V0IjogIkxvZ291dCIKICAgIH0KICB9LAogICJjb25maXJtIjoKICB7CiAgICAicmVzdG9yZSI6ICJBbGwgZGF0YSB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhvc2UgZnJvbSB0aGUgYmFja3VwLiBTaG91bGQgdGhlIGZpbGVzIGJlIHJlc3RvcmVkPyIKICB9LAogICJhbGVydCI6CiAgewogICAgImZpbGVMb2FkaW5nRXJyb3IiOiAiRmlsZSBjb3VsZG4ndCBiZSBsb2FkZWQiLAogICAgImludmFsaWRDaGFubmVsTnVtYmVyIjogIkludmFsaWQgY2hhbm5lbCBudW1iZXIiLAogICAgIm1pc3NpbmdJbnB1dCI6ICJNaXNzaW5nIGlucHV0IgogIH0sCiAgImJ1dHRvbiI6CiAgewogICAgImJhY2siOiAiQmFjayIsCiAgICAiYmFja3VwIjogIkJhY2t1cCIsCiAgICAiYnVsa0VkaXQiOiAiQnVsayBFZGl0IiwKICAgICJjYW5jZWwiOiAiQ2FuY2VsIiwKICAgICJkZWxldGUiOiAiRGVsZXRlIiwKICAgICJkb25lIjogIkRvbmUiLAogICAgImxvZ2luIjogIkxvZ2luIiwKICAgICJuZXciOiAiTmV3IiwKICAgICJuZXh0IjogIk5leHQiLAogICAgInJlc3RvcmUiOiAiUmVzdG9yZSIsCiAgICAic2F2ZSI6ICJTYXZlIiwKICAgICJzZWFyY2giOiAiU2VhcmNoIiwKICAgICJ1cGRhdGUiOiAiVXBkYXRlIiwKICAgICJjcmFldGVBY2NvdW50IjogIkNyZWF0ZSBBY2NvdW50IiwKICAgICJyZXNldExvZ3MiOiAiUmVzZXQgTG9ncyIsCiAgICAidXBsb2FkTG9nbyI6ICJVcGxvYWQgTG9nbyIKICB9LAogICJmaWx0ZXIiOgogIHsKICAgICJ0YWJsZSI6CiAgICB7CiAgICAgICJuYW1lIjogIkZpbHRlciBOYW1lIiwKICAgICAgInR5cGUiOiAiRmlsdGVyIFR5cGUiLAogICAgICAiZmlsdGVyIjogIkZpbHRlciIKICAgIH0sCiAgICAiY3VzdG9tIjogIkN1c3RvbSIsCiAgICAiZ3JvdXAiOiAiR3JvdXAiLAogICAgIm5hbWUiOgogICAgewogICAgICAidGl0bGUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRmlsdGVyIG5hbWUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR5cGUiOgogICAgewogICAgICAidGl0bGUiOiAiVHlwZSIsCiAgICAgICJncm91cFRpdGxlIjogIkdyb3VwIFRpdGxlIiwKICAgICAgImN1c3RvbUZpbHRlciI6ICJDdXN0b20gRmlsdGVyIgogICAgfSwKICAgICJjYXNlU2Vuc2l0aXZlIjoKICAgIHsKICAgICAgInRpdGxlIjogIkNhc2UgU2Vuc2l0aXZlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbHRlclJ1bGUiOgogICAgewogICAgICAidGl0bGUiOiAiRmlsdGVyIFJ1bGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiU3BvcnQge0hEfSAhe0VTLElUfSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbHRlckdyb3VwIjoKICAgIHsKICAgICAgInRpdGxlIjogIkdyb3VwIFRpdGxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJTZWxlY3QgYSBNM1UgZ3JvdXAuIChDb3VudGVyKTxicj5DaGFuZ2luZyB0aGUgZ3JvdXAgdGl0bGUgaW4gdGhlIE0zVSBpbnZhbGlkYXRlcyB0aGUgZmlsdGVyLiIKICAgIH0sCiAgICAiaW5jbHVkZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJJbmNsdWRlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkZIRCxVSEQiLAogICAgICAiZGVzY3JpcHRpb24iOiAiQ2hhbm5lbCBuYW1lIG11c3QgaW5jbHVkZS48YnI+KENvbW1hIHNlcGFyYXRlZCkgQ29tbWEgbWVhbnMgb3IiCiAgICB9LAogICAgImV4Y2x1ZGUiOgogICAgewogICAgICAidGl0bGUiOiAiRXhjbHVkZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJFUyxJVCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFubmVsIG5hbWUgbXVzdCBub3QgY29udGFpbi48YnI+KENvbW1hIHNlcGFyYXRlZCkgQ29tbWEgbWVhbnMgb3IiCiAgICB9CgogIH0sCiAgInBsYXlsaXN0IjoKICB7CiAgICAidGFibGUiOgogICAgewogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAidHVuZXIiOiAiVHVuZXIiLAogICAgICAibGFzdFVwZGF0ZSI6ICJMYXN0IFVwZGF0ZSIsCiAgICAgICJhdmFpbGFiaWxpdHkiOiAiQXZhaWxhYmlsaXR5IiwKICAgICAgInR5cGUiOiAiVHlwZSIsCiAgICAgICJzdHJlYW1zIjogIlN0cmVhbXMiLAogICAgICAiZ3JvdXBUaXRsZSI6ICJncm91cC10aXRsZSIsCiAgICAgICJ0dmdJRCI6ICJ0dmctaWQiLAogICAgICAidW5pcXVlSUQiOiAiVW5pcXVlIElEIgogICAgfSwKICAgICJwbGF5bGlzdFR5cGUiOgogICAgewogICAgICAidGl0bGUiOiAiUGxheWxpc3QgdHlwZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ0eXBlIjoKICAgIHsKICAgICAgInRpdGxlIjogIlR5cGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAibmFtZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJOYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBsYXlsaXN0IG5hbWUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbGVNM1UiOgogICAgewogICAgICAidGl0bGUiOiAiTTNVIEZpbGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRmlsZSBwYXRoIG9yIFVSTCBvZiB0aGUgTTNVIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsZUhESFIiOgogICAgewogICAgICAidGl0bGUiOiAiSERIb21lUnVuIElQIiwKICAgICAgInBsYWNlaG9sZGVyIjogIklQIGFkZHJlc3MgYW5kIHBvcnQgKDE5Mi4xNjguMS4xMDo1MDA0KSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInR1bmVyIjoKICAgIHsKICAgICAgInRpdGxlIjogIlR1bmVyIC8gU3RyZWFtcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIHBhcmFsbGVsIGNvbm5lY3Rpb25zIHRoYXQgY2FuIGJlIGVzdGFibGlzaGVkIHRvIHRoZSBwcm92aWRlci4gPGJyPk9ubHkgYXZhaWxhYmxlIHdpdGggYWN0aXZhdGVkIGJ1ZmZlci48YnI+TmV3IHNldHRpbmdzIHdpbGwgb25seSBiZSBhcHBsaWVkIGFmdGVyIHF1aXR0aW5nIGFsbCBzdHJlYW1zLiIKICAgIH0KICB9LAogICJ4bWx0diI6CiAgewogICAgInRhYmxlIjoKICAgIHsKICAgICAgImd1aWRlIjogIkd1aWRlIiwKICAgICAgImxhc3RVcGRhdGUiOiAiTGFzdCBVcGRhdGUiLAogICAgICAiYXZhaWxhYmlsaXR5IjogIkF2YWlsYWJpbGl0eSIsCiAgICAgICJjaGFubmVscyI6ICJDaGFubmVscyIsCiAgICAgICJwcm9ncmFtcyI6ICJQcm9ncmFtcyIKICAgIH0sCiAgICAibmFtZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJOYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkd1aWRlIG5hbWUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbGVYTUxUViI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJYTUxUViBGaWxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkZpbGUgcGF0aCBvciBVUkwgb2YgdGhlIFhNTFRWIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0KICB9LAogICJtYXBwaW5nIjoKICB7CiAgICAidGFibGUiOgogICAgewogICAgICAiY2hObyI6ICJDaC4gTm8uIiwKICAgICAgImxvZ28iOiAiTG9nbyIsCiAgICAgICJjaGFubmVsTmFtZSI6ICJDaGFubmVsIE5hbWUiLAogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAiZ3JvdXBUaXRsZSI6ICJHcm91cCBUaXRsZSIsCiAgICAgICJ4bWx0dkZpbGUiOiAiWE1MVFYgRmlsZSIsCiAgICAgICJ4bWx0dklEIjogIlhNTFRWIElEIgogICAgfSwKICAgICJhY3RpdmUiOgogICAgewogICAgICAidGl0bGUiOiAiQWN0aXZlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImNoYW5uZWxOYW1lIjoKICAgIHsKICAgICAgInRpdGxlIjogIkNoYW5uZWwgTmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJkZXNjcmlwdGlvbiI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJDaGFubmVsIERlc2NyaXB0aW9uIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlVzZWQgYnkgdGhlIER1bW15IGFzIGFuIFhNTCBkZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInVwZGF0ZUNoYW5uZWxOYW1lIjoKICAgIHsKICAgICAgInRpdGxlIjogIlVwZGF0ZSBDaGFubmVsIE5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiY2hhbm5lbExvZ28iOgogICAgewogICAgICAidGl0bGUiOiAiTG9nbyBVUkwiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidXBkYXRlQ2hhbm5lbExvZ28iOgogICAgewogICAgICAidGl0bGUiOiAiVXBkYXRlIENoYW5uZWwgTG9nbyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJlcGdDYXRlZ29yeSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJFUEcgQ2F0ZWdvcnkiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAibTN1R3JvdXBUaXRsZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJHcm91cCBUaXRsZSAoeHRldmUubTN1KSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ4bWx0dkZpbGUiOgogICAgewogICAgICAidGl0bGUiOiAiWE1MVFYgRmlsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ4bWx0dkNoYW5uZWwiOgogICAgewogICAgICAidGl0bGUiOiAiWE1MVFYgQ2hhbm5lbCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfQogIH0sCiAgInVzZXJzIjoKICB7CiAgICAidGFibGUiOgogICAgewogICAgICAidXNlcm5hbWUiOiAiVXNlcm5hbWUiLAogICAgICAicGFzc3dvcmQiOiAiUGFzc3dvcmQiLAogICAgICAid2ViIjogIldFQiIsCiAgICAgICJwbXMiOiAiUE1TIiwKICAgICAgIm0zdSI6ICJNM1UiLAogICAgICAieG1sIjogIlhNTCIsCiAgICAgICJhcGkiOiAiQVBJIgogICAgfSwKICAgICJ1c2VybmFtZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJVc2VybmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJVc2VybmFtZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInBhc3N3b3JkIjoKICAgIHsKICAgICAgInRpdGxlIjogIlBhc3N3b3JkIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBhc3N3b3JkIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiY29uZmlybSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJDb25maXJtIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBhc3N3b3JkIGNvbmZpcm0iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ3ZWIiOgogICAgewogICAgICAidGl0bGUiOiAiV2ViIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJwbXMiOgogICAgewogICAgICAidGl0bGUiOiAiUE1TIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJtM3UiOgogICAgewogICAgICAidGl0bGUiOiAiTTNVIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ4bWwiOgogICAgewogICAgICAidGl0bGUiOiAiWE1MIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJhcGkiOgogICAgewogICAgICAidGl0bGUiOiAiQVBJIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfQogIH0sCiAgInNldHRpbmdzIjoKICB7CiAgICAiY2F0ZWdvcnkiOgogICAgewogICAgICAiZ2VuZXJhbCI6ICJHZW5lcmFsIiwKICAgICAgImZpbGVzIjogIkZpbGVzIiwKICAgICAgInN0cmVhbWluZyI6ICJTdHJlYW1pbmciLAogICAgICAiYmFja3VwIjogIkJhY2t1cCIsCiAgICAgICJhdXRoZW50aWNhdGlvbiI6ICJBdXRoZW50aWNhdGlvbiIKICAgIH0sCiAgICAidXBkYXRlIjoKICAgIHsKICAgICAgInRpdGxlIjogIlNjaGVkdWxlIGZvciB1cGRhdGluZyAoUGxheWxpc3QsIFhNTFRWLCBCYWNrdXApIiwKICAgICAgInBsYWNlaG9sZGVyIjogIjAwMDAsMTAwMCwyMDAwIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlRpbWUgaW4gMjQgaG91ciBmb3JtYXQgKDA4MDAgPSA4OjAwIGFtKS4gTW9yZSB0aW1lcyBjYW4gYmUgZW50ZXJlZCBjb21tYSBzZXBhcmF0ZWQuIExlYXZlIHRoaXMgZmllbGQgZW1wdHkgaWYgbm8gdXBkYXRlcyBhcmUgdG8gYmUgY2FycmllZCBvdXQuIgogICAgfSwKICAgICJhcGkiOgogICAgewogICAgICAidGl0bGUiOiAiQVBJIEludGVyZmFjZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJWaWEgQVBJIGludGVyZmFjZSBpdCBpcyBwb3NzaWJsZSB0byBzZW5kIGNvbW1hbmRzIHRvIHhUZVZlLiBBUEkgZG9jdW1lbnRhdGlvbiBpcyA8YSBocmVmPSdodHRwczovL2dpdGh1Yi5jb20veHRldmUtcHJvamVjdC94VGVWZS1Eb2N1bWVudGF0aW9uL2Jsb2IvbWFzdGVyL2VuL2NvbmZpZ3VyYXRpb24ubWQjYXBpJz5oZXJlPC9hPiIKICAgIH0sCiAgICAiZXBnU291cmNlIjoKICAgIHsKICAgICAgInRpdGxlIjogIkVQRyBTb3VyY2UiLAogICAgICAiZGVzY3JpcHRpb24iOiAiUE1TOjxicj4tIFVzZSBFUEcgZGF0YSBmcm9tIFBsZXggb3IgRW1ieSA8YnI+PGJyPlhFUEc6PGJyPi0gVXNlIG9mIG9uZSBvciBtb3JlIFhNTFRWIGZpbGVzPGJyPi0gQ2hhbm5lbCBtYW5hZ2VtZW50PGJyPi0gTTNVIC8gWE1MVFYgZXhwb3J0IChIVFRQIGxpbmsgZm9yIElQVFYgYXBwcykiCiAgICB9LAogICAgInR1bmVyIjoKICAgIHsKICAgICAgInRpdGxlIjogIk51bWJlciBvZiBUdW5lcnMiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIHBhcmFsbGVsIGNvbm5lY3Rpb25zIHRoYXQgY2FuIGJlIGVzdGFibGlzaGVkIHRvIHRoZSBwcm92aWRlci48YnI+QXZhaWxhYmxlIGZvcjogUGxleCwgRW1ieSAoSERIUiksIE0zVSAod2l0aCBhY3RpdmUgYnVmZmVyKS48YnI+QWZ0ZXIgYSBjaGFuZ2UsIHhUZVZlIG11c3QgYmUgZGVsZXRlIGluIHRoZSBQbGV4IC8gRW1ieSBEVlIgc2V0dGluZ3MgYW5kIHNldCB1cCBhZ2Fpbi4iCiAgICB9LAogICAgImZpbGVzVXBkYXRlIjoKICAgIHsKICAgICAgInRpdGxlIjogIlVwZGF0ZXMgYWxsIGZpbGVzIGF0IHN0YXJ0dXAiLAogICAgICAiZGVzY3JpcHRpb24iOiAiVXBkYXRlcyBhbGwgcGxheWxpc3RzLCB0dW5lciBhbmQgWE1MVFYgZmlsZXMgYXQgc3RhcnR1cC4iCiAgICB9LAogICAgImNhY2hlSW1hZ2VzIjoKICAgIHsKICAgICAgInRpdGxlIjogIkltYWdlIENhY2hpbmciLAogICAgICAiZGVzY3JpcHRpb24iOiAiQWxsIGltYWdlcyBmcm9tIHRoZSBYTUxUViBmaWxlIGFyZSBjYWNoZWQsIGFsbG93aW5nIGZhc3RlciByZW5kZXJpbmcgb2YgdGhlIGdyaWQgaW4gdGhlIGNsaWVudC48YnI+RG93bmxvYWRpbmcgdGhlIGltYWdlcyBtYXkgdGFrZSBhIHdoaWxlIGFuZCB3aWxsIGJlIGRvbmUgaW4gdGhlIGJhY2tncm91bmQuIgogICAgfSwKICAgICJyZXBsYWNlRW1wdHlJbWFnZXMiOgogICAgewogICAgICAidGl0bGUiOiAiUmVwbGFjZSBtaXNzaW5nIHByb2dyYW0gaW1hZ2VzIiwKICAgICAgImRlc2NyaXB0aW9uIjogIklmIHRoZSBwb3N0ZXIgaW4gdGhlIFhNTFRWIHByb2dyYW0gaXMgbWlzc2luZywgdGhlIGNoYW5uZWwgbG9nbyB3aWxsIGJlIHVzZWQuIgogICAgfSwKICAgICJ4dGV2ZUF1dG9VcGRhdGUiOgogICAgewogICAgICAidGl0bGUiOiAiQXV0b21hdGljIHVwZGF0ZSBvZiB4VGVWZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiBhIG5ldyB2ZXJzaW9uIG9mIHhUZVZlIGlzIGF2YWlsYWJsZSwgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGluc3RhbGxlZC4gVGhlIHVwZGF0ZXMgYXJlIGRvd25sb2FkZWQgZnJvbSBHaXRIdWIuIgogICAgfSwKICAgICJzdHJlYW1CdWZmZXJpbmciOgogICAgewogICAgICAidGl0bGUiOiAiU3RyZWFtIEJ1ZmZlciIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJGdW5jdGlvbnMgb2YgdGhlIGJ1ZmZlcjo8YnI+LSBUaGUgc3RyZWFtIGlzIHBhc3NlZCBmcm9tIHhUZVZlLCBGRm1wZWcgb3IgVkxDIHRvIFBsZXgsIEVtYnkgb3IgTTNVIFBsYXllcjxicj4tIFNtYWxsIGplcmtpbmcgb2YgdGhlIHN0cmVhbXMgY2FuIGJlIGNvbXBlbnNhdGVkPGJyPi0gSExTIC8gTTNVOCBzdXBwb3J0PGJyPi0gUlRQIC8gUlRQUyBzdXBwb3J0IChvbmx5IEZGbXBlZyBvciBWTEMpPGJyPi0gUmUtc3RyZWFtaW5nPGJyPi0gU2VwYXJhdGUgdHVuZXIgbGltaXQgZm9yIGVhY2ggcGxheWxpc3QiLAogICAgICAiaW5mb19mYWxzZSI6ICJObyBCdWZmZXIgKENsaWVudCBjb25uZWN0cyB0byB0aGUgc3RyZWFtaW5nIHNlcnZlcikiLAogICAgICAiaW5mb194dGV2ZSI6ICJ4VGVWZSBjb25uZWN0cyB0byB0aGUgc3RyZWFtaW5nIHNlcnZlciIsCiAgICAgICJpbmZvX2ZmbXBlZyI6ICJGRm1wZWcgY29ubmVjdHMgdG8gdGhlIHN0cmVhbWluZyBzZXJ2ZXIiLAogICAgICAiaW5mb192bGMiOiAiVkxDIGNvbm5lY3RzIHRvIHRoZSBzdHJlYW1pbmcgc2VydmVyIgoKICAgIH0sCiAgICAidWRweHkiOgogICAgewogICAgICAidGl0bGUiOiAiVURQeHkgYWRkcmVzcyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgYWRkcmVzcyBvZiB5b3VyIFVEUHh5IHNlcnZlci4gSWYgc2V0LCBhbmQgdGhlIGNoYW5uZWwgVVJMcyBpbiB0aGUgbTN1IGlzIG11bHRpY2FzdCwgeFRlVmUgd2lsbCByZXdyaXRlIGl0IHNvIHRoYXQgaXQgaXMgYWNjZXNzZWQgdmlhIHRoZSBVRFB4eSBzZXJ2aWNlLiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJob3N0OnBvcnQiCiAgICB9LAogICAgImZmbXBlZ1BhdGgiOgogICAgewogICAgICAidGl0bGUiOiAiRkZtcGVnIEJpbmFyeSBQYXRoIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBhdGggdG8gRkZtcGVnIGJpbmFyeS4iLAogICAgICAicGxhY2Vob2xkZXIiOiAiL3BhdGgvdG8vZmZtcGVnIgogICAgfSwKICAgICJmZm1wZWdPcHRpb25zIjoKICAgIHsKICAgICAgInRpdGxlIjogIkZGbXBlZyBPcHRpb25zIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkZGbXBlZyBvcHRpb25zLjxicj5Pbmx5IGNoYW5nZSBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuPGJyPkxlYXZlIGJsYW5rIHRvIHNldCBkZWZhdWx0IHNldHRpbmdzLiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJMZWF2ZSBibGFuayB0byBzZXQgZGVmYXVsdCBzZXR0aW5ncyIKICAgIH0sCiAgICAidmxjUGF0aCI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJWTEMgLyBDVkxDIEJpbmFyeSBQYXRoIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBhdGggdG8gVkxDIC8gQ1ZMQyBiaW5hcnkuIiwKICAgICAgInBsYWNlaG9sZGVyIjogIi9wYXRoL3RvL2N2bGMiCiAgICB9LAogICAgInZsY09wdGlvbnMiOgogICAgewogICAgICAidGl0bGUiOiAiVkxDIC8gQ1ZMQyBPcHRpb25zIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlZMQyAvIENWTEMgb3B0aW9ucy48YnI+T25seSBjaGFuZ2UgaWYgeW91IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nLjxicj5MZWF2ZSBibGFuayB0byBzZXQgZGVmYXVsdCBzZXR0aW5ncy4iLAogICAgICAicGxhY2Vob2xkZXIiOiAiTGVhdmUgYmxhbmsgdG8gc2V0IGRlZmF1bHQgc2V0dGluZ3MiCiAgICB9LAogICAgImJ1ZmZlclNpemUiOgogICAgewogICAgICAidGl0bGUiOiAiQnVmZmVyIFNpemUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiQnVmZmVyIHNpemUgaW4gTUIuPGJyPk0zVTg6IElmIHRoZSBUUyBzZWdtZW50IHNtYWxsZXIgdGhlbiB0aGUgYnVmZmVyIHNpemUsIHRoZSBmaWxlIHNpemUgb2YgdGhlIHNlZ21lbnQgaXMgdXNlZC4iCiAgICB9LAogICAgImJ1ZmZlclRpbWVvdXQiOgogICAgewogICAgICAidGl0bGUiOiAiVGltZW91dCBmb3IgbmV3IGNsaWVudCBjb25uZWN0aW9ucyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgeFRlVmUgYnVmZmVyIHdhaXRzIHVudGlsIG5ldyBjbGllbnQgY29ubmVjdGlvbnMgYXJlIGVzdGFibGlzaGVkLiBIZWxwZnVsIGZvciBmYXN0IGNoYW5uZWwgc3dpdGNoaW5nLiBWYWx1ZSBpbiBtaWxsaXNlY29uZHMuIiwKICAgICAgInBsYWNlaG9sZGVyIjogIjEwMCIKICAgIH0sCiAgICAidXNlckFnZW50IjoKICAgIHsKICAgICAgInRpdGxlIjogIlVzZXIgQWdlbnQiLAogICAgICAiZGVzY3JpcHRpb24iOiAiVXNlciBBZ2VudCBmb3IgSFRUUCByZXF1ZXN0cy4gRm9yIGV2ZXJ5IEhUVFAgY29ubmVjdGlvbiwgdGhpcyB2YWx1ZSBpcyB1c2VkIGZvciB0aGUgdXNlciBhZ2VudC4gU2hvdWxkIG9ubHkgYmUgY2hhbmdlZCBpZiB4VGVWZSBpcyBibG9ja2VkLiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJ4VGVWZSIKICAgIH0sCiAgICAiYmFja3VwUGF0aCI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJMb2NhdGlvbiBmb3IgYXV0b21hdGljIGJhY2t1cHMiLAogICAgICAicGxhY2Vob2xkZXIiOiAiL21udC9kYXRhL2JhY2t1cC94dGV2ZS8iLAogICAgICAiZGVzY3JpcHRpb24iOiAiQmVmb3JlIGFueSB1cGRhdGUgb2YgdGhlIHByb3ZpZGVyIGRhdGEgYnkgdGhlIHNjaGVkdWxlLCB4VGVWZSBjcmVhdGVzIGEgYmFja3VwLiBUaGUgcGF0aCBmb3IgdGhlIGF1dG9tYXRpYyBiYWNrdXBzIGNhbiBiZSBjaGFuZ2VkLiB4VGVWZSByZXF1aXJlcyB3cml0ZSBwZXJtaXNzaW9uIGZvciB0aGlzIGZvbGRlci4iCiAgICB9LAogICAgInRlbXBQYXRoIjoKICAgIHsKICAgICAgInRpdGxlIjogIkxvY2F0aW9uIGZvciB0aGUgdGVtcG9yYXJ5IGZpbGVzIiwKICAgICAgInBsYWNlaG9sZGVyIjogIi90bXAveHRldmUvIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkxvY2F0aW9uIGZvciB0aGUgYnVmZmVyIGZpbGVzLiIKICAgIH0sCiAgICAiYmFja3VwS2VlcCI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJOdW1iZXIgb2YgYmFja3VwcyB0byBrZWVwIiwKICAgICAgImRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBiYWNrdXBzIHRvIGtlZXAuIE9sZGVyIGJhY2t1cHMgYXJlIGF1dG9tYXRpY2FsbHkgZGVsZXRlZC4iCiAgICB9LAogICAgImF1dGhlbnRpY2F0aW9uV0VCIjoKICAgIHsKICAgICAgInRpdGxlIjogIldFQiBBdXRoZW50aWNhdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJBY2Nlc3MgdG8gdGhlIHdlYiBpbnRlcmZhY2Ugb25seSBwb3NzaWJsZSB3aXRoIGNyZWRlbnRpYWxzLiIKICAgIH0sCiAgICAiYXV0aGVudGljYXRpb25QTVMiOgogICAgewogICAgICAidGl0bGUiOiAiUE1TIEF1dGhlbnRpY2F0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBsZXggcmVxdWVzdHMgYXJlIG9ubHkgcG9zc2libGUgd2l0aCBhdXRoZW50aWNhdGlvbi4gPGJyPjxiPldhcm5pbmchISE8L2I+IEFmdGVyIGFjdGl2YXRpbmcgdGhpcyBmdW5jdGlvbiB4VGVWZSBtdXN0IGJlIGRlbGV0ZSBpbiB0aGUgUE1TIERWUiBzZXR0aW5ncyBhbmQgc2V0IHVwIGFnYWluLiIKICAgIH0sCiAgICAiYXV0aGVudGljYXRpb25NM1UiOgogICAgewogICAgICAidGl0bGUiOiAiTTNVIEF1dGhlbnRpY2F0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkRvd25sb2FkaW5nIHRoZSB4dGV2ZS5tM3UgZmlsZSB2aWEgYW4gSFRUUCByZXF1ZXN0IGlzIG9ubHkgcG9zc2libGUgd2l0aCBhdXRoZW50aWNhdGlvbi4iCiAgICB9LAogICAgImF1dGhlbnRpY2F0aW9uWE1MIjoKICAgIHsKICAgICAgInRpdGxlIjogIlhNTCBBdXRoZW50aWNhdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJEb3dubG9hZGluZyB0aGUgeHRldmUueG1sIGZpbGUgdmlhIGFuIEhUVFAgcmVxdWVzdCBpcyBvbmx5IHBvc3NpYmxlIHdpdGggYXV0aGVudGljYXRpb24iCiAgICB9LAogICAgImF1dGhlbnRpY2F0aW9uQVBJIjoKICAgIHsKICAgICAgInRpdGxlIjogIkFQSSBBdXRoZW50aWNhdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJBY2Nlc3MgdG8gdGhlIEFQSSBpbnRlcmZhY2UgaXMgb25seSBwb3NzaWJsZSB3aXRoIGF1dGhlbnRpY2F0aW9uLiIKICAgIH0KICB9LAogICJ3aXphcmQiOgogIHsKICAgICJlcGdTb3VyY2UiOgogICAgewogICAgICAidGl0bGUiOiAiRVBHIFNvdXJjZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJQTVM6PGJyPi0gVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5IDxicj48YnI+WEVQRzo8YnI+LSBVc2Ugb2Ygb25lIG9yIG1vcmUgWE1MVFYgZmlsZXM8YnI+LSBDaGFubmVsIG1hbmFnZW1lbnQ8YnI+LSBNM1UgLyBYTUxUViBleHBvcnQgKEhUVFAgbGluayBmb3IgSVBUViBhcHBzKSIKICAgIH0sCiAgICAidHVuZXIiOgogICAgewogICAgICAidGl0bGUiOiAiTnVtYmVyIG9mIHR1bmVycyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJOdW1iZXIgb2YgcGFyYWxsZWwgY29ubmVjdGlvbnMgdGhhdCBjYW4gYmUgZXN0YWJsaXNoZWQgdG8gdGhlIHByb3ZpZGVyLjxicj5BdmFpbGFibGUgZm9yOiBQbGV4LCBFbWJ5IChIREhSKSwgTTNVICh3aXRoIGFjdGl2ZSBidWZmZXIpLjxicj5BZnRlciBhIGNoYW5nZSwgeFRlVmUgbXVzdCBiZSBkZWxldGUgaW4gdGhlIFBsZXggLyBFbWJ5IERWUiBzZXR0aW5ncyBhbmQgc2V0IHVwIGFnYWluLiIKICAgIH0sCiAgICAibTN1IjoKICAgIHsKICAgICAgInRpdGxlIjogIk0zVSBQbGF5bGlzdCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWxlIHBhdGggb3IgVVJMIG9mIHRoZSBNM1UiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTG9jYWwgb3IgcmVtb3RlIHBsYXlsaXN0cyIKICAgIH0sCiAgICAieG1sdHYiOgogICAgewogICAgICAidGl0bGUiOiAiWE1MVFYgRmlsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWxlIHBhdGggb3IgVVJMIG9mIHRoZSBYTUxUViIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJMb2NhbCBvciByZW1vdGUgWE1MVFYgZmlsZSIKICAgIH0KICB9LAogICJsb2dpbiI6CiAgewogICAgImZhaWxlZCI6ICJVc2VyIGF1dGhlbnRpY2F0aW9uIGZhaWxlZCIsCiAgICAiaGVhZGxpbmUiOiAiTG9naW4iLAogICAgInVzZXJuYW1lIjoKICAgIHsKICAgICAgInRpdGxlIjogIlVzZXJuYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlVzZXJuYW1lIgogICAgfSwKICAgICJwYXNzd29yZCI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJQYXNzd29yZCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJQYXNzd29yZCIKICAgIH0KICB9LAogICJhY2NvdW50IjoKICB7CiAgICAiZmFpbGVkIjogIlBhc3N3b3JkIGRvZXMgbm90IG1hdGNoIiwKICAgICJoZWFkbGluZSI6ICJDcmVhdGUgdXNlciBhY2NvdW50IiwKICAgICJ1c2VybmFtZSI6CiAgICB7CiAgICAgICJ0aXRsZSI6ICJVc2VybmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJVc2VybmFtZSIKICAgIH0sCiAgICAicGFzc3dvcmQiOgogICAgewogICAgICAidGl0bGUiOiAiUGFzc3dvcmQiLAogICAgICAicGxhY2Vob2xkZXIiOiAiUGFzc3dvcmQiCiAgICB9LAogICAgImNvbmZpcm0iOgogICAgewogICAgICAidGl0bGUiOiAiQ29uZmlybSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJDb25maXJtIgogICAgfQogIH0KfQ=="
+ webUI["html/index.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImNzcy9iYXNlLmNzcyIgdHlwZT0idGV4dC9jc3MiPgoKICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL21lbnVfdHMuanMiPjwvc2NyaXB0PgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9zZXR0aW5nc190cy5qcyI+PC9zY3JpcHQ+CiAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2xvZ3NfdHMuanMiPjwvc2NyaXB0PgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9iYXNlX3RzLmpzIj48L3NjcmlwdD4KCjwvaGVhZD4KCjxib2R5IG9ubG9hZD0iamF2YXNjcmlwdDogUGFnZVJlYWR5KCk7Ij4KCiAgPGRpdiBpZD0ibG9hZGluZyIgY2xhc3M9Im5vbmUiPgogICAgPGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj4KICA8L2Rpdj4KCiAgPGRpdiBpZD0icG9wdXAiIGNsYXNzPSJub25lIj4KICAgIDxkaXYgaWQ9InBvcHVwLWN1c3RvbSI+PC9kaXY+CiAgPC9kaXY+CgogIDxkaXYgaWQ9ImxheW91dCI+CgogICAgPCEtLQogICAgICAgIDxkaXYgaWQ9Im5vdGlmaWNhdGlvbiI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJlbGVtZW50Ij4KICAgICAgICAgICAgPGg1PlhFUEc8L2g1PgogICAgICAgICAgICA8cHJlPjExLjA1LjIwMTkgLSAyMDoyMTwvcHJlPgogICAgICAgICAgICA8aHI+CiAgICAgICAgICAgIDxwPkhhbGxvIGRhcyBpc3QgZWluIFRlc3QuIFVuZCBub2NoIG1laHIgVGV4dC48L3A+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgLS0+CgogICAgPGRpdiBpZD0ibWVudS13cmFwcGVyIiBjbGFzcz0ibGF5b3V0LWxlZnQiPgogICAgICA8ZGl2IGlkPSJicmFuY2giPjwvZGl2PgogICAgICA8ZGl2IGlkPSJsb2dvIj48L2Rpdj4KICAgICAgPG5hdiBpZD0ibWFpbi1tZW51Ij48L25hdj4KICAgIDwvZGl2PgoKICAgIDxkaXYgY2xhc3M9ImxheW91dC1yaWdodCI+CgogICAgICA8dGFibGUgaWQ9ImNsaWVudEluZm8iIGNsYXNzPSIiPgoKICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij54VGVWZTo8L3RkPgogICAgICAgICAgPHRkIGlkPSJ2ZXJzaW9uIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5PUzo8L3RkPgogICAgICAgICAgPHRkIGlkPSJvcyIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSBwaG9uZSI+RFZSIElQOjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9IkRWUiIgY2xhc3M9InRkVmFsTGluayBwaG9uZSI+Jm5ic3A7PC90ZD4KICAgICAgICA8L3RyPgoKICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5VVUlEOjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9InV1aWQiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkFyY2g6PC90ZD4KICAgICAgICAgIDx0ZCBpZD0iYXJjaCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSBwaG9uZSI+TTNVIFVSTDo8L3RkPgogICAgICAgICAgPHRkIGlkPSJtM3UtdXJsIiBjbGFzcz0idGRWYWxMaW5rIHBob25lIj4mbmJzcDs8L3RkPgogICAgICAgIDwvdHI+CgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkF2YWlsYWJsZSBTdHJlYW1zOjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkVQRyBTb3VyY2U6PC90ZD4KICAgICAgICAgIDx0ZCBpZD0iZXBnU291cmNlIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5IHBob25lIj5YRVBHIFVSTDo8L3RkPgogICAgICAgICAgPHRkIGlkPSJ4ZXBnLXVybCIgY2xhc3M9InRkVmFsTGluayBwaG9uZSI+Jm5ic3A7PC90ZD4KICAgICAgICA8L3RyPgoKICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5YRVBHIENoYW5uZWxzOjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9InhlcGciIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPkVycm9yczo8L3RkPgogICAgICAgICAgPHRkIGlkPSJlcnJvcnMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgIDx0ZCBjbGFzcz0idGRLZXkiPldhcm5pbmdzOjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9Indhcm5pbmdzIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgPC90cj4KCiAgICAgIDwvdGFibGU+CgogICAgICA8ZGl2IGlkPSJteVN0cmVhbXNCb3giIGNsYXNzPSJub3RWaXNpYmxlIj4KCiAgICAgICAgPGRpdiBpZD0iYWxsU3RyZWFtcyI+CiAgICAgICAgICA8dGFibGUgaWQ9ImFjdGl2ZVN0cmVhbXMiPjwvdGFibGU+CiAgICAgICAgICA8dGFibGUgaWQ9ImluYWN0aXZlU3RyZWFtcyI+PC90YWJsZT4KICAgICAgICA8L2Rpdj4KCiAgICAgIDwvZGl2PgoKICAgICAgPGRpdiBpZD0iY29udGVudCIgY2xhc3M9IiI+PC9kaXY+CgogICAgPC9kaXY+CgogIDwvZGl2PgoKPC9ib2R5PgoKPC9odG1sPg=="
+ webUI["html/js/authentication_ts.js"] = "ZnVuY3Rpb24gbG9naW4oKSB7CiAgICB2YXIgZXJyID0gZmFsc2U7CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudCIpOwogICAgdmFyIGZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYXV0aGVudGljYXRpb24iKTsKICAgIHZhciBpbnB1dHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIik7CiAgICBmb3IgKHZhciBpID0gaW5wdXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgdmFyIGtleSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgIHZhciB2YWx1ZSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgaW5wdXRzW2ldLnN0eWxlLmJvcmRlckNvbG9yID0gInJlZCI7CiAgICAgICAgICAgIGVyciA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGRhdGFba2V5XSA9IHZhbHVlOwogICAgfQogICAgaWYgKGVyciA9PSB0cnVlKSB7CiAgICAgICAgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoZGF0YS5oYXNPd25Qcm9wZXJ0eSgiY29uZmlybSIpKSB7CiAgICAgICAgaWYgKGRhdGFbImNvbmZpcm0iXSAhPSBkYXRhWyJwYXNzd29yZCJdKSB7CiAgICAgICAgICAgIGFsZXJ0KCJzZGFmc2QiKTsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3N3b3JkJykuc3R5bGUuYm9yZGVyQ29sb3IgPSAicmVkIjsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbmZpcm0nKS5zdHlsZS5ib3JkZXJDb2xvciA9ICJyZWQiOwogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZXJyIikuaW5uZXJIVE1MID0gInt7LmFjY291bnQuZmFpbGVkfX0iOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgZm9ybS5zdWJtaXQoKTsKfQo="
+ webUI["html/js/base_ts.js"] = "dmFyIFNFUlZFUiA9IG5ldyBPYmplY3QoKTsKdmFyIEJVTEtfRURJVCA9IGZhbHNlOwp2YXIgQ09MVU1OX1RPX1NPUlQ7CnZhciBTRUFSQ0hfTUFQUElORyA9IG5ldyBPYmplY3QoKTsKdmFyIFVORE8gPSBuZXcgT2JqZWN0KCk7CnZhciBTRVJWRVJfQ09OTkVDVElPTiA9IGZhbHNlOwp2YXIgV1NfQVZBSUxBQkxFID0gZmFsc2U7Ci8vIE1lbnUKdmFyIG1lbnVJdGVtcyA9IG5ldyBBcnJheSgpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJwbGF5bGlzdCIsICJ7ey5tYWluTWVudS5pdGVtLnBsYXlsaXN0fX0iLCAibTN1LnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5wbGF5bGlzdH19IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJmaWx0ZXIiLCAie3subWFpbk1lbnUuaXRlbS5maWx0ZXJ9fSIsICJmaWx0ZXIucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLmZpbHRlcn19IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJ4bWx0diIsICJ7ey5tYWluTWVudS5pdGVtLnhtbHR2fX0iLCAieG1sdHYucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLnhtbHR2fX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oIm1hcHBpbmciLCAie3subWFpbk1lbnUuaXRlbS5tYXBwaW5nfX0iLCAibWFwcGluZy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUubWFwcGluZ319IikpOwptZW51SXRlbXMucHVzaChuZXcgTWFpbk1lbnVJdGVtKCJ1c2VycyIsICJ7ey5tYWluTWVudS5pdGVtLnVzZXJzfX0iLCAidXNlcnMucG5nIiwgInt7Lm1haW5NZW51LmhlYWRsaW5lLnVzZXJzfX0iKSk7Cm1lbnVJdGVtcy5wdXNoKG5ldyBNYWluTWVudUl0ZW0oInNldHRpbmdzIiwgInt7Lm1haW5NZW51Lml0ZW0uc2V0dGluZ3N9fSIsICJzZXR0aW5ncy5wbmciLCAie3subWFpbk1lbnUuaGVhZGxpbmUuc2V0dGluZ3N9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibG9nIiwgInt7Lm1haW5NZW51Lml0ZW0ubG9nfX0iLCAibG9nLnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5sb2d9fSIpKTsKbWVudUl0ZW1zLnB1c2gobmV3IE1haW5NZW51SXRlbSgibG9nb3V0IiwgInt7Lm1haW5NZW51Lml0ZW0ubG9nb3V0fX0iLCAibG9nb3V0LnBuZyIsICJ7ey5tYWluTWVudS5oZWFkbGluZS5sb2dvdXR9fSIpKTsKLy8gU2V0dGluZ3MgY2F0ZWdvcmllcwp2YXIgc2V0dGluZ3NDYXRlZ29yeSA9IG5ldyBBcnJheSgpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5nZW5lcmFsfX0iLCAidGxzTW9kZSx4dGV2ZUF1dG9VcGRhdGUsaG9zdElQLGhvc3ROYW1lLHR1bmVyLGVwZ1NvdXJjZSxkaXNhbGxvd1VSTER1cGxpY2F0ZXMsY2xlYXJYTUxUVkNhY2hlLGFwaSIpKTsKc2V0dGluZ3NDYXRlZ29yeS5wdXNoKG5ldyBTZXR0aW5nc0NhdGVnb3J5SXRlbSgie3suc2V0dGluZ3MuY2F0ZWdvcnkubWFwcGluZ319IiwgImRlZmF1bHRNaXNzaW5nRVBHLGVuYWJsZU1hcHBlZENoYW5uZWxzIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5maWxlc319IiwgInVwZGF0ZSxmaWxlcy51cGRhdGUsdGVtcC5wYXRoLGNhY2hlLmltYWdlcyx4ZXBnLnJlcGxhY2UubWlzc2luZy5pbWFnZXMiKSk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LnN0cmVhbWluZ319IiwgImJ1ZmZlcix1ZHB4eSxidWZmZXIuc2l6ZS5rYixzdG9yZUJ1ZmZlckluUkFNLGJ1ZmZlci50aW1lb3V0LHVzZXIuYWdlbnQsZmZtcGVnLnBhdGgsZmZtcGVnLm9wdGlvbnMsdmxjLnBhdGgsdmxjLm9wdGlvbnMiKSk7CnNldHRpbmdzQ2F0ZWdvcnkucHVzaChuZXcgU2V0dGluZ3NDYXRlZ29yeUl0ZW0oInt7LnNldHRpbmdzLmNhdGVnb3J5LmJhY2t1cH19IiwgImJhY2t1cC5wYXRoLGJhY2t1cC5rZWVwIikpOwpzZXR0aW5nc0NhdGVnb3J5LnB1c2gobmV3IFNldHRpbmdzQ2F0ZWdvcnlJdGVtKCJ7ey5zZXR0aW5ncy5jYXRlZ29yeS5hdXRoZW50aWNhdGlvbn19IiwgImF1dGhlbnRpY2F0aW9uLndlYixhdXRoZW50aWNhdGlvbi5wbXMsYXV0aGVudGljYXRpb24ubTN1LGF1dGhlbnRpY2F0aW9uLnhtbCxhdXRoZW50aWNhdGlvbi5hcGkiKSk7CmZ1bmN0aW9uIHNob3dQb3BVcEVsZW1lbnQoZWxtKSB7CiAgICB2YXIgYWxsRWxlbWVudHMgPSBuZXcgQXJyYXkoInBvcHVwLWN1c3RvbSIpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGxFbGVtZW50cy5sZW5ndGg7IGkrKykgewogICAgICAgIHNob3dFbGVtZW50KGFsbEVsZW1lbnRzW2ldLCBmYWxzZSk7CiAgICB9CiAgICBzaG93RWxlbWVudChlbG0sIHRydWUpOwogICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgc2hvd0VsZW1lbnQoInBvcHVwIiwgdHJ1ZSk7CiAgICB9LCAxMCk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc2hvd0VsZW1lbnQoZWxtSUQsIHR5cGUpIHsKICAgIHZhciBjc3NDbGFzczsKICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgY3NzQ2xhc3MgPSAiYmxvY2siOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICBjc3NDbGFzcyA9ICJub25lIjsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbG1JRCkuY2xhc3NOYW1lID0gY3NzQ2xhc3M7Cn0KZnVuY3Rpb24gY2hhbmdlQnV0dG9uQWN0aW9uKGVsZW1lbnQsIGJ1dHRvbklELCBhdHRyaWJ1dGUpIHsKICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQub3B0aW9uc1tlbGVtZW50LnNlbGVjdGVkSW5kZXhdLnZhbHVlOwogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uSUQpLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIHZhbHVlKTsKfQpmdW5jdGlvbiBnZXRMb2NhbERhdGEoZGF0YVR5cGUsIGlkKSB7CiAgICBsZXQgZGF0YSA9IHt9OwogICAgc3dpdGNoIChkYXRhVHlwZSkgewogICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbGVzIl1bZGF0YVR5cGVdW2lkXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAiaGRociI6CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbGVzIl1bZGF0YVR5cGVdW2lkXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAiZmlsdGVyIjoKICAgICAgICBjYXNlICJjdXN0b20tZmlsdGVyIjoKICAgICAgICBjYXNlICJncm91cC10aXRsZSI6CiAgICAgICAgICAgIGlmIChpZCA9PSAtMSkgewogICAgICAgICAgICAgICAgZGF0YVsiYWN0aXZlIl0gPSB0cnVlOwogICAgICAgICAgICAgICAgZGF0YVsiY2FzZVNlbnNpdGl2ZSJdID0gZmFsc2U7CiAgICAgICAgICAgICAgICBkYXRhWyJkZXNjcmlwdGlvbiJdID0gIiI7CiAgICAgICAgICAgICAgICBkYXRhWyJleGNsdWRlIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbImZpbHRlciJdID0gIiI7CiAgICAgICAgICAgICAgICBkYXRhWyJpbmNsdWRlIl0gPSAiIjsKICAgICAgICAgICAgICAgIGRhdGFbIm5hbWUiXSA9ICIiOwogICAgICAgICAgICAgICAgZGF0YVsidHlwZSJdID0gImdyb3VwLXRpdGxlIjsKICAgICAgICAgICAgICAgIGRhdGFbInByZXNlcnZlTWFwcGluZyJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGRhdGFbInN0YXJ0aW5nQ2hhbm5lbCJdID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJtYXBwaW5nLmZpcnN0LmNoYW5uZWwiXTsKICAgICAgICAgICAgICAgIFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsdGVyIl1baWRdID0gZGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWx0ZXIiXVtpZF07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJ1c2VycyI6CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbInVzZXJzIl1baWRdWyJkYXRhIl07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm1hcHBpbmciOgogICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJ4ZXBnIl1bImVwZ01hcHBpbmciXVtpZF07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm0zdUdyb3VwcyI6CiAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbImRhdGEiXVsicGxheWxpc3QiXVsibTN1Il1bImdyb3VwcyJdOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBkYXRhOwp9CmZ1bmN0aW9uIGdldE93bk9ialByb3BzKG9iamVjdCkgewogICAgcmV0dXJuIG9iamVjdCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iamVjdCkgOiBbXTsKfQpmdW5jdGlvbiBnZXRBbGxTZWxlY3RlZENoYW5uZWxzKCkgewogICAgdmFyIGNoYW5uZWxzID0gbmV3IEFycmF5KCk7CiAgICBpZiAoQlVMS19FRElUID09IGZhbHNlKSB7CiAgICAgICAgcmV0dXJuIGNoYW5uZWxzOwogICAgfQogICAgdmFyIHRycyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X3RhYmxlIikuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRSIik7CiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHRycy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmICh0cnNbaV0uc3R5bGUuZGlzcGxheSAhPSAibm9uZSIpIHsKICAgICAgICAgICAgaWYgKHRyc1tpXS5maXJzdENoaWxkLmZpcnN0Q2hpbGQuY2hlY2tlZCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICBjaGFubmVscy5wdXNoKHRyc1tpXS5pZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gY2hhbm5lbHM7Cn0KZnVuY3Rpb24gc2VsZWN0QWxsQ2hhbm5lbHMoKSB7CiAgICB2YXIgYnVsayA9IGZhbHNlOwogICAgdmFyIHRycyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X3RhYmxlIikuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRSIik7CiAgICBpZiAodHJzWzBdLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZC5jaGVja2VkID09IHRydWUpIHsKICAgICAgICBidWxrID0gdHJ1ZTsKICAgIH0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgdHJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKHRyc1tpXS5zdHlsZS5kaXNwbGF5ICE9ICJub25lIikgewogICAgICAgICAgICBzd2l0Y2ggKGJ1bGspIHsKICAgICAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgICAgICB0cnNbaV0uZmlyc3RDaGlsZC5maXJzdENoaWxkLmNoZWNrZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgICAgICAgICB0cnNbaV0uZmlyc3RDaGlsZC5maXJzdENoaWxkLmNoZWNrZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBidWxrRWRpdCgpIHsKICAgIEJVTEtfRURJVCA9ICFCVUxLX0VESVQ7CiAgICB2YXIgY2xhc3NOYW1lOwogICAgdmFyIHJvd3MgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJidWxrIik7CiAgICBzd2l0Y2ggKEJVTEtfRURJVCkgewogICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgY2xhc3NOYW1lID0gImJ1bGsgc2hvd0J1bGsiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICBjbGFzc05hbWUgPSAiYnVsayBoaWRlQnVsayI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgcm93c1tpXS5jbGFzc05hbWUgPSBjbGFzc05hbWU7CiAgICAgICAgcm93c1tpXS5jaGVja2VkID0gZmFsc2U7CiAgICB9CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc29ydFRhYmxlKGNvbHVtbikgewogICAgaWYgKGNvbHVtbiA9PSBDT0xVTU5fVE9fU09SVCkgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfdGFibGUiKTsKICAgIGNvbnN0IHRhYmxlSGVhZCA9IHRhYmxlLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUUiIpWzBdOwogICAgY29uc3QgdGFibGVJdGVtcyA9IHRhYmxlSGVhZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiVEQiKTsKICAgIGNvbnN0IHNvcnRBcnIgPSBbXTsKICAgIGxldCB4VmFsdWU7CiAgICBpZiAoY29sdW1uID49IDAgJiYgQ09MVU1OX1RPX1NPUlQgPj0gMCkgewogICAgICAgIHRhYmxlSXRlbXNbQ09MVU1OX1RPX1NPUlRdLmNsYXNzTmFtZSA9ICJwb2ludGVyIjsKICAgICAgICB0YWJsZUl0ZW1zW2NvbHVtbl0uY2xhc3NOYW1lID0gInNvcnRUaGlzIjsKICAgIH0KICAgIENPTFVNTl9UT19TT1JUID0gY29sdW1uOwogICAgY29uc3Qgcm93cyA9IHRhYmxlLnJvd3M7CiAgICBpZiAocm93c1sxXSAhPSB1bmRlZmluZWQpIHsKICAgICAgICBjb25zdCB0YWJsZUhlYWRlciA9IHJvd3NbMF07CiAgICAgICAgbGV0IHggPSByb3dzWzFdLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJURCIpW2NvbHVtbl07CiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHggPSByb3dzW2ldLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJURCIpW2NvbHVtbl07CiAgICAgICAgICAgIHN3aXRjaCAoeC5jaGlsZE5vZGVzWzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAiaW5wdXQiOgogICAgICAgICAgICAgICAgICAgIHhWYWx1ZSA9IHguZ2V0RWxlbWVudHNCeVRhZ05hbWUoIklOUFVUIilbMF0udmFsdWUudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInAiOgogICAgICAgICAgICAgICAgICAgIHhWYWx1ZSA9IHguZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlAiKVswXS5pbm5lclRleHQudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc29ydEFyci5wdXNoKHsga2V5OiB4VmFsdWUgPyB4VmFsdWUgOiBpLCByb3c6IHJvd3NbaV0gfSk7CiAgICAgICAgfQogICAgICAgIHdoaWxlICh0YWJsZS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgIHRhYmxlLnJlbW92ZUNoaWxkKHRhYmxlLmZpcnN0Q2hpbGQpOwogICAgICAgIH0KICAgICAgICBzb3J0QXJyLnNvcnQoKHNlMSwgc2UyKSA9PiB7CiAgICAgICAgICAgIGNvbnN0IHNlMUtleU51bSA9IHBhcnNlRmxvYXQoU3RyaW5nKHNlMS5rZXkpKTsKICAgICAgICAgICAgY29uc3Qgc2UyS2V5TnVtID0gcGFyc2VGbG9hdChTdHJpbmcoc2UyLmtleSkpOwogICAgICAgICAgICBpZiAoIWlzTmFOKHNlMUtleU51bSkgJiYgIWlzTmFOKHNlMktleU51bSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzZTFLZXlOdW0gLSBzZTJLZXlOdW07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNlMS5rZXkgPCBzZTIua2V5KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNlMS5rZXkgPiBzZTIua2V5KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9KTsKICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZCh0YWJsZUhlYWRlcik7CiAgICAgICAgc29ydEFyci5mb3JFYWNoKChzZSkgPT4gewogICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChzZS5yb3cpOwogICAgICAgIH0pOwogICAgfQogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIGNyZWF0ZVNlYXJjaE9iaigpIHsKICAgIFNFQVJDSF9NQVBQSU5HID0gbmV3IE9iamVjdCgpOwogICAgdmFyIGRhdGEgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdOwogICAgdmFyIGNoYW5uZWxzID0gZ2V0T3duT2JqUHJvcHMoZGF0YSk7CiAgICB2YXIgY2hhbm5lbEtleXMgPSBbIngtYWN0aXZlIiwgIngtY2hhbm5lbElEIiwgIngtbmFtZSIsICJ1cGRhdGVDaGFubmVsTmFtZVJlZ2V4IiwgIl9maWxlLm0zdS5uYW1lIiwgIngtZ3JvdXAtdGl0bGUiLCAieC14bWx0di1maWxlIl07CiAgICBjaGFubmVscy5mb3JFYWNoKGlkID0+IHsKICAgICAgICBjaGFubmVsS2V5cy5mb3JFYWNoKGtleSA9PiB7CiAgICAgICAgICAgIGlmIChrZXkgPT0gIngtYWN0aXZlIikgewogICAgICAgICAgICAgICAgc3dpdGNoIChkYXRhW2lkXVtrZXldKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICAgICAgICAgICAgICBTRUFSQ0hfTUFQUElOR1tpZF0gPSAib25saW5lICI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIFNFQVJDSF9NQVBQSU5HW2lkXSA9ICJvZmZsaW5lICI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGtleSA9PSAieC14bWx0di1maWxlIikgewogICAgICAgICAgICAgICAgICAgIHZhciB4bWx0dkZpbGUgPSBnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZGF0YVtpZF1ba2V5XSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeG1sdHZGaWxlICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICBTRUFSQ0hfTUFQUElOR1tpZF0gPSBTRUFSQ0hfTUFQUElOR1tpZF0gKyB4bWx0dkZpbGUgKyAiICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgU0VBUkNIX01BUFBJTkdbaWRdID0gU0VBUkNIX01BUFBJTkdbaWRdICsgZGF0YVtpZF1ba2V5XSArICIgIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfSk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc2VhcmNoSW5NYXBwaW5nKCkgewogICAgdmFyIHNlYXJjaFZhbHVlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNlYXJjaE1hcHBpbmciKS52YWx1ZTsKICAgIHZhciB0cnMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY29udGVudF90YWJsZSIpLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUUiIpOwogICAgZm9yICh2YXIgaSA9IDE7IGkgPCB0cnMubGVuZ3RoOyArK2kpIHsKICAgICAgICB2YXIgaWQgPSB0cnNbaV0uZ2V0QXR0cmlidXRlKCJpZCIpOwogICAgICAgIHZhciBlbGVtZW50ID0gU0VBUkNIX01BUFBJTkdbaWRdOwogICAgICAgIHN3aXRjaCAoZWxlbWVudC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFZhbHVlLnRvTG93ZXJDYXNlKCkpKSB7CiAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKSB7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIikpIHsKICAgICAgICB2YXIgZWxtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgICAgICAgdmFyIGRpdnMgPSBuZXcgQXJyYXkoIm15U3RyZWFtc0JveCIsICJjbGllbnRJbmZvIiwgImNvbnRlbnQiKTsKICAgICAgICB2YXIgZWxlbWVudHNIZWlnaHQgPSAwIC0gZWxtLm9mZnNldEhlaWdodDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpdnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgZWxlbWVudHNIZWlnaHQgPSBlbGVtZW50c0hlaWdodCArIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRpdnNbaV0pLm9mZnNldEhlaWdodDsKICAgICAgICB9CiAgICAgICAgZWxtLnN0eWxlLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGVsZW1lbnRzSGVpZ2h0ICsgInB4IjsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBjaGFuZ2VDaGFubmVsTnVtYmVyKGVsZW1lbnQpIHsKICAgIHZhciBkYklEID0gZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUuaWQ7CiAgICB2YXIgbmV3TnVtYmVyID0gcGFyc2VGbG9hdChlbGVtZW50LnZhbHVlKTsKICAgIHZhciBjaGFubmVsTnVtYmVycyA9IFtdOwogICAgdmFyIGRhdGEgPSBTRVJWRVJbInhlcGciXVsiZXBnTWFwcGluZyJdOwogICAgdmFyIGNoYW5uZWxzID0gZ2V0T3duT2JqUHJvcHMoZGF0YSk7CiAgICBpZiAoaXNOYU4obmV3TnVtYmVyKSkgewogICAgICAgIGFsZXJ0KCJ7ey5hbGVydC5pbnZhbGlkQ2hhbm5lbE51bWJlcn19Iik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY2hhbm5lbHMuZm9yRWFjaChpZCA9PiB7CiAgICAgICAgdmFyIGNoYW5uZWxOdW1iZXIgPSBwYXJzZUZsb2F0KGRhdGFbaWRdWyJ4LWNoYW5uZWxJRCJdKTsKICAgICAgICBjaGFubmVsTnVtYmVycy5wdXNoKGNoYW5uZWxOdW1iZXIpOwogICAgfSk7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoYW5uZWxOdW1iZXJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgaWYgKGNoYW5uZWxOdW1iZXJzLmluZGV4T2YobmV3TnVtYmVyKSA9PSAtMSkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKE1hdGguZmxvb3IobmV3TnVtYmVyKSA9PSBuZXdOdW1iZXIpIHsKICAgICAgICAgICAgbmV3TnVtYmVyID0gbmV3TnVtYmVyICsgMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIG5ld051bWJlciA9IG5ld051bWJlciArIDAuMTsKICAgICAgICAgICAgbmV3TnVtYmVyLnRvRml4ZWQoMSk7CiAgICAgICAgICAgIG5ld051bWJlciA9IE1hdGgucm91bmQobmV3TnVtYmVyICogMTApIC8gMTA7CiAgICAgICAgfQogICAgfQogICAgZGF0YVtkYklEXVsieC1jaGFubmVsSUQiXSA9IG5ld051bWJlci50b1N0cmluZygpOwogICAgZWxlbWVudC52YWx1ZSA9IG5ld051bWJlcjsKICAgIGlmIChDT0xVTU5fVE9fU09SVCA9PSAxKSB7CiAgICAgICAgQ09MVU1OX1RPX1NPUlQgPSAtMTsKICAgICAgICBzb3J0VGFibGUoMSk7CiAgICB9CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gYmFja3VwKCkgewogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgY21kID0gInh0ZXZlQmFja3VwIjsKICAgIHZhciBzZXJ2ZXIgPSBuZXcgU2VydmVyKGNtZCk7CiAgICBzZXJ2ZXIucmVxdWVzdChkYXRhKTsKICAgIHJldHVybjsKfQpmdW5jdGlvbiB0b2dnbGVDaGFubmVsU3RhdHVzKGlkKSB7CiAgICB2YXIgZWxlbWVudDsKICAgIHZhciBzdGF0dXM7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImFjdGl2ZSIpKSB7CiAgICAgICAgdmFyIGNoZWNrYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImFjdGl2ZSIpOwogICAgICAgIHN0YXR1cyA9IChjaGVja2JveCkuY2hlY2tlZDsKICAgIH0KICAgIHZhciBpZHMgPSBnZXRBbGxTZWxlY3RlZENoYW5uZWxzKCk7CiAgICBpZiAoaWRzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgaWRzLnB1c2goaWQpOwogICAgfQogICAgaWRzLmZvckVhY2goaWQgPT4gewogICAgICAgIHZhciBjaGFubmVsID0gU0VSVkVSWyJ4ZXBnIl1bImVwZ01hcHBpbmciXVtpZF07CiAgICAgICAgY2hhbm5lbFsieC1hY3RpdmUiXSA9IHN0YXR1czsKICAgICAgICBzd2l0Y2ggKGNoYW5uZWxbIngtYWN0aXZlIl0pIHsKICAgICAgICAgICAgY2FzZSB0cnVlOgogICAgICAgICAgICAgICAgaWYgKGNoYW5uZWxbIngteG1sdHYtZmlsZSJdID09ICItIiB8fCBjaGFubmVsWyJ4LW1hcHBpbmciXSA9PSAiLSIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoQlVMS19FRElUID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KGNoYW5uZWxbIngtbmFtZSJdICsgIjogTWlzc2luZyBYTUxUViBmaWxlIC8gY2hhbm5lbCIpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja2JveC5jaGVja2VkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbIngtYWN0aXZlIl0gPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICAgICAgLy8gY29kZS4uLgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChjaGFubmVsWyJ4LWFjdGl2ZSJdID09IGZhbHNlKSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jbGFzc05hbWUgPSAibm90QWN0aXZlRVBHIjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jbGFzc05hbWUgPSAiYWN0aXZlRVBHIjsKICAgICAgICB9CiAgICB9KTsKfQpmdW5jdGlvbiB0b2dnbGVHcm91cFVwZGF0ZUNiKHhlcGdJZCwgdGFyZ2V0KSB7CiAgICB0YXJnZXQuY2xhc3NOYW1lID0gJ2NoYW5nZWQnOwogICAgY29uc3QgZ3JvdXBJbnB1dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9IngtZ3JvdXAtdGl0bGUiXScpOwogICAgY29uc3QgbWFwcGluZyA9IGdldExvY2FsRGF0YSgnbWFwcGluZycsIHhlcGdJZCk7CiAgICBpZiAodGFyZ2V0LmNoZWNrZWQpIHsKICAgICAgICBncm91cElucHV0LmRhdGFzZXQub2xkVmFsdWUgPSBncm91cElucHV0LnZhbHVlOwogICAgICAgIGdyb3VwSW5wdXQudmFsdWUgPSBtYXBwaW5nWydncm91cC10aXRsZSddOwogICAgICAgIGdyb3VwSW5wdXQuZGlzYWJsZWQgPSB0cnVlOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZ3JvdXBJbnB1dC52YWx1ZSA9IGdyb3VwSW5wdXQuZGF0YXNldC5vbGRWYWx1ZTsKICAgICAgICBncm91cElucHV0LmRpc2FibGVkID0gZmFsc2U7CiAgICB9CiAgICBncm91cElucHV0LmNsYXNzTmFtZSA9ICdjaGFuZ2VkJzsKfQpmdW5jdGlvbiByZXN0b3JlKCkgewogICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGxvYWQnKSkgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGxvYWQnKS5yZW1vdmUoKTsKICAgIH0KICAgIHZhciByZXN0b3JlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgIHJlc3RvcmUuc2V0QXR0cmlidXRlKCJ0eXBlIiwgImZpbGUiKTsKICAgIHJlc3RvcmUuc2V0QXR0cmlidXRlKCJjbGFzcyIsICJub3RWaXNpYmxlIik7CiAgICByZXN0b3JlLnNldEF0dHJpYnV0ZSgibmFtZSIsICIiKTsKICAgIHJlc3RvcmUuaWQgPSAidXBsb2FkIjsKICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQocmVzdG9yZSk7CiAgICByZXN0b3JlLmNsaWNrKCk7CiAgICByZXN0b3JlLm9uY2hhbmdlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBmaWxlbmFtZSA9IHJlc3RvcmUuZmlsZXNbMF0ubmFtZTsKICAgICAgICB2YXIgY2hlY2sgPSBjb25maXJtKCJGaWxlOiAiICsgZmlsZW5hbWUgKyAiXG57ey5jb25maXJtLnJlc3RvcmV9fSIpOwogICAgICAgIGlmIChjaGVjayA9PSB0cnVlKSB7CiAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOwogICAgICAgICAgICB2YXIgZmlsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9ZmlsZV0nKS5maWxlc1swXTsKICAgICAgICAgICAgaWYgKGZpbGUpIHsKICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpOwogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICB2YXIgY21kID0gInh0ZXZlUmVzdG9yZSI7CiAgICAgICAgICAgICAgICAgICAgZGF0YVsiYmFzZTY0Il0gPSByZWFkZXIucmVzdWx0OwogICAgICAgICAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSBuZXcgU2VydmVyKGNtZCk7CiAgICAgICAgICAgICAgICAgICAgc2VydmVyLnJlcXVlc3QoZGF0YSk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgYWxlcnQoIkZpbGUgY291bGQgbm90IGJlIGxvYWRlZCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3RvcmUucmVtb3ZlKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9OwogICAgcmV0dXJuOwp9CmZ1bmN0aW9uIHVwbG9hZExvZ28oKSB7CiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZCcpKSB7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZCcpLnJlbW92ZSgpOwogICAgfQogICAgdmFyIHVwbG9hZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklOUFVUIik7CiAgICB1cGxvYWQuc2V0QXR0cmlidXRlKCJ0eXBlIiwgImZpbGUiKTsKICAgIHVwbG9hZC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIm5vdFZpc2libGUiKTsKICAgIHVwbG9hZC5zZXRBdHRyaWJ1dGUoIm5hbWUiLCAiIik7CiAgICB1cGxvYWQuaWQgPSAidXBsb2FkIjsKICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodXBsb2FkKTsKICAgIHVwbG9hZC5jbGljaygpOwogICAgdXBsb2FkLm9uYmx1ciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBhbGVydCgpOwogICAgfTsKICAgIHVwbG9hZC5vbmNoYW5nZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZmlsZW5hbWUgPSB1cGxvYWQuZmlsZXNbMF0ubmFtZTsKICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgICB2YXIgZmlsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9ZmlsZV0nKS5maWxlc1swXTsKICAgICAgICBpZiAoZmlsZSkgewogICAgICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTsKICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgICAgICAgdmFyIGNtZCA9ICJ1cGxvYWRMb2dvIjsKICAgICAgICAgICAgICAgIGRhdGFbImJhc2U2NCJdID0gcmVhZGVyLnJlc3VsdDsKICAgICAgICAgICAgICAgIGRhdGFbImZpbGVuYW1lIl0gPSBmaWxlLm5hbWU7CiAgICAgICAgICAgICAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcihjbWQpOwogICAgICAgICAgICAgICAgc2VydmVyLnJlcXVlc3QoZGF0YSk7CiAgICAgICAgICAgICAgICB2YXIgdXBkYXRlTG9nbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGUtaWNvbicpOwogICAgICAgICAgICAgICAgdXBkYXRlTG9nby5jaGVja2VkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB1cGRhdGVMb2dvLmNsYXNzTmFtZSA9ICJjaGFuZ2VkIjsKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGFsZXJ0KCJGaWxlIGNvdWxkIG5vdCBiZSBsb2FkZWQiKTsKICAgICAgICB9CiAgICAgICAgdXBsb2FkLnJlbW92ZSgpOwogICAgICAgIHJldHVybjsKICAgIH07Cn0KZnVuY3Rpb24gY2hlY2tVbmRvKGtleSkgewogICAgc3dpdGNoIChrZXkpIHsKICAgICAgICBjYXNlICJlcGdNYXBwaW5nIjoKICAgICAgICAgICAgaWYgKFVORE8uaGFzT3duUHJvcGVydHkoa2V5KSkgewogICAgICAgICAgICAgICAgU0VSVkVSWyJ4ZXBnIl1ba2V5XSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoVU5ET1trZXldKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBVTkRPW2tleV0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KFNFUlZFUlsieGVwZyJdW2tleV0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiB1cGRhdGVMb2coKSB7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcigidXBkYXRlTG9nIik7CiAgICBzZXJ2ZXIucmVxdWVzdChuZXcgT2JqZWN0KCkpOwp9Cg=="
+ webUI["html/js/configuration_ts.js"] = "Y2xhc3MgV2l6YXJkQ2F0ZWdvcnkgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gImNvbnRlbnQiOwogICAgfQogICAgY3JlYXRlQ2F0ZWdvcnlIZWFkbGluZSh2YWx1ZSkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSDQiKTsKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQp9CmNsYXNzIFdpemFyZEl0ZW0gZXh0ZW5kcyBXaXphcmRDYXRlZ29yeSB7CiAgICBjb25zdHJ1Y3RvcihrZXksIGhlYWRsaW5lKSB7CiAgICAgICAgc3VwZXIoKTsKICAgICAgICB0aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgdGhpcy5rZXkgPSBrZXk7CiAgICB9CiAgICBjcmVhdGVXaXphcmQoKSB7CiAgICAgICAgdmFyIGhlYWRsaW5lID0gdGhpcy5jcmVhdGVDYXRlZ29yeUhlYWRsaW5lKHRoaXMuaGVhZGxpbmUpOwogICAgICAgIHZhciBrZXkgPSB0aGlzLmtleTsKICAgICAgICB2YXIgY29udGVudCA9IG5ldyBQb3B1cENvbnRlbnQoKTsKICAgICAgICB2YXIgZGVzY3JpcHRpb247CiAgICAgICAgdmFyIGRvYyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuRG9jdW1lbnRJRCk7CiAgICAgICAgZG9jLmlubmVySFRNTCA9ICIiOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChoZWFkbGluZSk7CiAgICAgICAgc3dpdGNoIChrZXkpIHsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IDEwMDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dC5wdXNoKGkpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIjEiLCBrZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBzZWxlY3QuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gInt7LndpemFyZC50dW5lci5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJlcGdTb3VyY2UiOgogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBbIlBNUyIsICJYRVBHIl07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gWyJQTVMiLCAiWEVQRyJdOwogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIlhFUEciLCBrZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAid2l6YXJkIik7CiAgICAgICAgICAgICAgICBzZWxlY3QuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gInt7LndpemFyZC5lcGdTb3VyY2UuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAibTN1IjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBrZXksICIiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sud2l6YXJkLm0zdS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIndpemFyZCIpOwogICAgICAgICAgICAgICAgaW5wdXQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLm0zdS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ4bWx0diI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0Iiwga2V5LCAiIik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LndpemFyZC54bWx0di5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImNsYXNzIiwgIndpemFyZCIpOwogICAgICAgICAgICAgICAgaW5wdXQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAie3sud2l6YXJkLnhtbHR2LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHByZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlBSRSIpOwogICAgICAgIHByZS5pbm5lckhUTUwgPSBkZXNjcmlwdGlvbjsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQocHJlKTsKICAgIH0KfQpmdW5jdGlvbiByZWFkeUZvckNvbmZpZ3VyYXRpb24od2l6YXJkKSB7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcigiZ2V0U2VydmVyQ29uZmlnIik7CiAgICBzZXJ2ZXIucmVxdWVzdChuZXcgT2JqZWN0KCkpOwogICAgc2hvd0VsZW1lbnQoImxvYWRpbmciLCBmYWxzZSk7CiAgICBjb25maWd1cmF0aW9uV2l6YXJkW3dpemFyZF0uY3JlYXRlV2l6YXJkKCk7Cn0KZnVuY3Rpb24gc2F2ZVdpemFyZCgpIHsKICAgIHZhciBjbWQgPSAic2F2ZVdpemFyZCI7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnQiKTsKICAgIHZhciBjb25maWcgPSBkaXYuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgid2l6YXJkIik7CiAgICB2YXIgd2l6YXJkID0gbmV3IE9iamVjdCgpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb25maWcubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgbmFtZTsKICAgICAgICB2YXIgdmFsdWU7CiAgICAgICAgc3dpdGNoIChjb25maWdbaV0udGFnTmFtZSkgewogICAgICAgICAgICBjYXNlICJTRUxFQ1QiOgogICAgICAgICAgICAgICAgbmFtZSA9IGNvbmZpZ1tpXS5uYW1lOwogICAgICAgICAgICAgICAgdmFsdWUgPSBjb25maWdbaV0udmFsdWU7CiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmFsdWUgaXMgYSBudW1iZXIsIHN0b3JlIGl0IGFzIGEgbnVtYmVyCiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgd2l6YXJkW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB3aXphcmRbbmFtZV0gPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiSU5QVVQiOgogICAgICAgICAgICAgICAgc3dpdGNoIChjb25maWdbaV0udHlwZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gY29uZmlnW2ldLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gY29uZmlnW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc2cgPSBuYW1lLnRvVXBwZXJDYXNlKCkgKyAiOiAiICsgInt7LmFsZXJ0Lm1pc3NpbmdJbnB1dH19IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KG1zZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBjb2RlLi4uCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICAgIGRhdGFbIndpemFyZCJdID0gd2l6YXJkOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9Ci8vIFdpemFyZAp2YXIgY29uZmlndXJhdGlvbldpemFyZCA9IG5ldyBBcnJheSgpOwpjb25maWd1cmF0aW9uV2l6YXJkLnB1c2gobmV3IFdpemFyZEl0ZW0oInR1bmVyIiwgInt7LndpemFyZC50dW5lci50aXRsZX19IikpOwpjb25maWd1cmF0aW9uV2l6YXJkLnB1c2gobmV3IFdpemFyZEl0ZW0oImVwZ1NvdXJjZSIsICJ7ey53aXphcmQuZXBnU291cmNlLnRpdGxlfX0iKSk7CmNvbmZpZ3VyYXRpb25XaXphcmQucHVzaChuZXcgV2l6YXJkSXRlbSgibTN1IiwgInt7LndpemFyZC5tM3UudGl0bGV9fSIpKTsKY29uZmlndXJhdGlvbldpemFyZC5wdXNoKG5ldyBXaXphcmRJdGVtKCJ4bWx0diIsICJ7ey53aXphcmQueG1sdHYudGl0bGV9fSIpKTsK"
+ webUI["html/js/logs_ts.js"] = "Y2xhc3MgTG9nIHsKICAgIGNyZWF0ZUxvZyhlbnRyeSkgewogICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUFJFIik7CiAgICAgICAgZW50cnkgPSBTdHJpbmcoZW50cnkpOwogICAgICAgIGlmIChlbnRyeS5pbmRleE9mKCJXQVJOSU5HIikgIT0gLTEpIHsKICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSAid2FybmluZ01zZyI7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeS5pbmRleE9mKCJFUlJPUiIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImVycm9yTXNnIjsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5LmluZGV4T2YoIkRFQlVHIikgIT0gLTEpIHsKICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSAiZGVidWdNc2ciOwogICAgICAgIH0KICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGVudHJ5OwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQp9CmZ1bmN0aW9uIHNob3dMb2dzKGJvdHRvbSkgewogICAgdmFyIGxvZyA9IG5ldyBMb2coKTsKICAgIHZhciBsb2dzID0gU0VSVkVSWyJsb2ciXVsibG9nIl07CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfbG9nIik7CiAgICBkaXYuaW5uZXJIVE1MID0gIiI7CiAgICB2YXIga2V5cyA9IGdldE93bk9ialByb3BzKGxvZ3MpOwogICAga2V5cy5mb3JFYWNoKGxvZ0lEID0+IHsKICAgICAgICB2YXIgZW50cnkgPSBsb2cuY3JlYXRlTG9nKGxvZ3NbbG9nSURdKTsKICAgICAgICBkaXYuYXBwZW5kKGVudHJ5KTsKICAgIH0pOwogICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgaWYgKGJvdHRvbSA9PSB0cnVlKSB7CiAgICAgICAgICAgIHZhciB3cmFwcGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImJveC13cmFwcGVyIik7CiAgICAgICAgICAgIHdyYXBwZXIuc2Nyb2xsVG9wID0gd3JhcHBlci5zY3JvbGxIZWlnaHQ7CiAgICAgICAgfQogICAgfSwgMTApOwp9CmZ1bmN0aW9uIHJlc2V0TG9ncygpIHsKICAgIHZhciBjbWQgPSAicmVzZXRMb2dzIjsKICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9Cg=="
+ webUI["html/js/menu_ts.js"] = "Y2xhc3MgTWFpbk1lbnUgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgICAgdGhpcy5Eb2N1bWVudElEID0gIm1haW4tbWVudSI7CiAgICAgICAgdGhpcy5IVE1MVGFnID0gIkxJIjsKICAgICAgICB0aGlzLkltYWdlUGF0aCA9ICJpbWcvIjsKICAgIH0KICAgIGNyZWF0ZUlNRyhzcmMpIHsKICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklNRyIpOwogICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCJzcmMiLCB0aGlzLkltYWdlUGF0aCArIHNyYyk7CiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoImFsdCIsIHNyYyk7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CiAgICBjcmVhdGVWYWx1ZSh2YWx1ZSkgewogICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9Cn0KY2xhc3MgTWFpbk1lbnVJdGVtIGV4dGVuZHMgTWFpbk1lbnUgewogICAgY29uc3RydWN0b3IobWVudUtleSwgdmFsdWUsIGltYWdlLCBoZWFkbGluZSkgewogICAgICAgIHN1cGVyKCk7CiAgICAgICAgdGhpcy5tZW51S2V5ID0gbWVudUtleTsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgdGhpcy5pbWdTcmMgPSBpbWFnZTsKICAgICAgICB0aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICB9CiAgICBjcmVhdGVJdGVtKCkgewogICAgICAgIGxldCBpdGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiTEkiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgib25jbGljayIsICJqYXZhc2NyaXB0OiBvcGVuVGhpc01lbnUodGhpcykiKTsKICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgiaWQiLCB0aGlzLmlkKTsKICAgICAgICBsZXQgaW1nID0gdGhpcy5jcmVhdGVJTUcodGhpcy5pbWdTcmMpOwogICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuY3JlYXRlVmFsdWUodGhpcy52YWx1ZSk7CiAgICAgICAgaXRlbS5hcHBlbmRDaGlsZChpbWcpOwogICAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQodmFsdWUpOwogICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChpdGVtKTsKICAgICAgICBzd2l0Y2ggKHRoaXMubWVudUtleSkgewogICAgICAgICAgICBjYXNlICJwbGF5bGlzdCI6CiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlSGVhZGVyID0gWyJ7ey5wbGF5bGlzdC50YWJsZS5wbGF5bGlzdH19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnR1bmVyfX0iLCAie3sucGxheWxpc3QudGFibGUubGFzdFVwZGF0ZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLmF2YWlsYWJpbGl0eX19ICUiLCAie3sucGxheWxpc3QudGFibGUudHlwZX19IiwgInt7LnBsYXlsaXN0LnRhYmxlLnN0cmVhbXN9fSIsICJ7ey5wbGF5bGlzdC50YWJsZS5ncm91cFRpdGxlfX0gJSIsICJ7ey5wbGF5bGlzdC50YWJsZS50dmdJRH19ICUiLCAie3sucGxheWxpc3QudGFibGUudW5pcXVlSUR9fSAlIl07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3sueG1sdHYudGFibGUuZ3VpZGV9fSIsICJ7ey54bWx0di50YWJsZS5sYXN0VXBkYXRlfX0iLCAie3sueG1sdHYudGFibGUuYXZhaWxhYmlsaXR5fX0gJSIsICJ7ey54bWx0di50YWJsZS5jaGFubmVsc319IiwgInt7LnhtbHR2LnRhYmxlLnByb2dyYW1zfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgdGhpcy50YWJsZUhlYWRlciA9IFsie3suZmlsdGVyLnRhYmxlLnN0YXJ0aW5nQ2hhbm5lbH19IiwgInt7LmZpbHRlci50YWJsZS5uYW1lfX0iLCAie3suZmlsdGVyLnRhYmxlLnR5cGV9fSIsICJ7ey5maWx0ZXIudGFibGUuZmlsdGVyfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1c2VycyI6CiAgICAgICAgICAgICAgICB0aGlzLnRhYmxlSGVhZGVyID0gWyJ7ey51c2Vycy50YWJsZS51c2VybmFtZX19IiwgInt7LnVzZXJzLnRhYmxlLnBhc3N3b3JkfX0iLCAie3sudXNlcnMudGFibGUud2VifX0iLCAie3sudXNlcnMudGFibGUucG1zfX0iLCAie3sudXNlcnMudGFibGUubTN1fX0iLCAie3sudXNlcnMudGFibGUueG1sfX0iLCAie3sudXNlcnMudGFibGUuYXBpfX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgICAgIHRoaXMudGFibGVIZWFkZXIgPSBbIkJVTEsiLCAie3subWFwcGluZy50YWJsZS5jaE5vfX0iLCAie3subWFwcGluZy50YWJsZS5sb2dvfX0iLCAie3subWFwcGluZy50YWJsZS5jaGFubmVsTmFtZX19IiwgInt7Lm1hcHBpbmcudGFibGUudXBkYXRlQ2hhbm5lbE5hbWVSZWdleH19IiwgInt7Lm1hcHBpbmcudGFibGUucGxheWxpc3R9fSIsICJ7ey5tYXBwaW5nLnRhYmxlLmdyb3VwVGl0bGV9fSIsICJ7ey5tYXBwaW5nLnRhYmxlLnhtbHR2RmlsZX19IiwgInt7Lm1hcHBpbmcudGFibGUueG1sdHZJRH19IiwgInt7Lm1hcHBpbmcudGFibGUudGltZXNoaWZ0fX0iXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KfQpjbGFzcyBDb250ZW50IHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJjb250ZW50IjsKICAgICAgICB0aGlzLlRhYmxlSUQgPSAiY29udGVudF90YWJsZSI7CiAgICAgICAgdGhpcy5oZWFkZXJDbGFzcyA9ICJjb250ZW50X3RhYmxlX2hlYWRlciI7CiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbklEID0gImNvbnRlbnQtaW50ZXJhY3Rpb24iOwogICAgfQogICAgY3JlYXRlSGVhZGxpbmUodmFsdWUpIHsKICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkgzIik7CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KICAgIGNyZWF0ZUhSKCkgewogICAgICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJIUiIpOwogICAgfQogICAgY3JlYXRlSW50ZXJhY3Rpb24oKSB7CiAgICAgICAgbGV0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTsKICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgiaWQiLCB0aGlzLmludGVyYWN0aW9uSUQpOwogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQogICAgY3JlYXRlRElWKCkgewogICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiRElWIik7CiAgICAgICAgZWxlbWVudC5pZCA9IHRoaXMuRGl2SUQ7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CiAgICBjcmVhdGVUQUJMRSgpIHsKICAgICAgICBsZXQgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRBQkxFIik7CiAgICAgICAgZWxlbWVudC5pZCA9IHRoaXMuVGFibGVJRDsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KICAgIGNyZWF0ZVRhYmxlUm93KCkgewogICAgICAgIGxldCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9IHRoaXMuaGVhZGVyQ2xhc3M7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CiAgICBjcmVhdGVUYWJsZUNvbnRlbnQobWVudUtleSkgewogICAgICAgIGxldCBkYXRhID0ge307CiAgICAgICAgbGV0IHJvd3MgPSBbXTsKICAgICAgICBsZXQgZmlsZVR5cGVzID0gW107CiAgICAgICAgc3dpdGNoIChtZW51S2V5KSB7CiAgICAgICAgICAgIGNhc2UgInBsYXlsaXN0IjoKICAgICAgICAgICAgICAgIGZpbGVUeXBlcyA9IFsibTN1IiwgImhkaHIiXTsKICAgICAgICAgICAgICAgIGZpbGVUeXBlcy5mb3JFYWNoKGZpbGVUeXBlID0+IHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWxlcyJdW2ZpbGVUeXBlXTsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE93bk9ialByb3BzKGRhdGEpOwogICAgICAgICAgICAgICAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgiJyArIGZpbGVUeXBlICsgJyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJuYW1lIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTRVJWRVJbInNldHRpbmdzIl1bImJ1ZmZlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsidHVuZXIiXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsibGFzdC51cGRhdGUiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsicHJvdmlkZXIuYXZhaWxhYmlsaXR5Il07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bInR5cGUiXS50b1VwcGVyQ2FzZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJjb21wYXRpYmlsaXR5Il1bInN0cmVhbXMiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsiY29tcGF0aWJpbGl0eSJdWyJncm91cC50aXRsZSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJjb21wYXRpYmlsaXR5Il1bInR2Zy5pZCJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJjb21wYXRpYmlsaXR5Il1bInN0cmVhbS5pZCJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvd3MucHVzaCh0cik7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgZGVsZXRlIFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsdGVyIl1bLTFdOwogICAgICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsdGVyIl07CiAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE93bk9ialByb3BzKGRhdGEpOwogICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAgICAgICAgICAgICB0ci5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCInICsgZGF0YVtrZXldWyJ0eXBlIl0gKyAnIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsic3RhcnRpbmdDaGFubmVsIl07CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJuYW1lIl07CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGFba2V5XVsidHlwZSJdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICJ7ey5maWx0ZXIuY3VzdG9tfX0iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImdyb3VwLXRpdGxlIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAie3suZmlsdGVyLmdyb3VwfX0iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJmaWx0ZXIiXTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgcm93cy5wdXNoKHRyKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIGZpbGVUeXBlcyA9IG5ldyBBcnJheSgieG1sdHYiKTsKICAgICAgICAgICAgICAgIGZpbGVUeXBlcy5mb3JFYWNoKGZpbGVUeXBlID0+IHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gU0VSVkVSWyJzZXR0aW5ncyJdWyJmaWxlcyJdW2ZpbGVUeXBlXTsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE93bk9ialByb3BzKGRhdGEpOwogICAgICAgICAgICAgICAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgiJyArIGZpbGVUeXBlICsgJyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJuYW1lIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bImxhc3QudXBkYXRlIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bInByb3ZpZGVyLmF2YWlsYWJpbGl0eSJdOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJjb21wYXRpYmlsaXR5Il1bInhtbHR2LmNoYW5uZWxzIl07CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bImNvbXBhdGliaWxpdHkiXVsieG1sdHYucHJvZ3JhbXMiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICByb3dzLnB1c2godHIpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidXNlcnMiOgogICAgICAgICAgICAgICAgZmlsZVR5cGVzID0gbmV3IEFycmF5KCJ1c2VycyIpOwogICAgICAgICAgICAgICAgZmlsZVR5cGVzLmZvckVhY2goZmlsZVR5cGUgPT4gewogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBTRVJWRVJbZmlsZVR5cGVdOwogICAgICAgICAgICAgICAgICAgIHZhciBrZXlzID0gZ2V0T3duT2JqUHJvcHMoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmlkID0ga2V5OwogICAgICAgICAgICAgICAgICAgICAgICB0ci5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCInICsgZmlsZVR5cGUgKyAnIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bImRhdGEiXVsidXNlcm5hbWUiXTsKICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICIqKioqKioiOwogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVtrZXldWyJkYXRhIl1bImF1dGhlbnRpY2F0aW9uLndlYiJdID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAi4pyTIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XVsiZGF0YSJdWyJhdXRoZW50aWNhdGlvbi5wbXMiXSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIuKckyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIi0iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhW2tleV1bImRhdGEiXVsiYXV0aGVudGljYXRpb24ubTN1Il0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICLinJMiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9ICItIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVtrZXldWyJkYXRhIl1bImF1dGhlbnRpY2F0aW9uLnhtbCJdID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAi4pyTIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XVsiZGF0YSJdWyJhdXRoZW50aWNhdGlvbi5hcGkiXSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIuKckyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gIi0iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcm93cy5wdXNoKHRyKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgIm1hcHBpbmciOgogICAgICAgICAgICAgICAgQlVMS19FRElUID0gZmFsc2U7CiAgICAgICAgICAgICAgICBjcmVhdGVTZWFyY2hPYmooKTsKICAgICAgICAgICAgICAgIGNoZWNrVW5kbygiZXBnTWFwcGluZyIpOwogICAgICAgICAgICAgICAgZGF0YSA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl07CiAgICAgICAgICAgICAgICB2YXIga2V5cyA9IGdldE93bk9ialByb3BzKGRhdGEpOwogICAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICAgICAgICAgICAgICB0ci5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGRhdGFba2V5XVsieC1hY3RpdmUiXSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIHRydWU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ci5jbGFzc05hbWUgPSAiYWN0aXZlRVBHIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIGZhbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHIuY2xhc3NOYW1lID0gIm5vdEFjdGl2ZUVQRyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gQnVsawogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJCVUxLIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQoY2VsbC5jcmVhdGVDZWxsKCkpOwogICAgICAgICAgICAgICAgICAgIC8vIENoYW5uZWwgbnVtYmVyCiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIklOUFVUQ0hBTk5FTCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGRhdGFba2V5XVsieC1jaGFubmVsSUQiXTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZChjZWxsLmNyZWF0ZUNlbGwoKSk7CiAgICAgICAgICAgICAgICAgICAgLy8gTG9nbwogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJJTUciOwogICAgICAgICAgICAgICAgICAgIGNlbGwuaW1hZ2VVUkwgPSBkYXRhW2tleV1bInR2Zy1sb2dvIl07CiAgICAgICAgICAgICAgICAgICAgdmFyIHRkID0gY2VsbC5jcmVhdGVDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgdGQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgibWFwcGluZyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgdGQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGQpOwogICAgICAgICAgICAgICAgICAgIC8vIENoYW5uZWwgbmFtZQogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNsYXNzTmFtZSA9IGRhdGFba2V5XVsieC1jYXRlZ29yeSJdOwogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bIngtbmFtZSJdOwogICAgICAgICAgICAgICAgICAgIHZhciB0ZCA9IGNlbGwuY3JlYXRlQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIHRkLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIm1hcHBpbmciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgIHRkLmlkID0ga2V5OwogICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKHRkKTsKICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgY2hhbm5lbCBuYW1lIHJlZ2V4CiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIlAiOwogICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bInVwZGF0ZS1jaGFubmVsLW5hbWUtcmVnZXgiXTsKICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gUGxheWxpc3QKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZShkYXRhW2tleV1bIl9maWxlLm0zdS5pZCJdLCAibTN1IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gR3JvdXAgKGdyb3VwLXRpdGxlKQogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJ4LWdyb3VwLXRpdGxlIl07CiAgICAgICAgICAgICAgICAgICAgdmFyIHRkID0gY2VsbC5jcmVhdGVDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgdGQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgibWFwcGluZyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgdGQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGQpOwogICAgICAgICAgICAgICAgICAgIC8vIFhNTFRWIGZpbGUKICAgICAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IG5ldyBDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFba2V5XVsieC14bWx0di1maWxlIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZGF0YVtrZXldWyJ4LXhtbHR2LWZpbGUiXSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudmFsdWUgPSBkYXRhW2tleV1bIngteG1sdHYtZmlsZSJdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgdGQgPSBjZWxsLmNyZWF0ZUNlbGwoKTsKICAgICAgICAgICAgICAgICAgICB0ZC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtYXBwaW5nIiwgdGhpcyknKTsKICAgICAgICAgICAgICAgICAgICB0ZC5pZCA9IGtleTsKICAgICAgICAgICAgICAgICAgICB0ci5hcHBlbmRDaGlsZCh0ZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gWE1MVFYgQ2hhbm5lbAogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBkYXRhW2tleV1bIngtbWFwcGluZyJdOwogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPiAyMCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGRhdGFba2V5XVsieC1tYXBwaW5nIl0uc3Vic3RyaW5nKDAsIDIwKSArICIuLi4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRkID0gY2VsbC5jcmVhdGVDZWxsKCk7CiAgICAgICAgICAgICAgICAgICAgdGQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgibWFwcGluZyIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICAgICAgdGQuaWQgPSBrZXk7CiAgICAgICAgICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGQpOwogICAgICAgICAgICAgICAgICAgIC8vIFRpbWVTaGlmdAogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjZWxsLmNoaWxkVHlwZSA9ICJQIjsKICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZGF0YVtrZXldWyJ4LXRpbWVzaGlmdCJdOwogICAgICAgICAgICAgICAgICAgIHZhciB0ZCA9IGNlbGwuY3JlYXRlQ2VsbCgpOwogICAgICAgICAgICAgICAgICAgIHRkLnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoIm1hcHBpbmciLCB0aGlzKScpOwogICAgICAgICAgICAgICAgICAgIHRkLmlkID0ga2V5OwogICAgICAgICAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKHRkKTsKICAgICAgICAgICAgICAgICAgICByb3dzLnB1c2godHIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAic2V0dGluZ3MiOgogICAgICAgICAgICAgICAgYWxlcnQoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiByb3dzOwogICAgfQp9CmNsYXNzIENlbGwgewogICAgY3JlYXRlQ2VsbCgpIHsKICAgICAgICBsZXQgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgIGlmICh0aGlzLmNoaWxkID09IHRydWUpIHsKICAgICAgICAgICAgdmFyIGVsZW1lbnQ7CiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5jaGlsZFR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgIlAiOgogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY2hpbGRUeXBlKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSB0aGlzLmNsYXNzTmFtZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIklOUFVUIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNoaWxkVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiSU5QVVRDSEFOTkVMIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2c2NyaXB0OiBjaGFuZ2VDaGFubmVsTnVtYmVyKHRoaXMpIik7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiQlVMSyI6CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklOUFVUIik7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jaGVja2VkID0gdGhpcy52YWx1ZTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnR5cGUgPSAiY2hlY2tib3giOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImJ1bGsgaGlkZUJ1bGsiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiQlVMS19IRUFEIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNoZWNrZWQgPSB0aGlzLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQudHlwZSA9ICJjaGVja2JveCI7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSAiYnVsayBoaWRlQnVsayI7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAiamF2YXNjcmlwdDogc2VsZWN0QWxsQ2hhbm5lbHMoKSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiSU1HIjoKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNoaWxkVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoInNyYyIsIHRoaXMuaW1hZ2VVUkwpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmltYWdlVVJMICE9ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCJvbmVycm9yIiwgImphdmFzY3JpcHQ6IHRoaXMub25lcnJvcj1udWxsO3RoaXMuc3JjPScnIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vb25lcnJvcj0idGhpcy5vbmVycm9yPW51bGw7dGhpcy5zcmM9J21pc3NpbmcuZ2lmJzsiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdGQuaW5uZXJIVE1MID0gdGhpcy52YWx1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMub25jbGljayA9PSB0cnVlKSB7CiAgICAgICAgICAgIHRkLnNldEF0dHJpYnV0ZSgib25jbGljayIsIHRoaXMub25jbGlja0Z1bmN0aW9uKTsKICAgICAgICAgICAgdGQuY2xhc3NOYW1lID0gInBvaW50ZXIiOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy50ZENsYXNzTmFtZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdGQuY2xhc3NOYW1lID0gdGhpcy50ZENsYXNzTmFtZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRkOwogICAgfQp9CmNsYXNzIFNob3dDb250ZW50IGV4dGVuZHMgQ29udGVudCB7CiAgICBjb25zdHJ1Y3RvcihtZW51SUQpIHsKICAgICAgICBzdXBlcigpOwogICAgICAgIHRoaXMubWVudUlEID0gbWVudUlEOwogICAgfQogICAgY3JlYXRlSW5wdXQodHlwZSwgbmFtZSwgdmFsdWUpIHsKICAgICAgICBsZXQgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTlBVVCIpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidHlwZSIsIHR5cGUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgibmFtZSIsIG5hbWUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIGlucHV0OwogICAgfQogICAgc2hvdygpIHsKICAgICAgICBDT0xVTU5fVE9fU09SVCA9IC0xOwogICAgICAgIC8vIERlbGV0ZSBvbGQgY29udGVudAogICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5pbm5lckhUTUwgPSAiIjsKICAgICAgICBzaG93UHJldmlldyhmYWxzZSk7CiAgICAgICAgLy8gSGVhZGxpbmUKICAgICAgICBsZXQgaGVhZGxpbmUgPSBtZW51SXRlbXNbdGhpcy5tZW51SURdLmhlYWRsaW5lOwogICAgICAgIGxldCBtZW51S2V5ID0gbWVudUl0ZW1zW3RoaXMubWVudUlEXS5tZW51S2V5OwogICAgICAgIGxldCBoID0gdGhpcy5jcmVhdGVIZWFkbGluZShoZWFkbGluZSk7CiAgICAgICAgZG9jLmFwcGVuZENoaWxkKGgpOwogICAgICAgIGxldCBociA9IHRoaXMuY3JlYXRlSFIoKTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoaHIpOwogICAgICAgIC8vIEludGVyYWN0aW9uCiAgICAgICAgbGV0IGRpdiA9IHRoaXMuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQoZGl2KTsKICAgICAgICBsZXQgaW50ZXJhY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmludGVyYWN0aW9uSUQpOwogICAgICAgIHN3aXRjaCAobWVudUtleSkgewogICAgICAgICAgICBjYXNlICJwbGF5bGlzdCI6CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLm5ld319Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImlkIiwgIi0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInBsYXlsaXN0IiknKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5uZXd9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsIC0xKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoImZpbHRlciIsIHRoaXMpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieG1sdHYiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5uZXd9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJ4bWx0diIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgieG1sdHYiKScpOwogICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24ubmV3fX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgiaWQiLCAidXNlcnMiKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoInVzZXJzIiknKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJtYXBwaW5nIjoKICAgICAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoIm1hcHBpbmciLCAiIiwgIiIpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJidXR0b24iLCBtZW51S2V5LCAie3suYnV0dG9uLmJ1bGtFZGl0fX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBidWxrRWRpdCgpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSB0aGlzLmNyZWF0ZUlucHV0KCJzZWFyY2giLCAic2VhcmNoIiwgIiIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJzZWFyY2hNYXBwaW5nIik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmJ1dHRvbi5zZWFyY2h9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gInNlYXJjaCI7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgJ2phdmFzY3JpcHQ6IHNlYXJjaEluTWFwcGluZygpJyk7CiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAic2V0dGluZ3MiOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5zYXZlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzYXZlU2V0dGluZ3MoKTsnKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24uYmFja3VwfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBiYWNrdXAoKTsnKTsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IHRoaXMuY3JlYXRlSW5wdXQoImJ1dHRvbiIsIG1lbnVLZXksICJ7ey5idXR0b24ucmVzdG9yZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogcmVzdG9yZSgpOycpOwogICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTsKICAgICAgICAgICAgICAgIHdyYXBwZXIuc2V0QXR0cmlidXRlKCJpZCIsICJib3gtd3JhcHBlciIpOwogICAgICAgICAgICAgICAgZG9jLmFwcGVuZENoaWxkKHdyYXBwZXIpOwogICAgICAgICAgICAgICAgdGhpcy5EaXZJRCA9ICJjb250ZW50X3NldHRpbmdzIjsKICAgICAgICAgICAgICAgIHZhciBzZXR0aW5ncyA9IHRoaXMuY3JlYXRlRElWKCk7CiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHNldHRpbmdzKTsKICAgICAgICAgICAgICAgIHNob3dTZXR0aW5ncygpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBjYXNlICJsb2ciOgogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gdGhpcy5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgbWVudUtleSwgInt7LmJ1dHRvbi5yZXNldExvZ3N9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHJlc2V0TG9ncygpOycpOwogICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTsKICAgICAgICAgICAgICAgIHdyYXBwZXIuc2V0QXR0cmlidXRlKCJpZCIsICJib3gtd3JhcHBlciIpOwogICAgICAgICAgICAgICAgZG9jLmFwcGVuZENoaWxkKHdyYXBwZXIpOwogICAgICAgICAgICAgICAgdGhpcy5EaXZJRCA9ICJjb250ZW50X2xvZyI7CiAgICAgICAgICAgICAgICB2YXIgbG9ncyA9IHRoaXMuY3JlYXRlRElWKCk7CiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGxvZ3MpOwogICAgICAgICAgICAgICAgc2hvd0xvZ3ModHJ1ZSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGNhc2UgImxvZ291dCI6CiAgICAgICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICAgICAgICAgICAgICAgIGRvY3VtZW50LmNvb2tpZSA9ICJUb2tlbj0gOyBleHBpcmVzID0gVGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMCBHTVQiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLy8gQ3JlYXRlIHRhYmxlIChpZiBuZWVkZWQpCiAgICAgICAgdmFyIHRhYmxlSGVhZGVyID0gbWVudUl0ZW1zW3RoaXMubWVudUlEXS50YWJsZUhlYWRlcjsKICAgICAgICBpZiAodGFibGVIZWFkZXIubGVuZ3RoID4gMCkgewogICAgICAgICAgICB2YXIgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkRJViIpOwogICAgICAgICAgICBkb2MuYXBwZW5kQ2hpbGQod3JhcHBlcik7CiAgICAgICAgICAgIHdyYXBwZXIuc2V0QXR0cmlidXRlKCJpZCIsICJib3gtd3JhcHBlciIpOwogICAgICAgICAgICB2YXIgdGFibGUgPSB0aGlzLmNyZWF0ZVRBQkxFKCk7CiAgICAgICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQodGFibGUpOwogICAgICAgICAgICB2YXIgaGVhZGVyID0gdGhpcy5jcmVhdGVUYWJsZVJvdygpOwogICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChoZWFkZXIpOwogICAgICAgICAgICAvLyBUYWJsZSBoZWFkZXIKICAgICAgICAgICAgdGFibGVIZWFkZXIuZm9yRWFjaChlbGVtZW50ID0+IHsKICAgICAgICAgICAgICAgIHZhciBjZWxsID0gbmV3IENlbGwoKTsKICAgICAgICAgICAgICAgIGNlbGwuY2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgY2VsbC5jaGlsZFR5cGUgPSAiUCI7CiAgICAgICAgICAgICAgICBjZWxsLnZhbHVlID0gZWxlbWVudDsKICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09ICJCVUxLIikgewogICAgICAgICAgICAgICAgICAgIGNlbGwuY2hpbGRUeXBlID0gIkJVTEtfSEVBRCI7CiAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG1lbnVLZXkgPT0gIm1hcHBpbmciKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7Lm1hcHBpbmcudGFibGUuY2hOb319IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5jdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoMSk7IjsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC50ZENsYXNzTmFtZSA9ICJzb3J0VGhpcyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09ICJ7ey5tYXBwaW5nLnRhYmxlLmNoYW5uZWxOYW1lfX0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGljayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGlja0Z1bmN0aW9uID0gImphdmFzY3JpcHQ6IHNvcnRUYWJsZSgzKTsiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSAie3subWFwcGluZy50YWJsZS51cGRhdGVDaGFubmVsTmFtZVJlZ2V4fX0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGljayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGlja0Z1bmN0aW9uID0gImphdmFzY3JpcHQ6IHNvcnRUYWJsZSg0KTsiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSAie3subWFwcGluZy50YWJsZS5wbGF5bGlzdH19IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5jdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoNSk7IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7Lm1hcHBpbmcudGFibGUuZ3JvdXBUaXRsZX19IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5jdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoNik7IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7Lm1hcHBpbmcudGFibGUudGltZXNoaWZ0fX0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGljayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwub25jbGlja0Z1bmN0aW9uID0gImphdmFzY3JpcHQ6IHNvcnRUYWJsZSg5KTsiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChtZW51S2V5ID09ICJmaWx0ZXIiKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7LmZpbHRlci50YWJsZS5zdGFydGluZ0NoYW5uZWx9fSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrRnVuY3Rpb24gPSAiamF2YXNjcmlwdDogc29ydFRhYmxlKDApOyI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwudGRDbGFzc05hbWUgPSAic29ydFRoaXMiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSAie3suZmlsdGVyLnRhYmxlLm5hbWV9fSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrRnVuY3Rpb24gPSAiamF2YXNjcmlwdDogc29ydFRhYmxlKDEpOyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ID09ICJ7ey5maWx0ZXIudGFibGUudHlwZX19IikgewogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsLm9uY2xpY2tGdW5jdGlvbiA9ICJqYXZhc2NyaXB0OiBzb3J0VGFibGUoMik7IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gInt7LmZpbHRlci50YWJsZS5maWx0ZXJ9fSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5vbmNsaWNrRnVuY3Rpb24gPSAiamF2YXNjcmlwdDogc29ydFRhYmxlKDMpOyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaGVhZGVyLmFwcGVuZENoaWxkKGNlbGwuY3JlYXRlQ2VsbCgpKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRhYmxlLmFwcGVuZENoaWxkKGhlYWRlcik7CiAgICAgICAgICAgIC8vIENvbnRlbnQgb2YgdGhlIHRhYmxlCiAgICAgICAgICAgIHZhciByb3dzID0gdGhpcy5jcmVhdGVUYWJsZUNvbnRlbnQobWVudUtleSk7CiAgICAgICAgICAgIHJvd3MuZm9yRWFjaCh0ciA9PiB7CiAgICAgICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZCh0cik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKG1lbnVLZXkpIHsKICAgICAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgICAgICBzb3J0VGFibGUoMSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmlsdGVyIjoKICAgICAgICAgICAgICAgIHNob3dQcmV2aWV3KHRydWUpOwogICAgICAgICAgICAgICAgc29ydFRhYmxlKDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBDT0xVTU5fVE9fU09SVCA9IC0xOwogICAgICAgICAgICAgICAgc29ydFRhYmxlKDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgZmFsc2UpOwogICAgfQp9CmZ1bmN0aW9uIFBhZ2VSZWFkeSgpIHsKICAgIGxldCBzZXJ2ZXIgPSBuZXcgU2VydmVyKCJnZXRTZXJ2ZXJDb25maWciKTsKICAgIHNlcnZlci5yZXF1ZXN0KHt9KTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJyZXNpemUiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogICAgfSwgdHJ1ZSk7CiAgICBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgdXBkYXRlTG9nKCk7CiAgICB9LCAxMDAwMCk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gY3JlYXRlTGF5b3V0KCkgewogICAgLy8gQ2xpZW50IEluZm8KICAgIGxldCBvYmogPSBTRVJWRVJbImNsaWVudEluZm8iXTsKICAgIGxldCBrZXlzID0gZ2V0T3duT2JqUHJvcHMob2JqKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChrZXlzW2ldKSkgewogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChrZXlzW2ldKS5pbm5lckhUTUwgPSBvYmpba2V5c1tpXV07CiAgICAgICAgICAgIGlmIChsb2NhdGlvbi5wcm90b2NvbCA9PT0gJ2h0dHBzOicpIHsKICAgICAgICAgICAgICAgIGlmIChrZXlzW2ldID09PSAieGVwZy11cmwiIHx8IGtleXNbaV0gPT09ICJtM3UtdXJsIiB8fCBrZXlzW2ldID09PSAiRFZSIikgewogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDsKICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodGFyZ2V0LmlubmVyVGV4dC5zcGxpdCgiICIpWzBdKS50aGVuKCgpID0+IHsgfSk7CiAgICAgICAgICAgICAgICAgICAgfSwgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgaWYgKCFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibWFpbi1tZW51IikpIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvLyBDcmVhdGUgbWVudQogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm1haW4tbWVudSIpLmlubmVySFRNTCA9ICIiOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtZW51SXRlbXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBtZW51SXRlbXNbaV0uaWQgPSBpOwogICAgICAgIHN3aXRjaCAobWVudUl0ZW1zW2ldWyJtZW51S2V5Il0pIHsKICAgICAgICAgICAgY2FzZSAidXNlcnMiOgogICAgICAgICAgICBjYXNlICJsb2dvdXQiOgogICAgICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtc1tpXS5jcmVhdGVJdGVtKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgICAgIGlmIChTRVJWRVJbImNsaWVudEluZm8iXVsiZXBnU291cmNlIl0gPT0gIlhFUEciKSB7CiAgICAgICAgICAgICAgICAgICAgbWVudUl0ZW1zW2ldLmNyZWF0ZUl0ZW0oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgbWVudUl0ZW1zW2ldLmNyZWF0ZUl0ZW0oKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBvcGVuVGhpc01lbnUoZWxlbWVudCkgewogICAgbGV0IGlkID0gZWxlbWVudC5pZDsKICAgIGxldCBjb250ZW50ID0gbmV3IFNob3dDb250ZW50KGlkKTsKICAgIGNvbnRlbnQuc2hvdygpOwogICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogICAgcmV0dXJuOwp9CmNsYXNzIFBvcHVwV2luZG93IHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICAgIHRoaXMuRG9jdW1lbnRJRCA9ICJwb3B1cC1jdXN0b20iOwogICAgICAgIHRoaXMuSW50ZXJhY3Rpb25JRCA9ICJpbnRlcmFjdGlvbiI7CiAgICAgICAgdGhpcy5kb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgfQogICAgY3JlYXRlVGl0bGUodGl0bGUpIHsKICAgICAgICBsZXQgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgIHRkLmNsYXNzTmFtZSA9ICJsZWZ0IjsKICAgICAgICB0ZC5pbm5lckhUTUwgPSB0aXRsZSArICI6IjsKICAgICAgICByZXR1cm4gdGQ7CiAgICB9CiAgICBjcmVhdGVDb250ZW50KGVsZW1lbnQpIHsKICAgICAgICBsZXQgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgIHRkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgICAgIHJldHVybiB0ZDsKICAgIH0KICAgIGNyZWF0ZUludGVyYWN0aW9uKCkgewogICAgICAgIGxldCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICBkaXYuc2V0QXR0cmlidXRlKCJpZCIsICJwb3B1cC1pbnRlcmFjdGlvbiIpOwogICAgICAgIGRpdi5jbGFzc05hbWUgPSAiaW50ZXJhY3Rpb24iOwogICAgICAgIHRoaXMuZG9jLmFwcGVuZENoaWxkKGRpdik7CiAgICB9Cn0KY2xhc3MgUG9wdXBDb250ZW50IGV4dGVuZHMgUG9wdXBXaW5kb3cgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgICB0aGlzLnRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEFCTEUiKTsKICAgIH0KICAgIGNyZWF0ZUhlYWRsaW5lKGhlYWRsaW5lKSB7CiAgICAgICAgdGhpcy5kb2MuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJIMyIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gaGVhZGxpbmUudG9VcHBlckNhc2UoKTsKICAgICAgICB0aGlzLmRvYy5hcHBlbmRDaGlsZChlbGVtZW50KTsKICAgICAgICAvLyBDcmVhdGUgdGFibGUKICAgICAgICB0aGlzLnRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEFCTEUiKTsKICAgICAgICB0aGlzLmRvYy5hcHBlbmRDaGlsZCh0aGlzLnRhYmxlKTsKICAgIH0KICAgIGFwcGVuZFJvdyh0aXRsZSwgZWxlbWVudCkgewogICAgICAgIGxldCB0ciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgLy8gVGl0bGUKICAgICAgICBpZiAodGl0bGUubGVuZ3RoICE9IDApIHsKICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGhpcy5jcmVhdGVUaXRsZSh0aXRsZSkpOwogICAgICAgIH0KICAgICAgICAvLyBDb250ZW50CiAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGhpcy5jcmVhdGVDb250ZW50KGVsZW1lbnQpKTsKICAgICAgICB0aGlzLnRhYmxlLmFwcGVuZENoaWxkKHRyKTsKICAgIH0KICAgIGNyZWF0ZUlucHV0KHR5cGUsIG5hbWUsIHZhbHVlKSB7CiAgICAgICAgbGV0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSU5QVVQiKTsKICAgICAgICBpZiAodmFsdWUgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIHZhbHVlID0gIiI7CiAgICAgICAgfQogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidHlwZSIsIHR5cGUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgibmFtZSIsIG5hbWUpOwogICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIGlucHV0OwogICAgfQogICAgY3JlYXRlQ2hlY2tib3gobmFtZSkgewogICAgICAgIGxldCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIklOUFVUIik7CiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ0eXBlIiwgImNoZWNrYm94Iik7CiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgcmV0dXJuIGlucHV0OwogICAgfQogICAgLy8gQ3JlYXRlcyBhIHNlbGVjdGlvbiBvZiBtdWx0aXBsZSBvcHRpb25zIHZhbHVlcyB3aXRoIHRleHQgZGVzY3JpcHRpb25zCiAgICBjcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBzZXQsIGRiS2V5KSB7CiAgICAgICAgbGV0IHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlNFTEVDVCIpOwogICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm5hbWUiLCBkYktleSk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGxldCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKTsKICAgICAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgidmFsdWUiLCB2YWx1ZXNbaV0pOwogICAgICAgICAgICBvcHRpb24uaW5uZXJUZXh0ID0gdGV4dFtpXTsKICAgICAgICAgICAgc2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7CiAgICAgICAgfQogICAgICAgIGlmIChzZXQgIT0gIiIpIHsKICAgICAgICAgICAgc2VsZWN0LnZhbHVlID0gc2V0OwogICAgICAgIH0KICAgICAgICBpZiAoc2V0ID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBzZWxlY3QudmFsdWUgPSB2YWx1ZXNbMF07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxlY3Q7CiAgICB9CiAgICBzZWxlY3RPcHRpb24oc2VsZWN0LCB2YWx1ZSkgewogICAgICAgIC8vc2VsZWN0LnNlbGVjdGVkT3B0aW9ucyA9IHZhbHVlCiAgICAgICAgbGV0IHMgPSBzZWxlY3Q7CiAgICAgICAgcy5vcHRpb25zW3Muc2VsZWN0ZWRJbmRleF0udmFsdWUgPSB2YWx1ZTsKICAgICAgICByZXR1cm4gc2VsZWN0OwogICAgfQogICAgZGVzY3JpcHRpb24odmFsdWUpIHsKICAgICAgICBsZXQgdHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJUUiIpOwogICAgICAgIGxldCB0ZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgbGV0IHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBzcGFuLmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgIHRyLmFwcGVuZENoaWxkKHRkKTsKICAgICAgICB0ci5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUNvbnRlbnQoc3BhbikpOwogICAgICAgIHRoaXMudGFibGUuYXBwZW5kQ2hpbGQodHIpOwogICAgfQogICAgLy8gSW50ZXJhY3Rpb24KICAgIGFkZEludGVyYWN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBsZXQgaW50ZXJhY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtaW50ZXJhY3Rpb24iKTsKICAgICAgICBpbnRlcmFjdGlvbi5hcHBlbmRDaGlsZChlbGVtZW50KTsKICAgIH0KfQpmdW5jdGlvbiBvcGVuUG9wVXAoZGF0YVR5cGUsIGVsZW1lbnQpIHsKICAgIGxldCBkYXRhID0ge307CiAgICBsZXQgaWQ7CiAgICBzd2l0Y2ggKGVsZW1lbnQpIHsKICAgICAgICBjYXNlIHVuZGVmaW5lZDoKICAgICAgICAgICAgc3dpdGNoIChkYXRhVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAiZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGlmIChpZCA9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSAtMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGdldExvY2FsRGF0YSgiZmlsdGVyIiwgaWQpOwogICAgICAgICAgICAgICAgICAgIGRhdGFbInR5cGUiXSA9ICJncm91cC10aXRsZSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJjdXN0b20tZmlsdGVyIjoKICAgICAgICAgICAgICAgICAgICBpZiAoaWQgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gLTE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBnZXRMb2NhbERhdGEoImZpbHRlciIsIGlkKTsKICAgICAgICAgICAgICAgICAgICBkYXRhWyJ0eXBlIl0gPSAiY3VzdG9tLWZpbHRlciI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGRhdGFbImlkLnByb3ZpZGVyIl0gPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgZGF0YVsidHlwZSJdID0gZGF0YVR5cGU7CiAgICAgICAgICAgICAgICAgICAgaWQgPSAiLSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaWQgPSBlbGVtZW50LmlkOwogICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxEYXRhKGRhdGFUeXBlLCBpZCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgbGV0IGNvbnRlbnQgPSBuZXcgUG9wdXBDb250ZW50KCk7CiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7CiAgICAgICAgY2FzZSAicGxheWxpc3QiOgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUhlYWRsaW5lKCJ7ey5wbGF5bGlzdC5wbGF5bGlzdFR5cGUudGl0bGV9fSIpOwogICAgICAgICAgICAvLyBUeXBlCiAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJNM1UiLCAiSERIb21lUnVuIl07CiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbImphdmFzY3JpcHQ6IG9wZW5Qb3BVcCgnbTN1JykiLCAiamF2YXNjcmlwdDogb3BlblBvcFVwKCdoZGhyJykiXTsKICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgIiIsICJ0eXBlIik7CiAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoImlkIiwgInR5cGUiKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAnamF2YXNjcmlwdDogY2hhbmdlQnV0dG9uQWN0aW9uKHRoaXMsICJuZXh0IiwgIm9uY2xpY2siKScpOyAvLyBjaGFuZ2VCdXR0b25BY3Rpb24KICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LnR5cGUudGl0bGV9fSIsIHNlbGVjdCk7CiAgICAgICAgICAgIC8vIEludGVyYWN0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gQWJvcnQKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImNhbmNlbCIsICJ7ey5idXR0b24uY2FuY2VsfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIE5leHQKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgIm5leHQiLCAie3suYnV0dG9uLm5leHR9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJtM3UiKScpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImlkIiwgJ25leHQnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoZGF0YVR5cGUpOwogICAgICAgICAgICAvLyBOYW1lCiAgICAgICAgICAgIHZhciBkYktleSA9ICJuYW1lIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QubmFtZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5uYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIERlc2NyaXB0aW9uCiAgICAgICAgICAgIHZhciBkYktleSA9ICJkZXNjcmlwdGlvbiI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnBsYXlsaXN0LmRlc2NyaXB0aW9uLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LmRlc2NyaXB0aW9uLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIFVSTAogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZmlsZS5zb3VyY2UiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5wbGF5bGlzdC5maWxlTTNVLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LmZpbGVNM1UudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gVHVuZXIKICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYnVmZmVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFtdOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFtdOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnB1c2goaS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gInR1bmVyIjsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmZvY3VzIiwgImphdmFzY3JpcHQ6IHJldHVybjsiKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC50dW5lci50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJ0dW5lciI7CiAgICAgICAgICAgICAgICBpZiAoZGF0YVtkYktleV0gPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YVtkYktleV0gPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJub3RBdmFpbGFibGUiOwogICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LnR1bmVyLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3sucGxheWxpc3QudHVuZXIuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAvLyBJbnRlcmF0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gRGVsZXRlCiAgICAgICAgICAgIGlmIChkYXRhWyJpZC5wcm92aWRlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImRlbGV0ZSIsICJ7ey5idXR0b24uZGVsZXRlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJkZWxldGUiOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoIm0zdSIsICInICsgaWQgKyAnIiwgdHJ1ZSwgMCknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImJhY2siLCAie3suYnV0dG9uLmJhY2t9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IG9wZW5Qb3BVcCgicGxheWxpc3QiKScpOwogICAgICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQWJvcnQKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImNhbmNlbCIsICJ7ey5idXR0b24uY2FuY2VsfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIFVwZGF0ZQogICAgICAgICAgICBpZiAoZGF0YVsiaWQucHJvdmlkZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJ1cGRhdGUiLCAie3suYnV0dG9uLnVwZGF0ZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgibTN1IiwgIicgKyBpZCArICciLCBmYWxzZSwgMSknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNhdmUKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInNhdmUiLCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgibTN1IiwgIicgKyBpZCArICciLCBmYWxzZSwgMCknKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgImhkaHIiOgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUhlYWRsaW5lKGRhdGFUeXBlKTsKICAgICAgICAgICAgLy8gTmFtZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAibmFtZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnBsYXlsaXN0Lm5hbWUucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sucGxheWxpc3QubmFtZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBEZXNjcmlwdGlvbgogICAgICAgICAgICB2YXIgZGJLZXkgPSAiZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBVUkwKICAgICAgICAgICAgdmFyIGRiS2V5ID0gImZpbGUuc291cmNlIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sucGxheWxpc3QuZmlsZUhESFIucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sucGxheWxpc3QuZmlsZUhESFIudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gVHVuZXIKICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYnVmZmVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFtdOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFtdOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTAwOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnB1c2goaS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gInR1bmVyIjsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmZvY3VzIiwgImphdmFzY3JpcHQ6IHJldHVybjsiKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5wbGF5bGlzdC50dW5lci50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJ0dW5lciI7CiAgICAgICAgICAgICAgICBpZiAoZGF0YVtkYktleV0gPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YVtkYktleV0gPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJub3RBdmFpbGFibGUiOwogICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnBsYXlsaXN0LnR1bmVyLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3sucGxheWxpc3QudHVuZXIuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAvLyBJbnRlcmFjdGlvbgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUludGVyYWN0aW9uKCk7CiAgICAgICAgICAgIC8vIERlbGV0ZQogICAgICAgICAgICBpZiAoZGF0YVsiaWQucHJvdmlkZXIiXSAhPSAiLSIpIHsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJkZWxldGUiLCAie3suYnV0dG9uLmRlbGV0ZX19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiaGRociIsICInICsgaWQgKyAnIiwgdHJ1ZSwgMCknKTsKICAgICAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJkZWxldGUiOwogICAgICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiYmFjayIsICJ7ey5idXR0b24uYmFja319Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogb3BlblBvcFVwKCJwbGF5bGlzdCIpJyk7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBBYm9ydAogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gVXBkYXRlCiAgICAgICAgICAgIGlmIChkYXRhWyJpZC5wcm92aWRlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInVwZGF0ZSIsICJ7ey5idXR0b24udXBkYXRlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJoZGhyIiwgIicgKyBpZCArICciLCBmYWxzZSwgMSknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNhdmUKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInNhdmUiLCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiaGRociIsICInICsgaWQgKyAnIiwgZmFsc2UsIDApJyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJmaWx0ZXIiOgogICAgICAgICAgICBjb250ZW50LmNyZWF0ZUhlYWRsaW5lKGRhdGFUeXBlKTsKICAgICAgICAgICAgLy8gVHlwZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAidHlwZSI7CiAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJNM1U6ICIgKyAie3suZmlsdGVyLnR5cGUuZ3JvdXBUaXRsZX19IiwgInhUZVZlOiAiICsgInt7LmZpbHRlci50eXBlLmN1c3RvbUZpbHRlcn19Il07CiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbImphdmFzY3JpcHQ6IG9wZW5Qb3BVcCgnZ3JvdXAtdGl0bGUnKSIsICJqYXZhc2NyaXB0OiBvcGVuUG9wVXAoJ2N1c3RvbS1maWx0ZXInKSJdOwogICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCAiamF2YXNjcmlwdDogb3BlblBvcFVwKCdncm91cC10aXRsZScpIiwgZGJLZXkpOwogICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJpZCIsIGlkKTsKICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAnamF2YXNjcmlwdDogY2hhbmdlQnV0dG9uQWN0aW9uKHRoaXMsICJuZXh0IiwgIm9uY2xpY2siKTsnKTsgLy8gY2hhbmdlQnV0dG9uQWN0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIudHlwZS50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgLy8gSW50ZXJhY3Rpb24KICAgICAgICAgICAgY29udGVudC5jcmVhdGVJbnRlcmFjdGlvbigpOwogICAgICAgICAgICAvLyBBYm9ydAogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gTmV4dAogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAibmV4dCIsICJ7ey5idXR0b24ubmV4dH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBvcGVuUG9wVXAoImdyb3VwLXRpdGxlIiknKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICduZXh0Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJjdXN0b20tZmlsdGVyIjoKICAgICAgICBjYXNlICJncm91cC10aXRsZSI6CiAgICAgICAgICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgImN1c3RvbS1maWx0ZXIiOgogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7LmZpbHRlci5jdXN0b219fSIgKyAiIEZpbHRlciIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7LmZpbHRlci5ncm91cH19IiArICIgRmlsdGVyIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gTmFtZSAgICAgIAogICAgICAgICAgICB2YXIgZGJLZXkgPSAibmFtZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmZpbHRlci5uYW1lLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5uYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIERlc2NyaXB0aW9uCiAgICAgICAgICAgIHZhciBkYktleSA9ICJkZXNjcmlwdGlvbiI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmZpbHRlci5kZXNjcmlwdGlvbi5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIuZGVzY3JpcHRpb24udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gVHlwZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAidHlwZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImhpZGRlbiIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCIiLCBpbnB1dCk7CiAgICAgICAgICAgIHZhciBmaWx0ZXJUeXBlID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIHN3aXRjaCAoZmlsdGVyVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAiY3VzdG9tLWZpbHRlciI6CiAgICAgICAgICAgICAgICAgICAgLy8gQ2FzZSBzZW5zaXRpdmUKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAiY2FzZVNlbnNpdGl2ZSI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIuY2FzZVNlbnNpdGl2ZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIC8vIEZpbHRlciBSdWxlIChDdXN0b20pCiAgICAgICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gImZpbHRlciI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5maWx0ZXIuZmlsdGVyUnVsZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5maWx0ZXJSdWxlLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnRpbmcgQ2hhbm5lbCBOdW1iZXIgTWFwcGluZwogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJzdGFydGluZ0NoYW5uZWwiOwogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suZmlsdGVyLnN0YXJ0aW5nQ2hhbm5lbC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5zdGFydGluZ0NoYW5uZWwudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImdyb3VwLXRpdGxlIjoKICAgICAgICAgICAgICAgICAgICAvL2FsZXJ0KGRiS2V5ICsgIiAiICsgZmlsdGVyVHlwZSkKICAgICAgICAgICAgICAgICAgICAvLyBGaWx0ZXIgYmFzZWQgb24gdGhlIGdyb3VwcyBpbiB0aGUgTTNVCiAgICAgICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gImZpbHRlciI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGdyb3Vwc00zVSA9IGdldExvY2FsRGF0YSgibTN1R3JvdXBzIiwgIiIpOwogICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gZ3JvdXBzTTNVWyJ0ZXh0Il07CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IGdyb3Vwc00zVVsidmFsdWUiXTsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhW2RiS2V5XSwgZGJLZXkpOwogICAgICAgICAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5maWx0ZXJHcm91cC50aXRsZX19Iiwgc2VsZWN0KTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKCJ7ey5maWx0ZXIuZmlsdGVyR3JvdXAuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAgICAgICAgIC8vIENhc2Ugc2Vuc2V0aXZlCiAgICAgICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gImNhc2VTZW5zaXRpdmUiOwogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goZGJLZXkpOwogICAgICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3suZmlsdGVyLmNhc2VTZW5zaXRpdmUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAiaW5jbHVkZSI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5maWx0ZXIuaW5jbHVkZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LmZpbHRlci5pbmNsdWRlLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3suZmlsdGVyLmluY2x1ZGUuZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJleGNsdWRlIjsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmZpbHRlci5leGNsdWRlLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3suZmlsdGVyLmV4Y2x1ZGUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKCJ7ey5maWx0ZXIuZXhjbHVkZS5kZXNjcmlwdGlvbn19Iik7CiAgICAgICAgICAgICAgICAgICAgLy8gUHJlc2VydmUgTTNVIFBsYXlsaXN0IENoYW5uZWwgTWFwcGluZwogICAgICAgICAgICAgICAgICAgIHZhciBkYktleSA9ICJwcmVzZXJ2ZU1hcHBpbmciOwogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goZGJLZXkpOwogICAgICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3suZmlsdGVyLnByZXNlcnZlTWFwcGluZy50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0aW5nIENoYW5uZWwgTnVtYmVyIE1hcHBpbmcKICAgICAgICAgICAgICAgICAgICB2YXIgZGJLZXkgPSAic3RhcnRpbmdDaGFubmVsIjsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LmZpbHRlci5zdGFydGluZ0NoYW5uZWwucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5maWx0ZXIuc3RhcnRpbmdDaGFubmVsLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEludGVyYWN0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gRGVsZXRlCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJkZWxldGUiLCAie3suYnV0dG9uLmRlbGV0ZX19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJmaWx0ZXIiLCAiJyArIGlkICsgJyIsIHRydWUsIDApJyk7CiAgICAgICAgICAgIGlucHV0LmNsYXNzTmFtZSA9ICJkZWxldGUiOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gQWJvcnQKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgImNhbmNlbCIsICJ7ey5idXR0b24uY2FuY2VsfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIFNhdmUKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInNhdmUiLCAie3suYnV0dG9uLnNhdmV9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiZmlsdGVyIiwgIicgKyBpZCArICciLCBmYWxzZSwgMCknKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInhtbHR2IjoKICAgICAgICAgICAgY29udGVudC5jcmVhdGVIZWFkbGluZShkYXRhVHlwZSk7CiAgICAgICAgICAgIC8vIE5hbWUKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIm5hbWUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey54bWx0di5uYW1lLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnhtbHR2Lm5hbWUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gRGVzY3JpcHRpb24KICAgICAgICAgICAgdmFyIGRiS2V5ID0gImRlc2NyaXB0aW9uIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sueG1sdHYuZGVzY3JpcHRpb24ucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sueG1sdHYuZGVzY3JpcHRpb24udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gVVJMCiAgICAgICAgICAgIHZhciBkYktleSA9ICJmaWxlLnNvdXJjZSI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnhtbHR2LmZpbGVYTUxUVi5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey54bWx0di5maWxlWE1MVFYudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gSW50ZXJhY3Rpb24KICAgICAgICAgICAgY29udGVudC5jcmVhdGVJbnRlcmFjdGlvbigpOwogICAgICAgICAgICAvLyBEZWxldGUKICAgICAgICAgICAgaWYgKGRhdGFbImlkLnByb3ZpZGVyIl0gIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiZGVsZXRlIiwgInt7LmJ1dHRvbi5kZWxldGV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoInhtbHR2IiwgIicgKyBpZCArICciLCB0cnVlLCAwKScpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBBYm9ydAogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi5jYW5jZWx9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2xpY2siLCAnamF2YXNjcmlwdDogc2hvd0VsZW1lbnQoInBvcHVwIiwgZmFsc2UpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgLy8gVXBkYXRlCiAgICAgICAgICAgIGlmIChkYXRhWyJpZC5wcm92aWRlciJdICE9ICItIikgewogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgiYnV0dG9uIiwgInVwZGF0ZSIsICJ7ey5idXR0b24udXBkYXRlfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnb25jbGljaycsICdqYXZhc2NyaXB0OiBzYXZlUG9wdXBEYXRhKCJ4bWx0diIsICInICsgaWQgKyAnIiwgZmFsc2UsIDEpJyk7CiAgICAgICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBTYXZlCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJzYXZlIiwgInt7LmJ1dHRvbi5zYXZlfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoInhtbHR2IiwgIicgKyBpZCArICciLCBmYWxzZSwgMCknKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgInVzZXJzIjoKICAgICAgICAgICAgY29udGVudC5jcmVhdGVIZWFkbGluZSgie3subWFpbk1lbnUuaXRlbS51c2Vyc319Iik7CiAgICAgICAgICAgIC8vIFVzZXIgbmFtZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAidXNlcm5hbWUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey51c2Vycy51c2VybmFtZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy51c2VybmFtZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBOZXcgUGFyc3N3b3JkCiAgICAgICAgICAgIHZhciBkYktleSA9ICJwYXNzd29yZCI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInBhc3N3b3JkIiwgZGJLZXksICIiKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey51c2Vycy5wYXNzd29yZC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy5wYXNzd29yZC50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBDb25maXJtYXRpb24KICAgICAgICAgICAgdmFyIGRiS2V5ID0gImNvbmZpcm0iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJwYXNzd29yZCIsIGRiS2V5LCAiIik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3sudXNlcnMuY29uZmlybS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy5jb25maXJtLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uIFdFQgogICAgICAgICAgICB2YXIgZGJLZXkgPSAiYXV0aGVudGljYXRpb24ud2ViIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgaWYgKGRhdGFbImRlZmF1bHRVc2VyIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgImphdmFzY3JpcHQ6IHJldHVybiBmYWxzZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy53ZWIudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQXV0aGVudGljYXRpb24gUE1TCiAgICAgICAgICAgIHZhciBkYktleSA9ICJhdXRoZW50aWNhdGlvbi5wbXMiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sudXNlcnMucG1zLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uIE0zVQogICAgICAgICAgICB2YXIgZGJLZXkgPSAiYXV0aGVudGljYXRpb24ubTN1IjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7LnVzZXJzLm0zdS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBBdXRoZW50aWNhdGlvbiBYTUwKICAgICAgICAgICAgdmFyIGRiS2V5ID0gImF1dGhlbnRpY2F0aW9uLnhtbCI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goZGJLZXkpOwogICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey51c2Vycy54bWwudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQXV0aGVudGljYXRpb24gQVBJCiAgICAgICAgICAgIHZhciBkYktleSA9ICJhdXRoZW50aWNhdGlvbi5hcGkiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3sudXNlcnMuYXBpLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIC8vIEludGVyYWN0aW9uCiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSW50ZXJhY3Rpb24oKTsKICAgICAgICAgICAgLy8gRGVsZXRlCiAgICAgICAgICAgIGlmIChkYXRhWyJkZWZhdWx0VXNlciJdICE9IHRydWUgJiYgaWQgIT0gIi0iKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiZGVsZXRlIiwgInt7LmJ1dHRvbi5kZWxldGV9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuY2xhc3NOYW1lID0gImRlbGV0ZSI7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2xpY2snLCAnamF2YXNjcmlwdDogc2F2ZVBvcHVwRGF0YSgiJyArIGRhdGFUeXBlICsgJyIsICInICsgaWQgKyAnIiwgdHJ1ZSwgMCknKTsKICAgICAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFib3J0CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLmNhbmNlbH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICAvLyBTYXZlCiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJzYXZlIiwgInt7LmJ1dHRvbi5zYXZlfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHNhdmVQb3B1cERhdGEoIicgKyBkYXRhVHlwZSArICciLCAiJyArIGlkICsgJyIsICJmYWxzZSIpOycpOwogICAgICAgICAgICBjb250ZW50LmFkZEludGVyYWN0aW9uKGlucHV0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAibWFwcGluZyI6CiAgICAgICAgICAgIGNvbnRlbnQuY3JlYXRlSGVhZGxpbmUoInt7Lm1haW5NZW51Lml0ZW0ubWFwcGluZ319Iik7CiAgICAgICAgICAgIC8vIEFjdGl2ZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAieC1hY3RpdmUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KGRiS2V5KTsKICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICBpbnB1dC5pZCA9ICJhY3RpdmUiOwogICAgICAgICAgICAvL2lucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKQogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRvZ2dsZUNoYW5uZWxTdGF0dXMoJyIgKyBpZCArICInLCB0aGlzKSIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy5hY3RpdmUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQ2hhbm5lbCBuYW1lCiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LW5hbWUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICBpZiAoQlVMS19FRElUID09IHRydWUpIHsKICAgICAgICAgICAgICAgIGlucHV0LnN0eWxlLmJvcmRlciA9ICJzb2xpZCAxcHggcmVkIjsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicmVhZG9ubHkiLCAidHJ1ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLmNoYW5uZWxOYW1lLnRpdGxlfX0iLCBpbnB1dCk7CiAgICAgICAgICAgIGNvbnRlbnQuZGVzY3JpcHRpb24oZGF0YVsibmFtZSJdKTsKICAgICAgICAgICAgLy8gRGVzY3JpcHRpb24KICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngtZGVzY3JpcHRpb24iOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5tYXBwaW5nLmRlc2NyaXB0aW9uLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy5kZXNjcmlwdGlvbi50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBVcGRhdGUgdGhlIGNoYW5uZWwgeC1uYW1lCiAgICAgICAgICAgIGlmIChkYXRhLmhhc093blByb3BlcnR5KCJfdXVpZC5rZXkiKSkgewogICAgICAgICAgICAgICAgaWYgKGRhdGFbIl91dWlkLmtleSJdICE9ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngtdXBkYXRlLWNoYW5uZWwtbmFtZSI7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy51cGRhdGVDaGFubmVsTmFtZS50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENoYW5uZWwgbmFtZSByZWdleCBmb3IgdXBkYXRpbmcgdGhlIGNoYW5uZWwgbmFtZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAidXBkYXRlLWNoYW5uZWwtbmFtZS1yZWdleCI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7Lm1hcHBpbmcudXBkYXRlQ2hhbm5lbE5hbWVSZWdleC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcudXBkYXRlQ2hhbm5lbE5hbWVSZWdleC50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKCJ7ey5tYXBwaW5nLnVwZGF0ZUNoYW5uZWxOYW1lUmVnZXguZGVzY3JpcHRpb259fSIpOwogICAgICAgICAgICAvLyBDaGFubmVsIGdyb3VwIHJlZ2V4IGZvciB1cGRhdGluZyB0aGUgY2hhbm5lbCBuYW1lCiAgICAgICAgICAgIHZhciBkYktleSA9ICJ1cGRhdGUtY2hhbm5lbC1uYW1lLWJ5LWdyb3VwLXJlZ2V4IjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3subWFwcGluZy51cGRhdGVDaGFubmVsTmFtZUJ5R3JvdXBSZWdleC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcudXBkYXRlQ2hhbm5lbE5hbWVCeUdyb3VwUmVnZXgudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgY29udGVudC5kZXNjcmlwdGlvbigie3subWFwcGluZy51cGRhdGVDaGFubmVsTmFtZUJ5R3JvdXBSZWdleC5kZXNjcmlwdGlvbn19Iik7CiAgICAgICAgICAgIC8vIExvZ28gVVJMIChDaGFubmVsKSAKICAgICAgICAgICAgdmFyIGRiS2V5ID0gInR2Zy1sb2dvIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsIGRiS2V5LCBkYXRhW2RiS2V5XSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJjaGFubmVsLWljb24iKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coInt7Lm1hcHBpbmcuY2hhbm5lbExvZ28udGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gQ2hhbm5lbCBsb2dvIHVwZGF0ZQogICAgICAgICAgICB2YXIgZGJLZXkgPSAieC11cGRhdGUtY2hhbm5lbC1pY29uIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhW2RiS2V5XTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJpZCIsICJ1cGRhdGUtaWNvbiIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnOyBjaGFuZ2VDaGFubmVsTG9nbygnIiArIGlkICsgIicpOyIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy51cGRhdGVDaGFubmVsTG9nby50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICAvLyBFeHBhbmQgRVBHIGNhdGVnb3J5CiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LWNhdGVnb3J5IjsKICAgICAgICAgICAgdmFyIHRleHQgPSBbIi0iLCAiS2lkcyAoRW1ieSBvbmx5KSIsICJOZXdzIiwgIk1vdmllIiwgIlNlcmllcyIsICJTcG9ydHMiXTsKICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFsiIiwgIktpZHMiLCAiTmV3cyIsICJNb3ZpZSIsICJTZXJpZXMiLCAiU3BvcnRzIl07CiAgICAgICAgICAgIHZhciBzZWxlY3QgPSBjb250ZW50LmNyZWF0ZVNlbGVjdCh0ZXh0LCB2YWx1ZXMsIGRhdGFbZGJLZXldLCBkYktleSk7CiAgICAgICAgICAgIHNlbGVjdC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLmVwZ0NhdGVnb3J5LnRpdGxlfX0iLCBzZWxlY3QpOwogICAgICAgICAgICAvLyBNM1UgZ3JvdXAgdGl0bGUKICAgICAgICAgICAgdmFyIGRiS2V5ID0gIngtZ3JvdXAtdGl0bGUiOwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgZGJLZXksIGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICBpbnB1dC5kYXRhc2V0Lm9sZFZhbHVlID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLm0zdUdyb3VwVGl0bGUudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgaWYgKGRhdGFbImdyb3VwLXRpdGxlIl0gIT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKGRhdGFbImdyb3VwLXRpdGxlIl0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkYXRhWyJ4LXVwZGF0ZS1jaGFubmVsLWdyb3VwIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgaW5wdXQuZGlzYWJsZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFVwZGF0ZSBjaGFubmVsIGdyb3VwIGNoZWNrYm94CiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LXVwZGF0ZS1jaGFubmVsLWdyb3VwIjsKICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChkYktleSk7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdG9nZ2xlR3JvdXBVcGRhdGVDYignIiArIGlkICsgIicsIHRoaXMpOyIpOwogICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGNvbnRlbnQuYXBwZW5kUm93KCJ7ey5tYXBwaW5nLnVwZGF0ZUNoYW5uZWxHcm91cC50aXRsZX19IiwgaW5wdXQpOwogICAgICAgICAgICBjb250ZW50LmRlc2NyaXB0aW9uKCJ7ey5tYXBwaW5nLnVwZGF0ZUNoYW5uZWxHcm91cC5kZXNjcmlwdGlvbn19Iik7CiAgICAgICAgICAgIC8vIFhNTFRWIGZpbGUKICAgICAgICAgICAgdmFyIGRiS2V5ID0gJ3gteG1sdHYtZmlsZSc7CiAgICAgICAgICAgIGNvbnN0IHhtbFR2RmlsZSA9IGRhdGFbZGJLZXldOwogICAgICAgICAgICB2YXIgeG1sVHYgPSBuZXcgWE1MVFZGaWxlKCk7CiAgICAgICAgICAgIGNvbnN0IHhtbFR2RmlsZVNlbGVjdCA9IHhtbFR2LmdldEZpbGVzKGRhdGFbZGJLZXldKTsKICAgICAgICAgICAgeG1sVHZGaWxlU2VsZWN0LnNldEF0dHJpYnV0ZSgnbmFtZScsIGRiS2V5KTsKICAgICAgICAgICAgeG1sVHZGaWxlU2VsZWN0LnNldEF0dHJpYnV0ZSgnaWQnLCAncG9wdXAteG1sdHYnKTsKICAgICAgICAgICAgeG1sVHZGaWxlU2VsZWN0LnNldEF0dHJpYnV0ZSgnb25jaGFuZ2UnLCBgamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCc7IHNldFhtbHR2Q2hhbm5lbCgnJHtpZH0nLCB0aGlzKTtgKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coJ3t7Lm1hcHBpbmcueG1sdHZGaWxlLnRpdGxlfX0nLCB4bWxUdkZpbGVTZWxlY3QpOwogICAgICAgICAgICAvLyBYTUxUViBNYXBwaW5nCiAgICAgICAgICAgIHZhciBkYktleSA9ICd4LW1hcHBpbmcnOwogICAgICAgICAgICB2YXIgeG1sVHYgPSBuZXcgWE1MVFZGaWxlKCk7CiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRYbWxUdklkID0gZGF0YVtkYktleV07CiAgICAgICAgICAgIGNvbnN0IFt4bWxUdklkQ29udGFpbmVyLCB4bWxUdklkSW5wdXQsIHhtbFR2SWREYXRhbGlzdF0gPSB4bWxUdi5uZXdYbWxUdklkUGlja2VyKHhtbFR2RmlsZSwgY3VycmVudFhtbFR2SWQpOwogICAgICAgICAgICB4bWxUdklkQ29udGFpbmVyLnNldEF0dHJpYnV0ZSgnaWQnLCAneG1sdHYtaWQtcGlja2VyLWNvbnRhaW5lcicpOwogICAgICAgICAgICB4bWxUdklkSW5wdXQuc2V0QXR0cmlidXRlKCdsaXN0JywgJ3htbHR2LWlkLXBpY2tlci1kYXRhbGlzdCcpOwogICAgICAgICAgICB4bWxUdklkSW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3gtbWFwcGluZycpOyAvLyBTaG91bGQgc3RheSB4LW1hcHBpbmcgYXMgaXQgd2lsbCBiZSB1c2VkIGluIGRvbmVQb3B1cERhdGEgdG8gbWFrZSBhIHNlcnZlciByZXF1ZXN0CiAgICAgICAgICAgIHhtbFR2SWRJbnB1dC5zZXRBdHRyaWJ1dGUoJ2lkJywgJ3htbHR2LWlkLXBpY2tlci1pbnB1dCcpOwogICAgICAgICAgICB4bWxUdklkSW5wdXQuc2V0QXR0cmlidXRlKCdvbmNoYW5nZScsIGBqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJzsgY2hlY2tYbWx0dkNoYW5uZWwoJyR7aWR9JywgdGhpcy52YWx1ZSwgJyR7eG1sVHZGaWxlfScpO2ApOwogICAgICAgICAgICB4bWxUdklkRGF0YWxpc3Quc2V0QXR0cmlidXRlKCdpZCcsICd4bWx0di1pZC1waWNrZXItZGF0YWxpc3QnKTsKICAgICAgICAgICAgY29udGVudC5hcHBlbmRSb3coJ3t7Lm1hcHBpbmcueG1sdHZDaGFubmVsLnRpdGxlfX0nLCB4bWxUdklkQ29udGFpbmVyKTsKICAgICAgICAgICAgLy8gVGltZXNoaWZ0CiAgICAgICAgICAgIHZhciBkYktleSA9ICJ4LXRpbWVzaGlmdCI7CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCBkYktleSwgZGF0YVtkYktleV0pOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3subWFwcGluZy50aW1lc2hpZnQucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoImlkIiwgInRpbWVzaGlmdCIpOwogICAgICAgICAgICBjb250ZW50LmFwcGVuZFJvdygie3subWFwcGluZy50aW1lc2hpZnQudGl0bGV9fSIsIGlucHV0KTsKICAgICAgICAgICAgLy8gSW50ZXJhY3Rpb24KICAgICAgICAgICAgY29udGVudC5jcmVhdGVJbnRlcmFjdGlvbigpOwogICAgICAgICAgICAvLyBVcGxvYWQgbG9nbwogICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJidXR0b24iLCAiY2FuY2VsIiwgInt7LmJ1dHRvbi51cGxvYWRMb2dvfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IHVwbG9hZExvZ28oKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIC8vIEFib3J0CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJjYW5jZWwiLCAie3suYnV0dG9uLmNhbmNlbH19Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jbGljayIsICdqYXZhc2NyaXB0OiBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7Jyk7CiAgICAgICAgICAgIGNvbnRlbnQuYWRkSW50ZXJhY3Rpb24oaW5wdXQpOwogICAgICAgICAgICAvLyBGaW5pc2hlZAogICAgICAgICAgICB2YXIgaWRzID0gW107CiAgICAgICAgICAgIGlkcyA9IGdldEFsbFNlbGVjdGVkQ2hhbm5lbHMoKTsKICAgICAgICAgICAgaWYgKGlkcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgaWRzLnB1c2goaWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoImJ1dHRvbiIsICJzYXZlIiwgInt7LmJ1dHRvbi5kb25lfX0iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNsaWNrIiwgJ2phdmFzY3JpcHQ6IGRvbmVQb3B1cERhdGEoIicgKyBkYXRhVHlwZSArICciLCAiJyArIGlkcyArICciLCAiZmFsc2UiKTsnKTsKICAgICAgICAgICAgY29udGVudC5hZGRJbnRlcmFjdGlvbihpbnB1dCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgc2hvd1BvcFVwRWxlbWVudCgncG9wdXAtY3VzdG9tJyk7Cn0KY2xhc3MgWE1MVFZGaWxlIHsKICAgIGdldEZpbGVzKHNldCkgewogICAgICAgIGxldCBmaWxlSURzID0gZ2V0T3duT2JqUHJvcHMoU0VSVkVSWyJ4ZXBnIl1bInhtbHR2TWFwIl0pOwogICAgICAgIGxldCB2YWx1ZXMgPSBuZXcgQXJyYXkoIi0iKTsKICAgICAgICBsZXQgdGV4dCA9IG5ldyBBcnJheSgiLSIpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZUlEcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBpZiAoZmlsZUlEc1tpXSAhPSAieFRlVmUgRHVtbXkiKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChnZXRWYWx1ZUZyb21Qcm92aWRlckZpbGUoZmlsZUlEc1tpXSwgInhtbHR2IiwgImZpbGUueHRldmUiKSk7CiAgICAgICAgICAgICAgICB0ZXh0LnB1c2goZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKGZpbGVJRHNbaV0sICJ4bWx0diIsICJuYW1lIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFsdWVzLnB1c2goZmlsZUlEc1tpXSk7CiAgICAgICAgICAgICAgICB0ZXh0LnB1c2goZmlsZUlEc1tpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbGV0IHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlNFTEVDVCIpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiT1BUSU9OIik7CiAgICAgICAgICAgIG9wdGlvbi5zZXRBdHRyaWJ1dGUoInZhbHVlIiwgdmFsdWVzW2ldKTsKICAgICAgICAgICAgb3B0aW9uLmlubmVyVGV4dCA9IHRleHRbaV07CiAgICAgICAgICAgIHNlbGVjdC5hcHBlbmRDaGlsZChvcHRpb24pOwogICAgICAgIH0KICAgICAgICBpZiAoc2V0ICE9ICIiKSB7CiAgICAgICAgICAgIHNlbGVjdC52YWx1ZSA9IHNldDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGVjdDsKICAgIH0KICAgIC8qKgogICAgICogQHBhcmFtIHhtbFR2RmlsZSBYTUwgZmlsZSBwYXRoIHRvIGdldCBFUEcgZnJvbS4KICAgICAqIEBwYXJhbSBjdXJyZW50WG1sVHZJZCBDdXJyZW50IFhNTFRWIElEIHRvIHNldCBpbml0aWFsIGlucHV0IHZhbHVlIHRvLgogICAgICogQHJldHVybnMgQXJyYXkgb2YsIHNlcXVlbnRpYWxseToKICAgICAqIDEpIENvbnRhaW5lciBvZiB0aGUgcGlja2VyLgogICAgICogMikgSW5wdXQgZmllbGQgdG8gdHlwZSBhdCBhbmQgZ2V0IGNob2ljZSBmcm9tLgogICAgICogMykgRGF0YWxpc3QgY29udGFpbmluZyBldmVyeSBvcHRpb24uCiAgICAgKi8KICAgIG5ld1htbFR2SWRQaWNrZXIoeG1sVHZGaWxlLCBjdXJyZW50WG1sVHZJZCkgewogICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTsKICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAndGV4dCcpOwogICAgICAgIC8vIEluaXRpYWxseSwgc2V0IHZhbHVlIHRvICctJyBpZiBpbnB1dCBpcyBlbXB0eQogICAgICAgIGlucHV0LnZhbHVlID0gKGN1cnJlbnRYbWxUdklkKSA/IGN1cnJlbnRYbWxUdklkIDogJy0nOwogICAgICAgIC8vIFdoZW4gaW5wdXQgaXMgZm9jdXNlZCwgcmVtb3ZlICctJyBmcm9tIGl0CiAgICAgICAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCAoZXZ0KSA9PiB7CiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2dC50YXJnZXQ7CiAgICAgICAgICAgIHRhcmdldC52YWx1ZSA9ICh0YXJnZXQudmFsdWUgPT09ICctJykgPyAnJyA6IHRhcmdldC52YWx1ZTsKICAgICAgICB9KTsKICAgICAgICAvLyBXaGVuIGlucHV0IGxvc2UgZm9jdXMgb3IgdGFrZSBhIHZhbHVlLCBpZiBpdCdzIGVtcHR5LCBzZXQgdmFsdWUgdG8gJy0nCiAgICAgICAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIHNldEZhbGxiYWNrVmFsdWUpOwogICAgICAgIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHNldEZhbGxiYWNrVmFsdWUpOwogICAgICAgIGZ1bmN0aW9uIHNldEZhbGxiYWNrVmFsdWUoZXZ0KSB7CiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2dC50YXJnZXQ7CiAgICAgICAgICAgIHRhcmdldC52YWx1ZSA9ICh0YXJnZXQudmFsdWUpID8gdGFyZ2V0LnZhbHVlIDogJy0nOwogICAgICAgIH0KICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgIGNvbnN0IGRhdGFsaXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGF0YWxpc3QnKTsKICAgICAgICBjb25zdCBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTsKICAgICAgICBvcHRpb24uc2V0QXR0cmlidXRlKCd2YWx1ZScsICctJyk7CiAgICAgICAgb3B0aW9uLmlubmVyVGV4dCA9ICctJzsKICAgICAgICBkYXRhbGlzdC5hcHBlbmRDaGlsZChvcHRpb24pOwogICAgICAgIGNvbnN0IGVwZyA9IFNFUlZFUlsneGVwZyddWyd4bWx0dk1hcCddW3htbFR2RmlsZV07CiAgICAgICAgaWYgKGVwZykgewogICAgICAgICAgICBjb25zdCBwcm9ncmFtSWRzID0gZ2V0T3duT2JqUHJvcHMoZXBnKTsKICAgICAgICAgICAgcHJvZ3JhbUlkcy5mb3JFYWNoKChwcm9ncmFtSWQpID0+IHsKICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyYW0gPSBlcGdbcHJvZ3JhbUlkXTsKICAgICAgICAgICAgICAgIGlmIChwcm9ncmFtLmhhc093blByb3BlcnR5KCdkaXNwbGF5LW5hbWVzJykpIHsKICAgICAgICAgICAgICAgICAgICBwcm9ncmFtWydkaXNwbGF5LW5hbWVzJ10uZm9yRWFjaCgoZGlzcGxheU5hbWUpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbi5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgcHJvZ3JhbUlkKTsKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uLmlubmVyVGV4dCA9IGRpc3BsYXlOYW1lWydWYWx1ZSddOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhbGlzdC5hcHBlbmRDaGlsZChvcHRpb24pOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7CiAgICAgICAgICAgICAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgndmFsdWUnLCBwcm9ncmFtSWQpOwogICAgICAgICAgICAgICAgICAgIG9wdGlvbi5pbm5lclRleHQgPSAnLSc7CiAgICAgICAgICAgICAgICAgICAgZGF0YWxpc3QuYXBwZW5kQ2hpbGQob3B0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkYXRhbGlzdCk7CiAgICAgICAgcmV0dXJuIFtjb250YWluZXIsIGlucHV0LCBkYXRhbGlzdF07CiAgICB9Cn0KZnVuY3Rpb24gZ2V0VmFsdWVGcm9tUHJvdmlkZXJGaWxlKGZpbGUsIGZpbGVUeXBlLCBrZXkpIHsKICAgIGlmIChmaWxlID09ICJ4VGVWZSBEdW1teSIpIHsKICAgICAgICByZXR1cm4gZmlsZTsKICAgIH0KICAgIGxldCBmaWxlSUQ7CiAgICBsZXQgaW5kaWNhdG9yID0gZmlsZS5jaGFyQXQoMCk7CiAgICBzd2l0Y2ggKGluZGljYXRvcikgewogICAgICAgIGNhc2UgIk0iOgogICAgICAgICAgICBmaWxlVHlwZSA9ICJtM3UiOwogICAgICAgICAgICBmaWxlSUQgPSBmaWxlOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJIIjoKICAgICAgICAgICAgZmlsZVR5cGUgPSAiaGRociI7CiAgICAgICAgICAgIGZpbGVJRCA9IGZpbGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIlgiOgogICAgICAgICAgICBmaWxlVHlwZSA9ICJ4bWx0diI7CiAgICAgICAgICAgIGZpbGVJRCA9IGZpbGUuc3Vic3RyaW5nKDAsIGZpbGUubGFzdEluZGV4T2YoJy4nKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiZmlsZXMiXVtmaWxlVHlwZV0uaGFzT3duUHJvcGVydHkoZmlsZUlEKSA9PSB0cnVlKSB7CiAgICAgICAgdmFyIGRhdGEgPSBTRVJWRVJbInNldHRpbmdzIl1bImZpbGVzIl1bZmlsZVR5cGVdW2ZpbGVJRF07CiAgICAgICAgcmV0dXJuIGRhdGFba2V5XTsKICAgIH0KICAgIHJldHVybjsKfQpmdW5jdGlvbiBzZXRYbWx0dkNoYW5uZWwoZXBnTWFwSWQsIHhtbFR2RmlsZVNlbGVjdCkgewogICAgY29uc3QgeG1sVHYgPSBuZXcgWE1MVFZGaWxlKCk7CiAgICBjb25zdCBuZXdYbWxUdkZpbGUgPSB4bWxUdkZpbGVTZWxlY3QudmFsdWU7CiAgICAvLyBSZW1vdmUgb2xkIFhNTFRWIElEIHNlbGVjdGlvbiBib3gKICAgIGNvbnN0IHhtbFR2SWRQaWNrZXJQYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG1sdHYtaWQtcGlja2VyLWNvbnRhaW5lcicpLnBhcmVudEVsZW1lbnQ7CiAgICB4bWxUdklkUGlja2VyUGFyZW50LmlubmVySFRNTCA9ICcnOwogICAgLy8gQ3JlYXRlIG5ldyBYTUxUViBJRCBzZWxlY3Rpb24gYm94CiAgICBjb25zdCB0dmdJZCA9IFNFUlZFUlsneGVwZyddWydlcGdNYXBwaW5nJ11bZXBnTWFwSWRdWyd0dmctaWQnXTsKICAgIGNvbnN0IFt4bWxUdklkQ29udGFpbmVyLCB4bWxUdklkSW5wdXQsIHhtbFR2SWREYXRhbGlzdF0gPSB4bWxUdi5uZXdYbWxUdklkUGlja2VyKG5ld1htbFR2RmlsZSwgdHZnSWQpOwogICAgeG1sVHZJZENvbnRhaW5lci5zZXRBdHRyaWJ1dGUoJ2lkJywgJ3htbHR2LWlkLXBpY2tlci1jb250YWluZXInKTsKICAgIHhtbFR2SWRJbnB1dC5zZXRBdHRyaWJ1dGUoJ2xpc3QnLCAneG1sdHYtaWQtcGlja2VyLWRhdGFsaXN0Jyk7CiAgICB4bWxUdklkSW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3gtbWFwcGluZycpOyAvLyBTaG91bGQgc3RheSB4LW1hcHBpbmcgYXMgaXQgd2lsbCBiZSB1c2VkIGluIGRvbmVQb3B1cERhdGEgdG8gbWFrZSBhIHNlcnZlciByZXF1ZXN0CiAgICB4bWxUdklkSW5wdXQuc2V0QXR0cmlidXRlKCdpZCcsICd4bWx0di1pZC1waWNrZXItaW5wdXQnKTsKICAgIHhtbFR2SWRJbnB1dC5zZXRBdHRyaWJ1dGUoJ29uY2hhbmdlJywgYGphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnOyBjaGVja1htbHR2Q2hhbm5lbCgnJHtlcGdNYXBJZH0nLCB0aGlzLnZhbHVlLCAnJHtuZXdYbWxUdkZpbGV9Jyk7YCk7CiAgICB4bWxUdklkSW5wdXQuY2xhc3NMaXN0LmFkZCgnY2hhbmdlZCcpOwogICAgeG1sVHZJZERhdGFsaXN0LnNldEF0dHJpYnV0ZSgnaWQnLCAneG1sdHYtaWQtcGlja2VyLWRhdGFsaXN0Jyk7CiAgICAvLyBBZGQgbmV3IFhNTFRWIElEIHNlbGVjdGlvbiBib3ggdG8gaXQncyBwYXJlbnQKICAgIHhtbFR2SWRQaWNrZXJQYXJlbnQuYXBwZW5kQ2hpbGQoeG1sVHZJZENvbnRhaW5lcik7CiAgICBjaGVja1htbHR2Q2hhbm5lbChlcGdNYXBJZCwgeG1sVHZJZElucHV0LnZhbHVlLCBuZXdYbWxUdkZpbGUpOwp9CmZ1bmN0aW9uIGNoZWNrWG1sdHZDaGFubmVsKGVwZ01hcElkLCBuZXdYbWxUdklkLCB4bWxUdkZpbGUpIHsKICAgIGNvbnN0IGNoYW5uZWxBY3RpdmVDYiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhY3RpdmUnKTsKICAgIGNvbnN0IGNoYW5uZWxBY3RpdmUgPSBuZXdYbWxUdklkICE9ICctJzsKICAgIGNoYW5uZWxBY3RpdmVDYi5jaGVja2VkID0gY2hhbm5lbEFjdGl2ZTsKICAgIGNoYW5uZWxBY3RpdmVDYi5jbGFzc05hbWUgPSAnY2hhbmdlZCc7CiAgICBpZiAoeG1sVHZGaWxlICE9ICd4VGVWZSBEdW1teScgJiYgY2hhbm5lbEFjdGl2ZSA9PSB0cnVlKSB7CiAgICAgICAgY2hhbmdlQ2hhbm5lbExvZ28oZXBnTWFwSWQpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICh4bWxUdkZpbGUgPT0gJ3hUZVZlIER1bW15JykgewogICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGRhdGUtaWNvbicpLmNoZWNrZWQgPSBmYWxzZTsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlLWljb24nKS5jbGFzc05hbWUgPSAnY2hhbmdlZCc7CiAgICB9Cn0KZnVuY3Rpb24gY2hhbmdlQ2hhbm5lbExvZ28oZXBnTWFwSWQpIHsKICAgIGNvbnN0IGNoYW5uZWwgPSBTRVJWRVJbJ3hlcGcnXVsnZXBnTWFwcGluZyddW2VwZ01hcElkXTsKICAgIGNvbnN0IHhtbFR2RmlsZVNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwb3B1cC14bWx0dicpOwogICAgY29uc3QgeG1sVHZGaWxlID0geG1sVHZGaWxlU2VsZWN0Lm9wdGlvbnNbeG1sVHZGaWxlU2VsZWN0LnNlbGVjdGVkSW5kZXhdLnZhbHVlOwogICAgY29uc3QgeG1sVHZJZElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3htbHR2LWlkLXBpY2tlci1pbnB1dCcpOwogICAgY29uc3QgbmV3WG1sVHZJZCA9IHhtbFR2SWRJbnB1dC52YWx1ZTsKICAgIGNvbnN0IHVwZGF0ZUxvZ28gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBkYXRlLWljb24nKS5jaGVja2VkOwogICAgbGV0IGxvZ287CiAgICBpZiAodXBkYXRlTG9nbyA9PSB0cnVlICYmIHhtbFR2RmlsZSAhPSAneFRlVmUgRHVtbXknKSB7CiAgICAgICAgaWYgKFNFUlZFUlsneGVwZyddWyd4bWx0dk1hcCddW3htbFR2RmlsZV0uaGFzT3duUHJvcGVydHkobmV3WG1sVHZJZCkpIHsKICAgICAgICAgICAgbG9nbyA9IFNFUlZFUlsneGVwZyddWyd4bWx0dk1hcCddW3htbFR2RmlsZV1bbmV3WG1sVHZJZF1bJ2ljb24nXTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxvZ28gPSBjaGFubmVsWyd0dmctbG9nbyddOwogICAgICAgIH0KICAgICAgICB2YXIgbG9nb0lucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoYW5uZWwtaWNvbicpOwogICAgICAgIGxvZ29JbnB1dC52YWx1ZSA9IGxvZ287CiAgICAgICAgaWYgKEJVTEtfRURJVCA9PSBmYWxzZSkgewogICAgICAgICAgICBsb2dvSW5wdXQuY2xhc3NOYW1lID0gJ2NoYW5nZWQnOwogICAgICAgIH0KICAgIH0KfQpmdW5jdGlvbiBzYXZlUG9wdXBEYXRhKGRhdGFUeXBlLCBpZCwgcmVtb3ZlLCBvcHRpb24pIHsKICAgIGlmIChkYXRhVHlwZSA9PSAibWFwcGluZyIpIHsKICAgICAgICBsZXQgZGF0YSA9IHt9OwogICAgICAgIGxldCBjbWQgPSAic2F2ZUVwZ01hcHBpbmciOwogICAgICAgIGRhdGFbImVwZ01hcHBpbmciXSA9IFNFUlZFUlsieGVwZyJdWyJlcGdNYXBwaW5nIl07CiAgICAgICAgbGV0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgICAgICBzZXJ2ZXIucmVxdWVzdChkYXRhKTsKICAgICAgICBkZWxldGUgVU5ET1siZXBnTWFwcGluZyJdOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicG9wdXAtY3VzdG9tIik7CiAgICBsZXQgaW5wdXRzID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUQUJMRSIpWzBdLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJTlBVVCIpOwogICAgbGV0IHNlbGVjdHMgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRBQkxFIilbMF0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlNFTEVDVCIpOwogICAgbGV0IGlucHV0ID0ge307CiAgICBsZXQgY29uZmlybU1zZzsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0cy5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciBuYW1lOwogICAgICAgIG5hbWUgPSBzZWxlY3RzW2ldLm5hbWU7CiAgICAgICAgdmFyIHZhbHVlID0gc2VsZWN0c1tpXS52YWx1ZTsKICAgICAgICBzd2l0Y2ggKG5hbWUpIHsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgaW5wdXRbbmFtZV0gPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIHN3aXRjaCAoaW5wdXRzW2ldLnR5cGUpIHsKICAgICAgICAgICAgY2FzZSAiY2hlY2tib3giOgogICAgICAgICAgICAgICAgbmFtZSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgICAgICAgICAgaW5wdXRbbmFtZV0gPSBpbnB1dHNbaV0uY2hlY2tlZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICAgICAgY2FzZSAiaGlkZGVuIjoKICAgICAgICAgICAgY2FzZSAicGFzc3dvcmQiOgogICAgICAgICAgICAgICAgbmFtZSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgICAgICAgICAgc3dpdGNoIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IHBhcnNlSW50KGlucHV0c1tpXS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gaW5wdXRzW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGxldCBkYXRhID0ge307CiAgICBsZXQgY21kOwogICAgaWYgKHJlbW92ZSA9PSB0cnVlKSB7CiAgICAgICAgaW5wdXRbImRlbGV0ZSJdID0gdHJ1ZTsKICAgIH0KICAgIHN3aXRjaCAoZGF0YVR5cGUpIHsKICAgICAgICBjYXNlICJ1c2VycyI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgdXNlcj8iOwogICAgICAgICAgICBpZiAoaWQgPT0gIi0iKSB7CiAgICAgICAgICAgICAgICBjbWQgPSAic2F2ZU5ld1VzZXIiOwogICAgICAgICAgICAgICAgZGF0YVsidXNlckRhdGEiXSA9IGlucHV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgY21kID0gInNhdmVVc2VyRGF0YSI7CiAgICAgICAgICAgICAgICBsZXQgZCA9IHt9OwogICAgICAgICAgICAgICAgZFtpZF0gPSBpbnB1dDsKICAgICAgICAgICAgICAgIGRhdGFbInVzZXJEYXRhIl0gPSBkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIm0zdSI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgcGxheWxpc3Q/IjsKICAgICAgICAgICAgc3dpdGNoIChvcHRpb24pIHsKICAgICAgICAgICAgICAgIC8vIFBvcHVwOiBTYXZlCiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInNhdmVGaWxlc00zVSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvLyBQb3B1cDogVXBkYXRlCiAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInVwZGF0ZUZpbGVNM1UiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl0gPSB7fTsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV0gPSB7fTsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdID0gaW5wdXQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgImhkaHIiOgogICAgICAgICAgICBjb25maXJtTXNnID0gIkRlbGV0ZSB0aGlzIEhESG9tZVJ1biB0dW5lcj8iOwogICAgICAgICAgICBzd2l0Y2ggKG9wdGlvbikgewogICAgICAgICAgICAgICAgLy8gUG9wdXA6IFNhdmUKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBjbWQgPSAic2F2ZUZpbGVzSERIUiI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvLyBQb3B1cDogVXBkYXRlCiAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgY21kID0gInVwZGF0ZUZpbGVIREhSIjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRhWyJmaWxlcyJdID0ge307CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl1bZGF0YVR5cGVdID0ge307CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl1bZGF0YVR5cGVdW2lkXSA9IGlucHV0OwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJ4bWx0diI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgWE1MVFYgZmlsZT8iOwogICAgICAgICAgICBzd2l0Y2ggKG9wdGlvbikgewogICAgICAgICAgICAgICAgLy8gUG9wdXA6IFNhdmUKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBjbWQgPSAic2F2ZUZpbGVzWE1MVFYiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgLy8gUG9wdXA6IFVwZGF0ZQogICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgIGNtZCA9ICJ1cGRhdGVGaWxlWE1MVFYiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGFbImZpbGVzIl0gPSB7fTsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV0gPSB7fTsKICAgICAgICAgICAgZGF0YVsiZmlsZXMiXVtkYXRhVHlwZV1baWRdID0gaW5wdXQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgImZpbHRlciI6CiAgICAgICAgICAgIGNvbmZpcm1Nc2cgPSAiRGVsZXRlIHRoaXMgZmlsdGVyPyI7CiAgICAgICAgICAgIGNtZCA9ICJzYXZlRmlsdGVyIjsKICAgICAgICAgICAgZGF0YVsiZmlsdGVyIl0gPSB7fTsKICAgICAgICAgICAgZGF0YVsiZmlsdGVyIl1baWRdID0gaW5wdXQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChyZW1vdmUgPT0gdHJ1ZSkgewogICAgICAgIGlmICghY29uZmlybShjb25maXJtTXNnKSkgewogICAgICAgICAgICBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBsZXQgc2VydmVyID0gbmV3IFNlcnZlcihjbWQpOwogICAgc2VydmVyLnJlcXVlc3QoZGF0YSk7Cn0KZnVuY3Rpb24gZG9uZVBvcHVwRGF0YShkYXRhVHlwZSwgaWRzU3RyKSB7CiAgICBsZXQgaWRzID0gaWRzU3RyLnNwbGl0KCcsJyk7CiAgICBsZXQgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInBvcHVwLWN1c3RvbSIpOwogICAgbGV0IGlucHV0cyA9IGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJjaGFuZ2VkIik7CiAgICBpZHMuZm9yRWFjaChpZCA9PiB7CiAgICAgICAgbGV0IGlucHV0OwogICAgICAgIGlucHV0ID0gU0VSVkVSWyJ4ZXBnIl1bImVwZ01hcHBpbmciXVtpZF07CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgbGV0IG5hbWU7CiAgICAgICAgICAgIGxldCB2YWx1ZTsKICAgICAgICAgICAgc3dpdGNoIChpbnB1dHNbaV0udGFnTmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSAiSU5QVVQiOgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoaW5wdXRzW2ldLnR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2hlY2tib3giOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGlucHV0c1tpXS5uYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBpbnB1dHNbaV0uY2hlY2tlZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gaW5wdXRzW2ldLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0W25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJTRUxFQ1QiOgogICAgICAgICAgICAgICAgICAgIG5hbWUgPSBpbnB1dHNbaV0ubmFtZTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGlucHV0c1tpXS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICBpbnB1dFtuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAobmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSAidHZnLWxvZ28iOgogICAgICAgICAgICAgICAgICAgIC8vKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzJdLmZpcnN0Q2hpbGQgYXMgSFRNTEVsZW1lbnQpLnNldEF0dHJpYnV0ZSgic3JjIiwgdmFsdWUpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ4LW5hbWUiOgogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzNdLmZpcnN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ4LWNhdGVnb3J5IjoKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1szXS5maXJzdENoaWxkLmNsYXNzTmFtZSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAidXBkYXRlLWNoYW5uZWwtbmFtZS1yZWdleCI6CiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNoaWxkTm9kZXNbNF0uZmlyc3RDaGlsZC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIngtZ3JvdXAtdGl0bGUiOgogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzZdLmZpcnN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ4LXhtbHR2LWZpbGUiOgogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSAieFRlVmUgRHVtbXkiICYmIHZhbHVlICE9ICItIikgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGdldFZhbHVlRnJvbVByb3ZpZGVyRmlsZSh2YWx1ZSwgInhtbHR2IiwgIm5hbWUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09ICItIikgewogICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFsieC1hY3RpdmUiXSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1s3XS5maXJzdENoaWxkLmlubmVySFRNTCA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieC1tYXBwaW5nIjoKICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gIi0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0WyJ4LWFjdGl2ZSJdID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5jaGlsZE5vZGVzWzhdLmZpcnN0Q2hpbGQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ4LXRpbWVzaGlmdCI6CiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNoaWxkTm9kZXNbOV0uZmlyc3RDaGlsZC5pbm5lckhUTUwgPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3JlYXRlU2VhcmNoT2JqKCk7CiAgICAgICAgICAgIHNlYXJjaEluTWFwcGluZygpOwogICAgICAgIH0KICAgICAgICBpZiAoaW5wdXRbIngtYWN0aXZlIl0gPT0gZmFsc2UpIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsYXNzTmFtZSA9ICJub3RBY3RpdmVFUEciOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmNsYXNzTmFtZSA9ICJhY3RpdmVFUEciOwogICAgICAgIH0KICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuY2hpbGROb2Rlc1syXS5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSgic3JjIiwgaW5wdXRbInR2Zy1sb2dvIl0pOwogICAgfSk7CiAgICBzaG93RWxlbWVudCgicG9wdXAiLCBmYWxzZSk7CiAgICByZXR1cm47Cn0KZnVuY3Rpb24gc2hvd1ByZXZpZXcoZWxlbWVudCkgewogICAgbGV0IGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJteVN0cmVhbXNCb3giKTsKICAgIHN3aXRjaCAoZWxlbWVudCkgewogICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgIGRpdi5jbGFzc05hbWUgPSAibm90VmlzaWJsZSI7CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBzdHJlYW1zID0gWyJhY3RpdmVTdHJlYW1zIiwgImluYWN0aXZlU3RyZWFtcyJdOwogICAgc3RyZWFtcy5mb3JFYWNoKHByZXZpZXcgPT4gewogICAgICAgIGxldCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHByZXZpZXcpOwogICAgICAgIHRhYmxlLmlubmVySFRNTCA9ICIiOwogICAgICAgIGxldCBvYmogPSBTRVJWRVJbImRhdGEiXVsiU3RyZWFtUHJldmlld1VJIl1bcHJldmlld107CiAgICAgICAgb2JqLmZvckVhY2goY2hhbm5lbCA9PiB7CiAgICAgICAgICAgIGxldCB0ciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRSIik7CiAgICAgICAgICAgIGxldCB0ZEtleSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgIGxldCB0ZFZhbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgIHRkS2V5LmNsYXNzTmFtZSA9ICJ0ZEtleSI7CiAgICAgICAgICAgIHRkVmFsLmNsYXNzTmFtZSA9ICJ0ZFZhbCI7CiAgICAgICAgICAgIHN3aXRjaCAocHJldmlldykgewogICAgICAgICAgICAgICAgY2FzZSAiYWN0aXZlU3RyZWFtcyI6CiAgICAgICAgICAgICAgICAgICAgdGRLZXkuaW5uZXJUZXh0ID0gIkNoYW5uZWw6ICgrKSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJpbmFjdGl2ZVN0cmVhbXMiOgogICAgICAgICAgICAgICAgICAgIHRkS2V5LmlubmVyVGV4dCA9ICJDaGFubmVsOiAoLSkiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRkVmFsLmlubmVyVGV4dCA9IGNoYW5uZWw7CiAgICAgICAgICAgIHRyLmFwcGVuZENoaWxkKHRkS2V5KTsKICAgICAgICAgICAgdHIuYXBwZW5kQ2hpbGQodGRWYWwpOwogICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZCh0cik7CiAgICAgICAgfSk7CiAgICB9KTsKICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgZmFsc2UpOwogICAgZGl2LmNsYXNzTmFtZSA9ICJ2aXNpYmxlIjsKICAgIHJldHVybjsKfQo="
+ webUI["html/js/network_ts.js"] = "Y2xhc3MgU2VydmVyIHsKICAgIGNvbnN0cnVjdG9yKGNtZCkgewogICAgICAgIHRoaXMuY21kID0gY21kOwogICAgfQogICAgcmVxdWVzdChkYXRhKSB7CiAgICAgICAgaWYgKFNFUlZFUl9DT05ORUNUSU9OID09IHRydWUpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfQ09OTkVDVElPTiA9IHRydWU7CiAgICAgICAgaWYgKHRoaXMuY21kICE9ICJ1cGRhdGVMb2ciKSB7CiAgICAgICAgICAgIHNob3dFbGVtZW50KCJsb2FkaW5nIiwgdHJ1ZSk7CiAgICAgICAgICAgIFVORE8gPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAod2luZG93LmxvY2F0aW9uLnByb3RvY29sKSB7CiAgICAgICAgICAgIGNhc2UgImh0dHA6IjoKICAgICAgICAgICAgICAgIHRoaXMucHJvdG9jb2wgPSAid3M6Ly8iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImh0dHBzOiI6CiAgICAgICAgICAgICAgICB0aGlzLnByb3RvY29sID0gIndzczovLyI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHVybCA9IHRoaXMucHJvdG9jb2wgKyB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgKyAiOiIgKyB3aW5kb3cubG9jYXRpb24ucG9ydCArICIvZGF0YS8iICsgIj9Ub2tlbj0iICsgZ2V0Q29va2llKCJUb2tlbiIpOwogICAgICAgIGRhdGFbImNtZCJdID0gdGhpcy5jbWQ7CiAgICAgICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh1cmwpOwogICAgICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgV1NfQVZBSUxBQkxFID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5zZW5kKEpTT04uc3RyaW5naWZ5KGRhdGEpKTsKICAgICAgICB9OwogICAgICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAod3NFcnJFdnQpIHsKICAgICAgICAgICAgY29uc29sZS5sb2coIk5vIHdlYnNvY2tldCBjb25uZWN0aW9uIHRvIHhUZVZlIGNvdWxkIGJlIGVzdGFibGlzaGVkLiBDaGVjayB5b3VyIG5ldHdvcmsgY29uZmlndXJhdGlvbi4iKTsKICAgICAgICAgICAgU0VSVkVSX0NPTk5FQ1RJT04gPSBmYWxzZTsKICAgICAgICAgICAgaWYgKFdTX0FWQUlMQUJMRSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYWxlcnQoIk5vIHdlYnNvY2tldCBjb25uZWN0aW9uIHRvIHhUZVZlIGNvdWxkIGJlIGVzdGFibGlzaGVkLiBDaGVjayB5b3VyIG5ldHdvcmsgY29uZmlndXJhdGlvbi4iKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgd3Mub25tZXNzYWdlID0gZnVuY3Rpb24gKHdzTWVzc2FnZUV2dCkgewogICAgICAgICAgICBTRVJWRVJfQ09OTkVDVElPTiA9IGZhbHNlOwogICAgICAgICAgICBzaG93RWxlbWVudCgibG9hZGluZyIsIGZhbHNlKTsKICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBKU09OLnBhcnNlKHdzTWVzc2FnZUV2dC5kYXRhKTsKICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJ0b2tlbiIpKSB7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5jb29raWUgPSAiVG9rZW49IiArIHJlc3BvbnNlWyJ0b2tlbiJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXNwb25zZVsic3RhdHVzIl0gPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3BvbnNlWyJlcnIiXSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCdvcGVuTGluaycpKSB7CiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24gPSByZXNwb25zZVsnb3BlbkxpbmsnXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoInJlbG9hZCIpKSB7CiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJhbGVydCIpKSB7CiAgICAgICAgICAgICAgICBhbGVydChyZXNwb25zZVsiYWxlcnQiXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJsb2dvVVJMIikpIHsKICAgICAgICAgICAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY2hhbm5lbC1pY29uIik7CiAgICAgICAgICAgICAgICBkaXYudmFsdWUgPSByZXNwb25zZVsibG9nb1VSTCJdOwogICAgICAgICAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICJjaGFuZ2VkIjsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKGRhdGFbImNtZCJdKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ1cGRhdGVMb2ciOgogICAgICAgICAgICAgICAgICAgIFNFUlZFUlsibG9nIl0gPSByZXNwb25zZVsibG9nIl07CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X2xvZyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dMb2dzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBTRVJWRVIgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSID0gcmVzcG9uc2U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhhc093blByb3BlcnR5KCJvcGVuTWVudSIpKSB7CiAgICAgICAgICAgICAgICB2YXIgbWVudSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJlc3BvbnNlWyJvcGVuTWVudSJdKTsKICAgICAgICAgICAgICAgIG1lbnUuY2xpY2soKTsKICAgICAgICAgICAgICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoInJlbG9hZCIpKSB7CiAgICAgICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocmVzcG9uc2UuaGFzT3duUHJvcGVydHkoIndpemFyZCIpKSB7CiAgICAgICAgICAgICAgICBjcmVhdGVMYXlvdXQoKTsKICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb25XaXphcmRbcmVzcG9uc2VbIndpemFyZCJdXS5jcmVhdGVXaXphcmQoKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBjcmVhdGVMYXlvdXQoKTsKICAgICAgICB9OwogICAgfQp9CmZ1bmN0aW9uIGdldENvb2tpZShuYW1lKSB7CiAgICB2YXIgdmFsdWUgPSAiOyAiICsgZG9jdW1lbnQuY29va2llOwogICAgdmFyIHBhcnRzID0gdmFsdWUuc3BsaXQoIjsgIiArIG5hbWUgKyAiPSIpOwogICAgaWYgKHBhcnRzLmxlbmd0aCA9PSAyKSB7CiAgICAgICAgcmV0dXJuIHBhcnRzLnBvcCgpLnNwbGl0KCI7Iikuc2hpZnQoKTsKICAgIH0KfQo="
+ webUI["html/js/settings_ts.js"] = "Y2xhc3MgU2V0dGluZ3NDYXRlZ29yeSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgICB0aGlzLkRvY3VtZW50SUQgPSAiY29udGVudF9zZXR0aW5ncyI7CiAgICB9CiAgICBjcmVhdGVDYXRlZ29yeUhlYWRsaW5lKHZhbHVlKSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJINCIpOwogICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CiAgICBjcmVhdGVIUigpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkhSIik7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CiAgICBjcmVhdGVTZXR0aW5ncyhzZXR0aW5nc0tleSkgewogICAgICAgIHZhciBzZXR0aW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICB2YXIgY29udGVudCA9IG5ldyBQb3B1cENvbnRlbnQoKTsKICAgICAgICB2YXIgZGF0YSA9IFNFUlZFUlsic2V0dGluZ3MiXVtzZXR0aW5nc0tleV07CiAgICAgICAgc3dpdGNoIChzZXR0aW5nc0tleSkgewogICAgICAgICAgICAvLyBUZXh0IGlucHV0cwogICAgICAgICAgICBjYXNlICJ1cGRhdGUiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnVwZGF0ZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidXBkYXRlIiwgZGF0YS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudXBkYXRlLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJiYWNrdXAucGF0aCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYmFja3VwUGF0aC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAiYmFja3VwLnBhdGgiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MuYmFja3VwUGF0aC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidGVtcC5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy50ZW1wUGF0aC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidGVtcC5wYXRoIiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnRtcFBhdGgucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInVzZXIuYWdlbnQiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnVzZXJBZ2VudC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidXNlci5hZ2VudCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy51c2VyQWdlbnQucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJ1ZmZlci50aW1lb3V0IjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5idWZmZXJUaW1lb3V0LnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJidWZmZXIudGltZW91dCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy5idWZmZXJUaW1lb3V0LnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmZm1wZWcucGF0aCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuZmZtcGVnUGF0aC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAiZmZtcGVnLnBhdGgiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MuZmZtcGVnUGF0aC5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmZtcGVnLm9wdGlvbnMiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmZmbXBlZ09wdGlvbnMudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgImZmbXBlZy5vcHRpb25zIiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLmZmbXBlZ09wdGlvbnMucGxhY2Vob2xkZXJ9fSIpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInZsYy5wYXRoIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy52bGNQYXRoLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJ2bGMucGF0aCIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy52bGNQYXRoLnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ2bGMub3B0aW9ucyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudmxjT3B0aW9ucy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlSW5wdXQoInRleHQiLCAidmxjLm9wdGlvbnMiLCBkYXRhKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiLCAie3suc2V0dGluZ3MudmxjT3B0aW9ucy5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgLy8gQ2hlY2tib3hlcwogICAgICAgICAgICBjYXNlICJ0bHNNb2RlIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy50bHNNb2RlLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJkaXNhbGxvd1VSTER1cGxpY2F0ZXMiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmRpc2FsbG93VVJMRHVwbGljYXRlcy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ud2ViIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbldFQi50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ucG1zIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvblBNUy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ubTN1IjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbk0zVS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ueG1sIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvblhNTC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24uYXBpIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbkFQSS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmlsZXMudXBkYXRlIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5maWxlc1VwZGF0ZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiY2FjaGUuaW1hZ2VzIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5jYWNoZUltYWdlcy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieGVwZy5yZXBsYWNlLm1pc3NpbmcuaW1hZ2VzIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5yZXBsYWNlRW1wdHlJbWFnZXMudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInN0b3JlQnVmZmVySW5SQU0iOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnN0b3JlQnVmZmVySW5SQU0udGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInh0ZXZlQXV0b1VwZGF0ZSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MueHRldmVBdXRvVXBkYXRlLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVDaGVja2JveChzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBpbnB1dC5jaGVja2VkID0gZGF0YTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJjbGVhclhNTFRWQ2FjaGUiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmNsZWFyWE1MVFZDYWNoZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYXBpIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5hcGkudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUNoZWNrYm94KHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgIGlucHV0LmNoZWNrZWQgPSBkYXRhOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChpbnB1dCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgICAgICAgICBzZXR0aW5nLmFwcGVuZENoaWxkKHRkUmlnaHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImVuYWJsZU1hcHBlZENoYW5uZWxzIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5lbmFibGVNYXBwZWRDaGFubmVscy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGNvbnRlbnQuY3JlYXRlQ2hlY2tib3goc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGRhdGE7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgLy8gU2VsZWN0CiAgICAgICAgICAgIGNhc2UgImhvc3RJUCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuaG9zdElQLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBTRVJWRVJbImlwQWRkcmVzc2VzVjRIb3N0Il07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gU0VSVkVSWyJpcEFkZHJlc3Nlc1Y0SG9zdCJdOwogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgZGF0YSwgc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiaG9zdE5hbWUiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLmhvc3ROYW1lLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gY29udGVudC5jcmVhdGVJbnB1dCgidGV4dCIsICJob3N0TmFtZSIsIGRhdGEpOwogICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIsICJ7ey5zZXR0aW5ncy5ob3N0TmFtZS5wbGFjZWhvbGRlcn19Iik7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoIm9uY2hhbmdlIiwgImphdmFzY3JpcHQ6IHRoaXMuY2xhc3NOYW1lID0gJ2NoYW5nZWQnIik7CiAgICAgICAgICAgICAgICB0ZFJpZ2h0LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidHVuZXIiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnR1bmVyLnRpdGxlfX0iICsgIjoiOwogICAgICAgICAgICAgICAgdmFyIHRkUmlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdmFyIHRleHQgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IDEwMDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dC5wdXNoKGkpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdCA9IGNvbnRlbnQuY3JlYXRlU2VsZWN0KHRleHQsIHZhbHVlcywgZGF0YSwgc2V0dGluZ3NLZXkpOwogICAgICAgICAgICAgICAgc2VsZWN0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoc2VsZWN0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRMZWZ0KTsKICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZXBnU291cmNlIjoKICAgICAgICAgICAgICAgIHZhciB0ZExlZnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJURCIpOwogICAgICAgICAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICJ7ey5zZXR0aW5ncy5lcGdTb3VyY2UudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFsiUE1TIiwgIlhFUEciXTsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBbIlBNUyIsICJYRVBHIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJkZWZhdWx0TWlzc2luZ0VQRyI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuZGVmYXVsdE1pc3NpbmdFUEcudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgdGV4dCA9IFsKICAgICAgICAgICAgICAgICAgICAiLSIsICIzMCBNaW51dGVzICgzMF9NaW51dGVzKSIsICI2MCBNaW51dGVzICg2MF9NaW51dGVzKSIsICI5MCBNaW51dGVzICg5MF9NaW51dGVzKSIsCiAgICAgICAgICAgICAgICAgICAgIjEyMCBNaW51dGVzICgxMjBfTWludXRlcykiLCAiMTgwIE1pbnV0ZXMgKDE4MF9NaW51dGVzKSIsICIyNDAgTWludXRlcyAoMjQwX01pbnV0ZXMpIiwgIjM2MCBNaW51dGVzICgzNjBfTWludXRlcykiCiAgICAgICAgICAgICAgICBdOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFsKICAgICAgICAgICAgICAgICAgICAiLSIsICIzMF9NaW51dGVzIiwgIjYwX01pbnV0ZXMiLCAiOTBfTWludXRlcyIsICIxMjBfTWludXRlcyIsICIxODBfTWludXRlcyIsICIyNDBfTWludXRlcyIsICIzNjBfTWludXRlcyIKICAgICAgICAgICAgICAgIF07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJiYWNrdXAua2VlcCI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYmFja3VwS2VlcC50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gWyI1IiwgIjEwIiwgIjIwIiwgIjMwIiwgIjQwIiwgIjUwIl07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gWyI1IiwgIjEwIiwgIjIwIiwgIjMwIiwgIjQwIiwgIjUwIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJidWZmZXIuc2l6ZS5rYiI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MuYnVmZmVyU2l6ZS50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gWyIwLjUgTUIiLCAiMSBNQiIsICIyIE1CIiwgIjMgTUIiLCAiNCBNQiIsICI1IE1CIiwgIjYgTUIiLCAiNyBNQiIsICI4IE1CIl07CiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gWyI1MTIiLCAiMTAyNCIsICIyMDQ4IiwgIjMwNzIiLCAiNDA5NiIsICI1MTIwIiwgIjYxNDQiLCAiNzE2OCIsICI4MTkyIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJidWZmZXIiOgogICAgICAgICAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB0ZExlZnQuaW5uZXJIVE1MID0gInt7LnNldHRpbmdzLnN0cmVhbUJ1ZmZlcmluZy50aXRsZX19IiArICI6IjsKICAgICAgICAgICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0ID0gWyJ7ey5zZXR0aW5ncy5zdHJlYW1CdWZmZXJpbmcuaW5mb19mYWxzZX19IiwgInhUZVZlOiAoe3suc2V0dGluZ3Muc3RyZWFtQnVmZmVyaW5nLmluZm9feHRldmV9fSkiLCAiRkZtcGVnOiAoe3suc2V0dGluZ3Muc3RyZWFtQnVmZmVyaW5nLmluZm9fZmZtcGVnfX0pIiwgIlZMQzogKHt7LnNldHRpbmdzLnN0cmVhbUJ1ZmZlcmluZy5pbmZvX3ZsY319KSJdOwogICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFsiLSIsICJ4dGV2ZSIsICJmZm1wZWciLCAidmxjIl07CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ID0gY29udGVudC5jcmVhdGVTZWxlY3QodGV4dCwgdmFsdWVzLCBkYXRhLCBzZXR0aW5nc0tleSk7CiAgICAgICAgICAgICAgICBzZWxlY3Quc2V0QXR0cmlidXRlKCJvbmNoYW5nZSIsICJqYXZhc2NyaXB0OiB0aGlzLmNsYXNzTmFtZSA9ICdjaGFuZ2VkJyIpOwogICAgICAgICAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChzZWxlY3QpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1ZHB4eSI6CiAgICAgICAgICAgICAgICB2YXIgdGRMZWZ0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICAgICAgICAgIHRkTGVmdC5pbm5lckhUTUwgPSAie3suc2V0dGluZ3MudWRweHkudGl0bGV9fSIgKyAiOiI7CiAgICAgICAgICAgICAgICB2YXIgdGRSaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSBjb250ZW50LmNyZWF0ZUlucHV0KCJ0ZXh0IiwgInVkcHh5IiwgZGF0YSk7CiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgInt7LnNldHRpbmdzLnVkcHh5LnBsYWNlaG9sZGVyfX0iKTsKICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgib25jaGFuZ2UiLCAiamF2YXNjcmlwdDogdGhpcy5jbGFzc05hbWUgPSAnY2hhbmdlZCciKTsKICAgICAgICAgICAgICAgIHRkUmlnaHQuYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZExlZnQpOwogICAgICAgICAgICAgICAgc2V0dGluZy5hcHBlbmRDaGlsZCh0ZFJpZ2h0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0dGluZzsKICAgIH0KICAgIGNyZWF0ZURlc2NyaXB0aW9uKHNldHRpbmdzS2V5KSB7CiAgICAgICAgdmFyIGRlc2NyaXB0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVFIiKTsKICAgICAgICB2YXIgdGV4dDsKICAgICAgICBzd2l0Y2ggKHNldHRpbmdzS2V5KSB7CiAgICAgICAgICAgIGNhc2UgInRsc01vZGUiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy50bHNNb2RlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImRpc2FsbG93VVJMRHVwbGljYXRlcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmRpc2FsbG93VVJMRHVwbGljYXRlcy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi53ZWIiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbldFQi5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi5tM3UiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvbk0zVS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi5wbXMiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvblBNUy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi54bWwiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hdXRoZW50aWNhdGlvblhNTC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi5hcGkiOgogICAgICAgICAgICAgICAgaWYgKFNFUlZFUlsic2V0dGluZ3MiXVsiYXV0aGVudGljYXRpb24ud2ViIl0gPT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYXV0aGVudGljYXRpb25BUEkuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAieHRldmVBdXRvVXBkYXRlIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MueHRldmVBdXRvVXBkYXRlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJhY2t1cC5rZWVwIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYmFja3VwS2VlcC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJiYWNrdXAucGF0aCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmJhY2t1cFBhdGguZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidGVtcC5wYXRoIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudGVtcFBhdGguZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiYnVmZmVyIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3Muc3RyZWFtQnVmZmVyaW5nLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImJ1ZmZlci5zaXplLmtiIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuYnVmZmVyU2l6ZS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJzdG9yZUJ1ZmZlckluUkFNIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3Muc3RvcmVCdWZmZXJJblJBTS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJidWZmZXIudGltZW91dCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmJ1ZmZlclRpbWVvdXQuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidXNlci5hZ2VudCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnVzZXJBZ2VudC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJmZm1wZWcucGF0aCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmZmbXBlZ1BhdGguZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZmZtcGVnLm9wdGlvbnMiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5mZm1wZWdPcHRpb25zLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInZsYy5wYXRoIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudmxjUGF0aC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ2bGMub3B0aW9ucyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnZsY09wdGlvbnMuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZXBnU291cmNlIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MuZXBnU291cmNlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImhvc3RJUCI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmhvc3RJUC5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJob3N0TmFtZSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmhvc3ROYW1lLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInR1bmVyIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudHVuZXIuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAidXBkYXRlIjoKICAgICAgICAgICAgICAgIHRleHQgPSAie3suc2V0dGluZ3MudXBkYXRlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImNsZWFyWE1MVFZDYWNoZSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmNsZWFyWE1MVFZDYWNoZS5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJhcGkiOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5hcGkuZGVzY3JpcHRpb259fSI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAiZGVmYXVsdE1pc3NpbmdFUEciOgogICAgICAgICAgICAgICAgdGV4dCA9ICJ7ey5zZXR0aW5ncy5kZWZhdWx0TWlzc2luZ0VQRy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJlbmFibGVNYXBwZWRDaGFubmVscyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmVuYWJsZU1hcHBlZENoYW5uZWxzLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImZpbGVzLnVwZGF0ZSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmZpbGVzVXBkYXRlLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImNhY2hlLmltYWdlcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLmNhY2hlSW1hZ2VzLmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgInhlcGcucmVwbGFjZS5taXNzaW5nLmltYWdlcyI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnJlcGxhY2VFbXB0eUltYWdlcy5kZXNjcmlwdGlvbn19IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJ1ZHB4eSI6CiAgICAgICAgICAgICAgICB0ZXh0ID0gInt7LnNldHRpbmdzLnVkcHh5LmRlc2NyaXB0aW9ufX0iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0ZXh0ID0gIiI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdmFyIHRkTGVmdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlREIik7CiAgICAgICAgdGRMZWZ0LmlubmVySFRNTCA9ICIiOwogICAgICAgIHZhciB0ZFJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVEQiKTsKICAgICAgICB2YXIgcHJlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiUFJFIik7CiAgICAgICAgcHJlLmlubmVySFRNTCA9IHRleHQ7CiAgICAgICAgdGRSaWdodC5hcHBlbmRDaGlsZChwcmUpOwogICAgICAgIGRlc2NyaXB0aW9uLmFwcGVuZENoaWxkKHRkTGVmdCk7CiAgICAgICAgZGVzY3JpcHRpb24uYXBwZW5kQ2hpbGQodGRSaWdodCk7CiAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgfQp9CmNsYXNzIFNldHRpbmdzQ2F0ZWdvcnlJdGVtIGV4dGVuZHMgU2V0dGluZ3NDYXRlZ29yeSB7CiAgICBjb25zdHJ1Y3RvcihoZWFkbGluZSwgc2V0dGluZ3NLZXlzKSB7CiAgICAgICAgc3VwZXIoKTsKICAgICAgICB0aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgICAgdGhpcy5zZXR0aW5nc0tleXMgPSBzZXR0aW5nc0tleXM7CiAgICB9CiAgICBjcmVhdGVDYXRlZ29yeSgpIHsKICAgICAgICB2YXIgaGVhZGxpbmUgPSB0aGlzLmNyZWF0ZUNhdGVnb3J5SGVhZGxpbmUodGhpcy5oZWFkbGluZSk7CiAgICAgICAgdmFyIHNldHRpbmdzS2V5cyA9IHRoaXMuc2V0dGluZ3NLZXlzOwogICAgICAgIHZhciBkb2MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkRvY3VtZW50SUQpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZChoZWFkbGluZSk7CiAgICAgICAgLy8gQ3JlYXRlIGEgdGFibGUgZm9yIHRoZSBjYXRlZ29yeQogICAgICAgIHZhciB0YWJsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIlRBQkxFIik7CiAgICAgICAgdmFyIGtleXMgPSBzZXR0aW5nc0tleXMuc3BsaXQoIiwiKTsKICAgICAgICBrZXlzLmZvckVhY2goc2V0dGluZ3NLZXkgPT4gewogICAgICAgICAgICBzd2l0Y2ggKHNldHRpbmdzS2V5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi5wbXMiOgogICAgICAgICAgICAgICAgY2FzZSAiYXV0aGVudGljYXRpb24ubTN1IjoKICAgICAgICAgICAgICAgIGNhc2UgImF1dGhlbnRpY2F0aW9uLnhtbCI6CiAgICAgICAgICAgICAgICBjYXNlICJhdXRoZW50aWNhdGlvbi5hcGkiOgogICAgICAgICAgICAgICAgICAgIGlmIChTRVJWRVJbInNldHRpbmdzIl1bImF1dGhlbnRpY2F0aW9uLndlYiJdID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSB0aGlzLmNyZWF0ZVNldHRpbmdzKHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgICAgICB2YXIgZGVzY3JpcHRpb24gPSB0aGlzLmNyZWF0ZURlc2NyaXB0aW9uKHNldHRpbmdzS2V5KTsKICAgICAgICAgICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChpdGVtKTsKICAgICAgICAgICAgICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBkb2MuYXBwZW5kQ2hpbGQodGFibGUpOwogICAgICAgIGRvYy5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUhSKCkpOwogICAgfQp9CmZ1bmN0aW9uIHNob3dTZXR0aW5ncygpIHsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0dGluZ3NDYXRlZ29yeS5sZW5ndGg7IGkrKykgewogICAgICAgIHNldHRpbmdzQ2F0ZWdvcnlbaV0uY3JlYXRlQ2F0ZWdvcnkoKTsKICAgIH0KfQpmdW5jdGlvbiBzYXZlU2V0dGluZ3MoKSB7CiAgICB2YXIgY21kID0gInNhdmVTZXR0aW5ncyI7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRlbnRfc2V0dGluZ3MiKTsKICAgIHZhciBzZXR0aW5ncyA9IGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJjaGFuZ2VkIik7CiAgICB2YXIgbmV3U2V0dGluZ3MgPSBuZXcgT2JqZWN0KCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldHRpbmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIG5hbWU7CiAgICAgICAgdmFyIHZhbHVlOwogICAgICAgIHN3aXRjaCAoc2V0dGluZ3NbaV0udGFnTmFtZSkgewogICAgICAgICAgICBjYXNlICJJTlBVVCI6CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHNldHRpbmdzW2ldLnR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjaGVja2JveCI6CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBzZXR0aW5nc1tpXS5uYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNldHRpbmdzW2ldLmNoZWNrZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NldHRpbmdzW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gc2V0dGluZ3NbaV0ubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBzZXR0aW5nc1tpXS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJ1cGRhdGUiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3BsaXQoIiwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmZpbHRlcihmdW5jdGlvbiAoZSkgeyByZXR1cm4gZTsgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJidWZmZXIudGltZW91dCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUZsb2F0KHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBuZXdTZXR0aW5nc1tuYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJTRUxFQ1QiOgogICAgICAgICAgICAgICAgbmFtZSA9IHNldHRpbmdzW2ldLm5hbWU7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHNldHRpbmdzW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZhbHVlIGlzIGEgbnVtYmVyLCBzdG9yZSBpdCBhcyBhIG51bWJlcgogICAgICAgICAgICAgICAgaWYgKGlzTmFOKHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgIG5ld1NldHRpbmdzW25hbWVdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBuZXdTZXR0aW5nc1tuYW1lXSA9IHBhcnNlSW50KHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgZGF0YVsic2V0dGluZ3MiXSA9IG5ld1NldHRpbmdzOwogICAgdmFyIHNlcnZlciA9IG5ldyBTZXJ2ZXIoY21kKTsKICAgIHNlcnZlci5yZXF1ZXN0KGRhdGEpOwp9Cg=="
+ webUI["html/lang/en.json"] = "ewogICJtYWluTWVudSI6IHsKICAgICJpdGVtIjogewogICAgICAicGxheWxpc3QiOiAiUGxheWxpc3QiLAogICAgICAicG1zSUQiOiAiUE1TIElEIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIiLAogICAgICAieG1sdHYiOiAiWE1MVFYiLAogICAgICAibWFwcGluZyI6ICJNYXBwaW5nIiwKICAgICAgInVzZXJzIjogIlVzZXJzIiwKICAgICAgInNldHRpbmdzIjogIlNldHRpbmdzIiwKICAgICAgImxvZyI6ICJMb2ciLAogICAgICAibG9nb3V0IjogIkxvZ291dCIKICAgIH0sCiAgICAiaGVhZGxpbmUiOiB7CiAgICAgICJwbGF5bGlzdCI6ICJMb2NhbCBvciByZW1vdGUgcGxheWxpc3RzIiwKICAgICAgImZpbHRlciI6ICJGaWx0ZXIgcGxheWxpc3QiLAogICAgICAieG1sdHYiOiAiTG9jYWwgb3IgcmVtb3RlIFhNTFRWIGZpbGVzIiwKICAgICAgIm1hcHBpbmciOiAiTWFwIHBsYXlsaXN0IGNoYW5uZWxzIHRvIEVQRyBjaGFubmVscyIsCiAgICAgICJ1c2VycyI6ICJVc2VyIG1hbmFnZW1lbnQiLAogICAgICAic2V0dGluZ3MiOiAiU2V0dGluZ3MiLAogICAgICAibG9nIjogIkxvZyIsCiAgICAgICJsb2dvdXQiOiAiTG9nb3V0IgogICAgfQogIH0sCiAgImNvbmZpcm0iOiB7CiAgICAicmVzdG9yZSI6ICJBbGwgZGF0YSB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhvc2UgZnJvbSB0aGUgYmFja3VwLiBTaG91bGQgdGhlIGZpbGVzIGJlIHJlc3RvcmVkPyIKICB9LAogICJhbGVydCI6IHsKICAgICJmaWxlTG9hZGluZ0Vycm9yIjogIkZpbGUgY291bGRuJ3QgYmUgbG9hZGVkIiwKICAgICJpbnZhbGlkQ2hhbm5lbE51bWJlciI6ICJJbnZhbGlkIGNoYW5uZWwgbnVtYmVyIiwKICAgICJtaXNzaW5nSW5wdXQiOiAiTWlzc2luZyBpbnB1dCIKICB9LAogICJidXR0b24iOiB7CiAgICAiYmFjayI6ICJCYWNrIiwKICAgICJiYWNrdXAiOiAiQmFja3VwIiwKICAgICJidWxrRWRpdCI6ICJCdWxrIEVkaXQiLAogICAgImNhbmNlbCI6ICJDYW5jZWwiLAogICAgImRlbGV0ZSI6ICJEZWxldGUiLAogICAgImRvbmUiOiAiRG9uZSIsCiAgICAibG9naW4iOiAiTG9naW4iLAogICAgIm5ldyI6ICJOZXciLAogICAgIm5leHQiOiAiTmV4dCIsCiAgICAicmVzdG9yZSI6ICJSZXN0b3JlIiwKICAgICJzYXZlIjogIlNhdmUiLAogICAgInNlYXJjaCI6ICJTZWFyY2giLAogICAgInVwZGF0ZSI6ICJVcGRhdGUiLAogICAgImNyYWV0ZUFjY291bnQiOiAiQ3JlYXRlIEFjY291bnQiLAogICAgInJlc2V0TG9ncyI6ICJSZXNldCBMb2dzIiwKICAgICJ1cGxvYWRMb2dvIjogIlVwbG9hZCBMb2dvIgogIH0sCiAgImZpbHRlciI6IHsKICAgICJ0YWJsZSI6IHsKICAgICAgInN0YXJ0aW5nQ2hhbm5lbCI6ICJTdGFydGluZyBDaC4gTm8uIiwKICAgICAgIm5hbWUiOiAiRmlsdGVyIE5hbWUiLAogICAgICAidHlwZSI6ICJGaWx0ZXIgVHlwZSIsCiAgICAgICJmaWx0ZXIiOiAiRmlsdGVyIgogICAgfSwKICAgICJjdXN0b20iOiAiQ3VzdG9tIiwKICAgICJncm91cCI6ICJNM1UgR3JvdXAiLAogICAgIm5hbWUiOiB7CiAgICAgICJ0aXRsZSI6ICJGaWx0ZXIgTmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWx0ZXIgbmFtZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImRlc2NyaXB0aW9uIjogewogICAgICAidGl0bGUiOiAiRGVzY3JpcHRpb24iLAogICAgICAicGxhY2Vob2xkZXIiOiAiRGVzY3JpcHRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ0eXBlIjogewogICAgICAidGl0bGUiOiAiVHlwZSIsCiAgICAgICJncm91cFRpdGxlIjogIkdyb3VwIFRpdGxlIiwKICAgICAgImN1c3RvbUZpbHRlciI6ICJDdXN0b20gRmlsdGVyIgogICAgfSwKICAgICJjYXNlU2Vuc2l0aXZlIjogewogICAgICAidGl0bGUiOiAiQ2FzZSBTZW5zaXRpdmUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZmlsdGVyUnVsZSI6IHsKICAgICAgInRpdGxlIjogIkZpbHRlciBSdWxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlNwb3J0IHtIRH0gIXtFUyxJVH0iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWx0ZXJHcm91cCI6IHsKICAgICAgInRpdGxlIjogIkdyb3VwIFRpdGxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJTZWxlY3QgYSBNM1UgZ3JvdXAuIChDb3VudGVyKTxicj5DaGFuZ2luZyB0aGUgZ3JvdXAgdGl0bGUgaW4gdGhlIE0zVSBpbnZhbGlkYXRlcyB0aGUgZmlsdGVyLiIKICAgIH0sCiAgICAiaW5jbHVkZSI6IHsKICAgICAgInRpdGxlIjogIkluY2x1ZGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRkhELFVIRCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFubmVsIG5hbWUgbXVzdCBpbmNsdWRlLjxicj4oQ29tbWEgc2VwYXJhdGVkKSBDb21tYSBtZWFucyBvciIKICAgIH0sCiAgICAiZXhjbHVkZSI6IHsKICAgICAgInRpdGxlIjogIkV4Y2x1ZGUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRVMsSVQiLAogICAgICAiZGVzY3JpcHRpb24iOiAiQ2hhbm5lbCBuYW1lIG11c3Qgbm90IGNvbnRhaW4uPGJyPihDb21tYSBzZXBhcmF0ZWQpIENvbW1hIG1lYW5zIG9yIgogICAgfSwKICAgICJwcmVzZXJ2ZU1hcHBpbmciOiB7CiAgICAgICJ0aXRsZSI6ICJQcmVzZXJ2ZSBFeGlzdGluZyBNM1U8YnI+Q2hhbm5lbCBOdW1iZXJzIiwKICAgICAgInBhbGNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJQcmVzZXJ2ZSBleGlzdGluZyBNM1UgcGxheWxpc3QgY2hhbm5lbCBudW1iZXJzPyIKICAgIH0sCiAgICAic3RhcnRpbmdDaGFubmVsIjogewogICAgICAidGl0bGUiOiAiU3RhcnRpbmcgQ2hhbm5lbCBOdW1iZXIiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0KICB9LAogICJwbGF5bGlzdCI6IHsKICAgICJ0YWJsZSI6IHsKICAgICAgInBsYXlsaXN0IjogIlBsYXlsaXN0IiwKICAgICAgInR1bmVyIjogIlR1bmVyIiwKICAgICAgImxhc3RVcGRhdGUiOiAiTGFzdCBVcGRhdGUiLAogICAgICAiYXZhaWxhYmlsaXR5IjogIkF2YWlsYWJpbGl0eSIsCiAgICAgICJ0eXBlIjogIlR5cGUiLAogICAgICAic3RyZWFtcyI6ICJTdHJlYW1zIiwKICAgICAgImdyb3VwVGl0bGUiOiAiZ3JvdXAtdGl0bGUiLAogICAgICAidHZnSUQiOiAidHZnLWlkIiwKICAgICAgInVuaXF1ZUlEIjogIlVuaXF1ZSBJRCIKICAgIH0sCiAgICAicGxheWxpc3RUeXBlIjogewogICAgICAidGl0bGUiOiAiUGxheWxpc3QgdHlwZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ0eXBlIjogewogICAgICAidGl0bGUiOiAiVHlwZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJuYW1lIjogewogICAgICAidGl0bGUiOiAiTmFtZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJQbGF5bGlzdCBuYW1lIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAiZGVzY3JpcHRpb24iOiB7CiAgICAgICJ0aXRsZSI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJEZXNjcmlwdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImZpbGVNM1UiOiB7CiAgICAgICJ0aXRsZSI6ICJNM1UgRmlsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWxlIHBhdGggb3IgVVJMIG9mIHRoZSBNM1UiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWxlSERIUiI6IHsKICAgICAgInRpdGxlIjogIkhESG9tZVJ1biBJUCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJJUCBhZGRyZXNzIGFuZCBwb3J0ICgxOTIuMTY4LjEuMTA6NTAwNCkiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ0dW5lciI6IHsKICAgICAgInRpdGxlIjogIlR1bmVyIC8gU3RyZWFtcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIHBhcmFsbGVsIGNvbm5lY3Rpb25zIHRoYXQgY2FuIGJlIGVzdGFibGlzaGVkIHRvIHRoZSBwcm92aWRlci4gPGJyPk9ubHkgYXZhaWxhYmxlIHdpdGggYWN0aXZhdGVkIGJ1ZmZlci48YnI+TmV3IHNldHRpbmdzIHdpbGwgb25seSBiZSBhcHBsaWVkIGFmdGVyIHF1aXR0aW5nIGFsbCBzdHJlYW1zLiIKICAgIH0KICB9LAogICJ4bWx0diI6IHsKICAgICJ0YWJsZSI6IHsKICAgICAgImd1aWRlIjogIkd1aWRlIiwKICAgICAgImxhc3RVcGRhdGUiOiAiTGFzdCBVcGRhdGUiLAogICAgICAiYXZhaWxhYmlsaXR5IjogIkF2YWlsYWJpbGl0eSIsCiAgICAgICJjaGFubmVscyI6ICJDaGFubmVscyIsCiAgICAgICJwcm9ncmFtcyI6ICJQcm9ncmFtcyIKICAgIH0sCiAgICAibmFtZSI6IHsKICAgICAgInRpdGxlIjogIk5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiR3VpZGUgbmFtZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImRlc2NyaXB0aW9uIjogewogICAgICAidGl0bGUiOiAiRGVzY3JpcHRpb24iLAogICAgICAicGxhY2Vob2xkZXIiOiAiRGVzY3JpcHRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJmaWxlWE1MVFYiOiB7CiAgICAgICJ0aXRsZSI6ICJYTUxUViBGaWxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIkZpbGUgcGF0aCBvciBVUkwgb2YgdGhlIFhNTFRWIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0KICB9LAogICJtYXBwaW5nIjogewogICAgInRhYmxlIjogewogICAgICAiY2hObyI6ICJDaC4gTm8uIiwKICAgICAgImxvZ28iOiAiTG9nbyIsCiAgICAgICJjaGFubmVsTmFtZSI6ICJDaGFubmVsIE5hbWUiLAogICAgICAidXBkYXRlQ2hhbm5lbE5hbWVSZWdleCI6ICJVcGQuIFJ4LiIsCiAgICAgICJwbGF5bGlzdCI6ICJQbGF5bGlzdCIsCiAgICAgICJncm91cFRpdGxlIjogIkdyb3VwIFRpdGxlIiwKICAgICAgInhtbHR2RmlsZSI6ICJYTUxUViBGaWxlIiwKICAgICAgInhtbHR2SUQiOiAiWE1MVFYgSUQiLAogICAgICAidGltZXNoaWZ0IjogIlRpbWVzaGlmdCIKICAgIH0sCiAgICAiYWN0aXZlIjogewogICAgICAidGl0bGUiOiAiQWN0aXZlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImNoYW5uZWxOYW1lIjogewogICAgICAidGl0bGUiOiAiQ2hhbm5lbCBOYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImRlc2NyaXB0aW9uIjogewogICAgICAidGl0bGUiOiAiQ2hhbm5lbCBEZXNjcmlwdGlvbiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJVc2VkIGJ5IHRoZSBEdW1teSBhcyBhbiBYTUwgZGVzY3JpcHRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ1cGRhdGVDaGFubmVsTmFtZSI6IHsKICAgICAgInRpdGxlIjogIlVwZGF0ZSBDaGFubmVsIE5hbWUiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidXBkYXRlQ2hhbm5lbE5hbWVSZWdleCI6IHsKICAgICAgInRpdGxlIjogIkNoYW5uZWwgbmFtZSB1cGRhdGUgcmVnZXgiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRm9yIGV4YW1wbGUgXlBQVlsgXFxcXC1fXT8xLioiLAogICAgICAiZGVzY3JpcHRpb24iOiAiT24gdXBkYXRlLCBpZiBhbnkgbmV3IGNoYW5uZWwgbmFtZSBtYXRjaGVzIHRoaXMgcmVnZXgsIHJlbmFtZSBjdXJyZW50IGNoYW5uZWwgdG8gdGhlIGZpcnN0IG1hdGNoaW5nIG5hbWUiCiAgICB9LAogICAgInVwZGF0ZUNoYW5uZWxOYW1lQnlHcm91cFJlZ2V4IjogewogICAgICAidGl0bGUiOiAiT25seSBieSBncm91cCByZWdleCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiUmVuYW1lIHRoaXMgY2hhbm5lbCBvbmx5IGlmIGN1cnJlbnQgdXNlci1kZWZpbmVkIGdyb3VwIG1hdGNoZXMgdGhpcyByZWdleCIKICAgIH0sCiAgICAidXBkYXRlQ2hhbm5lbEdyb3VwIjogewogICAgICAidGl0bGUiOiAiVXBkYXRlIENoYW5uZWwgR3JvdXAiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIklmIGNoZWNrZWQsIHVzZSBncm91cCBmcm9tIHRoZSBkYXRhYmFzZSIKICAgIH0sCiAgICAiY2hhbm5lbExvZ28iOiB7CiAgICAgICJ0aXRsZSI6ICJMb2dvIFVSTCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ1cGRhdGVDaGFubmVsTG9nbyI6IHsKICAgICAgInRpdGxlIjogIlVzZSBsb2dvIGZyb20gTTNVIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImVwZ0NhdGVnb3J5IjogewogICAgICAidGl0bGUiOiAiRVBHIENhdGVnb3J5IiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgIm0zdUdyb3VwVGl0bGUiOiB7CiAgICAgICJ0aXRsZSI6ICJHcm91cCBUaXRsZSAoeHRldmUubTN1KSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ4bWx0dkZpbGUiOiB7CiAgICAgICJ0aXRsZSI6ICJYTUxUViBGaWxlIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInhtbHR2Q2hhbm5lbCI6IHsKICAgICAgInRpdGxlIjogIlhNTFRWIENoYW5uZWwiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAidGltZXNoaWZ0IjogewogICAgICAidGl0bGUiOiAiVGltZXNoaWZ0IiwKICAgICAgInBsYWNlaG9sZGVyIjogIjAiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfQogIH0sCiAgInVzZXJzIjogewogICAgInRhYmxlIjogewogICAgICAidXNlcm5hbWUiOiAiVXNlcm5hbWUiLAogICAgICAicGFzc3dvcmQiOiAiUGFzc3dvcmQiLAogICAgICAid2ViIjogIldFQiIsCiAgICAgICJwbXMiOiAiUE1TIiwKICAgICAgIm0zdSI6ICJNM1UiLAogICAgICAieG1sIjogIlhNTCIsCiAgICAgICJhcGkiOiAiQVBJIgogICAgfSwKICAgICJ1c2VybmFtZSI6IHsKICAgICAgInRpdGxlIjogIlVzZXJuYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlVzZXJuYW1lIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAicGFzc3dvcmQiOiB7CiAgICAgICJ0aXRsZSI6ICJQYXNzd29yZCIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJQYXNzd29yZCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImNvbmZpcm0iOiB7CiAgICAgICJ0aXRsZSI6ICJDb25maXJtIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBhc3N3b3JkIGNvbmZpcm0iLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ3ZWIiOiB7CiAgICAgICJ0aXRsZSI6ICJXZWIgQWNjZXNzIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgInBtcyI6IHsKICAgICAgInRpdGxlIjogIlBNUyBBY2Nlc3MiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0sCiAgICAibTN1IjogewogICAgICAidGl0bGUiOiAiTTNVIEFjY2VzcyIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIiLAogICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgfSwKICAgICJ4bWwiOiB7CiAgICAgICJ0aXRsZSI6ICJYTUwgQWNjZXNzIiwKICAgICAgInBsYWNlaG9sZGVyIjogIiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICB9LAogICAgImFwaSI6IHsKICAgICAgInRpdGxlIjogIkFQSSBBY2Nlc3MiLAogICAgICAicGxhY2Vob2xkZXIiOiAiIiwKICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgIH0KICB9LAogICJzZXR0aW5ncyI6IHsKICAgICJjYXRlZ29yeSI6IHsKICAgICAgImdlbmVyYWwiOiAiR2VuZXJhbCIsCiAgICAgICJtYXBwaW5nIjogIk1hcHBpbmciLAogICAgICAiZmlsZXMiOiAiRmlsZXMiLAogICAgICAic3RyZWFtaW5nIjogIlN0cmVhbWluZyIsCiAgICAgICJiYWNrdXAiOiAiQmFja3VwIiwKICAgICAgImF1dGhlbnRpY2F0aW9uIjogIkF1dGhlbnRpY2F0aW9uIgogICAgfSwKICAgICJ1cGRhdGUiOiB7CiAgICAgICJ0aXRsZSI6ICJTY2hlZHVsZSBmb3IgdXBkYXRpbmcgKFBsYXlsaXN0LCBYTUxUViwgQmFja3VwKSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIwMDAwLDEwMDAsMjAwMCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaW1lIGluIDI0IGhvdXIgZm9ybWF0ICgwODAwID0gODowMCBhbSkuIE1vcmUgdGltZXMgY2FuIGJlIGVudGVyZWQgY29tbWEgc2VwYXJhdGVkLiBMZWF2ZSB0aGlzIGZpZWxkIGVtcHR5IGlmIG5vIHVwZGF0ZXMgYXJlIHRvIGJlIGNhcnJpZWQgb3V0LiIKICAgIH0sCiAgICAiYXBpIjogewogICAgICAidGl0bGUiOiAiQVBJIEludGVyZmFjZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJWaWEgQVBJIGludGVyZmFjZSBpdCBpcyBwb3NzaWJsZSB0byBzZW5kIGNvbW1hbmRzIHRvIHhUZVZlLiBBUEkgZG9jdW1lbnRhdGlvbiBpcyA8YSBocmVmPSdodHRwczovL2dpdGh1Yi5jb20veHRldmUtcHJvamVjdC94VGVWZS1Eb2N1bWVudGF0aW9uL2Jsb2IvbWFzdGVyL2VuL2NvbmZpZ3VyYXRpb24ubWQjYXBpJz5oZXJlPC9hPiIKICAgIH0sCiAgICAiY2xlYXJYTUxUVkNhY2hlIjogewogICAgICAidGl0bGUiOiAiQ2xlYXIgWE1MVFYgY2FjaGUiLAogICAgICAiZGVzY3JpcHRpb24iOiAiSWYgY2hlY2tlZCwgZG8gbm90IGtlZXAgWE1MVFYgY2FjaGUgaW4gbWVtb3J5Ljxicj5TaWduaWZpY2FsbHkgcmVkdWNlcyBSQU0gdXNhZ2UgaW4gaWRsZSBtb2RlLDxicj5idXQgc2lnbmlmaWNhbGx5IHNsb3dpbmcgZG93biBldmVyeSBzdWJzZXF1ZW50IHVwZGF0ZSBpbiBYRVBHIGRhdGFiYXNlLiIKICAgIH0sCiAgICAiZGVmYXVsdE1pc3NpbmdFUEciOiB7CiAgICAgICJ0aXRsZSI6ICJGaWxsIE1pc3NpbmcgRVBHIERhdGEiLAogICAgICAiZGVzY3JpcHRpb24iOiAiV2hlbiB0aGVyZSBpcyBubyBtYXRjaGluZyBFUEcgZGF0YSBmb3IgY2hhbm5lbCwgPGJyPmF1dG9maWxsIHdpdGggeFRlVmUgZHVtbXkgRVBHIGRhdGE/IgogICAgfSwKICAgICJlbmFibGVNYXBwZWRDaGFubmVscyI6IHsKICAgICAgInRpdGxlIjogIkVuYWJsZSBtYXBwZWQgY2hhbm5lbHMiLAogICAgICAiZGVzY3JpcHRpb24iOiAiQXV0b21hdGljYWxseSBlbmFibGUgY2hhbm5lbHMgd2l0aCBhc3NpZ25lZCBFUEcgZGF0YSIKICAgIH0sCiAgICAiZGlzYWxsb3dVUkxEdXBsaWNhdGVzIjogewogICAgICAidGl0bGUiOiAiRGlzYWxsb3cgVVJMIGR1cGxpY2F0ZXMiLAogICAgICAiZGVzY3JpcHRpb24iOiAiSWYgY2hlY2tlZCwgZG8gbm90IGFkZCBhIG5ldyBjaGFubmVsIGZyb20gcGxheWxpc3QgaWYgY2hhbm5lbCB3aXRoIHN1Y2ggVVJMIGFscmVhZHkgZXhpc3RzIgogICAgfSwKICAgICJlcGdTb3VyY2UiOiB7CiAgICAgICJ0aXRsZSI6ICJFUEcgU291cmNlIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBNUzo8YnI+LSBVc2UgRVBHIGRhdGEgZnJvbSBQbGV4IG9yIEVtYnkgPGJyPjxicj5YRVBHOjxicj4tIFVzZSBvZiBvbmUgb3IgbW9yZSBYTUxUViBmaWxlczxicj4tIENoYW5uZWwgbWFuYWdlbWVudDxicj4tIE0zVSAvIFhNTFRWIGV4cG9ydCAoSFRUUCBsaW5rIGZvciBJUFRWIGFwcHMpIgogICAgfSwKICAgICJ0dW5lciI6IHsKICAgICAgInRpdGxlIjogIk51bWJlciBvZiBUdW5lcnMiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIHBhcmFsbGVsIGNvbm5lY3Rpb25zIHRoYXQgY2FuIGJlIGVzdGFibGlzaGVkIHRvIHRoZSBwcm92aWRlci48YnI+QXZhaWxhYmxlIGZvcjogUGxleCwgRW1ieSAoSERIUiksIE0zVSAod2l0aCBhY3RpdmUgYnVmZmVyKS48YnI+QWZ0ZXIgYSBjaGFuZ2UsIHhUZVZlIG11c3QgYmUgZGVsZXRlIGluIHRoZSBQbGV4IC8gRW1ieSBEVlIgc2V0dGluZ3MgYW5kIHNldCB1cCBhZ2Fpbi4iCiAgICB9LAogICAgImhvc3RJUCI6IHsKICAgICAgInRpdGxlIjogIkhvc3QgSVAiLAogICAgICAiZGVzY3JpcHRpb24iOiAiSVAgYWRkcmVzcyB4VGVWZSB3aWxsIHVzZSB0byBmb3JtIE0zVSBhbmQgWE1MVFYgZmlsZXMiCiAgICB9LAogICAgImhvc3ROYW1lIjogewogICAgICAidGl0bGUiOiAiSG9zdCBOYW1lIE92ZXJyaWRlIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkhvc3RuYW1lIHhUZVZlIHdpbGwgdXNlIHRvIGZvcm0gTTNVIGFuZCBYTUxUViBmaWxlcy4gVGhpcyB3aWxsIG92ZXJyaWRlIEhvc3QgSVAgaWYgc2V0IgogICAgfSwKICAgICJ0bHNNb2RlIjogewogICAgICAidGl0bGUiOiAiVExTIChIVFRQUykgbW9kZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFuZ2VzIHdlYiBzZXJ2ZXIgcHJvdG9jb2wgdG8gSFRUUFMuPGJyPkZvciBkZXRhaWxzLCBzZWUgPGE+aHR0cHM6Ly9naXRodWIuY29tL1NlbmV4Q3JlbnNoYXcveFRlVmUjdGxzLW1vZGU8L2E+IgogICAgfSwKICAgICJmaWxlc1VwZGF0ZSI6IHsKICAgICAgInRpdGxlIjogIlVwZGF0ZXMgYWxsIGZpbGVzIGF0IHN0YXJ0dXAiLAogICAgICAiZGVzY3JpcHRpb24iOiAiVXBkYXRlcyBhbGwgcGxheWxpc3RzLCB0dW5lciBhbmQgWE1MVFYgZmlsZXMgYXQgc3RhcnR1cC4iCiAgICB9LAogICAgImNhY2hlSW1hZ2VzIjogewogICAgICAidGl0bGUiOiAiSW1hZ2UgQ2FjaGluZyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJBbGwgaW1hZ2VzIGZyb20gdGhlIFhNTFRWIGZpbGUgYXJlIGNhY2hlZCwgYWxsb3dpbmcgZmFzdGVyIHJlbmRlcmluZyBvZiB0aGUgZ3JpZCBpbiB0aGUgY2xpZW50Ljxicj5Eb3dubG9hZGluZyB0aGUgaW1hZ2VzIG1heSB0YWtlIGEgd2hpbGUgYW5kIHdpbGwgYmUgZG9uZSBpbiB0aGUgYmFja2dyb3VuZC4iCiAgICB9LAogICAgInJlcGxhY2VFbXB0eUltYWdlcyI6IHsKICAgICAgInRpdGxlIjogIlJlcGxhY2UgbWlzc2luZyBwcm9ncmFtIGltYWdlcyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiB0aGUgcG9zdGVyIGluIHRoZSBYTUxUViBwcm9ncmFtIGlzIG1pc3NpbmcsIHRoZSBjaGFubmVsIGxvZ28gd2lsbCBiZSB1c2VkLiIKICAgIH0sCiAgICAieHRldmVBdXRvVXBkYXRlIjogewogICAgICAidGl0bGUiOiAiQXV0b21hdGljIHVwZGF0ZSBvZiB4VGVWZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiBhIG5ldyB2ZXJzaW9uIG9mIHhUZVZlIGlzIGF2YWlsYWJsZSwgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGluc3RhbGxlZC4gVGhlIHVwZGF0ZXMgYXJlIGRvd25sb2FkZWQgZnJvbSBHaXRIdWIuIgogICAgfSwKICAgICJzdHJlYW1CdWZmZXJpbmciOiB7CiAgICAgICJ0aXRsZSI6ICJTdHJlYW0gQnVmZmVyIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkZ1bmN0aW9ucyBvZiB0aGUgYnVmZmVyOjxicj4tIFRoZSBzdHJlYW0gaXMgcGFzc2VkIGZyb20geFRlVmUsIEZGbXBlZyBvciBWTEMgdG8gUGxleCwgRW1ieSBvciBNM1UgUGxheWVyPGJyPi0gU21hbGwgamVya2luZyBvZiB0aGUgc3RyZWFtcyBjYW4gYmUgY29tcGVuc2F0ZWQ8YnI+LSBITFMgLyBNM1U4IHN1cHBvcnQ8YnI+LSBSVFAgLyBSVFBTIHN1cHBvcnQgKG9ubHkgRkZtcGVnIG9yIFZMQyk8YnI+LSBSZS1zdHJlYW1pbmc8YnI+LSBTZXBhcmF0ZSB0dW5lciBsaW1pdCBmb3IgZWFjaCBwbGF5bGlzdCIsCiAgICAgICJpbmZvX2ZhbHNlIjogIk5vIEJ1ZmZlciAoQ2xpZW50IGNvbm5lY3RzIHRvIHRoZSBzdHJlYW1pbmcgc2VydmVyKSIsCiAgICAgICJpbmZvX3h0ZXZlIjogInhUZVZlIGNvbm5lY3RzIHRvIHRoZSBzdHJlYW1pbmcgc2VydmVyIiwKICAgICAgImluZm9fZmZtcGVnIjogIkZGbXBlZyBjb25uZWN0cyB0byB0aGUgc3RyZWFtaW5nIHNlcnZlciIsCiAgICAgICJpbmZvX3ZsYyI6ICJWTEMgY29ubmVjdHMgdG8gdGhlIHN0cmVhbWluZyBzZXJ2ZXIiCiAgICB9LAogICAgInVkcHh5IjogewogICAgICAidGl0bGUiOiAiVURQeHkgYWRkcmVzcyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgYWRkcmVzcyBvZiB5b3VyIFVEUHh5IHNlcnZlci4gSWYgc2V0LCBhbmQgdGhlIGNoYW5uZWwgVVJMcyBpbiB0aGUgbTN1IGlzIG11bHRpY2FzdCwgeFRlVmUgd2lsbCByZXdyaXRlIGl0IHNvIHRoYXQgaXQgaXMgYWNjZXNzZWQgdmlhIHRoZSBVRFB4eSBzZXJ2aWNlLiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJob3N0OnBvcnQiCiAgICB9LAogICAgImZmbXBlZ1BhdGgiOiB7CiAgICAgICJ0aXRsZSI6ICJGRm1wZWcgQmluYXJ5IFBhdGgiLAogICAgICAiZGVzY3JpcHRpb24iOiAiUGF0aCB0byBGRm1wZWcgYmluYXJ5LiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICIvcGF0aC90by9mZm1wZWciCiAgICB9LAogICAgImZmbXBlZ09wdGlvbnMiOiB7CiAgICAgICJ0aXRsZSI6ICJGRm1wZWcgT3B0aW9ucyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJGRm1wZWcgb3B0aW9ucy48YnI+T25seSBjaGFuZ2UgaWYgeW91IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nLjxicj5MZWF2ZSBibGFuayB0byBzZXQgZGVmYXVsdCBzZXR0aW5ncy4iLAogICAgICAicGxhY2Vob2xkZXIiOiAiTGVhdmUgYmxhbmsgdG8gc2V0IGRlZmF1bHQgc2V0dGluZ3MiCiAgICB9LAogICAgInZsY1BhdGgiOiB7CiAgICAgICJ0aXRsZSI6ICJWTEMgLyBDVkxDIEJpbmFyeSBQYXRoIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBhdGggdG8gVkxDIC8gQ1ZMQyBiaW5hcnkuIiwKICAgICAgInBsYWNlaG9sZGVyIjogIi9wYXRoL3RvL2N2bGMiCiAgICB9LAogICAgInZsY09wdGlvbnMiOiB7CiAgICAgICJ0aXRsZSI6ICJWTEMgLyBDVkxDIE9wdGlvbnMiLAogICAgICAiZGVzY3JpcHRpb24iOiAiVkxDIC8gQ1ZMQyBvcHRpb25zLjxicj5Pbmx5IGNoYW5nZSBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuPGJyPkxlYXZlIGJsYW5rIHRvIHNldCBkZWZhdWx0IHNldHRpbmdzLiIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJMZWF2ZSBibGFuayB0byBzZXQgZGVmYXVsdCBzZXR0aW5ncyIKICAgIH0sCiAgICAiYnVmZmVyU2l6ZSI6IHsKICAgICAgInRpdGxlIjogIkJ1ZmZlciBTaXplIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkJ1ZmZlciBzaXplIGluIE1CLjxicj5NM1U4OiBJZiB0aGUgVFMgc2VnbWVudCBzbWFsbGVyIHRoZW4gdGhlIGJ1ZmZlciBzaXplLCB0aGUgZmlsZSBzaXplIG9mIHRoZSBzZWdtZW50IGlzIHVzZWQuIgogICAgfSwKICAgICJzdG9yZUJ1ZmZlckluUkFNIjogewogICAgICAidGl0bGUiOiAiU3RvcmUgYnVmZmVyIGluIFJBTSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiBjaGVja2VkLCB3cml0ZSBidWZmZXIgdG8gUkFNIGluc3RlYWQgb2Ygd3JpdGluZyB0byBkaXNrIgogICAgfSwKICAgICJidWZmZXJUaW1lb3V0IjogewogICAgICAidGl0bGUiOiAiVGltZW91dCBmb3IgbmV3IGNsaWVudCBjb25uZWN0aW9ucyIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgeFRlVmUgYnVmZmVyIHdhaXRzIHVudGlsIG5ldyBjbGllbnQgY29ubmVjdGlvbnMgYXJlIGVzdGFibGlzaGVkLiBIZWxwZnVsIGZvciBmYXN0IGNoYW5uZWwgc3dpdGNoaW5nLiBWYWx1ZSBpbiBtaWxsaXNlY29uZHMuIiwKICAgICAgInBsYWNlaG9sZGVyIjogIjEwMCIKICAgIH0sCiAgICAidXNlckFnZW50IjogewogICAgICAidGl0bGUiOiAiVXNlciBBZ2VudCIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJVc2VyIEFnZW50IGZvciBIVFRQIHJlcXVlc3RzLiBGb3IgZXZlcnkgSFRUUCBjb25uZWN0aW9uLCB0aGlzIHZhbHVlIGlzIHVzZWQgZm9yIHRoZSB1c2VyIGFnZW50LiBTaG91bGQgb25seSBiZSBjaGFuZ2VkIGlmIHhUZVZlIGlzIGJsb2NrZWQuIiwKICAgICAgInBsYWNlaG9sZGVyIjogInhUZVZlIgogICAgfSwKICAgICJiYWNrdXBQYXRoIjogewogICAgICAidGl0bGUiOiAiTG9jYXRpb24gZm9yIGF1dG9tYXRpYyBiYWNrdXBzIiwKICAgICAgInBsYWNlaG9sZGVyIjogIi9tbnQvZGF0YS9iYWNrdXAveHRldmUvIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkJlZm9yZSBhbnkgdXBkYXRlIG9mIHRoZSBwcm92aWRlciBkYXRhIGJ5IHRoZSBzY2hlZHVsZSwgeFRlVmUgY3JlYXRlcyBhIGJhY2t1cC4gVGhlIHBhdGggZm9yIHRoZSBhdXRvbWF0aWMgYmFja3VwcyBjYW4gYmUgY2hhbmdlZC4geFRlVmUgcmVxdWlyZXMgd3JpdGUgcGVybWlzc2lvbiBmb3IgdGhpcyBmb2xkZXIuIgogICAgfSwKICAgICJ0ZW1wUGF0aCI6IHsKICAgICAgInRpdGxlIjogIkxvY2F0aW9uIGZvciB0aGUgdGVtcG9yYXJ5IGZpbGVzIiwKICAgICAgInBsYWNlaG9sZGVyIjogIi90bXAveHRldmUvIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkxvY2F0aW9uIGZvciB0aGUgYnVmZmVyIGZpbGVzLiIKICAgIH0sCiAgICAiYmFja3VwS2VlcCI6IHsKICAgICAgInRpdGxlIjogIk51bWJlciBvZiBiYWNrdXBzIHRvIGtlZXAiLAogICAgICAiZGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIGJhY2t1cHMgdG8ga2VlcC4gT2xkZXIgYmFja3VwcyBhcmUgYXV0b21hdGljYWxseSBkZWxldGVkLiIKICAgIH0sCiAgICAiYXV0aGVudGljYXRpb25XRUIiOiB7CiAgICAgICJ0aXRsZSI6ICJXRUIgQXV0aGVudGljYXRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiQWNjZXNzIHRvIHRoZSB3ZWIgaW50ZXJmYWNlIG9ubHkgcG9zc2libGUgd2l0aCBjcmVkZW50aWFscy4iCiAgICB9LAogICAgImF1dGhlbnRpY2F0aW9uUE1TIjogewogICAgICAidGl0bGUiOiAiUE1TIEF1dGhlbnRpY2F0aW9uIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlBsZXggcmVxdWVzdHMgYXJlIG9ubHkgcG9zc2libGUgd2l0aCBhdXRoZW50aWNhdGlvbi4gPGJyPjxiPldhcm5pbmchISE8L2I+IEFmdGVyIGFjdGl2YXRpbmcgdGhpcyBmdW5jdGlvbiB4VGVWZSBtdXN0IGJlIGRlbGV0ZSBpbiB0aGUgUE1TIERWUiBzZXR0aW5ncyBhbmQgc2V0IHVwIGFnYWluLiIKICAgIH0sCiAgICAiYXV0aGVudGljYXRpb25NM1UiOiB7CiAgICAgICJ0aXRsZSI6ICJNM1UgQXV0aGVudGljYXRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiRG93bmxvYWRpbmcgdGhlIHh0ZXZlLm0zdSBmaWxlIHZpYSBhbiBIVFRQIHJlcXVlc3QgaXMgb25seSBwb3NzaWJsZSB3aXRoIGF1dGhlbnRpY2F0aW9uLiIKICAgIH0sCiAgICAiYXV0aGVudGljYXRpb25YTUwiOiB7CiAgICAgICJ0aXRsZSI6ICJYTUwgQXV0aGVudGljYXRpb24iLAogICAgICAiZGVzY3JpcHRpb24iOiAiRG93bmxvYWRpbmcgdGhlIHh0ZXZlLnhtbCBmaWxlIHZpYSBhbiBIVFRQIHJlcXVlc3QgaXMgb25seSBwb3NzaWJsZSB3aXRoIGF1dGhlbnRpY2F0aW9uIgogICAgfSwKICAgICJhdXRoZW50aWNhdGlvbkFQSSI6IHsKICAgICAgInRpdGxlIjogIkFQSSBBdXRoZW50aWNhdGlvbiIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJBY2Nlc3MgdG8gdGhlIEFQSSBpbnRlcmZhY2UgaXMgb25seSBwb3NzaWJsZSB3aXRoIGF1dGhlbnRpY2F0aW9uLiIKICAgIH0KICB9LAogICJ3aXphcmQiOiB7CiAgICAiZXBnU291cmNlIjogewogICAgICAidGl0bGUiOiAiRVBHIFNvdXJjZSIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJQTVM6PGJyPi0gVXNlIEVQRyBkYXRhIGZyb20gUGxleCBvciBFbWJ5IDxicj48YnI+WEVQRzo8YnI+LSBVc2Ugb2Ygb25lIG9yIG1vcmUgWE1MVFYgZmlsZXM8YnI+LSBDaGFubmVsIG1hbmFnZW1lbnQ8YnI+LSBNM1UgLyBYTUxUViBleHBvcnQgKEhUVFAgbGluayBmb3IgSVBUViBhcHBzKSIKICAgIH0sCiAgICAidHVuZXIiOiB7CiAgICAgICJ0aXRsZSI6ICJOdW1iZXIgb2YgdHVuZXJzIiwKICAgICAgImRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBwYXJhbGxlbCBjb25uZWN0aW9ucyB0aGF0IGNhbiBiZSBlc3RhYmxpc2hlZCB0byB0aGUgcHJvdmlkZXIuPGJyPkF2YWlsYWJsZSBmb3I6IFBsZXgsIEVtYnkgKEhESFIpLCBNM1UgKHdpdGggYWN0aXZlIGJ1ZmZlcikuPGJyPkFmdGVyIGEgY2hhbmdlLCB4VGVWZSBtdXN0IGJlIGRlbGV0ZSBpbiB0aGUgUGxleCAvIEVtYnkgRFZSIHNldHRpbmdzIGFuZCBzZXQgdXAgYWdhaW4uIgogICAgfSwKICAgICJtM3UiOiB7CiAgICAgICJ0aXRsZSI6ICJNM1UgUGxheWxpc3QiLAogICAgICAicGxhY2Vob2xkZXIiOiAiRmlsZSBwYXRoIG9yIFVSTCBvZiB0aGUgTTNVIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkxvY2FsIG9yIHJlbW90ZSBwbGF5bGlzdHMiCiAgICB9LAogICAgInhtbHR2IjogewogICAgICAidGl0bGUiOiAiWE1MVFYgRmlsZSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJGaWxlIHBhdGggb3IgVVJMIG9mIHRoZSBYTUxUViIsCiAgICAgICJkZXNjcmlwdGlvbiI6ICJMb2NhbCBvciByZW1vdGUgWE1MVFYgZmlsZSIKICAgIH0KICB9LAogICJsb2dpbiI6IHsKICAgICJmYWlsZWQiOiAiVXNlciBhdXRoZW50aWNhdGlvbiBmYWlsZWQiLAogICAgImhlYWRsaW5lIjogIkxvZ2luIiwKICAgICJ1c2VybmFtZSI6IHsKICAgICAgInRpdGxlIjogIlVzZXJuYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlVzZXJuYW1lIgogICAgfSwKICAgICJwYXNzd29yZCI6IHsKICAgICAgInRpdGxlIjogIlBhc3N3b3JkIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBhc3N3b3JkIgogICAgfQogIH0sCiAgImFjY291bnQiOiB7CiAgICAiZmFpbGVkIjogIlBhc3N3b3JkIGRvZXMgbm90IG1hdGNoIiwKICAgICJoZWFkbGluZSI6ICJDcmVhdGUgdXNlciBhY2NvdW50IiwKICAgICJ1c2VybmFtZSI6IHsKICAgICAgInRpdGxlIjogIlVzZXJuYW1lIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlVzZXJuYW1lIgogICAgfSwKICAgICJwYXNzd29yZCI6IHsKICAgICAgInRpdGxlIjogIlBhc3N3b3JkIiwKICAgICAgInBsYWNlaG9sZGVyIjogIlBhc3N3b3JkIgogICAgfSwKICAgICJjb25maXJtIjogewogICAgICAidGl0bGUiOiAiQ29uZmlybSIsCiAgICAgICJwbGFjZWhvbGRlciI6ICJDb25maXJtIgogICAgfQogIH0KfQ=="
+ webUI["html/login.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImNzcy9iYXNlLmNzcyIgdHlwZT0idGV4dC9jc3MiPgogIDxzY3JpcHQgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJqcy9uZXR3b3JrX3RzLmpzIj48L3NjcmlwdD4KICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0Pgo8L2hlYWQ+Cgo8Ym9keT4KCiAgPGRpdiBpZD0iaGVhZGVyIiBjbGFzcz0iaW1nQ2VudGVyIj48L2Rpdj4KCiAgPGRpdiBpZD0iYm94Ij4KCiAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj57ey5sb2dpbi5oZWFkbGluZX19PC9oMT4KICAgIDwvZGl2PgoKICAgIDxwIGlkPSJlcnIiIGNsYXNzPSJlcnJvck1zZyBjZW50ZXIiPnt7LmF1dGhlbnRpY2F0aW9uRXJyfX08L3A+CgogICAgPGRpdiBpZD0iY29udGVudCI+CgogICAgICA8Zm9ybSBpZD0iYXV0aGVudGljYXRpb24iIGFjdGlvbj0iIiBtZXRob2Q9InBvc3QiPgoKICAgICAgICA8aDU+e3subG9naW4udXNlcm5hbWUudGl0bGV9fTo8L2g1PgogICAgICAgIDxpbnB1dCBpZD0idXNlcm5hbWUiIHR5cGU9InRleHQiIG5hbWU9InVzZXJuYW1lIiBwbGFjZWhvbGRlcj0iVXNlcm5hbWUiIHZhbHVlPSIiPgogICAgICAgIDxoNT57ey5sb2dpbi5wYXNzd29yZC50aXRsZX19OjwvaDU+CiAgICAgICAgPGlucHV0IGlkPSJwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIiBwbGFjZWhvbGRlcj0iUGFzc3dvcmQiIHZhbHVlPSIiPgoKICAgICAgPC9mb3JtPgoKICAgIDwvZGl2PgoKICAgIDxkaXYgaWQ9ImJveC1mb290ZXIiPgogICAgICA8aW5wdXQgaWQ9InN1Ym1pdCIgY2xhc3M9IiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0ie3suYnV0dG9uLmxvZ2lufX0iIG9uY2xpY2s9ImphdmFzY3JpcHQ6IGxvZ2luKCk7Ij4KICAgIDwvZGl2PgoKICA8L2Rpdj4KCjwvYm9keT4KCjwvaHRtbD4="
+ webUI["html/maintenance.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KCjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCIgLz4KICA8dGl0bGU+eFRlVmU8L3RpdGxlPgogIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImNzcy9iYXNlLmNzcyIgdHlwZT0idGV4dC9jc3MiPgo8L2hlYWQ+Cgo8Ym9keT4KCiAgPGRpdiBpZD0iaGVhZGVyIiBjbGFzcz0iaW1nQ2VudGVyIj48L2Rpdj4KCiAgPGRpdiBpZD0iYm94Ij4KCiAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgIDxoMSBpZD0iaGVhZC10ZXh0IiBjbGFzcz0iY2VudGVyIj5NYWludGVuYW5jZTwvaDE+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJjb250ZW50Ij4KICAgICAgeFRlVmUgaXMgdXBkYXRpbmcgdGhlIGRhdGFiYXNlLCBwbGVhc2UgdHJ5IGFnYWluIGxhdGVyLgogICAgPC9kaXY+CgogICAgPGRpdiBpZD0iYm94LWZvb3RlciI+PC9kaXY+CgogIDwvZGl2PgoKPC9ib2R5PgoKPC9odG1sPg=="
webUI["html/video/stream-limit.ts"] = "R0AREABC8CUAAcEAAP8B/wAB/IAUSBIBBkZGbXBlZwlTZXJ2aWNlMDF3fEPK//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9HQAAQAACwDQABwQAAAAHwACqxBLL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0dQABAAArASAAHBAADhAPAAG+EA8AAVvU1W////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////R0EAMAdQAAB7DH4AAAAB4AAAgMAKMQAJEKERAAfYYQAAAAEJ8AAAAAFnZAAorNlAeAIn5cBEAAADAAQAAAMAyDxgxlgAAAABaOvjyyLAAAABBgX//6rcRem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTUyIHIyODU0IGU5YTU5MDMgLSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDE3IC0gaHR0cDovL3dHAQARd3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2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ACqxBLL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0dQABEAArASAAHBAADhAPAAG+EA8AAVvU1W////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////RwEAGO10tGlFAwyE91Tzg8923ovJk1dv2xh1gVlYQFtWdZ6NSQ8vgHM7/tMfIZPsqgCU856rdBJJRMDaor/oWA7pkvSmC2aqaC5fd/mkWUPTuG8fRhGqOY1rKxLNSI3HtTQAcuVBxRM0NfMw0ky/JMJYZiCgXcNsxpxl+khr/9fKtO5Fg2VNBti92xcZimHUZDJMQTBOY6vSR9L1N2O/kJQCpdfuc9bkcUTMjH/es/lAySxvbiislkohqkpHAQAZVatwHI0t9eHCUfDyWUEtuCNyDwQFOVMtaYEQJrTrhQX0VduT86F0u0wN9ag0uPsrmX6Rid/x5S7KI1SkS+qP6cdmgSP57uiF4dG6IKsWNfGBLY09H/CFlrg73WINQkkp2diKkdEmtZetn8+ZAKzR5eXN5FebiKt6pIkNLuSofjosypEs2o6boKsfpmbtOV0idOeWDM9C8EIcn3aZwk1s2KBDvt1DlY+i2Cuvhk3XoKLT+pq/bOC5QkcBABolcOXneZXLoQw9W1PH1f/of92Ytjj8okrWijcQAKlE5l8XoTb9qrOiZnDOhqwcMlB9H9rorq041I89hChohYoSkJElcM8V+r8WYN5axD1BNyfwaHAOm4UN2/VEYOkNSfMjmx2S0WW/F2ha8Jj4fc4QgqcXr+TnnbwqLkLTValK4Qa1pcv7PIbDq6zCUfxe04guZ8xEhPQjp17/G6IB/6uq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wnibxQ/cXEblVnM47wbCN3iy4eHjYB5MoIICrSYmd8nt4V0toLs084KJlmnur5FbApYM4W79ff4oZkW88Cg8Fv8TnWhh1Hqc4UlhMbRKm2QxDgfBxar3U7BwNR6prrXXjqfR7ja3tPli+H7Jez/xcTg32QpHAQAdTa7pSSgBvmOqzz175NAFIhwE9p3d71F9jLvhaPv8q1iKopL0kizwzEWElnXWmNhfLkl/Au8KujnoKUaxVdTe+zAZm2dOkejnpNVtVj0Aw9wKcG3ZQ1iRZrUFRIoPKYlmR+oi0LrupuhYABtgPbdCbDtezGTr0nw9wVd/rZ6V+1wcoJ6+8VAVueIdwI3brqm6EoFHiI8L6lER+9SefB8fHo4NYgr/I8jSxaa/2PLX2K/DjrlY6bN8fEcBAB7DXsuh8DITF6CYWj2HTFvqfzlic3QHXnHtvsTFNpyVY1LY8y/fRK2mwALN6IB5W3OuyoKiA3K0lJdQUv2gYhHWvPTV218HYrD0rkbMxRH0SiEEkrHDeOt5T1HtWD13D2/QvMu535fsfZyeaFDjdCE9M0Xi8Lfc7Xj1ZNGend7Jo7/cEiczFkc1vB4z2JpFGZreV2EdquyEzC2STFJtfimyx8QlLngEuR1cxH+lWEcFX+mvBa/eqktIRwEAH6VazFLPNsnHZqsI66TVoArQuUUGFAzr8MT8GZ9V6qpZa5D0jA/4eGi6Kq0smUgRExnqIbSMLWqDf/Pk2YT3MpHTu9VE3Dn9blgB6KsVIkWnB98Y2n/6DrZDcF94Ndu0Ka4U/RZwdV5O5KcO+lU2ZiIOYTYZ6Ie0d+tApxYxJ+YmxaDoCyRNe6crw/yzR5SflT8ddi/E2BM+l+nwVDiKZ/714fmrBxFKWuqLiQNHV19o1cZ8Ubun+ZtHQAASAACwDQABwQAAAAHwACqxBLL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0dQABIAArASAAHBAADhAPAAG+EA8AAVvU1W////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////RwEAEH1s3BdtHdF1ln55B24wdACF/ggcRtPmB4IUB6cZJ+m32I4R48ZkdhAFBulgWcsv0wZwH0o1yi3i4qm3rJ98AUKdB9PsNyG9gURV0bTw4myAj6g5Dgodfv6w9bsbOxsGUWkvgAJ3rrR010BvZbIa6CMRCQRjxkCfRF77ansRJZT0JzhtYeSS/ZJob8Rr2jrng3W2rkmHtE+rdqlPiHxmwkRZvYGhBxwiJO2L6f+l/cABsfs09rA+A0pHAQAREZay3TBUIAfMWhApE+LaPgeyOYtaPFONA9aC0h4QrFkaLZfb86678MK+zLgqDBsDoj50eZHMVcczRjs4sYlv7RG8RIWKb5lB9Kn/8+CkxiiA11cHH1yzLX2SKCmhsak/+P/zYQ1EDvEj33bl9e3Jd62cTI+Qw99KrsWnUMN8hFNeXzoGHA3aec+Li4NFboF8sa6lCPR6Csxsvxw8DJaWCnER5Z0p+nKhXavF/eNHQ0DX47ohycc87UcBABKsYHCHXXe3vK1cFYDWO6rhwM6hxCdJ+/X+VB1akQejL6iBMdUPuadUqBnbprwJM0dWpSSn9uuZZeqe46iZOGIJUo69d8x+ZSvPcBH/dK1Y0LJnoWdgWH51SQg7eYqcwjQW3BOy7ZF02Hn1EhTuhsN7ms8zv3WIeEBDBq0T3Idl+Tmw9iJU9skVYiwygHG2+0XwrLa6y+uiQPwMzrnEr1kuf24XoAqrJTZQiVH3aQF4d94yDreWu2KPRwEAE2FsynHZaUcBXEFbeX0nSxZ7sRcRjJvc7RYOny6N8QFwKDVO7jpRWWYM55kuepBOyZ+7BFYeG+FU1kR+ZfmqyDNkD4D1IPwNh6u9JQxDymfN/aMcQC3WxdvCKquPsAut6dugpGkOFtIe+W3ayc4V/J978P+h1EDFMbFjxRPuXht0K2dBQZCJ0ybISUDqWzhPuep8CdxSU4MvMVfdXh7FLl/BqKJUTT+vM+Pz3XnqCQQmH5TjQ4CK55VHAQAUEtgfkBwIYgtwHkhjmtLw7HNTeJeMfTjATEKcyuKzItSeYxHBmGzQ/+G2otpPCOkVAXJ9mfx7LxrW4joZ0ttTRQJ/wqMUK1IN349LiJoo8y/+FwN4jPNDwIleJG697riqnmLOweFW8spHKLBfnHcyC1pG6EIxFpTqUQ0KHqXD/KXIHKioJNAOVwQ1Gfloxebo/Tdtd00dpHP3gcsAOnV75APCYOjVIlwm2X6ViDeZw6Btdb/Br/+yokcBABU3+eOESLlneGbR5SLiL8wPkoRaZ5X7xFlMTMvsv9yHk26bVdmsubSdbYS1Hy64n0+NnL7C1aLD7aJxOudMjVW5goZbfO2KxBQkCD4HFA284wbaB5vOL7mRilCn6YEs1kiwf22+fBLNUmXDb2p353wrD/ygTDhlki66USvUmd/ZAs9uzAddegEzy7Xn00YysWTu/hegYyZtWFC+X5dhLubWJ7n96y5wjrP7PAOXoQQtFUH9j/rBiP/7RwEAFnL/wYKYuj80mPGtimSbF/E9K7XwjwBz8yHZubmVMTCmwkZBM4h0FR1thnUGiSjqjJT6SfunWCZ/dZDQplrzS00UKcUP399SyM+nNG1br8Za0ZYwWch8nyLHYXSRuxdnrfUUespsOQo1cWSLGf0pV2HIcHoiAAEKwPU6irB5BSoFvB1qKVjgEk+QwAEYAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAABHAQA3pAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AwAAAwAAAwAAAwAAAwAAAwBbwUdBABgAAAHgAACAwAoxAAmBIREAB/SBAAAAAQnwAAAAAUGaJGxDv/6plgAAAwAAAwAAAwAAAwAAAwAAAwAAAwAKCKB0AIhy1ftwLNISWucTFC7xeBcaIzP3oZjZo8uT9hqZVstWGnrPz+vjaA5FuCO+K2w7/o39LygDO7aL+0zSrN90LW7r133x8+f+PEKk8d7pd2fj4RYuMOXOYunzFzRX/4IvR1XsK5WJYwVkOca3yfo7DTvUBP9rgSiTRwEAGQD6CFK1PBC4qYCa+coLVnX+jgODNrau5YJXIekDI4+wUNV+5T5HE4e2t5EGAjn77+kC1Vghmvx8KqPnylVUvsaTofheggxHsPuxn1zQt6nA59UglrRUMn8b4pmrvfqTBSqU949+AcNAI6M/eAqz6r0RG5KNeBhx8R2f0x2kujwHU3pc3rlPb6ZrFM/2HiG97eEIezrvWFG7YAAAAwAAAwAE1KRo1VfbdZQ/tOpNGxFmTcQoFidyD2tHAQAapTTIErUKA2Rc9uIzGJu+oW0uNOxRyl6oJNUNJp5L9TIshNS1CmUKgdCaE3LkLwdE8iUkUnIGfWLiWpWmjzsINYC8dnDaSptB53yJkBu0SsR00oo1PZ0pl4ZzoXGSYQJTPaVCbj6FNqm5wcnUqKTB/rgHdPdnDj0K8asLABeo/n3XCXrDorI+LYSD1FBgmV9O7RZdjfL0NnXOQkiq/ZGirwVV0cUF1aHtZx1yHlAAZKuuu7TqB13CAUcBADuRAP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yj/IrOvAEoXDNGy+nrxWN0l8cmuqWYaUJpuM9XgAAADAAADAAKmR0EAPAcQAACJHH4AAAAB4AAAgMAKMQAJSOERAAkQoQAAAAEJ8AAAAAFBnkJ4hf8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAC/BmhyuvLmkCgKTgACEXfOVvHRHdpBEEmTTz9pIZCa2FD0CXukzDCakOHekTpJQSdsfd7a/jjM1/5lBtKCAGQ6zOCSQ6DeKtyw+CugDuuglGipwmvQW+FIDjnZ6HRd0uaSOGy6VB3h9MI1o4nqaCqVwwIgubYZFHAQA9XgD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////WcZrO6BEiqf8pCxYwlz2mkdUzY/ipM/TIHS4m5xQAAAMAAAMAAA5sVm90p14dlvWgBgY7XQ9KVOJKLtaMAN5KiffVQtNuzW5DfL+RewZpAAADAAADAAAQMUdBAB4AAAHgAACAgAUhAAkswQAAAAEJ8AAAAAEBnmF0Qr8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAABJfBjP2+4+W7ZybyT130+Ma4WSqICfd/dS4YtjrLlmh5VBlfrtwJqdN1PBTYDkwGOOONqZQeFN6lLGJoDzvuh3kv1aDBLqug+JhvrSeu5ebnvcrtQzb2REwJL3h9mvtkr0WfDu4AAADAAADAAs32Y4C/6Ns79oCGj6oqLltY3T4I0/QRwEAP5wA//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8BeoWLRnKQmVgO/RBoBfcK85AAAAMAAAMACFhHQQAwBxAAAJcsfgAAAAHgAACAwAoxAAllAREACUjhAAAAAQnwAAAAAQGeY2pCvwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAEmDKfLGXsvBBQPNYXlEd6WueJ4deApfcHESlG+7V6u0AiWQqJvNZYM+3Js3Lj9Ldc9yYIHqruVwfMtCYGlX3wMavI/DrhMuJw+RreIF8SKsJD8CMccAAAAMAAAMACrFZOBgEqaP/8EyWsAHV6CgcAgfyox/roEcBADGuAP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAADAAADAHTBR0EAEgAAAeAAAIDACjEACfGhEQAJZQEAAAABCfAAAAABQZpoSahBaJlMCHf//qmWAAADAAADAAADAAADAAADAAADAAADAAALf8A2bry6lUyIAQGNFfVK2Cd7h4qDqmqpvmXfkfTwo2Ab79AHhajxJ4MPWIgAAA84xLRIx7I2CrWjWe96OvgkzgS9mtvhuxdzAgpuIOJI3DEY9mviDDZz8XSAAAADAAADAB7AZkj9AAHHGvk+Pzlku8UkWa5HAQAzogD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////6HjAkbF/gsWuvw4QAAAAwAAAwAccUdBADQHEAAApTx+AAAAAeAAAIDACjEACblhEQAJgSEAAAABCfAAAAABQZ6GRREsL/8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAAA3URJB/3lMHSmOd0GYZnfpoR80WdqxlyHzPX+V81VUMeXIGrRgq5agd+ACdjoGI036yQ/rmpGw0CmMBrKwpI+nwFo3SP0s1rI2yHBZaiPJjSUgw33rBkxXcq55kfLf2sAAAAwAAAwACBWolidWDnIeQAAADRwEANbEA//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AAAMADulHQQA2NAD///////////////////////////////////////////////////////////////////8AAAHgAACAgAUhAAmdQQAAAAEJ8AAAAAEBnqV0Qr8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAABJXNihCnx11JUosH2hBE53O/YN+GPHqcnJiQBIf3maTAAj5iRt+7GYUKBAU9iCXTiouCjGYgAAAAwAAAwA9p4HQBg2cAAADAAADAADGgUdBADc4EAAAs0x+AP////////////////////////////////////////////////////////////////8AAAHgAACAwAoxAAnVgREACblhAAAAAQnwAAAAAQGep2pCvwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwBR6/L83y+ZevtMZ0FW4lp8qV7fVXQAhLAWlS6mDxvpaSUgChorvgTMXtxJEIAAAAMAAAMACqFCAAADAAADAAADAAz4R0EAOCsA////////////////////////////////////////////////////////AAAB4AAAgMAKMQALYiERAAnVgQAAAAEJ8AAAAAFBmqxJqEFsmUwId//+qZYAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAApQTq0hABLvkcWCYrAaRRPNDrECJGlF/11BYvG9+JJ9Y86nxnmQzPxtAAe1UgOsXAAADAAADAAADAAADAAADAAADAAADA/JHQQA5JhAAAMFcfgD/////////////////////////////////////////AAAB4AAAgMAKMQALKeERAAnxoQAAAAEJ8AAAAAFBnspFFSwv/wAAAwAAAwAAAwAAAwAAAwAAAwAAAwAADdRFmvrVE0KXDOGwWddlwYa1foib7tXZKmkua6R4APb4b8+tXwdSNNqgf2IVNwGTohgQAcMvp6SiQxpiQym4AAADAAADAANUNUAAAAMAAAMAAAMBN0dBADo8AP//////////////////////////////////////////////////////////////////////////////AAAB4AAAgIAFIQALDcEAAAABCfAAAAABAZ7pdEK/AAADAAADAAADAAADAAADAAADAAADAAADAFHTAfujIUaaLSuklb9y0/so9AEtQAqkAxOviALQZ5jNt/iOkABrCOZ4md0iUnFwAAADAAADAALwckAAAAMAAAMAAATcR0EAO0IQAADPbH4A//////////////////////////////////////////////////////////////////////////////8AAAHgAACAwAoxAAtGAREACynhAAAAAQnwAAAAAQGe62pCvwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwBR6/L83y+WryR9gmVKPGbIhJpkgAFgHCej3gB6rAHPgHHAAAADAAADAAAYIV0AAAMAAAMAAAMABnxHQQA8UQD//////////////////////////////////////////////////////////////////////////////////////////////////////////wAAAeAAAIDACjEAC9KhEQALRgEAAAABCfAAAAABQZrwSahBbJlMCG///qeEAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAADAAAZ8UdBAD00EAAA3Xx+AP///////////////////////////////////////////////////////////wAAAeAAAIDACjEAC5phEQALYiEAAAABCfAAAAABQZ8ORRUsL/8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAAA3URZr61RNClwzhI2ZXdRHYLZWc1yTgKRhTIXBNABHQKIIyYNyc+AaEn1jhATEAAAMAAAMAAAMAckkIAAADAAADAAADAEbBR0EAPkYA////////////////////////////////////////////////////////////////////////////////////////////AAAB4AAAgIAFIQALfkEAAAABCfAAAAABAZ8tdEK/AAADAAADAAADAAADAAADAAADAAADAAADAFHTAfujIUAYRtY0f/43cIs2OjxACR2hMR1QBGYX+34JGAAAAwAAAwAAAwKEJ6AAAAMAAAMAAAMA3oFHQQA/QhAAAOuMfgD//////////////////////////////////////////////////////////////////////////////wAAAeAAAIDACjEAC7aBEQALmmEAAAABCfAAAAABAZ8vakK/AAADAAADAAADAAADAAADAAADAAADAAADAFHr8vzfL5avJH2CZUo8ZsiEmmSAAWAcJ6PeAHqsAc+AccAAAAMAAAMAABghXQAAAwAAAwAAAwAGfEdBADBRAP//////////////////////////////////////////////////////////////////////////////////////////////////////////AAAB4AAAgMAKMQANQyERAAu2gQAAAAEJ8AAAAAFBmzRJqEFsmUwIZ//+nhAAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAGVAR0EAMTQQAAD5nH4A////////////////////////////////////////////////////////////AAAB4AAAgMAKMQANCuERAAvSoQAAAAEJ8AAAAAFBn1JFFSwv/wAAAwAAAwAAAwAAAwAAAwAAAwAAAwAADdRFmvrVE0KXDOEjZld1EdgtlZzXJOApGFMhcE0AEdAogjJg3Jz4BoSfWOEBMQAAAwAAAwAAAwBySQgAAAMAAAMAAAMARsFHQQAyRgD///////////////////////////////////////////////////////////////////////////////////////////8AAAHgAACAgAUhAAvuwQAAAAEJ8AAAAAEBn3F0Qr8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAUdMB+6MhQBhG1jR//jdwizY6PEAJHaExHVAEZhf7fgkYAAADAAADAAADAoQnoAAAAwAAAwAAAwDegEdBADNCEAABB6x+AP//////////////////////////////////////////////////////////////////////////////AAAB4AAAgMAKMQANJwERAA0K4QAAAAEJ8AAAAAEBn3NqQr8AAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAUevy/N8vlq8kfYJlSjxmyISaZIABYBwno94AeqwBz4BxwAAAAwAAAwAAGCFdAAADAAADAAADAAZ8R0EANFIA////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAB4AAAgMAKMQANs6ERAA0nAQAAAAEJ8AAAAAFBm3hJqEFsmUwIV//+OEAAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAAMAAYtHQQA1NBAAARW8fgD///////////////////////////////////////////////////////////8AAAHgAACAwAoxAA17YREADUMhAAAAAQnwAAAAAUGflkUVLC//AAADAAADAAADAAADAAADAAADAAADAAAN1EWa+tUTQpcM4SNmV3UR2C2VnNck4CkYUyFwTQAR0CiCMmDcnPgGhJ9Y4QExAAADAAADAAADAHJJCAAAAwAAAwAAAwBGwEdBADZGAP///////////////////////////////////////////////////////////////////////////////////////////wAAAeAAAICABSEADV9BAAAAAQnwAAAAAQGftXRCvwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwBR0wH7oyFAGEbWNH/+N3CLNjo8QAkdoTEdUARmF/t+CRgAAAMAAAMAAAMChCegAAADAAADAAADAN6BR0EAN0IQAAEjzH4A//////////////////////////////////////////////////////////////////////////////8AAAHgAACAwAoxAA2XgREADXthAAAAAQnwAAAAAQGft2pCvwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwBR6/L83y+WryR9gmVKPGbIhJpkgAFgHCej3gB6rAHPgHHAAAADAAADAAAYIV0AAAMAAAMAAAMABn0="
- webUI["html/configuration.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvY29uZmlndXJhdGlvbl90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbWVudV90cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvc2V0dGluZ3NfdHMuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9ImpzL2Jhc2VfdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keSBvbmxvYWQ9ImphdmFzY3JpcHQ6IHJlYWR5Rm9yQ29uZmlndXJhdGlvbigwKTsiPgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImxvYWRpbmciIGNsYXNzPSJibG9jayI+CiAgICAgICAgPGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgogICAgICA8ZGl2IGlkPSJib3giPgogICAgICAgIAogICAgICAgIDx0YWJsZSBpZD0iY2xpZW50SW5mbyIgY2xhc3M9InZpc2libGUiPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5WZXJzaW9uOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0idmVyc2lvbiIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5PUzo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9Im9zIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5VVUlEOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0idXVpZCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgICA8dGQgY2xhc3M9InRkS2V5Ij5BcmNoOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0iYXJjaCIgY2xhc3M9InRkVmFsIj4mbmJzcDs8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+U3RyZWFtczo8L3RkPgogICAgICAgICAgICA8dGQgaWQ9InN0cmVhbXMiIGNsYXNzPSJ0ZFZhbCI+Jm5ic3A7PC90ZD4KICAgICAgICAgICAgPHRkIGNsYXNzPSJ0ZEtleSI+RFZSOjwvdGQ+CiAgICAgICAgICAgIDx0ZCBpZD0iRFZSIiBjbGFzcz0idGRWYWwiPiZuYnNwOzwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgIDwvdGFibGU+CiAgICAgICAgCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPkNvbmZpZ3VyYXRpb248L2gxPiAgICAgIAogICAgICAgIDwvZGl2PgogICAgICAgIDxwIGlkPSJlcnIiIGNsYXNzPSJlcnJvck1zZyBjZW50ZXIiPjwvcD4gICAKICAgICAgICA8ZGl2IGlkPSJjb250ZW50Ij4KICAgICAgICAgICAgCiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBpZD0iYm94LWZvb3RlciI+CiAgICAgICAgICA8aW5wdXQgaWQ9Im5leHQiIGNsYXNzPSIiIHR5cGU9ImJ1dHRvbiIgbmFtZT0ibmV4dCIgdmFsdWU9Ik5leHQiIG9uY2xpY2s9ImphdmFzY3JpcHQ6IHNhdmVXaXphcmQoKTsiPgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvYm9keT4KPC9odG1sPg=="
- webUI["html/img/log.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMC0xNFQxMToxMDo0MjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CkP32mEAAANASURBVGgF7ZlPiE1RHMffw1AYhiL5k1HEijJiYaFZiHoyFspW2RFRkkSZGgtFWJIwi9FYmo0VOywkKTbKgjSlWcifRCPX51dv6s2d33md77vvXjfmV9859/7u93x/v98959x73p1KRbAkSargAhgDH0E/qIYkuHYEvAPGvwbmNOEerXM/0Q6BRSFuZj/ix0DaDnvCkGppIucDAe4OhzvkcUO+GaELAf8ux7/b8Zlrr+Pvc3zm6nX8NccXdKmFLHaUPJ/Ruhyu5zNap8Nd6PiCLrUQTyi0Rjy/5/M0Zd+smB7M32XwtgBr07aC6yfSTs7XO77OALfH4VbgHsD/HLytVquJx4nyIdQFBsHftscksK5Z0sGhpuN8Or4Aa5sJFHjtO7G2MjKvvZjN1sglOpSlCMt9LrDZ4S4Hd0Qg24vrK+gAZbPtjMqTdFKhEdkIsYxFWP720JlioUK6pzDL41jtpRIqxOOWxecuB3fhRGT8E85YBK8VygI6GSRTCxlH3TaJgyw4O2678aCxO94LbNPovYDdmOrUukIBN/MqwjJEOwGPOHR31W4VONVCLEBR9lAJpBbSrYhn5K5R+quFnGUOr1ICtMIlxjz6XVb6qot9JeKvCPSAdlQJJHDtd8hOIN0wtRDLxx6Ntr0ulalTq1TJNyYzXUjj3SjD8X87Iva7uR8s5+2bi6FtX1oOgi8g2tSn1g2yPx+t3gIR/c90s1+C1vuO/YkxdWrdjxFtE2dE0VELWaqIZ+QuUfqrhZxmyKUvgEoyE1xizOR4YOI8plXXyAZEbYsyTJvXFsUW+x6wGUSbWogJ237rZHSEgojq1CooLT3MdCH6Pcu3xz8zIq0s9lvc2+sgz6dWH/rnQPB/jlybZGoh99hCHJqk0P6TD0jaI/4b7dVYeXVq2bemokyKpRZiHwWKMimWWshxhryjoEpOKXHUNbIN8WcUc5s2r8Vue7l9oAaiTS3EhDeB6EUYnUlGojq1MobLr3uokB/5hcys7OYWKuRl5nD5Cbi5uYXw0ntPHoay2S8Seuol5RZSJ0r/n/DEc/BdrN9kTZrH7BkwDspgwyQxW6uggU3nHnAXvAG/QZE2SrARsL8hJffwDxM0mNDPvT8IAAAAAElFTkSuQmCC"
- webUI["html/img/m3u.png"] = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAsSwAALEsBpT2WqQAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjI4ODwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+Mjg4PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0wNy0yOFQxOTowNzozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CumjVbcAAAGWSURBVGgF7VoxTgJRFGTFaGKBFnbEcABjb0fiBego7D2ABYmn8ARKRWFNQ6gx4QRQGWJJoY2VhXGdl7Dkh7Dsx3ns3yXvJ5P97L6d92bmhwYqlcWK43gK5L2enP51NP8F7pN721wPnOITZx9qG6HxI8QIZO+9XCHeL+VQKKm8QMyxb6+iCpH528AQYs58xIQWknV8mhDxCjEXWWJCC8maT55fAmOIudpUXAYhMn8dGEHMTZqYsgiR+U+BAcTcrhNTJiEy/xHQg5jOqpjD1RsBP3+id8u3P8TUoij6SuoLIwRDfWOofjLYtteyHa1UfcvvcUT1jqpGauVuHnyAdragjv/TAkley3uhj9Y5ZhDQa2+Olgmhz4IygSWibChNZ4nQFioTWCLKhtJ0lghtoTKBJaJsKE1nidAWKhNYIsqG0nSWCG2hMoElomwoTWeJ0BYqE1giyobSdJYIbaEygSWibChNZ4nQFioTWCLKhtJ0biJzmi1/guXMrpDn/OegO3bXMuAH0TtgAvwARV3y57Q34AGoJkL+AErKZ9cqbH7AAAAAAElFTkSuQmCC"
- webUI["html/img/x_white.png"] = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOC0xMS0xNVQxNzoxMToyNTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjM8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xNDQ8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFj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"
- webUI["html/js/base.js"] = "dmFyIGNvbmZpZyAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciBtZW51ICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgc3ViTWVudSAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGFjdGl2ZVN0cmVhbXMgPSBuZXcgT2JqZWN0KCk7CnZhciB4RVBHICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgdXNlcnMgICAgICAgICA9IG5ldyBPYmplY3QoKTsKdmFyIGxvZyAgICAgICAgICAgPSBuZXcgT2JqZWN0KCk7CnZhciB1bmRvICAgICAgICAgID0gbmV3IE9iamVjdCgpOwp2YXIgd2ViU29ja2V0cyAgICA9IHRydWU7CnZhciBjbG9zZUxvZywgdmVyc2lvbiwgYWN0aXZlTWVudTsKdmFyIGNvbHVtblRvU29ydCAgPSAwCgoKaWYgKHdpbmRvdy5XZWJTb2NrZXQgPT09IHVuZGVmaW5lZCkgewogIGFsZXJ0KCJZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJTb2NrZXRzIik7CiAgd2ViU29ja2V0cyA9IGZhbHNlOwp9IAoKZnVuY3Rpb24gcGFnZVJlYWR5KCkgewogIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogIGRhdGFbImNtZCJdID0gImdldFNlcnZlckNvbmZpZyI7CiAgeFRlVmUoZGF0YSk7CiAgLy9zaG93TG9hZGluZ1NjcmVlbihmYWxzZSk7CgogIHZhciByZXNpemVIYW5kbGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgib3BlblN0cmVhbXMiKTsKICB2YXIgYm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpOwogIHJlc2l6ZUhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLCBpbml0aWFsaXNlUmVzaXplLCBmYWxzZSk7CgogIGZ1bmN0aW9uIGluaXRpYWxpc2VSZXNpemUoZSkgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlbW92ZSIsIHN0YXJ0UmVzaXppbmcsIGZhbHNlKTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJtb3VzZXVwIiwgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgfQoKICBmdW5jdGlvbiBzdGFydFJlc2l6aW5nKGUpIHsKICAgIGJveC5zdHlsZS5oZWlnaHQgPSAoZS5jbGllbnRZIC0gYm94Lm9mZnNldFRvcCkgKyAicHgiOwogICAgICAKICAgIHZhciBlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWxsU3RyZWFtcyIpOwogICAgaWYgKGUuY2xpZW50WSA+IDEyMCkgewogICAgICBlbG0uY2xhc3NOYW1lID0gInZpc2libGUiOyAKICAgIH0gZWxzZSB7CiAgICAgIGVsbS5jbGFzc05hbWUgPSAibm90VmlzaWJsZSI7IAogICAgfQoKICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKCiAgfQogIGZ1bmN0aW9uIHN0b3BSZXNpemluZyhlKSB7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzdGFydFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgc3RvcFJlc2l6aW5nLCBmYWxzZSk7CiAgICAgIGNhbGN1bGF0ZVdyYXBwZXJIZWlnaHQoKTsKICB9CgogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJyZXNpemUiLCBmdW5jdGlvbigpewogICAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwogIH0sIHRydWUpOwp9CgoKZnVuY3Rpb24gZ2V0T2JqS2V5cyhvYmopIHsKICB2YXIga2V5cyA9IG5ldyBBcnJheSgpOwoKICBmb3IgKHZhciBpIGluIG9iaikgewogICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkgewogICAgICBrZXlzLnB1c2goaSk7CiAgICB9CiAgfQoKICByZXR1cm4ga2V5czsKfQoKCmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQoaXRlbSkgewogIC8vY29uc29sZS5sb2coaXRlbSk7CiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0ZW1bIl9lbGVtZW50Il0pOwogIGlmIChpdGVtLmhhc093blByb3BlcnR5KCJfdGV4dCIpKSB7CiAgICAvL2VsZW1lbnQuaW5uZXJIVE1MID0gIjxwPiIgKyBpdGVtWyJfdGV4dCJdICsgIjwvcD4iOwogICAgZWxlbWVudC5pbm5lckhUTUwgPSBpdGVtWyJfdGV4dCJdOwogIH0KCiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGl0ZW0pOwogIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewogICAgaWYgKGtleXNbaV0uY2hhckF0KDApICE9ICJfIikgewogICAgICAvL2NvbnNvbGUubG9nKGtleXNbaV0sIGl0ZW1ba2V5c1tpXV0pOwogICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShrZXlzW2ldLCBpdGVtW2tleXNbaV1dKTsKICAgIH0KICB9CgogIC8vY29uc29sZS5sb2coZWxlbWVudCk7CiAgcmV0dXJuIGVsZW1lbnQ7Cn0KCmZ1bmN0aW9uIG1vZGlmeU9wdGlvbihpZCwgb3B0aW9ucywgdmFsdWVzKSB7CiAgdmFyIHNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICBzZWxlY3QuaW5uZXJIVE1MID0gIiI7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgb3B0aW9ucy5sZW5ndGg7IGkrKykgewogIAogICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRJT04iKQogIAogICAgZWxlbWVudC52YWx1ZSA9IHZhbHVlc1tpXTsKICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gb3B0aW9uc1tpXTsKCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgCiAgfQoKfQoKCmZ1bmN0aW9uIHN0YXJ0V2ViU29ja2V0KCkgewogIGlmICh3ZWJTb2NrZXRzID09IGZhbHNlKSB7CiAgICByZXR1cm47CiAgfQoKICAvL3dzLnNlbmQoJ3siY21kIjogImdldFNlcnZlckNvbmZpZzEifScpOwoKfQoKZnVuY3Rpb24gY2hlY2tFcnIob2JqKSB7CiAgLy9hbGVydChvYmpbImVyciJdKQogIC8vc2NyZWVuTG9nKG9ialsiZXJyIl0sICJlcnJvciIpCiAgY29uc29sZS5sb2cob2JqKTsKICB2YXIgbmV3T2JqID0gbmV3IE9iamVjdCgpOwogIHZhciBuZXdFcnIgPSBuZXcgT2JqZWN0KCk7CiAgbmV3RXJyWyJrZXkiXSAgID0gIkVycm9yIjsKICBuZXdFcnJbInZhbHVlIl0gPSBvYmpbImVyciJdOwogIG5ld0VyclsidHlwZSJdICA9ICJlcnJvciI7CgogIG5ld09ialswXSA9IG5ld0VycgogIHNob3dMb2cobmV3T2JqKTsKICByZXR1cm4KfQoKZnVuY3Rpb24gc2NyZWVuTG9nKG1zZywgbXNnVHlwZSwgc2hvdykgewogIHJldHVybgogIGNsZWFyVGltZW91dChjbG9zZUxvZykKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIHZhciBuZXdNc2cgPSBuZXcgT2JqZWN0KCk7CiAgCiAgbmV3TXNnWyJfZWxlbWVudCJdID0gIlAiOwogIAogIHN3aXRjaChtc2dUeXBlKSB7CiAgICBjYXNlICJlcnJvciI6ICAgbmV3TXNnWyJjbGFzcyJdID0gImVycm9yTXNnIjsgYnJlYWs7CiAgICBjYXNlICJ3YXJuaW5nIjogbmV3TXNnWyJjbGFzcyJdID0gIndhcm5pbmdNc2ciOyBicmVhazsKICAgIC8vZGVmYXVsdDogICAgICBuZXdNc2dbImNsYXNzIl0gPSAiaW5mb01zZyIKICB9CgogIG5ld01zZ1siX3RleHQiXSA9IG1zZzsKCiAgZGl2LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQobmV3TXNnKSk7CgogIGRpdi5zY3JvbGxUb3AgPSBkaXYuc2Nyb2xsSGVpZ2h0OwoKICBpZiAoc2hvdyA9PSBmYWxzZSkgewogICAgcmV0dXJuOwogIH0KCiAgZGl2LmNsYXNzTmFtZSA9ICIiCiAgY2xvc2VMb2cgPSBzZXRUaW1lb3V0KGNsb3NlU2NyZWVuTG9nLCAxMDAwMCk7Cn0KCgpmdW5jdGlvbiBjbG9zZVNjcmVlbkxvZygpIHsKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIGRpdi5jbGFzc05hbWUgPSAic2NyZWVuTG9nSGlkZGVuIgp9CgpmdW5jdGlvbiBzaG93U2NyZWVuTG9nKCkgewogIGNsZWFyVGltZW91dChjbG9zZUxvZykKICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNjcmVlbkxvZyIpOwogIHZhciBjdXJyZW50Q2xhc3MgPSBkaXYuY2xhc3NOYW1lOwogIGRpdi5jbGFzc05hbWUgPSAic2NyZWVuTG9nSGlkZGVuIgoKICBzd2l0Y2goY3VycmVudENsYXNzKSB7CiAgICBjYXNlICJzY3JlZW5Mb2dIaWRkZW4iOiAgZGl2LmNsYXNzTmFtZSA9ICIiOyBicmVhazsgCiAgICBjYXNlICIiOiBkaXYuY2xhc3NOYW1lID0gInNjcmVlbkxvZ0hpZGRlbiI7IGJyZWFrOwogIH0KfQoKZnVuY3Rpb24gc2hvd0xvYWRpbmdTY3JlZW4oZWxtKSB7CiAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJsb2FkaW5nIik7CiAgc3dpdGNoKGVsbSkgewogICAgY2FzZSB0cnVlOiBkaXYuY2xhc3NOYW1lID0gImJsb2NrIjsgYnJlYWs7CiAgICBjYXNlIGZhbHNlOiBkaXYuY2xhc3NOYW1lID0gIm5vbmUiOyBicmVhazsKCiAgICAvKgogICAgY2FzZSB0cnVlOiBkaXYuc3R5bGUuZGlzcGxheSA9ICJibG9jayI7IGJyZWFrOwogICAgY2FzZSBmYWxzZTogZGl2LnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7IGJyZWFrOwogICAgKi8KICB9Cn0KCmZ1bmN0aW9uIGNyZWF0ZUNsaW50SW5mbyhvYmopIHsKICAvL2NvbnNvbGUubG9nKG9iaik7CiAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKG9iaik7CiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CiAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChrZXlzW2ldKSl7CiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGtleXNbaV0pLmlubmVySFRNTCA9IG9ialtrZXlzW2ldXTsKICAgIH0KICB9CiAgLy9kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY2xpZW50SW5mbyIpLmNsYXNzTmFtZSA9ICJ2aXNpYmxlIjsKfQoKZnVuY3Rpb24gc2hvd0VsZW1lbnQoZWxtSUQsIHR5cGUpIHsKICBzd2l0Y2godHlwZSkgewogICAgY2FzZSB0cnVlOiAgY3NzQ2xhc3MgPSAiYmxvY2siOyBicmVhazsKICAgIGNhc2UgZmFsc2U6IGNzc0NsYXNzID0gIm5vbmUiOyBicmVhazsKICB9CgogIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsbUlEKS5jbGFzc05hbWUgPSBjc3NDbGFzczsKfSAKCmZ1bmN0aW9uIHNob3dQb3BVcEVsZW1lbnQoZWxtKSB7CiAgdmFyIGFsbEVsZW1lbnRzID0gbmV3IEFycmF5KCJkZWxldGVVc2VyRGV0YWlsIiwgIm1hcHBpbmctZGV0YWlsIiwgInVzZXItZGV0YWlsIiwgImZpbGUtZGV0YWlsIik7CgogIGZvciAodmFyIGkgPSAwOyBpIDwgYWxsRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKICAgIHNob3dFbGVtZW50KGFsbEVsZW1lbnRzW2ldLCBmYWxzZSkKICB9CgogIHNob3dFbGVtZW50KGVsbSwgdHJ1ZSkKCiAgc2V0VGltZW91dChmdW5jdGlvbigpeyAKICAgIHNob3dFbGVtZW50KCJwb3B1cCIsIHRydWUpOwogIH0sIDEwKTsKfQoKICAvLyBib2R5Li4uCgpmdW5jdGlvbiBzaG93U3RyZWFtcyhmb3JjZSkgewoKICB2YXIgZWxtQm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15U3RyZWFtc0JveCIpOwogIHZhciBlbG0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYWxsU3RyZWFtcyIpOwogIC8vY29uc29sZS5sb2coZWxtKTsKICBzaG93ID0gZWxtLmNsYXNzTmFtZTsKCiAgc3dpdGNoKGZvcmNlKSB7CiAgICBjYXNlIHRydWU6IHNob3cgPSAibm90VmlzaWJsZSI7IGJyZWFrOwogICAgY2FzZSBmYWxzZTogc2hvdyA9ICJ2aXNpYmxlIjsgYnJlYWs7CiAgfQoKICBzd2l0Y2goc2hvdykgewogICAgY2FzZSAibm90VmlzaWJsZSI6IAogICAgICBlbG0uY2xhc3NOYW1lID0gInZpc2libGUiOyAKICAgICAgZWxtQm94LnN0eWxlLmhlaWdodCA9ICIxMDBweCI7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6IAogICAgICBlbG0uY2xhc3NOYW1lID0gIm5vdFZpc2libGUiOyAKICAgICAgZWxtQm94LnN0eWxlLmhlaWdodCA9ICIyMHB4IjsKICAgICAgYnJlYWs7CiAgfQoKICB2YXIgc2hvdyA9IGVsbS5zdHlsZS5kaXNwbGF5OyB7CiAgICAvL2NvbnNvbGUubG9nKGVsbS5zdHlsZS5kaXNwbGF5KTsKICB9CiAgCiAgY2FsY3VsYXRlV3JhcHBlckhlaWdodCgpOwp9CgpmdW5jdGlvbiB4dGV2ZUJhY2t1cCgpIHsKICBjb25zb2xlLmxvZygieHRldmVCYWNrdXAiKTsKICB2YXIgZGF0YSA9IG5ldyBPYmplY3QoKTsKICBkYXRhWyJjbWQiXSA9ICJ4dGV2ZUJhY2t1cCI7CgogIHhUZVZlKGRhdGEpOwp9CgpmdW5jdGlvbiB4dGV2ZVJlc3RvcmUoZWxtKSB7CiAgdmFyIHJlc3RvcmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJJTlBVVCIpOwogIHJlc3RvcmUuc2V0QXR0cmlidXRlKCJ0eXBlIiwgImZpbGUiKTsKICByZXN0b3JlLnNldEF0dHJpYnV0ZSgiY2xhc3MiLCAibm90VmlzaWJsZSIpOwogIHJlc3RvcmUuc2V0QXR0cmlidXRlKCJuYW1lIiwgIiIpOwogIHJlc3RvcmUuaWQgPSAidXBsb2FkIjsKCiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyZXN0b3JlKTsKICByZXN0b3JlLmNsaWNrKCk7CgogIHJlc3RvcmUub25jaGFuZ2UgPSBmdW5jdGlvbigpIHsKICAgIHZhciBmaWxlbmFtZSA9IHJlc3RvcmUuZmlsZXNbMF0ubmFtZQogICAgLy9jb25zb2xlLmxvZyhyZXN0b3JlLnNyY0VsZW1lbnQuZmlsZXNbMF0pOwogICAgdmFyIGNoZWNrID0gY29uZmlybSgiRmlsZTogIiArIGZpbGVuYW1lICsgIlxuQWxsIGRhdGEgd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRob3NlIGZyb20gdGhlIGJhY2t1cC5cblNob3VsZCB0aGUgZmlsZXMgYmUgcmVzdG9yZWQ/Iik7IAogICAgaWYgKGNoZWNrID09IHRydWUpIHsKICAgICAgdmFyIHJlYWRlciAgPSBuZXcgRmlsZVJlYWRlcigpOwogICAgICB2YXIgZmlsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9ZmlsZV0nKS5maWxlc1swXTsKICAgICAgaWYgKGZpbGUpIHsKICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTsKICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICBjb25zb2xlLmxvZyhyZWFkZXIucmVzdWx0KTsKICAgICAgICAgIHZhciBkYXRhID0gbmV3IE9iamVjdCgpOwogICAgICAgICAgZGF0YVsiY21kIl0gICAgID0gInh0ZXZlUmVzdG9yZSIKICAgICAgICAgIGRhdGFbImJhc2U2NCJdICA9IHJlYWRlci5yZXN1bHQKCiAgICAgICAgICB4VGVWZShkYXRhKTsKICAgICAgICAgIHJldHVybgogICAgICAgIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYWxlcnQoIkZpbGUgY291bGQgbm90IGJlIGxvYWRlZCIpCiAgICAgIH0KICAgIH0KICB9Owp9CgpmdW5jdGlvbiBnZXRCYXNlNjQoZmlsZSkgewogICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7CiAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbigpIHsKICAgICBjb25zb2xlLmxvZyhyZWFkZXIucmVzdWx0KTsKICAgfTsKICAgcmVhZGVyLm9uZXJyb3IgPSBmdW5jdGlvbihlcnJvcikgewogICAgIGNvbnNvbGUubG9nKCdFcnJvcjogJywgZXJyb3IpOwogICB9Owp9CgpmdW5jdGlvbiBsb2dvdXQoKSB7CiAgZG9jdW1lbnQuY29va2llLnNwbGl0KCc7JykuZm9yRWFjaChmdW5jdGlvbihjKSB7CiAgICBkb2N1bWVudC5jb29raWUgPSBjLnRyaW0oKS5zcGxpdCgnPScpWzBdICsgJz07JyArICdleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgVVRDOyc7CiAgfSk7CiAgbG9jYXRpb24ucmVsb2FkKCk7Cn0KCmZ1bmN0aW9uIGdldENvb2tpZShuYW1lKSB7CiAgdmFyIHZhbHVlID0gIjsgIiArIGRvY3VtZW50LmNvb2tpZTsKICB2YXIgcGFydHMgPSB2YWx1ZS5zcGxpdCgiOyAiICsgbmFtZSArICI9Iik7CiAgaWYgKHBhcnRzLmxlbmd0aCA9PSAyKSByZXR1cm4gcGFydHMucG9wKCkuc3BsaXQoIjsiKS5zaGlmdCgpOwp9CgpmdW5jdGlvbiBzZXRDb29raWUodG9rZW4pIHsKICAvL2NvbnNvbGUubG9nKHRva2VuKTsKICBkb2N1bWVudC5jb29raWUgPSAiVG9rZW49IiArIHRva2VuCn0KCg=="
- webUI["html/js/logs_ts.js"] = "dmFyIExvZyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHsKICAgIGZ1bmN0aW9uIExvZygpIHsKICAgIH0KICAgIExvZy5wcm90b3R5cGUuY3JlYXRlTG9nID0gZnVuY3Rpb24gKGVudHJ5KSB7CiAgICAgICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJQUkUiKTsKICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiV0FSTklORyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gIndhcm5pbmdNc2ciOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkuaW5kZXhPZigiRVJST1IiKSAhPSAtMSkgewogICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9ICJlcnJvck1zZyI7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeS5pbmRleE9mKCJERUJVRyIpICE9IC0xKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gImRlYnVnTXNnIjsKICAgICAgICB9CiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBlbnRyeTsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH07CiAgICByZXR1cm4gTG9nOwp9KCkpOwpmdW5jdGlvbiBzaG93TG9ncyhib3R0b20pIHsKICAgIHZhciBsb2cgPSBuZXcgTG9nKCk7CiAgICB2YXIgbG9ncyA9IFNFUlZFUlsibG9nIl1bImxvZyJdOwogICAgdmFyIGRpdiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjb250ZW50X2xvZyIpOwogICAgZGl2LmlubmVySFRNTCA9ICIiOwogICAgdmFyIGtleXMgPSBnZXRPYmpLZXlzKGxvZ3MpOwogICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChsb2dJRCkgewogICAgICAgIHZhciBlbnRyeSA9IGxvZy5jcmVhdGVMb2cobG9nc1tsb2dJRF0pOwogICAgICAgIGRpdi5hcHBlbmQoZW50cnkpOwogICAgfSk7CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAoYm90dG9tID09IHRydWUpIHsKICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYm94LXdyYXBwZXIiKTsKICAgICAgICAgICAgd3JhcHBlci5zY3JvbGxUb3AgPSB3cmFwcGVyLnNjcm9sbEhlaWdodDsKICAgICAgICB9CiAgICB9LCAxMCk7Cn0KZnVuY3Rpb24gcmVzZXRMb2dzKCkgewogICAgdmFyIGNtZCA9ICJyZXNldExvZ3MiOwogICAgdmFyIGRhdGEgPSBuZXcgT2JqZWN0KCk7CiAgICB2YXIgc2VydmVyID0gbmV3IFNlcnZlcihjbWQpOwogICAgc2VydmVyLnJlcXVlc3QoZGF0YSk7Cn0K"
- webUI["html/maintenance.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgPC9oZWFkPgoKICAgIDxib2R5PgogICAgICAgICAgCiAgICAgIDxkaXYgaWQ9ImhlYWRlciIgY2xhc3M9ImltZ0NlbnRlciI+PC9kaXY+CgogICAgICA8ZGl2IGlkPSJib3giPgoKICAgICAgICA8ZGl2IGlkPSJoZWFkbGluZSI+CiAgICAgICAgICA8aDEgaWQ9ImhlYWQtdGV4dCIgY2xhc3M9ImNlbnRlciI+TWFpbnRlbmFuY2U8L2gxPiAgICAgIAogICAgICAgIDwvZGl2PiAgCgogICAgICAgIDxkaXYgaWQ9ImNvbnRlbnQiPgogICAgICAgICAgeFRlVmUgaXMgdXBkYXRpbmcgdGhlIGRhdGFiYXNlLCBwbGVhc2UgdHJ5IGFnYWluIGxhdGVyLgogICAgICAgIDwvZGl2PgoKICAgICAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj48L2Rpdj4KICAgICAgICAKICAgICAgPC9kaXY+CgogICAgPC9ib2R5Pgo8L2h0bWw+"
- webUI["html/create-first-user.html"] = "PCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+IAogICAgPHRpdGxlPnhUZVZlPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL3NjcmVlbi5jc3MiIHR5cGU9InRleHQvY3NzIj4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL2Jhc2UuY3NzIiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvbmV0d29ya190cy5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ianMvYXV0aGVudGljYXRpb25fdHMuanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KCiAgICA8Ym9keT4KICAgICAgICAgIAogICAgICA8ZGl2IGlkPSJoZWFkZXIiIGNsYXNzPSJpbWdDZW50ZXIiPjwvZGl2PgoKICAgICAgPGRpdiBpZD0iYm94Ij4KCiAgICAgICAgPGRpdiBpZD0iaGVhZGxpbmUiPgogICAgICAgICAgPGgxIGlkPSJoZWFkLXRleHQiIGNsYXNzPSJjZW50ZXIiPnt7LmFjY291bnQuaGVhZGxpbmV9fTwvaDE+CiAgICAgICAgPC9kaXY+CgogICAgICAgIDxwIGlkPSJlcnIiIGNsYXNzPSJlcnJvck1zZyBjZW50ZXIiPjwvcD4KCiAgICAgICAgPGRpdiBpZD0iY29udGVudCI+CgogICAgICAgICAgICA8Zm9ybSBpZD0iYXV0aGVudGljYXRpb24iIGFjdGlvbj0iIiBtZXRob2Q9InBvc3QiPgoKICAgICAgICAgICAgICA8aDU+e3suYWNjb3VudC51c2VybmFtZS50aXRsZX19OjwvaDU+CiAgICAgICAgICAgICAgPGlucHV0IGlkPSJ1c2VybmFtZSIgdHlwZT0idGV4dCIgbmFtZT0idXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJVc2VybmFtZSIgdmFsdWU9IiI+CiAgICAgICAgICAgICAgPGg1Pnt7LmFjY291bnQucGFzc3dvcmQudGl0bGV9fTo8L2g1PgogICAgICAgICAgICAgIDxpbnB1dCBpZD0icGFzc3dvcmQiIHR5cGU9InBhc3N3b3JkIiBuYW1lPSJwYXNzd29yZCIgcGxhY2Vob2xkZXI9IlBhc3N3b3JkIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICA8aDU+e3suYWNjb3VudC5jb25maXJtLnRpdGxlfX06PC9oNT4KICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImNvbmZpcm0iICB0eXBlPSJwYXNzd29yZCIgbmFtZT0iY29uZmlybSIgIHBsYWNlaG9sZGVyPSJDb25maXJtIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICAKICAgICAgICAgICAgPC9mb3JtPgoKICAgICAgICA8L2Rpdj4KICAgICAgICAKICAgICAgICA8ZGl2IGlkPSJib3gtZm9vdGVyIj4KICAgICAgICAgIDxpbnB1dCBpZD0ic3VibWl0IiBjbGFzcz0iIiB0eXBlPSJidXR0b24iIHZhbHVlPSJ7ey5idXR0b24uY3JhZXRlQWNjb3VudH19IiBvbmNsaWNrPSJqYXZhc2NyaXB0OiBsb2dpbigpOyI+CiAgICAgICAgPC9kaXY+CiAgICAgIAogICAgICAgIAogICAgICA8L2Rpdj4KICAgIDwvYm9keT4KPC9odG1sPg=="
}
diff --git a/src/webserver.go b/src/webserver.go
index 9e519cb..436c2df 100644
--- a/src/webserver.go
+++ b/src/webserver.go
@@ -1,6 +1,7 @@
package src
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -9,16 +10,20 @@ import (
"os"
"strconv"
"strings"
+ "time"
"xteve/src/internal/authentication"
"github.com/gorilla/websocket"
+ "github.com/samber/lo"
)
-// StartWebserver : Startet den Webserver
-func StartWebserver() (err error) {
+// webAlerts channel to send to client
+var webAlerts = make(chan string, 3)
+var restartWebserver = make(chan bool, 1)
- var port = Settings.Port
+// StartWebserver : Start the Webserver
+func StartWebserver() (err error) {
http.HandleFunc("/", Index)
http.HandleFunc("/stream/", Stream)
@@ -30,31 +35,70 @@ func StartWebserver() (err error) {
http.HandleFunc("/api/", API)
http.HandleFunc("/images/", Images)
http.HandleFunc("/data_images/", DataImages)
+ // http.HandleFunc("/auto/", Auto)
- //http.HandleFunc("/auto/", Auto)
+ for {
- showInfo("DVR IP:" + System.IPAddress + ":" + Settings.Port)
+ showInfo("Web server:" + "Starting")
- var ips = len(System.IPAddressesV4) + len(System.IPAddressesV6) - 1
- switch ips {
+ showInfo("DVR IP:" + Settings.HostIP + ":" + Settings.Port)
- case 0:
- showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/", System.ServerProtocol.WEB, System.IPAddress, Settings.Port))
+ var ips = len(System.IPAddressesV4) + len(System.IPAddressesV6) - 1
+ switch ips {
- case 1:
- showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/ | xTeVe is also available via the other %d IP.", System.ServerProtocol.WEB, System.IPAddress, Settings.Port, ips))
+ case 0:
+ showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/", System.ServerProtocol.WEB, Settings.HostIP, Settings.Port))
- default:
- showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/ | xTeVe is also available via the other %d IP's.", System.ServerProtocol.WEB, System.IPAddress, Settings.Port, len(System.IPAddressesV4)+len(System.IPAddressesV6)-1))
+ case 1:
+ showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/ | xTeVe is also available via the other %d IP.", System.ServerProtocol.WEB, Settings.HostIP, Settings.Port, ips))
- }
+ default:
+ showHighlight(fmt.Sprintf("Web Interface:%s://%s:%s/web/ | xTeVe is also available via the other %d IP's.", System.ServerProtocol.WEB, Settings.HostIP, Settings.Port, len(System.IPAddressesV4)+len(System.IPAddressesV6)-1))
- if err = http.ListenAndServe(":"+port, nil); err != nil {
- ShowError(err, 1001)
- return
+ }
+
+ var port = Settings.Port
+ server := http.Server{Addr: ":" + port}
+
+ go func() {
+ var err error
+
+ if Settings.TLSMode {
+ if !allFilesExist(System.File.ServerCertPrivKey, System.File.ServerCert) {
+ if err = genCertFiles(); err != nil {
+ ShowError(err, 7000)
+ }
+ }
+
+ err = server.ListenAndServeTLS(System.File.ServerCert, System.File.ServerCertPrivKey)
+ if err != nil && err != http.ErrServerClosed {
+ ShowError(err, 1017)
+ err = server.ListenAndServe()
+ }
+ } else {
+ err = server.ListenAndServe()
+ }
+
+ if err != nil && err != http.ErrServerClosed {
+ ShowError(err, 1001)
+ return
+ }
+ }()
+
+ <-restartWebserver
+ showInfo("Web server:" + "Restarting")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ if err = server.Shutdown(ctx); err != nil {
+ ShowError(err, 1016)
+ return
+ }
+
+ <-ctx.Done()
+ showInfo("Web server:" + "Stopped")
}
- return
}
// Index : Web Server /
@@ -71,6 +115,11 @@ func Index(w http.ResponseWriter, r *http.Request) {
showDebug(debug, 2)
switch path {
+ case "/favicon.ico":
+ if value, ok := webUI["html"+path].(string); ok {
+ response = []byte(GetHTMLString(value))
+ w.Header().Set("Content-Type", "image/x-icon")
+ }
case "/discover.json":
response, err = getDiscover()
@@ -81,7 +130,7 @@ func Index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
case "/lineup.json":
- if Settings.AuthenticationPMS == true {
+ if Settings.AuthenticationPMS {
_, err := basicAuth(r, "authentication.pms")
if err != nil {
@@ -114,7 +163,6 @@ func Index(w http.ResponseWriter, r *http.Request) {
httpStatusError(w, r, 500)
- return
}
// Stream : Web Server /stream/
@@ -142,12 +190,12 @@ func Stream(w http.ResponseWriter, r *http.Request) {
showInfo(fmt.Sprintf("Buffer:false [%s]", Settings.Buffer))
case "xteve":
- if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
+ if strings.Contains(streamInfo.URL, "rtsp://") || strings.Contains(streamInfo.URL, "rtp://") {
err = errors.New("RTSP and RTP streams are not supported")
ShowError(err, 2004)
showInfo("Streaming URL:" + streamInfo.URL)
- http.Redirect(w, r, streamInfo.URL, 302)
+ http.Redirect(w, r, streamInfo.URL, http.StatusFound)
showInfo("Streaming Info:URL was passed to the client")
return
@@ -167,12 +215,12 @@ func Stream(w http.ResponseWriter, r *http.Request) {
showInfo(fmt.Sprintf("Channel Name:%s", streamInfo.Name))
showInfo(fmt.Sprintf("Client User-Agent:%s", r.Header.Get("User-Agent")))
- // Prüfen ob der Buffer verwendet werden soll
+ // Check whether the Buffer should be used
switch Settings.Buffer {
case "-":
showInfo("Streaming URL:" + streamInfo.URL)
- http.Redirect(w, r, streamInfo.URL, 302)
+ http.Redirect(w, r, streamInfo.URL, http.StatusFound)
showInfo("Streaming Info:URL was passed to the client.")
showInfo("Streaming Info:xTeVe is no longer involved, the client connects directly to the streaming server.")
@@ -182,10 +230,9 @@ func Stream(w http.ResponseWriter, r *http.Request) {
}
- return
}
-// Auto : HDHR routing (wird derzeit nicht benutzt)
+// Auto : HDHR routing (is currently not used)
func Auto(w http.ResponseWriter, r *http.Request) {
var channelID = strings.Replace(r.RequestURI, "/auto/v", "", 1)
@@ -207,10 +254,9 @@ func Auto(w http.ResponseWriter, r *http.Request) {
}
*/
- return
}
-// xTeVe : Web Server /xmltv/ und /m3u/
+// xTeVe : Web Server /xmltv/ and /m3u/
func xTeVe(w http.ResponseWriter, r *http.Request) {
var requestType, groupTitle, file, content, contentType string
@@ -220,7 +266,7 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
setGlobalDomain(r.Host)
- // XMLTV Datei
+ // XMLTV File
if strings.Contains(path, "xmltv/") {
requestType = "xml"
@@ -235,15 +281,15 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
}
- // M3U Datei
+ // M3U File
if strings.Contains(path, "m3u/") {
requestType = "m3u"
groupTitle = r.URL.Query().Get("group-title")
- if System.Dev == false {
- // false: Dateiname wird im Header gesetzt
- // true: M3U wird direkt im Browser angezeigt
+ if !System.Dev {
+ // false: File name is set in the header
+ // true: M3U is displayed directly in the browser
w.Header().Set("Content-Disposition", "attachment; filename="+getFilenameFromPath(path))
}
@@ -258,7 +304,7 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
}
- // Authentifizierung überprüfen
+ // Check Authentication
err = urlAuth(r, requestType)
if err != nil {
ShowError(err, 000)
@@ -277,7 +323,6 @@ func xTeVe(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(content))
}
- return
}
// Images : Image Cache /images/
@@ -297,10 +342,9 @@ func Images(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write(content)
- return
}
-// DataImages : Image Pfad für Logos / Bilder die hochgeladen wurden /data_images/
+// DataImages : Image path for Logos / Images that have been uploaded / data_images /
func DataImages(w http.ResponseWriter, r *http.Request) {
var path = strings.TrimPrefix(r.URL.Path, "/")
@@ -317,7 +361,6 @@ func DataImages(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write(content)
- return
}
// WS : Web Sockets /ws/
@@ -329,31 +372,40 @@ func WS(w http.ResponseWriter, r *http.Request) {
var newToken string
- /*
- if r.Header.Get("Origin") != "http://"+r.Host {
- httpStatusError(w, r, 403)
- return
- }
- */
+ // if r.Header.Get("Origin") != "http://" + r.Host {
+ // httpStatusError(w, r, 403)
+ // return
+ // }
+
+ u := websocket.Upgrader{ReadBufferSize: 1024, WriteBufferSize: 1024}
+
+ conn, err := u.Upgrade(w, r, w.Header())
- conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
if err != nil {
ShowError(err, 0)
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
return
}
+ defer conn.Close()
setGlobalDomain(r.Host)
for {
+ select {
+ case response.Alert = <-webAlerts:
+ //
+ default:
+ //
+ }
+
err = conn.ReadJSON(&request)
if err != nil {
return
}
- if System.ConfigurationWizard == false {
+ if !System.ConfigurationWizard {
switch Settings.AuthenticationWEB {
@@ -392,77 +444,116 @@ func WS(w http.ResponseWriter, r *http.Request) {
}
switch request.Cmd {
- // Daten lesen
+ // Read Data
case "getServerConfig":
- //response.Config = Settings
+ // response.Config = Settings
case "updateLog":
response = setDefaultResponseData(response, false)
if err = conn.WriteJSON(response); err != nil {
ShowError(err, 1022)
- } else {
- return
- break
}
return
case "loadFiles":
- //response.Response = Settings.Files
+ // response.Response = Settings.Files
- // Daten schreiben
+ // Save Data
case "saveSettings":
var authenticationUpdate = Settings.AuthenticationWEB
+ var previousTLSMode = Settings.TLSMode
+ var previousHostIP = Settings.HostIP
+ var previousHostName = Settings.HostName
+ var previousStoreBufferInRAM = Settings.StoreBufferInRAM
+ var previousClearXMLTVCache = Settings.ClearXMLTVCache
+
response.Settings, err = updateServerSettings(request)
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("settings", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "settings"))
- if Settings.AuthenticationWEB == true && authenticationUpdate == false {
+ if Settings.AuthenticationWEB && !authenticationUpdate {
response.Reload = true
}
+ if Settings.TLSMode != previousTLSMode {
+ showInfo("Web server:" + "Toggling TLS mode")
+
+ reinitialize()
+
+ response.OpenLink = System.URLBase + "/web/"
+ restartWebserver <- true
+ }
+
+ if Settings.HostIP != previousHostIP {
+ showInfo("Web server:" + fmt.Sprintf("Changing host IP to %s", Settings.HostIP))
+
+ reinitialize()
+
+ response.OpenLink = System.URLBase + "/web/"
+ restartWebserver <- true
+ }
+
+ if Settings.HostName != previousHostName {
+ Settings.HostIP = previousHostName
+ showInfo("Web server:" + fmt.Sprintf("Changing host name to %s", Settings.HostName))
+
+ reinitialize()
+
+ response.OpenLink = System.URLBase + "/web/"
+ restartWebserver <- true
+ }
+
+ if Settings.StoreBufferInRAM != previousStoreBufferInRAM {
+ initBufferVFS(Settings.StoreBufferInRAM)
+ }
+
+ if Settings.ClearXMLTVCache && !previousClearXMLTVCache {
+ clearXMLTVCache()
+ }
+
}
case "saveFilesM3U":
err = saveFiles(request, "m3u")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("playlist", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "playlist"))
}
case "updateFileM3U":
err = updateFile(request, "m3u")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("playlist", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "playlist"))
}
case "saveFilesHDHR":
err = saveFiles(request, "hdhr")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("playlist", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "playlist"))
}
case "updateFileHDHR":
err = updateFile(request, "hdhr")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("playlist", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "playlist"))
}
case "saveFilesXMLTV":
err = saveFiles(request, "xmltv")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("xmltv", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "xmltv"))
}
case "updateFileXMLTV":
err = updateFile(request, "xmltv")
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("xmltv", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "xmltv"))
}
case "saveFilter":
response.Settings, err = saveFilter(request)
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("filter", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "filter"))
}
case "saveEpgMapping":
@@ -471,20 +562,20 @@ func WS(w http.ResponseWriter, r *http.Request) {
case "saveUserData":
err = saveUserData(request)
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("users", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "users"))
}
case "saveNewUser":
err = saveNewUser(request)
if err == nil {
- response.OpenMenu = strconv.Itoa(indexOfString("users", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "users"))
}
case "resetLogs":
WebScreenLog.Log = make([]string, 0)
WebScreenLog.Errors = 0
WebScreenLog.Warnings = 0
- response.OpenMenu = strconv.Itoa(indexOfString("log", System.WEB.Menu))
+ response.OpenMenu = strconv.Itoa(lo.IndexOf(System.WEB.Menu, "log"))
case "xteveBackup":
file, errNew := xteveBackup()
@@ -550,17 +641,16 @@ func WS(w http.ResponseWriter, r *http.Request) {
}
- /*
- case "wizardCompleted":
- System.ConfigurationWizard = false
- response.Reload = true
- */
+ // case "wizardCompleted":
+ // System.ConfigurationWizard = false
+ // response.Reload = true
+
default:
fmt.Println("+ + + + + + + + + + +", request.Cmd)
var requestMap = make(map[string]interface{}) // Debug
_ = requestMap
- if System.Dev == true {
+ if System.Dev {
fmt.Println(mapToJSON(requestMap))
}
@@ -573,7 +663,7 @@ func WS(w http.ResponseWriter, r *http.Request) {
}
response = setDefaultResponseData(response, true)
- if System.ConfigurationWizard == true {
+ if System.ConfigurationWizard {
response.ConfigurationWizard = System.ConfigurationWizard
}
@@ -585,7 +675,6 @@ func WS(w http.ResponseWriter, r *http.Request) {
}
- return
}
// Web : Web Server /web/
@@ -601,7 +690,7 @@ func Web(w http.ResponseWriter, r *http.Request) {
setGlobalDomain(r.Host)
- if System.Dev == true {
+ if System.Dev {
lang, err = loadJSONFileToMap(fmt.Sprintf("html/lang/%s.json", Settings.Language))
if err != nil {
@@ -665,7 +754,7 @@ func Web(w http.ResponseWriter, r *http.Request) {
confirm = r.FormValue("confirm")
}
- // Erster Benutzer wird angelegt (Passwortbestätigung ist vorhanden)
+ // First user is created (Password confirmation is available)
if len(confirm) > 0 {
var token, err = createFirstUserForAuthentication(username, password)
@@ -673,14 +762,14 @@ func Web(w http.ResponseWriter, r *http.Request) {
httpStatusError(w, r, 429)
return
}
- // Redirect, damit die Daten aus dem Browser gelöscht werden.
+ // Redirect so that the Data is deleted from the Browser.
w = authentication.SetCookieToken(w, token)
- http.Redirect(w, r, "/web", 301)
+ http.Redirect(w, r, "/web", http.StatusMovedPermanently)
return
}
- // Benutzername und Passwort vorhanden, wird jetzt überprüft
+ // Username and Password available, will now be checked
if len(username) > 0 && len(password) > 0 {
var token, err = authentication.UserAuthentication(username, password)
@@ -691,11 +780,11 @@ func Web(w http.ResponseWriter, r *http.Request) {
}
w = authentication.SetCookieToken(w, token)
- http.Redirect(w, r, "/web", 301) // Redirect, damit die Daten aus dem Browser gelöscht werden.
+ http.Redirect(w, r, "/web", http.StatusMovedPermanently) // Redirect so that the Data is deleted from the Browser.
} else {
w = authentication.SetCookieToken(w, "-")
- http.Redirect(w, r, "/web", 301) // Redirect, damit die Daten aus dem Browser gelöscht werden.
+ http.Redirect(w, r, "/web", http.StatusMovedPermanently) // Redirect so that the Data is deleted from the Browser.
}
return
@@ -724,7 +813,7 @@ func Web(w http.ResponseWriter, r *http.Request) {
return
}
- if len(allUserData) == 0 && Settings.AuthenticationWEB == true {
+ if len(allUserData) == 0 && Settings.AuthenticationWEB {
file = requestFile + "create-first-user.html"
}
@@ -732,9 +821,9 @@ func Web(w http.ResponseWriter, r *http.Request) {
requestFile = file
- if value, ok := webUI[requestFile]; ok {
+ if _, ok := webUI[requestFile]; ok {
- content = GetHTMLString(value.(string))
+ //content = GetHTMLString(value.(string))
if contentType == "text/plain" {
w.Header().Set("Content-Disposition", "attachment; filename="+getFilenameFromPath(requestFile))
@@ -749,7 +838,6 @@ func Web(w http.ResponseWriter, r *http.Request) {
}
if value, ok := webUI[requestFile].(string); ok {
-
content = GetHTMLString(value)
contentType = getContentType(requestFile)
@@ -764,8 +852,8 @@ func Web(w http.ResponseWriter, r *http.Request) {
contentType = getContentType(requestFile)
- if System.Dev == true {
- // Lokale Webserver Dateien werden geladen, nur für die Entwicklung
+ if System.Dev {
+ // Local web server Files are loaded, only for Development
content, _ = readStringFromFile(requestFile)
}
@@ -783,37 +871,37 @@ func Web(w http.ResponseWriter, r *http.Request) {
func API(w http.ResponseWriter, r *http.Request) {
/*
- API Bedingungen (ohne Authentifizierung):
- - API muss in den Einstellungen aktiviert sein
+ API conditions (without Authentication):
+ - API must be activated in the Settings
- Beispiel API Request mit curl
+ Example API Request with curl
Status:
curl -X POST -H "Content-Type: application/json" -d '{"cmd":"status"}' http://localhost:34400/api/
- - - - -
- API Bedingungen (mit Authentifizierung):
- - API muss in den Einstellungen aktiviert sein
- - API muss bei den Authentifizierungseinstellungen aktiviert sein
- - Benutzer muss die Berechtigung API haben
+ API conditions (with Authentication):
+ - API must be activated in the Settings
+ - API must be activated in the Authentication Settings
+ - User must have API authorization
- Nach jeder API Anfrage wird ein Token generiert, dieser ist einmal in 60 Minuten gültig.
- In jeder Antwort ist ein neuer Token enthalten
+ A Token is generated after each API request, which is valid once every 60 minutes.
+ A new Token is included in every answer
- Beispiel API Request mit curl
- Login:
+ Example API Request with curl
+ Login request:
curl -X POST -H "Content-Type: application/json" -d '{"cmd":"login","username":"plex","password":"123"}' http://localhost:34400/api/
- Antwort:
+ Response:
{
"status": true,
"token": "U0T-NTSaigh-RlbkqERsHvUpgvaaY2dyRGuwIIvv"
}
- Status mit Verwendung eines Tokens:
+ Status Request using a Token:
curl -X POST -H "Content-Type: application/json" -d '{"cmd":"status","token":"U0T-NTSaigh-RlbkqERsHvUpgvaaY2dyRGuwIIvv"}' http://localhost:4400/api/
- Antwort:
+ Response:
{
"epg.source": "XEPG",
"status": true,
@@ -840,13 +928,12 @@ func API(w http.ResponseWriter, r *http.Request) {
response.Status = false
response.Error = err.Error()
w.Write([]byte(mapToJSON(response)))
- return
}
response.Status = true
- if Settings.API == false {
+ if !Settings.API {
httpStatusError(w, r, 423)
return
}
@@ -872,7 +959,7 @@ func API(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "application/json")
- if Settings.AuthenticationAPI == true {
+ if Settings.AuthenticationAPI {
var token string
switch len(request.Token) {
case 0:
@@ -884,7 +971,7 @@ func API(w http.ResponseWriter, r *http.Request) {
}
} else {
- err = errors.New("Login incorrect")
+ err = errors.New("login incorrect")
if err != nil {
responseAPIError(err)
return
@@ -912,7 +999,7 @@ func API(w http.ResponseWriter, r *http.Request) {
}
switch request.Cmd {
- case "login": // Muss nichts übergeben werden
+ case "login": // Nothing has to be handed over
case "status":
@@ -926,6 +1013,13 @@ func API(w http.ResponseWriter, r *http.Request) {
response.URLM3U = System.ServerProtocol.M3U + "://" + System.Domain + "/m3u/xteve.m3u"
response.URLXepg = System.ServerProtocol.XML + "://" + System.Domain + "/xmltv/xteve.xml"
+ BufferInformation.Range(func(k, v interface{}) bool {
+ playlist := v.(Playlist)
+ response.TunerActive += int64(len(playlist.Streams))
+ response.TunerAll += int64(playlist.Tuner)
+ return true
+ })
+
case "update.m3u":
err = getProviderData("m3u", "")
if err != nil {
@@ -969,10 +1063,9 @@ func API(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(mapToJSON(response)))
- return
}
-// Download : Datei Download
+// Download : File Download
func Download(w http.ResponseWriter, r *http.Request) {
var path = r.URL.Path
@@ -987,14 +1080,14 @@ func Download(w http.ResponseWriter, r *http.Request) {
os.RemoveAll(System.Folder.Temp + getFilenameFromPath(path))
w.Write([]byte(content))
- return
+
}
func setDefaultResponseData(response ResponseStruct, data bool) (defaults ResponseStruct) {
defaults = response
- // Folgende Daten immer an den Client übergeben
+ // Always transfer the following Data to the Client
defaults.ClientInfo.ARCH = System.ARCH
defaults.ClientInfo.EpgSource = Settings.EpgSource
defaults.ClientInfo.DVR = System.Addresses.DVR
@@ -1005,13 +1098,15 @@ func setDefaultResponseData(response ResponseStruct, data bool) (defaults Respon
defaults.ClientInfo.UUID = Settings.UUID
defaults.ClientInfo.Errors = WebScreenLog.Errors
defaults.ClientInfo.Warnings = WebScreenLog.Warnings
+ defaults.IPAddressesV4Host = System.IPAddressesV4Host
+ defaults.Settings.HostIP = Settings.HostIP
defaults.Notification = System.Notification
defaults.Log = WebScreenLog
switch System.Branch {
case "master":
- defaults.ClientInfo.Version = fmt.Sprintf("%s", System.Version)
+ defaults.ClientInfo.Version = System.Version
default:
defaults.ClientInfo.Version = fmt.Sprintf("%s (%s)", System.Version, System.Build)
@@ -1019,7 +1114,7 @@ func setDefaultResponseData(response ResponseStruct, data bool) (defaults Respon
}
- if data == true {
+ if data {
defaults.Users, _ = authentication.GetAllUserData()
//defaults.DVR = System.DVRAddress
@@ -1060,7 +1155,7 @@ func setDefaultResponseData(response ResponseStruct, data bool) (defaults Respon
func httpStatusError(w http.ResponseWriter, r *http.Request, httpStatusCode int) {
http.Error(w, fmt.Sprintf("%s [%d]", http.StatusText(httpStatusCode), httpStatusCode), httpStatusCode)
- return
+
}
func getContentType(filename string) (contentType string) {
diff --git a/src/xepg.go b/src/xepg.go
index 97c7734..0f42dd8 100644
--- a/src/xepg.go
+++ b/src/xepg.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"path"
+ "regexp"
"runtime"
"sort"
@@ -17,9 +18,11 @@ import (
"time"
"xteve/src/internal/imgcache"
+
+ "github.com/samber/lo"
)
-// Provider XMLTV Datei überprüfen
+// Check provider XMLTV File
func checkXMLCompatibility(id string, body []byte) (err error) {
var xmltv XMLTV
@@ -38,7 +41,7 @@ func checkXMLCompatibility(id string, body []byte) (err error) {
return
}
-// XEPG Daten erstellen
+// Create XEPG Data
func buildXEPG(background bool) {
if System.ScanInProgress == 1 {
@@ -69,9 +72,9 @@ func buildXEPG(background bool) {
createXMLTVFile()
createM3UFile()
- showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
+ showInfo("XEPG:" + "Ready to use")
- if Settings.CacheImages == true && System.ImageCachingInProgress == 0 {
+ if Settings.CacheImages && System.ImageCachingInProgress == 0 {
go func() {
@@ -93,12 +96,9 @@ func buildXEPG(background bool) {
System.ScanInProgress = 0
- // Cache löschen
- /*
- Data.Cache.XMLTV = make(map[string]XMLTV)
- Data.Cache.XMLTV = nil
- */
- runtime.GC()
+ if Settings.ClearXMLTVCache {
+ clearXMLTVCache()
+ }
}()
@@ -114,7 +114,7 @@ func buildXEPG(background bool) {
createXMLTVFile()
createM3UFile()
- if Settings.CacheImages == true && System.ImageCachingInProgress == 0 {
+ if Settings.CacheImages && System.ImageCachingInProgress == 0 {
go func() {
@@ -134,14 +134,13 @@ func buildXEPG(background bool) {
}
- showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
+ showInfo("XEPG:" + "Ready to use")
System.ScanInProgress = 0
- // Cache löschen
- //Data.Cache.XMLTV = make(map[string]XMLTV)
- //Data.Cache.XMLTV = nil
- runtime.GC()
+ if Settings.ClearXMLTVCache {
+ clearXMLTVCache()
+ }
}()
@@ -156,54 +155,7 @@ func buildXEPG(background bool) {
}
-// XEPG Daten aktualisieren
-func updateXEPG(background bool) {
-
- if System.ScanInProgress == 1 {
- return
- }
-
- System.ScanInProgress = 1
-
- if Settings.EpgSource == "XEPG" {
-
- switch background {
-
- case false:
-
- createXEPGDatabase()
- mapping()
- cleanupXEPG()
-
- go func() {
-
- createXMLTVFile()
- createM3UFile()
- showInfo("XEPG:" + fmt.Sprintf("Ready to use"))
-
- System.ScanInProgress = 0
-
- }()
-
- case true:
- System.ScanInProgress = 0
-
- }
-
- } else {
-
- System.ScanInProgress = 0
-
- }
-
- // Cache löschen
- //Data.Cache.XMLTV = nil //make(map[string]XMLTV)
- //Data.Cache.XMLTV = make(map[string]XMLTV)
-
- return
-}
-
-// Mapping Menü für die XMLTV Dateien erstellen
+// Create Mapping Menu for the XMLTV Files
func createXEPGMapping() {
Data.XMLTV.Files = getLocalProviderFiles("xmltv")
@@ -211,20 +163,6 @@ func createXEPGMapping() {
var tmpMap = make(map[string]interface{})
- var friendlyDisplayName = func(channel Channel) (displayName string) {
- var dn = channel.DisplayName
- displayName = dn[0].Value
-
- switch len(dn) {
- case 1:
- displayName = dn[0].Value
- default:
- displayName = fmt.Sprintf("%s (%s)", dn[1].Value, dn[0].Value)
- }
-
- return
- }
-
if len(Data.XMLTV.Files) > 0 {
for i := len(Data.XMLTV.Files) - 1; i >= 0; i-- {
@@ -235,7 +173,6 @@ func createXEPGMapping() {
var fileID = strings.TrimSuffix(getFilenameFromPath(file), path.Ext(getFilenameFromPath(file)))
showInfo("XEPG:" + "Parse XMLTV file: " + getProviderParameter(fileID, "xmltv", "name"))
- //xmltv, err = getLocalXMLTV(file)
var xmltv XMLTV
err = getLocalXMLTV(file, &xmltv)
@@ -246,17 +183,17 @@ func createXEPGMapping() {
ShowError(err, 000)
}
- // XML Parsen (Provider Datei)
+ // XML Parsing (Provider File)
if err == nil {
- // Daten aus der XML Datei in eine temporäre Map schreiben
+ // Write Data from the XML File to a temporary Map
var xmltvMap = make(map[string]interface{})
for _, c := range xmltv.Channel {
var channel = make(map[string]interface{})
channel["id"] = c.ID
- channel["display-name"] = friendlyDisplayName(*c)
+ channel["display-names"] = c.DisplayNames
channel["icon"] = c.Icon.Src
xmltvMap[c.ID] = channel
@@ -271,42 +208,40 @@ func createXEPGMapping() {
}
Data.XMLTV.Mapping = tmpMap
- tmpMap = make(map[string]interface{})
} else {
- if System.ConfigurationWizard == false {
+ if !System.ConfigurationWizard {
showWarning(1007)
}
}
- // Auswahl für den Dummy erstellen
+ // Create selection for the Dummy
var dummy = make(map[string]interface{})
var times = []string{"30", "60", "90", "120", "180", "240", "360"}
for _, i := range times {
- var dummyChannel = make(map[string]string)
- dummyChannel["display-name"] = i + " Minutes"
+ var dummyChannel = make(map[string]interface{})
+ dummyChannel["display-names"] = []DisplayName{{Value: i + " Minutes"}}
dummyChannel["id"] = i + "_Minutes"
dummyChannel["icon"] = ""
- dummy[dummyChannel["id"]] = dummyChannel
+ dummy[dummyChannel["id"].(string)] = dummyChannel
}
Data.XMLTV.Mapping["xTeVe Dummy"] = dummy
- return
}
-// XEPG Datenbank erstellen / aktualisieren
+// Create / update XEPG Database
func createXEPGDatabase() (err error) {
- var allChannelNumbers = make([]float64, 0, System.UnfilteredChannelLimit)
- Data.Cache.Streams.Active = make([]string, 0, System.UnfilteredChannelLimit)
- Data.XEPG.Channels = make(map[string]interface{}, System.UnfilteredChannelLimit)
+ var allChannelNumbers = make([]float64, 0)
+ Data.Cache.Streams.Active = make([]string, 0)
+ Data.XEPG.Channels = make(map[string]interface{})
Data.XEPG.Channels, err = loadJSONFileToMap(System.File.XEPG)
if err != nil {
@@ -316,7 +251,7 @@ func createXEPGDatabase() (err error) {
var createNewID = func() (xepg string) {
- var firstID = 0 //len(Data.XEPG.Channels)
+ var firstID = 0
newXEPGID:
@@ -329,15 +264,21 @@ func createXEPGDatabase() (err error) {
return
}
- var getFreeChannelNumber = func() (xChannelID string) {
+ var getFreeChannelNumber = func(startingChannel ...string) (xChannelID string) {
sort.Float64s(allChannelNumbers)
var firstFreeNumber float64 = Settings.MappingFirstChannel
+ if startingChannel != nil {
+ var startingChannel, _ = strconv.ParseFloat(startingChannel[0], 64)
+ if startingChannel > 0 {
+ firstFreeNumber = startingChannel
+ }
+ }
for {
- if indexOfFloat64(firstFreeNumber, allChannelNumbers) == -1 {
+ if lo.IndexOf(allChannelNumbers, firstFreeNumber) == -1 {
xChannelID = fmt.Sprintf("%g", firstFreeNumber)
allChannelNumbers = append(allChannelNumbers, firstFreeNumber)
return
@@ -347,17 +288,16 @@ func createXEPGDatabase() (err error) {
}
- return
}
- var generateHashForChannel = func(m3uID string, groupTitle string, tvgID string, tvgName string, uuidKey string, uuidValue string) string {
- hash := md5.Sum([]byte(m3uID + groupTitle + tvgID + tvgName + uuidKey + uuidValue))
+ var generateHashForChannel = func(m3uID string, name string, groupTitle string, tvgID string, tvgName string, uuidKey string, uuidValue string) string {
+ hash := md5.Sum([]byte(m3uID + name + groupTitle + tvgID + tvgName + uuidKey + uuidValue))
return hex.EncodeToString(hash[:])
}
showInfo("XEPG:" + "Update database")
- // Kanal mit fehlenden Kanalnummern löschen. Delete channel with missing channel numbers
+ // Delete Channel with missing Channel Numbers.
for id, dxc := range Data.XEPG.Channels {
var xepgChannel XEPGChannelStruct
@@ -377,22 +317,22 @@ func createXEPGDatabase() (err error) {
}
// Make a map of the db channels based on their previously downloaded attributes -- filename, group, title, etc
- var xepgChannelsValuesMap = make(map[string]XEPGChannelStruct, System.UnfilteredChannelLimit)
+ var xepgChannelsValuesMap = make(map[string]XEPGChannelStruct)
for _, v := range Data.XEPG.Channels {
var channel XEPGChannelStruct
err = json.Unmarshal([]byte(mapToJSON(v)), &channel)
if err != nil {
return
}
- channelHash := generateHashForChannel(channel.FileM3UID, channel.GroupTitle, channel.TvgID, channel.TvgName, channel.UUIDKey, channel.UUIDValue)
+ channelHash := generateHashForChannel(channel.FileM3UID, channel.Name, channel.GroupTitle, channel.TvgID, channel.TvgName, channel.UUIDKey, channel.UUIDValue)
xepgChannelsValuesMap[channelHash] = channel
}
for _, dsa := range Data.Streams.Active {
- var channelExists = false // Entscheidet ob ein Kanal neu zu Datenbank hinzugefügt werden soll. Decides whether a channel should be added to the database
- var channelHasUUID = false // Überprüft, ob der Kanal (Stream) eindeutige ID's besitzt. Checks whether the channel (stream) has unique IDs
- var currentXEPGID string // Aktuelle Datenbank ID (XEPG). Wird verwendet, um den Kanal in der Datenbank mit dem Stream der M3u zu aktualisieren. Current database ID (XEPG) Used to update the channel in the database with the stream of the M3u
+ var channelExists = false // Decides whether a Channel should be added to the Database
+ var channelHasUUID = false // Checks whether the Channel (Stream) has Unique IDs
+ var currentXEPGID string // Current Database ID (XEPG) Used to update the Channel in the Database with the Stream of the M3U
var m3uChannel M3UChannelStructXEPG
@@ -403,8 +343,8 @@ func createXEPGDatabase() (err error) {
Data.Cache.Streams.Active = append(Data.Cache.Streams.Active, m3uChannel.Name+m3uChannel.FileM3UID)
- // Try to find the channel based on matching all known values. If that fails, then move to full channel scan
- m3uChannelHash := generateHashForChannel(m3uChannel.FileM3UID, m3uChannel.GroupTitle, m3uChannel.TvgID, m3uChannel.TvgName, m3uChannel.UUIDKey, m3uChannel.UUIDValue)
+ // Try to find the channel based on matching all known values. If that fails, then move to full channel scan
+ m3uChannelHash := generateHashForChannel(m3uChannel.FileM3UID, m3uChannel.Name, m3uChannel.GroupTitle, m3uChannel.TvgID, m3uChannel.TvgName, m3uChannel.UUIDKey, m3uChannel.UUIDValue)
if val, ok := xepgChannelsValuesMap[m3uChannelHash]; ok {
channelExists = true
currentXEPGID = val.XEPG
@@ -413,7 +353,7 @@ func createXEPGDatabase() (err error) {
}
} else {
- // XEPG Datenbank durchlaufen um nach dem Kanal zu suchen. Run through the XEPG database to search for the channel (full scan)
+ // Run through the XEPG Database to search for the Channel (full scan)
for _, dxc := range xepgChannelsValuesMap {
if m3uChannel.FileM3UID == dxc.FileM3UID {
@@ -421,7 +361,7 @@ func createXEPGDatabase() (err error) {
dxc.FileM3UID = m3uChannel.FileM3UID
dxc.FileM3UName = m3uChannel.FileM3UName
- // Vergleichen des Streams anhand einer UUID in der M3U mit dem Kanal in der Databank. Compare the stream using a UUID in the M3U with the channel in the database
+ // Compare the Stream using a UUID in the M3U with the Channel in the Database
if len(dxc.UUIDValue) > 0 && len(m3uChannel.UUIDValue) > 0 {
if dxc.UUIDValue == m3uChannel.UUIDValue && dxc.UUIDKey == m3uChannel.UUIDKey {
@@ -434,7 +374,8 @@ func createXEPGDatabase() (err error) {
}
} else {
- // Vergleichen des Streams mit dem Kanal in der Databank anhand des Kanalnamens. Compare the stream to the channel in the database using the channel name
+
+ // Compare the Stream to the Channel in the Database using the Channel Name
if dxc.Name == m3uChannel.Name {
channelExists = true
currentXEPGID = dxc.XEPG
@@ -443,6 +384,41 @@ func createXEPGDatabase() (err error) {
}
+ // Rename the Channel if it's update regex matches new channel name
+ if len(dxc.UpdateChannelNameRegex) == 0 {
+ continue
+ }
+ // Guard against the situation when both channels have UUIDValue, they are different, but names are the same
+ if dxc.Name == m3uChannel.Name {
+ continue
+ }
+ nameRx, err := regexp.Compile(dxc.UpdateChannelNameRegex)
+ if err != nil {
+ ShowError(err, 1018)
+ continue
+ }
+ if !nameRx.MatchString(m3uChannel.Name) {
+ continue
+ }
+ if len(dxc.UpdateChannelNameByGroupRegex) > 0 {
+ groupRx, err := regexp.Compile(dxc.UpdateChannelNameByGroupRegex)
+ if err != nil {
+ ShowError(err, 1018)
+ continue
+ }
+ if !groupRx.MatchString(dxc.XGroupTitle) {
+ // Found the channel name to update but it has wrong group
+ continue
+ }
+ }
+ showInfo("XEPG:" + fmt.Sprintf("Renaming the channel '%v' to '%v'", dxc.Name, m3uChannel.Name))
+ channelExists = true
+ // dxc.Name will be assigned later in channelExists switch
+ dxc.XName = m3uChannel.Name
+ currentXEPGID = dxc.XEPG
+ Data.XEPG.Channels[currentXEPGID] = dxc
+ break
+
}
}
@@ -451,38 +427,50 @@ func createXEPGDatabase() (err error) {
switch channelExists {
case true:
- // Bereits vorhandener Kanal
+ // Existing Channel
var xepgChannel XEPGChannelStruct
err = json.Unmarshal([]byte(mapToJSON(Data.XEPG.Channels[currentXEPGID])), &xepgChannel)
if err != nil {
return
}
- // Streaming URL aktualisieren
+ // Update Streaming URL
xepgChannel.URL = m3uChannel.URL
- // Name aktualisieren, anhand des Names wird überprüft ob der Kanal noch in einer Playlist verhanden. Funktion: cleanupXEPG
+ // Update Name, the Name is used to check whether the Channel is still available in a Playlist. Function: cleanupXEPG
xepgChannel.Name = m3uChannel.Name
- // Kanalname aktualisieren, nur mit Kanal ID's möglich
- if channelHasUUID == true {
- if xepgChannel.XUpdateChannelName == true {
+ // Update Channel Name, only possible with Channel ID's
+ if channelHasUUID {
+ if xepgChannel.XUpdateChannelName {
xepgChannel.XName = m3uChannel.Name
}
}
- // Kanallogo aktualisieren. Wird bei vorhandenem Logo in der XMLTV Datei wieder überschrieben
- if xepgChannel.XUpdateChannelIcon == true {
+ // Update GroupTitle
+ xepgChannel.GroupTitle = m3uChannel.GroupTitle
+
+ if xepgChannel.XUpdateChannelGroup {
+ xepgChannel.XGroupTitle = m3uChannel.GroupTitle
+ }
+
+ // Update Channel Logo. Will be overwritten again if the Logo is present in the XMLTV file
+ if xepgChannel.XUpdateChannelIcon {
xepgChannel.TvgLogo = m3uChannel.TvgLogo
}
Data.XEPG.Channels[currentXEPGID] = xepgChannel
case false:
- // Neuer Kanal
+ // New Channel
var xepg = createNewID()
- var xChannelID = getFreeChannelNumber()
-
+ xChannelID := func() string {
+ if m3uChannel.PreserveMapping == "true" {
+ return getFreeChannelNumber(m3uChannel.UUIDValue)
+ } else {
+ return getFreeChannelNumber(m3uChannel.StartingChannel)
+ }
+ }()
var newChannel XEPGChannelStruct
newChannel.FileM3UID = m3uChannel.FileM3UID
newChannel.FileM3UName = m3uChannel.FileM3UName
@@ -493,6 +481,11 @@ func createXEPGDatabase() (err error) {
newChannel.TvgID = m3uChannel.TvgID
newChannel.TvgLogo = m3uChannel.TvgLogo
newChannel.TvgName = m3uChannel.TvgName
+ if m3uChannel.TvgShift == "" {
+ newChannel.TvgShift = "0"
+ } else {
+ newChannel.TvgShift = m3uChannel.TvgShift
+ }
newChannel.URL = m3uChannel.URL
newChannel.XmltvFile = ""
newChannel.XMapping = ""
@@ -506,6 +499,7 @@ func createXEPGDatabase() (err error) {
newChannel.XGroupTitle = m3uChannel.GroupTitle
newChannel.XEPG = xepg
newChannel.XChannelID = xChannelID
+ newChannel.XTimeshift = newChannel.TvgShift
Data.XEPG.Channels[xepg] = newChannel
@@ -521,7 +515,7 @@ func createXEPGDatabase() (err error) {
return
}
-// Kanäle automatisch zuordnen und das Mapping überprüfen
+// Automatically assign Channels and check the Mapping
func mapping() (err error) {
showInfo("XEPG:" + "Map channels")
@@ -533,20 +527,27 @@ func mapping() (err error) {
return
}
- // Automatische Mapping für neue Kanäle. Wird nur ausgeführt, wenn der Kanal deaktiviert ist und keine XMLTV Datei und kein XMLTV Kanal zugeordnet ist.
- if xepgChannel.XActive == false {
+ // Automatic mapping for new Channels. Is only executed if the Channel is deactivated and no XMLTV file and no XMLTV Channel is assigned.
+ if !xepgChannel.XActive {
- // Werte kann "-" sein, deswegen len < 1
- if len(xepgChannel.XmltvFile) < 1 && len(xepgChannel.XmltvFile) < 1 {
+ // Values can be "-", therefore len <= 1
+ // If either XmltvFile (XMLTV file / EPG source) or XMapping (XMLTV Channel / EPG program) is "-" or null, then look for a matching EPG program.
+ if len(xepgChannel.XmltvFile) <= 1 || len(xepgChannel.XMapping) <= 1 {
var tvgID = xepgChannel.TvgID
- // Default für neuen Kanal setzen
- xepgChannel.XmltvFile = "-"
- xepgChannel.XMapping = "-"
+ // Set default for new Channel
+ if Settings.DefaultMissingEPG != "-" {
+ xepgChannel.XmltvFile = "xTeVe Dummy"
+ xepgChannel.XMapping = Settings.DefaultMissingEPG
+ } else {
+ xepgChannel.XmltvFile = "-"
+ xepgChannel.XMapping = "-"
+ }
Data.XEPG.Channels[xepg] = xepgChannel
+ xmltvMapLoop:
for file, xmltvChannels := range Data.XMLTV.Mapping {
if channel, ok := xmltvChannels.(map[string]interface{})[tvgID]; ok {
@@ -555,9 +556,8 @@ func mapping() (err error) {
xepgChannel.XmltvFile = file
xepgChannel.XMapping = channelID
- xepgChannel.XActive = true
- // Falls in der XMLTV Datei ein Logo existiert, wird dieses verwendet. Falls nicht, dann das Logo aus der M3U Datei
+ // If there is a Logo in the XMLTV file, this will be used. If not, then the Logo from the M3U file
if icon, ok := channel.(map[string]interface{})["icon"].(string); ok {
if len(icon) > 0 {
xepgChannel.TvgLogo = icon
@@ -569,6 +569,36 @@ func mapping() (err error) {
}
+ } else {
+
+ // Search for the proper XEPG channel ID by comparing it's name with every alias in XML file
+ for _, xmltvChannel := range xmltvChannels.(map[string]interface{}) {
+ xmltvNames := xmltvChannel.(map[string]interface{})["display-names"].([]DisplayName)
+
+ for _, xmltvName := range xmltvNames {
+ xmltvNameSolid := strings.ReplaceAll(xmltvName.Value, " ", "")
+ xepgNameSolid := strings.ReplaceAll(xepgChannel.Name, " ", "")
+
+ if !strings.EqualFold(xmltvNameSolid, xepgNameSolid) {
+ continue
+ }
+
+ xepgChannel.XmltvFile = file
+ xepgChannel.XMapping = xmltvChannel.(map[string]interface{})["id"].(string)
+
+ // If there is a Logo in the XMLTV file, this will be used.
+ // If not, then the Logo from the M3U file.
+ if icon, ok := xmltvChannel.(map[string]interface{})["icon"].(string); ok {
+ if len(icon) > 0 {
+ xepgChannel.TvgLogo = icon
+ }
+ }
+
+ Data.XEPG.Channels[xepg] = xepgChannel
+ break xmltvMapLoop
+ }
+ }
+
}
}
@@ -577,8 +607,12 @@ func mapping() (err error) {
}
- // Überprüfen, ob die zugeordneten XMLTV Dateien und Kanäle noch existieren.
- if xepgChannel.XActive == true {
+ if Settings.EnableMappedChannels && (xepgChannel.XmltvFile != "-" || xepgChannel.XMapping != "-") {
+ xepgChannel.XActive = true
+ }
+
+ // Check whether the assigned XMLTV Files and Channels still exist.
+ if xepgChannel.XActive {
var mapping = xepgChannel.XMapping
var file = xepgChannel.XmltvFile
@@ -589,10 +623,10 @@ func mapping() (err error) {
if channel, ok := value[mapping].(map[string]interface{}); ok {
- // Kanallogo aktualisieren
+ // Update Channel Logo
if logo, ok := channel["icon"].(string); ok {
- if xepgChannel.XUpdateChannelIcon == true && len(logo) > 0 {
+ if xepgChannel.XUpdateChannelIcon && len(logo) > 0 {
xepgChannel.TvgLogo = logo
}
@@ -610,7 +644,7 @@ func mapping() (err error) {
var fileID = strings.TrimSuffix(getFilenameFromPath(file), path.Ext(getFilenameFromPath(file)))
- ShowError(fmt.Errorf("Missing XMLTV file: %s", getProviderParameter(fileID, "xmltv", "name")), 0)
+ ShowError(fmt.Errorf("missing XMLTV file: %s", getProviderParameter(fileID, "xmltv", "name")), 0)
showWarning(2301)
xepgChannel.XActive = false
@@ -642,11 +676,10 @@ func mapping() (err error) {
return
}
-// XMLTV Datei erstellen
+// Create XMLTV File
func createXMLTVFile() (err error) {
// Image Cache
- // 4edd81ab7c368208cc6448b615051b37.jpg
var imgc = Data.Cache.Images
Data.Cache.ImagesFiles = []string{}
@@ -658,7 +691,7 @@ func createXMLTVFile() (err error) {
for _, file := range files {
- if indexOfString(file.Name(), Data.Cache.ImagesCache) == -1 {
+ if lo.IndexOf(Data.Cache.ImagesCache, file.Name()) == -1 {
Data.Cache.ImagesCache = append(Data.Cache.ImagesCache, file.Name())
}
@@ -691,24 +724,25 @@ func createXMLTVFile() (err error) {
err := json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
if err == nil {
- if xepgChannel.XActive == true {
+ if xepgChannel.XActive {
- // Kanäle
+ // Channels
var channel Channel
channel.ID = xepgChannel.XChannelID
channel.Icon = Icon{Src: imgc.Image.GetURL(xepgChannel.TvgLogo)}
- channel.DisplayName = append(channel.DisplayName, DisplayName{Value: xepgChannel.XName})
+ channel.DisplayNames = append(channel.DisplayNames, DisplayName{Value: xepgChannel.XName})
xepgXML.Channel = append(xepgXML.Channel, &channel)
- // Programme
+ // Programs
*tmpProgram, err = getProgramData(xepgChannel)
if err == nil {
- for _, program := range tmpProgram.Program {
- xepgXML.Program = append(xepgXML.Program, program)
- }
+ // for _, program := range tmpProgram.Program {
+ // xepgXML.Program = append(xepgXML.Program, program)
+ // }
+ xepgXML.Program = append(xepgXML.Program, tmpProgram.Program...)
}
@@ -730,7 +764,7 @@ func createXMLTVFile() (err error) {
return
}
-// Programmdaten erstellen (createXMLTVFile)
+// Create Program Data (createXMLTVFile)
func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
var xmltvFile = System.Folder.Data + xepgChannel.XmltvFile
@@ -752,57 +786,63 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
for _, xmltvProgram := range xmltv.Program {
if xmltvProgram.Channel == channelID {
- //fmt.Println(&channelID)
var program = &Program{}
// Channel ID
program.Channel = xepgChannel.XChannelID
- program.Start = xmltvProgram.Start
- program.Stop = xmltvProgram.Stop
+ timeshift, _ := strconv.Atoi(xepgChannel.XTimeshift)
+ progStart := strings.Split(xmltvProgram.Start, " ")
+ progStop := strings.Split(xmltvProgram.Stop, " ")
+ tzStart, _ := strconv.Atoi(progStart[1])
+ tzStop, _ := strconv.Atoi(progStop[1])
+ progStart[1] = fmt.Sprintf("%+05d", tzStart+timeshift*100)
+ progStop[1] = fmt.Sprintf("%+05d", tzStop+timeshift*100)
+ program.Start = strings.Join(progStart, " ")
+ program.Stop = strings.Join(progStop, " ")
// Title
program.Title = xmltvProgram.Title
- // Sub title (Untertitel)
+ // Subtitle
program.SubTitle = xmltvProgram.SubTitle
- // Description (Beschreibung)
+ // Description
program.Desc = xmltvProgram.Desc
- // Category (Kategorie)
+ // Category
getCategory(program, xmltvProgram, xepgChannel)
- // Credits : (Credits)
+ // Credits
program.Credits = xmltvProgram.Credits
- // Rating (Bewertung)
+ // Rating
program.Rating = xmltvProgram.Rating
- // StarRating (Bewertung / Kritiken)
+ // StarRating
program.StarRating = xmltvProgram.StarRating
- // Country (Länder)
+ // Country
program.Country = xmltvProgram.Country
- // Program icon (Poster / Cover)
+ // Program icon
getPoster(program, xmltvProgram, xepgChannel)
- // Language (Sprache)
+ // Language
program.Language = xmltvProgram.Language
- // Episodes numbers (Episodennummern)
+ // Episodes numbers
getEpisodeNum(program, xmltvProgram, xepgChannel)
- // Video (Videoparameter)
+ // Video
getVideo(program, xmltvProgram, xepgChannel)
- // Date (Datum)
+ // Date
program.Date = xmltvProgram.Date
- // Previously shown (Wiederholung)
+ // Previously shown
program.PreviouslyShown = xmltvProgram.PreviouslyShown
- // New (Neu)
+ // New
program.New = xmltvProgram.New
// Live
@@ -820,7 +860,7 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
return
}
-// Dummy Daten erstellen (createXMLTVFile)
+// Create Dummy Data (createXMLTVFile)
func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
var imgc = Data.Cache.Images
@@ -861,7 +901,7 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
epg.Desc = append(epg.Desc, &Desc{Value: xepgChannel.XDescription, Lang: "en"})
}
- if Settings.XepgReplaceMissingImages == true {
+ if Settings.XepgReplaceMissingImages {
poster.Src = imgc.Image.GetURL(xepgChannel.TvgLogo)
epg.Poster = append(epg.Poster, poster)
}
@@ -882,7 +922,7 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
return
}
-// Kategorien erweitern (createXMLTVFile)
+// Expand Categories (createXMLTVFile)
func getCategory(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelStruct) {
for _, i := range xmltvProgram.Category {
@@ -903,10 +943,9 @@ func getCategory(program *Program, xmltvProgram *Program, xepgChannel XEPGChanne
}
- return
}
-// Programm Poster Cover aus der XMLTV Datei laden
+// Load the Poster Cover Program from the XMLTV File
func getPoster(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelStruct) {
var imgc = Data.Cache.Images
@@ -916,7 +955,7 @@ func getPoster(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelS
program.Poster = append(program.Poster, poster)
}
- if Settings.XepgReplaceMissingImages == true {
+ if Settings.XepgReplaceMissingImages {
if len(xmltvProgram.Poster) == 0 {
var poster Poster
@@ -928,7 +967,7 @@ func getPoster(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelS
}
-// Episodensystem übernehmen, falls keins vorhanden ist und eine Kategorie im Mapping eingestellt wurden, wird eine Episode erstellt
+// Apply Episode system, if none is available and a Category has been set in the mapping, an Episode is created
func getEpisodeNum(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelStruct) {
program.EpisodeNum = xmltvProgram.EpisodeNum
@@ -950,10 +989,9 @@ func getEpisodeNum(program *Program, xmltvProgram *Program, xepgChannel XEPGChan
}
- return
}
-// Videoparameter erstellen (createXMLTVFile)
+// Create Video Parameters (createXMLTVFile)
func getVideo(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelStruct) {
var video Video
@@ -976,30 +1014,29 @@ func getVideo(program *Program, xmltvProgram *Program, xepgChannel XEPGChannelSt
program.Video = video
- return
}
-// Lokale Provider XMLTV Datei laden
+// Load Local Provider XMLTV file
func getLocalXMLTV(file string, xmltv *XMLTV) (err error) {
if _, ok := Data.Cache.XMLTV[file]; !ok {
- // Cache initialisieren
+ // Initialize Cache
if len(Data.Cache.XMLTV) == 0 {
Data.Cache.XMLTV = make(map[string]XMLTV)
}
- // XML Daten lesen
+ // Read XML Data
content, err := readByteFromFile(file)
- // Lokale XML Datei existiert nicht im Ordner: data
+ // Local XML File does not exist in the folder: Data
if err != nil {
ShowError(err, 1004)
- err = errors.New("Local copy of the file no longer exists")
+ err = errors.New("local copy of the file no longer exists")
return err
}
- // XML Datei parsen
+ // Parse XML File
err = xml.Unmarshal(content, &xmltv)
if err != nil {
return err
@@ -1014,7 +1051,7 @@ func getLocalXMLTV(file string, xmltv *XMLTV) (err error) {
return
}
-// M3U Datei erstellen
+// Create M3U File
func createM3UFile() {
showInfo("XEPG:" + fmt.Sprintf("Create M3U file (%s)", System.File.M3U))
@@ -1025,14 +1062,11 @@ func createM3UFile() {
saveMapToJSONFile(System.File.URLS, Data.Cache.StreamingURLS)
- return
}
-// XEPG Datenbank bereinigen
+// Clean up the XEPG Database
func cleanupXEPG() {
- //fmt.Println(Settings.Files.M3U)
-
var sourceIDs []string
for source := range Settings.Files.M3U {
@@ -1043,29 +1077,26 @@ func cleanupXEPG() {
sourceIDs = append(sourceIDs, source)
}
- showInfo("XEPG:" + fmt.Sprintf("Cleanup database"))
+ showInfo("XEPG:" + "Cleanup database")
Data.XEPG.XEPGCount = 0
for id, dxc := range Data.XEPG.Channels {
-
var xepgChannel XEPGChannelStruct
err := json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
- if err == nil {
-
- if indexOfString(xepgChannel.Name+xepgChannel.FileM3UID, Data.Cache.Streams.Active) == -1 {
- delete(Data.XEPG.Channels, id)
- } else {
- if xepgChannel.XActive == true {
- Data.XEPG.XEPGCount++
- }
- }
-
- if indexOfString(xepgChannel.FileM3UID, sourceIDs) == -1 {
- delete(Data.XEPG.Channels, id)
- }
-
+ if err != nil {
+ continue
+ }
+ if lo.IndexOf(Data.Cache.Streams.Active, xepgChannel.Name+xepgChannel.FileM3UID) == -1 {
+ delete(Data.XEPG.Channels, id)
+ continue
+ }
+ if lo.IndexOf(sourceIDs, xepgChannel.FileM3UID) == -1 {
+ delete(Data.XEPG.Channels, id)
+ continue
+ }
+ if xepgChannel.XActive {
+ Data.XEPG.XEPGCount++
}
-
}
err := saveMapToJSONFile(System.File.XEPG, Data.XEPG.Channels)
@@ -1080,34 +1111,10 @@ func cleanupXEPG() {
showWarning(2005)
}
- return
}
-// Streaming URL für die Channels App generieren
-func getStreamByChannelID(channelID string) (playlistID, streamURL string, err error) {
-
- err = errors.New("Channel not found")
-
- for _, dxc := range Data.XEPG.Channels {
-
- var xepgChannel XEPGChannelStruct
- err := json.Unmarshal([]byte(mapToJSON(dxc)), &xepgChannel)
-
- fmt.Println(xepgChannel.XChannelID)
-
- if err == nil {
-
- if channelID == xepgChannel.XChannelID {
-
- playlistID = xepgChannel.FileM3UID
- streamURL = xepgChannel.URL
-
- return playlistID, streamURL, nil
- }
-
- }
-
- }
-
- return
+// clearXMLTVCache empties XMLTV cache and runs a garbage collector
+func clearXMLTVCache() {
+ Data.Cache.XMLTV = make(map[string]XMLTV)
+ runtime.GC()
}
diff --git a/ts/authentication_ts.ts b/ts/authentication_ts.ts
index 133b71a..f823b94 100644
--- a/ts/authentication_ts.ts
+++ b/ts/authentication_ts.ts
@@ -6,8 +6,6 @@ function login() {
var inputs:any = div.getElementsByTagName("INPUT")
- console.log(inputs)
-
for (var i = inputs.length - 1; i >= 0; i--) {
var key:string = (inputs[i] as HTMLInputElement).name
@@ -39,8 +37,6 @@ function login() {
}
}
-
- console.log(data)
form.submit();
diff --git a/ts/base_ts.ts b/ts/base_ts.ts
index e5cd134..90630ae 100644
--- a/ts/base_ts.ts
+++ b/ts/base_ts.ts
@@ -7,10 +7,9 @@ var SERVER_CONNECTION = false
var WS_AVAILABLE = false
-// Menü
+// Menu
var menuItems = new Array()
menuItems.push(new MainMenuItem("playlist", "{{.mainMenu.item.playlist}}", "m3u.png", "{{.mainMenu.headline.playlist}}"))
-//menuItems.push(new MainMenuItem("pmsID", "{{.mainMenu.item.pmsID}}", "number.png", "{{.mainMenu.headline.pmsID}}"))
menuItems.push(new MainMenuItem("filter", "{{.mainMenu.item.filter}}", "filter.png", "{{.mainMenu.headline.filter}}"))
menuItems.push(new MainMenuItem("xmltv", "{{.mainMenu.item.xmltv}}", "xmltv.png", "{{.mainMenu.headline.xmltv}}"))
menuItems.push(new MainMenuItem("mapping", "{{.mainMenu.item.mapping}}", "mapping.png", "{{.mainMenu.headline.mapping}}"))
@@ -19,10 +18,12 @@ menuItems.push(new MainMenuItem("settings", "{{.mainMenu.item.settings}}", "sett
menuItems.push(new MainMenuItem("log", "{{.mainMenu.item.log}}", "log.png", "{{.mainMenu.headline.log}}"))
menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}"))
-// Kategorien für die Einstellungen
+// Settings categories
var settingsCategory = new Array()
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
-settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
+settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "tlsMode,xteveAutoUpdate,hostIP,hostName,tuner,epgSource,disallowURLDuplicates,clearXMLTVCache,api"))
+settingsCategory.push(new SettingsCategoryItem("{{.settings.category.mapping}}", "defaultMissingEPG,enableMappedChannels"))
+settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
+settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,storeBufferInRAM,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"))
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"))
@@ -60,7 +61,7 @@ function changeButtonAction(element, buttonID, attribute) {
}
function getLocalData(dataType, id):object {
- var data = new Object()
+ let data = {}
switch(dataType) {
case "m3u":
data = SERVER["settings"]["files"][dataType][id]
@@ -82,6 +83,8 @@ function getLocalData(dataType, id):object {
data["include"] = ""
data["name"] = ""
data["type"] = "group-title"
+ data["preserveMapping"] = true
+ data["startingChannel"] = SERVER["settings"]["mapping.first.channel"]
SERVER["settings"]["filter"][id] = data
}
data = SERVER["settings"]["filter"][id]
@@ -107,16 +110,8 @@ function getLocalData(dataType, id):object {
return data
}
-function getObjKeys(obj) {
- var keys = new Array();
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- keys.push(i);
- }
- }
-
- return keys;
+function getOwnObjProps(object: Object): string[] {
+ return object ? Object.getOwnPropertyNames(object) : [];
}
function getAllSelectedChannels():string[] {
@@ -201,38 +196,38 @@ function bulkEdit() {
}
function sortTable(column) {
- //console.log(columm);
if (column == COLUMN_TO_SORT) {
return;
}
+ const table = document.getElementById("content_table");
+ const tableHead = table.getElementsByTagName("TR")[0];
+ const tableItems = tableHead.getElementsByTagName("TD");
- var table = document.getElementById("content_table");
- var tableHead = table.getElementsByTagName("TR")[0];
- var tableItems = tableHead.getElementsByTagName("TD");
+ type SortEntry = {
+ key: string | number;
+ row: HTMLTableRowElement;
+ }
- var sortObj = new Object();
- var x, xValue;
- var tableHeader
- var sortByString = false
+ const sortArr: SortEntry[] = [];
+ let xValue: string | number;
- if (column > 0 && COLUMN_TO_SORT > 0) {
+ if (column >= 0 && COLUMN_TO_SORT >= 0) {
tableItems[COLUMN_TO_SORT].className = "pointer";
tableItems[column].className = "sortThis";
}
COLUMN_TO_SORT = column;
-
- var rows = (table as HTMLTableElement).rows;
+ const rows = (table as HTMLTableElement).rows;
if (rows[1] != undefined) {
- tableHeader = rows[0]
+ const tableHeader = rows[0];
- x = rows[1].getElementsByTagName("TD")[column];
+ let x: any = rows[1].getElementsByTagName("TD")[column];
- for (i = 1; i < rows.length; i++) {
+ for (let i = 1; i < rows.length; i++) {
x = rows[i].getElementsByTagName("TD")[column];
@@ -245,32 +240,11 @@ function sortTable(column) {
xValue = x.getElementsByTagName("P")[0].innerText.toLowerCase();
break;
- default: console.log(x.childNodes[0].tagName);
+ default:
+ break;
}
- if (xValue == "" || xValue == NaN) {
-
- xValue = i
- sortObj[i] = rows[i];
-
- } else {
-
- switch(isNaN(xValue)) {
- case false:
-
- xValue = parseFloat(xValue);
- sortObj[xValue] = rows[i]
- break;
-
- case true:
-
- sortByString = true
- sortObj[xValue.toLowerCase() + i] = rows[i]
- break;
-
- }
-
- }
+ sortArr.push({key: xValue ? xValue : i, row: rows[i]});
}
@@ -278,25 +252,30 @@ function sortTable(column) {
table.removeChild(table.firstChild);
}
- var sortValues = getObjKeys(sortObj)
+ sortArr.sort((se1: SortEntry, se2: SortEntry): number => {
+ const se1KeyNum = parseFloat(String(se1.key));
+ const se2KeyNum = parseFloat(String(se2.key));
- if (sortByString == true) {
- sortValues.sort()
- console.log(sortValues);
- } else {
- function sortFloat(a, b) {
- return a - b;
+ if (!isNaN(se1KeyNum) && !isNaN(se2KeyNum)) {
+ return se1KeyNum - se2KeyNum;
}
- sortValues.sort(sortFloat);
- }
- table.appendChild(tableHeader)
+ if (se1.key < se2.key) {
+ return -1;
+ }
- for (var i = 0; i < sortValues.length; i++) {
+ if (se1.key > se2.key) {
+ return 1;
+ }
- table.appendChild(sortObj[sortValues[i]])
+ return 0;
+ });
- }
+ table.appendChild(tableHeader);
+
+ sortArr.forEach((se: SortEntry) => {
+ table.appendChild(se.row);
+ });
}
@@ -307,9 +286,9 @@ function createSearchObj() {
SEARCH_MAPPING = new Object()
var data = SERVER["xepg"]["epgMapping"]
- var channels = getObjKeys(data)
+ var channels = getOwnObjProps(data)
- var channelKeys:string[] = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"]
+ var channelKeys:string[] = ["x-active", "x-channelID", "x-name", "updateChannelNameRegex", "_file.m3u.name", "x-group-title", "x-xmltv-file"]
channels.forEach(id => {
@@ -403,7 +382,7 @@ function changeChannelNumber(element) {
var newNumber:number = parseFloat(element.value)
var channelNumbers:number[] = []
var data = SERVER["xepg"]["epgMapping"]
- var channels = getObjKeys(data)
+ var channels = getOwnObjProps(data)
if (isNaN(newNumber)) {
alert("{{.alert.invalidChannelNumber}}")
@@ -436,8 +415,6 @@ function changeChannelNumber(element) {
data[dbID]["x-channelID"] = newNumber.toString()
element.value = newNumber
- console.log(data[dbID]["x-channelID"])
-
if (COLUMN_TO_SORT == 1) {
COLUMN_TO_SORT = -1
sortTable(1)
@@ -449,17 +426,12 @@ function changeChannelNumber(element) {
function backup() {
var data = new Object()
- console.log("Backup data")
-
var cmd = "xteveBackup"
-
- console.log("SEND TO SERVER");
- console.log(data)
-
var server:Server = new Server(cmd)
server.request(data)
return
+
}
function toggleChannelStatus(id:string) {
@@ -514,6 +486,24 @@ function toggleChannelStatus(id:string) {
}
+function toggleGroupUpdateCb(xepgId: string, target: HTMLInputElement) {
+ target.className = 'changed';
+
+ const groupInput: HTMLInputElement = document.querySelector('input[name="x-group-title"]');
+ const mapping = getLocalData('mapping', xepgId);
+
+ if (target.checked) {
+ groupInput.dataset.oldValue = groupInput.value;
+ groupInput.value = mapping['group-title'];
+ groupInput.disabled = true;
+ } else {
+ groupInput.value = groupInput.dataset.oldValue;
+ groupInput.disabled = false;
+ }
+
+ groupInput.className = 'changed';
+}
+
function restore() {
if (document.getElementById('upload')) {
@@ -543,7 +533,6 @@ function restore() {
reader.readAsDataURL(file);
reader.onload = function() {
- console.log(reader.result);
var data = new Object();
var cmd = "xteveRestore"
data["base64"] = reader.result
@@ -596,7 +585,6 @@ function uploadLogo() {
reader.readAsDataURL(file);
reader.onload = function() {
- console.log(reader.result);
var data = new Object();
var cmd = "uploadLogo"
data["base64"] = reader.result
@@ -640,32 +628,8 @@ function checkUndo(key:string) {
return
}
-function sortSelect(elem) {
-
- var tmpAry = [];
- var selectedValue = elem[elem.selectedIndex].value;
-
- for (var i=0;i 0) elem.options[0] = null;
-
- var newSelectedIndex = 0;
-
- for (var i=0;i {
diff --git a/ts/menu_ts.ts b/ts/menu_ts.ts
index c8480c4..b666385 100644
--- a/ts/menu_ts.ts
+++ b/ts/menu_ts.ts
@@ -5,13 +5,14 @@ class MainMenu {
ImagePath:string = "img/"
createIMG(src):any {
- var element = document.createElement("IMG")
+ let element = document.createElement("IMG")
element.setAttribute("src", this.ImagePath + src)
+ element.setAttribute("alt", src)
return element
}
createValue(value):any {
- var element = document.createElement("P")
+ let element = document.createElement("P")
element.innerHTML = value
return element
}
@@ -34,16 +35,16 @@ class MainMenuItem extends MainMenu {
}
createItem():void {
- var item = document.createElement("LI")
+ let item = document.createElement("LI")
item.setAttribute("onclick", "javascript: openThisMenu(this)")
item.setAttribute("id", this.id)
- var img = this.createIMG(this.imgSrc)
- var value = this.createValue(this.value)
+ let img = this.createIMG(this.imgSrc)
+ let value = this.createValue(this.value)
item.appendChild(img)
item.appendChild(value)
- var doc = document.getElementById(this.DocumentID)
+ let doc = document.getElementById(this.DocumentID)
doc.appendChild(item)
switch(this.menuKey) {
@@ -56,20 +57,18 @@ class MainMenuItem extends MainMenu {
break
case "filter":
- this.tableHeader = ["{{.filter.table.name}}", "{{.filter.table.type}}", "{{.filter.table.filter}}"]
+ this.tableHeader = ["{{.filter.table.startingChannel}}", "{{.filter.table.name}}", "{{.filter.table.type}}", "{{.filter.table.filter}}"]
break
case "users":
this.tableHeader = ["{{.users.table.username}}", "{{.users.table.password}}", "{{.users.table.web}}", "{{.users.table.pms}}", "{{.users.table.m3u}}", "{{.users.table.xml}}", "{{.users.table.api}}"]
break
- case "mapping":
- this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}"]
+ case "mapping":
+ this.tableHeader = ["BULK", "{{.mapping.table.chNo}}", "{{.mapping.table.logo}}", "{{.mapping.table.channelName}}", "{{.mapping.table.updateChannelNameRegex}}", "{{.mapping.table.playlist}}", "{{.mapping.table.groupTitle}}", "{{.mapping.table.xmltvFile}}", "{{.mapping.table.xmltvID}}", "{{.mapping.table.timeshift}}"]
break
}
-
- //console.log(this.menuKey, this.tableHeader);
}
}
@@ -83,54 +82,54 @@ class Content {
interactionID:string = "content-interaction"
createHeadline(value):any {
- var element = document.createElement("H3")
+ let element = document.createElement("H3")
element.innerHTML = value
return element
}
createHR():any {
- var element = document.createElement("HR")
- return element
+ return document.createElement("HR")
}
createInteraction():any {
- var element = document.createElement("DIV")
+ let element = document.createElement("DIV")
element.setAttribute("id", this.interactionID)
return element
}
createDIV():any {
- var element = document.createElement("DIV")
+ let element = document.createElement("DIV")
element.id = this.DivID
return element
}
createTABLE():any {
- var element = document.createElement("TABLE")
+ let element = document.createElement("TABLE")
element.id = this.TableID
return element
}
createTableRow():any {
- var element = document.createElement("TR")
+ let element = document.createElement("TR")
element.className = this.headerClass
return element
}
createTableContent(menuKey:string):string[] {
- var data = new Object()
- var rows = new Array()
+ let data = {}
+ let rows = []
+ let fileTypes = []
switch(menuKey) {
case "playlist":
- var fileTypes = new Array("m3u", "hdhr")
+ fileTypes = ["m3u", "hdhr"]
fileTypes.forEach(fileType => {
data = SERVER["settings"]["files"][fileType]
- var keys = getObjKeys(data)
+ var keys = getOwnObjProps(data)
keys.forEach(key => {
var tr = document.createElement("TR")
@@ -203,16 +202,22 @@ class Content {
});
break
- case "filter":
+ case "filter":
delete SERVER["settings"]["filter"][-1]
data = SERVER["settings"]["filter"]
- var keys = getObjKeys(data)
+ var keys = getOwnObjProps(data)
keys.forEach(key => {
var tr = document.createElement("TR")
tr.id = key
tr.setAttribute('onclick', 'javascript: openPopUp("' + data[key]["type"] + '", this)')
-
+
+ var cell:Cell = new Cell()
+ cell.child = true
+ cell.childType = "P"
+ cell.value = data[key]["startingChannel"]
+ tr.appendChild(cell.createCell())
+
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
@@ -230,11 +235,11 @@ class Content {
case "group-title":
cell.value = "{{.filter.group}}"
break;
-
+
default:
break;
}
-
+
tr.appendChild(cell.createCell())
var cell:Cell = new Cell()
@@ -249,63 +254,63 @@ class Content {
break
case "xmltv":
- var fileTypes = new Array("xmltv")
+ fileTypes = new Array("xmltv")
fileTypes.forEach(fileType => {
-
+
data = SERVER["settings"]["files"][fileType]
-
- var keys = getObjKeys(data)
-
+
+ var keys = getOwnObjProps(data)
+
keys.forEach(key => {
var tr = document.createElement("TR")
-
+
tr.id = key
tr.setAttribute('onclick', 'javascript: openPopUp("' + fileType + '", this)')
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
- cell.value = data[key]["name"]
+ cell.value = data[key]["name"]
tr.appendChild(cell.createCell())
-
+
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
cell.value = data[key]["last.update"]
tr.appendChild(cell.createCell())
-
+
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
cell.value = data[key]["provider.availability"]
tr.appendChild(cell.createCell())
-
+
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
cell.value = data[key]["compatibility"]["xmltv.channels"]
tr.appendChild(cell.createCell())
-
+
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
cell.value = data[key]["compatibility"]["xmltv.programs"]
tr.appendChild(cell.createCell())
-
+
rows.push(tr)
});
-
+
});
break
case "users":
- var fileTypes = new Array("users")
+ fileTypes = new Array("users")
fileTypes.forEach(fileType => {
data = SERVER[fileType]
- var keys = getObjKeys(data)
+ var keys = getOwnObjProps(data)
keys.forEach(key => {
var tr = document.createElement("TR")
@@ -384,16 +389,13 @@ class Content {
BULK_EDIT = false
createSearchObj()
checkUndo("epgMapping")
- console.log("MAPPING")
data = SERVER["xepg"]["epgMapping"]
- var keys = getObjKeys(data)
+ var keys = getOwnObjProps(data)
keys.forEach(key => {
var tr = document.createElement("TR")
tr.id = key
- //tr.setAttribute('oncontextmenu', 'javascript: rightClick(this)')
-
switch (data[key]["x-active"]) {
case true:
tr.className = "activeEPG"
@@ -411,12 +413,11 @@ class Content {
cell.value = false
tr.appendChild(cell.createCell())
- // Kanalnummer
+ // Channel number
var cell:Cell = new Cell()
cell.child = true
cell.childType = "INPUTCHANNEL"
cell.value = data[key]["x-channelID"]
- //td.setAttribute('onclick', 'javascript: changeChannelNumber("' + key + '", this)')
tr.appendChild(cell.createCell())
// Logo
@@ -430,7 +431,7 @@ class Content {
tr.appendChild(td)
- // Kanalname
+ // Channel name
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
@@ -440,13 +441,21 @@ class Content {
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
td.id = key
tr.appendChild(td)
-
+
+ // Update channel name regex
+ var cell:Cell = new Cell()
+ cell.child = true
+ cell.childType = "P"
+ cell.value = data[key]["update-channel-name-regex"]
+ var td = cell.createCell()
+ td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
+ td.id = key
+ tr.appendChild(td)
// Playlist
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
- //cell.value = data[key]["_file.m3u.name"]
cell.value = getValueFromProviderFile(data[key]["_file.m3u.id"], "m3u", "name")
var td = cell.createCell()
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
@@ -454,7 +463,7 @@ class Content {
tr.appendChild(td)
- // Gruppe (group-title)
+ // Group (group-title)
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
@@ -464,7 +473,7 @@ class Content {
td.id = key
tr.appendChild(td)
- // XMLTV Datei
+ // XMLTV file
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
@@ -480,11 +489,10 @@ class Content {
td.id = key
tr.appendChild(td)
- // XMLTV Kanal
+ // XMLTV Channel
var cell:Cell = new Cell()
cell.child = true
cell.childType = "P"
- //var value = str.substring(1, 4);
var value = data[key]["x-mapping"]
if (value.length > 20) {
value = data[key]["x-mapping"].substring(0, 20) + "..."
@@ -493,7 +501,16 @@ class Content {
var td = cell.createCell()
td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
td.id = key
+ tr.appendChild(td)
+ // TimeShift
+ var cell:Cell = new Cell()
+ cell.child = true
+ cell.childType = "P"
+ cell.value = data[key]["x-timeshift"]
+ var td = cell.createCell()
+ td.setAttribute('onclick', 'javascript: openPopUp("mapping", this)')
+ td.id = key
tr.appendChild(td)
rows.push(tr)
@@ -506,8 +523,6 @@ class Content {
break
default:
- console.log("Table content (menuKey):", menuKey);
-
break
}
@@ -527,10 +542,10 @@ class Cell {
tdClassName:string
imageURL:string
onclick:boolean
- onclickFunktion:string
+ onclickFunction:string
createCell():any {
- var td = document.createElement("TD")
+ let td = document.createElement("TD")
if (this.child == true) {
@@ -587,7 +602,7 @@ class Cell {
}
if (this.onclick == true) {
- td.setAttribute("onclick", this.onclickFunktion)
+ td.setAttribute("onclick", this.onclickFunction)
td.className = "pointer"
}
@@ -611,7 +626,7 @@ class ShowContent extends Content {
createInput(type:string, name:string, value:string,):any {
- var input = document.createElement("INPUT")
+ let input = document.createElement("INPUT")
input.setAttribute("type", type)
input.setAttribute("name", name)
input.setAttribute("value", value)
@@ -620,25 +635,25 @@ class ShowContent extends Content {
show():void {
COLUMN_TO_SORT = -1
- // Alten Inhalt löschen
- var doc = document.getElementById(this.DocumentID)
+ // Delete old content
+ let doc = document.getElementById(this.DocumentID)
doc.innerHTML = ""
showPreview(false)
- // Überschrift
- var headline:string[] = menuItems[this.menuID].headline
+ // Headline
+ let headline:string[] = menuItems[this.menuID].headline
- var menuKey = menuItems[this.menuID].menuKey
- var h = this.createHeadline(headline)
+ let menuKey = menuItems[this.menuID].menuKey
+ let h = this.createHeadline(headline)
doc.appendChild(h)
- var hr = this.createHR()
+ let hr = this.createHR()
doc.appendChild(hr)
- // Interaktion
- var div =this.createInteraction()
+ // Interaction
+ let div =this.createInteraction()
doc.appendChild(div)
- var interaction = document.getElementById(this.interactionID)
+ let interaction = document.getElementById(this.interactionID)
switch (menuKey) {
case "playlist":
var input = this.createInput("button", menuKey, "{{.button.new}}")
@@ -711,7 +726,6 @@ class ShowContent extends Content {
showSettings()
return
- break
case "log":
var input = this.createInput("button", menuKey, "{{.button.resetLogs}}")
@@ -729,7 +743,6 @@ class ShowContent extends Content {
showLogs(true)
return
- break
case "logout":
location.reload()
@@ -737,11 +750,10 @@ class ShowContent extends Content {
break
default:
- console.log("Show content (menuKey):", menuKey);
break;
}
- // Tabelle erstellen (falls benötigt)
+ // Create table (if needed)
var tableHeader:string[] = menuItems[this.menuID].tableHeader
if (tableHeader.length > 0) {
var wrapper = document.createElement("DIV")
@@ -754,7 +766,7 @@ class ShowContent extends Content {
var header = this.createTableRow()
table.appendChild(header)
- // Kopfzeile der Tablle
+ // Table header
tableHeader.forEach(element => {
var cell:Cell = new Cell()
cell.child = true
@@ -769,33 +781,68 @@ class ShowContent extends Content {
if (element == "{{.mapping.table.chNo}}") {
cell.onclick = true
- cell.onclickFunktion = "javascript: sortTable(1);"
+ cell.onclickFunction = "javascript: sortTable(1);"
cell.tdClassName = "sortThis"
}
if (element == "{{.mapping.table.channelName}}") {
cell.onclick = true
- cell.onclickFunktion = "javascript: sortTable(3);"
+ cell.onclickFunction = "javascript: sortTable(3);"
+ }
+
+ if (element == "{{.mapping.table.updateChannelNameRegex}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(4);"
}
if (element == "{{.mapping.table.playlist}}") {
cell.onclick = true
- cell.onclickFunktion = "javascript: sortTable(4);"
+ cell.onclickFunction = "javascript: sortTable(5);"
}
if (element == "{{.mapping.table.groupTitle}}") {
cell.onclick = true
- cell.onclickFunktion = "javascript: sortTable(5);"
+ cell.onclickFunction = "javascript: sortTable(6);"
}
+ if (element == "{{.mapping.table.timeshift}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(9);"
+ }
+
}
+ if (menuKey == "filter") {
+
+ if (element == "{{.filter.table.startingChannel}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(0);"
+ cell.tdClassName = "sortThis"
+ }
+
+ if (element == "{{.filter.table.name}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(1);"
+ }
+
+ if (element == "{{.filter.table.type}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(2);"
+ }
+
+ if (element == "{{.filter.table.filter}}") {
+ cell.onclick = true
+ cell.onclickFunction = "javascript: sortTable(3);"
+ }
+
+ }
+
header.appendChild(cell.createCell())
});
table.appendChild(header)
- // Inhalt der Tabelle
+ // Content of the table
var rows:any = this.createTableContent(menuKey)
rows.forEach(tr => {
table.appendChild(tr)
@@ -826,8 +873,8 @@ class ShowContent extends Content {
function PageReady() {
- var server:Server = new Server("getServerConfig")
- server.request(new Object())
+ let server:Server = new Server("getServerConfig")
+ server.request({})
window.addEventListener("resize", function(){
calculateWrapperHeight();
@@ -844,14 +891,21 @@ function PageReady() {
function createLayout() {
// Client Info
- var obj = SERVER["clientInfo"]
- var keys = getObjKeys(obj);
+ let obj = SERVER["clientInfo"]
+ let keys = getOwnObjProps(obj);
for (var i = 0; i < keys.length; i++) {
-
+
if (document.getElementById(keys[i])) {
document.getElementById(keys[i]).innerHTML = obj[keys[i]];
+ if (location.protocol === 'https:') {
+ if (keys[i] === "xepg-url" || keys[i] === "m3u-url" || keys[i] === "DVR") {
+ document.getElementById(keys[i]).addEventListener('click', function (event) {
+ const target = event.target as HTMLElement;
+ navigator.clipboard.writeText(target.innerText.split(" ")[0]).then(() => {});
+ },false);
+ }
+ }
}
-
}
if (!document.getElementById("main-menu")) {
@@ -860,7 +914,7 @@ function createLayout() {
- // Menü erstellen
+ // Create menu
document.getElementById("main-menu").innerHTML = ""
for (let i = 0; i < menuItems.length; i++) {
@@ -893,8 +947,8 @@ function createLayout() {
}
function openThisMenu(element) {
- var id = element.id
- var content:ShowContent = new ShowContent(id)
+ let id = element.id
+ let content:ShowContent = new ShowContent(id)
content.show()
calculateWrapperHeight()
@@ -907,20 +961,20 @@ class PopupWindow {
doc = document.getElementById(this.DocumentID)
createTitle(title:string):any {
- var td = document.createElement("TD")
+ let td = document.createElement("TD")
td.className = "left"
td.innerHTML = title + ":"
return td
}
createContent(element):any {
- var td = document.createElement("TD")
+ let td = document.createElement("TD")
td.appendChild(element)
return td
}
createInteraction():any {
- var div = document.createElement("div")
+ let div = document.createElement("div")
div.setAttribute("id", "popup-interaction")
div.className = "interaction"
this.doc.appendChild(div)
@@ -937,15 +991,15 @@ class PopupContent extends PopupWindow{
element.innerHTML = headline.toUpperCase()
this.doc.appendChild(element)
- // Tabelle erstellen
+ // Create table
this.table = document.createElement("TABLE")
this.doc.appendChild(this.table)
}
appendRow(title:string, element:any):void {
- var tr = document.createElement("TR")
+ let tr = document.createElement("TR")
- // Bezeichnung
+ // Title
if (title.length != 0) {
tr.appendChild(this.createTitle(title))
}
@@ -958,8 +1012,8 @@ class PopupContent extends PopupWindow{
createInput(type:string, name:string, value:string):any {
-
- var input = document.createElement("INPUT")
+
+ let input = document.createElement("INPUT")
if (value == undefined) {
value = ""
}
@@ -971,18 +1025,19 @@ class PopupContent extends PopupWindow{
}
createCheckbox(name:string):any {
- var input = document.createElement("INPUT")
+ let input = document.createElement("INPUT")
input.setAttribute("type", "checkbox")
input.setAttribute("name", name)
return input
}
+ // Creates a selection of multiple options values with text descriptions
createSelect(text:string[], values:string[], set:string, dbKey:string):any {
- var select = document.createElement("SELECT")
+ let select = document.createElement("SELECT")
select.setAttribute("name", dbKey)
for (let i = 0; i < text.length; i++) {
- var option = document.createElement("OPTION")
+ let option = document.createElement("OPTION")
option.setAttribute("value", values[i])
option.innerText = text[i]
select.appendChild(option)
@@ -1000,15 +1055,15 @@ class PopupContent extends PopupWindow{
selectOption(select:any, value:string):any {
//select.selectedOptions = value
- var s:HTMLSelectElement = (select as HTMLSelectElement)
+ let s:HTMLSelectElement = (select as HTMLSelectElement)
s.options[s.selectedIndex].value = value
return select
}
description(value:string):any {
- var tr = document.createElement("TR")
- var td = document.createElement("TD")
- var span = document.createElement("PRE")
+ let tr = document.createElement("TR")
+ let td = document.createElement("TD")
+ let span = document.createElement("PRE")
span.innerHTML = value
@@ -1019,17 +1074,17 @@ class PopupContent extends PopupWindow{
this.table.appendChild(tr)
}
- // Interaktion
+ // Interaction
addInteraction(element:any) {
- var interaction = document.getElementById("popup-interaction")
+ let interaction = document.getElementById("popup-interaction")
interaction.appendChild(element)
}
}
function openPopUp(dataType, element) {
- var data:object = new Object();
- var id:any
+ let data:object = {};
+ let id:any
switch (element) {
case undefined:
@@ -1064,8 +1119,8 @@ function openPopUp(dataType, element) {
data = getLocalData(dataType, id)
break;
}
-
- var content:PopupContent = new PopupContent()
+
+ let content:PopupContent = new PopupContent()
switch (dataType) {
case "playlist":
@@ -1078,14 +1133,14 @@ function openPopUp(dataType, element) {
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick")') // changeButtonAction
content.appendRow("{{.playlist.type.title}}", select)
- // Interaktion
+ // Interaction
content.createInteraction()
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Weiter
+ // Next
var input = content.createInput("button", "next", "{{.button.next}}")
input.setAttribute("onclick", 'javascript: openPopUp("m3u")')
input.setAttribute("id", 'next')
@@ -1100,7 +1155,7 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.playlist.name.placeholder}}")
content.appendRow("{{.playlist.name.title}}", input)
- // Beschreibung
+ // Description
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.description.placeholder}}")
@@ -1114,8 +1169,8 @@ function openPopUp(dataType, element) {
// Tuner
if (SERVER["settings"]["buffer"] != "-") {
- var text:string[] = new Array()
- var values:string[] = new Array()
+ var text:string[] = []
+ var values:string[] = []
for (var i = 1; i <= 100; i++) {
text.push(i.toString())
@@ -1139,9 +1194,9 @@ function openPopUp(dataType, element) {
content.description("{{.playlist.tuner.description}}")
- // Interaktion
+ // Interation
content.createInteraction()
- // Löschen
+ // Delete
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
input.className = "delete"
@@ -1153,19 +1208,19 @@ function openPopUp(dataType, element) {
content.addInteraction(input)
}
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Aktualisieren
+ // Update
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 1)')
content.addInteraction(input)
}
- // Speichern
+ // Save
var input = content.createInput("button", "save", "{{.button.save}}")
input.setAttribute('onclick', 'javascript: savePopupData("m3u", "' + id + '", false, 0)')
content.addInteraction(input)
@@ -1179,7 +1234,7 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.playlist.name.placeholder}}")
content.appendRow("{{.playlist.name.title}}", input)
- // Beschreibung
+ // Description
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.playlist.description.placeholder}}")
@@ -1193,8 +1248,8 @@ function openPopUp(dataType, element) {
// Tuner
if (SERVER["settings"]["buffer"] != "-") {
- var text:string[] = new Array()
- var values:string[] = new Array()
+ var text:string[] = []
+ var values:string[] = []
for (var i = 1; i <= 100; i++) {
text.push(i.toString())
@@ -1218,9 +1273,9 @@ function openPopUp(dataType, element) {
content.description("{{.playlist.tuner.description}}")
- // Interaktion
+ // Interaction
content.createInteraction()
- // Löschen
+ // Delete
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", true, 0)')
@@ -1232,19 +1287,19 @@ function openPopUp(dataType, element) {
content.addInteraction(input)
}
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Aktualisieren
+ // Update
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 1)')
content.addInteraction(input)
}
- // Speichern
+ // Save
var input = content.createInput("button", "save", "{{.button.save}}")
input.setAttribute('onclick', 'javascript: savePopupData("hdhr", "' + id + '", false, 0)')
content.addInteraction(input)
@@ -1262,14 +1317,14 @@ function openPopUp(dataType, element) {
select.setAttribute("onchange", 'javascript: changeButtonAction(this, "next", "onclick");') // changeButtonAction
content.appendRow("{{.filter.type.title}}", select)
- // Interaktion
+ // Interaction
content.createInteraction()
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Weiter
+ // Next
var input = content.createInput("button", "next", "{{.button.next}}")
input.setAttribute("onclick", 'javascript: openPopUp("group-title")')
input.setAttribute("id", 'next')
@@ -1281,11 +1336,11 @@ function openPopUp(dataType, element) {
switch (dataType) {
case "custom-filter":
- content.createHeadline("{{.filter.custom}}")
+ content.createHeadline("{{.filter.custom}}" + " Filter")
break;
case "group-title":
- content.createHeadline("{{.filter.group}}")
+ content.createHeadline("{{.filter.group}}" + " Filter")
break;
}
@@ -1295,13 +1350,13 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.filter.name.placeholder}}")
content.appendRow("{{.filter.name.title}}", input)
- // Beschreibung
+ // Description
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.description.placeholder}}")
content.appendRow("{{.filter.description.title}}", input)
- // Typ
+ // Type
var dbKey:string = "type"
var input = content.createInput("hidden", dbKey, data[dbKey])
content.appendRow("", input)
@@ -1311,23 +1366,29 @@ function openPopUp(dataType, element) {
switch (filterType) {
case "custom-filter":
- // Groß- Kleinschreibung beachten
+ // Case sensitive
var dbKey:string = "caseSensitive"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.filter.caseSensitive.title}}", input)
- // Filterregel (Benutzerdefiniert)
+ // Filter Rule (Custom)
var dbKey:string = "filter"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.filter.filterRule.placeholder}}")
content.appendRow("{{.filter.filterRule.title}}", input)
+ // Starting Channel Number Mapping
+ var dbKey:string = "startingChannel"
+ var input = content.createInput("text", dbKey, data[dbKey])
+ input.setAttribute("placeholder", "{{.filter.startingChannel.placeholder}}")
+ content.appendRow("{{.filter.startingChannel.title}}", input)
+
break;
case "group-title":
//alert(dbKey + " " + filterType)
- // Filter basierend auf den Gruppen in der M3U
+ // Filter based on the groups in the M3U
var dbKey:string = "filter"
var groupsM3U = getLocalData("m3uGroups", "")
var text:string[] = groupsM3U["text"]
@@ -1338,7 +1399,7 @@ function openPopUp(dataType, element) {
content.appendRow("{{.filter.filterGroup.title}}", select)
content.description("{{.filter.filterGroup.description}}")
- // Groß- Kleinschreibung beachten
+ // Case sensetive
var dbKey:string = "caseSensitive"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
@@ -1357,28 +1418,40 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.filter.exclude.placeholder}}")
content.appendRow("{{.filter.exclude.title}}", input)
content.description("{{.filter.exclude.description}}")
-
- break
+
+ // Preserve M3U Playlist Channel Mapping
+ var dbKey:string = "preserveMapping"
+ var input = content.createCheckbox(dbKey)
+ input.checked = data[dbKey]
+ content.appendRow("{{.filter.preserveMapping.title}}", input)
+
+ // Starting Channel Number Mapping
+ var dbKey:string = "startingChannel"
+ var input = content.createInput("text", dbKey, data[dbKey])
+ input.setAttribute("placeholder", "{{.filter.startingChannel.placeholder}}")
+ content.appendRow("{{.filter.startingChannel.title}}", input)
+
+ break;
default:
break;
}
- // Interaktion
+ // Interaction
content.createInteraction()
- // Löschen
+ // Delete
var input = content.createInput("button", "delete", "{{.button.delete}}")
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", true, 0)')
input.className = "delete"
content.addInteraction(input)
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Speichern
+ // Save
var input = content.createInput("button", "save", "{{.button.save}}")
input.setAttribute('onclick', 'javascript: savePopupData("filter", "' + id + '", false, 0)')
content.addInteraction(input)
@@ -1393,7 +1466,7 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.xmltv.name.placeholder}}")
content.appendRow("{{.xmltv.name.title}}", input)
- // Beschreibung
+ // Description
var dbKey:string = "description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.xmltv.description.placeholder}}")
@@ -1405,9 +1478,9 @@ function openPopUp(dataType, element) {
input.setAttribute("placeholder", "{{.xmltv.fileXMLTV.placeholder}}")
content.appendRow("{{.xmltv.fileXMLTV.title}}", input)
- // Interaktion
+ // Interaction
content.createInteraction()
- // Löschen
+ // Delete
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", true, 0)')
@@ -1415,19 +1488,19 @@ function openPopUp(dataType, element) {
content.addInteraction(input)
}
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Aktualisieren
+ // Update
if (data["id.provider"]!= "-") {
var input = content.createInput("button", "update", "{{.button.update}}")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 1)')
content.addInteraction(input)
}
- // Speichern
+ // Save
var input = content.createInput("button", "save", "{{.button.save}}")
input.setAttribute('onclick', 'javascript: savePopupData("xmltv", "' + id + '", false, 0)')
content.addInteraction(input)
@@ -1435,25 +1508,25 @@ function openPopUp(dataType, element) {
case "users":
content.createHeadline("{{.mainMenu.item.users}}")
- // Benutzername
+ // User name
var dbKey:string = "username"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.users.username.placeholder}}")
content.appendRow("{{.users.username.title}}", input)
- // Neues Passwort
+ // New Parssword
var dbKey:string = "password"
var input = content.createInput("password", dbKey, "")
input.setAttribute("placeholder", "{{.users.password.placeholder}}")
content.appendRow("{{.users.password.title}}", input)
- // Bestätigung
+ // Confirmation
var dbKey:string = "confirm"
var input = content.createInput("password", dbKey, "")
input.setAttribute("placeholder", "{{.users.confirm.placeholder}}")
content.appendRow("{{.users.confirm.title}}", input)
- // Berechtigung WEB
+ // Authentication WEB
var dbKey:string = "authentication.web"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
@@ -1462,34 +1535,34 @@ function openPopUp(dataType, element) {
}
content.appendRow("{{.users.web.title}}", input)
- // Berechtigung PMS
+ // Authentication PMS
var dbKey:string = "authentication.pms"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.pms.title}}", input)
- // Berechtigung M3U
+ // Authentication M3U
var dbKey:string = "authentication.m3u"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.m3u.title}}", input)
- // Berechtigung XML
+ // Authentication XML
var dbKey:string = "authentication.xml"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.xml.title}}", input)
- // Berechtigung API
+ // Authentication API
var dbKey:string = "authentication.api"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
content.appendRow("{{.users.api.title}}", input)
- // Interaktion
+ // Interaction
content.createInteraction()
- // Löschen
+ // Delete
if (data["defaultUser"]!= true && id != "-") {
var input = content.createInput("button", "delete", "{{.button.delete}}")
input.className = "delete"
@@ -1497,12 +1570,12 @@ function openPopUp(dataType, element) {
content.addInteraction(input)
}
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Speichern
+ // Save
var input = content.createInput("button", "save", "{{.button.save}}")
input.setAttribute("onclick", 'javascript: savePopupData("' + dataType + '", "' + id + '", "false");')
content.addInteraction(input)
@@ -1511,7 +1584,7 @@ function openPopUp(dataType, element) {
case "mapping":
content.createHeadline("{{.mainMenu.item.mapping}}")
- // Aktiv
+ // Active
var dbKey:string = "x-active"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
@@ -1520,7 +1593,7 @@ function openPopUp(dataType, element) {
input.setAttribute("onchange", "javascript: toggleChannelStatus('" + id + "', this)")
content.appendRow("{{.mapping.active.title}}", input)
- // Kanalname
+ // Channel name
var dbKey:string = "x-name"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("onchange", "javascript: this.className = 'changed'")
@@ -1532,14 +1605,14 @@ function openPopUp(dataType, element) {
content.description(data["name"])
- // Beschreibung
+ // Description
var dbKey:string = "x-description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}")
input.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.description.title}}", input)
- // Aktualisierung des Kanalnamens
+ // Update the channel x-name
if (data.hasOwnProperty("_uuid.key")) {
if (data["_uuid.key"] != "") {
var dbKey:string = "x-update-channel-name"
@@ -1550,14 +1623,30 @@ function openPopUp(dataType, element) {
}
}
- // Logo URL (Kanal)
+ // Channel name regex for updating the channel name
+ var dbKey:string = "update-channel-name-regex"
+ var input = content.createInput("text", dbKey, data[dbKey])
+ input.setAttribute("placeholder", "{{.mapping.updateChannelNameRegex.placeholder}}")
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ content.appendRow("{{.mapping.updateChannelNameRegex.title}}", input)
+ content.description("{{.mapping.updateChannelNameRegex.description}}")
+
+ // Channel group regex for updating the channel name
+ var dbKey:string = "update-channel-name-by-group-regex"
+ var input = content.createInput("text", dbKey, data[dbKey])
+ input.setAttribute("placeholder", "{{.mapping.updateChannelNameByGroupRegex.placeholder}}")
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ content.appendRow("{{.mapping.updateChannelNameByGroupRegex.title}}", input)
+ content.description("{{.mapping.updateChannelNameByGroupRegex.description}}")
+
+ // Logo URL (Channel)
var dbKey:string = "tvg-logo"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("onchange", "javascript: this.className = 'changed'")
input.setAttribute("id", "channel-icon")
content.appendRow("{{.mapping.channelLogo.title}}", input)
- // Aktualisierung des Kanallogos
+ // Channel logo update
var dbKey:string = "x-update-channel-icon"
var input = content.createCheckbox(dbKey)
input.checked = data[dbKey]
@@ -1565,7 +1654,7 @@ function openPopUp(dataType, element) {
input.setAttribute("onchange", "javascript: this.className = 'changed'; changeChannelLogo('" + id + "');")
content.appendRow("{{.mapping.updateChannelLogo.title}}", input)
- // Erweitern der EPG Kategorie
+ // Expand EPG category
var dbKey:string = "x-category"
var text:string[] = ["-", "Kids (Emby only)", "News", "Movie", "Series", "Sports"]
var values:string[] = ["", "Kids", "News", "Movie", "Series", "Sports"]
@@ -1573,53 +1662,73 @@ function openPopUp(dataType, element) {
select.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.epgCategory.title}}", select)
- // M3U Gruppentitel
+ // M3U group title
var dbKey:string = "x-group-title"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ input.dataset.oldValue = data[dbKey]
content.appendRow("{{.mapping.m3uGroupTitle.title}}", input)
-
if (data["group-title"] != undefined) {
content.description(data["group-title"])
}
+ if (data["x-update-channel-group"] == true) {
+ input.disabled = true;
+ }
- // XMLTV Datei
- var dbKey:string = "x-xmltv-file"
- var xmlFile = data[dbKey]
- var xmltv:XMLTVFile = new XMLTVFile()
- var select = xmltv.getFiles(data[dbKey])
- select.setAttribute("name", dbKey)
- select.setAttribute("id", "popup-xmltv")
- select.setAttribute("onchange", "javascript: this.className = 'changed'; setXmltvChannel('" + id + "',this);")
- content.appendRow("{{.mapping.xmltvFile.title}}", select)
- var file = data[dbKey]
+ // Update channel group checkbox
+ var dbKey:string = "x-update-channel-group"
+ var input = content.createCheckbox(dbKey)
+ input.setAttribute("onchange", "javascript: toggleGroupUpdateCb('" + id + "', this);")
+ input.checked = data[dbKey]
+ content.appendRow("{{.mapping.updateChannelGroup.title}}", input)
+ content.description("{{.mapping.updateChannelGroup.description}}")
+
+ // XMLTV file
+ var dbKey = 'x-xmltv-file';
+ const xmlTvFile: string = data[dbKey];
+ var xmlTv = new XMLTVFile();
+ const xmlTvFileSelect = xmlTv.getFiles(data[dbKey]);
+ xmlTvFileSelect.setAttribute('name', dbKey);
+ xmlTvFileSelect.setAttribute('id', 'popup-xmltv');
+ xmlTvFileSelect.setAttribute('onchange', `javascript: this.className = 'changed'; setXmltvChannel('${id}', this);`);
+ content.appendRow('{{.mapping.xmltvFile.title}}', xmlTvFileSelect);
// XMLTV Mapping
- var dbKey:string = "x-mapping"
- var xmltv:XMLTVFile = new XMLTVFile()
- var select = xmltv.getPrograms(file, data[dbKey])
- select.setAttribute("name", dbKey)
- select.setAttribute("id", "popup-mapping")
- select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');")
-
- sortSelect(select)
- content.appendRow("{{.mapping.xmltvChannel.title}}", select)
-
- // Interaktion
+ var dbKey: string = 'x-mapping';
+ var xmlTv = new XMLTVFile();
+ const currentXmlTvId: string = data[dbKey];
+ const [xmlTvIdContainer, xmlTvIdInput, xmlTvIdDatalist] = xmlTv.newXmlTvIdPicker(xmlTvFile, currentXmlTvId);
+ xmlTvIdContainer.setAttribute('id', 'xmltv-id-picker-container');
+ xmlTvIdInput.setAttribute('list', 'xmltv-id-picker-datalist');
+ xmlTvIdInput.setAttribute('name', 'x-mapping'); // Should stay x-mapping as it will be used in donePopupData to make a server request
+ xmlTvIdInput.setAttribute('id', 'xmltv-id-picker-input');
+ xmlTvIdInput.setAttribute('onchange', `javascript: this.className = 'changed'; checkXmltvChannel('${id}', this.value, '${xmlTvFile}');`);
+ xmlTvIdDatalist.setAttribute('id', 'xmltv-id-picker-datalist');
+ content.appendRow('{{.mapping.xmltvChannel.title}}', xmlTvIdContainer);
+
+ // Timeshift
+ var dbKey:string = "x-timeshift"
+ var input = content.createInput("text", dbKey, data[dbKey])
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ input.setAttribute("placeholder", "{{.mapping.timeshift.placeholder}}")
+ input.setAttribute("id", "timeshift")
+ content.appendRow("{{.mapping.timeshift.title}}", input)
+
+ // Interaction
content.createInteraction()
- // Logo hochladen
+ // Upload logo
var input = content.createInput("button", "cancel", "{{.button.uploadLogo}}")
input.setAttribute("onclick", 'javascript: uploadLogo();')
content.addInteraction(input)
- // Abbrechen
+ // Abort
var input = content.createInput("button", "cancel", "{{.button.cancel}}")
input.setAttribute("onclick", 'javascript: showElement("popup", false);')
content.addInteraction(input)
- // Fertig
- var ids:string[] = new Array()
+ // Finished
+ var ids:string[] = []
ids = getAllSelectedChannels()
if (ids.length == 0) {
ids.push(id)
@@ -1641,9 +1750,9 @@ class XMLTVFile {
File:string
getFiles(set:string):any {
- var fileIDs:string[] = getObjKeys(SERVER["xepg"]["xmltvMap"])
- var values = new Array("-");
- var text = new Array("-");
+ let fileIDs:string[] = getOwnObjProps(SERVER["xepg"]["xmltvMap"])
+ let values = new Array("-");
+ let text = new Array("-");
for (let i = 0; i < fileIDs.length; i++) {
if (fileIDs[i] != "xTeVe Dummy") {
@@ -1656,7 +1765,7 @@ class XMLTVFile {
}
- var select = document.createElement("SELECT")
+ let select = document.createElement("SELECT")
for (let i = 0; i < text.length; i++) {
var option = document.createElement("OPTION")
option.setAttribute("value", values[i])
@@ -1671,42 +1780,72 @@ class XMLTVFile {
return select
}
- getPrograms(file:string, set:string):any {
- //var fileIDs:string[] = getObjKeys(SERVER["xepg"]["xmltvMap"])
- var values = getObjKeys(SERVER["xepg"]["xmltvMap"][file]);
- var text = new Array()
- var displayName:string
+ /**
+ * @param xmlTvFile XML file path to get EPG from.
+ * @param currentXmlTvId Current XMLTV ID to set initial input value to.
+ * @returns Array of, sequentially:
+ * 1) Container of the picker.
+ * 2) Input field to type at and get choice from.
+ * 3) Datalist containing every option.
+ */
+ newXmlTvIdPicker(xmlTvFile: string, currentXmlTvId: string): [HTMLDivElement, HTMLInputElement, HTMLDataListElement] {
+ const container = document.createElement('div');
+ const input = document.createElement('input');
+ input.setAttribute('type', 'text');
+
+ // Initially, set value to '-' if input is empty
+ input.value = (currentXmlTvId) ? currentXmlTvId : '-';
+
+ // When input is focused, remove '-' from it
+ input.addEventListener('focus', (evt) => {
+ const target = evt.target as HTMLInputElement;
+ target.value = (target.value === '-') ? '' : target.value;
+ });
- for (let i = 0; i < values.length; i++) {
- if (SERVER["xepg"]["xmltvMap"][file][values[i]].hasOwnProperty('display-name') == true) {
- displayName = SERVER["xepg"]["xmltvMap"][file][values[i]]["display-name"];
- } else {
- displayName = "-"
- }
-
- text[i] = displayName + " (" + values[i] + ")";
+ // When input lose focus or take a value, if it's empty, set value to '-'
+ input.addEventListener('blur', setFallbackValue);
+ input.addEventListener('change', setFallbackValue);
+ function setFallbackValue(evt: Event) {
+ const target = evt.target as HTMLInputElement;
+ target.value = (target.value) ? target.value : '-';
}
- text.unshift("-");
- values.unshift("-");
+ container.appendChild(input);
- var select = document.createElement("SELECT")
- for (let i = 0; i < text.length; i++) {
- var option = document.createElement("OPTION")
- option.setAttribute("value", values[i])
- option.innerText = text[i]
- select.appendChild(option)
- }
+ const datalist = document.createElement('datalist');
- if(set != "") {
- (select as HTMLSelectElement).value = set
+ const option = document.createElement('option');
+ option.setAttribute('value', '-');
+ option.innerText = '-';
+ datalist.appendChild(option);
+
+ const epg: Object = SERVER['xepg']['xmltvMap'][xmlTvFile];
+
+ if (epg) {
+ const programIds = getOwnObjProps(epg);
+
+ programIds.forEach((programId) => {
+ const program: Object = epg[programId];
+
+ if (program.hasOwnProperty('display-names')) {
+ program['display-names'].forEach((displayName: Object) => {
+ const option = document.createElement('option');
+ option.setAttribute('value', programId);
+ option.innerText = displayName['Value'];
+ datalist.appendChild(option);
+ });
+ } else {
+ const option = document.createElement('option');
+ option.setAttribute('value', programId);
+ option.innerText = '-';
+ datalist.appendChild(option);
+ }
+ });
}
- if ((select as HTMLSelectElement).value != set) {
- (select as HTMLSelectElement).value = "-"
- }
+ container.appendChild(datalist);
- return select
+ return [container, input, datalist];
}
return
@@ -1718,8 +1857,8 @@ function getValueFromProviderFile(file:string, fileType, key) {
return file
}
- var fileID:string
- var indicator = file.charAt(0)
+ let fileID:string
+ let indicator = file.charAt(0)
switch (indicator) {
case "M":
@@ -1748,115 +1887,97 @@ function getValueFromProviderFile(file:string, fileType, key) {
}
-function setXmltvChannel(id, element) {
+function setXmltvChannel(epgMapId: string, xmlTvFileSelect: HTMLSelectElement) {
- var xmltv:XMLTVFile = new XMLTVFile()
- var xmlFile = element.value
+ const xmlTv = new XMLTVFile();
+ const newXmlTvFile = xmlTvFileSelect.value;
- var tvgId:string = SERVER["xepg"]["epgMapping"][id]["tvg-id"]
- var td = document.getElementById("popup-mapping").parentElement
- td.innerHTML = ""
+ // Remove old XMLTV ID selection box
+ const xmlTvIdPickerParent = document.getElementById('xmltv-id-picker-container').parentElement as HTMLTableCellElement;
+ xmlTvIdPickerParent.innerHTML = '';
+
+ // Create new XMLTV ID selection box
+ const tvgId: string = SERVER['xepg']['epgMapping'][epgMapId]['tvg-id'];
+
+ const [xmlTvIdContainer, xmlTvIdInput, xmlTvIdDatalist] = xmlTv.newXmlTvIdPicker(newXmlTvFile, tvgId);
+ xmlTvIdContainer.setAttribute('id', 'xmltv-id-picker-container');
+ xmlTvIdInput.setAttribute('list', 'xmltv-id-picker-datalist');
+ xmlTvIdInput.setAttribute('name', 'x-mapping'); // Should stay x-mapping as it will be used in donePopupData to make a server request
+ xmlTvIdInput.setAttribute('id', 'xmltv-id-picker-input');
+ xmlTvIdInput.setAttribute('onchange', `javascript: this.className = 'changed'; checkXmltvChannel('${epgMapId}', this.value, '${newXmlTvFile}');`);
+ xmlTvIdInput.classList.add('changed');
+ xmlTvIdDatalist.setAttribute('id', 'xmltv-id-picker-datalist');
+
+ // Add new XMLTV ID selection box to it's parent
+ xmlTvIdPickerParent.appendChild(xmlTvIdContainer);
+
+ checkXmltvChannel(epgMapId, xmlTvIdInput.value, newXmlTvFile);
- var select = xmltv.getPrograms(element.value, tvgId)
- select.setAttribute("name", "x-mapping")
- select.setAttribute("id", "popup-mapping")
- select.setAttribute("onchange", "javascript: this.className = 'changed'; checkXmltvChannel('" + id + "',this,'" + xmlFile + "');")
- select.className = "changed"
- sortSelect(select)
- td.appendChild(select);
-
- checkXmltvChannel(id, select, xmlFile)
}
-function checkXmltvChannel(id:string, element:any, xmlFile) {
-
- var value = (element as HTMLSelectElement).value
- var bool:boolean
- var checkbox = document.getElementById('active')
- var channel:any = SERVER["xepg"]["epgMapping"][id]
- var updateLogo:boolean
-
+function checkXmltvChannel(epgMapId: string, newXmlTvId: string, xmlTvFile: string) {
- if (value == "-") {
- bool = false
- } else {
- bool = true
- }
+ const channelActiveCb = document.getElementById('active') as HTMLInputElement;
- (checkbox as HTMLInputElement).checked = bool
- checkbox.className = "changed"
- console.log(xmlFile);
-
- // Kanallogo aktualisieren
- /*
- updateLogo = (document.getElementById("update-icon") as HTMLInputElement).checked
- console.log(updateLogo);
- */
-
- if(xmlFile != "xTeVe Dummy" && bool == true) {
-
- //(document.getElementById("update-icon") as HTMLInputElement).checked = true;
- //(document.getElementById("update-icon") as HTMLInputElement).className = "changed";
+ const channelActive = newXmlTvId != '-';
- console.log("ID", id)
- changeChannelLogo(id)
+ channelActiveCb.checked = channelActive;
+ channelActiveCb.className = 'changed';
- return
+ if(xmlTvFile != 'xTeVe Dummy' && channelActive == true) {
+ changeChannelLogo(epgMapId);
+ return;
}
- if (xmlFile == "xTeVe Dummy") {
- (document.getElementById("update-icon") as HTMLInputElement).checked = false;
- (document.getElementById("update-icon") as HTMLInputElement).className = "changed";
+ if (xmlTvFile == 'xTeVe Dummy') {
+ (document.getElementById('update-icon') as HTMLInputElement).checked = false;
+ (document.getElementById('update-icon') as HTMLInputElement).className = 'changed';
}
- return
}
-function changeChannelLogo(id:string) {
+function changeChannelLogo(epgMapId: string) {
+
+ const channel: Object = SERVER['xepg']['epgMapping'][epgMapId];
- var updateLogo:boolean
- var channel:any = SERVER["xepg"]["epgMapping"][id]
+ const xmlTvFileSelect = document.getElementById('popup-xmltv') as HTMLSelectElement;
+ const xmlTvFile = xmlTvFileSelect.options[xmlTvFileSelect.selectedIndex].value;
- var f = (document.getElementById("popup-xmltv") as HTMLSelectElement);
- var xmltvFile = f.options[f.selectedIndex].value;
+ const xmlTvIdInput = document.getElementById('xmltv-id-picker-input') as HTMLInputElement;
+ const newXmlTvId = xmlTvIdInput.value;
- var m = (document.getElementById("popup-mapping") as HTMLSelectElement);
- var xMapping = m.options[m.selectedIndex].value;
+ const updateLogo = (document.getElementById('update-icon') as HTMLInputElement).checked;
- var xmltvLogo = SERVER["xepg"]["xmltvMap"][xmltvFile][xMapping]["icon"]
- updateLogo = (document.getElementById("update-icon") as HTMLInputElement).checked
+ let logo: string;
- if (updateLogo == true && xmltvFile != "xTeVe Dummy") {
+ if (updateLogo == true && xmlTvFile != 'xTeVe Dummy') {
- if (SERVER["xepg"]["xmltvMap"][xmltvFile].hasOwnProperty(xMapping)) {
- var logo = xmltvLogo
+ if (SERVER['xepg']['xmltvMap'][xmlTvFile].hasOwnProperty(newXmlTvId)) {
+ logo = SERVER['xepg']['xmltvMap'][xmlTvFile][newXmlTvId]['icon'];
} else {
- logo = channel["tvg-logo"]
+ logo = channel['tvg-logo'];
}
- var logoInput = (document.getElementById("channel-icon") as HTMLInputElement);
- logoInput.value = logo
+ var logoInput = (document.getElementById('channel-icon') as HTMLInputElement);
+ logoInput.value = logo;
+
if (BULK_EDIT == false) {
- logoInput.className = "changed"
+ logoInput.className = 'changed';
}
}
}
-function savePopupData(dataType:string, id:string, remove:Boolean, option:number) {
+function savePopupData(dataType: string, id: string, remove: Boolean, option: number) {
if (dataType == "mapping") {
- var data = new Object()
- console.log("Save mapping data")
-
- cmd = "saveEpgMapping"
+ let data = {}
+ let cmd = "saveEpgMapping"
data["epgMapping"] = SERVER["xepg"]["epgMapping"]
-
- console.log("SEND TO SERVER");
- var server:Server = new Server(cmd)
+ let server:Server = new Server(cmd)
server.request(data)
delete UNDO["epgMapping"]
@@ -1864,14 +1985,13 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
return
}
- console.log("Save popup data")
- var div = document.getElementById("popup-custom")
+ let div = document.getElementById("popup-custom")
- var inputs = div.getElementsByTagName("TABLE")[0].getElementsByTagName("INPUT");
- var selects = div.getElementsByTagName("TABLE")[0].getElementsByTagName("SELECT");
+ let inputs = div.getElementsByTagName("TABLE")[0].getElementsByTagName("INPUT");
+ let selects = div.getElementsByTagName("TABLE")[0].getElementsByTagName("SELECT");
- var input = new Object();
- var confirmMsg: string
+ let input = {};
+ let confirmMsg: string
for (let i = 0; i < selects.length; i++) {
@@ -1922,9 +2042,9 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
}
- var data = new Object()
+ let data = {}
- var cmd:string
+ let cmd:string
if (remove == true) {
input["delete"] = true
@@ -1939,7 +2059,7 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
data["userData"] = input
} else {
cmd = "saveUserData"
- var d = new Object()
+ let d = {}
d[id] = input
data["userData"] = d
}
@@ -1962,8 +2082,8 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
}
- data["files"] = new Object
- data["files"][dataType] = new Object
+ data["files"] = {}
+ data["files"][dataType] = {}
data["files"][dataType][id] = input
break
@@ -1984,8 +2104,8 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
}
- data["files"] = new Object
- data["files"][dataType] = new Object
+ data["files"] = {}
+ data["files"][dataType] = {}
data["files"][dataType][id] = input
break
@@ -2006,8 +2126,8 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
}
- data["files"] = new Object
- data["files"][dataType] = new Object
+ data["files"] = {}
+ data["files"][dataType] = {}
data["files"][dataType][id] = input
break
@@ -2016,14 +2136,12 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
confirmMsg = "Delete this filter?"
cmd = "saveFilter"
- data["filter"] = new Object
+ data["filter"] = {}
data["filter"][id] = input
break
default:
- console.log(dataType, id);
return
- break;
}
@@ -2035,32 +2153,26 @@ function savePopupData(dataType:string, id:string, remove:Boolean, option:number
}
}
-
- console.log("SEND TO SERVER");
-
- console.log(data);
-
- var server:Server = new Server(cmd)
+
+ let server:Server = new Server(cmd)
server.request(data)
}
function donePopupData(dataType:string, idsStr:string) {
-
- var ids:string[] = idsStr.split(',');
- var div = document.getElementById("popup-custom")
- var inputs = div.getElementsByClassName("changed")
-
+
+ let ids:string[] = idsStr.split(',');
+ let div = document.getElementById("popup-custom")
+ let inputs = div.getElementsByClassName("changed")
+
ids.forEach(id => {
- var input = new Object();
+ let input: Object;
input = SERVER["xepg"]["epgMapping"][id]
- console.log(input);
-
for (let i = 0; i < inputs.length; i++) {
-
- var name:string
- var value:any
+
+ let name:string
+ let value:any
switch (inputs[i].tagName) {
@@ -2105,8 +2217,12 @@ function donePopupData(dataType:string, idsStr:string) {
(document.getElementById(id).childNodes[3].firstChild as HTMLElement).className = value
break
+ case "update-channel-name-regex":
+ (document.getElementById(id).childNodes[4].firstChild as HTMLElement).innerHTML = value
+ break
+
case "x-group-title":
- (document.getElementById(id).childNodes[5].firstChild as HTMLElement).innerHTML = value
+ (document.getElementById(id).childNodes[6].firstChild as HTMLElement).innerHTML = value
break
case "x-xmltv-file":
@@ -2118,7 +2234,7 @@ function donePopupData(dataType:string, idsStr:string) {
input["x-active"] = false
}
- (document.getElementById(id).childNodes[6].firstChild as HTMLElement).innerHTML = value
+ (document.getElementById(id).childNodes[7].firstChild as HTMLElement).innerHTML = value
break
case "x-mapping":
@@ -2126,10 +2242,14 @@ function donePopupData(dataType:string, idsStr:string) {
input["x-active"] = false
}
- (document.getElementById(id).childNodes[7].firstChild as HTMLElement).innerHTML = value
+ (document.getElementById(id).childNodes[8].firstChild as HTMLElement).innerHTML = value
break
+ case "x-timeshift":
+ (document.getElementById(id).childNodes[9].firstChild as HTMLElement).innerHTML = value
+ break
+
default:
}
@@ -2145,7 +2265,6 @@ function donePopupData(dataType:string, idsStr:string) {
document.getElementById(id).className = "activeEPG"
}
- console.log(input["tvg-logo"]);
(document.getElementById(id).childNodes[2].firstChild as HTMLElement).setAttribute("src", input["tvg-logo"])
@@ -2158,28 +2277,27 @@ function donePopupData(dataType:string, idsStr:string) {
function showPreview(element:boolean) {
- var div = document.getElementById("myStreamsBox")
+ let div = document.getElementById("myStreamsBox")
switch (element) {
case false:
div.className = "notVisible"
return
- break;
}
-
- var streams:string[] = ["activeStreams", "inactiveStreams"]
+
+ let streams:string[] = ["activeStreams", "inactiveStreams"]
streams.forEach(preview => {
-
- var table = document.getElementById(preview)
+
+ let table = document.getElementById(preview)
table.innerHTML = ""
- var obj:string[] = SERVER["data"]["StreamPreviewUI"][preview]
+ let obj:string[] = SERVER["data"]["StreamPreviewUI"][preview]
obj.forEach(channel => {
-
- var tr = document.createElement("TR")
- var tdKey = document.createElement("TD")
- var tdVal = document.createElement("TD")
+
+ let tr = document.createElement("TR")
+ let tdKey = document.createElement("TD")
+ let tdVal = document.createElement("TD")
tdKey.className = "tdKey"
tdVal.className = "tdVal"
diff --git a/ts/network_ts.ts b/ts/network_ts.ts
index 35b9318..491d1a4 100644
--- a/ts/network_ts.ts
+++ b/ts/network_ts.ts
@@ -13,8 +13,7 @@ class Server {
}
SERVER_CONNECTION = true
-
- console.log(data)
+
if (this.cmd != "updateLog") {
showElement("loading", true)
UNDO = new Object()
@@ -36,18 +35,11 @@ class Server {
ws.onopen = function() {
WS_AVAILABLE = true
-
- console.log("REQUEST (JS):");
- console.log(data)
-
- console.log("REQUEST: (JSON)");
- console.log(JSON.stringify(data))
-
this.send(JSON.stringify(data));
-
+
}
- ws.onerror = function(e) {
+ ws.onerror = function(wsErrEvt) {
console.log("No websocket connection to xTeVe could be established. Check your network configuration.")
SERVER_CONNECTION = false
@@ -59,31 +51,33 @@ class Server {
}
- ws.onmessage = function (e) {
+ ws.onmessage = function (wsMessageEvt) {
SERVER_CONNECTION = false
showElement("loading", false)
- console.log("RESPONSE:");
- var response = JSON.parse(e.data);
-
- console.log(response);
+ const response: Object = JSON.parse(wsMessageEvt.data);
if (response.hasOwnProperty("token")) {
- document.cookie = "Token=" + response["token"]
+ document.cookie = "Token=" + response["token"];
}
if (response["status"] == false) {
-
- alert(response["err"])
+ alert(response["err"]);
+ return;
+ }
- if (response.hasOwnProperty("reload")) {
- location.reload()
- }
+ if (response.hasOwnProperty('openLink')) {
+ window.location = response['openLink'];
+ }
- return
+ if (response.hasOwnProperty("reload")) {
+ window.location.reload();
}
+ if (response.hasOwnProperty("alert")) {
+ alert(response["alert"]);
+ }
if (response.hasOwnProperty("logoURL")) {
var div = (document.getElementById("channel-icon") as HTMLInputElement)
@@ -99,7 +93,6 @@ class Server {
showLogs(false)
}
return
- break;
default:
SERVER = new Object()
@@ -113,19 +106,10 @@ class Server {
showElement("popup", false)
}
- if (response.hasOwnProperty("openLink")) {
- window.location = response["openLink"]
- }
-
- if (response.hasOwnProperty("alert")) {
- alert(response["alert"])
- }
-
if (response.hasOwnProperty("reload")) {
location.reload()
}
-
if (response.hasOwnProperty("wizard")) {
createLayout()
configurationWizard[response["wizard"]].createWizard()
@@ -143,5 +127,7 @@ class Server {
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
- if (parts.length == 2) return parts.pop().split(";").shift();
-}
\ No newline at end of file
+ if (parts.length == 2) {
+ return parts.pop().split(";").shift();
+ }
+}
diff --git a/ts/settings_ts.ts b/ts/settings_ts.ts
index 432f91a..b9064c5 100644
--- a/ts/settings_ts.ts
+++ b/ts/settings_ts.ts
@@ -18,7 +18,7 @@ class SettingsCategory {
switch (settingsKey) {
- // Texteingaben
+ // Text inputs
case "update":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.update.title}}" + ":"
@@ -145,7 +145,35 @@ class SettingsCategory {
setting.appendChild(tdRight)
break
- // Checkboxen
+ // Checkboxes
+ case "tlsMode":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.tlsMode.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var input = content.createCheckbox(settingsKey)
+ input.checked = data
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(input)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
+ case "disallowURLDuplicates":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.disallowURLDuplicates.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var input = content.createCheckbox(settingsKey)
+ input.checked = data
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(input)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
case "authentication.web":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.authenticationWEB.title}}" + ":"
@@ -258,6 +286,20 @@ class SettingsCategory {
setting.appendChild(tdRight)
break
+ case "storeBufferInRAM":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.storeBufferInRAM.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var input = content.createCheckbox(settingsKey)
+ input.checked = data
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(input)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
case "xteveAutoUpdate":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.xteveAutoUpdate.title}}" + ":"
@@ -272,6 +314,20 @@ class SettingsCategory {
setting.appendChild(tdRight)
break
+ case "clearXMLTVCache":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.clearXMLTVCache.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var input = content.createCheckbox(settingsKey)
+ input.checked = data
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(input)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
case "api":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.api.title}}" + ":"
@@ -286,7 +342,48 @@ class SettingsCategory {
setting.appendChild(tdRight)
break
- // Select
+ case "enableMappedChannels":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.enableMappedChannels.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var input = content.createCheckbox(settingsKey)
+ input.checked = data
+ input.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(input)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
+ // Select
+ case "hostIP":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.hostIP.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var text: any[] = SERVER["ipAddressesV4Host"]
+ var values: any[] = SERVER["ipAddressesV4Host"]
+
+ var select = content.createSelect(text, values, data, settingsKey)
+ select.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(select)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break;
+
+ case "hostName":
+ var tdLeft = document.createElement("TD");
+ tdLeft.innerHTML = "{{.settings.hostName.title}}" + ":";
+ var tdRight = document.createElement("TD");
+ var input = content.createInput("text", "hostName", data);
+ input.setAttribute("placeholder", "{{.settings.hostName.placeholder}}");
+ input.setAttribute("onchange", "javascript: this.className = 'changed'");
+ tdRight.appendChild(input);
+ setting.appendChild(tdLeft);
+ setting.appendChild(tdRight);
+ break;
case "tuner":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.tuner.title}}" + ":"
@@ -324,6 +421,27 @@ class SettingsCategory {
setting.appendChild(tdRight)
break
+ case "defaultMissingEPG":
+ var tdLeft = document.createElement("TD")
+ tdLeft.innerHTML = "{{.settings.defaultMissingEPG.title}}" + ":"
+
+ var tdRight = document.createElement("TD")
+ var text:any[] = [
+ "-", "30 Minutes (30_Minutes)", "60 Minutes (60_Minutes)", "90 Minutes (90_Minutes)",
+ "120 Minutes (120_Minutes)", "180 Minutes (180_Minutes)", "240 Minutes (240_Minutes)", "360 Minutes (360_Minutes)"
+ ]
+ var values:any[] = [
+ "-", "30_Minutes", "60_Minutes", "90_Minutes", "120_Minutes", "180_Minutes", "240_Minutes", "360_Minutes"
+ ]
+
+ var select = content.createSelect(text, values, data, settingsKey)
+ select.setAttribute("onchange", "javascript: this.className = 'changed'")
+ tdRight.appendChild(select)
+
+ setting.appendChild(tdLeft)
+ setting.appendChild(tdRight)
+ break
+
case "backup.keep":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.backupKeep.title}}" + ":"
@@ -400,6 +518,14 @@ class SettingsCategory {
var text:string
switch (settingsKey) {
+ case "tlsMode":
+ text = "{{.settings.tlsMode.description}}"
+ break
+
+ case "disallowURLDuplicates":
+ text = "{{.settings.disallowURLDuplicates.description}}"
+ break
+
case "authentication.web":
text = "{{.settings.authenticationWEB.description}}"
break
@@ -446,6 +572,10 @@ class SettingsCategory {
text = "{{.settings.bufferSize.description}}"
break
+ case "storeBufferInRAM":
+ text = "{{.settings.storeBufferInRAM.description}}"
+ break
+
case "buffer.timeout":
text = "{{.settings.bufferTimeout.description}}"
break
@@ -474,6 +604,14 @@ class SettingsCategory {
text = "{{.settings.epgSource.description}}"
break
+ case "hostIP":
+ text = "{{.settings.hostIP.description}}"
+ break;
+
+ case "hostName":
+ text = "{{.settings.hostName.description}}"
+ break;
+
case "tuner":
text = "{{.settings.tuner.description}}"
break
@@ -482,10 +620,22 @@ class SettingsCategory {
text = "{{.settings.update.description}}"
break
+ case "clearXMLTVCache":
+ text = "{{.settings.clearXMLTVCache.description}}"
+ break
+
case "api":
text = "{{.settings.api.description}}"
break
+ case "defaultMissingEPG":
+ text = "{{.settings.defaultMissingEPG.description}}"
+ break
+
+ case "enableMappedChannels":
+ text = "{{.settings.enableMappedChannels.description}}"
+ break
+
case "files.update":
text = "{{.settings.filesUpdate.description}}"
break
@@ -542,7 +692,7 @@ class SettingsCategoryItem extends SettingsCategory {
var doc = document.getElementById(this.DocumentID)
doc.appendChild(headline)
- // Tabelle für die Kategorie erstellen
+ // Create a table for the category
var table = document.createElement("TABLE")
@@ -579,7 +729,6 @@ class SettingsCategoryItem extends SettingsCategory {
}
function showSettings() {
- console.log("SETTINGS");
for (let i = 0; i < settingsCategory.length; i++) {
settingsCategory[i].createCategory()
@@ -588,7 +737,6 @@ function showSettings() {
}
function saveSettings() {
- console.log("Save Settings");
var cmd = "saveSettings"
var div = document.getElementById("content_settings")
@@ -636,7 +784,7 @@ function saveSettings() {
name = (settings[i] as HTMLSelectElement).name
value = (settings[i] as HTMLSelectElement).value
- // Wenn der Wert eine Zahl ist, wird dieser als Zahl gespeichert
+ // If the value is a number, store it as a number
if(isNaN(value)){
newSettings[name] = value
} else {
@@ -654,4 +802,5 @@ function saveSettings() {
var server:Server = new Server(cmd)
server.request(data)
+
}
diff --git a/ts/tsconfig.json b/ts/tsconfig.json
new file mode 100644
index 0000000..ba9756d
--- /dev/null
+++ b/ts/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es6",
+ "sourceMap": false,
+ "outDir": "../html/js"
+ },
+ "include": [
+ "*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/update_version.sh b/update_version.sh
new file mode 100755
index 0000000..d215ce0
--- /dev/null
+++ b/update_version.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+VERSION=`cat VERSION`
+cat << EOF > release.json
+{
+ "version": "$VERSION",
+ "go_version": "1.19.0"
+}
+EOF
+
+cat << EOF > src/version.go
+package src
+
+// Version : Version, the Build Number is parsed in the main func
+const Version = "$VERSION"
+EOF
+
+sed -Ei "s/ARG XTEVE_VERSION.*/ARG XTEVE_VERSION=$VERSION/" Dockerfile
diff --git a/xteve.go b/xteve.go
index 36a9546..d1271ef 100644
--- a/xteve.go
+++ b/xteve.go
@@ -1,7 +1,8 @@
// Copyright 2019 marmei. All rights reserved.
+// Copyright 2022 senexcrenshaw. All rights reserved.
// Use of this source code is governed by a MIT license that can be found in the
// LICENSE file.
-// GitHub: https://github.com/xteve-project/xTeVe
+// GitHub: https://github.com/SenexCrenshaw/xTeVe
package main
@@ -16,7 +17,7 @@ import (
"xteve/src"
)
-// GitHubStruct : GitHub Account. Über diesen Account werden die Updates veröffentlicht
+// GitHubStruct : GitHub Account. The Updates are published via this Account
type GitHubStruct struct {
Branch string
Repo string
@@ -26,23 +27,18 @@ type GitHubStruct struct {
// GitHub : GitHub Account
// If you want to fork this project, enter your Github account here. This prevents a newer version of xTeVe from updating your version.
-var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-Downloads", Update: true}
+var GitHub = GitHubStruct{Branch: "main", User: "SenexCrenshaw", Repo: "xTeVe", Update: false}
-/*
- Branch: GitHub Branch
- User: GitHub Username
- Repo: GitHub Repository
- Update: Automatic updates from the GitHub repository [true|false]
-*/
+// Branch: GitHub Branch
+// User: GitHub Username
+// Repo: GitHub Repository
+// Update: Automatic updates from the GitHub repository [true|false]
-// Name : Programmname
+// Name : Program Name
const Name = "xTeVe"
-// Version : Version, die Build Nummer wird in der main func geparst.
-const Version = "2.2.0.0200"
-
-// DBVersion : Datanbank Version
-const DBVersion = "2.1.0"
+// DBVersion : Database Version
+const DBVersion = "2.3.0"
// APIVersion : API Version
const APIVersion = "1.1.0"
@@ -56,17 +52,20 @@ var port = flag.String("port", "", ": Server port [34400] (default: 344
var restore = flag.String("restore", "", ": Restore from backup ["+sampleRestore+"xteve_backup.zip]")
var gitBranch = flag.String("branch", "", ": Git Branch [master|beta] (default: master)")
+var noUpdates = flag.Bool("no-updates", false, ": Disable updates")
var debug = flag.Int("debug", 0, ": Debug level [0 - 3] (default: 0)")
var info = flag.Bool("info", false, ": Show system info")
+var version = flag.Bool("version", false, ": Show system version")
var h = flag.Bool("h", false, ": Show help")
-// Aktiviert den Entwicklungsmodus. Für den Webserver werden dann die lokalen Dateien verwendet.
+// Activates Development Mode. The local Files are then used for the Webserver.
var dev = flag.Bool("dev", false, ": Activates the developer mode, the source code must be available. The local files for the web interface are used.")
+var buildwebui = flag.Bool("buildwebui", false, ": Builds webUI.go and exits.")
func main() {
- // Build-Nummer von der Versionsnummer trennen
- var build = strings.Split(Version, ".")
+ // Separate Build Number from Version Number
+ var build = strings.Split(src.Version, ".")
var system = &src.System
system.APIVersion = APIVersion
@@ -77,7 +76,7 @@ func main() {
system.Name = Name
system.Version = strings.Join(build[0:len(build)-1], ".")
- // Panic !!!
+ // Panic
defer func() {
if r := recover(); r != nil {
@@ -121,11 +120,26 @@ func main() {
return
}
+ if *buildwebui {
+ src.HTMLInit("webUI", "src", "html"+string(os.PathSeparator), "src"+string(os.PathSeparator)+"webUI.go")
+ err := src.BuildGoFile()
+ if err != nil {
+ src.ShowError(err, 0)
+ } else {
+ fmt.Println("webUI.go built successfully")
+ }
+ os.Exit(0)
+ }
+
system.Dev = *dev
- // Systeminformationen anzeigen
- if *info {
+ if *version {
+ src.ShowSystemVersion()
+ return
+ }
+ // Display System Information
+ if *info {
system.Flag.Info = true
err := src.Init()
@@ -150,6 +164,11 @@ func main() {
fmt.Println("Git Branch is now:", system.Flag.Branch)
}
+ // Updates
+ if noUpdates != nil {
+ system.GitHub.Update = false
+ }
+
// Debug Level
system.Flag.Debug = *debug
if system.Flag.Debug > 3 {
@@ -157,12 +176,12 @@ func main() {
return
}
- // Speicherort für die Konfigurationsdateien
+ // Storage location for the Configuration Files
if len(*configFolder) > 0 {
system.Folder.Config = *configFolder
}
- // Backup wiederherstellen
+ // Restore Backup
if len(*restore) > 0 {
system.Flag.Restore = *restore
diff --git a/xteve_test.go b/xteve_test.go
new file mode 100644
index 0000000..ef64976
--- /dev/null
+++ b/xteve_test.go
@@ -0,0 +1,7 @@
+package main
+
+import "testing"
+
+func TestMain(t *testing.T) {
+ main()
+}