├── LICENSE ├── README.md ├── WiFiTerm.cpp ├── WiFiTerm.h ├── WiFiTermBuffer.cpp ├── WiFiTermBuffer.h ├── WiFiTerm_webfiles.cpp ├── WiFiTerm_webfiles.h ├── examples ├── esp32 │ ├── Basic │ │ └── Basic.ino │ ├── Full_Demo │ │ └── Full_Demo.ino │ └── Serial_Gateway │ │ └── Serial_Gateway.ino └── esp8266 │ ├── Basic │ └── Basic.ino │ ├── Full_Demo │ └── Full_Demo.ino │ └── Serial_Gateway │ └── Serial_Gateway.ino ├── webfiles.py └── webfiles ├── favicon.ico ├── icons ├── greenArrow.png └── redArrow.png ├── scripts └── term.js ├── styles └── term.css └── term.html /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 bricoleau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Remote WiFi Terminal for Arduino 2 | ================================ 3 | 4 | As easy to use as the Serial terminal provided with Arduino IDE 5 | 6 | ##### Supported Hardware ##### 7 | - ESP8266 [Arduino for ESP8266](https://github.com/esp8266/Arduino/) 8 | - ESP32 [Arduino for ESP32](https://github.com/espressif/arduino-esp32) 9 | 10 | ##### Required Libraries ##### 11 | - [Arduino Websockets](https://github.com/Links2004/arduinoWebSockets) 12 | 13 | ##### First Steps ##### 14 | 15 | - run example Full_Demo.ino 16 | 17 | -------------------------------------------------------------------------------- /WiFiTerm.cpp: -------------------------------------------------------------------------------- 1 | #include "WiFiTerm.h" 2 | #include "WiFiTerm_webfiles.h" 3 | 4 | WiFiTerm term; 5 | 6 | WiFiTerm::WiFiTerm() : 7 | txBuf(WIFITERM_TX_BUF_SIZE), 8 | rxBuf(WIFITERM_RX_BUF_SIZE), 9 | webSocket(WIFITERM_WEBSOCKET_PORT) 10 | { 11 | setTimeout(0); 12 | unlink(); 13 | } 14 | 15 | void WiFiTerm::begin(WebServer &server) 16 | { 17 | WiFiTerm_webfiles.begin(server); 18 | webSocket.begin(); 19 | webSocket.onEvent(WiFiTerm::webSocketEvent); 20 | } 21 | 22 | void WiFiTerm::handleClient() 23 | { 24 | send(); 25 | webSocket.loop(); 26 | } 27 | 28 | void WiFiTerm::setAsDefaultWhenUrlNotFound() 29 | { 30 | if (WiFiTerm_webfiles.server != NULL) 31 | { 32 | WiFiTerm_webfiles.server->onNotFound([]() 33 | { 34 | static const char location_P[] PROGMEM = "Location"; 35 | static const char text_plane_P[] PROGMEM = "text/plane"; 36 | char arg1[20]; 37 | char arg2[20]; 38 | 39 | strcpy_P(arg1, location_P); 40 | strcpy_P(arg2, webfiles_term_html_path_P); 41 | WiFiTerm_webfiles.server->sendHeader((const char*)arg1, (const char*)arg2, true); 42 | 43 | strcpy_P(arg1, text_plane_P); 44 | arg2[0] = '\0'; 45 | WiFiTerm_webfiles.server->send(302, (const char*)arg1, (const char*)arg2); 46 | }); 47 | } 48 | } 49 | 50 | void WiFiTerm::activateArduinoFavicon() 51 | { 52 | WiFiTerm_webfiles.activateFavicon(); 53 | } 54 | 55 | size_t WiFiTerm::write(uint8_t character) 56 | { 57 | if (txBuf.isFull()) send(); 58 | txBuf.write(character); 59 | if (linked != NULL) linked->write(character); 60 | return 1; 61 | } 62 | 63 | void WiFiTerm::send() 64 | { 65 | if (txBuf.isNotEmpty()) 66 | { 67 | if (webSocket.connectedClients()) 68 | { 69 | size_t nb = txBuf.available(); 70 | char content[nb]; 71 | size_t i = 0; 72 | while (txBuf.available()) content[i++] = txBuf.read(); 73 | webSocket.broadcastTXT(content, nb); 74 | } 75 | else 76 | { 77 | txBuf.flush(); 78 | } 79 | } 80 | } 81 | 82 | void WiFiTerm::sendPrevious(uint8_t num) 83 | { 84 | size_t nb = txBuf.previousAvailable(); 85 | if (nb) 86 | { 87 | char content[nb]; 88 | txBuf.peekPrevious(content); 89 | webSocket.sendTXT(num, content, nb); 90 | } 91 | } 92 | 93 | void WiFiTerm::webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) 94 | { 95 | switch(type) 96 | { 97 | case WStype_CONNECTED: 98 | term.sendPrevious(num); 99 | break; 100 | case WStype_TEXT: 101 | if (length == 0) //This is supposed to be a ping 102 | { 103 | term.webSocket.sendBIN(num, payload, 0); //pong 104 | } 105 | else 106 | { 107 | while (length--) term.rxBuf.write(*payload++); 108 | } 109 | default:; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /WiFiTerm.h: -------------------------------------------------------------------------------- 1 | #ifndef WiFiTerm_h 2 | #define WiFiTerm_h 3 | 4 | #include 5 | #include 6 | #include "WiFiTermBuffer.h" 7 | 8 | #if defined(ESP32) 9 | #include 10 | #elif defined(ESP8266) 11 | #include 12 | #define WebServer ESP8266WebServer 13 | #endif 14 | 15 | #define WIFITERM_TX_BUF_SIZE 300 16 | #define WIFITERM_RX_BUF_SIZE 100 17 | #define WIFITERM_WEBSOCKET_PORT 81 18 | 19 | class WiFiTerm : public Stream //with embedded Print class 20 | { 21 | private : 22 | WiFiTermBuffer txBuf, rxBuf; 23 | WebSocketsServer webSocket; 24 | 25 | public : 26 | WiFiTerm(); 27 | 28 | void begin(WebServer &server); 29 | void handleClient(); 30 | 31 | //web options 32 | void setAsDefaultWhenUrlNotFound(); 33 | void activateArduinoFavicon(); 34 | inline int connectedClients() {return webSocket.connectedClients();} 35 | 36 | //required for Print class 37 | size_t write(uint8_t character); 38 | 39 | //required for Stream class 40 | inline int read() {return rxBuf.read();} 41 | inline int peek() {return rxBuf.peek();} 42 | inline int available() {return rxBuf.available();} 43 | inline void flush() {rxBuf.flush();} 44 | 45 | inline void resetTx() {txBuf.reset();} 46 | private : 47 | void send(); 48 | void sendPrevious(uint8_t num); 49 | static void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length); 50 | 51 | //Add-on : link to another Print Class 52 | private : 53 | Print *linked; 54 | public : 55 | inline void link(Print& p) {linked = &p;} 56 | inline void unlink() {linked = NULL;} 57 | }; 58 | 59 | extern WiFiTerm term; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /WiFiTermBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "WiFiTermBuffer.h" 2 | 3 | WiFiTermBuffer::WiFiTermBuffer(size_t size) 4 | { 5 | _size = size; 6 | _buffer = (char *) malloc(_size); 7 | reset(); 8 | } 9 | 10 | WiFiTermBuffer::~WiFiTermBuffer() 11 | { 12 | free(_buffer); 13 | } 14 | 15 | void WiFiTermBuffer::reset() 16 | { 17 | _ix_read = 0; 18 | _ix_write = 0; 19 | _available = 0; 20 | _previous = 0; 21 | } 22 | 23 | size_t WiFiTermBuffer::write(uint8_t c) 24 | { 25 | _buffer[_ix_write++] = c; 26 | if (_ix_write == _size) _ix_write = 0; 27 | if (_available < _size) _available++; 28 | if (_available + _previous > _size) _previous = _size - _available; 29 | _ix_read = (_ix_write >= _available) ? 0 : _size; 30 | _ix_read += _ix_write; 31 | _ix_read -= _available; 32 | return 1; 33 | } 34 | 35 | int WiFiTermBuffer::read() 36 | { 37 | if (_available == 0) return -1; 38 | char c = _buffer[_ix_read++]; 39 | if (_ix_read == _size) _ix_read = 0; 40 | _available--; 41 | _previous++; 42 | return c; 43 | } 44 | 45 | void WiFiTermBuffer::flush() 46 | { 47 | _ix_read = _ix_write; 48 | _previous += _available; 49 | _available = 0; 50 | } 51 | 52 | int WiFiTermBuffer::peek() const 53 | { 54 | if (_available == 0) return -1; 55 | char c = _buffer[_ix_read]; 56 | return c; 57 | } 58 | 59 | void WiFiTermBuffer::peekPrevious(char *to) const 60 | { 61 | size_t len = _previous; 62 | size_t ix = (_ix_read >= _previous) ? 0 : _size; 63 | ix += _ix_read; 64 | ix -= _previous; 65 | while (len--) 66 | { 67 | *to++ = _buffer[ix++]; 68 | if (ix == _size) ix = 0; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WiFiTermBuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef WiFiTermBuffer_h 2 | #define WiFiTermBuffer_h 3 | 4 | //circular buffer for WiFiTerm 5 | 6 | #include 7 | 8 | class WiFiTermBuffer 9 | { 10 | private : 11 | char *_buffer; 12 | size_t _size, _ix_read, _ix_write, _available, _previous; 13 | 14 | public : 15 | WiFiTermBuffer(size_t); 16 | ~WiFiTermBuffer(); 17 | 18 | void reset(); 19 | 20 | size_t write(uint8_t); 21 | int read(); 22 | int peek() const; 23 | void flush(); 24 | inline int available() const {return _available;} 25 | 26 | inline size_t size() const {return _size;} 27 | inline bool isEmpty() const {return _available == 0;} 28 | inline bool isNotEmpty() const {return _available != 0;} 29 | inline bool isFull() const {return _available == _size;} 30 | inline bool isNotFull() const {return _available != _size;} 31 | 32 | inline size_t previousAvailable() const {return _previous;} 33 | void peekPrevious(char *to) const;//peek only previously read char 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /WiFiTerm_webfiles.cpp: -------------------------------------------------------------------------------- 1 | //Generated by webfiles.py 2 | 3 | #include "WiFiTerm_webfiles.h" 4 | 5 | WiFiTerm_webfiles_c WiFiTerm_webfiles; 6 | 7 | WiFiTerm_webfiles_c::WiFiTerm_webfiles_c() 8 | { 9 | server = NULL; 10 | } 11 | 12 | const char webfiles_favicon_ico_path_P[] PROGMEM = "/favicon.ico"; 13 | const char webfiles_term_html_path_P[] PROGMEM = "/term.html"; 14 | const char webfiles_icons_greenArrow_png_path_P[] PROGMEM = "/icons/greenArrow.png"; 15 | const char webfiles_icons_redArrow_png_path_P[] PROGMEM = "/icons/redArrow.png"; 16 | const char webfiles_scripts_term_js_path_P[] PROGMEM = "/scripts/term.js"; 17 | const char webfiles_styles_term_css_path_P[] PROGMEM = "/styles/term.css"; 18 | 19 | const char WiFiTerm_webfiles_content_type_ico_P[] PROGMEM = "image/vnd.microsoft.icon"; 20 | const char WiFiTerm_webfiles_content_type_html_P[] PROGMEM = "text/html"; 21 | const char WiFiTerm_webfiles_content_type_png_P[] PROGMEM = "image/png"; 22 | const char WiFiTerm_webfiles_content_type_js_P[] PROGMEM = "application/javascript"; 23 | const char WiFiTerm_webfiles_content_type_css_P[] PROGMEM = "text/css"; 24 | 25 | void WiFiTerm_webfiles_c::begin(WebServer &webServer) 26 | { 27 | server = &webServer; 28 | 29 | char path[22]; 30 | 31 | strcpy_P(path, webfiles_term_html_path_P); 32 | server->on(path, send_webfiles_term_html); 33 | 34 | strcpy_P(path, webfiles_icons_greenArrow_png_path_P); 35 | server->on(path, send_webfiles_icons_greenArrow_png); 36 | 37 | strcpy_P(path, webfiles_icons_redArrow_png_path_P); 38 | server->on(path, send_webfiles_icons_redArrow_png); 39 | 40 | strcpy_P(path, webfiles_scripts_term_js_path_P); 41 | server->on(path, send_webfiles_scripts_term_js); 42 | 43 | strcpy_P(path, webfiles_styles_term_css_path_P); 44 | server->on(path, send_webfiles_styles_term_css); 45 | } 46 | 47 | void WiFiTerm_webfiles_c::activateFavicon() 48 | { 49 | char path[22]; 50 | if (server != NULL) 51 | { 52 | strcpy_P(path, webfiles_favicon_ico_path_P); 53 | server->on(path, send_webfiles_favicon_ico); 54 | } 55 | } 56 | 57 | const char webfiles_favicon_ico_P[] PROGMEM = 58 | { 59 | 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 60 | 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 61 | 0x08, 0x06, 0x00, 0x00, 0x00, 0x57, 0x02, 0xf9, 0x87, 0x00, 0x00, 0x0b, 62 | 0x51, 0x49, 0x44, 0x41, 0x54, 0x68, 0x81, 0xbd, 0x9a, 0x7b, 0x70, 0x94, 63 | 0xd5, 0x15, 0xc0, 0x7f, 0x67, 0x77, 0x93, 0x90, 0x64, 0x4d, 0x20, 0x98, 64 | 0x18, 0x0c, 0x79, 0x90, 0x80, 0x0f, 0x04, 0x41, 0x50, 0x51, 0x5b, 0x2c, 65 | 0x18, 0x28, 0x8a, 0x8a, 0x3a, 0xb6, 0x8e, 0x0f, 0xac, 0x56, 0x1b, 0x6d, 66 | 0xc3, 0x7f, 0xd6, 0x51, 0x1c, 0xb4, 0x7f, 0x74, 0x8a, 0x56, 0x9c, 0xda, 67 | 0x71, 0x2c, 0x3b, 0x2d, 0xab, 0xad, 0x56, 0x9c, 0xa9, 0xb5, 0xb5, 0xa2, 68 | 0x12, 0x54, 0x7c, 0x74, 0x40, 0x51, 0x44, 0xf1, 0x81, 0x84, 0x57, 0x88, 69 | 0x09, 0x89, 0x9a, 0xcd, 0x6b, 0x37, 0x1b, 0xd8, 0x24, 0x9b, 0xec, 0x9e, 70 | 0xfe, 0xf1, 0x3d, 0xf6, 0xdb, 0xcd, 0xe6, 0x01, 0x52, 0xcf, 0xcc, 0xee, 71 | 0x9c, 0xef, 0x7e, 0xf7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0x75, 0xef, 0xfd, 72 | 0x84, 0xef, 0x0a, 0x3e, 0xbf, 0x0b, 0xa8, 0x04, 0x2e, 0x45, 0x75, 0x01, 73 | 0x30, 0x13, 0x91, 0x0a, 0xd0, 0x22, 0x90, 0x4c, 0xa3, 0x93, 0x46, 0x41, 74 | 0xda, 0x51, 0x6d, 0x02, 0xea, 0x11, 0xd9, 0x09, 0x6c, 0x03, 0x1a, 0xa9, 75 | 0xad, 0x89, 0x7f, 0x97, 0xe9, 0xe5, 0x84, 0x47, 0xae, 0xdf, 0x50, 0x8c, 76 | 0xc8, 0xed, 0xc0, 0x2d, 0x28, 0x33, 0x01, 0x17, 0xa8, 0x83, 0xe4, 0x58, 77 | 0xb8, 0xc6, 0x41, 0xea, 0x11, 0x9e, 0x07, 0x9e, 0xa1, 0xb6, 0xa6, 0xed, 78 | 0x44, 0xd8, 0x38, 0x7e, 0x01, 0x7c, 0xfe, 0x4a, 0x60, 0x0d, 0xb0, 0x12, 79 | 0x25, 0x33, 0x99, 0x2f, 0x07, 0xa3, 0x23, 0xf2, 0xaf, 0x20, 0xc3, 0xfa, 80 | 0x44, 0x81, 0x8d, 0xc0, 0x5a, 0x6a, 0x6b, 0x1a, 0xff, 0x3f, 0x02, 0xac, 81 | 0xdf, 0x90, 0x83, 0xc8, 0x1a, 0xe0, 0x1e, 0xd0, 0x09, 0x63, 0x6b, 0x7a, 82 | 0x24, 0x18, 0xb5, 0x7f, 0x3f, 0xf0, 0x38, 0x86, 0x20, 0x91, 0xf1, 0xb0, 83 | 0x35, 0x3e, 0x01, 0xd6, 0x6f, 0x98, 0x87, 0xc8, 0x73, 0xc0, 0xcc, 0xd1, 84 | 0x99, 0x18, 0x8f, 0x00, 0x4e, 0x18, 0xb1, 0x7f, 0x3d, 0x70, 0x2b, 0xb5, 85 | 0x35, 0xbb, 0xc7, 0xa2, 0xe0, 0x1a, 0x73, 0x0e, 0x9f, 0x7f, 0x25, 0xc8, 86 | 0x76, 0xd0, 0x99, 0x89, 0x46, 0x87, 0x09, 0x24, 0x31, 0xe0, 0xc0, 0x55, 87 | 0xc7, 0x81, 0x33, 0x52, 0x9f, 0x99, 0xc0, 0x76, 0x63, 0xee, 0xd1, 0x61, 88 | 0x64, 0x75, 0xf9, 0xfc, 0x80, 0xde, 0x87, 0xca, 0x23, 0xa0, 0xae, 0x44, 89 | 0x77, 0x6b, 0xa2, 0x91, 0x70, 0xc6, 0x78, 0x9f, 0x8a, 0x5b, 0x92, 0xa4, 90 | 0xed, 0x13, 0x47, 0xe4, 0x01, 0x60, 0x1d, 0xb5, 0x35, 0x69, 0xd9, 0xf4, 91 | 0x8c, 0x28, 0x80, 0xea, 0x7d, 0x88, 0x3c, 0x6a, 0xcc, 0x71, 0x3c, 0xcc, 92 | 0xd8, 0x04, 0xd2, 0x30, 0xc8, 0x08, 0x7d, 0x25, 0x4d, 0xbb, 0x80, 0x61, 93 | 0x21, 0x8f, 0x9a, 0x53, 0xac, 0x4b, 0xc7, 0x66, 0xfa, 0x15, 0xf0, 0xf9, 94 | 0x57, 0xa2, 0x3c, 0x8b, 0xe0, 0x4a, 0xf0, 0xa7, 0xa0, 0x32, 0x06, 0x3e, 95 | 0x16, 0xf3, 0x27, 0x80, 0xab, 0x80, 0x10, 0x07, 0x6e, 0xa3, 0xb6, 0x66, 96 | 0xe3, 0xd8, 0x02, 0xf8, 0xfc, 0xf3, 0x50, 0xb6, 0x03, 0x39, 0xe3, 0x9a, 97 | 0xc4, 0x29, 0xc0, 0x77, 0x8f, 0x42, 0xa3, 0x8d, 0x89, 0x20, 0x2c, 0x4c, 98 | 0x75, 0xec, 0xe4, 0xd1, 0x46, 0xa8, 0xdc, 0x05, 0xcc, 0x3c, 0x4e, 0xe2, 99 | 0xe3, 0x64, 0x72, 0xcc, 0xe4, 0x96, 0x96, 0x2d, 0x07, 0xd4, 0x03, 0x17, 100 | 0x38, 0x43, 0x6c, 0x72, 0x14, 0x12, 0xd6, 0x80, 0xce, 0x44, 0x31, 0xb5, 101 | 0xaa, 0x0e, 0xdf, 0x4c, 0x13, 0x49, 0x92, 0xa2, 0x88, 0xf3, 0x59, 0x1c, 102 | 0x51, 0xe5, 0x78, 0x70, 0x49, 0x6e, 0x4f, 0xa5, 0x6f, 0x28, 0x76, 0x4d, 103 | 0x32, 0xcb, 0x16, 0x18, 0x19, 0x76, 0x2f, 0xca, 0x84, 0x74, 0xa2, 0x8f, 104 | 0x0c, 0x27, 0xd1, 0xde, 0x47, 0x35, 0x2d, 0x5b, 0xd8, 0x7e, 0x84, 0x73, 105 | 0xac, 0x8c, 0xed, 0x58, 0x01, 0x5d, 0x03, 0x3a, 0xc1, 0x52, 0x02, 0xa2, 106 | 0x24, 0xf0, 0xd4, 0xdf, 0x58, 0xef, 0xcc, 0x72, 0xc1, 0x6e, 0x13, 0xc7, 107 | 0x98, 0xe3, 0xc5, 0x9d, 0x34, 0x04, 0x84, 0x09, 0x18, 0xa5, 0x8c, 0x21, 108 | 0x0e, 0x00, 0xbe, 0x0d, 0xc5, 0x28, 0xcd, 0x08, 0x99, 0xc6, 0x12, 0x26, 109 | 0x2b, 0x63, 0xc6, 0xc4, 0x3c, 0x6e, 0xa8, 0xaa, 0xe4, 0xd2, 0xd3, 0x8b, 110 | 0x99, 0x91, 0x9f, 0x4f, 0xb6, 0xc7, 0x4d, 0x34, 0x16, 0xa7, 0xa9, 0xb7, 111 | 0x97, 0x0f, 0x02, 0xed, 0xfc, 0xa7, 0xb1, 0x89, 0x9d, 0xed, 0x1d, 0x38, 112 | 0xa2, 0xc6, 0xc8, 0x8a, 0x34, 0xdb, 0xbd, 0x99, 0x19, 0x5c, 0x37, 0xad, 113 | 0x9c, 0x65, 0xa5, 0x53, 0x39, 0x77, 0x72, 0x01, 0xa7, 0x66, 0x1b, 0xba, 114 | 0x6b, 0xef, 0xeb, 0xe7, 0xf3, 0xce, 0x2e, 0xb6, 0x1c, 0x69, 0xe5, 0xe5, 115 | 0xaf, 0x9a, 0xe8, 0x1b, 0x1a, 0x22, 0x51, 0x3b, 0x99, 0x8a, 0x51, 0xa2, 116 | 0x08, 0xe5, 0xd4, 0xd6, 0xb4, 0x99, 0x02, 0xf8, 0x57, 0xa3, 0x3c, 0x92, 117 | 0xbc, 0x5c, 0x42, 0xd9, 0x29, 0x5e, 0x1e, 0xbb, 0xf8, 0x42, 0xae, 0xaf, 118 | 0xac, 0xc0, 0x25, 0xe9, 0x38, 0x49, 0xc0, 0xce, 0xf6, 0x0e, 0xee, 0xff, 119 | 0xe0, 0x23, 0xb6, 0x7d, 0xdb, 0x36, 0x3c, 0xa7, 0x39, 0x20, 0xdb, 0xe3, 120 | 0xe6, 0x9e, 0x39, 0xb3, 0xb9, 0x67, 0xce, 0x6c, 0x26, 0x65, 0x65, 0x8e, 121 | 0x4a, 0x33, 0xd0, 0xd7, 0xc7, 0xef, 0x3e, 0xf9, 0x8c, 0x3f, 0xef, 0xdd, 122 | 0x47, 0x2c, 0x1e, 0x27, 0xc9, 0xd1, 0x45, 0x1e, 0xa0, 0xb6, 0xe6, 0xf7, 123 | 0x62, 0xd4, 0xf3, 0xfa, 0x39, 0x30, 0x2b, 0x31, 0x54, 0x58, 0x5e, 0x56, 124 | 0xca, 0xc6, 0x25, 0x8b, 0x98, 0x94, 0x95, 0x35, 0xea, 0x24, 0x4e, 0x88, 125 | 0xc5, 0xe3, 0x3c, 0xb1, 0x67, 0x2f, 0xab, 0x3f, 0xdc, 0xc5, 0x60, 0x7c, 126 | 0x78, 0x99, 0x3f, 0x73, 0xd2, 0x44, 0x5e, 0x58, 0x7a, 0x19, 0xb3, 0x26, 127 | 0x17, 0x8c, 0x9b, 0x26, 0xc0, 0x9b, 0x2d, 0xad, 0xdc, 0xb8, 0xf5, 0x1d, 128 | 0x82, 0x03, 0x51, 0xb3, 0x45, 0x01, 0xbe, 0x04, 0x99, 0x23, 0xf8, 0x36, 129 | 0x4c, 0x47, 0xe5, 0x00, 0xa2, 0x2e, 0xcb, 0x7c, 0xae, 0xaa, 0x28, 0xe3, 130 | 0x5f, 0xcb, 0xaa, 0xc9, 0x72, 0xbb, 0x93, 0x08, 0x85, 0xa3, 0x51, 0x3e, 131 | 0xed, 0xec, 0xa2, 0xbb, 0x7f, 0x80, 0xbc, 0xcc, 0x0c, 0x66, 0x4f, 0x2e, 132 | 0xa0, 0x70, 0xc2, 0x04, 0xc4, 0xb1, 0x3a, 0xaa, 0xca, 0x1b, 0x2d, 0xad, 133 | 0x5c, 0xff, 0xc6, 0xdb, 0x44, 0x86, 0x86, 0x6c, 0x33, 0xba, 0x74, 0x4a, 134 | 0x31, 0x9b, 0xae, 0x58, 0xca, 0xc4, 0xac, 0x2c, 0xd4, 0x8c, 0x32, 0x22, 135 | 0xc2, 0x50, 0x3c, 0xce, 0x81, 0x50, 0x0f, 0x87, 0xc3, 0x61, 0x50, 0xa8, 136 | 0xca, 0xcf, 0xe3, 0xac, 0x89, 0xf9, 0xf6, 0x8a, 0x8b, 0x08, 0xaa, 0xca, 137 | 0xc7, 0x1d, 0x9d, 0x54, 0xbf, 0x52, 0x47, 0x6f, 0x74, 0xd0, 0x10, 0x40, 138 | 0x24, 0x0e, 0x9c, 0x29, 0xf8, 0xfc, 0x77, 0xa0, 0x3c, 0x6d, 0xcd, 0x34, 139 | 0x3d, 0x3f, 0x8f, 0x8f, 0x7f, 0x72, 0x2d, 0x79, 0x99, 0x19, 0x36, 0x53, 140 | 0x2d, 0x47, 0x8f, 0xf1, 0xd0, 0xae, 0x4f, 0x78, 0xb1, 0xa1, 0x91, 0xbe, 141 | 0xa1, 0x18, 0x56, 0x5f, 0x8f, 0x4b, 0xa8, 0x9e, 0x7a, 0x3a, 0xbf, 0x39, 142 | 0x7f, 0x1e, 0x17, 0x9f, 0x56, 0x94, 0x24, 0xec, 0xeb, 0x2d, 0xad, 0x5c, 143 | 0xbb, 0x65, 0x2b, 0xd1, 0x58, 0x9c, 0x05, 0xa7, 0x15, 0xb2, 0xf5, 0xea, 144 | 0xe5, 0x78, 0x33, 0x12, 0x95, 0xcb, 0x40, 0x2c, 0xce, 0xfa, 0x2f, 0xf7, 145 | 0xf2, 0xe4, 0x9e, 0x7a, 0x9a, 0x7b, 0x8f, 0xe2, 0x74, 0x98, 0xaa, 0xfc, 146 | 0x3c, 0xee, 0x9d, 0x3b, 0x9b, 0x9a, 0xb3, 0xcf, 0x4c, 0x32, 0xdd, 0x7f, 147 | 0x34, 0x34, 0x72, 0xf3, 0x5b, 0xef, 0x3a, 0x02, 0x92, 0xde, 0xe9, 0x66, 148 | 0xf9, 0xd5, 0xbf, 0x44, 0x64, 0xbe, 0x15, 0x35, 0x9e, 0xad, 0xfe, 0x11, 149 | 0xe7, 0x4e, 0x2e, 0x40, 0x44, 0x10, 0x11, 0xde, 0x6b, 0x0b, 0xb0, 0x78, 150 | 0xd3, 0x66, 0x3e, 0x0c, 0xb4, 0x33, 0x14, 0xb7, 0xed, 0x0f, 0x04, 0xe2, 151 | 0x0a, 0x87, 0xc3, 0xbd, 0x3c, 0x7b, 0xe0, 0x10, 0xfd, 0xb1, 0x18, 0x8b, 152 | 0x4a, 0xa6, 0xe0, 0x76, 0xb9, 0x10, 0x11, 0x66, 0xe4, 0xe7, 0x33, 0x31, 153 | 0x2b, 0x93, 0xcf, 0xbb, 0xba, 0x79, 0x7b, 0xc5, 0x72, 0xc3, 0x49, 0x4d, 154 | 0x9a, 0x0d, 0xe1, 0x30, 0xcb, 0x5e, 0xdb, 0xc2, 0x73, 0x07, 0x1a, 0xe8, 155 | 0x19, 0x8c, 0x92, 0xa8, 0xb7, 0x0c, 0x08, 0x0e, 0x0c, 0xb0, 0xf9, 0x48, 156 | 0x0b, 0xbb, 0x3b, 0xbb, 0xb8, 0x76, 0x5a, 0x05, 0x99, 0x6e, 0x37, 0x22, 157 | 0xc2, 0xac, 0x82, 0x49, 0xec, 0x68, 0x6b, 0xa7, 0x31, 0xdc, 0x6b, 0xf2, 158 | 0x41, 0xc0, 0xcd, 0x95, 0x57, 0xdf, 0x8f, 0x48, 0x19, 0xc0, 0xec, 0x82, 159 | 0x49, 0xfc, 0xe1, 0x92, 0x8b, 0x6c, 0x93, 0x68, 0x0c, 0x87, 0x59, 0xbc, 160 | 0x69, 0xb3, 0x61, 0x7b, 0x56, 0x68, 0x34, 0x24, 0x4f, 0x4c, 0x28, 0x8a, 161 | 0x02, 0xef, 0x7d, 0x1b, 0xa0, 0x31, 0x1c, 0x66, 0x45, 0x45, 0x39, 0x2e, 162 | 0x73, 0xd9, 0x2f, 0x2c, 0x2a, 0xe4, 0xaa, 0xf2, 0x32, 0x2a, 0x4e, 0x39, 163 | 0xc5, 0xa6, 0xf9, 0x65, 0x57, 0x37, 0x8b, 0x37, 0xd5, 0x71, 0x38, 0xc1, 164 | 0x04, 0x6e, 0x11, 0x72, 0x33, 0x3c, 0xb8, 0x45, 0x18, 0xb2, 0x92, 0x98, 165 | 0xc0, 0xc1, 0x9e, 0x10, 0x47, 0x8e, 0x1e, 0xe3, 0xba, 0x69, 0xe5, 0xb6, 166 | 0x39, 0x95, 0x78, 0x73, 0xf9, 0xfb, 0xc1, 0x43, 0x96, 0x22, 0xfb, 0x5c, 167 | 0x08, 0x15, 0xa6, 0xf5, 0xf2, 0xd3, 0xaa, 0x4a, 0xc3, 0xcf, 0x55, 0x51, 168 | 0x55, 0x56, 0x7f, 0xb8, 0x8b, 0x50, 0x74, 0xc0, 0x61, 0x18, 0x66, 0x8c, 169 | 0x37, 0x51, 0x7b, 0x2d, 0xcd, 0x49, 0x9f, 0x3f, 0x74, 0x98, 0x35, 0x3b, 170 | 0x3f, 0xb6, 0x6d, 0x1c, 0xe0, 0x8c, 0x89, 0xf9, 0x66, 0x17, 0x25, 0x10, 171 | 0xe9, 0xe3, 0xaa, 0xba, 0x37, 0x09, 0xf4, 0x45, 0xb0, 0x53, 0xb7, 0x2a, 172 | 0x57, 0x95, 0x97, 0xd1, 0x71, 0xfb, 0xad, 0xbc, 0xb8, 0xac, 0x3a, 0xa9, 173 | 0x1d, 0x85, 0x8d, 0x07, 0x1b, 0x78, 0xaf, 0x2d, 0x60, 0xd3, 0x58, 0x38, 174 | 0xa5, 0x98, 0x29, 0x39, 0xd9, 0x96, 0xfe, 0x2a, 0x5c, 0xa8, 0x18, 0xc6, 175 | 0xab, 0xc2, 0x25, 0xc5, 0x45, 0xf6, 0x32, 0x07, 0x07, 0xa2, 0x6c, 0xfa, 176 | 0xaa, 0xd9, 0xb1, 0xb4, 0x62, 0xc4, 0x78, 0x35, 0x33, 0x8b, 0xbd, 0xec, 177 | 0xe2, 0x88, 0xd3, 0xf0, 0xd8, 0x67, 0x5f, 0x50, 0x77, 0xa4, 0xc5, 0xa6, 178 | 0x63, 0xfd, 0x14, 0xb8, 0xf3, 0xdd, 0x6d, 0x34, 0xf7, 0xf6, 0x26, 0xc6, 179 | 0x99, 0x63, 0xdd, 0x22, 0x4c, 0xf0, 0xb8, 0xc9, 0x74, 0xb9, 0x1c, 0xf4, 180 | 0x13, 0x74, 0x9f, 0xdd, 0x7f, 0xd0, 0xa6, 0x93, 0xe1, 0x72, 0x71, 0x41, 181 | 0x51, 0xa1, 0xa5, 0x9f, 0x22, 0x8f, 0x91, 0xbc, 0x8c, 0x31, 0xa5, 0x5e, 182 | 0x2f, 0xaa, 0x8a, 0x88, 0x50, 0x1f, 0x0c, 0x12, 0x75, 0x84, 0xc2, 0x65, 183 | 0xa5, 0x53, 0x79, 0x6a, 0xd1, 0x42, 0x52, 0x21, 0x1c, 0x8d, 0x72, 0xee, 184 | 0x3f, 0x5f, 0x22, 0xa6, 0x6a, 0xe7, 0xc0, 0x55, 0xdb, 0x76, 0xb0, 0xf8, 185 | 0xc6, 0xd3, 0xc9, 0xc9, 0xf0, 0xd8, 0xf4, 0x5e, 0x68, 0x68, 0x64, 0xf3, 186 | 0x91, 0x96, 0x84, 0xb0, 0xc0, 0x5d, 0xe7, 0x9c, 0xc5, 0x43, 0xf3, 0xcf, 187 | 0x23, 0xdb, 0x63, 0x44, 0xbb, 0x85, 0x53, 0xa6, 0xd0, 0xf2, 0xb3, 0x9b, 188 | 0xf8, 0xaa, 0xb7, 0x97, 0x4b, 0x5f, 0x7e, 0x0d, 0xcb, 0xb1, 0x77, 0x77, 189 | 0x76, 0xd9, 0x74, 0x00, 0xca, 0xbc, 0x5e, 0xcb, 0x22, 0x32, 0x3d, 0xce, 190 | 0x0a, 0xd0, 0x6d, 0x76, 0x50, 0x55, 0x47, 0x1c, 0x37, 0xde, 0x67, 0x7b, 191 | 0xdc, 0x94, 0xe4, 0xe6, 0x0c, 0x13, 0xc0, 0x9b, 0xe1, 0x31, 0xd7, 0x48, 192 | 0xed, 0x40, 0xd2, 0xd1, 0xdf, 0x47, 0xf7, 0xc0, 0x80, 0xcd, 0x98, 0xaa, 193 | 0x72, 0x30, 0xd4, 0x93, 0xd4, 0x07, 0x85, 0x53, 0x32, 0x32, 0x6c, 0x9a, 194 | 0xaa, 0x4a, 0x96, 0xdb, 0x45, 0x49, 0x6e, 0x0e, 0x7d, 0xb1, 0x21, 0x12, 195 | 0x7c, 0x61, 0x2b, 0xd2, 0x32, 0x4d, 0xb7, 0x2b, 0xa1, 0x04, 0x0f, 0x2a, 196 | 0x51, 0x84, 0x4c, 0x14, 0x3a, 0xfa, 0xfb, 0xa9, 0xca, 0xcf, 0x03, 0xa0, 197 | 0x2a, 0x2f, 0xcf, 0xe4, 0xdf, 0x30, 0x97, 0xb7, 0x5b, 0xbf, 0xe1, 0x9c, 198 | 0x17, 0xfe, 0x3d, 0x4c, 0x80, 0x58, 0x5c, 0x0d, 0xc7, 0x73, 0x68, 0xf6, 199 | 0xc1, 0xf9, 0xe7, 0x31, 0xd5, 0x9b, 0x9b, 0xd4, 0xef, 0xd7, 0x73, 0x67, 200 | 0xb3, 0xf1, 0x50, 0x03, 0x0d, 0xa1, 0xb0, 0xa5, 0x2f, 0xfe, 0xb6, 0xff, 201 | 0x20, 0x75, 0x47, 0x5a, 0x58, 0x3a, 0xb5, 0x84, 0x27, 0x7e, 0x78, 0x31, 202 | 0x3b, 0xda, 0x02, 0xfc, 0xe2, 0xbf, 0xdb, 0x89, 0xc6, 0x62, 0xd8, 0xa6, 203 | 0xab, 0x30, 0x23, 0x3f, 0x2f, 0x29, 0xd7, 0xb4, 0xf7, 0xf5, 0x9b, 0x8a, 204 | 0x90, 0xa8, 0x0b, 0xa1, 0xdd, 0x22, 0xb8, 0xbb, 0xa3, 0xd3, 0x96, 0xb2, 205 | 0xd4, 0x9b, 0xcb, 0x82, 0xa2, 0x42, 0x5b, 0x5b, 0xbd, 0x83, 0x83, 0xec, 206 | 0xeb, 0x0e, 0x19, 0xbf, 0x60, 0xc8, 0xc6, 0x0f, 0xf6, 0x84, 0x92, 0x4a, 207 | 0xe9, 0xc5, 0x25, 0x53, 0xb8, 0x77, 0xee, 0xb9, 0x69, 0x56, 0x2a, 0x83, 208 | 0xe7, 0xaa, 0x17, 0x91, 0xe5, 0x49, 0x24, 0xc7, 0xee, 0x81, 0x01, 0xf6, 209 | 0x05, 0x43, 0xb4, 0x1e, 0x3d, 0x06, 0xc0, 0xb1, 0xc1, 0x41, 0xf6, 0x05, 210 | 0x43, 0x1c, 0xee, 0x09, 0x3b, 0x46, 0x2a, 0xd7, 0x57, 0x56, 0xd8, 0x7c, 211 | 0xa9, 0x2a, 0x9f, 0x76, 0x74, 0x5a, 0xf2, 0xb5, 0xbb, 0x80, 0x26, 0xab, 212 | 0xe3, 0x2b, 0x4d, 0x47, 0x92, 0x96, 0xea, 0xb7, 0x17, 0xce, 0x37, 0xcb, 213 | 0x55, 0x93, 0x43, 0x71, 0xe2, 0xce, 0x0d, 0x80, 0x81, 0x9f, 0x6d, 0x96, 214 | 0x0a, 0x1e, 0x33, 0x8c, 0xaa, 0x2a, 0xfd, 0xb1, 0x98, 0x8d, 0x2f, 0x28, 215 | 0x2a, 0xe4, 0xa9, 0x45, 0x0b, 0x4d, 0x53, 0x55, 0xfb, 0xf7, 0x7e, 0x5b, 216 | 0x80, 0x2b, 0x37, 0xbf, 0xc1, 0x83, 0x1f, 0x7d, 0x92, 0xc4, 0x38, 0x28, 217 | 0x73, 0x0b, 0x4f, 0xe5, 0x86, 0xaa, 0x4a, 0x9b, 0xaf, 0xfd, 0xa1, 0x1e, 218 | 0xc3, 0x1c, 0x0d, 0x1e, 0x9b, 0x5c, 0xa0, 0xf5, 0xd6, 0x06, 0xe6, 0xad, 219 | 0xd6, 0xaf, 0xd9, 0x17, 0x0c, 0xd9, 0x1e, 0xbf, 0x74, 0x6a, 0x09, 0x8f, 220 | 0x5c, 0x74, 0x81, 0xb9, 0x7c, 0xa6, 0x87, 0x8e, 0x50, 0x47, 0x5f, 0x54, 221 | 0x7c, 0x1a, 0xef, 0xac, 0x58, 0x4e, 0x61, 0x76, 0xb6, 0x3d, 0x7e, 0x47, 222 | 0x5b, 0x3b, 0x57, 0xbc, 0xf6, 0x3a, 0x83, 0xf1, 0xb8, 0xdd, 0x76, 0xcb, 223 | 0x8c, 0x2a, 0x36, 0x2e, 0x59, 0x44, 0x8e, 0x27, 0xc3, 0x8e, 0x38, 0x81, 224 | 0xbe, 0x3e, 0xea, 0x9a, 0x5b, 0xf8, 0xa8, 0xbd, 0x03, 0xdb, 0xbe, 0x10, 225 | 0x4a, 0xbd, 0x5e, 0x5e, 0xfc, 0x71, 0xb5, 0x9d, 0xc8, 0x00, 0xfe, 0xb4, 226 | 0x67, 0x2f, 0x71, 0x9b, 0x0f, 0xad, 0x77, 0x73, 0xe5, 0x8a, 0x22, 0x84, 227 | 0x6b, 0x2c, 0xfe, 0x0e, 0x87, 0xc3, 0xdc, 0x3c, 0x63, 0xba, 0x3d, 0xe1, 228 | 0x25, 0xc5, 0xa7, 0x31, 0xab, 0xa0, 0x80, 0x8f, 0x02, 0x1d, 0xf4, 0x44, 229 | 0x07, 0x92, 0x4b, 0x5b, 0x84, 0xfc, 0xac, 0x4c, 0xd6, 0xcc, 0x9f, 0x8b, 230 | 0x7f, 0xd1, 0x42, 0xf2, 0x33, 0x33, 0xed, 0x89, 0x9a, 0x7b, 0x7b, 0xb9, 231 | 0x7c, 0xf3, 0xeb, 0xec, 0xe9, 0x0e, 0xd2, 0xd5, 0x3f, 0xc0, 0xf2, 0xb2, 232 | 0x52, 0xfb, 0xdd, 0xec, 0xc9, 0x05, 0x5c, 0x3b, 0xad, 0x9c, 0x43, 0x3d, 233 | 0x61, 0xbe, 0xb2, 0x12, 0x9a, 0xc5, 0x13, 0xc6, 0x14, 0xd7, 0x4d, 0x2b, 234 | 0xe7, 0xa5, 0xcb, 0x97, 0x50, 0xe6, 0xf5, 0xda, 0xe3, 0xf6, 0x74, 0x07, 235 | 0xf9, 0xd5, 0xb6, 0xf7, 0x89, 0xd9, 0x56, 0x20, 0x3e, 0xc1, 0xe7, 0x9f, 236 | 0x8e, 0xea, 0x01, 0x04, 0xfb, 0xec, 0xe7, 0xe1, 0x05, 0xe7, 0xb3, 0xfa, 237 | 0xbc, 0x39, 0x38, 0x21, 0x1a, 0x8f, 0xb3, 0xb5, 0xe5, 0x6b, 0x76, 0x04, 238 | 0x02, 0x74, 0xf4, 0xf5, 0x33, 0x29, 0x2b, 0x8b, 0x79, 0xa7, 0x4e, 0xe6, 239 | 0x8a, 0xb2, 0xd2, 0xa4, 0xba, 0x09, 0xe0, 0x9b, 0x63, 0x11, 0xaa, 0x5f, 240 | 0xad, 0xe3, 0x40, 0x30, 0x64, 0x73, 0xb4, 0xfa, 0xbc, 0x39, 0xac, 0x5d, 241 | 0x70, 0xfe, 0xb0, 0xed, 0x41, 0x7d, 0x30, 0xc4, 0x1b, 0x2d, 0xad, 0x34, 242 | 0x98, 0x76, 0x3f, 0x3d, 0x3f, 0x8f, 0x2b, 0xca, 0x4a, 0x39, 0xcb, 0x4c, 243 | 0x80, 0x16, 0x04, 0x07, 0xa2, 0x2c, 0x7c, 0xf9, 0x55, 0xea, 0x83, 0x41, 244 | 0xcb, 0xc2, 0xe2, 0x20, 0x67, 0x0a, 0xeb, 0xfd, 0x2e, 0x84, 0xcf, 0x51, 245 | 0x66, 0x59, 0x0e, 0xeb, 0x12, 0x58, 0x77, 0xf1, 0x85, 0xdc, 0x33, 0x67, 246 | 0x76, 0x92, 0xf7, 0x8f, 0x07, 0x3e, 0xe9, 0xe8, 0xe4, 0xfa, 0xd7, 0xdf, 247 | 0x32, 0x0a, 0xb4, 0x94, 0x8d, 0xcd, 0x9d, 0x67, 0x9d, 0xc1, 0x93, 0x0b, 248 | 0x2f, 0x21, 0xdb, 0x33, 0xf2, 0x71, 0x54, 0x3a, 0x68, 0x8b, 0x44, 0x58, 249 | 0xb1, 0x65, 0x2b, 0xbb, 0x02, 0x1d, 0xce, 0x2d, 0xc1, 0x97, 0x08, 0x73, 250 | 0xdc, 0xd4, 0xbd, 0xaa, 0x5c, 0xb9, 0x22, 0x1f, 0x61, 0x09, 0x60, 0x9b, 251 | 0xfa, 0x9b, 0xa6, 0x3f, 0xfc, 0xa0, 0xb8, 0xd8, 0x88, 0xf5, 0xa6, 0x63, 252 | 0x02, 0x69, 0xf1, 0xc8, 0xd0, 0x10, 0xeb, 0x3e, 0xfd, 0x82, 0x9f, 0xbf, 253 | 0xbb, 0x8d, 0xae, 0x81, 0x81, 0xe4, 0x9d, 0x98, 0x89, 0x7f, 0xda, 0xd9, 254 | 0xc5, 0x2b, 0x4d, 0xcd, 0xcc, 0x9a, 0x5c, 0x40, 0x99, 0x37, 0xd7, 0x56, 255 | 0x8e, 0x33, 0x49, 0xa5, 0xe2, 0x9b, 0x9b, 0x5b, 0xb8, 0x66, 0xcb, 0x56, 256 | 0xf6, 0x87, 0x42, 0x09, 0x5a, 0xc6, 0xeb, 0x3f, 0xb2, 0xaa, 0x66, 0xbb, 257 | 0xb5, 0x23, 0x2b, 0x46, 0xb5, 0xd9, 0xce, 0xca, 0xd6, 0xc9, 0x80, 0x40, 258 | 0xae, 0x27, 0x83, 0xdb, 0xce, 0x9c, 0xc1, 0x4d, 0x33, 0xaa, 0x98, 0x5f, 259 | 0x78, 0x2a, 0x13, 0x1c, 0x7b, 0x84, 0xc1, 0x78, 0x9c, 0xfa, 0x60, 0x88, 260 | 0x97, 0x1a, 0x9b, 0x78, 0x6a, 0xdf, 0x7e, 0xbe, 0x8d, 0xa4, 0x1e, 0x28, 261 | 0x9b, 0xea, 0x32, 0x62, 0xb6, 0x8d, 0x8b, 0x08, 0x97, 0x95, 0x9c, 0xce, 262 | 0x1d, 0x67, 0x9f, 0x41, 0x75, 0x49, 0x09, 0x45, 0xd9, 0xc9, 0xe7, 0x08, 263 | 0x6d, 0x91, 0x3e, 0xde, 0x6c, 0x69, 0xc5, 0xbf, 0xef, 0x00, 0xef, 0xb7, 264 | 0x05, 0x6c, 0x95, 0x1b, 0x39, 0x49, 0x01, 0x89, 0xa2, 0x5a, 0xce, 0xaa, 265 | 0xbb, 0xda, 0x12, 0x7a, 0xf2, 0x6d, 0x78, 0x1a, 0xe4, 0x0e, 0xfb, 0xd9, 266 | 0x91, 0x31, 0x2d, 0x0d, 0xe6, 0x78, 0x3c, 0x4c, 0xf5, 0xe6, 0x92, 0x9f, 267 | 0x91, 0xc1, 0xd1, 0xa1, 0x21, 0xbe, 0x39, 0x16, 0xa1, 0x27, 0x1a, 0x1d, 268 | 0x79, 0xef, 0x3b, 0x16, 0xa8, 0x91, 0x55, 0x8b, 0x73, 0xb2, 0x29, 0xca, 269 | 0xce, 0x06, 0x8c, 0x6d, 0x64, 0x20, 0xd2, 0x67, 0x94, 0x26, 0x4e, 0x3e, 270 | 0x92, 0x70, 0xfd, 0x2b, 0xb5, 0x77, 0xdd, 0x09, 0x49, 0x67, 0xa3, 0xb2, 271 | 0x16, 0xb8, 0x19, 0xcc, 0x63, 0x15, 0x47, 0x0d, 0x67, 0x8d, 0x8e, 0x0c, 272 | 0x0d, 0x25, 0x4a, 0x02, 0x27, 0xd5, 0xd4, 0x4d, 0xf7, 0x88, 0x13, 0x33, 273 | 0x4c, 0xd8, 0x98, 0x2a, 0x5f, 0x1f, 0x8b, 0xf0, 0xf5, 0xd1, 0xc8, 0xd8, 274 | 0x87, 0x01, 0x06, 0xf4, 0xa3, 0xb2, 0xd6, 0x7a, 0x48, 0x1c, 0xab, 0x18, 275 | 0xe7, 0x2c, 0x8f, 0xa7, 0x26, 0x27, 0xdb, 0x04, 0xec, 0x36, 0x0b, 0x4d, 276 | 0x83, 0x3b, 0x84, 0x4d, 0x24, 0xba, 0x14, 0x3c, 0xa9, 0x04, 0x4f, 0xd3, 277 | 0x3e, 0x26, 0xae, 0x8f, 0xb3, 0x2a, 0x71, 0x8b, 0x93, 0x7a, 0x3f, 0xb0, 278 | 0x16, 0xa4, 0x3e, 0xc1, 0x4d, 0xc2, 0x63, 0x12, 0xe5, 0xb4, 0xe3, 0x9d, 279 | 0x85, 0x8b, 0xb3, 0xdd, 0xd1, 0xd7, 0xee, 0x97, 0xf2, 0x0c, 0xe6, 0x4a, 280 | 0xa5, 0xfe, 0x18, 0x1d, 0x17, 0xa9, 0x37, 0x2d, 0xc5, 0x86, 0x64, 0x01, 281 | 0x8c, 0x33, 0xc7, 0x5b, 0x41, 0x23, 0x09, 0xa9, 0x2d, 0x1a, 0xea, 0xa0, 282 | 0x97, 0x82, 0x93, 0x82, 0x93, 0x06, 0x4f, 0x6b, 0x12, 0x23, 0xf5, 0x4f, 283 | 0x0b, 0x06, 0x6f, 0x29, 0x57, 0x4f, 0xc3, 0x6f, 0x68, 0x6a, 0x6b, 0x76, 284 | 0x83, 0xdc, 0x8d, 0x6a, 0xdc, 0x58, 0x31, 0x4d, 0x98, 0xc8, 0x58, 0xf8, 285 | 0xb8, 0xfa, 0x3b, 0x76, 0x5c, 0x16, 0xe3, 0xe9, 0xfa, 0x24, 0xe3, 0x71, 286 | 0xe0, 0xee, 0x74, 0x57, 0x4e, 0x23, 0xbb, 0x8a, 0xcf, 0x7f, 0x1f, 0xf0, 287 | 0xe8, 0xa8, 0x3a, 0x39, 0xd1, 0xe8, 0x73, 0xfc, 0x70, 0x3f, 0xb5, 0x35, 288 | 0x69, 0x2f, 0x38, 0x46, 0xbb, 0x23, 0x5b, 0x07, 0xdc, 0x0f, 0xc4, 0xed, 289 | 0xfd, 0xaf, 0xed, 0x53, 0x29, 0x8e, 0xed, 0xf4, 0xb5, 0x93, 0x0b, 0x71, 290 | 0x93, 0x87, 0xb4, 0xcc, 0xc3, 0x78, 0xf4, 0xe7, 0xf3, 0xaf, 0x44, 0xf5, 291 | 0x2f, 0x40, 0x8e, 0x33, 0x8f, 0xdb, 0xb8, 0xb3, 0xe9, 0x44, 0x21, 0x1d, 292 | 0x0d, 0x91, 0x08, 0x86, 0xd9, 0x0c, 0xbb, 0x95, 0x49, 0x1d, 0x3a, 0x36, 293 | 0xf8, 0xfc, 0xf3, 0x00, 0xc7, 0x35, 0xeb, 0xff, 0x1d, 0x4e, 0xe2, 0x35, 294 | 0x2b, 0x98, 0x8e, 0xcd, 0x05, 0xc0, 0xc3, 0x28, 0xfd, 0x89, 0x58, 0x6e, 295 | 0xff, 0x25, 0x1c, 0xd8, 0x7a, 0x18, 0xd7, 0xd5, 0x2a, 0xa9, 0x7d, 0xfa, 296 | 0x41, 0x1f, 0xc6, 0xb8, 0x85, 0x19, 0x93, 0x79, 0x38, 0x11, 0x17, 0xf4, 297 | 0xf9, 0x2b, 0x41, 0xd7, 0x80, 0xac, 0x44, 0x35, 0xf3, 0xe4, 0x98, 0x90, 298 | 0x7c, 0x0f, 0x9f, 0x1a, 0xa4, 0x82, 0x6f, 0x43, 0x31, 0x98, 0x1f, 0x7b, 299 | 0x60, 0x7d, 0xec, 0x71, 0x5c, 0x10, 0x47, 0xb5, 0x1e, 0xe4, 0x79, 0xd0, 300 | 0x67, 0x58, 0x75, 0xd7, 0xf7, 0xf4, 0xb1, 0x47, 0x2a, 0xac, 0xf7, 0xbb, 301 | 0x40, 0x8d, 0xcf, 0x6d, 0x44, 0x8c, 0xcf, 0x6d, 0xa0, 0x02, 0xa5, 0x28, 302 | 0x51, 0xdd, 0x12, 0x05, 0xda, 0x31, 0xf6, 0xdf, 0xf5, 0x28, 0x3b, 0x91, 303 | 0x93, 0xf3, 0xb9, 0xcd, 0xff, 0x00, 0xeb, 0xa8, 0x49, 0x3d, 0x7e, 0x65, 304 | 0x6c, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 305 | 0x60, 0x82 306 | }; 307 | 308 | void WiFiTerm_webfiles_c::send_webfiles_favicon_ico() 309 | { 310 | if (WiFiTerm_webfiles.server != NULL) 311 | { 312 | WiFiTerm_webfiles.server->send_P( 313 | 200, 314 | WiFiTerm_webfiles_content_type_ico_P, 315 | webfiles_favicon_ico_P, 316 | 2954 317 | ); 318 | } 319 | } 320 | 321 | const char webfiles_term_html_P[] PROGMEM = 322 | { 323 | 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 324 | 0x6d, 0x6c, 0x3e, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x20, 325 | 0x20, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x20, 0x20, 326 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 327 | 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x75, 0x74, 0x66, 328 | 0x2d, 0x38, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 329 | 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 330 | 0x65, 0x3d, 0x22, 0x76, 0x69, 0x65, 0x77, 0x70, 0x6f, 0x72, 0x74, 0x22, 331 | 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x77, 0x69, 332 | 0x64, 0x74, 0x68, 0x3d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x77, 333 | 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 334 | 0x6c, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x31, 0x2e, 0x30, 0x22, 335 | 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 336 | 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 337 | 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, 338 | 0x66, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 339 | 0x72, 0x6d, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 340 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x63, 0x72, 0x69, 341 | 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 342 | 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 343 | 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x73, 0x63, 0x72, 0x69, 0x70, 344 | 0x74, 0x73, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 345 | 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x20, 0x20, 346 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6e, 0x6f, 0x73, 0x63, 0x72, 347 | 0x69, 0x70, 0x74, 0x3e, 0x49, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x4a, 348 | 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x21, 0x3c, 0x2f, 349 | 0x6e, 0x6f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x20, 0x20, 350 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 351 | 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 352 | 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x69, 353 | 0x74, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x68, 354 | 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x62, 0x6f, 355 | 0x64, 0x79, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 356 | 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x65, 0x72, 357 | 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 358 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 359 | 0x20, 0x69, 0x64, 0x3d, 0x22, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 360 | 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 361 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x54, 0x65, 362 | 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 363 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 364 | 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 365 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 366 | 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x3e, 0x0a, 367 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 368 | 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 369 | 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x3e, 370 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 371 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 372 | 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 373 | 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x78, 0x74, 0x49, 374 | 0x6e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x6e, 0x74, 375 | 0x65, 0x72, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 376 | 0x64, 0x65, 0x72, 0x3d, 0x22, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 377 | 0x2e, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x61, 0x78, 0x6c, 0x65, 0x6e, 0x67, 378 | 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 379 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 380 | 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 381 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 382 | 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x6e, 383 | 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x3e, 0x0a, 384 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 385 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 386 | 0x74, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x6e, 0x64, 387 | 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x6f, 0x6e, 0x63, 0x6c, 388 | 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x29, 0x22, 389 | 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 390 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 391 | 0x20, 0x20, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 392 | 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x52, 0x65, 0x64, 0x22, 0x20, 393 | 0x73, 0x72, 0x63, 0x3d, 0x22, 0x69, 0x63, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 394 | 0x65, 0x64, 0x41, 0x72, 0x72, 0x6f, 0x77, 0x2e, 0x70, 0x6e, 0x67, 0x22, 395 | 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 396 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 397 | 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69, 0x64, 0x3d, 398 | 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x47, 0x72, 0x65, 399 | 0x65, 0x6e, 0x22, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x69, 0x63, 0x6f, 400 | 0x6e, 0x73, 0x2f, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x41, 0x72, 0x72, 0x6f, 401 | 0x77, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 402 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 403 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x75, 0x74, 0x74, 404 | 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 405 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 406 | 0x76, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 407 | 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 408 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 409 | 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6f, 0x75, 0x74, 0x70, 0x75, 410 | 0x74, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 411 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x65, 0x78, 412 | 0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 413 | 0x6c, 0x79, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x78, 0x74, 0x4f, 0x75, 414 | 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 415 | 0x61, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 416 | 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0a, 0x20, 0x20, 417 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 418 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 419 | 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e 420 | }; 421 | 422 | void WiFiTerm_webfiles_c::send_webfiles_term_html() 423 | { 424 | if (WiFiTerm_webfiles.server != NULL) 425 | { 426 | WiFiTerm_webfiles.server->send_P( 427 | 200, 428 | WiFiTerm_webfiles_content_type_html_P, 429 | webfiles_term_html_P, 430 | 1160 431 | ); 432 | } 433 | } 434 | 435 | const char webfiles_icons_greenArrow_png_P[] PROGMEM = 436 | { 437 | 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 438 | 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 439 | 0x08, 0x02, 0x00, 0x00, 0x00, 0xb9, 0x11, 0xa0, 0xea, 0x00, 0x00, 0x00, 440 | 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 441 | 0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x01, 0x4f, 0x49, 0x44, 442 | 0x41, 0x54, 0x78, 0xda, 0xbd, 0x93, 0x4d, 0x4b, 0x42, 0x51, 0x10, 0x86, 443 | 0x1f, 0x07, 0x06, 0x2c, 0xe5, 0x6e, 0x5d, 0x45, 0x3f, 0xa2, 0x45, 0xb4, 444 | 0x10, 0x32, 0x28, 0x0a, 0x0b, 0x89, 0xa0, 0x28, 0x4b, 0x8c, 0xda, 0x44, 445 | 0xa2, 0x90, 0x88, 0x85, 0x12, 0x5a, 0xf9, 0x51, 0x8a, 0xa5, 0x45, 0xb8, 446 | 0x52, 0x71, 0x13, 0x18, 0xb4, 0x13, 0x44, 0xda, 0x08, 0xb5, 0xe9, 0x57, 447 | 0x75, 0xaf, 0x04, 0x51, 0x44, 0x04, 0x5e, 0x3a, 0x0c, 0x07, 0xe6, 0xf0, 448 | 0xce, 0x33, 0x73, 0xce, 0x99, 0xe1, 0xe5, 0x0f, 0xab, 0xff, 0xd6, 0xff, 449 | 0x5d, 0xc0, 0x5f, 0x28, 0xae, 0xa0, 0xcb, 0x17, 0xf2, 0x8d, 0x4a, 0xf1, 450 | 0x94, 0x3c, 0xec, 0x32, 0xe1, 0x9f, 0xe8, 0xf6, 0xba, 0x23, 0x50, 0xee, 451 | 0x3c, 0x8e, 0x6b, 0x07, 0x09, 0x98, 0x23, 0x5b, 0xce, 0xfe, 0x4c, 0x69, 452 | 0x3f, 0xb5, 0x1b, 0x9d, 0x46, 0xf3, 0xb1, 0xf9, 0xc5, 0x3a, 0x4d, 0xf3, 453 | 0xb0, 0xd5, 0x69, 0xd5, 0x1f, 0xea, 0x46, 0xd5, 0xe0, 0x1e, 0xa9, 0x08, 454 | 0x69, 0x58, 0xc0, 0xbf, 0xef, 0xff, 0x4e, 0x71, 0xaf, 0xb8, 0x99, 0x85, 455 | 0x79, 0x58, 0x84, 0x65, 0x08, 0xc0, 0x1a, 0xac, 0xc3, 0x26, 0x6c, 0x63, 456 | 0x5e, 0x84, 0x08, 0x54, 0xa0, 0x0e, 0xb7, 0x50, 0x40, 0x52, 0xc2, 0x2a, 457 | 0x93, 0x4b, 0x93, 0xbd, 0xe7, 0xde, 0x27, 0xc5, 0xb9, 0xe1, 0x94, 0xb0, 458 | 0xc8, 0x81, 0x48, 0x54, 0xe4, 0x48, 0x24, 0x29, 0x92, 0x16, 0xc9, 0x8a, 459 | 0xe4, 0x44, 0x8a, 0x22, 0x65, 0x91, 0xaa, 0x50, 0x85, 0x1a, 0xdc, 0x40, 460 | 0x09, 0x32, 0x98, 0x1a, 0xb6, 0x90, 0x19, 0xc9, 0xd5, 0x72, 0x1f, 0x94, 461 | 0xb1, 0xe0, 0x98, 0x95, 0xf0, 0x10, 0xa2, 0x10, 0x87, 0x63, 0xac, 0xb2, 462 | 0x33, 0x70, 0x61, 0x65, 0xe6, 0x72, 0x18, 0x69, 0xda, 0x15, 0x14, 0x21, 463 | 0x0f, 0x59, 0x38, 0x81, 0x18, 0x84, 0x60, 0x9a, 0xc0, 0x41, 0xc0, 0xa2, 464 | 0x18, 0x3b, 0x86, 0xee, 0xab, 0x46, 0x54, 0x63, 0xaa, 0x71, 0xd5, 0xa4, 465 | 0x6a, 0x4a, 0xf5, 0x54, 0xf5, 0x4c, 0x35, 0xa7, 0x9a, 0x57, 0x2d, 0xa8, 466 | 0x16, 0x87, 0xbb, 0xe9, 0x9e, 0xab, 0x66, 0x54, 0xd3, 0xaa, 0x09, 0x2b, 467 | 0x64, 0x7c, 0x6f, 0x9c, 0x29, 0xbc, 0x61, 0xaf, 0x4d, 0xb5, 0xd8, 0xf3, 468 | 0x2e, 0xf6, 0xfc, 0x91, 0x3d, 0xfd, 0x62, 0x5b, 0xef, 0xfe, 0xd3, 0x1c, 469 | 0xd9, 0x33, 0xd3, 0x83, 0xd7, 0xc1, 0xef, 0x82, 0x77, 0x8b, 0x17, 0x39, 470 | 0x33, 0x7b, 0x13, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 471 | 0x44, 0xae, 0x42, 0x60, 0x82 472 | }; 473 | 474 | void WiFiTerm_webfiles_c::send_webfiles_icons_greenArrow_png() 475 | { 476 | if (WiFiTerm_webfiles.server != NULL) 477 | { 478 | WiFiTerm_webfiles.server->send_P( 479 | 200, 480 | WiFiTerm_webfiles_content_type_png_P, 481 | webfiles_icons_greenArrow_png_P, 482 | 413 483 | ); 484 | } 485 | } 486 | 487 | const char webfiles_icons_redArrow_png_P[] PROGMEM = 488 | { 489 | 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 490 | 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 491 | 0x08, 0x02, 0x00, 0x00, 0x00, 0xb9, 0x11, 0xa0, 0xea, 0x00, 0x00, 0x00, 492 | 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 493 | 0x12, 0x01, 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x01, 0x48, 0x49, 0x44, 494 | 0x41, 0x54, 0x78, 0xda, 0xbd, 0x94, 0x4b, 0x4b, 0x42, 0x51, 0x10, 0x80, 495 | 0x3f, 0x07, 0x06, 0x7c, 0x71, 0xb7, 0xae, 0xc4, 0x5f, 0xe2, 0xc2, 0xb5, 496 | 0x0b, 0x7f, 0x45, 0xdb, 0x0a, 0x82, 0x68, 0x13, 0x61, 0x61, 0x41, 0xa1, 497 | 0x11, 0x12, 0x58, 0xd0, 0xd5, 0x0c, 0xa5, 0xb2, 0x0c, 0x49, 0xf3, 0x6a, 498 | 0x5a, 0x4a, 0x52, 0x46, 0x0f, 0x28, 0xfa, 0x41, 0xdd, 0x6e, 0x45, 0x10, 499 | 0x51, 0x52, 0x97, 0x0e, 0xc3, 0xc0, 0x61, 0x86, 0x6f, 0xe6, 0xcc, 0xe3, 500 | 0x30, 0x18, 0xe1, 0xdc, 0xf7, 0xfb, 0xdf, 0x3b, 0x30, 0x0a, 0x25, 0x13, 501 | 0x08, 0x24, 0x63, 0xb1, 0xbf, 0x52, 0x06, 0xa1, 0xd0, 0x0e, 0xcc, 0x84, 502 | 0xc3, 0xbd, 0x46, 0xe3, 0xf7, 0x94, 0xc7, 0x50, 0xe8, 0xc9, 0xe3, 0x69, 503 | 0xd8, 0x20, 0x28, 0x24, 0x93, 0x5f, 0x53, 0xba, 0xc5, 0x62, 0xcb, 0x34, 504 | 0xdb, 0xf9, 0xfc, 0xab, 0xb4, 0xde, 0xc5, 0x32, 0x4d, 0xab, 0x50, 0xb0, 505 | 0x72, 0xb9, 0x1b, 0xc3, 0x78, 0x80, 0x5b, 0x91, 0x16, 0x24, 0x21, 0x15, 506 | 0x8f, 0x7f, 0xa6, 0x4c, 0x05, 0x83, 0x93, 0x4e, 0x90, 0x59, 0x98, 0x87, 507 | 0x25, 0x48, 0xc3, 0x1a, 0xac, 0xc3, 0x06, 0xe4, 0x61, 0x1f, 0x86, 0x70, 508 | 0x07, 0xd7, 0xd0, 0x83, 0xba, 0xc8, 0x0a, 0x4c, 0x47, 0x22, 0x03, 0xcb, 509 | 0xfa, 0xa0, 0xcc, 0x79, 0xbd, 0x19, 0x91, 0x4d, 0x91, 0xbc, 0x48, 0x49, 510 | 0xa4, 0x22, 0x52, 0x13, 0x69, 0x8a, 0x74, 0x44, 0x7a, 0x22, 0x03, 0x91, 511 | 0xa1, 0xc8, 0x15, 0x5c, 0xc2, 0x05, 0x9c, 0xc1, 0x09, 0x1c, 0x88, 0xd8, 512 | 0x61, 0x26, 0x44, 0xca, 0xa9, 0xd4, 0x1b, 0x25, 0xe5, 0xf3, 0x65, 0xc1, 513 | 0x84, 0x22, 0x94, 0xa1, 0x02, 0x47, 0x70, 0x0c, 0x4d, 0x68, 0x43, 0x07, 514 | 0xba, 0x70, 0xee, 0xe8, 0x53, 0xb0, 0x5f, 0x64, 0x57, 0xa7, 0xea, 0x38, 515 | 0xaf, 0xc2, 0x38, 0x2c, 0x27, 0x12, 0x2f, 0x94, 0x45, 0xc3, 0xc8, 0xaa, 516 | 0x9a, 0xaa, 0xdb, 0xaa, 0x25, 0xd5, 0x3d, 0xd5, 0x43, 0xd5, 0x9a, 0x6a, 517 | 0x5d, 0xb5, 0xa9, 0x6a, 0xa9, 0xb6, 0x54, 0xdb, 0x8e, 0xb6, 0xaf, 0x0d, 518 | 0xc7, 0x54, 0x55, 0xdd, 0x55, 0xdd, 0x52, 0x4d, 0xfb, 0xfd, 0x63, 0xb0, 519 | 0x10, 0x8d, 0xba, 0x94, 0x8b, 0x3b, 0x75, 0x71, 0xa7, 0x47, 0xee, 0xcc, 520 | 0x8b, 0x6b, 0xb3, 0xfb, 0x4f, 0x7b, 0xe4, 0xce, 0x4e, 0xff, 0xf8, 0xbf, 521 | 0x3c, 0x03, 0x97, 0xf8, 0x5e, 0xc5, 0x83, 0xd5, 0x53, 0x87, 0x00, 0x00, 522 | 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 523 | }; 524 | 525 | void WiFiTerm_webfiles_c::send_webfiles_icons_redArrow_png() 526 | { 527 | if (WiFiTerm_webfiles.server != NULL) 528 | { 529 | WiFiTerm_webfiles.server->send_P( 530 | 200, 531 | WiFiTerm_webfiles_content_type_png_P, 532 | webfiles_icons_redArrow_png_P, 533 | 406 534 | ); 535 | } 536 | } 537 | 538 | const char webfiles_scripts_term_js_P[] PROGMEM = 539 | { 540 | 0x76, 0x61, 0x72, 0x20, 0x77, 0x73, 0x3b, 0x0d, 0x0a, 0x76, 0x61, 0x72, 541 | 0x20, 0x45, 0x53, 0x50, 0x5f, 0x69, 0x70, 0x3b, 0x0d, 0x0a, 0x6c, 0x65, 542 | 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 543 | 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 544 | 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x73, 0x49, 545 | 0x6e, 0x69, 0x74, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 546 | 0x20, 0x77, 0x73, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x57, 0x65, 547 | 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x22, 0x77, 0x73, 0x3a, 548 | 0x2f, 0x2f, 0x22, 0x20, 0x2b, 0x20, 0x45, 0x53, 0x50, 0x5f, 0x69, 0x70, 549 | 0x20, 0x2b, 0x20, 0x22, 0x3a, 0x38, 0x31, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 550 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x73, 0x2e, 0x6f, 0x6e, 0x6f, 551 | 0x70, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 552 | 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x7b, 553 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 554 | 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 555 | 0x75, 0x65, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 556 | 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 557 | 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 558 | 0x20, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 559 | 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 560 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x73, 0x2e, 0x6f, 0x6e, 0x6d, 0x65, 561 | 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 562 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 563 | 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 564 | 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x28, 0x65, 565 | 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x3d, 566 | 0x3d, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x20, 567 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 568 | 0x20, 0x20, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x54, 0x78, 569 | 0x74, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 570 | 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 571 | 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x61, 572 | 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x73, 0x65, 573 | 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 574 | 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x6e, 0x67, 575 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 576 | 0x20, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x50, 0x6f, 0x6e, 577 | 0x67, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 578 | 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 579 | 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x73, 580 | 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x66, 581 | 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x76, 0x65, 582 | 0x6e, 0x74, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 583 | 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 584 | 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0d, 0x0a, 0x20, 585 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x66, 0x66, 0x6c, 0x69, 586 | 0x6e, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 587 | 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 588 | 0x74, 0x28, 0x77, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x2c, 0x20, 0x31, 0x30, 589 | 0x30, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 590 | 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x61, 591 | 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x6e, 0x67, 592 | 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 593 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 594 | 0x65, 0x50, 0x6f, 0x6e, 0x67, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 595 | 0x20, 0x20, 0x20, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x6f, 596 | 0x72, 0x50, 0x6f, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 597 | 0x20, 0x20, 0x20, 0x20, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 598 | 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 599 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x50, 600 | 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x28, 0x29, 0x20, 0x7b, 0x0d, 601 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 0x6e, 602 | 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 603 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x77, 604 | 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x72, 0x50, 0x6f, 0x6e, 605 | 0x67, 0x2b, 0x2b, 0x20, 0x3e, 0x20, 0x32, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 606 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 607 | 0x6f, 0x66, 0x66, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 608 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 609 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x73, 0x2e, 0x73, 0x65, 610 | 0x6e, 0x64, 0x28, 0x22, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 611 | 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 612 | 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x68, 0x61, 0x6e, 0x64, 0x6c, 613 | 0x65, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x31, 614 | 0x30, 0x30, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 615 | 0x6c, 0x65, 0x74, 0x20, 0x69, 0x73, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 616 | 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0d, 0x0a, 0x0d, 617 | 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 618 | 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 619 | 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x69, 0x73, 0x4f, 0x6e, 0x6c, 620 | 0x69, 0x6e, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 621 | 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 622 | 0x74, 0x6f, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x28, 0x29, 0x3b, 0x0d, 623 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x4f, 624 | 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 625 | 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x7d, 0x20, 626 | 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 627 | 0x20, 0x6f, 0x66, 0x66, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 0x20, 0x7b, 628 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 629 | 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 630 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 631 | 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x64, 0x28, 0x29, 0x3b, 632 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 633 | 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 634 | 0x73, 0x65, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 635 | 0x7d, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 636 | 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 637 | 0x6f, 0x6e, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0d, 638 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 639 | 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 640 | 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 641 | 0x6d, 0x67, 0x52, 0x65, 0x64, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 642 | 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 643 | 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 644 | 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 645 | 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 646 | 0x28, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x47, 0x72, 647 | 0x65, 0x65, 0x6e, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 648 | 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x22, 0x69, 649 | 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x22, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 650 | 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 651 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 652 | 0x65, 0x64, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 653 | 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 654 | 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 655 | 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x52, 0x65, 0x64, 656 | 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x64, 0x69, 0x73, 657 | 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x68, 0x65, 658 | 0x72, 0x69, 0x74, 0x22, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 659 | 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 660 | 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 661 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x47, 0x72, 0x65, 0x65, 662 | 0x6e, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x64, 0x69, 663 | 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x22, 0x6e, 0x6f, 0x6e, 664 | 0x65, 0x22, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 665 | 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 666 | 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x75, 0x70, 0x28, 667 | 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 668 | 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 669 | 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x74, 0x78, 670 | 0x74, 0x49, 0x6e, 0x22, 0x29, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 671 | 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 672 | 0x6b, 0x65, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x2c, 0x20, 0x66, 0x75, 673 | 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 674 | 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 675 | 0x66, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6b, 0x65, 0x79, 676 | 0x43, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x31, 0x33, 0x29, 677 | 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 678 | 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 679 | 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x3b, 0x0d, 680 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 681 | 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 682 | 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x73, 0x65, 683 | 0x6e, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x29, 0x2e, 0x63, 684 | 0x6c, 0x69, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 685 | 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 686 | 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 687 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x45, 0x53, 0x50, 0x6c, 688 | 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0d, 689 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x6f, 0x63, 690 | 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 691 | 0x68, 0x6f, 0x73, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 692 | 0x66, 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x22, 693 | 0x29, 0x20, 0x6c, 0x6f, 0x63, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x6f, 0x6d, 694 | 0x70, 0x74, 0x28, 0x22, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x45, 0x53, 695 | 0x50, 0x20, 0x69, 0x70, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 696 | 0x22, 0x2c, 0x22, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 697 | 0x2e, 0x38, 0x30, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 698 | 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x3b, 0x0d, 699 | 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 700 | 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 701 | 0x75, 0x74, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 702 | 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 703 | 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 704 | 0x22, 0x74, 0x78, 0x74, 0x4f, 0x75, 0x74, 0x22, 0x29, 0x2e, 0x69, 0x6e, 705 | 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x22, 0x22, 706 | 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 707 | 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 708 | 0x54, 0x78, 0x74, 0x28, 0x74, 0x78, 0x74, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 709 | 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 710 | 0x61, 0x72, 0x65, 0x61, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 711 | 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 712 | 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x74, 0x78, 0x74, 0x4f, 713 | 0x75, 0x74, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 714 | 0x61, 0x72, 0x20, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x42, 715 | 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x65, 0x78, 716 | 0x74, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 717 | 0x54, 0x6f, 0x70, 0x20, 0x2b, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 718 | 0x65, 0x61, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x69, 719 | 0x67, 0x68, 0x74, 0x20, 0x2b, 0x20, 0x32, 0x30, 0x20, 0x3e, 0x3d, 0x20, 720 | 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 721 | 0x6f, 0x6c, 0x6c, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x3b, 0x0d, 722 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 723 | 0x61, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 724 | 0x2b, 0x3d, 0x20, 0x74, 0x78, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 725 | 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 726 | 0x64, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x29, 0x20, 0x74, 0x65, 0x78, 727 | 0x74, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 728 | 0x54, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 729 | 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x65, 0x69, 730 | 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 731 | 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x6e, 0x64, 732 | 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 733 | 0x20, 0x28, 0x69, 0x73, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x20, 734 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 735 | 0x61, 0x72, 0x20, 0x74, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 736 | 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 737 | 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x74, 0x78, 738 | 0x74, 0x49, 0x6e, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 739 | 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 740 | 0x20, 0x28, 0x74, 0x78, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 741 | 0x20, 0x3e, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 742 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x73, 0x2e, 743 | 0x73, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x78, 0x74, 0x29, 0x3b, 0x0d, 0x0a, 744 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 745 | 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 746 | 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 747 | 0x22, 0x74, 0x78, 0x74, 0x49, 0x6e, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 748 | 0x75, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 749 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 750 | 0x20, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 751 | 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 752 | 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 753 | 0x72, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x48, 0x65, 754 | 0x69, 0x67, 0x68, 0x74, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 755 | 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 756 | 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 757 | 0x61, 0x6c, 0x22, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 758 | 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 759 | 0x76, 0x61, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 760 | 0x69, 0x67, 0x68, 0x74, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 761 | 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 762 | 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 763 | 0x22, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x69, 764 | 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 765 | 0x72, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x48, 766 | 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 767 | 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 768 | 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 769 | 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 770 | 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 771 | 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 772 | 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 773 | 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 774 | 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 775 | 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 776 | 0x22, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x69, 777 | 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 778 | 0x72, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 779 | 0x74, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x6e, 780 | 0x65, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3e, 0x20, 0x69, 0x6e, 781 | 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x48, 0x65, 0x69, 782 | 0x67, 0x68, 0x74, 0x20, 0x3f, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 783 | 0x69, 0x6e, 0x65, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3a, 0x20, 784 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x48, 785 | 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 786 | 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 787 | 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 788 | 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 789 | 0x6c, 0x65, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 790 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 791 | 0x2b, 0x20, 0x22, 0x70, 0x78, 0x22, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 792 | 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 793 | 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 794 | 0x6e, 0x61, 0x6c, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 795 | 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 796 | 0x20, 0x2d, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 797 | 0x68, 0x74, 0x20, 0x2d, 0x20, 0x32, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 798 | 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 799 | 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 800 | 0x64, 0x28, 0x22, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x29, 0x2e, 801 | 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 802 | 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 0x69, 0x67, 803 | 0x68, 0x74, 0x20, 0x2b, 0x20, 0x22, 0x70, 0x78, 0x22, 0x3b, 0x0d, 0x0a, 804 | 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 805 | 0x61, 0x72, 0x65, 0x61, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 806 | 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 807 | 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x74, 0x78, 0x74, 0x4f, 808 | 0x75, 0x74, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 809 | 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 0x6f, 810 | 0x6c, 0x6c, 0x54, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 811 | 0x61, 0x72, 0x65, 0x61, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 812 | 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x77, 813 | 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x72, 0x65, 0x73, 0x69, 814 | 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x3b, 815 | 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 816 | 0x20, 0x73, 0x65, 0x74, 0x75, 0x70, 0x28, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 817 | 0x20, 0x20, 0x20, 0x20, 0x45, 0x53, 0x50, 0x5f, 0x69, 0x70, 0x20, 0x3d, 818 | 0x20, 0x67, 0x65, 0x74, 0x45, 0x53, 0x50, 0x6c, 0x6f, 0x63, 0x61, 0x74, 819 | 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 820 | 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x53, 821 | 0x65, 0x74, 0x75, 0x70, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 822 | 0x20, 0x77, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 823 | 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x29, 824 | 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 825 | 0x65, 0x50, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6e, 0x67, 0x28, 0x29, 0x3b, 826 | 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x77, 0x69, 0x6e, 0x64, 0x6f, 827 | 0x77, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 828 | 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x44, 0x4f, 0x4d, 0x43, 829 | 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 830 | 0x22, 0x2c, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x3d, 831 | 0x3e, 0x20, 0x7b, 0x73, 0x65, 0x74, 0x75, 0x70, 0x28, 0x29, 0x3b, 0x7d, 832 | 0x29, 0x3b, 0x0d, 0x0a 833 | }; 834 | 835 | void WiFiTerm_webfiles_c::send_webfiles_scripts_term_js() 836 | { 837 | if (WiFiTerm_webfiles.server != NULL) 838 | { 839 | WiFiTerm_webfiles.server->send_P( 840 | 200, 841 | WiFiTerm_webfiles_content_type_js_P, 842 | webfiles_scripts_term_js_P, 843 | 3508 844 | ); 845 | } 846 | } 847 | 848 | const char webfiles_styles_term_css_P[] PROGMEM = 849 | { 850 | 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x23, 0x74, 851 | 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, 852 | 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x77, 0x69, 0x64, 0x74, 853 | 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 854 | 0x6e, 0x3a, 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 855 | 0x30, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 856 | 0x33, 0x30, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 857 | 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x7b, 0x0d, 0x0a, 858 | 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 859 | 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 860 | 0x62, 0x28, 0x34, 0x38, 0x2c, 0x20, 0x34, 0x38, 0x2c, 0x20, 0x34, 0x38, 861 | 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 862 | 0x72, 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, 0x0d, 0x0a, 0x20, 863 | 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 864 | 0x6c, 0x79, 0x3a, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 865 | 0x20, 0x4e, 0x65, 0x77, 0x22, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 866 | 0x0a, 0x23, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x0d, 0x0a, 867 | 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 868 | 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 869 | 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 870 | 0x20, 0x22, 0x41, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3b, 0x0d, 0x0a, 0x20, 871 | 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 872 | 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0d, 0x0a, 873 | 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 874 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 875 | 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x70, 876 | 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 877 | 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 878 | 0x30, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 879 | 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 880 | 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 881 | 0x30, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 882 | 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 883 | 0x31, 0x34, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 884 | 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 885 | 0x3a, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 886 | 0x0d, 0x0a, 0x68, 0x31, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 887 | 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 888 | 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 889 | 0x65, 0x3a, 0x20, 0x32, 0x65, 0x6d, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 890 | 0x0d, 0x0a, 0x23, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 891 | 0x20, 0x7b, 0x0d, 0x0a, 0x2f, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 892 | 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x3b, 0x20, 893 | 0x2a, 0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 894 | 0x74, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 895 | 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x63, 0x61, 0x6c, 896 | 0x63, 0x28, 0x31, 0x30, 0x30, 0x25, 0x20, 0x2d, 0x20, 0x37, 0x30, 0x70, 897 | 0x78, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x69, 898 | 0x6e, 0x70, 0x75, 0x74, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x7b, 899 | 0x0d, 0x0a, 0x2f, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 900 | 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x3b, 0x2a, 0x2f, 0x0d, 901 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x20, 902 | 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 903 | 0x0a, 0x23, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x52, 0x65, 904 | 0x64, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 905 | 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 906 | 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x69, 0x6e, 907 | 0x70, 0x75, 0x74, 0x49, 0x6d, 0x67, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x20, 908 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 909 | 0x61, 0x79, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0d, 0x0a, 0x7d, 910 | 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x42, 0x75, 0x74, 911 | 0x74, 0x6f, 0x6e, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 912 | 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x0d, 913 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 914 | 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x38, 0x70, 0x78, 0x3b, 915 | 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x74, 0x78, 0x74, 0x49, 916 | 0x6e, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 917 | 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x0d, 0x0a, 0x7d, 918 | 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x74, 0x78, 0x74, 0x49, 0x6e, 0x2c, 0x20, 919 | 0x23, 0x73, 0x65, 0x6e, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 920 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 921 | 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 922 | 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, 0x39, 0x32, 0x2c, 0x20, 0x31, 923 | 0x39, 0x32, 0x2c, 0x20, 0x31, 0x39, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 924 | 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x62, 0x6c, 925 | 0x61, 0x63, 0x6b, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 926 | 0x74, 0x78, 0x74, 0x4f, 0x75, 0x74, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 927 | 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 928 | 0x25, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 929 | 0x68, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x0d, 0x0a, 0x20, 930 | 0x20, 0x20, 0x20, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 931 | 0x67, 0x3a, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 932 | 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x69, 933 | 0x7a, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0d, 0x0a, 0x20, 934 | 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 935 | 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, 936 | 0x28, 0x36, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x29, 937 | 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 938 | 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 939 | 0x0a, 0x0d, 0x0a, 0x23, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x23, 940 | 0x74, 0x78, 0x74, 0x49, 0x6e, 0x2c, 0x20, 0x23, 0x6f, 0x75, 0x74, 0x70, 941 | 0x75, 0x74, 0x2c, 0x20, 0x23, 0x74, 0x78, 0x74, 0x4f, 0x75, 0x74, 0x20, 942 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x3a, 943 | 0x20, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 944 | 0x0d, 0x0a, 0x0d, 0x0a, 0x23, 0x74, 0x78, 0x74, 0x4f, 0x75, 0x74, 0x20, 945 | 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 946 | 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x30, 0x2e, 0x38, 0x65, 0x6d, 0x3b, 947 | 0x0d, 0x0a, 0x7d, 0x0d, 0x0a 948 | }; 949 | 950 | void WiFiTerm_webfiles_c::send_webfiles_styles_term_css() 951 | { 952 | if (WiFiTerm_webfiles.server != NULL) 953 | { 954 | WiFiTerm_webfiles.server->send_P( 955 | 200, 956 | WiFiTerm_webfiles_content_type_css_P, 957 | webfiles_styles_term_css_P, 958 | 1169 959 | ); 960 | } 961 | } 962 | 963 | -------------------------------------------------------------------------------- /WiFiTerm_webfiles.h: -------------------------------------------------------------------------------- 1 | //Generated by webfiles.py 2 | 3 | //6 file(s) : 4 | // /favicon.ico 5 | // size : 2954 bytes 6 | // content_type : image/vnd.microsoft.icon 7 | // /term.html 8 | // size : 1160 bytes 9 | // content_type : text/html 10 | // /icons/greenArrow.png 11 | // size : 413 bytes 12 | // content_type : image/png 13 | // /icons/redArrow.png 14 | // size : 406 bytes 15 | // content_type : image/png 16 | // /scripts/term.js 17 | // size : 3508 bytes 18 | // content_type : application/javascript 19 | // /styles/term.css 20 | // size : 1169 bytes 21 | // content_type : text/css 22 | 23 | #ifndef WiFiTerm_webfiles_h 24 | #define WiFiTerm_webfiles_h 25 | 26 | #if defined(ESP32) 27 | #include 28 | #elif defined(ESP8266) 29 | #include 30 | #define WebServer ESP8266WebServer 31 | #endif 32 | 33 | class WiFiTerm_webfiles_c 34 | { 35 | public : 36 | WiFiTerm_webfiles_c(); 37 | 38 | void begin(WebServer &webServer); 39 | void activateFavicon(); //must be specificly activated 40 | 41 | WebServer *server; 42 | 43 | private : 44 | static void send_webfiles_favicon_ico(); 45 | static void send_webfiles_term_html(); 46 | static void send_webfiles_icons_greenArrow_png(); 47 | static void send_webfiles_icons_redArrow_png(); 48 | static void send_webfiles_scripts_term_js(); 49 | static void send_webfiles_styles_term_css(); 50 | }; 51 | 52 | extern WiFiTerm_webfiles_c WiFiTerm_webfiles; 53 | 54 | extern const char webfiles_favicon_ico_path_P[]; 55 | extern const char webfiles_term_html_path_P[]; 56 | extern const char webfiles_icons_greenArrow_png_path_P[]; 57 | extern const char webfiles_icons_redArrow_png_path_P[]; 58 | extern const char webfiles_scripts_term_js_path_P[]; 59 | extern const char webfiles_styles_term_css_path_P[]; 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /examples/esp32/Basic/Basic.ino: -------------------------------------------------------------------------------- 1 | #include 2 | const char* ssid = ""; //adjust to your own values 3 | const char* password = ""; //adjust to your own values 4 | 5 | #include "WiFiTerm.h" 6 | 7 | WebServer server(80); 8 | 9 | void setup() 10 | { 11 | Serial.begin(115200); 12 | Serial.print("\nConnecting to WIFI"); 13 | WiFi.begin(ssid, password); 14 | while (WiFi.status() != WL_CONNECTED) 15 | { 16 | delay(500); 17 | Serial.print('.'); 18 | } 19 | Serial.println("connected"); 20 | Serial.print("IP address: "); 21 | Serial.println(WiFi.localIP()); 22 | 23 | server.begin(); 24 | Serial.println("webServer started"); 25 | 26 | term.begin(server); 27 | Serial.println("term started"); 28 | } 29 | 30 | void loop() 31 | { 32 | server.handleClient(); 33 | term.handleClient(); 34 | 35 | if (term.available()) 36 | { 37 | term.print("Received : "); 38 | term.println(term.readString()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/esp32/Full_Demo/Full_Demo.ino: -------------------------------------------------------------------------------- 1 | //WiFiTerm full demo 2 | // 3 | //Please open Serial terminal and follow instructions 4 | // 5 | #include 6 | const char* ssid = ""; //adjust to your own values 7 | const char* password = ""; //adjust to your own values 8 | 9 | #include "WiFiTerm.h" 10 | 11 | WebServer server(80); 12 | 13 | void setup() 14 | { 15 | Serial.begin(115200); 16 | term.link(Serial); //optional : echo every print() on Serial 17 | 18 | term.println("Welcome to WiFiTerm full demo example"); 19 | 20 | term.print("\nConnecting to WiFi"); 21 | WiFi.begin(ssid, password); 22 | while (WiFi.status() != WL_CONNECTED) 23 | { 24 | delay(500); 25 | term.print('.'); 26 | } 27 | term.println("connected"); 28 | 29 | server.begin(); 30 | term.begin(server); 31 | 32 | term.setAsDefaultWhenUrlNotFound(); //optional : redirect any unknown url to /term.html 33 | term.activateArduinoFavicon(); //optional : send Arduino icon when a browser asks for favicon 34 | 35 | term.println("WiFiTerm started"); 36 | term.println(); 37 | 38 | Serial.print("I'm waiting for you at http://"); 39 | Serial.print(WiFi.localIP()); 40 | Serial.println("/term.html"); 41 | 42 | term.unlink(); //optional : stop echo on Serial 43 | term.println("Welcome here"); 44 | term.println("Please note that previous lines were printed BEFORE WiFiTerm connection"); 45 | term.println("Now send me some text..."); 46 | } 47 | 48 | void loop() 49 | { 50 | server.handleClient(); 51 | term.handleClient(); 52 | 53 | static int step = 0; 54 | static long unsigned int timer, speed, nb; 55 | 56 | if (step == 0) 57 | { 58 | if (term.available()) 59 | { 60 | term.print("Ok I received : "); 61 | while (term.available()) //standard way 62 | { 63 | char c = term.read(); 64 | term.print(c); 65 | } 66 | term.println(); 67 | step++; 68 | } 69 | } 70 | else if (step == 4) 71 | { 72 | if (term.available()) 73 | { 74 | term.print("Ok I received : "); 75 | term.println(term.readString()); //shortest way 76 | step++; 77 | } 78 | } 79 | else if (step == 2) 80 | { 81 | term.println("\nNow you can test window resizing"); 82 | term.println("Send me a number to continue..."); 83 | step++; 84 | } 85 | else if (step == 3) 86 | { 87 | if (term.available()) 88 | { 89 | int i = term.parseInt(); //coolest way to get an int 90 | term.print("Ok I received "); 91 | term.println(i); 92 | 93 | term.println("\nNow I will freeze for 15 seconds"); 94 | term.println("The above button turns red while offline"); 95 | term.handleClient(); 96 | delay(15000); //Don't use big delays in your programs ! 97 | term.println("Ok I'm back"); 98 | term.println("Please send me something to continue..."); 99 | step++; 100 | } 101 | } 102 | else if (step == 1) 103 | { 104 | term.println(); 105 | term.println("Let's try to print a very long text :"); 106 | term.println(); 107 | term.println(F("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur interdum arcu eget convallis imperdiet. " 108 | "Nam eleifend pellentesque dui nec viverra. Maecenas a faucibus mi, nec tempus orci. Aenean id ligula luctus, " 109 | "mollis libero non, semper urna. Donec viverra enim sed turpis vestibulum, ac fermentum erat porta. Nam ac rhoncus " 110 | "risus. Quisque eu ornare enim. Duis et arcu vel turpis molestie sagittis eu consectetur metus.\n\n" 111 | "Nam tempus finibus neque, sed ornare ante porta ut. Nam iaculis, augue vel egestas auctor, elit tellus placerat tellus, " 112 | "sit amet dignissim nunc metus nec magna. In id facilisis augue, sed ornare sapien. Ut est quam, tincidunt aliquam varius nec, " 113 | "tempor in risus. Nam vehicula ac quam eget dictum. Nulla euismod, mi non bibendum vehicula, nibh metus sagittis nulla, nec " 114 | "ullamcorper nunc felis sed eros. Quisque quis bibendum turpis.\n\n" 115 | "Phasellus vestibulum diam ante, non feugiat augue fermentum eu. Nam ullamcorper condimentum ultricies. Duis placerat eget mauris " 116 | "ut faucibus. Nam vitae sapien quis sapien ullamcorper condimentum nec ut dolor. Nunc aliquet pellentesque purus, tristique eleifend " 117 | "lectus sodales sit amet. Nam nec viverra metus. Proin id pretium lectus, id mattis enim. Cras ultricies iaculis hendrerit. " 118 | "Duis fringilla cursus ipsum non ullamcorper. Aliquam maximus ante eu iaculis vestibulum. Curabitur in enim non est viverra lacinia.\n\n" 119 | "Proin ornare massa eu ex scelerisque, id ultricies ipsum interdum. Duis congue, odio nec euismod feugiat, orci est lacinia arcu, " 120 | "vitae placerat orci ante sed dolor. Sed ac vestibulum orci. Nulla at efficitur lacus, a tincidunt diam. Morbi interdum felis sapien, " 121 | "ac mollis erat semper a. Suspendisse potenti. Pellentesque bibendum efficitur ante. Nullam elit diam, ultricies sed condimentum nec, " 122 | "accumsan imperdiet nisl. Praesent non nunc quis mi lobortis mollis. Duis convallis justo vitae sagittis gravida.\n\n" 123 | "Fusce ligula massa, ornare eu feugiat quis, ornare volutpat neque. Vivamus lacus nisi, ultricies vel imperdiet a, " 124 | "interdum semper est. Etiam aliquam fermentum mauris ut vehicula. Morbi congue tempor finibus. Maecenas laoreet vitae dui non interdum. " 125 | "Aliquam a cursus nisl, vel eleifend mi. Sed sit amet hendrerit dolor. Aenean cursus volutpat mi eu vestibulum. Praesent ultrices, " 126 | "elit ac tincidunt fringilla, felis erat ullamcorper urna, id sagittis felis nibh non libero. Mauris rhoncus erat sed sollicitudin congue. " 127 | "Mauris mollis quam a magna mattis, quis tempus nulla eleifend. Cras volutpat tempus est, at faucibus lorem hendrerit sed. Phasellus et lobortis ex, " 128 | "non sollicitudin elit. Curabitur ornare mauris tellus, at lobortis velit luctus non.")); 129 | step++; 130 | } 131 | else if (step == 5 || step == 7 || step == 9) 132 | { 133 | speed = (step == 5) ? 1000 : (step == 7 ? 500 : 100); 134 | term.printf("\nSpeed test %lums", speed); //By the way : printf is working fine ! 135 | term.println(); 136 | timer = millis(); 137 | step++; 138 | nb = 0; 139 | } 140 | else if (step == 6 || step == 8 || step == 10) 141 | { 142 | if (nb * speed < 10000UL) 143 | { 144 | if (millis() - timer >= speed) 145 | { 146 | term.println(++nb); 147 | timer += speed; 148 | } 149 | } 150 | else 151 | { 152 | step++; 153 | } 154 | } 155 | else if (step == 11) 156 | { 157 | term.println(); 158 | term.println("Did you notice?"); 159 | term.println("Automatic scroll can be disabled/enabled by an action on the scrollbar"); 160 | term.println(); 161 | if (term.connectedClients() < 2) 162 | { 163 | term.println("Now reset your ESP and test it again using multiple terms simultaneously"); 164 | term.println("WiFiTerm can handle up to 5 clients"); 165 | term.println("Test with your computer, smartphone, tablet, etc."); 166 | } 167 | else 168 | { 169 | term.println("End of demo\nI hope you enjoyed"); 170 | } 171 | step++; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /examples/esp32/Serial_Gateway/Serial_Gateway.ino: -------------------------------------------------------------------------------- 1 | //Gateway Serial <-> WiFiTerm 2 | //with embedded baudrate selector 3 | 4 | #include 5 | const char* ssid = ""; //adjust to your own values 6 | const char* password = ""; //adjust to your own values 7 | 8 | #include "WiFiTerm.h" 9 | 10 | WebServer server(80); 11 | 12 | const uint32_t baud_rates[] = { 13 | 300, 14 | 1200, 15 | 2400, 16 | 4800, 17 | 9600, 18 | 19200, 19 | 38400, 20 | 57600, 21 | 74880, 22 | 115200, 23 | 230400 24 | }; 25 | const uint8_t nb_baud_rates = sizeof(baud_rates) / sizeof(uint32_t); 26 | 27 | uint8_t baud_rate_selection = 0; 28 | uint32_t baud_rate = 0; 29 | uint8_t timeout_ms = 1; 30 | 31 | void setup() 32 | { 33 | pinMode(LED_BUILTIN, OUTPUT); 34 | 35 | WiFi.begin(ssid, password); 36 | while (WiFi.status() != WL_CONNECTED) 37 | { 38 | delay(250); 39 | digitalWrite(LED_BUILTIN, LOW); 40 | delay(250); 41 | digitalWrite(LED_BUILTIN, HIGH); 42 | } 43 | 44 | server.begin(); 45 | term.begin(server); 46 | 47 | while (baud_rate_selection == 0) 48 | { 49 | term.println("Please select Serial baud rate :"); 50 | for (size_t i=0; i'); 57 | 58 | while (!term.available()) 59 | { 60 | server.handleClient(); 61 | term.handleClient(); 62 | delay(100); 63 | } 64 | 65 | int i = term.parseInt(); 66 | term.flush(); 67 | term.println(i); 68 | if (1 <= i && i <= nb_baud_rates) 69 | { 70 | baud_rate_selection = i; 71 | baud_rate = baud_rates[baud_rate_selection - 1]; 72 | timeout_ms = 1 + 10000 / baud_rate; 73 | } 74 | else 75 | { 76 | term.println("Invalid selection\n"); 77 | } 78 | } 79 | 80 | Serial.begin(baud_rate); 81 | term.print("Gateway started at "); 82 | term.print(baud_rate); 83 | term.println(" bps"); 84 | term.println(); 85 | } 86 | 87 | void loop() 88 | { 89 | server.handleClient(); 90 | term.handleClient(); 91 | 92 | //term to Serial 93 | if (term.available()) 94 | { 95 | Serial.println(term.readString()); 96 | } 97 | 98 | //Serial to term 99 | size_t qty = WIFITERM_TX_BUF_SIZE; 100 | while (Serial.available() && qty--) 101 | { 102 | char c = Serial.read(); 103 | term.print(c); 104 | if (!Serial.available()) 105 | { 106 | delay(timeout_ms); //wait for next char 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/esp8266/Basic/Basic.ino: -------------------------------------------------------------------------------- 1 | #include 2 | const char* ssid = ""; 3 | const char* password = ""; 4 | 5 | #include "WiFiTerm.h" 6 | 7 | ESP8266WebServer server(80); 8 | 9 | void setup() 10 | { 11 | Serial.begin(115200); 12 | Serial.print("\nConnecting to WIFI"); 13 | WiFi.begin(ssid, password); 14 | while (WiFi.status() != WL_CONNECTED) 15 | { 16 | delay(500); 17 | Serial.print('.'); 18 | } 19 | Serial.println("connected"); 20 | Serial.print("IP address: "); 21 | Serial.println(WiFi.localIP()); 22 | 23 | server.begin(); 24 | Serial.println("webServer started"); 25 | 26 | term.begin(server); 27 | Serial.println("term started"); 28 | } 29 | 30 | void loop() 31 | { 32 | server.handleClient(); 33 | term.handleClient(); 34 | 35 | if (term.available()) 36 | { 37 | term.print("Received : "); 38 | term.println(term.readString()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/esp8266/Full_Demo/Full_Demo.ino: -------------------------------------------------------------------------------- 1 | //WiFiTerm full demo 2 | // 3 | //Please open Serial terminal and follow instructions 4 | // 5 | #include 6 | const char* ssid = ""; //adjust to your own values 7 | const char* password = ""; //adjust to your own values 8 | 9 | #include "WiFiTerm.h" 10 | 11 | ESP8266WebServer server(80); 12 | 13 | void setup() 14 | { 15 | Serial.begin(115200); 16 | term.link(Serial); //optional : echo every print() on Serial 17 | 18 | term.println("Welcome to WiFiTerm full demo example"); 19 | 20 | term.print("\nConnecting to WiFi"); 21 | WiFi.begin(ssid, password); 22 | while (WiFi.status() != WL_CONNECTED) 23 | { 24 | delay(500); 25 | term.print('.'); 26 | } 27 | term.println("connected"); 28 | 29 | server.begin(); 30 | term.begin(server); 31 | 32 | term.setAsDefaultWhenUrlNotFound(); //optional : redirect any unknown url to /term.html 33 | term.activateArduinoFavicon(); //optional : send Arduino icon when a browser asks for favicon 34 | 35 | term.println("WiFiTerm started"); 36 | term.println(); 37 | 38 | Serial.print("I'm waiting for you at http://"); 39 | Serial.print(WiFi.localIP()); 40 | Serial.println("/term.html"); 41 | 42 | term.unlink(); //optional : stop echo on Serial 43 | term.println("Welcome here"); 44 | term.println("Please note that previous lines were printed BEFORE WiFiTerm connection"); 45 | term.println("Now send me some text..."); 46 | } 47 | 48 | void loop() 49 | { 50 | server.handleClient(); 51 | term.handleClient(); 52 | 53 | static int step = 0; 54 | static long unsigned int timer, speed, nb; 55 | 56 | if (step == 0) 57 | { 58 | if (term.available()) 59 | { 60 | term.print("Ok I received : "); 61 | while (term.available()) //standard way 62 | { 63 | char c = term.read(); 64 | term.print(c); 65 | } 66 | term.println(); 67 | step++; 68 | } 69 | } 70 | else if (step == 4) 71 | { 72 | if (term.available()) 73 | { 74 | term.print("Ok I received : "); 75 | term.println(term.readString()); //shortest way 76 | step++; 77 | } 78 | } 79 | else if (step == 2) 80 | { 81 | term.println("\nNow you can test window resizing"); 82 | term.println("Send me a number to continue..."); 83 | step++; 84 | } 85 | else if (step == 3) 86 | { 87 | if (term.available()) 88 | { 89 | int i = term.parseInt(); //coolest way to get an int 90 | term.print("Ok I received "); 91 | term.println(i); 92 | 93 | term.println("\nNow I will freeze for 15 seconds"); 94 | term.println("The above button turns red while offline"); 95 | term.handleClient(); 96 | delay(15000); //Don't use big delays in your programs ! 97 | term.println("Ok I'm back"); 98 | term.println("Please send me something to continue..."); 99 | step++; 100 | } 101 | } 102 | else if (step == 1) 103 | { 104 | term.println(); 105 | term.println("Let's try to print a very long text :"); 106 | term.println(); 107 | term.println(F("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur interdum arcu eget convallis imperdiet. " 108 | "Nam eleifend pellentesque dui nec viverra. Maecenas a faucibus mi, nec tempus orci. Aenean id ligula luctus, " 109 | "mollis libero non, semper urna. Donec viverra enim sed turpis vestibulum, ac fermentum erat porta. Nam ac rhoncus " 110 | "risus. Quisque eu ornare enim. Duis et arcu vel turpis molestie sagittis eu consectetur metus.\n\n" 111 | "Nam tempus finibus neque, sed ornare ante porta ut. Nam iaculis, augue vel egestas auctor, elit tellus placerat tellus, " 112 | "sit amet dignissim nunc metus nec magna. In id facilisis augue, sed ornare sapien. Ut est quam, tincidunt aliquam varius nec, " 113 | "tempor in risus. Nam vehicula ac quam eget dictum. Nulla euismod, mi non bibendum vehicula, nibh metus sagittis nulla, nec " 114 | "ullamcorper nunc felis sed eros. Quisque quis bibendum turpis.\n\n" 115 | "Phasellus vestibulum diam ante, non feugiat augue fermentum eu. Nam ullamcorper condimentum ultricies. Duis placerat eget mauris " 116 | "ut faucibus. Nam vitae sapien quis sapien ullamcorper condimentum nec ut dolor. Nunc aliquet pellentesque purus, tristique eleifend " 117 | "lectus sodales sit amet. Nam nec viverra metus. Proin id pretium lectus, id mattis enim. Cras ultricies iaculis hendrerit. " 118 | "Duis fringilla cursus ipsum non ullamcorper. Aliquam maximus ante eu iaculis vestibulum. Curabitur in enim non est viverra lacinia.\n\n" 119 | "Proin ornare massa eu ex scelerisque, id ultricies ipsum interdum. Duis congue, odio nec euismod feugiat, orci est lacinia arcu, " 120 | "vitae placerat orci ante sed dolor. Sed ac vestibulum orci. Nulla at efficitur lacus, a tincidunt diam. Morbi interdum felis sapien, " 121 | "ac mollis erat semper a. Suspendisse potenti. Pellentesque bibendum efficitur ante. Nullam elit diam, ultricies sed condimentum nec, " 122 | "accumsan imperdiet nisl. Praesent non nunc quis mi lobortis mollis. Duis convallis justo vitae sagittis gravida.\n\n" 123 | "Fusce ligula massa, ornare eu feugiat quis, ornare volutpat neque. Vivamus lacus nisi, ultricies vel imperdiet a, " 124 | "interdum semper est. Etiam aliquam fermentum mauris ut vehicula. Morbi congue tempor finibus. Maecenas laoreet vitae dui non interdum. " 125 | "Aliquam a cursus nisl, vel eleifend mi. Sed sit amet hendrerit dolor. Aenean cursus volutpat mi eu vestibulum. Praesent ultrices, " 126 | "elit ac tincidunt fringilla, felis erat ullamcorper urna, id sagittis felis nibh non libero. Mauris rhoncus erat sed sollicitudin congue. " 127 | "Mauris mollis quam a magna mattis, quis tempus nulla eleifend. Cras volutpat tempus est, at faucibus lorem hendrerit sed. Phasellus et lobortis ex, " 128 | "non sollicitudin elit. Curabitur ornare mauris tellus, at lobortis velit luctus non.")); 129 | step++; 130 | } 131 | else if (step == 5 || step == 7 || step == 9) 132 | { 133 | speed = (step == 5) ? 1000 : (step == 7 ? 500 : 100); 134 | term.printf("\nSpeed test %lums", speed); //By the way : printf is working fine ! 135 | term.println(); 136 | timer = millis(); 137 | step++; 138 | nb = 0; 139 | } 140 | else if (step == 6 || step == 8 || step == 10) 141 | { 142 | if (nb * speed < 10000UL) 143 | { 144 | if (millis() - timer >= speed) 145 | { 146 | term.println(++nb); 147 | timer += speed; 148 | } 149 | } 150 | else 151 | { 152 | step++; 153 | } 154 | } 155 | else if (step == 11) 156 | { 157 | term.println(); 158 | term.println("Did you notice?"); 159 | term.println("Automatic scroll can be disabled/enabled by an action on the scrollbar"); 160 | term.println(); 161 | if (term.connectedClients() < 2) 162 | { 163 | term.println("Now reset your ESP and test it again using multiple terms simultaneously"); 164 | term.println("WiFiTerm can handle up to 5 clients"); 165 | term.println("Test with your computer, smartphone, tablet, etc."); 166 | } 167 | else 168 | { 169 | term.println("End of demo\nI hope you enjoyed"); 170 | } 171 | step++; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /examples/esp8266/Serial_Gateway/Serial_Gateway.ino: -------------------------------------------------------------------------------- 1 | //Gateway Serial <-> WiFiTerm 2 | //with embedded baudrate selector 3 | 4 | #include 5 | const char* ssid = ""; 6 | const char* password = ""; 7 | 8 | #include "WiFiTerm.h" 9 | 10 | ESP8266WebServer server(80); 11 | 12 | const uint32_t baud_rates[] = { 13 | 300, 14 | 1200, 15 | 2400, 16 | 4800, 17 | 9600, 18 | 19200, 19 | 38400, 20 | 57600, 21 | 74880, 22 | 115200, 23 | 230400 24 | }; 25 | const uint8_t nb_baud_rates = sizeof(baud_rates) / sizeof(uint32_t); 26 | 27 | uint8_t baud_rate_selection = 0; 28 | uint32_t baud_rate = 0; 29 | uint8_t timeout_ms = 1; 30 | 31 | void setup() 32 | { 33 | pinMode(LED_BUILTIN, OUTPUT); 34 | 35 | WiFi.begin(ssid, password); 36 | while (WiFi.status() != WL_CONNECTED) 37 | { 38 | delay(250); 39 | digitalWrite(LED_BUILTIN, LOW); 40 | delay(250); 41 | digitalWrite(LED_BUILTIN, HIGH); 42 | } 43 | 44 | server.begin(); 45 | term.begin(server); 46 | 47 | while (baud_rate_selection == 0) 48 | { 49 | term.println("Please select Serial baud rate :"); 50 | for (size_t i=0; i'); 57 | 58 | while (!term.available()) 59 | { 60 | server.handleClient(); 61 | term.handleClient(); 62 | delay(100); 63 | } 64 | 65 | int i = term.parseInt(); 66 | term.flush(); 67 | term.println(i); 68 | if (1 <= i && i <= nb_baud_rates) 69 | { 70 | baud_rate_selection = i; 71 | baud_rate = baud_rates[baud_rate_selection - 1]; 72 | timeout_ms = 1 + 10000 / baud_rate; 73 | } 74 | else 75 | { 76 | term.println("Invalid selection\n"); 77 | } 78 | } 79 | 80 | Serial.begin(baud_rate); 81 | term.print("Gateway started at "); 82 | term.print(baud_rate); 83 | term.println(" bps"); 84 | term.println(); 85 | } 86 | 87 | void loop() 88 | { 89 | server.handleClient(); 90 | term.handleClient(); 91 | 92 | //term to Serial 93 | if (term.available()) 94 | { 95 | Serial.println(term.readString()); 96 | } 97 | 98 | //Serial to term 99 | size_t qty = WIFITERM_TX_BUF_SIZE; 100 | while (Serial.available() && qty--) 101 | { 102 | char c = Serial.read(); 103 | term.print(c); 104 | if (!Serial.available()) 105 | { 106 | delay(timeout_ms); //wait for next char 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /webfiles.py: -------------------------------------------------------------------------------- 1 | # This program analyses webfiles/* and generates a cpp library for ESP32 / ESP8266 2 | # Each file is converted into PROGMEM data 3 | 4 | from pathlib import Path 5 | import mimetypes 6 | 7 | cur_dir = Path(__file__).absolute().parent 8 | search_dir = cur_dir / "webfiles" 9 | items = list(search_dir.rglob("*")) 10 | src = cur_dir.parts[-1] 11 | if src == "src": 12 | src = cur_dir.parts[-2] 13 | if src[-7:] == "-master": 14 | src = src[:(len(src)-len("-master"))] 15 | master = src + "_webfiles" 16 | cl = master + "_c" 17 | 18 | print("\nAnalyzing dir", search_dir, "..." ) 19 | files = {} 20 | content_types = {} 21 | maxuri = 0 22 | for item in items: 23 | if item.is_file(): 24 | print(" ", item.relative_to(search_dir)) 25 | 26 | key = str(item.relative_to(cur_dir)).replace("\\","/").replace("/","_").replace(" ","_").replace(".","_") 27 | 28 | files[key]= {} 29 | files[key]['name'] = item.name 30 | 31 | files[key]['suffix'] = item.suffix 32 | content_types[files[key]['suffix']] = {} 33 | content_types[files[key]['suffix']]['value'] = mimetypes.types_map[item.suffix] 34 | content_types[files[key]['suffix']]['name'] = master + "_content_type_" + item.suffix.replace(".", "") + "_P" 35 | 36 | files[key]['uri'] = "/" + str(item.relative_to(search_dir)).replace("\\","/") 37 | maxuri = max(maxuri, len(files[key]['uri'])) 38 | 39 | f = open(item, "rb") 40 | content = f.read() 41 | f.close 42 | dumpHexa = "" 43 | size = 0 44 | for c in content: 45 | if size > 0: 46 | dumpHexa += "," 47 | if size % 12 == 0 : 48 | dumpHexa += "\n" 49 | if size % 12 == 0: 50 | dumpHexa += " " 51 | dumpHexa += " 0x%02x" %c 52 | size += 1 53 | 54 | files[key]['size'] = size 55 | files[key]['cpp'] = "const char " + key + "_P[] PROGMEM =\n{\n" + dumpHexa + "\n};\n\n" 56 | files[key]['cpp'] += "void " + cl + "::send_" + key + "()\n{\n" 57 | files[key]['cpp'] += " if (" + master + ".server != NULL)\n {\n" 58 | files[key]['cpp'] += " " + master + ".server->send_P(\n" 59 | files[key]['cpp'] += " 200,\n" 60 | files[key]['cpp'] += " " + content_types[files[key]['suffix']]['name'] + ",\n" 61 | files[key]['cpp'] += " " + key + "_P,\n" 62 | files[key]['cpp'] += " " + str(size) + "\n );\n }\n}\n\n" 63 | 64 | 65 | header = "//Generated by " + str(Path(__file__).name) + "\n\n" 66 | header += "//" + str(len(files)) + " file(s) :\n" 67 | favicon = False 68 | for file in files: 69 | header += "// " + files[file]['uri'] + "\n" 70 | header += "// size : " + str(files[file]['size']) + " bytes\n" 71 | header += "// content_type : " + content_types[files[file]['suffix']]['value'] + "\n" 72 | if file == "webfiles_favicon_ico" : 73 | favicon = True 74 | 75 | header += "\n#ifndef " + master + "_h\n" 76 | header += "#define " + master + "_h\n\n" 77 | header += "#if defined(ESP32)\n" 78 | header += " #include \n" 79 | header += "#elif defined(ESP8266)\n" 80 | header += " #include \n" 81 | header += " #define WebServer ESP8266WebServer\n" 82 | header += "#endif\n\n" 83 | 84 | header += "class " + cl + "\n{\n" 85 | header += " public :\n " + cl + "();\n\n" 86 | header += " void begin(WebServer &webServer);\n" 87 | if favicon: 88 | header += " void activateFavicon(); //must be specificly activated\n\n" 89 | header += " WebServer *server;\n\n" 90 | header += " private :\n" 91 | for file in files: 92 | header += " static void send_" + file + "();\n" 93 | header += "};\n\nextern " + cl + " " + master + ";\n\n" 94 | for file in files: 95 | header += "extern const char " + file + "_path_P[];\n" 96 | header += "\n#endif\n\n" 97 | 98 | master_h = master + ".h" 99 | f = open(cur_dir / master_h, "w") 100 | f.write(header) 101 | f.close 102 | 103 | cpp = "//Generated by " + str(Path(__file__).name) + "\n\n" 104 | cpp += "#include \"" + master + ".h\"\n\n" 105 | cpp += cl + " " + master + ";\n\n" 106 | 107 | cpp += cl + "::" + cl + "()\n" 108 | cpp += "{\n" 109 | cpp += " server = NULL;\n" 110 | cpp += "}\n\n" 111 | 112 | for file in files: 113 | cpp += "const char " + file + "_path_P[] PROGMEM = \"" + files[file]['uri'] + "\";\n" 114 | 115 | cpp += '\n' 116 | for content_type in content_types: 117 | cpp += "const char " + content_types[content_type]['name'] + "[] PROGMEM = \"" + content_types[content_type]['value'] + "\";\n" 118 | 119 | cpp += "\nvoid " + cl + "::begin(WebServer &webServer)\n" 120 | cpp += "{\n" 121 | cpp += " server = &webServer;\n\n" 122 | cpp += " char path[" + str(maxuri+1) + "];\n" 123 | for file in files: 124 | if file != "webfiles_favicon_ico": 125 | cpp += "\n strcpy_P(path, " + file + "_path_P);\n" 126 | cpp += " server->on(path, send_" + file + ");\n" 127 | cpp += "}\n\n" 128 | 129 | if favicon: 130 | cpp += "void " + cl + "::activateFavicon()\n" 131 | cpp += "{\n" 132 | cpp += " char path[" + str(maxuri+1) + "];\n" 133 | cpp += " if (server != NULL)\n" 134 | cpp += " {\n" 135 | cpp += " strcpy_P(path, webfiles_favicon_ico_path_P);\n" 136 | cpp += " server->on(path, send_webfiles_favicon_ico);\n" 137 | cpp += " }\n" 138 | cpp += "}\n\n" 139 | 140 | for file in files: 141 | cpp += files[file]['cpp'] 142 | 143 | master_cpp = master + ".cpp" 144 | f = open(cur_dir / master_cpp, "w") 145 | f.write(cpp) 146 | f.close 147 | 148 | print("\nGenerated files :") 149 | print(" ", cur_dir / master_h) 150 | print(" ", cur_dir / master_cpp) 151 | input('Press ENTER to quit...') 152 | -------------------------------------------------------------------------------- /webfiles/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bricoleau/WiFiTerm/551341469507c54d4a16d3f2d0f67d741c7898c4/webfiles/favicon.ico -------------------------------------------------------------------------------- /webfiles/icons/greenArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bricoleau/WiFiTerm/551341469507c54d4a16d3f2d0f67d741c7898c4/webfiles/icons/greenArrow.png -------------------------------------------------------------------------------- /webfiles/icons/redArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bricoleau/WiFiTerm/551341469507c54d4a16d3f2d0f67d741c7898c4/webfiles/icons/redArrow.png -------------------------------------------------------------------------------- /webfiles/scripts/term.js: -------------------------------------------------------------------------------- 1 | var ws; 2 | var ESP_ip; 3 | let connected = false; 4 | 5 | function wsInit() { 6 | ws = new WebSocket("ws://" + ESP_ip + ":81"); 7 | 8 | ws.onopen = function (event) { 9 | connected = true; 10 | resetOutput(); 11 | online(); 12 | } 13 | 14 | ws.onmessage = function (event) { 15 | if (typeof(event.data) == "string") { 16 | receiveTxt(event.data); 17 | } else { //anything else is considered as a pong 18 | receivePong(); 19 | } 20 | } 21 | 22 | ws.onclose = function (event) { 23 | connected = false; 24 | offline(); 25 | setTimeout(wsInit, 1000); 26 | } 27 | } 28 | 29 | let waitingForPong = 0; 30 | 31 | function receivePong() { 32 | waitingForPong = 0; 33 | online(); 34 | } 35 | 36 | function handlePingPong() { 37 | if (connected) { 38 | if (waitingForPong++ > 2) { 39 | offline(); 40 | } 41 | ws.send(""); 42 | } 43 | setTimeout(handlePingPong, 1000); 44 | } 45 | 46 | let isOnline = false; 47 | 48 | function online() { 49 | if (!isOnline) { 50 | inputButtonGreen(); 51 | isOnline = true; 52 | } 53 | } 54 | 55 | function offline() { 56 | if (isOnline) { 57 | inputButtonRed(); 58 | isOnline = false; 59 | } 60 | } 61 | 62 | function inputButtonGreen() { 63 | document.getElementById("inputImgRed").style.display = "none"; 64 | document.getElementById("inputImgGreen").style.display = "inherit"; 65 | } 66 | 67 | function inputButtonRed() { 68 | document.getElementById("inputImgRed").style.display = "inherit"; 69 | document.getElementById("inputImgGreen").style.display = "none"; 70 | } 71 | 72 | function inputButtonSetup() { 73 | document.getElementById("txtIn").addEventListener("keydown", function(event) { 74 | if (event.keyCode === 13) { 75 | event.preventDefault(); 76 | document.getElementById("sendButton").click(); 77 | } 78 | }); 79 | } 80 | 81 | function getESPlocation() { 82 | var loc = location.hostname; 83 | if (loc == "") loc = prompt("Enter ESP ip address","192.168.1.80"); 84 | return loc; 85 | } 86 | 87 | function resetOutput() { 88 | document.getElementById("txtOut").innerHTML = ""; 89 | } 90 | 91 | function receiveTxt(txt) { 92 | var textarea = document.getElementById("txtOut"); 93 | var scrolledBottom = (textarea.scrollTop + textarea.clientHeight + 20 >= textarea.scrollHeight); 94 | textarea.innerHTML += txt; 95 | if (scrolledBottom) textarea.scrollTop = textarea.scrollHeight; 96 | } 97 | 98 | function send() { 99 | if (isOnline) { 100 | var txt = document.getElementById("txtIn").value; 101 | if (txt.length > 0) { 102 | ws.send(txt); 103 | document.getElementById("txtIn").value = ""; 104 | } 105 | } 106 | } 107 | 108 | function resize() { 109 | var terminalHeight=document.getElementById("terminal").clientHeight; 110 | var headerHeight=document.getElementById("header").clientHeight; 111 | var inputLineHeight=document.getElementById("inputLine").clientHeight; 112 | var inputButtonHeight=document.getElementById("inputButton").clientHeight; 113 | var inputHeight = inputLineHeight > inputButtonHeight ? inputLineHeight : inputButtonHeight; 114 | document.getElementById("input").style.height = inputHeight + "px"; 115 | var outputHight = terminalHeight - headerHeight - inputHeight - 20; 116 | document.getElementById("output").style.height = outputHight + "px"; 117 | var textarea = document.getElementById("txtOut"); 118 | textarea.scrollTop = textarea.scrollHeight; 119 | } 120 | window.onresize = resize; 121 | 122 | function setup() { 123 | ESP_ip = getESPlocation(); 124 | inputButtonSetup(); 125 | wsInit(); 126 | resize(); 127 | handlePingPong(); 128 | } 129 | 130 | window.addEventListener("DOMContentLoaded", (event) => {setup();}); 131 | -------------------------------------------------------------------------------- /webfiles/styles/term.css: -------------------------------------------------------------------------------- 1 | html,body,#terminal{height:100%;width:100%;margin:0;padding:0;min-width:300px;} 2 | 3 | #terminal { 4 | background-color: rgb(48, 48, 48); 5 | color: white; 6 | font-family: "Courier New"; 7 | } 8 | 9 | #header { 10 | padding: 10px; 11 | font-family: "Arial"; 12 | text-align: center; 13 | } 14 | 15 | #input { 16 | padding-left: 10px; 17 | padding-right: 10px; 18 | } 19 | 20 | #output { 21 | padding: 10px; 22 | padding-left: 14px; 23 | padding-right: 14px; 24 | } 25 | 26 | h1 { 27 | margin: 0; 28 | font-size: 2em; 29 | } 30 | 31 | #inputLine { 32 | /* padding: 4px; */ 33 | float: left; 34 | width: calc(100% - 70px); 35 | } 36 | 37 | #inputButton { 38 | /* padding: 3px;*/ 39 | float: right; 40 | } 41 | 42 | #inputImgRed { 43 | display: inherit; 44 | } 45 | 46 | #inputImgGreen { 47 | display: none; 48 | } 49 | 50 | #sendButton { 51 | width: 50px; 52 | border-radius: 8px; 53 | } 54 | 55 | #txtIn { 56 | width: 100%; 57 | } 58 | 59 | #txtIn, #sendButton { 60 | background-color: rgba(192, 192, 192); 61 | color: black; 62 | } 63 | 64 | #txtOut { 65 | width: 100%; 66 | height: 100%; 67 | box-sizing: border-box; 68 | resize: none; 69 | background-color: rgb(60, 60, 60); 70 | color: white; 71 | } 72 | 73 | #input, #txtIn, #output, #txtOut { 74 | font: inherit; 75 | } 76 | 77 | #txtOut { 78 | font-size: 0.8em; 79 | } 80 | -------------------------------------------------------------------------------- /webfiles/term.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Terminal 10 | 11 | 12 |
13 | 16 |
17 |
18 | 19 |
20 |
21 | 25 |
26 |
27 |
28 | 29 |
30 |
31 | 32 | --------------------------------------------------------------------------------