From ffb56936f1f09196f7085dea72adf09bede11872 Mon Sep 17 00:00:00 2001 From: Thaddeus Hughes Date: Sat, 3 Jan 2026 22:38:52 -0600 Subject: [PATCH] logtool. and lots of things in the main firmware. better integration into main fixed scheduler and timestamping simplified the api there ditched integer 64-bit storage types (not needed. 32 bits is plenty for everything except current time - but that's handled in RTC, everything else is deltas) web remote! --- main/control_fsm.c | 212 +++++- main/control_fsm.h | 19 +- main/landingpage.html | 1262 +++++++++++++++++++++--------- main/main.c | 24 +- main/power_mgmt.c | 52 +- main/rf_433.c | 20 +- main/rf_433.h | 6 +- main/rtc.c | 71 +- main/rtc.h | 23 +- main/solar.c | 10 +- main/solar.h | 4 +- main/storage.c | 20 +- main/storage.h | 54 +- main/uart_comms.c | 26 +- main/webpage.h | 4 +- main/webpage_brotli.h | 530 ++++++++----- main/webpage_gzip.h | 623 +++++++++------ main/webpage_minified.html | 14 +- main/webserver.c | 1478 ++++++++++++++++++++++++------------ 19 files changed, 2946 insertions(+), 1506 deletions(-) diff --git a/main/control_fsm.c b/main/control_fsm.c index 02156c8..62a16ea 100644 --- a/main/control_fsm.c +++ b/main/control_fsm.c @@ -39,8 +39,10 @@ bridge_t bridge_map[] = { bool relay_states[8] = {false}; int64_t override_times[8] = {-1}; +int64_t override_cooldown[8] = {-1}; bool enabled = false; + RTC_DATA_ATTR float remaining_distance = 0.0f; float fsm_get_remaining_distance(void) { return remaining_distance; } void fsm_set_remaining_distance(float x) { remaining_distance = x;} @@ -48,6 +50,9 @@ void fsm_set_remaining_distance(float x) { remaining_distance = x;} // Track the starting encoder count for the current move static int32_t move_start_encoder = 0; +// Track total jack up time to use for jack down duration +static int64_t jack_up_total_time = 0; + volatile fsm_state_t current_state = STATE_IDLE; volatile int64_t current_time = 0; volatile bool start_running_request = false; @@ -56,6 +61,13 @@ void setRelay(int8_t relay, bool state) { relay_states[relay] = state; } +bool isRunning() { + for (int i=0;i<8;i++) { + if (relay_states[i]) return true; + } + return false; +} + void driveRelays() { uint8_t state = 0x00; //relay_states[0] = (current_time / 1000000) % 2; // for testing purposes @@ -78,8 +90,8 @@ fsm_state_t fsm_get_state() { return current_state; } -static uint64_t timer_end = 0; -static uint64_t timer_start = 0; +static int64_t timer_end = 0; +static int64_t timer_start = 0; static inline void set_timer(uint64_t us) { timer_end = current_time + us; timer_start = current_time; @@ -87,8 +99,14 @@ static inline void set_timer(uint64_t us) { static inline bool timer_done() { return current_time >= timer_end; } void pulseOverride(relay_t relay) { - if (current_state == STATE_IDLE) - override_times[relay] = current_time + get_param_value_t(PARAM_RF_PULSE_LENGTH).u64; + if (current_state == STATE_IDLE) { + // Check if this relay is in cooldown + if (override_cooldown[relay] > current_time) { + // Still cooling down, ignore the command + return; + } + override_times[relay] = current_time + get_param_value_t(PARAM_RF_PULSE_LENGTH).u32; + } } /*void fsm_begin_auto_move() { @@ -113,6 +131,7 @@ int8_t fsm_get_current_progress(int8_t denominator) { int8_t x = 0; switch (current_state) { case STATE_DRIVE: + case STATE_JACK_UP_START: case STATE_JACK_UP: case STATE_JACK_DOWN: case STATE_MOVE_START_DELAY: @@ -142,7 +161,7 @@ void control_task(void *param) { esp_task_wdt_add(NULL); TickType_t xLastWakeTime = xTaskGetTickCount(); - const TickType_t xFrequency = pdMS_TO_TICKS(50); + const TickType_t xFrequency = pdMS_TO_TICKS(20); enabled = true; @@ -156,7 +175,10 @@ void control_task(void *param) { case FSM_CMD_START: if (current_state == STATE_IDLE) { // Check if we have remaining distance before starting - if (remaining_distance > 0.0f) { + if (remaining_distance > 0.0f + && !efuse_is_tripped(BRIDGE_DRIVE) + && !efuse_is_tripped(BRIDGE_JACK) + && !efuse_is_tripped(BRIDGE_AUX)) { current_state = STATE_MOVE_START_DELAY; set_timer(TRANSITION_DELAY_US); } else { @@ -249,20 +271,86 @@ void control_task(void *param) { // State transitions switch (current_state) { case STATE_IDLE: - break; + //ESP_LOGI("FSM", "IDLE @ %lld", current_time); + for (uint8_t i = 0; i < N_RELAYS; ++i) { + //ESP_LOGI("FSM", "t[%d] %lld", i, override_times[i]); + bool active = override_times[i] > current_time; + if (active) rtc_reset_shutdown_timer(); + + // Current limiting for manual jack down override (RELAY_B2) + if (i == RELAY_B2 && active) { + int64_t elapsed = current_time - (override_times[i] - get_param_value_t(PARAM_RF_PULSE_LENGTH).u32); + int64_t delay = get_param_value_t(PARAM_EFUSE_INRUSH_US).u32; + + // After inrush delay, check for current spike + if (elapsed > delay) { + float current = get_bridge_A(BRIDGE_JACK); + float threshold = get_param_value_t(PARAM_JACK_I_DOWN).f32; + + if (current > threshold) { + // Current spike detected - stop jacking down and start cooldown + override_times[i] = -1; + override_cooldown[i] = current_time + get_param_value_t(PARAM_EFUSE_TCOOL).u32; + active = false; + } + } + } + + // prohibit movement past jack limit switch + //if (i == BRIDGE_JACK*2+(bridge_polarities[BRIDGE_JACK]>0?0:1) && get_sensor(SENSOR_JACK)) + // setRelay(i, false); + //else + setRelay(i, active); + //if (active) ESP_LOGI("FSM", "RUN CHANNEL %d (%lld %c %lld)", i, (long long) override_times[i], active ? '>':'<', (long long) current_time); + + } + break; case STATE_MOVE_START_DELAY: if (timer_done()) { - current_state = STATE_JACK_UP; - set_timer(JACK_TIME); + current_state = STATE_JACK_UP_START; + set_timer(JACK_TIME / 2); // First phase is half of total jack time + jack_up_total_time = 0; // Reset jack up time tracker + } + break; + case STATE_JACK_UP_START: + { + // Track elapsed time + int64_t elapsed = current_time - timer_start; + jack_up_total_time = elapsed; + + // Get current sensing parameters + int64_t delay = get_param_value_t(PARAM_EFUSE_INRUSH_US).u32; + float current = get_bridge_A(BRIDGE_JACK); + float threshold = get_param_value_t(PARAM_JACK_I_UP).f32; + + // After inrush delay, check for current spike OR half-time timeout + if (elapsed > delay) { + if (current > threshold || timer_done()) { + ESP_LOGI(TAG, "START->UP BY CURRENT"); + current_state = STATE_JACK_UP; + set_timer(JACK_TIME); // Second phase is also half of total jack time + } + } + + // E-fuse trip should still cause undo + if (efuse_is_tripped(BRIDGE_JACK)) { + ESP_LOGI(TAG, "START->UP BY TIME"); + current_state = STATE_UNDO_JACK_START; + } } break; case STATE_JACK_UP: - if (timer_done()) { - current_state = STATE_DRIVE_START_DELAY; - set_timer(TRANSITION_DELAY_US); - } - if (efuse_is_tripped(BRIDGE_JACK)) { - current_state = STATE_UNDO_JACK_START; + { + if (timer_done() || efuse_is_tripped(BRIDGE_JACK)) { + // Track total time including first phase + jack_up_total_time += current_time - timer_start; + current_state = STATE_DRIVE_START_DELAY; + set_timer(TRANSITION_DELAY_US); + } + if (efuse_is_tripped(BRIDGE_JACK)) { + ESP_LOGE(TAG, "JACK TRIPPED EFUSE"); + current_state = STATE_UNDO_JACK_START; + } } break; case STATE_DRIVE_START_DELAY: @@ -326,17 +414,38 @@ void control_task(void *param) { case STATE_DRIVE_END_DELAY: if (timer_done()) { current_state = STATE_JACK_DOWN; - set_timer(JACK_TIME); + set_timer(jack_up_total_time); // Use the tracked jack up time } break; case STATE_JACK_DOWN: - if (timer_done()) { // || get_sensor(SENSOR_JACK)) { - current_state = STATE_IDLE; - } - - // assume we hit something hard and should stop - if (efuse_is_tripped(BRIDGE_JACK)) { - current_state = STATE_IDLE; + { + // Get current sensing parameters + int64_t delay = get_param_value_t(PARAM_EFUSE_INRUSH_US).u32; + int64_t elapsed = current_time - timer_start; + + // After inrush delay, check for current spike + if (elapsed > delay) { + float current = get_bridge_A(BRIDGE_JACK); + float threshold = get_param_value_t(PARAM_JACK_I_DOWN).f32; + + if (current > threshold) { + ESP_LOGI(TAG, "DOWN->IDLE BY CURRENT"); + // Current spike detected - we've hit the ground + current_state = STATE_IDLE; + break; + } + } + + // Timeout - finished jacking down + if (timer_done()) { + ESP_LOGI(TAG, "DOWN->IDLE BY TIME"); + current_state = STATE_IDLE; + } + + // E-fuse trip - assume we hit something hard + if (efuse_is_tripped(BRIDGE_JACK)) { + current_state = STATE_IDLE; + } } break; @@ -396,22 +505,41 @@ void control_task(void *param) { // Output control switch (current_state) { case STATE_IDLE: - //ESP_LOGI("FSM", "IDLE @ %lld", current_time); - for (uint8_t i = 0; i < N_RELAYS; ++i) { - //ESP_LOGI("FSM", "t[%d] %lld", i, override_times[i]); - bool active = override_times[i] > current_time; - if (active) reset_shutdown_timer(); - - // prohibit movement past jack limit switch - //if (i == BRIDGE_JACK*2+(bridge_polarities[BRIDGE_JACK]>0?0:1) && get_sensor(SENSOR_JACK)) - // setRelay(i, false); - //else - setRelay(i, active); - //if (active) ESP_LOGI("FSM", "RUN CHANNEL %d (%lld %c %lld)", i, (long long) override_times[i], active ? '>':'<', (long long) current_time); - - } - break; + //ESP_LOGI("FSM", "IDLE @ %lld", current_time); + for (uint8_t i = 0; i < N_RELAYS; ++i) { + //ESP_LOGI("FSM", "t[%d] %lld", i, override_times[i]); + bool active = override_times[i] > current_time; + if (active) rtc_reset_shutdown_timer(); + + // Current limiting for manual jack down override (RELAY_B2) + if (i == RELAY_B2 && active) { + int64_t elapsed = current_time - (override_times[i] - get_param_value_t(PARAM_RF_PULSE_LENGTH).u32); + int64_t delay = get_param_value_t(PARAM_EFUSE_INRUSH_US).u32; + + // After inrush delay, check for current spike + if (elapsed > delay) { + float current = get_bridge_A(BRIDGE_JACK); + float threshold = get_param_value_t(PARAM_JACK_I_DOWN).f32; + + if (current > threshold) { + // Current spike detected - stop jacking down + override_times[i] = -1; + active = false; + } + } + } + + // prohibit movement past jack limit switch + //if (i == BRIDGE_JACK*2+(bridge_polarities[BRIDGE_JACK]>0?0:1) && get_sensor(SENSOR_JACK)) + // setRelay(i, false); + //else + setRelay(i, active); + //if (active) ESP_LOGI("FSM", "RUN CHANNEL %d (%lld %c %lld)", i, (long long) override_times[i], active ? '>':'<', (long long) current_time); + + } + break; case STATE_CALIBRATE_JACK_MOVE: + case STATE_JACK_UP_START: case STATE_JACK_UP: // jack up and fluff setRelay(RELAY_A1, false); @@ -421,7 +549,7 @@ void control_task(void *param) { setRelay(RELAY_B2, false); setRelay(RELAY_A3, true); - reset_shutdown_timer(); + rtc_reset_shutdown_timer(); break; case STATE_CALIBRATE_DRIVE_MOVE: case STATE_DRIVE: @@ -433,7 +561,7 @@ void control_task(void *param) { setRelay(RELAY_B2, false); setRelay(RELAY_A3, true); - reset_shutdown_timer(); + rtc_reset_shutdown_timer(); break; case STATE_UNDO_JACK: case STATE_JACK_DOWN: @@ -445,7 +573,7 @@ void control_task(void *param) { setRelay(RELAY_B2, true); setRelay(RELAY_A3, true); - reset_shutdown_timer(); + rtc_reset_shutdown_timer(); break; case STATE_UNDO_JACK_START: case STATE_DRIVE_START_DELAY: @@ -458,7 +586,7 @@ void control_task(void *param) { setRelay(RELAY_B2, false); setRelay(RELAY_A3, true); - reset_shutdown_timer(); + rtc_reset_shutdown_timer(); break; case STATE_CALIBRATE_JACK_DELAY: default: diff --git a/main/control_fsm.h b/main/control_fsm.h index 93e1507..6476b6c 100644 --- a/main/control_fsm.h +++ b/main/control_fsm.h @@ -26,14 +26,15 @@ typedef enum { typedef enum { STATE_IDLE = 0, - STATE_MOVE_START_DELAY = 1, - STATE_JACK_UP = 2, - STATE_DRIVE_START_DELAY = 3, - STATE_DRIVE = 4, - STATE_DRIVE_END_DELAY = 5, - STATE_JACK_DOWN = 6, - STATE_UNDO_JACK = 7, - STATE_UNDO_JACK_START = 8, + STATE_MOVE_START_DELAY, + STATE_JACK_UP_START, + STATE_JACK_UP, + STATE_DRIVE_START_DELAY, + STATE_DRIVE, + STATE_DRIVE_END_DELAY, + STATE_JACK_DOWN, + STATE_UNDO_JACK, + STATE_UNDO_JACK_START, STATE_CALIBRATE_JACK_DELAY, STATE_CALIBRATE_JACK_MOVE, @@ -67,6 +68,8 @@ void pulseOverride(relay_t relay/*, int64_t pulse*/); esp_err_t fsm_init(); esp_err_t fsm_stop(); +bool isRunning(); + void fsm_set_cal_val(float v); int64_t fsm_get_cal_t(); int64_t fsm_get_cal_e(); diff --git a/main/landingpage.html b/main/landingpage.html index d78b5e0..bf70e1c 100644 --- a/main/landingpage.html +++ b/main/landingpage.html @@ -26,10 +26,14 @@ black: #2f2f2f input, button { border: 1px solid #ba965b; border-radius: 5px; background-color: #efede9; text-align: right; box-sizing: border-box; } input[type="text"], input[type="number"] { font-family: monospace; } + input[readonly] { background-color: #e4e4e4; } + + button { text-align: center; } .changed, #commit_btn { background-color: #2a493d !important; color: #ffffff !important; } - #commit_btn { width: 100%; margin-top: 10px; padding: 10px; cursor: pointer; border: none; font-weight: bold; } - #commit_btn[disabled] { background-color: #444 !important; color: #888; cursor: not-allowed; } + #cancel_btn { background-color: #723 !important; color: #ffffff !important; } + #commit_btn, #cancel_btn { width: 45%; margin-top: 10px; padding: 10px; cursor: pointer; border: none; font-weight: bold; } + #commit_btn[disabled], #cancel_btn[disabled] { background-color: #444 !important; color: #888; cursor: not-allowed; } table { width: 100%; border-collapse: collapse; text-align: left; } td { padding: 8px; border-bottom: 1px solid #efede9; } summary { border-radius: 5px; font-weight: bold; text-align: left; color: #fff; background-color: #723; padding: 0.3rem;} @@ -42,11 +46,105 @@ black: #2f2f2f font-size: 2.5rem; } + /* Popup modal styles */ + #popup-overlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + z-index: 1000; + justify-content: center; + align-items: center; + } + + #popup-content { + background-color: #2a493d; + color: #ffffff; + padding: 30px; + border-radius: 10px; + text-align: center; + max-width: 400px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); + } + + #popup-content h2 { + margin-top: 0; + color: #ffffff; + background-color: #2a493d; + } + + #popup-content p { + background-color: #2a493d; + color: #ffffff; + font-size: 1.1rem; + } + @media screen and (max-width: 350px) { #content { max-width: 100%; padding: 0 5px; } table tr td { display: block; width: 100%; box-sizing: border-box; } /* Stack table cells vertically on mobile for better usability */ table tr { display: block; margin-bottom: 10px; } } + + #popup-buttons { + background-color: #2a493d; + margin-top: 20px; + display: flex; + gap: 10px; + justify-content: center; + flex-wrap: wrap; + } + + #popup-buttons button { + background-color: #efede9; + color: #2f2f2f; + border: 1px solid #ba965b; + padding: 10px 20px; + cursor: pointer; + border-radius: 5px; + font-weight: bold; + min-width: 100px; + } + + #popup-buttons button:hover { + background-color: #ba965b; + color: #ffffff; + } + + #popup-buttons button.primary { + background-color: #ba965b; + color: #ffffff; + } + + #popup-buttons button.primary:hover { + background-color: #8a7045; + } + + #popup-input-container { + background-color: #2a493d; + margin: 20px 0; + } + + #popup-input { + width: 100%; + padding: 10px; + border: 1px solid #ba965b; + border-radius: 5px; + background-color: #efede9; + color: #2f2f2f; + text-align: center; + font-size: 1.1rem; + } + + .sqbtn { + width: 35%; + padding: 30px; + font-weight: bold; + } + + @@ -65,7 +163,6 @@ black: #2f2f2f - @@ -73,32 +170,36 @@ black: #2f2f2f - - + - + - + + + + + - + - + - + @@ -112,10 +213,57 @@ black: #2f2f2f
+
Schedule Start
Schedule End
# Moves/Day
Next Move At
Remain. Distance (ft)
Move Distance (ft)
Jack Height (in)
Battery (V)
+

+
+ REMOTE CONTROL +
+ + + + + +
+
+
DANGER ZONE @@ -126,8 +274,11 @@ black: #2f2f2f - + + @@ -137,442 +288,793 @@ black: #2f2f2f
Firmware - + + +
Log File
+
+ + + \ No newline at end of file diff --git a/main/main.c b/main/main.c index edae43e..a87e2f9 100644 --- a/main/main.c +++ b/main/main.c @@ -22,7 +22,7 @@ esp_err_t send_log() { entry[0] = LOG_ENTRY_SIZE; // Pack 64-bit timestamp into bytes 1-8 - uint64_t be_timestamp = rtc_time_ms(); + uint64_t be_timestamp = rtc_get_ms(); memcpy(&entry[1], &be_timestamp, 8); // Pack 32-bit voltages/currents into bytes 9-24 @@ -174,7 +174,7 @@ void app_main(void) { if (adc_init() != ESP_OK) ESP_LOGE(TAG, "ADC FAILED"); if (storage_init() != ESP_OK) ESP_LOGE(TAG, "STORAGE FAILED"); if (log_init() != ESP_OK) ESP_LOGE(TAG, "LOG FAILED"); - if (run_solar_fsm() != ESP_OK) ESP_LOGE(TAG, "SOLAR FAILED"); + if (solar_run_fsm() != ESP_OK) ESP_LOGE(TAG, "SOLAR FAILED"); // TODO: Do a 12V check and enter deep sleep if there's a problem @@ -194,7 +194,7 @@ void app_main(void) { } else */if (cause == ESP_SLEEP_WAKEUP_EXT0) { ESP_LOGI("MAIN", "Woke from button press"); } else { - if (!alarm_tripped()) { + if (!rtc_alarm_tripped()) { //enter_deep_sleep(); } } @@ -209,7 +209,7 @@ void app_main(void) { /*** MAIN LOOP ***/ TickType_t xLastWakeTime = xTaskGetTickCount(); - const TickType_t xFrequency = pdMS_TO_TICKS(100); + const TickType_t xFrequency = pdMS_TO_TICKS(50); /*while(true) { ESP_LOGI(TAG, "TICK"); @@ -223,7 +223,7 @@ void app_main(void) { i2c_poll_buttons(); if (i2c_get_button_state(0)) - reset_shutdown_timer(); + rtc_reset_shutdown_timer(); switch (fsm_get_state()) { case STATE_IDLE: @@ -250,7 +250,7 @@ void app_main(void) { } // when not actively moving we log at a low frequency - if (esp_timer_get_time() > last_log_time + DEEP_SLEEP_US) + if (isRunning() || (esp_timer_get_time() > last_log_time + DEEP_SLEEP_US)) send_log(); if(i2c_get_button_ms(0) > 2100) @@ -268,20 +268,24 @@ void app_main(void) { break; case STATE_CALIBRATE_JACK_DELAY: + send_log(); if (i2c_get_button_tripped(0)) fsm_request(FSM_CMD_CALIBRATE_JACK_START); break; case STATE_CALIBRATE_JACK_MOVE: + send_log(); if (i2c_get_button_tripped(0)) fsm_request(FSM_CMD_CALIBRATE_JACK_END); break; case STATE_CALIBRATE_DRIVE_DELAY: + send_log(); if (i2c_get_button_tripped(0)) fsm_request(FSM_CMD_CALIBRATE_DRIVE_START); break; case STATE_CALIBRATE_DRIVE_MOVE: + send_log(); if (i2c_get_button_tripped(0)) fsm_request(FSM_CMD_CALIBRATE_DRIVE_END); break; @@ -299,14 +303,14 @@ void app_main(void) { - if (alarm_tripped()) { + if (rtc_alarm_tripped()) { fsm_request(FSM_CMD_START); - set_next_alarm(); + rtc_schedule_next_alarm(); } - run_solar_fsm(); + solar_run_fsm(); - check_shutdown_timer(); + rtc_check_shutdown_timer(); esp_task_wdt_reset(); } } \ No newline at end of file diff --git a/main/power_mgmt.c b/main/power_mgmt.c index b4cf53a..b8c9bb2 100644 --- a/main/power_mgmt.c +++ b/main/power_mgmt.c @@ -63,6 +63,9 @@ typedef struct { float heat; bool tripped; int64_t trip_time; + + // Inrush tolerance tracking + int64_t inrush_start_time; // When instantaneous overcurrent first detected (0 = not in overcurrent) } isens_channel_t; static isens_channel_t isens[N_BRIDGES] = {0}; @@ -112,7 +115,7 @@ float get_raw_battery_voltage(void) { != ESP_OK) { return NAN; } // Voltage divider: 150kohm to 1Mohm -> gain = 1.15 -> scale = 1150/150 - return voltage_mv * 0.00766666666 + get_param_value_t(PARAM_V_SENS_OFFSET).f32; // same as / 1000.0 * 1150.0 / 150.0; + return voltage_mv * get_param_value_t(PARAM_V_SENS_K).f32 + get_param_value_t(PARAM_V_SENS_OFFSET).f32; // same as / 1000.0 * 1150.0 / 150.0; } esp_err_t process_battery_voltage(void) @@ -127,10 +130,11 @@ esp_err_t process_battery_voltage(void) if (isnan(raw)) { //ESP_LOGI(TAG, "RAW BATTERY IS NAN"); } else { - if (isnan(ema_battery) || isnan(alpha)) + if (isnan(ema_battery) || isnan(alpha)) { ema_battery = raw; - else + } else { ema_battery = alpha * (float)raw + (1.0f - alpha) * ema_battery; + } } } @@ -174,7 +178,7 @@ esp_err_t process_bridge_current(bridge_t bridge) { break; case BRIDGE_DRIVE: // ACS37220LEZATR-100B3 is 100A capable and 13.2 mV/A - raw_a = (voltage_mv - 1650.0f) / 13.2f; + raw_a = -(voltage_mv - 1650.0f) / 13.2f; break; } @@ -187,10 +191,11 @@ esp_err_t process_bridge_current(bridge_t bridge) { //ESP_LOGI(TAG, "RAW BATTERY IS NAN"); channel->ema_current = NAN; } else { - if (isnan(ema_battery) || isnan(alpha)) + if (isnan(ema_battery) || isnan(alpha)) { channel->ema_current = raw_a; - else + } else { channel->ema_current = alpha * raw_a + (1.0f - alpha) * channel->ema_current; + } } } @@ -208,11 +213,12 @@ esp_err_t process_bridge_current(bridge_t bridge) { if (isnan(raw_a)) { //ESP_LOGI(TAG, "RAW BATTERY IS NAN"); } else { - if (isnan(ema_battery) || isnan(alpha)) + if (isnan(ema_battery) || isnan(alpha)) { channel->az_offset = channel->ema_current; - else + } else { channel->az_offset = alpha * channel->ema_current + (1.0f - alpha) * channel->az_offset; + } } } } @@ -244,12 +250,26 @@ esp_err_t process_bridge_current(bridge_t bridge) { // Normalize the current as a fraction of rated current float I_norm = fabsf(channel->current / I_nominal); - // Instant trip on extreme overcurrent + // Instant trip on extreme overcurrent - but with inrush tolerance if (I_norm >= get_param_value_t(PARAM_EFUSE_KINST).f32) { - channel->tripped = true; - channel->trip_time = now; - //ESP_LOGI(TAG, "FUSE TRIP: Inom: %+.5f HEAT:%+2.5f", I_norm, channel->heat); - return ESP_OK; // no more processing, if we're over, we're over + // Start tracking if this is the first time we've seen overcurrent + if (channel->inrush_start_time == 0) { + channel->inrush_start_time = now; + } + + // Check if overcurrent has persisted long enough + int64_t inrush_duration = now - channel->inrush_start_time; + if (inrush_duration >= get_param_value_t(PARAM_EFUSE_INRUSH_US).u32) { + channel->tripped = true; + channel->trip_time = now; + channel->inrush_start_time = 0; // Reset for next time + //ESP_LOGI(TAG, "FUSE TRIP: Inom: %+.5f HEAT:%+2.5f", I_norm, channel->heat); + return ESP_OK; // no more processing, if we're over, we're over + } + // Still in overcurrent but within inrush tolerance window - don't trip yet + } else { + // Current dropped below threshold - reset inrush timer + channel->inrush_start_time = 0; } // Accumulate heat @@ -275,13 +295,13 @@ esp_err_t process_bridge_current(bridge_t bridge) { // And enough time has passed // Go ahead and reset the e-fuse } else if (channel->tripped && - (now - channel->trip_time) > get_param_value_t(PARAM_EFUSE_TCOOL).i64) { + (now - channel->trip_time) > get_param_value_t(PARAM_EFUSE_TCOOL).u32) { channel->tripped = false; // channel.heat = 0.0f // I think we should wait for the e-fuse to catch up } - //if (bridge == BRIDGE_DRIVE) - // ESP_LOGI(TAG, "FUSE: Inom: %+.5f HEAT:%+2.5f", I_norm, channel->heat); + //if (bridge == BRIDGE_JACK) + //ESP_LOGI(TAG, "FUSE: raw_a: %+.4f cur: %+.4f Inorm: %+.5f HEAT:%+2.5f", raw_a, channel->current, I_norm, channel->heat); return ESP_OK; } diff --git a/main/rf_433.c b/main/rf_433.c index 2faa1fe..9ff676a 100644 --- a/main/rf_433.c +++ b/main/rf_433.c @@ -41,7 +41,7 @@ int learn_flag = -1; bool controls_enabled = true; // Temporary storage for learned keycodes (not committed to params yet) -static int64_t temp_keycodes[NUM_RF_BUTTONS] = {-1, -1, -1, -1, -1, -1, -1, -1}; +static int64_t temp_keycodes[NUM_RF_BUTTONS] = {0}; // For rmt_rx_register_event_callbacks static bool rfrx_done(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *udata) { @@ -137,7 +137,7 @@ static void rf_433_receiver_task(void* param) { if (learn_flag >= 0) { // Store to temporary storage, not to params yet - temp_keycodes[learn_flag] = (int64_t)code; + temp_keycodes[learn_flag] = (uint32_t)code; ESP_LOGI(TAG, "LEARNED KEYCODE (temp storage)"); learn_flag = -1; } else if (controls_enabled) { @@ -151,9 +151,9 @@ static void rf_433_receiver_task(void* param) { }; for (uint8_t i = 0; i < NUM_RF_BUTTONS; i++) { - int64_t match = get_param_value_t(PARAM_KEYCODE_0+i).i64; + uint32_t match = get_param_value_t(PARAM_KEYCODE_0+i).u32; // Compare just the code (lower 32 bits) - if ((uint32_t)match == code && code!=-1) { + if ((uint32_t)match == code && code!=0) { switch (i) { case 0: pulseOverride(RELAY_A1); pulseOverride(RELAY_A3); break; case 1: pulseOverride(RELAY_B1); pulseOverride(RELAY_A3); break; @@ -216,8 +216,8 @@ esp_err_t rf_433_init() { esp_err_t rf_433_stop() { return ESP_OK; } -void rf_433_set_keycode(uint8_t index, int64_t code) { - set_param_value_t(PARAM_KEYCODE_0+index, (param_value_t){.i64=code}); +void rf_433_set_keycode(uint8_t index, uint32_t code) { + set_param_value_t(PARAM_KEYCODE_0+index, (param_value_t){.u32=code}); } void rf_433_learn_keycode(uint8_t index) { @@ -237,18 +237,18 @@ void rf_433_enable_controls() { controls_enabled = true; } -int64_t rf_433_get_temp_keycode(uint8_t index) { - if (index >= NUM_RF_BUTTONS) return -1; +int32_t rf_433_get_temp_keycode(uint8_t index) { + if (index >= NUM_RF_BUTTONS) return 0; return temp_keycodes[index]; } -void rf_433_set_temp_keycode(uint8_t index, int64_t code) { +void rf_433_set_temp_keycode(uint8_t index, uint32_t code) { if (index >= NUM_RF_BUTTONS) return; temp_keycodes[index] = code; } void rf_433_clear_temp_keycodes() { for (uint8_t i = 0; i < NUM_RF_BUTTONS; i++) { - temp_keycodes[i] = -1; + temp_keycodes[i] = 0; } } \ No newline at end of file diff --git a/main/rf_433.h b/main/rf_433.h index 9c80fdf..5f289d2 100644 --- a/main/rf_433.h +++ b/main/rf_433.h @@ -16,7 +16,7 @@ int64_t recieveKeycode(); esp_err_t rf_433_init(); esp_err_t rf_433_stop(); -void rf_433_set_keycode(uint8_t index, int64_t code); +void rf_433_set_keycode(uint8_t index, uint32_t code); /* int8_t rf_433_get_keycode(); @@ -29,8 +29,8 @@ void rf_433_cancel_learn_keycode(); void rf_433_disable_controls(); void rf_433_enable_controls(); -int64_t rf_433_get_temp_keycode(uint8_t index); -void rf_433_set_temp_keycode(uint8_t index, int64_t code); +int32_t rf_433_get_temp_keycode(uint8_t index); +void rf_433_set_temp_keycode(uint8_t index, uint32_t code); void rf_433_clear_temp_keycodes(); #endif \ No newline at end of file diff --git a/main/rtc.c b/main/rtc.c index c423b7c..f52fb35 100644 --- a/main/rtc.c +++ b/main/rtc.c @@ -67,13 +67,13 @@ esp_err_t rtc_xtal_init(void) { return ESP_OK; } -void reset_shutdown_timer(void) +void rtc_reset_shutdown_timer(void) { last_activity_tick = xTaskGetTickCount(); rtc_wdt_feed(); } -void enter_deep_sleep(void) +void rtc_enter_deep_sleep(void) { //close_current_log(); fsm_request(FSM_CMD_STOP); @@ -82,21 +82,7 @@ void enter_deep_sleep(void) esp_deep_sleep_start(); } -void rtc_set_time(struct tm *tm) { - rtc_set = true; - struct timeval tv = { .tv_sec = mktime(tm), .tv_usec = 0 }; - settimeofday(&tv, NULL); - reset_solar_fsm(); -} - -void rtc_get_time(struct tm *tm) -{ - time_t raw; - time(&raw); - localtime_r(&raw, tm); -} - -int64_t system_rtc_get_raw_time(void) +int64_t rtc_get_s(void) { struct timeval tv; gettimeofday(&tv, NULL); @@ -104,22 +90,24 @@ int64_t system_rtc_get_raw_time(void) } -void system_rtc_set_raw_time(int64_t tv_sec) +void rtc_set_s(int64_t tv_sec) { rtc_set = true; settimeofday(&(struct timeval){.tv_sec = tv_sec, .tv_usec=0}, NULL); + solar_reset_fsm(); + rtc_schedule_next_alarm(); } -uint64_t rtc_time_ms(void) +int64_t rtc_get_ms(void) { struct timeval tv; gettimeofday(&tv, NULL); - return (uint64_t)tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; + return (int64_t)tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; } -int64_t system_rtc_seconds_into_day(void) +int64_t rtc_get_s_in_day(void) { - return system_rtc_get_raw_time() % 86400UL; + return rtc_get_s() % 86400UL; } esp_sleep_wakeup_cause_t rtc_wakeup_cause(void) @@ -136,18 +124,18 @@ esp_sleep_wakeup_cause_t rtc_wakeup_cause(void) /* -------------------------------------------------------------------------- */ /* Unified periodic update */ /* -------------------------------------------------------------------------- */ -void check_shutdown_timer(void) +void rtc_check_shutdown_timer(void) { TickType_t elapsed = xTaskGetTickCount() - last_activity_tick; if (elapsed * portTICK_PERIOD_MS >= POWER_INACTIVITY_TIMEOUT_MS) - enter_deep_sleep(); + rtc_enter_deep_sleep(); } /* -------------------------------------------------------------------------- */ /* Time adjustment helpers */ /* -------------------------------------------------------------------------- */ -void adjust_rtc_hour(char *key, int8_t dir) +/*void adjust_rtc_hour(char *key, int8_t dir) { struct tm t; rtc_get_time(&t); @@ -169,13 +157,13 @@ void adjust_rtc_min(char *key, int8_t dir) if (t.tm_min < 0) t.tm_min = 59; rtc_set_time(&t); set_next_alarm(); -} +}*/ -void set_next_alarm(void) { - int8_t start_h = 0; //get_param_i8("sched_start"); - int8_t end_h = 23; //get_param_i8("sched_end"); - int8_t num = 0; //get_param_i8("sched_num"); +void rtc_schedule_next_alarm(void) { + int64_t start_sec = get_param_value_t(PARAM_MOVE_START).u32; + int64_t end_sec = get_param_value_t(PARAM_MOVE_END).u32; + int16_t num = get_param_value_t(PARAM_NUM_MOVES).i16; if (num <= 0) { next_alarm_time_s = -1; @@ -183,15 +171,12 @@ void set_next_alarm(void) { } // Current time info - uint32_t s_into_day = system_rtc_seconds_into_day(); - time_t current_time = system_rtc_get_raw_time(); + int64_t s_into_day = rtc_get_s_in_day(); + time_t current_time = rtc_get_s(); time_t today_midnight = current_time - s_into_day; - int start_sec = start_h * 3600; - int end_sec = end_h * 3600; - - bool overnight = (start_h > end_h); - int total_duration = overnight ? (86400 - start_sec) + end_sec : end_sec - start_sec; + bool overnight = (start_sec > end_sec); + int64_t total_duration = overnight ? (86400 - start_sec) + end_sec : end_sec - start_sec; // Determine period start time_t period_start; @@ -216,7 +201,7 @@ void set_next_alarm(void) { int64_t spacing = total_duration / (num - 1); time_t next_alarm = -1; - for (int8_t i = 0; i < num; i++) { + for (int16_t i = 0; i < num; i++) { time_t alarm_time = period_start + spacing * i; if (alarm_time > current_time) { next_alarm = alarm_time; @@ -234,12 +219,16 @@ void set_next_alarm(void) { ESP_LOGI("ALARM", "SET FOR %lld (in %lld s)", next_alarm_time_s, next_alarm_time_s - current_time); } -bool alarm_tripped() { +int64_t rtc_get_next_alarm_s() { + return next_alarm_time_s; +} + +bool rtc_alarm_tripped() { if (!rtc_is_set()) return false; if (next_alarm_time_s < 0) { - set_next_alarm(); + rtc_schedule_next_alarm(); return false; } - return system_rtc_get_raw_time() > next_alarm_time_s; + return rtc_get_s() > next_alarm_time_s; } \ No newline at end of file diff --git a/main/rtc.h b/main/rtc.h index e95da69..1930088 100644 --- a/main/rtc.h +++ b/main/rtc.h @@ -30,24 +30,23 @@ esp_err_t rtc_xtal_init(); bool rtc_is_set(); -void set_next_alarm(void); -void reset_shutdown_timer(); // reset shutoff timer -void enter_deep_sleep(); -void check_shutdown_timer(); +void rtc_check_shutdown_timer(); +void rtc_reset_shutdown_timer(); // reset shutoff timer +void rtc_enter_deep_sleep(); esp_sleep_wakeup_cause_t rtc_wakeup_cause(); -void adjust_rtc_hour(char *key, int8_t dir); -void adjust_rtc_min(char *key, int8_t dir); +/*void adjust_rtc_hour(char *key, int8_t dir); +void adjust_rtc_min(char *key, int8_t dir);*/ -void rtc_get_time(struct tm * timeinfo); +int64_t rtc_get_s (void); +int64_t rtc_get_ms(void); +void rtc_set_s(int64_t); -int64_t system_rtc_get_raw_time(void); -void system_rtc_set_raw_time(int64_t); +void rtc_schedule_next_alarm(void); +int64_t rtc_get_next_alarm_s(); -bool alarm_tripped(); - -uint64_t rtc_time_ms(); +bool rtc_alarm_tripped(); /* -------------------------------------------------------------------------- */ #endif /* MAIN_RTC_H_ */ \ No newline at end of file diff --git a/main/solar.c b/main/solar.c index eaa711f..f6f6dfc 100644 --- a/main/solar.c +++ b/main/solar.c @@ -16,7 +16,7 @@ typedef enum { RTC_DATA_ATTR charge_state_t current_charge_state = CHG_STATE_FLOAT; RTC_DATA_ATTR int64_t timer; -esp_err_t reset_solar_fsm() { +esp_err_t solar_reset_fsm() { timer = -1; current_charge_state = CHG_STATE_FLOAT; return ESP_OK; @@ -32,10 +32,10 @@ esp_err_t init_solar_gpio() { return ESP_OK; } -esp_err_t run_solar_fsm() { +esp_err_t solar_run_fsm() { init_solar_gpio(); - int64_t now = system_rtc_get_raw_time(); + int64_t now = rtc_get_ms(); //ESP_LOGI("BAT", "FSM STATE %d", current_charge_state); @@ -50,7 +50,7 @@ esp_err_t run_solar_fsm() { //if (rtc_is_set()) { switch(current_charge_state) { case CHG_STATE_BULK: - if (now > timer+get_param_value_t(PARAM_CHG_BULK_S).i64) { + if (now > timer+get_param_value_t(PARAM_CHG_BULK_S).u32) { current_charge_state = CHG_STATE_FLOAT; } @@ -61,7 +61,7 @@ esp_err_t run_solar_fsm() { timer = now; } - if (now > timer+get_param_value_t(PARAM_CHG_LOW_S).i64) { + if (now > timer+get_param_value_t(PARAM_CHG_LOW_S).u32) { timer = now; current_charge_state = CHG_STATE_BULK; } diff --git a/main/solar.h b/main/solar.h index e979d00..e07c6cb 100644 --- a/main/solar.h +++ b/main/solar.h @@ -10,7 +10,7 @@ #include "esp_err.h" -esp_err_t run_solar_fsm(); -esp_err_t reset_solar_fsm(); +esp_err_t solar_run_fsm(); +esp_err_t solar_reset_fsm(); #endif /* MAIN_SOLAR_H_ */ diff --git a/main/storage.c b/main/storage.c index 1ee9d75..a003516 100644 --- a/main/storage.c +++ b/main/storage.c @@ -145,7 +145,7 @@ char* get_param_string(param_idx_t id) { param_type_e get_param_type(param_idx_t id) { if (id >= NUM_PARAMS) { - return PARAM_TYPE_u64; // Default fallback + return PARAM_TYPE_f64; // Default fallback } return parameter_types[id]; } @@ -175,12 +175,6 @@ const char* get_param_json_string(param_idx_t id, char* buffer, size_t buf_size) case PARAM_TYPE_i32: snprintf(buffer, buf_size, "%ld", (long)val.i32); break; - case PARAM_TYPE_u64: - snprintf(buffer, buf_size, "%llu", (unsigned long long)val.u64); - break; - case PARAM_TYPE_i64: - snprintf(buffer, buf_size, "%lld", (long long)val.i64); - break; case PARAM_TYPE_f32: if (isnan(val.f32) || isinf(val.f32)) { snprintf(buffer, buf_size, "null"); @@ -251,12 +245,6 @@ static void pack_param(uint8_t *dest, param_idx_t id) { case PARAM_TYPE_f32: memcpy(dest, ¶meter_table[id].f32, 4); break; - case PARAM_TYPE_u64: - memcpy(dest, ¶meter_table[id].u64, 8); - break; - case PARAM_TYPE_i64: - memcpy(dest, ¶meter_table[id].i64, 8); - break; case PARAM_TYPE_f64: memcpy(dest, ¶meter_table[id].f64, 8); break; @@ -288,12 +276,6 @@ static void unpack_param(const uint8_t *src, param_idx_t id) { case PARAM_TYPE_f32: memcpy(¶meter_table[id].f32, src, 4); break; - case PARAM_TYPE_u64: - memcpy(¶meter_table[id].u64, src, 8); - break; - case PARAM_TYPE_i64: - memcpy(¶meter_table[id].i64, src, 8); - break; case PARAM_TYPE_f64: memcpy(¶meter_table[id].f64, src, 8); break; diff --git a/main/storage.h b/main/storage.h index 26ff23e..b85d727 100644 --- a/main/storage.h +++ b/main/storage.h @@ -25,8 +25,6 @@ typedef union { int16_t i16; uint32_t u32; int32_t i32; - uint64_t u64; - int64_t i64; float f32; double f64; char str[16]; // 15 chars + null terminator @@ -38,8 +36,6 @@ typedef enum { PARAM_TYPE_i16 = 1, PARAM_TYPE_u32 = 2, PARAM_TYPE_i32 = 3, - PARAM_TYPE_u64 = 4, - PARAM_TYPE_i64 = 5, PARAM_TYPE_f32 = 6, PARAM_TYPE_f64 = 7, PARAM_TYPE_str = 8 @@ -59,8 +55,6 @@ static inline uint8_t param_type_size(param_type_e type) { case PARAM_TYPE_u32: case PARAM_TYPE_i32: case PARAM_TYPE_f32: return 4; - case PARAM_TYPE_u64: - case PARAM_TYPE_i64: case PARAM_TYPE_f64: return 8; case PARAM_TYPE_str: return 16; default: return 8; // Fallback @@ -83,44 +77,48 @@ static inline uint8_t param_type_size(param_type_e type) { // ============================================================================ #define PARAM_LIST \ - PARAM_DEF(BOOT_TIME, i64, 0, "us") \ + PARAM_DEF(BOOT_TIME, i32, 0, "us") \ PARAM_DEF(NUM_MOVES, u32, 0, "") \ PARAM_DEF(MOVE_START, u32, 0, "s") \ PARAM_DEF(MOVE_END, u32, 0, "s") \ PARAM_DEF(DRIVE_DIST, f32, 10, "ft") \ PARAM_DEF(JACK_DIST, f32, 5, "in") \ - PARAM_DEF(DRIVE_KE, f32, 4000, "n/ft") \ - PARAM_DEF(DRIVE_KT, f32, 600, "ms/ft") \ - PARAM_DEF(JACK_KT, f32, 600, "ms/in") \ - PARAM_DEF(KEYCODE_0, i32, -1, "") \ - PARAM_DEF(KEYCODE_1, i32, -1, "") \ - PARAM_DEF(KEYCODE_2, i32, -1, "") \ - PARAM_DEF(KEYCODE_3, i32, -1, "") \ - PARAM_DEF(KEYCODE_4, i32, -1, "") \ - PARAM_DEF(KEYCODE_5, i32, -1, "") \ - PARAM_DEF(KEYCODE_6, i32, -1, "") \ - PARAM_DEF(KEYCODE_7, i32, -1, "") \ - PARAM_DEF(ADC_ALPHA_BATTERY, f32, 0.02, "-") \ - PARAM_DEF(ADC_ALPHA_ISENS, f32, 0.02, "-") \ + PARAM_DEF(DRIVE_KE, f32, 29.2, "n/ft") \ + PARAM_DEF(DRIVE_KT, f32, 2880000, "us/ft") \ + PARAM_DEF(JACK_KT, f32, 1428571, "ms/in") \ + PARAM_DEF(KEYCODE_0, u32, 0, "") \ + PARAM_DEF(KEYCODE_1, u32, 0, "") \ + PARAM_DEF(KEYCODE_2, u32, 0, "") \ + PARAM_DEF(KEYCODE_3, u32, 0, "") \ + PARAM_DEF(KEYCODE_4, u32, 0, "") \ + PARAM_DEF(KEYCODE_5, u32, 0, "") \ + PARAM_DEF(KEYCODE_6, u32, 0, "") \ + PARAM_DEF(KEYCODE_7, u32, 0, "") \ + PARAM_DEF(ADC_ALPHA_BATTERY, f32, 0.5, "-") \ + PARAM_DEF(ADC_ALPHA_ISENS, f32, 0.6, "-") \ PARAM_DEF(ADC_ALPHA_IAZ, f32, 0.005, "-") \ PARAM_DEF(ADC_DB_IAZ, f32, 5.0, "A") \ PARAM_DEF(EFUSE_INOM_1, f32, 40.0, "A") \ PARAM_DEF(EFUSE_INOM_2, f32, 6.0, "A") \ - PARAM_DEF(EFUSE_INOM_3, f32, 2.0, "A") \ + PARAM_DEF(EFUSE_INOM_3, f32, 4.0, "A") \ PARAM_DEF(EFUSE_HEAT_THRESH, f32, 60.0, "i/i^2-s") \ - PARAM_DEF(EFUSE_KINST, f32, 4.0, "i/i") \ + PARAM_DEF(EFUSE_KINST, f32, 5.0, "i/i") \ PARAM_DEF(EFUSE_TAUCOOL, f32, 0.2, "i") \ - PARAM_DEF(EFUSE_TCOOL, i64, 5000000, "us") \ + PARAM_DEF(EFUSE_TCOOL, u32, 5000000, "us") \ PARAM_DEF(LOW_PROTECTION_V, f32, 10.0, "V") \ - PARAM_DEF(LOW_PROTECTION_S, i64, 10, "s") \ + PARAM_DEF(LOW_PROTECTION_S, u32, 10, "s") \ PARAM_DEF(CHG_LOW_V, f32, 5.0, "V") \ - PARAM_DEF(CHG_LOW_S, i64, 5, "s") \ - PARAM_DEF(CHG_BULK_S, i64, 20, "s") \ - PARAM_DEF(RF_PULSE_LENGTH, u64, 350000, "us") \ + PARAM_DEF(CHG_LOW_S, u32, 5, "s") \ + PARAM_DEF(CHG_BULK_S, u32, 20, "s") \ + PARAM_DEF(RF_PULSE_LENGTH, u32, 350000, "us") \ PARAM_DEF(V_SENS_OFFSET, f32, 0.4, "V") \ - PARAM_DEF(WIFI_CHANNEL, i16, 6, "") \ + PARAM_DEF(WIFI_CHANNEL, u16, 6, "") \ PARAM_DEF(WIFI_SSID, str, "sc.local", "") \ PARAM_DEF(WIFI_PASS, str, "password", "") \ + PARAM_DEF(EFUSE_INRUSH_US, u32, 300000, "us") \ + PARAM_DEF(JACK_I_UP, f32, 5.0, "A") \ + PARAM_DEF(JACK_I_DOWN, f32, 8.0, "A") \ + PARAM_DEF(V_SENS_K, f32, 0.00766666666, "V/mV") \ // Generate enum for parameter indices diff --git a/main/uart_comms.c b/main/uart_comms.c index 1c81aa0..4f5a952 100644 --- a/main/uart_comms.c +++ b/main/uart_comms.c @@ -74,25 +74,15 @@ static void print_param_value(param_idx_t id, param_value_t val) { (long)val.i32, (unsigned long)val.i32); break; - case PARAM_TYPE_u64: - printf("%llu (0x%016llX)\n", - (unsigned long long)val.u64, - (unsigned long long)val.u64); - break; - - case PARAM_TYPE_i64: - printf("%lld (0x%016llX)\n", - (long long)val.i64, (unsigned long long)val.i64); - break; - case PARAM_TYPE_f32: printf("%.6f (0x%08lX as bits)\n", val.f32, (unsigned long)val.u32); break; + case PARAM_TYPE_f64: printf("%.6f (0x%016llX as bits)\n", - val.f64, (unsigned long long)val.u64); + val.f64, (unsigned long long)val.f64); break; case PARAM_TYPE_str: @@ -113,7 +103,7 @@ static esp_err_t parse_param_value(const char *orig_str, param_type_e type, para while (isspace((unsigned char)*str)) str++; // Check for negative sign on unsigned integer types - bool is_unsigned_int = (type == PARAM_TYPE_u16 || type == PARAM_TYPE_u32 || type == PARAM_TYPE_u64); + bool is_unsigned_int = (type == PARAM_TYPE_u16 || type == PARAM_TYPE_u32); if (is_unsigned_int && *str == '-') { return ESP_FAIL; } @@ -123,15 +113,17 @@ static esp_err_t parse_param_value(const char *orig_str, param_type_e type, para switch (type) { case PARAM_TYPE_u16: + val->u16 = strtoull(str, &endptr, 0); + break; case PARAM_TYPE_u32: - case PARAM_TYPE_u64: - val->u64 = strtoull(str, &endptr, 0); + val->u32 = strtoull(str, &endptr, 0); break; case PARAM_TYPE_i16: + val->i16 = strtoll(str, &endptr, 0); + break; case PARAM_TYPE_i32: - case PARAM_TYPE_i64: - val->i64 = strtoll(str, &endptr, 0); + val->i32 = strtoll(str, &endptr, 0); break; case PARAM_TYPE_f32: diff --git a/main/webpage.h b/main/webpage.h index d452250..2656036 100644 --- a/main/webpage.h +++ b/main/webpage.h @@ -1,3 +1,3 @@ -const char html_content[] = {0x1f,0x8b,0x08,0x00,0xc7,0x88,0x54,0x69,0x02,0xff,0xbd,0x1a,0xfd,0x77,0xda,0x46,0xf2,0xf7,0xfc,0x15,0x1b,0x27,0xe7,0x4a,0x89,0x10,0x60,0x3b,0x69,0x22,0x2c,0xdc,0xc4,0x71,0x9a,0xf6,0x12,0xdb,0xcf,0x1f,0xbd,0x77,0xe7,0xf2,0xac,0x45,0x5a,0x40,0xb5,0xd0,0x52,0x69,0x31,0xe6,0x88,0xfe,0xf7,0x9b,0xd9,0x5d,0x7d,0x00,0x32,0xce,0xa5,0x77,0x8e,0x5f,0x40,0x5a,0xcd,0xce,0xcc,0xce,0xf7,0x8c,0xd8,0x7f,0x1a,0x70,0x5f,0xcc,0x27,0x8c,0x8c,0xc4,0x38,0xea,0xee,0x8b,0x50,0x44,0xac,0x7b,0xc8,0x63,0x91,0xf0,0x88,0x9c,0xd2,0x98,0x45,0xfb,0x4d,0xb5,0xb8,0x3f,0x66,0x82,0x12,0x1f,0x1e,0xb1,0x58,0xb8,0x5b,0xb3,0x30,0x10,0x23,0x37,0x60,0xb7,0xa1,0xcf,0x1a,0xf2,0xc6,0x0a,0xe3,0x50,0x84,0x34,0x6a,0xa4,0x3e,0x8d,0x98,0xdb,0xb6,0x5b,0x5b,0x24,0xa6,0x63,0xe6,0xde,0x86,0x6c,0x36,0xe1,0x89,0xe8,0xee,0xa7,0x62,0x0e,0x98,0x9e,0xcd,0x12,0x3a,0x99,0xb0,0x64,0x21,0xd8,0x9d,0x68,0xd0,0x28,0x1c,0xc6,0x8e,0x0f,0x48,0x59,0xd2,0xe9,0xf3,0xbb,0x46,0x1a,0xfe,0x3b,0x8c,0x87,0x4e,0x9f,0x27,0x01,0x4b,0x1a,0xb0,0x92,0x3d,0xd3,0x54,0x17,0x63,0x7a,0xa7,0x68,0x39,0xaf,0x5a,0xad,0xc9,0x5d,0x67,0x4c,0x93,0x61,0x18,0x3b,0x74,0x2a,0x78,0x67,0x42,0x83,0x00,0xf7,0xb5,0x48,0x1b,0x1e,0x65,0x7d,0x1e,0xcc,0x6b,0x08,0xe8,0x1d,0xad,0x12,0x3c,0x7b,0xb1,0xf0,0x79,0xc4,0x13,0xe7,0xd9,0xce,0x00,0xff,0x3a,0x7d,0xea,0xdf,0x0c,0x13,0x3e,0x8d,0x83,0x86,0x7e,0x30,0x18,0x0c,0x3a,0x03,0x60,0xa1,0x31,0xa0,0xe3,0x30,0x9a,0x3b,0xc7,0x5c,0x70,0x72,0x4e,0xe3,0xd4,0xfa,0x8d,0x25,0x01,0x8d,0xa9,0x95,0xc2,0x4d,0x23,0x65,0x49,0xa8,0x01,0xe1,0x0c,0xcc,0x69,0xdb,0x3b,0x09,0x1b,0x67,0x61,0x3c,0x99,0x0a,0xab,0x3f,0x15,0x82,0xc7,0x55,0x8e,0x92,0x70,0x38,0x12,0xf5,0x27,0xae,0xe1,0x81,0x0d,0x58,0xc0,0xde,0x76,0x14,0x8c,0xd3,0x9e,0xdc,0x91,0x94,0x47,0x61,0x40,0x9e,0xf5,0xe9,0xdb,0xd7,0xaf,0xfa,0xfa,0x41,0x23,0xa1,0x41,0x38,0x4d,0x9d,0x57,0x20,0x1c,0x25,0xa8,0x76,0xab,0xf5,0x37,0xc5,0xc2,0x15,0xea,0xd9,0x45,0x06,0x7a,0x56,0x65,0x21,0x9e,0x8e,0xfb,0x2c,0xe9,0x2d,0xaa,0x07,0x1c,0xf3,0x98,0xa7,0x13,0xea,0xb3,0x6c,0x9d,0x6d,0x25,0xc8,0xcc,0xf6,0x47,0x34,0x1e,0xb2,0xc0,0x02,0xe5,0x8c,0xc7,0xa1,0xb8,0xee,0x8b,0x78,0x51,0xca,0xeb,0x69,0x38,0x46,0x95,0xd3,0x58,0xd4,0x9c,0x65,0x87,0xee,0xbd,0xdd,0x0d,0x4a,0x90,0x6c,0x09,0xc7,0x34,0x49,0x01,0x68,0xc2,0x43,0x6d,0x11,0xf2,0xc0,0x31,0x8f,0x59,0xe5,0x44,0x5a,0x8f,0x0d,0xc1,0x27,0x0e,0xaa,0xbb,0x50,0xa7,0xbc,0x91,0x47,0x99,0x31,0x94,0xaf,0xf3,0x63,0xab,0x55,0x45,0x7f,0x15,0x84,0x29,0xed,0x47,0x2c,0xe8,0xe5,0xcc,0xbe,0x79,0xf3,0xa6,0xa3,0x69,0xc6,0x1c,0x0f,0x19,0xf1,0x19,0x0b,0x6a,0xb8,0xde,0xdb,0xdb,0xab,0xb0,0x2c,0x10,0xcb,0x42,0x4b,0x1d,0x20,0x22,0x3a,0x49,0x99,0x93,0x5f,0x74,0x2a,0x02,0x8b,0xd8,0x40,0x54,0x95,0x21,0x82,0x45,0xa1,0x69,0x10,0xee,0xb8,0xaa,0x4c,0xad,0xe5,0xfc,0x34,0x6f,0xc0,0x90,0xd3,0xe9,0x18,0x0e,0xbb,0x64,0xcb,0x12,0x63,0xc5,0x36,0xd7,0x79,0xfd,0x71,0x67,0xb7,0xc6,0x22,0x72,0xb4,0xf6,0x2e,0xd8,0xe5,0x9a,0x94,0x6c,0x7f,0x9c,0x73,0xa6,0xc4,0x5d,0xb5,0xe4,0x57,0x68,0xc9,0xcf,0xc6,0xe9,0xb0,0xc6,0x14,0x46,0xed,0x45,0x09,0xba,0xa3,0x40,0x7f,0x1a,0xb3,0x20,0xa4,0x24,0xf5,0x13,0xc6,0x62,0x42,0xe3,0x80,0x18,0x52,0x04,0xfb,0xee,0xee,0x2b,0x50,0x91,0xb9,0xa8,0xf1,0x69,0xa9,0xd8,0xd2,0x8d,0x81,0x63,0x25,0x65,0x22,0x12,0x22,0x85,0x56,0xe7,0x29,0x95,0xad,0xa0,0xda,0x49,0x44,0xe7,0x4e,0x3f,0xe2,0xfe,0x4d,0xb1,0x75,0xa1,0x4d,0x25,0x17,0x36,0x1a,0xc8,0x32,0x64,0xb6,0xdf,0x54,0x81,0x69,0xbf,0x39,0x62,0x34,0xe8,0xee,0x63,0xec,0xe8,0xee,0x07,0xe1,0x2d,0x09,0x03,0x57,0x07,0xab,0xe2,0x5e,0xf3,0xdd,0xdd,0x1f,0xb5,0xbb,0x87,0xd1,0xd4,0xbf,0x39,0x04,0xe3,0x82,0x03,0xc2,0xe6,0x36,0x04,0x50,0xa4,0x0a,0x5f,0x00,0x2f,0x10,0x93,0x74,0x1f,0xc2,0x63,0x3f,0x0a,0xfd,0x1b,0x77,0x2b,0x65,0x71,0xa0,0xe1,0x8d,0x1f,0x52,0x41,0x13,0xf1,0x83,0xb9,0x45,0xfc,0x88,0xa6,0xa9,0x0b,0xe2,0xef,0x9e,0x5f,0xbc,0x3b,0xbb,0xd8,0x6f,0xaa,0x6d,0xc0,0x0f,0xe2,0xf8,0x06,0x3c,0x7c,0xb2,0x84,0x86,0xc8,0xe3,0xb8,0x0f,0x59,0x08,0x50,0x3b,0x39,0xfd,0x6f,0x89,0x01,0x0a,0xbe,0xcc,0xf3,0xe5,0xf1,0x87,0x93,0x15,0x2c,0x4d,0x3c,0x7f,0x33,0x97,0x45,0x55,0x24,0x90,0x40,0x22,0x88,0x2c,0xb1,0xbb,0xdb,0xdd,0x97,0x41,0x08,0x45,0x0a,0x66,0x45,0x12,0x90,0x3c,0x8f,0xa3,0x79,0x15,0xc3,0x86,0x2d,0x61,0x7c,0x2d,0xc2,0x31,0x43,0x26,0x65,0x1c,0x72,0x41,0xcb,0x37,0x87,0x2a,0x24,0x19,0x62,0x14,0xa6,0x26,0x08,0x81,0x4d,0xdc,0x36,0x91,0x41,0x2e,0xa0,0x82,0x21,0x7c,0x03,0x14,0x4e,0xa3,0x2e,0xc9,0xcf,0x08,0x98,0x62,0x3e,0xc3,0xc0,0x50,0x1c,0x37,0x65,0xe2,0x02,0x20,0x2f,0xf8,0x31,0x9f,0x19,0x66,0xf7,0x7c,0x1e,0xfb,0x04,0x17,0xea,0x8e,0xa8,0xd5,0x7c,0xee,0x8f,0x58,0x30,0x05,0x6b,0x3b,0x47,0x8d,0x96,0x82,0x2c,0x0f,0xc8,0x6f,0xd9,0xb5,0x54,0x77,0xc9,0xb0,0xfa,0xca,0xb7,0x6a,0x9e,0x55,0x88,0x06,0x6a,0x9b,0xa8,0x1c,0xa1,0xb1,0xd5,0xd3,0x00,0x4d,0xfd,0x05,0x0a,0xcf,0xc8,0x17,0x40,0x92,0x36,0x3f,0xd0,0x79,0x0d,0x01,0x48,0x14,0xd7,0x48,0x24,0x25,0xe3,0x30,0x76,0x5b,0xdf,0x42,0x47,0xe5,0x96,0x1a,0x4a,0x67,0x6c,0x4c,0xc3,0xd8,0x26,0x1f,0x42,0x90,0x4a,0xec,0x33,0x62,0x0c,0x84,0x59,0x43,0x33,0x91,0x70,0xe0,0xf2,0xd7,0xe0,0xb2,0x62,0x93,0xb6,0x37,0xd3,0xc3,0x73,0x3d,0x48,0x2c,0x48,0x42,0x10,0xa1,0x24,0xf4,0xd7,0x4f,0xf8,0x2b,0x78,0x1c,0xf9,0x24,0xa3,0x2b,0x31,0xc2,0xb8,0x8e,0xde,0x1f,0x00,0xf2,0xbf,0x22,0xf7,0x9e,0x0a,0x08,0xc5,0x73,0x62,0xfc,0x56,0x47,0xe9,0x96,0x47,0x82,0x0e,0xd9,0x06,0x27,0xeb,0x9e,0x26,0x7c,0x98,0xd0,0x31,0x39,0xfb,0x48,0x40,0x39,0x5c,0xb0,0x7b,0xe3,0xc1,0x44,0x41,0x9e,0x7d,0x3c,0x67,0x7f,0x4e,0x19,0xc8,0x13,0xbc,0x24,0xdf,0xfd,0x2e,0x8a,0xc8,0x7b,0x09,0x9e,0x6e,0x0a,0x09,0x1a,0x63,0x9e,0x8b,0x55,0x58,0xcd,0x53,0x74,0x41,0x48,0x2d,0x9d,0x52,0x40,0x9c,0xa2,0x27,0x52,0xd0,0xa1,0x52,0x7a,0x05,0x79,0x3f,0x51,0xff,0x03,0xa8,0x4e,0xc3,0x28,0x85,0x1a,0x53,0xe5,0xcb,0xee,0x87,0x77,0xc7,0x3f,0x1f,0x9d,0x91,0x7f,0x9d,0x1c,0x1f,0x41,0x7c,0xd7,0x8b,0x64,0x25,0x40,0x1f,0x42,0x22,0xeb,0x27,0x54,0x84,0x3c,0xbe,0x3f,0xfe,0xf9,0x1a,0x88,0x19,0x3f,0xa0,0xca,0x20,0xfa,0x29,0xed,0x2e,0x6d,0xd6,0xfc,0x90,0x4d,0xbb,0xa5,0x81,0xe1,0xf6,0x0f,0x78,0x51,0xbb,0x7f,0x5d,0x31,0x1f,0xc3,0x64,0x3c,0xa3,0x09,0x5b,0x55,0x2b,0xf5,0x7d,0x36,0x11,0xae,0xdd,0x0f,0x65,0x18,0x1b,0x68,0xb0,0xeb,0x41,0x88,0x69,0x0f,0x8d,0x05,0xaf,0x96,0x42,0xdd,0x74,0x12,0x71,0x1a,0x2c,0xc9,0x58,0x2d,0xe5,0x34,0x40,0xca,0x97,0x72,0x81,0x94,0x54,0xef,0x65,0xec,0x33,0x1f,0x02,0x58,0xb4,0x6e,0x28,0x40,0x29,0xe2,0xc3,0x25,0x32,0x01,0x9f,0xc5,0x88,0x17,0xf6,0xe0,0x16,0xa0,0xf3,0x41,0xaf,0x10,0x58,0xda,0x60,0x2a,0x5a,0x61,0x88,0x53,0x6b,0xae,0x78,0xb0,0x31,0x4d,0x25,0xac,0xcf,0xb9,0xf8,0xae,0xac,0x78,0x76,0xf4,0xfe,0xe4,0xa4,0x9a,0x84,0x0b,0xd3,0x6a,0x42,0x09,0x90,0x7f,0x42,0x65,0x13,0x4e,0x44,0x37,0x62,0x82,0x4c,0xd0,0x42,0x7f,0xa3,0xd1,0x94,0xa5,0xee,0x55,0xcf,0x92,0xb7,0xc7,0xd0,0xf8,0x94,0x77,0x97,0xd0,0x19,0xe1,0x1d,0x14,0x6d,0x31,0xb8,0x3b,0xb8,0x38,0x9c,0xa7,0x0b,0xad,0xd7,0x74,0x0c,0xa5,0x84,0x3d,0x64,0xe2,0x28,0x62,0x78,0xf9,0x7e,0xfe,0x4b,0x60,0x84,0x81,0xd9,0xa1,0x29,0xe6,0x9d,0xc1,0x34,0xf6,0xd1,0x3c,0x48,0xf5,0x6c,0x70,0x14,0xc4,0x6e,0x2e,0xf4,0x85,0xeb,0xba,0x9e,0xcc,0x2d,0xde,0xf6,0xf6,0x53,0x20,0x80,0x96,0x60,0x78,0xff,0x08,0xc1,0x15,0xfb,0x0c,0x2a,0x1f,0x02,0x41,0x1b,0x22,0x28,0x69,0x90,0x49,0xc4,0x68,0xca,0x88,0x86,0xb1,0x3d,0xf3,0xeb,0xd7,0x0a,0x0e,0x25,0xb2,0x25,0x24,0x1f,0x64,0x7b,0x47,0x66,0x88,0x4b,0x3d,0x06,0x2c,0x3e,0x60,0x49,0x10,0xa1,0x8f,0xd5,0x93,0xac,0xed,0x02,0x1d,0x59,0x6d,0xf2,0x2e,0x61,0x64,0xce,0xa7,0x24,0x9d,0x26,0xec,0x00,0x09,0xd0,0x19,0x0d,0x05,0x19,0x30,0xe1,0x8f,0x0c,0xcf,0x6e,0x02,0x3d,0xcf,0x5a,0x40,0x2b,0x39,0xe2,0x81,0xe3,0x9d,0x9e,0x9c,0x5f,0x78,0x16,0x16,0x5d,0x2c,0x49,0x9d,0xc5,0xd6,0xa1,0xaa,0xad,0x1a,0x17,0x60,0xbe,0x5b,0x8e,0x07,0x85,0x17,0xa8,0x56,0x3a,0x48,0xf3,0x8f,0x94,0xc7,0x5e,0x66,0x61,0x69,0xe6,0xfc,0x7a,0x7e,0x72,0x6c,0xa7,0x02,0x99,0x08,0x07,0x73,0x03,0x05,0xe1,0xe8,0x83,0x64,0x26,0xfc,0xad,0x08,0xaf,0xf4,0x40,0x7a,0x07,0x91,0x74,0xf1,0x58,0x2c,0x79,0x40,0xf8,0xfa,0xf9,0x02,0x89,0x66,0x2a,0xfb,0x7b,0xc8,0x5e,0x07,0x6d,0x86,0x8e,0x05,0x06,0xd2,0xf1,0x44,0x18,0xde,0x69,0xc2,0xd2,0x94,0x14,0xe6,0x8c,0xfa,0x62,0x89,0x4d,0x96,0x96,0xe9,0x10,0xf2,0x20,0x81,0xb6,0x13,0x8b,0x3d,0x12,0x0a,0x9b,0x5c,0x8c,0x58,0x6c,0x49,0x47,0x27,0xf0,0x84,0xfa,0x62,0x4a,0x23,0x28,0x77,0x21,0x48,0x46,0x18,0x52,0x73,0x95,0x90,0x11,0x4b,0x24,0x44,0x08,0xd9,0x85,0xa5,0x8e,0x67,0x76,0xc2,0x81,0xf1,0x34,0x4c,0x8f,0xe9,0xb1,0x01,0xc6,0x99,0xb2,0x8f,0xe0,0x86,0xc2,0x00,0x86,0x4c,0xd3,0x5c,0x20,0x6f,0x40,0x77,0x02,0x76,0xca,0xdc,0x47,0x15,0x14,0x38,0x81,0x12,0x0f,0xb0,0x97,0x73,0x60,0xf3,0x1b,0xc5,0x12,0xd4,0x6f,0x54,0xb3,0x53,0x3c,0x43,0xac,0x06,0x78,0x0a,0x88,0x17,0xcd,0x57,0x06,0x57,0xef,0xc0,0xa8,0x96,0x06,0x43,0x66,0x78,0x50,0x29,0xbe,0xf6,0x4c,0xd3,0xbe,0x45,0x07,0xc5,0x42,0x90,0xda,0xac,0x09,0xa7,0xb5,0x6a,0x00,0x7f,0x5c,0x01,0x14,0x08,0xf8,0x02,0xfa,0x78,0xd3,0xa9,0x81,0x7e,0x53,0x07,0x9d,0x65,0x59,0x61,0x78,0xd5,0x3d,0x2c,0x32,0x17,0x09,0x13,0xd3,0x24,0x26,0x2c,0xb2,0x65,0x50,0xfa,0x0c,0x2a,0xb2,0xa1,0xdd,0x31,0x3c,0xdd,0x4b,0x7b,0xa6,0x85,0xa8,0xcb,0x54,0xe8,0x99,0x76,0x9e,0x23,0xdd,0xa7,0x6d,0x8b,0x45,0x25,0x6e,0xc1,0x3f,0x86,0x77,0x80,0x57,0x4d,0x17,0x62,0x25,0x26,0x28,0x0f,0xdc,0x8a,0x4e,0xe5,0x33,0xb3,0xa3,0xc9,0x2a,0x95,0x03,0x88,0x79,0x10,0x4f,0xa3,0xc8,0x39,0x96,0xb5,0x04,0x2e,0xd8,0x39,0xb2,0xd8,0x5c,0x73,0x1e,0xa9,0x7d,0xa8,0x6b,0xc5,0x14,0x72,0xf0,0x42,0x40,0x23,0xba,0xc9,0x44,0x52,0x09,0xa8,0x6d,0xac,0xaa,0x45,0xc5,0x43,0xe7,0x01,0x5d,0xc2,0x2e,0x8c,0x90,0x3c,0x62,0x36,0x64,0x10,0x03,0x21,0x4d,0x4b,0xc9,0x36,0xc4,0x88,0xa7,0xb7,0x33,0xd7,0x68,0xbe,0x20,0x3f,0x5d,0x5f,0x9f,0x5e,0x9e,0x1d,0x5d,0x5f,0x93,0x17,0x4d,0x12,0xb3,0x19,0xf9,0x80,0x2e,0x5e,0x40,0xbf,0x68,0xb3,0x5d,0xd0,0x8f,0xe0,0xbf,0x9c,0x9f,0x9c,0x4b,0x7b,0x33,0x4c,0x3b,0x05,0x9b,0x64,0x46,0xcb,0x6a,0xbf,0x35,0x3b,0x5a,0x8b,0x08,0xeb,0x55,0xf4,0xc8,0x32,0x7c,0xa0,0x2b,0xa6,0xe2,0x41,0x2e,0x21,0x89,0xbe,0xaf,0x8a,0x2d,0x6b,0x47,0xe9,0x6b,0xb9,0x48,0xad,0xdf,0xb2,0x0c,0x93,0xef,0x84,0xc6,0xc7,0x5b,0x32,0x21,0x58,0xb0,0xaa,0xe9,0x44,0x2e,0xca,0xe7,0xe9,0xd7,0xaf,0xcb,0xb9,0x45,0x3e,0xc2,0xf9,0x5a,0xe5,0x89,0xca,0x33,0xf2,0xc9,0x14,0x2f,0xe5,0x93,0x0d,0x26,0xd5,0x52,0xc2,0x4d,0x84,0x7f,0x0d,0x6d,0xcf,0xd7,0xaf,0xc6,0xb2,0x4c,0x56,0xac,0x94,0x25,0x09,0x4f,0xc0,0x46,0x8b,0xf4,0x70,0x28,0x13,0x40,0x0c,0x59,0x01,0x76,0xdb,0x44,0xb6,0x4a,0xb3,0x50,0x8c,0x08,0x56,0xac,0x44,0xcd,0x06,0x7f,0x48,0x55,0x9e,0x80,0x64,0xb0,0xbd,0x6d,0x2c,0x37,0x57,0x96,0x62,0x0b,0x57,0x0c,0x08,0x3e,0x19,0x84,0x0b,0x30,0x23,0xcc,0x6c,0xda,0x08,0x24,0x45,0xc3,0x3b,0xc2,0x2f,0x4c,0xb3,0x29,0xa6,0x1d,0x8c,0x20,0x9e,0xc5,0xcc,0x2c,0x81,0xa4,0xc8,0x92,0x0b,0x3c,0x8b,0x61,0x66,0x95,0x5c,0x09,0xdb,0x83,0xf4,0x82,0x7f,0xfa,0xf4,0xe5,0x8b,0xa1,0xef,0x72,0xe7,0xf3,0x9e,0x2f,0xb4,0x31,0x7c,0xa1,0x62,0x64,0x0f,0x22,0x0e,0x04,0x34,0x4c,0x73,0xf7,0x75,0xab,0x05,0x26,0x33,0xa1,0x81,0x6c,0xe4,0x8c,0x1d,0xcb,0x6b,0x79,0x66,0xe6,0x6c,0xd8,0xf3,0x37,0xdc,0xd3,0x7c,0x5d,0xb7,0xcd,0x2b,0x59,0x5a,0xe2,0x54,0x5a,0xb1,0x2c,0x62,0x5c,0x14,0xb7,0xbc,0x02,0x8f,0x19,0x00,0xd2,0x8e,0xbc,0xb1,0x13,0x3e,0x4b,0xed,0x88,0xc5,0x43,0x31,0xea,0xb6,0x3a,0xa6,0x5a,0x0c,0x18,0xec,0x63,0x67,0x20,0xb7,0x96,0xd9,0x29,0xed,0xc0,0x86,0x7d,0x47,0x14,0xc4,0x66,0xa0,0x2d,0x58,0xa1,0xe9,0x76,0x95,0x87,0xf2,0x99,0xaa,0x98,0xec,0x10,0x1c,0x2c,0x11,0xb8,0x71,0x0d,0xbb,0x69,0x4d,0xe4,0x84,0xb6,0x44,0x77,0x15,0xf6,0x9e,0xba,0xd0,0x2f,0x84,0x01,0x69,0x6d,0x6f,0xaf,0xae,0x63,0xdc,0x38,0x58,0x5a,0x74,0x3c,0x5c,0xf3,0xac,0x09,0x18,0xa9,0x5b,0xb1,0xdc,0x1a,0x3c,0xd5,0x07,0x25,0xa2,0x62,0x55,0x63,0xea,0x00,0x7b,0xc0,0x72,0xcc,0x92,0x4f,0x17,0x5f,0x3e,0xbb,0xde,0x13,0x52,0xf3,0x0f,0xab,0xcd,0xe7,0x8b,0x30,0x93,0xf5,0xe2,0x06,0x08,0x79,0xba,0x07,0xa0,0x74,0x39,0x2d,0x2b,0xe6,0xad,0xe7,0x0b,0xfc,0xe6,0x03,0x22,0xcf,0xe3,0x7a,0xaa,0xdf,0xf2,0x0e,0xf2,0x0b,0xc7,0xc3,0xf1,0x97,0x97,0x6d,0x61,0x41,0xba,0x05,0x9e,0x82,0x5c,0x6c,0x11,0xe5,0xc1,0xb0,0x1b,0xb7,0xc1,0x3d,0x8f,0x25,0x52,0x77,0x6b,0xad,0x4f,0xdd,0xea,0x3e,0xc8,0x73,0xe1,0xc8,0x20,0x94,0xaf,0x5f,0x3d,0xef,0x1e,0xfe,0x21,0x59,0x4a,0x9b,0x41,0x65,0xab,0x23,0x00,0xdb,0x35,0x25,0x65,0xfa,0x7e,0x7e,0x41,0x87,0xa8,0x2f,0x74,0x6d,0x80,0x83,0xac,0x25,0xbf,0xd1,0xa9,0x8f,0x6e,0x01,0x02,0x3d,0x9c,0x81,0xc0,0x21,0x4c,0x60,0x25,0x0d,0xbe,0x05,0x36,0xc4,0x6c,0xb0,0x65,0xc0,0x62,0xa7,0x60,0x77,0xbe,0x30,0x30,0x33,0xa3,0xb9,0x16,0x53,0x80,0x22,0x70,0x55,0xd5,0xd8,0x56,0xe1,0xa6,0x9c,0x77,0x14,0x50,0xcb,0x5e,0x59,0xdd,0xb3,0xd3,0x33,0xcb,0x4d,0xe0,0x28,0xdf,0xb0,0x65,0x57,0x6f,0x29,0x3b,0xf6,0x5a,0x6e,0xf6,0x14,0x37,0x45,0x9f,0x5d,0x0b,0xf4,0xaa,0x57,0xfa,0xe9,0x4a,0xe3,0x0d,0x91,0x08,0x32,0xd2,0x52,0x16,0x37,0x2d,0x70,0xa8,0xc0,0x55,0xa6,0xa1,0x05,0x01,0x71,0x4d,0xc7,0xcd,0x76,0x41,0x81,0xa9,0xef,0xba,0x22,0x03,0x80,0xcc,0x12,0x4d,0x55,0x54,0xe8,0xb8,0x57,0x23,0x3e,0x4d,0x52,0x6b,0x1c,0xc6,0x53,0xc1,0xd2,0x5e,0x8e,0xc8,0x4e,0xa1,0x9c,0x82,0x5a,0x11,0xea,0x37,0x7b,0x4c,0x27,0x86,0x4a,0xde,0x45,0x12,0xdb,0x29,0x08,0xcb,0xed,0x2f,0x30,0x2a,0xbd,0xd4,0x38,0x5e,0xbc,0x6e,0xd5,0xb1,0x01,0x5b,0xcc,0x0c,0x8e,0xb7,0xc4,0x88,0x14,0xff,0xf7,0xb3,0xb1,0xfb,0xdf,0xb3,0xb1,0x8b,0x6c,0xe4,0x3c,0x54,0xf4,0x59,0x0a,0x75,0xef,0x5b,0x84,0xba,0xb7,0x24,0xd4,0x52,0xe3,0x25,0x9a,0x57,0xdf,0x82,0xe6,0x15,0xa2,0xa9,0xa6,0x92,0x6a,0xba,0x92,0x71,0x55,0x05,0xed,0x22,0x47,0x76,0xd6,0xac,0x43,0xd1,0xb8,0xbf,0x40,0x91,0x35,0xc9,0x67,0x1c,0x43,0x32,0x9d,0x55,0xbc,0xf4,0xb6,0x71,0x7e,0xe4,0xad,0xf7,0x2d,0x95,0xec,0x28,0x75,0x82,0xd5,0xc9,0x29,0x58,0x8a,0x85,0xb4,0xf1,0xa2,0xe7,0xd6,0x14,0x31,0xb9,0x8e,0x2e,0x20,0x55,0x5f,0xcd,0xa1,0x57,0xb3,0xc6,0x50,0x9a,0x8f,0x20,0xd5,0xcf,0x7b,0x6e,0x8e,0x22,0x07,0x6a,0x2c,0x2b,0xd2,0x92,0x7a,0xd7,0x6a,0xb7,0x94,0x03,0xba,0xad,0x9e,0x9b,0x13,0xbc,0x47,0xff,0x16,0x9b,0x70,0x7f,0xe4,0x56,0xd2,0x23,0x1e,0xd5,0xbe,0xbc,0x38,0x34,0x4a,0x06,0x1a,0x6d,0x64,0xc1,0x5a,0x27,0x60,0x36,0xb1,0x54,0xeb,0x18,0x6b,0xb5,0xe4,0x5f,0xef,0x36,0x24,0x5f,0x20,0xef,0xbc,0x00,0xcc,0x40,0xfa,0xfc,0x66,0x7b,0xfb,0xbe,0x3a,0x07,0xca,0x34,0x70,0x83,0x6a,0x41,0x5e,0x44,0xd4,0x3f,0xa7,0x50,0xf2,0x9d,0xcb,0x60,0xc8,0x93,0x77,0x51,0xa4,0xa3,0xa9,0x5d,0x80,0xea,0x9c,0x0a,0xf6,0xd7,0x3a,0xd8,0x54,0x73,0x39,0x9b,0x6a,0xfc,0x7a,0x1b,0xc8,0x67,0x60,0x8b,0x4d,0x78,0x65,0x71,0xad,0xb9,0xf9,0x05,0x59,0x83,0x4a,0xf0,0x9b,0x99,0xb7,0xd2,0x89,0xbb,0xc8,0xd6,0x13,0xca,0x12,0x3e,0x13,0xc2,0x85,0xda,0xa7,0xdc,0xac,0x90,0xa0,0xd2,0x5c,0xd5,0x5e,0x3b,0x2c,0x4a,0xa1,0xed,0x5c,0x86,0x5f,0x2d,0x94,0xa5,0x43,0xdd,0x55,0x3b,0x96,0xfb,0xcb,0xe9,0x75,0xfb,0xf8,0xff,0xb5,0xa3,0x2b,0x1c,0x58,0xd0,0xd6,0x39,0x77,0xd9,0x92,0xf1,0xac,0x31,0xb9,0xc1,0x86,0xb2,0x55,0x59,0xd8,0x32,0xde,0xa7,0xff,0x80,0x52,0x59,0x9a,0xa1,0xa7,0x1b,0x6f,0xf9,0x5e,0x23,0x07,0x51,0x8e,0x06,0xcf,0x20,0xa9,0x76,0xd2,0xc9,0x55,0x18,0xf4,0xf4,0x53,0x15,0xbd,0xd4,0xb5,0x2c,0x5b,0xca,0x42,0x05,0x4b,0xec,0x35,0x50,0x19,0x6f,0x66,0x2c,0x39,0xa4,0x29,0x68,0x46,0x41,0x43,0xa5,0xa5,0xba,0xc0,0xd5,0x76,0x51,0x4b,0xdb,0xcc,0x4e,0xfa,0x7f,0x80,0xb5,0xd8,0x37,0x6c,0x9e,0x02,0xce,0xdc,0xba,0xa1,0x76,0x83,0x7a,0xce,0x58,0xf3,0xd5,0xc9,0xff,0x5c,0x15,0x40,0x53,0x09,0xfc,0x60,0xc9,0x06,0x8b,0x7a,0x57,0x55,0x58,0xdd,0x45,0x2e,0xb1,0xa7,0x15,0x83,0xdc,0xde,0xd6,0xe6,0xbd,0x41,0x29,0xe6,0x46,0x3f,0x34,0xad,0xca,0x09,0xf3,0xf6,0x77,0xd5,0x39,0x57,0x87,0xa7,0x52,0x89,0x38,0x75,0x95,0xac,0xca,0xd8,0xbc,0x34,0x96,0xd5,0x7d,0x71,0x01,0x61,0xe3,0x55,0x51,0x8b,0x2f,0x20,0x23,0x40,0xf7,0xe0,0x1d,0x73,0x89,0x83,0xa8,0xc2,0x0b,0x79,0xd5,0x1d,0x7c,0x96,0xa3,0x77,0x57,0x30,0x5c,0xb5,0x7a,0x9d,0x87,0x3a,0x73,0x2e,0xe8,0xf7,0xa9,0x88,0x03,0x0f,0xa2,0x01,0x7a,0x61,0x74,0x9c,0xab,0x0a,0xa9,0x66,0xc8,0x56,0xd1,0xe0,0x1f,0x68,0xe6,0xf5,0xf8,0x38,0x9d,0xfa,0x3e,0x4b,0xd3,0xc1,0x34,0xb2,0x89,0x1e,0x22,0x8e,0xe9,0x5c,0xcf,0x10,0x6d,0xcf,0x74,0x96,0xc1,0x07,0x14,0x10,0x06,0x0e,0xf1,0x5e,0x16,0x28,0xd5,0x24,0x41,0xf7,0x84,0x85,0x68,0x98,0x98,0xf1,0xe4,0x86,0xc8,0xbe,0x90,0x04,0x53,0x39,0x86,0x54,0x5a,0x00,0x8d,0x96,0x79,0xbb,0x78,0x45,0x61,0x84,0xe6,0xe2,0x31,0x02,0xc6,0x00,0xec,0x1f,0x4d,0x2b,0x66,0x91,0x13,0xd6,0xcd,0x20,0x6b,0x5e,0x9a,0x48,0x75,0xa9,0xf1,0x9e,0x9e,0x16,0x7b,0x1f,0x79,0x02,0xc6,0x02,0x5c,0x7a,0x67,0xec,0x16,0xd8,0x62,0x70,0x75,0x09,0xa8,0x3d,0x9c,0x96,0x7b,0x3d,0x0b,0x27,0xaf,0x31,0x0b,0x0e,0x79,0x80,0xe0,0xe8,0xbf,0xd6,0xf2,0x47,0x4f,0x1a,0x58,0xd1,0xa0,0x5f,0x60,0x1f,0x2e,0xa7,0xb7,0x9a,0x3e,0xa1,0x70,0xbd,0x87,0x2f,0x79,0x12,0xf9,0x92,0x47,0xd3,0x4f,0x71,0x40,0x98,0x6a,0xce,0xec,0x27,0x4f,0xd4,0xe8,0xf1,0xe4,0xef,0x38,0x70,0x94,0x33,0x64,0x0b,0x5a,0x7a,0x16,0x93,0x01,0xc7,0x5f,0x47,0xe0,0x35,0x51,0xc3,0xcb,0x14,0x74,0x99,0xcf,0x76,0x1e,0x2f,0x3c,0x0f,0xae,0xe5,0x0c,0xfa,0x5a,0xb0,0xf1,0x44,0xce,0x0c,0xad,0xc7,0xa4,0xad,0xa3,0x84,0x1a,0x56,0x16,0x09,0xd3,0x6d,0x75,0xc2,0xfd,0xbd,0x4e,0xf8,0xf2,0xa5,0xb9,0xa8,0x9a,0x9f,0x66,0x0d,0xcb,0xbf,0x53,0x10,0x59,0x08,0x21,0x18,0x84,0xcb,0xa3,0x5b,0x68,0xb2,0x74,0x79,0xc9,0xa7,0x22,0x5f,0xb3,0xda,0x38,0x81,0xb0,0xb4,0xb9,0xab,0x37,0x69,0x04,0x7a,0xcc,0x97,0xed,0xac,0xb9,0xe7,0xc0,0x55,0xc5,0x5e,0xa0,0x3d,0xcc,0x7e,0x8f,0x7f,0x8f,0x95,0xb2,0x50,0x27,0x6b,0x8f,0x2b,0x43,0xe5,0x39,0x94,0x5d,0xb9,0xd2,0x63,0x68,0xb1,0xcb,0x9d,0xa0,0xe6,0x19,0x2a,0x37,0xe0,0x31,0x23,0x06,0xf8,0xd5,0x1f,0xd3,0x54,0x80,0x7e,0x4b,0x13,0x00,0x61,0xdf,0x32,0x32,0x8d,0xf5,0xb9,0xc6,0x2c,0x30,0x41,0xef,0x56,0x79,0xcc,0x46,0xdb,0xd4,0x01,0xa8,0xb4,0x4f,0xa0,0xef,0xaa,0x34,0x61,0x3c,0xa6,0x76,0xf4,0x04,0x52,0x65,0x6b,0x35,0x56,0x84,0xe4,0xac,0x19,0x7a,0x60,0xc2,0x04,0x7d,0x9f,0x7f,0x83,0x21,0x05,0xfc,0x43,0xe1,0x71,0x70,0xd0,0x64,0xad,0x1e,0xab,0xd1,0xce,0x56,0x97,0x5c,0x58,0xdc,0xde,0x7e,0xd4,0x83,0x32,0xa1,0x1c,0x00,0x2a,0x81,0x80,0xdd,0x39,0xa1,0x85,0xa7,0x74,0x80,0x37,0x0c,0x3f,0xb5,0x76,0x59,0x54,0x76,0x79,0xdb,0xf0,0x7c,0xf1,0xf6,0x65,0x98,0x61,0x5a,0xc2,0x55,0xc8,0xeb,0x95,0x12,0xc0,0x5d,0x39,0xe2,0x52,0xbb,0xa4,0x26,0xcb,0xa6,0xcc,0x48,0x2b,0x95,0x63,0x85,0x20,0x94,0x22,0x80,0xbf,0xb7,0x8a,0x09,0x63,0xd4,0x63,0x16,0x10,0x90,0x02,0xbe,0x4b,0x1a,0x0f,0xd7,0x10,0xdf,0xd5,0x1c,0xe8,0x96,0xf4,0xbe,0x32,0x1e,0x52,0xc7,0x23,0x5a,0x11,0x8b,0xcb,0x58,0x26,0x95,0xa9,0x5e,0x94,0xbb,0x5e,0xf1,0x3b,0x00,0xa2,0xdf,0xed,0x8f,0xd1,0x31,0x0e,0x21,0xe8,0xe3,0x18,0xf2,0xe9,0x93,0x27,0x5e,0xad,0xca,0xeb,0xfc,0xe2,0x40,0x23,0x7d,0xe9,0x7a,0x6b,0x11,0xca,0x21,0xc7,0x5c,0x90,0x32,0xb0,0xfc,0x1e,0x7b,0xce,0x46,0xf0,0xe7,0xab,0x41,0x06,0x62,0xa0,0xd7,0x51,0x01,0x53,0x6f,0xfc,0xa6,0xda,0x6d,0xed,0x8d,0xf4,0x83,0xef,0x36,0x22,0x3e,0xac,0x79,0xb1,0x21,0x46,0x09,0x64,0xc4,0x23,0x15,0x46,0xf2,0xfa,0x24,0x07,0x20,0x33,0x9a,0xca,0xf9,0x38,0xbf,0xf1,0x94,0x7c,0xfb,0x11,0xef,0xaf,0xbe,0xfc,0xc0,0x35,0xc3,0xb4,0x20,0x2a,0xbb,0xf7,0x4d,0x0d,0x2c,0x90,0xf5,0x18,0xdf,0x3a,0x04,0x78,0xe7,0x96,0x53,0x6c,0x0c,0xe5,0x43,0x26,0xf2,0xc9,0xc2,0xea,0x0c,0xfa,0xf9,0xe2,0xca,0xfb,0xf5,0xdd,0x31,0x54,0x10,0x1f,0x8f,0xde,0xc3,0xe7,0x97,0x77,0x67,0xf0,0xf9,0xee,0xf4,0x4c,0x5e,0xff,0x13,0x3e,0x7f,0xbd,0x3c,0x96,0x9f,0x9f,0x71,0xfd,0xf2,0x67,0xf8,0x3c,0x3f,0x3a,0x85,0xcf,0x93,0x43,0x30,0x33,0xef,0xf8,0xe4,0x37,0xac,0x3e,0x8e,0x0e,0xbd,0xde,0x95,0x26,0xf5,0x05,0x7b,0x79,0xc3,0xec,0x01,0x6e,0xbd,0xf2,0x11,0x0a,0x8f,0x7f,0x82,0x52,0x40,0xc8,0x8d,0x55,0xc6,0x3e,0xe1,0x1c,0xa8,0x9e,0xb3,0x65,0xc0,0x2f,0x6a,0x4a,0x54,0x07,0xea,0x59,0xd3,0x24,0x72,0x2f,0xcf,0x3e,0xdb,0x3e,0x14,0xa1,0x82,0xa9,0xce,0x04,0xee,0x0d,0x94,0x1c,0x68,0xbb,0xec,0x73,0x15,0x80,0x9e,0x7c,0x1a,0x1e,0x05,0xa9,0x53,0x7b,0x94,0xb0,0x81,0x0b,0x28,0x2c,0x6a,0xe7,0x5a,0xc7,0x37,0xe6,0x3c,0xa1,0x43,0x06,0x0c,0x2f,0x89,0x36,0xc3,0xdf,0x53,0x78,0x65,0xd7,0x8f,0xce,0x63,0xe3,0x0f,0x00,0xe3,0xe0,0x70,0x14,0x46,0x81,0x41,0x81,0x9e,0x2d,0xe7,0xa4,0x86,0xb9,0x02,0xa6,0xe2,0x43,0x01,0x86,0x0c,0x27,0xec,0x96,0xdf,0x54,0x18,0x06,0x2e,0x8a,0xd7,0x1c,0x68,0x32,0x6b,0x89,0xa8,0xf8,0x59,0x84,0x2e,0x89,0x21,0xff,0x48,0xb8,0x2c,0x9b,0x41,0x98,0x07,0x51,0x71,0xc5,0x7f,0xc5,0xb6,0x3b,0xfb,0x4d,0xfd,0x63,0x84,0xfd,0xa6,0xfa,0xe5,0x62,0x53,0xfe,0x98,0xfb,0x3f,0xe8,0x8e,0xf2,0xea,0xdc,0x2d,0x00,0x00}; +const char html_content[] = {0x1f,0x8b,0x08,0x00,0x98,0xec,0x59,0x69,0x02,0xff,0xed,0x3c,0xfb,0x57,0xdb,0xc6,0xd2,0x3f,0xdf,0xfe,0x15,0x0b,0x49,0x88,0x94,0xc8,0xc2,0xe6,0x91,0xb6,0x36,0x72,0x2e,0x01,0xa7,0x4d,0x1b,0x1e,0x87,0x47,0xda,0xfb,0x71,0x39,0x48,0xb6,0xd6,0x58,0x8d,0x2c,0xa9,0x92,0x0c,0xa1,0xc2,0xff,0xfb,0x9d,0xd9,0x87,0xb4,0x92,0x65,0x63,0x92,0x9b,0xf4,0x7c,0xe7,0xfb,0x9a,0x53,0xb0,0x57,0xb3,0xb3,0xb3,0xf3,0x9e,0x9d,0x15,0x3b,0x2b,0x6e,0x38,0x48,0xef,0x22,0x4a,0x46,0xe9,0xd8,0xef,0xee,0xa4,0x5e,0xea,0xd3,0xee,0x5e,0x18,0xa4,0x71,0xe8,0x93,0x63,0x27,0xa0,0xfe,0xce,0x3a,0x1f,0xdc,0x19,0xd3,0xd4,0x21,0x03,0x78,0x44,0x83,0xd4,0x5a,0xbd,0xf5,0xdc,0x74,0x64,0xb9,0xf4,0xc6,0x1b,0xd0,0x06,0xfb,0x62,0x78,0x81,0x97,0x7a,0x8e,0xdf,0x48,0x06,0x8e,0x4f,0xad,0x96,0xd9,0x5c,0x25,0x81,0x33,0xa6,0xd6,0x8d,0x47,0x6f,0xa3,0x30,0x4e,0xbb,0x3b,0x49,0x7a,0x07,0x98,0x9e,0xdc,0xc6,0x4e,0x14,0xd1,0x38,0x4b,0xe9,0xa7,0xb4,0xe1,0xf8,0xde,0x75,0xd0,0x1e,0x00,0x52,0x1a,0x77,0xfa,0xe1,0xa7,0x46,0xe2,0xfd,0xe5,0x05,0xd7,0xed,0x7e,0x18,0xbb,0x34,0x6e,0xc0,0xc8,0xf4,0x89,0x58,0x35,0x1b,0x3b,0x9f,0xf8,0x5a,0xed,0xed,0x66,0x33,0xfa,0xd4,0x19,0x3b,0xf1,0xb5,0x17,0xb4,0x9d,0x49,0x1a,0x76,0x22,0xc7,0x75,0x71,0x5e,0x93,0xb4,0xe0,0xd1,0xb4,0x1f,0xba,0x77,0x35,0x0b,0x88,0x19,0xcd,0x02,0x7c,0xfa,0x22,0x1b,0x84,0x7e,0x18,0xb7,0x9f,0x6c,0x0c,0xf1,0x5f,0xa7,0xef,0x0c,0x3e,0x5e,0xc7,0xe1,0x24,0x70,0x1b,0xe2,0xc1,0x70,0x38,0xec,0x0c,0x81,0x84,0xc6,0xd0,0x19,0x7b,0xfe,0x5d,0xfb,0x30,0x4c,0x43,0x72,0xea,0x04,0x89,0xf1,0x81,0xc6,0xae,0x13,0x38,0x46,0x02,0x5f,0x1a,0x09,0x8d,0x3d,0x01,0x08,0x7b,0xa0,0xed,0x96,0xb9,0x11,0xd3,0xf1,0xd4,0x0b,0xa2,0x49,0x6a,0xf4,0x27,0x69,0x1a,0x06,0x2a,0x45,0xb1,0x77,0x3d,0x4a,0xeb,0x77,0x5c,0x43,0x03,0x1d,0x52,0x97,0xfe,0xd8,0xe1,0x30,0xed,0x56,0xf4,0x89,0x24,0xa1,0xef,0xb9,0xe4,0x49,0xdf,0xf9,0xf1,0xd5,0x76,0x5f,0x3c,0x68,0xc4,0x8e,0xeb,0x4d,0x92,0xf6,0x36,0x30,0x87,0x33,0xaa,0xd5,0x6c,0x3e,0xe3,0x24,0x5c,0xa0,0x9c,0x2d,0x24,0xe0,0xd2,0x50,0x06,0x82,0xc9,0xb8,0x4f,0xe3,0xcb,0x4c,0xdd,0xe0,0x38,0x0c,0xc2,0x24,0x72,0x06,0x54,0xcc,0x8c,0xa9,0xe3,0x86,0x81,0x7f,0x77,0x99,0xd5,0x10,0xb6,0x85,0xff,0xa6,0xb3,0xfb,0xe3,0x1c,0x9f,0x9a,0x83,0x91,0x13,0x5c,0x53,0xd7,0x00,0x29,0x8e,0xc7,0x5e,0x7a,0xd5,0x4f,0x83,0xac,0x60,0xec,0x8a,0x37,0x46,0xdd,0x70,0x82,0xb4,0x66,0xd3,0x1b,0xce,0xd6,0x8f,0x9b,0x6e,0x01,0x02,0x9a,0xe0,0x04,0x03,0xea,0x3f,0x06,0xc7,0xf7,0x1b,0x9b,0x25,0x04,0x39,0x11,0x46,0x09,0xd9,0x24,0x4e,0x00,0x3a,0x0a,0x3d,0xa1,0x87,0x8c,0xcd,0x41,0x18,0x50,0xc1,0xc7,0xad,0xed,0x67,0x42,0x79,0x1a,0x69,0x18,0xb5,0x51,0xc7,0x72,0x1d,0x62,0x5f,0x18,0xff,0x6e,0x29,0x0a,0xb5,0xfd,0x7d,0xb3,0xa9,0xae,0x74,0xe1,0x7a,0x89,0xd3,0xf7,0xa9,0x7b,0xa9,0xae,0x59,0x8c,0xca,0xad,0xfc,0xf0,0xc3,0x0f,0x1d,0x41,0x48,0x10,0x22,0x1b,0xfd,0xf0,0x96,0xba,0x35,0x7b,0xda,0xda,0xda,0x52,0xf6,0x94,0x22,0x96,0x4c,0x28,0x00,0x40,0xf8,0x4e,0x94,0xd0,0xb6,0xfc,0xd0,0x51,0x44,0xe2,0xd3,0x61,0xaa,0xea,0x45,0xea,0x66,0xb9,0xd2,0x81,0xf8,0xc6,0xaa,0x5e,0x09,0x85,0x93,0x7b,0xfc,0x01,0x6c,0x2a,0x99,0x8c,0x81,0x05,0x25,0xb3,0x62,0x18,0x15,0x33,0xa9,0xe5,0x7f,0x8d,0x72,0x4a,0xb4,0xe6,0x26,0x98,0xc8,0x0c,0xef,0xcc,0xc1,0x58,0x52,0xc6,0x65,0xa0,0x1a,0xd5,0x36,0x1a,0xd5,0x93,0x71,0x72,0x5d,0xa3,0x6c,0xa3,0x56,0x56,0x80,0x6e,0x08,0xd0,0x28,0x8c,0x26,0x51,0x23,0xbc,0xa1,0xb1,0xef,0xdc,0x65,0x7f,0x35,0xbc,0xc0,0xa5,0x9f,0x90,0x01,0xcd,0x1a,0x72,0x9b,0xec,0xbf,0xfe,0x66,0xe7,0x8f,0x49,0x92,0x7a,0xc3,0xbb,0x86,0xf0,0x3d,0xd2,0x81,0xb0,0xe5,0x1a,0x5e,0x4a,0xc7,0x89,0x1c,0x2a,0x18,0xda,0x19,0xf1,0x3d,0xb0,0xcf,0x20,0xde,0x08,0x16,0xe4,0x1b,0x88,0xc2,0x04,0x9c,0x63,0x18,0xb4,0x87,0xde,0x27,0x10,0x29,0xaa,0x50,0xb3,0x83,0xcc,0x03,0x07,0x24,0x08,0x94,0x4e,0x4e,0xe1,0x66,0x8d,0x83,0x9c,0x63,0x23,0x15,0x16,0xb7,0xb8,0x77,0x94,0xde,0x72,0xab,0xa9,0xaa,0xeb,0x26,0x7e,0x61,0x7e,0x67,0x04,0x66,0x7d,0x0b,0x1e,0x73,0x0b,0xc4,0xfe,0x0a,0xfe,0x17,0xbb,0xdf,0x72,0x2b,0x34,0x91,0xd1,0x46,0xb6,0x50,0xc8,0x82,0x08,0xc5,0x40,0xaa,0xdb,0x22,0xd1,0x52,0x18,0x54,0x41,0xb7,0x50,0x7a,0xff,0x1c,0x53,0xd7,0x73,0x48,0x32,0x88,0x29,0x0d,0x88,0x13,0xb8,0x44,0x63,0x7b,0xda,0xb1,0x36,0xb7,0x61,0x1f,0x7a,0x56,0x13,0x1c,0x18,0xfb,0x8b,0x78,0x00,0xfa,0xc6,0x6d,0x84,0xa4,0x31,0x61,0x2a,0x5f,0xe7,0x72,0x95,0xa9,0x52,0x72,0x7d,0x3f,0x1c,0x7c,0xcc,0xa7,0x66,0x62,0x77,0xd2,0x54,0x90,0x8b,0x65,0x48,0xb9,0x65,0xee,0x0b,0x93,0x6c,0xfe,0x2e,0x7d,0x0a,0xb4,0x42,0x14,0x6c,0xe3,0x8f,0x79,0xaa,0x76,0xed,0x44,0x52,0x90,0x39,0x5b,0x37,0xd4,0x55,0x11,0x4d,0x65,0x4d,0x22,0xfc,0x70,0x39,0xa4,0x55,0xbd,0xdb,0x7f,0x21,0xba,0x8c,0x81,0xa0,0x9c,0x65,0x15,0x5f,0x48,0x36,0x6a,0x1d,0x62,0x1d,0xa1,0xed,0x11,0xda,0xa5,0x51,0xfb,0xcc,0x8c,0x62,0x8f,0xf9,0x9b,0x85,0x8a,0xc3,0x29,0x9c,0x2e,0xc4,0xc0,0x57,0xa9,0x91,0xc7,0x0f,0xce,0xf7,0xcd,0xad,0x6d,0x39,0x99,0x05,0x3b,0x26,0x05,0xc7,0x0b,0x6a,0xe1,0x4b,0x7a,0xce,0x84,0x41,0x9a,0xa5,0xd9,0x15,0xc6,0x2f,0x63,0xc0,0x5f,0x12,0xd9,0x6b,0x42,0x90,0x6a,0x3c,0x66,0xf2,0x27,0x06,0x37,0x0e,0xbf,0xb9,0xfd,0xac,0xec,0x02,0xaa,0x02,0xda,0x59,0xe7,0xf9,0xd9,0xce,0xfa,0x08,0xe2,0x7d,0x77,0x07,0x53,0xa8,0xee,0x8e,0xeb,0xdd,0x10,0xcf,0xb5,0x44,0xce,0x96,0x7f,0x17,0xba,0xda,0xdd,0x19,0xb5,0xba,0x7b,0xfe,0x64,0xf0,0x71,0x0f,0xc2,0x1d,0x98,0x27,0x4c,0x6e,0x41,0x1e,0x89,0x36,0x03,0xbf,0x00,0x3e,0x45,0x4c,0x4c,0x1a,0x24,0x0c,0x06,0xbe,0x37,0xf8,0x68,0xad,0x26,0x34,0x70,0x05,0xbc,0xf6,0x3c,0x49,0x9d,0x38,0x7d,0xae,0xaf,0x92,0x81,0xef,0x24,0x89,0x05,0xae,0xbf,0x7b,0x7a,0xb6,0x7b,0x72,0xb6,0xb3,0xce,0xa7,0x01,0x3d,0x88,0x63,0x09,0x3c,0x61,0x54,0x42,0x43,0xd8,0x76,0xac,0x87,0xa2,0x13,0xac,0x76,0x74,0xfc,0xd8,0xc5,0x00,0x45,0x58,0xa6,0xf9,0xfc,0x70,0xff,0xa8,0x82,0x65,0x1d,0xf7,0xbf,0x2e,0x79,0xa1,0xb2,0x04,0xf2,0x68,0x1f,0x12,0xac,0xc0,0xda,0xec,0xee,0x30,0xbd,0x41,0x96,0x42,0x48,0x23,0x32,0xd3,0x52,0x31,0x2c,0x98,0x72,0xfe,0xfb,0xd5,0xd9,0xbb,0x83,0x1e,0x12,0xc9,0xb2,0x2c,0x0b,0x34,0xf3,0xe3,0x1e,0x4f,0xb8,0xb4,0x74,0xe4,0x25,0x3a,0x30,0x81,0x46,0x56,0x8b,0xb0,0x5c,0xcf,0x75,0x52,0x9a,0x7a,0x63,0xda,0x00,0x77,0xe5,0xf8,0x5d,0x22,0xf7,0x08,0x98,0x82,0xf0,0x16,0x93,0x92,0x7c,0xbb,0x09,0x4d,0xcf,0x00,0xf2,0x2c,0x3c,0x0c,0x6f,0x35,0xbd,0x7b,0x7a,0x17,0x0c,0x08,0x0e,0xd4,0x6d,0x51,0x88,0xf9,0x74,0x30,0xa2,0xee,0x04,0x7c,0xe5,0x29,0x4a,0xb4,0x60,0xa4,0x4a,0xed,0xc1,0xd1,0x87,0xde,0x15,0x13,0x6f,0x41,0x33,0xff,0x25,0x67,0x0b,0xb2,0x79,0xb2,0x0a,0x0b,0x2e,0x5a,0xa8,0x87,0xfa,0x36,0x77,0x99,0xde,0xe1,0xfe,0x17,0x2c,0xf2,0x84,0x1c,0x80,0xd3,0x48,0xd6,0xf7,0x9d,0xbb,0xfa,0x35,0x0e,0xcf,0x0f,0xd8,0x3a,0xa7,0x04,0x7c,0xa1,0xd5,0x5c,0x66,0x29,0x9e,0x6b,0xd7,0x2c,0x76,0x08,0x7e,0x82,0xad,0x47,0x76,0xe7,0x30,0xee,0xb0,0xf7,0xfb,0xd9,0xd5,0xee,0xfb,0xdd,0x93,0x83,0x5c,0x47,0x6a,0x65,0x3a,0x8b,0xfb,0x84,0x8e,0xc1,0x9d,0x99,0x64,0xdf,0x03,0x4b,0x83,0xe4,0x93,0x68,0xc3,0x54,0xaf,0x5f,0xe4,0xa4,0x77,0x70,0xb5,0xff,0xee,0x54,0x91,0x0d,0xfc,0x74,0x7d,0xca,0x51,0x80,0xe3,0x40,0x1c,0x5c,0xbd,0x96,0xda,0x16,0xdb,0xd1,0x12,0xeb,0xee,0x9f,0xbc,0x03,0x79,0xb1,0x95,0xbf,0x9c,0x97,0xbf,0x80,0x91,0x93,0x9f,0x99,0x5b,0x23,0x9a,0x17,0xcc,0x59,0xf2,0x97,0xdd,0xbd,0x5f,0xff,0x5b,0x2b,0xbe,0x71,0x52,0x70,0xed,0x77,0x44,0xfb,0x50,0xb7,0xd8,0x4d,0xe8,0xa7,0xce,0x35,0x5d,0x60,0xda,0xdd,0xe3,0x38,0xbc,0x8e,0x9d,0x31,0x39,0x79,0x4b,0x80,0xd5,0x61,0x4a,0xe7,0x7a,0xa1,0x88,0x43,0x9e,0xbc,0x3d,0xa5,0x7f,0x4e,0x28,0x70,0x15,0x6c,0x53,0xce,0xde,0xf5,0x7d,0xf2,0x86,0xc7,0xbf,0x45,0x8e,0x48,0x60,0x94,0xd5,0x07,0x73,0xe6,0x79,0x51,0x92,0x2f,0x84,0xda,0x84,0x09,0xab,0x19,0x53,0x3f,0x74,0x5c,0x4d,0xef,0x74,0x41,0x90,0x03,0x27,0x76,0x0b,0xdc,0x75,0x98,0xf2,0xa2,0x27,0xc7,0xc4,0x87,0x8e,0x1d,0x20,0x31,0x41,0x4f,0xe2,0x80,0x4e,0x70,0x1d,0x52,0xc8,0xec,0xc7,0xfc,0x7f,0x97,0x42,0xec,0xf5,0x93,0xee,0x8e,0xa8,0x35,0xba,0xa0,0x92,0x47,0x67,0x3d,0xb2,0x77,0x74,0x78,0x76,0x72,0xf4,0x1e,0x42,0x94,0x18,0x27,0x08,0x4e,0x0a,0xf6,0x8c,0xc3,0x49,0x42,0x21,0x9b,0x0d,0xc0,0x51,0xa3,0xfb,0xe1,0x7c,0xd4,0x9e,0x0f,0x6f,0xdd,0xe7,0x06,0xa1,0x37,0x10,0xab,0xc0,0x5d,0x43,0xd0,0x0a,0x27,0x83,0x11,0x83,0x58,0x08,0xc8,0xfd,0x3a,0x0b,0x9f,0x12,0xb9,0x4f,0x81,0x72,0x0b,0xa3,0x8c,0x98,0xa2,0xcb,0x27,0x93,0xa8,0x3a,0xcc,0x56,0x81,0x78,0x51,0x1a,0xef,0xbe,0xfd,0x6d,0x3f,0xdf,0xf1,0x12,0xa4,0xc7,0xf4,0x66,0x39,0xd2,0xcb,0x80,0x5f,0x85,0xf4,0x93,0xde,0x87,0xc7,0x90,0x3e,0x89,0x96,0xa3,0xbc,0x04,0xf7,0x55,0x08,0x3f,0x3f,0x7e,0x0c,0xdd,0x38,0xb4,0x1c,0xe5,0x15,0xc8,0xaf,0x42,0xfb,0xfe,0xd1,0x6f,0x87,0x8f,0xa1,0xde,0x99,0x7c,0x5a,0x8e,0xf8,0x32,0xe0,0x57,0xa1,0x7d,0xf7,0xfc,0x77,0xc5,0x09,0xe5,0x66,0x5d,0x6b,0xe3,0xfb,0xbb,0x87,0x3f,0xf5,0x4e,0xc8,0xff,0x1c,0x1d,0xf6,0x54,0x03,0x2f,0x27,0x91,0x7b,0x90,0x46,0xf7,0x63,0xe6,0x93,0xe6,0xe7,0x68,0x03,0x01,0x04,0x7b,0xfc,0x03,0xc2,0x00,0x64,0x68,0x3c,0x1c,0x94,0x26,0xcf,0x32,0x74,0x76,0xb6,0x1b,0x7b,0x37,0x14,0xa7,0xef,0xe3,0x87,0xda,0xf9,0xb3,0x6e,0xfc,0xad,0x17,0x8f,0x6f,0x9d,0x98,0x56,0x83,0x80,0x33,0x18,0xd0,0x28,0xb5,0xcc,0xbe,0xc7,0x52,0xad,0xa1,0x00,0xbb,0x1a,0x7a,0x90,0xc3,0xf0,0x24,0x55,0x3d,0x2c,0xe0,0xd1,0x06,0x1f,0x76,0x89,0x9a,0xa2,0x4d,0x22,0xf4,0xc4,0x25,0xdf,0xca,0x87,0xe4,0xba,0xa8,0xee,0x6c,0x80,0x14,0x94,0xcc,0x25,0xf6,0x7d,0x78,0x0d,0x60,0xfe,0x6c,0xa8,0x81,0x95,0xfc,0xf0,0xba,0xb4,0x0c,0xea,0x1a,0xe2,0x85,0x39,0x38,0x05,0x55,0x53,0x8c,0x10,0x18,0x5a,0x10,0x6c,0x84,0x10,0x11,0xa7,0x90,0x66,0xfe,0x60,0x61,0x7a,0x1d,0xd3,0x7e,0x18,0xa6,0x9f,0x95,0xcd,0x9f,0xf4,0xde,0x1c,0x1d,0x9d,0x2d,0x90,0x72,0xb9,0x68,0xf0,0x29,0x7d,0x7c,0xd5,0xb0,0xb1,0xf9,0x7d,0xf7,0xf4,0x7d,0xaf,0x77,0x5c,0xa7,0xe2,0xeb,0x50,0x21,0xc9,0x9f,0xa2,0x58,0x2a,0x9d,0x40,0x55,0x46,0x8b,0x42,0x6a,0xa3,0x18,0x14,0x47,0xee,0xeb,0xa3,0x8d,0xee,0x4e,0x54,0x0c,0x8f,0x69,0x92,0x40,0x2a,0x01,0x0f,0xa2,0x0a,0x96,0x4a,0xe9,0x5a,0xa3,0x55,0x4a,0x46,0xa2,0x4c,0xa9,0x25,0x54,0x14,0xd1,0xe5,0xad,0xf0,0x9f,0xc9,0x20,0xf6,0xa2,0xb4,0xeb,0xd3,0x94,0x40,0xe2,0xe9,0x58,0xd9,0xd4,0x88,0x30,0xb2,0x9f,0xa1,0x54,0xf7,0x20,0xc5,0x49,0xa9,0x6b,0xad,0xb4,0x8c,0x28,0xf4,0xfd,0x77,0x58,0xf0,0xde,0x38,0x3e,0x24,0x4e,0xbe,0x6f,0x8c,0x43,0xd7,0xf1,0x4f,0x28,0xd4,0xb6,0x37,0x94,0x8d,0x74,0x80,0xda,0x24,0x25,0x90,0x72,0xc1,0xc2,0x5d,0x37,0x1c,0x4c,0xc6,0xc0,0x07,0xf3,0x9a,0xa6,0x3d,0x9f,0xe2,0xc7,0x37,0x77,0xef,0x5c,0xcd,0x73,0xf5,0xce,0x70,0x12,0x0c,0xd0,0xf4,0x48,0x32,0x0a,0x6f,0x0f,0x10,0x8f,0xc6,0x18,0x64,0x08,0x7e,0x88,0xc3,0xf5,0xc4,0xba,0xb8,0x34,0xc2,0x08,0x21,0x13,0x20,0x4c,0xcf,0x90,0x4a,0xc1,0x74,0x6b,0x1e,0x7e,0xbb,0x24,0x1b,0x5b,0x37,0x18,0xe6,0x9e,0xff,0xd0,0x04,0x06,0x06,0xe0,0x82,0x84,0x87,0x27,0x08,0x40,0x98,0x22,0xa8,0x7d,0x78,0x8a,0x00,0x84,0x29,0x4c,0x56,0x7b,0x52,0xba,0x0f,0xcd,0xab,0x28,0x83,0x9c,0xff,0xf0,0x82,0x0c,0xcc,0xd6,0x3b,0x82,0x07,0x26,0x1e,0x5f,0xec,0x89,0x8e,0x4f,0x89,0xe3,0xf0,0xcc,0x0b,0x00,0xf5,0xcf,0x67,0x07,0xef,0x2d,0x29,0x05,0xc1,0x7a,0x13,0xa5,0xf4,0x0e,0x31,0xbd,0xd6,0xca,0x74,0x9b,0x4c,0x2b,0x4d,0xa1,0x95,0x96,0xcd,0x4e,0xcd,0x6c,0x49,0x9c,0xc9,0xdc,0x9e,0x44,0xc2,0x06,0xcf,0x60,0xe4,0xfe,0xde,0x46,0x32,0x0a,0x30,0xd0,0xa8,0x49,0x05,0xee,0x03,0x0e,0x01,0x60,0x01,0x04,0x0b,0x0c,0xe8,0x28,0xf4,0x5d,0xe0,0x56,0x09,0xf4,0xb8,0x78,0xc0,0x26,0x88,0x3a,0x37,0x9c,0xa4,0x9a,0xa6,0x5b,0x5d,0x39,0x7f,0x08,0x8c,0x82,0x6c,0xd5,0x68,0x35,0x9b,0xba,0xde,0x5e,0xbc,0x0d,0xb4,0x2e,0xbb,0x90,0xaa,0xc2,0x19,0x3b,0x1f,0x06,0x84,0x71,0xcf,0x19,0x8c,0x34,0x70,0xab,0x56,0x97,0x69,0x26,0x7f,0x52,0x88,0x64,0xc0,0xac,0x47,0x48,0x45,0xb3,0xf9,0x63,0x10,0x86,0x38,0xca,0x52,0x65,0x01,0x48,0xd8,0x77,0x03,0x3f,0x88,0x33,0xae,0xb5,0x35,0x01,0xc8,0x3c,0xd9,0x7b,0x28,0xba,0x4c,0xc7,0x45,0xc9,0xf2,0xc7,0xb9,0xde,0x99,0xd2,0x11,0xe2,0x76,0x19,0x21,0x31,0x4d,0x26,0x7e,0x6a,0xcd,0x8a,0x2f,0x13,0x67,0x74,0xb8,0x0a,0xe3,0x3a,0x67,0x6f,0xbb,0x24,0x89,0x69,0xf1,0xb8,0xa3,0xda,0xf8,0xda,0x9a,0xa5,0xa9,0xdf,0x35,0xbe,0x8c,0x6e,0xa0,0xed,0xeb,0xc6,0xc8,0x73,0x29,0x37,0x65,0x9d,0xed,0x02,0x62,0xaf,0x8f,0x8e,0x16,0xb6,0xa1,0x7c,0x93,0x93,0xa6,0x0a,0x7b,0xf1,0x1c,0x0a,0x3c,0xf8,0xc8,0xf3,0x5d,0x8d,0x8f,0xea,0x53,0xdd,0x10,0x06,0x5c,0x95,0x0d,0x1e,0x91,0xda,0xd3,0xdc,0x81,0x28,0xab,0x7e,0x96,0x77,0xe8,0xcc,0x59,0x86,0xab,0xc0,0xc2,0xed,0xaf,0xb4,0xc4,0xd6,0x0b,0x6a,0xd8,0x73,0x90,0x29,0x26,0x04,0x9a,0xb4,0x22,0x66,0x67,0x96,0x2d,0x86,0x6d,0x3d,0x8b,0x69,0x3a,0x89,0x03,0x12,0xd0,0x5b,0x02,0x95,0xde,0xd8,0x4b,0x18,0x2b,0x99,0x1b,0xed,0x66,0x25,0xaf,0x2a,0x86,0x8d,0x79,0x6e,0xf2,0x82,0x75,0x4c,0xda,0xf6,0x1e,0x2b,0xf7,0x6c,0x83,0x09,0xad,0xbd,0xd2,0x9a,0x1a,0xe2,0xc1,0xd1,0xaf,0xf9,0x60,0xd3,0x90,0x67,0xa7,0x2b,0xcd,0xe9,0x25,0x70,0xb8,0x42,0xf6,0xae,0x4f,0xe3,0xb4,0x4a,0xf4,0x61,0x98,0x7a,0x03,0xfa,0x55,0x68,0x5e,0x8e,0x34,0xc4,0x72,0xc2,0x72,0x07,0x29,0xe5,0x02,0xaf,0xbd,0xcf,0x9a,0xd5,0x84,0x3f,0xf7,0x82,0x6b,0xdb,0xb0,0x8f,0xb1,0x30,0xbf,0xf5,0xa0,0x70,0x8e,0xe9,0x10,0x48,0x19,0x11,0x48,0xd1,0x76,0xf0,0x98,0x0d,0xa3,0xe1,0xaa,0x8c,0xd0,0x93,0x20,0xc5,0x14,0x68,0xb5,0xbb,0x0d,0xf9,0x29,0x3c,0xec,0x92,0x84,0x82,0x7b,0x75,0x13,0xd3,0x34,0x6d,0xe3,0xe2,0x52,0xef,0xa0,0x32,0xe5,0x70,0xd6,0xb6,0x91,0x7f,0xce,0x83,0x20,0x38,0x1a,0xf9,0x99,0x79,0x9a,0x2c,0x07,0x69,0x34,0xca,0xd3,0x1f,0xf6,0xd3,0x39,0x28,0x68,0xa4,0x32,0x6d,0x6d,0x4d,0x53,0xbe,0x95,0x3c,0x46,0x3e,0xae,0x17,0xa4,0xed,0x58,0x4d,0x9c,0x01,0xb9,0x7e,0x9c,0x53,0x36,0x43,0xb7,0x6e,0xcc,0x9c,0x04,0x80,0x35,0xb6,0xe8,0x66,0x95,0xeb,0x67,0x7b,0x78,0x46,0x58,0xc3,0x76,0x74,0xaf,0x04,0x34,0x83,0x9c,0x52,0xf0,0xe2,0xf6,0xd9,0x88,0x12,0x7e,0x6d,0x00,0x72,0x2e,0xf0,0xff,0xa0,0x24,0xd4,0x4d,0x48,0x1a,0x92,0x3e,0x24,0xc3,0x80,0x62,0x14,0x87,0x81,0xf7,0x17,0x75,0x91,0xb3,0x42,0xf8,0xf9,0xe9,0x63,0xad,0x0e,0x18,0xd2,0x5b,0xb4,0x1d,0x9c,0xcf,0x98,0x5b,0x3e,0xbe,0x34,0x9c,0x5b,0xc7,0x43,0x0e,0xab,0x27,0x11,0x53,0xd4,0x1d,0x9e,0x83,0x40,0xaa,0x1c,0x50,0xf7,0x68,0xd8,0x3b,0x3a,0x83,0xe4,0xa5,0x9c,0x6f,0xc0,0x98,0xdc,0x94,0x02,0x76,0x7f,0xaf,0x95,0x26,0x35,0x15,0x05,0xb6,0x8f,0x20,0xcd,0x0a,0x87,0xe4,0x2c,0x86,0x22,0x0a,0xcc,0x4c,0x2a,0xde,0xc0,0x09,0x02,0x60,0xc3,0x18,0x0f,0xc5,0x80,0xcb,0x9e,0x0f,0x1f,0x63,0xec,0x2c,0x21,0x18,0x9e,0xa2,0xf0,0x63,0x32,0x2f,0x21,0xa2,0xf3,0xab,0x70,0x60,0xbe,0xfa,0xeb,0x53,0x54,0x1e,0x4f,0x88,0xeb,0x9d,0xcb,0x73,0xab,0x62,0x0b,0x4a,0xdd,0x37,0xe0,0x59,0xaf,0xc1,0x0b,0xbf,0x8c,0xfd,0x5a,0x5b,0x63,0xbf,0x20,0x8a,0xb0,0xdf,0xfb,0x74,0xe8,0x80,0xc3,0xd5,0x30,0x65,0x90,0x18,0xd7,0xd6,0xca,0x3a,0x52,0x3c,0xd1,0x0d,0x35,0x99,0x16,0xe8,0xd5,0xa9,0xb3,0x5a,0x5f,0x37,0x01,0xf4,0x69,0xbb,0xa9,0xea,0x93,0x52,0x48,0x66,0x2a,0x1d,0x96,0x36,0x9f,0x12,0xee,0x5b,0x99,0x06,0x90,0x02,0x93,0xba,0xda,0xd8,0x3d,0x74,0xc6,0x14,0x30,0x0e,0xb5,0x15,0xf9,0xcd,0xb2,0x2c,0x9b,0xb1,0xc8,0x5e,0x5b,0x5b,0xe1,0x5a,0x52,0xf2,0xca,0xf6,0x6f,0xe8,0x1c,0xfa,0xf4,0xda,0x43,0xbf,0x77,0x03,0x5e,0x83,0x34,0x48,0x04,0x44,0x24,0x14,0xef,0xc2,0x20,0x8c,0x69,0xeb,0x3a,0x4c,0x56,0x31,0xf2,0xf2,0x65,0x1e,0x4a,0xa1,0x0e,0xc2,0xed,0x20,0x24,0xe0,0x64,0x1b,0x43,0xf4,0xdc,0x28,0xb0,0xd1,0x29,0x35,0xc2,0x24,0xbb,0xa0,0x26,0x77,0xe1,0x84,0x24,0x93,0x98,0xbe,0x9e,0x5d,0x8e,0x15,0x31,0xcb,0xac,0xc6,0x00,0x67,0xd1,0xe9,0x69,0x7c,0x27,0x33,0x81,0x08,0x0c,0x82,0x5a,0x1c,0xd1,0x90,0xa6,0x90,0xb1,0xd8,0xe6,0x7a,0x14,0x26,0x60,0xba,0xd9,0x98,0xa6,0xa3,0xd0,0x6d,0xdb,0xc7,0x47,0xa7,0x67,0xb6,0x81,0x4d,0x22,0x1a,0x27,0xed,0x6c,0x55,0x38,0x99,0x06,0xa6,0x6b,0xab,0x6d,0x1b,0x02,0x34,0x24,0x18,0xcc,0x67,0xac,0xff,0x91,0x40,0x0e,0x03,0xd1,0x3b,0x74,0xef,0xda,0xbf,0x9c,0x1e,0x1d,0x42,0xe0,0xc4,0x5d,0x7a,0xc3,0x3b,0x2d,0x83,0x1d,0xb4,0xc5,0x2e,0xc0,0x87,0xeb,0x1d,0x94,0x8b,0xa4,0xc0,0x0c,0x3f,0xea,0x99,0xb2,0x1d,0x1e,0x6e,0x6c,0x21,0x4b,0xf2,0xfc,0x69,0x26,0x67,0x3e,0x27,0x43,0xa8,0xbb,0xa8,0xdb,0x26,0x4f,0xb3,0x7c,0x36,0x30,0x2e,0x9d,0x24,0xd3,0xd9,0xa1,0x33,0xb0,0xa6,0x29,0x78,0x4d,0x1e,0xa0,0xa6,0xb3,0x32,0x7b,0x3d,0x13,0x42,0xda,0x4a,0x8a,0xc8,0x38,0x72,0xca,0x30,0x19,0x1b,0x90,0x1a,0x4e,0x61,0x9b,0xc0,0x22,0x50,0x2a,0x74,0x24,0x21,0xa4,0x04,0x50,0x3a,0xc3,0x57,0x63,0x96,0xf4,0x43,0x9a,0xde,0x86,0xf1,0x47,0x42,0xe3,0x18,0x4a,0x48,0xa0,0x8c,0x9a,0x22,0xc6,0x01,0x3d,0xd3,0xaa,0xe2,0x16,0x47,0x11,0x98,0x15,0xf3,0x64,0x45,0x12,0xcb,0xf2,0x64,0xa0,0x18,0x4f,0x38,0xec,0xd7,0x36,0x80,0x5e,0xb1,0x8f,0x6d,0xf6,0x91,0x9d,0x5c,0xd8,0xc8,0xcc,0x3a,0x6d,0x38,0x1b,0x81,0x7b,0x61,0xba,0x90,0xaf,0x40,0x52,0xf0,0xc8,0x4f,0x33,0xc4,0x3a,0x35,0x09,0xca,0xd2,0x0b,0x26,0x4c,0x2f,0xfe,0xf7,0xa8,0x45,0x71,0x3c,0xf3,0x25,0xda,0x30,0x8b,0x98,0xb3,0x05,0xaf,0x30,0xc5,0xbb,0xa9,0xd6,0xd4,0xcd,0x34,0x3c,0xc7,0x36,0xe8,0x1e,0xd8,0xbf,0xa6,0xbf,0x64,0x0f,0x13,0xd8,0x15,0xd5,0x5a,0xfa,0x34,0x67,0x69,0xee,0x77,0xd1,0x85,0xeb,0xc6,0x52,0xfa,0xf3,0x68,0x85,0x51,0x7c,0x9c,0x1a,0xea,0x98,0xc0,0x82,0xf0,0xd6,0x5a,0x7f,0x41,0xfe,0x79,0x75,0x75,0x7c,0x7e,0xd2,0xbb,0xba,0x22,0x2f,0xd6,0x59,0x2e,0xb6,0x0f,0xe2,0xe6,0x39,0xbc,0x75,0x4d,0x35,0x5b,0x74,0x0f,0x81,0x01,0x6c,0x4c,0x54,0x56,0xb0,0x69,0x98,0x8f,0x99,0xc7,0x5b,0x70,0xa9,0xff,0x02,0xb7,0x04,0xb1,0xb2,0xf1,0x34,0x3b,0x65,0x22,0xd2,0xc4,0xb3,0x03,0x10,0xee,0x08,0x58,0xd0,0xd2,0xcd,0xc8,0x71,0x59,0xc7,0x4f,0xdb,0x30,0xec,0xa6,0x5d,0x03,0x8b,0xcb,0x42,0xda,0x30,0x03,0x78,0x56,0x05,0xfc,0x39,0x9c,0xc4,0x49,0x1d,0x64,0x7b,0x66,0x79,0xd0,0xd1,0x94,0x2e,0x07,0x7b,0xca,0x73,0xb5,0x3a,0x58,0xc8,0xd9,0x95,0x86,0x29,0xe3,0x82,0x9a,0xe8,0x2a,0xcf,0xa8,0x0f,0x01,0xd3,0xaf,0x16,0x57,0xe2,0x6e,0x1b,0x08,0x19,0xf9,0x59,0x34,0x3f,0x6c,0xdd,0x94,0x5d,0x11,0x3c,0x0d,0x61,0x0f,0xf3,0x1e,0x4b,0xf9,0xa1,0x52,0x9c,0xcc,0xed,0xb5,0x71,0xc2,0xb2,0x1a,0x5a,0x79,0xfe,0x92,0x88,0x6e,0x15,0x2b,0xdb,0x12,0xeb,0xc2,0x2e,0xda,0xac,0x90,0x7e,0xc8,0x66,0x28,0x7c,0xcc,0x7b,0x96,0x98,0x95,0xe4,0x4d,0x37,0xf8,0x92,0xb7,0xc3,0xec,0xcb,0x22,0x77,0xa8,0xb4,0xc2,0x26,0x9f,0xae,0x04,0x21,0x60,0x92,0xec,0xd4,0xe7,0xaa,0xd0,0xa5,0xe3,0xdd,0x93,0xdd,0x83,0xab,0xa7,0x99,0x04,0x32,0x3d,0xd7,0x4c,0x26,0x7d,0x6e,0xd7,0x1a,0x64,0x8b,0x78,0x56,0xa2,0xd0,0x9f,0x23,0x2b,0x8d,0x2a,0x58,0x75,0x23,0x47,0x25,0x1d,0x1e,0xb6,0x39,0x6d,0xa6,0xe1,0x17,0x23,0xd4,0x14,0x63,0xcc,0xb5,0xe0,0xd2,0xca,0x41,0x99,0x0a,0x9b,0x50,0x95,0x79,0x60,0x41,0x6d,0xe0,0xf4,0xd8,0x89,0xb4,0x43,0xd6,0xb8,0xd3,0x3b,0x0a,0x76,0xa1,0xeb,0x1a,0xc3,0xf3,0xe2,0x55,0xf3,0xa5,0x40,0xa5,0xc3,0xe7,0x29,0xf5,0x21,0xba,0xcf,0x02,0xc3,0x48,0x42,0xdf,0x42,0x0e,0x9c,0x6a,0xe5,0xf5,0xf4,0xfb,0xfb,0x66,0x21,0xc6,0x49,0x84,0x2d,0xd9,0xd3,0x92,0x48,0xc0,0x2e,0x87,0x61,0xac,0xb1,0x4c,0xcd,0x6a,0x76,0xbc,0x9d,0xb2,0xc4,0x4c,0x9f,0x06,0xd7,0xe9,0xa8,0xe3,0xbd,0x7c,0xa9,0x03,0x6f,0x25,0x76,0x69,0xa4,0x4f,0xb3,0x32,0xf8,0x85,0x77,0x89,0xec,0x9c,0x27,0x82,0x5a,0xe0,0x15,0x6d,0x45,0xa2,0xbd,0xbf,0x5f,0x51,0xf9,0x8c,0xc9,0x44,0xbe,0x9f,0x42,0xbf,0xc5,0xf1,0x51,0xa2,0x28,0xf9,0xfd,0x7d,0x5e,0x97,0x38,0xb0,0xd7,0x1b,0x79,0x58,0x01,0xb2,0xc9,0xc5,0xa9,0xd2,0x5f,0x23,0x38,0xc2,0x18,0x6e,0x1d,0x38,0xe9,0xc8,0x1c,0xfa,0x21,0xf0,0x64,0x86,0xcf,0xeb,0x9b,0xaf,0xc0,0x33,0x4a,0xd9,0x2e,0x04,0x7d,0x86,0xa0,0xeb,0xaf,0x9a,0x7a,0xa7,0x2c,0x10,0xf4,0x61,0xc2,0x07,0xb0,0xf5,0x16,0x39,0x09,0x29,0xf8,0x59,0xdf,0xc0,0xf5,0xa0,0x82,0x79,0x86,0x86,0x99,0xc8,0x5d,0x2a,0x32,0x78,0xe0,0xe6,0x0c,0x14,0xd6,0x99,0xf3,0xf0,0xcf,0x09,0x8d,0xef,0x4e,0xa9,0x4f,0x07,0x69,0x18,0xef,0xfa,0x50,0x38,0x08,0x19,0x48,0x7e,0x63,0xe8,0x2b,0xcd,0x15,0x7a,0x02,0x2c,0x6d,0xea,0x3c,0x66,0xb1,0xca,0x31,0x72,0xee,0xb0,0x32,0xb3,0xb2,0x69,0x27,0xd7,0x32,0x76,0xd6,0x0b,0x45,0x48,0x69,0x3e,0x27,0x07,0x2a,0x5b,0x69,0xa2,0xb8,0x02,0x7c,0x05,0x11,0xe5,0xb1,0x80,0x81,0xb8,0xa9,0x25,0xe3,0x85,0xa6,0x2a,0xba,0x71,0x07,0xe1,0xc0,0x72,0xd3,0x72,0x74,0x30,0xc6,0x18,0x0c,0xc4,0xb0,0x08,0x0c,0x86,0x8b,0xc7,0x2a,0x69,0xe1,0xfe,0x0d,0x2e,0x79,0x3e,0x24,0x1c,0x7d,0x2e,0x64,0x31,0x55,0x3a,0x75,0x43,0x94,0xd7,0x62,0x3c,0x77,0xe0,0x1d,0xb1,0x53,0x13,0x15,0x4a,0xd5,0x0c,0x5c,0xc2,0x3c,0x3f,0xdb,0xd3,0x90,0x3e,0x4e,0x0e,0x12,0x60,0x94,0xdc,0x84,0xc4,0xaa,0xaf,0xb3,0xf2,0x95,0x49,0x57,0xdd,0xbf,0xbc,0xfd,0x60,0xeb,0x72,0x99,0x58,0xfa,0xe2,0x2b,0xcc,0xc5,0x55,0x07,0x50,0xb1,0xfe,0x4e,0x81,0xcc,0x64,0x91,0x3f,0xf9,0xcd,0x03,0x2e,0x08,0x93,0x84,0x54,0x2a,0xe3,0x72,0x02,0xa5,0x60,0x29,0x5c,0xc9,0x39,0xbe,0xd2,0x79,0x69,0x67,0x29,0x48,0x3b,0x65,0x03,0xe2,0x57,0x0f,0x20,0xc5,0xd7,0x66,0x5c,0x51,0x85,0x12,0x74,0x0b,0x9c,0x78,0xb6,0x1a,0x85,0x02,0x29,0xb9,0xbf,0xe7,0xe7,0xf4,0xd5,0xf1,0x8b,0x9c,0xa0,0x4b,0x8b,0xeb,0xf2,0x34,0x65,0xd7,0xed,0x8a,0x54,0xd6,0x3e,0x85,0x0a,0x0a,0xcb,0x12,0x3c,0xed,0x6f,0xdb,0x12,0x09,0x3f,0xf0,0xf8,0xa6,0x79,0xa1,0x5c,0x79,0xb9,0x8c,0xf0,0x2d,0xcb,0x02,0xf1,0x54,0x21,0xc1,0xfb,0x06,0xdc,0x0a,0x92,0xcf,0xab,0x11,0x4a,0x16,0x28,0xcf,0x71,0xb9,0xdb,0xed,0x56,0xbd,0x26,0x68,0x0c,0x94,0xf7,0x8a,0xcf,0x5c,0x98,0x19,0x34,0x17,0x65,0x06,0xcd,0xaf,0x94,0x38,0x56,0xfc,0x95,0x82,0x19,0xdc,0xd5,0x43,0x29,0x3f,0x58,0xa3,0x5d,0x23,0x00,0xa9,0x32,0x6c,0x49,0x95,0xfb,0x6c,0x22,0xe1,0x7c,0x05,0xf5,0xa9,0x70,0x3a,0xe7,0x31,0xeb,0x25,0xf1,0xa5,0x72,0x10,0xd4,0x05,0x0d,0x8f,0xab,0x14,0x6d,0xfc,0x29,0x4c,0xa5,0x26,0xe2,0x2f,0xc8,0x11,0x58,0xb0,0x3d,0x7f,0xa7,0xd5,0x94,0x62,0x82,0x98,0x1e,0xfe,0xe2,0x84,0xa0,0x22,0xe7,0xb4,0x50,0x35,0x89,0x2e,0xf0,0x64,0x88,0xd8,0x8c,0xd3,0xc1,0x15,0xb0,0xff,0xfe,0x7e,0xf6,0x6c,0x8b,0xad,0x6c,0x8e,0x93,0xeb,0x15,0xcb,0xba,0x09,0x3d,0x97,0xe0,0x29,0x1a,0xca,0x11,0x86,0x40,0x80,0xdc,0x40,0x25,0x8c,0x80,0x16,0x77,0x80,0xaa,0x33,0xc4,0x70,0x79,0x96,0x18,0x84,0x52,0xe3,0x2d,0xde,0x15,0xd7,0x36,0x74,0x6e,0x6d,0xe8,0xf3,0xde,0xd5,0xe5,0xee,0x43,0x8d,0xcd,0xc3,0xe7,0xca,0x02,0x2b,0x39,0xfc,0xe2,0xa0,0xbe,0xb6,0x56,0x1f,0xd4,0x01,0x55,0x8e,0x21,0x0f,0x0a,0xf3,0x8a,0x8a,0x82,0x82,0x17,0xe8,0x5b,0x3b,0xc5,0xda,0x79,0x3c,0xe6,0xae,0x1c,0x7c,0x74,0x6d,0x55,0x91,0x3f,0x5d,0xaa,0xae,0xc8,0xa1,0x1f,0xae,0x2c,0x72,0xd0,0x25,0x6a,0x8b,0x82,0x88,0x65,0xaa,0x8b,0x1c,0x7a,0x51,0x7d,0x31,0x95,0x92,0x3b,0x9a,0xa4,0x8a,0xe8,0x8a,0xdb,0x7c,0x8a,0x00,0x03,0xf0,0x3b,0x57,0x8e,0xef,0xc4,0xe3,0x5c,0x8c,0x4b,0x32,0xbe,0x98,0x59,0xb0,0x9f,0x2f,0xf8,0x7f,0x9e,0xff,0x8c,0x3f,0x45,0xc8,0x03,0xc3,0xe3,0xa6,0x7e,0x9c,0x77,0xad,0x35,0xe9,0x45,0xaa,0x29,0xbb,0x0c,0x72,0x4a,0x3d,0x56,0xb2,0xbf,0x22,0x5f,0xe8,0x70,0x9f,0x51,0xca,0x16,0x54,0x53,0x9c,0xc5,0xf1,0xd9,0x36,0x39,0x8b,0x0a,0xb6,0x54,0x83,0x5f,0x71,0x28,0x65,0xba,0x72,0xbf,0xd2,0xd2,0xf5,0xaa,0xff,0x53,0x99,0xc2,0x34,0x8f,0x5d,0xd6,0x60,0xfb,0x65,0x9f,0xf0,0x30,0x23,0xc4,0x63,0x0d,0x9e,0xde,0x5a,0x47,0xfd,0x3f,0x20,0x79,0x35,0x81,0xb2,0xd8,0x03,0x71,0x55,0x78,0xad,0x9b,0x08,0xac,0x69,0x8e,0xd1,0xd7,0xad,0xae,0x73,0xd1,0xbc,0x34,0xd9,0x1d,0x55,0xba,0x17,0x8e,0x23,0xbc,0xae,0xd2,0x87,0x21,0x9d,0xe9,0xff,0xcc,0x1d,0x02,0x5d,0x24,0xb2,0x17,0x1f,0xe9,0x1d,0xcf,0x8e,0x2e,0x21,0x99,0x55,0x17,0x17,0xb9,0xec,0x4c,0xf5,0x03,0x13,0xa6,0xdc,0xa8,0x78,0x41,0xb2,0xe2,0x7d,0x11,0xbf,0x3d,0xc1,0x62,0xb5,0x06,0xe0,0xc9,0x16,0xcb,0xf9,0xb2,0xda,0xdb,0x0f,0xb3,0xdc,0x94,0x81,0x8e,0x65,0x9d,0x19,0x63,0x66,0xa9,0x4f,0xdc,0x59,0x72,0xbf,0x71,0x78,0x6b,0xc9,0xd9,0x09,0x44,0xfb,0x13,0xd6,0xde,0x80,0xf4,0xc1,0x6f,0x59,0xf0,0x4c,0x8c,0xee,0xc1,0x77,0xad,0xc9,0xc7,0x37,0xaa,0xe3,0x2d,0xbd,0xc3,0xe0,0x4b,0xfd,0x21,0x58,0xb6,0x53,0xf0,0x73,0x5e,0x4f,0x5a,0xde,0x0f,0x50,0x92,0x53,0xfc,0x01,0x94,0x72,0xc6,0xe0,0x59,0x3a,0xda,0xa6,0xfd,0x9a,0xf7,0xec,0xdb,0x32,0x71,0x35,0x64,0xc1,0x61,0x95,0xe5,0x64,0xcc,0xb0,0x55,0x8c,0xe4,0xd7,0x71,0xa5,0x86,0x6a,0xe5,0xe3,0x0f,0x76,0x2d,0x77,0xca,0x37,0x58,0xea,0x08,0x8b,0x73,0x91,0x1a,0xb1,0x34,0x67,0x52,0x9f,0xea,0xed,0x29,0xc6,0x61,0xbc,0x77,0x55,0x98,0x79,0xe9,0xae,0x16,0xec,0x3c,0x7f,0x6a,0xb2,0x26,0x7a,0xde,0x5a,0xaa,0xef,0x74,0x16,0xd0,0xf9,0x7e,0xb0,0x09,0x22,0x00,0x34,0xcc,0x65,0xe5,0x92,0x56,0x01,0x8b,0x9f,0x12,0x30,0x0d,0xd4,0x61,0xfc,0xcc,0x3b,0x16,0xf8,0xc9,0xc4,0xf7,0x69,0xc1,0xdc,0x5c,0x51,0x5e,0xe0,0x8d,0x32,0x2c,0x2e,0x66,0x73,0xc0,0x63,0xde,0xa2,0x48,0x58,0x75,0x49,0x1c,0xc2,0xee,0x9e,0x89,0x3d,0x08,0x55,0x9c,0x73,0x42,0x2c,0x6e,0x90,0xc9,0x8d,0xb3,0x49,0x64,0xf5,0x69,0x96,0xaf,0x3f,0x5d,0x7d,0xfd,0xef,0xe0,0xdf,0x41,0x4d,0x17,0xc3,0x19,0x82,0xd9,0x0b,0xae,0x9a,0xca,0xf9,0xb1,0x13,0xc7,0xce,0xdd,0x9b,0xc9,0x70,0x48,0x63,0x99,0x4f,0x22,0x32,0x65,0x18,0x0c,0x44,0xe9,0x9f,0x71,0x12,0x30,0x59,0x93,0xb2,0xb1,0x0d,0x9b,0x5d,0x51,0xe2,0xd7,0x9a,0x56,0x67,0x6e,0x64,0x11,0xf9,0x66,0xce,0x6a,0xf7,0xbb,0x7f,0xfc,0x83,0x54,0xfe,0x5b,0x6e,0x2a,0x29,0xbf,0xdf,0xc5,0x5e,0x23,0x06,0x7c,0x05,0x31,0x2a,0x0f,0x4c,0xd3,0xe4,0x37,0xa2,0x3e,0x7f,0xb9,0xe2,0x6d,0x1d,0x82,0xef,0x09,0x8b,0x01,0xf1,0x3e,0x0e,0xe9,0x87,0x3e,0xec,0x86,0x75,0xa1,0x39,0x43,0x1b,0xec,0xea,0x37,0xe4,0xf1,0xab,0xdd,0xe6,0xb3,0xda,0xb5,0xf9,0x60,0xd1,0x8f,0xfe,0x34,0x8a,0x59,0x15,0xff,0xfb,0xc1,0xfb,0x9f,0xd3,0x34,0x3a,0xc1,0x1b,0xe3,0x49,0xda,0x81,0x61,0x53,0xc8,0xc8,0x71,0xdd,0x1e,0x76,0xfd,0xd0,0x2f,0x52,0x70,0x46,0x78,0x5b,0x84,0x2f,0x02,0xe9,0x31,0xe8,0x2f,0xa8,0x08,0x15,0x67,0x0e,0xe8,0xb3,0x27,0xcc,0xf3,0x88,0x5a,0x96,0xc6,0xf8,0x46,0x13,0x0e,0xc3,0x57,0x51,0x8c,0xb3,0x8d,0xe2,0x14,0x40,0x4e,0xdd,0x75,0xcc,0x61,0x53,0xc7,0x7f,0x81,0x97,0x68,0x0c,0x89,0x79,0x51,0x77,0xbb,0xb2,0x53,0xd0,0xd5,0x62,0x16,0xf8,0xe0,0xe2,0x4b,0xc9,0x77,0x55,0x48,0x79,0x69,0x3f,0xc3,0x32,0x87,0xf3,0x80,0x63,0x14,0x96,0x69,0xa9,0x56,0x2a,0xcd,0x14,0x6a,0x12,0x0c,0x62,0xd8,0x9b,0x44,0xce,0xcc,0xb2,0x04,0x11,0xd8,0x86,0x26,0x01,0x78,0xfd,0xd0,0xb5,0xa0,0x0a,0x5b,0x5b,0x2b,0x06,0x76,0x36,0x9b,0xcd,0xd7,0xb9,0x61,0xb7,0x39,0x52,0xad,0x9a,0xb6,0xf5,0x78,0x49,0x22,0x6d,0x2c,0x6f,0x55,0x14,0x78,0xa6,0xa5,0x6f,0xa2,0x14,0xc5,0x0b,0x2e,0xf5,0xc4,0xb1,0x1a,0x47,0x50,0xb7,0x78,0xcd,0x52,0x55,0x48,0xdc,0x09,0x6b,0x36,0x72,0xf6,0x2c,0x5a,0xc0,0xe9,0x43,0x0c,0x5a,0x6a,0x01,0xb1,0x29,0x5e,0xcd,0xfa,0x94,0x63,0x05,0x31,0x20,0xde,0x10,0x1c,0xb4,0x26,0x0e,0x02,0xa0,0x8a,0x04,0xad,0xb0,0xf9,0x82,0x50,0x63,0x09,0xbd,0xfc,0x99,0x9d,0x0f,0x60,0x8b,0xaf,0x38,0x1d,0x00,0x60,0xf5,0x74,0x20,0x1c,0xa4,0x14,0x4c,0x26,0x05,0x8f,0x3e,0xce,0xe7,0x83,0xc2,0x29,0x8e,0x44,0xfa,0xe3,0x92,0xdc,0xd5,0xde,0xbc,0xf4,0x28,0xe4,0x9c,0xc5,0x68,0x58,0x21,0x1f,0xe1,0x73,0xa0,0x6e,0x4d,0x26,0x83,0x01,0xa8,0xd9,0x10,0x12,0xe5,0xbb,0x15,0x22,0x1c,0x9d,0x97,0x08,0x37,0x07,0x7c,0x43,0xeb,0xef,0xc7,0xdd,0xff,0xbf,0x3d,0xf2,0x05,0xb7,0x47,0xf2,0x72,0x5d,0xbd,0x09,0x36,0x1b,0xc8,0x7a,0xf5,0x87,0x18,0x45,0xe6,0x9a,0xbf,0x11,0xa3,0x79,0x7a,0xf6,0x0d,0x5a,0x93,0x76,0x3c,0xbc,0xc2,0x4d,0x07,0xb6,0x81,0x21,0x3d,0xa0,0x7e,0xdb,0x43,0x3d,0xaf,0x26,0x17,0x35,0x6f,0xea,0x28,0xd7,0xfe,0xf0,0xd0,0x0d,0x1b,0x35,0x6f,0xc3,0x18,0x74,0x0f,0xfc,0x8b,0x7d,0x42,0x6f,0x80,0x36,0x54,0xc8,0xf3,0x08,0xbb,0x33,0x28,0x9f,0x4b,0x83,0xad,0x44,0xdd,0xbd,0xd0,0x45,0x70,0x76,0x91,0xb6,0xfc,0xe3,0xf2,0xe1,0x4e,0xaf,0xa0,0x04,0x6f,0x95,0x90,0x2d,0x7c,0xc7,0x28,0x66,0x77,0x2b,0x88,0x7c,0x57,0xd6,0xc3,0x1e,0x22,0xa7,0xd1,0xfc,0xee,0xbb,0x63,0xf4,0xb0,0xe4,0xe8,0x57,0x7e,0x23,0x07,0x02,0xa2,0x81,0x0d,0x62,0x48,0x1e,0x42,0xbc,0x94,0xc2,0x9a,0xc5,0x80,0x70,0x1c,0xa5,0x89,0xf9,0xb7,0xb6,0x88,0x51,0x0e,0x4c,0xfb,0xae,0x52,0x3a,0x8e,0xec,0xe9,0xa3,0x0f,0x06,0xd9,0x64,0x64,0x07,0xce,0xc7,0x3b,0x27,0x31,0x3b,0x8a,0x51,0xd2,0xa3,0xbf,0x67,0x53,0xe2,0x04,0x90,0xed,0xc8,0x58,0x7e,0x3b,0x62,0x1a,0x6e,0x68,0xc0,0xff,0x7e,0x4b,0x52,0x6c,0xa6,0xdc,0x7c,0xda,0x62,0x8d,0xa6,0xec,0x9b,0xee,0xaa,0xce,0x64,0x16,0xe5,0xce,0xca,0xd9,0xa7,0x0c,0xd4,0xec,0x2e,0x6e,0x8d,0x8b,0xe0,0xef,0xbc,0x81,0x8b,0xf0,0x5e,0xb6,0xa6,0xeb,0x5b,0xe8,0x2c,0x14,0x23,0xc3,0xfe,0x17,0xe6,0xab,0x5c,0xaf,0xf9,0x5d,0x87,0xca,0x63,0x92,0xbf,0x22,0x80,0xd7,0x62,0x62,0x69,0x1f,0xd8,0x3e,0x2e,0x66,0x82,0x45,0xdc,0xa2,0x1d,0xb8,0xf8,0x86,0x86,0x06,0x21,0x14,0xdf,0xda,0x07,0x53,0x28,0xac,0x85,0xbd,0x34,0x43,0x26,0x81,0xb0,0xb7,0x31,0x54,0xb1,0x26,0xde,0x31,0x14,0xe6,0xf7,0x46,0x5c,0xe8,0x35,0xfe,0x4e,0xbe,0x37,0x5a,0xcc,0x50,0xfe,0x5e,0xb3,0xe5,0xb9,0x4d,0xbd,0xc9,0xd6,0x1e,0xde,0x0e,0x46,0x74,0xf0,0x11,0xf3,0x15,0x50,0xee,0xb9,0x67,0xc9,0x25,0x5f,0x09,0x62,0xb5,0x78,0x57,0x26,0xcb,0xdf,0x55,0xa8,0x3d,0x5f,0xee,0x54,0x67,0xb1,0x43,0x8c,0x01,0x7e,0x7b,0x5d,0x7c,0x84,0x07,0x6d,0xa8,0x1f,0x17,0x1f,0x31,0xd7,0x52,0x49,0x6b,0xe8,0x9a,0x56,0x47,0x2c,0x8c,0xa5,0xdf,0x56,0x04,0x34,0xe5,0x7e,0xd3,0xe0,0x7f,0x0d,0xc5,0x33,0x70,0x9f,0xb0,0x47,0x76,0x9d,0xb6,0xce,0x5b,0xd4,0x9d,0xb6,0xfc,0xda,0xfb,0xd7,0xde,0xd1,0x7e,0x0f,0xaa,0x79,0x6f,0x2a,0x8f,0x05,0x2a,0x67,0x25,0x95,0xad,0xd6,0xdc,0xb7,0xe0,0x17,0x18,0x8b,0x63,0x23,0x2b,0x93,0x68,0x9b,0xed,0xd2,0xec,0xe6,0xa5,0x21,0x9f,0xb4,0xca,0x4f,0x5a,0xc5,0x93,0x8d,0xf2,0x93,0x8d,0xe2,0xc9,0x66,0xf9,0xc9,0xe6,0xe5,0xb4,0xf3,0xcd,0x7d,0x7c,0xb1,0x4b,0xe6,0xff,0x4a,0xce,0xfd,0x0b,0xb9,0xfe,0x60,0x27,0x6a,0xba,0x7c,0xe3,0x59,0xe9,0x33,0x8b,0x4e,0xc5,0x67,0x35,0xb0,0x44,0x8f,0xf5,0xc1,0xee,0x1c,0x0b,0x59,0xee,0x63,0xdb,0x73,0xdf,0xd4,0x5e,0x68,0x90,0xc7,0x64,0x96,0x6e,0x8b,0xb7,0x14,0x2d,0x3b,0x7f,0x65,0x9b,0x08,0x3f,0x3f,0x46,0x0f,0x20,0x6b,0xd1,0x95,0xef,0xbe,0xb3,0x3b,0x75,0x82,0xad,0xf1,0x00,0xaf,0x05,0xce,0x97,0x78,0x5a,0x5f,0x89,0x50,0x6d,0xd2,0xc0,0x17,0x9e,0xd7,0xbb,0x76,0x7b,0x21,0xd4,0xd3,0xac,0x82,0x78,0xca,0x67,0x75,0x66,0x64,0x20,0xd0,0x94,0xa2,0x91,0xec,0x02,0x2e,0x6a,0x2e,0xc2,0x7e,0x23,0x65,0xa3,0xcb,0xf5,0x18,0x67,0xde,0x1f,0x7c,0xb0,0xcf,0xe8,0x87,0xd7,0xf6,0x23,0xf3,0x39,0xb9,0x08,0x81,0xb9,0xec,0x80,0xe9,0xb3,0xba,0xbd,0x2c,0x45,0xf7,0xc3,0x7e,0x35,0x5a,0xe0,0x18,0x14,0x28,0x0b,0x6f,0xd6,0x81,0xa0,0xc7,0xf8,0xa7,0x00,0x5c,0xfc,0xa6,0xdc,0x41,0x79,0xe0,0x1a,0xdc,0xd3,0xec,0xc2,0xfe,0x65,0xf7,0x10,0x4b,0xd1,0xde,0x1b,0xbc,0xaf,0xb5,0x7b,0x02,0x3f,0x77,0x8f,0x4f,0xd8,0xe7,0x7f,0xe1,0xed,0xac,0xf3,0x43,0xf6,0xf3,0x3d,0x8e,0x9f,0xff,0x04,0x3f,0x4f,0x7b,0xc7,0xf0,0xf3,0x68,0x0f,0xeb,0xe9,0xc3,0xa3,0x0f,0x58,0x30,0xf4,0xf6,0xec,0xcb,0x8b,0xf2,0xed,0xbc,0xcb,0xe9,0x52,0x77,0xf9,0xe6,0xb6,0x66,0x1e,0x71,0xeb,0xce,0x36,0x26,0xb1,0x6f,0x9d,0x9f,0xbc,0x17,0x67,0xc6,0xbc,0x35,0x00,0xdf,0x35,0xe4,0x1c,0xa8,0xd9,0xdc,0x43,0x65,0x07,0x6d,0xd9,0x1c,0x41,0x09,0x6d,0x01,0x0a,0xc3,0x31,0xa5,0x20,0xf1,0x34,0x99,0x25,0xe5,0x40,0x70,0x89,0xb5,0x53,0x76,0xee,0x69,0xe4,0x08,0xd1,0x72,0x4b,0x87,0xc0,0x0e,0xac,0x97,0x1f,0xd0,0x96,0xc1,0xb8,0x5b,0xcc,0xc1,0x90,0xe0,0x98,0xde,0x84,0x1f,0x15,0x82,0x81,0x8a,0xdc,0x04,0x50,0xbd,0xeb,0xd4,0x8e,0x47,0x7c,0x49,0x29,0x5a,0x82,0xaa,0x75,0x6c,0xda,0x9c,0xdb,0x9a,0xc8,0xb4,0x63,0xa8,0xa5,0x90,0xad,0xa2,0x60,0x95,0x76,0x57,0x7e,0x6b,0x52,0x2d,0xf9,0xd5,0xf6,0xff,0x66,0xf9,0xdd,0x8b,0x34,0x8c,0x0a,0x74,0x2a,0x82,0xd9,0xeb,0xf2,0xea,0x53,0x79,0x61,0xbe,0x68,0x7c,0xcc,0x1c,0xfd,0xdc,0x78,0x89,0xd7,0xf7,0x7c,0x2f,0xbd,0xe3,0x81,0xc1,0x36,0x94,0xc3,0xf8,0x7c,0x1e,0x94,0xef,0x2e,0x0d,0x5e,0x97,0xe8,0x68,0x6b,0x9f,0xb9,0x2f,0x0c,0x8a,0xb7,0x90,0x91,0x80,0xba,0x85,0x5c,0x07,0x94,0x25,0xbf,0xe0,0x22,0x45,0x89,0xe9,0xd3,0xce,0xce,0xba,0x78,0x8f,0x75,0x67,0x9d,0xff,0x91,0xa3,0x75,0xf6,0xe7,0x2f,0xff,0x03,0xe7,0xd4,0x6d,0x45,0x0e,0x53,0x00,0x00}; -const unsigned int html_content_len = 3910; +const unsigned int html_content_len = 6013; diff --git a/main/webpage_brotli.h b/main/webpage_brotli.h index 51c399e..daaf06d 100644 --- a/main/webpage_brotli.h +++ b/main/webpage_brotli.h @@ -4,214 +4,330 @@ #include const unsigned char PROGMEM html_content_br[] = { - 0x1b, 0xdb, 0x2d, 0x00, 0x8c, 0xc3, 0x38, 0x86, 0x3c, 0x28, 0x7e, 0x6c, 0x06, 0x44, 0x69, 0x91, - 0x2e, 0x7f, 0x9a, 0xff, 0x7f, 0x3f, 0x5f, 0x38, 0xe7, 0xf0, 0xb4, 0xf6, 0x22, 0xf7, 0x2b, 0xe8, - 0x16, 0xa7, 0x55, 0xe7, 0xa5, 0x54, 0x87, 0x61, 0xb1, 0xc1, 0x8e, 0xe6, 0x40, 0x78, 0x40, 0xd7, - 0x46, 0x96, 0x66, 0x3a, 0xa7, 0x35, 0xe3, 0x77, 0xac, 0x76, 0x60, 0xf0, 0x49, 0x75, 0x52, 0xf6, - 0x97, 0xe8, 0xff, 0xa6, 0x96, 0x77, 0x69, 0x1d, 0xc6, 0x30, 0x0c, 0x76, 0x1c, 0x00, 0x43, 0xe0, - 0xea, 0x97, 0xf9, 0x56, 0xb3, 0xdf, 0xc9, 0xda, 0xdd, 0xf7, 0x64, 0xfb, 0x9a, 0xe3, 0x94, 0x52, - 0xff, 0xcc, 0x48, 0x2e, 0xda, 0x94, 0x2b, 0xb5, 0x38, 0xa5, 0x55, 0x8a, 0x43, 0x61, 0x02, 0x97, - 0xe5, 0xe0, 0xb1, 0x00, 0x9a, 0x45, 0xb6, 0xec, 0xe5, 0x66, 0x0a, 0xd4, 0xa3, 0x4d, 0x83, 0x6e, - 0xae, 0x09, 0x5e, 0xcc, 0x95, 0xc5, 0x1d, 0x29, 0xab, 0x24, 0x76, 0xa0, 0xcd, 0xf3, 0x20, 0x04, - 0xb2, 0xd2, 0x4b, 0xb1, 0x12, 0x04, 0xb4, 0x88, 0xf8, 0x26, 0xd2, 0x83, 0xc1, 0x9f, 0x34, 0x21, - 0xa4, 0xf4, 0xb4, 0x3d, 0x96, 0x70, 0xa5, 0x28, 0x36, 0xba, 0xc7, 0xd9, 0x43, 0x68, 0xb3, 0x8f, - 0xf7, 0x56, 0xdf, 0xbf, 0xf7, 0xa7, 0x39, 0x0f, 0x5d, 0x6d, 0xf7, 0x04, 0xb5, 0xc1, 0x62, 0xdc, - 0xa2, 0x71, 0x0c, 0x4b, 0x91, 0xd0, 0x80, 0x4e, 0x91, 0xaf, 0xb1, 0x2f, 0x13, 0x77, 0x13, 0x0c, - 0xc7, 0x7e, 0xe0, 0xc8, 0x36, 0x9b, 0xee, 0x3e, 0x2f, 0xa1, 0x7a, 0x47, 0x48, 0xd9, 0x56, 0x7b, - 0xfd, 0xf5, 0x95, 0x6c, 0x13, 0x7c, 0xcd, 0x4d, 0x87, 0x3f, 0xd8, 0x16, 0xb9, 0xc9, 0x71, 0xd9, - 0xda, 0x82, 0xe3, 0xc3, 0xd3, 0xb6, 0xac, 0x3d, 0x28, 0x12, 0x04, 0xa9, 0x55, 0x2a, 0x22, 0x08, - 0x7f, 0xad, 0x7d, 0xe5, 0x78, 0x76, 0xb9, 0x2b, 0x8b, 0xf2, 0x52, 0xd1, 0xb1, 0x06, 0xdf, 0xb3, - 0x37, 0x76, 0x79, 0xb6, 0xd8, 0xa8, 0x04, 0x9e, 0xda, 0x5a, 0xa1, 0x6f, 0xba, 0x98, 0x3a, 0xf4, - 0x0a, 0x41, 0xf4, 0x1c, 0xaf, 0xd9, 0x1a, 0xdc, 0x6f, 0x98, 0xe2, 0x4c, 0x42, 0x8b, 0x8d, 0x52, - 0x57, 0xc9, 0x41, 0x2d, 0xd3, 0x60, 0x53, 0xbd, 0x2f, 0x3a, 0x37, 0xe6, 0xbc, 0x97, 0x08, 0xbc, - 0x88, 0xa7, 0x1b, 0xe0, 0xbf, 0x25, 0xdb, 0xdc, 0x8c, 0x69, 0x33, 0x4d, 0x28, 0x9e, 0xfa, 0xcc, - 0x98, 0xe6, 0xf3, 0xcb, 0x59, 0x11, 0x6c, 0xca, 0xa7, 0xe3, 0xc2, 0x4b, 0x8b, 0x83, 0x68, 0x16, - 0x67, 0xf1, 0xcc, 0x89, 0x31, 0xad, 0xd0, 0x0c, 0x8b, 0xf5, 0xed, 0x74, 0x3e, 0x1e, 0x67, 0xd1, - 0x5a, 0xef, 0x1d, 0xc3, 0x14, 0xb8, 0x79, 0xf1, 0x29, 0x55, 0xf9, 0x0e, 0x8d, 0x6c, 0xc4, 0xea, - 0x7c, 0x25, 0x6f, 0xce, 0xff, 0xe9, 0x77, 0x24, 0xa8, 0x5a, 0x47, 0x55, 0x66, 0xa2, 0x56, 0xd1, - 0x9f, 0x06, 0xc8, 0x2e, 0xec, 0xda, 0x51, 0xa2, 0x06, 0x28, 0x41, 0x5a, 0x6a, 0xd4, 0xbc, 0xb8, - 0xa5, 0x9e, 0xcc, 0x6b, 0x5d, 0xaa, 0xaa, 0xbd, 0x7d, 0xe5, 0xdd, 0xcd, 0xf9, 0x74, 0x86, 0x15, - 0x92, 0xf4, 0xa9, 0xe5, 0xac, 0x2d, 0xeb, 0x96, 0x3a, 0x51, 0x6e, 0x8f, 0x85, 0x6b, 0x72, 0x1b, - 0x9b, 0xaf, 0x59, 0x1c, 0xee, 0xb4, 0xbe, 0xee, 0xd1, 0x61, 0xc3, 0x7f, 0x71, 0x56, 0x99, 0x4c, - 0x83, 0xc7, 0x4f, 0x58, 0x8c, 0xbe, 0x1e, 0xd4, 0xd8, 0x0c, 0xc5, 0x15, 0xcd, 0x44, 0xe8, 0x66, - 0xc0, 0xd1, 0x35, 0x01, 0x57, 0x91, 0x72, 0xb8, 0xb8, 0xa1, 0xda, 0x52, 0xd8, 0x4b, 0xd0, 0x70, - 0x7e, 0x6a, 0xd1, 0xd1, 0x6d, 0x69, 0x73, 0x65, 0x8d, 0xe3, 0x77, 0x88, 0x24, 0x8e, 0xd0, 0x6d, - 0x2f, 0x32, 0x34, 0xfb, 0x54, 0xab, 0x09, 0x32, 0xc3, 0x92, 0x79, 0x5c, 0xf6, 0x28, 0x11, 0xd1, - 0xd1, 0x73, 0x19, 0xc9, 0x7a, 0x29, 0x8a, 0xe3, 0xf8, 0x2a, 0x67, 0x23, 0x1b, 0x5a, 0x89, 0xd8, - 0x16, 0x6e, 0x0e, 0x82, 0x84, 0xe3, 0x74, 0xc4, 0x7f, 0x07, 0x67, 0xd5, 0x86, 0x75, 0xb3, 0x06, - 0xdb, 0x63, 0x91, 0xe8, 0x05, 0x22, 0x68, 0x8d, 0x1c, 0xae, 0x96, 0xd6, 0xc6, 0xcd, 0xe1, 0xe6, - 0x74, 0xf2, 0xaa, 0x84, 0x25, 0x51, 0x72, 0x70, 0xdb, 0x23, 0xcd, 0xf0, 0x10, 0x37, 0xa6, 0x68, - 0xca, 0x7d, 0xe0, 0xf7, 0x55, 0xbe, 0x75, 0x73, 0xcb, 0x1e, 0xbb, 0x59, 0xd4, 0x5a, 0x72, 0x1b, - 0xce, 0x92, 0x95, 0xdd, 0x8a, 0xfa, 0xba, 0x1f, 0xd8, 0x06, 0xd1, 0xa4, 0x52, 0x29, 0x1f, 0xad, - 0xd0, 0x26, 0x13, 0x60, 0x7a, 0x9d, 0x3b, 0x10, 0x7d, 0xbc, 0x4d, 0x3d, 0xde, 0xdf, 0x14, 0xf8, - 0x02, 0x74, 0x68, 0xe2, 0xcb, 0x01, 0xc2, 0x11, 0x1e, 0xe3, 0x48, 0x3a, 0xce, 0x27, 0x41, 0x3d, - 0x21, 0xb5, 0xc2, 0xe8, 0x8e, 0x39, 0x48, 0x95, 0xf5, 0x81, 0xf3, 0x7e, 0xfb, 0x37, 0xad, 0x74, - 0x27, 0x20, 0xf9, 0xfa, 0x36, 0xdb, 0x60, 0xa6, 0xb7, 0x9a, 0x0c, 0x6a, 0x33, 0xba, 0x80, 0x9a, - 0x87, 0x34, 0xa6, 0x2a, 0x31, 0xc8, 0xf7, 0x38, 0x03, 0xb9, 0xfa, 0xa0, 0x6f, 0x4d, 0x74, 0x2a, - 0x37, 0x15, 0x18, 0x0a, 0x5b, 0x3a, 0xa7, 0x3d, 0x7a, 0x79, 0x2a, 0xee, 0xf7, 0x57, 0x69, 0x8a, - 0xfb, 0xf8, 0xf4, 0x80, 0x0e, 0x0e, 0x37, 0x7a, 0x61, 0x0f, 0xb7, 0x81, 0xb9, 0xd7, 0x59, 0x8f, - 0xef, 0xac, 0xeb, 0xad, 0xa1, 0x71, 0x5e, 0x24, 0x5f, 0x7c, 0x6f, 0xf4, 0x3b, 0x9d, 0x6c, 0x86, - 0x31, 0x0e, 0x27, 0x76, 0x37, 0xc8, 0x57, 0xd4, 0xb0, 0x55, 0x59, 0x11, 0xda, 0x0f, 0xf1, 0xea, - 0x79, 0x42, 0xdd, 0xaa, 0xbd, 0xa3, 0x32, 0x46, 0x99, 0x8d, 0xb9, 0x96, 0x30, 0x76, 0x45, 0x06, - 0xb0, 0xdd, 0x0a, 0x6d, 0xf2, 0x04, 0xf5, 0xf6, 0x6f, 0x71, 0xe3, 0x95, 0x10, 0x36, 0x2b, 0x7e, - 0xe4, 0xc6, 0x16, 0x96, 0xb2, 0x84, 0x96, 0x26, 0x16, 0xcf, 0xfc, 0xcb, 0xab, 0xb3, 0x74, 0x2f, - 0xc7, 0x13, 0x58, 0xf9, 0x9c, 0x0b, 0x6c, 0xae, 0xe7, 0x61, 0x1b, 0x52, 0xe8, 0x3f, 0x3d, 0x54, - 0xe7, 0xd2, 0x5e, 0x9a, 0x2d, 0x70, 0xaa, 0x46, 0x1e, 0x43, 0x31, 0x45, 0x4c, 0x4b, 0x66, 0x3c, - 0x9b, 0x7e, 0xa1, 0xf8, 0x32, 0x48, 0x86, 0xd5, 0x08, 0xf0, 0x3a, 0x03, 0xb6, 0x30, 0xa4, 0x57, - 0x2a, 0xed, 0xdc, 0x04, 0xcb, 0xcc, 0xa7, 0x26, 0x2f, 0x32, 0xcd, 0x52, 0xa1, 0x7b, 0xcd, 0x7d, - 0xe7, 0x62, 0x98, 0x05, 0x75, 0x01, 0x93, 0xee, 0x3c, 0xb7, 0x55, 0xc9, 0xb1, 0xff, 0x51, 0x92, - 0x07, 0xa6, 0xdb, 0x80, 0xcd, 0xf2, 0x15, 0xc0, 0x16, 0xfc, 0x25, 0x08, 0xeb, 0x04, 0xc4, 0x36, - 0x52, 0xfa, 0x0e, 0x91, 0x0c, 0x5e, 0x70, 0xd8, 0xcf, 0x77, 0xe7, 0x03, 0x0e, 0xac, 0xb8, 0x70, - 0xc8, 0xbb, 0xbc, 0x2d, 0x41, 0x4b, 0x9d, 0xa3, 0x01, 0xc9, 0xcd, 0x96, 0x95, 0xa5, 0xbb, 0xa0, - 0x51, 0xd6, 0x15, 0x21, 0x84, 0x81, 0x29, 0x9b, 0xdd, 0x51, 0x07, 0xc2, 0x7e, 0xa2, 0xd9, 0x9c, - 0x0f, 0x40, 0x93, 0x9c, 0x8c, 0xcd, 0xdc, 0xb2, 0x85, 0x83, 0xee, 0xf3, 0xdd, 0x5e, 0xe9, 0x4a, - 0xe7, 0xb6, 0x73, 0xa5, 0xfd, 0xa3, 0xe9, 0xa9, 0x04, 0xf1, 0x82, 0x1b, 0xe4, 0x65, 0xcc, 0x2a, - 0xc1, 0xec, 0xb2, 0xe8, 0xc2, 0x40, 0x83, 0x74, 0x71, 0x42, 0x2f, 0x2c, 0x2f, 0xaa, 0xb2, 0x96, - 0xfd, 0xf3, 0xd1, 0x4b, 0xc6, 0xec, 0x4b, 0xe1, 0xd0, 0xfe, 0xf5, 0x83, 0x41, 0x2f, 0xab, 0x3b, - 0x66, 0x3a, 0xab, 0xdd, 0x8a, 0xd6, 0x95, 0x8f, 0x36, 0xd2, 0x3a, 0xa0, 0x75, 0x8a, 0xb3, 0xa0, - 0x17, 0xab, 0x6e, 0xb0, 0xe6, 0xc9, 0x25, 0x2d, 0xb5, 0x27, 0xa8, 0xcf, 0x29, 0xd8, 0x93, 0x74, - 0x41, 0x49, 0x1f, 0x6c, 0xa0, 0x0b, 0x50, 0x26, 0x2b, 0xe9, 0xbf, 0x59, 0xf5, 0x2b, 0xb6, 0xc7, - 0x22, 0x87, 0x79, 0x70, 0x13, 0x03, 0x22, 0x62, 0xf9, 0x32, 0xe4, 0x30, 0xec, 0x75, 0x5c, 0x33, - 0xc1, 0x23, 0xc9, 0x68, 0x29, 0x22, 0x83, 0x72, 0x12, 0x0d, 0x6c, 0x73, 0xb8, 0x13, 0x25, 0xc3, - 0xf1, 0x98, 0x0e, 0x35, 0x9b, 0xfd, 0x42, 0x9e, 0xe9, 0x60, 0x95, 0xa2, 0x20, 0xc1, 0x0b, 0xfd, - 0x94, 0x61, 0x70, 0xb5, 0x43, 0x73, 0x34, 0x2a, 0x57, 0x3d, 0x45, 0x23, 0x0a, 0x74, 0xb0, 0xa3, - 0x65, 0x26, 0x51, 0x6e, 0x6c, 0xfb, 0xbd, 0x1d, 0xed, 0xf6, 0x9f, 0x60, 0x39, 0xda, 0x1e, 0x0b, - 0xc6, 0x6f, 0x5f, 0x36, 0x8b, 0xd9, 0x2c, 0x91, 0x03, 0x8d, 0x07, 0xc3, 0x2e, 0x76, 0x8f, 0x3a, - 0xbc, 0x71, 0x74, 0xd6, 0x75, 0x53, 0xe8, 0xb5, 0x82, 0x0d, 0xa4, 0x60, 0x8f, 0x27, 0xb2, 0x06, - 0x3b, 0x08, 0xa0, 0x4e, 0xfd, 0x7a, 0xbd, 0x7b, 0x10, 0x8d, 0x91, 0xc6, 0x95, 0x59, 0xe5, 0xe1, - 0xb3, 0xab, 0x01, 0x15, 0x15, 0xfe, 0x4f, 0xe4, 0xf7, 0xba, 0x03, 0x57, 0xac, 0xa7, 0xf2, 0xd6, - 0xaa, 0xac, 0xef, 0x32, 0xce, 0x7d, 0x06, 0x25, 0x28, 0x62, 0xa4, 0xf0, 0xa6, 0xc8, 0x6b, 0xcb, - 0x4c, 0x1f, 0xae, 0x0f, 0x56, 0xf0, 0xd0, 0xbe, 0xa0, 0x74, 0x16, 0xd4, 0x07, 0xeb, 0x62, 0x2f, - 0xc2, 0x8d, 0x7c, 0x82, 0x41, 0x92, 0x8d, 0xc7, 0x85, 0xc1, 0x60, 0xd3, 0x85, 0x6c, 0xe5, 0xa2, - 0xae, 0xfe, 0x06, 0x55, 0x09, 0x96, 0x28, 0xd8, 0x44, 0x20, 0x98, 0x96, 0x06, 0x65, 0x17, 0xb3, - 0x05, 0xe8, 0xe9, 0x3d, 0xdd, 0xad, 0x6c, 0xe5, 0xcc, 0x40, 0x7f, 0xfa, 0xea, 0xd0, 0xe4, 0x56, - 0xe4, 0xb5, 0x05, 0x00, 0x57, 0xd1, 0x7a, 0x1b, 0x2e, 0x1f, 0x6a, 0xac, 0xce, 0x9e, 0x4d, 0x84, - 0x45, 0x34, 0xa5, 0xe8, 0xc9, 0xe6, 0xba, 0x58, 0x60, 0xb2, 0xe0, 0x22, 0xc9, 0x72, 0x48, 0xb9, - 0x10, 0xa0, 0x9a, 0x18, 0x50, 0x18, 0x19, 0xec, 0x4e, 0xbc, 0x14, 0xea, 0xc1, 0x4f, 0xee, 0x29, - 0x58, 0x9b, 0xec, 0x8c, 0x01, 0xe4, 0x0e, 0xfc, 0x20, 0xb1, 0xf7, 0x26, 0xcb, 0x51, 0x5e, 0x5b, - 0x0c, 0x7c, 0x5b, 0xe7, 0xd7, 0xd8, 0xf7, 0x34, 0x98, 0xc8, 0x29, 0xc4, 0x31, 0x6e, 0xf7, 0x62, - 0x8d, 0xf7, 0x1e, 0xf9, 0xac, 0x78, 0x0b, 0x65, 0x65, 0xa2, 0xee, 0x96, 0x95, 0x64, 0x4c, 0x70, - 0x71, 0x37, 0x1f, 0xcd, 0x8b, 0x42, 0x70, 0x7f, 0xba, 0x60, 0xc0, 0xe4, 0x95, 0x38, 0x5c, 0xcd, - 0x20, 0xe5, 0xe4, 0x0c, 0xea, 0x4d, 0xb0, 0xac, 0xd2, 0xef, 0x58, 0x5d, 0x23, 0x4a, 0xb2, 0x30, - 0x24, 0xa6, 0xa9, 0x0e, 0x30, 0xf7, 0x9a, 0xe0, 0x4a, 0xcb, 0xc5, 0x4c, 0x45, 0x60, 0x0f, 0x82, - 0x65, 0xb0, 0x3c, 0xcf, 0x3f, 0xb2, 0x64, 0xc1, 0xcc, 0x96, 0x4c, 0x70, 0x93, 0x26, 0x46, 0x40, - 0x84, 0x01, 0xf4, 0xeb, 0x22, 0x78, 0xe6, 0xe0, 0xec, 0xe5, 0x01, 0x4d, 0xc8, 0xae, 0xc4, 0x78, - 0x66, 0x41, 0x92, 0x2d, 0xc1, 0xe5, 0xe1, 0x89, 0x31, 0xf9, 0x50, 0xa1, 0xd7, 0x57, 0xda, 0x8b, - 0xd0, 0x39, 0x60, 0xfb, 0xae, 0xd9, 0xd6, 0x25, 0x3a, 0xbc, 0xb4, 0x24, 0x31, 0x1a, 0x04, 0x4f, - 0xb2, 0xec, 0x9c, 0x29, 0x1e, 0x5b, 0x65, 0xc1, 0x60, 0x74, 0x51, 0xe1, 0x25, 0xc6, 0x0f, 0x0e, - 0x26, 0xe5, 0x0c, 0x40, 0x5a, 0xbd, 0xfd, 0xda, 0x1a, 0x5b, 0x88, 0xe1, 0xca, 0x0c, 0x3d, 0x6b, - 0x8c, 0x93, 0x4b, 0x50, 0x90, 0x84, 0xd7, 0x49, 0x7e, 0xcb, 0x4a, 0xbf, 0x90, 0xb5, 0x26, 0xf9, - 0xcb, 0xad, 0x44, 0x59, 0xf0, 0x88, 0x4f, 0x8e, 0x53, 0x98, 0x39, 0x14, 0xd5, 0x12, 0xd1, 0x1c, - 0xe1, 0x4c, 0xec, 0x83, 0xeb, 0xeb, 0x9e, 0xd1, 0x28, 0x98, 0x39, 0x89, 0x22, 0x05, 0x17, 0x50, - 0x98, 0x9d, 0xbb, 0xe3, 0x51, 0xbe, 0xd0, 0xe2, 0xbe, 0xb1, 0xfa, 0x26, 0xb2, 0x86, 0xff, 0xa2, - 0x79, 0xf2, 0x92, 0xd2, 0x68, 0x95, 0x8f, 0xb1, 0x80, 0x9f, 0x7c, 0xdb, 0x66, 0x1d, 0xed, 0xf1, - 0x28, 0xda, 0xc5, 0x89, 0xa9, 0x68, 0x52, 0x0c, 0xee, 0x45, 0x44, 0x44, 0xcf, 0x2f, 0xa8, 0xea, - 0xc3, 0x1d, 0xad, 0x0c, 0xba, 0x4b, 0x60, 0x9f, 0x84, 0x41, 0x4b, 0xba, 0xac, 0x69, 0x49, 0x27, - 0x2b, 0xde, 0xc5, 0x92, 0x21, 0x0c, 0x45, 0x07, 0x2b, 0xc1, 0xa2, 0xc1, 0xcb, 0x63, 0x02, 0x00, - 0xbc, 0xe9, 0xb6, 0xe5, 0x10, 0x01, 0x73, 0xed, 0x08, 0xf6, 0x65, 0xc2, 0x73, 0x56, 0x03, 0x2e, - 0xf2, 0x08, 0x90, 0xe0, 0xad, 0xa1, 0x78, 0x65, 0x33, 0x27, 0x80, 0x3a, 0xd8, 0x1a, 0xfd, 0xec, - 0x6f, 0x7a, 0x53, 0x6e, 0x34, 0xdc, 0x1c, 0x43, 0x80, 0x7d, 0xee, 0x3b, 0x84, 0xd0, 0x96, 0x55, - 0x0e, 0xf7, 0x5d, 0xa3, 0xd9, 0xd9, 0x78, 0x0c, 0x20, 0x0f, 0x56, 0x74, 0xe6, 0x3e, 0x5f, 0x31, - 0x45, 0x1e, 0x33, 0xf8, 0x38, 0xde, 0x35, 0x8f, 0x37, 0x3b, 0x3a, 0x7b, 0x9a, 0xe0, 0x62, 0x59, - 0xa5, 0x25, 0x4c, 0x8e, 0xec, 0x74, 0x44, 0x4d, 0x8e, 0xaf, 0x2f, 0x63, 0x50, 0xa1, 0x5a, 0xa1, - 0x9e, 0xe0, 0x88, 0xb5, 0x78, 0x68, 0xea, 0xde, 0x64, 0xac, 0x60, 0x01, 0x59, 0xa0, 0x67, 0x7d, - 0xd1, 0x9d, 0x18, 0x83, 0xc2, 0x85, 0x50, 0xc6, 0x85, 0x4b, 0xbe, 0x19, 0x09, 0x7c, 0x78, 0x04, - 0x35, 0x50, 0x42, 0xa5, 0x3d, 0xdd, 0x51, 0x64, 0xb2, 0xe0, 0x5f, 0xe2, 0xce, 0xa1, 0x00, 0xf4, - 0xef, 0x13, 0x94, 0xe4, 0x53, 0xd6, 0x3a, 0xed, 0x11, 0x0d, 0xb8, 0xed, 0x72, 0x1c, 0x86, 0xcb, - 0x80, 0x77, 0x4c, 0x2f, 0xdf, 0xb3, 0x18, 0xb7, 0x59, 0x8c, 0xfe, 0x91, 0x57, 0x84, 0xbd, 0xde, - 0xb4, 0x64, 0xa1, 0xbc, 0xd8, 0xef, 0xfc, 0x72, 0xa0, 0xba, 0xe8, 0x6e, 0x9b, 0x40, 0x87, 0x4b, - 0xe0, 0x24, 0xf8, 0x04, 0x1a, 0xe7, 0xa0, 0xef, 0xb4, 0xd7, 0x19, 0xcb, 0x86, 0xc2, 0x1a, 0x56, - 0x09, 0xe9, 0x77, 0xe5, 0x9a, 0xef, 0xbb, 0xc1, 0x51, 0xac, 0x53, 0x4e, 0xdc, 0xe7, 0x5a, 0xe0, - 0xe5, 0x44, 0x16, 0xc3, 0x04, 0x96, 0xb3, 0xb7, 0xeb, 0x17, 0xda, 0x64, 0x25, 0x11, 0xcb, 0x7a, - 0xd6, 0x77, 0x51, 0x83, 0x79, 0x9d, 0xc6, 0x5c, 0x7f, 0x2f, 0x77, 0x5f, 0x75, 0xab, 0x1e, 0x25, - 0xe5, 0x16, 0x62, 0x86, 0x86, 0x39, 0x92, 0xe3, 0x91, 0xb9, 0x0e, 0x39, 0x3c, 0xde, 0x00, 0xc0, - 0x71, 0x6d, 0x3f, 0x9f, 0x5a, 0xa9, 0xed, 0xfc, 0x31, 0x87, 0xed, 0x32, 0xc0, 0xf7, 0xee, 0x55, - 0x97, 0x62, 0xd6, 0xa6, 0x9f, 0xc9, 0x48, 0x4a, 0x5c, 0x79, 0xe1, 0x60, 0xe8, 0x77, 0x1b, 0x26, - 0x07, 0xcf, 0x35, 0xc5, 0x12, 0x20, 0x6f, 0x16, 0x28, 0x93, 0x09, 0xcb, 0x51, 0x36, 0x0f, 0x09, - 0xe9, 0xa0, 0x4c, 0x2b, 0x5e, 0x7f, 0x9a, 0xc2, 0x1d, 0x19, 0x31, 0xaa, 0xbe, 0x5e, 0x3f, 0x53, - 0xbd, 0x76, 0x7f, 0x89, 0xae, 0x9b, 0x4b, 0x5f, 0xdb, 0x1f, 0x70, 0x83, 0x45, 0x4a, 0xab, 0xae, - 0xce, 0xf7, 0x3b, 0x96, 0xe0, 0xf4, 0x4e, 0x48, 0xf2, 0x8f, 0x07, 0xa4, 0xd4, 0x05, 0x11, 0x35, - 0xc6, 0x42, 0x18, 0xf2, 0xce, 0xf6, 0x24, 0x97, 0xa4, 0xfc, 0xde, 0xab, 0x68, 0x5c, 0x3d, 0x91, - 0xa4, 0xec, 0xe6, 0x02, 0xe2, 0x8d, 0xd7, 0x57, 0x79, 0x92, 0x4f, 0xef, 0xcc, 0x24, 0xc6, 0xe3, - 0xcd, 0xaf, 0xe4, 0x18, 0x20, 0x6b, 0x3b, 0x08, 0x01, 0x2e, 0x82, 0xac, 0x3d, 0x7d, 0xc4, 0x24, - 0xa2, 0x01, 0x67, 0x4a, 0x87, 0xe9, 0x34, 0x07, 0xd3, 0xde, 0xa2, 0x5c, 0x3d, 0x1d, 0x7a, 0xbd, - 0x13, 0x0f, 0x02, 0x82, 0xb1, 0xfd, 0xbb, 0x8b, 0x67, 0xd7, 0xcc, 0xf8, 0x51, 0xc3, 0x54, 0x37, - 0xec, 0x9d, 0x9e, 0xdf, 0x7a, 0xce, 0x50, 0xb7, 0x93, 0xba, 0xd3, 0x8b, 0x6b, 0x16, 0x0a, 0x27, - 0x6c, 0x91, 0x45, 0xcc, 0x7b, 0xe3, 0x92, 0xe4, 0x64, 0x9d, 0xc2, 0x10, 0x4a, 0xbf, 0xb4, 0x92, - 0x82, 0x7a, 0x09, 0xae, 0xa4, 0x9f, 0x96, 0x4f, 0xef, 0x9e, 0xbb, 0x47, 0xf4, 0xb5, 0x00, 0xf5, - 0x4b, 0x4b, 0x48, 0x82, 0x0b, 0x68, 0x28, 0xf0, 0xe3, 0x80, 0x82, 0xfc, 0x61, 0xa2, 0x26, 0x2d, - 0x90, 0x03, 0x4e, 0x57, 0x7d, 0xcb, 0x70, 0x76, 0xd9, 0x2f, 0xf1, 0x5a, 0x63, 0x3e, 0x56, 0xd8, - 0x43, 0x4a, 0xc9, 0x98, 0x80, 0x35, 0x11, 0x30, 0x63, 0x84, 0x3d, 0xdf, 0x12, 0x24, 0xc2, 0xfb, - 0x68, 0x9c, 0x52, 0xa6, 0x65, 0x70, 0x60, 0x36, 0xf2, 0xd0, 0x6c, 0xff, 0x91, 0x88, 0x84, 0xea, - 0x9e, 0x20, 0xbf, 0x7f, 0xcb, 0xb9, 0x42, 0x64, 0xd1, 0xe4, 0x61, 0x09, 0xcc, 0x24, 0x83, 0x91, - 0xba, 0xb6, 0x69, 0xe5, 0xf4, 0xc9, 0x31, 0xf7, 0x38, 0xb0, 0x6c, 0xe6, 0xf2, 0x56, 0x7d, 0x5e, - 0xe0, 0x01, 0x64, 0x73, 0x1d, 0x86, 0xba, 0x0e, 0x8d, 0x8e, 0x5a, 0x4a, 0xb9, 0x70, 0x55, 0x1c, - 0x50, 0xa6, 0xd1, 0xe6, 0x47, 0x9b, 0xf6, 0x69, 0x55, 0x71, 0xd4, 0xb6, 0x0c, 0xce, 0x72, 0xf5, - 0x8c, 0x89, 0x68, 0xbc, 0xd4, 0xbb, 0xde, 0x70, 0xac, 0xe7, 0xfb, 0xf1, 0x40, 0xec, 0x60, 0x6f, - 0xd8, 0xa5, 0x8d, 0x0a, 0x36, 0x97, 0x08, 0x37, 0xff, 0xb0, 0x8d, 0x3a, 0xaa, 0xc0, 0x7b, 0xc0, - 0xab, 0x27, 0xe7, 0x85, 0x8a, 0x9d, 0xe6, 0x00, 0xf4, 0x4e, 0x2c, 0x65, 0x52, 0x93, 0x56, 0x24, - 0xe8, 0x59, 0x38, 0x1b, 0x29, 0xcf, 0x19, 0x47, 0x1c, 0xa7, 0xb2, 0x4c, 0x44, 0x35, 0x75, 0xdf, - 0x6b, 0x29, 0xa9, 0x52, 0x5f, 0x14, 0xa0, 0x5c, 0x97, 0xd4, 0x59, 0x8a, 0x59, 0x68, 0xb5, 0x8d, - 0xef, 0xff, 0x08, 0xe4, 0x29, 0x68, 0x79, 0x3c, 0xaa, 0xf5, 0xed, 0x41, 0xd7, 0x29, 0x08, 0x36, - 0xe5, 0x81, 0xa8, 0x98, 0x33, 0x3c, 0xaf, 0xd1, 0x05, 0x05, 0x63, 0x62, 0xbb, 0x2a, 0x03, 0x27, - 0x95, 0x67, 0x5d, 0xfd, 0x5a, 0x17, 0x69, 0x08, 0xe2, 0x60, 0x34, 0x8d, 0xaa, 0x8b, 0x28, 0x2b, - 0xc0, 0xf2, 0x3c, 0xc1, 0x6d, 0xb7, 0x80, 0x04, 0x9e, 0x7a, 0x55, 0xc5, 0x3d, 0x41, 0x0d, 0x00, - 0x1d, 0xad, 0x07, 0xe0, 0xdd, 0x0e, 0xe0, 0xe2, 0x6d, 0x2d, 0x74, 0x1e, 0xc3, 0xaf, 0xee, 0xed, - 0x32, 0x0c, 0x05, 0x3c, 0xfe, 0x55, 0x9d, 0xbf, 0x41, 0xbe, 0xd4, 0xe8, 0x53, 0x4b, 0x3c, 0x14, - 0x9d, 0x97, 0x4a, 0x1c, 0xbc, 0x9b, 0x56, 0x9b, 0xec, 0x21, 0x65, 0x1e, 0x86, 0x4b, 0x4a, 0x03, - 0xe6, 0x8d, 0x03, 0x2d, 0xe6, 0x80, 0xb5, 0xb4, 0xbb, 0xc0, 0x4e, 0x02, 0x75, 0x19, 0x50, 0x09, - 0x90, 0x60, 0x79, 0xc5, 0xe2, 0x22, 0x7f, 0xb6, 0x4d, 0xb3, 0xdc, 0x37, 0x96, 0x50, 0x91, 0x9c, - 0x12, 0x7d, 0x3c, 0x71, 0x6e, 0x38, 0x5d, 0x5e, 0x29, 0x1d, 0xf1, 0x6d, 0x69, 0x71, 0x2f, 0xbe, - 0xe5, 0xb3, 0xa8, 0xa3, 0x54, 0xc0, 0x95, 0xa5, 0x52, 0xef, 0xfc, 0xaa, 0x66, 0x0c, 0x60, 0x7a, - 0x46, 0xb3, 0xb5, 0xa5, 0x8d, 0xdc, 0x54, 0x0c, 0xb8, 0x20, 0xe7, 0x1d, 0x3d, 0xa8, 0x4e, 0x7e, - 0xba, 0xac, 0x00, 0x99, 0x90, 0xd5, 0xd9, 0x32, 0xb3, 0x21, 0xb1, 0x5f, 0xdb, 0xc3, 0xed, 0x10, - 0x92, 0x21, 0x8e, 0x42, 0x3f, 0x11, 0xbc, 0x35, 0x01, 0x0f, 0x93, 0x25, 0x6b, 0x02, 0xf7, 0x0b, - 0x4d, 0xf3, 0xb0, 0xc3, 0x6d, 0x5c, 0xbe, 0x93, 0x2f, 0x2e, 0x41, 0x62, 0x43, 0x06, 0xe3, 0x8b, - 0x0c, 0x53, 0xfc, 0xe7, 0x9d, 0x06, 0xc7, 0x34, 0x86, 0xe1, 0x81, 0xf1, 0x67, 0x6f, 0xb7, 0xa4, - 0xb6, 0x43, 0xfa, 0x06, 0x4e, 0x10, 0x64, 0x64, 0xe2, 0x63, 0x8b, 0x71, 0xca, 0xbb, 0xf1, 0xea, - 0x33, 0x62, 0x07, 0x68, 0x2f, 0x61, 0xc4, 0xf7, 0x03, 0x23, 0x2c, 0xe6, 0x7d, 0x4e, 0xd1, 0x01, - 0xaa, 0x78, 0xae, 0x22, 0x0a, 0x3a, 0x61, 0x39, 0xbe, 0x89, 0x53, 0x24, 0x93, 0x4e, 0x3a, 0x3a, - 0x4d, 0xa1, 0x05, 0x97, 0x3d, 0x86, 0xc3, 0x7c, 0x3a, 0x9a, 0x0f, 0xf4, 0x90, 0x2f, 0x36, 0x1f, - 0xf9, 0xa4, 0xd9, 0x3d, 0x6b, 0x7e, 0x72, 0x62, 0x7e, 0xbc, 0xf9, 0x53, 0x2d, 0x20, 0x3b, 0x32, - 0x6c, 0xff, 0x58, 0x79, 0xc5, 0x92, 0x01, 0x33, 0xec, 0x5e, 0x8c, 0x7d, 0xe7, 0x1f, 0xc2, 0xa2, - 0x3b, 0x61, 0x66, 0x87, 0x8e, 0x32, 0x37, 0x3c, 0xb4, 0x1b, 0x2e, 0x1b, 0xcc, 0x9f, 0x39, 0x05, - 0xbe, 0x2b, 0xa1, 0xf9, 0x74, 0x1a, 0x2b, 0x7d, 0x35, 0x57, 0xbe, 0x7e, 0x16, 0x0a, 0x52, 0xf1, - 0x50, 0x05, 0xe4, 0x5f, 0x8d, 0x4b, 0x76, 0x02, 0xdc, 0x90, 0x12, 0x1f, 0x2d, 0x9e, 0x9f, 0xe1, - 0xc4, 0x0a, 0x91, 0x22, 0xca, 0x93, 0xb7, 0xfa, 0x4f, 0xf6, 0x9d, 0x1e, 0x4e, 0xfc, 0x68, 0x1e, - 0x07, 0x7d, 0x87, 0x33, 0xd8, 0x6f, 0x7e, 0xd8, 0xff, 0x35, 0x73, 0x03, 0x30, 0x84, 0x8b, 0x3b, - 0x88, 0x32, 0x2c, 0x93, 0x5b, 0x20, 0x03, 0x7e, 0x68, 0x74, 0x27, 0x63, 0x13, 0xa8, 0xc1, 0x4f, - 0x0d, 0x9c, 0xd6, 0x0b, 0xd1, 0xb4, 0x4e, 0xe2, 0x13, 0x07, 0x34, 0x40, 0x3f, 0xfc, 0xc5, 0x1b, - 0xe3, 0xa7, 0x37, 0xa3, 0x00, 0xc9, 0x80, 0x55, 0xed, 0x45, 0x13, 0x60, 0x42, 0x82, 0xa3, 0x58, - 0x86, 0x84, 0x44, 0xc5, 0xb2, 0x11, 0x10, 0x22, 0xde, 0x81, 0xcf, 0x29, 0x98, 0x16, 0xfb, 0x20, - 0xb7, 0x85, 0xaa, 0x62, 0x65, 0x32, 0x3e, 0x96, 0x40, 0x23, 0x94, 0xd6, 0xbb, 0x8c, 0x19, 0x09, - 0x58, 0xb5, 0x5d, 0x46, 0x13, 0x3f, 0x3b, 0xa4, 0x87, 0x0b, 0x27, 0x0c, 0x2b, 0x9b, 0xd3, 0x12, - 0x41, 0x8c, 0x67, 0x05, 0x9d, 0x69, 0x7c, 0xef, 0xc6, 0xd1, 0x84, 0x05, 0xf9, 0x71, 0x13, 0x67, - 0x8a, 0x78, 0x42, 0x0b, 0xc6, 0xd3, 0x2f, 0x87, 0xda, 0x33, 0xa8, 0x25, 0x1b, 0x85, 0xa1, 0x1a, - 0x50, 0x47, 0xd5, 0xb4, 0xba, 0x4c, 0x14, 0xb6, 0x03, 0x20, 0x95, 0x6c, 0xed, 0xd1, 0xce, 0xf4, - 0xdd, 0x76, 0x7e, 0x7d, 0x39, 0xd4, 0x69, 0x6a, 0x17, 0x8f, 0xda, 0xee, 0x94, 0x88, 0x6d, 0x0e, - 0xae, 0x45, 0x2a, 0x7f, 0x8c, 0xb8, 0x83, 0x40, 0x2a, 0x54, 0xe9, 0xb7, 0x0b, 0x06, 0x3c, 0x26, - 0x91, 0xaf, 0xa9, 0x1a, 0x9b, 0xe2, 0xc1, 0xf2, 0x45, 0x62, 0x5f, 0x00, 0xbd, 0x66, 0x93, 0x71, - 0x44, 0x3e, 0x7c, 0xef, 0xe4, 0x04, 0x60, 0xf7, 0xd2, 0x46, 0xba, 0x4c, 0x78, 0xd7, 0x43, 0x62, - 0x2e, 0x35, 0x23, 0x0e, 0x56, 0x8d, 0x0d, 0x98, 0xcb, 0x91, 0xff, 0x35, 0x88, 0xa3, 0x4c, 0xf7, - 0x19, 0x0d, 0xf1, 0xc1, 0x1c, 0x8a, 0x69, 0x72, 0xe4, 0xea, 0xfa, 0x9b, 0x6b, 0x54, 0xba, 0xea, - 0xf8, 0xc6, 0xee, 0x2a, 0xed, 0x1f, 0x1f, 0xb6, 0x9b, 0xb6, 0xb9, 0x3b, 0xd8, 0x46, 0xd1, 0x51, - 0xe4, 0x99, 0x57, 0xd2, 0xee, 0x35, 0xd7, 0xdc, 0xc6, 0x87, 0xdc, 0x1c, 0x9a, 0xcd, 0x00, 0x08, - 0xcc, 0x7f, 0xbf, 0x04, 0xe0, 0x49, 0x77, 0x64, 0x39, 0x48, 0xd0, 0xc7, 0xb7, 0xb0, 0x65, 0x31, - 0x67, 0x82, 0x2c, 0xd9, 0x41, 0x44, 0xb0, 0xf7, 0x91, 0x75, 0xc1, 0x63, 0x87, 0xfe, 0xe6, 0xbe, - 0x5b, 0xf3, 0xbb, 0x4c, 0x13, 0x88, 0x57, 0x85, 0xec, 0x77, 0x8d, 0x8f, 0x99, 0xee, 0x4d, 0x4f, - 0xff, 0x87, 0xe9, 0xab, 0x27, 0xdd, 0x77, 0x83, 0xe6, 0xdf, 0xab, 0xeb, 0x8d, 0xa7, 0xdf, 0x4b, - 0x8d, 0xaf, 0x85, 0x76, 0xe3, 0xd3, 0xf3, 0x7e, 0x63, 0xd5, 0x1a, 0x3e, 0xeb, 0x45, 0x21, 0x87, - 0x74, 0x9d, 0x1d, 0x5e, 0xb8, 0xe4, 0x47, 0x21, 0xf5, 0x7d, 0x37, 0x17, 0x36, 0x37, 0x08, 0x97, - 0x17, 0x79, 0x97, 0xe0, 0xa3, 0xc2, 0xe1, 0x36, 0x0b, 0xbd, 0x77, 0xce, 0xc0, 0xb4, 0x5b, 0x58, - 0xff, 0xc3, 0xa7, 0x63, 0xbc, 0xb7, 0x15, 0x7d, 0xff, 0x52, 0xdf, 0xb1, 0x0f, 0xf5, 0x4e, 0x82, - 0x79, 0x91, 0x6b, 0xbd, 0x3d, 0x02, 0x34, 0x6f, 0xe6, 0xa7, 0x70, 0xce, 0xa0, 0xec, 0xe8, 0x73, - 0x9f, 0x4b, 0x37, 0x6d, 0x85, 0xb9, 0x84, 0xfc, 0x3c, 0xb1, 0x5f, 0xf6, 0xce, 0x51, 0xdf, 0x35, - 0xef, 0xbb, 0xf1, 0x72, 0xb3, 0x35, 0x8c, 0xae, 0xd4, 0x96, 0x27, 0xf6, 0x21, 0x73, 0x40, 0xdb, - 0x86, 0x5a, 0x1d, 0x04, 0x25, 0x1e, 0x21, 0x7f, 0xa1, 0xd0, 0xf7, 0x6c, 0x79, 0xdb, 0x5c, 0xaf, - 0xb9, 0x69, 0xab, 0xa1, 0x0e, 0x40, 0x1b, 0xa7, 0x30, 0x42, 0x65, 0xcf, 0x52, 0x8b, 0x3b, 0x8c, - 0x0b, 0x77, 0x02, 0xef, 0x4f, 0xe0, 0x8a, 0xea, 0xa0, 0xf1, 0x5b, 0x7b, 0xc8, 0xdb, 0x4e, 0xf7, + 0x1b, 0x0d, 0x53, 0x00, 0x1c, 0x87, 0xe9, 0xb6, 0x20, 0xff, 0x45, 0xc3, 0xc3, 0x5c, 0x49, 0xdb, + 0x95, 0x46, 0x48, 0x32, 0x7b, 0xf9, 0x36, 0xfd, 0xef, 0xe6, 0xe7, 0x4b, 0x1c, 0x71, 0xb4, 0xc9, + 0x22, 0xc4, 0x95, 0xb4, 0x56, 0xd6, 0x94, 0x1e, 0xc7, 0xc5, 0x63, 0x58, 0x83, 0x0c, 0xf5, 0xd4, + 0x18, 0x46, 0x88, 0x1c, 0x4f, 0xc8, 0xc2, 0x6d, 0xa9, 0x2e, 0xae, 0x14, 0x45, 0x44, 0xd2, 0x1f, + 0x78, 0x83, 0x6a, 0xd0, 0xff, 0x54, 0xb6, 0xcd, 0x1d, 0xdb, 0x69, 0x16, 0xf7, 0x07, 0x5e, 0xf1, + 0x43, 0xc2, 0x61, 0xf2, 0x45, 0xfc, 0xff, 0xf7, 0xab, 0x72, 0xdd, 0x90, 0x5c, 0x36, 0x62, 0x8d, + 0x02, 0x0c, 0x91, 0x5a, 0x1d, 0x23, 0xfb, 0x5f, 0x78, 0x77, 0xfa, 0x7d, 0xe8, 0x93, 0x82, 0xae, + 0xb3, 0x55, 0x0d, 0x43, 0x35, 0xbd, 0x00, 0x70, 0xef, 0x7b, 0xef, 0x17, 0xce, 0x4c, 0x03, 0x55, + 0x77, 0x00, 0x51, 0x11, 0xb8, 0x48, 0x09, 0x64, 0xd5, 0x02, 0xd9, 0xc8, 0xb8, 0x44, 0xc6, 0x6d, + 0xa3, 0x36, 0x9a, 0x63, 0x78, 0xf2, 0x7d, 0x0c, 0xd3, 0xee, 0xe9, 0xbe, 0x76, 0xdd, 0xee, 0xd6, + 0x44, 0x51, 0x11, 0x11, 0x05, 0xcd, 0xb3, 0x85, 0x1e, 0xf0, 0x6a, 0x4e, 0x2c, 0x6e, 0x48, 0x59, + 0x81, 0x98, 0xc1, 0xe7, 0x61, 0x10, 0x01, 0x19, 0x78, 0x25, 0x26, 0x82, 0x32, 0xcd, 0x13, 0xdf, + 0xc4, 0xf2, 0xe0, 0xe8, 0xa7, 0xcc, 0x0a, 0x52, 0xd9, 0xc2, 0xc7, 0x94, 0x10, 0x8b, 0xee, 0xc2, + 0x3b, 0x9a, 0xfd, 0x0c, 0x65, 0xbd, 0x4e, 0xb7, 0x56, 0xbf, 0x7c, 0x17, 0x5b, 0x21, 0xf7, 0xc3, + 0x26, 0x77, 0x05, 0x6a, 0xc3, 0x48, 0x63, 0x34, 0x4f, 0xf3, 0x52, 0x6a, 0x68, 0x20, 0x27, 0x1f, + 0x53, 0x1c, 0x0b, 0x24, 0x8c, 0x82, 0xbe, 0x8e, 0xe7, 0xa1, 0xd8, 0x36, 0xfa, 0xab, 0x7f, 0xa7, + 0x98, 0xd6, 0x11, 0x96, 0x6c, 0x83, 0xaf, 0x7f, 0xfc, 0xc3, 0xe5, 0xb7, 0xe2, 0x6b, 0x5e, 0xef, + 0xf1, 0xc7, 0xe6, 0x6c, 0x5e, 0xe7, 0xb4, 0x6c, 0x66, 0x70, 0xbc, 0xb7, 0xef, 0x8a, 0x4d, 0xcc, + 0x8a, 0x02, 0xb3, 0xd4, 0xc4, 0x8a, 0x0a, 0x44, 0x3c, 0xd5, 0xb1, 0x78, 0x3c, 0xbe, 0x58, 0x15, + 0xb6, 0x78, 0x64, 0xca, 0xb1, 0xce, 0xbe, 0xc7, 0x2f, 0xf2, 0xe8, 0x72, 0xb4, 0x30, 0x00, 0x1e, + 0xe9, 0x62, 0xcb, 0xc3, 0x3e, 0x2d, 0x1d, 0x7a, 0x40, 0x10, 0x5d, 0xf3, 0x29, 0x5b, 0x83, 0xe7, + 0x8d, 0x33, 0x5c, 0x48, 0x87, 0x85, 0x30, 0x16, 0x12, 0x79, 0x76, 0x63, 0xbd, 0xa5, 0x26, 0xf6, + 0x0d, 0x64, 0x07, 0xdb, 0x8d, 0x98, 0x16, 0x22, 0xe7, 0x87, 0xff, 0x96, 0x31, 0x8d, 0x61, 0xac, + 0xb7, 0xa3, 0xa2, 0xf4, 0x0e, 0xb6, 0x66, 0xea, 0xff, 0x92, 0xf9, 0xa2, 0xeb, 0x80, 0x5c, 0x5d, + 0xa2, 0x22, 0xf0, 0xbf, 0x45, 0x3f, 0x1f, 0x3e, 0x1a, 0x58, 0x67, 0x9b, 0x62, 0xeb, 0x88, 0x1e, + 0x07, 0x06, 0xe7, 0xe0, 0x55, 0x7f, 0xf0, 0x2a, 0x11, 0x19, 0x43, 0x80, 0xa1, 0xd2, 0x60, 0xf8, + 0x16, 0xe1, 0xf2, 0xd3, 0x86, 0xa3, 0x53, 0xc3, 0xa8, 0x47, 0x74, 0x01, 0xa5, 0x05, 0x86, 0xdf, + 0x1e, 0xb8, 0xd2, 0x3a, 0xb4, 0x6a, 0xba, 0x49, 0x0e, 0x09, 0xd7, 0xae, 0x71, 0xc9, 0x39, 0xf9, + 0xf0, 0x28, 0x4d, 0x64, 0xfa, 0xb5, 0xbe, 0xc3, 0x75, 0x63, 0xe9, 0xfa, 0xd0, 0xe1, 0x70, 0x88, + 0x65, 0x7b, 0x62, 0x28, 0xe0, 0xee, 0xc1, 0x44, 0xc3, 0x0a, 0x34, 0x6d, 0x1c, 0xe2, 0x5f, 0x81, + 0x29, 0x68, 0xda, 0x22, 0xa2, 0x93, 0x74, 0x9e, 0x7c, 0x88, 0x32, 0x72, 0x9c, 0x89, 0x01, 0xaa, + 0x2e, 0x2a, 0xf1, 0x3c, 0x88, 0x11, 0xa8, 0x03, 0xfd, 0x95, 0xd5, 0xc0, 0x15, 0x1b, 0xfc, 0x7d, + 0x99, 0x5a, 0x4e, 0x1b, 0xf2, 0xc1, 0x14, 0xac, 0xe3, 0xa3, 0xcf, 0xd6, 0xda, 0xec, 0x35, 0xc1, + 0x6d, 0xfc, 0x7b, 0x72, 0xed, 0xb2, 0xef, 0x1c, 0xf9, 0x6f, 0xd9, 0x61, 0xc0, 0x55, 0x60, 0x86, + 0x20, 0x71, 0x44, 0xa2, 0xcc, 0xf2, 0xd3, 0xf2, 0x62, 0x60, 0x04, 0x09, 0xbd, 0xc1, 0x06, 0xc7, + 0x44, 0x30, 0xc8, 0xbc, 0xc3, 0xa6, 0x79, 0xb1, 0x46, 0xaa, 0xab, 0x65, 0xf0, 0xb1, 0xe5, 0xea, + 0x22, 0x49, 0x20, 0x67, 0xf7, 0x86, 0x8c, 0x9a, 0xda, 0xd4, 0x3c, 0xa5, 0x8e, 0xa4, 0x0b, 0x4c, + 0xd3, 0x76, 0x84, 0x6b, 0xa7, 0x95, 0x93, 0x00, 0x9a, 0x89, 0x2a, 0x15, 0xc7, 0x3c, 0x3e, 0x14, + 0xbc, 0x63, 0xd5, 0x0f, 0xbc, 0x87, 0xaa, 0x95, 0xa7, 0xa5, 0x5a, 0x0c, 0xef, 0x3b, 0x71, 0x79, + 0x33, 0x06, 0xb6, 0x1a, 0xda, 0x78, 0xcd, 0x8a, 0xbf, 0xd7, 0x5b, 0x62, 0x44, 0x74, 0x21, 0x99, + 0xa8, 0xc1, 0x5c, 0xf4, 0xee, 0x62, 0x33, 0xfb, 0x78, 0x2f, 0x7f, 0x2c, 0xab, 0xea, 0x23, 0x8b, + 0xc5, 0x74, 0x75, 0xaf, 0x69, 0x20, 0x8b, 0x6d, 0x86, 0x50, 0x41, 0xa8, 0xec, 0xd0, 0x75, 0xc2, + 0xfc, 0x08, 0x28, 0xff, 0xf6, 0xfc, 0x12, 0x64, 0x1f, 0x65, 0xbb, 0xda, 0xbb, 0x15, 0x5b, 0x8e, + 0x4c, 0x08, 0x15, 0x27, 0xa2, 0x39, 0xe0, 0xda, 0x25, 0x9b, 0xc5, 0x89, 0x0b, 0x0c, 0x29, 0x5d, + 0x1d, 0xc5, 0xdd, 0xfe, 0x09, 0xfb, 0xf4, 0x8b, 0x24, 0x72, 0x6b, 0xad, 0xc3, 0x6b, 0x0c, 0x6a, + 0xc7, 0xfa, 0x21, 0x03, 0xa8, 0xd0, 0x7b, 0x21, 0xbe, 0x0e, 0x55, 0x6b, 0x01, 0x0e, 0x37, 0xfc, + 0x1a, 0x66, 0x75, 0x53, 0x35, 0xc6, 0x83, 0xfc, 0x70, 0x5b, 0xd1, 0x67, 0x8a, 0xf1, 0xc8, 0x72, + 0x53, 0x3a, 0xbe, 0x9e, 0x4f, 0x82, 0x44, 0x3a, 0xf1, 0x70, 0x2c, 0x2f, 0x3c, 0x42, 0xa1, 0x90, + 0x62, 0x79, 0xf2, 0x84, 0x87, 0xf9, 0x95, 0x1e, 0x8e, 0x00, 0x60, 0x85, 0x67, 0xb6, 0x9f, 0x7a, + 0x59, 0x0d, 0x5a, 0xc7, 0x0c, 0xd9, 0x2c, 0x34, 0x04, 0x8b, 0xfc, 0xf4, 0x42, 0x3c, 0xfc, 0xda, + 0xdd, 0xa2, 0x3e, 0x52, 0x80, 0xba, 0x6a, 0xff, 0xa9, 0xe0, 0xc8, 0xcf, 0x86, 0xc1, 0xe8, 0x32, + 0x75, 0x90, 0x49, 0x22, 0x39, 0x6b, 0x29, 0x52, 0x8d, 0x96, 0x66, 0xb9, 0x4d, 0x96, 0x31, 0xbd, + 0xfa, 0xac, 0xa5, 0xe2, 0x9f, 0x36, 0x15, 0xb8, 0x79, 0x8e, 0xad, 0x12, 0xde, 0x90, 0xa0, 0x13, + 0x91, 0xab, 0xac, 0xf5, 0x22, 0x42, 0x2d, 0xc8, 0xd3, 0xec, 0xa7, 0x29, 0xcf, 0xf6, 0x51, 0x6d, + 0x01, 0x86, 0xa8, 0x9e, 0x5d, 0x4e, 0x9b, 0x35, 0x8f, 0xa4, 0xbd, 0xe1, 0x9a, 0x23, 0xf5, 0x60, + 0x6d, 0xde, 0xee, 0x2e, 0x41, 0x5b, 0xd7, 0x5a, 0x35, 0x94, 0xcf, 0xf6, 0xf1, 0x7d, 0xa0, 0x01, + 0x7e, 0x86, 0x43, 0x6d, 0xb7, 0xf1, 0x5e, 0xfb, 0x9e, 0x39, 0xf9, 0x25, 0x26, 0xd0, 0x5b, 0xb4, + 0xa8, 0xc1, 0xc2, 0x1b, 0x07, 0xd9, 0x98, 0xdf, 0xf3, 0x9b, 0xbd, 0x16, 0xd2, 0x96, 0x82, 0x92, + 0xee, 0xad, 0xfb, 0x7d, 0xa0, 0xfd, 0x78, 0xd7, 0x43, 0x8f, 0xa1, 0x05, 0xc0, 0x53, 0x8b, 0xf2, + 0x66, 0xf7, 0xc0, 0x24, 0xaa, 0x49, 0x3d, 0x93, 0x36, 0x68, 0x23, 0x80, 0xdc, 0x9f, 0x77, 0x1a, + 0x09, 0xed, 0x4c, 0xa4, 0x13, 0xa0, 0x75, 0x6b, 0x6f, 0x05, 0x13, 0x49, 0xb2, 0xde, 0x7f, 0xe8, + 0x9f, 0xff, 0xcd, 0x0f, 0xde, 0x4a, 0xc8, 0xbe, 0x3e, 0xf5, 0x52, 0x2c, 0x8c, 0x26, 0x93, 0xb3, + 0xda, 0x29, 0x59, 0xb1, 0x01, 0x26, 0xc8, 0xb4, 0x31, 0x86, 0x3d, 0x9d, 0xcf, 0x29, 0x8b, 0x55, + 0xbc, 0xe9, 0x4b, 0x07, 0x81, 0xa2, 0x4e, 0x71, 0x86, 0xf8, 0x26, 0x07, 0xf6, 0xb1, 0x3e, 0xaf, + 0xed, 0x33, 0xb4, 0xbd, 0x87, 0xf4, 0x9c, 0xb7, 0xf6, 0x6e, 0xe3, 0x73, 0xe8, 0x3e, 0x9b, 0xee, + 0x2f, 0xbd, 0x0f, 0x6d, 0xfa, 0xf9, 0xfd, 0xae, 0xd9, 0xa6, 0x6a, 0xd2, 0x6f, 0x24, 0x6f, 0xc7, + 0xee, 0xa0, 0xc0, 0x85, 0xb7, 0x9d, 0x88, 0x09, 0xf2, 0x60, 0x17, 0xef, 0xaf, 0xa1, 0x49, 0xb2, + 0x90, 0xd2, 0x49, 0x34, 0x5f, 0x63, 0xf0, 0xe9, 0xe7, 0xe7, 0xd9, 0xa9, 0x8c, 0x3f, 0x07, 0x79, + 0x37, 0x04, 0xf4, 0xad, 0xbf, 0xb8, 0x29, 0x3d, 0x0b, 0xeb, 0xfc, 0xa1, 0x46, 0xb6, 0x8c, 0x86, + 0x01, 0x38, 0x44, 0x62, 0xf5, 0x93, 0x86, 0xa9, 0xaa, 0x1b, 0x36, 0xee, 0x06, 0x3f, 0xbd, 0x0c, + 0x19, 0x9f, 0x60, 0x35, 0x40, 0xaa, 0x87, 0x8f, 0x45, 0x56, 0x1d, 0x2c, 0x1c, 0x5b, 0xc0, 0x4b, + 0xe2, 0xc2, 0x23, 0xc0, 0xb6, 0x95, 0xcf, 0x00, 0x59, 0xbd, 0x9d, 0x58, 0xbc, 0xcb, 0x4c, 0xdd, + 0xd4, 0xfa, 0xf2, 0xe2, 0x14, 0x09, 0xa4, 0x71, 0x22, 0x6e, 0xf9, 0xcf, 0x7d, 0x76, 0x27, 0x53, + 0xb2, 0x02, 0x08, 0x7c, 0x20, 0xa8, 0x3c, 0x93, 0x71, 0x32, 0x33, 0x62, 0xa8, 0xae, 0x05, 0x02, + 0xd1, 0x94, 0x86, 0x89, 0x0a, 0x4c, 0xba, 0xa7, 0xa8, 0xf7, 0xe4, 0x8c, 0x04, 0x93, 0x0d, 0x82, + 0x5b, 0xcd, 0x9d, 0x85, 0x1f, 0x87, 0x26, 0x0d, 0x1f, 0xf9, 0x4d, 0x8b, 0xe9, 0xe7, 0x42, 0xb0, + 0x01, 0x99, 0x75, 0x04, 0xcf, 0x98, 0xac, 0x6f, 0xc5, 0xfa, 0x9f, 0x7b, 0x26, 0xe6, 0x1a, 0x6e, + 0x6f, 0x14, 0xd9, 0x39, 0x23, 0xe7, 0x9f, 0x71, 0xdc, 0x39, 0x91, 0x5b, 0x07, 0x2a, 0x29, 0x8e, + 0x86, 0x3e, 0x47, 0xae, 0x58, 0xa9, 0x10, 0x2e, 0x1f, 0x2d, 0xcf, 0x56, 0x3f, 0x7b, 0x86, 0x26, + 0x91, 0x1f, 0x81, 0x26, 0xb0, 0x3f, 0x07, 0x5d, 0xa5, 0x3b, 0x26, 0xde, 0x8e, 0x55, 0xa8, 0x0b, + 0x00, 0xbb, 0xa3, 0x3c, 0xd5, 0x34, 0x7c, 0xad, 0x60, 0xed, 0xe6, 0xc3, 0xee, 0xd5, 0x85, 0x74, + 0xb0, 0xa8, 0xed, 0xed, 0x7c, 0xf6, 0xa2, 0x77, 0x52, 0x5d, 0x3b, 0xfa, 0x77, 0x80, 0xe3, 0x86, + 0x1c, 0xbf, 0x74, 0x7f, 0xdf, 0x61, 0x5f, 0xdc, 0x6e, 0x97, 0x87, 0xdd, 0x85, 0xdc, 0xbe, 0xa4, + 0xaf, 0x7b, 0xf6, 0xbd, 0xb8, 0xc0, 0xe2, 0xda, 0x77, 0x72, 0xfd, 0x92, 0xbe, 0xc3, 0x31, 0x3a, + 0x0c, 0xec, 0xe5, 0x63, 0xce, 0x0f, 0x77, 0x17, 0xeb, 0xf8, 0x25, 0xfd, 0x77, 0x76, 0xd2, 0x0e, + 0x8c, 0x48, 0x8a, 0x76, 0xbc, 0x9c, 0x3f, 0xe2, 0x99, 0xc9, 0x7c, 0xb7, 0x3a, 0x3d, 0xd2, 0xfa, + 0x35, 0x24, 0x48, 0x3e, 0xea, 0xe9, 0x54, 0x95, 0x0b, 0xc7, 0x97, 0x12, 0xe5, 0xb4, 0x62, 0xe9, + 0x10, 0xd2, 0x09, 0x3b, 0x8f, 0xd9, 0x82, 0x66, 0x95, 0x60, 0x01, 0x38, 0xa4, 0x26, 0xdf, 0xb0, + 0x63, 0x16, 0x9e, 0xd0, 0x42, 0x2b, 0xfa, 0x14, 0x61, 0xe5, 0x30, 0xc6, 0xf4, 0x33, 0xde, 0xe6, + 0xae, 0xa8, 0x08, 0xa8, 0x1f, 0xfb, 0x2c, 0xa9, 0x45, 0x89, 0x5b, 0xe5, 0xca, 0xa9, 0x9f, 0x6b, + 0x8d, 0x48, 0x50, 0x35, 0x8a, 0x30, 0xac, 0x71, 0xc0, 0xc1, 0xa6, 0x4c, 0x88, 0x69, 0xd4, 0xff, + 0x6b, 0xdf, 0x68, 0x31, 0x87, 0x8d, 0x24, 0x8f, 0x0b, 0x2b, 0xf1, 0x94, 0x1a, 0x61, 0xd0, 0x7e, + 0x7c, 0xc8, 0x8b, 0xb2, 0xd2, 0xa1, 0x1d, 0xac, 0x5c, 0xbf, 0xba, 0x8e, 0xe6, 0x4c, 0x07, 0x17, + 0x20, 0x4f, 0x5e, 0x3a, 0x2f, 0x22, 0xb5, 0xc2, 0xe1, 0x8c, 0x04, 0xb8, 0xf8, 0x40, 0xaf, 0x4c, + 0x17, 0xb1, 0x1b, 0x0e, 0xf5, 0xca, 0xe0, 0x25, 0xfa, 0xc6, 0x17, 0xf7, 0xc8, 0x4c, 0xdc, 0x4b, + 0xad, 0xc0, 0x50, 0x79, 0x33, 0xd8, 0xcb, 0x1c, 0x9a, 0x57, 0xd9, 0x61, 0x9f, 0x44, 0xc9, 0x3c, + 0xd6, 0xc7, 0x6e, 0x7b, 0xa1, 0x42, 0x6b, 0x54, 0x63, 0x6a, 0xe4, 0xba, 0x52, 0xb7, 0x3b, 0x2a, + 0x4b, 0x36, 0x5c, 0xef, 0xee, 0xdc, 0x77, 0x9f, 0xe5, 0xc2, 0x0e, 0x52, 0xbc, 0xf9, 0x1a, 0xa3, + 0x2c, 0x26, 0xc8, 0x90, 0xb7, 0x78, 0x64, 0x29, 0x5d, 0x9c, 0x1c, 0xfb, 0xe1, 0x74, 0x34, 0xdd, + 0x0a, 0x3f, 0x8a, 0xe0, 0x2c, 0x85, 0x88, 0xaa, 0x2c, 0x1c, 0x5f, 0xcc, 0x1b, 0x18, 0x38, 0x43, + 0x8d, 0x1e, 0x6a, 0xa3, 0xdc, 0x00, 0xef, 0x9c, 0xb4, 0x45, 0xf7, 0x6f, 0xb4, 0x79, 0xb5, 0xfd, + 0x0b, 0x5c, 0x5a, 0x99, 0xcd, 0xa2, 0xfe, 0x8c, 0xc4, 0x1a, 0x2a, 0x2d, 0x65, 0x0a, 0x89, 0xb5, + 0xd2, 0x82, 0x51, 0x63, 0x80, 0xea, 0xc2, 0xbf, 0x87, 0x95, 0x4b, 0x24, 0x95, 0x88, 0x93, 0x12, + 0x23, 0xdd, 0xa7, 0xe9, 0x0c, 0xb5, 0x1f, 0xf7, 0x50, 0x88, 0x10, 0x62, 0xca, 0x88, 0xbf, 0x20, + 0x0a, 0x63, 0x9c, 0xf3, 0xa7, 0xc7, 0x80, 0xd0, 0x77, 0xf5, 0xbc, 0xf2, 0x84, 0x4e, 0xdb, 0x0c, + 0xd1, 0xa8, 0xfb, 0x87, 0x1c, 0xc3, 0x9d, 0x63, 0x5c, 0xf3, 0x37, 0xff, 0xcd, 0x0c, 0xf3, 0x4b, + 0x06, 0x6f, 0x27, 0xfa, 0x8d, 0x13, 0x84, 0x83, 0x41, 0x81, 0xd6, 0xf3, 0xbc, 0xcc, 0x60, 0xf0, + 0x00, 0xbb, 0x8c, 0xc6, 0x4a, 0xa8, 0x31, 0xc2, 0x3a, 0xac, 0x17, 0xad, 0x6a, 0x29, 0x96, 0x3b, + 0xf4, 0x7b, 0x95, 0x53, 0x38, 0xfe, 0x7c, 0x8b, 0xb1, 0x8c, 0x7b, 0x40, 0x39, 0xd5, 0x24, 0xee, + 0x39, 0xab, 0x38, 0x82, 0xb8, 0xd7, 0x75, 0x0e, 0x10, 0xae, 0x00, 0x3d, 0x5a, 0xf7, 0x78, 0xe4, + 0xa8, 0x28, 0xa7, 0xa8, 0xc8, 0x0a, 0x3c, 0xa1, 0xae, 0x31, 0x0b, 0xf5, 0xa1, 0x55, 0x5e, 0x81, + 0xbb, 0x1e, 0x0b, 0x8f, 0x9e, 0xf4, 0x71, 0xf2, 0x2f, 0x03, 0x65, 0x30, 0x64, 0x8a, 0xad, 0xef, + 0x07, 0xf6, 0xb4, 0x06, 0x48, 0x93, 0x02, 0x25, 0xac, 0xe2, 0x9c, 0xb5, 0xd8, 0x59, 0xe0, 0x55, + 0x67, 0xd4, 0x4a, 0x77, 0x66, 0x4e, 0xef, 0x5d, 0x74, 0x4d, 0x19, 0x75, 0xd2, 0x67, 0x92, 0x26, + 0xae, 0x60, 0x27, 0x4b, 0x0c, 0xe6, 0x81, 0xcd, 0x8f, 0xd6, 0xa2, 0x97, 0x79, 0xfc, 0xc3, 0xfd, + 0x5c, 0xed, 0x24, 0x71, 0x8c, 0xdc, 0x0c, 0x4e, 0x1c, 0xec, 0xfd, 0xb9, 0xb5, 0x92, 0x9d, 0x08, + 0xed, 0x55, 0x8a, 0x19, 0xb6, 0x25, 0x44, 0x86, 0x54, 0x83, 0x53, 0x28, 0x0b, 0xcb, 0xd0, 0x4f, + 0x07, 0x21, 0x21, 0xe6, 0x09, 0xc5, 0xe3, 0x69, 0x6e, 0x8c, 0x44, 0x27, 0x63, 0xa6, 0x9c, 0x7f, + 0x5a, 0x92, 0x90, 0x5c, 0x56, 0xc8, 0xa0, 0x1a, 0x80, 0xe5, 0xbf, 0x01, 0xa8, 0xff, 0xa4, 0xe2, + 0x9c, 0x43, 0x4a, 0x9c, 0xce, 0x33, 0x0b, 0xbd, 0xc4, 0x79, 0x1c, 0x89, 0x28, 0xb6, 0x2a, 0x4c, + 0xba, 0xf4, 0x21, 0x02, 0x16, 0xe2, 0x60, 0xfe, 0x40, 0x37, 0x69, 0x87, 0x23, 0x13, 0xd1, 0x21, + 0x0f, 0x9e, 0x43, 0x94, 0xe6, 0x51, 0x02, 0x19, 0xa4, 0xa3, 0xa0, 0xdd, 0xe8, 0x25, 0x5f, 0xc5, + 0x08, 0xdd, 0xf0, 0x8f, 0x9a, 0xa3, 0x2b, 0x49, 0x58, 0xd6, 0xda, 0xc4, 0xab, 0x2a, 0x36, 0x6c, + 0x59, 0xae, 0xb9, 0x3d, 0xb7, 0x1e, 0x6d, 0xe9, 0x58, 0xe9, 0xe6, 0x2c, 0x70, 0x56, 0xfe, 0x73, + 0x41, 0xc8, 0x2a, 0xf3, 0xa9, 0xd6, 0xa4, 0x97, 0xf2, 0xd3, 0x26, 0x5f, 0x93, 0x31, 0xe3, 0xee, + 0x4f, 0x1b, 0xbd, 0x88, 0x2b, 0x3b, 0x1f, 0xe3, 0x15, 0x6d, 0x8d, 0xc4, 0x93, 0xb5, 0x9f, 0x31, + 0xce, 0x20, 0x46, 0x1d, 0xa7, 0xf2, 0x08, 0x3e, 0xd3, 0x06, 0x6b, 0x5e, 0x42, 0x97, 0xc1, 0x45, + 0x0f, 0x20, 0xe5, 0x5f, 0xe4, 0x07, 0x97, 0xd3, 0x0a, 0x76, 0xc1, 0xe3, 0xec, 0xc9, 0xcd, 0x23, + 0xca, 0x7a, 0xcd, 0xc8, 0x4a, 0x77, 0xb0, 0xb9, 0x6b, 0x3a, 0x36, 0x04, 0xa0, 0xf4, 0xf6, 0xae, + 0x96, 0xee, 0x1e, 0x6a, 0xbf, 0xbd, 0xcc, 0x6a, 0x64, 0xb7, 0xc1, 0x87, 0x3c, 0xf0, 0x1b, 0x95, + 0x62, 0x9c, 0xce, 0xc0, 0x54, 0x78, 0xe1, 0x76, 0x95, 0x46, 0xf8, 0x58, 0x2a, 0x42, 0x7d, 0x06, + 0x13, 0xb0, 0xf8, 0x89, 0xb3, 0x2d, 0x3a, 0x1d, 0x10, 0x35, 0x79, 0xb5, 0x38, 0x9f, 0x65, 0x30, + 0x5e, 0x67, 0x93, 0x44, 0x2e, 0xb1, 0x5c, 0x43, 0xd6, 0x8d, 0x40, 0xf4, 0xee, 0xbc, 0x26, 0xad, + 0xb2, 0x7b, 0xf2, 0x14, 0x8e, 0xfb, 0xd6, 0x80, 0xbd, 0x01, 0xdf, 0x21, 0x44, 0xec, 0x15, 0x03, + 0xcc, 0x37, 0x1e, 0x76, 0x3f, 0x61, 0xec, 0x06, 0xa6, 0x4f, 0xbf, 0xf4, 0xc3, 0xd6, 0x8b, 0xaf, + 0x85, 0x67, 0xe4, 0x6f, 0xe7, 0xfe, 0x0e, 0xa3, 0xdd, 0x8a, 0xb6, 0x85, 0x5d, 0xde, 0xff, 0xeb, + 0x5d, 0x49, 0x78, 0xf0, 0xff, 0xc2, 0x2a, 0x26, 0x00, 0xe9, 0x81, 0x8c, 0xd3, 0x41, 0x85, 0xc7, + 0x4b, 0xeb, 0x73, 0x18, 0x88, 0xe0, 0x40, 0x17, 0x66, 0x03, 0x73, 0x93, 0xaf, 0x40, 0x6f, 0x84, + 0x8f, 0xf4, 0x43, 0x72, 0xc8, 0xbf, 0xe0, 0x36, 0xae, 0x2e, 0xec, 0xc7, 0xd5, 0xf3, 0x8f, 0x8d, + 0x68, 0xf4, 0x64, 0x8e, 0x8c, 0x77, 0x09, 0xd3, 0x4e, 0x0f, 0xfe, 0x47, 0xe9, 0x71, 0xa3, 0xc6, + 0x54, 0xf3, 0x66, 0xb3, 0x68, 0xbb, 0x4b, 0x8b, 0x8c, 0xc4, 0x27, 0x9b, 0x87, 0x07, 0x5b, 0x4f, + 0x34, 0x4d, 0x01, 0xfb, 0x4c, 0x32, 0xcf, 0x74, 0x47, 0x74, 0xc7, 0xc7, 0xdb, 0x70, 0xb1, 0x5c, + 0x04, 0x1a, 0x10, 0x3f, 0x9d, 0x31, 0x4d, 0xeb, 0xb5, 0x95, 0xaf, 0x24, 0x19, 0xa6, 0xed, 0xc7, + 0x06, 0x3b, 0x05, 0x3e, 0xe5, 0xe1, 0xcb, 0xcb, 0x93, 0x24, 0x68, 0x40, 0xb2, 0x01, 0x10, 0xea, + 0x16, 0x49, 0x42, 0x27, 0x6a, 0xed, 0x26, 0x40, 0x81, 0x9a, 0x83, 0x30, 0xde, 0x23, 0x94, 0x1f, + 0xf3, 0x04, 0x34, 0xf5, 0x6e, 0x23, 0xad, 0x1b, 0x93, 0x63, 0x21, 0x2e, 0x3b, 0x24, 0xf9, 0x42, + 0xfc, 0x15, 0x4d, 0xfd, 0x04, 0x9a, 0x0d, 0xb1, 0x31, 0xad, 0x6d, 0x51, 0x03, 0xc2, 0xf9, 0x87, + 0xe0, 0x25, 0x67, 0x89, 0x88, 0xd1, 0x74, 0x8e, 0x93, 0xa4, 0x41, 0x29, 0x96, 0x33, 0x7b, 0x1e, + 0x91, 0x83, 0x16, 0x77, 0x64, 0x98, 0x5b, 0x74, 0x06, 0x08, 0xf1, 0x41, 0x42, 0x7c, 0x39, 0x03, + 0x24, 0x09, 0x54, 0x6a, 0xc2, 0x24, 0xdd, 0x88, 0x24, 0x88, 0xf5, 0x90, 0xeb, 0x25, 0xd1, 0x11, + 0xdf, 0xbb, 0x2d, 0x9c, 0xcc, 0xcd, 0xed, 0xe3, 0x5f, 0x6f, 0xe2, 0x0a, 0xd3, 0x34, 0x30, 0x5b, + 0x9a, 0x32, 0x0e, 0x12, 0x1b, 0x32, 0xb5, 0xaf, 0xe8, 0x38, 0x02, 0xf2, 0x2c, 0xf8, 0x75, 0x5f, + 0x25, 0x3a, 0x43, 0xa3, 0x82, 0x80, 0xfd, 0xd1, 0x15, 0x7e, 0xf9, 0x57, 0xb2, 0xea, 0xee, 0xdc, + 0x7b, 0xc6, 0xf0, 0x2d, 0xc8, 0xf3, 0x6c, 0x4d, 0xd6, 0x02, 0xda, 0x7c, 0xf5, 0xf7, 0x69, 0x68, + 0x32, 0x9a, 0xbc, 0x73, 0xb0, 0xcc, 0x63, 0x6c, 0x6c, 0x04, 0xa6, 0x6b, 0x5d, 0x8e, 0x78, 0xfc, + 0xc1, 0xb0, 0x5d, 0x57, 0xb2, 0xc5, 0x7a, 0x7e, 0xb9, 0xba, 0x97, 0x61, 0x39, 0x6d, 0x9a, 0x92, + 0x7b, 0x22, 0x44, 0x30, 0x79, 0xe3, 0x62, 0x71, 0xaf, 0xda, 0xfe, 0x83, 0x10, 0x13, 0x53, 0xe5, + 0x94, 0x3c, 0x06, 0x64, 0xe5, 0xac, 0x1d, 0x7c, 0x17, 0x67, 0xd3, 0xc9, 0xae, 0xa5, 0xa2, 0x1d, + 0x20, 0x90, 0x7d, 0xd3, 0x94, 0xb8, 0x18, 0x66, 0x41, 0xea, 0x44, 0x9e, 0xba, 0x75, 0x4a, 0xcc, + 0xb7, 0xc9, 0xe3, 0x6a, 0x64, 0x34, 0x15, 0x13, 0x11, 0x2b, 0xb4, 0xf1, 0xb4, 0x27, 0x60, 0x5f, + 0x6b, 0x88, 0xd6, 0x66, 0x65, 0x30, 0x71, 0xfb, 0x29, 0x54, 0xe5, 0x5a, 0x16, 0x80, 0xd1, 0x67, + 0x63, 0x71, 0x34, 0xcc, 0x82, 0x08, 0xb7, 0x0b, 0x55, 0xcf, 0x7d, 0xc6, 0xc8, 0x10, 0x89, 0x57, + 0x75, 0x47, 0x80, 0x64, 0x4c, 0x02, 0x8b, 0x8b, 0x30, 0x2c, 0x85, 0x58, 0x43, 0x2f, 0xc7, 0x9d, + 0x3c, 0xe6, 0xef, 0xf9, 0xfc, 0xe1, 0x89, 0x14, 0x7b, 0x2f, 0x3c, 0x23, 0x34, 0x4a, 0x11, 0x68, + 0x46, 0x87, 0xcf, 0x18, 0x0a, 0x8c, 0x58, 0x6d, 0xb4, 0x03, 0xe4, 0xc5, 0xa8, 0x76, 0x72, 0x0f, + 0x68, 0xe3, 0x95, 0xf1, 0xa2, 0xbb, 0x68, 0x86, 0x46, 0x11, 0x11, 0xe0, 0x84, 0x1a, 0x30, 0x63, + 0x7a, 0xb6, 0x9b, 0x78, 0xa9, 0x41, 0x79, 0xa7, 0xf4, 0x82, 0x33, 0xee, 0xdb, 0x80, 0x0b, 0x07, + 0x78, 0xb6, 0xd7, 0x56, 0x7b, 0x10, 0xd1, 0x2a, 0xbc, 0x17, 0xd8, 0xf8, 0xee, 0x01, 0x69, 0x68, + 0xb0, 0x44, 0x23, 0xe4, 0x62, 0xab, 0x3b, 0xba, 0xfe, 0x9c, 0xda, 0x5b, 0xea, 0x9e, 0x8b, 0xc7, + 0xf3, 0xf9, 0x51, 0xa5, 0x3d, 0x40, 0x73, 0x71, 0xde, 0x9d, 0x76, 0x81, 0xe4, 0xf8, 0xfb, 0x69, + 0x8d, 0x64, 0x0d, 0x62, 0x0f, 0x60, 0x96, 0x73, 0xeb, 0xea, 0x11, 0xdc, 0x0e, 0xb5, 0xb7, 0xd2, + 0x07, 0xcc, 0x23, 0x06, 0xe7, 0x0d, 0xf8, 0x7e, 0x88, 0x9d, 0x76, 0x30, 0xd0, 0xe6, 0xf5, 0x78, + 0xfe, 0x82, 0x9f, 0x05, 0x17, 0x3d, 0x50, 0xbb, 0xd8, 0x53, 0xae, 0xf1, 0xd5, 0xfa, 0xc8, 0x9a, + 0xdd, 0x43, 0xd0, 0xdb, 0x48, 0xf8, 0xb8, 0xcd, 0x6f, 0x38, 0xc3, 0x59, 0xf4, 0xe9, 0x36, 0x53, + 0xde, 0xfc, 0x61, 0xfd, 0xbf, 0xb4, 0xbd, 0xc5, 0xeb, 0xdf, 0xc4, 0xa8, 0x34, 0x45, 0x4c, 0xe8, + 0xba, 0xc8, 0xac, 0xff, 0x0e, 0x8b, 0x0a, 0x42, 0x51, 0x35, 0xb0, 0x8a, 0xe5, 0x3d, 0x33, 0xc0, + 0xa9, 0x52, 0x80, 0x2c, 0x32, 0xec, 0x85, 0x29, 0xf4, 0x88, 0xa0, 0x03, 0x14, 0xbc, 0x23, 0xbf, + 0x55, 0x90, 0x89, 0xfa, 0x36, 0x8a, 0xdc, 0xb4, 0x10, 0x5f, 0x92, 0x61, 0x9c, 0x79, 0x2b, 0x36, + 0xdd, 0x3e, 0x65, 0x4f, 0x53, 0x56, 0xb5, 0xae, 0x00, 0x59, 0x21, 0x9a, 0xb5, 0xa2, 0xb7, 0xcc, + 0x4a, 0x29, 0xde, 0xb2, 0x12, 0x95, 0xd8, 0x06, 0xcc, 0xe4, 0x87, 0x90, 0x3a, 0xac, 0x77, 0xb8, + 0x9b, 0x87, 0x8c, 0xb5, 0x28, 0xf6, 0xfc, 0x8c, 0xcc, 0xe9, 0x09, 0x0f, 0x68, 0x6e, 0x85, 0xda, + 0xc1, 0xe1, 0xac, 0x2a, 0xad, 0x55, 0xeb, 0x97, 0x0f, 0x20, 0x32, 0xe0, 0xdb, 0x7d, 0xda, 0x35, + 0x0c, 0x99, 0x3f, 0x05, 0x9c, 0x63, 0x7a, 0xa0, 0xea, 0xcc, 0x99, 0xca, 0xf3, 0xe9, 0xb9, 0xb0, + 0xe5, 0x83, 0x60, 0x2d, 0xc9, 0x39, 0x93, 0x31, 0x1b, 0xe7, 0x3f, 0x97, 0x53, 0x06, 0xb5, 0xc9, + 0x4e, 0xda, 0xec, 0x76, 0xc0, 0x84, 0x20, 0xf4, 0x9e, 0x4b, 0x58, 0xfd, 0xf3, 0x4b, 0x7d, 0xf1, + 0x36, 0x0f, 0xbd, 0x8f, 0x56, 0xff, 0x11, 0x0f, 0x68, 0x34, 0xfd, 0x1d, 0xbc, 0x18, 0xdb, 0xdc, + 0xcb, 0x30, 0xd7, 0xe0, 0x78, 0xd4, 0x59, 0x49, 0x53, 0x6c, 0x8f, 0x7f, 0xcd, 0x96, 0x47, 0x4b, + 0x08, 0x2b, 0x9d, 0x94, 0xd6, 0xbe, 0x9c, 0xb4, 0x29, 0xaf, 0x73, 0x4d, 0xac, 0x84, 0xc1, 0xe2, + 0xbc, 0x53, 0xae, 0x42, 0x70, 0x05, 0x75, 0x8b, 0x76, 0xf0, 0xd2, 0x9d, 0x96, 0x33, 0x94, 0xc6, + 0xb3, 0x21, 0xc9, 0xc3, 0x4a, 0x43, 0x36, 0x40, 0xcf, 0x1e, 0x8f, 0x0d, 0xef, 0x28, 0x50, 0xb8, + 0xd5, 0x9a, 0xc6, 0x9d, 0xbd, 0xb5, 0x26, 0xf4, 0x39, 0xb1, 0xb4, 0x4d, 0xc8, 0xc0, 0x98, 0xdf, + 0x56, 0x89, 0x28, 0x4b, 0x55, 0x1a, 0xe2, 0x99, 0x77, 0x42, 0x8c, 0x92, 0x59, 0x73, 0x18, 0xd7, + 0x4f, 0xe8, 0x0e, 0x2e, 0xb5, 0x86, 0xfc, 0x4d, 0x77, 0x7e, 0xfc, 0xf4, 0xfe, 0xee, 0xa5, 0x06, + 0x13, 0xac, 0xe6, 0x63, 0xcc, 0x07, 0x30, 0xcc, 0x64, 0x46, 0xc1, 0x61, 0xc5, 0xf8, 0x03, 0xd1, + 0x42, 0x08, 0x7a, 0x38, 0x1e, 0xe1, 0xda, 0xdb, 0x36, 0x34, 0xe8, 0x4a, 0x48, 0xe4, 0x12, 0x2a, + 0x9f, 0x68, 0xa2, 0x4e, 0xf6, 0xeb, 0x8f, 0xdd, 0xba, 0x49, 0x55, 0x49, 0x06, 0xed, 0x70, 0x8e, + 0xd5, 0x1f, 0x2f, 0xb0, 0xb4, 0x92, 0x8d, 0xb6, 0x86, 0xb1, 0x15, 0x10, 0x46, 0x77, 0x97, 0xfb, + 0xd6, 0xd9, 0x79, 0x0a, 0xd1, 0x50, 0x1a, 0xce, 0xff, 0x66, 0x61, 0x50, 0x94, 0x56, 0x4a, 0x4b, + 0xc5, 0x14, 0x42, 0xc9, 0xa8, 0x0e, 0x51, 0x7d, 0x40, 0xce, 0x56, 0x6c, 0x53, 0x9d, 0x31, 0x26, + 0x89, 0xdd, 0xa3, 0x19, 0xf9, 0x21, 0x64, 0xbb, 0x86, 0xc8, 0xd1, 0x98, 0x9d, 0x57, 0x71, 0xe5, + 0xd0, 0x47, 0x9b, 0xfb, 0xa5, 0x54, 0x05, 0xe4, 0x98, 0x1b, 0xb4, 0x98, 0x99, 0xbd, 0x64, 0x34, + 0xaf, 0x11, 0xc6, 0x5e, 0x62, 0x13, 0x9b, 0xd7, 0x09, 0x13, 0x2f, 0x4d, 0x6a, 0xbd, 0x22, 0x2a, + 0x43, 0x1d, 0x10, 0xcc, 0x3d, 0xea, 0x7b, 0x63, 0xf3, 0x38, 0x52, 0x94, 0x20, 0x12, 0xe3, 0xc8, + 0x2a, 0x1c, 0xe4, 0x06, 0x74, 0x9b, 0xb0, 0x94, 0xc3, 0x82, 0x03, 0x6d, 0x01, 0xb1, 0x08, 0x08, + 0x4a, 0x46, 0x01, 0xf8, 0xb9, 0x3c, 0x6e, 0x98, 0x40, 0xe8, 0x75, 0xc4, 0x00, 0xa4, 0x93, 0x10, + 0x06, 0xf3, 0x74, 0xba, 0x62, 0xd9, 0x62, 0xc0, 0x2c, 0xd2, 0x0f, 0x8a, 0x71, 0x96, 0x41, 0x2e, + 0x5d, 0x02, 0xd2, 0x97, 0x06, 0x3c, 0xc1, 0x14, 0x22, 0x32, 0x3f, 0x38, 0xc7, 0x49, 0x22, 0x5d, + 0x27, 0xc6, 0x66, 0x11, 0x30, 0x01, 0x6a, 0xa8, 0xc2, 0xdc, 0xd3, 0x47, 0xa3, 0x10, 0x9f, 0x16, + 0xa6, 0x91, 0x6a, 0xcd, 0x88, 0x9e, 0x7d, 0x14, 0xfb, 0x8c, 0x38, 0x5b, 0xf2, 0xe4, 0xa6, 0x70, + 0xd0, 0xf0, 0x15, 0x03, 0xfa, 0xf7, 0x02, 0x23, 0x1b, 0x72, 0xe8, 0x83, 0x90, 0x0a, 0x65, 0x16, + 0x59, 0x18, 0x8c, 0xc9, 0x23, 0x34, 0x06, 0x2f, 0x19, 0xda, 0x52, 0x24, 0x7d, 0xb9, 0xc4, 0x7a, + 0x27, 0x66, 0x9c, 0x93, 0x86, 0x57, 0xe8, 0xe7, 0x74, 0xe9, 0xe0, 0x6d, 0xd6, 0x6f, 0x41, 0x2d, + 0x3c, 0x06, 0x79, 0x96, 0x82, 0x0e, 0xd7, 0x5a, 0x62, 0xff, 0x67, 0x5b, 0xe3, 0x39, 0x13, 0x1c, + 0xd9, 0x60, 0xb0, 0x3a, 0x07, 0xc8, 0x33, 0x6d, 0x6d, 0xe2, 0xb0, 0x94, 0xf1, 0x2a, 0x78, 0x06, + 0x0a, 0xe3, 0xe0, 0xc4, 0x19, 0xd0, 0xc3, 0x41, 0x09, 0x48, 0x91, 0x2b, 0x2f, 0x2f, 0x4f, 0x8d, + 0xf0, 0xd9, 0x02, 0xac, 0x70, 0x57, 0xbf, 0xbf, 0xe6, 0x58, 0x09, 0x47, 0xc8, 0x3f, 0xff, 0x92, + 0x22, 0x03, 0xc4, 0x2c, 0x9f, 0x63, 0x85, 0x20, 0xad, 0x60, 0xf9, 0xf0, 0xe7, 0xcf, 0xa0, 0x5c, + 0x2f, 0xe7, 0x7b, 0xfc, 0xf1, 0xd8, 0xbf, 0x95, 0xa3, 0xa3, 0x47, 0x6c, 0xf6, 0xba, 0x41, 0x34, + 0x32, 0x11, 0x7a, 0xd2, 0x20, 0x2f, 0x33, 0xba, 0xcd, 0x50, 0x55, 0x38, 0x77, 0xec, 0x83, 0xed, + 0x80, 0x82, 0xbe, 0x78, 0x55, 0xc0, 0x27, 0xbf, 0xf7, 0x94, 0xf7, 0x2c, 0x60, 0xb7, 0xfa, 0x50, + 0xe2, 0x80, 0xef, 0x4d, 0x7d, 0x2d, 0xbf, 0x37, 0x57, 0xd2, 0x2f, 0xb8, 0xd1, 0x81, 0x94, 0x0d, + 0x3f, 0xb5, 0x2a, 0xf6, 0xf7, 0x21, 0x49, 0x8e, 0x36, 0x04, 0x8a, 0xab, 0x18, 0xd2, 0x1a, 0x16, + 0x2a, 0x16, 0xfe, 0x9c, 0xbf, 0x96, 0xc6, 0xb7, 0xa9, 0x93, 0x89, 0x9d, 0x7f, 0xf4, 0xef, 0xdf, + 0xec, 0x96, 0x85, 0xb8, 0xa8, 0x7f, 0x17, 0x1f, 0x35, 0xef, 0xf2, 0x51, 0xf7, 0x2e, 0x37, 0xb9, + 0xd7, 0xbf, 0x27, 0xdf, 0xab, 0x98, 0x7b, 0xab, 0x1f, 0x0f, 0xfe, 0xc9, 0x58, 0xf4, 0xe9, 0x4c, + 0xfc, 0x0d, 0x35, 0x77, 0x7e, 0x9e, 0x57, 0xb9, 0xdb, 0x64, 0x65, 0x6d, 0xe4, 0x5b, 0xdf, 0x94, + 0x05, 0x1c, 0xe8, 0xab, 0xbe, 0x1b, 0xe2, 0x48, 0x55, 0x7b, 0x4b, 0x49, 0x22, 0x8b, 0xfb, 0xc2, + 0x27, 0xcd, 0xf5, 0xc7, 0x20, 0x01, 0xc5, 0x76, 0xae, 0xe8, 0x4c, 0x9b, 0x4c, 0x95, 0x41, 0x2b, + 0x33, 0x78, 0x73, 0x0b, 0xbd, 0x9b, 0xe2, 0x68, 0xe1, 0x0c, 0xb1, 0x5c, 0x46, 0xc0, 0x7d, 0x94, + 0x24, 0x91, 0x2b, 0x38, 0xef, 0x63, 0x71, 0x13, 0xde, 0x72, 0xb4, 0xa7, 0x78, 0x60, 0x04, 0x31, + 0x48, 0x7d, 0xde, 0x3f, 0xc6, 0x34, 0xe3, 0x3b, 0x74, 0x68, 0xdc, 0xab, 0xf3, 0x85, 0x75, 0xdc, + 0xda, 0xd3, 0xd0, 0x44, 0xfe, 0x99, 0x97, 0x0a, 0xe1, 0xdb, 0xc3, 0x89, 0x66, 0xfc, 0x45, 0x32, + 0xc7, 0xc5, 0x41, 0x59, 0x3e, 0xd5, 0xb3, 0x7d, 0x13, 0x2f, 0x8b, 0x1f, 0xfc, 0xd4, 0xf9, 0x05, + 0x9d, 0x43, 0x19, 0x08, 0xdb, 0x11, 0x94, 0x20, 0xcc, 0x9e, 0x9b, 0xfe, 0xe3, 0x5e, 0x42, 0xfa, + 0xb4, 0xd9, 0x76, 0x25, 0x22, 0x40, 0x91, 0x8c, 0xb4, 0x80, 0x32, 0x51, 0x11, 0x0b, 0x16, 0xae, + 0xff, 0xe4, 0x41, 0xa3, 0xc4, 0x79, 0x59, 0xa2, 0xd9, 0xb4, 0x03, 0x48, 0xe0, 0x42, 0xb9, 0x6f, + 0x7a, 0xb0, 0x80, 0x88, 0x60, 0xd4, 0x55, 0x76, 0x79, 0xf4, 0x88, 0x08, 0xb5, 0xba, 0xe2, 0x4b, + 0x61, 0xd2, 0x7c, 0xde, 0x79, 0x4b, 0x10, 0x8e, 0xee, 0x9b, 0xfe, 0x8b, 0x8a, 0x03, 0x46, 0xd8, + 0xde, 0xdf, 0x23, 0xe7, 0xed, 0x1a, 0x38, 0xe3, 0xe6, 0x85, 0x7e, 0xb9, 0xcd, 0x7e, 0xaf, 0x07, + 0xc6, 0x8f, 0xd5, 0x11, 0xad, 0xfd, 0xe3, 0xde, 0xe0, 0x34, 0x4d, 0x2f, 0xcd, 0x36, 0x02, 0x46, + 0x40, 0xe5, 0xc9, 0x04, 0x08, 0x39, 0x2d, 0x62, 0x99, 0xad, 0xc5, 0x63, 0xbd, 0x7d, 0x95, 0x0a, + 0xaf, 0x15, 0x36, 0x3a, 0x26, 0x50, 0x5e, 0x4d, 0x46, 0xd4, 0xf2, 0x52, 0x31, 0xc9, 0xd5, 0xe3, + 0xa3, 0xc3, 0xf6, 0xed, 0x45, 0x4c, 0xa4, 0xd5, 0x0a, 0x73, 0xdf, 0x48, 0x2c, 0x6b, 0x26, 0x6b, + 0xf1, 0x27, 0x68, 0x41, 0x85, 0xd7, 0xd9, 0x55, 0x55, 0x55, 0xad, 0xb5, 0xd7, 0xca, 0x5c, 0x5c, + 0xe0, 0x8e, 0xc0, 0x3b, 0xf5, 0x52, 0x8a, 0xb6, 0x53, 0x7c, 0x48, 0x9a, 0x50, 0xf3, 0xce, 0x8e, + 0xbc, 0x94, 0x67, 0x5d, 0xb0, 0x23, 0xe4, 0x1e, 0x1e, 0x9d, 0xd9, 0x4f, 0xf5, 0x8c, 0x8e, 0xe1, + 0x4e, 0x5a, 0x0b, 0xf8, 0x0b, 0x3b, 0xfc, 0xde, 0x57, 0x45, 0x6d, 0x9b, 0x18, 0x60, 0x55, 0xb6, + 0x2d, 0x83, 0x1c, 0xc8, 0x83, 0x87, 0xe9, 0xcc, 0xe4, 0x80, 0x6b, 0x0c, 0x4b, 0xc9, 0xb6, 0x29, + 0xbd, 0xc4, 0x6c, 0x45, 0xe6, 0x12, 0x8f, 0x1e, 0xd7, 0x44, 0xb3, 0x1d, 0xe2, 0x70, 0x57, 0x6c, + 0x8e, 0xff, 0xab, 0xcf, 0x98, 0x26, 0x03, 0x47, 0x26, 0x33, 0x66, 0x47, 0x55, 0x1f, 0x32, 0x8e, + 0xaa, 0xe6, 0xa3, 0x6e, 0x6f, 0x17, 0xee, 0x0d, 0x01, 0xea, 0x55, 0xab, 0x12, 0x8c, 0x0e, 0x8d, + 0xa3, 0x81, 0x2d, 0x0f, 0x97, 0x3f, 0x07, 0x18, 0x79, 0x00, 0x74, 0x6c, 0x10, 0x33, 0x8f, 0xce, + 0xf9, 0x8e, 0x9a, 0xd9, 0xc9, 0x83, 0x07, 0xe2, 0x9f, 0x01, 0x78, 0x0f, 0xcc, 0x8b, 0xc0, 0x23, + 0xf0, 0x55, 0x84, 0x0c, 0x1e, 0x70, 0x5c, 0xfc, 0x27, 0xcb, 0xd6, 0x4d, 0x90, 0x7a, 0xe8, 0x3f, + 0x8c, 0x15, 0x9e, 0x62, 0x26, 0xe9, 0xa0, 0xe1, 0xe3, 0x84, 0xd4, 0xaa, 0xb3, 0x83, 0x47, 0xdb, + 0xeb, 0xd3, 0xf0, 0x69, 0x85, 0xd2, 0x49, 0xf7, 0xee, 0xde, 0xae, 0x25, 0x1f, 0x98, 0x04, 0x71, + 0xde, 0x3c, 0x15, 0x0a, 0x6c, 0x78, 0xf2, 0xea, 0x8a, 0x03, 0xba, 0x87, 0xb1, 0xa0, 0x8c, 0xf6, + 0xca, 0xa2, 0xdf, 0xc1, 0xed, 0x7d, 0x1b, 0x72, 0x1f, 0x2a, 0x2a, 0x3c, 0x1d, 0x84, 0x9b, 0x99, + 0x80, 0x1a, 0xe4, 0x98, 0xd8, 0x4c, 0x46, 0xa3, 0xed, 0x9b, 0xdd, 0x62, 0x87, 0xf5, 0xfd, 0xb9, + 0x21, 0x4d, 0x85, 0xd0, 0x93, 0x35, 0xdc, 0xa1, 0xd4, 0x66, 0xe6, 0x1e, 0xe2, 0x55, 0xdd, 0xed, + 0x35, 0x14, 0x9d, 0xc7, 0x5d, 0xf0, 0x29, 0x20, 0x16, 0x2f, 0x82, 0xca, 0xa5, 0x73, 0x8c, 0x4a, + 0xaa, 0x7b, 0x2a, 0x71, 0x4f, 0x27, 0x41, 0x3f, 0x09, 0xd8, 0x89, 0xa0, 0x05, 0x80, 0x2c, 0x33, + 0x4a, 0x47, 0xdc, 0x7a, 0xf9, 0x56, 0x19, 0xf5, 0xb5, 0x4e, 0x92, 0x85, 0x0f, 0x5e, 0x0f, 0xb4, + 0x1e, 0x17, 0xee, 0x22, 0x05, 0x3c, 0x51, 0x8a, 0x6e, 0xd8, 0x1e, 0x91, 0x72, 0x26, 0xea, 0x0a, + 0x0d, 0xbc, 0x8c, 0x4b, 0x6c, 0x73, 0x14, 0x8c, 0x5c, 0x12, 0x22, 0x88, 0xed, 0x1c, 0xbe, 0xd5, + 0x08, 0xd7, 0xb6, 0x0c, 0x69, 0x1a, 0x43, 0x42, 0x51, 0x72, 0x20, 0xd7, 0xe5, 0x8b, 0xad, 0xf3, + 0xf5, 0x13, 0x46, 0x2d, 0xda, 0x66, 0x55, 0x40, 0xce, 0xf2, 0xb8, 0x81, 0xf3, 0x8e, 0xc4, 0x9d, + 0x01, 0x8f, 0x65, 0xd5, 0xdd, 0xfa, 0x9c, 0x03, 0x5d, 0xde, 0xe3, 0x69, 0x93, 0x7e, 0x1e, 0x13, + 0xc6, 0xb8, 0x87, 0xe0, 0xdd, 0x19, 0x1f, 0xb3, 0x5d, 0xfa, 0xc2, 0x77, 0x66, 0x4c, 0x10, 0x18, + 0xb3, 0xb5, 0x95, 0xcc, 0xc4, 0xf1, 0x64, 0x9b, 0xf7, 0x46, 0x3f, 0xef, 0xb8, 0x0a, 0x9d, 0x09, + 0xb1, 0x6c, 0xcb, 0x52, 0xfa, 0xfe, 0x4a, 0xdb, 0x19, 0xa2, 0xdb, 0x0d, 0xc1, 0xec, 0xda, 0xe5, + 0xfe, 0xf9, 0x9e, 0xb2, 0x5e, 0x2b, 0x75, 0x44, 0x0c, 0xaf, 0xde, 0x2d, 0x48, 0xa4, 0xc9, 0x6e, + 0xac, 0xc1, 0x22, 0x95, 0xd9, 0xf4, 0xe7, 0x1d, 0x19, 0xba, 0xf5, 0x2e, 0xa3, 0x62, 0xfe, 0xdb, + 0x79, 0x41, 0x50, 0x4f, 0x9e, 0x61, 0x77, 0xcf, 0x13, 0xbe, 0x5c, 0x33, 0x7e, 0xb7, 0x6d, 0x7d, + 0x49, 0xeb, 0x41, 0x01, 0x23, 0x36, 0x5a, 0x47, 0x9b, 0xfe, 0x41, 0xc7, 0x1b, 0x28, 0x6b, 0x78, + 0xc7, 0x5d, 0xb2, 0xc9, 0xbb, 0x3c, 0x93, 0xa1, 0xf1, 0xfd, 0xd6, 0xd0, 0x40, 0x1e, 0xb5, 0x67, + 0x38, 0xe5, 0x49, 0xf7, 0xa9, 0xd6, 0x0b, 0x1a, 0xd3, 0x06, 0xbe, 0xb8, 0xc8, 0x99, 0xb6, 0x97, + 0x63, 0x03, 0x96, 0x25, 0x0d, 0x31, 0x1c, 0x67, 0x74, 0xc2, 0x95, 0xe2, 0xa8, 0x27, 0xdc, 0xae, + 0x59, 0x35, 0x4f, 0x4e, 0x26, 0x1a, 0xbd, 0xf7, 0xe3, 0x5b, 0xe6, 0x3d, 0xd0, 0x10, 0x98, 0xfd, + 0x44, 0x4d, 0x88, 0x0f, 0x40, 0xff, 0x5f, 0x37, 0x3b, 0xbf, 0x57, 0x6a, 0x62, 0xca, 0x0b, 0xa4, + 0xc0, 0x1f, 0xdc, 0xb9, 0x67, 0xb3, 0xe3, 0xd8, 0x39, 0x88, 0x00, 0x00, 0x25, 0xf0, 0xc9, 0x9b, + 0x69, 0xb5, 0x22, 0xd2, 0xcb, 0x30, 0x61, 0xdc, 0x0b, 0x88, 0x1f, 0x97, 0x08, 0x5f, 0xd9, 0x2b, + 0xdc, 0xdd, 0x0c, 0x36, 0x2a, 0x41, 0x01, 0x05, 0x54, 0x3e, 0x54, 0x36, 0x31, 0xc4, 0x97, 0x69, + 0xb1, 0x49, 0x97, 0x9f, 0x75, 0xff, 0x27, 0x2f, 0x27, 0x7b, 0xdc, 0x18, 0x9b, 0xa0, 0x49, 0xfd, + 0x2e, 0x7b, 0x44, 0x79, 0xd1, 0x8b, 0xdd, 0x21, 0xc3, 0x50, 0x05, 0x0d, 0x75, 0x60, 0x20, 0xb3, + 0x22, 0x6d, 0x23, 0x09, 0x87, 0x9d, 0x2c, 0x88, 0x61, 0x02, 0x34, 0x7b, 0x12, 0x97, 0x11, 0x50, + 0x21, 0x93, 0x6f, 0x2a, 0x15, 0x30, 0x9b, 0x3f, 0xcc, 0xed, 0xd7, 0x95, 0xba, 0xb9, 0xf4, 0x46, + 0x76, 0x25, 0x06, 0xa7, 0x2b, 0xec, 0x1c, 0xea, 0xe9, 0x8c, 0x9e, 0x60, 0x41, 0x31, 0xf2, 0x10, + 0x3d, 0x8a, 0xea, 0x7f, 0x2c, 0x03, 0xe2, 0xbe, 0xd9, 0xe9, 0x15, 0x96, 0x97, 0x71, 0xd1, 0x25, + 0xf9, 0x26, 0xa1, 0xd8, 0xc6, 0x3b, 0x70, 0xdd, 0xe4, 0x57, 0x40, 0xe0, 0x69, 0xfd, 0xc9, 0x9a, + 0x5f, 0x62, 0xd6, 0x16, 0xa4, 0x99, 0xc1, 0xb4, 0x26, 0xf6, 0x31, 0x4f, 0x34, 0x3e, 0xe1, 0x8a, + 0x47, 0xc3, 0x52, 0x8e, 0x1f, 0xd2, 0xca, 0x99, 0x54, 0xc7, 0x7a, 0x6b, 0x40, 0x31, 0x9d, 0x56, + 0xc4, 0x6d, 0x62, 0x5c, 0xea, 0xa9, 0x3e, 0x7d, 0x19, 0x65, 0x43, 0x0b, 0xcf, 0x3b, 0x0b, 0x9c, + 0x11, 0xa5, 0x51, 0x62, 0x5a, 0x1b, 0xa9, 0xce, 0x97, 0x38, 0xc7, 0x88, 0xf7, 0xb8, 0xf0, 0xb7, + 0x9a, 0xeb, 0x0c, 0xb5, 0x43, 0xd9, 0xef, 0x12, 0xed, 0x2f, 0x09, 0x25, 0x37, 0x66, 0x73, 0x41, + 0x46, 0x8c, 0xaa, 0xeb, 0x68, 0x91, 0x02, 0xe8, 0xcd, 0x3a, 0x85, 0x70, 0x54, 0xbb, 0xb5, 0xb7, + 0xd1, 0xbb, 0x45, 0xef, 0x36, 0xfa, 0xb7, 0xe8, 0xdf, 0xc6, 0xe0, 0x7f, 0x6b, 0x30, 0x8b, 0x86, + 0xcf, 0xab, 0x94, 0x22, 0x0f, 0xb4, 0x0c, 0x7e, 0x98, 0x98, 0xaf, 0xa7, 0x8d, 0xba, 0x44, 0x51, + 0xf9, 0x2c, 0xba, 0x66, 0x94, 0xf3, 0x86, 0xa3, 0xc4, 0x62, 0x3d, 0x6b, 0x2d, 0x0d, 0x1d, 0x55, + 0x5b, 0x97, 0xd4, 0xde, 0x5e, 0x3e, 0x65, 0x66, 0xb1, 0xa8, 0xeb, 0x65, 0x92, 0xd8, 0x79, 0xa4, + 0x62, 0x87, 0x78, 0xd8, 0xb6, 0x9e, 0x01, 0xd8, 0xb5, 0x47, 0xbf, 0x6a, 0xe3, 0xe4, 0x84, 0x4d, + 0xe6, 0xc6, 0xb8, 0x40, 0x39, 0x86, 0x7b, 0xf8, 0x05, 0x71, 0x2d, 0xd5, 0x4b, 0x45, 0x67, 0xc3, + 0x3b, 0x3b, 0xe7, 0xd4, 0xe5, 0x1c, 0x1d, 0x02, 0x5e, 0x44, 0x9f, 0x93, 0x4d, 0x3e, 0x30, 0x28, + 0xae, 0x91, 0xac, 0x26, 0x30, 0x59, 0xc1, 0x08, 0x69, 0xd6, 0x33, 0xf1, 0x0d, 0x42, 0xcf, 0x18, + 0x1a, 0x43, 0x58, 0x57, 0xd7, 0x78, 0x6d, 0xe5, 0x7a, 0x70, 0x32, 0x9d, 0x0b, 0x68, 0x5e, 0xe8, + 0xb1, 0x93, 0x69, 0xf0, 0x1a, 0x5f, 0x14, 0xd3, 0x0f, 0x1d, 0xdb, 0x45, 0x8d, 0x01, 0xcb, 0x3f, + 0x76, 0x09, 0x68, 0x5d, 0x47, 0x13, 0xf1, 0x75, 0x7d, 0x61, 0x97, 0xec, 0x09, 0xb1, 0x29, 0xdc, + 0x9f, 0xde, 0x0e, 0x53, 0x7e, 0x63, 0x32, 0x20, 0xbf, 0x70, 0x2d, 0x20, 0xbf, 0x37, 0x15, 0x90, + 0x27, 0x45, 0xf5, 0x7e, 0x6c, 0xec, 0xbd, 0x69, 0xb3, 0xaf, 0x8e, 0x25, 0xd7, 0x4e, 0x5a, 0xff, + 0xda, 0xaf, 0x6e, 0x71, 0xed, 0x47, 0xbb, 0xb9, 0xf6, 0x43, 0xde, 0x7d, 0x07, 0xcf, 0x5c, 0x1b, + 0xb3, 0xa9, 0x85, 0xde, 0xee, 0x67, 0xd1, 0x9e, 0x2f, 0x4d, 0x3d, 0x33, 0x28, 0xcb, 0xbb, 0xe7, + 0x33, 0x1e, 0x5c, 0x45, 0xdf, 0xab, 0xa4, 0xdf, 0x98, 0xd4, 0x03, 0x19, 0xe7, 0x39, 0xf6, 0x3e, + 0x36, 0xc0, 0xbc, 0x63, 0xd9, 0xe7, 0xe5, 0x19, 0x0e, 0x11, 0xe9, 0x89, 0x74, 0x70, 0x15, 0xe6, + 0x2a, 0x33, 0xdb, 0xc4, 0x82, 0xf9, 0xc9, 0xce, 0xb2, 0xe8, 0xcd, 0x63, 0xdf, 0xe7, 0x04, 0x9c, + 0xef, 0xd0, 0x74, 0x04, 0xaf, 0xe5, 0x80, 0x79, 0x27, 0xad, 0x75, 0xca, 0xac, 0x51, 0x7e, 0x43, + 0xa4, 0x3f, 0xdc, 0x71, 0xb3, 0xfd, 0xb7, 0xf2, 0x75, 0x55, 0x31, 0x40, 0x12, 0x8f, 0x92, 0x1e, + 0xd5, 0xfa, 0x72, 0x4a, 0x58, 0xcc, 0x15, 0xbd, 0xa6, 0x58, 0x6c, 0x02, 0xe2, 0x60, 0x5b, 0xbd, + 0x99, 0x2e, 0x73, 0x5b, 0xf6, 0xec, 0xc8, 0x49, 0xdb, 0xec, 0xd7, 0x4e, 0x3f, 0x13, 0x0e, 0x8a, + 0x81, 0xbd, 0xbc, 0x02, 0x69, 0x80, 0x44, 0x4c, 0xe6, 0x8d, 0x0b, 0x77, 0x77, 0x18, 0x8a, 0x75, + 0xff, 0xa8, 0xb9, 0x32, 0xa9, 0x72, 0xd8, 0xc8, 0xd8, 0x21, 0x2f, 0x7e, 0x69, 0x16, 0xcb, 0xf1, + 0x71, 0x5c, 0xf6, 0x23, 0x95, 0x69, 0x83, 0x8a, 0xd1, 0x1c, 0xa9, 0x3a, 0xd1, 0x81, 0x0e, 0x76, + 0x58, 0xc6, 0x14, 0x16, 0xf1, 0xa3, 0x71, 0x4e, 0x51, 0x3b, 0x4d, 0x29, }; -const unsigned int html_content_br_len = 3296; +const unsigned int html_content_br_len = 5148; #endif // HTML_CONTENT_BR_H \ No newline at end of file diff --git a/main/webpage_gzip.h b/main/webpage_gzip.h index d7d5e2a..7455eb8 100644 --- a/main/webpage_gzip.h +++ b/main/webpage_gzip.h @@ -4,253 +4,384 @@ #include const unsigned char PROGMEM html_content_gz[] = { - 0x1f, 0x8b, 0x08, 0x00, 0xc7, 0x88, 0x54, 0x69, 0x02, 0xff, 0xbd, 0x1a, 0xfd, 0x77, 0xda, 0x46, - 0xf2, 0xf7, 0xfc, 0x15, 0x1b, 0x27, 0xe7, 0x4a, 0x89, 0x10, 0x60, 0x3b, 0x69, 0x22, 0x2c, 0xdc, - 0xc4, 0x71, 0x9a, 0xf6, 0x12, 0xdb, 0xcf, 0x1f, 0xbd, 0x77, 0xe7, 0xf2, 0xac, 0x45, 0x5a, 0x40, - 0xb5, 0xd0, 0x52, 0x69, 0x31, 0xe6, 0x88, 0xfe, 0xf7, 0x9b, 0xd9, 0x5d, 0x7d, 0x00, 0x32, 0xce, - 0xa5, 0x77, 0x8e, 0x5f, 0x40, 0x5a, 0xcd, 0xce, 0xcc, 0xce, 0xf7, 0x8c, 0xd8, 0x7f, 0x1a, 0x70, - 0x5f, 0xcc, 0x27, 0x8c, 0x8c, 0xc4, 0x38, 0xea, 0xee, 0x8b, 0x50, 0x44, 0xac, 0x7b, 0xc8, 0x63, - 0x91, 0xf0, 0x88, 0x9c, 0xd2, 0x98, 0x45, 0xfb, 0x4d, 0xb5, 0xb8, 0x3f, 0x66, 0x82, 0x12, 0x1f, - 0x1e, 0xb1, 0x58, 0xb8, 0x5b, 0xb3, 0x30, 0x10, 0x23, 0x37, 0x60, 0xb7, 0xa1, 0xcf, 0x1a, 0xf2, - 0xc6, 0x0a, 0xe3, 0x50, 0x84, 0x34, 0x6a, 0xa4, 0x3e, 0x8d, 0x98, 0xdb, 0xb6, 0x5b, 0x5b, 0x24, - 0xa6, 0x63, 0xe6, 0xde, 0x86, 0x6c, 0x36, 0xe1, 0x89, 0xe8, 0xee, 0xa7, 0x62, 0x0e, 0x98, 0x9e, - 0xcd, 0x12, 0x3a, 0x99, 0xb0, 0x64, 0x21, 0xd8, 0x9d, 0x68, 0xd0, 0x28, 0x1c, 0xc6, 0x8e, 0x0f, - 0x48, 0x59, 0xd2, 0xe9, 0xf3, 0xbb, 0x46, 0x1a, 0xfe, 0x3b, 0x8c, 0x87, 0x4e, 0x9f, 0x27, 0x01, - 0x4b, 0x1a, 0xb0, 0x92, 0x3d, 0xd3, 0x54, 0x17, 0x63, 0x7a, 0xa7, 0x68, 0x39, 0xaf, 0x5a, 0xad, - 0xc9, 0x5d, 0x67, 0x4c, 0x93, 0x61, 0x18, 0x3b, 0x74, 0x2a, 0x78, 0x67, 0x42, 0x83, 0x00, 0xf7, - 0xb5, 0x48, 0x1b, 0x1e, 0x65, 0x7d, 0x1e, 0xcc, 0x6b, 0x08, 0xe8, 0x1d, 0xad, 0x12, 0x3c, 0x7b, - 0xb1, 0xf0, 0x79, 0xc4, 0x13, 0xe7, 0xd9, 0xce, 0x00, 0xff, 0x3a, 0x7d, 0xea, 0xdf, 0x0c, 0x13, - 0x3e, 0x8d, 0x83, 0x86, 0x7e, 0x30, 0x18, 0x0c, 0x3a, 0x03, 0x60, 0xa1, 0x31, 0xa0, 0xe3, 0x30, - 0x9a, 0x3b, 0xc7, 0x5c, 0x70, 0x72, 0x4e, 0xe3, 0xd4, 0xfa, 0x8d, 0x25, 0x01, 0x8d, 0xa9, 0x95, - 0xc2, 0x4d, 0x23, 0x65, 0x49, 0xa8, 0x01, 0xe1, 0x0c, 0xcc, 0x69, 0xdb, 0x3b, 0x09, 0x1b, 0x67, - 0x61, 0x3c, 0x99, 0x0a, 0xab, 0x3f, 0x15, 0x82, 0xc7, 0x55, 0x8e, 0x92, 0x70, 0x38, 0x12, 0xf5, - 0x27, 0xae, 0xe1, 0x81, 0x0d, 0x58, 0xc0, 0xde, 0x76, 0x14, 0x8c, 0xd3, 0x9e, 0xdc, 0x91, 0x94, - 0x47, 0x61, 0x40, 0x9e, 0xf5, 0xe9, 0xdb, 0xd7, 0xaf, 0xfa, 0xfa, 0x41, 0x23, 0xa1, 0x41, 0x38, - 0x4d, 0x9d, 0x57, 0x20, 0x1c, 0x25, 0xa8, 0x76, 0xab, 0xf5, 0x37, 0xc5, 0xc2, 0x15, 0xea, 0xd9, - 0x45, 0x06, 0x7a, 0x56, 0x65, 0x21, 0x9e, 0x8e, 0xfb, 0x2c, 0xe9, 0x2d, 0xaa, 0x07, 0x1c, 0xf3, - 0x98, 0xa7, 0x13, 0xea, 0xb3, 0x6c, 0x9d, 0x6d, 0x25, 0xc8, 0xcc, 0xf6, 0x47, 0x34, 0x1e, 0xb2, - 0xc0, 0x02, 0xe5, 0x8c, 0xc7, 0xa1, 0xb8, 0xee, 0x8b, 0x78, 0x51, 0xca, 0xeb, 0x69, 0x38, 0x46, - 0x95, 0xd3, 0x58, 0xd4, 0x9c, 0x65, 0x87, 0xee, 0xbd, 0xdd, 0x0d, 0x4a, 0x90, 0x6c, 0x09, 0xc7, - 0x34, 0x49, 0x01, 0x68, 0xc2, 0x43, 0x6d, 0x11, 0xf2, 0xc0, 0x31, 0x8f, 0x59, 0xe5, 0x44, 0x5a, - 0x8f, 0x0d, 0xc1, 0x27, 0x0e, 0xaa, 0xbb, 0x50, 0xa7, 0xbc, 0x91, 0x47, 0x99, 0x31, 0x94, 0xaf, - 0xf3, 0x63, 0xab, 0x55, 0x45, 0x7f, 0x15, 0x84, 0x29, 0xed, 0x47, 0x2c, 0xe8, 0xe5, 0xcc, 0xbe, - 0x79, 0xf3, 0xa6, 0xa3, 0x69, 0xc6, 0x1c, 0x0f, 0x19, 0xf1, 0x19, 0x0b, 0x6a, 0xb8, 0xde, 0xdb, - 0xdb, 0xab, 0xb0, 0x2c, 0x10, 0xcb, 0x42, 0x4b, 0x1d, 0x20, 0x22, 0x3a, 0x49, 0x99, 0x93, 0x5f, - 0x74, 0x2a, 0x02, 0x8b, 0xd8, 0x40, 0x54, 0x95, 0x21, 0x82, 0x45, 0xa1, 0x69, 0x10, 0xee, 0xb8, - 0xaa, 0x4c, 0xad, 0xe5, 0xfc, 0x34, 0x6f, 0xc0, 0x90, 0xd3, 0xe9, 0x18, 0x0e, 0xbb, 0x64, 0xcb, - 0x12, 0x63, 0xc5, 0x36, 0xd7, 0x79, 0xfd, 0x71, 0x67, 0xb7, 0xc6, 0x22, 0x72, 0xb4, 0xf6, 0x2e, - 0xd8, 0xe5, 0x9a, 0x94, 0x6c, 0x7f, 0x9c, 0x73, 0xa6, 0xc4, 0x5d, 0xb5, 0xe4, 0x57, 0x68, 0xc9, - 0xcf, 0xc6, 0xe9, 0xb0, 0xc6, 0x14, 0x46, 0xed, 0x45, 0x09, 0xba, 0xa3, 0x40, 0x7f, 0x1a, 0xb3, - 0x20, 0xa4, 0x24, 0xf5, 0x13, 0xc6, 0x62, 0x42, 0xe3, 0x80, 0x18, 0x52, 0x04, 0xfb, 0xee, 0xee, - 0x2b, 0x50, 0x91, 0xb9, 0xa8, 0xf1, 0x69, 0xa9, 0xd8, 0xd2, 0x8d, 0x81, 0x63, 0x25, 0x65, 0x22, - 0x12, 0x22, 0x85, 0x56, 0xe7, 0x29, 0x95, 0xad, 0xa0, 0xda, 0x49, 0x44, 0xe7, 0x4e, 0x3f, 0xe2, - 0xfe, 0x4d, 0xb1, 0x75, 0xa1, 0x4d, 0x25, 0x17, 0x36, 0x1a, 0xc8, 0x32, 0x64, 0xb6, 0xdf, 0x54, - 0x81, 0x69, 0xbf, 0x39, 0x62, 0x34, 0xe8, 0xee, 0x63, 0xec, 0xe8, 0xee, 0x07, 0xe1, 0x2d, 0x09, - 0x03, 0x57, 0x07, 0xab, 0xe2, 0x5e, 0xf3, 0xdd, 0xdd, 0x1f, 0xb5, 0xbb, 0x87, 0xd1, 0xd4, 0xbf, - 0x39, 0x04, 0xe3, 0x82, 0x03, 0xc2, 0xe6, 0x36, 0x04, 0x50, 0xa4, 0x0a, 0x5f, 0x00, 0x2f, 0x10, - 0x93, 0x74, 0x1f, 0xc2, 0x63, 0x3f, 0x0a, 0xfd, 0x1b, 0x77, 0x2b, 0x65, 0x71, 0xa0, 0xe1, 0x8d, - 0x1f, 0x52, 0x41, 0x13, 0xf1, 0x83, 0xb9, 0x45, 0xfc, 0x88, 0xa6, 0xa9, 0x0b, 0xe2, 0xef, 0x9e, - 0x5f, 0xbc, 0x3b, 0xbb, 0xd8, 0x6f, 0xaa, 0x6d, 0xc0, 0x0f, 0xe2, 0xf8, 0x06, 0x3c, 0x7c, 0xb2, - 0x84, 0x86, 0xc8, 0xe3, 0xb8, 0x0f, 0x59, 0x08, 0x50, 0x3b, 0x39, 0xfd, 0x6f, 0x89, 0x01, 0x0a, - 0xbe, 0xcc, 0xf3, 0xe5, 0xf1, 0x87, 0x93, 0x15, 0x2c, 0x4d, 0x3c, 0x7f, 0x33, 0x97, 0x45, 0x55, - 0x24, 0x90, 0x40, 0x22, 0x88, 0x2c, 0xb1, 0xbb, 0xdb, 0xdd, 0x97, 0x41, 0x08, 0x45, 0x0a, 0x66, - 0x45, 0x12, 0x90, 0x3c, 0x8f, 0xa3, 0x79, 0x15, 0xc3, 0x86, 0x2d, 0x61, 0x7c, 0x2d, 0xc2, 0x31, - 0x43, 0x26, 0x65, 0x1c, 0x72, 0x41, 0xcb, 0x37, 0x87, 0x2a, 0x24, 0x19, 0x62, 0x14, 0xa6, 0x26, - 0x08, 0x81, 0x4d, 0xdc, 0x36, 0x91, 0x41, 0x2e, 0xa0, 0x82, 0x21, 0x7c, 0x03, 0x14, 0x4e, 0xa3, - 0x2e, 0xc9, 0xcf, 0x08, 0x98, 0x62, 0x3e, 0xc3, 0xc0, 0x50, 0x1c, 0x37, 0x65, 0xe2, 0x02, 0x20, - 0x2f, 0xf8, 0x31, 0x9f, 0x19, 0x66, 0xf7, 0x7c, 0x1e, 0xfb, 0x04, 0x17, 0xea, 0x8e, 0xa8, 0xd5, - 0x7c, 0xee, 0x8f, 0x58, 0x30, 0x05, 0x6b, 0x3b, 0x47, 0x8d, 0x96, 0x82, 0x2c, 0x0f, 0xc8, 0x6f, - 0xd9, 0xb5, 0x54, 0x77, 0xc9, 0xb0, 0xfa, 0xca, 0xb7, 0x6a, 0x9e, 0x55, 0x88, 0x06, 0x6a, 0x9b, - 0xa8, 0x1c, 0xa1, 0xb1, 0xd5, 0xd3, 0x00, 0x4d, 0xfd, 0x05, 0x0a, 0xcf, 0xc8, 0x17, 0x40, 0x92, - 0x36, 0x3f, 0xd0, 0x79, 0x0d, 0x01, 0x48, 0x14, 0xd7, 0x48, 0x24, 0x25, 0xe3, 0x30, 0x76, 0x5b, - 0xdf, 0x42, 0x47, 0xe5, 0x96, 0x1a, 0x4a, 0x67, 0x6c, 0x4c, 0xc3, 0xd8, 0x26, 0x1f, 0x42, 0x90, - 0x4a, 0xec, 0x33, 0x62, 0x0c, 0x84, 0x59, 0x43, 0x33, 0x91, 0x70, 0xe0, 0xf2, 0xd7, 0xe0, 0xb2, - 0x62, 0x93, 0xb6, 0x37, 0xd3, 0xc3, 0x73, 0x3d, 0x48, 0x2c, 0x48, 0x42, 0x10, 0xa1, 0x24, 0xf4, - 0xd7, 0x4f, 0xf8, 0x2b, 0x78, 0x1c, 0xf9, 0x24, 0xa3, 0x2b, 0x31, 0xc2, 0xb8, 0x8e, 0xde, 0x1f, - 0x00, 0xf2, 0xbf, 0x22, 0xf7, 0x9e, 0x0a, 0x08, 0xc5, 0x73, 0x62, 0xfc, 0x56, 0x47, 0xe9, 0x96, - 0x47, 0x82, 0x0e, 0xd9, 0x06, 0x27, 0xeb, 0x9e, 0x26, 0x7c, 0x98, 0xd0, 0x31, 0x39, 0xfb, 0x48, - 0x40, 0x39, 0x5c, 0xb0, 0x7b, 0xe3, 0xc1, 0x44, 0x41, 0x9e, 0x7d, 0x3c, 0x67, 0x7f, 0x4e, 0x19, - 0xc8, 0x13, 0xbc, 0x24, 0xdf, 0xfd, 0x2e, 0x8a, 0xc8, 0x7b, 0x09, 0x9e, 0x6e, 0x0a, 0x09, 0x1a, - 0x63, 0x9e, 0x8b, 0x55, 0x58, 0xcd, 0x53, 0x74, 0x41, 0x48, 0x2d, 0x9d, 0x52, 0x40, 0x9c, 0xa2, - 0x27, 0x52, 0xd0, 0xa1, 0x52, 0x7a, 0x05, 0x79, 0x3f, 0x51, 0xff, 0x03, 0xa8, 0x4e, 0xc3, 0x28, - 0x85, 0x1a, 0x53, 0xe5, 0xcb, 0xee, 0x87, 0x77, 0xc7, 0x3f, 0x1f, 0x9d, 0x91, 0x7f, 0x9d, 0x1c, - 0x1f, 0x41, 0x7c, 0xd7, 0x8b, 0x64, 0x25, 0x40, 0x1f, 0x42, 0x22, 0xeb, 0x27, 0x54, 0x84, 0x3c, - 0xbe, 0x3f, 0xfe, 0xf9, 0x1a, 0x88, 0x19, 0x3f, 0xa0, 0xca, 0x20, 0xfa, 0x29, 0xed, 0x2e, 0x6d, - 0xd6, 0xfc, 0x90, 0x4d, 0xbb, 0xa5, 0x81, 0xe1, 0xf6, 0x0f, 0x78, 0x51, 0xbb, 0x7f, 0x5d, 0x31, - 0x1f, 0xc3, 0x64, 0x3c, 0xa3, 0x09, 0x5b, 0x55, 0x2b, 0xf5, 0x7d, 0x36, 0x11, 0xae, 0xdd, 0x0f, - 0x65, 0x18, 0x1b, 0x68, 0xb0, 0xeb, 0x41, 0x88, 0x69, 0x0f, 0x8d, 0x05, 0xaf, 0x96, 0x42, 0xdd, - 0x74, 0x12, 0x71, 0x1a, 0x2c, 0xc9, 0x58, 0x2d, 0xe5, 0x34, 0x40, 0xca, 0x97, 0x72, 0x81, 0x94, - 0x54, 0xef, 0x65, 0xec, 0x33, 0x1f, 0x02, 0x58, 0xb4, 0x6e, 0x28, 0x40, 0x29, 0xe2, 0xc3, 0x25, - 0x32, 0x01, 0x9f, 0xc5, 0x88, 0x17, 0xf6, 0xe0, 0x16, 0xa0, 0xf3, 0x41, 0xaf, 0x10, 0x58, 0xda, - 0x60, 0x2a, 0x5a, 0x61, 0x88, 0x53, 0x6b, 0xae, 0x78, 0xb0, 0x31, 0x4d, 0x25, 0xac, 0xcf, 0xb9, - 0xf8, 0xae, 0xac, 0x78, 0x76, 0xf4, 0xfe, 0xe4, 0xa4, 0x9a, 0x84, 0x0b, 0xd3, 0x6a, 0x42, 0x09, - 0x90, 0x7f, 0x42, 0x65, 0x13, 0x4e, 0x44, 0x37, 0x62, 0x82, 0x4c, 0xd0, 0x42, 0x7f, 0xa3, 0xd1, - 0x94, 0xa5, 0xee, 0x55, 0xcf, 0x92, 0xb7, 0xc7, 0xd0, 0xf8, 0x94, 0x77, 0x97, 0xd0, 0x19, 0xe1, - 0x1d, 0x14, 0x6d, 0x31, 0xb8, 0x3b, 0xb8, 0x38, 0x9c, 0xa7, 0x0b, 0xad, 0xd7, 0x74, 0x0c, 0xa5, - 0x84, 0x3d, 0x64, 0xe2, 0x28, 0x62, 0x78, 0xf9, 0x7e, 0xfe, 0x4b, 0x60, 0x84, 0x81, 0xd9, 0xa1, - 0x29, 0xe6, 0x9d, 0xc1, 0x34, 0xf6, 0xd1, 0x3c, 0x48, 0xf5, 0x6c, 0x70, 0x14, 0xc4, 0x6e, 0x2e, - 0xf4, 0x85, 0xeb, 0xba, 0x9e, 0xcc, 0x2d, 0xde, 0xf6, 0xf6, 0x53, 0x20, 0x80, 0x96, 0x60, 0x78, - 0xff, 0x08, 0xc1, 0x15, 0xfb, 0x0c, 0x2a, 0x1f, 0x02, 0x41, 0x1b, 0x22, 0x28, 0x69, 0x90, 0x49, - 0xc4, 0x68, 0xca, 0x88, 0x86, 0xb1, 0x3d, 0xf3, 0xeb, 0xd7, 0x0a, 0x0e, 0x25, 0xb2, 0x25, 0x24, - 0x1f, 0x64, 0x7b, 0x47, 0x66, 0x88, 0x4b, 0x3d, 0x06, 0x2c, 0x3e, 0x60, 0x49, 0x10, 0xa1, 0x8f, - 0xd5, 0x93, 0xac, 0xed, 0x02, 0x1d, 0x59, 0x6d, 0xf2, 0x2e, 0x61, 0x64, 0xce, 0xa7, 0x24, 0x9d, - 0x26, 0xec, 0x00, 0x09, 0xd0, 0x19, 0x0d, 0x05, 0x19, 0x30, 0xe1, 0x8f, 0x0c, 0xcf, 0x6e, 0x02, - 0x3d, 0xcf, 0x5a, 0x40, 0x2b, 0x39, 0xe2, 0x81, 0xe3, 0x9d, 0x9e, 0x9c, 0x5f, 0x78, 0x16, 0x16, - 0x5d, 0x2c, 0x49, 0x9d, 0xc5, 0xd6, 0xa1, 0xaa, 0xad, 0x1a, 0x17, 0x60, 0xbe, 0x5b, 0x8e, 0x07, - 0x85, 0x17, 0xa8, 0x56, 0x3a, 0x48, 0xf3, 0x8f, 0x94, 0xc7, 0x5e, 0x66, 0x61, 0x69, 0xe6, 0xfc, - 0x7a, 0x7e, 0x72, 0x6c, 0xa7, 0x02, 0x99, 0x08, 0x07, 0x73, 0x03, 0x05, 0xe1, 0xe8, 0x83, 0x64, - 0x26, 0xfc, 0xad, 0x08, 0xaf, 0xf4, 0x40, 0x7a, 0x07, 0x91, 0x74, 0xf1, 0x58, 0x2c, 0x79, 0x40, - 0xf8, 0xfa, 0xf9, 0x02, 0x89, 0x66, 0x2a, 0xfb, 0x7b, 0xc8, 0x5e, 0x07, 0x6d, 0x86, 0x8e, 0x05, - 0x06, 0xd2, 0xf1, 0x44, 0x18, 0xde, 0x69, 0xc2, 0xd2, 0x94, 0x14, 0xe6, 0x8c, 0xfa, 0x62, 0x89, - 0x4d, 0x96, 0x96, 0xe9, 0x10, 0xf2, 0x20, 0x81, 0xb6, 0x13, 0x8b, 0x3d, 0x12, 0x0a, 0x9b, 0x5c, - 0x8c, 0x58, 0x6c, 0x49, 0x47, 0x27, 0xf0, 0x84, 0xfa, 0x62, 0x4a, 0x23, 0x28, 0x77, 0x21, 0x48, - 0x46, 0x18, 0x52, 0x73, 0x95, 0x90, 0x11, 0x4b, 0x24, 0x44, 0x08, 0xd9, 0x85, 0xa5, 0x8e, 0x67, - 0x76, 0xc2, 0x81, 0xf1, 0x34, 0x4c, 0x8f, 0xe9, 0xb1, 0x01, 0xc6, 0x99, 0xb2, 0x8f, 0xe0, 0x86, - 0xc2, 0x00, 0x86, 0x4c, 0xd3, 0x5c, 0x20, 0x6f, 0x40, 0x77, 0x02, 0x76, 0xca, 0xdc, 0x47, 0x15, - 0x14, 0x38, 0x81, 0x12, 0x0f, 0xb0, 0x97, 0x73, 0x60, 0xf3, 0x1b, 0xc5, 0x12, 0xd4, 0x6f, 0x54, - 0xb3, 0x53, 0x3c, 0x43, 0xac, 0x06, 0x78, 0x0a, 0x88, 0x17, 0xcd, 0x57, 0x06, 0x57, 0xef, 0xc0, - 0xa8, 0x96, 0x06, 0x43, 0x66, 0x78, 0x50, 0x29, 0xbe, 0xf6, 0x4c, 0xd3, 0xbe, 0x45, 0x07, 0xc5, - 0x42, 0x90, 0xda, 0xac, 0x09, 0xa7, 0xb5, 0x6a, 0x00, 0x7f, 0x5c, 0x01, 0x14, 0x08, 0xf8, 0x02, - 0xfa, 0x78, 0xd3, 0xa9, 0x81, 0x7e, 0x53, 0x07, 0x9d, 0x65, 0x59, 0x61, 0x78, 0xd5, 0x3d, 0x2c, - 0x32, 0x17, 0x09, 0x13, 0xd3, 0x24, 0x26, 0x2c, 0xb2, 0x65, 0x50, 0xfa, 0x0c, 0x2a, 0xb2, 0xa1, - 0xdd, 0x31, 0x3c, 0xdd, 0x4b, 0x7b, 0xa6, 0x85, 0xa8, 0xcb, 0x54, 0xe8, 0x99, 0x76, 0x9e, 0x23, - 0xdd, 0xa7, 0x6d, 0x8b, 0x45, 0x25, 0x6e, 0xc1, 0x3f, 0x86, 0x77, 0x80, 0x57, 0x4d, 0x17, 0x62, - 0x25, 0x26, 0x28, 0x0f, 0xdc, 0x8a, 0x4e, 0xe5, 0x33, 0xb3, 0xa3, 0xc9, 0x2a, 0x95, 0x03, 0x88, - 0x79, 0x10, 0x4f, 0xa3, 0xc8, 0x39, 0x96, 0xb5, 0x04, 0x2e, 0xd8, 0x39, 0xb2, 0xd8, 0x5c, 0x73, - 0x1e, 0xa9, 0x7d, 0xa8, 0x6b, 0xc5, 0x14, 0x72, 0xf0, 0x42, 0x40, 0x23, 0xba, 0xc9, 0x44, 0x52, - 0x09, 0xa8, 0x6d, 0xac, 0xaa, 0x45, 0xc5, 0x43, 0xe7, 0x01, 0x5d, 0xc2, 0x2e, 0x8c, 0x90, 0x3c, - 0x62, 0x36, 0x64, 0x10, 0x03, 0x21, 0x4d, 0x4b, 0xc9, 0x36, 0xc4, 0x88, 0xa7, 0xb7, 0x33, 0xd7, - 0x68, 0xbe, 0x20, 0x3f, 0x5d, 0x5f, 0x9f, 0x5e, 0x9e, 0x1d, 0x5d, 0x5f, 0x93, 0x17, 0x4d, 0x12, - 0xb3, 0x19, 0xf9, 0x80, 0x2e, 0x5e, 0x40, 0xbf, 0x68, 0xb3, 0x5d, 0xd0, 0x8f, 0xe0, 0xbf, 0x9c, - 0x9f, 0x9c, 0x4b, 0x7b, 0x33, 0x4c, 0x3b, 0x05, 0x9b, 0x64, 0x46, 0xcb, 0x6a, 0xbf, 0x35, 0x3b, - 0x5a, 0x8b, 0x08, 0xeb, 0x55, 0xf4, 0xc8, 0x32, 0x7c, 0xa0, 0x2b, 0xa6, 0xe2, 0x41, 0x2e, 0x21, - 0x89, 0xbe, 0xaf, 0x8a, 0x2d, 0x6b, 0x47, 0xe9, 0x6b, 0xb9, 0x48, 0xad, 0xdf, 0xb2, 0x0c, 0x93, - 0xef, 0x84, 0xc6, 0xc7, 0x5b, 0x32, 0x21, 0x58, 0xb0, 0xaa, 0xe9, 0x44, 0x2e, 0xca, 0xe7, 0xe9, - 0xd7, 0xaf, 0xcb, 0xb9, 0x45, 0x3e, 0xc2, 0xf9, 0x5a, 0xe5, 0x89, 0xca, 0x33, 0xf2, 0xc9, 0x14, - 0x2f, 0xe5, 0x93, 0x0d, 0x26, 0xd5, 0x52, 0xc2, 0x4d, 0x84, 0x7f, 0x0d, 0x6d, 0xcf, 0xd7, 0xaf, - 0xc6, 0xb2, 0x4c, 0x56, 0xac, 0x94, 0x25, 0x09, 0x4f, 0xc0, 0x46, 0x8b, 0xf4, 0x70, 0x28, 0x13, - 0x40, 0x0c, 0x59, 0x01, 0x76, 0xdb, 0x44, 0xb6, 0x4a, 0xb3, 0x50, 0x8c, 0x08, 0x56, 0xac, 0x44, - 0xcd, 0x06, 0x7f, 0x48, 0x55, 0x9e, 0x80, 0x64, 0xb0, 0xbd, 0x6d, 0x2c, 0x37, 0x57, 0x96, 0x62, - 0x0b, 0x57, 0x0c, 0x08, 0x3e, 0x19, 0x84, 0x0b, 0x30, 0x23, 0xcc, 0x6c, 0xda, 0x08, 0x24, 0x45, - 0xc3, 0x3b, 0xc2, 0x2f, 0x4c, 0xb3, 0x29, 0xa6, 0x1d, 0x8c, 0x20, 0x9e, 0xc5, 0xcc, 0x2c, 0x81, - 0xa4, 0xc8, 0x92, 0x0b, 0x3c, 0x8b, 0x61, 0x66, 0x95, 0x5c, 0x09, 0xdb, 0x83, 0xf4, 0x82, 0x7f, - 0xfa, 0xf4, 0xe5, 0x8b, 0xa1, 0xef, 0x72, 0xe7, 0xf3, 0x9e, 0x2f, 0xb4, 0x31, 0x7c, 0xa1, 0x62, - 0x64, 0x0f, 0x22, 0x0e, 0x04, 0x34, 0x4c, 0x73, 0xf7, 0x75, 0xab, 0x05, 0x26, 0x33, 0xa1, 0x81, - 0x6c, 0xe4, 0x8c, 0x1d, 0xcb, 0x6b, 0x79, 0x66, 0xe6, 0x6c, 0xd8, 0xf3, 0x37, 0xdc, 0xd3, 0x7c, - 0x5d, 0xb7, 0xcd, 0x2b, 0x59, 0x5a, 0xe2, 0x54, 0x5a, 0xb1, 0x2c, 0x62, 0x5c, 0x14, 0xb7, 0xbc, - 0x02, 0x8f, 0x19, 0x00, 0xd2, 0x8e, 0xbc, 0xb1, 0x13, 0x3e, 0x4b, 0xed, 0x88, 0xc5, 0x43, 0x31, - 0xea, 0xb6, 0x3a, 0xa6, 0x5a, 0x0c, 0x18, 0xec, 0x63, 0x67, 0x20, 0xb7, 0x96, 0xd9, 0x29, 0xed, - 0xc0, 0x86, 0x7d, 0x47, 0x14, 0xc4, 0x66, 0xa0, 0x2d, 0x58, 0xa1, 0xe9, 0x76, 0x95, 0x87, 0xf2, - 0x99, 0xaa, 0x98, 0xec, 0x10, 0x1c, 0x2c, 0x11, 0xb8, 0x71, 0x0d, 0xbb, 0x69, 0x4d, 0xe4, 0x84, - 0xb6, 0x44, 0x77, 0x15, 0xf6, 0x9e, 0xba, 0xd0, 0x2f, 0x84, 0x01, 0x69, 0x6d, 0x6f, 0xaf, 0xae, - 0x63, 0xdc, 0x38, 0x58, 0x5a, 0x74, 0x3c, 0x5c, 0xf3, 0xac, 0x09, 0x18, 0xa9, 0x5b, 0xb1, 0xdc, - 0x1a, 0x3c, 0xd5, 0x07, 0x25, 0xa2, 0x62, 0x55, 0x63, 0xea, 0x00, 0x7b, 0xc0, 0x72, 0xcc, 0x92, - 0x4f, 0x17, 0x5f, 0x3e, 0xbb, 0xde, 0x13, 0x52, 0xf3, 0x0f, 0xab, 0xcd, 0xe7, 0x8b, 0x30, 0x93, - 0xf5, 0xe2, 0x06, 0x08, 0x79, 0xba, 0x07, 0xa0, 0x74, 0x39, 0x2d, 0x2b, 0xe6, 0xad, 0xe7, 0x0b, - 0xfc, 0xe6, 0x03, 0x22, 0xcf, 0xe3, 0x7a, 0xaa, 0xdf, 0xf2, 0x0e, 0xf2, 0x0b, 0xc7, 0xc3, 0xf1, - 0x97, 0x97, 0x6d, 0x61, 0x41, 0xba, 0x05, 0x9e, 0x82, 0x5c, 0x6c, 0x11, 0xe5, 0xc1, 0xb0, 0x1b, - 0xb7, 0xc1, 0x3d, 0x8f, 0x25, 0x52, 0x77, 0x6b, 0xad, 0x4f, 0xdd, 0xea, 0x3e, 0xc8, 0x73, 0xe1, - 0xc8, 0x20, 0x94, 0xaf, 0x5f, 0x3d, 0xef, 0x1e, 0xfe, 0x21, 0x59, 0x4a, 0x9b, 0x41, 0x65, 0xab, - 0x23, 0x00, 0xdb, 0x35, 0x25, 0x65, 0xfa, 0x7e, 0x7e, 0x41, 0x87, 0xa8, 0x2f, 0x74, 0x6d, 0x80, - 0x83, 0xac, 0x25, 0xbf, 0xd1, 0xa9, 0x8f, 0x6e, 0x01, 0x02, 0x3d, 0x9c, 0x81, 0xc0, 0x21, 0x4c, - 0x60, 0x25, 0x0d, 0xbe, 0x05, 0x36, 0xc4, 0x6c, 0xb0, 0x65, 0xc0, 0x62, 0xa7, 0x60, 0x77, 0xbe, - 0x30, 0x30, 0x33, 0xa3, 0xb9, 0x16, 0x53, 0x80, 0x22, 0x70, 0x55, 0xd5, 0xd8, 0x56, 0xe1, 0xa6, - 0x9c, 0x77, 0x14, 0x50, 0xcb, 0x5e, 0x59, 0xdd, 0xb3, 0xd3, 0x33, 0xcb, 0x4d, 0xe0, 0x28, 0xdf, - 0xb0, 0x65, 0x57, 0x6f, 0x29, 0x3b, 0xf6, 0x5a, 0x6e, 0xf6, 0x14, 0x37, 0x45, 0x9f, 0x5d, 0x0b, - 0xf4, 0xaa, 0x57, 0xfa, 0xe9, 0x4a, 0xe3, 0x0d, 0x91, 0x08, 0x32, 0xd2, 0x52, 0x16, 0x37, 0x2d, - 0x70, 0xa8, 0xc0, 0x55, 0xa6, 0xa1, 0x05, 0x01, 0x71, 0x4d, 0xc7, 0xcd, 0x76, 0x41, 0x81, 0xa9, - 0xef, 0xba, 0x22, 0x03, 0x80, 0xcc, 0x12, 0x4d, 0x55, 0x54, 0xe8, 0xb8, 0x57, 0x23, 0x3e, 0x4d, - 0x52, 0x6b, 0x1c, 0xc6, 0x53, 0xc1, 0xd2, 0x5e, 0x8e, 0xc8, 0x4e, 0xa1, 0x9c, 0x82, 0x5a, 0x11, - 0xea, 0x37, 0x7b, 0x4c, 0x27, 0x86, 0x4a, 0xde, 0x45, 0x12, 0xdb, 0x29, 0x08, 0xcb, 0xed, 0x2f, - 0x30, 0x2a, 0xbd, 0xd4, 0x38, 0x5e, 0xbc, 0x6e, 0xd5, 0xb1, 0x01, 0x5b, 0xcc, 0x0c, 0x8e, 0xb7, - 0xc4, 0x88, 0x14, 0xff, 0xf7, 0xb3, 0xb1, 0xfb, 0xdf, 0xb3, 0xb1, 0x8b, 0x6c, 0xe4, 0x3c, 0x54, - 0xf4, 0x59, 0x0a, 0x75, 0xef, 0x5b, 0x84, 0xba, 0xb7, 0x24, 0xd4, 0x52, 0xe3, 0x25, 0x9a, 0x57, - 0xdf, 0x82, 0xe6, 0x15, 0xa2, 0xa9, 0xa6, 0x92, 0x6a, 0xba, 0x92, 0x71, 0x55, 0x05, 0xed, 0x22, - 0x47, 0x76, 0xd6, 0xac, 0x43, 0xd1, 0xb8, 0xbf, 0x40, 0x91, 0x35, 0xc9, 0x67, 0x1c, 0x43, 0x32, - 0x9d, 0x55, 0xbc, 0xf4, 0xb6, 0x71, 0x7e, 0xe4, 0xad, 0xf7, 0x2d, 0x95, 0xec, 0x28, 0x75, 0x82, - 0xd5, 0xc9, 0x29, 0x58, 0x8a, 0x85, 0xb4, 0xf1, 0xa2, 0xe7, 0xd6, 0x14, 0x31, 0xb9, 0x8e, 0x2e, - 0x20, 0x55, 0x5f, 0xcd, 0xa1, 0x57, 0xb3, 0xc6, 0x50, 0x9a, 0x8f, 0x20, 0xd5, 0xcf, 0x7b, 0x6e, - 0x8e, 0x22, 0x07, 0x6a, 0x2c, 0x2b, 0xd2, 0x92, 0x7a, 0xd7, 0x6a, 0xb7, 0x94, 0x03, 0xba, 0xad, - 0x9e, 0x9b, 0x13, 0xbc, 0x47, 0xff, 0x16, 0x9b, 0x70, 0x7f, 0xe4, 0x56, 0xd2, 0x23, 0x1e, 0xd5, - 0xbe, 0xbc, 0x38, 0x34, 0x4a, 0x06, 0x1a, 0x6d, 0x64, 0xc1, 0x5a, 0x27, 0x60, 0x36, 0xb1, 0x54, - 0xeb, 0x18, 0x6b, 0xb5, 0xe4, 0x5f, 0xef, 0x36, 0x24, 0x5f, 0x20, 0xef, 0xbc, 0x00, 0xcc, 0x40, - 0xfa, 0xfc, 0x66, 0x7b, 0xfb, 0xbe, 0x3a, 0x07, 0xca, 0x34, 0x70, 0x83, 0x6a, 0x41, 0x5e, 0x44, - 0xd4, 0x3f, 0xa7, 0x50, 0xf2, 0x9d, 0xcb, 0x60, 0xc8, 0x93, 0x77, 0x51, 0xa4, 0xa3, 0xa9, 0x5d, - 0x80, 0xea, 0x9c, 0x0a, 0xf6, 0xd7, 0x3a, 0xd8, 0x54, 0x73, 0x39, 0x9b, 0x6a, 0xfc, 0x7a, 0x1b, - 0xc8, 0x67, 0x60, 0x8b, 0x4d, 0x78, 0x65, 0x71, 0xad, 0xb9, 0xf9, 0x05, 0x59, 0x83, 0x4a, 0xf0, - 0x9b, 0x99, 0xb7, 0xd2, 0x89, 0xbb, 0xc8, 0xd6, 0x13, 0xca, 0x12, 0x3e, 0x13, 0xc2, 0x85, 0xda, - 0xa7, 0xdc, 0xac, 0x90, 0xa0, 0xd2, 0x5c, 0xd5, 0x5e, 0x3b, 0x2c, 0x4a, 0xa1, 0xed, 0x5c, 0x86, - 0x5f, 0x2d, 0x94, 0xa5, 0x43, 0xdd, 0x55, 0x3b, 0x96, 0xfb, 0xcb, 0xe9, 0x75, 0xfb, 0xf8, 0xff, - 0xb5, 0xa3, 0x2b, 0x1c, 0x58, 0xd0, 0xd6, 0x39, 0x77, 0xd9, 0x92, 0xf1, 0xac, 0x31, 0xb9, 0xc1, - 0x86, 0xb2, 0x55, 0x59, 0xd8, 0x32, 0xde, 0xa7, 0xff, 0x80, 0x52, 0x59, 0x9a, 0xa1, 0xa7, 0x1b, - 0x6f, 0xf9, 0x5e, 0x23, 0x07, 0x51, 0x8e, 0x06, 0xcf, 0x20, 0xa9, 0x76, 0xd2, 0xc9, 0x55, 0x18, - 0xf4, 0xf4, 0x53, 0x15, 0xbd, 0xd4, 0xb5, 0x2c, 0x5b, 0xca, 0x42, 0x05, 0x4b, 0xec, 0x35, 0x50, - 0x19, 0x6f, 0x66, 0x2c, 0x39, 0xa4, 0x29, 0x68, 0x46, 0x41, 0x43, 0xa5, 0xa5, 0xba, 0xc0, 0xd5, - 0x76, 0x51, 0x4b, 0xdb, 0xcc, 0x4e, 0xfa, 0x7f, 0x80, 0xb5, 0xd8, 0x37, 0x6c, 0x9e, 0x02, 0xce, - 0xdc, 0xba, 0xa1, 0x76, 0x83, 0x7a, 0xce, 0x58, 0xf3, 0xd5, 0xc9, 0xff, 0x5c, 0x15, 0x40, 0x53, - 0x09, 0xfc, 0x60, 0xc9, 0x06, 0x8b, 0x7a, 0x57, 0x55, 0x58, 0xdd, 0x45, 0x2e, 0xb1, 0xa7, 0x15, - 0x83, 0xdc, 0xde, 0xd6, 0xe6, 0xbd, 0x41, 0x29, 0xe6, 0x46, 0x3f, 0x34, 0xad, 0xca, 0x09, 0xf3, - 0xf6, 0x77, 0xd5, 0x39, 0x57, 0x87, 0xa7, 0x52, 0x89, 0x38, 0x75, 0x95, 0xac, 0xca, 0xd8, 0xbc, - 0x34, 0x96, 0xd5, 0x7d, 0x71, 0x01, 0x61, 0xe3, 0x55, 0x51, 0x8b, 0x2f, 0x20, 0x23, 0x40, 0xf7, - 0xe0, 0x1d, 0x73, 0x89, 0x83, 0xa8, 0xc2, 0x0b, 0x79, 0xd5, 0x1d, 0x7c, 0x96, 0xa3, 0x77, 0x57, - 0x30, 0x5c, 0xb5, 0x7a, 0x9d, 0x87, 0x3a, 0x73, 0x2e, 0xe8, 0xf7, 0xa9, 0x88, 0x03, 0x0f, 0xa2, - 0x01, 0x7a, 0x61, 0x74, 0x9c, 0xab, 0x0a, 0xa9, 0x66, 0xc8, 0x56, 0xd1, 0xe0, 0x1f, 0x68, 0xe6, - 0xf5, 0xf8, 0x38, 0x9d, 0xfa, 0x3e, 0x4b, 0xd3, 0xc1, 0x34, 0xb2, 0x89, 0x1e, 0x22, 0x8e, 0xe9, - 0x5c, 0xcf, 0x10, 0x6d, 0xcf, 0x74, 0x96, 0xc1, 0x07, 0x14, 0x10, 0x06, 0x0e, 0xf1, 0x5e, 0x16, - 0x28, 0xd5, 0x24, 0x41, 0xf7, 0x84, 0x85, 0x68, 0x98, 0x98, 0xf1, 0xe4, 0x86, 0xc8, 0xbe, 0x90, - 0x04, 0x53, 0x39, 0x86, 0x54, 0x5a, 0x00, 0x8d, 0x96, 0x79, 0xbb, 0x78, 0x45, 0x61, 0x84, 0xe6, - 0xe2, 0x31, 0x02, 0xc6, 0x00, 0xec, 0x1f, 0x4d, 0x2b, 0x66, 0x91, 0x13, 0xd6, 0xcd, 0x20, 0x6b, - 0x5e, 0x9a, 0x48, 0x75, 0xa9, 0xf1, 0x9e, 0x9e, 0x16, 0x7b, 0x1f, 0x79, 0x02, 0xc6, 0x02, 0x5c, - 0x7a, 0x67, 0xec, 0x16, 0xd8, 0x62, 0x70, 0x75, 0x09, 0xa8, 0x3d, 0x9c, 0x96, 0x7b, 0x3d, 0x0b, - 0x27, 0xaf, 0x31, 0x0b, 0x0e, 0x79, 0x80, 0xe0, 0xe8, 0xbf, 0xd6, 0xf2, 0x47, 0x4f, 0x1a, 0x58, - 0xd1, 0xa0, 0x5f, 0x60, 0x1f, 0x2e, 0xa7, 0xb7, 0x9a, 0x3e, 0xa1, 0x70, 0xbd, 0x87, 0x2f, 0x79, - 0x12, 0xf9, 0x92, 0x47, 0xd3, 0x4f, 0x71, 0x40, 0x98, 0x6a, 0xce, 0xec, 0x27, 0x4f, 0xd4, 0xe8, - 0xf1, 0xe4, 0xef, 0x38, 0x70, 0x94, 0x33, 0x64, 0x0b, 0x5a, 0x7a, 0x16, 0x93, 0x01, 0xc7, 0x5f, - 0x47, 0xe0, 0x35, 0x51, 0xc3, 0xcb, 0x14, 0x74, 0x99, 0xcf, 0x76, 0x1e, 0x2f, 0x3c, 0x0f, 0xae, - 0xe5, 0x0c, 0xfa, 0x5a, 0xb0, 0xf1, 0x44, 0xce, 0x0c, 0xad, 0xc7, 0xa4, 0xad, 0xa3, 0x84, 0x1a, - 0x56, 0x16, 0x09, 0xd3, 0x6d, 0x75, 0xc2, 0xfd, 0xbd, 0x4e, 0xf8, 0xf2, 0xa5, 0xb9, 0xa8, 0x9a, - 0x9f, 0x66, 0x0d, 0xcb, 0xbf, 0x53, 0x10, 0x59, 0x08, 0x21, 0x18, 0x84, 0xcb, 0xa3, 0x5b, 0x68, - 0xb2, 0x74, 0x79, 0xc9, 0xa7, 0x22, 0x5f, 0xb3, 0xda, 0x38, 0x81, 0xb0, 0xb4, 0xb9, 0xab, 0x37, - 0x69, 0x04, 0x7a, 0xcc, 0x97, 0xed, 0xac, 0xb9, 0xe7, 0xc0, 0x55, 0xc5, 0x5e, 0xa0, 0x3d, 0xcc, - 0x7e, 0x8f, 0x7f, 0x8f, 0x95, 0xb2, 0x50, 0x27, 0x6b, 0x8f, 0x2b, 0x43, 0xe5, 0x39, 0x94, 0x5d, - 0xb9, 0xd2, 0x63, 0x68, 0xb1, 0xcb, 0x9d, 0xa0, 0xe6, 0x19, 0x2a, 0x37, 0xe0, 0x31, 0x23, 0x06, - 0xf8, 0xd5, 0x1f, 0xd3, 0x54, 0x80, 0x7e, 0x4b, 0x13, 0x00, 0x61, 0xdf, 0x32, 0x32, 0x8d, 0xf5, - 0xb9, 0xc6, 0x2c, 0x30, 0x41, 0xef, 0x56, 0x79, 0xcc, 0x46, 0xdb, 0xd4, 0x01, 0xa8, 0xb4, 0x4f, - 0xa0, 0xef, 0xaa, 0x34, 0x61, 0x3c, 0xa6, 0x76, 0xf4, 0x04, 0x52, 0x65, 0x6b, 0x35, 0x56, 0x84, - 0xe4, 0xac, 0x19, 0x7a, 0x60, 0xc2, 0x04, 0x7d, 0x9f, 0x7f, 0x83, 0x21, 0x05, 0xfc, 0x43, 0xe1, - 0x71, 0x70, 0xd0, 0x64, 0xad, 0x1e, 0xab, 0xd1, 0xce, 0x56, 0x97, 0x5c, 0x58, 0xdc, 0xde, 0x7e, - 0xd4, 0x83, 0x32, 0xa1, 0x1c, 0x00, 0x2a, 0x81, 0x80, 0xdd, 0x39, 0xa1, 0x85, 0xa7, 0x74, 0x80, - 0x37, 0x0c, 0x3f, 0xb5, 0x76, 0x59, 0x54, 0x76, 0x79, 0xdb, 0xf0, 0x7c, 0xf1, 0xf6, 0x65, 0x98, - 0x61, 0x5a, 0xc2, 0x55, 0xc8, 0xeb, 0x95, 0x12, 0xc0, 0x5d, 0x39, 0xe2, 0x52, 0xbb, 0xa4, 0x26, - 0xcb, 0xa6, 0xcc, 0x48, 0x2b, 0x95, 0x63, 0x85, 0x20, 0x94, 0x22, 0x80, 0xbf, 0xb7, 0x8a, 0x09, - 0x63, 0xd4, 0x63, 0x16, 0x10, 0x90, 0x02, 0xbe, 0x4b, 0x1a, 0x0f, 0xd7, 0x10, 0xdf, 0xd5, 0x1c, - 0xe8, 0x96, 0xf4, 0xbe, 0x32, 0x1e, 0x52, 0xc7, 0x23, 0x5a, 0x11, 0x8b, 0xcb, 0x58, 0x26, 0x95, - 0xa9, 0x5e, 0x94, 0xbb, 0x5e, 0xf1, 0x3b, 0x00, 0xa2, 0xdf, 0xed, 0x8f, 0xd1, 0x31, 0x0e, 0x21, - 0xe8, 0xe3, 0x18, 0xf2, 0xe9, 0x93, 0x27, 0x5e, 0xad, 0xca, 0xeb, 0xfc, 0xe2, 0x40, 0x23, 0x7d, - 0xe9, 0x7a, 0x6b, 0x11, 0xca, 0x21, 0xc7, 0x5c, 0x90, 0x32, 0xb0, 0xfc, 0x1e, 0x7b, 0xce, 0x46, - 0xf0, 0xe7, 0xab, 0x41, 0x06, 0x62, 0xa0, 0xd7, 0x51, 0x01, 0x53, 0x6f, 0xfc, 0xa6, 0xda, 0x6d, - 0xed, 0x8d, 0xf4, 0x83, 0xef, 0x36, 0x22, 0x3e, 0xac, 0x79, 0xb1, 0x21, 0x46, 0x09, 0x64, 0xc4, - 0x23, 0x15, 0x46, 0xf2, 0xfa, 0x24, 0x07, 0x20, 0x33, 0x9a, 0xca, 0xf9, 0x38, 0xbf, 0xf1, 0x94, - 0x7c, 0xfb, 0x11, 0xef, 0xaf, 0xbe, 0xfc, 0xc0, 0x35, 0xc3, 0xb4, 0x20, 0x2a, 0xbb, 0xf7, 0x4d, - 0x0d, 0x2c, 0x90, 0xf5, 0x18, 0xdf, 0x3a, 0x04, 0x78, 0xe7, 0x96, 0x53, 0x6c, 0x0c, 0xe5, 0x43, - 0x26, 0xf2, 0xc9, 0xc2, 0xea, 0x0c, 0xfa, 0xf9, 0xe2, 0xca, 0xfb, 0xf5, 0xdd, 0x31, 0x54, 0x10, - 0x1f, 0x8f, 0xde, 0xc3, 0xe7, 0x97, 0x77, 0x67, 0xf0, 0xf9, 0xee, 0xf4, 0x4c, 0x5e, 0xff, 0x13, - 0x3e, 0x7f, 0xbd, 0x3c, 0x96, 0x9f, 0x9f, 0x71, 0xfd, 0xf2, 0x67, 0xf8, 0x3c, 0x3f, 0x3a, 0x85, - 0xcf, 0x93, 0x43, 0x30, 0x33, 0xef, 0xf8, 0xe4, 0x37, 0xac, 0x3e, 0x8e, 0x0e, 0xbd, 0xde, 0x95, - 0x26, 0xf5, 0x05, 0x7b, 0x79, 0xc3, 0xec, 0x01, 0x6e, 0xbd, 0xf2, 0x11, 0x0a, 0x8f, 0x7f, 0x82, - 0x52, 0x40, 0xc8, 0x8d, 0x55, 0xc6, 0x3e, 0xe1, 0x1c, 0xa8, 0x9e, 0xb3, 0x65, 0xc0, 0x2f, 0x6a, - 0x4a, 0x54, 0x07, 0xea, 0x59, 0xd3, 0x24, 0x72, 0x2f, 0xcf, 0x3e, 0xdb, 0x3e, 0x14, 0xa1, 0x82, - 0xa9, 0xce, 0x04, 0xee, 0x0d, 0x94, 0x1c, 0x68, 0xbb, 0xec, 0x73, 0x15, 0x80, 0x9e, 0x7c, 0x1a, - 0x1e, 0x05, 0xa9, 0x53, 0x7b, 0x94, 0xb0, 0x81, 0x0b, 0x28, 0x2c, 0x6a, 0xe7, 0x5a, 0xc7, 0x37, - 0xe6, 0x3c, 0xa1, 0x43, 0x06, 0x0c, 0x2f, 0x89, 0x36, 0xc3, 0xdf, 0x53, 0x78, 0x65, 0xd7, 0x8f, - 0xce, 0x63, 0xe3, 0x0f, 0x00, 0xe3, 0xe0, 0x70, 0x14, 0x46, 0x81, 0x41, 0x81, 0x9e, 0x2d, 0xe7, - 0xa4, 0x86, 0xb9, 0x02, 0xa6, 0xe2, 0x43, 0x01, 0x86, 0x0c, 0x27, 0xec, 0x96, 0xdf, 0x54, 0x18, - 0x06, 0x2e, 0x8a, 0xd7, 0x1c, 0x68, 0x32, 0x6b, 0x89, 0xa8, 0xf8, 0x59, 0x84, 0x2e, 0x89, 0x21, - 0xff, 0x48, 0xb8, 0x2c, 0x9b, 0x41, 0x98, 0x07, 0x51, 0x71, 0xc5, 0x7f, 0xc5, 0xb6, 0x3b, 0xfb, - 0x4d, 0xfd, 0x63, 0x84, 0xfd, 0xa6, 0xfa, 0xe5, 0x62, 0x53, 0xfe, 0x98, 0xfb, 0x3f, 0xe8, 0x8e, - 0xf2, 0xea, 0xdc, 0x2d, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x98, 0xec, 0x59, 0x69, 0x02, 0xff, 0xed, 0x3c, 0xfb, 0x57, 0xdb, 0xc6, + 0xd2, 0x3f, 0xdf, 0xfe, 0x15, 0x0b, 0x49, 0x88, 0x94, 0xc8, 0xc2, 0xe6, 0x91, 0xb6, 0x36, 0x72, + 0x2e, 0x01, 0xa7, 0x4d, 0x1b, 0x1e, 0x87, 0x47, 0xda, 0xfb, 0x71, 0x39, 0x48, 0xb6, 0xd6, 0x58, + 0x8d, 0x2c, 0xa9, 0x92, 0x0c, 0xa1, 0xc2, 0xff, 0xfb, 0x9d, 0xd9, 0x87, 0xb4, 0x92, 0x65, 0x63, + 0x92, 0x9b, 0xf4, 0x7c, 0xe7, 0xfb, 0x9a, 0x53, 0xb0, 0x57, 0xb3, 0xb3, 0xb3, 0xf3, 0x9e, 0x9d, + 0x15, 0x3b, 0x2b, 0x6e, 0x38, 0x48, 0xef, 0x22, 0x4a, 0x46, 0xe9, 0xd8, 0xef, 0xee, 0xa4, 0x5e, + 0xea, 0xd3, 0xee, 0x5e, 0x18, 0xa4, 0x71, 0xe8, 0x93, 0x63, 0x27, 0xa0, 0xfe, 0xce, 0x3a, 0x1f, + 0xdc, 0x19, 0xd3, 0xd4, 0x21, 0x03, 0x78, 0x44, 0x83, 0xd4, 0x5a, 0xbd, 0xf5, 0xdc, 0x74, 0x64, + 0xb9, 0xf4, 0xc6, 0x1b, 0xd0, 0x06, 0xfb, 0x62, 0x78, 0x81, 0x97, 0x7a, 0x8e, 0xdf, 0x48, 0x06, + 0x8e, 0x4f, 0xad, 0x96, 0xd9, 0x5c, 0x25, 0x81, 0x33, 0xa6, 0xd6, 0x8d, 0x47, 0x6f, 0xa3, 0x30, + 0x4e, 0xbb, 0x3b, 0x49, 0x7a, 0x07, 0x98, 0x9e, 0xdc, 0xc6, 0x4e, 0x14, 0xd1, 0x38, 0x4b, 0xe9, + 0xa7, 0xb4, 0xe1, 0xf8, 0xde, 0x75, 0xd0, 0x1e, 0x00, 0x52, 0x1a, 0x77, 0xfa, 0xe1, 0xa7, 0x46, + 0xe2, 0xfd, 0xe5, 0x05, 0xd7, 0xed, 0x7e, 0x18, 0xbb, 0x34, 0x6e, 0xc0, 0xc8, 0xf4, 0x89, 0x58, + 0x35, 0x1b, 0x3b, 0x9f, 0xf8, 0x5a, 0xed, 0xed, 0x66, 0x33, 0xfa, 0xd4, 0x19, 0x3b, 0xf1, 0xb5, + 0x17, 0xb4, 0x9d, 0x49, 0x1a, 0x76, 0x22, 0xc7, 0x75, 0x71, 0x5e, 0x93, 0xb4, 0xe0, 0xd1, 0xb4, + 0x1f, 0xba, 0x77, 0x35, 0x0b, 0x88, 0x19, 0xcd, 0x02, 0x7c, 0xfa, 0x22, 0x1b, 0x84, 0x7e, 0x18, + 0xb7, 0x9f, 0x6c, 0x0c, 0xf1, 0x5f, 0xa7, 0xef, 0x0c, 0x3e, 0x5e, 0xc7, 0xe1, 0x24, 0x70, 0x1b, + 0xe2, 0xc1, 0x70, 0x38, 0xec, 0x0c, 0x81, 0x84, 0xc6, 0xd0, 0x19, 0x7b, 0xfe, 0x5d, 0xfb, 0x30, + 0x4c, 0x43, 0x72, 0xea, 0x04, 0x89, 0xf1, 0x81, 0xc6, 0xae, 0x13, 0x38, 0x46, 0x02, 0x5f, 0x1a, + 0x09, 0x8d, 0x3d, 0x01, 0x08, 0x7b, 0xa0, 0xed, 0x96, 0xb9, 0x11, 0xd3, 0xf1, 0xd4, 0x0b, 0xa2, + 0x49, 0x6a, 0xf4, 0x27, 0x69, 0x1a, 0x06, 0x2a, 0x45, 0xb1, 0x77, 0x3d, 0x4a, 0xeb, 0x77, 0x5c, + 0x43, 0x03, 0x1d, 0x52, 0x97, 0xfe, 0xd8, 0xe1, 0x30, 0xed, 0x56, 0xf4, 0x89, 0x24, 0xa1, 0xef, + 0xb9, 0xe4, 0x49, 0xdf, 0xf9, 0xf1, 0xd5, 0x76, 0x5f, 0x3c, 0x68, 0xc4, 0x8e, 0xeb, 0x4d, 0x92, + 0xf6, 0x36, 0x30, 0x87, 0x33, 0xaa, 0xd5, 0x6c, 0x3e, 0xe3, 0x24, 0x5c, 0xa0, 0x9c, 0x2d, 0x24, + 0xe0, 0xd2, 0x50, 0x06, 0x82, 0xc9, 0xb8, 0x4f, 0xe3, 0xcb, 0x4c, 0xdd, 0xe0, 0x38, 0x0c, 0xc2, + 0x24, 0x72, 0x06, 0x54, 0xcc, 0x8c, 0xa9, 0xe3, 0x86, 0x81, 0x7f, 0x77, 0x99, 0xd5, 0x10, 0xb6, + 0x85, 0xff, 0xa6, 0xb3, 0xfb, 0xe3, 0x1c, 0x9f, 0x9a, 0x83, 0x91, 0x13, 0x5c, 0x53, 0xd7, 0x00, + 0x29, 0x8e, 0xc7, 0x5e, 0x7a, 0xd5, 0x4f, 0x83, 0xac, 0x60, 0xec, 0x8a, 0x37, 0x46, 0xdd, 0x70, + 0x82, 0xb4, 0x66, 0xd3, 0x1b, 0xce, 0xd6, 0x8f, 0x9b, 0x6e, 0x01, 0x02, 0x9a, 0xe0, 0x04, 0x03, + 0xea, 0x3f, 0x06, 0xc7, 0xf7, 0x1b, 0x9b, 0x25, 0x04, 0x39, 0x11, 0x46, 0x09, 0xd9, 0x24, 0x4e, + 0x00, 0x3a, 0x0a, 0x3d, 0xa1, 0x87, 0x8c, 0xcd, 0x41, 0x18, 0x50, 0xc1, 0xc7, 0xad, 0xed, 0x67, + 0x42, 0x79, 0x1a, 0x69, 0x18, 0xb5, 0x51, 0xc7, 0x72, 0x1d, 0x62, 0x5f, 0x18, 0xff, 0x6e, 0x29, + 0x0a, 0xb5, 0xfd, 0x7d, 0xb3, 0xa9, 0xae, 0x74, 0xe1, 0x7a, 0x89, 0xd3, 0xf7, 0xa9, 0x7b, 0xa9, + 0xae, 0x59, 0x8c, 0xca, 0xad, 0xfc, 0xf0, 0xc3, 0x0f, 0x1d, 0x41, 0x48, 0x10, 0x22, 0x1b, 0xfd, + 0xf0, 0x96, 0xba, 0x35, 0x7b, 0xda, 0xda, 0xda, 0x52, 0xf6, 0x94, 0x22, 0x96, 0x4c, 0x28, 0x00, + 0x40, 0xf8, 0x4e, 0x94, 0xd0, 0xb6, 0xfc, 0xd0, 0x51, 0x44, 0xe2, 0xd3, 0x61, 0xaa, 0xea, 0x45, + 0xea, 0x66, 0xb9, 0xd2, 0x81, 0xf8, 0xc6, 0xaa, 0x5e, 0x09, 0x85, 0x93, 0x7b, 0xfc, 0x01, 0x6c, + 0x2a, 0x99, 0x8c, 0x81, 0x05, 0x25, 0xb3, 0x62, 0x18, 0x15, 0x33, 0xa9, 0xe5, 0x7f, 0x8d, 0x72, + 0x4a, 0xb4, 0xe6, 0x26, 0x98, 0xc8, 0x0c, 0xef, 0xcc, 0xc1, 0x58, 0x52, 0xc6, 0x65, 0xa0, 0x1a, + 0xd5, 0x36, 0x1a, 0xd5, 0x93, 0x71, 0x72, 0x5d, 0xa3, 0x6c, 0xa3, 0x56, 0x56, 0x80, 0x6e, 0x08, + 0xd0, 0x28, 0x8c, 0x26, 0x51, 0x23, 0xbc, 0xa1, 0xb1, 0xef, 0xdc, 0x65, 0x7f, 0x35, 0xbc, 0xc0, + 0xa5, 0x9f, 0x90, 0x01, 0xcd, 0x1a, 0x72, 0x9b, 0xec, 0xbf, 0xfe, 0x66, 0xe7, 0x8f, 0x49, 0x92, + 0x7a, 0xc3, 0xbb, 0x86, 0xf0, 0x3d, 0xd2, 0x81, 0xb0, 0xe5, 0x1a, 0x5e, 0x4a, 0xc7, 0x89, 0x1c, + 0x2a, 0x18, 0xda, 0x19, 0xf1, 0x3d, 0xb0, 0xcf, 0x20, 0xde, 0x08, 0x16, 0xe4, 0x1b, 0x88, 0xc2, + 0x04, 0x9c, 0x63, 0x18, 0xb4, 0x87, 0xde, 0x27, 0x10, 0x29, 0xaa, 0x50, 0xb3, 0x83, 0xcc, 0x03, + 0x07, 0x24, 0x08, 0x94, 0x4e, 0x4e, 0xe1, 0x66, 0x8d, 0x83, 0x9c, 0x63, 0x23, 0x15, 0x16, 0xb7, + 0xb8, 0x77, 0x94, 0xde, 0x72, 0xab, 0xa9, 0xaa, 0xeb, 0x26, 0x7e, 0x61, 0x7e, 0x67, 0x04, 0x66, + 0x7d, 0x0b, 0x1e, 0x73, 0x0b, 0xc4, 0xfe, 0x0a, 0xfe, 0x17, 0xbb, 0xdf, 0x72, 0x2b, 0x34, 0x91, + 0xd1, 0x46, 0xb6, 0x50, 0xc8, 0x82, 0x08, 0xc5, 0x40, 0xaa, 0xdb, 0x22, 0xd1, 0x52, 0x18, 0x54, + 0x41, 0xb7, 0x50, 0x7a, 0xff, 0x1c, 0x53, 0xd7, 0x73, 0x48, 0x32, 0x88, 0x29, 0x0d, 0x88, 0x13, + 0xb8, 0x44, 0x63, 0x7b, 0xda, 0xb1, 0x36, 0xb7, 0x61, 0x1f, 0x7a, 0x56, 0x13, 0x1c, 0x18, 0xfb, + 0x8b, 0x78, 0x00, 0xfa, 0xc6, 0x6d, 0x84, 0xa4, 0x31, 0x61, 0x2a, 0x5f, 0xe7, 0x72, 0x95, 0xa9, + 0x52, 0x72, 0x7d, 0x3f, 0x1c, 0x7c, 0xcc, 0xa7, 0x66, 0x62, 0x77, 0xd2, 0x54, 0x90, 0x8b, 0x65, + 0x48, 0xb9, 0x65, 0xee, 0x0b, 0x93, 0x6c, 0xfe, 0x2e, 0x7d, 0x0a, 0xb4, 0x42, 0x14, 0x6c, 0xe3, + 0x8f, 0x79, 0xaa, 0x76, 0xed, 0x44, 0x52, 0x90, 0x39, 0x5b, 0x37, 0xd4, 0x55, 0x11, 0x4d, 0x65, + 0x4d, 0x22, 0xfc, 0x70, 0x39, 0xa4, 0x55, 0xbd, 0xdb, 0x7f, 0x21, 0xba, 0x8c, 0x81, 0xa0, 0x9c, + 0x65, 0x15, 0x5f, 0x48, 0x36, 0x6a, 0x1d, 0x62, 0x1d, 0xa1, 0xed, 0x11, 0xda, 0xa5, 0x51, 0xfb, + 0xcc, 0x8c, 0x62, 0x8f, 0xf9, 0x9b, 0x85, 0x8a, 0xc3, 0x29, 0x9c, 0x2e, 0xc4, 0xc0, 0x57, 0xa9, + 0x91, 0xc7, 0x0f, 0xce, 0xf7, 0xcd, 0xad, 0x6d, 0x39, 0x99, 0x05, 0x3b, 0x26, 0x05, 0xc7, 0x0b, + 0x6a, 0xe1, 0x4b, 0x7a, 0xce, 0x84, 0x41, 0x9a, 0xa5, 0xd9, 0x15, 0xc6, 0x2f, 0x63, 0xc0, 0x5f, + 0x12, 0xd9, 0x6b, 0x42, 0x90, 0x6a, 0x3c, 0x66, 0xf2, 0x27, 0x06, 0x37, 0x0e, 0xbf, 0xb9, 0xfd, + 0xac, 0xec, 0x02, 0xaa, 0x02, 0xda, 0x59, 0xe7, 0xf9, 0xd9, 0xce, 0xfa, 0x08, 0xe2, 0x7d, 0x77, + 0x07, 0x53, 0xa8, 0xee, 0x8e, 0xeb, 0xdd, 0x10, 0xcf, 0xb5, 0x44, 0xce, 0x96, 0x7f, 0x17, 0xba, + 0xda, 0xdd, 0x19, 0xb5, 0xba, 0x7b, 0xfe, 0x64, 0xf0, 0x71, 0x0f, 0xc2, 0x1d, 0x98, 0x27, 0x4c, + 0x6e, 0x41, 0x1e, 0x89, 0x36, 0x03, 0xbf, 0x00, 0x3e, 0x45, 0x4c, 0x4c, 0x1a, 0x24, 0x0c, 0x06, + 0xbe, 0x37, 0xf8, 0x68, 0xad, 0x26, 0x34, 0x70, 0x05, 0xbc, 0xf6, 0x3c, 0x49, 0x9d, 0x38, 0x7d, + 0xae, 0xaf, 0x92, 0x81, 0xef, 0x24, 0x89, 0x05, 0xae, 0xbf, 0x7b, 0x7a, 0xb6, 0x7b, 0x72, 0xb6, + 0xb3, 0xce, 0xa7, 0x01, 0x3d, 0x88, 0x63, 0x09, 0x3c, 0x61, 0x54, 0x42, 0x43, 0xd8, 0x76, 0xac, + 0x87, 0xa2, 0x13, 0xac, 0x76, 0x74, 0xfc, 0xd8, 0xc5, 0x00, 0x45, 0x58, 0xa6, 0xf9, 0xfc, 0x70, + 0xff, 0xa8, 0x82, 0x65, 0x1d, 0xf7, 0xbf, 0x2e, 0x79, 0xa1, 0xb2, 0x04, 0xf2, 0x68, 0x1f, 0x12, + 0xac, 0xc0, 0xda, 0xec, 0xee, 0x30, 0xbd, 0x41, 0x96, 0x42, 0x48, 0x23, 0x32, 0xd3, 0x52, 0x31, + 0x2c, 0x98, 0x72, 0xfe, 0xfb, 0xd5, 0xd9, 0xbb, 0x83, 0x1e, 0x12, 0xc9, 0xb2, 0x2c, 0x0b, 0x34, + 0xf3, 0xe3, 0x1e, 0x4f, 0xb8, 0xb4, 0x74, 0xe4, 0x25, 0x3a, 0x30, 0x81, 0x46, 0x56, 0x8b, 0xb0, + 0x5c, 0xcf, 0x75, 0x52, 0x9a, 0x7a, 0x63, 0xda, 0x00, 0x77, 0xe5, 0xf8, 0x5d, 0x22, 0xf7, 0x08, + 0x98, 0x82, 0xf0, 0x16, 0x93, 0x92, 0x7c, 0xbb, 0x09, 0x4d, 0xcf, 0x00, 0xf2, 0x2c, 0x3c, 0x0c, + 0x6f, 0x35, 0xbd, 0x7b, 0x7a, 0x17, 0x0c, 0x08, 0x0e, 0xd4, 0x6d, 0x51, 0x88, 0xf9, 0x74, 0x30, + 0xa2, 0xee, 0x04, 0x7c, 0xe5, 0x29, 0x4a, 0xb4, 0x60, 0xa4, 0x4a, 0xed, 0xc1, 0xd1, 0x87, 0xde, + 0x15, 0x13, 0x6f, 0x41, 0x33, 0xff, 0x25, 0x67, 0x0b, 0xb2, 0x79, 0xb2, 0x0a, 0x0b, 0x2e, 0x5a, + 0xa8, 0x87, 0xfa, 0x36, 0x77, 0x99, 0xde, 0xe1, 0xfe, 0x17, 0x2c, 0xf2, 0x84, 0x1c, 0x80, 0xd3, + 0x48, 0xd6, 0xf7, 0x9d, 0xbb, 0xfa, 0x35, 0x0e, 0xcf, 0x0f, 0xd8, 0x3a, 0xa7, 0x04, 0x7c, 0xa1, + 0xd5, 0x5c, 0x66, 0x29, 0x9e, 0x6b, 0xd7, 0x2c, 0x76, 0x08, 0x7e, 0x82, 0xad, 0x47, 0x76, 0xe7, + 0x30, 0xee, 0xb0, 0xf7, 0xfb, 0xd9, 0xd5, 0xee, 0xfb, 0xdd, 0x93, 0x83, 0x5c, 0x47, 0x6a, 0x65, + 0x3a, 0x8b, 0xfb, 0x84, 0x8e, 0xc1, 0x9d, 0x99, 0x64, 0xdf, 0x03, 0x4b, 0x83, 0xe4, 0x93, 0x68, + 0xc3, 0x54, 0xaf, 0x5f, 0xe4, 0xa4, 0x77, 0x70, 0xb5, 0xff, 0xee, 0x54, 0x91, 0x0d, 0xfc, 0x74, + 0x7d, 0xca, 0x51, 0x80, 0xe3, 0x40, 0x1c, 0x5c, 0xbd, 0x96, 0xda, 0x16, 0xdb, 0xd1, 0x12, 0xeb, + 0xee, 0x9f, 0xbc, 0x03, 0x79, 0xb1, 0x95, 0xbf, 0x9c, 0x97, 0xbf, 0x80, 0x91, 0x93, 0x9f, 0x99, + 0x5b, 0x23, 0x9a, 0x17, 0xcc, 0x59, 0xf2, 0x97, 0xdd, 0xbd, 0x5f, 0xff, 0x5b, 0x2b, 0xbe, 0x71, + 0x52, 0x70, 0xed, 0x77, 0x44, 0xfb, 0x50, 0xb7, 0xd8, 0x4d, 0xe8, 0xa7, 0xce, 0x35, 0x5d, 0x60, + 0xda, 0xdd, 0xe3, 0x38, 0xbc, 0x8e, 0x9d, 0x31, 0x39, 0x79, 0x4b, 0x80, 0xd5, 0x61, 0x4a, 0xe7, + 0x7a, 0xa1, 0x88, 0x43, 0x9e, 0xbc, 0x3d, 0xa5, 0x7f, 0x4e, 0x28, 0x70, 0x15, 0x6c, 0x53, 0xce, + 0xde, 0xf5, 0x7d, 0xf2, 0x86, 0xc7, 0xbf, 0x45, 0x8e, 0x48, 0x60, 0x94, 0xd5, 0x07, 0x73, 0xe6, + 0x79, 0x51, 0x92, 0x2f, 0x84, 0xda, 0x84, 0x09, 0xab, 0x19, 0x53, 0x3f, 0x74, 0x5c, 0x4d, 0xef, + 0x74, 0x41, 0x90, 0x03, 0x27, 0x76, 0x0b, 0xdc, 0x75, 0x98, 0xf2, 0xa2, 0x27, 0xc7, 0xc4, 0x87, + 0x8e, 0x1d, 0x20, 0x31, 0x41, 0x4f, 0xe2, 0x80, 0x4e, 0x70, 0x1d, 0x52, 0xc8, 0xec, 0xc7, 0xfc, + 0x7f, 0x97, 0x42, 0xec, 0xf5, 0x93, 0xee, 0x8e, 0xa8, 0x35, 0xba, 0xa0, 0x92, 0x47, 0x67, 0x3d, + 0xb2, 0x77, 0x74, 0x78, 0x76, 0x72, 0xf4, 0x1e, 0x42, 0x94, 0x18, 0x27, 0x08, 0x4e, 0x0a, 0xf6, + 0x8c, 0xc3, 0x49, 0x42, 0x21, 0x9b, 0x0d, 0xc0, 0x51, 0xa3, 0xfb, 0xe1, 0x7c, 0xd4, 0x9e, 0x0f, + 0x6f, 0xdd, 0xe7, 0x06, 0xa1, 0x37, 0x10, 0xab, 0xc0, 0x5d, 0x43, 0xd0, 0x0a, 0x27, 0x83, 0x11, + 0x83, 0x58, 0x08, 0xc8, 0xfd, 0x3a, 0x0b, 0x9f, 0x12, 0xb9, 0x4f, 0x81, 0x72, 0x0b, 0xa3, 0x8c, + 0x98, 0xa2, 0xcb, 0x27, 0x93, 0xa8, 0x3a, 0xcc, 0x56, 0x81, 0x78, 0x51, 0x1a, 0xef, 0xbe, 0xfd, + 0x6d, 0x3f, 0xdf, 0xf1, 0x12, 0xa4, 0xc7, 0xf4, 0x66, 0x39, 0xd2, 0xcb, 0x80, 0x5f, 0x85, 0xf4, + 0x93, 0xde, 0x87, 0xc7, 0x90, 0x3e, 0x89, 0x96, 0xa3, 0xbc, 0x04, 0xf7, 0x55, 0x08, 0x3f, 0x3f, + 0x7e, 0x0c, 0xdd, 0x38, 0xb4, 0x1c, 0xe5, 0x15, 0xc8, 0xaf, 0x42, 0xfb, 0xfe, 0xd1, 0x6f, 0x87, + 0x8f, 0xa1, 0xde, 0x99, 0x7c, 0x5a, 0x8e, 0xf8, 0x32, 0xe0, 0x57, 0xa1, 0x7d, 0xf7, 0xfc, 0x77, + 0xc5, 0x09, 0xe5, 0x66, 0x5d, 0x6b, 0xe3, 0xfb, 0xbb, 0x87, 0x3f, 0xf5, 0x4e, 0xc8, 0xff, 0x1c, + 0x1d, 0xf6, 0x54, 0x03, 0x2f, 0x27, 0x91, 0x7b, 0x90, 0x46, 0xf7, 0x63, 0xe6, 0x93, 0xe6, 0xe7, + 0x68, 0x03, 0x01, 0x04, 0x7b, 0xfc, 0x03, 0xc2, 0x00, 0x64, 0x68, 0x3c, 0x1c, 0x94, 0x26, 0xcf, + 0x32, 0x74, 0x76, 0xb6, 0x1b, 0x7b, 0x37, 0x14, 0xa7, 0xef, 0xe3, 0x87, 0xda, 0xf9, 0xb3, 0x6e, + 0xfc, 0xad, 0x17, 0x8f, 0x6f, 0x9d, 0x98, 0x56, 0x83, 0x80, 0x33, 0x18, 0xd0, 0x28, 0xb5, 0xcc, + 0xbe, 0xc7, 0x52, 0xad, 0xa1, 0x00, 0xbb, 0x1a, 0x7a, 0x90, 0xc3, 0xf0, 0x24, 0x55, 0x3d, 0x2c, + 0xe0, 0xd1, 0x06, 0x1f, 0x76, 0x89, 0x9a, 0xa2, 0x4d, 0x22, 0xf4, 0xc4, 0x25, 0xdf, 0xca, 0x87, + 0xe4, 0xba, 0xa8, 0xee, 0x6c, 0x80, 0x14, 0x94, 0xcc, 0x25, 0xf6, 0x7d, 0x78, 0x0d, 0x60, 0xfe, + 0x6c, 0xa8, 0x81, 0x95, 0xfc, 0xf0, 0xba, 0xb4, 0x0c, 0xea, 0x1a, 0xe2, 0x85, 0x39, 0x38, 0x05, + 0x55, 0x53, 0x8c, 0x10, 0x18, 0x5a, 0x10, 0x6c, 0x84, 0x10, 0x11, 0xa7, 0x90, 0x66, 0xfe, 0x60, + 0x61, 0x7a, 0x1d, 0xd3, 0x7e, 0x18, 0xa6, 0x9f, 0x95, 0xcd, 0x9f, 0xf4, 0xde, 0x1c, 0x1d, 0x9d, + 0x2d, 0x90, 0x72, 0xb9, 0x68, 0xf0, 0x29, 0x7d, 0x7c, 0xd5, 0xb0, 0xb1, 0xf9, 0x7d, 0xf7, 0xf4, + 0x7d, 0xaf, 0x77, 0x5c, 0xa7, 0xe2, 0xeb, 0x50, 0x21, 0xc9, 0x9f, 0xa2, 0x58, 0x2a, 0x9d, 0x40, + 0x55, 0x46, 0x8b, 0x42, 0x6a, 0xa3, 0x18, 0x14, 0x47, 0xee, 0xeb, 0xa3, 0x8d, 0xee, 0x4e, 0x54, + 0x0c, 0x8f, 0x69, 0x92, 0x40, 0x2a, 0x01, 0x0f, 0xa2, 0x0a, 0x96, 0x4a, 0xe9, 0x5a, 0xa3, 0x55, + 0x4a, 0x46, 0xa2, 0x4c, 0xa9, 0x25, 0x54, 0x14, 0xd1, 0xe5, 0xad, 0xf0, 0x9f, 0xc9, 0x20, 0xf6, + 0xa2, 0xb4, 0xeb, 0xd3, 0x94, 0x40, 0xe2, 0xe9, 0x58, 0xd9, 0xd4, 0x88, 0x30, 0xb2, 0x9f, 0xa1, + 0x54, 0xf7, 0x20, 0xc5, 0x49, 0xa9, 0x6b, 0xad, 0xb4, 0x8c, 0x28, 0xf4, 0xfd, 0x77, 0x58, 0xf0, + 0xde, 0x38, 0x3e, 0x24, 0x4e, 0xbe, 0x6f, 0x8c, 0x43, 0xd7, 0xf1, 0x4f, 0x28, 0xd4, 0xb6, 0x37, + 0x94, 0x8d, 0x74, 0x80, 0xda, 0x24, 0x25, 0x90, 0x72, 0xc1, 0xc2, 0x5d, 0x37, 0x1c, 0x4c, 0xc6, + 0xc0, 0x07, 0xf3, 0x9a, 0xa6, 0x3d, 0x9f, 0xe2, 0xc7, 0x37, 0x77, 0xef, 0x5c, 0xcd, 0x73, 0xf5, + 0xce, 0x70, 0x12, 0x0c, 0xd0, 0xf4, 0x48, 0x32, 0x0a, 0x6f, 0x0f, 0x10, 0x8f, 0xc6, 0x18, 0x64, + 0x08, 0x7e, 0x88, 0xc3, 0xf5, 0xc4, 0xba, 0xb8, 0x34, 0xc2, 0x08, 0x21, 0x13, 0x20, 0x4c, 0xcf, + 0x90, 0x4a, 0xc1, 0x74, 0x6b, 0x1e, 0x7e, 0xbb, 0x24, 0x1b, 0x5b, 0x37, 0x18, 0xe6, 0x9e, 0xff, + 0xd0, 0x04, 0x06, 0x06, 0xe0, 0x82, 0x84, 0x87, 0x27, 0x08, 0x40, 0x98, 0x22, 0xa8, 0x7d, 0x78, + 0x8a, 0x00, 0x84, 0x29, 0x4c, 0x56, 0x7b, 0x52, 0xba, 0x0f, 0xcd, 0xab, 0x28, 0x83, 0x9c, 0xff, + 0xf0, 0x82, 0x0c, 0xcc, 0xd6, 0x3b, 0x82, 0x07, 0x26, 0x1e, 0x5f, 0xec, 0x89, 0x8e, 0x4f, 0x89, + 0xe3, 0xf0, 0xcc, 0x0b, 0x00, 0xf5, 0xcf, 0x67, 0x07, 0xef, 0x2d, 0x29, 0x05, 0xc1, 0x7a, 0x13, + 0xa5, 0xf4, 0x0e, 0x31, 0xbd, 0xd6, 0xca, 0x74, 0x9b, 0x4c, 0x2b, 0x4d, 0xa1, 0x95, 0x96, 0xcd, + 0x4e, 0xcd, 0x6c, 0x49, 0x9c, 0xc9, 0xdc, 0x9e, 0x44, 0xc2, 0x06, 0xcf, 0x60, 0xe4, 0xfe, 0xde, + 0x46, 0x32, 0x0a, 0x30, 0xd0, 0xa8, 0x49, 0x05, 0xee, 0x03, 0x0e, 0x01, 0x60, 0x01, 0x04, 0x0b, + 0x0c, 0xe8, 0x28, 0xf4, 0x5d, 0xe0, 0x56, 0x09, 0xf4, 0xb8, 0x78, 0xc0, 0x26, 0x88, 0x3a, 0x37, + 0x9c, 0xa4, 0x9a, 0xa6, 0x5b, 0x5d, 0x39, 0x7f, 0x08, 0x8c, 0x82, 0x6c, 0xd5, 0x68, 0x35, 0x9b, + 0xba, 0xde, 0x5e, 0xbc, 0x0d, 0xb4, 0x2e, 0xbb, 0x90, 0xaa, 0xc2, 0x19, 0x3b, 0x1f, 0x06, 0x84, + 0x71, 0xcf, 0x19, 0x8c, 0x34, 0x70, 0xab, 0x56, 0x97, 0x69, 0x26, 0x7f, 0x52, 0x88, 0x64, 0xc0, + 0xac, 0x47, 0x48, 0x45, 0xb3, 0xf9, 0x63, 0x10, 0x86, 0x38, 0xca, 0x52, 0x65, 0x01, 0x48, 0xd8, + 0x77, 0x03, 0x3f, 0x88, 0x33, 0xae, 0xb5, 0x35, 0x01, 0xc8, 0x3c, 0xd9, 0x7b, 0x28, 0xba, 0x4c, + 0xc7, 0x45, 0xc9, 0xf2, 0xc7, 0xb9, 0xde, 0x99, 0xd2, 0x11, 0xe2, 0x76, 0x19, 0x21, 0x31, 0x4d, + 0x26, 0x7e, 0x6a, 0xcd, 0x8a, 0x2f, 0x13, 0x67, 0x74, 0xb8, 0x0a, 0xe3, 0x3a, 0x67, 0x6f, 0xbb, + 0x24, 0x89, 0x69, 0xf1, 0xb8, 0xa3, 0xda, 0xf8, 0xda, 0x9a, 0xa5, 0xa9, 0xdf, 0x35, 0xbe, 0x8c, + 0x6e, 0xa0, 0xed, 0xeb, 0xc6, 0xc8, 0x73, 0x29, 0x37, 0x65, 0x9d, 0xed, 0x02, 0x62, 0xaf, 0x8f, + 0x8e, 0x16, 0xb6, 0xa1, 0x7c, 0x93, 0x93, 0xa6, 0x0a, 0x7b, 0xf1, 0x1c, 0x0a, 0x3c, 0xf8, 0xc8, + 0xf3, 0x5d, 0x8d, 0x8f, 0xea, 0x53, 0xdd, 0x10, 0x06, 0x5c, 0x95, 0x0d, 0x1e, 0x91, 0xda, 0xd3, + 0xdc, 0x81, 0x28, 0xab, 0x7e, 0x96, 0x77, 0xe8, 0xcc, 0x59, 0x86, 0xab, 0xc0, 0xc2, 0xed, 0xaf, + 0xb4, 0xc4, 0xd6, 0x0b, 0x6a, 0xd8, 0x73, 0x90, 0x29, 0x26, 0x04, 0x9a, 0xb4, 0x22, 0x66, 0x67, + 0x96, 0x2d, 0x86, 0x6d, 0x3d, 0x8b, 0x69, 0x3a, 0x89, 0x03, 0x12, 0xd0, 0x5b, 0x02, 0x95, 0xde, + 0xd8, 0x4b, 0x18, 0x2b, 0x99, 0x1b, 0xed, 0x66, 0x25, 0xaf, 0x2a, 0x86, 0x8d, 0x79, 0x6e, 0xf2, + 0x82, 0x75, 0x4c, 0xda, 0xf6, 0x1e, 0x2b, 0xf7, 0x6c, 0x83, 0x09, 0xad, 0xbd, 0xd2, 0x9a, 0x1a, + 0xe2, 0xc1, 0xd1, 0xaf, 0xf9, 0x60, 0xd3, 0x90, 0x67, 0xa7, 0x2b, 0xcd, 0xe9, 0x25, 0x70, 0xb8, + 0x42, 0xf6, 0xae, 0x4f, 0xe3, 0xb4, 0x4a, 0xf4, 0x61, 0x98, 0x7a, 0x03, 0xfa, 0x55, 0x68, 0x5e, + 0x8e, 0x34, 0xc4, 0x72, 0xc2, 0x72, 0x07, 0x29, 0xe5, 0x02, 0xaf, 0xbd, 0xcf, 0x9a, 0xd5, 0x84, + 0x3f, 0xf7, 0x82, 0x6b, 0xdb, 0xb0, 0x8f, 0xb1, 0x30, 0xbf, 0xf5, 0xa0, 0x70, 0x8e, 0xe9, 0x10, + 0x48, 0x19, 0x11, 0x48, 0xd1, 0x76, 0xf0, 0x98, 0x0d, 0xa3, 0xe1, 0xaa, 0x8c, 0xd0, 0x93, 0x20, + 0xc5, 0x14, 0x68, 0xb5, 0xbb, 0x0d, 0xf9, 0x29, 0x3c, 0xec, 0x92, 0x84, 0x82, 0x7b, 0x75, 0x13, + 0xd3, 0x34, 0x6d, 0xe3, 0xe2, 0x52, 0xef, 0xa0, 0x32, 0xe5, 0x70, 0xd6, 0xb6, 0x91, 0x7f, 0xce, + 0x83, 0x20, 0x38, 0x1a, 0xf9, 0x99, 0x79, 0x9a, 0x2c, 0x07, 0x69, 0x34, 0xca, 0xd3, 0x1f, 0xf6, + 0xd3, 0x39, 0x28, 0x68, 0xa4, 0x32, 0x6d, 0x6d, 0x4d, 0x53, 0xbe, 0x95, 0x3c, 0x46, 0x3e, 0xae, + 0x17, 0xa4, 0xed, 0x58, 0x4d, 0x9c, 0x01, 0xb9, 0x7e, 0x9c, 0x53, 0x36, 0x43, 0xb7, 0x6e, 0xcc, + 0x9c, 0x04, 0x80, 0x35, 0xb6, 0xe8, 0x66, 0x95, 0xeb, 0x67, 0x7b, 0x78, 0x46, 0x58, 0xc3, 0x76, + 0x74, 0xaf, 0x04, 0x34, 0x83, 0x9c, 0x52, 0xf0, 0xe2, 0xf6, 0xd9, 0x88, 0x12, 0x7e, 0x6d, 0x00, + 0x72, 0x2e, 0xf0, 0xff, 0xa0, 0x24, 0xd4, 0x4d, 0x48, 0x1a, 0x92, 0x3e, 0x24, 0xc3, 0x80, 0x62, + 0x14, 0x87, 0x81, 0xf7, 0x17, 0x75, 0x91, 0xb3, 0x42, 0xf8, 0xf9, 0xe9, 0x63, 0xad, 0x0e, 0x18, + 0xd2, 0x5b, 0xb4, 0x1d, 0x9c, 0xcf, 0x98, 0x5b, 0x3e, 0xbe, 0x34, 0x9c, 0x5b, 0xc7, 0x43, 0x0e, + 0xab, 0x27, 0x11, 0x53, 0xd4, 0x1d, 0x9e, 0x83, 0x40, 0xaa, 0x1c, 0x50, 0xf7, 0x68, 0xd8, 0x3b, + 0x3a, 0x83, 0xe4, 0xa5, 0x9c, 0x6f, 0xc0, 0x98, 0xdc, 0x94, 0x02, 0x76, 0x7f, 0xaf, 0x95, 0x26, + 0x35, 0x15, 0x05, 0xb6, 0x8f, 0x20, 0xcd, 0x0a, 0x87, 0xe4, 0x2c, 0x86, 0x22, 0x0a, 0xcc, 0x4c, + 0x2a, 0xde, 0xc0, 0x09, 0x02, 0x60, 0xc3, 0x18, 0x0f, 0xc5, 0x80, 0xcb, 0x9e, 0x0f, 0x1f, 0x63, + 0xec, 0x2c, 0x21, 0x18, 0x9e, 0xa2, 0xf0, 0x63, 0x32, 0x2f, 0x21, 0xa2, 0xf3, 0xab, 0x70, 0x60, + 0xbe, 0xfa, 0xeb, 0x53, 0x54, 0x1e, 0x4f, 0x88, 0xeb, 0x9d, 0xcb, 0x73, 0xab, 0x62, 0x0b, 0x4a, + 0xdd, 0x37, 0xe0, 0x59, 0xaf, 0xc1, 0x0b, 0xbf, 0x8c, 0xfd, 0x5a, 0x5b, 0x63, 0xbf, 0x20, 0x8a, + 0xb0, 0xdf, 0xfb, 0x74, 0xe8, 0x80, 0xc3, 0xd5, 0x30, 0x65, 0x90, 0x18, 0xd7, 0xd6, 0xca, 0x3a, + 0x52, 0x3c, 0xd1, 0x0d, 0x35, 0x99, 0x16, 0xe8, 0xd5, 0xa9, 0xb3, 0x5a, 0x5f, 0x37, 0x01, 0xf4, + 0x69, 0xbb, 0xa9, 0xea, 0x93, 0x52, 0x48, 0x66, 0x2a, 0x1d, 0x96, 0x36, 0x9f, 0x12, 0xee, 0x5b, + 0x99, 0x06, 0x90, 0x02, 0x93, 0xba, 0xda, 0xd8, 0x3d, 0x74, 0xc6, 0x14, 0x30, 0x0e, 0xb5, 0x15, + 0xf9, 0xcd, 0xb2, 0x2c, 0x9b, 0xb1, 0xc8, 0x5e, 0x5b, 0x5b, 0xe1, 0x5a, 0x52, 0xf2, 0xca, 0xf6, + 0x6f, 0xe8, 0x1c, 0xfa, 0xf4, 0xda, 0x43, 0xbf, 0x77, 0x03, 0x5e, 0x83, 0x34, 0x48, 0x04, 0x44, + 0x24, 0x14, 0xef, 0xc2, 0x20, 0x8c, 0x69, 0xeb, 0x3a, 0x4c, 0x56, 0x31, 0xf2, 0xf2, 0x65, 0x1e, + 0x4a, 0xa1, 0x0e, 0xc2, 0xed, 0x20, 0x24, 0xe0, 0x64, 0x1b, 0x43, 0xf4, 0xdc, 0x28, 0xb0, 0xd1, + 0x29, 0x35, 0xc2, 0x24, 0xbb, 0xa0, 0x26, 0x77, 0xe1, 0x84, 0x24, 0x93, 0x98, 0xbe, 0x9e, 0x5d, + 0x8e, 0x15, 0x31, 0xcb, 0xac, 0xc6, 0x00, 0x67, 0xd1, 0xe9, 0x69, 0x7c, 0x27, 0x33, 0x81, 0x08, + 0x0c, 0x82, 0x5a, 0x1c, 0xd1, 0x90, 0xa6, 0x90, 0xb1, 0xd8, 0xe6, 0x7a, 0x14, 0x26, 0x60, 0xba, + 0xd9, 0x98, 0xa6, 0xa3, 0xd0, 0x6d, 0xdb, 0xc7, 0x47, 0xa7, 0x67, 0xb6, 0x81, 0x4d, 0x22, 0x1a, + 0x27, 0xed, 0x6c, 0x55, 0x38, 0x99, 0x06, 0xa6, 0x6b, 0xab, 0x6d, 0x1b, 0x02, 0x34, 0x24, 0x18, + 0xcc, 0x67, 0xac, 0xff, 0x91, 0x40, 0x0e, 0x03, 0xd1, 0x3b, 0x74, 0xef, 0xda, 0xbf, 0x9c, 0x1e, + 0x1d, 0x42, 0xe0, 0xc4, 0x5d, 0x7a, 0xc3, 0x3b, 0x2d, 0x83, 0x1d, 0xb4, 0xc5, 0x2e, 0xc0, 0x87, + 0xeb, 0x1d, 0x94, 0x8b, 0xa4, 0xc0, 0x0c, 0x3f, 0xea, 0x99, 0xb2, 0x1d, 0x1e, 0x6e, 0x6c, 0x21, + 0x4b, 0xf2, 0xfc, 0x69, 0x26, 0x67, 0x3e, 0x27, 0x43, 0xa8, 0xbb, 0xa8, 0xdb, 0x26, 0x4f, 0xb3, + 0x7c, 0x36, 0x30, 0x2e, 0x9d, 0x24, 0xd3, 0xd9, 0xa1, 0x33, 0xb0, 0xa6, 0x29, 0x78, 0x4d, 0x1e, + 0xa0, 0xa6, 0xb3, 0x32, 0x7b, 0x3d, 0x13, 0x42, 0xda, 0x4a, 0x8a, 0xc8, 0x38, 0x72, 0xca, 0x30, + 0x19, 0x1b, 0x90, 0x1a, 0x4e, 0x61, 0x9b, 0xc0, 0x22, 0x50, 0x2a, 0x74, 0x24, 0x21, 0xa4, 0x04, + 0x50, 0x3a, 0xc3, 0x57, 0x63, 0x96, 0xf4, 0x43, 0x9a, 0xde, 0x86, 0xf1, 0x47, 0x42, 0xe3, 0x18, + 0x4a, 0x48, 0xa0, 0x8c, 0x9a, 0x22, 0xc6, 0x01, 0x3d, 0xd3, 0xaa, 0xe2, 0x16, 0x47, 0x11, 0x98, + 0x15, 0xf3, 0x64, 0x45, 0x12, 0xcb, 0xf2, 0x64, 0xa0, 0x18, 0x4f, 0x38, 0xec, 0xd7, 0x36, 0x80, + 0x5e, 0xb1, 0x8f, 0x6d, 0xf6, 0x91, 0x9d, 0x5c, 0xd8, 0xc8, 0xcc, 0x3a, 0x6d, 0x38, 0x1b, 0x81, + 0x7b, 0x61, 0xba, 0x90, 0xaf, 0x40, 0x52, 0xf0, 0xc8, 0x4f, 0x33, 0xc4, 0x3a, 0x35, 0x09, 0xca, + 0xd2, 0x0b, 0x26, 0x4c, 0x2f, 0xfe, 0xf7, 0xa8, 0x45, 0x71, 0x3c, 0xf3, 0x25, 0xda, 0x30, 0x8b, + 0x98, 0xb3, 0x05, 0xaf, 0x30, 0xc5, 0xbb, 0xa9, 0xd6, 0xd4, 0xcd, 0x34, 0x3c, 0xc7, 0x36, 0xe8, + 0x1e, 0xd8, 0xbf, 0xa6, 0xbf, 0x64, 0x0f, 0x13, 0xd8, 0x15, 0xd5, 0x5a, 0xfa, 0x34, 0x67, 0x69, + 0xee, 0x77, 0xd1, 0x85, 0xeb, 0xc6, 0x52, 0xfa, 0xf3, 0x68, 0x85, 0x51, 0x7c, 0x9c, 0x1a, 0xea, + 0x98, 0xc0, 0x82, 0xf0, 0xd6, 0x5a, 0x7f, 0x41, 0xfe, 0x79, 0x75, 0x75, 0x7c, 0x7e, 0xd2, 0xbb, + 0xba, 0x22, 0x2f, 0xd6, 0x59, 0x2e, 0xb6, 0x0f, 0xe2, 0xe6, 0x39, 0xbc, 0x75, 0x4d, 0x35, 0x5b, + 0x74, 0x0f, 0x81, 0x01, 0x6c, 0x4c, 0x54, 0x56, 0xb0, 0x69, 0x98, 0x8f, 0x99, 0xc7, 0x5b, 0x70, + 0xa9, 0xff, 0x02, 0xb7, 0x04, 0xb1, 0xb2, 0xf1, 0x34, 0x3b, 0x65, 0x22, 0xd2, 0xc4, 0xb3, 0x03, + 0x10, 0xee, 0x08, 0x58, 0xd0, 0xd2, 0xcd, 0xc8, 0x71, 0x59, 0xc7, 0x4f, 0xdb, 0x30, 0xec, 0xa6, + 0x5d, 0x03, 0x8b, 0xcb, 0x42, 0xda, 0x30, 0x03, 0x78, 0x56, 0x05, 0xfc, 0x39, 0x9c, 0xc4, 0x49, + 0x1d, 0x64, 0x7b, 0x66, 0x79, 0xd0, 0xd1, 0x94, 0x2e, 0x07, 0x7b, 0xca, 0x73, 0xb5, 0x3a, 0x58, + 0xc8, 0xd9, 0x95, 0x86, 0x29, 0xe3, 0x82, 0x9a, 0xe8, 0x2a, 0xcf, 0xa8, 0x0f, 0x01, 0xd3, 0xaf, + 0x16, 0x57, 0xe2, 0x6e, 0x1b, 0x08, 0x19, 0xf9, 0x59, 0x34, 0x3f, 0x6c, 0xdd, 0x94, 0x5d, 0x11, + 0x3c, 0x0d, 0x61, 0x0f, 0xf3, 0x1e, 0x4b, 0xf9, 0xa1, 0x52, 0x9c, 0xcc, 0xed, 0xb5, 0x71, 0xc2, + 0xb2, 0x1a, 0x5a, 0x79, 0xfe, 0x92, 0x88, 0x6e, 0x15, 0x2b, 0xdb, 0x12, 0xeb, 0xc2, 0x2e, 0xda, + 0xac, 0x90, 0x7e, 0xc8, 0x66, 0x28, 0x7c, 0xcc, 0x7b, 0x96, 0x98, 0x95, 0xe4, 0x4d, 0x37, 0xf8, + 0x92, 0xb7, 0xc3, 0xec, 0xcb, 0x22, 0x77, 0xa8, 0xb4, 0xc2, 0x26, 0x9f, 0xae, 0x04, 0x21, 0x60, + 0x92, 0xec, 0xd4, 0xe7, 0xaa, 0xd0, 0xa5, 0xe3, 0xdd, 0x93, 0xdd, 0x83, 0xab, 0xa7, 0x99, 0x04, + 0x32, 0x3d, 0xd7, 0x4c, 0x26, 0x7d, 0x6e, 0xd7, 0x1a, 0x64, 0x8b, 0x78, 0x56, 0xa2, 0xd0, 0x9f, + 0x23, 0x2b, 0x8d, 0x2a, 0x58, 0x75, 0x23, 0x47, 0x25, 0x1d, 0x1e, 0xb6, 0x39, 0x6d, 0xa6, 0xe1, + 0x17, 0x23, 0xd4, 0x14, 0x63, 0xcc, 0xb5, 0xe0, 0xd2, 0xca, 0x41, 0x99, 0x0a, 0x9b, 0x50, 0x95, + 0x79, 0x60, 0x41, 0x6d, 0xe0, 0xf4, 0xd8, 0x89, 0xb4, 0x43, 0xd6, 0xb8, 0xd3, 0x3b, 0x0a, 0x76, + 0xa1, 0xeb, 0x1a, 0xc3, 0xf3, 0xe2, 0x55, 0xf3, 0xa5, 0x40, 0xa5, 0xc3, 0xe7, 0x29, 0xf5, 0x21, + 0xba, 0xcf, 0x02, 0xc3, 0x48, 0x42, 0xdf, 0x42, 0x0e, 0x9c, 0x6a, 0xe5, 0xf5, 0xf4, 0xfb, 0xfb, + 0x66, 0x21, 0xc6, 0x49, 0x84, 0x2d, 0xd9, 0xd3, 0x92, 0x48, 0xc0, 0x2e, 0x87, 0x61, 0xac, 0xb1, + 0x4c, 0xcd, 0x6a, 0x76, 0xbc, 0x9d, 0xb2, 0xc4, 0x4c, 0x9f, 0x06, 0xd7, 0xe9, 0xa8, 0xe3, 0xbd, + 0x7c, 0xa9, 0x03, 0x6f, 0x25, 0x76, 0x69, 0xa4, 0x4f, 0xb3, 0x32, 0xf8, 0x85, 0x77, 0x89, 0xec, + 0x9c, 0x27, 0x82, 0x5a, 0xe0, 0x15, 0x6d, 0x45, 0xa2, 0xbd, 0xbf, 0x5f, 0x51, 0xf9, 0x8c, 0xc9, + 0x44, 0xbe, 0x9f, 0x42, 0xbf, 0xc5, 0xf1, 0x51, 0xa2, 0x28, 0xf9, 0xfd, 0x7d, 0x5e, 0x97, 0x38, + 0xb0, 0xd7, 0x1b, 0x79, 0x58, 0x01, 0xb2, 0xc9, 0xc5, 0xa9, 0xd2, 0x5f, 0x23, 0x38, 0xc2, 0x18, + 0x6e, 0x1d, 0x38, 0xe9, 0xc8, 0x1c, 0xfa, 0x21, 0xf0, 0x64, 0x86, 0xcf, 0xeb, 0x9b, 0xaf, 0xc0, + 0x33, 0x4a, 0xd9, 0x2e, 0x04, 0x7d, 0x86, 0xa0, 0xeb, 0xaf, 0x9a, 0x7a, 0xa7, 0x2c, 0x10, 0xf4, + 0x61, 0xc2, 0x07, 0xb0, 0xf5, 0x16, 0x39, 0x09, 0x29, 0xf8, 0x59, 0xdf, 0xc0, 0xf5, 0xa0, 0x82, + 0x79, 0x86, 0x86, 0x99, 0xc8, 0x5d, 0x2a, 0x32, 0x78, 0xe0, 0xe6, 0x0c, 0x14, 0xd6, 0x99, 0xf3, + 0xf0, 0xcf, 0x09, 0x8d, 0xef, 0x4e, 0xa9, 0x4f, 0x07, 0x69, 0x18, 0xef, 0xfa, 0x50, 0x38, 0x08, + 0x19, 0x48, 0x7e, 0x63, 0xe8, 0x2b, 0xcd, 0x15, 0x7a, 0x02, 0x2c, 0x6d, 0xea, 0x3c, 0x66, 0xb1, + 0xca, 0x31, 0x72, 0xee, 0xb0, 0x32, 0xb3, 0xb2, 0x69, 0x27, 0xd7, 0x32, 0x76, 0xd6, 0x0b, 0x45, + 0x48, 0x69, 0x3e, 0x27, 0x07, 0x2a, 0x5b, 0x69, 0xa2, 0xb8, 0x02, 0x7c, 0x05, 0x11, 0xe5, 0xb1, + 0x80, 0x81, 0xb8, 0xa9, 0x25, 0xe3, 0x85, 0xa6, 0x2a, 0xba, 0x71, 0x07, 0xe1, 0xc0, 0x72, 0xd3, + 0x72, 0x74, 0x30, 0xc6, 0x18, 0x0c, 0xc4, 0xb0, 0x08, 0x0c, 0x86, 0x8b, 0xc7, 0x2a, 0x69, 0xe1, + 0xfe, 0x0d, 0x2e, 0x79, 0x3e, 0x24, 0x1c, 0x7d, 0x2e, 0x64, 0x31, 0x55, 0x3a, 0x75, 0x43, 0x94, + 0xd7, 0x62, 0x3c, 0x77, 0xe0, 0x1d, 0xb1, 0x53, 0x13, 0x15, 0x4a, 0xd5, 0x0c, 0x5c, 0xc2, 0x3c, + 0x3f, 0xdb, 0xd3, 0x90, 0x3e, 0x4e, 0x0e, 0x12, 0x60, 0x94, 0xdc, 0x84, 0xc4, 0xaa, 0xaf, 0xb3, + 0xf2, 0x95, 0x49, 0x57, 0xdd, 0xbf, 0xbc, 0xfd, 0x60, 0xeb, 0x72, 0x99, 0x58, 0xfa, 0xe2, 0x2b, + 0xcc, 0xc5, 0x55, 0x07, 0x50, 0xb1, 0xfe, 0x4e, 0x81, 0xcc, 0x64, 0x91, 0x3f, 0xf9, 0xcd, 0x03, + 0x2e, 0x08, 0x93, 0x84, 0x54, 0x2a, 0xe3, 0x72, 0x02, 0xa5, 0x60, 0x29, 0x5c, 0xc9, 0x39, 0xbe, + 0xd2, 0x79, 0x69, 0x67, 0x29, 0x48, 0x3b, 0x65, 0x03, 0xe2, 0x57, 0x0f, 0x20, 0xc5, 0xd7, 0x66, + 0x5c, 0x51, 0x85, 0x12, 0x74, 0x0b, 0x9c, 0x78, 0xb6, 0x1a, 0x85, 0x02, 0x29, 0xb9, 0xbf, 0xe7, + 0xe7, 0xf4, 0xd5, 0xf1, 0x8b, 0x9c, 0xa0, 0x4b, 0x8b, 0xeb, 0xf2, 0x34, 0x65, 0xd7, 0xed, 0x8a, + 0x54, 0xd6, 0x3e, 0x85, 0x0a, 0x0a, 0xcb, 0x12, 0x3c, 0xed, 0x6f, 0xdb, 0x12, 0x09, 0x3f, 0xf0, + 0xf8, 0xa6, 0x79, 0xa1, 0x5c, 0x79, 0xb9, 0x8c, 0xf0, 0x2d, 0xcb, 0x02, 0xf1, 0x54, 0x21, 0xc1, + 0xfb, 0x06, 0xdc, 0x0a, 0x92, 0xcf, 0xab, 0x11, 0x4a, 0x16, 0x28, 0xcf, 0x71, 0xb9, 0xdb, 0xed, + 0x56, 0xbd, 0x26, 0x68, 0x0c, 0x94, 0xf7, 0x8a, 0xcf, 0x5c, 0x98, 0x19, 0x34, 0x17, 0x65, 0x06, + 0xcd, 0xaf, 0x94, 0x38, 0x56, 0xfc, 0x95, 0x82, 0x19, 0xdc, 0xd5, 0x43, 0x29, 0x3f, 0x58, 0xa3, + 0x5d, 0x23, 0x00, 0xa9, 0x32, 0x6c, 0x49, 0x95, 0xfb, 0x6c, 0x22, 0xe1, 0x7c, 0x05, 0xf5, 0xa9, + 0x70, 0x3a, 0xe7, 0x31, 0xeb, 0x25, 0xf1, 0xa5, 0x72, 0x10, 0xd4, 0x05, 0x0d, 0x8f, 0xab, 0x14, + 0x6d, 0xfc, 0x29, 0x4c, 0xa5, 0x26, 0xe2, 0x2f, 0xc8, 0x11, 0x58, 0xb0, 0x3d, 0x7f, 0xa7, 0xd5, + 0x94, 0x62, 0x82, 0x98, 0x1e, 0xfe, 0xe2, 0x84, 0xa0, 0x22, 0xe7, 0xb4, 0x50, 0x35, 0x89, 0x2e, + 0xf0, 0x64, 0x88, 0xd8, 0x8c, 0xd3, 0xc1, 0x15, 0xb0, 0xff, 0xfe, 0x7e, 0xf6, 0x6c, 0x8b, 0xad, + 0x6c, 0x8e, 0x93, 0xeb, 0x15, 0xcb, 0xba, 0x09, 0x3d, 0x97, 0xe0, 0x29, 0x1a, 0xca, 0x11, 0x86, + 0x40, 0x80, 0xdc, 0x40, 0x25, 0x8c, 0x80, 0x16, 0x77, 0x80, 0xaa, 0x33, 0xc4, 0x70, 0x79, 0x96, + 0x18, 0x84, 0x52, 0xe3, 0x2d, 0xde, 0x15, 0xd7, 0x36, 0x74, 0x6e, 0x6d, 0xe8, 0xf3, 0xde, 0xd5, + 0xe5, 0xee, 0x43, 0x8d, 0xcd, 0xc3, 0xe7, 0xca, 0x02, 0x2b, 0x39, 0xfc, 0xe2, 0xa0, 0xbe, 0xb6, + 0x56, 0x1f, 0xd4, 0x01, 0x55, 0x8e, 0x21, 0x0f, 0x0a, 0xf3, 0x8a, 0x8a, 0x82, 0x82, 0x17, 0xe8, + 0x5b, 0x3b, 0xc5, 0xda, 0x79, 0x3c, 0xe6, 0xae, 0x1c, 0x7c, 0x74, 0x6d, 0x55, 0x91, 0x3f, 0x5d, + 0xaa, 0xae, 0xc8, 0xa1, 0x1f, 0xae, 0x2c, 0x72, 0xd0, 0x25, 0x6a, 0x8b, 0x82, 0x88, 0x65, 0xaa, + 0x8b, 0x1c, 0x7a, 0x51, 0x7d, 0x31, 0x95, 0x92, 0x3b, 0x9a, 0xa4, 0x8a, 0xe8, 0x8a, 0xdb, 0x7c, + 0x8a, 0x00, 0x03, 0xf0, 0x3b, 0x57, 0x8e, 0xef, 0xc4, 0xe3, 0x5c, 0x8c, 0x4b, 0x32, 0xbe, 0x98, + 0x59, 0xb0, 0x9f, 0x2f, 0xf8, 0x7f, 0x9e, 0xff, 0x8c, 0x3f, 0x45, 0xc8, 0x03, 0xc3, 0xe3, 0xa6, + 0x7e, 0x9c, 0x77, 0xad, 0x35, 0xe9, 0x45, 0xaa, 0x29, 0xbb, 0x0c, 0x72, 0x4a, 0x3d, 0x56, 0xb2, + 0xbf, 0x22, 0x5f, 0xe8, 0x70, 0x9f, 0x51, 0xca, 0x16, 0x54, 0x53, 0x9c, 0xc5, 0xf1, 0xd9, 0x36, + 0x39, 0x8b, 0x0a, 0xb6, 0x54, 0x83, 0x5f, 0x71, 0x28, 0x65, 0xba, 0x72, 0xbf, 0xd2, 0xd2, 0xf5, + 0xaa, 0xff, 0x53, 0x99, 0xc2, 0x34, 0x8f, 0x5d, 0xd6, 0x60, 0xfb, 0x65, 0x9f, 0xf0, 0x30, 0x23, + 0xc4, 0x63, 0x0d, 0x9e, 0xde, 0x5a, 0x47, 0xfd, 0x3f, 0x20, 0x79, 0x35, 0x81, 0xb2, 0xd8, 0x03, + 0x71, 0x55, 0x78, 0xad, 0x9b, 0x08, 0xac, 0x69, 0x8e, 0xd1, 0xd7, 0xad, 0xae, 0x73, 0xd1, 0xbc, + 0x34, 0xd9, 0x1d, 0x55, 0xba, 0x17, 0x8e, 0x23, 0xbc, 0xae, 0xd2, 0x87, 0x21, 0x9d, 0xe9, 0xff, + 0xcc, 0x1d, 0x02, 0x5d, 0x24, 0xb2, 0x17, 0x1f, 0xe9, 0x1d, 0xcf, 0x8e, 0x2e, 0x21, 0x99, 0x55, + 0x17, 0x17, 0xb9, 0xec, 0x4c, 0xf5, 0x03, 0x13, 0xa6, 0xdc, 0xa8, 0x78, 0x41, 0xb2, 0xe2, 0x7d, + 0x11, 0xbf, 0x3d, 0xc1, 0x62, 0xb5, 0x06, 0xe0, 0xc9, 0x16, 0xcb, 0xf9, 0xb2, 0xda, 0xdb, 0x0f, + 0xb3, 0xdc, 0x94, 0x81, 0x8e, 0x65, 0x9d, 0x19, 0x63, 0x66, 0xa9, 0x4f, 0xdc, 0x59, 0x72, 0xbf, + 0x71, 0x78, 0x6b, 0xc9, 0xd9, 0x09, 0x44, 0xfb, 0x13, 0xd6, 0xde, 0x80, 0xf4, 0xc1, 0x6f, 0x59, + 0xf0, 0x4c, 0x8c, 0xee, 0xc1, 0x77, 0xad, 0xc9, 0xc7, 0x37, 0xaa, 0xe3, 0x2d, 0xbd, 0xc3, 0xe0, + 0x4b, 0xfd, 0x21, 0x58, 0xb6, 0x53, 0xf0, 0x73, 0x5e, 0x4f, 0x5a, 0xde, 0x0f, 0x50, 0x92, 0x53, + 0xfc, 0x01, 0x94, 0x72, 0xc6, 0xe0, 0x59, 0x3a, 0xda, 0xa6, 0xfd, 0x9a, 0xf7, 0xec, 0xdb, 0x32, + 0x71, 0x35, 0x64, 0xc1, 0x61, 0x95, 0xe5, 0x64, 0xcc, 0xb0, 0x55, 0x8c, 0xe4, 0xd7, 0x71, 0xa5, + 0x86, 0x6a, 0xe5, 0xe3, 0x0f, 0x76, 0x2d, 0x77, 0xca, 0x37, 0x58, 0xea, 0x08, 0x8b, 0x73, 0x91, + 0x1a, 0xb1, 0x34, 0x67, 0x52, 0x9f, 0xea, 0xed, 0x29, 0xc6, 0x61, 0xbc, 0x77, 0x55, 0x98, 0x79, + 0xe9, 0xae, 0x16, 0xec, 0x3c, 0x7f, 0x6a, 0xb2, 0x26, 0x7a, 0xde, 0x5a, 0xaa, 0xef, 0x74, 0x16, + 0xd0, 0xf9, 0x7e, 0xb0, 0x09, 0x22, 0x00, 0x34, 0xcc, 0x65, 0xe5, 0x92, 0x56, 0x01, 0x8b, 0x9f, + 0x12, 0x30, 0x0d, 0xd4, 0x61, 0xfc, 0xcc, 0x3b, 0x16, 0xf8, 0xc9, 0xc4, 0xf7, 0x69, 0xc1, 0xdc, + 0x5c, 0x51, 0x5e, 0xe0, 0x8d, 0x32, 0x2c, 0x2e, 0x66, 0x73, 0xc0, 0x63, 0xde, 0xa2, 0x48, 0x58, + 0x75, 0x49, 0x1c, 0xc2, 0xee, 0x9e, 0x89, 0x3d, 0x08, 0x55, 0x9c, 0x73, 0x42, 0x2c, 0x6e, 0x90, + 0xc9, 0x8d, 0xb3, 0x49, 0x64, 0xf5, 0x69, 0x96, 0xaf, 0x3f, 0x5d, 0x7d, 0xfd, 0xef, 0xe0, 0xdf, + 0x41, 0x4d, 0x17, 0xc3, 0x19, 0x82, 0xd9, 0x0b, 0xae, 0x9a, 0xca, 0xf9, 0xb1, 0x13, 0xc7, 0xce, + 0xdd, 0x9b, 0xc9, 0x70, 0x48, 0x63, 0x99, 0x4f, 0x22, 0x32, 0x65, 0x18, 0x0c, 0x44, 0xe9, 0x9f, + 0x71, 0x12, 0x30, 0x59, 0x93, 0xb2, 0xb1, 0x0d, 0x9b, 0x5d, 0x51, 0xe2, 0xd7, 0x9a, 0x56, 0x67, + 0x6e, 0x64, 0x11, 0xf9, 0x66, 0xce, 0x6a, 0xf7, 0xbb, 0x7f, 0xfc, 0x83, 0x54, 0xfe, 0x5b, 0x6e, + 0x2a, 0x29, 0xbf, 0xdf, 0xc5, 0x5e, 0x23, 0x06, 0x7c, 0x05, 0x31, 0x2a, 0x0f, 0x4c, 0xd3, 0xe4, + 0x37, 0xa2, 0x3e, 0x7f, 0xb9, 0xe2, 0x6d, 0x1d, 0x82, 0xef, 0x09, 0x8b, 0x01, 0xf1, 0x3e, 0x0e, + 0xe9, 0x87, 0x3e, 0xec, 0x86, 0x75, 0xa1, 0x39, 0x43, 0x1b, 0xec, 0xea, 0x37, 0xe4, 0xf1, 0xab, + 0xdd, 0xe6, 0xb3, 0xda, 0xb5, 0xf9, 0x60, 0xd1, 0x8f, 0xfe, 0x34, 0x8a, 0x59, 0x15, 0xff, 0xfb, + 0xc1, 0xfb, 0x9f, 0xd3, 0x34, 0x3a, 0xc1, 0x1b, 0xe3, 0x49, 0xda, 0x81, 0x61, 0x53, 0xc8, 0xc8, + 0x71, 0xdd, 0x1e, 0x76, 0xfd, 0xd0, 0x2f, 0x52, 0x70, 0x46, 0x78, 0x5b, 0x84, 0x2f, 0x02, 0xe9, + 0x31, 0xe8, 0x2f, 0xa8, 0x08, 0x15, 0x67, 0x0e, 0xe8, 0xb3, 0x27, 0xcc, 0xf3, 0x88, 0x5a, 0x96, + 0xc6, 0xf8, 0x46, 0x13, 0x0e, 0xc3, 0x57, 0x51, 0x8c, 0xb3, 0x8d, 0xe2, 0x14, 0x40, 0x4e, 0xdd, + 0x75, 0xcc, 0x61, 0x53, 0xc7, 0x7f, 0x81, 0x97, 0x68, 0x0c, 0x89, 0x79, 0x51, 0x77, 0xbb, 0xb2, + 0x53, 0xd0, 0xd5, 0x62, 0x16, 0xf8, 0xe0, 0xe2, 0x4b, 0xc9, 0x77, 0x55, 0x48, 0x79, 0x69, 0x3f, + 0xc3, 0x32, 0x87, 0xf3, 0x80, 0x63, 0x14, 0x96, 0x69, 0xa9, 0x56, 0x2a, 0xcd, 0x14, 0x6a, 0x12, + 0x0c, 0x62, 0xd8, 0x9b, 0x44, 0xce, 0xcc, 0xb2, 0x04, 0x11, 0xd8, 0x86, 0x26, 0x01, 0x78, 0xfd, + 0xd0, 0xb5, 0xa0, 0x0a, 0x5b, 0x5b, 0x2b, 0x06, 0x76, 0x36, 0x9b, 0xcd, 0xd7, 0xb9, 0x61, 0xb7, + 0x39, 0x52, 0xad, 0x9a, 0xb6, 0xf5, 0x78, 0x49, 0x22, 0x6d, 0x2c, 0x6f, 0x55, 0x14, 0x78, 0xa6, + 0xa5, 0x6f, 0xa2, 0x14, 0xc5, 0x0b, 0x2e, 0xf5, 0xc4, 0xb1, 0x1a, 0x47, 0x50, 0xb7, 0x78, 0xcd, + 0x52, 0x55, 0x48, 0xdc, 0x09, 0x6b, 0x36, 0x72, 0xf6, 0x2c, 0x5a, 0xc0, 0xe9, 0x43, 0x0c, 0x5a, + 0x6a, 0x01, 0xb1, 0x29, 0x5e, 0xcd, 0xfa, 0x94, 0x63, 0x05, 0x31, 0x20, 0xde, 0x10, 0x1c, 0xb4, + 0x26, 0x0e, 0x02, 0xa0, 0x8a, 0x04, 0xad, 0xb0, 0xf9, 0x82, 0x50, 0x63, 0x09, 0xbd, 0xfc, 0x99, + 0x9d, 0x0f, 0x60, 0x8b, 0xaf, 0x38, 0x1d, 0x00, 0x60, 0xf5, 0x74, 0x20, 0x1c, 0xa4, 0x14, 0x4c, + 0x26, 0x05, 0x8f, 0x3e, 0xce, 0xe7, 0x83, 0xc2, 0x29, 0x8e, 0x44, 0xfa, 0xe3, 0x92, 0xdc, 0xd5, + 0xde, 0xbc, 0xf4, 0x28, 0xe4, 0x9c, 0xc5, 0x68, 0x58, 0x21, 0x1f, 0xe1, 0x73, 0xa0, 0x6e, 0x4d, + 0x26, 0x83, 0x01, 0xa8, 0xd9, 0x10, 0x12, 0xe5, 0xbb, 0x15, 0x22, 0x1c, 0x9d, 0x97, 0x08, 0x37, + 0x07, 0x7c, 0x43, 0xeb, 0xef, 0xc7, 0xdd, 0xff, 0xbf, 0x3d, 0xf2, 0x05, 0xb7, 0x47, 0xf2, 0x72, + 0x5d, 0xbd, 0x09, 0x36, 0x1b, 0xc8, 0x7a, 0xf5, 0x87, 0x18, 0x45, 0xe6, 0x9a, 0xbf, 0x11, 0xa3, + 0x79, 0x7a, 0xf6, 0x0d, 0x5a, 0x93, 0x76, 0x3c, 0xbc, 0xc2, 0x4d, 0x07, 0xb6, 0x81, 0x21, 0x3d, + 0xa0, 0x7e, 0xdb, 0x43, 0x3d, 0xaf, 0x26, 0x17, 0x35, 0x6f, 0xea, 0x28, 0xd7, 0xfe, 0xf0, 0xd0, + 0x0d, 0x1b, 0x35, 0x6f, 0xc3, 0x18, 0x74, 0x0f, 0xfc, 0x8b, 0x7d, 0x42, 0x6f, 0x80, 0x36, 0x54, + 0xc8, 0xf3, 0x08, 0xbb, 0x33, 0x28, 0x9f, 0x4b, 0x83, 0xad, 0x44, 0xdd, 0xbd, 0xd0, 0x45, 0x70, + 0x76, 0x91, 0xb6, 0xfc, 0xe3, 0xf2, 0xe1, 0x4e, 0xaf, 0xa0, 0x04, 0x6f, 0x95, 0x90, 0x2d, 0x7c, + 0xc7, 0x28, 0x66, 0x77, 0x2b, 0x88, 0x7c, 0x57, 0xd6, 0xc3, 0x1e, 0x22, 0xa7, 0xd1, 0xfc, 0xee, + 0xbb, 0x63, 0xf4, 0xb0, 0xe4, 0xe8, 0x57, 0x7e, 0x23, 0x07, 0x02, 0xa2, 0x81, 0x0d, 0x62, 0x48, + 0x1e, 0x42, 0xbc, 0x94, 0xc2, 0x9a, 0xc5, 0x80, 0x70, 0x1c, 0xa5, 0x89, 0xf9, 0xb7, 0xb6, 0x88, + 0x51, 0x0e, 0x4c, 0xfb, 0xae, 0x52, 0x3a, 0x8e, 0xec, 0xe9, 0xa3, 0x0f, 0x06, 0xd9, 0x64, 0x64, + 0x07, 0xce, 0xc7, 0x3b, 0x27, 0x31, 0x3b, 0x8a, 0x51, 0xd2, 0xa3, 0xbf, 0x67, 0x53, 0xe2, 0x04, + 0x90, 0xed, 0xc8, 0x58, 0x7e, 0x3b, 0x62, 0x1a, 0x6e, 0x68, 0xc0, 0xff, 0x7e, 0x4b, 0x52, 0x6c, + 0xa6, 0xdc, 0x7c, 0xda, 0x62, 0x8d, 0xa6, 0xec, 0x9b, 0xee, 0xaa, 0xce, 0x64, 0x16, 0xe5, 0xce, + 0xca, 0xd9, 0xa7, 0x0c, 0xd4, 0xec, 0x2e, 0x6e, 0x8d, 0x8b, 0xe0, 0xef, 0xbc, 0x81, 0x8b, 0xf0, + 0x5e, 0xb6, 0xa6, 0xeb, 0x5b, 0xe8, 0x2c, 0x14, 0x23, 0xc3, 0xfe, 0x17, 0xe6, 0xab, 0x5c, 0xaf, + 0xf9, 0x5d, 0x87, 0xca, 0x63, 0x92, 0xbf, 0x22, 0x80, 0xd7, 0x62, 0x62, 0x69, 0x1f, 0xd8, 0x3e, + 0x2e, 0x66, 0x82, 0x45, 0xdc, 0xa2, 0x1d, 0xb8, 0xf8, 0x86, 0x86, 0x06, 0x21, 0x14, 0xdf, 0xda, + 0x07, 0x53, 0x28, 0xac, 0x85, 0xbd, 0x34, 0x43, 0x26, 0x81, 0xb0, 0xb7, 0x31, 0x54, 0xb1, 0x26, + 0xde, 0x31, 0x14, 0xe6, 0xf7, 0x46, 0x5c, 0xe8, 0x35, 0xfe, 0x4e, 0xbe, 0x37, 0x5a, 0xcc, 0x50, + 0xfe, 0x5e, 0xb3, 0xe5, 0xb9, 0x4d, 0xbd, 0xc9, 0xd6, 0x1e, 0xde, 0x0e, 0x46, 0x74, 0xf0, 0x11, + 0xf3, 0x15, 0x50, 0xee, 0xb9, 0x67, 0xc9, 0x25, 0x5f, 0x09, 0x62, 0xb5, 0x78, 0x57, 0x26, 0xcb, + 0xdf, 0x55, 0xa8, 0x3d, 0x5f, 0xee, 0x54, 0x67, 0xb1, 0x43, 0x8c, 0x01, 0x7e, 0x7b, 0x5d, 0x7c, + 0x84, 0x07, 0x6d, 0xa8, 0x1f, 0x17, 0x1f, 0x31, 0xd7, 0x52, 0x49, 0x6b, 0xe8, 0x9a, 0x56, 0x47, + 0x2c, 0x8c, 0xa5, 0xdf, 0x56, 0x04, 0x34, 0xe5, 0x7e, 0xd3, 0xe0, 0x7f, 0x0d, 0xc5, 0x33, 0x70, + 0x9f, 0xb0, 0x47, 0x76, 0x9d, 0xb6, 0xce, 0x5b, 0xd4, 0x9d, 0xb6, 0xfc, 0xda, 0xfb, 0xd7, 0xde, + 0xd1, 0x7e, 0x0f, 0xaa, 0x79, 0x6f, 0x2a, 0x8f, 0x05, 0x2a, 0x67, 0x25, 0x95, 0xad, 0xd6, 0xdc, + 0xb7, 0xe0, 0x17, 0x18, 0x8b, 0x63, 0x23, 0x2b, 0x93, 0x68, 0x9b, 0xed, 0xd2, 0xec, 0xe6, 0xa5, + 0x21, 0x9f, 0xb4, 0xca, 0x4f, 0x5a, 0xc5, 0x93, 0x8d, 0xf2, 0x93, 0x8d, 0xe2, 0xc9, 0x66, 0xf9, + 0xc9, 0xe6, 0xe5, 0xb4, 0xf3, 0xcd, 0x7d, 0x7c, 0xb1, 0x4b, 0xe6, 0xff, 0x4a, 0xce, 0xfd, 0x0b, + 0xb9, 0xfe, 0x60, 0x27, 0x6a, 0xba, 0x7c, 0xe3, 0x59, 0xe9, 0x33, 0x8b, 0x4e, 0xc5, 0x67, 0x35, + 0xb0, 0x44, 0x8f, 0xf5, 0xc1, 0xee, 0x1c, 0x0b, 0x59, 0xee, 0x63, 0xdb, 0x73, 0xdf, 0xd4, 0x5e, + 0x68, 0x90, 0xc7, 0x64, 0x96, 0x6e, 0x8b, 0xb7, 0x14, 0x2d, 0x3b, 0x7f, 0x65, 0x9b, 0x08, 0x3f, + 0x3f, 0x46, 0x0f, 0x20, 0x6b, 0xd1, 0x95, 0xef, 0xbe, 0xb3, 0x3b, 0x75, 0x82, 0xad, 0xf1, 0x00, + 0xaf, 0x05, 0xce, 0x97, 0x78, 0x5a, 0x5f, 0x89, 0x50, 0x6d, 0xd2, 0xc0, 0x17, 0x9e, 0xd7, 0xbb, + 0x76, 0x7b, 0x21, 0xd4, 0xd3, 0xac, 0x82, 0x78, 0xca, 0x67, 0x75, 0x66, 0x64, 0x20, 0xd0, 0x94, + 0xa2, 0x91, 0xec, 0x02, 0x2e, 0x6a, 0x2e, 0xc2, 0x7e, 0x23, 0x65, 0xa3, 0xcb, 0xf5, 0x18, 0x67, + 0xde, 0x1f, 0x7c, 0xb0, 0xcf, 0xe8, 0x87, 0xd7, 0xf6, 0x23, 0xf3, 0x39, 0xb9, 0x08, 0x81, 0xb9, + 0xec, 0x80, 0xe9, 0xb3, 0xba, 0xbd, 0x2c, 0x45, 0xf7, 0xc3, 0x7e, 0x35, 0x5a, 0xe0, 0x18, 0x14, + 0x28, 0x0b, 0x6f, 0xd6, 0x81, 0xa0, 0xc7, 0xf8, 0xa7, 0x00, 0x5c, 0xfc, 0xa6, 0xdc, 0x41, 0x79, + 0xe0, 0x1a, 0xdc, 0xd3, 0xec, 0xc2, 0xfe, 0x65, 0xf7, 0x10, 0x4b, 0xd1, 0xde, 0x1b, 0xbc, 0xaf, + 0xb5, 0x7b, 0x02, 0x3f, 0x77, 0x8f, 0x4f, 0xd8, 0xe7, 0x7f, 0xe1, 0xed, 0xac, 0xf3, 0x43, 0xf6, + 0xf3, 0x3d, 0x8e, 0x9f, 0xff, 0x04, 0x3f, 0x4f, 0x7b, 0xc7, 0xf0, 0xf3, 0x68, 0x0f, 0xeb, 0xe9, + 0xc3, 0xa3, 0x0f, 0x58, 0x30, 0xf4, 0xf6, 0xec, 0xcb, 0x8b, 0xf2, 0xed, 0xbc, 0xcb, 0xe9, 0x52, + 0x77, 0xf9, 0xe6, 0xb6, 0x66, 0x1e, 0x71, 0xeb, 0xce, 0x36, 0x26, 0xb1, 0x6f, 0x9d, 0x9f, 0xbc, + 0x17, 0x67, 0xc6, 0xbc, 0x35, 0x00, 0xdf, 0x35, 0xe4, 0x1c, 0xa8, 0xd9, 0xdc, 0x43, 0x65, 0x07, + 0x6d, 0xd9, 0x1c, 0x41, 0x09, 0x6d, 0x01, 0x0a, 0xc3, 0x31, 0xa5, 0x20, 0xf1, 0x34, 0x99, 0x25, + 0xe5, 0x40, 0x70, 0x89, 0xb5, 0x53, 0x76, 0xee, 0x69, 0xe4, 0x08, 0xd1, 0x72, 0x4b, 0x87, 0xc0, + 0x0e, 0xac, 0x97, 0x1f, 0xd0, 0x96, 0xc1, 0xb8, 0x5b, 0xcc, 0xc1, 0x90, 0xe0, 0x98, 0xde, 0x84, + 0x1f, 0x15, 0x82, 0x81, 0x8a, 0xdc, 0x04, 0x50, 0xbd, 0xeb, 0xd4, 0x8e, 0x47, 0x7c, 0x49, 0x29, + 0x5a, 0x82, 0xaa, 0x75, 0x6c, 0xda, 0x9c, 0xdb, 0x9a, 0xc8, 0xb4, 0x63, 0xa8, 0xa5, 0x90, 0xad, + 0xa2, 0x60, 0x95, 0x76, 0x57, 0x7e, 0x6b, 0x52, 0x2d, 0xf9, 0xd5, 0xf6, 0xff, 0x66, 0xf9, 0xdd, + 0x8b, 0x34, 0x8c, 0x0a, 0x74, 0x2a, 0x82, 0xd9, 0xeb, 0xf2, 0xea, 0x53, 0x79, 0x61, 0xbe, 0x68, + 0x7c, 0xcc, 0x1c, 0xfd, 0xdc, 0x78, 0x89, 0xd7, 0xf7, 0x7c, 0x2f, 0xbd, 0xe3, 0x81, 0xc1, 0x36, + 0x94, 0xc3, 0xf8, 0x7c, 0x1e, 0x94, 0xef, 0x2e, 0x0d, 0x5e, 0x97, 0xe8, 0x68, 0x6b, 0x9f, 0xb9, + 0x2f, 0x0c, 0x8a, 0xb7, 0x90, 0x91, 0x80, 0xba, 0x85, 0x5c, 0x07, 0x94, 0x25, 0xbf, 0xe0, 0x22, + 0x45, 0x89, 0xe9, 0xd3, 0xce, 0xce, 0xba, 0x78, 0x8f, 0x75, 0x67, 0x9d, 0xff, 0x91, 0xa3, 0x75, + 0xf6, 0xe7, 0x2f, 0xff, 0x03, 0xe7, 0xd4, 0x6d, 0x45, 0x0e, 0x53, 0x00, 0x00, }; -const unsigned int html_content_gz_len = 3910; +const unsigned int html_content_gz_len = 6013; #endif // HTML_CONTENT_GZ_H \ No newline at end of file diff --git a/main/webpage_minified.html b/main/webpage_minified.html index fbc6955..1109f95 100644 --- a/main/webpage_minified.html +++ b/main/webpage_minified.html @@ -1,10 +1,8 @@ -Control Panel

CluckCommand

Schedule Start
Schedule End
# Moves/Day
Remain. Distance (ft)
Move Distance (ft)
Jack Height (in)
Battery (V)
Program RF Remote


DANGER ZONE
Calibration
Firmware
Log File
\ No newline at end of file +`;for(let i=0;i<4;i++)learnedCodes[i]===0?summary+=`${buttonNames[i]}: -
`:summary+=`${buttonNames[i]}: ${learnedCodes[i]}
`;await modalAlert(summary),await fetchStatus()}catch(e){await modalAlert(`RF programming error: ${e.message}`)}}async function downloadLogFile(){try{let response=await fetch(`./log`);if(!response.ok){await modalAlert(`Failed to download log file: ${response.status} ${response.statusText}`);return}let blob=await response.blob(),now=/* @__PURE__ */ new Date,formattedDate=`${String(now.getDate()).padStart(2,`0`)}${[`JAN`,`FEB`,`MAR`,`APR`,`MAY`,`JUN`,`JUL`,`AUG`,`SEP`,`OCT`,`NOV`,`DEC`][now.getMonth()]}${now.getFullYear()}-${String(now.getHours()).padStart(2,`0`)}${String(now.getMinutes()).padStart(2,`0`)}`,url=URL.createObjectURL(blob),a=document.createElement(`a`);a.href=url,a.download=`storage-${formattedDate}.bin`,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(url)}catch(error){await modalAlert(`Error downloading log file: ${error.message}`)}}function startPolling(){fetchStatus(),pollInterval=setInterval(fetchStatus,3e3)}function stopPolling(){pollInterval&&=(clearInterval(pollInterval),null)}document.addEventListener(`visibilitychange`,function(){document.hidden?stopPolling():(fetchStatus(),pollInterval=setInterval(fetchStatus,3e3))}),window.onload=function(){ge(`commit_btn`).disabled=!0,ge(`cancel_btn`).disabled=!0,startPolling()}; \ No newline at end of file diff --git a/main/webserver.c b/main/webserver.c index 8dd2de5..a451734 100644 --- a/main/webserver.c +++ b/main/webserver.c @@ -25,7 +25,6 @@ #include "esp_log.h" #include "nvs_flash.h" #include "esp_http_server.h" -//#include "esp_https_server.h" #include "esp_netif.h" #include #include @@ -41,14 +40,13 @@ #define HOSTNAME "sc.local" -#define SOFT_AP_SSID "sc_main" -#define SOFT_AP_PASSWORD "stockcropper" #define SERVER_PORT 80 static const char *TAG = "WEBSERVER"; // HTTPS /* +#include "esp_https_server.h" extern const uint8_t servercert_pem_start[] asm("_binary_servercert_pem_start"); extern const uint8_t servercert_pem_end[] asm("_binary_servercert_pem_end"); extern const uint8_t prvtkey_pem_start[] asm("_binary_prvtkey_pem_start"); @@ -62,41 +60,88 @@ char httpBuffer[4096]; /* Handler to serve the HTML page */ static esp_err_t root_get_handler(httpd_req_t *req) { ESP_LOGI(TAG, "root_get_handler"); - // Send the HTML response - httpd_resp_set_type(req, "text/html"); // Original MIME type - httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); // Tell browser it's gzipped - return httpd_resp_send(req, (const char *)html_content, html_content_len); + if (req == NULL) { + ESP_LOGE(TAG, "Null request pointer"); + return ESP_FAIL; + } + + // Send the HTML response + esp_err_t err = httpd_resp_set_type(req, "text/html"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set response type: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set content encoding header: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_send(req, (const char *)html_content, html_content_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send HTML response: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_set_hdr(req, "Connection", "close"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set connection header: %s", esp_err_to_name(err)); + // Continue anyway + } + + return err; } // Cache the storage partition pointer to avoid repeated lookups static const esp_partition_t *cached_storage_partition = NULL; static esp_err_t log_handler(httpd_req_t *req) { - ESP_LOGI(TAG, "log_handler"); + //ESP_LOGI(TAG, "log_handler"); + + if (req == NULL) { + ESP_LOGE(TAG, "Null request pointer"); + return ESP_FAIL; + } + + rtc_reset_shutdown_timer(); int32_t tail = -1; - if (req -> method == HTTP_GET) { + if (req->method == HTTP_GET) { // give the whole log } - if (req -> method == HTTP_POST) { + else if (req->method == HTTP_POST) { int ret = httpd_req_recv(req, httpBuffer, sizeof(httpBuffer)); if (ret <= 0) { if (ret == HTTPD_SOCK_ERR_TIMEOUT) { - httpd_resp_send_408(req); + ESP_LOGW(TAG, "Socket timeout during receive"); + return httpd_resp_send_408(req); } - return ESP_FAIL; + ESP_LOGE(TAG, "Failed to receive POST data: %d", ret); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Failed to receive data"); } + + if (ret >= (int)sizeof(httpBuffer)) { + ESP_LOGE(TAG, "POST data exceeds buffer size"); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Request too large"); + } + httpBuffer[ret] = '\0'; // Null-terminate the string //ESP_LOGI(TAG, "LOG POST %.*s", ret, httpBuffer); if(sscanf(httpBuffer, "%ld", (long*)&tail) != 1) { // if malformed, just send the whole log. + ESP_LOGW(TAG, "Malformed tail parameter, using default"); tail = -1; } } + else { + ESP_LOGE(TAG, "Unsupported HTTP method: %d", req->method); + return httpd_resp_send_err(req, HTTPD_405_METHOD_NOT_ALLOWED, "Method not allowed"); + } // Use cached partition pointer instead of looking it up each time const esp_partition_t *storage_partition = cached_storage_partition; @@ -152,22 +197,44 @@ static esp_err_t log_handler(httpd_req_t *req) { // Send HTTP headers char len_str[16]; - sprintf(len_str, "%u", (unsigned)total_size); - httpd_resp_set_type(req, "application/octet-stream"); - httpd_resp_set_hdr(req, "Content-Disposition", "attachment; filename=\"sc_storage.bin\""); - httpd_resp_set_hdr(req, "Content-Length", len_str); + int written = snprintf(len_str, sizeof(len_str), "%u", (unsigned)total_size); + if (written < 0 || written >= (int)sizeof(len_str)) { + ESP_LOGE(TAG, "Failed to format content length"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Internal error formatting response"); + } + + esp_err_t err = httpd_resp_set_type(req, "application/octet-stream"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set response type: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_set_hdr(req, "Content-Disposition", "attachment; filename=\"sc_storage.bin\""); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set content disposition: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_set_hdr(req, "Content-Length", len_str); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set content length: %s", esp_err_to_name(err)); + return err; + } // Send head/tail pointers in big-endian format int32_t htail = htobe32(tail); int32_t hhead = htobe32(head); memcpy(&httpBuffer[0], &(htail), 4); memcpy(&httpBuffer[4], &(hhead), 4); - if (httpd_resp_send_chunk(req, (const char *)httpBuffer, 8) != ESP_OK) { - ESP_LOGE(TAG, "Failed to send head/tail chunk"); - return ESP_FAIL; + + err = httpd_resp_send_chunk(req, (const char *)httpBuffer, 8); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send head/tail chunk: %s", esp_err_to_name(err)); + return err; } - int32_t sent = 8; + //int32_t sent = 8; int32_t offset = tail; // Only send data if there's something to send @@ -179,7 +246,7 @@ static esp_err_t log_handler(httpd_req_t *req) { while (offset < (int32_t)storage_partition->size) { size_t to_read = MIN(sizeof(httpBuffer), storage_partition->size - offset); - esp_err_t err = esp_partition_read(storage_partition, offset, httpBuffer, to_read); + err = esp_partition_read(storage_partition, offset, httpBuffer, to_read); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to read partition at offset %ld: %s", (long)offset, esp_err_to_name(err)); @@ -187,12 +254,14 @@ static esp_err_t log_handler(httpd_req_t *req) { "Failed to read storage"); } - if (httpd_resp_send_chunk(req, (const char *)httpBuffer, to_read) != ESP_OK) { - ESP_LOGE(TAG, "Failed to send chunk at offset %ld", (long)offset); - return ESP_FAIL; + err = httpd_resp_send_chunk(req, (const char *)httpBuffer, to_read); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send chunk at offset %ld: %s", + (long)offset, esp_err_to_name(err)); + return err; } - sent += to_read; + //sent += to_read; offset += to_read; } @@ -206,7 +275,7 @@ static esp_err_t log_handler(httpd_req_t *req) { while (offset < head) { size_t to_read = MIN(sizeof(httpBuffer), head - offset); - esp_err_t err = esp_partition_read(storage_partition, offset, httpBuffer, to_read); + err = esp_partition_read(storage_partition, offset, httpBuffer, to_read); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to read partition at offset %ld: %s", (long)offset, esp_err_to_name(err)); @@ -214,332 +283,76 @@ static esp_err_t log_handler(httpd_req_t *req) { "Failed to read storage"); } - if (httpd_resp_send_chunk(req, (const char *)httpBuffer, to_read) != ESP_OK) { - ESP_LOGE(TAG, "Failed to send chunk at offset %ld", (long)offset); - return ESP_FAIL; + err = httpd_resp_send_chunk(req, (const char *)httpBuffer, to_read); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send chunk at offset %ld: %s", + (long)offset, esp_err_to_name(err)); + return err; } - sent += to_read; + //sent += to_read; offset += to_read; } } - //ESP_LOGI(TAG, "Transfer complete: sent %ld bytes (expected %ld)", (long)sent, (long)total_size); - - // End chunked transfer - if (httpd_resp_send_chunk(req, NULL, 0) != ESP_OK) { - ESP_LOGE(TAG, "Failed to send final empty chunk"); - return ESP_FAIL; + // Send empty chunk to signal end + err = httpd_resp_send_chunk(req, NULL, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send final chunk: %s", esp_err_to_name(err)); + return err; } - //ESP_LOGI(TAG, "Final empty chunk sent successfully"); - return ESP_OK; + //ESP_LOGI(TAG, "Successfully sent %ld bytes", (long)sent); + + err = httpd_resp_set_hdr(req, "Connection", "close"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set connection header: %s", esp_err_to_name(err)); + // Continue anyway + } + + return err; } -// set time: timestamp (unix epoch, seconds) -static esp_err_t st_post_handler(httpd_req_t *req) { - ESP_LOGI(TAG, "st_post_handler"); - // Send the HTML response +/** + * Unified GET handler - returns complete system status + * Response format: + * { + * "time": 1234567, + * "rtc_valid": true, + * "state": 2, + * "voltage": 12.45, + * "remaining_dist": 12.0, + * "msg": "IDLE", + * "parameters": { + * "values": [12, 45, -3, 45.6, ...], + * "names": ["param1", "param2", ...], + * "units": ["s", "ms", "inches", ...] + * }, + * ... other parameters as direct key-value pairs + * } + */ +static esp_err_t get_handler(httpd_req_t *req) { + ESP_LOGI(TAG, "get_handler"); - int ret = httpd_req_recv(req, httpBuffer, sizeof(httpBuffer)); - if (ret <= 0) { - if (ret == HTTPD_SOCK_ERR_TIMEOUT) { - httpd_resp_send_408(req); - } - return ESP_FAIL; - } - httpBuffer[ret] = '\0'; // Null-terminate the string - - ESP_LOGI(TAG, "ST POST %.*s", ret, httpBuffer); - int64_t tv = -1; - - /*if(sscanf(httpBuffer, "%d-%d-%dT%d:%d", &tv) == 1) { - system_rtc_set_raw_time(tv); - }*/ - if(sscanf(httpBuffer, "%lld", &tv) == 1) { - system_rtc_set_raw_time(tv); - } - - return httpd_resp_send(req, "200 OK", HTTPD_RESP_USE_STRLEN); -} - -// set parameters id & value -// set parameters - accepts multiple parameters with mixed key types -static esp_err_t sp_post_handler(httpd_req_t *req) { - char content[512]; // Increased buffer for multiple parameters - size_t recv_size = (req->content_len < sizeof(content)) ? req->content_len : sizeof(content) - 1; - - // 1. Receive the data - int ret = httpd_req_recv(req, content, recv_size); - if (ret <= 0) { - if (ret == HTTPD_SOCK_ERR_TIMEOUT) { - httpd_resp_send_408(req); - } - return ESP_FAIL; - } - content[ret] = '\0'; // Null-terminate the string - - // 2. Parse the JSON - cJSON *root = cJSON_Parse(content); - if (root == NULL) { - ESP_LOGE(TAG, "Failed to parse JSON: %s", content); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); - return ESP_FAIL; - } - - int params_updated = 0; - int params_failed = 0; - - // 3. Iterate through all items in the JSON object - cJSON *item = NULL; - cJSON_ArrayForEach(item, root) { - int param_id = -1; - const char *key = item->string; - - if (key == NULL) { - ESP_LOGW(TAG, "Skipping item with null key"); - params_failed++; - continue; - } - - // Try to parse key as a parameter ID (numeric string like "4") - char *endptr; - long parsed_id = strtol(key, &endptr, 10); - if (*endptr == '\0' && parsed_id >= 0 && parsed_id < NUM_PARAMS) { - // Key is a valid numeric string - param_id = (int)parsed_id; - } else { - // Key is a string name, search for matching parameter - for (uint8_t i = 0; i < NUM_PARAMS; i++) { - if (strcmp(key, get_param_name(i)) == 0) { - param_id = i; - break; - } - } - } - - // Check if we found a valid parameter - if (param_id < 0 || param_id >= NUM_PARAMS) { - ESP_LOGW(TAG, "Unknown parameter key: %s", key); - params_failed++; - continue; - } - - // Get the value - if (cJSON_IsNumber(item)) { - - double param_val = item->valuedouble; - - ESP_LOGI(TAG, "Updating Param '%s' (ID: %d) to Value: %.2f", key, param_id, param_val); - - // Set the parameter based on its type - switch(get_param_type(param_id)) { - case PARAM_TYPE_u16: - set_param_value_t(param_id, (param_value_t){.u16 = round(param_val)}); - break; - case PARAM_TYPE_i16: - set_param_value_t(param_id, (param_value_t){.i16 = round(param_val)}); - break; - case PARAM_TYPE_u32: - set_param_value_t(param_id, (param_value_t){.u32 = round(param_val)}); - break; - case PARAM_TYPE_i32: - set_param_value_t(param_id, (param_value_t){.i32 = round(param_val)}); - break; - case PARAM_TYPE_u64: - set_param_value_t(param_id, (param_value_t){.u64 = round(param_val)}); - break; - case PARAM_TYPE_i64: - set_param_value_t(param_id, (param_value_t){.i64 = round(param_val)}); - break; - case PARAM_TYPE_f32: - set_param_value_t(param_id, (param_value_t){.f32 = param_val}); - break; - case PARAM_TYPE_f64: - set_param_value_t(param_id, (param_value_t){.f64 = param_val}); - break; - default: - ESP_LOGW(TAG, "Unknown parameter type for ID %d", param_id); - params_failed++; - continue; - } - } else if (cJSON_IsString(item)) { - set_param_string(param_id, item->valuestring); - } else { - ESP_LOGW(TAG, "Parameter bad type: %s", key); - params_failed++; - continue; - } - - params_updated++; - } - - commit_params(); - - cJSON_Delete(root); - - // 5. Send Success Response - return httpd_resp_send(req, "200 OK", HTTPD_RESP_USE_STRLEN); -} - - -static esp_err_t cmd_post_handler(httpd_req_t *req) { - ESP_LOGI(TAG, "cmd_post_handler"); - // Send the HTML response - int ret = httpd_req_recv(req, httpBuffer, sizeof(httpBuffer)); - if (ret <= 0) { - if (ret == HTTPD_SOCK_ERR_TIMEOUT) { - httpd_resp_send_408(req); - } - return ESP_FAIL; - } - httpBuffer[ret] = '\0'; // Null-terminate the string - - cJSON *root = cJSON_Parse(httpBuffer); - if (root == NULL) { - ESP_LOGE(TAG, "Failed to parse JSON: %s", httpBuffer); - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); + if (req == NULL) { + ESP_LOGE(TAG, "Null request pointer"); return ESP_FAIL; } - cJSON *cmd = cJSON_GetObjectItem(root, "cmd"); + rtc_reset_shutdown_timer(); - if (!cJSON_IsString(cmd) || cmd->valuestring == NULL) - return httpd_resp_send(req, "400 Bad Request", HTTPD_RESP_USE_STRLEN); - - if (strcmp(cmd->valuestring, "stop") == 0) { - fsm_request(FSM_CMD_STOP); - ESP_LOGI(TAG, "FSM_CMD_STOP"); - } else if (strcmp(cmd->valuestring, "undo") == 0) { - fsm_request(FSM_CMD_UNDO); - ESP_LOGI(TAG, "FSM_CMD_UNDO"); - } else if (strcmp(cmd->valuestring, "reboot") == 0) { - // Send response FIRST - httpd_resp_send(req, "Rebooting...", HTTPD_RESP_USE_STRLEN); - - set_param_value_t(PARAM_BOOT_TIME, (param_value_t){.i64 = system_rtc_get_raw_time()}); - - // THEN delay and reboot - vTaskDelay(pdMS_TO_TICKS(2000)); // Give time for TCP to close properly - esp_restart(); - } else if (strcmp(cmd->valuestring, "start") == 0) { - fsm_request(FSM_CMD_START); - ESP_LOGI(TAG, "FSM_CMD_START"); - } else if (strcmp(cmd->valuestring, "cal_jack_start") == 0) { - fsm_request(FSM_CMD_CALIBRATE_JACK_PREP); - ESP_LOGI(TAG, "FSM_CMD_CALIBRATE_JACK_PREP"); - } else if (strcmp(cmd->valuestring, "cal_jack_finish") == 0) { - cJSON *i = cJSON_GetObjectItem(root, "amt"); - if (cJSON_IsNumber(i) && i->valuedouble >= 0 && i->valuedouble < 8) { - ESP_LOGI(TAG, "FSM_CMD_CALIBRATE_JACK_FINISH"); - fsm_set_cal_val(i->valuedouble); - fsm_request(FSM_CMD_CALIBRATE_JACK_FINISH); - } - } else if (strcmp(cmd->valuestring, "cal_drive_start") == 0) { - fsm_request(FSM_CMD_CALIBRATE_DRIVE_PREP); - ESP_LOGI(TAG, "FSM_CMD_CALIBRATE_DRIVE_PREP"); - } else if (strcmp(cmd->valuestring, "cal_drive_finish") == 0) { - cJSON *i = cJSON_GetObjectItem(root, "amt"); - if (cJSON_IsNumber(i) && i->valuedouble >= 0 && i->valuedouble < 8) { - ESP_LOGI(TAG, "FSM_CMD_CALIBRATE_DRIVE_FINISH"); - fsm_set_cal_val(i->valuedouble); - fsm_request(FSM_CMD_CALIBRATE_DRIVE_FINISH); - } - } else if (strcmp(cmd->valuestring, "cal_get") == 0) { - ESP_LOGI(TAG, "CAL_GET"); - sprintf(httpBuffer, "{\"e\":%lld,\"t\":%lld}", fsm_get_cal_e(), fsm_get_cal_t()); - - httpd_resp_set_type(req, "application/json"); - return httpd_resp_send(req, httpBuffer, HTTPD_RESP_USE_STRLEN); - } - - else if (strcmp(cmd->valuestring, "remaining_dist") == 0) { - cJSON *i = cJSON_GetObjectItem(root, "amt"); - if (cJSON_IsNumber(i)) { - ESP_LOGI(TAG, "remaining_dist"); - fsm_set_remaining_distance(i->valuedouble); - } - } - - else if (strcmp(cmd->valuestring, "rfp") == 0) { - cJSON *i = cJSON_GetObjectItem(root, "channel"); - if (cJSON_IsNumber(i) && i->valueint >= 0 && i->valueint < 8) { - rf_433_learn_keycode(i->valueint); - } else { - rf_433_cancel_learn_keycode(); - } - } else if (strcmp(cmd->valuestring, "rf_status") == 0) { - // Return current temp RF button codes (from temp storage, not params) - int head = 0; - head += sprintf(httpBuffer, "{\"codes\":["); - - for (uint8_t i = 0; i < NUM_RF_BUTTONS; i++) { - if (i > 0) head += sprintf(httpBuffer+head, ","); - - int64_t code = rf_433_get_temp_keycode(i); - head += sprintf(httpBuffer+head, "%ld", (long)code); - } - - head += sprintf(httpBuffer+head, "]}"); - - httpd_resp_set_type(req, "application/json"); - return httpd_resp_send(req, httpBuffer, head); - } else if (strcmp(cmd->valuestring, "rf_clear_temp") == 0) { - rf_433_clear_temp_keycodes(); - ESP_LOGI(TAG, "RF temp keycodes cleared"); - } else if (strcmp(cmd->valuestring, "rf_set_temp") == 0) { - // Set a temp keycode (for skipping) - cJSON *index = cJSON_GetObjectItem(root, "index"); - cJSON *code = cJSON_GetObjectItem(root, "code"); - if (cJSON_IsNumber(index) && cJSON_IsNumber(code)) { - rf_433_set_temp_keycode(index->valueint, (int64_t)code->valuedouble); - ESP_LOGI(TAG, "RF temp keycode %d set to %ld", index->valueint, (long)(int64_t)code->valuedouble); - } - } else if (strcmp(cmd->valuestring, "rf_disable") == 0) { - rf_433_disable_controls(); - ESP_LOGI(TAG, "RF controls disabled"); - } else if (strcmp(cmd->valuestring, "rf_enable") == 0) { - rf_433_enable_controls(); - ESP_LOGI(TAG, "RF controls enabled"); - } else { - ESP_LOGE(TAG, "Command not valid: %s", httpBuffer); - return httpd_resp_send(req, "400 Bad Request", HTTPD_RESP_USE_STRLEN); - } - - httpd_resp_set_type(req, "text/html"); - return httpd_resp_send(req, "200 OK", HTTPD_RESP_USE_STRLEN); + int head = 0; -} - -/* Handler for Status GET request*/ -static esp_err_t status_get_handler(httpd_req_t *req) { - ESP_LOGI(TAG, "status_get_handler"); - size_t head = 0; - - // Set the response type to JSON - httpd_resp_set_type(req, "application/json"); - - // Start building the JSON string with time - head += sprintf(httpBuffer+head, "{\"time\":%lld,\"rtc_set\":%s,", - system_rtc_get_raw_time(), - rtc_is_set()?"true":"false"); + // Start JSON object + head += sprintf(httpBuffer+head, "{"); + head += sprintf(httpBuffer+head, "\"time\":%lld,", (long long)rtc_get_s()); + head += sprintf(httpBuffer+head, "\"rtc_set\":%s,", rtc_is_set() ? "true" : "false"); + head += sprintf(httpBuffer+head, "\"state\":%d,", fsm_get_state()); + head += sprintf(httpBuffer+head, "\"voltage\":%.3f,", get_battery_V()); + head += sprintf(httpBuffer+head, "\"remaining_dist\":%.3f,", fsm_get_remaining_distance()); + head += sprintf(httpBuffer+head, "\"next_alarm\":%lld,", rtc_get_next_alarm_s()); - float vbat = get_battery_V(); - if (fpclassify(vbat) == FP_NORMAL) { - head += sprintf(httpBuffer+head, "\"battery\":%f,", - vbat); - } else { - head += sprintf(httpBuffer+head, "\"battery\":null,"); - } - - float d = fsm_get_remaining_distance(); - if (fpclassify(d) == FP_NORMAL) { - head += sprintf(httpBuffer+head, "\"remaining_dist\":%f,\"msg\":\"",d); - } else { - head += sprintf(httpBuffer+head, "\"remaining_dist\":null,\"msg\":\""); - } - - + head += sprintf(httpBuffer+head, "\"msg\":\""); switch(fsm_get_state()) { case STATE_IDLE: @@ -554,273 +367,1006 @@ static esp_err_t status_get_handler(httpd_req_t *req) { break; } + if (fsm_get_remaining_distance()<=0) { + head += sprintf(httpBuffer+head, " | DISTANCE LIMIT HIT"); + } if (efuse_is_tripped(BRIDGE_AUX)) head += sprintf(httpBuffer+head, " | AUX EFUSE TRIP"); if (efuse_is_tripped(BRIDGE_JACK)) head += sprintf(httpBuffer+head, " | JACK EFUSE TRIP"); if (efuse_is_tripped(BRIDGE_DRIVE)) head += sprintf(httpBuffer+head, " | DRIVE EFUSE TRIP"); - if (!rtc_is_set()) { - head += sprintf(httpBuffer+head, " | RTC NOT SET"); + head += sprintf(httpBuffer+head, " | CLOCK NOT SET"); } + // Add parameters metadata object + head += sprintf(httpBuffer+head, "\",\"parameters\":{"); - head += sprintf(httpBuffer+head, "\",\"values\":["); - + // Values array + //head += sprintf(httpBuffer+head, "\"names\":["); for (param_idx_t i = 0; i < NUM_PARAMS; i++) { if (i > 0) { head += sprintf(httpBuffer+head, ","); } - - // Retrieve the parameter; assuming get_param(i) returns a param_t struct with union - param_value_t param = get_param_value_t(i); - - // Append the parameter value based on its type + + head += sprintf(httpBuffer+head, "\"%s\":", get_param_name(i)); + + param_value_t value = get_param_value_t(i); + switch (get_param_type(i)) { - case PARAM_TYPE_u16: head+=sprintf(httpBuffer+head, "%u", param.u16); break; - case PARAM_TYPE_i16: head+=sprintf(httpBuffer+head, "%d", param.i16); break; - case PARAM_TYPE_u32: head+=sprintf(httpBuffer+head, "%lu", (unsigned long)param.u32); break; - case PARAM_TYPE_i32: head+=sprintf(httpBuffer+head, "%ld", (long)param.i32); break; - case PARAM_TYPE_u64: head+=sprintf(httpBuffer+head, "%llu", param.u64); break; - case PARAM_TYPE_i64: head+=sprintf(httpBuffer+head, "%lld", param.i64); break; case PARAM_TYPE_f32: - if (fpclassify(param.f32) == FP_NORMAL) - head+=sprintf(httpBuffer+head, "%.8f", param.f32); - else - head+=sprintf(httpBuffer+head, "null"); - break; + head += sprintf(httpBuffer+head, "%.4f", value.f32); + break; case PARAM_TYPE_f64: - if (fpclassify(param.f32) == FP_NORMAL) - head+=sprintf(httpBuffer+head, "%.8f", param.f64); - else - head+=sprintf(httpBuffer+head, "null"); - break; - case PARAM_TYPE_str: - head+=sprintf(httpBuffer+head, "\"%s\"", param.str); - break; + head += sprintf(httpBuffer+head, "%.4f", value.f64); + break; + case PARAM_TYPE_i32: + head += sprintf(httpBuffer+head, "%ld", (long)value.i32); + break; + case PARAM_TYPE_i16: + head += sprintf(httpBuffer+head, "%d", value.i16); + break; + case PARAM_TYPE_u32: + head += sprintf(httpBuffer+head, "%lu", (long)value.u32); + break; + case PARAM_TYPE_u16: + head += sprintf(httpBuffer+head, "%u", value.u16); + break; + case PARAM_TYPE_str: + head += sprintf(httpBuffer+head, "\"%s\"", get_param_string(i)); + break; + default: + head += sprintf(httpBuffer+head, "null"); + break; } } + /*head += sprintf(httpBuffer+head, "],"); - head += sprintf(httpBuffer+head, "], \"names\":["); + // Names array + head += sprintf(httpBuffer+head, "\"names\":["); for (param_idx_t i = 0; i < NUM_PARAMS; i++) { if (i > 0) { head += sprintf(httpBuffer+head, ","); } head += sprintf(httpBuffer+head, "\"%s\"", get_param_name(i)); - } - - head += sprintf(httpBuffer+head, "], \"units\":["); + } + head += sprintf(httpBuffer+head, "],"); + + // Units array + head += sprintf(httpBuffer+head, "\"units\":["); for (param_idx_t i = 0; i < NUM_PARAMS; i++) { if (i > 0) { head += sprintf(httpBuffer+head, ","); } head += sprintf(httpBuffer+head, "\"%s\"", get_param_unit(i)); - } + } + head += sprintf(httpBuffer+head, "]");*/ + + // Close parameters object + head += sprintf(httpBuffer+head, "}"); + + // Close main JSON object + head += sprintf(httpBuffer+head, "}"); + + // Check if buffer might overflow + if (head >= (int)(sizeof(httpBuffer) - 100)) { + ESP_LOGE(TAG, "GET response buffer near overflow"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Status data too large"); + } - // Close the JSON array and object - head += sprintf(httpBuffer+head, "]}"); - - return httpd_resp_send(req, httpBuffer, head); + esp_err_t err = httpd_resp_set_type(req, "application/json"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set response type: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_send(req, httpBuffer, head); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send status response: %s", esp_err_to_name(err)); + return err; + } + + + err = httpd_resp_set_hdr(req, "Connection", "close"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set connection header: %s", esp_err_to_name(err)); + // Continue anyway + } + + return err; } + +/** + * Unified POST handler - handles commands, parameter updates, time updates + * Request format (all fields optional): + * { + * "time": 1234567, // Update RTC time + * "state": 2, // Update FSM state + * "cmd": "start", // Execute command + * "voltage": 12.45, // Update individual parameter + * "parameters": { // Batch update parameters + * "PARAM_NAME": -15, + * "PARAM_NAME2": 12.0 + * } + * } + */ +static esp_err_t post_handler(httpd_req_t *req) { + ESP_LOGI(TAG, "post_handler"); + + if (req == NULL) { + ESP_LOGE(TAG, "Null request pointer"); + return ESP_FAIL; + } + + rtc_reset_shutdown_timer(); + + // Receive POST data + int ret = httpd_req_recv(req, httpBuffer, sizeof(httpBuffer)); + if (ret <= 0) { + if (ret == HTTPD_SOCK_ERR_TIMEOUT) { + ESP_LOGW(TAG, "Socket timeout during receive"); + return httpd_resp_send_408(req); + } + ESP_LOGE(TAG, "Failed to receive POST data: %d", ret); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Failed to receive data"); + } + + if (ret >= (int)sizeof(httpBuffer)) { + ESP_LOGE(TAG, "POST data exceeds buffer size"); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Request too large"); + } + + httpBuffer[ret] = '\0'; + + ESP_LOGI(TAG, "POST: %.*s", ret, httpBuffer); + + // Parse JSON + cJSON *root = cJSON_Parse(httpBuffer); + if (root == NULL) { + const char *error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) { + ESP_LOGE(TAG, "JSON parse error before: %s", error_ptr); + } + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); + } + + bool cmd_executed = false; + bool sleep_requested = false; + bool reboot_requested = false; + const char *error_msg = NULL; + int params_updated = 0; + int params_failed = 0; + + // Process time if present + cJSON *time = cJSON_GetObjectItem(root, "time"); + if (cJSON_IsNumber(time)) { + int64_t new_time = (int64_t)cJSON_GetNumberValue(time); + ESP_LOGI(TAG, "Setting time to %lld", new_time); + rtc_set_s(new_time); + } + + + cJSON *remaining_dist = cJSON_GetObjectItem(root, "remaining_dist"); + if (cJSON_IsNumber(remaining_dist)) { + int64_t new_dist = (int64_t)cJSON_GetNumberValue(remaining_dist); + ESP_LOGI(TAG, "Setting time to %lld", new_dist); + fsm_set_remaining_distance(new_dist); + } + + // WE DO NOT PROCESS STATE. STATE IS A READ-ONLY. + + // Process command if present + cJSON *cmd = cJSON_GetObjectItem(root, "cmd"); + if (cJSON_IsString(cmd)) { + const char *cmd_str = cmd->valuestring; + ESP_LOGI(TAG, "Executing command: %s", cmd_str); + + /* + // Claude made this, wtf? + if (strcmp(cmd_str, "trigger") == 0) { + // Trigger RF433 transmitter + rf_433_transmit(); + cmd_executed = true; + } else */ + if (strcmp(cmd_str, "start") == 0) { + // Start operation - transition FSM to running state + //fsm_set_state(FSM_STATE_RUNNING); + fsm_request(FSM_CMD_START); + cmd_executed = true; + } + else if (strcmp(cmd_str, "stop") == 0) { + // Stop operation - transition FSM to idle state + //fsm_set_state(FSM_STATE_IDLE); + fsm_request(FSM_CMD_STOP); + cmd_executed = true; + } + else if (strcmp(cmd_str, "undo") == 0) { + // Stop operation - transition FSM to idle state + //fsm_set_state(FSM_STATE_IDLE); + fsm_request(FSM_CMD_UNDO); + cmd_executed = true; + } + else if (strcmp(cmd_str, "fwd") == 0) { + pulseOverride(RELAY_A1); pulseOverride(RELAY_A3); + cmd_executed = true; + } + else if (strcmp(cmd_str, "rev") == 0) { + pulseOverride(RELAY_B1); pulseOverride(RELAY_A3); + cmd_executed = true; + } + else if (strcmp(cmd_str, "up") == 0) { + pulseOverride(RELAY_A2); + cmd_executed = true; + } + else if (strcmp(cmd_str, "down") == 0) { + pulseOverride(RELAY_B2); + cmd_executed = true; + } + else if (strcmp(cmd_str, "aux") == 0) { + pulseOverride(RELAY_A3); + cmd_executed = true; + } + else if (strcmp(cmd_str, "reboot") == 0) { + reboot_requested = true; + cmd_executed = true; + } + else if (strcmp(cmd_str, "sleep") == 0) { + sleep_requested = true; + cmd_executed = true; + } + /*else if (strcmp(cmd_str, "rfp") == 0) { + // RF programming command - get channel parameter + cJSON *channel = cJSON_GetObjectItem(root, "channel"); + if (cJSON_IsNumber(channel)) { + int ch = (int)cJSON_GetNumberValue(channel); + ESP_LOGI(TAG, "RF programming channel: %d", ch); + rf_433_learn(ch); + cmd_executed = true; + } else { + ESP_LOGW(TAG, "rfp command missing or invalid channel parameter"); + error_msg = "rfp requires channel parameter"; + } + }*/ + else if (strcmp(cmd_str, "rf_clear_temp") == 0) { + rf_433_clear_temp_keycodes(); + cmd_executed = true; + } + else if (strcmp(cmd_str, "rf_disable") == 0) { + rf_433_disable_controls(); + cmd_executed = true; + } + else if (strcmp(cmd_str, "rf_enable") == 0) { + rf_433_enable_controls(); + cmd_executed = true; + } + else if (strcmp(cmd_str, "rf_learn") == 0) { + // Start learning for a specific channel + cJSON *channel = cJSON_GetObjectItem(root, "channel"); + if (cJSON_IsNumber(channel)) { + int ch = (int)cJSON_GetNumberValue(channel); + if (ch >= 0 && ch < NUM_RF_BUTTONS) { + rf_433_learn_keycode(ch); + cmd_executed = true; + } else if (ch == -1) { + rf_433_cancel_learn_keycode(); + cmd_executed = true; + } else { + error_msg = "Invalid channel number"; + } + } else { + error_msg = "rf_learn requires channel parameter"; + } + } + else if (strcmp(cmd_str, "rf_set_temp") == 0) { + cJSON *index = cJSON_GetObjectItem(root, "index"); + cJSON *code = cJSON_GetObjectItem(root, "code"); + if (cJSON_IsNumber(index) && cJSON_IsNumber(code)) { + int idx = (int)cJSON_GetNumberValue(index); + int32_t rf_code = (int32_t)cJSON_GetNumberValue(code); + rf_433_set_temp_keycode(idx, rf_code); + cmd_executed = true; + } else { + error_msg = "rf_set_temp requires index and code parameters"; + } + } + else if (strcmp(cmd_str, "rf_status") == 0) { + // Return current temp keycodes + cJSON *response = cJSON_CreateObject(); + cJSON *codes_array = cJSON_CreateArray(); + + for (int i = 0; i < 4; i++) { // Only return first 4 for web UI + int32_t code = rf_433_get_temp_keycode(i); + cJSON_AddItemToArray(codes_array, cJSON_CreateNumber(code)); + } + + cJSON_AddItemToObject(response, "codes", codes_array); + + char *json_str = cJSON_Print(response); + cJSON_Delete(response); + cJSON_Delete(root); + + esp_err_t err = httpd_resp_set_type(req, "application/json"); + if (err == ESP_OK) { + err = httpd_resp_send(req, json_str, strlen(json_str)); + } + free(json_str); + return err; + } + else { + ESP_LOGW(TAG, "Unknown command: %s", cmd_str); + error_msg = "Unknown command"; + } + } + + // Process batch parameter updates if present + cJSON *parameters = cJSON_GetObjectItem(root, "parameters"); + if (cJSON_IsObject(parameters)) { + // Process individual parameter updates (direct key-value pairs) + cJSON *item = NULL; + cJSON_ArrayForEach(item, parameters) { + const char *key = item->string; + ESP_LOGW(TAG, "PARAMETER %s", key); + + // Find parameter index by name + param_idx_t param_idx = NUM_PARAMS; + for (param_idx_t i = 0; i < NUM_PARAMS; i++) { + if (strcmp(get_param_name(i), key) == 0) { + param_idx = i; + break; + } + } + + if (param_idx == NUM_PARAMS) { + ESP_LOGW(TAG, "UNKNOWN PARAMETER %s", key); + // Not a known parameter, skip silently + continue; + } + + cJSON *value_json = cJSON_GetObjectItem(parameters, key); + + // Set parameter value based on type + switch (get_param_type(param_idx)) { + case PARAM_TYPE_f32: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.f32=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_f64: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.f64=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_i32: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.i32=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_i16: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.i16=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_u32: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.u32=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_u16: + if (cJSON_IsNumber(value_json)) { + set_param_value_t(param_idx, + (param_value_t){.u16=value_json->valueint}); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + case PARAM_TYPE_str: + if (cJSON_IsString(value_json)) { + set_param_string(param_idx, value_json->valuestring); + params_updated++; + } else { ESP_LOGW(TAG, "PARAM TYPE MISMATCH FOR %s", key); } + break; + default: + break; + } + } + + if (params_updated > 0) { + rtc_schedule_next_alarm(); + commit_params(); + } + } + + cJSON_Delete(root); + + // Send response + esp_err_t err; + char response[256]; + int response_len; + + if (reboot_requested) { + // Special handling for reboot + response_len = snprintf(response, sizeof(response), + "{\"status\":\"ok\",\"message\":\"Rebooting...\"}"); + + if (response_len > 0 && response_len < (int)sizeof(response)) { + err = httpd_resp_set_type(req, "application/json"); + if (err == ESP_OK) { + err = httpd_resp_send(req, response, response_len); + } + } + + ESP_LOGI(TAG, "Rebooting in 2 seconds..."); + vTaskDelay(pdMS_TO_TICKS(2000)); + esp_restart(); + return ESP_OK; // Never reached + } + + if (sleep_requested) { + // Special handling for sleep + response_len = snprintf(response, sizeof(response), + "{\"status\":\"ok\",\"message\":\"Sleeping...\"}"); + + if (response_len > 0 && response_len < (int)sizeof(response)) { + err = httpd_resp_set_type(req, "application/json"); + if (err == ESP_OK) { + err = httpd_resp_send(req, response, response_len); + } + } + + ESP_LOGI(TAG, "Sleeping in 2 seconds..."); + vTaskDelay(pdMS_TO_TICKS(2000)); + rtc_enter_deep_sleep(); + return ESP_OK; // Never reached + } + + if (error_msg != NULL) { + err = httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, error_msg); + } else { + response_len = snprintf(response, sizeof(response), + "{\"status\":\"ok\",\"params_updated\":%d,\"params_failed\":%d,\"cmd_executed\":%s}", + params_updated, params_failed, cmd_executed ? "true" : "false"); + + if (response_len < 0 || response_len >= (int)sizeof(response)) { + ESP_LOGE(TAG, "Failed to format response"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Internal error"); + } + + err = httpd_resp_set_type(req, "application/json"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set response type: %s", esp_err_to_name(err)); + return err; + } + + err = httpd_resp_send(req, response, response_len); + } + + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send response: %s", esp_err_to_name(err)); + return err; + } + + + err = httpd_resp_set_hdr(req, "Connection", "close"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set connection header: %s", esp_err_to_name(err)); + // Continue anyway + } + + return err; +} + static esp_err_t ota_post_handler(httpd_req_t *req) { ESP_LOGI(TAG, "OTA POST request received"); + + if (req == NULL) { + ESP_LOGE(TAG, "Null request pointer"); + return ESP_FAIL; + } + + rtc_reset_shutdown_timer(); esp_ota_handle_t update_handle = 0; const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL); if (update_partition == NULL) { ESP_LOGE(TAG, "No OTA partition found"); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "No OTA partition"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "No OTA partition available"); } + ESP_LOGI(TAG, "Starting OTA update on partition: %s", update_partition->label); + esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA begin failed"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "OTA begin failed"); } - - char buf[1024]; int recv_len; int total_len = req->content_len; int remaining = total_len; + int received = 0; + + if (total_len <= 0) { + ESP_LOGE(TAG, "Invalid content length: %d", total_len); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, + "Invalid or missing content length"); + } + + ESP_LOGI(TAG, "Expected OTA size: %d bytes", total_len); + + int timeout_count = 0; + const int MAX_TIMEOUTS = 3; while (remaining > 0) { - recv_len = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf))); - if (recv_len <= 0) { + recv_len = httpd_req_recv(req, httpBuffer, MIN(remaining, sizeof(httpBuffer))); + + if (recv_len < 0) { if (recv_len == HTTPD_SOCK_ERR_TIMEOUT) { - continue; + timeout_count++; + ESP_LOGW(TAG, "Socket timeout (%d/%d), retrying...", + timeout_count, MAX_TIMEOUTS); + + if (timeout_count < MAX_TIMEOUTS) { + continue; + } else { + ESP_LOGE(TAG, "Too many timeouts, aborting OTA"); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_408_REQ_TIMEOUT, + "Request timeout"); + } + } else if (recv_len == HTTPD_SOCK_ERR_FAIL) { + ESP_LOGE(TAG, "Socket error during receive"); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Socket error during OTA"); + } else { + ESP_LOGE(TAG, "Unexpected error during receive: %d", recv_len); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "OTA receive failed"); } + } + + if (recv_len == 0) { + ESP_LOGE(TAG, "Connection closed prematurely. Received %d of %d bytes", + received, total_len); esp_ota_abort(update_handle); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Receive failed"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Connection closed during OTA"); } - err = esp_ota_write(update_handle, (const void *)buf, recv_len); + // Reset timeout counter on successful receive + timeout_count = 0; + + err = esp_ota_write(update_handle, (const void *)httpBuffer, recv_len); if (err != ESP_OK) { - esp_ota_abort(update_handle); ESP_LOGE(TAG, "esp_ota_write failed (%s)", esp_err_to_name(err)); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA write failed"); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "OTA write failed"); } remaining -= recv_len; + received += recv_len; + + // Log progress every 10% + if (total_len > 0 && (received % (total_len / 10)) < recv_len) { + ESP_LOGI(TAG, "OTA progress: %d%%", (received * 100) / total_len); + } + } + + ESP_LOGI(TAG, "OTA data received completely. Total: %d bytes", received); + + if (received != total_len) { + ESP_LOGE(TAG, "Size mismatch: received %d, expected %d", received, total_len); + esp_ota_abort(update_handle); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "OTA size mismatch"); } err = esp_ota_end(update_handle); if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_ota_end failed (%s)", esp_err_to_name(err)); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA end failed"); + if (err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGE(TAG, "Image validation failed"); + return httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, + "OTA image validation failed"); + } else { + ESP_LOGE(TAG, "esp_ota_end failed (%s)", esp_err_to_name(err)); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "OTA end failed"); + } } err = esp_ota_set_boot_partition(update_partition); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)", esp_err_to_name(err)); - return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Set boot partition failed"); + return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Failed to set boot partition"); } ESP_LOGI(TAG, "OTA update successful. Rebooting in 2 seconds..."); - // Send response FIRST - httpd_resp_send(req, "OTA update successful, rebooting...", HTTPD_RESP_USE_STRLEN); + // Send success response FIRST + err = httpd_resp_set_type(req, "application/json"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set response type: %s", esp_err_to_name(err)); + // Continue anyway, try to send response + } - set_param_value_t(PARAM_BOOT_TIME, (param_value_t){.i64 = system_rtc_get_raw_time()}); + err = httpd_resp_send(req, "{\"status\":\"ok\",\"message\":\"OTA update successful, rebooting...\"}", + HTTPD_RESP_USE_STRLEN); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to send response: %s", esp_err_to_name(err)); + // Continue with reboot anyway + } + + // Update boot time parameter + // set_param_value_t(PARAM_BOOT_TIME, (param_value_t){.i32 = system_rtc_get_raw_time()}); // THEN delay and reboot vTaskDelay(pdMS_TO_TICKS(2000)); // Give time for TCP to close properly esp_restart(); + return ESP_OK; // Never reached +} + + +static esp_err_t catchall_handler(httpd_req_t *req) { + ESP_LOGI(TAG, "catchall_handler; %s", req->uri); + const char *uri = req->uri; + + // Windows NCSI + if (strcmp(uri, "/connecttest.txt") == 0) { + httpd_resp_set_type(req, "text/plain"); + httpd_resp_sendstr(req, "Microsoft Connect Test"); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; + } + + if (strncmp(uri, "/success.txt", 12) == 0) { // Handles query params too + httpd_resp_set_type(req, "text/plain"); + httpd_resp_sendstr(req, "Success"); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; + } + + if (strcmp(uri, "/canonical.html") == 0) { + httpd_resp_set_type(req, "text/html"); + httpd_resp_sendstr(req, "SuccessSuccess"); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; + } + + // Android + if (strcmp(uri, "/generate_204") == 0 || strcmp(uri, "/gen_204") == 0) { + httpd_resp_set_status(req, "204 No Content"); + httpd_resp_send(req, NULL, 0); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; + } + + // iOS/macOS + if (strcmp(uri, "/hotspot-detect.html") == 0 || + strcmp(uri, "/library/test/success.html") == 0) { + httpd_resp_set_status(req, "302 Found"); + httpd_resp_set_hdr(req, "Location", "/"); + httpd_resp_send(req, NULL, 0); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; + } + + // Default 404 + httpd_resp_send_404(req); + httpd_resp_set_hdr(req, "Connection", "close"); + return ESP_OK; } + +/************************************************ +**************** URI HANDLER MAP **************** +************************************************/ + httpd_uri_t uris[] = {{ - .uri = "/status", - .method = HTTP_GET, - .handler = status_get_handler, - .user_ctx = NULL -},{ .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = NULL },{ - .uri = "/st", - .method = HTTP_ANY, - .handler = st_post_handler, + .uri = "/get", + .method = HTTP_GET, + .handler = get_handler, + .user_ctx = NULL +},{ + .uri = "/post", + .method = HTTP_POST, + .handler = post_handler, .user_ctx = NULL },{ .uri = "/log", .method = HTTP_ANY, .handler = log_handler, .user_ctx = NULL -},{ - .uri = "/sp", - .method = HTTP_POST, - .handler = sp_post_handler, - .user_ctx = NULL -},{ - .uri = "/cmd", - .method = HTTP_POST, - .handler = cmd_post_handler, - .user_ctx = NULL },{ .uri = "/ota", .method = HTTP_POST, .handler = ota_post_handler, .user_ctx = NULL +},{ + .uri = "/*", + .method = HTTP_GET, + .handler = catchall_handler, + .user_ctx = NULL }}; +/********************************************************** +**************** WIFI + WEB SERVER RUNNERS **************** +**********************************************************/ -static void startHttpServer(void) { +bool server_running = false; + +static esp_err_t startHttpServer(void) { + if (server_running) return ESP_OK; + ESP_LOGI(TAG, "STARTING HTTP"); httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - config.server_port = SERVER_PORT; + config.server_port = 80; + config.max_open_sockets = 7; + config.lru_purge_enable = true; + config.uri_match_fn = httpd_uri_match_wildcard; // enable wildcarding - if (httpd_start(&httpServerInstance, &config) == ESP_OK) { - for (uint8_t i=0; i<(sizeof(uris)/sizeof(httpd_uri_t)); i++) - httpd_register_uri_handler(httpServerInstance, &uris[i]); - } + esp_err_t err = httpd_start(&httpServerInstance, &config); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start HTTP server: %s", esp_err_to_name(err)); + return err; + } + + ESP_LOGI(TAG, "HTTP server started successfully"); + + // Register URI handlers + for (uint8_t i = 0; i < (sizeof(uris)/sizeof(httpd_uri_t)); i++) { + err = httpd_register_uri_handler(httpServerInstance, &uris[i]); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to register URI handler for %s: %s", + uris[i].uri, esp_err_to_name(err)); + // Continue registering other handlers even if one fails + } else { + ESP_LOGI(TAG, "Registered URI handler: %s", uris[i].uri); + } + } + + server_running = true; + + return ESP_OK; +} + +static esp_err_t stopHttpServer(void) { + if (!server_running) return ESP_OK; + ESP_LOGI(TAG, "STOPPING HTTP"); + if (httpServerInstance == NULL) { + ESP_LOGW(TAG, "HTTP server not running"); + return ESP_ERR_INVALID_STATE; + } + + esp_err_t err = httpd_stop(httpServerInstance); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to stop HTTP server: %s", esp_err_to_name(err)); + return err; + } + + httpServerInstance = NULL; + ESP_LOGI(TAG, "HTTP server stopped"); + server_running = false; + return ESP_OK; } /* Event handler for WiFi events */ + +int n_connected = 0; + static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - if (event_id == WIFI_EVENT_AP_STACONNECTED) { - ESP_LOGI(TAG, "Station connected."); - //startHttpServer(); + + + if (event_id == WIFI_EVENT_AP_STACONNECTED) { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "Station connected, AID=%d", event->aid); + rtc_reset_shutdown_timer(); + n_connected ++; + if (n_connected > 0) + startHttpServer(); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { - ESP_LOGI(TAG, "Station disconnected."); - //stopHttpServer(); + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + ESP_LOGI(TAG, "Station disconnected, AID=%d", event->aid); + n_connected --; + if (n_connected <= 0) + stopHttpServer(); } } -void launchSoftAp() { - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); +static esp_err_t launchSoftAp(void) { + esp_err_t err; + + err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + // NVS partition was truncated and needs to be erased + ESP_LOGW(TAG, "NVS partition needs erasing, performing erase..."); + err = nvs_flash_erase(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to erase NVS: %s", esp_err_to_name(err)); + return err; + } + // Retry init after erase + err = nvs_flash_init(); + } + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize NVS: %s", esp_err_to_name(err)); + return err; + } + + err = esp_netif_init(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize netif: %s", esp_err_to_name(err)); + return err; + } + + err = esp_event_loop_create_default(); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + ESP_LOGE(TAG, "Failed to create event loop: %s", esp_err_to_name(err)); + return err; + } esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); - assert(ap_netif); + if (ap_netif == NULL) { + ESP_LOGE(TAG, "Failed to create default WiFi AP interface"); + return ESP_FAIL; + } - ESP_ERROR_CHECK(esp_netif_set_hostname(ap_netif, HOSTNAME)); + err = esp_netif_set_hostname(ap_netif, HOSTNAME); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set hostname: %s", esp_err_to_name(err)); + // Non-critical, continue + } wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + err = esp_wifi_init(&cfg); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize WiFi: %s", esp_err_to_name(err)); + return err; + } - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, - ESP_EVENT_ANY_ID, - &wifi_event_handler, - NULL, - NULL)); + err = esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &wifi_event_handler, + NULL, + NULL); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to register event handler: %s", esp_err_to_name(err)); + return err; + } wifi_config_t wifi_config = { .ap = { .channel = get_param_value_t(PARAM_WIFI_CHANNEL).i16, - .ssid = SOFT_AP_SSID, - .password = SOFT_AP_PASSWORD, .max_connection = 4, .authmode = WIFI_AUTH_WPA2_PSK }, }; // Get the strings from your parameter system - char* ssid_str = get_param_string(PARAM_WIFI_SSID); - char* password_str = get_param_string(PARAM_WIFI_PASS); - - // Allocate and set the SSID and password - memcpy(wifi_config.ap.ssid, ssid_str, 16); - memcpy(wifi_config.ap.password, password_str, 16); - - // password minimum length of 8 - if (strlen(password_str) < 8) { - wifi_config.ap.password[0] = '\0'; - wifi_config.ap.authmode = WIFI_AUTH_OPEN; - } - - if (wifi_config.ap.channel > 11 || wifi_config.ap.channel < 1) - wifi_config.ap.channel = 6; - - // Set the length of SSID - wifi_config.ap.ssid_len = strlen(ssid_str); + char* ssid_str = get_param_string(PARAM_WIFI_SSID); + char* password_str = get_param_string(PARAM_WIFI_PASS); + + if (ssid_str == NULL || password_str == NULL) { + ESP_LOGE(TAG, "Failed to get WiFi credentials from parameters"); + return ESP_FAIL; + } + + // Allocate and set the SSID and password + memcpy(wifi_config.ap.ssid, ssid_str, MIN(strlen(ssid_str), sizeof(wifi_config.ap.ssid))); + memcpy(wifi_config.ap.password, password_str, MIN(strlen(password_str), sizeof(wifi_config.ap.password))); + + // password minimum length of 8 + if (strlen(password_str) < 8) { + ESP_LOGW(TAG, "Password too short, using open authentication"); + wifi_config.ap.password[0] = '\0'; + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + } + + // Validate WiFi channel + if (wifi_config.ap.channel > 11 || wifi_config.ap.channel < 1) { + ESP_LOGW(TAG, "Invalid WiFi channel %d, using default channel 6", + wifi_config.ap.channel); + wifi_config.ap.channel = 6; + } + + // Set the length of SSID + wifi_config.ap.ssid_len = strlen(ssid_str); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + err = esp_wifi_set_mode(WIFI_MODE_AP); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set WiFi mode: %s", esp_err_to_name(err)); + return err; + } + + err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set WiFi config: %s", esp_err_to_name(err)); + return err; + } + + err = esp_wifi_start(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start WiFi: %s", esp_err_to_name(err)); + return err; + } // Start DNS server with your specific hostname - // Option 1: Only respond to your hostname - ESP_ERROR_CHECK(simple_dns_server_start("192.168.4.1")); - - // Option 2: Respond to ALL domains (captive portal style) - // ESP_ERROR_CHECK(simple_dns_server_start(HOSTNAME, "192.168.4.1", true)); + err = simple_dns_server_start("192.168.4.1"); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start DNS server: %s", esp_err_to_name(err)); + // Non-critical, continue + } // Start mDNS for .local domain - ESP_ERROR_CHECK(mdns_init()); - ESP_ERROR_CHECK(mdns_hostname_set(HOSTNAME)); - ESP_ERROR_CHECK(mdns_instance_name_set("ClusterCommand")); - ESP_ERROR_CHECK(mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0)); + err = mdns_init(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize mDNS: %s", esp_err_to_name(err)); + // Non-critical, continue + } else { + err = mdns_hostname_set(HOSTNAME); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to set mDNS hostname: %s", esp_err_to_name(err)); + } + + err = mdns_instance_name_set("ClusterCommand"); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to set mDNS instance name: %s", esp_err_to_name(err)); + } + + err = mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to add mDNS service: %s", esp_err_to_name(err)); + } + } - ESP_LOGI(TAG, "SoftAP ready. Access at: http://%s or http://%s.local or http://192.168.4.1", + uint8_t *placeholder = (wifi_config.ap.authmode == WIFI_AUTH_OPEN) + ? (uint8_t*)"" + : wifi_config.ap.password; + ESP_LOGI(TAG, "SoftAP ready. SSID: %s, Channel: %d, Password: %s", + wifi_config.ap.ssid, wifi_config.ap.channel, placeholder); + ESP_LOGI(TAG, "Access at: http://%s or http://%s.local or http://192.168.4.1", HOSTNAME, HOSTNAME); + + return ESP_OK; } esp_err_t webserver_init(void) { - launchSoftAp(); - startHttpServer(); + ESP_LOGI(TAG, "Initializing webserver..."); + + esp_err_t err = launchSoftAp(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to launch SoftAP: %s", esp_err_to_name(err)); + return err; + } + + err = startHttpServer(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to start HTTP server: %s", esp_err_to_name(err)); + return err; + } + + ESP_LOGI(TAG, "Webserver initialization complete"); return ESP_OK; } \ No newline at end of file