From 73ba1e49fad1f99aa4a7fde4fdfae8a4136eea01 Mon Sep 17 00:00:00 2001 From: Jeremy Poulter Date: Sat, 24 Jul 2021 21:29:17 +0100 Subject: [PATCH 1/2] Changed to use ETag/If-None-Match for caching The date format for the Last-Modified header was wrong and was a bit brute force. Using ETag allows proper caching of the each individual file, even over firmware updates. Also added the Cache-Control header, to force the browser to check with the WiFi module if the file hase changed before using a cached version. --- scripts/extra_script.py | 13 +++--- src/web_server_static.cpp | 12 ++--- src/web_static/web_server.assets.js.h | 1 + src/web_static/web_server.emoncms.jpg.h | 1 + src/web_static/web_server.favicon-152.png.h | 1 + src/web_static/web_server.favicon-167.png.h | 1 + src/web_static/web_server.favicon-16x16.png.h | 1 + src/web_static/web_server.favicon-180.png.h | 1 + src/web_static/web_server.favicon-32x32.png.h | 1 + src/web_static/web_server.home.html.h | 1 + src/web_static/web_server.home.js.h | 1 + src/web_static/web_server.lib.js.h | 1 + src/web_static/web_server.ohm.jpg.h | 1 + src/web_static/web_server.style.css.h | 1 + src/web_static/web_server.term.html.h | 1 + src/web_static/web_server.term.js.h | 1 + src/web_static/web_server.wifi_portal.html.h | 1 + src/web_static/web_server.wifi_portal.js.h | 1 + src/web_static/web_server.wifi_signal_1.svg.h | 1 + src/web_static/web_server.wifi_signal_2.svg.h | 1 + src/web_static/web_server.wifi_signal_3.svg.h | 1 + src/web_static/web_server.wifi_signal_4.svg.h | 1 + src/web_static/web_server.wifi_signal_5.svg.h | 1 + src/web_static/web_server.zones.json.h | 1 + src/web_static/web_server_static_files.h | 44 +++++++++---------- test/basic.http | 4 +- 26 files changed, 59 insertions(+), 36 deletions(-) diff --git a/scripts/extra_script.py b/scripts/extra_script.py index 77a85cd2..8b1a2da4 100644 --- a/scripts/extra_script.py +++ b/scripts/extra_script.py @@ -1,11 +1,7 @@ from os.path import join, isfile, isdir, basename from os import listdir, system -import json from pprint import pprint -import re -import requests -import subprocess -import sys +import hashlib Import("env") @@ -29,6 +25,7 @@ def text_to_header(source_file): for line in original.splitlines(): output += u"\n \"{}\\n\"".format(line.replace('\\', '\\\\').replace('"', '\\"')) output += ";\n" + output += "static const char CONTENT_{}_ETAG[] PROGMEM = \"{}\";\n".format(filename, hashlib.sha256(original.encode('utf-8')).hexdigest()) return output def binary_to_header(source_file): @@ -36,10 +33,13 @@ def binary_to_header(source_file): output = "static const char CONTENT_"+filename+"[] PROGMEM = {\n " count = 0 + etag = hashlib.sha256() + with open(source_file, "rb") as source_fh: byte = source_fh.read(1) while byte != b"": output += "0x{:02x}, ".format(ord(byte)) + etag.update(byte) count += 1 if 16 == count: output += "\n " @@ -48,6 +48,7 @@ def binary_to_header(source_file): byte = source_fh.read(1) output += "0x00 };\n" + output += "static const char CONTENT_{}_ETAG[] PROGMEM = \"{}\";\n".format(filename, etag.hexdigest()) return output def data_to_header(env, target, source): @@ -100,7 +101,7 @@ def make_static(env, target, source): filetype = "JSON" c_name = get_c_name(out_file) - output += " { \"/"+out_file+"\", CONTENT_"+c_name+", sizeof(CONTENT_"+c_name+") - 1, _CONTENT_TYPE_"+filetype+" },\n" + output += " { \"/"+out_file+"\", CONTENT_"+c_name+", sizeof(CONTENT_"+c_name+") - 1, _CONTENT_TYPE_"+filetype+", CONTENT_"+c_name+"_ETAG },\n" output += "};\n" diff --git a/src/web_server_static.cpp b/src/web_server_static.cpp index e7549534..06695a66 100644 --- a/src/web_server_static.cpp +++ b/src/web_server_static.cpp @@ -19,6 +19,7 @@ struct StaticFile const char *data; size_t length; const char *type; + const char *etag; }; #include "web_static/web_server_static_files.h" @@ -34,9 +35,6 @@ static const char _HOME_PAGE[] PROGMEM = "/home.html"; static const char _WIFI_PAGE[] PROGMEM = "/wifi_portal.html"; #define WIFI_PAGE FPSTR(_WIFI_PAGE) -static const char _BUILD_TIME[] PROGMEM = __DATE__ " " __TIME__ " GMT"; -#define BUILD_TIME FPSTR(_BUILD_TIME) - class StaticFileResponse: public MongooseHttpServerResponse { private: @@ -87,8 +85,10 @@ bool web_static_handle(MongooseHttpServerRequest *request) { MongooseHttpServerResponseBasic *response = request->beginResponse(); - MongooseString ifModified = request->headers("If-Modified-Since"); - if(ifModified.equals(BUILD_TIME)) { + response->addHeader(F("Cache-Control"), F("public, max-age=30, must-revalidate")); + + MongooseString ifNoneMatch = request->headers("If-None-Match"); + if(ifNoneMatch.equals(file->etag)) { request->send(304); return true; } @@ -101,7 +101,7 @@ bool web_static_handle(MongooseHttpServerRequest *request) response->addHeader(F("Access-Control-Allow-Origin"), F("*")); } - response->addHeader("Last-Modified", BUILD_TIME); + response->addHeader("Etag", file->etag); response->setContent((const uint8_t *)file->data, file->length); request->send(response); diff --git a/src/web_static/web_server.assets.js.h b/src/web_static/web_server.assets.js.h index 11abecfc..0d84edb4 100644 --- a/src/web_static/web_server.assets.js.h +++ b/src/web_static/web_server.assets.js.h @@ -1,2 +1,3 @@ static const char CONTENT_ASSETS_JS[] PROGMEM = "!function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,\"a\",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p=\"\",o(o.s=0)}([function(e,t,r){\"use strict\";r.r(t);r(1)},function(e,t,r){}]);\n"; +static const char CONTENT_ASSETS_JS_ETAG[] PROGMEM = "837f049a68283a7e286faa6915b5c7d8cf49e0fc90152592dd1d0c81b5a3a6bf"; diff --git a/src/web_static/web_server.emoncms.jpg.h b/src/web_static/web_server.emoncms.jpg.h index e1dbc02f..efb33d8b 100644 --- a/src/web_static/web_server.emoncms.jpg.h +++ b/src/web_static/web_server.emoncms.jpg.h @@ -157,3 +157,4 @@ static const char CONTENT_EMONCMS_JPG[] PROGMEM = { 0x04, 0x78, 0x86, 0x20, 0x2d, 0x23, 0x9e, 0xf5, 0x0f, 0x9d, 0xa3, 0x86, 0x4e, 0x31, 0x72, 0x61, 0x3f, 0xcb, 0x08, 0x7b, 0x92, 0x59, 0x79, 0xe7, 0xc8, 0x53, 0x36, 0x77, 0x0a, 0x33, 0x1a, 0xe0, 0x75, 0x7a, 0xac, 0xab, 0xe5, 0x7f, 0x43, 0x5f, 0x9f, 0xff, 0xd9, 0x00 }; +static const char CONTENT_EMONCMS_JPG_ETAG[] PROGMEM = "2d8b327212b657791147a1a0b4f047ea068e97850272d10ce982adcd705d6805"; diff --git a/src/web_static/web_server.favicon-152.png.h b/src/web_static/web_server.favicon-152.png.h index c919694b..a1e1e941 100644 --- a/src/web_static/web_server.favicon-152.png.h +++ b/src/web_static/web_server.favicon-152.png.h @@ -149,3 +149,4 @@ static const char CONTENT_FAVICON_152_PNG[] PROGMEM = { 0x54, 0x98, 0x0a, 0x53, 0x61, 0x2a, 0x4c, 0x85, 0xa9, 0x30, 0x15, 0xa6, 0xc2, 0x54, 0x18, 0x36, 0xfe, 0x03, 0x41, 0xf7, 0xc7, 0x3c, 0xd0, 0xda, 0x1a, 0x12, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00 }; +static const char CONTENT_FAVICON_152_PNG_ETAG[] PROGMEM = "6bb51a4549bd1a410f20cccd544771491b350d22f4d1ddf4ddc726c26faaf3ef"; diff --git a/src/web_static/web_server.favicon-167.png.h b/src/web_static/web_server.favicon-167.png.h index 493936c6..a4fa7285 100644 --- a/src/web_static/web_server.favicon-167.png.h +++ b/src/web_static/web_server.favicon-167.png.h @@ -163,3 +163,4 @@ static const char CONTENT_FAVICON_167_PNG[] PROGMEM = { 0xa6, 0xd3, 0x74, 0x9a, 0x4e, 0xd3, 0x69, 0x3a, 0x4d, 0xa7, 0xe9, 0x34, 0x9d, 0xa6, 0xd3, 0x74, 0x9a, 0xce, 0xbe, 0x8e, 0xff, 0x00, 0xb7, 0x45, 0xa5, 0xa6, 0x7f, 0x7f, 0xa7, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00 }; +static const char CONTENT_FAVICON_167_PNG_ETAG[] PROGMEM = "c04aabe76eafbcfc4f9c90b5036359aace07ae2e07f1712311e19c0a87868978"; diff --git a/src/web_static/web_server.favicon-16x16.png.h b/src/web_static/web_server.favicon-16x16.png.h index 9d7b4f0f..55ba7fac 100644 --- a/src/web_static/web_server.favicon-16x16.png.h +++ b/src/web_static/web_server.favicon-16x16.png.h @@ -42,3 +42,4 @@ static const char CONTENT_FAVICON_16X16_PNG[] PROGMEM = { 0x94, 0x1b, 0xf4, 0xf5, 0xf9, 0xf7, 0xc6, 0xfb, 0xb0, 0x00, 0x34, 0x06, 0x06, 0x1a, 0x7e, 0xc7, 0xc4, 0x51, 0xbf, 0xf3, 0x2f, 0xa4, 0x85, 0xfd, 0x2b, 0x20, 0x03, 0xac, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00 }; +static const char CONTENT_FAVICON_16X16_PNG_ETAG[] PROGMEM = "c282688b944a78e5ccf6a176f3f4b3cfa85fc157cf7eb215d73543b037416cdc"; diff --git a/src/web_static/web_server.favicon-180.png.h b/src/web_static/web_server.favicon-180.png.h index fda80c9e..e60d5c5c 100644 --- a/src/web_static/web_server.favicon-180.png.h +++ b/src/web_static/web_server.favicon-180.png.h @@ -172,3 +172,4 @@ static const char CONTENT_FAVICON_180_PNG[] PROGMEM = { 0xd1, 0x26, 0xda, 0x44, 0x9b, 0x68, 0x13, 0x6d, 0xa2, 0x4d, 0xb4, 0x89, 0x36, 0xd1, 0x26, 0xda, 0x44, 0x3f, 0xd7, 0xe8, 0xff, 0x01, 0xfb, 0x6b, 0x1c, 0x61, 0xb6, 0x3a, 0x07, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00 }; +static const char CONTENT_FAVICON_180_PNG_ETAG[] PROGMEM = "5f88008c6f89bd97a14d56abb3e78c0cf368216a8715b155d6720535159f54fa"; diff --git a/src/web_static/web_server.favicon-32x32.png.h b/src/web_static/web_server.favicon-32x32.png.h index ea7ee7c2..2ab44926 100644 --- a/src/web_static/web_server.favicon-32x32.png.h +++ b/src/web_static/web_server.favicon-32x32.png.h @@ -77,3 +77,4 @@ static const char CONTENT_FAVICON_32X32_PNG[] PROGMEM = { 0x94, 0x28, 0x9a, 0xe3, 0xb9, 0x90, 0x59, 0xfb, 0xff, 0xe3, 0xf4, 0x61, 0x0b, 0xf8, 0x1b, 0x89, 0xbc, 0xd3, 0x48, 0xe7, 0x1c, 0x1e, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00 }; +static const char CONTENT_FAVICON_32X32_PNG_ETAG[] PROGMEM = "b95eba8ce98b49dd982be70a4aaf033cbce086e033b34d2f20f14bfcff25d631"; diff --git a/src/web_static/web_server.home.html.h b/src/web_static/web_server.home.html.h index c688c213..57df8038 100644 --- a/src/web_static/web_server.home.html.h +++ b/src/web_static/web_server.home.html.h @@ -72,3 +72,4 @@ static const char CONTENT_HOME_HTML[] PROGMEM = " click: vehicle.tesla.logout,\n" " text: (vehicle.tesla.fetching() ? 'Saving' : (vehicle.tesla.success() ? 'Saved' : 'Logout')),\n" " disable: vehicle.tesla.fetching\"> Logout

Error

Status

Status
Battery Level:
Battery Range:
Time to full charge:

Powered by OpenEVSE and OpenEnergyMonitor
Version: V
\n"; +static const char CONTENT_HOME_HTML_ETAG[] PROGMEM = "52442d017b1cfee59d37552f6500f2ea46ab14ba78e011cbbfeaaa02632a8037"; diff --git a/src/web_static/web_server.home.js.h b/src/web_static/web_server.home.js.h index 9e126c4c..1bba91b4 100644 --- a/src/web_static/web_server.home.js.h +++ b/src/web_static/web_server.home.js.h @@ -1,3 +1,4 @@ static const char CONTENT_HOME_JS[] PROGMEM = "\"use strict\";function _createForOfIteratorHelper(e,t){var n=\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(!n){if(Array.isArray(e)||(n=_unsupportedIterableToArray(e))||t&&e&&\"number\"==typeof e.length){n&&(e=n);var o=0,t=function(){};return{s:t,n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:t}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}var a,r=!0,i=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){i=!0,a=e},f:function(){try{r||null==n.return||n.return()}finally{if(i)throw a}}}}function _unsupportedIterableToArray(e,t){if(e){if(\"string\"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return\"Map\"===(n=\"Object\"===n&&e.constructor?e.constructor.name:n)||\"Set\"===n?Array.from(e):\"Arguments\"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n\"+e.ret),t.cmd(e.cmd)},\"json\").always(function(){t.rapiSend(!1)})}}function TimeViewModel(t){var o=this;function a(e){return(e<10?\"0\":\"\")+e}o.evseTimedate=ko.observable(new Date),o.localTimedate=ko.observable(new Date),o.nowTimedate=ko.observable(null),o.hasRTC=ko.observable(!0),o.elapsedNow=ko.observable(new Date(0)),o.elapsedLocal=ko.observable(new Date),o.divertUpdateNow=ko.observable(new Date(0)),o.divertUpdateLocal=ko.observable(new Date),o.vehicleUpdateNow=ko.observable(new Date(0)),o.vehicleUpdateLocal=ko.observable(new Date),o.date=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"\";var e=o.nowTimedate();return e.getFullYear()+\"-\"+a(e.getMonth()+1)+\"-\"+a(e.getDate())},write:function(e){var t=o.evseTimedate();e+=\" \"+a(t.getHours())+\":\"+a(t.getMinutes())+\":\"+a(t.getSeconds()),o.evseTimedate(new Date(e)),o.localTimedate(new Date)}}),o.time=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"--:--:--\";var e=o.nowTimedate();return a(e.getHours())+\":\"+a(e.getMinutes())+\":\"+a(e.getSeconds())},write:function(e){var t=e.split(\":\"),e=o.evseTimedate();e.setHours(parseInt(t[0])),e.setMinutes(parseInt(t[1])),o.evseTimedate(e),o.localTimedate(new Date)}}),o.elapsed=ko.pureComputed(function(){if(null===o.nowTimedate())return\"0:00:00\";var e=o.elapsedNow().getTime(),t=(e=Math.floor(e/1e3))%60,n=(e=Math.floor(e/60))%60;return Math.floor(e/60)+\":\"+a(n)+\":\"+a(t)}),t.status.elapsed.subscribe(function(e){o.elapsedNow(new Date(1e3*e)),o.elapsedLocal(new Date)}),o.divert_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.divertUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.divert_update.subscribe(function(e){o.divertUpdateNow(new Date(1e3*e)),o.divertUpdateLocal(new Date)}),o.vehicle_state_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.vehicleUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.vehicle_state_update.subscribe(function(e){o.vehicleUpdateNow(new Date(1e3*e)),o.vehicleUpdateLocal(new Date)});var n=null;o.automaticTime=ko.observable(!0),o.timeUpdate=function(e){o.hasRTC(!(1=e){o.timeLimit(n.value);break}}},o.selectChargeLimit=function(e){if(o.chargeLimit()!==e)for(var t=0;t=e){o.chargeLimit(n.value);break}}};var r=[function(){return!1===o.status.time()?o.openevse.time(o.time.timeUpdate):new DummyRequest},function(){return o.openevse.service_level(function(e,t){o.serviceLevel(e),o.actualServiceLevel(t)})},function(){return o.updateCurrentCapacity()},function(){return o.openevse.current_capacity(function(e){o.currentCapacity(e)})},function(){return o.openevse.time_limit(function(e){o.selectTimeLimit(e)})},function(){return o.openevse.charge_limit(function(e){o.selectChargeLimit(e)})},function(){return o.openevse.gfi_self_test(function(e){o.gfiSelfTestEnabled(e)})},function(){return o.openevse.ground_check(function(e){o.groundCheckEnabled(e)})},function(){return o.openevse.stuck_relay_check(function(e){o.stuckRelayEnabled(e)})},function(){return o.openevse.temp_check(function(e){o.tempCheckEnabled(e)})},function(){return o.openevse.diode_check(function(e){o.diodeCheckEnabled(e)})},function(){return o.openevse.vent_required(function(e){o.ventRequiredEnabled(e)})},function(){return o.openevse.temp_check(function(){o.tempCheckSupported(!0)},o.tempCheckEnabled()).error(function(){o.tempCheckSupported(!1)})},function(){return o.openevse.timer(function(e,t,n){o.delayTimerEnabled(e),o.delayTimerStart(t),o.delayTimerStop(n)})}];o.updateCount=ko.observable(0),o.updateTotal=ko.observable(r.length),o.updateCurrentCapacity=function(){return o.openevse.current_capacity_range(function(e,t){o.minCurrentLevel(e),o.maxCurrentLevel(t);t=o.currentCapacity();o.currentLevels.removeAll();for(var n=o.minCurrentLevel();n<=o.maxCurrentLevel();n++)o.currentLevels.push({name:n+\" A\",value:n});o.currentCapacity(t)})},o.updatingServiceLevel=ko.observable(!1),o.savedServiceLevel=ko.observable(!1),o.updatingCurrentCapacity=ko.observable(!1),o.savedCurrentCapacity=ko.observable(!1),o.updatingTimeLimit=ko.observable(!1),o.savedTimeLimit=ko.observable(!1),o.updatingChargeLimit=ko.observable(!1),o.savedChargeLimit=ko.observable(!1),o.updatingDelayTimer=ko.observable(!1),o.savedDelayTimer=ko.observable(!1),o.updatingStatus=ko.observable(!1),o.savedStatus=ko.observable(!1),o.updatingGfiSelfTestEnabled=ko.observable(!1),o.savedGfiSelfTestEnabled=ko.observable(!1),o.updatingGroundCheckEnabled=ko.observable(!1),o.savedGroundCheckEnabled=ko.observable(!1),o.updatingStuckRelayEnabled=ko.observable(!1),o.savedStuckRelayEnabled=ko.observable(!1),o.updatingTempCheckEnabled=ko.observable(!1),o.savedTempCheckEnabled=ko.observable(!1),o.updatingDiodeCheckEnabled=ko.observable(!1),o.savedDiodeCheckEnabled=ko.observable(!1),o.updatingVentRequiredEnabled=ko.observable(!1),o.savedVentRequiredEnabled=ko.observable(!1);var i=!(o.setForTime=function(e,t){e(!0),setTimeout(function(){e(!1)},t)});function s(e){return/([01]\\d|2[0-3]):([0-5]\\d)/.test(e)}o.subscribe=function(){i||(o.serviceLevel.subscribe(function(e){o.updatingServiceLevel(!0),o.openevse.service_level(function(e,t){o.setForTime(o.savedServiceLevel,2e3),o.actualServiceLevel(t),o.updateCurrentCapacity().always(function(){})},e).always(function(){o.updatingServiceLevel(!1)})}),o.currentCapacity.subscribe(function(t){!0!==o.updatingServiceLevel()&&(o.updatingCurrentCapacity(!0),o.openevse.current_capacity(function(e){o.setForTime(o.savedCurrentCapacity,2e3),t!==e&&o.currentCapacity(e)},t).always(function(){o.updatingCurrentCapacity(!1)}))}),o.timeLimit.subscribe(function(t){o.updatingTimeLimit(!0),o.openevse.time_limit(function(e){o.setForTime(o.savedTimeLimit,2e3),t!==e&&o.selectTimeLimit(e)},t).always(function(){o.updatingTimeLimit(!1)})}),o.chargeLimit.subscribe(function(t){o.updatingChargeLimit(!0),o.openevse.charge_limit(function(e){o.setForTime(o.savedChargeLimit,2e3),t!==e&&o.selectChargeLimit(e)},t).always(function(){o.updatingChargeLimit(!1)})}),o.gfiSelfTestEnabled.subscribe(function(t){o.updatingGfiSelfTestEnabled(!0),o.openevse.gfi_self_test(function(e){o.setForTime(o.savedGfiSelfTestEnabled,2e3),t!==e&&o.gfiSelfTestEnabled(e)},t).always(function(){o.updatingGfiSelfTestEnabled(!1)})}),o.groundCheckEnabled.subscribe(function(t){o.updatingGroundCheckEnabled(!0),o.openevse.ground_check(function(e){o.setForTime(o.savedGroundCheckEnabled,2e3),t!==e&&o.groundCheckEnabled(e)},t).always(function(){o.updatingGroundCheckEnabled(!1)})}),o.stuckRelayEnabled.subscribe(function(t){o.updatingStuckRelayEnabled(!0),o.savedStuckRelayEnabled(!1),o.openevse.stuck_relay_check(function(e){o.savedStuckRelayEnabled(!0),setTimeout(function(){o.savedStuckRelayEnabled(!1)},2e3),t!==e&&o.stuckRelayEnabled(e)},t).always(function(){o.updatingStuckRelayEnabled(!1)})}),o.tempCheckEnabled.subscribe(function(t){o.updatingTempCheckEnabled(!0),o.openevse.temp_check(function(e){o.setForTime(o.savedTempCheckEnabled,2e3),t!==e&&o.tempCheckEnabled(e)},t).always(function(){o.updatingTempCheckEnabled(!1)})}),o.diodeCheckEnabled.subscribe(function(t){o.updatingDiodeCheckEnabled(!0),o.openevse.diode_check(function(e){o.setForTime(o.savedDiodeCheckEnabled,2e3),t!==e&&o.diodeCheckEnabled(e)},t).always(function(){o.updatingDiodeCheckEnabled(!1)})}),o.ventRequiredEnabled.subscribe(function(t){o.updatingVentRequiredEnabled(!0),o.openevse.vent_required(function(e){o.setForTime(o.savedVentRequiredEnabled,2e3),t!==e&&o.ventRequiredEnabled(e)},t).always(function(){o.updatingVentRequiredEnabled(!1)})}),i=!0)},o.update=function(){var e=0>10|55296,1023&e|56320))}function r(){C()}var e,d,w,i,o,p,h,g,x,u,c,C,T,a,k,v,s,l,m,_=\"sizzle\"+ +new Date,b=n.document,E=0,y=0,S=ue(),N=ue(),A=ue(),D=ue(),O=function(e,t){return e===t&&(c=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,M=t.push,L=t.push,P=t.slice,R=function(e,t){for(var n=0,r=e.length;n+~]|\"+B+\")\"+B+\"*\"),z=new RegExp(B+\"|>\"),G=new RegExp($),X=new RegExp(\"^\"+H+\"$\"),Y={ID:new RegExp(\"^#(\"+H+\")\"),CLASS:new RegExp(\"^\\\\.(\"+H+\")\"),TAG:new RegExp(\"^(\"+H+\"|[*])\"),ATTR:new RegExp(\"^\"+F),PSEUDO:new RegExp(\"^\"+$),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+B+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+B+\"*(?:([+-]|)\"+B+\"*(\\\\d+)|))\"+B+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+I+\")$\",\"i\"),needsContext:new RegExp(\"^\"+B+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+B+\"*((?:-\\\\d)?\\\\d*)\"+B+\"*\\\\)|)(?=[^-]|$)\",\"i\")},K=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,Z=/^h\\d$/i,ee=/^[^{]+\\{\\s*\\[native \\w/,te=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ne=/[+~]/,re=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+B+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),oe=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,ie=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},ae=be(function(e){return!0===e.disabled&&\"fieldset\"===e.nodeName.toLowerCase()},{dir:\"parentNode\",next:\"legend\"});try{L.apply(t=P.call(b.childNodes),b.childNodes),t[b.childNodes.length].nodeType}catch(e){L={apply:t.length?function(e,t){M.apply(e,P.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(t,e,n,r){var o,i,a,s,u,c,l=e&&e.ownerDocument,f=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==f&&9!==f&&11!==f)return n;if(!r&&(C(e),e=e||T,k)){if(11!==f&&(s=te.exec(t)))if(c=s[1]){if(9===f){if(!(i=e.getElementById(c)))return n;if(i.id===c)return n.push(i),n}else if(l&&(i=l.getElementById(c))&&m(e,i)&&i.id===c)return n.push(i),n}else{if(s[2])return L.apply(n,e.getElementsByTagName(t)),n;if((c=s[3])&&d.getElementsByClassName&&e.getElementsByClassName)return L.apply(n,e.getElementsByClassName(c)),n}if(d.qsa&&!D[t+\" \"]&&(!v||!v.test(t))&&(1!==f||\"object\"!==e.nodeName.toLowerCase())){if(c=t,l=e,1===f&&(z.test(t)||J.test(t))){for((l=ne.test(t)&&ge(e.parentNode)||e)===e&&d.scope||((a=e.getAttribute(\"id\"))?a=a.replace(oe,ie):e.setAttribute(\"id\",a=_)),o=(u=p(t)).length;o--;)u[o]=(a?\"#\"+a:\":scope\")+\" \"+me(u[o]);c=u.join(\",\")}try{return L.apply(n,l.querySelectorAll(c)),n}catch(e){D(t,!0)}finally{a===_&&e.removeAttribute(\"id\")}}}return g(t.replace(V,\"$1\"),e,n,r)}function ue(){var n=[];function r(e,t){return n.push(e+\" \")>w.cacheLength&&delete r[n.shift()],r[e+\" \"]=t}return r}function ce(e){return e[_]=!0,e}function le(e){var t=T.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t)}}function fe(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)w.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function he(a){return ce(function(i){return i=+i,ce(function(e,t){for(var n,r=a([],e.length,i),o=r.length;o--;)e[n=r[o]]&&(e[n]=!(t[n]=e[n]))})})}function ge(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=se.support={},o=se.isXML=function(e){var t=e&&e.namespaceURI,e=e&&(e.ownerDocument||e).documentElement;return!K.test(t||e&&e.nodeName||\"HTML\")},C=se.setDocument=function(e){var t,e=e?e.ownerDocument||e:b;return e!=T&&9===e.nodeType&&e.documentElement&&(a=(T=e).documentElement,k=!o(T),b!=T&&(t=T.defaultView)&&t.top!==t&&(t.addEventListener?t.addEventListener(\"unload\",r,!1):t.attachEvent&&t.attachEvent(\"onunload\",r)),d.scope=le(function(e){return a.appendChild(e).appendChild(T.createElement(\"div\")),void 0!==e.querySelectorAll&&!e.querySelectorAll(\":scope fieldset div\").length}),d.attributes=le(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),d.getElementsByTagName=le(function(e){return e.appendChild(T.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),d.getElementsByClassName=ee.test(T.getElementsByClassName),d.getById=le(function(e){return a.appendChild(e).id=_,!T.getElementsByName||!T.getElementsByName(_).length}),d.getById?(w.filter.ID=function(e){var t=e.replace(re,f);return function(e){return e.getAttribute(\"id\")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&k){e=t.getElementById(e);return e?[e]:[]}}):(w.filter.ID=function(e){var t=e.replace(re,f);return function(e){e=void 0!==e.getAttributeNode&&e.getAttributeNode(\"id\");return e&&e.value===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&k){var n,r,o,i=t.getElementById(e);if(i){if((n=i.getAttributeNode(\"id\"))&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if((n=i.getAttributeNode(\"id\"))&&n.value===e)return[i]}return[]}}),w.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"!==e)return i;for(;n=i[o++];)1===n.nodeType&&r.push(n);return r},w.find.CLASS=d.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&k)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=ee.test(T.querySelectorAll))&&(le(function(e){var t;a.appendChild(e).innerHTML=\"\",e.querySelectorAll(\"[msallowcapture^='']\").length&&v.push(\"[*^$]=\"+B+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||v.push(\"\\\\[\"+B+\"*(?:value|\"+I+\")\"),e.querySelectorAll(\"[id~=\"+_+\"-]\").length||v.push(\"~=\"),(t=T.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||v.push(\"\\\\[\"+B+\"*name\"+B+\"*=\"+B+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\":checked\").length||v.push(\":checked\"),e.querySelectorAll(\"a#\"+_+\"+*\").length||v.push(\".#.+[+~]\"),e.querySelectorAll(\"\\\\\\f\"),v.push(\"[\\\\r\\\\n\\\\f]\")}),le(function(e){e.innerHTML=\"\";var t=T.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&v.push(\"name\"+B+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&v.push(\":enabled\",\":disabled\"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&v.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),v.push(\",.*:\")})),(d.matchesSelector=ee.test(l=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&le(function(e){d.disconnectedMatch=l.call(e,\"*\"),l.call(e,\"[s!='']:x\"),s.push(\"!=\",$)}),v=v.length&&new RegExp(v.join(\"|\")),s=s.length&&new RegExp(s.join(\"|\")),t=ee.test(a.compareDocumentPosition),m=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,t=t&&t.parentNode;return e===t||!(!t||1!==t.nodeType||!(n.contains?n.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},O=t?function(e,t){if(e===t)return c=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==b&&m(b,e)?-1:t==T||t.ownerDocument==b&&m(b,t)?1:u?R(u,e)-R(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],s=[t];if(!o||!i)return e==T?-1:t==T?1:o?-1:i?1:u?R(u,e)-R(u,t):0;if(o===i)return de(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?de(a[r],s[r]):a[r]==b?-1:s[r]==b?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),d.matchesSelector&&k&&!D[t+\" \"]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=l.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){D(t,!0)}return 0\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(re,f),e[3]=(e[3]||e[4]||e[5]||\"\").replace(re,f),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&G.test(n)&&(t=p(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(re,f).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=S[e+\" \"];return t||(t=new RegExp(\"(^|\"+B+\")\"+e+\"(\"+B+\"|$)\"))&&S(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(t,n,r){return function(e){e=se.attr(e,t);return null==e?\"!=\"===n:!n||(e+=\"\",\"=\"===n?e===r:\"!=\"===n?e!==r:\"^=\"===n?r&&0===e.indexOf(r):\"*=\"===n?r&&-1\",\"#\"===e.firstChild.getAttribute(\"href\")})||fe(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),d.attributes&&le(function(e){return e.innerHTML=\"\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||fe(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),le(function(e){return null==e.getAttribute(\"disabled\")})||fe(I,function(e,t,n){if(!n)return!0===e[t]?t.toLowerCase():(t=e.getAttributeNode(t))&&t.specified?t.value:null}),se}(C);k.find=p,k.expr=p.selectors,k.expr[\":\"]=k.expr.pseudos,k.uniqueSort=k.unique=p.uniqueSort,k.text=p.getText,k.isXMLDoc=p.isXML,k.contains=p.contains,k.escapeSelector=p.escape;function x(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&k(e).is(n))break;r.push(e)}return r}function _(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var E=k.expr.match.needsContext;function S(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function A(e,n,r){return y(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\\w-]+))$/;(k.fn.init=function(e,t,n){if(!e)return this;if(n=n||O,\"string\"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):y(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:D.exec(e))||!r[1]&&t)return(!t||t.jquery?t||n:this.constructor(t)).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:T,!0)),N.test(r[1])&&k.isPlainObject(t))for(var r in t)y(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(e=T.getElementById(r[2]))&&(this[0]=e,this.length=1),this}).prototype=k.fn;var O=k(T),j=/^(?:parents|prev(?:Until|All))/,q={children:!0,contents:!0,next:!0,prev:!0};function M(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\\x20\\t\\r\\n\\f]*)/i,de=/^$|^module$|\\/(?:java|ecma)script/i;f=T.createDocumentFragment().appendChild(T.createElement(\"div\")),(p=T.createElement(\"input\")).setAttribute(\"type\",\"radio\"),p.setAttribute(\"checked\",\"checked\"),p.setAttribute(\"name\",\"t\"),f.appendChild(p),b.checkClone=f.cloneNode(!0).cloneNode(!0).lastChild.checked,f.innerHTML=\"\",b.noCloneChecked=!!f.cloneNode(!0).lastChild.defaultValue,f.innerHTML=\"\",b.option=!!f.lastChild;var pe={thead:[1,\"\",\"
\"],col:[2,\"\",\"
\"],tr:[2,\"\",\"
\"],td:[3,\"\",\"
\"],_default:[0,\"\",\"\"]};function he(e,t){var n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):void 0!==e.querySelectorAll?e.querySelectorAll(t||\"*\"):[];return void 0===t||t&&S(e,t)?k.merge([e],n):n}function ge(e,t){for(var n=0,r=e.length;n\",\"\"]);var ve=/<|&#?\\w+;/;function me(e,t,n,r,o){for(var i,a,s,u,c,l=t.createDocumentFragment(),f=[],d=0,p=e.length;d\\s*$/g;function Se(e,t){return S(e,\"table\")&&S(11!==t.nodeType?t:t.firstChild,\"tr\")&&k(e).children(\"tbody\")[0]||e}function Ne(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function Ae(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function De(e,t){var n,r,o,i;if(1===t.nodeType){if(X.hasData(e)&&(i=X.get(e).events))for(o in X.remove(t,\"handle events\"),i)for(n=0,r=i[o].length;n\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",o=function(e){r.remove(),o=null,e&&t(\"error\"===e.type?404:200,e.type)}),T.head.appendChild(r[0])},abort:function(){o&&o()}}});var Gt=[],Xt=/(=)\\?(?=&|$)|\\?\\?/;k.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Gt.pop()||k.expando+\"_\"+St.guid++;return this[e]=!0,e}}),k.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,o,i,a=!1!==e.jsonp&&(Xt.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Xt.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=y(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Xt,\"$1\"+r):!1!==e.jsonp&&(e.url+=(Nt.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return i||k.error(r+\" was not called\"),i[0]},e.dataTypes[0]=\"json\",o=C[r],C[r]=function(){i=arguments},n.always(function(){void 0===o?k(C).removeProp(r):C[r]=o,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),i&&y(o)&&o(i[0]),i=o=void 0}),\"script\"}),b.createHTMLDocument=((f=T.implementation.createHTMLDocument(\"\").body).innerHTML=\"
\",2===f.childNodes.length),k.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(b.createHTMLDocument?((r=(t=T.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=T.location.href,t.head.appendChild(r)):t=T),r=!n&&[],(n=N.exec(e))?[t.createElement(n[1])]:(n=me([e],t,r),r&&r.length&&k(r).remove(),k.merge([],n.childNodes)));var r},k.fn.load=function(e,t,n){var r,o,i,a=this,s=e.indexOf(\" \");return-1\").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,o,i,a,s=k.css(e,\"position\"),u=k(e),c={};\"static\"===s&&(e.style.position=\"relative\"),i=u.offset(),r=k.css(e,\"top\"),a=k.css(e,\"left\"),a=(\"absolute\"===s||\"fixed\"===s)&&-1<(r+a).indexOf(\"auto\")?(o=(s=u.position()).top,s.left):(o=parseFloat(r)||0,parseFloat(a)||0),null!=(t=y(t)?t.call(e,n,k.extend({},i)):t).top&&(c.top=t.top-i.top+o),null!=t.left&&(c.left=t.left-i.left+a),\"using\"in t?t.using.call(e,c):u.css(c)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n=this[0];return n?n.getClientRects().length?(e=n.getBoundingClientRect(),n=n.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],o={top:0,left:0};if(\"fixed\"===k.css(r,\"position\"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&\"static\"===k.css(e,\"position\");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((o=k(e).offset()).top+=k.css(e,\"borderTopWidth\",!0),o.left+=k.css(e,\"borderLeftWidth\",!0))}return{top:t.top-o.top-k.css(r,\"marginTop\",!0),left:t.left-o.left-k.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===k.css(e,\"position\");)e=e.offsetParent;return e||re})}}),k.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,o){var i=\"pageYOffset\"===o;k.fn[t]=function(e){return $(this,function(e,t,n){var r;return g(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n?r?r[o]:e[t]:void(r?r.scrollTo(i?r.pageXOffset:n,i?n:r.pageYOffset):e[t]=n)},t,e,arguments.length)}}),k.each([\"top\",\"left\"],function(e,n){k.cssHooks[n]=Ge(b.pixelPosition,function(e,t){if(t)return t=ze(e,n),$e.test(t)?k(e).position()[n]+\"px\":t})}),k.each({Height:\"height\",Width:\"width\"},function(a,s){k.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,i){k.fn[i]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),o=r||(!0===e||!0===t?\"margin\":\"border\");return $(this,function(e,t,n){var r;return g(e)?0===i.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?k.css(e,t,o):k.style(e,t,n,o)},s,n?e:void 0,n)}})}),k.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){k.fn[n]=function(e,t){return 0(e=e||\"\").length)&&e.substring(0,t.length)===t},vd:function(e,t){if(e===t)return!0;if(11===e.nodeType)return!1;if(t.contains)return t.contains(1!==e.nodeType?e.parentNode:e);if(t.compareDocumentPosition)return 16==(16&t.compareDocumentPosition(e));for(;e&&e!=t;)e=e.parentNode;return!!e},Sb:function(e){return N.a.vd(e,e.ownerDocument.documentElement)},kd:function(e){return!!N.a.Lb(e,N.a.Sb)},R:function(e){return e&&e.tagName&&e.tagName.toLowerCase()},Ac:function(e){return N.onError?function(){try{return e.apply(this,arguments)}catch(e){throw N.onError&&N.onError(e),e}}:e},setTimeout:(c=function(e,t){return setTimeout(N.a.Ac(e),t)},h.toString=function(){return c.toString()},h),Gc:function(e){setTimeout(function(){throw N.onError&&N.onError(e),e},0)},B:function(t,e,n){var r=N.a.Ac(n);if(n=l[e],N.options.useOnlyNativeEvents||n||!Ne)if(n||\"function\"!=typeof t.addEventListener){if(void 0===t.attachEvent)throw Error(\"Browser doesn't support addEventListener or attachEvent\");var o=function(e){r.call(t,e)},i=\"on\"+e;t.attachEvent(i,o),N.a.K.za(t,function(){t.detachEvent(i,o)})}else t.addEventListener(e,r,!1);else u=u||(\"function\"==typeof Ne(t).on?\"on\":\"bind\"),Ne(t)[u](e,r)},Fb:function(e,t){if(!e||!e.nodeType)throw Error(\"element must be a DOM node when calling triggerEvent\");var n=!(\"input\"!==N.a.R(e)||!e.type||\"click\"!=t.toLowerCase())&&(\"checkbox\"==(n=e.type)||\"radio\"==n);if(N.options.useOnlyNativeEvents||!Ne||n)if(\"function\"==typeof Ee.createEvent){if(\"function\"!=typeof e.dispatchEvent)throw Error(\"The supplied element doesn't support dispatchEvent\");(n=Ee.createEvent(s[t]||\"HTMLEvents\")).initEvent(t,!0,!0,_e,0,0,0,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(n)}else if(n&&e.click)e.click();else{if(void 0===e.fireEvent)throw Error(\"Browser doesn't support triggering events\");e.fireEvent(\"on\"+t)}else Ne(e).trigger(t)},f:function(e){return N.O(e)?e():e},bc:function(e){return N.O(e)?e.v():e},Eb:function(t,e,n){var r;e&&(\"object\"===_typeof(t.classList)?(r=t.classList[n?\"add\":\"remove\"],N.a.D(e.match(p),function(e){r.call(t.classList,e)})):\"string\"==typeof t.className.baseVal?o(t.className,\"baseVal\",e,n):o(t,\"className\",e,n))},Bb:function(e,t){var n=N.a.f(t);null!==n&&n!==ke||(n=\"\");t=N.h.firstChild(e);!t||3!=t.nodeType||N.h.nextSibling(t)?N.h.va(e,[e.ownerDocument.createTextNode(n)]):t.data=n,N.a.Ad(e)},Yc:function(e,t){if(e.name=t,d<=7)try{var n=e.name.replace(/[&<>'\"]/g,function(e){return\"&#\"+e.charCodeAt(0)+\";\"});e.mergeAttributes(Ee.createElement(\"\"),!1)}catch(e){}},Ad:function(e){9<=d&&((e=1==e.nodeType?e:e.parentNode).style&&(e.style.zoom=e.style.zoom))},wd:function(e){var t;d&&(t=e.style.width,e.style.width=0,e.style.width=t)},Pd:function(e,t){e=N.a.f(e),t=N.a.f(t);for(var n=[],r=e;r<=t;r++)n.push(r);return n},la:function(e){for(var t=[],n=0,r=e.length;n\",\"\"],tbody:e,tfoot:e,tr:[2,\"\",\"
\"],td:e=[3,\"\",\"
\"],th:e,option:e=[1,\"\"],optgroup:e},f=N.a.W<=8,N.a.ua=function(e,t){var n;if(Ne){if(Ne.parseHTML)n=Ne.parseHTML(e,t)||[];else if((n=Ne.clean([e],t))&&n[0]){for(var r=n[0];r.parentNode&&11!==r.parentNode.nodeType;)r=r.parentNode;r.parentNode&&r.parentNode.removeChild(r)}}else{var r=(n=!(n=t)?Ee:n).parentWindow||n.defaultView||_e,o=N.a.Db(e).toLowerCase(),i=n.createElement(\"div\"),t=(o=o.match(/^(?:\\x3c!--.*?--\\x3e\\s*?)*?<([a-z]+)[\\s>]/))&&l[o[1]]||u,o=t[0];for(t=\"ignored
\"+t[1]+e+t[2]+\"
\",\"function\"==typeof r.innerShiv?i.appendChild(r.innerShiv(t)):(f&&n.body.appendChild(i),i.innerHTML=t,f&&i.parentNode.removeChild(i));o--;)i=i.lastChild;n=N.a.la(i.lastChild.childNodes)}return n},N.a.Md=function(e,t){t=N.a.ua(e,t);return t.length&&t[0].parentElement||N.a.Yb(t)},N.a.fc=function(e,t){if(N.a.Tb(e),null!==(t=N.a.f(t))&&t!==ke)if(\"string\"!=typeof t&&(t=t.toString()),Ne)Ne(e).html(t);else for(var n=N.a.ua(t,e.ownerDocument),r=0;r]*))?)*\\s+)data-bind\\s*=\\s*([\"'])([\\s\\S]*?)\\3/gi,be=/\\x3c!--\\s*ko\\b\\s*([\\s\\S]*?)\\s*--\\x3e/g,{xd:function(e,t,n){t.isTemplateRewritten(e,n)||t.rewriteTemplate(e,function(e){return N.kc.Ld(e,t)},n)},Ld:function(e,i){return e.replace(me,function(e,t,n,r,o){return Ce(o,t,n,i)}).replace(be,function(e,t){return Ce(t,\"\\x3c!-- ko --\\x3e\",\"#comment\",i)})},md:function(n,r){return N.aa.Xb(function(e,t){e=e.nextSibling;e&&e.nodeName.toLowerCase()===r&&N.ib(e,n,t)})}}),N.b(\"__tr_ambtns\",N.kc.md),function(){N.C={},N.C.F=function(e){var t;(this.F=e)&&(t=N.a.R(e),this.ab=\"script\"===t?1:\"textarea\"===t?2:\"template\"==t&&e.content&&11===e.content.nodeType?3:4)},N.C.F.prototype.text=function(){var e=1===this.ab?\"text\":2===this.ab?\"value\":\"innerHTML\";if(0==arguments.length)return this.F[e];var t=arguments[0];\"innerHTML\"==e?N.a.fc(this.F,t):this.F[e]=t};var t=N.a.g.Z()+\"_\";N.C.F.prototype.data=function(e){if(1===arguments.length)return N.a.g.get(this.F,t+e);N.a.g.set(this.F,t+e,arguments[1])};var o=N.a.g.Z();N.C.F.prototype.nodes=function(){var e=this.F;if(0==arguments.length){var t,n=N.a.g.get(e,o)||{},r=n.lb||(3===this.ab?e.content:4===this.ab?e:ke);return r&&!n.jd||(t=this.text())&&t!==n.bb&&(r=N.a.Md(t,e.ownerDocument),N.a.g.set(e,o,{lb:r,bb:t,jd:!0})),r}n=arguments[0],this.ab!==ke&&this.text(\"\"),N.a.g.set(e,o,{lb:n})},N.C.ia=function(e){this.F=e},N.C.ia.prototype=new N.C.F,N.C.ia.prototype.constructor=N.C.ia,N.C.ia.prototype.text=function(){if(0==arguments.length){var e=N.a.g.get(this.F,o)||{};return e.bb===ke&&e.lb&&(e.bb=e.lb.innerHTML),e.bb}N.a.g.set(this.F,o,{bb:arguments[0]})},N.b(\"templateSources\",N.C),N.b(\"templateSources.domElement\",N.C.F),N.b(\"templateSources.anonymousTemplate\",N.C.ia)}(),function(){function r(e,t,n){var r;for(t=N.h.nextSibling(t);e&&(r=e)!==t;)n(r,e=N.h.nextSibling(r))}function d(e,t){if(e.length){var o=e[0],i=e[e.length-1],n=o.parentNode,a=N.ga.instance,s=a.preprocessNode;if(s){if(r(o,i,function(e,t){var n=e.previousSibling,r=s.call(a,e);r&&(e===o&&(o=r[0]||t),e===i&&(i=r[r.length-1]||n))}),e.length=0,!o)return;o===i?e.push(o):(e.push(o,i),N.a.Ua(e,n))}r(o,i,function(e){1!==e.nodeType&&8!==e.nodeType||N.vc(t,e)}),r(o,i,function(e){1!==e.nodeType&&8!==e.nodeType||N.aa.cd(e,[t])}),N.a.Ua(e,n)}}function u(e){return e.nodeType?e:0\"+t+\"<\\/script>\")},0
  \n";
+static const char CONTENT_TERM_HTML_ETAG[] PROGMEM = "9bd77665eb816544b67953669f1b762d55d5675616a9462c8ad6ae2f04bd4cec";
diff --git a/src/web_static/web_server.term.js.h b/src/web_static/web_server.term.js.h
index 4dfe8e6a..437d6a95 100644
--- a/src/web_static/web_server.term.js.h
+++ b/src/web_static/web_server.term.js.h
@@ -1,3 +1,4 @@
 static const char CONTENT_TERM_JS[] PROGMEM = 
   "\"use strict\";function _typeof(e){return(_typeof=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e})(e)}!function(e,t){\"object\"===(\"undefined\"==typeof module?\"undefined\":_typeof(module))&&\"object\"===_typeof(module.exports)?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:void 0,function(T,e){function g(e){return null!=e&&e===e.window}var t=[],n=Object.getPrototypeOf,s=t.slice,m=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,o=t.indexOf,r={},i=r.toString,y=r.hasOwnProperty,a=y.toString,l=a.call(Object),v={},x=function(e){return\"function\"==typeof e&&\"number\"!=typeof e.nodeType&&\"function\"!=typeof e.item},C=T.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,o,i=(n=n||C).createElement(\"script\");if(i.text=e,t)for(r in c)(o=t[r]||t.getAttribute&&t.getAttribute(r))&&i.setAttribute(r,o);n.head.appendChild(i).parentNode.removeChild(i)}function h(e){return null==e?e+\"\":\"object\"===_typeof(e)||\"function\"==typeof e?r[i.call(e)]||\"object\":_typeof(e)}var f=\"3.6.0\",S=function e(t,n){return new e.fn.init(t,n)};function p(e){var t=!!e&&\"length\"in e&&e.length,n=h(e);return!x(e)&&!g(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&0>10|55296,1023&e|56320))}function r(){T()}var e,p,b,i,o,d,h,g,w,u,l,T,C,a,S,m,s,c,y,E=\"sizzle\"+ +new Date,v=n.document,k=0,x=0,A=ue(),N=ue(),j=ue(),D=ue(),q=function(e,t){return e===t&&(l=!0),0},L={}.hasOwnProperty,t=[],H=t.pop,O=t.push,P=t.push,R=t.slice,M=function(e,t){for(var n=0,r=e.length;n+~]|\"+W+\")\"+W+\"*\"),V=new RegExp(W+\"|>\"),G=new RegExp(F),Y=new RegExp(\"^\"+_+\"$\"),Q={ID:new RegExp(\"^#(\"+_+\")\"),CLASS:new RegExp(\"^\\\\.(\"+_+\")\"),TAG:new RegExp(\"^(\"+_+\"|[*])\"),ATTR:new RegExp(\"^\"+$),PSEUDO:new RegExp(\"^\"+F),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+W+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+W+\"*(?:([+-]|)\"+W+\"*(\\\\d+)|))\"+W+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+I+\")$\",\"i\"),needsContext:new RegExp(\"^\"+W+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+W+\"*((?:-\\\\d)?\\\\d*)\"+W+\"*\\\\)|)(?=[^-]|$)\",\"i\")},J=/HTML$/i,K=/^(?:input|select|textarea|button)$/i,Z=/^h\\d$/i,ee=/^[^{]+\\{\\s*\\[native \\w/,te=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ne=/[+~]/,re=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+W+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),oe=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,ie=function(e,t){return t?\"\\0\"===e?\"�\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},ae=ve(function(e){return!0===e.disabled&&\"fieldset\"===e.nodeName.toLowerCase()},{dir:\"parentNode\",next:\"legend\"});try{P.apply(t=R.call(v.childNodes),v.childNodes),t[v.childNodes.length].nodeType}catch(e){P={apply:t.length?function(e,t){O.apply(e,R.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(t,e,n,r){var o,i,a,s,u,l,c=e&&e.ownerDocument,f=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==f&&9!==f&&11!==f)return n;if(!r&&(T(e),e=e||C,S)){if(11!==f&&(s=te.exec(t)))if(l=s[1]){if(9===f){if(!(i=e.getElementById(l)))return n;if(i.id===l)return n.push(i),n}else if(c&&(i=c.getElementById(l))&&y(e,i)&&i.id===l)return n.push(i),n}else{if(s[2])return P.apply(n,e.getElementsByTagName(t)),n;if((l=s[3])&&p.getElementsByClassName&&e.getElementsByClassName)return P.apply(n,e.getElementsByClassName(l)),n}if(p.qsa&&!D[t+\" \"]&&(!m||!m.test(t))&&(1!==f||\"object\"!==e.nodeName.toLowerCase())){if(l=t,c=e,1===f&&(V.test(t)||X.test(t))){for((c=ne.test(t)&&ge(e.parentNode)||e)===e&&p.scope||((a=e.getAttribute(\"id\"))?a=a.replace(oe,ie):e.setAttribute(\"id\",a=E)),o=(u=d(t)).length;o--;)u[o]=(a?\"#\"+a:\":scope\")+\" \"+ye(u[o]);l=u.join(\",\")}try{return P.apply(n,c.querySelectorAll(l)),n}catch(e){D(t,!0)}finally{a===E&&e.removeAttribute(\"id\")}}}return g(t.replace(z,\"$1\"),e,n,r)}function ue(){var n=[];function r(e,t){return n.push(e+\" \")>b.cacheLength&&delete r[n.shift()],r[e+\" \"]=t}return r}function le(e){return e[E]=!0,e}function ce(e){var t=C.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t)}}function fe(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function he(a){return le(function(i){return i=+i,le(function(e,t){for(var n,r=a([],e.length,i),o=r.length;o--;)e[n=r[o]]&&(e[n]=!(t[n]=e[n]))})})}function ge(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in p=se.support={},o=se.isXML=function(e){var t=e&&e.namespaceURI,e=e&&(e.ownerDocument||e).documentElement;return!J.test(t||e&&e.nodeName||\"HTML\")},T=se.setDocument=function(e){var t,e=e?e.ownerDocument||e:v;return e!=C&&9===e.nodeType&&e.documentElement&&(a=(C=e).documentElement,S=!o(C),v!=C&&(t=C.defaultView)&&t.top!==t&&(t.addEventListener?t.addEventListener(\"unload\",r,!1):t.attachEvent&&t.attachEvent(\"onunload\",r)),p.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement(\"div\")),void 0!==e.querySelectorAll&&!e.querySelectorAll(\":scope fieldset div\").length}),p.attributes=ce(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),p.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),p.getElementsByClassName=ee.test(C.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=E,!C.getElementsByName||!C.getElementsByName(E).length}),p.getById?(b.filter.ID=function(e){var t=e.replace(re,f);return function(e){return e.getAttribute(\"id\")===t}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&S){e=t.getElementById(e);return e?[e]:[]}}):(b.filter.ID=function(e){var t=e.replace(re,f);return function(e){e=void 0!==e.getAttributeNode&&e.getAttributeNode(\"id\");return e&&e.value===t}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&S){var n,r,o,i=t.getElementById(e);if(i){if((n=i.getAttributeNode(\"id\"))&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if((n=i.getAttributeNode(\"id\"))&&n.value===e)return[i]}return[]}}),b.find.TAG=p.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if(\"*\"!==e)return i;for(;n=i[o++];)1===n.nodeType&&r.push(n);return r},b.find.CLASS=p.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&S)return t.getElementsByClassName(e)},s=[],m=[],(p.qsa=ee.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=\"\",e.querySelectorAll(\"[msallowcapture^='']\").length&&m.push(\"[*^$]=\"+W+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||m.push(\"\\\\[\"+W+\"*(?:value|\"+I+\")\"),e.querySelectorAll(\"[id~=\"+E+\"-]\").length||m.push(\"~=\"),(t=C.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||m.push(\"\\\\[\"+W+\"*name\"+W+\"*=\"+W+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\":checked\").length||m.push(\":checked\"),e.querySelectorAll(\"a#\"+E+\"+*\").length||m.push(\".#.+[+~]\"),e.querySelectorAll(\"\\\\\\f\"),m.push(\"[\\\\r\\\\n\\\\f]\")}),ce(function(e){e.innerHTML=\"\";var t=C.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&m.push(\"name\"+W+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&m.push(\":enabled\",\":disabled\"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&m.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),m.push(\",.*:\")})),(p.matchesSelector=ee.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,\"*\"),c.call(e,\"[s!='']:x\"),s.push(\"!=\",F)}),m=m.length&&new RegExp(m.join(\"|\")),s=s.length&&new RegExp(s.join(\"|\")),t=ee.test(a.compareDocumentPosition),y=t||ee.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,t=t&&t.parentNode;return e===t||!(!t||1!==t.nodeType||!(n.contains?n.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},q=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==v&&y(v,e)?-1:t==C||t.ownerDocument==v&&y(v,t)?1:u?M(u,e)-M(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],s=[t];if(!o||!i)return e==C?-1:t==C?1:o?-1:i?1:u?M(u,e)-M(u,t):0;if(o===i)return pe(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?pe(a[r],s[r]):a[r]==v?-1:s[r]==v?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),p.matchesSelector&&S&&!D[t+\" \"]&&(!s||!s.test(t))&&(!m||!m.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){D(t,!0)}return 0\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(re,f),e[3]=(e[3]||e[4]||e[5]||\"\").replace(re,f),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&G.test(n)&&(t=d(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(re,f).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=A[e+\" \"];return t||(t=new RegExp(\"(^|\"+W+\")\"+e+\"(\"+W+\"|$)\"))&&A(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(t,n,r){return function(e){e=se.attr(e,t);return null==e?\"!=\"===n:!n||(e+=\"\",\"=\"===n?e===r:\"!=\"===n?e!==r:\"^=\"===n?r&&0===e.indexOf(r):\"*=\"===n?r&&-1\",\"#\"===e.firstChild.getAttribute(\"href\")})||fe(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),p.attributes&&ce(function(e){return e.innerHTML=\"\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||fe(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute(\"disabled\")})||fe(I,function(e,t,n){if(!n)return!0===e[t]?t.toLowerCase():(t=e.getAttributeNode(t))&&t.specified?t.value:null}),se}(T);S.find=d,S.expr=d.selectors,S.expr[\":\"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;function w(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&S(e).is(n))break;r.push(e)}return r}function E(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function j(e,n,r){return x(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\\w-]+))$/;(S.fn.init=function(e,t,n){if(!e)return this;if(n=n||q,\"string\"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):x(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this);if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:D.exec(e))||!r[1]&&t)return(!t||t.jquery?t||n:this.constructor(t)).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),N.test(r[1])&&S.isPlainObject(t))for(var r in t)x(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(e=C.getElementById(r[2]))&&(this[0]=e,this.length=1),this}).prototype=S.fn;var q=S(C),L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\\x20\\t\\r\\n\\f]*)/i,pe=/^$|^module$|\\/(?:java|ecma)script/i;f=C.createDocumentFragment().appendChild(C.createElement(\"div\")),(d=C.createElement(\"input\")).setAttribute(\"type\",\"radio\"),d.setAttribute(\"checked\",\"checked\"),d.setAttribute(\"name\",\"t\"),f.appendChild(d),v.checkClone=f.cloneNode(!0).cloneNode(!0).lastChild.checked,f.innerHTML=\"\",v.noCloneChecked=!!f.cloneNode(!0).lastChild.defaultValue,f.innerHTML=\"\",v.option=!!f.lastChild;var de={thead:[1,\"\",\"
\"],col:[2,\"\",\"
\"],tr:[2,\"\",\"
\"],td:[3,\"\",\"
\"],_default:[0,\"\",\"\"]};function he(e,t){var n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):void 0!==e.querySelectorAll?e.querySelectorAll(t||\"*\"):[];return void 0===t||t&&A(e,t)?S.merge([e],n):n}function ge(e,t){for(var n=0,r=e.length;n\",\"\"]);var me=/<|&#?\\w+;/;function ye(e,t,n,r,o){for(var i,a,s,u,l,c=t.createDocumentFragment(),f=[],p=0,d=e.length;p\\s*$/g;function Ae(e,t){return A(e,\"table\")&&A(11!==t.nodeType?t:t.firstChild,\"tr\")&&S(e).children(\"tbody\")[0]||e}function Ne(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function je(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function De(e,t){var n,r,o,i;if(1===t.nodeType){if(Y.hasData(e)&&(i=Y.get(e).events))for(o in Y.remove(t,\"handle events\"),i)for(n=0,r=i[o].length;n\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",o=function(e){r.remove(),o=null,e&&t(\"error\"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){o&&o()}}});var Gt=[],Yt=/(=)\\?(?=&|$)|\\?\\?/;S.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Gt.pop()||S.expando+\"_\"+At.guid++;return this[e]=!0,e}}),S.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,o,i,a=!1!==e.jsonp&&(Yt.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Yt.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=x(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,\"$1\"+r):!1!==e.jsonp&&(e.url+=(Nt.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return i||S.error(r+\" was not called\"),i[0]},e.dataTypes[0]=\"json\",o=T[r],T[r]=function(){i=arguments},n.always(function(){void 0===o?S(T).removeProp(r):T[r]=o,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),i&&x(o)&&o(i[0]),i=o=void 0}),\"script\"}),v.createHTMLDocument=((f=C.implementation.createHTMLDocument(\"\").body).innerHTML=\"
\",2===f.childNodes.length),S.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=C.location.href,t.head.appendChild(r)):t=C),r=!n&&[],(n=N.exec(e))?[t.createElement(n[1])]:(n=ye([e],t,r),r&&r.length&&S(r).remove(),S.merge([],n.childNodes)));var r},S.fn.load=function(e,t,n){var r,o,i,a=this,s=e.indexOf(\" \");return-1\").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,i||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,o,i,a,s=S.css(e,\"position\"),u=S(e),l={};\"static\"===s&&(e.style.position=\"relative\"),i=u.offset(),r=S.css(e,\"top\"),a=S.css(e,\"left\"),a=(\"absolute\"===s||\"fixed\"===s)&&-1<(r+a).indexOf(\"auto\")?(o=(s=u.position()).top,s.left):(o=parseFloat(r)||0,parseFloat(a)||0),null!=(t=x(t)?t.call(e,n,S.extend({},i)):t).top&&(l.top=t.top-i.top+o),null!=t.left&&(l.left=t.left-i.left+a),\"using\"in t?t.using.call(e,l):u.css(l)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n=this[0];return n?n.getClientRects().length?(e=n.getBoundingClientRect(),n=n.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],o={top:0,left:0};if(\"fixed\"===S.css(r,\"position\"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&\"static\"===S.css(e,\"position\");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((o=S(e).offset()).top+=S.css(e,\"borderTopWidth\",!0),o.left+=S.css(e,\"borderLeftWidth\",!0))}return{top:t.top-o.top-S.css(r,\"marginTop\",!0),left:t.left-o.left-S.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&\"static\"===S.css(e,\"position\");)e=e.offsetParent;return e||re})}}),S.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,o){var i=\"pageYOffset\"===o;S.fn[t]=function(e){return F(this,function(e,t,n){var r;return g(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n?r?r[o]:e[t]:void(r?r.scrollTo(i?r.pageXOffset:n,i?n:r.pageYOffset):e[t]=n)},t,e,arguments.length)}}),S.each([\"top\",\"left\"],function(e,n){S.cssHooks[n]=Ge(v.pixelPosition,function(e,t){if(t)return t=Ve(e,n),Fe.test(t)?S(e).position()[n]+\"px\":t})}),S.each({Height:\"height\",Width:\"width\"},function(a,s){S.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,i){S.fn[i]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),o=r||(!0===e||!0===t?\"margin\":\"border\");return F(this,function(e,t,n){var r;return g(e)?0===i.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?S.css(e,t,o):S.style(e,t,n,o)},s,n?e:void 0,n)}})}),S.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){S.fn[n]=function(e,t){return 0 OpenEVSE

OpenEVSE

WiFi

WiFi Setup

Mode:

Connect to network:

Scanning...

SSID:

Passkey:

Connecting to a local WiFi network is not essential. OpenEVSE can be configured and controlled while in standalone WiFi AP (Access Point) mode:

Note: remote logging features e.g Emoncms will not work while in AP standalone mode

Connecting to ...

Please connect this device to and navigate to the IP address displayed on your OpenEVSE display.

Alternatively you can use or


Powered by OpenEVSE and OpenEnergyMonitor
Version: V
\n"; +static const char CONTENT_WIFI_PORTAL_HTML_ETAG[] PROGMEM = "62a60bec5ed94bf95132896cfeeea4ab2bc89a5fd5731a1b85b4096e7c636f73"; diff --git a/src/web_static/web_server.wifi_portal.js.h b/src/web_static/web_server.wifi_portal.js.h index 558ecc31..d1094b4b 100644 --- a/src/web_static/web_server.wifi_portal.js.h +++ b/src/web_static/web_server.wifi_portal.js.h @@ -1,3 +1,4 @@ static const char CONTENT_WIFI_PORTAL_JS[] PROGMEM = "\"use strict\";function WiFiPortalViewModel(i,n){var e=this;e.baseHost=ko.observable(\"\"!==i?i:\"openevse.local\"),e.basePort=ko.observable(n),e.baseEndpoint=ko.pureComputed(function(){var i=\"//\"+e.baseHost();return 80!==e.basePort()&&(i+=\":\"+e.basePort()),i}),e.config=new ConfigViewModel(e.baseEndpoint),e.status=new StatusViewModel(e.baseEndpoint),e.scan=new WiFiScanViewModel(e.baseEndpoint),e.wifi=new WiFiConfigViewModel(e.baseEndpoint,e.config,e.status,e.scan),e.initialised=ko.observable(!1),e.updating=ko.observable(!1),e.wifi.selectedNet.subscribe(function(i){!1!==i&&e.config.ssid(i.ssid())}),e.config.ssid.subscribe(function(i){e.wifi.setSsid(i)}),e.wifiPassword=new PasswordViewModel(e.config.pass);var t=null;e.start=function(){e.updating(!0),e.config.update(function(){e.status.update(function(){e.initialised(!0),t=setTimeout(e.update,5e3),e.updating(!1)})})},e.update=function(){e.updating()||(e.updating(!0),null!==t&&(clearTimeout(t),t=null),e.status.update(function(){t=setTimeout(e.update,5e3),e.updating(!1)}))}}function scaleString(i,n,e){return(parseInt(i)/n).toFixed(e)}!function(){var n=window.location.hostname,e=window.location.port;$(function(){var i=new WiFiPortalViewModel(n,e);ko.applyBindings(i),i.start()})}();\n" "//# sourceMappingURL=wifi_portal.js.map\n"; +static const char CONTENT_WIFI_PORTAL_JS_ETAG[] PROGMEM = "a1979f741317f95194924f24deffc2c00c5edd9d2845d32380c4dc4ceabc8b89"; diff --git a/src/web_static/web_server.wifi_signal_1.svg.h b/src/web_static/web_server.wifi_signal_1.svg.h index d3dfaf88..98919b5d 100644 --- a/src/web_static/web_server.wifi_signal_1.svg.h +++ b/src/web_static/web_server.wifi_signal_1.svg.h @@ -1,2 +1,3 @@ static const char CONTENT_WIFI_SIGNAL_1_SVG[] PROGMEM = "\n"; +static const char CONTENT_WIFI_SIGNAL_1_SVG_ETAG[] PROGMEM = "0ed5d2caf5b0aae57528a0144db7d5010d847f9c53d0a18e7b8703eac8171d4b"; diff --git a/src/web_static/web_server.wifi_signal_2.svg.h b/src/web_static/web_server.wifi_signal_2.svg.h index 4a5b0809..95863a56 100644 --- a/src/web_static/web_server.wifi_signal_2.svg.h +++ b/src/web_static/web_server.wifi_signal_2.svg.h @@ -1,2 +1,3 @@ static const char CONTENT_WIFI_SIGNAL_2_SVG[] PROGMEM = "\n"; +static const char CONTENT_WIFI_SIGNAL_2_SVG_ETAG[] PROGMEM = "9277930f075deb2c8b9c7d463d8d1303730194716d0cb3f5ad5486cfba6fc705"; diff --git a/src/web_static/web_server.wifi_signal_3.svg.h b/src/web_static/web_server.wifi_signal_3.svg.h index 171f7b15..fd1406e8 100644 --- a/src/web_static/web_server.wifi_signal_3.svg.h +++ b/src/web_static/web_server.wifi_signal_3.svg.h @@ -1,2 +1,3 @@ static const char CONTENT_WIFI_SIGNAL_3_SVG[] PROGMEM = "\n"; +static const char CONTENT_WIFI_SIGNAL_3_SVG_ETAG[] PROGMEM = "3dadbb702339509d1b908178a64f0e18d53bdd09307097324ded52d28d3f957b"; diff --git a/src/web_static/web_server.wifi_signal_4.svg.h b/src/web_static/web_server.wifi_signal_4.svg.h index d9c2be27..25c65323 100644 --- a/src/web_static/web_server.wifi_signal_4.svg.h +++ b/src/web_static/web_server.wifi_signal_4.svg.h @@ -1,2 +1,3 @@ static const char CONTENT_WIFI_SIGNAL_4_SVG[] PROGMEM = "\n"; +static const char CONTENT_WIFI_SIGNAL_4_SVG_ETAG[] PROGMEM = "4c300c06578573b4ac38be8eebc11d6540907402dcab6cf989dad44f4af14046"; diff --git a/src/web_static/web_server.wifi_signal_5.svg.h b/src/web_static/web_server.wifi_signal_5.svg.h index 2043211f..eed03c76 100644 --- a/src/web_static/web_server.wifi_signal_5.svg.h +++ b/src/web_static/web_server.wifi_signal_5.svg.h @@ -1,2 +1,3 @@ static const char CONTENT_WIFI_SIGNAL_5_SVG[] PROGMEM = "\n"; +static const char CONTENT_WIFI_SIGNAL_5_SVG_ETAG[] PROGMEM = "3fe3ecd90d3991298c822ab8e4106a1e4909f90f765ad8e6df738fd440cf93c2"; diff --git a/src/web_static/web_server.zones.json.h b/src/web_static/web_server.zones.json.h index 349fea9c..28f4db42 100644 --- a/src/web_static/web_server.zones.json.h +++ b/src/web_static/web_server.zones.json.h @@ -462,3 +462,4 @@ static const char CONTENT_ZONES_JSON[] PROGMEM = "\"Pacific/Wake\":\"<+12>-12\",\n" "\"Pacific/Wallis\":\"<+12>-12\"\n" "}\n"; +static const char CONTENT_ZONES_JSON_ETAG[] PROGMEM = "7641cf7331c8ae6124b008c962061938c20f26ae538e30e0484afc06adb88af9"; diff --git a/src/web_static/web_server_static_files.h b/src/web_static/web_server_static_files.h index eb046af2..31ae1dca 100644 --- a/src/web_static/web_server_static_files.h +++ b/src/web_static/web_server_static_files.h @@ -21,26 +21,26 @@ #include "web_server.wifi_signal_5.svg.h" #include "web_server.zones.json.h" StaticFile staticFiles[] = { - { "/assets.js", CONTENT_ASSETS_JS, sizeof(CONTENT_ASSETS_JS) - 1, _CONTENT_TYPE_JS }, - { "/emoncms.jpg", CONTENT_EMONCMS_JPG, sizeof(CONTENT_EMONCMS_JPG) - 1, _CONTENT_TYPE_JPEG }, - { "/favicon-152.png", CONTENT_FAVICON_152_PNG, sizeof(CONTENT_FAVICON_152_PNG) - 1, _CONTENT_TYPE_PNG }, - { "/favicon-167.png", CONTENT_FAVICON_167_PNG, sizeof(CONTENT_FAVICON_167_PNG) - 1, _CONTENT_TYPE_PNG }, - { "/favicon-16x16.png", CONTENT_FAVICON_16X16_PNG, sizeof(CONTENT_FAVICON_16X16_PNG) - 1, _CONTENT_TYPE_PNG }, - { "/favicon-180.png", CONTENT_FAVICON_180_PNG, sizeof(CONTENT_FAVICON_180_PNG) - 1, _CONTENT_TYPE_PNG }, - { "/favicon-32x32.png", CONTENT_FAVICON_32X32_PNG, sizeof(CONTENT_FAVICON_32X32_PNG) - 1, _CONTENT_TYPE_PNG }, - { "/home.html", CONTENT_HOME_HTML, sizeof(CONTENT_HOME_HTML) - 1, _CONTENT_TYPE_HTML }, - { "/home.js", CONTENT_HOME_JS, sizeof(CONTENT_HOME_JS) - 1, _CONTENT_TYPE_JS }, - { "/lib.js", CONTENT_LIB_JS, sizeof(CONTENT_LIB_JS) - 1, _CONTENT_TYPE_JS }, - { "/ohm.jpg", CONTENT_OHM_JPG, sizeof(CONTENT_OHM_JPG) - 1, _CONTENT_TYPE_JPEG }, - { "/style.css", CONTENT_STYLE_CSS, sizeof(CONTENT_STYLE_CSS) - 1, _CONTENT_TYPE_CSS }, - { "/term.html", CONTENT_TERM_HTML, sizeof(CONTENT_TERM_HTML) - 1, _CONTENT_TYPE_HTML }, - { "/term.js", CONTENT_TERM_JS, sizeof(CONTENT_TERM_JS) - 1, _CONTENT_TYPE_JS }, - { "/wifi_portal.html", CONTENT_WIFI_PORTAL_HTML, sizeof(CONTENT_WIFI_PORTAL_HTML) - 1, _CONTENT_TYPE_HTML }, - { "/wifi_portal.js", CONTENT_WIFI_PORTAL_JS, sizeof(CONTENT_WIFI_PORTAL_JS) - 1, _CONTENT_TYPE_JS }, - { "/wifi_signal_1.svg", CONTENT_WIFI_SIGNAL_1_SVG, sizeof(CONTENT_WIFI_SIGNAL_1_SVG) - 1, _CONTENT_TYPE_SVG }, - { "/wifi_signal_2.svg", CONTENT_WIFI_SIGNAL_2_SVG, sizeof(CONTENT_WIFI_SIGNAL_2_SVG) - 1, _CONTENT_TYPE_SVG }, - { "/wifi_signal_3.svg", CONTENT_WIFI_SIGNAL_3_SVG, sizeof(CONTENT_WIFI_SIGNAL_3_SVG) - 1, _CONTENT_TYPE_SVG }, - { "/wifi_signal_4.svg", CONTENT_WIFI_SIGNAL_4_SVG, sizeof(CONTENT_WIFI_SIGNAL_4_SVG) - 1, _CONTENT_TYPE_SVG }, - { "/wifi_signal_5.svg", CONTENT_WIFI_SIGNAL_5_SVG, sizeof(CONTENT_WIFI_SIGNAL_5_SVG) - 1, _CONTENT_TYPE_SVG }, - { "/zones.json", CONTENT_ZONES_JSON, sizeof(CONTENT_ZONES_JSON) - 1, _CONTENT_TYPE_JSON }, + { "/assets.js", CONTENT_ASSETS_JS, sizeof(CONTENT_ASSETS_JS) - 1, _CONTENT_TYPE_JS, CONTENT_ASSETS_JS_ETAG }, + { "/emoncms.jpg", CONTENT_EMONCMS_JPG, sizeof(CONTENT_EMONCMS_JPG) - 1, _CONTENT_TYPE_JPEG, CONTENT_EMONCMS_JPG_ETAG }, + { "/favicon-152.png", CONTENT_FAVICON_152_PNG, sizeof(CONTENT_FAVICON_152_PNG) - 1, _CONTENT_TYPE_PNG, CONTENT_FAVICON_152_PNG_ETAG }, + { "/favicon-167.png", CONTENT_FAVICON_167_PNG, sizeof(CONTENT_FAVICON_167_PNG) - 1, _CONTENT_TYPE_PNG, CONTENT_FAVICON_167_PNG_ETAG }, + { "/favicon-16x16.png", CONTENT_FAVICON_16X16_PNG, sizeof(CONTENT_FAVICON_16X16_PNG) - 1, _CONTENT_TYPE_PNG, CONTENT_FAVICON_16X16_PNG_ETAG }, + { "/favicon-180.png", CONTENT_FAVICON_180_PNG, sizeof(CONTENT_FAVICON_180_PNG) - 1, _CONTENT_TYPE_PNG, CONTENT_FAVICON_180_PNG_ETAG }, + { "/favicon-32x32.png", CONTENT_FAVICON_32X32_PNG, sizeof(CONTENT_FAVICON_32X32_PNG) - 1, _CONTENT_TYPE_PNG, CONTENT_FAVICON_32X32_PNG_ETAG }, + { "/home.html", CONTENT_HOME_HTML, sizeof(CONTENT_HOME_HTML) - 1, _CONTENT_TYPE_HTML, CONTENT_HOME_HTML_ETAG }, + { "/home.js", CONTENT_HOME_JS, sizeof(CONTENT_HOME_JS) - 1, _CONTENT_TYPE_JS, CONTENT_HOME_JS_ETAG }, + { "/lib.js", CONTENT_LIB_JS, sizeof(CONTENT_LIB_JS) - 1, _CONTENT_TYPE_JS, CONTENT_LIB_JS_ETAG }, + { "/ohm.jpg", CONTENT_OHM_JPG, sizeof(CONTENT_OHM_JPG) - 1, _CONTENT_TYPE_JPEG, CONTENT_OHM_JPG_ETAG }, + { "/style.css", CONTENT_STYLE_CSS, sizeof(CONTENT_STYLE_CSS) - 1, _CONTENT_TYPE_CSS, CONTENT_STYLE_CSS_ETAG }, + { "/term.html", CONTENT_TERM_HTML, sizeof(CONTENT_TERM_HTML) - 1, _CONTENT_TYPE_HTML, CONTENT_TERM_HTML_ETAG }, + { "/term.js", CONTENT_TERM_JS, sizeof(CONTENT_TERM_JS) - 1, _CONTENT_TYPE_JS, CONTENT_TERM_JS_ETAG }, + { "/wifi_portal.html", CONTENT_WIFI_PORTAL_HTML, sizeof(CONTENT_WIFI_PORTAL_HTML) - 1, _CONTENT_TYPE_HTML, CONTENT_WIFI_PORTAL_HTML_ETAG }, + { "/wifi_portal.js", CONTENT_WIFI_PORTAL_JS, sizeof(CONTENT_WIFI_PORTAL_JS) - 1, _CONTENT_TYPE_JS, CONTENT_WIFI_PORTAL_JS_ETAG }, + { "/wifi_signal_1.svg", CONTENT_WIFI_SIGNAL_1_SVG, sizeof(CONTENT_WIFI_SIGNAL_1_SVG) - 1, _CONTENT_TYPE_SVG, CONTENT_WIFI_SIGNAL_1_SVG_ETAG }, + { "/wifi_signal_2.svg", CONTENT_WIFI_SIGNAL_2_SVG, sizeof(CONTENT_WIFI_SIGNAL_2_SVG) - 1, _CONTENT_TYPE_SVG, CONTENT_WIFI_SIGNAL_2_SVG_ETAG }, + { "/wifi_signal_3.svg", CONTENT_WIFI_SIGNAL_3_SVG, sizeof(CONTENT_WIFI_SIGNAL_3_SVG) - 1, _CONTENT_TYPE_SVG, CONTENT_WIFI_SIGNAL_3_SVG_ETAG }, + { "/wifi_signal_4.svg", CONTENT_WIFI_SIGNAL_4_SVG, sizeof(CONTENT_WIFI_SIGNAL_4_SVG) - 1, _CONTENT_TYPE_SVG, CONTENT_WIFI_SIGNAL_4_SVG_ETAG }, + { "/wifi_signal_5.svg", CONTENT_WIFI_SIGNAL_5_SVG, sizeof(CONTENT_WIFI_SIGNAL_5_SVG) - 1, _CONTENT_TYPE_SVG, CONTENT_WIFI_SIGNAL_5_SVG_ETAG }, + { "/zones.json", CONTENT_ZONES_JSON, sizeof(CONTENT_ZONES_JSON) - 1, _CONTENT_TYPE_JSON, CONTENT_ZONES_JSON_ETAG }, }; diff --git a/test/basic.http b/test/basic.http index 838ea3d9..446e18ba 100644 --- a/test/basic.http +++ b/test/basic.http @@ -21,10 +21,10 @@ GET {{baseUrl}}/ HTTP/1.1 ### -@lastModified = {{index.response.headers.Last-Modified}} +@etag = {{index.response.headers.etag}} GET {{baseUrl}}/ HTTP/1.1 -If-Modified-Since: {{lastModified}} +If-None-Match: {{etag}} ### From 4de2aa974f3dc60dbdcc09d474da71058595f4f9 Mon Sep 17 00:00:00 2001 From: Jeremy Poulter Date: Sat, 24 Jul 2021 22:08:10 +0100 Subject: [PATCH 2/2] Latest GUI --- gui | 2 +- src/web_static/web_server.home.html.h | 4 ++-- src/web_static/web_server.home.js.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gui b/gui index b4558b53..943d1d98 160000 --- a/gui +++ b/gui @@ -1 +1 @@ -Subproject commit b4558b535f68e2ace6ee45237959d7fef87faf17 +Subproject commit 943d1d98e840ecbf472c52ccd731c8dadc8f5d73 diff --git a/src/web_static/web_server.home.html.h b/src/web_static/web_server.home.html.h index 57df8038..291acdf0 100644 --- a/src/web_static/web_server.home.html.h +++ b/src/web_static/web_server.home.html.h @@ -62,7 +62,7 @@ static const char CONTENT_HOME_HTML[] PROGMEM = " optionsText: 'name',\n" " optionsValue: 'id',\n" " value: config.tesla_vehicle_id,\n" - " visible: vehicle.tesla.vehicles().length > 0\"> Fetching vehicle info ...


Open Vehicle Monitoring System


MQTT

MQTT not enabled.

You need to enable MQTT on the Services tab.

State of Charge:

The battery level of charge as a percentage

Range:

The range (on electric) of the vehicle based on the current battery level

Time to charge:

The time until the battery is fully charged in seconds

Error

Status

Status
Battery Level:
Battery Range:
Time to full charge:

Powered by OpenEVSE and OpenEnergyMonitor
Version: V
\n"; -static const char CONTENT_HOME_HTML_ETAG[] PROGMEM = "52442d017b1cfee59d37552f6500f2ea46ab14ba78e011cbbfeaaa02632a8037"; +static const char CONTENT_HOME_HTML_ETAG[] PROGMEM = "f2b1719419cf72504a973245567519fd45863fda3a42732d11173f27eb44625b"; diff --git a/src/web_static/web_server.home.js.h b/src/web_static/web_server.home.js.h index 1bba91b4..1a764ad9 100644 --- a/src/web_static/web_server.home.js.h +++ b/src/web_static/web_server.home.js.h @@ -1,4 +1,4 @@ static const char CONTENT_HOME_JS[] PROGMEM = - "\"use strict\";function _createForOfIteratorHelper(e,t){var n=\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(!n){if(Array.isArray(e)||(n=_unsupportedIterableToArray(e))||t&&e&&\"number\"==typeof e.length){n&&(e=n);var o=0,t=function(){};return{s:t,n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:t}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}var a,r=!0,i=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){i=!0,a=e},f:function(){try{r||null==n.return||n.return()}finally{if(i)throw a}}}}function _unsupportedIterableToArray(e,t){if(e){if(\"string\"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return\"Map\"===(n=\"Object\"===n&&e.constructor?e.constructor.name:n)||\"Set\"===n?Array.from(e):\"Arguments\"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n\"+e.ret),t.cmd(e.cmd)},\"json\").always(function(){t.rapiSend(!1)})}}function TimeViewModel(t){var o=this;function a(e){return(e<10?\"0\":\"\")+e}o.evseTimedate=ko.observable(new Date),o.localTimedate=ko.observable(new Date),o.nowTimedate=ko.observable(null),o.hasRTC=ko.observable(!0),o.elapsedNow=ko.observable(new Date(0)),o.elapsedLocal=ko.observable(new Date),o.divertUpdateNow=ko.observable(new Date(0)),o.divertUpdateLocal=ko.observable(new Date),o.vehicleUpdateNow=ko.observable(new Date(0)),o.vehicleUpdateLocal=ko.observable(new Date),o.date=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"\";var e=o.nowTimedate();return e.getFullYear()+\"-\"+a(e.getMonth()+1)+\"-\"+a(e.getDate())},write:function(e){var t=o.evseTimedate();e+=\" \"+a(t.getHours())+\":\"+a(t.getMinutes())+\":\"+a(t.getSeconds()),o.evseTimedate(new Date(e)),o.localTimedate(new Date)}}),o.time=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"--:--:--\";var e=o.nowTimedate();return a(e.getHours())+\":\"+a(e.getMinutes())+\":\"+a(e.getSeconds())},write:function(e){var t=e.split(\":\"),e=o.evseTimedate();e.setHours(parseInt(t[0])),e.setMinutes(parseInt(t[1])),o.evseTimedate(e),o.localTimedate(new Date)}}),o.elapsed=ko.pureComputed(function(){if(null===o.nowTimedate())return\"0:00:00\";var e=o.elapsedNow().getTime(),t=(e=Math.floor(e/1e3))%60,n=(e=Math.floor(e/60))%60;return Math.floor(e/60)+\":\"+a(n)+\":\"+a(t)}),t.status.elapsed.subscribe(function(e){o.elapsedNow(new Date(1e3*e)),o.elapsedLocal(new Date)}),o.divert_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.divertUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.divert_update.subscribe(function(e){o.divertUpdateNow(new Date(1e3*e)),o.divertUpdateLocal(new Date)}),o.vehicle_state_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.vehicleUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.vehicle_state_update.subscribe(function(e){o.vehicleUpdateNow(new Date(1e3*e)),o.vehicleUpdateLocal(new Date)});var n=null;o.automaticTime=ko.observable(!0),o.timeUpdate=function(e){o.hasRTC(!(1=e){o.timeLimit(n.value);break}}},o.selectChargeLimit=function(e){if(o.chargeLimit()!==e)for(var t=0;t=e){o.chargeLimit(n.value);break}}};var r=[function(){return!1===o.status.time()?o.openevse.time(o.time.timeUpdate):new DummyRequest},function(){return o.openevse.service_level(function(e,t){o.serviceLevel(e),o.actualServiceLevel(t)})},function(){return o.updateCurrentCapacity()},function(){return o.openevse.current_capacity(function(e){o.currentCapacity(e)})},function(){return o.openevse.time_limit(function(e){o.selectTimeLimit(e)})},function(){return o.openevse.charge_limit(function(e){o.selectChargeLimit(e)})},function(){return o.openevse.gfi_self_test(function(e){o.gfiSelfTestEnabled(e)})},function(){return o.openevse.ground_check(function(e){o.groundCheckEnabled(e)})},function(){return o.openevse.stuck_relay_check(function(e){o.stuckRelayEnabled(e)})},function(){return o.openevse.temp_check(function(e){o.tempCheckEnabled(e)})},function(){return o.openevse.diode_check(function(e){o.diodeCheckEnabled(e)})},function(){return o.openevse.vent_required(function(e){o.ventRequiredEnabled(e)})},function(){return o.openevse.temp_check(function(){o.tempCheckSupported(!0)},o.tempCheckEnabled()).error(function(){o.tempCheckSupported(!1)})},function(){return o.openevse.timer(function(e,t,n){o.delayTimerEnabled(e),o.delayTimerStart(t),o.delayTimerStop(n)})}];o.updateCount=ko.observable(0),o.updateTotal=ko.observable(r.length),o.updateCurrentCapacity=function(){return o.openevse.current_capacity_range(function(e,t){o.minCurrentLevel(e),o.maxCurrentLevel(t);t=o.currentCapacity();o.currentLevels.removeAll();for(var n=o.minCurrentLevel();n<=o.maxCurrentLevel();n++)o.currentLevels.push({name:n+\" A\",value:n});o.currentCapacity(t)})},o.updatingServiceLevel=ko.observable(!1),o.savedServiceLevel=ko.observable(!1),o.updatingCurrentCapacity=ko.observable(!1),o.savedCurrentCapacity=ko.observable(!1),o.updatingTimeLimit=ko.observable(!1),o.savedTimeLimit=ko.observable(!1),o.updatingChargeLimit=ko.observable(!1),o.savedChargeLimit=ko.observable(!1),o.updatingDelayTimer=ko.observable(!1),o.savedDelayTimer=ko.observable(!1),o.updatingStatus=ko.observable(!1),o.savedStatus=ko.observable(!1),o.updatingGfiSelfTestEnabled=ko.observable(!1),o.savedGfiSelfTestEnabled=ko.observable(!1),o.updatingGroundCheckEnabled=ko.observable(!1),o.savedGroundCheckEnabled=ko.observable(!1),o.updatingStuckRelayEnabled=ko.observable(!1),o.savedStuckRelayEnabled=ko.observable(!1),o.updatingTempCheckEnabled=ko.observable(!1),o.savedTempCheckEnabled=ko.observable(!1),o.updatingDiodeCheckEnabled=ko.observable(!1),o.savedDiodeCheckEnabled=ko.observable(!1),o.updatingVentRequiredEnabled=ko.observable(!1),o.savedVentRequiredEnabled=ko.observable(!1);var i=!(o.setForTime=function(e,t){e(!0),setTimeout(function(){e(!1)},t)});function s(e){return/([01]\\d|2[0-3]):([0-5]\\d)/.test(e)}o.subscribe=function(){i||(o.serviceLevel.subscribe(function(e){o.updatingServiceLevel(!0),o.openevse.service_level(function(e,t){o.setForTime(o.savedServiceLevel,2e3),o.actualServiceLevel(t),o.updateCurrentCapacity().always(function(){})},e).always(function(){o.updatingServiceLevel(!1)})}),o.currentCapacity.subscribe(function(t){!0!==o.updatingServiceLevel()&&(o.updatingCurrentCapacity(!0),o.openevse.current_capacity(function(e){o.setForTime(o.savedCurrentCapacity,2e3),t!==e&&o.currentCapacity(e)},t).always(function(){o.updatingCurrentCapacity(!1)}))}),o.timeLimit.subscribe(function(t){o.updatingTimeLimit(!0),o.openevse.time_limit(function(e){o.setForTime(o.savedTimeLimit,2e3),t!==e&&o.selectTimeLimit(e)},t).always(function(){o.updatingTimeLimit(!1)})}),o.chargeLimit.subscribe(function(t){o.updatingChargeLimit(!0),o.openevse.charge_limit(function(e){o.setForTime(o.savedChargeLimit,2e3),t!==e&&o.selectChargeLimit(e)},t).always(function(){o.updatingChargeLimit(!1)})}),o.gfiSelfTestEnabled.subscribe(function(t){o.updatingGfiSelfTestEnabled(!0),o.openevse.gfi_self_test(function(e){o.setForTime(o.savedGfiSelfTestEnabled,2e3),t!==e&&o.gfiSelfTestEnabled(e)},t).always(function(){o.updatingGfiSelfTestEnabled(!1)})}),o.groundCheckEnabled.subscribe(function(t){o.updatingGroundCheckEnabled(!0),o.openevse.ground_check(function(e){o.setForTime(o.savedGroundCheckEnabled,2e3),t!==e&&o.groundCheckEnabled(e)},t).always(function(){o.updatingGroundCheckEnabled(!1)})}),o.stuckRelayEnabled.subscribe(function(t){o.updatingStuckRelayEnabled(!0),o.savedStuckRelayEnabled(!1),o.openevse.stuck_relay_check(function(e){o.savedStuckRelayEnabled(!0),setTimeout(function(){o.savedStuckRelayEnabled(!1)},2e3),t!==e&&o.stuckRelayEnabled(e)},t).always(function(){o.updatingStuckRelayEnabled(!1)})}),o.tempCheckEnabled.subscribe(function(t){o.updatingTempCheckEnabled(!0),o.openevse.temp_check(function(e){o.setForTime(o.savedTempCheckEnabled,2e3),t!==e&&o.tempCheckEnabled(e)},t).always(function(){o.updatingTempCheckEnabled(!1)})}),o.diodeCheckEnabled.subscribe(function(t){o.updatingDiodeCheckEnabled(!0),o.openevse.diode_check(function(e){o.setForTime(o.savedDiodeCheckEnabled,2e3),t!==e&&o.diodeCheckEnabled(e)},t).always(function(){o.updatingDiodeCheckEnabled(!1)})}),o.ventRequiredEnabled.subscribe(function(t){o.updatingVentRequiredEnabled(!0),o.openevse.vent_required(function(e){o.setForTime(o.savedVentRequiredEnabled,2e3),t!==e&&o.ventRequiredEnabled(e)},t).always(function(){o.updatingVentRequiredEnabled(!1)})}),i=!0)},o.update=function(){var e=0=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:t}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}var a,r=!0,i=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return r=e.done,e},e:function(e){i=!0,a=e},f:function(){try{r||null==n.return||n.return()}finally{if(i)throw a}}}}function _unsupportedIterableToArray(e,t){if(e){if(\"string\"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return\"Map\"===(n=\"Object\"===n&&e.constructor?e.constructor.name:n)||\"Set\"===n?Array.from(e):\"Arguments\"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n\"+e.ret),t.cmd(e.cmd)},\"json\").always(function(){t.rapiSend(!1)})}}function TimeViewModel(t){var o=this;function a(e){return(e<10?\"0\":\"\")+e}o.evseTimedate=ko.observable(new Date),o.localTimedate=ko.observable(new Date),o.nowTimedate=ko.observable(null),o.hasRTC=ko.observable(!0),o.elapsedNow=ko.observable(new Date(0)),o.elapsedLocal=ko.observable(new Date),o.divertUpdateNow=ko.observable(new Date(0)),o.divertUpdateLocal=ko.observable(new Date),o.vehicleUpdateNow=ko.observable(new Date(0)),o.vehicleUpdateLocal=ko.observable(new Date),o.date=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"\";var e=o.nowTimedate();return e.getFullYear()+\"-\"+a(e.getMonth()+1)+\"-\"+a(e.getDate())},write:function(e){var t=o.evseTimedate();e+=\" \"+a(t.getHours())+\":\"+a(t.getMinutes())+\":\"+a(t.getSeconds()),o.evseTimedate(new Date(e)),o.localTimedate(new Date)}}),o.time=ko.pureComputed({read:function(){if(null===o.nowTimedate())return\"--:--:--\";var e=o.nowTimedate();return a(e.getHours())+\":\"+a(e.getMinutes())+\":\"+a(e.getSeconds())},write:function(e){var t=e.split(\":\"),e=o.evseTimedate();e.setHours(parseInt(t[0])),e.setMinutes(parseInt(t[1])),o.evseTimedate(e),o.localTimedate(new Date)}}),o.elapsed=ko.pureComputed(function(){if(null===o.nowTimedate())return\"0:00:00\";var e=o.elapsedNow().getTime(),t=(e=Math.floor(e/1e3))%60,n=(e=Math.floor(e/60))%60;return Math.floor(e/60)+\":\"+a(n)+\":\"+a(t)}),t.status.elapsed.subscribe(function(e){o.elapsedNow(new Date(1e3*e)),o.elapsedLocal(new Date)}),o.divert_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.divertUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.divert_update.subscribe(function(e){o.divertUpdateNow(new Date(1e3*e)),o.divertUpdateLocal(new Date)}),o.vehicle_state_update=ko.pureComputed(function(){if(null===o.nowTimedate())return!1;var e=o.vehicleUpdateNow().getTime();return Math.floor(e/1e3)}),t.status.vehicle_state_update.subscribe(function(e){o.vehicleUpdateNow(new Date(1e3*e)),o.vehicleUpdateLocal(new Date)});var n=null;o.automaticTime=ko.observable(!0),o.timeUpdate=function(e){o.hasRTC(!(1=e){o.timeLimit(n.value);break}}},o.selectChargeLimit=function(e){if(o.chargeLimit()!==e)for(var t=0;t=e){o.chargeLimit(n.value);break}}};var r=[function(){return!1===o.status.time()?o.openevse.time(o.time.timeUpdate):new DummyRequest},function(){return o.openevse.service_level(function(e,t){o.serviceLevel(e),o.actualServiceLevel(t)})},function(){return o.updateCurrentCapacity()},function(){return o.openevse.current_capacity(function(e){o.currentCapacity(e)})},function(){return o.openevse.time_limit(function(e){o.selectTimeLimit(e)})},function(){return o.openevse.charge_limit(function(e){o.selectChargeLimit(e)})},function(){return o.openevse.gfi_self_test(function(e){o.gfiSelfTestEnabled(e)})},function(){return o.openevse.ground_check(function(e){o.groundCheckEnabled(e)})},function(){return o.openevse.stuck_relay_check(function(e){o.stuckRelayEnabled(e)})},function(){return o.openevse.temp_check(function(e){o.tempCheckEnabled(e)})},function(){return o.openevse.diode_check(function(e){o.diodeCheckEnabled(e)})},function(){return o.openevse.vent_required(function(e){o.ventRequiredEnabled(e)})},function(){return o.openevse.temp_check(function(){o.tempCheckSupported(!0)},o.tempCheckEnabled()).error(function(){o.tempCheckSupported(!1)})},function(){return o.openevse.timer(function(e,t,n){o.delayTimerEnabled(e),o.delayTimerStart(t),o.delayTimerStop(n)})}];o.updateCount=ko.observable(0),o.updateTotal=ko.observable(r.length),o.updateCurrentCapacity=function(){return o.openevse.current_capacity_range(function(e,t){o.minCurrentLevel(e),o.maxCurrentLevel(t);t=o.currentCapacity();o.currentLevels.removeAll();for(var n=o.minCurrentLevel();n<=o.maxCurrentLevel();n++)o.currentLevels.push({name:n+\" A\",value:n});o.currentCapacity(t)})},o.updatingServiceLevel=ko.observable(!1),o.savedServiceLevel=ko.observable(!1),o.updatingCurrentCapacity=ko.observable(!1),o.savedCurrentCapacity=ko.observable(!1),o.updatingTimeLimit=ko.observable(!1),o.savedTimeLimit=ko.observable(!1),o.updatingChargeLimit=ko.observable(!1),o.savedChargeLimit=ko.observable(!1),o.updatingDelayTimer=ko.observable(!1),o.savedDelayTimer=ko.observable(!1),o.updatingStatus=ko.observable(!1),o.savedStatus=ko.observable(!1),o.updatingGfiSelfTestEnabled=ko.observable(!1),o.savedGfiSelfTestEnabled=ko.observable(!1),o.updatingGroundCheckEnabled=ko.observable(!1),o.savedGroundCheckEnabled=ko.observable(!1),o.updatingStuckRelayEnabled=ko.observable(!1),o.savedStuckRelayEnabled=ko.observable(!1),o.updatingTempCheckEnabled=ko.observable(!1),o.savedTempCheckEnabled=ko.observable(!1),o.updatingDiodeCheckEnabled=ko.observable(!1),o.savedDiodeCheckEnabled=ko.observable(!1),o.updatingVentRequiredEnabled=ko.observable(!1),o.savedVentRequiredEnabled=ko.observable(!1);var i=!(o.setForTime=function(e,t){e(!0),setTimeout(function(){e(!1)},t)});function s(e){return/([01]\\d|2[0-3]):([0-5]\\d)/.test(e)}o.subscribe=function(){i||(o.serviceLevel.subscribe(function(e){o.updatingServiceLevel(!0),o.openevse.service_level(function(e,t){o.setForTime(o.savedServiceLevel,2e3),o.actualServiceLevel(t),o.updateCurrentCapacity().always(function(){})},e).always(function(){o.updatingServiceLevel(!1)})}),o.currentCapacity.subscribe(function(t){!0!==o.updatingServiceLevel()&&(o.updatingCurrentCapacity(!0),o.openevse.current_capacity(function(e){o.setForTime(o.savedCurrentCapacity,2e3),t!==e&&o.currentCapacity(e)},t).always(function(){o.updatingCurrentCapacity(!1)}))}),o.timeLimit.subscribe(function(t){o.updatingTimeLimit(!0),o.openevse.time_limit(function(e){o.setForTime(o.savedTimeLimit,2e3),t!==e&&o.selectTimeLimit(e)},t).always(function(){o.updatingTimeLimit(!1)})}),o.chargeLimit.subscribe(function(t){o.updatingChargeLimit(!0),o.openevse.charge_limit(function(e){o.setForTime(o.savedChargeLimit,2e3),t!==e&&o.selectChargeLimit(e)},t).always(function(){o.updatingChargeLimit(!1)})}),o.gfiSelfTestEnabled.subscribe(function(t){o.updatingGfiSelfTestEnabled(!0),o.openevse.gfi_self_test(function(e){o.setForTime(o.savedGfiSelfTestEnabled,2e3),t!==e&&o.gfiSelfTestEnabled(e)},t).always(function(){o.updatingGfiSelfTestEnabled(!1)})}),o.groundCheckEnabled.subscribe(function(t){o.updatingGroundCheckEnabled(!0),o.openevse.ground_check(function(e){o.setForTime(o.savedGroundCheckEnabled,2e3),t!==e&&o.groundCheckEnabled(e)},t).always(function(){o.updatingGroundCheckEnabled(!1)})}),o.stuckRelayEnabled.subscribe(function(t){o.updatingStuckRelayEnabled(!0),o.savedStuckRelayEnabled(!1),o.openevse.stuck_relay_check(function(e){o.savedStuckRelayEnabled(!0),setTimeout(function(){o.savedStuckRelayEnabled(!1)},2e3),t!==e&&o.stuckRelayEnabled(e)},t).always(function(){o.updatingStuckRelayEnabled(!1)})}),o.tempCheckEnabled.subscribe(function(t){o.updatingTempCheckEnabled(!0),o.openevse.temp_check(function(e){o.setForTime(o.savedTempCheckEnabled,2e3),t!==e&&o.tempCheckEnabled(e)},t).always(function(){o.updatingTempCheckEnabled(!1)})}),o.diodeCheckEnabled.subscribe(function(t){o.updatingDiodeCheckEnabled(!0),o.openevse.diode_check(function(e){o.setForTime(o.savedDiodeCheckEnabled,2e3),t!==e&&o.diodeCheckEnabled(e)},t).always(function(){o.updatingDiodeCheckEnabled(!1)})}),o.ventRequiredEnabled.subscribe(function(t){o.updatingVentRequiredEnabled(!0),o.openevse.vent_required(function(e){o.setForTime(o.savedVentRequiredEnabled,2e3),t!==e&&o.ventRequiredEnabled(e)},t).always(function(){o.updatingVentRequiredEnabled(!1)})}),i=!0)},o.update=function(){var e=0