[{"C:\\Users\\sle11\\Documents\\VSCode\\squeezelite-esp32\\components\\wifi-manager\\webapp\\src\\js\\custom.js":"1"},{"size":62870,"mtime":1641847593736,"results":"2","hashOfConfig":"3"},{"filePath":"4","messages":"5","errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"6","usedDeprecatedRules":"7"},"7z2b57","C:\\Users\\sle11\\Documents\\VSCode\\squeezelite-esp32\\components\\wifi-manager\\webapp\\src\\js\\custom.js",["8"],"import he from 'he';\r\nimport { Promise } from 'es6-promise';\r\n\r\nif (!String.prototype.format) {\r\n Object.assign(String.prototype, {\r\n format() {\r\n const args = arguments;\r\n return this.replace(/{(\\d+)}/g, function(match, number) {\r\n return typeof args[number] !== 'undefined' ? args[number] : match;\r\n });\r\n }, \r\n }); \r\n}\r\nif (!String.prototype.encodeHTML) {\r\n Object.assign(String.prototype, {\r\n encodeHTML() {\r\n return he.encode(this).replace(/\\n/g, '
')\r\n },\r\n });\r\n}\r\nObject.assign(Date.prototype, {\r\n toLocalShort() {\r\n const opt = { dateStyle: 'short', timeStyle: 'short' };\r\n return this.toLocaleString(undefined, opt);\r\n },\r\n});\r\n\r\n\r\nconst nvsTypes = {\r\n NVS_TYPE_U8: 0x01,\r\n\r\n /*! < Type uint8_t */\r\n NVS_TYPE_I8: 0x11,\r\n\r\n /*! < Type int8_t */\r\n NVS_TYPE_U16: 0x02,\r\n\r\n /*! < Type uint16_t */\r\n NVS_TYPE_I16: 0x12,\r\n\r\n /*! < Type int16_t */\r\n NVS_TYPE_U32: 0x04,\r\n\r\n /*! < Type uint32_t */\r\n NVS_TYPE_I32: 0x14,\r\n\r\n /*! < Type int32_t */\r\n NVS_TYPE_U64: 0x08,\r\n\r\n /*! < Type uint64_t */\r\n NVS_TYPE_I64: 0x18,\r\n\r\n /*! < Type int64_t */\r\n NVS_TYPE_STR: 0x21,\r\n\r\n /*! < Type string */\r\n NVS_TYPE_BLOB: 0x42,\r\n\r\n /*! < Type blob */\r\n NVS_TYPE_ANY: 0xff /*! < Must be last */,\r\n};\r\nconst btIcons = {\r\n bt_playing: 'play-circle-fill',\r\n bt_disconnected: 'bluetooth-fill',\r\n bt_neutral: '',\r\n bt_connected: 'bluetooth-connect-fill',\r\n bt_disabled: '',\r\n play_arrow: 'play-circle-fill',\r\n pause: 'pause-circle-fill',\r\n stop: 'stop-circle-fill',\r\n '': '',\r\n};\r\n\r\nconst btStateIcons = [\r\n { desc: 'Idle', sub: ['bt_neutral'] },\r\n { desc: 'Discovering', sub: ['bt_disconnected'] },\r\n { desc: 'Discovered', sub: ['bt_disconnected'] },\r\n { desc: 'Unconnected', sub: ['bt_disconnected'] },\r\n { desc: 'Connecting', sub: ['bt_disconnected'] },\r\n { \r\n desc: 'Connected',\r\n sub: ['bt_connected', 'play_arrow', 'bt_playing', 'pause', 'stop'],\r\n },\r\n { desc: 'Disconnecting', sub: ['bt_disconnected'] },\r\n];\r\n\r\nconst pillcolors = {\r\n MESSAGING_INFO: 'badge-success',\r\n MESSAGING_WARNING: 'badge-warning',\r\n MESSAGING_ERROR: 'badge-danger',\r\n};\r\nconst connectReturnCode = {\r\n UPDATE_CONNECTION_OK : 0, \r\n\tUPDATE_FAILED_ATTEMPT : 1,\r\n\tUPDATE_USER_DISCONNECT : 2,\r\n UPDATE_LOST_CONNECTION : 3,\r\n UPDATE_FAILED_ATTEMPT_AND_RESTORE : 4\r\n}\r\nconst taskStates = {\r\n 0: 'eRunning',\r\n /*! < A task is querying the state of itself, so must be running. */\r\n 1: 'eReady',\r\n /*! < The task being queried is in a read or pending ready list. */\r\n 2: 'eBlocked',\r\n /*! < The task being queried is in the Blocked state. */\r\n 3: 'eSuspended',\r\n /*! < The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */\r\n 4: 'eDeleted',\r\n};\r\nconst flash_status_codes = {\r\n NONE : 0,\r\n REBOOT_TO_RECOVERY: 2,\r\n SET_FWURL: 5,\r\n FLASHING: 6,\r\n DONE: 7,\r\n UPLOADING: 8,\r\n ERROR: 9\r\n};\r\nlet flash_state=flash_status_codes.FLASH_NONE;\r\nlet flash_ota_dsc='';\r\nlet flash_ota_pct=0;\r\nlet older_recovery=false;\r\nlet presetsloaded=false;\r\nfunction isFlashExecuting(data){\r\n return (flash_state!=flash_status_codes.UPLOADING ) && (data.ota_dsc!='' || data.ota_pct>0);\r\n}\r\nfunction post_config(data){\r\n let confPayload={\r\n timestamp: Date.now(),\r\n config : data\r\n };\r\n $.ajax({\r\n url: '/config.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(confPayload),\r\n error: handleExceptionResponse,\r\n });\r\n}\r\nfunction process_ota_event(data){\r\n if(data.ota_dsc){\r\n flash_ota_dsc=data.ota_dsc;\r\n }\r\n if( data.ota_pct != undefined){\r\n flash_ota_pct=data.ota_pct;\r\n }\r\n \r\n if(flash_state==flash_status_codes.ERROR){\r\n return;\r\n }\r\n else if(isFlashExecuting(data)){\r\n flash_state=flash_status_codes.FLASHING;\r\n } \r\n else if(flash_state==flash_status_codes.FLASHING ){\r\n if(flash_ota_pct ==100){\r\n // we were processing OTA, and we've reached 100%\r\n flash_state=flash_status_codes.DONE;\r\n $('#flashfilename').val('');\r\n } \r\n else if(flash_ota_pct<0 && older_recovery){\r\n // we were processing OTA on an older recovery and we missed the \r\n // end of flashing.\r\n console.log('End of flashing from older recovery');\r\n if(data.ota_dsc==''){\r\n flash_ota_dsc = 'OTA Process Completed';\r\n }\r\n flash_state=flash_status_codes.DONE;\r\n }\r\n }\r\n else if(flash_state ==flash_status_codes.UPLOADING){ \r\n if(flash_ota_pct ==100){\r\n // we were processing OTA, and we've reached 100%\r\n // reset the progress bar \r\n flash_ota_pct = 0;\r\n flash_state=flash_status_codes.FLASHING;\r\n } \r\n }\r\n}\r\nfunction set_ota_error(message){\r\n flash_state=flash_status_codes.ERROR;\r\n handle_flash_state({\r\n ota_pct: 0,\r\n ota_dsc: message,\r\n event: flash_events.SET_ERROR\r\n }); \r\n}\r\nfunction show_update_dialog(){\r\n $('#otadiv').modal();\r\n if (flash_ota_pct >= 0) {\r\n update_progress();\r\n }\r\n if (flash_ota_dsc !== '') {\r\n $('span#flash-status').html(flash_ota_dsc);\r\n }\r\n}\r\nconst flash_events={\r\n SET_ERROR: function(data){\r\n if(data.ota_dsc){\r\n flash_ota_dsc=data.ota_dsc;\r\n }\r\n else {\r\n flash_ota_dsc = 'Error';\r\n }\r\n flash_ota_pct=data.ota_pct??0;\r\n $('#fwProgressLabel').parent().addClass('bg-danger');\r\n update_progress();\r\n show_update_dialog();\r\n },\r\n START_OTA : function() {\r\n if (flash_state == flash_status_codes.NONE || flash_state == flash_status_codes.ERROR || flash_state == undefined) {\r\n $('#fwProgressLabel').parent().removeClass('bg-danger');\r\n flash_state=flash_status_codes.REBOOT_TO_RECOVERY;\r\n if(!recovery){\r\n flash_ota_dsc = 'Starting recovery mode...';\r\n // Reboot system to recovery mode\r\n const data = {\r\n timestamp: Date.now(),\r\n };\r\n\r\n $.ajax({\r\n url: '/recovery.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(data),\r\n error: function(xhr, _ajaxOptions, thrownError){\r\n set_ota_error(`Unexpected error while trying to restart to recovery. (status=${xhr.status??''}, error=${thrownError??''} ) `);\r\n },\r\n complete: function(response) {\r\n console.log(response.responseText);\r\n },\r\n }); \r\n }\r\n else {\r\n flash_ota_dsc='Starting Update';\r\n }\r\n show_update_dialog();\r\n \r\n }\r\n else {\r\n console.warn('Unexpected status while starting flashing');\r\n } \r\n },\r\n FOUND_RECOVERY: function(data) {\r\n console.log(JSON.stringify(data));\r\n const url=$('#fw-url-input').val();\r\n if(flash_state == flash_status_codes.REBOOT_TO_RECOVERY){\r\n const fileInput = $('#flashfilename')[0].files;\r\n if (fileInput.length > 0) {\r\n flash_ota_dsc = 'Sending file to device.';\r\n flash_state= flash_status_codes.UPLOADING;\r\n const uploadPath = '/flash.json';\r\n const xhttp = new XMLHttpRequest();\r\n // xhrObj.upload.addEventListener(\"loadstart\", loadStartFunction, false); \r\n xhttp.upload.addEventListener(\"progress\", progressFunction, false); \r\n //xhrObj.upload.addEventListener(\"load\", transferCompleteFunction, false); \r\n xhttp.onreadystatechange = function() {\r\n if (xhttp.readyState === 4) {\r\n if(xhttp.status === 0 || xhttp.status === 404) {\r\n set_ota_error(`Upload Failed. Recovery version might not support uploading. Please use web update instead.`);\r\n $('#flashfilename').val('');\r\n }\r\n }\r\n };\r\n xhttp.open('POST', uploadPath, true);\r\n xhttp.send(fileInput[0] );\r\n }\r\n else if(url==''){\r\n flash_state= flash_status_codes.NONE;\r\n }\r\n else {\r\n flash_ota_dsc = 'Saving firmware URL location.';\r\n flash_state= flash_status_codes.SET_FWURL;\r\n let confData= { fwurl: {\r\n value: $('#fw-url-input').val(),\r\n type: 33,\r\n }\r\n };\r\n post_config(confData); \r\n }\r\n show_update_dialog();\r\n }\r\n },\r\n PROCESS_OTA_UPLOAD: function(data){\r\n flash_state= flash_status_codes.UPLOADING;\r\n process_ota_event(data);\r\n show_update_dialog();\r\n },\r\n PROCESS_OTA_STATUS: function(data){\r\n if(data.ota_pct>0){\r\n older_recovery = true;\r\n }\r\n if(flash_state == flash_status_codes.REBOOT_TO_RECOVERY){\r\n data.event = flash_events.FOUND_RECOVERY;\r\n handle_flash_state(data);\r\n }\r\n else if(flash_state==flash_status_codes.DONE && !recovery){\r\n flash_state=flash_status_codes.NONE;\r\n $('#rTable tr.release').removeClass('table-success table-warning');\r\n $('#fw-url-input').val('');\r\n }\r\n\r\n else {\r\n process_ota_event(data);\r\n if(flash_state && (flash_state >flash_status_codes.NONE && flash_ota_pct>=0) ) {\r\n show_update_dialog();\r\n }\r\n } \r\n },\r\n PROCESS_OTA: function(data) {\r\n process_ota_event(data);\r\n if(flash_state && (flash_state >flash_status_codes.NONE && flash_ota_pct>=0) ) {\r\n show_update_dialog();\r\n }\r\n }\r\n};\r\nwindow.hideSurrounding = function(obj){\r\n $(obj).parent().parent().hide();\r\n}\r\nfunction update_progress(){\r\n $('.progress-bar')\r\n .css('width', flash_ota_pct + '%')\r\n .attr('aria-valuenow', flash_ota_pct)\r\n .text(flash_ota_pct+'%')\r\n $('.progress-bar').html((flash_state==flash_status_codes.DONE?100:flash_ota_pct) + '%');\r\n\r\n}\r\nfunction handle_flash_state(data) {\r\n if(data.event) {\r\n data.event(data);\r\n } \r\n else {\r\n console.error('Unexpected error while processing handle_flash_state');\r\n return;\r\n }\r\n\r\n}\r\nwindow.hFlash = function(){\r\n // reset file upload selection if any;\r\n $('#flashfilename').val('');\r\n handle_flash_state({ event: flash_events.START_OTA, url: $('#fw-url-input').val() });\r\n}\r\nwindow.handleReboot = function(link){\r\n \r\n if(link=='reboot_ota'){\r\n $('#reboot_ota_nav').removeClass('active').prop(\"disabled\",true); delayReboot(500,'', 'reboot_ota');\r\n }\r\n else {\r\n $('#reboot_nav').removeClass('active'); delayReboot(500,'',link);\r\n }\r\n}\r\nfunction progressFunction(evt){ \r\n // if (evt.lengthComputable) { \r\n // progressBar.max = evt.total; \r\n // progressBar.value = evt.loaded; \r\n // percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + \"%\"; \r\n // } \r\n handle_flash_state({\r\n ota_pct: ( Math.round(evt.loaded / evt.total * 100)),\r\n ota_dsc: ('Uploading file to device'),\r\n event: flash_events.PROCESS_OTA_UPLOAD\r\n }); \r\n} \r\nfunction handlebtstate(data) {\r\n let icon = '';\r\n let tt = '';\r\n if (data.bt_status !== undefined && data.bt_sub_status !== undefined) {\r\n const iconsvg = btStateIcons[data.bt_status].sub[data.bt_sub_status];\r\n if (iconsvg) {\r\n icon = `#${btIcons[iconsvg]}`;\r\n tt = btStateIcons[data.bt_status].desc;\r\n } else {\r\n icon = `#${btIcons.bt_connected}`;\r\n tt = 'Output status';\r\n }\r\n }\r\n $('#o_type').title = tt;\r\n $('#o_bt').attr('xlink:href',icon);\r\n\r\n \r\n}\r\nfunction handleTemplateTypeRadio(outtype) {\r\n if (outtype === 'bt') {\r\n $('#bt').prop('checked', true);\r\n $('#o_bt').attr('display', 'inline');\r\n $('#o_spdif').attr('display', 'none');\r\n $('#o_i2s').attr('display', 'none');\r\n output = 'bt';\r\n } else if (outtype === 'spdif') {\r\n $('#spdif').prop('checked', true);\r\n $('#o_bt').attr('display', 'none');\r\n $('#o_spdif').attr('display', 'inline');\r\n $('#o_i2s').attr('display', 'none');\r\n output = 'spdif';\r\n } else {\r\n $('#i2s').prop('checked', true);\r\n $('#o_bt').attr('display', 'none');\r\n $('#o_spdif').attr('display', 'none');\r\n $('#o_i2s').attr('display', 'inline');\r\n output = 'i2s';\r\n }\r\n}\r\n\r\nfunction handleExceptionResponse(xhr, _ajaxOptions, thrownError) {\r\n console.log(xhr.status);\r\n console.log(thrownError);\r\n if (thrownError !== '') {\r\n showLocalMessage(thrownError, 'MESSAGING_ERROR');\r\n }\r\n}\r\nfunction HideCmdMessage(cmdname) {\r\n $('#toast_' + cmdname).css('display', 'none');\r\n $('#toast_' + cmdname)\r\n .removeClass('table-success')\r\n .removeClass('table-warning')\r\n .removeClass('table-danger')\r\n .addClass('table-success');\r\n $('#msg_' + cmdname).html('');\r\n}\r\nfunction showCmdMessage(cmdname, msgtype, msgtext, append = false) {\r\n let color = 'table-success';\r\n if (msgtype === 'MESSAGING_WARNING') {\r\n color = 'table-warning';\r\n } else if (msgtype === 'MESSAGING_ERROR') {\r\n color = 'table-danger';\r\n }\r\n $('#toast_' + cmdname).css('display', 'block');\r\n $('#toast_' + cmdname)\r\n .removeClass('table-success')\r\n .removeClass('table-warning')\r\n .removeClass('table-danger')\r\n .addClass(color);\r\n let escapedtext = msgtext\r\n .substring(0, msgtext.length - 1)\r\n .encodeHTML()\r\n .replace(/\\n/g, '
');\r\n escapedtext =\r\n ($('#msg_' + cmdname).html().length > 0 && append\r\n ? $('#msg_' + cmdname).html() + '
'\r\n : '') + escapedtext;\r\n $('#msg_' + cmdname).html(escapedtext);\r\n}\r\n\r\nlet releaseURL =\r\n 'https://api.github.com/repos/sle118/squeezelite-esp32/releases';\r\n \r\nlet recovery = false;\r\nconst commandHeader = 'squeezelite -b 500:2000 -d all=info -C 30 -W';\r\nlet blockAjax = false;\r\n//let blockFlashButton = false;\r\nlet apList = null;\r\n//let selectedSSID = '';\r\n//let checkStatusInterval = null;\r\nlet messagecount = 0;\r\nlet messageseverity = 'MESSAGING_INFO';\r\nlet StatusIntervalActive = false;\r\nlet LastRecoveryState = null;\r\nlet SystemConfig={};\r\nlet LastCommandsState = null;\r\nvar output = '';\r\nlet hostName = '';\r\nlet versionName='Squeezelite-ESP32';\r\nlet prevmessage='';\r\nlet project_name=versionName;\r\nlet platform_name=versionName;\r\nlet btSinkNamesOptSel='#cfg-audio-bt_source-sink_name';\r\nlet ConnectedToSSID={};\r\nlet ConnectingToSSID={};\r\nlet lmsBaseUrl;\r\nlet prevLMSIP='';\r\nconst ConnectingToActions = {\r\n 'CONN' : 0,'MAN' : 1,'STS' : 2,\r\n}\r\n\r\nPromise.prototype.delay = function(duration) {\r\n return this.then(\r\n function(value) {\r\n return new Promise(function(resolve) {\r\n setTimeout(function() {\r\n resolve(value);\r\n }, duration);\r\n });\r\n },\r\n function(reason) {\r\n return new Promise(function(_resolve, reject) {\r\n setTimeout(function() {\r\n reject(reason);\r\n }, duration);\r\n });\r\n }\r\n );\r\n};\r\n\r\nfunction startCheckStatusInterval() {\r\n StatusIntervalActive = true;\r\n setTimeout(checkStatus, 3000);\r\n}\r\n\r\n\r\nfunction RepeatCheckStatusInterval() {\r\n if (StatusIntervalActive) {\r\n startCheckStatusInterval();\r\n }\r\n}\r\n\r\nfunction getConfigJson(slimMode) {\r\n const config = {};\r\n $('input.nvs').each(function(_index, entry) {\r\n if (!slimMode) {\r\n const nvsType = parseInt(entry.attributes.nvs_type.value, 10);\r\n if (entry.id !== '') {\r\n config[entry.id] = {};\r\n if (\r\n nvsType === nvsTypes.NVS_TYPE_U8 ||\r\n nvsType === nvsTypes.NVS_TYPE_I8 ||\r\n nvsType === nvsTypes.NVS_TYPE_U16 ||\r\n nvsType === nvsTypes.NVS_TYPE_I16 ||\r\n nvsType === nvsTypes.NVS_TYPE_U32 ||\r\n nvsType === nvsTypes.NVS_TYPE_I32 ||\r\n nvsType === nvsTypes.NVS_TYPE_U64 ||\r\n nvsType === nvsTypes.NVS_TYPE_I64\r\n ) {\r\n config[entry.id].value = parseInt(entry.value);\r\n } else {\r\n config[entry.id].value = entry.value;\r\n }\r\n config[entry.id].type = nvsType;\r\n }\r\n } else {\r\n config[entry.id] = entry.value;\r\n }\r\n });\r\n const key = $('#nvs-new-key').val();\r\n const val = $('#nvs-new-value').val();\r\n if (key !== '') {\r\n if (!slimMode) {\r\n config[key] = {};\r\n config[key].value = val;\r\n config[key].type = 33;\r\n } else {\r\n config[key] = val;\r\n }\r\n }\r\n return config;\r\n}\r\n\r\n// eslint-disable-next-line no-unused-vars\r\nfunction onFileLoad(elementId, event) {\r\n let data = {};\r\n try {\r\n data = JSON.parse(elementId.srcElement.result);\r\n } catch (e) {\r\n alert('Parsing failed!\\r\\n ' + e);\r\n }\r\n $('input.nvs').each(function(_index, entry) {\r\n if (data[entry.id]) {\r\n if (data[entry.id] !== entry.value) {\r\n console.log(\r\n 'Changed ' + entry.id + ' ' + entry.value + '==>' + data[entry.id]\r\n );\r\n $(this).val(data[entry.id]);\r\n }\r\n }\r\n });\r\n}\r\n\r\n// eslint-disable-next-line no-unused-vars\r\nfunction onChooseFile(event, control) {\r\n if (typeof window.FileReader !== 'function') {\r\n throw \"The file API isn't supported on this browser.\";\r\n }\r\n const input = event.target;\r\n if (!input) {\r\n throw 'The browser does not properly implement the event object';\r\n }\r\n if (!input.files) {\r\n throw 'This browser does not support the `files` property of the file input.';\r\n }\r\n if (!input.files[0]) {\r\n return undefined;\r\n }\r\n \r\n const file = input.files[0];\r\n let fr = new FileReader();\r\n fr.onload = onFileLoad.bind(control)(input, event);\r\n fr.readAsText(file);\r\n input.value = '';\r\n}\r\n\r\n// pull json file from https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json and\r\n// load the names into cfg-hw-preset-model_name\r\nfunction loadPresets() {\r\n if(presetsloaded) return;\r\n presetsloaded = true;\r\n $.getJSON(\r\n 'https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json',\r\n function(data) {\r\n $.each(data, function(key, val) {\r\n if(key === 'name') {\r\n $('#cfg-hw-preset-model_name').append(\r\n $('').val(val).html(val)\r\n );\r\n }\r\n });\r\n }\r\n ).fail(function(jqxhr, textStatus, error) {\r\n const err = textStatus + ', ' + error;\r\n console.log('Request Failed: ' + err);\r\n $('hw-preset-section').hide();\r\n }\r\n );\r\n}\r\n\r\n \r\n\r\n\r\nfunction delayReboot(duration, cmdname, ota = 'reboot') {\r\n const url = '/'+ota+'.json';\r\n $('tbody#tasks').empty();\r\n $('#tasks_sect').css('visibility', 'collapse');\r\n Promise.resolve({ cmdname: cmdname, url: url })\r\n .delay(duration)\r\n .then(function(data) {\r\n if (data.cmdname.length > 0) {\r\n showCmdMessage(\r\n data.cmdname,\r\n 'MESSAGING_WARNING',\r\n 'System is rebooting.\\n',\r\n true\r\n );\r\n } else {\r\n showLocalMessage('System is rebooting.\\n', 'MESSAGING_WARNING');\r\n }\r\n console.log('now triggering reboot');\r\n $(\"button[onclick*='handleReboot']\").addClass('rebooting');\r\n $.ajax({\r\n url: data.url,\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n }),\r\n error: handleExceptionResponse,\r\n complete: function() {\r\n console.log('reboot call completed');\r\n Promise.resolve(data)\r\n .delay(6000)\r\n .then(function(rdata) {\r\n if (rdata.cmdname.length > 0) {\r\n HideCmdMessage(rdata.cmdname);\r\n }\r\n getCommands();\r\n getConfig();\r\n });\r\n },\r\n });\r\n });\r\n}\r\n// eslint-disable-next-line no-unused-vars\r\nwindow.saveAutoexec1 = function(apply) {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Saving.\\n', false);\r\n let commandLine = commandHeader + ' -n \"' + $('#player').val() + '\"';\r\n if (output === 'bt') {\r\n commandLine += ' -o \"BT\" -R -Z 192000';\r\n showCmdMessage(\r\n 'cfg-audio-tmpl',\r\n 'MESSAGING_INFO',\r\n 'Remember to configure the Bluetooth audio device name.\\n',\r\n true\r\n );\r\n } else if (output === 'spdif') {\r\n commandLine += ' -o SPDIF -Z 192000';\r\n } else {\r\n commandLine += ' -o I2S';\r\n }\r\n if ($('#optional').val() !== '') {\r\n commandLine += ' ' + $('#optional').val();\r\n }\r\n const data = {\r\n timestamp: Date.now(),\r\n };\r\n data.config = {\r\n autoexec1: { value: commandLine, type: 33 },\r\n autoexec: {\r\n value: $('#disable-squeezelite').prop('checked') ? '0' : '1',\r\n type: 33,\r\n },\r\n };\r\n\r\n $.ajax({\r\n url: '/config.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify(data),\r\n error: handleExceptionResponse,\r\n complete: function(response) {\r\n if (\r\n response.responseText.result &&\r\n JSON.parse(response.responseText).result === 'OK'\r\n ) {\r\n showCmdMessage('cfg-audio-tmpl', 'MESSAGING_INFO', 'Done.\\n', true);\r\n if (apply) {\r\n delayReboot(1500, 'cfg-audio-tmpl');\r\n }\r\n } else if (response.responseText.result) {\r\n showCmdMessage(\r\n 'cfg-audio-tmpl',\r\n 'MESSAGING_WARNING',\r\n JSON.parse(response.responseText).Result + '\\n',\r\n true\r\n );\r\n } else {\r\n showCmdMessage(\r\n 'cfg-audio-tmpl',\r\n 'MESSAGING_ERROR',\r\n response.statusText + '\\n'\r\n );\r\n }\r\n console.log(response.responseText);\r\n },\r\n });\r\n console.log('sent data:', JSON.stringify(data));\r\n}\r\nwindow.handleDisconnect = function(){\r\n $.ajax({\r\n url: '/connect.json',\r\n dataType: 'text',\r\n method: 'DELETE',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n }),\r\n });\r\n}\r\nfunction setPlatformFilter(val){\r\n if($('.upf').filter(function(){ return $(this).text().toUpperCase()===val.toUpperCase()}).length>0){\r\n $('#splf').val(val).trigger('input');\r\n return true;\r\n }\r\n return false;\r\n}\r\nwindow.handleConnect = function(){\r\n ConnectingToSSID.ssid = $('#manual_ssid').val();\r\n ConnectingToSSID.pwd = $('#manual_pwd').val();\r\n ConnectingToSSID.dhcpname = $('#dhcp-name2').val();\r\n $(\"*[class*='connecting']\").hide();\r\n $('#ssid-wait').text(ConnectingToSSID.ssid);\r\n $('.connecting').show();\r\n\r\n $.ajax({\r\n url: '/connect.json',\r\n dataType: 'text',\r\n method: 'POST',\r\n cache: false,\r\n contentType: 'application/json; charset=utf-8',\r\n data: JSON.stringify({\r\n timestamp: Date.now(),\r\n ssid: ConnectingToSSID.ssid,\r\n pwd: ConnectingToSSID.pwd\r\n }),\r\n error: handleExceptionResponse,\r\n });\r\n\r\n // now we can re-set the intervals regardless of result\r\n startCheckStatusInterval();\r\n\r\n}\r\n$(document).ready(function() {\r\n $('#wifiTable').on('click','tr', function() {\r\n\r\n });\r\n $('#fw-url-input').on('input', function() {\r\n if($(this).val().length>8 && ($(this).val().startsWith('http://') || $(this).val().startsWith('https://'))){\r\n $('#start-flash').show();\r\n } \r\n else {\r\n $('#start-flash').hide();\r\n }\r\n });\r\n $('.upSrch').on('input', function() {\r\n const val = this.value;\r\n $(\"#rTable tr\").removeClass(this.id+'_hide');\r\n if(val.length>0) {\r\n $(`#rTable td:nth-child(${$(this).parent().index()+1})`).filter(function(){ \r\n return !$(this).text().toUpperCase().includes(val.toUpperCase());\r\n }).parent().addClass(this.id+'_hide');\r\n }\r\n $('[class*=\"_hide\"]').hide();\r\n $('#rTable tr').not('[class*=\"_hide\"]').show()\r\n\r\n });\r\n setTimeout(refreshAP,1500);\r\n\r\n \r\n $('#otadiv').on('hidden.bs.modal', function () {\r\n // reset flash status. This should stop the state machine from\r\n // executing steps up to flashing itself.\r\n flash_state=flash_status_codes.NONE;\r\n });\r\n $('#WifiConnectDialog').on('shown.bs.modal', function () {\r\n $(\"*[class*='connecting']\").hide();\r\n if(ConnectingToSSID.Action!==ConnectingToActions.STS){\r\n $('.connecting-init').show();\r\n $('#manual_ssid').trigger('focus'); \r\n }\r\n else {\r\n handleWifiDialog();\r\n }\r\n })\r\n $('#WifiConnectDialog').on('hidden.bs.modal', function () {\r\n $('#WifiConnectDialog input').val('');\r\n })\r\n \r\n $('#uCnfrm').on('shown.bs.modal', function () {\r\n $('#selectedFWURL').text($('#fw-url-input').val());\r\n })\r\n \r\n $('input#show-commands')[0].checked = LastCommandsState === 1;\r\n $('a[href^=\"#tab-commands\"]').hide();\r\n $('#load-nvs').on('click', function() {\r\n $('#nvsfilename').trigger('click');\r\n });\r\n $('#clear-syslog').on('click', function() {\r\n messagecount = 0;\r\n messageseverity = 'MESSAGING_INFO';\r\n $('#msgcnt').text('');\r\n $('#syslogTable').html('');\r\n });\r\n \r\n $('#wifiTable').on('click','tr', function() {\r\n ConnectingToSSID.Action=ConnectingToActions.CONN;\r\n if($(this).children('td:eq(1)').text() == ConnectedToSSID.ssid){\r\n ConnectingToSSID.Action=ConnectingToActions.STS;\r\n return;\r\n }\r\n if(!$(this).is(':last-child')){\r\n ConnectingToSSID.ssid=$(this).children('td:eq(1)').text();\r\n $('#manual_ssid').val(ConnectingToSSID.ssid);\r\n } \r\n else {\r\n ConnectingToSSID.Action=ConnectingToActions.MAN;\r\n ConnectingToSSID.ssid='';\r\n $('#manual_ssid').val(ConnectingToSSID.ssid);\r\n }\r\n });\r\n\r\n\r\n $('#ok-credits').on('click', function() {\r\n $('#credits').slideUp('fast', function() {});\r\n $('#app').slideDown('fast', function() {});\r\n });\r\n\r\n $('#acredits').on('click', function(event) {\r\n event.preventDefault();\r\n $('#app').slideUp('fast', function() {});\r\n $('#credits').slideDown('fast', function() {});\r\n });\r\n\r\n $('input#show-commands').on('click', function() {\r\n this.checked = this.checked ? 1 : 0;\r\n if (this.checked) {\r\n $('a[href^=\"#tab-commands\"]').show();\r\n LastCommandsState = 1;\r\n } else {\r\n LastCommandsState = 0;\r\n $('a[href^=\"#tab-commands\"]').hide();\r\n }\r\n });\r\n\r\n $('input#show-nvs').on('click', function() {\r\n this.checked = this.checked ? 1 : 0;\r\n if (this.checked) {\r\n $('*[href*=\"-nvs\"]').show();\r\n } else {\r\n $('*[href*=\"-nvs\"]').hide();\r\n }\r\n });\r\n \r\n $('#save-as-nvs').on('click', function() {\r\n const config = getConfigJson(true);\r\n const a = document.createElement('a');\r\n a.href = URL.createObjectURL(\r\n new Blob([JSON.stringify(config, null, 2)], {\r\n type: 'text/plain',\r\n })\r\n );\r\n a.setAttribute(\r\n 'download',\r\n 'nvs_config_' + hostName + '_' + Date.now() + 'json'\r\n );\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n });\r\n\r\n $('#save-nvs').on('click', function() {\r\n post_config(getConfigJson(false));\r\n });\r\n \r\n $('#fwUpload').on('click', function() {\r\n const fileInput = document.getElementById('flashfilename').files;\r\n if (fileInput.length === 0) {\r\n alert('No file selected!');\r\n } else {\r\n handle_flash_state({ event: flash_events.START_OTA, file: fileInput[0] });\r\n }\r\n \r\n });\r\n $('[name=output-tmpl]').on('click', function() {\r\n handleTemplateTypeRadio(this.id);\r\n });\r\n\r\n $('#chkUpdates').on('click', function() {\r\n $('#rTable').html('');\r\n $.getJSON(releaseURL, function(data) {\r\n let i = 0;\r\n const branches = [];\r\n data.forEach(function(release) {\r\n const namecomponents = release.name.split('#');\r\n const branch = namecomponents[3];\r\n if (!branches.includes(branch)) {\r\n branches.push(branch);\r\n }\r\n });\r\n let fwb='';\r\n branches.forEach(function(branch) {\r\n fwb += '';\r\n });\r\n $('#fwbranch').append(fwb);\r\n\r\n data.forEach(function(release) {\r\n let url = '';\r\n release.assets.forEach(function(asset) {\r\n if (asset.name.match(/\\.bin$/)) {\r\n url = asset.browser_download_url;\r\n }\r\n });\r\n const namecomponents = release.name.split('#');\r\n const ver = namecomponents[0];\r\n const cfg = namecomponents[2];\r\n const branch = namecomponents[3];\r\n var bits = ver.substr(ver.lastIndexOf('-')+1);\r\n bits = (bits =='32' || bits == '16')?bits:'';\r\n\r\n let body = release.body;\r\n body = body.replace(/'/gi, '\"');\r\n body = body.replace(\r\n /[\\s\\S]+(### Revision Log[\\s\\S]+)### ESP-IDF Version Used[\\s\\S]+/,\r\n '$1'\r\n );\r\n body = body.replace(/- \\(.+?\\) /g, '- ');\r\n $('#rTable').append(`