diff --git a/README.md b/README.md index 1423999..cfaa7b6 100644 --- a/README.md +++ b/README.md @@ -69,4 +69,37 @@ The final version of the magnetometer uses a **moving average filter** to smooth ## Barcode (Line) Sensor + ## WiFi (Web Server) Module + +The WiFi (Web Server) Module within this project integrates Server-Side Includes (SSI) and Common Gateway Interface (CGI) handlers from the lwIP library, facilitating a web interface to display information and receive controls from a webpage. + +### Components Overview + +1. **[frontend.h](frtos/frontend/frontend.h):** This component initializes and manages the web server frontend. It establishes the initial connection to the WiFi network using environment variables such as WIFI_SSID and WIFI_PASSWORD. + +2. **[html_files](frtos/frontend/html_files):** This directory contains HTML files used for the web server display. These files are linked into lwIP to enable server-side processing and rendering. + +3. **[ssi.h](frtos/frontend/ssi.h):** Handles Server-Side Includes (SSI), which dynamically inserts content into web pages, allowing the display of real-time or changing information. + +4. **[cgi.h](frtos/frontend/cgi.h):** Manages Common Gateway Interface (CGI) handlers, enabling the reception of controls and user interactions from the web interface. + +5. **makefsdata Utility:** This tool generates `htmldata.c` by converting HTML files into hexadecimal representation to link them into lwIP. It involves converting filenames into hex, defining HTTP headers for file extensions, and converting HTML content into a hex array for efficient storage and retrieval. + + - **Automatic Generation of htmldata.c:** + - `makefsdata.c` creates `makefsdata.exe` automatically upon build, as specified in `CMakeLists.txt`. + - `makefsdata.exe` in turn generates `htmldata.c`, which links the HTML pages to lwIP for server-side processing, enabling seamless integration of web content. + +### Functionality and Implementation Details + +The WiFi (Web Server) Module offers the following functionalities: + +- **Dynamic Content Display:** SSI allows the server to include dynamic content in web pages, facilitating real-time updates or information display. + +- **User Interaction Handling:** CGI enables the server to process user interactions received from the web interface, enabling control and interaction with the Pico-based car. + +- **WiFi Connectivity:** `frontend.h` establishes a connection to the designated WiFi network using the environment variables WIFI_SSID and WIFI_PASSWORD. This connection is essential for enabling communication between the Pico device and the network. + + +The integration of SSI, CGI, and the makefsdata tool empowers the WiFi (Web Server) Module to provide a user-friendly interface for monitoring and controlling the Pico-based car within the defined network environment. + diff --git a/frtos/CMakeLists.txt b/frtos/CMakeLists.txt index 28447a9..3df3d1e 100644 --- a/frtos/CMakeLists.txt +++ b/frtos/CMakeLists.txt @@ -33,6 +33,7 @@ target_link_libraries(rtos_car hardware_adc hardware_pwm hardware_i2c + pico_lwip_http ) pico_enable_stdio_usb(rtos_car 1) pico_add_extra_outputs(rtos_car) diff --git a/frtos/frontend/CMakeLists.txt b/frtos/frontend/CMakeLists.txt index dd2581c..55a3c4b 100644 --- a/frtos/frontend/CMakeLists.txt +++ b/frtos/frontend/CMakeLists.txt @@ -28,5 +28,10 @@ target_include_directories(frontend PRIVATE ${CMAKE_CURRENT_LIST_DIR} ) +target_compile_definitions(frontend PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" +) + pico_enable_stdio_usb(frontend 1) pico_add_extra_outputs(frontend) \ No newline at end of file diff --git a/frtos/frontend/cgi.h b/frtos/frontend/cgi.h index 39a9f99..be28eac 100644 --- a/frtos/frontend/cgi.h +++ b/frtos/frontend/cgi.h @@ -2,6 +2,8 @@ #include "pico/cyw43_arch.h" #include "stdio.h" +#include "car_config.h" + // CGI handler for start/stop car const char * cgi_status_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { @@ -12,9 +14,17 @@ const char * cgi_status_handler(int iIndex, int iNumParams, char *pcParam[], cha if(strcmp(pcValue[0], "0") == 0){ cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0); printf("CAR STOP"); // call car stop func + /* + set_wheel_direction(DIRECTION_MASK); + set_wheel_speed_synced(0u, car_struct); + */ }else if(strcmp(pcValue[0], "1") == 0){ cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); printf("CAR START"); // call car start func + /* + set_wheel_direction(DIRECTION_FORWARD); + set_wheel_speed_synced(90u, car_struct); + */ } } @@ -54,7 +64,8 @@ static const tCGI cgi_handlers[] = { }, }; -void cgi_init(void) -{ +void cgi_init(void *params) +{ + car_struct_t *car_struct = (car_struct_t *)params; http_set_cgi_handlers(cgi_handlers, 2); } \ No newline at end of file diff --git a/frtos/frontend/frontend.c b/frtos/frontend/frontend.c index f58a485..797fc33 100644 --- a/frtos/frontend/frontend.c +++ b/frtos/frontend/frontend.c @@ -1,71 +1,23 @@ -#include "lwip/apps/httpd.h" #include "pico/stdlib.h" -#include "pico/cyw43_arch.h" -#include "lwipopts.h" -#include "ssi.h" -#include "cgi.h" -#include "FreeRTOS.h" -#include "task.h" -// WIFI Credentials - take care if pushing to GitHub! -const char WIFI_SSID[] = "XXX"; -const char WIFI_PASSWORD[] = "XXX"; +#include "frontend.h" +#include "car_config.h" -void print_ip_address() { - struct netif *netif = netif_list; - while (netif != NULL) { - if (netif_is_up(netif)) { - printf("IP Address: %s\n", ipaddr_ntoa(&(netif->ip_addr))); - } - netif = netif->next; - } -} - -static void webserver_run(){ - // Initialize web server - httpd_init(); - printf("Http server initialized\n"); - - // Configure SSI and CGI handler - ssi_init(); - printf("SSI Handler initialized\n"); - cgi_init(); - printf("CGI Handler initialized\n"); - - // Infinite loop - while (1) { - // Add any required delay or use other FreeRTOS features here if needed - vTaskDelay(pdMS_TO_TICKS(1000)); - } -} -static void webserver_task(){ - if (cyw43_arch_init()) - { - printf("failed to initialise\n"); - return; - } - - cyw43_arch_enable_sta_mode(); - - printf("Connecting to WiFi...\n"); - - // Connect to the WiFI network - loop until connected - while (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000) != 0) { - printf("Attempting to connect...\n"); - } - // Print a success message once connected - printf("Connected! \n"); - print_ip_address(); - - webserver_run(); - cyw43_arch_deinit(); -} int main() { stdio_init_all(); - // Create the FreeRTOS task for the web server - TaskHandle_t task_handle; - xTaskCreate(webserver_task, "WebServerTask", configMINIMAL_STACK_SIZE, NULL, 1, &task_handle); + obs_t obs; + motor_t motor_right; + motor_t motor_left; + motor_pid_t pid; + + car_struct_t car_struct = { .p_right_motor = &motor_right, + .p_left_motor = &motor_left, + .p_pid = &pid, + .obs = &obs}; + + webserver_init(&car_struct); //to test webserver only, remove car_struct from all frontend files + // Start the FreeRTOS scheduler vTaskStartScheduler(); diff --git a/frtos/frontend/frontend.h b/frtos/frontend/frontend.h new file mode 100644 index 0000000..245298d --- /dev/null +++ b/frtos/frontend/frontend.h @@ -0,0 +1,75 @@ +#include "lwip/apps/httpd.h" +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" +#include "lwipopts.h" +#include "ssi.h" +#include "cgi.h" +#include "FreeRTOS.h" +#include "task.h" + +#include "car_config.h" + +// print assigned ip addr +void print_ip_address() { + struct netif *netif = netif_list; + while (netif != NULL) { + if (netif_is_up(netif)) { + printf("IP Address: %s\n", ipaddr_ntoa(&(netif->ip_addr))); + } + netif = netif->next; + } +} + +// initializes server and handlers +static void webserver_run(void *params){ + car_struct_t *car_struct = (car_struct_t *)params; + + // Initialize web server + httpd_init(); + printf("Http server initialized\n"); + + // Configure SSI and CGI handler + ssi_init(&car_struct); + printf("SSI Handler initialized\n"); + cgi_init(&car_struct); + printf("CGI Handler initialized\n"); + + // Infinite loop + while (1) { + // Add any required delay or use other FreeRTOS features here if needed + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} +// webserver task connect wifi & start webserver_run +static void webserver_task(void *params){ + car_struct_t *car_struct = (car_struct_t *)params; + if (cyw43_arch_init()) + { + printf("failed to initialise\n"); + return; + } + + cyw43_arch_enable_sta_mode(); + + printf("Connecting to WiFi...\n"); + + // Connect to the WiFI network - loop until connected + while (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000) != 0) { + printf("Attempting to connect...\n"); + } + // Print a success message once connected + printf("Connected! \n"); + print_ip_address(); + + webserver_run(&car_struct); + cyw43_arch_deinit(); +} + +// frontend initialize - create task +void webserver_init(void *params) +{ + car_struct_t *car_struct = (car_struct_t *)params; + // Create the FreeRTOS task for the web server + TaskHandle_t task_handle; + xTaskCreate(webserver_task, "WebServerTask", configMINIMAL_STACK_SIZE, (void *)&car_struct, 1, &task_handle); +} \ No newline at end of file diff --git a/frtos/frontend/html_files/index.shtml b/frtos/frontend/html_files/index.shtml index a30f9a3..25cadf9 100644 --- a/frtos/frontend/html_files/index.shtml +++ b/frtos/frontend/html_files/index.shtml @@ -54,6 +54,11 @@ margin-top: 20px; } + .obstacle-output { + font-size: 24px; + margin-top: 20px; + } + .orientation-output { font-size: 24px; margin-top: 20px; @@ -92,6 +97,9 @@

PID Controller Output:

+
+

Obstacle:

+

Orientation:

diff --git a/frtos/frontend/htmldata.c b/frtos/frontend/htmldata.c index 8faf14a..26b4f05 100644 --- a/frtos/frontend/htmldata.c +++ b/frtos/frontend/htmldata.c @@ -125,258 +125,279 @@ static const unsigned char data_index_shtml[] = { 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x2E, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x2D, 0x6F, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, - 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x34, - 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, - 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, - 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x6D, 0x61, - 0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x20, 0x7B, 0x0D, 0x0A, + 0x20, 0x20, 0x2E, 0x6F, 0x62, 0x73, 0x74, 0x61, 0x63, 0x6C, + 0x65, 0x2D, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x66, 0x6F, 0x6E, 0x74, 0x2D, 0x73, + 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x32, 0x34, 0x70, 0x78, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2E, 0x6F, 0x72, 0x69, 0x65, 0x6E, + 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2D, 0x6F, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6F, 0x6E, 0x74, 0x2D, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, + 0x32, 0x34, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6D, + 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, 0x6F, 0x70, 0x3A, + 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, + 0x6D, 0x61, 0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x20, 0x7B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, + 0x2D, 0x74, 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, + 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3A, 0x20, 0x32, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6D, 0x61, 0x72, 0x67, 0x69, 0x6E, 0x2D, 0x74, - 0x6F, 0x70, 0x3A, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3A, 0x20, + 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x32, 0x30, 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x20, 0x32, 0x30, - 0x30, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, - 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x31, 0x70, 0x78, 0x20, - 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x33, 0x33, 0x33, - 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, - 0x68, 0x65, 0x61, 0x64, 0x3E, 0x0D, 0x0A, 0x3C, 0x62, 0x6F, - 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x68, 0x31, 0x3E, 0x43, 0x61, 0x72, 0x20, 0x43, 0x6F, 0x6E, - 0x74, 0x72, 0x6F, 0x6C, 0x20, 0x50, 0x61, 0x6E, 0x65, 0x6C, - 0x3C, 0x2F, 0x68, 0x31, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x74, 0x61, 0x69, 0x6E, - 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, - 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x69, 0x6D, 0x65, - 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x20, 0x69, - 0x64, 0x3D, 0x22, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, - 0x2D, 0x74, 0x69, 0x6D, 0x65, 0x22, 0x3E, 0x30, 0x20, 0x73, - 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x3C, 0x2F, 0x70, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x33, + 0x33, 0x33, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, + 0x3C, 0x2F, 0x68, 0x65, 0x61, 0x64, 0x3E, 0x0D, 0x0A, 0x3C, + 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x68, 0x31, 0x3E, 0x43, 0x61, 0x72, 0x20, 0x43, + 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x20, 0x50, 0x61, 0x6E, + 0x65, 0x6C, 0x3C, 0x2F, 0x68, 0x31, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x63, 0x6F, 0x6E, 0x74, 0x61, + 0x69, 0x6E, 0x65, 0x72, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75, - 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22, - 0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2E, 0x63, 0x67, - 0x69, 0x3F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3D, 0x31, - 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75, - 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, - 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x74, 0x69, + 0x6D, 0x65, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, + 0x20, 0x69, 0x64, 0x3D, 0x22, 0x65, 0x6C, 0x61, 0x70, 0x73, + 0x65, 0x64, 0x2D, 0x74, 0x69, 0x6D, 0x65, 0x22, 0x3E, 0x30, + 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x3C, 0x2F, + 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, + 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x73, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2E, 0x63, 0x67, 0x69, 0x3F, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x3D, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, + 0x3D, 0x31, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x53, - 0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, - 0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, - 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x53, 0x70, - 0x65, 0x65, 0x64, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, - 0x73, 0x70, 0x65, 0x65, 0x64, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, - 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, - 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, 0x65, 0x64, - 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x22, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, - 0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x70, - 0x65, 0x65, 0x64, 0x2E, 0x63, 0x67, 0x69, 0x3F, 0x73, 0x70, - 0x65, 0x65, 0x64, 0x3D, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62, - 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, - 0x20, 0x3E, 0x2D, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, - 0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x74, 0x61, 0x72, 0x74, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, + 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, - 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2E, - 0x63, 0x67, 0x69, 0x3F, 0x73, 0x70, 0x65, 0x65, 0x64, 0x3D, - 0x31, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, - 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, - 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, 0x2B, 0x3C, - 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, - 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, - 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x2E, 0x63, 0x67, 0x69, 0x3F, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x3D, 0x30, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, + 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, + 0x3E, 0x53, 0x74, 0x6F, 0x70, 0x3C, 0x2F, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x3E, + 0x53, 0x70, 0x65, 0x65, 0x64, 0x3A, 0x20, 0x3C, 0x21, 0x2D, + 0x2D, 0x23, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2D, 0x2D, 0x3E, + 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, 0x3E, 0x3C, 0x2F, 0x70, + 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x73, 0x70, 0x65, + 0x65, 0x64, 0x2D, 0x63, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3D, 0x22, 0x2F, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x2E, 0x63, 0x67, 0x69, 0x3F, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x3D, 0x30, 0x22, 0x20, 0x3E, + 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, + 0x6E, 0x22, 0x20, 0x3E, 0x2D, 0x3C, 0x2F, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3D, 0x22, 0x2F, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x2E, 0x63, 0x67, 0x69, 0x3F, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x3D, 0x31, 0x22, 0x20, 0x3E, 0x3C, 0x62, 0x75, 0x74, + 0x74, 0x6F, 0x6E, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, + 0x22, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x22, 0x20, 0x3E, + 0x2B, 0x3C, 0x2F, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, + 0x3C, 0x2F, 0x61, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x42, 0x61, 0x72, + 0x63, 0x6F, 0x64, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x6E, + 0x65, 0x72, 0x20, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3A, + 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, 0x62, 0x61, 0x72, 0x63, + 0x6F, 0x64, 0x65, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x73, 0x70, + 0x61, 0x6E, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, + 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, + 0x61, 0x73, 0x73, 0x3D, 0x22, 0x70, 0x69, 0x64, 0x2D, 0x6F, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3C, 0x70, 0x3E, 0x50, 0x49, 0x44, 0x20, 0x43, 0x6F, + 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x72, 0x20, 0x4F, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x3A, 0x20, 0x3C, 0x21, 0x2D, + 0x2D, 0x23, 0x70, 0x69, 0x64, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, + 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, - 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, + 0x6F, 0x62, 0x73, 0x74, 0x61, 0x63, 0x6C, 0x65, 0x2D, 0x6F, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x42, 0x61, 0x72, 0x63, 0x6F, - 0x64, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6E, 0x6E, 0x65, 0x72, - 0x20, 0x4F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3A, 0x20, 0x3C, - 0x21, 0x2D, 0x2D, 0x23, 0x62, 0x61, 0x72, 0x63, 0x6F, 0x64, - 0x65, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x73, 0x70, 0x61, 0x6E, - 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, - 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, - 0x73, 0x3D, 0x22, 0x70, 0x69, 0x64, 0x2D, 0x6F, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x70, 0x3E, 0x50, 0x49, 0x44, 0x20, 0x43, 0x6F, 0x6E, 0x74, - 0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x72, 0x20, 0x4F, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, - 0x70, 0x69, 0x64, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, + 0x20, 0x3C, 0x70, 0x3E, 0x4F, 0x62, 0x73, 0x74, 0x61, 0x63, + 0x6C, 0x65, 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, 0x6F, + 0x62, 0x73, 0x74, 0x61, 0x63, 0x6C, 0x65, 0x2D, 0x2D, 0x3E, + 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x3D, 0x22, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x2D, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x4F, + 0x72, 0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x3A, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x23, 0x6F, 0x72, 0x69, + 0x65, 0x6E, 0x74, 0x2D, 0x2D, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, - 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x6F, 0x72, - 0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2D, - 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x70, 0x3E, 0x4F, 0x72, 0x69, 0x65, 0x6E, - 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x3C, 0x21, - 0x2D, 0x2D, 0x23, 0x6F, 0x72, 0x69, 0x65, 0x6E, 0x74, 0x2D, - 0x2D, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, - 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6C, 0x61, - 0x73, 0x73, 0x3D, 0x22, 0x6D, 0x61, 0x7A, 0x65, 0x2D, 0x6D, - 0x61, 0x70, 0x22, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x6D, 0x61, - 0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x22, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x6D, 0x61, 0x7A, - 0x65, 0x20, 0x6D, 0x61, 0x70, 0x20, 0x70, 0x61, 0x72, 0x74, - 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, - 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x64, 0x69, - 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x46, - 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x6F, - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6E, - 0x64, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x20, - 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, - 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61, - 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x28, 0x29, - 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43, - 0x68, 0x65, 0x63, 0x6B, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69, - 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x6F, 0x72, - 0x65, 0x64, 0x20, 0x69, 0x6E, 0x20, 0x6C, 0x6F, 0x63, 0x61, - 0x6C, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x6C, 0x6F, - 0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, - 0x2E, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6D, 0x28, 0x27, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x27, - 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x28, 0x21, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, - 0x6D, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x49, 0x66, 0x20, 0x6E, - 0x6F, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69, - 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x74, 0x6F, 0x72, - 0x65, 0x64, 0x2C, 0x20, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x20, - 0x74, 0x69, 0x6D, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x69, - 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x22, 0x6D, 0x61, + 0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, 0x22, 0x20, 0x69, 0x64, + 0x3D, 0x22, 0x6D, 0x61, 0x7A, 0x65, 0x2D, 0x6D, 0x61, 0x70, + 0x22, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x21, 0x2D, 0x2D, + 0x20, 0x6D, 0x61, 0x7A, 0x65, 0x20, 0x6D, 0x61, 0x70, 0x20, + 0x70, 0x61, 0x72, 0x74, 0x20, 0x2D, 0x2D, 0x3E, 0x0D, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x46, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x74, 0x6F, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6C, 0x61, 0x79, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, + 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x75, 0x6E, 0x63, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, + 0x6D, 0x65, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2F, 0x2F, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x74, 0x6F, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6E, 0x20, + 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, 0x72, 0x61, + 0x67, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, - 0x3D, 0x20, 0x44, 0x61, 0x74, 0x65, 0x2E, 0x6E, 0x6F, 0x77, - 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3D, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, + 0x72, 0x61, 0x67, 0x65, 0x2E, 0x67, 0x65, 0x74, 0x49, 0x74, + 0x65, 0x6D, 0x28, 0x27, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6D, 0x65, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x53, 0x74, 0x6F, 0x72, - 0x61, 0x67, 0x65, 0x2E, 0x73, 0x65, 0x74, 0x49, 0x74, 0x65, - 0x6D, 0x28, 0x27, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, - 0x6D, 0x65, 0x27, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6D, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x29, 0x20, 0x7B, 0x0D, + 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, - 0x43, 0x61, 0x6C, 0x63, 0x75, 0x6C, 0x61, 0x74, 0x65, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, - 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x69, 0x6E, 0x20, - 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x0D, 0x0A, 0x20, + 0x49, 0x66, 0x20, 0x6E, 0x6F, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x74, 0x6F, 0x72, 0x65, 0x64, 0x2C, 0x20, 0x73, 0x65, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6E, 0x74, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6E, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x3D, - 0x20, 0x44, 0x61, 0x74, 0x65, 0x2E, 0x6E, 0x6F, 0x77, 0x28, - 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, - 0x74, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, - 0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x4D, 0x61, 0x74, 0x68, - 0x2E, 0x66, 0x6C, 0x6F, 0x6F, 0x72, 0x28, 0x28, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x20, - 0x2D, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, - 0x65, 0x29, 0x20, 0x2F, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29, - 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x44, 0x61, 0x74, 0x65, + 0x2E, 0x6E, 0x6F, 0x77, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x6C, + 0x53, 0x74, 0x6F, 0x72, 0x61, 0x67, 0x65, 0x2E, 0x73, 0x65, + 0x74, 0x49, 0x74, 0x65, 0x6D, 0x28, 0x27, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x27, 0x2C, 0x20, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6D, 0x65, 0x29, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x61, 0x6C, 0x63, 0x75, 0x6C, + 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6C, + 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, + 0x20, 0x69, 0x6E, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, + 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, + 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x3D, 0x20, 0x44, 0x61, 0x74, 0x65, 0x2E, + 0x6E, 0x6F, 0x77, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x20, 0x65, 0x6C, 0x61, 0x70, + 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x3D, 0x20, + 0x4D, 0x61, 0x74, 0x68, 0x2E, 0x66, 0x6C, 0x6F, 0x6F, 0x72, + 0x28, 0x28, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x74, 0x54, + 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x69, 0x6D, 0x65, 0x29, 0x20, 0x2F, 0x20, 0x31, + 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, + 0x61, 0x79, 0x65, 0x64, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x0D, 0x0A, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x64, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, + 0x67, 0x65, 0x74, 0x45, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x65, 0x6C, 0x61, 0x70, + 0x73, 0x65, 0x64, 0x2D, 0x74, 0x69, 0x6D, 0x65, 0x27, 0x29, + 0x2E, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, + 0x6E, 0x74, 0x20, 0x3D, 0x20, 0x60, 0x24, 0x7B, 0x65, 0x6C, + 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x7D, + 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x73, 0x60, 0x3B, + 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7D, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x43, 0x61, 0x6C, 0x6C, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, + 0x6D, 0x65, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x77, 0x68, 0x65, 0x6E, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x61, 0x67, 0x65, 0x20, 0x6C, 0x6F, 0x61, 0x64, + 0x73, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x6F, 0x6E, + 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x3D, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, + 0x54, 0x69, 0x6D, 0x65, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x64, 0x20, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, - 0x69, 0x6D, 0x65, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6F, 0x63, - 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x67, 0x65, 0x74, 0x45, - 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x42, 0x79, 0x49, 0x64, - 0x28, 0x27, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x2D, - 0x74, 0x69, 0x6D, 0x65, 0x27, 0x29, 0x2E, 0x74, 0x65, 0x78, - 0x74, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x20, 0x3D, - 0x20, 0x60, 0x24, 0x7B, 0x65, 0x6C, 0x61, 0x70, 0x73, 0x65, - 0x64, 0x54, 0x69, 0x6D, 0x65, 0x7D, 0x20, 0x73, 0x65, 0x63, - 0x6F, 0x6E, 0x64, 0x73, 0x60, 0x3B, 0x0D, 0x0A, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, - 0x2F, 0x20, 0x43, 0x61, 0x6C, 0x6C, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61, - 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x66, - 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x77, 0x68, - 0x65, 0x6E, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x67, - 0x65, 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x73, 0x0D, 0x0A, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6E, - 0x64, 0x6F, 0x77, 0x2E, 0x6F, 0x6E, 0x6C, 0x6F, 0x61, 0x64, - 0x20, 0x3D, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, - 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, 0x65, - 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6C, 0x61, - 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, - 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x73, 0x65, 0x63, 0x6F, - 0x6E, 0x64, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6E, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6C, 0x28, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6D, - 0x65, 0x2C, 0x20, 0x31, 0x30, 0x30, 0x30, 0x29, 0x3B, 0x0D, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, - 0x2F, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, - 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x3C, 0x2F, 0x68, - 0x74, 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, }; + 0x69, 0x6D, 0x65, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, + 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x0D, 0x0A, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x49, + 0x6E, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6C, 0x28, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x45, 0x6C, 0x61, 0x70, 0x73, 0x65, + 0x64, 0x54, 0x69, 0x6D, 0x65, 0x2C, 0x20, 0x31, 0x30, 0x30, + 0x30, 0x29, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, + 0x0A, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0D, 0x0A, + }; const struct fsdata_file file_index_shtml[] = {{ NULL, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13, FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT }}; diff --git a/frtos/frontend/makefsdata.exe b/frtos/frontend/makefsdata.exe index 30f333c..f242e1f 100644 Binary files a/frtos/frontend/makefsdata.exe and b/frtos/frontend/makefsdata.exe differ diff --git a/frtos/frontend/ssi.h b/frtos/frontend/ssi.h index df1e5b0..1de109e 100644 --- a/frtos/frontend/ssi.h +++ b/frtos/frontend/ssi.h @@ -3,8 +3,11 @@ #include "hardware/adc.h" #include "pico/stdlib.h" +#include "car_config.h" +car_struct_t *car_struct; + // SSI tags - tag length limited to 8 bytes by default -const char * ssi_tags[] = {"speed","barcode","pid","orient"}; +const char * ssi_tags[] = {"speed","barcode","pid","obstacle","orient"}; u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { size_t printed; @@ -12,8 +15,15 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { case 0: // Speed { // call getSpeed() function - const float Speed = adc_read() * 3.3f / (1 << 12); - printed = snprintf(pcInsert, iInsertLen, "%f ",Speed); + + /* + const float c_speed = car_struct->p_right_motor->speed.current_cms; + printf("\n\t%f\n",c_speed); + printed = snprintf(pcInsert, iInsertLen, "%f ",c_speed); + */ + + const float speed = adc_read() * 3.3f / (1 << 12); + printed = snprintf(pcInsert, iInsertLen, "%f ",speed); } break; case 1: // barcode @@ -25,15 +35,32 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { break; case 2: //PID { - // whatever to display for PID - const char* PID = "54" ; + // whatever to display for PID + const char* PID = "-" ; printed = snprintf(pcInsert, iInsertLen, "%s", PID); } break; - case 3: //Orientation + case 3: //Obstacle detected + { + // call getObstacleDetected() function + + /* + bool obstacle = car_struct->obs->ultrasonic_detected; + if (obstacle){ + printed = snprintf(pcInsert, iInsertLen, "%s", "YES"); + } + else{ + printed = snprintf(pcInsert, iInsertLen, "%s", "NO"); + } + */ + + printed = snprintf(pcInsert, iInsertLen, "%s", "YES"); + } + case 4: //Orientation { // call getOrientation() function - const char* orien = "South" ; + + const char* orien = "South"; printed = snprintf(pcInsert, iInsertLen, "%s", orien); } break; @@ -46,7 +73,10 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { } // Initialise the SSI handler -void ssi_init() { +void ssi_init(void *params) { + + car_struct = (car_struct_t *)params; + // Initialise ADC (internal pin) adc_init(); adc_set_temp_sensor_enabled(true); diff --git a/frtos/rtos_car.c b/frtos/rtos_car.c index 7eed31d..2798bb6 100644 --- a/frtos/rtos_car.c +++ b/frtos/rtos_car.c @@ -3,6 +3,7 @@ #include "ultrasonic_sensor.h" #include "car_config.h" #include "motor_init.h" +#include "frontend.h" /*! * @brief Check if the car is on the line @@ -151,6 +152,9 @@ main(void) .obs = &obs, .p_direction = &direction }; + // webserver frontend + webserver_init(&car_struct); + // Magnetometer magnetometer_init(&car_struct); // magnetometer_tasks_init(&car_struct);