From 0398c3360bf09cf3c4a4af900586b317cc43ad1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Mon, 8 Jul 2019 21:48:16 +0200 Subject: [PATCH] Save the post data in a file on the filesystem (#2810) * Use cross-browser JS for query params in EUS * Update EUS doc to explain how to use parameters * Remove ; in Lua code * Rewrite the endpoint table * Do not use properties as global Lua variables * remove enduser_setup.html.gz * rename folder 'eus' to 'enduser_setup' * Change input type for password to "password" * Replace outdated captive portal screen shot --- app/modules/enduser_setup.c | 249 +++++++++++++++--- app/modules/enduser_setup/.gitattributes | 1 + app/modules/enduser_setup/.gitignore | 1 + .../{eus => enduser_setup}/enduser_setup.html | 54 ++-- .../enduser_setup/enduser_setup.html.gz.def.h | 218 +++++++++++++++ app/modules/{eus => enduser_setup}/prepare.sh | 2 +- app/modules/eus/enduser_setup.html.gz | Bin 2423 -> 0 bytes app/modules/eus/http_html_backup.def | 205 -------------- docs/img/enduser-setup-captive-portal.png | Bin 0 -> 34739 bytes docs/img/enduser-setup.jpg | Bin 35554 -> 0 bytes docs/modules/enduser-setup.md | 114 ++++++-- 11 files changed, 547 insertions(+), 297 deletions(-) create mode 100644 app/modules/enduser_setup/.gitattributes create mode 100644 app/modules/enduser_setup/.gitignore rename app/modules/{eus => enduser_setup}/enduser_setup.html (83%) create mode 100644 app/modules/enduser_setup/enduser_setup.html.gz.def.h rename app/modules/{eus => enduser_setup}/prepare.sh (65%) delete mode 100644 app/modules/eus/enduser_setup.html.gz delete mode 100644 app/modules/eus/http_html_backup.def create mode 100644 docs/img/enduser-setup-captive-portal.png delete mode 100644 docs/img/enduser-setup.jpg diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index a03a87b0..addef5f4 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -93,6 +93,7 @@ static const char http_html_filename[] = "enduser_setup.html"; static const char http_header_200[] = "HTTP/1.1 200 OK\r\nCache-control:no-cache\r\nConnection:close\r\nContent-Type:text/html\r\n"; /* Note single \r\n here! */ static const char http_header_204[] = "HTTP/1.1 204 No Content\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_302[] = "HTTP/1.1 302 Moved\r\nLocation: /\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; +static const char http_header_302_trying[] = "HTTP/1.1 302 Moved\r\nLocation: /?trying=true\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_400[] = "HTTP/1.1 400 Bad request\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_404[] = "HTTP/1.1 404 Not found\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_405[] = "HTTP/1.1 405 Method Not Allowed\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; @@ -101,8 +102,8 @@ static const char http_header_500[] = "HTTP/1.1 500 Internal Error\r\nContent-Le static const char http_header_content_len_fmt[] = "Content-length:%5d\r\n\r\n"; static const char http_html_gzip_contentencoding[] = "Content-Encoding: gzip\r\n"; -/* Externally defined: static const char http_html_backup[] = ... */ -#include "eus/http_html_backup.def" +/* Externally defined: static const char enduser_setup_html_default[] = ... */ +#include "enduser_setup/enduser_setup.html.gz.def.h" typedef struct scan_listener { @@ -398,9 +399,9 @@ static err_t close_once_sent (void *arg, struct tcp_pcb *pcb, u16_t len) /** * Search String * - * Search string for first occurance of any char in srch_str. + * Search string for first occurence of any char in srch_str. * - * @return -1 iff no occurance of char was found. + * @return -1 if no occurence of char was found. */ static int enduser_setup_srch_str(const char *str, const char *srch_str) { @@ -418,9 +419,9 @@ static int enduser_setup_srch_str(const char *str, const char *srch_str) /** * Load HTTP Payload * - * @return - 0 iff payload loaded successfully - * 1 iff backup html was loaded - * 2 iff out of memory + * @return - 0 if payload loaded successfully + * 1 if default html was loaded + * 2 if out of memory */ static int enduser_setup_http_load_payload(void) { @@ -466,16 +467,16 @@ static int enduser_setup_http_load_payload(void) if (!f || err == VFS_RES_ERR || err2 == VFS_RES_ERR) { - ENDUSER_SETUP_DEBUG("Unable to load file enduser_setup.html, loading backup HTML..."); + ENDUSER_SETUP_DEBUG("Unable to load file enduser_setup.html, loading default HTML..."); - c_sprintf(cl_hdr, http_header_content_len_fmt, sizeof(http_html_backup)); + c_sprintf(cl_hdr, http_header_content_len_fmt, sizeof(enduser_setup_html_default)); cl_len = c_strlen(cl_hdr); - int html_len = LITLEN(http_html_backup); + int html_len = LITLEN(enduser_setup_html_default); - if (http_html_backup[0] == 0x1f && http_html_backup[1] == 0x8b) + if (enduser_setup_html_default[0] == 0x1f && enduser_setup_html_default[1] == 0x8b) { ce_len = c_strlen(http_html_gzip_contentencoding); - html_len = http_html_backup_len; /* Defined in eus/http_html_backup.def by xxd -i */ + html_len = enduser_setup_html_default_len; /* Defined in enduser_setup/enduser_setup.html.gz.def.h by xxd -i */ ENDUSER_SETUP_DEBUG("Content is gzipped"); } @@ -499,7 +500,7 @@ static int enduser_setup_http_load_payload(void) c_memcpy(&(state->http_payload_data[offset]), &(cl_hdr), cl_len); offset += cl_len; - c_memcpy(&(state->http_payload_data[offset]), &(http_html_backup), sizeof(http_html_backup)); + c_memcpy(&(state->http_payload_data[offset]), &(enduser_setup_html_default), sizeof(enduser_setup_html_default)); return 1; } @@ -548,7 +549,7 @@ static int enduser_setup_http_load_payload(void) * * Parse escaped and form encoded data of request. * - * @return - return 0 iff the HTTP parameter is decoded into a valid string. + * @return - return 0 if the HTTP parameter is decoded into a valid string. */ static int enduser_setup_http_urldecode(char *dst, const char *src, int src_len, int dst_len) { @@ -631,13 +632,167 @@ static void do_station_cfg (task_param_t param, uint8_t prio) luaM_free(lua_getstate(), cnf); } +/** + * Count the number of occurences of a character in a string + * + * return the number of times the character was encountered in the string + */ +static int count_char_occurence(const char *input, const char char_to_count) { + const char *current = input; + int occur = 0; + while (*current != 0) { + if (*current == char_to_count) occur++; + current++; + } + return occur; +} + +/* structure used to store the key/value pairs that we find in a HTTP POST body */ +struct keypairs_t { + char **keypairs; + int keypairs_nb; +}; + +static void enduser_setup_free_keypairs(struct keypairs_t *kp) { + if (kp == NULL) return; + + if (kp->keypairs != NULL) { + for (int i = 0; i < kp->keypairs_nb * 2; i++) { + os_free(kp->keypairs[i]); + } + } + os_free(kp->keypairs); + os_free(kp); +} + +static struct keypairs_t * enduser_setup_alloc_keypairs(int kp_number ){ + struct keypairs_t *kp = os_malloc(sizeof(struct keypairs_t)); + os_memset(kp, 0, sizeof(struct keypairs_t)); + + kp->keypairs = os_malloc(kp_number * 2 * sizeof(char *)); + kp->keypairs_nb = kp_number; + return kp; +} + +/** + * Parses a form-urlencoded body into a struct keypairs_t, which contains an array of key,values strings and the size of the array. + */ +static struct keypairs_t *enduser_setup_get_keypairs_from_form(char *form_body, int form_length) { + int keypair_nb = count_char_occurence(form_body, '&') + 1; + int equal_nb = count_char_occurence(form_body, '='); + + if (keypair_nb == 1 && equal_nb == 0) { + ENDUSER_SETUP_DEBUG("No keypair in form body"); + return NULL; + } + + struct keypairs_t *kp = enduser_setup_alloc_keypairs(keypair_nb); + + int current_idx = 0; + int err; + + char *body_copy = os_malloc(form_length+1); + os_bzero(body_copy, form_length+1); + os_memcpy(body_copy, form_body, form_length); + char *tok = strtok(body_copy, "="); + + char last_tok = '='; + while (tok) { + size_t len = strlen(tok); + kp->keypairs[current_idx] = os_malloc(len + 1); + err = enduser_setup_http_urldecode(kp->keypairs[current_idx], tok, len, len + 1); + if (err) { + ENDUSER_SETUP_DEBUG("Unable to decode parameter"); + enduser_setup_free_keypairs(kp); + os_free(body_copy); + return NULL; + } + + current_idx++; + if (current_idx > keypair_nb*2) { + ENDUSER_SETUP_DEBUG("Too many keypairs!"); + enduser_setup_free_keypairs(kp); + os_free(body_copy); + return NULL; + } + + if (last_tok == '=') { + tok = strtok(NULL, "&"); // now search for the '&' + last_tok='&'; + } else { + tok = strtok(NULL, "="); // search for the next '=' + last_tok='='; + } + } + os_free(body_copy); + return kp; +} + + +/** + * This function saves the form data received when the configuration is sent to the ESP into a eus_params.lua file + */ +static int enduser_setup_write_file_with_extra_configuration_data(char *form_body, int form_length) { + ENDUSER_SETUP_DEBUG("enduser: write data from posted form"); + ENDUSER_SETUP_DEBUG(form_body); + + // We will save the form data into a file in the LUA format: KEY="VALUE", so that configuration data is available for load in the lua code. + // As input, we have a string as such: "key1=value1&key2=value2&key3=value%203" (urlencoded), the number of '&' tells us how many keypairs there are (the count + 1) + + struct keypairs_t *kp = enduser_setup_get_keypairs_from_form(form_body, form_length); + if (kp == NULL || kp->keypairs_nb == 0) { + ENDUSER_SETUP_DEBUG("enduser: No extra configuration."); + if (kp != NULL) enduser_setup_free_keypairs(kp); + return 1; + } + + // Now that we have the keys and the values, let's save them in a lua file + int p_file = vfs_open("eus_params.lua", "w"); + if (p_file == 0) + { + ENDUSER_SETUP_DEBUG("Can't open file in write mode!"); + enduser_setup_free_keypairs(kp); + return 1; + } + + // write all key pairs as KEY="VALUE"\n into a Lua table, example: + // local p = {} + // p.wifi_ssid="ssid" + // p.wifi_password="password" + // p.device_name="foo-node" + // return p + vfs_write(p_file, "local p={}\n", 11); + int idx = 0; + for( idx = 0; idx < kp->keypairs_nb*2; idx=idx+2){ + char* to_write = kp->keypairs[idx]; + size_t length = c_strlen(to_write); + + vfs_write(p_file, "p.", 2); + + vfs_write(p_file, to_write, length); + + vfs_write(p_file, "=\"", 2); + + to_write = kp->keypairs[idx+1]; + length = c_strlen(to_write); + vfs_write(p_file, to_write, length); + + vfs_write(p_file, "\"\n", 2); + } + vfs_write(p_file, "return p\n", 9); + + vfs_close(p_file); + enduser_setup_free_keypairs(kp); + // TODO: we could call back in the LUA with an associative table setup, but this is MVP2... + return 0; +} /** * Handle HTTP Credentials * - * @return - return 0 iff credentials are found and handled successfully - * return 1 iff credentials aren't found - * return 2 iff an error occured + * @return - return 0 if credentials are found and handled successfully + * return 1 if credentials aren't found + * return 2 if an error occured */ static int enduser_setup_http_handle_credentials(char *data, unsigned short data_len) { @@ -682,7 +837,6 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data return 1; } - ENDUSER_SETUP_DEBUG(""); ENDUSER_SETUP_DEBUG("WiFi Credentials Stored"); ENDUSER_SETUP_DEBUG("-----------------------"); @@ -702,7 +856,7 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data /** * Serve HTML * - * @return - return 0 iff html was served successfully + * @return - return 0 if html was served successfully */ static int enduser_setup_http_serve_header(struct tcp_pcb *http_client, const char *header, uint32_t header_len) { @@ -763,7 +917,7 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len) /** * Serve HTML * - * @return - return 0 iff html was served successfully + * @return - return 0 if html was served successfully */ static int enduser_setup_http_serve_html(struct tcp_pcb *http_client) { @@ -957,6 +1111,37 @@ static void enduser_setup_handle_OPTIONS (struct tcp_pcb *http_client, char *dat } +static err_t enduser_setup_handle_POST(struct tcp_pcb *http_client, char* data, size_t data_len) +{ + ENDUSER_SETUP_DEBUG("Handling POST"); + if (c_strncmp(data + 5, "/setwifi ", 9) == 0) // User clicked the submit button + { + switch (enduser_setup_http_handle_credentials(data, data_len)) + { + case 0: { + // all went fine, extract all the form data into a file + char* body=strstr(data, "\r\n\r\n"); + char *content_length_str = strstr(data, "Content-Length: "); + if( body != NULL && content_length_str != NULL){ + int bodylength = c_atoi(content_length_str + 16); + body += 4; // length of the double CRLF found above + enduser_setup_write_file_with_extra_configuration_data(body, bodylength); + } + // redirect user to the base page with the trying flag + enduser_setup_http_serve_header(http_client, http_header_302_trying, LITLEN(http_header_302_trying)); + break; + } + case 1: + enduser_setup_http_serve_header(http_client, http_header_400, LITLEN(http_header_400)); + break; + default: + ENDUSER_SETUP_ERROR("http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); + break; + } + } +} + + /* --- WiFi AP scanning support -------------------------------------------- */ static void free_scan_listeners (void) @@ -1165,7 +1350,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s if (c_strncmp(data, "GET ", 4) == 0) { - if (c_strncmp(data + 4, "/ ", 2) == 0) + if (c_strncmp(data + 4, "/ ", 2) == 0 || c_strncmp(data + 4, "/?", 2) == 0) { if (enduser_setup_http_serve_html(http_client) != 0) { @@ -1237,21 +1422,6 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s break; } } - else if (c_strncmp(data + 4, "/setwifi?", 9) == 0) - { - switch (enduser_setup_http_handle_credentials(data, data_len)) - { - case 0: - enduser_setup_serve_status_as_json(http_client); - break; - case 1: - enduser_setup_http_serve_header(http_client, http_header_400, LITLEN(http_header_400)); - break; - default: - ENDUSER_SETUP_ERROR("http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); - break; - } - } else if (c_strncmp(data + 4, "/generate_204", 13) == 0) { /* Convince Android devices that they have internet access to avoid pesky dialogues. */ @@ -1267,6 +1437,10 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s { enduser_setup_handle_OPTIONS(http_client, data, data_len); } + else if (c_strncmp(data, "POST ", 5) == 0) + { + enduser_setup_handle_POST(http_client, data, data_len); + } else /* not GET or OPTIONS */ { enduser_setup_http_serve_header(http_client, http_header_405, LITLEN(http_header_405)); @@ -1279,6 +1453,7 @@ free_out: return ret; } + static err_t enduser_setup_http_connectcb(void *arg, struct tcp_pcb *pcb, err_t err) { ENDUSER_SETUP_DEBUG("enduser_setup_http_connectcb"); @@ -1332,7 +1507,7 @@ static int enduser_setup_http_start(void) int err = enduser_setup_http_load_payload(); if (err == 1) { - ENDUSER_SETUP_DEBUG("enduser_setup_http_start info. Loaded backup HTML."); + ENDUSER_SETUP_DEBUG("enduser_setup_http_start info. Loaded default HTML."); } else if (err == 2) { diff --git a/app/modules/enduser_setup/.gitattributes b/app/modules/enduser_setup/.gitattributes new file mode 100644 index 00000000..4a8a4378 --- /dev/null +++ b/app/modules/enduser_setup/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/app/modules/enduser_setup/.gitignore b/app/modules/enduser_setup/.gitignore new file mode 100644 index 00000000..f72d8a38 --- /dev/null +++ b/app/modules/enduser_setup/.gitignore @@ -0,0 +1 @@ +enduser_setup.html.gz diff --git a/app/modules/eus/enduser_setup.html b/app/modules/enduser_setup/enduser_setup.html similarity index 83% rename from app/modules/eus/enduser_setup.html rename to app/modules/enduser_setup/enduser_setup.html index 8a25e160..551795f4 100644 --- a/app/modules/eus/enduser_setup.html +++ b/app/modules/enduser_setup/enduser_setup.html @@ -153,14 +153,17 @@

Connect device to your Wi-Fi

- - - - - +
+ + + + + + +

Success!

@@ -180,6 +183,11 @@ var ab = $('#networks'), ap = $('#aplist'); var stopAll = false, ra, rs, submitted = false; + $.urlParam = function (name) { + var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href); + if (results == null) { return null;} + else { return decodeURI(results[1]) || 0;} + } function show(f, y) { if (y == null) y = f; $(f).style.display = y == f ? 'block' : 'none'; @@ -240,13 +248,6 @@ } } } - function submit() { - submitted = true; - var url = '/setwifi?wifi_ssid=' + encodeURIComponent($('#ssid').value) + '&wifi_password=' + encodeURIComponent($('#wifi_password').value); - clearTimeout(rs); - fetch(url, 'GET', newSt, 2); - cur('#f3'); - } function fetch(url, method, callback, time_out) { var xhr = new XMLHttpRequest(); xhr.onloadend = function () { @@ -305,18 +306,19 @@ fetch('/aplist?n=' + Math.random(), 'GET', gotAp, 10); } window.onload = function() { - ab.innerText = 'Scan for Networks'; - ab.onclick = refrAp; - $('#aplist').onchange = function () { - $('#ssid').value = $('#aplist').value; - }; - $('#submit').onclick = submit; - $('#bk2').onclick = function () { - cur('#f1') - } - rs = to(refr, 0.5); + let trying = $.urlParam('trying'); + ab.innerText = 'Scan for Networks'; + ab.onclick = refrAp; + $('#aplist').onchange = function () { + $('#ssid').value = $('#aplist').value; + }; + $('#bk2').onclick = function () { + cur('#f1') + } + rs = to(refr, 0.5); + if( trying ) cur("#f3"); } - \ No newline at end of file + diff --git a/app/modules/enduser_setup/enduser_setup.html.gz.def.h b/app/modules/enduser_setup/enduser_setup.html.gz.def.h new file mode 100644 index 00000000..d829ee0d --- /dev/null +++ b/app/modules/enduser_setup/enduser_setup.html.gz.def.h @@ -0,0 +1,218 @@ +static const char enduser_setup_html_default[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x9d, 0x59, + 0xfb, 0x73, 0xdb, 0xc6, 0xf1, 0xff, 0x59, 0xf9, 0x2b, 0x56, 0x92, 0xbf, + 0x06, 0x64, 0x93, 0x10, 0xa9, 0x87, 0xe3, 0x91, 0x48, 0x66, 0xfc, 0x4d, + 0x9c, 0x47, 0x27, 0x76, 0x3c, 0x96, 0x32, 0x69, 0xc6, 0x55, 0x33, 0x47, + 0xe0, 0x40, 0x5c, 0x04, 0xe2, 0xd0, 0xbb, 0x83, 0x28, 0x36, 0xf1, 0xff, + 0xde, 0x5d, 0x2c, 0x8e, 0x20, 0x08, 0x95, 0xd3, 0x76, 0x62, 0x89, 0xb8, + 0xc3, 0xbe, 0xf7, 0xb3, 0x0f, 0x2a, 0x93, 0xc3, 0x6f, 0x7e, 0xfa, 0xfa, + 0xf6, 0xd7, 0x0f, 0x6f, 0x21, 0x73, 0xcb, 0x7c, 0xf6, 0xc5, 0x84, 0x3f, + 0xf0, 0x53, 0x8a, 0x64, 0xf6, 0xc5, 0xc1, 0x64, 0x29, 0x9d, 0x80, 0x42, + 0x2c, 0xe5, 0x34, 0x78, 0x50, 0x72, 0x55, 0x6a, 0xe3, 0x02, 0x88, 0x75, + 0xe1, 0x64, 0xe1, 0xa6, 0xc1, 0x4a, 0x25, 0x2e, 0x9b, 0x26, 0xf2, 0x41, + 0xc5, 0x72, 0x58, 0x1f, 0x06, 0xa0, 0x0a, 0xe5, 0x94, 0xc8, 0x87, 0x36, + 0x16, 0xb9, 0x9c, 0x8e, 0xa3, 0x51, 0x40, 0x72, 0x9c, 0x72, 0xb9, 0x9c, + 0xfd, 0xa2, 0xbe, 0x55, 0xf0, 0xa3, 0x5e, 0xa8, 0x62, 0x72, 0xca, 0x37, + 0xf8, 0xca, 0xba, 0x75, 0x2e, 0xc1, 0xad, 0x4b, 0x39, 0x75, 0xf2, 0xd1, + 0x9d, 0xc6, 0xd6, 0xe2, 0xf5, 0xc1, 0x0b, 0xf8, 0x03, 0x7f, 0x1f, 0x2c, + 0x85, 0x41, 0xf2, 0x2b, 0x18, 0x5d, 0xd3, 0xa9, 0x14, 0x49, 0xa2, 0x8a, + 0x45, 0x73, 0xfc, 0x8c, 0x3f, 0xf8, 0x8f, 0x6c, 0x1e, 0xe0, 0xe7, 0x5c, + 0x27, 0x6b, 0x66, 0xca, 0xa4, 0x5a, 0x64, 0xee, 0x0a, 0xc6, 0xa3, 0xd1, + 0xff, 0xd5, 0x7c, 0x29, 0x5a, 0x3c, 0x4c, 0xc5, 0x52, 0xe5, 0xeb, 0x2b, + 0xb0, 0xa2, 0xb0, 0x43, 0x2b, 0x8d, 0x4a, 0xeb, 0x77, 0xa4, 0x74, 0x28, + 0x72, 0xb5, 0x40, 0x2d, 0xb1, 0x44, 0xcf, 0x4c, 0x7d, 0x3d, 0x17, 0xf1, + 0xfd, 0xc2, 0xe8, 0xaa, 0x48, 0xae, 0xe0, 0xf8, 0xe2, 0xe2, 0x22, 0xb9, + 0xb8, 0xd8, 0xd2, 0x79, 0xdc, 0xc4, 0x80, 0xf5, 0x95, 0xda, 0xa2, 0xd3, + 0x1a, 0x05, 0x88, 0xb9, 0xd5, 0x79, 0xe5, 0x24, 0x4b, 0xd6, 0xa5, 0x37, + 0xdc, 0xb0, 0x41, 0x7c, 0x98, 0x6b, 0xe7, 0xf4, 0xd2, 0x9f, 0x72, 0x99, + 0x6e, 0xde, 0xd4, 0x31, 0xbc, 0x82, 0xf3, 0xb3, 0x51, 0xf9, 0x78, 0xbd, + 0xed, 0xc9, 0xc5, 0x6b, 0x7f, 0xe3, 0x03, 0x22, 0x2a, 0xa7, 0xb7, 0x0c, + 0x52, 0x45, 0x59, 0xb9, 0x3a, 0x0a, 0x15, 0x0a, 0x2f, 0xe8, 0xc9, 0xca, + 0x5c, 0xc6, 0x8d, 0x85, 0xc3, 0x95, 0x9c, 0xdf, 0x2b, 0xf4, 0xb3, 0x2c, + 0xa5, 0x30, 0xa2, 0x88, 0xe5, 0x15, 0x14, 0xba, 0x90, 0x8d, 0x3d, 0x26, + 0x91, 0x66, 0x68, 0x44, 0xa2, 0x2a, 0xdb, 0x8d, 0x6d, 0xaa, 0x64, 0x9e, + 0x58, 0xc9, 0x52, 0x1a, 0xc2, 0xd6, 0x8d, 0xc7, 0xa1, 0xcd, 0x44, 0xa2, + 0x57, 0x78, 0x83, 0xff, 0x8d, 0x2f, 0xcb, 0x47, 0x18, 0xe3, 0x8f, 0x59, + 0xcc, 0x45, 0x38, 0x1a, 0x00, 0xff, 0x8b, 0x2e, 0x4e, 0x5a, 0x72, 0xf5, + 0xcf, 0x3a, 0x7d, 0x8d, 0x46, 0xbc, 0xea, 0xa6, 0x95, 0xfc, 0x86, 0x73, + 0xfc, 0xd5, 0x4f, 0x41, 0x9a, 0xa6, 0xec, 0xbf, 0x2a, 0x86, 0x1c, 0x15, + 0x8e, 0x53, 0x37, 0x2a, 0x43, 0xd4, 0xbf, 0x1b, 0x95, 0xae, 0xed, 0x64, + 0x20, 0xe6, 0x48, 0x25, 0x70, 0x1c, 0xc7, 0xf1, 0x16, 0xf3, 0xd0, 0xa7, + 0x65, 0xcc, 0x42, 0x7d, 0x36, 0x3c, 0x8a, 0xf6, 0x7a, 0x10, 0xeb, 0x5c, + 0x1b, 0xb4, 0xf2, 0xec, 0xec, 0x6c, 0x03, 0x38, 0xe4, 0x7c, 0x85, 0xca, + 0x96, 0xba, 0xd0, 0xb6, 0x14, 0xb1, 0xec, 0xb8, 0x8a, 0xd1, 0xea, 0x58, + 0xea, 0x93, 0xb5, 0x97, 0xb9, 0x0d, 0xc8, 0xb0, 0x51, 0xe8, 0x30, 0x97, + 0xf8, 0xde, 0x20, 0x14, 0xf7, 0x8a, 0x67, 0x54, 0xb0, 0x78, 0x66, 0xf5, + 0x11, 0xed, 0x64, 0xb5, 0x0f, 0x86, 0xf3, 0xb2, 0x71, 0xb0, 0x32, 0x96, + 0xb8, 0x4a, 0xad, 0x36, 0x25, 0x92, 0x28, 0x5b, 0xe6, 0x62, 0x8d, 0xc1, + 0xc8, 0x75, 0x7c, 0xbf, 0xeb, 0xf7, 0x53, 0x65, 0x96, 0xc8, 0x58, 0x1b, + 0xc1, 0xa5, 0xc2, 0xf0, 0xeb, 0xd8, 0x4c, 0xd9, 0xbf, 0x7c, 0x2a, 0xf9, + 0xe7, 0xe3, 0xf9, 0xc5, 0xe5, 0x97, 0xfd, 0xa4, 0xec, 0xf8, 0x77, 0x95, + 0xea, 0xb8, 0xb2, 0x83, 0xf6, 0x9c, 0xe9, 0x07, 0x69, 0xc8, 0xeb, 0x3e, + 0x5a, 0x47, 0x70, 0x86, 0xda, 0x28, 0x08, 0x03, 0x3e, 0x93, 0xab, 0x5e, + 0xd3, 0x76, 0x77, 0x39, 0x6f, 0x93, 0x42, 0xd9, 0x97, 0xec, 0x5e, 0x27, + 0xeb, 0xaf, 0x5e, 0xbd, 0xea, 0x03, 0x89, 0xd1, 0xbc, 0x2d, 0xe9, 0xa2, + 0x1b, 0x7f, 0x82, 0x5f, 0xd7, 0xff, 0x2e, 0x7d, 0x54, 0x39, 0x95, 0x2b, + 0xb7, 0x6e, 0xf4, 0xe7, 0x5a, 0x60, 0x68, 0xeb, 0x46, 0xc2, 0xca, 0x73, + 0x29, 0x50, 0x0c, 0x2a, 0xcb, 0x1a, 0xe5, 0x8f, 0xc3, 0x26, 0x38, 0x5f, + 0x5e, 0x52, 0x6c, 0xba, 0x36, 0x73, 0x22, 0xfb, 0x48, 0x65, 0x9b, 0x59, + 0xf9, 0x6e, 0x97, 0xad, 0x0b, 0xba, 0x5f, 0x8d, 0xde, 0xf6, 0x9e, 0xa5, + 0x6d, 0xfc, 0xfd, 0xcd, 0xff, 0x90, 0x81, 0xae, 0xe8, 0xe3, 0xc4, 0xe8, + 0x12, 0x59, 0x8a, 0x01, 0x1d, 0xd2, 0x33, 0xfe, 0x38, 0xaf, 0x3f, 0xe6, + 0xf7, 0x67, 0x2c, 0xd9, 0x03, 0xd1, 0x63, 0xaa, 0xc7, 0xbc, 0xdb, 0xa6, + 0x8d, 0xcc, 0x11, 0x85, 0x0f, 0xf2, 0xc9, 0x32, 0x27, 0x8b, 0x31, 0xda, + 0x2b, 0xee, 0xb1, 0x9d, 0x36, 0x7c, 0x89, 0xdd, 0x63, 0x5f, 0xcb, 0xf0, + 0x7a, 0x45, 0x99, 0x2b, 0xbb, 0x77, 0x38, 0xf4, 0xb4, 0xf6, 0x66, 0x96, + 0x9f, 0x1e, 0x7e, 0x44, 0xf4, 0x86, 0xc7, 0x9e, 0xae, 0xd6, 0x9b, 0x79, + 0xbd, 0x26, 0xd4, 0xab, 0xb8, 0xd6, 0x76, 0x63, 0xf4, 0xaa, 0x8b, 0xd4, + 0xd7, 0xaf, 0x5f, 0x5f, 0xef, 0x71, 0xa5, 0x19, 0x6e, 0xaf, 0x59, 0x0e, + 0x1b, 0x3e, 0xde, 0x91, 0xaa, 0x58, 0x62, 0x7f, 0xd8, 0x36, 0x44, 0x93, + 0xd3, 0x7a, 0x0f, 0xc0, 0x15, 0xe4, 0x94, 0x77, 0x8f, 0x2f, 0x26, 0x34, + 0xcf, 0x69, 0x41, 0x48, 0xd4, 0x03, 0xa8, 0x64, 0xda, 0x4c, 0x5c, 0xda, + 0x0d, 0x26, 0x7e, 0x2c, 0xd1, 0xc1, 0x13, 0x34, 0x7b, 0xc8, 0x0f, 0xc9, + 0x6c, 0x72, 0x8a, 0x37, 0x9d, 0x57, 0xe9, 0x18, 0x8f, 0x74, 0xce, 0xce, + 0x67, 0x5f, 0xeb, 0xa2, 0xa0, 0x56, 0xcb, 0xe4, 0xe0, 0x34, 0xac, 0x75, + 0x65, 0xe0, 0x17, 0x35, 0xfc, 0x56, 0xa1, 0xf2, 0xf3, 0x86, 0x32, 0xd5, + 0x66, 0x09, 0x22, 0x26, 0x77, 0xa7, 0x47, 0xa7, 0xa8, 0x6b, 0xa5, 0x52, + 0x75, 0x04, 0x4b, 0xe9, 0x32, 0x9d, 0x4c, 0x8f, 0x3e, 0xfc, 0x74, 0x73, + 0x7b, 0x44, 0xa4, 0x44, 0xcb, 0xdd, 0x86, 0x14, 0x15, 0x48, 0xa7, 0xcd, + 0xbd, 0xe5, 0x7d, 0xa6, 0xb9, 0x8f, 0x73, 0x61, 0xed, 0xb4, 0xa9, 0x08, + 0xb4, 0x8e, 0xaf, 0x3d, 0xb3, 0xb7, 0x9e, 0xa1, 0x4a, 0xd7, 0x7c, 0x8f, + 0xe9, 0xaa, 0x45, 0xd6, 0xf9, 0x98, 0x3d, 0x3f, 0x7e, 0x3c, 0xbb, 0x9c, + 0xc7, 0xd7, 0x18, 0xa7, 0x52, 0xb4, 0x44, 0x3c, 0x36, 0x88, 0x8c, 0x21, + 0xc7, 0xbb, 0x1a, 0x3f, 0xa3, 0x26, 0x7e, 0xed, 0x35, 0x71, 0x58, 0xf8, + 0x99, 0x27, 0x23, 0xf2, 0x59, 0xab, 0x12, 0xe6, 0x22, 0x07, 0x7f, 0xa3, + 0x63, 0xbb, 0x8c, 0xd5, 0x15, 0x10, 0x6b, 0x63, 0x50, 0xca, 0x54, 0xa7, + 0x29, 0x9f, 0x45, 0xa9, 0x9c, 0xc8, 0xb1, 0xad, 0x4c, 0xa9, 0xde, 0xa0, + 0xcc, 0x11, 0x57, 0x99, 0xce, 0x11, 0x88, 0xd3, 0xa0, 0x0e, 0x23, 0xbc, + 0x47, 0x79, 0x01, 0x9c, 0x76, 0x95, 0xb5, 0x4a, 0x4a, 0x8c, 0x07, 0x86, + 0xe9, 0xbf, 0x55, 0xc4, 0x34, 0xcb, 0x32, 0x97, 0x4e, 0x12, 0x51, 0x47, + 0xf3, 0x87, 0x46, 0x66, 0xab, 0xf5, 0x70, 0x38, 0x84, 0x5f, 0x75, 0x05, + 0x31, 0xc6, 0x11, 0x01, 0x0f, 0xb5, 0x15, 0x16, 0x32, 0x69, 0x50, 0x54, + 0x91, 0x40, 0x26, 0x1e, 0x24, 0xb8, 0x4c, 0x2e, 0xa1, 0xd4, 0x25, 0x54, + 0x25, 0x12, 0x30, 0x14, 0xf2, 0x4a, 0x40, 0xac, 0x13, 0x7a, 0x69, 0x74, + 0xb5, 0xc8, 0x88, 0x08, 0x52, 0x95, 0x4b, 0x90, 0x95, 0x45, 0xe3, 0x8d, + 0x58, 0xda, 0x88, 0x88, 0x86, 0xc3, 0x8e, 0x87, 0xec, 0xce, 0x91, 0xad, + 0xe6, 0x4b, 0xe5, 0x8e, 0xe0, 0x41, 0xe4, 0x15, 0x1e, 0x6f, 0x50, 0xcd, + 0x11, 0x1a, 0xc5, 0x29, 0x20, 0x58, 0x31, 0x34, 0xfb, 0x20, 0x3d, 0xf3, + 0x20, 0x1d, 0xcf, 0x6e, 0xaa, 0x38, 0x96, 0xd6, 0x1e, 0x22, 0x20, 0x3d, + 0x74, 0x1b, 0x2a, 0x85, 0x47, 0x0f, 0x65, 0xf4, 0xce, 0x78, 0x1c, 0x67, + 0xc2, 0x82, 0x65, 0xae, 0xb4, 0xca, 0xf3, 0x35, 0xc4, 0x8c, 0x73, 0x99, + 0x10, 0xc4, 0xc9, 0x03, 0x4e, 0x4d, 0x83, 0xd0, 0x68, 0x32, 0x37, 0x18, + 0x2a, 0xfc, 0x7d, 0x4a, 0x62, 0x60, 0x29, 0xd6, 0x50, 0x60, 0xdd, 0xc7, + 0xb9, 0xb6, 0xe4, 0xb8, 0xb2, 0x80, 0x2b, 0x23, 0x94, 0x62, 0x21, 0x23, + 0x5f, 0x15, 0x1d, 0xa3, 0xfb, 0xe6, 0x7b, 0x9a, 0xec, 0x6c, 0x76, 0x6b, + 0xd6, 0xd8, 0x5f, 0xa2, 0x88, 0x58, 0xc9, 0xab, 0x6e, 0x91, 0x50, 0xdf, + 0xee, 0xd7, 0x47, 0xd0, 0x14, 0x48, 0x30, 0xfb, 0x4e, 0xc3, 0xff, 0xe3, + 0xb0, 0x21, 0xbb, 0xd9, 0xe6, 0x1b, 0xe9, 0xaa, 0xd2, 0xd7, 0x4d, 0x47, + 0x3d, 0x3e, 0xb4, 0xbd, 0x80, 0x74, 0x5f, 0x90, 0x82, 0xc0, 0xba, 0x60, + 0xf6, 0x73, 0x99, 0x08, 0x87, 0x56, 0xc0, 0x8d, 0x13, 0xae, 0xb2, 0x6c, + 0xcc, 0x05, 0x52, 0x79, 0xde, 0x89, 0x8d, 0x8d, 0x2a, 0x6b, 0xbe, 0x07, + 0x61, 0xe0, 0x19, 0x4c, 0x21, 0xad, 0x8a, 0xba, 0xe2, 0x21, 0xe4, 0xca, + 0xd1, 0xe6, 0x04, 0xfe, 0x00, 0x83, 0xea, 0x4d, 0x01, 0x09, 0x0e, 0xb7, + 0xa5, 0x2c, 0x5c, 0xf4, 0x8f, 0x4a, 0x9a, 0xf5, 0x4d, 0x43, 0xd0, 0x52, + 0x5e, 0xc3, 0xe7, 0xeb, 0x46, 0x96, 0x98, 0xa3, 0xb0, 0x67, 0x61, 0x70, + 0xec, 0xfb, 0x41, 0x70, 0x32, 0x00, 0x51, 0x36, 0x97, 0x5c, 0x9e, 0xc1, + 0x89, 0xa7, 0xb6, 0x4e, 0x97, 0x6f, 0xf2, 0x9c, 0xf4, 0x8b, 0xdc, 0xca, + 0x01, 0x18, 0x81, 0x3f, 0x76, 0x00, 0x8c, 0x24, 0x4a, 0x21, 0xbf, 0xc2, + 0x76, 0x8b, 0x2c, 0xcf, 0xa2, 0xca, 0xe4, 0x1f, 0x08, 0x85, 0x1d, 0x8b, + 0xa9, 0xbc, 0x4e, 0xb8, 0xcb, 0x92, 0x50, 0x23, 0x6d, 0x95, 0x3b, 0x8b, + 0x24, 0x85, 0x5c, 0xc1, 0x47, 0xb9, 0x78, 0xfb, 0x58, 0x86, 0xc1, 0xa7, + 0xbf, 0x7d, 0xf5, 0xfc, 0x2e, 0x80, 0x97, 0x40, 0xd4, 0xf8, 0x11, 0x4c, + 0xc3, 0x4f, 0x7f, 0x7f, 0x7e, 0x7c, 0xf7, 0xe2, 0x24, 0x38, 0x89, 0xe4, + 0xa3, 0x8c, 0xc3, 0x95, 0x2a, 0xb0, 0x0d, 0x45, 0xb9, 0x8e, 0x05, 0xc9, + 0x8d, 0x32, 0x23, 0x53, 0x5e, 0xe0, 0x55, 0x0a, 0xe1, 0x46, 0x2a, 0x8a, + 0x45, 0x94, 0x6d, 0x45, 0x87, 0x8e, 0xd7, 0x9f, 0x89, 0x4e, 0xa2, 0xa1, + 0x5b, 0x51, 0x93, 0x54, 0x4a, 0x3f, 0x7f, 0xfc, 0xc1, 0xf3, 0x7e, 0x1a, + 0xdf, 0x9d, 0xc0, 0x9f, 0x7f, 0xc2, 0xa8, 0xa6, 0xa6, 0x9f, 0x8d, 0x0f, + 0x36, 0xd3, 0xab, 0x30, 0x1d, 0xc0, 0x1a, 0xe5, 0x7a, 0x8d, 0xeb, 0x56, + 0x17, 0x3e, 0x02, 0x2f, 0x93, 0xcf, 0xc2, 0xf4, 0x24, 0xaa, 0x07, 0x46, + 0xc4, 0xb3, 0x9f, 0x5e, 0xd5, 0x94, 0x29, 0x7c, 0x05, 0x41, 0xbd, 0x8f, + 0x06, 0x70, 0x05, 0x01, 0xf5, 0x8d, 0xe0, 0x7a, 0x57, 0x4f, 0xa6, 0x12, + 0x89, 0x12, 0x48, 0xc9, 0xd3, 0xb2, 0xfe, 0x1d, 0xa3, 0xd3, 0x61, 0x3c, + 0x1f, 0xc0, 0x63, 0xc3, 0xda, 0xb8, 0x68, 0xa5, 0xbb, 0x55, 0x4b, 0xa9, + 0x2b, 0x47, 0x6f, 0x69, 0x82, 0x8f, 0xe0, 0x05, 0x12, 0xf5, 0xd8, 0x31, + 0x94, 0x26, 0xdc, 0xf2, 0xed, 0xb0, 0xc9, 0xfc, 0x09, 0x5e, 0x20, 0x99, + 0x74, 0x71, 0x16, 0x06, 0xa7, 0x96, 0xf1, 0xfa, 0xbb, 0xd5, 0xc5, 0x57, + 0xc5, 0x94, 0x92, 0xf5, 0x4e, 0xb8, 0x2c, 0x32, 0x02, 0x13, 0xb3, 0x0c, + 0x11, 0x48, 0xc1, 0x77, 0x6f, 0x6f, 0x83, 0x01, 0xe5, 0xf5, 0xc6, 0x0d, + 0xe0, 0xac, 0xaf, 0x27, 0xae, 0xcc, 0xc6, 0x3d, 0x8a, 0x29, 0x62, 0x2e, + 0x1d, 0x23, 0x47, 0x93, 0x48, 0x7f, 0x75, 0xd6, 0xbf, 0x3a, 0xa7, 0xab, + 0x9e, 0x40, 0x56, 0x15, 0x22, 0x22, 0x13, 0x96, 0xca, 0xcb, 0xa7, 0x77, + 0xda, 0x58, 0x16, 0x62, 0x10, 0x17, 0x14, 0x22, 0x72, 0x73, 0x00, 0xe7, + 0x78, 0xe9, 0x1d, 0xb5, 0x70, 0x38, 0xc5, 0x75, 0x78, 0xd4, 0x70, 0x1f, + 0x50, 0x15, 0x50, 0x05, 0x44, 0xaa, 0x28, 0xa4, 0xb9, 0xc5, 0x01, 0x40, + 0x31, 0x7f, 0xb3, 0x12, 0x6a, 0xab, 0x62, 0x21, 0x24, 0xdf, 0x2d, 0xa1, + 0xf4, 0x84, 0x52, 0x81, 0x36, 0x01, 0x63, 0x0b, 0x9f, 0x59, 0x2e, 0x75, + 0x11, 0x9d, 0x42, 0x82, 0x99, 0x47, 0x7e, 0xeb, 0x0c, 0x72, 0x07, 0x5e, + 0xc9, 0x01, 0x5e, 0xc3, 0x5f, 0x6e, 0x7e, 0x7a, 0x1f, 0x95, 0xc2, 0x58, + 0x19, 0x26, 0x6c, 0x25, 0x7a, 0xb6, 0xb1, 0xc1, 0xaf, 0x0c, 0x3b, 0x96, + 0x1c, 0x7d, 0x53, 0xdf, 0x5f, 0xc1, 0x11, 0x2a, 0x4f, 0x22, 0xa6, 0x52, + 0x09, 0xf9, 0xd3, 0x54, 0x57, 0x8c, 0x54, 0x09, 0xca, 0x55, 0xa4, 0x71, + 0xeb, 0xde, 0x12, 0xfb, 0x27, 0x56, 0x1f, 0xfc, 0x90, 0xe4, 0x32, 0x18, + 0x34, 0x87, 0x66, 0xed, 0xe0, 0xb6, 0xb8, 0xb9, 0xfd, 0x56, 0xa8, 0x5c, + 0x26, 0x30, 0x84, 0x95, 0xd1, 0xe8, 0xb8, 0x1f, 0x8c, 0xbd, 0xf7, 0xbe, + 0x6d, 0x43, 0xa1, 0x1d, 0xa4, 0xba, 0x2a, 0x76, 0x48, 0xda, 0x23, 0x77, + 0xcc, 0xa7, 0x27, 0xc1, 0x61, 0x50, 0x13, 0xdd, 0x7d, 0x4a, 0x22, 0x06, + 0xd9, 0x1d, 0x9b, 0xce, 0x39, 0x72, 0x9b, 0x4a, 0x63, 0x51, 0xb6, 0x0e, + 0xc5, 0xd1, 0x16, 0xc9, 0x61, 0xdb, 0x90, 0x9e, 0x3f, 0x07, 0x2f, 0x04, + 0x66, 0x30, 0xee, 0x9c, 0x27, 0x70, 0xd9, 0x11, 0xf1, 0x5e, 0x22, 0x83, + 0xa0, 0x79, 0xa8, 0x12, 0x78, 0xdf, 0x38, 0x42, 0x13, 0xd8, 0xcf, 0x6c, + 0xaf, 0xe3, 0x49, 0x58, 0x58, 0xb7, 0x65, 0x81, 0xd7, 0x41, 0x09, 0x47, + 0x2d, 0x3e, 0xd3, 0x08, 0x78, 0x06, 0x74, 0x93, 0xe2, 0x83, 0xb6, 0xa5, + 0x3a, 0x53, 0x49, 0xba, 0xec, 0x81, 0x56, 0x30, 0xad, 0x07, 0x95, 0x97, + 0xee, 0x3d, 0xda, 0x95, 0x3d, 0x0e, 0x3c, 0x3d, 0xfd, 0xee, 0xb5, 0x2e, + 0x2e, 0x5e, 0x6c, 0xcc, 0x83, 0x66, 0x45, 0x1c, 0x40, 0x2c, 0xf2, 0x9c, + 0xbe, 0x34, 0x0d, 0xc0, 0xa1, 0xce, 0xdf, 0x50, 0xe9, 0x56, 0x7b, 0x7e, + 0xcc, 0x4c, 0xd3, 0x9a, 0xff, 0xfa, 0xee, 0xc7, 0xef, 0x9d, 0x2b, 0x3f, + 0x4a, 0x1c, 0x2b, 0xd6, 0x85, 0xac, 0x05, 0x5f, 0x47, 0xba, 0xc8, 0xb5, + 0x48, 0x64, 0x91, 0x74, 0xda, 0xbc, 0xb7, 0xcb, 0x4b, 0x0f, 0x89, 0x94, + 0xcd, 0x1e, 0x00, 0x3d, 0x1b, 0x69, 0x4b, 0x5d, 0x58, 0x49, 0xe1, 0x63, + 0x61, 0x9f, 0x5b, 0x89, 0x8e, 0xbd, 0xdf, 0x2f, 0x71, 0x38, 0x1e, 0x30, + 0x0e, 0x76, 0xb8, 0x4b, 0x59, 0x84, 0xde, 0xb9, 0xda, 0x53, 0x8a, 0x6d, + 0x6b, 0xaf, 0x95, 0xae, 0x71, 0xe2, 0x7b, 0x89, 0x76, 0x63, 0xd4, 0xde, + 0x20, 0x08, 0x4b, 0x87, 0x2d, 0x25, 0x10, 0x65, 0x99, 0x2b, 0x9e, 0x28, + 0xa7, 0xd4, 0xd8, 0x82, 0x96, 0xad, 0x35, 0x29, 0xf4, 0x71, 0xa2, 0xf1, + 0x30, 0xc6, 0x66, 0xf1, 0xa2, 0xee, 0xa5, 0x5b, 0x0a, 0x8a, 0x24, 0xec, + 0x37, 0xa7, 0x85, 0x76, 0x6f, 0x4a, 0x6a, 0x4e, 0x24, 0x78, 0x2b, 0xc4, + 0x34, 0x64, 0x37, 0x83, 0x8b, 0x11, 0x83, 0x2d, 0x88, 0x90, 0x4a, 0x84, + 0x70, 0xd8, 0x80, 0xbd, 0xdf, 0x4e, 0xe8, 0x75, 0xa7, 0xa3, 0x78, 0x9e, + 0x28, 0x97, 0xc5, 0xc2, 0x65, 0x08, 0x8f, 0xd1, 0x06, 0x1e, 0xa4, 0xa5, + 0xdb, 0x67, 0x88, 0xb2, 0x87, 0xad, 0xbe, 0x6c, 0x3d, 0xff, 0x5d, 0xc6, + 0x2e, 0xd8, 0x15, 0x44, 0x04, 0x9d, 0x3e, 0x45, 0xf7, 0x91, 0xd5, 0xc6, + 0x85, 0x6d, 0xca, 0xc4, 0x00, 0xe6, 0x9e, 0xd1, 0x4f, 0xa1, 0x79, 0x64, + 0xac, 0x55, 0x30, 0x04, 0x51, 0x3f, 0x34, 0x32, 0xc8, 0x90, 0x26, 0x1e, + 0xba, 0xb4, 0x80, 0x7a, 0x27, 0xba, 0x24, 0x21, 0x33, 0x5e, 0x60, 0x40, + 0xf8, 0x8a, 0xac, 0x17, 0xa4, 0xe6, 0x5d, 0xc0, 0x5c, 0xa9, 0x36, 0x10, + 0x12, 0xab, 0x42, 0xc6, 0xd1, 0x35, 0x7e, 0x4c, 0xea, 0xa8, 0x36, 0x71, + 0xb8, 0x86, 0x97, 0x2f, 0xd5, 0xc6, 0x0c, 0x12, 0xff, 0x72, 0x4b, 0x3e, + 0x35, 0x6f, 0x22, 0xfe, 0xa4, 0xee, 0x22, 0xb4, 0x27, 0xc1, 0x63, 0xd0, + 0x51, 0xe0, 0xb1, 0x75, 0x20, 0x4a, 0x2e, 0xf8, 0xef, 0x6f, 0xdf, 0xfd, + 0x88, 0x8a, 0x50, 0x10, 0xbf, 0x15, 0x73, 0x9a, 0xc8, 0x62, 0x9e, 0xb7, + 0x0b, 0x10, 0xbf, 0x70, 0x7a, 0x81, 0x19, 0xa7, 0xec, 0x79, 0x0c, 0x7a, + 0x7a, 0x5d, 0xc4, 0x88, 0xb3, 0x7b, 0x24, 0xaf, 0x69, 0x7a, 0x53, 0x03, + 0x69, 0xba, 0x33, 0xe7, 0xbd, 0xf6, 0xad, 0xd5, 0x72, 0x5f, 0xed, 0x4f, + 0x9d, 0x03, 0x23, 0xda, 0xb9, 0xf6, 0xa6, 0x1c, 0xc0, 0x25, 0xeb, 0xeb, + 0xf5, 0x00, 0x36, 0x4b, 0x3e, 0x0c, 0x50, 0x92, 0x89, 0xe5, 0xf6, 0xa0, + 0xaf, 0x2f, 0x08, 0xd6, 0xa2, 0xdc, 0xdd, 0x35, 0xa6, 0x7e, 0x5f, 0xf1, + 0x91, 0xac, 0xb7, 0x93, 0xc0, 0xff, 0xed, 0xc2, 0x97, 0x8a, 0x1f, 0xd1, + 0x14, 0x4a, 0xbe, 0xea, 0x3b, 0x73, 0x13, 0x8b, 0x82, 0x74, 0xfb, 0x94, + 0xda, 0xe0, 0x89, 0xc0, 0x90, 0x17, 0xfd, 0xc8, 0xb0, 0xfc, 0xbe, 0x5a, + 0xb6, 0x66, 0xbf, 0xda, 0x77, 0xa2, 0xa8, 0x44, 0x0e, 0x6f, 0x0b, 0x67, + 0xd6, 0xc1, 0xd3, 0xa1, 0x61, 0xa5, 0xbe, 0xd5, 0xf4, 0xec, 0x96, 0xc2, + 0xc4, 0x19, 0x4d, 0x7e, 0x32, 0xde, 0xe7, 0x03, 0x01, 0x89, 0xd2, 0x7a, + 0x38, 0xe0, 0x86, 0xde, 0x87, 0x8d, 0x07, 0x1e, 0x78, 0xda, 0x19, 0x85, + 0xa3, 0x40, 0xa9, 0x3d, 0x64, 0xef, 0x59, 0xbe, 0x78, 0x37, 0xdf, 0xb7, + 0x77, 0x71, 0xbf, 0xa1, 0x35, 0x6f, 0xd3, 0x8a, 0x78, 0x67, 0xe6, 0x86, + 0xbd, 0xdd, 0xad, 0xbd, 0xbf, 0xb9, 0x74, 0x80, 0xb1, 0x21, 0x07, 0xa7, + 0xd0, 0xae, 0xef, 0x61, 0xc0, 0x97, 0x14, 0xd7, 0xff, 0x30, 0x9b, 0x7b, + 0x92, 0xb9, 0xfd, 0xcd, 0x82, 0x28, 0x32, 0x51, 0x2c, 0x64, 0xbf, 0xd1, + 0x33, 0x65, 0x93, 0xcf, 0xa8, 0xfe, 0x8e, 0xda, 0xf9, 0x5a, 0xe2, 0x2f, + 0x39, 0x8f, 0x1b, 0xc9, 0xf3, 0x7b, 0x1c, 0xae, 0x5e, 0x71, 0x4f, 0x6a, + 0x77, 0x4e, 0xd6, 0x9c, 0xfd, 0x85, 0x70, 0x14, 0x35, 0x85, 0xa3, 0xd2, + 0xd0, 0x87, 0xe3, 0x04, 0x88, 0xed, 0x08, 0x17, 0xcf, 0xa3, 0x26, 0x9a, + 0x00, 0x93, 0x53, 0xff, 0xc5, 0x6c, 0x72, 0xca, 0x7f, 0x03, 0xc2, 0x07, + 0xfe, 0x1f, 0x53, 0xff, 0x02, 0x2a, 0x13, 0x18, 0xb6, 0xb0, 0x1a, 0x00, + 0x00 +}; +unsigned int enduser_setup_html_default_len = 2569; diff --git a/app/modules/eus/prepare.sh b/app/modules/enduser_setup/prepare.sh similarity index 65% rename from app/modules/eus/prepare.sh rename to app/modules/enduser_setup/prepare.sh index 133ea9bb..063a287e 100644 --- a/app/modules/eus/prepare.sh +++ b/app/modules/enduser_setup/prepare.sh @@ -3,5 +3,5 @@ # Uses zopfli for better gzip compression # sudo apt-get install zopfli zopfli --gzip ./enduser_setup.html -xxd -i ./enduser_setup.html.gz | sed 's/unsigned char/static const char/; s/__enduser_setup_html_gz/http_html_backup/' > http_html_backup.def +xxd -i ./enduser_setup.html.gz | sed 's/unsigned char/static const char/; s/__enduser_setup_html_gz/enduser_setup_html_default/' > enduser_setup.html.gz.def.h diff --git a/app/modules/eus/enduser_setup.html.gz b/app/modules/eus/enduser_setup.html.gz deleted file mode 100644 index a8897cd6937d23a40a36ece175e76e33f66fce48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2423 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 diff --git a/app/modules/eus/http_html_backup.def b/app/modules/eus/http_html_backup.def deleted file mode 100644 index 97e5592a..00000000 --- a/app/modules/eus/http_html_backup.def +++ /dev/null @@ -1,205 +0,0 @@ -static const char http_html_backup[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x95, 0x59, - 0x7b, 0x73, 0xdb, 0x36, 0x12, 0xff, 0xdb, 0xf9, 0x14, 0xeb, 0xba, 0x17, - 0xca, 0x8d, 0xde, 0xb2, 0xd3, 0x8c, 0xf5, 0xe8, 0xe4, 0xfa, 0xbe, 0x49, - 0xd2, 0x4e, 0xed, 0x4e, 0xaf, 0x93, 0xc9, 0x74, 0x20, 0x12, 0xb4, 0x50, - 0x53, 0x00, 0x0f, 0x00, 0x2d, 0xeb, 0xda, 0x7c, 0xf7, 0xdb, 0xe5, 0x12, - 0xa2, 0x28, 0xaa, 0x9a, 0xeb, 0x34, 0x7a, 0x10, 0xd8, 0xc7, 0xee, 0x6f, - 0x1f, 0xbb, 0x72, 0x67, 0xe7, 0x5f, 0xfd, 0xf0, 0xe5, 0xdd, 0xaf, 0x3f, - 0x7e, 0x0d, 0x2b, 0xbf, 0xce, 0x16, 0xcf, 0x66, 0xfc, 0x81, 0x9f, 0x52, - 0x24, 0x8b, 0x67, 0x67, 0xb3, 0xb5, 0xf4, 0x02, 0xb4, 0x58, 0xcb, 0x79, - 0xf4, 0xa8, 0xe4, 0x26, 0x37, 0xd6, 0x47, 0x10, 0x1b, 0xed, 0xa5, 0xf6, - 0xf3, 0x68, 0xa3, 0x12, 0xbf, 0x9a, 0x27, 0xf2, 0x51, 0xc5, 0xb2, 0x57, - 0x3e, 0x74, 0x41, 0x69, 0xe5, 0x95, 0xc8, 0x7a, 0x2e, 0x16, 0x99, 0x9c, - 0x8f, 0xfa, 0xc3, 0x88, 0xe4, 0x78, 0xe5, 0x33, 0xb9, 0xf8, 0x45, 0x7d, - 0xa3, 0xe0, 0x8d, 0xb9, 0x57, 0x7a, 0x36, 0xe0, 0x13, 0xbc, 0x72, 0x7e, - 0x9b, 0x49, 0xf0, 0xdb, 0x5c, 0xce, 0xbd, 0x7c, 0xf2, 0x83, 0xd8, 0x39, - 0x3c, 0x3e, 0xfb, 0x0c, 0xfe, 0xc0, 0xf7, 0xb3, 0xb5, 0xb0, 0x48, 0x7e, - 0x03, 0xc3, 0x29, 0x3d, 0xe5, 0x22, 0x49, 0x94, 0xbe, 0xaf, 0x1e, 0x3f, - 0xe2, 0x0b, 0xff, 0x91, 0xcd, 0x5d, 0xfc, 0x5c, 0x9a, 0x64, 0xcb, 0x4c, - 0x2b, 0xa9, 0xee, 0x57, 0xfe, 0x06, 0x46, 0xc3, 0xe1, 0x3f, 0x4a, 0xbe, - 0x14, 0x2d, 0xee, 0xa5, 0x62, 0xad, 0xb2, 0xed, 0x0d, 0x38, 0xa1, 0x5d, - 0xcf, 0x49, 0xab, 0xd2, 0xf2, 0x8e, 0x94, 0xf6, 0x44, 0xa6, 0xee, 0x51, - 0x4b, 0x2c, 0xd1, 0x33, 0x5b, 0x1e, 0x2f, 0x45, 0xfc, 0x70, 0x6f, 0x4d, - 0xa1, 0x93, 0x1b, 0xb8, 0xb8, 0xba, 0xba, 0x4a, 0xae, 0xae, 0xf6, 0x74, - 0x5e, 0x54, 0x18, 0xb0, 0xbe, 0xdc, 0x38, 0x74, 0xda, 0xa0, 0x00, 0xb1, - 0x74, 0x26, 0x2b, 0xbc, 0x64, 0xc9, 0x26, 0x0f, 0x86, 0x5b, 0x36, 0x88, - 0x1f, 0x96, 0xc6, 0x7b, 0xb3, 0x0e, 0x4f, 0x99, 0x4c, 0x77, 0x37, 0x25, - 0x86, 0x37, 0x30, 0x19, 0x0f, 0xf3, 0xa7, 0xe9, 0xbe, 0x27, 0x57, 0xaf, - 0xc2, 0x49, 0x00, 0x44, 0x14, 0xde, 0xec, 0x19, 0xa4, 0x74, 0x5e, 0xf8, - 0x12, 0x85, 0x02, 0x85, 0x6b, 0xfa, 0xe6, 0x64, 0x26, 0xe3, 0xca, 0xc2, - 0xde, 0x46, 0x2e, 0x1f, 0x14, 0xfa, 0x99, 0xe7, 0x52, 0x58, 0xa1, 0x63, - 0x79, 0x03, 0xda, 0x68, 0x59, 0xd9, 0x63, 0x13, 0x69, 0x7b, 0x56, 0x24, - 0xaa, 0x70, 0x4d, 0x6c, 0x53, 0x25, 0xb3, 0xc4, 0x49, 0x96, 0x52, 0x11, - 0xd6, 0x6e, 0x3c, 0xf5, 0xdc, 0x4a, 0x24, 0x66, 0x83, 0x27, 0xf8, 0xdf, - 0xe8, 0x3a, 0x7f, 0x82, 0x11, 0xbe, 0xec, 0xfd, 0x52, 0x74, 0x86, 0x5d, - 0xe0, 0x7f, 0xfd, 0xab, 0xcb, 0x9a, 0x5c, 0xfd, 0xb7, 0x0c, 0x5f, 0xa5, - 0x11, 0x8f, 0x9a, 0x61, 0x25, 0xbf, 0x61, 0x82, 0x6f, 0xed, 0x10, 0xa4, - 0x69, 0xca, 0xfe, 0x2b, 0xdd, 0x63, 0x54, 0x18, 0xa7, 0x26, 0x2a, 0x3d, - 0xd4, 0x7f, 0x88, 0x4a, 0xd3, 0x76, 0x32, 0x10, 0x63, 0xa4, 0x12, 0xb8, - 0x88, 0xe3, 0x78, 0x8f, 0xb9, 0x17, 0xc2, 0x32, 0x0a, 0x42, 0x39, 0x1a, - 0x21, 0x8b, 0x4e, 0x7a, 0x10, 0x9b, 0xcc, 0x58, 0xb4, 0x72, 0x3c, 0x1e, - 0xef, 0x12, 0x0e, 0x39, 0x5f, 0xa2, 0xb2, 0xb5, 0xd1, 0xc6, 0xe5, 0x22, - 0x96, 0x0d, 0x57, 0x11, 0xad, 0x86, 0xa5, 0x21, 0x58, 0x27, 0x99, 0x6b, - 0x40, 0x7a, 0x95, 0x42, 0x8f, 0xb1, 0xc4, 0x7b, 0x2b, 0xb5, 0x3f, 0x29, - 0x9e, 0xb3, 0x82, 0xc5, 0x33, 0x6b, 0x40, 0xb4, 0x1d, 0xd5, 0x46, 0x32, - 0x4c, 0xf2, 0xca, 0xc1, 0xc2, 0x3a, 0xe2, 0xca, 0x8d, 0xda, 0x95, 0x48, - 0xa2, 0x5c, 0x9e, 0x89, 0x2d, 0x82, 0x91, 0x99, 0xf8, 0xe1, 0xc0, 0xef, - 0xa3, 0x65, 0x96, 0xc8, 0xd8, 0x58, 0xc1, 0xa5, 0xc2, 0xe9, 0xd7, 0xb0, - 0x99, 0xa2, 0x7f, 0x7d, 0x2c, 0xf8, 0x93, 0xd1, 0xf2, 0xea, 0xfa, 0xf3, - 0xc3, 0xa0, 0xb4, 0xfc, 0xbb, 0x49, 0x4d, 0x5c, 0xb8, 0x6e, 0xfd, 0xbc, - 0x32, 0x8f, 0xd2, 0x92, 0xd7, 0xed, 0x6c, 0x1d, 0xc2, 0x18, 0xb5, 0x11, - 0x08, 0x5d, 0x7e, 0x26, 0x57, 0xf7, 0x35, 0x85, 0xee, 0x32, 0xa9, 0x83, - 0x42, 0xd1, 0x97, 0xec, 0x5e, 0x23, 0xea, 0x2f, 0x5f, 0xbe, 0x3c, 0x96, - 0x48, 0x21, 0x3b, 0x83, 0xa4, 0xab, 0x06, 0xfe, 0x9c, 0x7e, 0x4d, 0xff, - 0x1b, 0xf4, 0xfd, 0xc2, 0xab, 0x4c, 0xf9, 0x6d, 0xa5, 0x3f, 0x33, 0x02, - 0xa1, 0x2d, 0x1b, 0x09, 0x2b, 0xcf, 0xa4, 0x40, 0x31, 0xa8, 0x6c, 0x55, - 0x29, 0x7f, 0xea, 0x55, 0xe0, 0x7c, 0x7e, 0x4d, 0xd8, 0x34, 0x6d, 0x9e, - 0xe4, 0xc7, 0x33, 0x95, 0x6d, 0x66, 0xe5, 0x87, 0x5d, 0xb6, 0x2c, 0xe8, - 0x76, 0x35, 0x06, 0xdb, 0x5b, 0x96, 0x06, 0xfc, 0xf7, 0x4e, 0xfe, 0x7e, - 0x04, 0x9a, 0xa2, 0x2f, 0x12, 0x6b, 0x72, 0x64, 0xd1, 0x5d, 0x7a, 0x48, - 0xc7, 0xfc, 0x31, 0x29, 0x3f, 0x96, 0x0f, 0x63, 0x96, 0x1c, 0x12, 0x31, - 0xe4, 0x54, 0x8b, 0xf9, 0xb0, 0x4d, 0x5b, 0x99, 0x61, 0x16, 0x3e, 0xca, - 0xa3, 0x65, 0x4e, 0x16, 0x23, 0xda, 0x1b, 0xee, 0xb1, 0x8d, 0x36, 0x7c, - 0x8d, 0xdd, 0xe3, 0x54, 0xcb, 0x08, 0x7a, 0x45, 0x9e, 0x29, 0x77, 0x7a, - 0x38, 0x34, 0xb5, 0xb6, 0x67, 0x56, 0x98, 0x1e, 0x61, 0x44, 0xb4, 0x87, - 0xc7, 0xe9, 0xae, 0xd6, 0x9c, 0x79, 0xa1, 0x8f, 0x1c, 0xaf, 0xb8, 0xa6, - 0xed, 0xd6, 0x9a, 0x4d, 0x33, 0x53, 0x5f, 0xbd, 0x7a, 0x35, 0x3d, 0xe1, - 0x4a, 0x35, 0xdc, 0x5e, 0xb1, 0x1c, 0x36, 0x7c, 0x74, 0x20, 0x55, 0xa1, - 0xc4, 0xe3, 0xc3, 0x96, 0x89, 0x66, 0x83, 0x72, 0x0f, 0xc0, 0x15, 0x64, - 0xc0, 0xbb, 0xc7, 0xb3, 0x19, 0xcd, 0x73, 0x5a, 0x10, 0x12, 0xf5, 0x08, - 0x2a, 0x99, 0x57, 0x13, 0x17, 0x4f, 0xce, 0x66, 0x61, 0x2c, 0xd1, 0x43, - 0x20, 0xa8, 0xf6, 0x90, 0xef, 0x93, 0xc5, 0x6c, 0x80, 0x27, 0x8d, 0xab, - 0x74, 0x84, 0x8f, 0xf4, 0xbc, 0x9a, 0x2c, 0xbe, 0x34, 0x5a, 0x53, 0xab, - 0x65, 0x72, 0xf0, 0x06, 0xb6, 0xa6, 0xb0, 0xf0, 0x8b, 0xea, 0x7d, 0xa3, - 0x50, 0xf9, 0xa4, 0xa2, 0xe4, 0x0e, 0x42, 0xcc, 0x5a, 0xfa, 0x8d, 0xb1, - 0x0f, 0x8e, 0x77, 0x94, 0xea, 0x3c, 0xce, 0x84, 0x73, 0xf3, 0x2a, 0xcb, - 0x51, 0x23, 0x1f, 0x33, 0x6f, 0xd0, 0x5a, 0x65, 0x1f, 0x9f, 0xe2, 0x31, - 0x06, 0xa0, 0x14, 0x58, 0x22, 0xbc, 0x78, 0x7e, 0xf1, 0x34, 0xbe, 0x5e, - 0xc6, 0x53, 0xf4, 0x1c, 0xcf, 0x03, 0x0d, 0xcf, 0x01, 0xa2, 0xe2, 0x1c, - 0xe2, 0xe5, 0x8b, 0xbf, 0xa3, 0x1a, 0xbe, 0x66, 0x62, 0x76, 0x93, 0xbf, - 0xf2, 0xa0, 0x43, 0x2e, 0xe7, 0x54, 0x52, 0x2f, 0x53, 0x65, 0x06, 0xc7, - 0xc6, 0x5a, 0x64, 0x9a, 0x9b, 0x34, 0xe5, 0x67, 0x91, 0x2b, 0x2f, 0x32, - 0x6c, 0x0b, 0x73, 0xaa, 0x17, 0xc0, 0xd2, 0x89, 0xe5, 0xca, 0x64, 0x98, - 0x48, 0xf3, 0xa8, 0x84, 0x01, 0xde, 0xa1, 0xd2, 0x08, 0x06, 0x87, 0xc2, - 0x37, 0x2a, 0x55, 0xbf, 0xe5, 0xe8, 0x38, 0xe2, 0xf1, 0x77, 0xb5, 0x30, - 0xcd, 0x3a, 0xcf, 0xa4, 0x97, 0x44, 0xd4, 0x50, 0xfb, 0x63, 0x90, 0x39, - 0x68, 0xa1, 0xef, 0x8a, 0xe5, 0x5a, 0xf9, 0x7d, 0xec, 0x17, 0xb7, 0xe2, - 0x51, 0x36, 0x10, 0x3f, 0x12, 0xf0, 0x71, 0x08, 0xf8, 0x68, 0x71, 0x5b, - 0xc4, 0xb1, 0x74, 0xee, 0x1c, 0x83, 0x3b, 0x6a, 0x06, 0x48, 0xe1, 0x63, - 0x48, 0x8b, 0x5f, 0x31, 0x09, 0x42, 0x4e, 0xac, 0x84, 0x03, 0xc7, 0x5c, - 0x69, 0x91, 0x65, 0x5b, 0x88, 0x39, 0x67, 0x64, 0x42, 0xe9, 0xe2, 0x57, - 0x12, 0x18, 0xa6, 0x2a, 0x33, 0xfa, 0xb3, 0xa5, 0x45, 0xcb, 0xf1, 0x7d, - 0x40, 0x62, 0x60, 0x2d, 0xb6, 0xa0, 0xb1, 0x86, 0xe2, 0xcc, 0x38, 0x89, - 0xe4, 0xca, 0x01, 0xae, 0x5f, 0x90, 0x8b, 0x7b, 0xd9, 0x0f, 0x19, 0xd6, - 0x30, 0xba, 0x6d, 0x7e, 0xa0, 0x59, 0x8d, 0x17, 0x77, 0x76, 0x8b, 0xb5, - 0xda, 0xef, 0x13, 0xeb, 0xb8, 0x05, 0x0f, 0xf5, 0xc0, 0x76, 0x5e, 0x46, - 0x55, 0x62, 0x46, 0x8b, 0x6f, 0x0d, 0xfc, 0x13, 0x1b, 0x37, 0xd9, 0xcd, - 0x36, 0xdf, 0x4a, 0x5f, 0xe4, 0x47, 0xd1, 0xc3, 0x2f, 0x75, 0x5d, 0x91, - 0xee, 0x2b, 0x52, 0x10, 0x39, 0x1f, 0x2d, 0x7e, 0xce, 0x13, 0xe1, 0xd1, - 0x0a, 0xb8, 0xf5, 0xc2, 0x17, 0x8e, 0x8d, 0xb9, 0x42, 0xaa, 0xc0, 0x3b, - 0x73, 0xb1, 0x55, 0x79, 0xc9, 0xf7, 0x28, 0x2c, 0x7c, 0x0a, 0x73, 0x48, - 0x0b, 0x1d, 0x53, 0xb3, 0x80, 0x0e, 0x27, 0xad, 0xb1, 0x97, 0xf0, 0x07, - 0x58, 0x54, 0x6f, 0x35, 0x24, 0x38, 0x28, 0xd6, 0x52, 0xfb, 0xfe, 0x7f, - 0x0a, 0x69, 0xb7, 0xb7, 0x15, 0x41, 0x4d, 0x39, 0x85, 0x8f, 0xd3, 0x4a, - 0x96, 0x58, 0xa2, 0xb0, 0x4f, 0x3b, 0xd1, 0x45, 0xa8, 0xc3, 0xe8, 0xb2, - 0x0b, 0x22, 0xaf, 0x0e, 0xb9, 0x32, 0xa2, 0xcb, 0x40, 0xed, 0xbc, 0xc9, - 0x5f, 0x67, 0x19, 0xe9, 0x17, 0x99, 0x93, 0x5d, 0xb0, 0x02, 0x5f, 0xae, - 0x0b, 0x9c, 0x47, 0x18, 0xc2, 0x70, 0x35, 0x7d, 0x86, 0x2c, 0x3b, 0x23, - 0xdd, 0xca, 0x6c, 0x3a, 0x38, 0x88, 0xb6, 0x97, 0xdc, 0xa8, 0x54, 0x0a, - 0x9d, 0x2d, 0xcc, 0xe7, 0xa0, 0x31, 0x01, 0x2e, 0x01, 0xbf, 0x02, 0xef, - 0x31, 0x9f, 0x76, 0xd2, 0xcb, 0x7e, 0xd9, 0xab, 0xfa, 0x3c, 0x76, 0xe8, - 0xaa, 0xa4, 0x4c, 0xe1, 0x0b, 0x88, 0xca, 0x55, 0x28, 0x82, 0x1b, 0x88, - 0x28, 0xeb, 0xa3, 0xd0, 0x02, 0x77, 0x7a, 0x56, 0x2a, 0x91, 0x28, 0x81, - 0x95, 0x1c, 0x95, 0xf5, 0x17, 0x8c, 0xde, 0x74, 0xe2, 0x65, 0x17, 0x9e, - 0x2a, 0xd6, 0x0a, 0x47, 0x8c, 0xd5, 0x9d, 0x5a, 0x4b, 0x53, 0x78, 0xba, - 0xa5, 0xe1, 0x31, 0x84, 0xcf, 0x90, 0xa8, 0xc5, 0x6e, 0x65, 0x6a, 0x3b, - 0x7b, 0xbe, 0x9d, 0x57, 0x40, 0x5d, 0xe2, 0x01, 0x92, 0x49, 0x1f, 0xaf, - 0x3a, 0xd1, 0xc0, 0x71, 0x78, 0x7f, 0x77, 0x46, 0x7f, 0xa1, 0xe7, 0x11, - 0xbc, 0x80, 0xb7, 0xc2, 0xaf, 0xfa, 0x56, 0xe8, 0xc4, 0xac, 0x3b, 0x88, - 0x7b, 0xf4, 0xed, 0xd7, 0x77, 0x51, 0x17, 0xb4, 0xdc, 0xdc, 0xfa, 0x2e, - 0x8c, 0xdb, 0x7a, 0xe2, 0xc2, 0xee, 0xdc, 0x23, 0x4c, 0x31, 0x44, 0xe9, - 0x08, 0x39, 0x52, 0x22, 0xad, 0x8f, 0xc6, 0xed, 0xa3, 0x49, 0x38, 0x6a, - 0x08, 0x64, 0x55, 0x1d, 0x0c, 0x60, 0xc2, 0x52, 0x79, 0xef, 0x09, 0x4e, - 0x5b, 0xc7, 0x42, 0xac, 0x83, 0x39, 0x41, 0x44, 0x6e, 0x76, 0x61, 0x82, - 0x87, 0xc1, 0x51, 0x07, 0xe7, 0x73, 0xdc, 0xc4, 0x86, 0x15, 0xf7, 0x19, - 0x25, 0x0d, 0x25, 0x4c, 0x5f, 0x69, 0x2d, 0xed, 0x1d, 0xb6, 0x2f, 0xc2, - 0xfc, 0xf5, 0x46, 0xa8, 0xbd, 0x04, 0x87, 0x0e, 0xf9, 0xee, 0xf0, 0x15, - 0x5d, 0x52, 0x28, 0xd0, 0x26, 0x90, 0x98, 0x33, 0x24, 0xa3, 0x92, 0x4b, - 0x45, 0x67, 0x52, 0x48, 0x30, 0xf2, 0xc8, 0xef, 0xbc, 0x45, 0xee, 0x28, - 0x28, 0x39, 0xc3, 0x63, 0xf8, 0xd7, 0xed, 0x0f, 0xef, 0xfa, 0xb9, 0xb0, - 0x4e, 0x76, 0x12, 0xb6, 0x12, 0x3d, 0xdb, 0xd9, 0x10, 0xa6, 0xd5, 0x81, - 0x25, 0x9f, 0x7c, 0x55, 0x9e, 0xdf, 0xc0, 0x27, 0xa8, 0x3c, 0xe9, 0x33, - 0x95, 0x4a, 0x4a, 0x7f, 0x38, 0xc3, 0x63, 0xa4, 0x4a, 0x50, 0xae, 0x22, - 0x8d, 0x7b, 0xe7, 0x8e, 0xd8, 0xdf, 0xb3, 0xfa, 0xe8, 0xfb, 0x24, 0x93, - 0x51, 0xb7, 0x7a, 0xa8, 0x26, 0x1e, 0x77, 0x91, 0xdd, 0xe9, 0x37, 0x42, - 0x65, 0x32, 0x81, 0x1e, 0x6c, 0xac, 0x41, 0xc7, 0x43, 0x5b, 0x6f, 0xdf, - 0x57, 0x75, 0x07, 0xda, 0x78, 0x48, 0x4d, 0xa1, 0x0f, 0x49, 0xc2, 0x63, - 0x35, 0x3b, 0x8e, 0x37, 0xce, 0xf3, 0xa8, 0x24, 0xfa, 0xf0, 0x3e, 0xe9, - 0x73, 0x92, 0x7d, 0x60, 0xd3, 0x39, 0x46, 0x7e, 0x57, 0x69, 0x2c, 0xca, - 0x95, 0x50, 0x7c, 0xb2, 0x47, 0x72, 0x5e, 0xd7, 0xef, 0xf3, 0xe7, 0x10, - 0x84, 0xc0, 0x02, 0x46, 0x8d, 0xe7, 0x19, 0x5c, 0x37, 0x44, 0xbc, 0x93, - 0xc8, 0x20, 0xe0, 0x51, 0xd0, 0x6a, 0xf4, 0xae, 0x72, 0x04, 0xb3, 0x19, - 0xc2, 0xc4, 0x09, 0x3a, 0x8e, 0xa6, 0x85, 0xf3, 0x7b, 0x16, 0x04, 0x1d, - 0x65, 0xc0, 0xaf, 0x77, 0x91, 0xc6, 0x84, 0xe7, 0x84, 0xae, 0x42, 0x7c, - 0x56, 0x77, 0x20, 0x6f, 0x0b, 0x49, 0x87, 0xad, 0xa4, 0x15, 0x4c, 0x1b, - 0x92, 0x2a, 0x48, 0x0f, 0x1e, 0x1d, 0xca, 0x1e, 0x45, 0xbb, 0xf4, 0xe1, - 0xb7, 0x66, 0x85, 0x30, 0x32, 0xa1, 0xb8, 0x6b, 0x9c, 0x82, 0x01, 0x55, - 0x7e, 0x14, 0x96, 0x6c, 0xc2, 0x1a, 0x97, 0x9e, 0xe6, 0xf8, 0x17, 0xe5, - 0x30, 0xa7, 0x75, 0xa1, 0xac, 0x73, 0xa9, 0x63, 0x93, 0xc8, 0x9f, 0x7f, - 0xfa, 0xfe, 0x4b, 0x9c, 0xd1, 0x46, 0x4b, 0xed, 0x3b, 0x04, 0x09, 0xdd, - 0x23, 0x28, 0x88, 0x5f, 0x21, 0x2f, 0xa9, 0x1c, 0x9e, 0x37, 0x76, 0x80, - 0x53, 0xac, 0x0d, 0xc2, 0x9d, 0x8c, 0xe9, 0xf1, 0x12, 0xde, 0xf5, 0x20, - 0xb4, 0xf2, 0x78, 0x97, 0x09, 0x60, 0x4c, 0xa2, 0x76, 0x8f, 0xd8, 0x63, - 0x5d, 0x4b, 0xbf, 0x32, 0x49, 0x17, 0x62, 0x91, 0x65, 0xf4, 0x8b, 0xa5, - 0x0b, 0x1e, 0xf5, 0xfc, 0x86, 0x8a, 0x10, 0x9f, 0x00, 0xc5, 0xd3, 0xca, - 0xc2, 0x9c, 0xc4, 0xc3, 0xbf, 0xdf, 0xbe, 0xf9, 0xce, 0xfb, 0xfc, 0x27, - 0x89, 0x73, 0xc8, 0xf9, 0x0e, 0x6b, 0xc2, 0xeb, 0xbe, 0xd1, 0x99, 0x11, - 0x89, 0xd4, 0x49, 0x63, 0x92, 0x85, 0xc8, 0x04, 0xe9, 0x1d, 0x22, 0xe5, - 0xc0, 0x75, 0x81, 0xbe, 0x5b, 0xe9, 0x10, 0x02, 0x27, 0x29, 0x81, 0x58, - 0xd8, 0xc7, 0x5a, 0xa2, 0x67, 0x8f, 0x4f, 0x4b, 0xec, 0x8d, 0xba, 0x5c, - 0x09, 0x07, 0xdc, 0xb9, 0xd4, 0x9d, 0xe0, 0x5c, 0xe9, 0x29, 0x05, 0xb7, - 0xb6, 0x17, 0xa3, 0x5a, 0x39, 0xf1, 0x9d, 0x44, 0xbb, 0x11, 0xaa, 0xd7, - 0x58, 0x86, 0xb9, 0x8f, 0x10, 0x4d, 0x91, 0xe3, 0x90, 0x8c, 0x05, 0x29, - 0x1c, 0x50, 0x6b, 0x8f, 0x6a, 0xb6, 0xda, 0xa4, 0x4e, 0xc0, 0x09, 0xfe, - 0xfc, 0x13, 0x46, 0xd8, 0x2e, 0x3f, 0x2b, 0xa7, 0xc9, 0x9e, 0x02, 0x9d, - 0x74, 0xda, 0xd0, 0xdf, 0x1b, 0xff, 0x3a, 0xa7, 0xf6, 0x4c, 0x82, 0xf7, - 0x20, 0xa6, 0xa9, 0x3c, 0x0d, 0x3d, 0x98, 0x6b, 0x06, 0x9b, 0x30, 0xd5, - 0x2a, 0x11, 0xc2, 0x79, 0x55, 0xee, 0xed, 0x86, 0x4a, 0xd7, 0x8d, 0x9e, - 0x1a, 0x78, 0xfa, 0x99, 0xd4, 0xf7, 0x7e, 0x05, 0x0b, 0x18, 0xee, 0x0a, - 0x84, 0xb4, 0x34, 0x3b, 0x2d, 0x51, 0xb6, 0xab, 0xab, 0x25, 0xdb, 0x2c, - 0x7f, 0x97, 0xb1, 0x8f, 0x0e, 0x05, 0x11, 0x41, 0xa3, 0x53, 0xd3, 0x79, - 0xdf, 0x19, 0xeb, 0x3b, 0x75, 0xc8, 0x44, 0x17, 0x96, 0x81, 0x31, 0xcc, - 0xe1, 0x65, 0xdf, 0x62, 0xa9, 0x40, 0x0f, 0x44, 0xf9, 0xa5, 0x92, 0x41, - 0x86, 0x54, 0x78, 0x98, 0xdc, 0x51, 0xf5, 0xcd, 0x4c, 0x4e, 0x42, 0x16, - 0xbc, 0xf1, 0x80, 0x08, 0x3d, 0xa9, 0xdc, 0xa8, 0xaa, 0xbb, 0x88, 0xb9, - 0x52, 0x63, 0xa1, 0x43, 0xac, 0x0a, 0x19, 0x87, 0x53, 0xfc, 0x98, 0x95, - 0xa8, 0x56, 0x38, 0x4c, 0xe1, 0xc5, 0x0b, 0xb5, 0x33, 0x83, 0xc4, 0xbf, - 0xd8, 0x93, 0x4f, 0x75, 0x49, 0xc4, 0xef, 0xd5, 0x87, 0x3e, 0xd5, 0x30, - 0x95, 0x6e, 0x43, 0x41, 0xc8, 0xad, 0x33, 0x91, 0x73, 0xcb, 0xfb, 0xee, - 0xee, 0xed, 0x1b, 0x54, 0x84, 0x82, 0xf8, 0x56, 0x2c, 0x69, 0x27, 0x11, - 0xcb, 0xac, 0xde, 0x98, 0xf8, 0xc2, 0x9b, 0x7b, 0x8c, 0x38, 0x45, 0x2f, - 0xe4, 0x60, 0xa0, 0x37, 0x3a, 0xc6, 0x3c, 0x7b, 0x40, 0xf2, 0x92, 0xa6, - 0x35, 0x37, 0x91, 0xa6, 0x39, 0x75, 0xdf, 0x99, 0x30, 0x5c, 0x1c, 0x4f, - 0x96, 0xf6, 0xdc, 0x3d, 0xb3, 0xa2, 0x9e, 0xec, 0xaf, 0xf3, 0x2e, 0x5c, - 0xb3, 0xbe, 0x56, 0x17, 0x64, 0xb3, 0xe4, 0x63, 0x17, 0x25, 0xd9, 0x58, - 0xee, 0xaf, 0x3a, 0xe5, 0x01, 0xa5, 0xb5, 0xc8, 0x0f, 0xb7, 0xad, 0x79, - 0xd8, 0xd8, 0x02, 0x92, 0xe5, 0x7e, 0x16, 0x85, 0x3f, 0x1c, 0x84, 0x52, - 0x09, 0x4b, 0x0a, 0xb7, 0xc3, 0xe9, 0x51, 0x67, 0x6e, 0x63, 0xa1, 0x49, - 0x77, 0x08, 0xa9, 0x8b, 0x8e, 0x00, 0xc3, 0x5e, 0xb4, 0x91, 0x61, 0xf9, - 0x4d, 0xb5, 0xc1, 0x9a, 0xd3, 0x6a, 0xdf, 0x0a, 0x5d, 0x88, 0x0c, 0xbe, - 0xd6, 0xde, 0x6e, 0xa3, 0xe3, 0xd0, 0xb0, 0xd2, 0xd0, 0x6a, 0x5a, 0x76, - 0x4b, 0x61, 0xe3, 0x15, 0x56, 0x5a, 0x69, 0x7c, 0x88, 0x07, 0x26, 0x24, - 0x4a, 0x6b, 0xe5, 0x01, 0x4f, 0x94, 0x76, 0xda, 0x84, 0xc4, 0x83, 0x40, - 0xbb, 0x20, 0x38, 0x34, 0x4a, 0x6d, 0x66, 0xf6, 0xe9, 0xf5, 0x93, 0x97, - 0xf9, 0x53, 0x9b, 0x27, 0xf7, 0x1b, 0x5a, 0x74, 0x77, 0xad, 0x68, 0xa3, - 0x90, 0x64, 0xc3, 0x0d, 0x7b, 0xbf, 0x5b, 0x57, 0xfe, 0x02, 0xfc, 0x7f, - 0x81, 0x02, 0xf8, 0x8b, 0x40, 0x41, 0xe3, 0x77, 0x06, 0x91, 0xac, 0x84, - 0xbe, 0x97, 0xc7, 0xba, 0x38, 0xc0, 0xe1, 0xcc, 0x6c, 0xfc, 0x4a, 0x09, - 0x87, 0x2c, 0xf5, 0x63, 0x2d, 0x9c, 0x67, 0x36, 0x5e, 0xd7, 0xfa, 0xf9, - 0xa8, 0x26, 0xc1, 0xdf, 0x79, 0xf5, 0xfd, 0x71, 0xdd, 0xf5, 0xb6, 0xc0, - 0xf2, 0xcb, 0xf7, 0xe6, 0x62, 0x3c, 0xec, 0x5f, 0x57, 0xb8, 0x01, 0xcc, - 0x06, 0xe1, 0x37, 0xdb, 0x6c, 0xc0, 0x7f, 0x6a, 0xc1, 0x2f, 0xe5, 0xff, - 0xff, 0xf9, 0x1f, 0xa1, 0xc6, 0xa0, 0x64, 0x16, 0x1a, 0x00, 0x00 -}; -unsigned int http_html_backup_len = 2423; diff --git a/docs/img/enduser-setup-captive-portal.png b/docs/img/enduser-setup-captive-portal.png new file mode 100644 index 0000000000000000000000000000000000000000..92f52050e02aad134a671f31dcc528e4fb319ff2 GIT binary patch literal 34739 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 SX$GVXV6u`*5?R+x0{$1%yF5Su literal 0 HcmV?d00001 diff --git a/docs/img/enduser-setup.jpg b/docs/img/enduser-setup.jpg deleted file mode 100644 index 341cb711c2e53fba44b68107c2ae4ac8234256fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35554 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 C`nweX diff --git a/docs/modules/enduser-setup.md b/docs/modules/enduser-setup.md index 9eb367b0..86060d7a 100644 --- a/docs/modules/enduser-setup.md +++ b/docs/modules/enduser-setup.md @@ -3,49 +3,107 @@ | :----- | :-------------------- | :---------- | :------ | | 2015-09-02 | [Robert Foss](https://github.com/robertfoss) | [Robert Foss](https://github.com/robertfoss) | [enduser_setup.c](../../app/modules/enduser_setup.c)| -This module provides a simple way of configuring ESP8266 chips without using a serial interface or pre-programming WiFi credentials onto the chip. +This module provides a simple way of configuring ESP8266 chips without using a +serial interface or pre-programming WiFi credentials onto the chip. -![enduser setup config dialog](../img/enduser-setup.jpg "enduser setup config dialog") +After running [`enduser_setup.start()`](#enduser_setupstart), a wireless +network named "SetupGadget_XXXXXX" will starting. This prefix can be overridden +in `user_config.h` by defining `ENDUSER_SETUP_AP_SSID`. Connect to that SSID +and then navigate to the root of any website or to 192.168.4.1. +`http://example.com/` will work, but do not use `.local` domains because it +will fail on iOS. A web page similar to the one depicted below will load, +allowing the end user to provide their Wi-Fi credentials. -After running [`enduser_setup.start()`](#enduser_setupstart), a wireless network named "SetupGadget_XXXXXX" will start (this prefix can be overridden in `user_config.h` by defining -`ENDUSER_SETUP_AP_SSID`). Connect to that SSID and then navigate to the root -of any website (e.g., `http://example.com/` will work, but do not use `.local` domains because it will fail on iOS). A web page similar to the picture above will load, allowing the -end user to provide their Wi-Fi information. +![enduser setup config dialog](../img/enduser-setup-captive-portal.png "enduser setup config dialog") -After an IP address has been successfully obtained, then this module will stop as if [`enduser_setup.stop()`](#enduser_setupstop) had been called. There is a 10-second delay before -teardown to allow connected clients to obtain a last status message while the SoftAP is still active. +After an IP address has been successfully obtained, then this module will stop +as if [`enduser_setup.stop()`](#enduser_setupstop) had been called. There is a +10-second delay before teardown to allow connected clients to obtain a last +status message while the SoftAP is still active. -Alternative HTML can be served by placing a file called `enduser_setup.html` on the filesystem. Everything needed by the web page must be included in this one file. This file will be kept -in RAM, so keep it as small as possible. The file can be gzip'd ahead of time to reduce the size (i.e., using `gzip -n` or `zopfli`), and when served, the End User Setup module will add -the appropriate `Content-Encoding` header to the response. +Alternative HTML can be served by placing a file called `enduser_setup.html` on +the filesystem. Everything needed by the web page must be included in this one +file. This file will be kept in RAM, so keep it as small as possible. The file +can be gzip'd ahead of time to reduce the size (i.e., using `gzip -n` or +`zopfli`), and when served, the End User Setup module will add the appropriate +`Content-Encoding` header to the response. -*Note: If gzipped, the file can also be named `enduser_setup.html.gz` for semantic purposes. Gzip encoding is determined by the file's contents, not the filename.* +*Note: If gzipped, the file can also be named `enduser_setup.html.gz` for +semantic purposes. GZIP encoding is determined by the file's contents, not the +filename.* -The following HTTP endpoints exist: +### Additional configuration parameters + +You can also add some additional inputs in the `enduser_setup.html` (as long as +you keep those needed for the WiFi setup). The additional data will be written +in a `eus_params.lua` file in the root filesystem of the ESP8266, which you can +then load in your own code. In this case, the data will be saved as a set of +variables with the name being the input name, and the value being a string +representing what you put in the form. + +For instance, if your HTML contains two additional inputs: + +```html + + +``` + +Then the `eus_params.lua` file will contain the following: + +```lua +-- those wifi_* are the base parameters that are saved anyway +local p = {} +p.wifi_ssid="ssid" +p.wifi_password="password" +-- your own parameters: +p.timeout_delay="xxx" +p.device_name="yyy" +return p +``` + +### How to use the eus_params.lua file + +Simply include the file by using the `dofile` function: +```lua +p = dofile('eus_params.lua') +-- now use the parameters in the Lua table +print("Wifi device_name: " .. p.device_name) +``` + +### HTTP endpoints: + +|Path|Method|Description| +|----|------|-----------| +|/|GET|Returns HTML for the web page. Will return the contents of `enduser_setup.html` if it exists on the filesystem, otherwise will return a page embedded into the firmware image.| +|/aplist|GET|Forces the ESP8266 to perform a site survey across all channels, reporting access points that it can find. Return payload is a JSON array: `[{"ssid":"foobar","rssi":-36,"chan":3}]`| +|/generate_204|GET|Returns a HTTP 204 status (expected by certain Android clients during Wi-Fi connectivity checks)| +|/status|GET|Returns plaintext status description, used by the web page| +|/status.json|GET|Returns a JSON payload containing the ESP8266's chip id in hexadecimal format and the status code: 0=Idle, 1=Connecting, 2=Wrong Password, 3=Network not Found, 4=Failed, 5=Success| +|/setwifi|POST|HTML form post for setting the WiFi credentials. Expects HTTP content type `application/x-www-form-urlencoded`. Supports sending and storing additinal configuration parameters (as input fields). Returns the same payload as `/status.json` instead of redirecting to `/`. See also: `/update`.| +|/update|GET|Data submission target. Example: `http://example.com/update?wifi_ssid=foobar&wifi_password=CorrectHorseBatteryStaple`. Will redirect to `/` when complete. Note that will NOT update the `eus_params.lua` file i.e. it does NOT support sending arbitrary parameters. See also: `/setwifi`. | + +Module functions are described below. -|Endpoint|Description| -|--------|-----------| -|/|Returns HTML for the web page. Will return the contents of `enduser_setup.html` if it exists on the filesystem, otherwise will return a page embedded into the firmware image.| -|/aplist|Forces the ESP8266 to perform a site survey across all channels, reporting access points that it can find. Return payload is a JSON array: `[{"ssid":"foobar","rssi":-36,"chan":3}]`| -|/generate_204|Returns a HTTP 204 status (expected by certain Android clients during Wi-Fi connectivity checks)| -|/status|Returns plaintext status description, used by the web page| -|/status.json|Returns a JSON payload containing the ESP8266's chip id in hexadecimal format and the status code: 0=Idle, 1=Connecting, 2=Wrong Password, 3=Network not Found, 4=Failed, 5=Success| -|/setwifi|Endpoint intended for services to use for setting the wifi credentials. Identical to `/update` except returns the same payload as `/status.json` instead of redirecting to `/`.| -|/update|Form submission target. Example: `http://example.com/update?wifi_ssid=foobar&wifi_password=CorrectHorseBatteryStaple`. Must be a GET request. Will redirect to `/` when complete. | ## enduser_setup.manual() Controls whether manual AP configuration is used. -By default the `enduser_setup` module automatically configures an open access point when starting, and stops it when the device has been successfully joined to a WiFi network. If manual mode has been enabled, neither of this is done. The device must be manually configured for `wifi.SOFTAP` mode prior to calling `enduser_setup.start()`. Additionally, the portal is not stopped after the device has successfully joined to a WiFi network. +By default the `enduser_setup` module automatically configures an open access +point when starting, and stops it when the device has been successfully joined +to a WiFi network. If manual mode has been enabled, neither of this is done. +The device must be manually configured for `wifi.SOFTAP` mode prior to calling +`enduser_setup.start()`. Additionally, the portal is not stopped after the +device has successfully joined to a WiFi network. #### Syntax `enduser_setup.manual([on_off])` #### Parameters - - `on_off` a boolean value indicating whether to use manual mode; if not given, the function only returns the current setting. + - `on_off` a boolean value indicating whether to use manual mode; if not + given, the function only returns the current setting. #### Returns The current setting, true if manual mode is enabled, false if it is not. @@ -57,12 +115,12 @@ wifi.ap.config({ssid="MyPersonalSSID", auth=wifi.OPEN}) enduser_setup.manual(true) enduser_setup.start( function() - print("Connected to wifi as:" .. wifi.sta.getip()) + print("Connected to WiFi as:" .. wifi.sta.getip()) end, function(err, str) print("enduser_setup: Err #" .. err .. ": " .. str) end -); +) ``` ## enduser_setup.start() @@ -86,13 +144,13 @@ Starts the captive portal. ```lua enduser_setup.start( function() - print("Connected to wifi as:" .. wifi.sta.getip()) + print("Connected to WiFi as:" .. wifi.sta.getip()) end, function(err, str) print("enduser_setup: Err #" .. err .. ": " .. str) end, print -- Lua print function can serve as the debug callback -); +) ``` ## enduser_setup.stop()