diff options
author | Stefan Kerkmann <karlk90@pm.me> | 2022-07-14 11:50:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-14 11:50:00 +0200 |
commit | 3c58f989295e17d03b66db9a154e02cde7336ece (patch) | |
tree | f1e205d8cdc2d28d750bf0545261e9f5cbe609a2 | |
parent | 82685fc2acb0055b56fd57e9a842412a3e3a246c (diff) |
[Core] PMW33XX drivers overhaul (#17613)
* PMW33XX drivers overhaul
This combines the PMW3389 and PM3360 drivers as they only differ in the
firmware blobs and CPI get and set functions. The following changes have
been made:
* PMW3389 now gets the same multi-sensor feature that is already available on the
PMW3360.
* Introduced a shared pmw33xx_report_t struct is now directly readable via SPI
transactions instead of individual byte-sized reads, saving multiple
copies and bitshift operations.
* pmw33(89/60)_get_report functions had unreachable branches in their motion
detection logic these have been simplied as much as possible.
* The fast firmware upload option has been removed as this becomes obsolete by
the newly introduced polled waiting functions for ChibiOS polled waiting
* PMW33(60/89)_SPI_LSBFIRST and PMW33(60/89)_SPI_MODE config options
have been removed as they don't need to be configurable.
* All PMW3389 and PMW3360 defines have been unified to a PMW33XX prefix
to reduce code duplication and make the defines interchangeable
* Adjust keyboards to PMW33XX naming scheme
26 files changed, 1168 insertions, 1445 deletions
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 01dbdc3330..d7a00ba944 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -161,11 +161,9 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball) OPT_DEFS += -DSTM32_SPI -DHAL_USE_I2C=TRUE QUANTUM_LIB_SRC += i2c_master.c - else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360) - OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE - QUANTUM_LIB_SRC += spi_master.c - else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3389) + else ifneq ($(filter $(strip $(POINTING_DEVICE_DRIVER)),pmw3360 pmw3389),) OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE + SRC += drivers/sensors/pmw33xx_common.c QUANTUM_LIB_SRC += spi_master.c endif endif diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index 70129dfc9a..607c74c562 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -154,54 +154,61 @@ The Pimoroni Trackball module is a I2C based breakout board with an RGB enable t |`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` | |`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` | -### PMW 3360 Sensor +### PMW 3360 and PMW 3389 Sensor -This drivers supports multiple sensors _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards). -To use the PMW 3360 sensor, add this to your `rules.mk` +This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards). + +To use the **PMW 3360** sensor, add this to your `rules.mk` ```make POINTING_DEVICE_DRIVER = pmw3360 ``` -The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking. +The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI. -| Setting | Description | Default | -|-----------------------------|--------------------------------------------------------------------------------------------|---------------| -|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ | -|`PMW3360_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ | -|`PMW3360_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` | -|`PMW3360_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` | -|`PMW3360_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` | -|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | -|`PMW3360_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` | -|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor.| `0` | -|`PMW3360_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ | +To use the **PMW 3389** sensor, add this to your `rules.mk` -The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI. +```make +POINTING_DEVICE_DRIVER = pmw3389 +``` -To use multiple sensors, instead of setting `PMW3360_CS_PIN` you need to set `PMW3360_CS_PINS` and also handle and merge the read from this sensor in user code. +The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI. + +Both PMW 3360 and PMW 3389 are SPI driven optical sensors, that use a built in IR LED for surface tracking. + +| Setting | Description | Default | +| ---------------------------- | ------------------------------------------------------------------------------------------- | ------------- | +| `PMW33XX_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ | +| `PMW33XX_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ | +| `PMW33XX_CPI` | (Optional) Sets counts per inch sensitivity of the sensor. | _varies_ | +| `PMW33XX_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` | +| `PMW33XX_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | +| `PMW33XX_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` | +| `ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` | + +To use multiple sensors, instead of setting `PMW33XX_CS_PIN` you need to set `PMW33XX_CS_PINS` and also handle and merge the read from this sensor in user code. Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported. ```c // in config.h: -#define PMW3360_CS_PINS { B5, B6 } - +#define PMW33XX_CS_PINS { B5, B6 } // in keyboard.c: #ifdef POINTING_DEVICE_ENABLE void pointing_device_init_kb(void) { - pmw3360_init(1); // index 1 is the second device. - pointing_device_set_cpi(800); // applies to both sensors + pmw33xx_init(1); // index 1 is the second device. + pmw33xx_set_cpi(0, 800); // applies to first sensor + pmw33xx_set_cpi(1, 800); // applies to second sensor pointing_device_init_user(); } // Contains report from sensor #0 already, need to merge in from sensor #1 report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { - report_pmw3360_t data = pmw3360_read_burst(1); - if (data.isOnSurface && data.isMotion) { + pmw33xx_report_t report = pmw33xx_read_burst(1); + if (!report.motion.b.is_lifted && report.motion.b.is_motion) { // From quantum/pointing_device_drivers.c #define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt))) - mouse_report.x = constrain_hid(mouse_report.x + data.dx); - mouse_report.y = constrain_hid(mouse_report.y + data.dy); + mouse_report.x = constrain_hid(mouse_report.x + report.delta_x); + mouse_report.y = constrain_hid(mouse_report.y + report.delta_y); } return pointing_device_task_user(mouse_report); } @@ -209,30 +216,6 @@ report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { ``` -### PMW 3389 Sensor - -To use the PMW 3389 sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = pmw3389 -``` - -The PMW 3389 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking. - -| Setting | Description | Default | -|---------------------------------|--------------------------------------------------------------------------------------------|---------------| -|`PMW3389_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ | -|`PMW3389_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` | -|`PMW3389_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` | -|`PMW3389_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` | -|`PMW3389_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | -|`PMW3389_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` | -|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 30 degrees directly in the sensor. | `0` | -|`PMW3389_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ | - -The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI. - - ### Custom Driver If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk` diff --git a/drivers/sensors/pmw3360.c b/drivers/sensors/pmw3360.c index 5f4d17a3f0..2c6d91d588 100644 --- a/drivers/sensors/pmw3360.c +++ b/drivers/sensors/pmw3360.c @@ -1,291 +1,294 @@ -/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> - * Copyright 2019 Sunjun Kim - * Copyright 2020 Ploopy Corporation - * Copyright 2022 Ulrich Spörlein - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "spi_master.h" -#include "pmw3360.h" -#include "wait.h" -#include "debug.h" -#include "print.h" -#include "pmw3360_firmware.h" - -// Registers -// clang-format off -#define REG_Product_ID 0x00 -#define REG_Revision_ID 0x01 -#define REG_Motion 0x02 -#define REG_Delta_X_L 0x03 -#define REG_Delta_X_H 0x04 -#define REG_Delta_Y_L 0x05 -#define REG_Delta_Y_H 0x06 -#define REG_SQUAL 0x07 -#define REG_Raw_Data_Sum 0x08 -#define REG_Maximum_Raw_data 0x09 -#define REG_Minimum_Raw_data 0x0a -#define REG_Shutter_Lower 0x0b -#define REG_Shutter_Upper 0x0c -#define REG_Control 0x0d -#define REG_Config1 0x0f -#define REG_Config2 0x10 -#define REG_Angle_Tune 0x11 -#define REG_Frame_Capture 0x12 -#define REG_SROM_Enable 0x13 -#define REG_Run_Downshift 0x14 -#define REG_Rest1_Rate_Lower 0x15 -#define REG_Rest1_Rate_Upper 0x16 -#define REG_Rest1_Downshift 0x17 -#define REG_Rest2_Rate_Lower 0x18 -#define REG_Rest2_Rate_Upper 0x19 -#define REG_Rest2_Downshift 0x1a -#define REG_Rest3_Rate_Lower 0x1b -#define REG_Rest3_Rate_Upper 0x1c -#define REG_Observation 0x24 -#define REG_Data_Out_Lower 0x25 -#define REG_Data_Out_Upper 0x26 -#define REG_Raw_Data_Dump 0x29 -#define REG_SROM_ID 0x2a -#define REG_Min_SQ_Run 0x2b -#define REG_Raw_Data_Threshold 0x2c -#define REG_Config5 0x2f -#define REG_Power_Up_Reset 0x3a -#define REG_Shutdown 0x3b -#define REG_Inverse_Product_ID 0x3f -#define REG_LiftCutoff_Tune3 0x41 -#define REG_Angle_Snap 0x42 -#define REG_LiftCutoff_Tune1 0x4a -#define REG_Motion_Burst 0x50 -#define REG_LiftCutoff_Tune_Timeout 0x58 -#define REG_LiftCutoff_Tune_Min_Length 0x5a -#define REG_SROM_Load_Burst 0x62 -#define REG_Lift_Config 0x63 -#define REG_Raw_Data_Burst 0x64 -#define REG_LiftCutoff_Tune2 0x65 - -#define CPI_STEP 100 -// clang-format on - -// limits to 0--119, resulting in a CPI range of 100 -- 12000 (as only steps of 100 are possible). -#ifndef MAX_CPI -# define MAX_CPI 0x77 -#endif - -static const pin_t pins[] = PMW3360_CS_PINS; -#define NUMBER_OF_SENSORS (sizeof(pins) / sizeof(pin_t)) - -// per-sensor driver state -static bool _inBurst[NUMBER_OF_SENSORS] = {0}; - -#ifdef CONSOLE_ENABLE -void print_byte(uint8_t byte) { - dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); -} -#endif -#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) - -bool pmw3360_spi_start(int8_t index) { - bool status = spi_start(pins[index], PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR); - // tNCS-SCLK, 120ns - wait_us(1); - return status; -} - -spi_status_t pmw3360_write(int8_t index, uint8_t reg_addr, uint8_t data) { - pmw3360_spi_start(index); - - if (reg_addr != REG_Motion_Burst) { - _inBurst[index] = false; - } - - // send address of the register, with MSBit = 1 to indicate it's a write - spi_status_t status = spi_write(reg_addr | 0x80); - status = spi_write(data); - - // tSCLK-NCS for write operation is 35us - wait_us(35); - spi_stop(); - - // tSWW/tSWR (=180us) minus tSCLK-NCS. Could be shortened, but it looks like a safe lower bound - wait_us(145); - return status; -} - -uint8_t pmw3360_read(int8_t index, uint8_t reg_addr) { - pmw3360_spi_start(index); - // send adress of the register, with MSBit = 0 to indicate it's a read - spi_write(reg_addr & 0x7f); - // tSRAD (=160us) - wait_us(160); - uint8_t data = spi_read(); - - // tSCLK-NCS for read operation is 120ns - wait_us(1); - spi_stop(); - - // tSRW/tSRR (=20us) minus tSCLK-NCS - wait_us(19); - return data; -} - -bool pmw3360_check_signature(int8_t index) { - uint8_t pid = pmw3360_read(index, REG_Product_ID); - uint8_t iv_pid = pmw3360_read(index, REG_Inverse_Product_ID); - uint8_t SROM_ver = pmw3360_read(index, REG_SROM_ID); - return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04 -} - -void pmw3360_upload_firmware(int8_t index) { - // Datasheet claims we need to disable REST mode first, but during startup - // it's already disabled and we're not turning it on ... - // pmw3360_write(index, REG_Config2, 0x00); // disable REST mode - pmw3360_write(index, REG_SROM_Enable, 0x1d); - - wait_ms(10); - - pmw3360_write(index, REG_SROM_Enable, 0x18); - - pmw3360_spi_start(index); - spi_write(REG_SROM_Load_Burst | 0x80); - wait_us(15); - - for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) { - spi_write(pgm_read_byte(firmware_data + i)); -#ifndef PMW3360_FIRMWARE_UPLOAD_FAST - wait_us(15); -#endif +// Copyright 2022 Stefan Kerkmann (KarlK90) +// Copyright 2022 Ulrich Spörlein (@uqs) +// Copyright 2021 Alabastard (@Alabastard-64) +// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> +// Copyright 2019 Sunjun Kim +// Copyright 2020 Ploopy Corporation +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "pmw33xx_common.h" +#include "progmem.h" + +extern const size_t pmw33xx_number_of_sensors; + +uint16_t pmw33xx_get_cpi(uint8_t sensor) { + if (sensor >= pmw33xx_number_of_sensors) { + return 0; } - wait_us(200); - pmw3360_read(index, REG_SROM_ID); - pmw3360_write(index, REG_Config2, 0x00); + uint8_t cpival = pmw33xx_read(sensor, REG_Config1); + return (uint16_t)((cpival + 1) & 0xFF) * PMW33XX_CPI_STEP; } -bool pmw3360_init(int8_t index) { - if (index >= NUMBER_OF_SENSORS) { - return false; +void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) { + if (sensor >= pmw33xx_number_of_sensors) { + return; } - spi_init(); - // power up, need to first drive NCS high then low. - // the datasheet does not say for how long, 40us works well in practice. - pmw3360_spi_start(index); - wait_us(40); - spi_stop(); - wait_us(40); - pmw3360_write(index, REG_Power_Up_Reset, 0x5a); - wait_ms(50); - - // read registers and discard - pmw3360_read(index, REG_Motion); - pmw3360_read(index, REG_Delta_X_L); - pmw3360_read(index, REG_Delta_X_H); - pmw3360_read(index, REG_Delta_Y_L); - pmw3360_read(index, REG_Delta_Y_H); - - pmw3360_upload_firmware(index); - - spi_stop(); - - wait_ms(10); - pmw3360_set_cpi(PMW3360_CPI); - - wait_ms(1); - - pmw3360_write(index, REG_Config2, 0x00); - - pmw3360_write(index, REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -127, 127)); - - pmw3360_write(index, REG_Lift_Config, PMW3360_LIFTOFF_DISTANCE); - - bool init_success = pmw3360_check_signature(index); -#ifdef CONSOLE_ENABLE - if (init_success) { - dprintf("pmw3360 signature verified"); - } else { - dprintf("pmw3360 signature verification failed!"); - } -#endif - - return init_success; + uint8_t cpival = CONSTRAIN((cpi / PMW33XX_CPI_STEP) - 1, 0, (PMW33XX_CPI_MAX / PMW33XX_CPI_STEP) - 1U); + pmw33xx_write(sensor, REG_Config1, cpival); } -// Only support reading the value from sensor #0, no one is using this anyway. -uint16_t pmw3360_get_cpi(void) { - uint8_t cpival = pmw3360_read(0, REG_Config1); - return (uint16_t)((cpival + 1) & 0xFF) * CPI_STEP; -} - -// Write same CPI to all sensors. -void pmw3360_set_cpi(uint16_t cpi) { - uint8_t cpival = constrain((cpi / CPI_STEP) - 1, 0, MAX_CPI); - for (size_t i = 0; i < NUMBER_OF_SENSORS; i++) { - pmw3360_write(i, REG_Config1, cpival); - } -} +// PID, Inverse PID, SROM version +const uint8_t pmw33xx_firmware_signature[3] PROGMEM = {0x42, 0xBD, 0x04}; -report_pmw3360_t pmw3360_read_burst(int8_t index) { - report_pmw3360_t report = {0}; - if (index >= NUMBER_OF_SENSORS) { - return report; - } - - if (!_inBurst[index]) { -#ifdef CONSOLE_ENABLE - dprintf("burst on for index %d", index); -#endif - pmw3360_write(index, REG_Motion_Burst, 0x00); - _inBurst[index] = true; - } - - pmw3360_spi_start(index); - spi_write(REG_Motion_Burst); - wait_us(35); // waits for tSRAD_MOTBR - - report.motion = spi_read(); - spi_read(); // skip Observation - // delta registers - report.dx = spi_read(); - report.mdx = spi_read(); - report.dy = spi_read(); - report.mdy = spi_read(); - - if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird. - _inBurst[index] = false; - } - - spi_stop(); - -#ifdef CONSOLE_ENABLE - if (debug_mouse) { - print_byte(report.motion); - print_byte(report.dx); - print_byte(report.mdx); - print_byte(report.dy); - print_byte(report.mdy); - dprintf("\n"); - } -#endif - - report.isMotion = (report.motion & 0x80) != 0; - report.isOnSurface = (report.motion & 0x08) == 0; - report.dx |= (report.mdx << 8); - report.dx = report.dx * -1; - report.dy |= (report.mdy << 8); - report.dy = report.dy * -1; - - return report; -} +// Firmware Blob for PMW3360 +// clang-format off +const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM = { + 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF, + 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5, + 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79, + 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E, + 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B, + 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4, + 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF, + 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE, + 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF, + 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89, + 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5, + 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66, + 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4, + 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18, + 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A, + 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB, + 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3, + 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05, + 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8, + 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23, + 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C, + 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A, + 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1, + 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6, + 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8, + 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76, + 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5, + 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD, + 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5, + 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF, + 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8, + 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08, + 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42, + 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A, + 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11, + 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80, + 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69, + 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8, + 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72, + 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97, + 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F, + 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC, + 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E, + 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE, + 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30, + 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71, + 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2, + 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68, + 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7, + 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3, + 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67, + 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF, + 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95, + 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A, + 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8, + 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77, + 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08, + 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31, + 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A, + 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF, + 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62, + 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC, + 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99, + 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8, + 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D, + 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78, + 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B, + 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85, + 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07, + 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9, + 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B, + 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26, + 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5, + 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F, + 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97, + 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE, + 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72, + 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D, + 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D, + 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26, + 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7, + 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1, + 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1, + 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF, + 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9, + 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2, + 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F, + 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D, + 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E, + 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75, + 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F, + 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8, + 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E, + 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED, + 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD, + 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8, + 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88, + 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57, + 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA, + 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2, + 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7, + 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99, + 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A, + 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D, + 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF, + 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17, + 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF, + 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A, + 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62, + 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA, + 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF, + 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66, + 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5, + 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5, + 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF, + 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69, + 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F, + 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79, + 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A, + 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA, + 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50, + 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E, + 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5, + 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2, + 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54, + 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61, + 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8, + 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A, + 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A, + 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23, + 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B, + 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB, + 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4, + 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81, + 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, |