var dtLang = {
    "sProcessing": "处理中...",
    "lengthMenu": '显示 <select>' + '<option value="5">5</option>'
        + '<option value="20">20</option>'
        + '<option value="100">100</option>'
        + '<option value="-1">全部</option>' + '</select> 项结果',
    "sZeroRecords": "没有匹配结果",
    "sInfo": "显示第 _START_ 至 _END_ 项结果，共 _TOTAL_ 项",
    "sInfoEmpty": "显示第 0 至 0 项结果，共 0 项",
    "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
    "sInfoPostFix": "",
    "sSearch": "搜索:",
    "sUrl": "",
    "sEmptyTable": "表中数据为空",
    "sLoadingRecords": "载入中...",
    "sInfoThousands": ",",
    "oPaginate": {
        "sFirst": "首页",
        "sPrevious": "上页",
        "sNext": "下页",
        "sLast": "末页"
    },
    "oAria": {
        "sSortAscending": ": 以升序排列此列",
        "sSortDescending": ": 以降序排列此列"
    }
};

function applyRole(role) {
    global.wssocket.send("{\"action\":\"applyNodeRole\",\"role\":\"" + role
        + "\",\"pubKey\":\"" + global.sm2Key.publicKey + "\"}");
}

function WSHandler(event) {
    console.log(event);
    data = event.data;
    // console.log(" -->" + data);
    try {
        var obj = JSON.parse(data);

        switch (obj.action) {
            case 'onTransferTo':
                onTransferTo(obj);
                break;
            case 'onHashResult':
                onHashResult(obj);
                break;
            case 'onListMemoryFiles':
                onListMemoryFiles(obj);
                break;
            case 'onDumpContract':
                onDumpContract(obj);
                break;
            case 'onChangeDumpPeriod':
                onChangeDumpPeriod(obj);
                break;
            case 'onGetDumpPeriod':
                onGetDumpPeriod(obj);
                break;
            case 'onStaticVerifyResult':
                onStaticVerifyResult(obj);
                break;
            case "onListContractProcess":
                onListContractProcess(obj);
                break;
            case "onDeleteFile":
                onDeleteFile(obj);
                break;
            case "onCancelAuth":
                onCancelAuth(obj);
                break;
            case "onDownloadContract":
                onDownloadFile(obj);
                break;
            case "onChangePublic":
                onChangePublic(obj);
                break;
            case "onListProjects":
                onListProjects(obj);
                break;
            case "onListProject":
                onListProject(obj);
                break;
            case "onListLocalNodeLog":
                onListLocalNodeLog(obj);
                break;
            case "onListLocalNodeLogPie":
                onListLocalNodeLogPie(obj);
                break;
            case "onListLocalNodeLogLine":
                onListLocalNodeLogLine(obj);
                break;
            case "onListTheContractProcess":
                onListTheContractProcess(obj);
                break;
            case "onListLocalContractLog":
                onListLocalContractLog(obj);
                break;
            case "onListLocalContractLogPie":
                onListLocalContractLogPie(obj);
                break;
            case "onListLocalContractLogLine":
                onListLocalContractLogLine(obj);
                break;
            case "onGetNodeSessionID":
            case "onSessionID":
                onGetNodeSessionID(obj);
                break;
            case "onLogin":
                onNodeLogin(obj);
                break;
            case "onGetNodeRole":
            case "onGetRole":
                onGetNodeRole(obj);
                break;
            case "onApplyRole":
                onApplyRole(obj);
                break;
            case "onListAllAuthRole":
                onListAllAuthRole(obj);
                break;
            case "onListUnAuthRole":
                onListUnAuthRole(obj);
                break;
            case "onDeleteRole":
                onDeleteRole(obj);
                break;
            case "onCountRole":
                onCountRole(obj);
                break;
            case "onAuthNodeRole":
                onAuthNodeRole(obj);
                break;
            case "onApplyNet":
                onApplyNet(obj);
                break;
            case "onLoadNodeConfig":
                onLoadNodeConfig(obj);
                break;
            case "onChangeNodeName":
                onChangeNodeName(obj);
                break;
            case "onChangeYJSPath":
                onChangeYJSPath(obj);
                break;
            case "onChangeIpPort":
                onChangeIpPort(obj);
                break;
            case "onGetLicenceExpiredDate":
                $("#expiredDate").html(convertDate(data.data));
                break;
            case "onGetPeerID":
                global.peerID = obj.data;
                // getNodeTrustUnits();//still connecting to centerportalws
                break;
            case "onViewContractInstance":
                onViewContractInstance(obj);
                break;
            case 'onExecuteResult':
                onExecuteResult(obj);
                break;
            case 'onExecuteContractTrustfully':
                onExecuteContractTrustfully(obj);
                break;
            case 'onUploadFile':
                onUploadFile(obj);
                break;
            case 'onStartContract':
                onStartContract(obj);
                break;
            case 'onStartContractConfig':
                onStartContractConfig(obj);
                break;
            case 'onKillContractProcess':
                onStopContract(obj);
                break;
            case 'onKillAllContract':
                onKillAllContract(obj);
                break;
            case 'onSetPermission':
                onSetPermission(obj);
                break;
            case 'onOutputStream':
                displayOutput(obj);
                break;
            case 'onChangeNodeCenter':
                console.log("onChangeNodeCenter");
                onChangeNodeCenter(obj);
                break;
            case 'onException':
                onException(obj);
                break;
            // logException(obj);
            // break;
            default:
                displayOutput(obj);
                break;
        }
    } catch (err) {
        console.log(err);
    }
}

function onException(obj) {
    if (obj.data.startsWith("unauthorised action")) {
        const action = obj.data.replace("unauthorised action ", "");
        switch (action) {
            case "listContractProcess":
                mainVue.contracts = [];
                if (global.urlparam["contract"]) {
                    appendTargetContract(global.urlparam["contract"]);
                } else
                    alertNoPermission("listContractProcess无授权，请申请ContractUser权限", "提示");
                break;
            default:
                alertNoPermission(action + "无权限", "提示");
        }
    }
}

function alertNoPermission(message, title) {
    const npSpan = $("#nopermissionSpan");
    if (npSpan.length > 0) {
        console.log(message + " status:" + $("#dialog")[0].getAttribute("class"));
        npSpan.append("<br/>" + message);
    } else {
        let body = "<div class='row'><div class='col-sm-12'><span id='nopermissionSpan'>";
        body += message;
        body += "</span></div></div>";
        $("#dialogBodyDiv").html(body);
        showDialog("提示", function () {
            $("#dialogBodyDiv").html("");
        });
    }
}

function onExecuteResult(obj) {
    console.log(obj);
    global.executeResult = obj;
    if (global.executeResult.size) {
        onExecuteContractTrustfully(obj);
    }
    onExecuteResultInternal(obj);
}

function onExecuteContractTrustfully(obj) {
    console.log(obj);
    $("#consistencyResult").html(global.executeResult.size + "个结果一致");
}

function showContractResult(requestID) {
    var data = global.responseCollector[requestID][0];
    result = data;
    $("#statusSpan")[0].innerHTML = result.status;
    $("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
    if (result.result instanceof Object) {
        $("#responseArea")[0].value = JSON.stringify(result.result);
        $("#timeSpan")[0].innerHTML += "<br> JSON格式";
    } else {
        $("#timeSpan")[0].innerHTML += "<br> 字符串格式";
        $("#responseArea")[0].value = result.result;
    }
    if (global.responseCollector[requestID].hashCode != undefined)
        $("#hashDisplayDiv").html("溯源指纹:" + global.responseCollector[requestID].hashCode);
}


function switchContractResult() {
    const requestID = reqIDSpan.value;
    showContractResult(requestID);
}

function showInconsistentResult(list) {
    global.resultList = list;
    let html = "<table class='table table-striped'><thead><tr><td>status</td><td>executeTime</td><td>result</td></tr></thead><tbody>";
    for (const r of list) {
        html += "<tr><td>";
        const data = JSON.parse(r.data);
        html += data.status;
        html += "</td><td>";
        html += r.executeTime;
        html += "</td><td><textarea class='form-control'>";
        html += data.result;
        html += "</textarea></td></tr>";
    }
    html += "</tbody></table>";
    const consistencyResult = $("#consistencyResult");
    if (consistencyResult.length > 0) {
        consistencyResult.html(html);
    } else {
        $("#dialogBodyDiv").html(html);
        showDialog("调用结果不一致", function () {
        }, () => {
        });
    }
}

function showDialog(title, cb, cancelcb) {
    $("#dialogTitleH5").html(title);
    $("#dialogConfimBtn").off("click").on("click", cb);
    $("#dialogCloseBtn").off("click").on("click", cancelcb);
    $("#dialog").modal("show");
}

function onHashResult(obj) {
    $("#hashDisplayDiv").html("溯源指纹:" + obj.data);
    global.responseCollector[obj.responseID].hashCode = obj.data;
}

function displayOutput(obj) {
    console.log(obj);
}

function initWSocket() {
    let host = $("#urlInput")[0].value;
    document.title = `数瑞浏览器（${host}）`
    if (!host.startsWith("ws")) {
        if (location.href.startsWith("https")) {
            host = "wss://" + host;
        } else {
            host = "ws://" + host;
        }
    }
    if (host.endsWith("/SCIDE")) {
        host += "/SCExecutor";
    } else if (host.endsWith("/SCIDE/")) {
        host += "SCExecutor";
    } else if (host.endsWith("NodeCenterWS")) {
        //..
    } else if (!host.endsWith("/SCIDE/SCExecutor")) {
        host += "/SCIDE/SCExecutor";
    }
    console.log("connect ws:" + host);
    global.wssocket = createWssocket(host, () => {
        getSession();
    }, WSHandler);
    global.responseCollector = {};
    global.commited = {};
}

function getSession() {
    global.wssocket.send("{\"action\":\"getSessionID\"}");
}

function exportSMKeyPair() {
    const dialog = $("#dialog");
    dialog.html("Save Your key:<br/>" + JSON.stringify(global.sm2Key));
    dialog.dialog("open");
}

// ====== wsHandler
function onGetNodeSessionID(data) {
    console.log("onGetNodeSessionID");
    global.session = data.session;
    const loginParam = {
        pubKey: global.sm2Key.publicKey,
        signature: sm2.doSignature(global.session, global.sm2Key.privateKey, {hash: true, der: true}),
        action: "login"
    };
    global.wssocket.send(JSON.stringify(loginParam));
}

function onNodeLogin(data) {
    pubkeyDialogVue.myRole = data.data;
    global.myRole = data.data;
    listContracts();
}

function listContracts() {
    global.wssocket.send(JSON.stringify({action: "listContractProcess"}));
}

function changeApp() {
    global.currentContract = global.contracts[$("#selectContract")[0].value];
    if (!global.currentContract) {
        return;
    }
    console.log(global.currentContract);
    document.title = `数瑞浏览器（${global.currentContract.name} - ${$("#urlInput")[0].value}）`
    changeAppInternal(needRender(global.currentContract));
}

function changeAppInternal(requireRendering) {
    if ((global.urlparam["noRender"] !== "true") && requireRendering) {
        $("#mainDiv")[0].innerHTML = "";
        executeCurrentContract("getMainFrame", "", parseMainFrame);
    } else {
        let title = "只包含计算逻辑";
        if (requireRendering) {
            title = "包含界面";
        }
        title += getContractDesp();
        const html = "   <div class='container'>  <div class=\"card mt-3 \">\n"
            + "        <div class=\"card-body\">\n"
            + "          <h5 class=\"card-title\">"
            + title
            + "</h5>\n"
            + "          <div class=\"card-body\" >\n"
            + "            <div class=\"row\">\n"
            + "              <div class=\"col-sm-12 d-flex justify-content-center\">\n"
            + "                <div class=\"input-group mb-2\">\n"
            + "                  <div class=\"input-group-prepend\">\n"
            + "	            <select id=\"selectAction\" onchange=\"showDescription()\" class=\"custom-select\" style=\"-webkit-appearance: none;\"><option value=\"-1\">选择方法</option></select>		\n"
            + "                  </div>\n"
            + "                  <input type=\"text\" class=\"form-control\" id=\"argInput\" placeholder=\"填写参数\" >\n"
            + "                  <input type=\"text\" class=\"form-control col-2\" id=\"gasInput\" placeholder=\"填写gas\" >\n"
            + "                  <div class=\"input-group-append input-group-text\">\n"

            + "<input type=\"checkbox\" id=\"executeContractAsDebug\"   aria-label=\"Checkbox for isDebug\"  data-toggle=\"tooltip\"  title=\"模拟调用\"></input>"
            + "                  </div>\n"

            + "                  <div class=\"input-group-append\">\n"
            + "                    <button class=\"btn btn-outline-secondary\" type=\"button\" \n"
            + "                            onclick=\"triggerExecuteCurrentContract()\">\n"
            + "                      调用\n"
            + "                    </button>\n"
            + "                  </div>\n"
            + "                </div>\n"
            + "              </div>\n"
            + "            </div>"
            + "<div class='row mb-2'><div class='col-sm-12 d-flex '>"
            + "<div class=\"input-group\" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >方法描述</span></div><input class=\"input-group-text form-control\" id=\"descriptionSpan\" placeholder=\"暂无\"></input></div>"
            + "</div></div>"
            + "<div class='row mb-4'><div class='col-sm-12 d-flex'>"
            + "<div class=\"input-group \" ><div class=\"input-group-prepend\" > <span class=\"input-group-text\" >http接口</span></div><input class=\"input-group-text form-control\" id=\"sigOutput\"></input></div></div></div>\n"
            + "            <h5 class=\"card-title\">调用结果</h5>\n"
            + "	    <div class=\"input-group mb-3\">\n"
            + "              <div class=\"input-group-prepend\">\n"
            + "                <select class=\"custom-select form-control\" onchange='switchContractResult()' style=\"-webkit-appearance:none; appearance:none; height:100%\" id=\"reqIDSpan\"><option>请求ID</option></select>\n"
            + "              </div>\n"
            + "		<div class=\"input-group-append\"><span class=\"input-group-text\" id=\"statusSpan\">调用状态</span></div>\n"
            + "		<div class=\"input-group-append\"><span class=\"input-group-text\" id=\"timeSpan\">调用耗时</span></div>\n"
            + "		<textarea id=\"responseArea\" class=\"form-control\"></textarea>\n"
            + "            </div><div class='row mb-3'><div class='col-sm-12 d-flex' id='consistencyResult'> </div></div>"
            + "            <div class='row'><div class='col-sm-12 d-flex' id='hashDisplayDiv'> </div></div>"
            + "          </div>\n"
            + "        </div>\n"
            + "      </div></div>\n" + "";
        $("#mainDiv")[0].innerHTML = html;
        for (const f of global.currentContract.exportedFunctions) {
            $('#selectAction')
                .append(`<option value="${f.functionName}">${f.functionName}</option>`);
        }
    }
}

function getContractDesp() {
    try {
        const annos = global.currentContract.annotations;
        for (const anno of annos) {
            if (anno.type === "Description") {
                return ", " + JSON.parse(anno.args[0]);
            }
        }
    } catch (e) {
        console.log(e);
    }
    return "";
}

function triggerExecuteCurrentContract() {
    const funPos = $("#selectAction")[0].value;
    console.log(funPos);
    if (funPos < 0) {
        $("#dialogBodyDiv").html("请选择方法。");
        showDialog("提示");
        return;
    }
    var funNode;
    for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
        if (global.currentContract.exportedFunctions[i].functionName == funPos) {
            funNode = global.currentContract.exportedFunctions[i];
            break;
        }
    }
    console.log(funNode);
    const argInput = $("#argInput");
    var contract = global.currentContract;
    var gas = $("#gasInput")[0].value / 1;
    executeContractWithGas(contract.id, funNode.functionName, argInput[0].value, gas,
        fillResultInternal, executeContractAsDebug.checked);
    var iHtml = "/SCIDE/SCManager?action=executeContract&contractID="
        + global.currentContract.name + "&operation="
        + funNode.functionName + "&arg=" + argInput[0].value;

    var toSign = global.currentContract.name + "|" + funNode.functionName + "|"
        + argInput[0].value;
    if (gas > 0) {
        toSign += "|" + gas;
        iHtml += "&gasLimit=" + gas;
    }
    iHtml += "&pubkey=" + global.sm2Key.publicKey + "&signature=";
    toSign += "|" + global.sm2Key.publicKey;
    const signature = sm2.doSignature(toSign, global.sm2Key.privateKey, {hash: true, der: true});
    let urlPre = $("#urlInput")[0].value;
    if (urlPre.startsWith("ws")) {
        urlPre = urlPre.replace("ws", "http");
    }
    $("#sigOutput")[0].value = (urlPre + iHtml + signature);
}

function showDescription() {
    const funPos = $("#selectAction")[0].value;
    console.log($("#selectAction")[0]);
    console.log(funPos);
    console.log(global.currentContract.exportedFunctions);
    var funNode;
    for (var i = 0; i < global.currentContract.exportedFunctions.length; i++) {
        if (global.currentContract.exportedFunctions[i].functionName == funPos) {
            funNode = global.currentContract.exportedFunctions[i];
            break;
        }
    }

    console.log(funNode);
    for (const anno of funNode.annotations) {
        if (anno.type === "Description") {
            descriptionSpan.value = JSON.parse(anno.args[0]);
        }
    }
}

function fillResultInternal(result, data) {
    if (global.responseCollector[data.responseID] == undefined) {
        global.responseCollector[data.responseID] = [];
        const reqIDSpan = $("#reqIDSpan");
        reqIDSpan.append("<option value='" + data.responseID + "'>" + data.responseID + "</option>");
        reqIDSpan[0].value = data.responseID;
    }
    global.responseCollector[data.responseID].push(data);
    $("#statusSpan")[0].innerHTML = result.status;
    $("#timeSpan")[0].innerHTML = "调用耗时:" + data.executeTime + "(ms)";
    if (data.executionGas != undefined && data.executionGas > 0)
        $("#timeSpan")[0].innerHTML += "<br> " + data.executionGas + "(gas)";
    $("#timeSpan")[0].innerHTML
    if (result.result instanceof Object) {
        $("#responseArea")[0].value = JSON.stringify(result.result);
        $("#timeSpan")[0].innerHTML += "<br> JSON格式";
    } else {
        $("#timeSpan")[0].innerHTML += "<br> 字符串格式";
        $("#responseArea")[0].value = result.result;
    }
}


function parseMainFrame(data) {
    console.log("parseMainFrame");
    console.log(data);
    const mainHtml = data.result;
    executeCurrentContract("loadResource", mainHtml, loadMain);
}

function loadMain(data) {
    const html = data.result;
    $("#mainDiv").append(html);
    setTimeout(function () {
        console.log("listSize:");
        const scriptList = $("#mainDiv script");
        global.scriptList = [];
        global.scriptOrder = 0;
        console.log("listSize:" + scriptList.length);
        for (var i = 0; i < scriptList.length; i++) {
            const script = scriptList[i];
            const re = script.getAttribute("fromContract");
            if (!re) {
                continue;
            }
            global.scriptList.push(re);
        }
        if (global.scriptList.length > 0) {
            executeCurrentContract("loadResource", global.scriptList[0], loadScript);
        }
        const linkList = $("#mainDiv link");
        for (var i = 0; i < linkList.length; i++) {
            const link = linkList[i];
            const re = link.getAttribute("fromContract");
            executeCurrentContract("loadResource", re, loadCss);
        }
    }, 100);
}

function loadScript(data) {
    console.log("loadScript");
    global.lastScript = data;
    setTimeout(eval, 1, global.lastScript.result);
    global.scriptOrder++;
    if (global.scriptOrder < global.scriptList.length) {
        executeCurrentContract("loadResource", global.scriptList[global.scriptOrder], loadScript);
    }
}

function loadCss(data) {
    console.log("loadScript");
    global.lastCss = data;
    const ele = document.createElement("style");
    ele.setAttribute("type", "text/css");
    ele.innerHTML = data.result;
    document.body.append(ele);
}

function needRender(con) {
    for (const fun of con.exportedFunctions) {
        console.log(fun);
        if (fun.functionName === "needRender") {
            return true;
        }
    }
    return false;
}

function onListContractProcess(data) {
    console.log(data);
    console.log(data.data);
    global.contracts = JSON.parse(data.data);
    if (global.urlparam["contract"]) {
        appendTargetContract(global.urlparam["contract"]);
    } else {
        renewList();
    }
}

function renewList() {
    const selectedContract = $("#selectContract");
    selectedContract.html("");
    selectedContract.append("<option value='-1'>选择合约</option>");
    let selectValue = -1;
    console.log(global.contracts);
    console.log(global.contracts.length);
    for (let i = 0; i < global.contracts.length; ++i) {
        const c = global.contracts[i];
        console.log(c);
        if (c.contractStatus == "KILLED") continue;
        if (!c.id) {
            c.id = c.contractID;
        }
        if (!c.name) {
            c.name = c.contractName;
        }
        selectedContract.append(`<option value='${i}'>${c.name}</option>`);
        if (global.urlparam["contract"]) {
            if (global.urlparam["contract"] === c.name
                || global.urlparam["contract"] === c.id) {
                selectValue = i;
            }
        }
    }
    console.log(selectValue);
    selectedContract[0].value = selectValue;
    if (global.urlparam["contract"]) {
        changeApp();
    }
}

function appendTargetContract(target) {
    global.wssocket.send(JSON.stringify({
        action: "listTheContractProcess",
        contractID: target
    }));
}

function onListTheContractProcess(target) {
    console.log(target);
    const c = JSON.parse(target.data);
    let hasTheSame = false;
    if (!global.contracts) {
        global.contracts = [];
    }
    for (const con of global.contracts) {
        if (con.id === c.id) {
            hasTheSame = true;
        }
    }
    if (!hasTheSame) {
        global.contracts.push(c);
    }
    renewList();
    //"884422533"
}

function onListLocalNodeLog(data) {
    const userManTab = $("#v-pills-userManager-tab")[0];
    if (userManTab.getAttribute("aria-selected") === "true") {
        drawUserActivityGraph(data);
    } else {
        drawLocalLogGraphs(data);
    }
}

function onListAllAuthRole(data) {
    console.log("onListAllAuthRole");
    fillAuthRoleData(data.data);
}

function onListUnAuthRole(data) {
    console.log("onListUnAuthRole");
    fillUnAuthRoleData(data.data);
}

function onApplyNet(data) {
    console.log("onApplyNet");
}

function onCountRole(data) {
    console.log("onCountRole");
    setUserTypeDistribution(data.data);
}

function onAuthNodeRole(data) {
    myToast("授权/忽略操作", data.data);
    if (data.data === "success") {
        global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
        global.wssocket.send(JSON.stringify({action: "listUnAuthRole"}));
    }
}

function onApplyRole(data) {
    console.log(data.data);
    myToast("申请操作", data.data);
}

function onDeleteRole(data) {
    myToast("删除操作", data.data);
    global.wssocket.send(JSON.stringify({action: "listAllAuthRole"}));
}

// ====== wsHandler done!

function myToast(title, msg) {
    toastVue.toastTitle = title;
    toastVue.toastMessage = msg;
    $("#alertDiv").toast("show");
}

function countChar(str, c) {
    let ret = 0;
    for (const ch of str) {
        if (ch === c) {
            ret++;
        }
    }
    return ret;
}

function generate() {
    const key = sm2.generateKeyPairHex();
    global.sm2Key = key;
    localStorage.setItem("PrivKey", JSON.stringify(key));
}

function killAllContract() {
    global.wssocket.send(JSON.stringify({action: "killAllContract"}));
}

function init() {
    const urlParams = getRequestParameters();
    initVue();
    initGlobal(urlParams);

    if (global.urlparam["noRender"] === "true") {
        switchRenderBtn.innerHTML = "加载界面";
    }
    global.cbs = {};

    const urlInput = $("#urlInput");
    if (global.urlparam["self"] === "true") {
        if (document.location.href.startsWith("http")) {
            let path = document.location.origin + document.location.pathname;
            path = path.replace("/client/bdwareclient.html", "");
            urlInput[0].value = path.replace("http",
                "ws");
            if (global.urlparam["withNodeCenterWS"] === "true") {
                urlInput[0].value += "/NodeCenterWS";
            }
            connectNode();
        }
    } else if (global.urlparam["nodeAddr"]) {
        urlInput[0].value = global.urlparam["nodeAddr"];
        connectNode();
    } else {
        const lastNode = localStorage.getItem("lastNode");
        if (lastNode) {
            urlInput[0].value = lastNode;
            connectNode();
        }
    }
}

function connectNode() {
    localStorage.setItem("lastNode", $("#urlInput")[0].value);
    initWSocket();
}

function getRequestParameters() {
    if (isBaaS) {
        let params = location.href.replace(/[^#]*(#(\/)?|\?)/, '')
        let url = location.href.replace(params, '')
        while (!params) {
            url = url.replace(/(#(\/)?|\?)$/, '')
            params = url.replace(/[^#]*(#(\/)?|\?)/, '')
            url = url.replace(params, '')
        }
        if (url.endsWith('#') || url.endsWith('#\/')) {
            let sKey = Math.random().toString()
            localStorage.setItem(sKey, params)
            location.href = url.replace(/#(\/)?/, '?' + sKey)
        } else {
            let json = atob(localStorage.getItem(params))
            try {
                return JSON.parse(json);
            } catch (e) {
                localStorage.removeItem(params)
                alert('链接失效！')
                location.href = location.origin
            }
        }
    } else {
        const arr = (location.search || "").replace(/^\?/, '').split("&");
        const params = {};
        for (const a of arr) {
            const data = a.split("=");
            if (data.length === 2) {
                params[data[0]] = data[1];
            }
        }
        return params;
    }
}


function changeRender() {
    if (global.urlparam["noRender"] === "true") {
        global.urlparam["noRender"] = undefined;
        switchRenderBtn.innerHTML = "不加载界面";
    } else {
        global.urlparam["noRender"] = "true";
        switchRenderBtn.innerHTML = "加载界面";
    }
    changeApp();
}