From fbaffeb8e55838bc300480202c57c50db31ac6d7 Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 01/34] Remove remnant from VL53 ToF sensor Functions for changing the I2C speed are not required any more. --- src/OpenBikeSensorFirmware.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index fde5e54d..64a8b0e9 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -106,14 +106,6 @@ void handleButtonInServerMode(); bool loadConfig(ObsConfig &cfg); void copyCollectedSensorData(DataSet *set); -// The BMP280 can keep up to 3.4MHz I2C speed, so no need for an individual slower speed -void switch_wire_speed_to_VL53(){ - Wire.setClock(400000); -} -void switch_wire_speed_to_SSD1306(){ - Wire.setClock(500000); -} - void setupSensors() { sensorManager = new HCSR04SensorManager; @@ -211,6 +203,7 @@ void setup() { // Setup display //############################################################## Wire.begin(); + Wire.setClock(500000); Wire.beginTransmission(displayAddress); byte displayError = Wire.endTransmission(); if (displayError != 0) { @@ -218,8 +211,6 @@ void setup() { } obsDisplay = new SSD1306DisplayDevice; - switch_wire_speed_to_SSD1306(); - obsDisplay->showLogo(true); obsDisplay->showTextOnGrid(2, obsDisplay->startLine(), OBSVersion); From 7f66d11d514ad6c3752dbb690057d89d792d2140 Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 02/34] Remove commented out code in `displays.cpp` --- src/displays.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/displays.cpp b/src/displays.cpp index c5a9db13..a04877fd 100644 --- a/src/displays.cpp +++ b/src/displays.cpp @@ -161,27 +161,10 @@ void SSD1306DisplayDevice::showBatterieValue(int16_t input_val){ xlocation += 1; } - //cleanGridCellcomplete(3,0); - -/* if(input_val == -1){ - cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo6); - m_display->setColor(BLACK); - this->showTextOnGrid(3, 0, " " + String(0) + "%", Dialog_plain_8,3,0); - m_display->setColor(WHITE); - m_display->display(); - this->showTextOnGrid(3, 0, "calc", Dialog_plain_8,6,0); - }else{ - m_display->setColor(BLACK); - this->showTextOnGrid(3, 0, "calc", Dialog_plain_8,6,0); - m_display->setColor(WHITE); - m_display->display(); - } */ if(input_val >= 0){ String val = String(input_val); //showLogo(true); this->showTextOnGrid(xlocation, 0, val + "%", TINY_FONT, 6, 0); - //m_display[0]->drawXbm(192, 0, 8, 9, BatterieLogo1); if(input_val > 90){ cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); From db3c3bd44cb86f001b1ea081fcc595104650dd83 Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 03/34] Remove class `DisplayDevice` Does not serve any real purpose. --- src/displays.h | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/displays.h b/src/displays.h index 60aadb8d..290aae6f 100644 --- a/src/displays.h +++ b/src/displays.h @@ -60,18 +60,7 @@ const int DIO = 25; //Set the DIO pin connection to the display extern bool BMP280_active; -class DisplayDevice { - public: - DisplayDevice() {} - virtual ~DisplayDevice() {} - virtual void invert() = 0; - virtual void normalDisplay() = 0; - //virtual void drawString(int16_t, int16_t, String) = 0; - virtual void clear() = 0; -}; - - -class SSD1306DisplayDevice : public DisplayDevice { +class SSD1306DisplayDevice { private: void handleHighlight(); void displaySimple(uint16_t value); @@ -84,7 +73,7 @@ class SSD1306DisplayDevice : public DisplayDevice { bool mHighlighted = false; public: - SSD1306DisplayDevice() : DisplayDevice() { + SSD1306DisplayDevice() { m_display = new SSD1306(0x3c, 21, 22); // ADDRESS, SDA, SCL m_display->init(); m_display->setBrightness(255); From a74041efa9bceffd81f97eefa1cca0e2ea573ed0 Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 04/34] Rename class `SSD1306DisplayDevice` to `DisplayDevice` --- src/OpenBikeSensorFirmware.cpp | 4 ++-- src/configServer.cpp | 2 +- src/displays.cpp | 28 ++++++++++++++-------------- src/displays.h | 6 +++--- src/globals.h | 4 ++-- src/gps.cpp | 4 ++-- src/gps.h | 6 +++--- src/utils/alpdata.cpp | 4 ++-- src/utils/alpdata.h | 4 ++-- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 64a8b0e9..315b25d7 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -57,7 +57,7 @@ Button button(PUSHBUTTON_PIN); Config config; -SSD1306DisplayDevice* obsDisplay; +DisplayDevice* obsDisplay; HCSR04SensorManager* sensorManager; static BluetoothManager* bluetoothManager; @@ -209,7 +209,7 @@ void setup() { if (displayError != 0) { Serial.println("Display not found"); } - obsDisplay = new SSD1306DisplayDevice; + obsDisplay = new DisplayDevice; obsDisplay->showLogo(true); obsDisplay->showTextOnGrid(2, obsDisplay->startLine(), OBSVersion); diff --git a/src/configServer.cpp b/src/configServer.cpp index 5a4c118c..b1a154c0 100644 --- a/src/configServer.cpp +++ b/src/configServer.cpp @@ -492,7 +492,7 @@ String getIp() { } } -void updateDisplay(SSD1306DisplayDevice * const display, String action = "") { +void updateDisplay(DisplayDevice * const display, String action = "") { if (action.isEmpty()) { display->showTextOnGrid(0, 0, "Ver.:"); display->showTextOnGrid(1, 0, OBSVersion); diff --git a/src/displays.cpp b/src/displays.cpp index a04877fd..207c7ad7 100644 --- a/src/displays.cpp +++ b/src/displays.cpp @@ -25,7 +25,7 @@ #include "fonts/fonts.h" -void SSD1306DisplayDevice::showNumConfirmed() { +void DisplayDevice::showNumConfirmed() { String val = String(confirmedMeasurements); if (confirmedMeasurements <= 9) { val = "0" + val; @@ -34,7 +34,7 @@ void SSD1306DisplayDevice::showNumConfirmed() { this->prepareTextOnGrid(3, 5, "conf"); } -void SSD1306DisplayDevice::showNumButtonPressed() { +void DisplayDevice::showNumButtonPressed() { String val = String(numButtonReleased); if (numButtonReleased <= 9) { val = "0" + val; @@ -43,7 +43,7 @@ void SSD1306DisplayDevice::showNumButtonPressed() { this->prepareTextOnGrid(1, 5, "press"); } -void SSD1306DisplayDevice::displaySimple(uint16_t value) { +void DisplayDevice::displaySimple(uint16_t value) { if (value == MAX_SENSOR_VALUE) { this->prepareTextOnGrid(0, 0, "", HUGE_FONT, -7, -7); @@ -54,7 +54,7 @@ void SSD1306DisplayDevice::displaySimple(uint16_t value) { this->prepareTextOnGrid(3, 2, "cm", MEDIUM_FONT, -7, -5); } -void SSD1306DisplayDevice::showValues( +void DisplayDevice::showValues( HCSR04SensorInfo sensor1, HCSR04SensorInfo sensor2, uint16_t minDistanceToConfirm, int16_t batteryPercentage, int16_t TemperaturValue, int lastMeasurements, boolean insidePrivacyArea, double speed, uint8_t satellites) { @@ -141,7 +141,7 @@ void SSD1306DisplayDevice::showValues( } -void SSD1306DisplayDevice::showGPS(uint8_t sats) { +void DisplayDevice::showGPS(uint8_t sats) { String val = String(sats); if (sats <= 9) { val = "0" + val; @@ -150,7 +150,7 @@ void SSD1306DisplayDevice::showGPS(uint8_t sats) { this->prepareTextOnGrid(3, 5, "sats"); } -void SSD1306DisplayDevice::showBatterieValue(int16_t input_val){ +void DisplayDevice::showBatterieValue(int16_t input_val){ uint8_t x_offset_batterie_logo = 65; uint8_t y_offset_batterie_logo = 2; @@ -195,7 +195,7 @@ void SSD1306DisplayDevice::showBatterieValue(int16_t input_val){ //m_display->display(); } -void SSD1306DisplayDevice::showTemperatureValue(int16_t input_val){ +void DisplayDevice::showTemperatureValue(int16_t input_val){ uint8_t x_offset_temp_logo = 30; uint8_t y_offset_temp_logo = 2; cleanTemperatur(x_offset_temp_logo,y_offset_temp_logo); @@ -204,7 +204,7 @@ void SSD1306DisplayDevice::showTemperatureValue(int16_t input_val){ this->showTextOnGrid(1, 0, val + "°C", TINY_FONT); } -void SSD1306DisplayDevice::showSpeed(double velocity) { +void DisplayDevice::showSpeed(double velocity) { const int bufSize = 4; char buffer[bufSize]; if (velocity >= 0) { @@ -216,18 +216,18 @@ void SSD1306DisplayDevice::showSpeed(double velocity) { this->prepareTextOnGrid(1, 5, "km/h"); } -uint8_t SSD1306DisplayDevice::currentLine() const { +uint8_t DisplayDevice::currentLine() const { return mCurrentLine; } -uint8_t SSD1306DisplayDevice::newLine() { +uint8_t DisplayDevice::newLine() { if (mCurrentLine >= 5) { scrollUp(); } return ++mCurrentLine; } -uint8_t SSD1306DisplayDevice::scrollUp() { +uint8_t DisplayDevice::scrollUp() { for (uint8_t i = 0; i < 5; i++) { prepareTextOnGrid(2, i, obsDisplay->get_gridTextofCell(2, i + 1)); } @@ -235,11 +235,11 @@ uint8_t SSD1306DisplayDevice::scrollUp() { return mCurrentLine--; } -uint8_t SSD1306DisplayDevice::startLine() { +uint8_t DisplayDevice::startLine() { return mCurrentLine = 0; } -void SSD1306DisplayDevice::highlight(uint32_t highlightTimeMillis) { +void DisplayDevice::highlight(uint32_t highlightTimeMillis) { mHighlightTill = millis() + highlightTimeMillis; if (!mHighlighted) { if (mInverted) { @@ -251,7 +251,7 @@ void SSD1306DisplayDevice::highlight(uint32_t highlightTimeMillis) { } } -void SSD1306DisplayDevice::handleHighlight() { +void DisplayDevice::handleHighlight() { if (mHighlighted && mHighlightTill < millis()) { if (mInverted) { m_display->invertDisplay(); diff --git a/src/displays.h b/src/displays.h index 290aae6f..7c7cd4f3 100644 --- a/src/displays.h +++ b/src/displays.h @@ -60,7 +60,7 @@ const int DIO = 25; //Set the DIO pin connection to the display extern bool BMP280_active; -class SSD1306DisplayDevice { +class DisplayDevice { private: void handleHighlight(); void displaySimple(uint16_t value); @@ -73,7 +73,7 @@ class SSD1306DisplayDevice { bool mHighlighted = false; public: - SSD1306DisplayDevice() { + DisplayDevice() { m_display = new SSD1306(0x3c, 21, 22); // ADDRESS, SDA, SCL m_display->init(); m_display->setBrightness(255); @@ -81,7 +81,7 @@ class SSD1306DisplayDevice { m_display->display(); } - ~SSD1306DisplayDevice() { + ~DisplayDevice() { delete m_display; } diff --git a/src/globals.h b/src/globals.h index d430ed62..ba2b758e 100644 --- a/src/globals.h +++ b/src/globals.h @@ -27,7 +27,7 @@ #include // Forward declare classes to build (because there is a cyclic dependency between sensor.h and displays.h) -class SSD1306DisplayDevice; +class DisplayDevice; class HCSR04SensorManager; @@ -52,7 +52,7 @@ extern int numButtonReleased; extern Config config; -extern SSD1306DisplayDevice* obsDisplay; +extern DisplayDevice* obsDisplay; extern HCSR04SensorManager* sensorManager; diff --git a/src/gps.cpp b/src/gps.cpp index c1aff2f7..271dfc64 100644 --- a/src/gps.cpp +++ b/src/gps.cpp @@ -545,7 +545,7 @@ PrivacyArea Gps::newPrivacyArea(double latitude, double longitude, int radius) { return newPrivacyArea; } -bool Gps::hasFix(SSD1306DisplayDevice *display) const { +bool Gps::hasFix(DisplayDevice *display) const { bool result = false; if (mCurrentGpsRecord.hasValidFix() && mLastTimeTimeSet) { log_d("Got location..."); @@ -563,7 +563,7 @@ int32_t Gps::getMessagesWithFailedCrcCount() const { return mMessagesWithFailedCrcReceived; } -void Gps::showWaitStatus(SSD1306DisplayDevice const * display) const { +void Gps::showWaitStatus(DisplayDevice const * display) const { String satellitesString[2]; if (mValidMessagesReceived == 0) { // could not get any valid char from GPS module satellitesString[0] = "OFF?"; diff --git a/src/gps.h b/src/gps.h index d940a081..34403f44 100644 --- a/src/gps.h +++ b/src/gps.h @@ -31,7 +31,7 @@ #include "displays.h" #include "gpsrecord.h" -class SSD1306DisplayDevice; +class DisplayDevice; class Gps { public: @@ -47,7 +47,7 @@ class Gps { /* read and process data from serial, true if there was valid data. */ bool handle(); - bool hasFix(SSD1306DisplayDevice *display) const; + bool hasFix(DisplayDevice *display) const; /* Returns true if valid communication with the gps module was possible. */ bool moduleIsAlive() const; @@ -56,7 +56,7 @@ class Gps { uint8_t getValidSatellites() const; - void showWaitStatus(const SSD1306DisplayDevice *display) const; + void showWaitStatus(const DisplayDevice *display) const; /* Returns current speed, negative value means unknown speed. */ double getSpeed() const; diff --git a/src/utils/alpdata.cpp b/src/utils/alpdata.cpp index b889a1b9..9e3c51ff 100644 --- a/src/utils/alpdata.cpp +++ b/src/utils/alpdata.cpp @@ -30,7 +30,7 @@ /* Download http://alp.u-blox.com/current_14d.alp (ssl?) if there is a new one * Takes 5 seconds to update the data. */ -void AlpData::update(SSD1306DisplayDevice *display) { +void AlpData::update(DisplayDevice *display) { String lastModified = loadLastModified(); File f = SD.open(ALP_DATA_FILE_NAME, FILE_READ); @@ -95,7 +95,7 @@ void AlpData::update(SSD1306DisplayDevice *display) { httpClient.end(); } -void AlpData::displayHttpClientError(SSD1306DisplayDevice *display, int httpError) { +void AlpData::displayHttpClientError(DisplayDevice *display, int httpError) { display->showTextOnGrid(0, 4, String("ALP data failed ") + String(httpError).c_str()); String errorString = HTTPClient::errorToString(httpError); display->showTextOnGrid(0, 5, errorString.c_str()); diff --git a/src/utils/alpdata.h b/src/utils/alpdata.h index 5c4040f4..32cbecf9 100644 --- a/src/utils/alpdata.h +++ b/src/utils/alpdata.h @@ -39,7 +39,7 @@ static const char *const ALP_DOWNLOAD_URL = "https://alp.u-blox.com/current_14d. class AlpData { public: - static void update(SSD1306DisplayDevice *display); + static void update(DisplayDevice *display); static bool available(); static void saveMessage(const uint8_t *data, size_t size); static size_t loadMessage(uint8_t *data, size_t size); @@ -50,7 +50,7 @@ class AlpData { private: static void saveLastModified(const String &header); static String loadLastModified(); - static void displayHttpClientError(SSD1306DisplayDevice *display, int httpError); + static void displayHttpClientError(DisplayDevice *display, int httpError); File mAlpDataFile; }; From c159d245786747776b80fe46924be3b73980c810 Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 05/34] Switch to U8g2 display library OpenSans fonts were reconverted for U8g2. --- platformio.ini | 2 +- src/displays.cpp | 41 ++- src/displays.h | 130 ++++----- src/fonts/LICENSE.txt | 295 +++++++------------- src/fonts/OpenSans-Regular_14.h | 130 +++++++++ src/fonts/OpenSans-Regular_24.h | 208 +++++++++++++++ src/fonts/OpenSans-Regular_33.h | 307 +++++++++++++++++++++ src/fonts/OpenSans-Regular_6.h | 59 ++++ src/fonts/OpenSans-Regular_7.h | 70 +++++ src/fonts/README.md | 30 +-- src/fonts/fonts.h | 41 +-- src/fonts/opensans10.h | 459 -------------------------------- src/fonts/opensans20.h | 459 -------------------------------- src/fonts/opensans34.h | 459 -------------------------------- src/fonts/opensans50.h | 34 --- src/fonts/opensans8.h | 458 ------------------------------- 16 files changed, 971 insertions(+), 2211 deletions(-) create mode 100644 src/fonts/OpenSans-Regular_14.h create mode 100644 src/fonts/OpenSans-Regular_24.h create mode 100644 src/fonts/OpenSans-Regular_33.h create mode 100644 src/fonts/OpenSans-Regular_6.h create mode 100644 src/fonts/OpenSans-Regular_7.h delete mode 100644 src/fonts/opensans10.h delete mode 100644 src/fonts/opensans20.h delete mode 100644 src/fonts/opensans34.h delete mode 100644 src/fonts/opensans50.h delete mode 100644 src/fonts/opensans8.h diff --git a/platformio.ini b/platformio.ini index e7d5562e..9851fbf6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -51,7 +51,7 @@ lib_deps = ; https://arduinojson.org/v6/api/ bblanchon/ArduinoJson @ ^6.21.2 rlogiacco/CircularBuffer @ ^1.3.3 - thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays @ ^4.4.0 + olikraus/U8g2 @ ^2.35.9 adafruit/Adafruit BMP280 Library@^2.6.8 pololu/VL53L0X@^1.3.1 ; https://github.com/fhessel/esp32_https_server diff --git a/src/displays.cpp b/src/displays.cpp index 207c7ad7..0d361844 100644 --- a/src/displays.cpp +++ b/src/displays.cpp @@ -23,7 +23,7 @@ #include "displays.h" -#include "fonts/fonts.h" +#include "fonts/logos.h" void DisplayDevice::showNumConfirmed() { String val = String(confirmedMeasurements); @@ -46,10 +46,10 @@ void DisplayDevice::showNumButtonPressed() { void DisplayDevice::displaySimple(uint16_t value) { if (value == MAX_SENSOR_VALUE) { this->prepareTextOnGrid(0, 0, - "", HUGE_FONT, -7, -7); + "", HUGE_FONT, -7, 0); } else { this->prepareTextOnGrid(0, 0, - ObsUtils::to3DigitString(value), HUGE_FONT, -7, -7); + ObsUtils::to3DigitString(value), HUGE_FONT, -7, 0); } this->prepareTextOnGrid(3, 2, "cm", MEDIUM_FONT, -7, -5); } @@ -137,7 +137,7 @@ void DisplayDevice::showValues( showTemperatureValue(TemperaturValue); } - m_display->display(); + m_display->updateDisplay(); } @@ -161,45 +161,44 @@ void DisplayDevice::showBatterieValue(int16_t input_val){ xlocation += 1; } - if(input_val >= 0){ - String val = String(input_val); + if(input_val >= 0){ + String val = String(input_val); //showLogo(true); this->showTextOnGrid(xlocation, 0, val + "%", TINY_FONT, 6, 0); if(input_val > 90){ cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo1); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo1); }else if (input_val > 70) { cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo2); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo2); }else if (input_val> 50) { cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo3); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo3); }else if (input_val > 30) { cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo4); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo4); }else if (input_val >10) { cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo5); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo5); }else { cleanBattery(x_offset_batterie_logo, y_offset_batterie_logo); - m_display->drawXbm(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo6); + m_display->drawXBM(x_offset_batterie_logo, y_offset_batterie_logo, 8, 9, BatterieLogo6); } } - //m_display->display(); } void DisplayDevice::showTemperatureValue(int16_t input_val){ uint8_t x_offset_temp_logo = 30; uint8_t y_offset_temp_logo = 2; cleanTemperatur(x_offset_temp_logo,y_offset_temp_logo); - m_display->drawXbm(x_offset_temp_logo, y_offset_temp_logo, 8, 9, TempLogo); + m_display->drawXBM(x_offset_temp_logo, y_offset_temp_logo, 8, 9, TempLogo); String val = String(input_val); this->showTextOnGrid(1, 0, val + "°C", TINY_FONT); } @@ -231,7 +230,7 @@ uint8_t DisplayDevice::scrollUp() { for (uint8_t i = 0; i < 5; i++) { prepareTextOnGrid(2, i, obsDisplay->get_gridTextofCell(2, i + 1)); } - m_display->display(); + m_display->updateDisplay(); return mCurrentLine--; } @@ -242,22 +241,14 @@ uint8_t DisplayDevice::startLine() { void DisplayDevice::highlight(uint32_t highlightTimeMillis) { mHighlightTill = millis() + highlightTimeMillis; if (!mHighlighted) { - if (mInverted) { - m_display->normalDisplay(); - } else { - m_display->invertDisplay(); - } + setInversion(!mInverted); mHighlighted = true; } } void DisplayDevice::handleHighlight() { if (mHighlighted && mHighlightTill < millis()) { - if (mInverted) { - m_display->invertDisplay(); - } else { - m_display->normalDisplay(); - } + setInversion(mInverted); mHighlighted = false; } } diff --git a/src/displays.h b/src/displays.h index 7c7cd4f3..df979074 100644 --- a/src/displays.h +++ b/src/displays.h @@ -25,30 +25,27 @@ #define OBS_DISPLAYS_H #include -#include +#include #include "config.h" #include "globals.h" #include "gps.h" #include "logo.h" +#include "fonts/fonts.h" #include "sensor.h" -extern const uint8_t Open_Sans_Regular_Plain_8[]; -//// this font is part of OLEDDisplay::OLEDDisplay :/ -//extern const uint8_t ArialMT_Plain_10[]; // :( -extern const uint8_t Open_Sans_Regular_Plain_10[]; -extern const uint8_t Open_Sans_Regular_Plain_20[]; -extern const uint8_t Open_Sans_Regular_Plain_34[]; -extern const uint8_t Open_Sans_Regular_Plain_50[]; +#define BLACK 0 +#define WHITE 1 + extern const uint8_t BatterieLogo1[]; extern const uint8_t TempLogo[]; -#define TINY_FONT Open_Sans_Regular_Plain_8 -#define SMALL_FONT Open_Sans_Regular_Plain_10 -#define MEDIUM_FONT Open_Sans_Regular_Plain_20 -#define LARGE_FONT Open_Sans_Regular_Plain_34 -#define HUGE_FONT Open_Sans_Regular_Plain_50 +#define TINY_FONT OpenSans_Regular_6 +#define SMALL_FONT OpenSans_Regular_7 +#define MEDIUM_FONT OpenSans_Regular_14 +#define LARGE_FONT OpenSans_Regular_24 +#define HUGE_FONT OpenSans_Regular_33 // Forward declare classes to build (because there is a cyclic dependency between sensor.h and displays.h) class HCSR04SensorInfo; @@ -64,21 +61,24 @@ class DisplayDevice { private: void handleHighlight(); void displaySimple(uint16_t value); - SSD1306* m_display; + U8G2* m_display = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE); // original OBS display String gridText[ 4 ][ 6 ]; uint8_t mLastProgress = 255; uint8_t mCurrentLine = 0; bool mInverted = false; + bool mFlipped = true; uint32_t mHighlightTill = 0; bool mHighlighted = false; public: DisplayDevice() { - m_display = new SSD1306(0x3c, 21, 22); // ADDRESS, SDA, SCL - m_display->init(); - m_display->setBrightness(255); - m_display->setTextAlignment(TEXT_ALIGN_LEFT); - m_display->display(); + m_display->begin(); + m_display->setFlipMode(mFlipped); + m_display->setContrast(74); + m_display->setFontPosTop(); + m_display->setFontMode(1); + m_display->setDrawColor(WHITE); + m_display->updateDisplay(); } ~DisplayDevice() { @@ -96,20 +96,19 @@ class DisplayDevice { //############################################################## void invert() { - m_display->invertDisplay(); - m_display->display(); mInverted = true; + setInversion(mInverted); } void normalDisplay() { - m_display->normalDisplay(); - m_display->display(); mInverted = false; + setInversion(mInverted); } void flipScreen() { - m_display->flipScreenVertically(); - m_display->display(); + mFlipped = !mFlipped; + m_display->setFlipMode(mFlipped); + m_display->updateDisplay(); } void clear() { @@ -122,8 +121,8 @@ class DisplayDevice { //############################################################## void showLogo(bool val) { - m_display->drawXbm(0, 0, OBSLogo_width, OBSLogo_height, OBSLogo); - m_display->display(); + m_display->drawXBM(0, 0, OBSLogo_width, OBSLogo_height, OBSLogo); + m_display->updateDisplay(); } //############################################################## @@ -132,18 +131,18 @@ class DisplayDevice { void showGrid(bool val) { // Horizontal lines - m_display->drawHorizontalLine(0, 2, 128); - m_display->drawHorizontalLine(0, 12, 128); - m_display->drawHorizontalLine(0, 22, 128); - m_display->drawHorizontalLine(0, 32, 128); - m_display->drawHorizontalLine(0, 42, 128); - m_display->drawHorizontalLine(0, 52, 128); - m_display->drawHorizontalLine(0, 62, 128); + m_display->drawHLine(0, 2, 128); + m_display->drawHLine(0, 12, 128); + m_display->drawHLine(0, 22, 128); + m_display->drawHLine(0, 32, 128); + m_display->drawHLine(0, 42, 128); + m_display->drawHLine(0, 52, 128); + m_display->drawHLine(0, 62, 128); // Vertical lines - m_display->drawVerticalLine(32, 0, 64); - m_display->drawVerticalLine(64, 0, 64); - m_display->drawVerticalLine(96, 0, 64); + m_display->drawVLine(32, 0, 64); + m_display->drawVLine(64, 0, 64); + m_display->drawVLine(96, 0, 64); } //############################################################## @@ -166,7 +165,7 @@ class DisplayDevice { void showTextOnGrid(int16_t x, int16_t y, String text, const uint8_t* font = SMALL_FONT, int8_t offset_x_ = 0, int8_t offset_y_ = 0) { if (prepareTextOnGrid(x, y, text, font,offset_x_,offset_y_)) { - m_display->display(); + m_display->updateDisplay(); } } @@ -186,7 +185,7 @@ class DisplayDevice { // 2 => 8 - (2*2) = 4 // 3 => 8 - (3*2) = 2 int x_offset = 8 - (x * 2); - m_display->drawString(x * 32 + x_offset + offset_x_, y * 10 + 1 + offset_y_, gridText[x][y]); + m_display->drawStr(x * 32 + x_offset + offset_x_, y * 10 + 1 + offset_y_, gridText[x][y].c_str()); changed = true; } return changed; @@ -199,7 +198,7 @@ class DisplayDevice { gridText[x][y] = ""; } } - m_display->display(); + m_display->updateDisplay(); } // Override the existing WHITE text with BLACK @@ -208,23 +207,23 @@ class DisplayDevice { } void cleanGridCell(int16_t x, int16_t y,int8_t offset_x_, int8_t offset_y_) { - m_display->setColor(BLACK); + m_display->setDrawColor(BLACK); int x_offset = 8 - (x * 2); - m_display->drawString(x * 32 + x_offset + offset_x_, y * 10 + 1 + offset_y_, gridText[x][y]); + m_display->drawStr(x * 32 + x_offset + offset_x_, y * 10 + 1 + offset_y_, gridText[x][y].c_str()); gridText[x][y] = ""; - m_display->setColor(WHITE); + m_display->setDrawColor(WHITE); } void cleanBattery(int16_t x, int16_t y){ - m_display->setColor(BLACK); - m_display->drawXbm(x, y, 8, 9, BatterieLogo1); - m_display->setColor(WHITE); + m_display->setDrawColor(BLACK); + m_display->drawXBM(x, y, 8, 9, BatterieLogo1); + m_display->setDrawColor(WHITE); } void cleanTemperatur(int16_t x, int16_t y){ - m_display->setColor(BLACK); - m_display->drawXbm(x, y, 8, 9, TempLogo); - m_display->setColor(WHITE); + m_display->setDrawColor(BLACK); + m_display->drawXBM(x, y, 8, 9, TempLogo); + m_display->setDrawColor(WHITE); } void drawProgressBar(uint8_t y, uint32_t current, uint32_t target) { @@ -242,34 +241,34 @@ class DisplayDevice { uint16_t rowOffset = y * 10 + 3; if (mLastProgress != progress) { - m_display->drawRect(12, rowOffset, 104, 8); + m_display->drawFrame(12, rowOffset, 104, 8); if (progress != 0) { - m_display->fillRect(14, rowOffset + 2, progress > 100 ? 100 : progress, 4); + m_display->drawBox(14, rowOffset + 2, progress > 100 ? 100 : progress, 4); } - m_display->display(); + m_display->updateDisplay(); mLastProgress = progress; } } void drawWaitBar(uint8_t y, uint16_t tick) { uint16_t rowOffset = y * 10 + 3; - m_display->drawRect(12, rowOffset, 104, 8); - m_display->setColor(BLACK); - m_display->fillRect(14, rowOffset + 2, 100, 4); - m_display->setColor(WHITE); + m_display->drawFrame(12, rowOffset, 104, 8); + m_display->setDrawColor(BLACK); + m_display->drawBox(14, rowOffset + 2, 100, 4); + m_display->setDrawColor(WHITE); int16_t pos = 45 + (45.0 * sin(tick / 10.0)); - m_display->fillRect(14 + pos, rowOffset + 2, 10, 4); - m_display->display(); + m_display->drawBox(14 + pos, rowOffset + 2, 10, 4); + m_display->updateDisplay(); } void clearProgressBar(uint8_t y) { if (UINT8_MAX != mLastProgress) { clearTextLine(y); uint16_t rowOffset = y * 10 + 3; - m_display->setColor(BLACK); - m_display->fillRect(12, rowOffset, 104, 8); - m_display->setColor(WHITE); + m_display->setDrawColor(BLACK); + m_display->drawBox(12, rowOffset, 104, 8); + m_display->setDrawColor(WHITE); m_display->display(); mLastProgress = UINT8_MAX; } @@ -310,6 +309,15 @@ class DisplayDevice { uint16_t minDistanceToConfirm, int16_t batteryPercentage, int16_t TemperaturValue, int lastMeasurements, boolean insidePrivacyArea, double speed, uint8_t satellites); + + //############################################################## + // Internal methods + //############################################################## + + private: + void setInversion(bool enabled) { + m_display->sendF("c", enabled ? 0xa7 : 0xa6); // set inversion of the SSD1306 OLED + } }; #endif diff --git a/src/fonts/LICENSE.txt b/src/fonts/LICENSE.txt index d6456956..cb7002a8 100644 --- a/src/fonts/LICENSE.txt +++ b/src/fonts/LICENSE.txt @@ -1,202 +1,93 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/fonts/OpenSans-Regular_14.h b/src/fonts/OpenSans-Regular_14.h new file mode 100644 index 00000000..092a693d --- /dev/null +++ b/src/fonts/OpenSans-Regular_14.h @@ -0,0 +1,130 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--19-140-100-100-P-97-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_14[3910] U8G2_FONT_SECTION("OpenSans_Regular_14") = + "\277\0\4\3\5\5\4\5\6\22\27\377\373\16\373\16\375\2z\5\20\17) \6\0 ,\1!\15\303" + "%,#$\377*b\42\2\0\42\13\245dFAd\223\210\220\0##\314!d+&L&LD" + ",&\350\200(&.&LD,F\346\200(&.&L&LD\10\0$\35\351\345[)\60\314" + "D\42$B$H$\212\254\214*D(\204$B\342,\60\10\0%\60\316%\204c,F$(M" + "P\232T\61\42Q\61!\21#\61\21\22!YD\210\204LH\304H\205\304\10\211\304\10\305\210\4\11" + "\205\4E\215\0&\36\314%t\207NDJFJF,F\254P\205\20\215\14\221H\204\24\205\230\214" + "L\33\1'\11\242d&\341 \42\0(\23$f\63E$D$D\223\230\64\42jbDd\4)" + "\21$f\63!(FD&FD\237\204(I\3*\26)\245UGN\60H$B\342@fJ\42" + "HD(&\4\0+\15)\245\134)\60\243\3\241\300\214\0,\11\242d+\341\42\2\0-\7$d" + "\65\201\0.\12c$,#b\42\2\0/\23\307!\16I\245\134!p\241\244\240\320f\201\0\77\22\307%D\241D\231\224T\224\220" + "\252\260\350(E\0@+\17\246\213\313nhHPD\64$\250D\42FDfDFM\220\214L\220" + "\214L\220\10\211HDH\32\212\231\370\360\251\300#\0A\37\314!dKT\222P\42\60$ND," + "(JH\350 (,FLDL$\60BP\0B\26\311)d\341$h\42l+\11\233(\211\260" + "\71eS\22'\0C\21\312%d\311\204DbN\241^\12J\222\10\31D\32\313)t\341(\210$" + "l\42N\42\60\42p\207\21q\22a\42A$G\0E\15\307)\134\341 ,g\7ayvF\16" + "\307)T\341 ,\317\16\302\362\14\0G\27\313%t\311\206dDP\62R+\303\301\10\271\10\271\20" + "\32\241\3H\15\312)t!P\17\17\12\365a\0I\7\301),\341\1J\12D\36+'\377\177R" + "\1K\36\311)d!lJ\42H$F&Q\210P\204TQ\214LPL\220H\224D\330\230\0L" + "\12\307)T!,\377g\7M#\315)\214A\262\216\42.BY\204*\11\221\250\20E!jDd" + "\322\250\220\21\212\10\22\32\22\32\222JN\34\312)tA\216\214LBJ$JDHFQ\214\220\210" + "\224\204\224\204\30\335\234\0O\32\315%|\251lfF.FNB\62B\222\227!r\42rA\63c" + "E\0P\20\310)\134\301$\210jL\253\3\211\270\274\3Q\34-f{\251lfF.FNB\62" + "B\222\227!r\42rA\63c\265\302J\0R\37\311)d\301&h\42J\42,\42,\42,\42J" + "\342$F&H$*$J\42lL\0S\25\311%T\305DFBN\241\340B\301@\271\10\231\11" + "\33\0T\14\312!\134\341`HP\377G\0U\20\312)t!P\377p\214Lbd\246\6\0V " + "\313!\134AN\42NB,DJ&JF(HF*FJ$LB.BnpR\10\0W\62" + "\321!\224AL,\42jJBhJB(B(D(B(&F$F\211H\214\222\30\221 \11" + "\241\220\250\10\241\10\251\210(\252ecrb\62\0X\37\313!\134#.DJFUL\230\204\134D" + "\240\344\234\204X\210\224\214PT\214\224\204\234\0Y\26\312!\134A.\42LB*F\233(\11)\211" + "\270\71\311<\2Z\25\311%\134\341@NL.NLNL\235\230\134\234\334\201\0[\12$j\63\241" + "&\377\337\20\134\23\307!\201*\242F\244\42\0\253\25\7eL'$" + "\211\204H\204H\210H\214HL\210LH\0\254\11\251\244\134\341@\60\7\255\7$d\65\201\0\256*" + "\316%\204\251\60J*\60&\244&\42FD$\42FDF\211\214L\221\214\204\220\214HLH\210L" + "HL`T\224\234\21\0\257\10*\340W\341`\0\260\17\306$F\203$dH(\42D\202\2\0\261" + "\16i%\134)\60\243\3\241\300\254\17\4\262\17\6\241=\203$D*(HF&\310\0\263\15\6\241" + "=\203JHdJ\315\5\0\264\11c\60_C\42\11\0\265\20\350\351b!L_M\321PP\310\345" + "\16\0\266\36)\246c\345\242\344O\42JBH\242B\242B\242B\242B\242B\242B\242B\242B\2" + "\267\12cd-#b\42\2\0\270\13\244\340\42%D(\206\2\0\271\11\3\245=\245\42$\17\272\14" + "\305$>c\42F\233\210\11\0\273\22\7eL!&DOBD\42DH$bB\0\274'\315%" + "|%Ld,&\42J*YP\134\214\134L\214L\210\310X\314TL\204\220H\210P\214\211\230L" + "\234\4\0\275\42\315%|C,fJ&\42*,(.F.&\60D\202&$\211P\230\214XP" + "X\220T\256\14\276'\317!|\203LU\234P\24\221\240Lh\210T\214HLHI\214\240HD`" + "LD\234H\272\220\243\270(\271\20\0\277\23\310!CIL\36.\231\224\262\60\271\70\31\221\12\0\300" + "\42L\42dGV=\234\250$\241D`H\234\210XP\224\220\320APX\214\230\210\230H`\204\240" + "\0\301\42L\42dM\64=\240\250$\241D`H\234\210XP\224\220\320APX\214\230\210\230H`" + "\204\240\0\302$L\42dK\222ND\36JT\222P\42\60$ND,(JH\350 (,FL" + "DL$\60BP\0\303$,\42dg$,\202\36JT\222P\42\60$ND,(JH\350 " + "(,FLDL$\60BP\0\304$,\42dGDLD\36JT\222P\42\60$ND,(" + "JH\350 (,FLDL$\60BP\0\305$,\42dK\62$\60$RT\222P\42\60$" + "ND,(JH\350 (,FLDL$\60BP\0\306 \317!\214\355@,BTB\64D" + "RD\62FP\346F\341\235\220\134\224\230\224X\230\224\330\1\307\26j\346b\311\204DbN\241^\12" + "J\222\10YE*\24\233\1\310\20G*\134CL,\364 ,g\7ayv\311\17G*\134I\323" + "\203\260\234\35\204\345\331\1\312\22G*\134e(\42&\341AX\316\16\302\362\354\0\313\21'*\134C" + "$D$\360 ,g\7ayv\314\14C\42,AD$*$\377\17\315\14C*,C\42UH" + "\376\237\0\316\16E\42,c$b&.(\377O\0\317\15%\42,Ad$.(\377O\0\320!" + "\315!t\345,h*L(N&\60&\60\342H$P$\60&N&N&L(h\352\10\0\321" + " **tgB&dX\216\214LBJ$JDHFQ\214\220\210\224\204\224\204\30\335\234\0\322" + "\36M&|IX\70\36\260lfF.FNB\62B\222\227!r\42rA\63cE\0\323\35M" + "&|OT=`\331\314\214\134\214\234\204d\204$/C\344D\344\202f\306\212\0\324\37M&|K" + "\224P&\36\254lfF.FNB\62B\222\227!r\42rA\63cE\0\325\37-&|i$" + ",d\36\254lfF.FNB\62B\222\227!r\42rA\63cE\0\326\37-&|)D\60" + "D\36\254lfF.FNB\62B\222\227!r\42rA\63cE\0\327\23\350\344\134A*B&" + "F\42J,\42(&$*\0\330%\315%|\251Bf\204FLF\212BJ$B*\206H\206F" + "\210D\212$,\204Jd,hf&\244\10\0\331\22J*t'Ry\240\376\341\30\231\304\310L\15" + "\0\332\23J*tKN\60>P\377p\214Lbd\246\6\0\333\24J*tI\216*F\70P\377" + "p\214Lbd\246\6\0\334\24**tE$J$:P\377p\214Lbd\246\6\0\335\30J\42" + "\134MN\271\134D\230\204T\214\66Q\22R\22qs\222y\4\336\26\311)d!\60\320&h\42J" + "\42l\263\210(\211\223\300\204\0\337\35\351)d\243FI\224D\224D\220H\214L\242\230\240\230\221\240" + "\211\260MbF*\0\340\25\310%\134E.\60\272DFL.\344@\206\210\315\4I\0\341\25\310%" + "\134+LJ\272DFL.\344@\206\210\315\4I\0\342\26\310%\134G\212F&\266DFL.\344" + "@\206\210\315\4I\0\343\26\250%\134e$\42d\266DFL.\344@\206\210\315\4I\0\344\26\250" + "%\134%D&D\266DFL.\344@\206\210\315\4I\0\345\30\350%\134g($($j\270D" + "FL.\344@\206\210\315\4I\0\346\34N%\204\205\215\10\311\230\220\230T\310\301A\214\230\220\230\220" + "\230L\211\4M\5\0\347\24\347\345J\245b$\42J\317FB\212\242\344\302bF\0\350\26\311%\134" + "EP\60\276FIT\204\324\201\235`\340L\214\5\0\351\26\311%\134KL.\276FIT\204\324\201" + "\235`\340L\214\5\0\352\30\311%\134g,\42*&\272FIT\204\324\201\235`\340L\214\5\0\353" + "\27\251%\134E$H$\272FIT\204\324\201\235`\340L\214\5\0\354\14\303!,A$&*$" + "\377\0\355\14\303),\203\42*$\377\4\0\356\16\305!,CD\42M\134P\376\11\0\357\15\245!" + ",!dD.(\377\4\0\360\26\351%\134'Q\325\320D\240\222\13\231*\262\255$ddJ\0\361" + "\21\250)d\203\42$d\62\242b\244hL\237\5\362\25\311%\134EPy\315\210H\24\331f\21Q" + "\22\62\62%\0\363\26\311%\134KL.\276fD$\212l\263\210(\11\31\231\22\0\364\27\311%\134" + "I\214(F\270fD$\212l\263\210(\11\31\231\22\0\365\27\251%\134e$D\202\270fD$\212" + "l\263\210(\11\31\231\22\0\366\27\251%\134E$H$\272fD$\212l\263\210(\11\31\231\22\0" + "\367\17)\245\134GN\36\356@\36L\60\10\0\370\31I%\134\345bD$\250FbDd$f\42" + "(bFBF\342\4\0\371\16\310)dCNm\324~E\63A\22\372\16\310)dI,q\324~" + "E\63A\22\373\20\310)dG\212&F\62j\277\242\231 \11\374\20\250)dC$F$\64j\277" + "\242\231 \11\375\36i\342RK.\265XD\224\204\220\204PL\214\22\241\220\250\10\251\71uqbR" + "c\0\376\34\211\352b!\60/hF&\204$\302\42\302\226E\10I\214LD\320\4\346\20\0\377 " + "I\342RE$H$V,\42JBHB(&F\211PHT\204\324\234\272\70\61\251\61\0\0\0" + "\0\4\377\377\0"; diff --git a/src/fonts/OpenSans-Regular_24.h b/src/fonts/OpenSans-Regular_24.h new file mode 100644 index 00000000..e977aaa5 --- /dev/null +++ b/src/fonts/OpenSans-Regular_24.h @@ -0,0 +1,208 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--33-240-100-100-P-167-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_24[6419] U8G2_FONT_SECTION("OpenSans_Regular_24") = + "\277\0\4\3\5\6\5\6\6!'\375\370\30\370\30\373\3\313\10I\30\366 \6\0\200`\12!\16\4" + "\223`\32\373\277\20\321&\374b\1\42\22)\221o\13\63\276\231\220\231\20\222\20\222\20\212\0#:\23" + "\213`}R\242R\242R\242R\222S\222R\223RR\7\7\24\7\7TS\222R\223R\242R\242R" + "\242RR\7\7\24\7\7TJ\245D\245$\207&\245&\245D\245\344\0$\61o\223\336l\322j\17" + "\242\16J(dFF\344f\344f\4G\4)$M_\36\304\311\314\11\215\11\215\11\215\311L\220H" + "T\34\30\35\304Jk\7%N\27\223\340.\245R\207S\62\202RBc\252\244\306\244\324I\11\315I" + "\11\11J\311\14J\311\310\220H\211L\134\10\215\250\231\220\21\231\30\222\70Q%R\42#%\70#%" + "($%\67$%'\245lJ\231\330\220\324\234\314\224\340\325(\11\0&:\26\223 ^\346\7\322\63" + "\264c\262c\243c\243c\302C\303\63\343\367\20\365\20\365\24\203\62\64c\63SK\346hd\6)f" + "&\215F\213F\213\10\217,.\210\16\210\250\356\10'\11#\221\357\11\17\42t(\33\247\213\233ZB" + "\63C\63CCB\33\11\355WRC\253\244\206\246\206\246\246\4)\33\247\213\233\12SSRSRC" + "SRC[\351\321\336\14\15\11\15\11\315\14\1*\34\360\211\252|\323\342\32\316\310\214\34|\60Fk" + "*\42\71\62\67\64\66D&\25\4+\17\17\222\344l\303\373\354\340\3\261\341}\6,\16\5\211\34*" + "\23\24#KDFd\0-\10H\210\350\12\17\4.\10\204\220`\32\27\13/\32\13\213 \213\203\202" + "\353\6\7\5\27\12.\24\34\24\134(\270Pp\241$\0\60\42\17\223\340\134\205\7R\64\64c\63s" + "\23\223\22\223.K\373\324\322K\221\271\221\61\32V\7\202U\0\61\22\11\233\340lC\65&\27#\66" + "\23Ac\373\377\7\62\30\17\223\340Lv\7\63&\65r\304{,<;<\273\177|\360\201\0\63!" + "\17\223\340Lf\7\64\66$\222\303\273\235\245:\210;\10\256^\274\333\341\11\242\222\203\242\3)\0\64" + "(\21\213\340\274\323\304\265\266\22\243\23\223#\223\62\203\63sCsRcS\313\206\346\206\4g\6g" + "\16>\260\35\337\33\0\65!\17\223\340,\7\64\7\65\303;\226\226>\20;\240\22\252^\274\267\23\221" + "\24\65%\7U\7Q\0\66'\17\223\340|v\7Q\225\264\213\207\205\327\24M\34\210\30Q\320ML" + ":m\71!\71\61\70A\66CSt\60g\4\67\35\17\223\340\14\77\20^;<,<,\274vx" + "vxvxXx\355\360\354\360$\0\70/\17\223\340Lg\7\64D%s\23\223\22\223\42\222\42s" + "#TC\64c\7\201g\24ET$s\23\223\245\265\244\226\206#T\64\7dG\0\71'\17\223\340" + "Lv\7C\65\64c#\203\23\223\22\242M-\35R\20\231\34H\14\325\14\17\13\257]\24Ut " + "v\7:\14D\222`\32\7\24\363h/\26;\22\305\212\134*\23L\346\261\233\240\30Y\42\62\42\3" + "<\24\17\222\344\354\301\243\205\35R\322\16W\27\27\333\32\217\7=\15/\221\347\14\77\220\307\375\301\7" + "\2>\23\17\222\344\14\341\303\375x\264\256\260\316\256t\70\34\0\77\33\14\213\240+\67\7\24%\24\201" + "\243Z.\134G\270RT=\372IB\302\61\0@Sz\223\235\257\7\361\7\306t\205\264d\363S\362" + " B\362\60#sW\42b\7R\42RSRFcRUcbTrbTrRUrR\22R" + "bS\22RbC\23CC\22\62\42S\7\21FbET\363\200\363\220\363\220\363\220u\303\7\367\7" + "\222\0A\66\25\203`\235\363\60\363 \365\20\352!\324O\214\213L\317\14\317\14K\311N\215NM\316" + "I\316\15\36\330\35\34\204M\216\311J\315\16\315\316L\217L\217\210O\314\17B\64\21\233`\15\7U" + "\7\67c&\223#\243\23\243\23\243\23\243\23\223#\203\63\7F\7Fc&\223\24\243\23\243\23\263N" + "'F'&)\306L\16n\16\252\0C \22\223`\215\17\214.\212(c\250\311\347\307\347\367{\210" + "\371y\346\345\7\21e\7\205\7\61\0D)\23\233 \16\7\204\7WcF\223\64\263#\263\24\303\23" + "\303\23\323\376\343\211\341\211Y\212Q\222I\232\251\243\203\253\3B\0E\22\15\233\240\14\77\10\335O\17" + ">\10\335\77=xPF\21\15\233`\14\77\10\335\237\36|\20\272\377\24\0G\65\24\223 \216\7\241" + "\7V\27G\244A\364\20\363\20\363 \363\20\363 \363 \363 \223\7\224\7\344\316'\246'\246'\210" + "GhgH\207n\254\16\16\342\16f\0H\17\22\233 \16\303\376\307\7\177\354\377\361\0I\11\3\233" + "`\12\377\17\4J\20\311kZj\373\377\377\257&$*Nl\0K\65\21\233 \15\243\23\223\24\203" + "$\203\63sCcS\313\206\346f\6G&'F\17\42+\6I\350\206\346\246\306\246\250\306\210\346\206" + "\6g\6I&GF'f\7L\16\15\233`\14\243\373\377\177z\360\240\0MC\30\233\240\17\345\7" + "\343\7\343\7\304\7\305\22\26\262\23\26\243\23\26\243\42&\203#&\203\62\66r\63\66c\63\66cB" + "FRCFCRFCRV#SV#bf\22c\236\325\331\321\331\15\332\15\16N\62\23\233`" + "\16\304\17b\17D\17D-&-\10M\6m\346l\346\214\306\254\246\254\246\314\206\314h\354f\14G" + "\14),'L\17D\17d\17\202\217\11O\66\26\223\240~\7\301\7\205\27w\204T\263\64\304\63\343" + "#\343\23\363\23\363\20\366\20\366\20\366\20\366\20\366\20\366#\343#\343#\323C\263T\204d'\226\7" + "\305\207\0P\34\17\233 \15\7S\7&C\27\203\23\223\376pb\254\342\300\344\200hx\377\30\0Q" + "A\266\223\233~\7\301\7\205\27w\204T\263\64\304\63\343#\343\23\363\23\363\20\366\20\366\20\366\20\366" + "\20\366\20\366#\343#\343#\323C\263T\204d'\226\7\305\7\361@\364@\364@\364@\364@$\0" + "R\65\21\233 \15\7d\7FC\67\203\63\223#\223#\223#\223#\223#\223#\203\63s\64\7F" + "\7dSc\253\306\246\346\206\346\206\6g&G&GF'F\11S\42\17\223\240L\7Q\7%\26" + "\26\264\303\33\63\256=\275-&\236\226\36\26\236\245(\61\71(:\220\2T\64\22\203\240\14\177\20(" + "\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!\17!" + "\17!\17!\17!\17!\17!\10U\26\22\233 \16\303\376\377\217'FG\10iL\254\16\12\17\242" + "\0V\61\23\203 \15\323\23\322\23\303\23\263\63\262\63\243\63\223S\203S\203Ss\313\346\306\346\246&" + "\207&\207&gfGfG\244%\246%\246\353\331\17\2WR\35\213\340\17\262\243\226\244\226\244\22\223" + "\205#\202\206#s\23\202#s\42s\62s\42cCb\63bCS\63bCSBSRC\233\11" + "M\11\215\315\210\315\214\215\214\315\310\215\314\211\14\212\314M\14N\10N\14\32N\210V\226\222\226\262\245" + "\35\236\35\3X\60\23\203\340\34\263\63\223C\223Sss\12\247&gFgf'\246\313\353\347\313\253" + "'fgFg&\247\6\305\310\346\246&\207&gf'\246\7Y\42\22\203\240\14\303\23\263\23\243\63" + "\223\63\203SsScsS\202C\223\63\262\42\263\326\325\364\373\357\0Z\37\21\213\340\34\7\7!\7" + "\7\341\323\343\323\313\247\227OOS\257\246^M\275|\372\340\3\3[\16\247\233\333\12\17\244\364\377\377" + "W\7\7\134\36\13\213 \13\222\203\223\222\203\223\222\203\223\222\223\222\203\223\222\203\223\222\203\223\203\223\222" + "\3]\16\247\213\333\12\217\366\377\377G\7\7\3^ \360\211\251|\322\323\264\22\262\22\223\62\222\62s" + "CrR\313\244\344f\6e$'F%d\7_\10O\200\333\13\77\20`\11\247\260\364\14DS\33" + "a N\222\240LW\7CC\264\303\263\253\16D\16*\310\14\15+\13\317\16\204,\16$F\214\4" + "b\42/\233 \15\303\373X\306H\344@Db\246\202nb\322\323^\272\274\233\220\230\251\220\70\30\221" + "\61\2c\30L\222 \134F\7\42%\23\223\203\223\373\351\344h\311\314\201\224\5\0d!/\223 \335" + "\372\221\215\314\201\204\10\215\305\34\305\240\245i\277\234\220\234\230#\241\261\71\220\20\262\21e\36O\222\340" + "\134v\7R\64\64s#\202\23\223\226\7\77\10\336z\230\270\206\350\200\354\6\0f\26,\203\340zU" + "G\64A\223\242\12\17$\16\250D\365\377\63\0g\61P\213\230\134\7\64\7&SCs\63s\63\203" + "\62s\63sCSc\7\202\207\322\323\342\323\7d\7%T\7\242\265m-'\310J\16\254\16\242\0" + "h\30/\233 \15\303\373\211\221\310\201\210\304\20\5\335\304\244\304\244\377/\7i\14\3\233!\12\7\241" + "\7\377\240\0j\24\10t\31Z\253\344\341\247\366\377\177%&\21\63aR\3k+.\233`\14\302\372" + "\341\204\334\210\330\214\324\220\320\224\314\230\310\234\304\340\35\305\330\214\230\320\224\324\220\330\214\330\214\334\210\340" + "\204 \1l\11#\233 \12\377\17\12m\61Y\232\340\17\62V\66\42\7\61\7!\22\63\24\63\24d" + "u\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\203\206\13n\26O" + "\232 \15\62F\42\7\42\22\63\25t\23\223\22\223\376\277\34o\35P\222 ]\206\7S%\65s$" + "\203\23\243\376\351\304\340\310\340LI\325\301\240\25\0p\42O\233\30\15\62F\42\7\42\22\63\25t\23" + "\223\236v\351\345\335\204\304L\205\304\301\210\214\321\360~\14q!O\223\30M\66\62\7\22\42\64\26s" + "\24\203\226N\373rbpb\216\204\306\346@B\310FZ\177r\21J\232`\13B&\7\21,\244\310" + "\346\366\177\7s\33L\222 <\17\16\202&&E')\13\17+IGU\226\35\34\204\34\304\0t" + "\22\313\202 K\222\202\313\16\336\14\356\377r\360\312\0u\23N\232 \15\242\374\277\64\264;\220\261\70" + "\230\220\261\21v&P\202`\14\243\23\242\23\223\23\203\63\202\63sBcS[\311\11\315\315\314\315H" + "\212LNLN\310\326R\217\1w;X\212\240\16\202\203vtvtfu\42b\22S#S\22S" + "#C#R#C#C\332,\32\31\222\31\32\31\32\221\32\221\32\21\23\21\223\30\63\223\30\253+\244" + "+d\70I\4x#O\212`\14\223\23s\63c\63Sk\346F\4'&k\207I+'\346f\306" + "\206\244\326\314\215\14Z\16y,P\203X\14\263\22\242\23\223\23\203\63s\63sCbS[\311\11\315" + "\315\14\312HNLN\214J\310\26O\257\226^\274\362\262\26\0z\27M\212\340\33\7\25\7\245\223K" + "'\227Nn:\271t\362\340A\1{\26\252\213[{cTTs\373\263\241\252\271\302u\373C:\272" + "\1|\11\42\304\230\14\377\7\3}\31\253\213[\13\203\205\204\223\222\203\373\245\35\225\321\340~(\70G" + "U\66\10~\16\217\220\352\34v\7$\65\7t\26\0\240\6\0\200`\12\241\17\4\223Z\32\23\27\323" + "\42z\62\261\377\0\242\33\15\233\340l\243+\217\16FJF(\227\356\267\243\244%\64\7S\206\243\213" + "\0\243\32\21\213\340|\207\7TDc\323\343\373\366\300\350\300n|_\17S\37|`\244'\357\221\344" + "\34\261\21#%\23\7\66CDr\62s#\222\42\222\42\222\42\202\63rBC\64\7\26#%\23\261" + "\21\0\245+\21\213\340\14\263\266\23\223#\223\63sCsbScS\202\63\203\63\242\23\243\23\302\205" + "\7F\7\226\343+\17\214\16,\307\267\3\246\14\42\304\230\14\37\314C\34<(\247*-\223`<\7" + "\61\7$D\23\243\263\243\244v\7A\63\25c\23s\356&\250dJ\246\16KiGG\255(\16h" + "\16\202\0\250\11i\250\365\14\63n\6\251@\30\223\340\216\367\7\245\204\213\305\306\245\304\252d\244\16\242" + "$\244\246\242$\204\246#\204\246\247\304\247\304\247\304\247\304\211\246\211\246#\244\246\242D\244\16\242d\244" + "\254\204\306\305\206\5\11g\17\312/\1\252\22i\211-+\65\7qj,H\250\30\35TT\10\253\37" + "\256\211\42\134RaBk\206f\206f\206f\206V\315\214\315\214\315\214\315\214\11MIE\0\254\12/" + "\221\344\14\77\220\326\17\255\10H\210\350\12\17\4\256H\30\223\340\216\367\7\245\204\213\305\306\245d\16\242" + "d\204\16\244$\244\206\244$\244\206\246\42\244\206\246\306f\306\306\16\342\306\16\307F\346\250f\344\250f" + "\306\42\244\206\244D\204\26\311\310L\215\10\215\213\15\13\22\316\36\224_\2\257\10Q\200y\14\77\60\260" + "\24J\221\256;D\7!B\22b\234I\10\211\34\4\321\0\261\23o\222\341l\303\373\354\340\3\261\341" + "}\17v\360\201\0\262\21\312\211\352*\65\7\61A\203\332\351\273\203\3\3\263\25\311\211\352*%\7\21" + "Bs\312d\212\14\345\324\35\34\220\0\264\11\247\260\364<\64;\2\265\26O\233\30\15\223\376\177xw" + "\60sp@QRS=\274\217\1\266G\320\223\234M\7%\7\27\7\63\22\7\63\7\66\7\66\7\66" + "\7\66\7\66\7\66\7\66\7\66\7\66\22\7\63\22\7\63\42\7\62B\67\222\62\222\62\222\62\222\62\222" + "\62\222\62\222\62\222\62\222\62\222\62\222\62\222\62\222\62\2\267\11\204\220j\32\23\27\3\270\16\6\211\30" + "*BADCB\27$\0\271\16\307\211\352J#\7\22\22\61R\372\17\272\23j\211-;\65\7!" + "Be<\223\20\232\70\10*\1\273\33\255\221\42\14RQ\63SB;\222\232\231\232\331\321\310\320\310\320" + "\314\42\251(\0\274B\27\213\240N\243S\245B\24\222b\61\202\243\202\262r\263r\302b\322R\323R" + "\342B\353\204\244\346d\244\350D\206$d\245$D\207DD\205d$\205\24\16)\24:\240\32:\240" + "\22\26\223\226\232\26\1\275>\27\213\240>\243c\244R\23\222b\42\202\243\202\262r\263r\302b\322R" + "\323R\342BBeB\42\7Q\62\212\244D&\7E\347d\345F\347d\345F\5%\7%\7W\12" + "\36\214\14\36\14\276H\31\203\240.\306B\7\241CB\223\302\202\322r\303\202\222\205\242v\362R\362\20" + "B\363\20BR\42a\63R#\7\62C\64GR\21\322C\22\322B\42\302B\62\262C\62\262BJ" + "g\16\10\205\16\350\204\5\207\5\245E\0\277\36\15\213\232k\223L\347\61\32\225\25\235$d\70*:" + "*+;:\30BCs@s\3\300@\365\203`]\364\60\363@\363@\363@\363\330\317\303\314\203\324" + "C\250\207P\77\61.\62=\63<\63,%;\65:\65\71'\71\67x`wp\20\66\71&+\65" + ";\64;\63=\62=\42>\61\77\301A\365\203`\275\364 \363 \363 \363\60\362\270\230\207\231\7\251" + "\207P\17\241~b\134dzfxfXJvjtjrNrn\360\300\356\340 lrLVj" + "vhvfzdzD|b~\0\302\77\365\203`\235\363 \365\327\63\263b\363\330\316\303\314\203\324" + "C\250\207P\77\61.\62=\63<\63,%;\65:\65\71'\71\67x`wp\20\66\71&+\65" + ";\64;\63=\62=\42>\61\77\303\77\325\203`mT\241'\242\42\227R\364\30\317\303\314\203\324C" + "\250\207P\77\61.\62=\63<\63,%;\65:\65\71'\71\67x`wp\20\66\71&+\65;" + "\64;\63=\62=\42>\61\77\304=\265\203`mB\303\63\303B\363\30\317\303\314\203\324C\250\207P" + "\77\61.\62=\63<\63,%;\65:\65\71'\71\67x`wp\20\66\71&+\65;\64;\63" + "=\62=\42>\61\77\305\77\265\203`\215\364\20\366\62\342\62\342\62\342\366\20\364 \365\20\352!\324O" + "\214\213L\317\14\317\14K\311N\215NM\316I\316\15\36\330\35\34\204M\216\311J\315\16\315\316L\217" + "L\217\210O\314\17\306C\33\203`\277\7\7\262\7\7\242#\362P\62\362@\63\362@\352a\206\344a" + "\206\344A\246\344A\246\344!\306\16\350\306\16\310\346\344\347\304\17\314\17\254'\245'\245E\205G\205G" + "egeg\17\16\202\17\12\307,\22\224X\215\17\214.\212(c\250\311\347\307\347\367{\210\371y\346" + "\345\7\21e\7\205\7\301\362\20\362\364\20\363\20\362\20\302\306t\0\310\31\355\233\240,\244\263k\345Q" + "\34|\20\272\237\36|\20\272\177z\360\240\0\311\27\355\233\240|\224\273Gr\360A\350~z\360A\350" + "\376\351\301\203\2\312\33\355\233\240\134\223u\23S\63\253\346\201\17>\10\335O\17>\10\335\77=xP" + "\313\32\255\233\240(\274\270#\244\232\245!\236\31\37\31\237\230\237\230\207\260\207\260\207\260\207\260\207\260\207\260\37\31" + "\37\31\37\231\36\232\245\42$;\261<(>\4\324@\366\223\240\236\363\60\365\20\313g\206\247\346\61>" + "\10>(\274\270#\244\232\245!\236\31\37\31\237\230\237\230\207\260\207\260\207\260\207\260\207\260\207\260\37\31" + "\37\31\37\231\36\232\245\42$;\261<(>\4\325\77\326\223\240~S\262&\262\42\267Q\364X\37\4" + "\37\24^\334\21R\315\322\20\317\214\217\214O\314O\314C\330C\330C\330C\330C\330C\330\217\214\217" + "\214\217L\17\315R\21\222\235X\36\24\37\2\326=\266\223\240~B\322C\342B\362X\37\4\37\24^" + "\334\21R\315\322\20\317\214\217\214O\314O\314C\330C\330C\330C\330C\330C\330\217\214\217\214\217L" + "\17\315R\21\222\235X\36\24\37\2\327\35\316\221\344\34\301\223\22s#SC\63c\23\203\245\243\205\23" + "c\63CS#s\226\2\330EV\223\237\376\60\241\7!s\7\7Q\27\7a\204T\243\65\224\66\223" + "#+e&&g&\6\247\354\306\354\306\314\346\254\6\215&\215\6GV\216L\214\216L\210\16U\22" + "\25R\35\204\230\35\34\204\315\234\306\3\1\331\36\362\233 ^\363\364\363\20\363\20\363\250\207\375\377\37O" + "\214\216\20\322\230X\35\24\36D\1\332\32\362\233 \236\344\333\313\243\37\366\377\177<\61:BHcb" + "uPx\20\5\333\37\362\233 ~\343\305\23\243\63\203S\363H\207\375\377\37O\214\216\20\322\230X\35" + "\24\36D\1\334\35\262\233 ^B\222C\223B\362h\207\375\377\37O\214\216\20\322\230X\35\24\36D" + "\1\335&\362\203\240\254\343\344\333#\37\236\230\235\30\235\231\234\31\234\232\233\32\233\233\22\34\232\234\221\25" + "\231\265\256\246\337\177\7\336\35\17\233 \15\303\33\37\20\35\230LY\14^:m\351\360\216\342\300\344\200" + "hx\217\1\337\64\60\233`=\7q\7SD\64\203#\203#\203#\203\62s\63SDCTCc" + "CrCcCTS\65s$\203\24\223\23\243>\221\232\30\71\230\230\271\1\340%.\223\240<\263\264" + "\303\353\321]\35\14\15\321\16\317\256:\20\71\250 \63\64\254,<;\20\262\70\220\30\61\22\341&." + "\223\240\214\243\263\262\243\362(\257\16\206\206h\207gW\35\210\34T\220\31\32V\26\236\35\10Y\34H" + "\214\30\11\342(.\223\240\134\244\205v#Sb\362\210\256\16\206\206h\207gW\35\210\34T\220\31\32" + "V\26\236\35\10Y\34H\214\30\11\343(\16\223\240@P\201\306\215\60\32" + "\11d\221A\24\31\5\221BN)\345\20\63T\70\301\0+\23\326%\213Z\65\346\374K\17\374\200Q" + "c\316\277\4\0,\23\306\42uKA\205\22\210\240\2\21D\214\61\206 \0-\11\313 \227O\360\201" + "\1.\16\206\61\201\314@\304\3\42\224@\2\0/'O\30\201\321ESd\221\65\26\265\306\242\24Y" + "d\215E\255\261(E\26YcQk,J\221E\326X\324\32\14\0\60>V(\201Zd\32K\356" + "\30b\14A\244\20E\10Yc\20F\4aD\220\66\304p$\14\207\377\34\11\303\221\60\34\11\244\15" + "A\30\21\204\221A\26\31D\221BP\61\205\230\343\324j\347\0\61\33LH\201ZDN\61\206\240Q" + "\302\20%\244A\302 D\204B\20\375\377\377\1\62$V(\201\332sX;\17\204r\212!D\25\42" + "\30\221\324\234$-\22I\42\211\5\226H\377\27\37\370\1\3\63\67V(\201Z\223\224;\17\4\202\212" + "!D\25\22\32\221d\22I\344\220\24,\317\244\265Rk\17\311J\222\71&\221T$\222\304\22D+" + "\302\230\63\36\30\345\201\220\24\2\64$" + "\211x@\204\22H\0;\35\307'uLA\6\21&\30A\6\371\60D\6\21E\220A\11\62\310\30" + "d\20Q\0<\35\326%\213\332\32\346\210\345\235v\257\31g^\211&^\21A\24OD\20A\63G" + "\15=\17\25\63\225Z\360\7\306\207\23\17\374\300\0>\33\326%\213Z\20\352\230%^\322>Ybq" + "\247]\14c\207!g \221\241\2\77-R\30\201T\202N#\17\4q\206\31\42\25G\336x\304\21" + "\67\34\325H+\254\60\322hn\274\311\215\67>t\210+\314j\245\221\4\0@\205d\71y\351\227\356" + "\3A>P\334I\207\225WT\221\4\221J\14\271\303\14L\10I\10\15\62P+D\220\343\314\20\343" + "\24\63\316\20\303\20\64\316\10\343\20\64\316\71#\15d\14I\3\31C\322\70\307\14\65\316\61C\215\63" + "\302\60C\215\63\302\60\4\221\63\302\60\4\21C\302\70\343\24\63\304\70\244\214\60\10\21\344\254\240\310@" + "i\240\62\222\61\345\220\17\4\371@\220\17B\371 \224\30\334Q\5>P\344\3\302*\7\0AS]" + "\10\201\335\66r\301\5\33;\302\260#\214J\2\241D\14:\6\221d\20I\310\210\244\20H\12\201\343" + "\214G\16q\4\215F\22a$\21\66\326X\17\20\365\0Q\17\24D\32A\244\221C\36\61\344\21\63" + "\42!$\22B\42\31d\22A&\21\243\242J\0BFVX\201^\340\320\3\242<@\306@I\14" + "V\304h%\14G\302p$\14G\302p$\14G\302pC\214F\304Xe< \312;\17\14\62\22" + "\22\243\225\60\34\11\343\335\317\241V\302HH<@\306\3\203\274\3\0C/X\70\201\335\245\326\3\301" + "<\60\212\12\210\230%\210\211e\26Y&\241d\226I(\375\243\205\22Z(\241\25\65\63\15s\36\20" + "\350\201\260\24\1DIZX\201b\340\330\3\42=@\316H\251\14v\310pf\214W\306\200E\214H" + "\304\210%\14I\302\220$\14I\302\230\367I$I\30\222\204!I\30\261\204\21\211\30\260\210\361\312\30" + "\256\220\301\16\31(\231\7\310y@$\307\0E\33RX\201Z\360\3\354\315\177\357\1\21\36\20\341\1" + "\21\306\233\377{\17| \1F\30RX\201X\360\3\354\315\377\336\3\42< \302\3\42\214\67\377\337" + "\3G;[\70\201a\246\334\3\2=@\214\22\251\34\66\210\251\65K.\261\305\222K\307~\23\233$" + "\20I\2\221$\224H\4\211D\24HFy\204\230F\212*\307<`\320\3d\255\2\0H\23XX" + "\201b\60\244\375\77\371\300\37\30\322\376\177r\0I\11CX\201M\360\37HJ\25\214\312nLD\377" + "\377\377\377\357\220\60\302\11J$b\12\0KXWX\201\134\60\36\11\303\21\61\32\31\203\225\61V!" + "C\225\62R\61\3\225\63NA\343\220\64\14Q\243\220\65\10ac\220\66Di#\230\266\230\11e\225" + "Q\24)D\15S\322\70\5\15T\316H\344\214T\314P\245\214E\312`\204\14V\306hE\14G\304" + "x$\214W\0L\20RX\201X\60\336\374\377\377\277\367\300\7\22Mk`X\201jP*\243l:" + "\351\244\12#\256@\340\10'\220G\302\21\304\221p\4qC\34A\32\21g\20\66\306\31\204\215q\310" + "Xd\34B\324 \207\220D\310)\4\215r\12A\243\34\63\16)\307\20\63\314\61\244\20s\316(\304" + "\234C\310\70\347\220A\316AD\14t\20\11\4\235\64\2A'\335\251\242\216*\352\250\242\316\32\213\0" + "NJYX\201c@$\212(&\250\236z&\20gBiF\220f\6af\224e\10Y\246\20e" + "JI\306\220dLA\346\224c\20\71\6\25cR)F\221bT!f\21b\30\31\206\25a\32\21" + "\306\221`\334z\12f\21\305\2O@^\70\201\344\205\246s\17\214\225DJF\231S\134)\5\26B" + "$\31E\26A(\11\205\222@j\262\370\257\226@(\21\204\22Af\31D\22R`)\305\225c\224" + "I\210\240\365\300hO\246\5\0P'TX\201\134\320\316\3\201< \306\60I\214U\302`\250\335\37" + "#a\254\22\6:\342\1\61^ig\304\371\277\10\0QC\36:s\344\205\246s\17\214\225DJF" + "\231S\134)\5\26B$\31E\26A(\11\205\222@j\262\370\257\226@(\21\204\22Af\31D\22" + "R`)\305\225c\224I\210\240\365\300hO.]e{\2\0RTVX\201\134\320\322\3\301<\60" + "\310\70i\214U\306`E\214F\304hD\214F\304hD\214F\304hD\214F\304`E\214U\306H" + "\206< \312;\16\215S\316@\344\14T\314H\304\14E\312P\205\214E\310Xe\14F\306hD\214" + "V\302p$\14\207\36\1S/U(\201\331\223\324#\17\210\201\4\32E\211Q \211t\261\202\347\241" + "\227\134\366\16\64\260\304\22\351A\22D+\341\20$\36\30\343\201\220\324\1T\17Y\10\201Y\360o\221" + "J\377\377\377O\1U\42YH\201a@\42\376\377\377\42\11#\222@ \11\344\221AZ\31F\225\202" + "\310\71\17\10\345ZB\0VS[\10\201[@&\11D\222@b\11$\222A \31\344\21B\36)" + "\304\221B\32\61\244\221C\30\71d\21D\26I$\225D-\202\310\42\207\60rH#\206\64R\210#" + "\205\360\3\6[\21\12JsO\360\1b\350\377\377" + "\377\237y\340\1\134\60O\30\201Q\60\30Y\204\15F\330`d\21\66\30Y\204\15F\330`d\21\66" + "\30Y\204\15F\26ad\21\66\30Y\204\15F\26ad\21\66\0]\21\12\32sO\360\235\371\377\377" + "\377w\36x`\0^\63W\25\231Y%(\231D\232h\340\20\343\15\61\34\31\243\15\62\30)c\15" + "\63\24\71#\15\64\322t\206\32g\254Q\310\32e\264\61H#b\274\21\310#_\11\325\0sU\360" + "\7\6`\16\311\221\271[P\12)\245\20C\235\1a,T&\201\332\203R\63\257\24SJP$\22" + "H\207Xy\343\1!\14\42\241\250\264\20\303VZ*\231P\14\22M\214\261\306 \250\14b\77\326H" + "\201\134@$\375G\316!b\25\22\32A\305\14\223\212(\213\210\302H \215\4\322H n\4\342\360" + "\271\21H#\201\64\22\12#\241,\42L*b\4R\314\30\242\221\61V\31\345\34\0c$Q\66\201" + "\326\203\16\33N\34BDY\244\21F\32\255\15\67\71\322h\255\64\322J;\204\14W\330A\2\0d" + "\64\325\70\201\334H\377\231S\6Yc\14\27\206\60\205\204\21J\62\201,\265R\303\265\343.\207\32\256" + "%F\2Y%\224d\204)$\214\321\304 k\14s\312\0e&T\66\201\332s\326:\256\30b\10" + "AE\20E\304`\70\366\300\17\234H -\22X\255\60N)\345\31\207\22\1f\32\320\30\201\320t" + "N\62\252\224\22\12Y\204\321)&\224\307\233\71\322H+\254^\243\34" + "\275G\224\20g\34\361@\30\316\240\2\0\300\134\335\12\201\335Sr\311DSz\354\361at\344\202\13" + "\66v\204aG\30\225\4B\211\30t\14\42\311 \222\220\21I!\220\24\2\307\31\217\34\342\10\32\215" + "$\302H\42l\254\261\36 \352\1\242\36(\210\64\202H#\207\60\344\3D\22\66ba#\222\66`i\3\22\67 q\343\221\67\36y\303\21\370" + "@\10\4>P\342\3\1\307<\30;k\335\245\326\3\301<\60\212\12\210\230%\210\211e\26Y&\241" + "d\226I(\375\243\205\22Z(\241\25\65\63\15s\36\20\350\201\260T\24u\242e\32;\352\364\202\60" + "\17A\223\0\310%\322Z\201ZQ\134q\344\221\67\340\364\201\177\340\3\354\315\177\357\1\21\36\20\341\1" + "\21\306\233\377{\17| \1\311$\322Z\201\332T\32\325J\243\332\370\220x\340\3\354\315\177\357\1\21" + "\36\20\341\1\21\306\233\377{\17| \1\312+\322Z\201ZS\230aG\221@\20\31\304\220B\310H" + "\343\203\374\300\7\330\233\377\336\3\42< \302\3\42\214\67\377\367\36\370@\2\313%RZ\201\332\61\312" + "\60\244\320\314(\343C\356\201\17\260\67\377\275\7Dx@\204\7D\30o\376\357=\360\201\4\314\26\311" + "\12\201MP\12\61\224\31g\372 \14\63\377\377\377\177\1\0\315\25\311J\201MRF!\264\62}\60" + "\206\231\377\377\377\277\2\0\316\35\317\372\200\315B\224A\350\220@\12\31d\14C\302@\344\3:\330\374" + "\377\377\377\31\0\317\30M\12\201\315\60\312\10\244\240B\302(\343\203=\324\374\377\377\377\25\0\320X]" + "\30\201a\342\336\3\202=@\324@)\15f\320p\345\214W\314\200\304\214H\312\210\244\214X\310\220\204" + "\14I\310\220\204\14\371@I\17\224\364@I\204\14I\310\220\204\14I\310\220\204\214X\310\210\244\14X" + "\312\200\304\214W\314h\346\14f\320@)=@\324\3\202\65\6\0\321Z\231Z\201\343C\220P\247\214" + "\244\206PC\250\64\312Q\343\220\17Q\42QD\61A\365\324\63\201\70\23J\63\202\64\63\10\63\243," + "C\310\62\205(SJ\62\206$c\12\62\247\34\203\310\61\250\30\223J\61\212\24\243\12\61\213\20\303\310" + "\60\254\10\323\210\60\216\4\343\326S\60\213(\26\322H\336:\201\344Dt\245\311\246\366\370\260\212\246s" + "\17\214\225DJF\231S\134)\5\26B$\31E\26A(\11\205\222@j\262\370\257\226@(\21\204" + "\22Af\31D\22R`)\305\225c\224I\210\240\365\300hO\246\5\0\323F\336:\201dXp\311" + "\64=}\330E\323\271\7\306J\42%\243\314)\256\224\2\13!\222\214\42\213 \224\204BI \65Y" + "\374WK \224\10B\211 \263\14\42\11)\260\224\342\312\61\312$D\320z`\264'\323\2\324O\336" + ":\201dVr\301\307\222@(\31D\222B\340H\343\303 \232\316=\60V\22)\31eNq\245\24" + "X\10\221d\24Y\4\241$\24J\2\251\311\342\277Z\2\241D\20J\4\231e\20IH\201\245\24W" + "\216Q&!\202\326\3\243=\231\26\0\325P\236:\201\344D\220x\247\14\247\306pc\244'\312y\343" + "\220\17\223h:\367\300XI\244d\224\71\305\225R`!D\222Qd\21\204\222P(\11\244&\213\377" + "j\11\204\22A(\21d\226A$!\5\226R\134\71F\231\204\10Z\17\214\366dZ\0\326K^:" + "\201\344\64\314\220\204\20I\10\221\303\214\17\7\321t\356\201\261\222H\311(s\212+\245\300B\210$\243" + "\310\42\10%\241P\22HM\26\377\325\22\10%\202P\42\310,\203HB\12,\245\270r\214\62\11\21" + "\264\36\30\355\311\264\0\327\61\324\64\217\332 \234\10\204\221@\24\31\4\221B\14\71\204\220D\4Y\250" + "\231G\236ih\21A\22!\344\20C\12Ad\20E\2a$\10'\2\0\330e\336\70\177\344\34\36" + "*D\71A\320\3\6%\241\220Q\346\224fJi\210\220F\2\31\245\221P\4id\220P\30!$" + "\20FJb\304\240E\16R\4\241D\22J$!D\24:d\241C\26\62\204\241BX\11d\220F" + "\4\31\244\21A\265\62\220#\344\270RL+\247,s\326@\350\1\203\210pj\224\344\202\6\331+\331" + "J\201aSj\251\304Rv\334\361\241K\42\376\377\377\42\11#\222@ \11\344\221AZ\31F\225\202" + "\310\71\17\10\345ZB\0\332)\331J\201\341V(\241\205\322}(\223\210\377\377\277H\302\210$\20H" + "\2yd\220V\206Q\245 r\316\3B\271\226\20\0\333\61\331J\201aU\246\231'\222@\36\31\244" + "\221B\326@\344C\222D\374\377\377E\22F$\201@\22\310#\203\264\62\214*\5\221s\36\20\312\265" + "\204\0\334.YJ\201\341\63\312h\244\20F\12i\303\210\17s$\342\377\377/\222\60\42\11\4\222@" + "\36\31\244\225aT)\210\234\363\200P\256%\4\0\335>\332\12\201ZWh\251\64;}\250\223X\2" + "\201D\220G\10q\204\24F\14a\304\24E\20Q$\21D\24Ad\21C\30\61\244\21B\34\31\4" + "\22A \11D\42y\250\241\305\322\377[\0\336\62UX\201\134\60\344<\331\320\3\241<\60\306\70I" + "\214e\302`%\214F\302h\310\335\32j$\14V\302XE\214t\304\3c<\20\212;C\316O\2" + "\337R\326H\201]\203\226;\17\204b\214!D\221A\330\30\204\21A\330\30d\221A\26\31$\25B" + "P)\344\24CL\71\304\20D\314H\304\214D\14A\304\224CN\61\4\31B\222\31d\25AX\11" + "\244%\207\336\335\10\12\15b\322p\201\20&\210A\4\0\340\65\324(\201ZR`\201$Rq\310\361" + "!\206R\63\257\24SJP$\22H\207Xy\343\1!\14\42\241\250\264\20\303VZ*\231P\14\22" + "M\214\261\306 \250\14\341\63\324(\201ZV\134y\64\70}\310\241\324\314+\305\224\22\24\211\4\322!" + "V\336x@\10\203H(*-\304\260\225\226J&\24\203D\23c\254\61\10*\3\342;\324(\201Z" + "T\236i\207\221@\24\31\4\221B\314H\343C\7\245f^)\246\224\240H$\220\16\261\362\306\3B" + "\30DBQi!\206\255\264T\62\241\30$\232\30c\215AP\31\343=\224(\201\332B\220(\247\14" + "\242\306 c\244\42\12\42\343\220\17%\224\232y\245\230R\202\42\221@:\304\312\33\17\10a\20\11E" + "\245\205\30\266\322R\311\204b\220hb\214\65\6Ae\0\344\67T(\201\332\62!R\310!\205\240Q" + "\306\207:J\315\274RL)A\221H \35b\345\215\7\204\60\210\204\242\322B\14[i\251dB\61" + "H\64\61\306\32\203\240\62\0\345B\224)\201\332D\34bC\214\65\310P\302\10%\214P\203\214\65\304" + "`\310\221\17\61\224\232y\245\230R\202\42\221@:\304\312\33\17\10a\20\11E\245\205\30\266\322R\311" + "\204b\220hb\214\65\6Ae\0\346Pc&\201g\203\320I\215,\363D\63\304\250RJP\350\24" + "h\22\201E\21X\26\201d\21H\26A\17\60\362\300\3a<\360\200\20\5\221H\24\201E\225GV" + "yd\225G\226qD\35W\20\11d\5QJ\21\207\224\321\310#\353\64c\30\42\0\347\62\21\71k" + "\326\203\16\33N\34BDY\244\21F\32\255\15\67\71\322h\255\64\322J;\204\14W\330AK\270\341" + "\204+\314\70\342&\24\204A(\31\3\0\350/\324\70\201ZR`\201$\222\70\344\364!v\326:\256" + "\30b\10AE\20E\304`\70\366\300\17\234H -\22X\255\60N)\345\31\207\22\1\351.\324\70" + "\201ZF^q\345\321\340\370\220;k\35W\14\61\204\240\42\210\42b\60\34{\340\7N$\220\26\11" + "\254V\30\247\224\362\214C\211\0\352\66\324\70\201ZT\234q\207\221@\24\31\4\221B\314@\344C\347" + "\254u\134\61\304\20\202\212 \212\210\301p\354\201\37\70\221@Z$\260Za\234R\312\63\16%\2\0" + "\353\61T\70\201\332\62!R\310!\205\240Q\306\207\372Y\353\270b\210!\4\25A\24\21\203\341\330\3" + "\77p\42\201\264H`\265\302\70\245\224g\34J\4\0\354\25\311\370\200LPJ)\304\20\63\316\364A" + " \205\376\377\377\0\355\24\311H\201LRF!\264\62} H\241\377\377\277\2\0\356\33\317\350\200L" + "C\224A\310\220@\12\31\224\31\201\240\361\1%\213\376\377\377\12\0\357\24L\10\201L\60\314!\210\34" + "\63>\250\4\321\377\377\37\1\360@\326\70\201\333\23(\61\3\35a\322j\307\241\226\226\21D\221B\222" + "@D\222I\346Hg\220\302\304 \17\214aJ\12E\231@Xr\230;\357\366\220\303\32\21\204\21Q" + "\24!\306\24\363\22c\350\0\361\60\225H\201\334B\220\60\247\214\242\206\60c\244\62\312\61\343\220\17\231" + "Q\216\31c\221!\234H\304\10\223J(\213\204\262H m\4\322\360\377\257\21\362\70\326\70\201\334R" + "$\221E\222I\321\361\241\211\30C\317\230b\12Ie\220U\4a$\20\67\2q\230;\357z\310\341" + "\34\11\204\21AV\31$\225R\212\71.\61\206\16\0\363\66\326\70\201\134V`\211\64\71}\310\42\306" + "\320\63\246\230BR\31d\25A\30\11\304\215@\34\346\316\273\36r\70G\2aD\220U\6I\245\224" + "b\216K\214\241\3\0\364=\326\70\201\334D\242y\250\251E\6Q\304\14D\320\370\320C\214\241gL" + "\61\205\244\62\310*\202\60\22\210\33\201\70\314\235w=\344p\216\4\302\210 \253\14\222J)\305\34\227" + "\30C\7\0\365\77\226\70\201\334R\216\70\307\210\223\306\60c\244#\314\71\342\220\17E\304\30z\306\24" + "SH*\203\254\42\10#\201\270\21\210\303\334y\327C\16\347H \214\10\262\312 \251\224R\314q\211" + "\61t\0\366:V\70\201\334\62\314P\204\20E\10Q\303\214\17;\210\61\364\214)\246\220T\6YE" + "\20F\2q#\20\207\271\363\256\207\34\316\221@\30\21d\225AR)\245\230\343\22c\350\0\367\33V" + "%\215\332D$\221%\226H>\214<\360\3\346\303\10\221%\226H$I\0\370K\326\66\177\334\31\22" + "\32\303<\20\310\3\202\230b\12Ie\220t\4A(\220D\302\10\4\21\201\16\31\310\20r\16!\307" + "\220r\12\61\210\214\203\6\71H\20\204\2I$\234D\304Ae\24T\210)\246<\20\312\3\301\214\201" + "R\230\0\371$\324H\201\134B`\201$\322\342\370\220\31\316\376\277v\65\304\260\245\222\11\246\220\60D" + "\23c\254\61\312)\3\372#\324H\201\334U\36\5\311\243}\350\14g\377_\273\32b\330R\311\4S" + "H\30\242\211\61\326\30\345\224\1\373*\324H\201\134D\236ih\251DF\71\304\220B\20\371\340\17g" + "\377_\273\32b\330R\311\4SH\30\242\211\61\326\30\345\224\1\374(TH\201\134\62\314@\204\20D" + "\10A\303\214\17\331\341\354\377kWC\14[*\231`\12\11C\64\61\306\32\243\234\62\0\375P\227\13" + "k\327V$m\316>$\311#\201\70\22H#\202\64\62\10\33\204,R\210\42\205$bH\42\207 " + "r\250\64\16I\304\14E\12Y\204\220E\310hc\220F\4iD\214\67\2y#\214h\305\62)I" + "&\231cR\222\304\322TK\356@\0\376C\226Kk\134@$\375G\316!b\25\22\32A\305\14\223" + "\212(\213\210\302H \215\4\322H n\4\342\360\271\21H#\201\64\22\12#\241,\42L*b\4" + "R\314 \241\21\42V!\344\34\42\351\77\11\0\377V\27\13kW\63\312X\244\20E\12Y\243\214\17" + "+\344\221@\34\11\244\21A\32\31\204\15B\26)D\221B\22\61$\221C\20\71T\32\207$b\206" + "\42\205,B\310\42d\264\61H#\202\64\42\306\33\201\274\21F\264b\231\224$\223\314\61)Ibi" + "\252%w \0\0\0\0\4\377\377\0"; diff --git a/src/fonts/OpenSans-Regular_6.h b/src/fonts/OpenSans-Regular_6.h new file mode 100644 index 00000000..c48d0a91 --- /dev/null +++ b/src/fonts/OpenSans-Regular_6.h @@ -0,0 +1,59 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--8-60-100-100-P-43-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_6[1643] U8G2_FONT_SECTION("OpenSans_Regular_6") = + "\277\0\2\2\3\4\3\4\4\7\11\0\376\6\376\6\377\0\376\2\27\6N \5\0\242\2!\6\251\246" + "\262\2\42\5\222\362\66#\10\253f\267\324X\0$\11\263b\227L\65\22\0%\13\66\342\27S\227N" + "\63\251(&\12\65\242\247S\324\62\252\21'\5\11\266\22(\7:\236\226T\63)\7:\236\22S\17" + "*\10\34*\233FR\0+\10\243f\27\323J\0,\5\11\242\22-\5\211\352\22.\5\211\242\22/" + "\11\63\342Z\305\24#\0\60\10\64b\247\242\63\15\61\6\262b\267:\62\11\64b\247Q\216\345\10\63" + "\11\64b\247Q\216z\10\64\11\64b\37U\222C\7\65\10\263b\63\242\216#\66\11\64b\253bJ" + "f\32\67\11\64b\63r\231c\4\70\12\64b\247b\252FL\3\71\12\64b\247\242L;)\0:" + "\5\211\256\22;\5\11\256\22<\7\243f\273\262\0=\7\24j\63\322\0>\10$f\243Q\36\21\77" + "\11\63\342\62\253\14\23\0@\15\77\336\273\253\264T\245\206\312\324\4A\12\65b\233QNqe\35B" + "\12\264b\263\242J\346H\0C\13\65b\273rF\31f\64\2D\11\264\242\263\242s$\0E\10\263" + "\42\63bTqF\11\263\42\63b\34\61\2G\13\65\242\273rFQ\305\64\2H\10\264\242/\345\230" + "\62I\6\251\246\62\4J\5\61\236rK\11\264b\257\222\224\251\14L\7\253&\23\233\3M\12\265\342" + "\223\365\32i%UN\11\264\242\223\343Rg\0O\14\66\242;\263F\32\325i$\0P\11\263b\63" + "\222Z\61\2Q\15>\236;\263F\32\325id\230\0R\12\264b\263\242J\62\225\1S\12\64\42\67" + "\62\312H\17\1T\10\64\42\63b\356\2U\7\264\242/\235CV\13\65b\223e\25S\324(\2W" + "\15\67\342\23s\254T\245*\63'\0X\12\64b\223Q\231c\222\1Y\11\64\42\223Q\245[\0Z" + "\11\64b\63r\254\343\10[\6\271\336r\4\134\10\63\342\22s\254\3]\7:\336\242\372\0^\7\34" + ".'\223\14_\5\13\36\63`\5\11w\23a\7$\42w\304\64b\11\263b\23U\262F\0c\7" + "#\42\67\263\0d\11\64b\37U\222\62\15e\10$\42\67\206F\3f\7\262\342\262\272\0g\12\64" + "\32\63d\222#\16\1h\10\263b\23Ur\5i\6\241\252\62\2j\5\61\242rk\11\263\42\23\323" + "\212\252\0l\5\261\242rm\12\246\342s\244\250\242\212\1n\7\243b\63\222\25o\10$b\67\242L" + "\3p\10\253Z\63\222\32\22q\10,Z\67\242L;r\6\241\342\62\2s\7#\42\263\362\10t\7" + "\252\342\222Z\2u\7\243b\223\254\21v\10$\42\23\223\264\0w\11&\242\23\223U\266\0x\10$" + "\42WI\25\3y\12\64\32\23S\245c\224\0z\7#\42'S\32{\11;\336\232b\222-\0|" + "\6\71\33s\4}\11;\336\222cT\261\2~\6\14j\63\2\240\5\0\242\2\241\5\231\246\62\242\10" + "\263bW\311:\1\243\11\64b\253r\226q\4\244\7\243fW\251\21\245\12\64b\223Q%\327L\0" + "\246\6\71\33\243\5\247\11\64\42'+U\16\5\250\5\211v\23\251\15\66\342;SRQE\245\322H" + "\0\252\6\32\356\242\6\253\10\34\42\227TT\0\254\5\213f\63\255\5\211\352\22\256\13\66\342{\251\264" + "\254\244F\2\257\6\14:\63\2\260\7\33\356\266*\0\261\10,b\233\343L#\262\7#\352\242S\32" + "\263\7#\352\42\345\2\264\5\11w\23\265\10\253Z\223\254!\1\266\10\64^\67\16\65\15\267\5\200\252" + "\2\270\6\22\232\222\4\271\6\241\352\62\2\272\7\33\356V\215\0\273\10\34\42\223bJ\12\274\14\265\242" + "\23SL\245\212C#\0\275\13\265\242\23S\231\242\231b\2\276\14\66\242\243\241\312R\315\221r\0\277" + "\7#\342Vf\1\300\14=b\233QF\71\305\225u\0\301\14=b\233QF\71\305\225u\0\302\13" + "=b\267\63\312)\256\254\3\303\13=b\267\63\312)\256\254\3\304\12=b_\243\234\342\312:\305\13" + "=b\267\63\312)\256\254\3\306\14\67\342\77\242F\65\32\62\345<\307\15EZ\273rF\31f\64b" + "F\12\310\11\273\42\227F\214*\16\311\11\273\42\227F\214*\16\312\11\273\42\243F\214*\16\313\11\273" + "\42\23G\214*\16\314\6\251\252\62\4\315\7\271\242\222\206\0\316\7:\242\242S\7\317\7:\242\222Q" + "\17\320\11\264\242\263\242s$\0\321\11\274\242\247r\134\352\14\322\15>\242\233\341\314\32iT\247\221\0" + "\323\15>\242\237\321\314\32iT\247\221\0\324\15>\242\253\321\314\32iT\247\221\0\325\15>\242\253\321" + "\314\32iT\247\221\0\326\15>\242\233\341\314\32iT\247\221\0\327\7\233j\243t\0\330\15\66\242\253" + "c\212I\305\224\323H\0\331\10\274\242\227\241\347\20\332\10\274\242\227\241\347\20\333\11\274\242\247\221t\16" + "\1\334\11\274\242\233\221t\16\1\335\11<\42\233\62\252t\13\336\10\253f\63\222\32\22\337\12\264b\263" + "*\231\312\221\0\340\12\64\42\227QLi\304\64\341\12\64\42\233cJ#\246\1\342\12\64\42\247cJ" + "#\246\1\343\11\64\42\67\253\64b\32\344\12\64\42\227QLi\304\64\345\12\64&\247cJ#\246\1" + "\346\11&\342\67\324\230Y\11\347\7\63\32\67s%\350\11\64\42\233c\32\33\15\351\11\64\42\233c\32" + "\33\15\352\11\64\42\233c\32\33\15\353\12\64\42\227QLc\243\1\354\7\61\242\222F\0\355\7\261\242" + "\222F\0\356\7\62\242\242S\3\357\7\62\242\242S\3\360\11\64b\253\252\21e\32\361\10\263b\263*" + "W\0\362\11\64b\233c\222\62\15\363\11\64b\233c\222\62\15\364\11\64b\247c\222\62\15\365\11\64" + "b\67+)\323\0\366\11\64bWVR\246\1\367\10\243f\227\321J\0\370\11,b[\251\221\322\0" + "\371\11\263b\227Q\262F\0\372\11\263b\227Q\262F\0\373\11\263b\243Q\262F\0\374\11\263b\223" + "r\262F\0\375\13D\32\233aU\351\30%\0\376\11\273Z\23U\262\206\4\377\13D\32\247aU\351" + "\30%\0\0\0\0\4\377\377\0"; diff --git a/src/fonts/OpenSans-Regular_7.h b/src/fonts/OpenSans-Regular_7.h new file mode 100644 index 00000000..35b5b4e3 --- /dev/null +++ b/src/fonts/OpenSans-Regular_7.h @@ -0,0 +1,70 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--10-70-100-100-P-52-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_7[2012] U8G2_FONT_SECTION("OpenSans_Regular_7") = + "\277\0\2\2\4\4\3\4\5\12\14\377\376\7\376\7\376\1\71\2\230\7\277 \5\0\304\11!\7q\305" + "\311P\1\42\6\62e\312\1#\16vDk\312)\16\231\322Xu\212\0$\14\224=[\34S\313T" + "\215\30\1%\16wE\214\254\312\244\325N\315T*\0&\14v\305\233\216m\235\242\65R\0'\6\61" + "e\311\0(\10\222\264Y\245\312T)\12\222\265I*SR\25\0*\11D][\34)\246\4+\11" + "DM[\216#E\0,\6\42<\231\2-\6\23\324\311\0.\6\21\305I\0/\10sDj+V" + "\21\60\13uD\333\214\332N\61-\0\61\7rE\333\352\1\62\12uD\333\206\31\345\366\20\63\14u" + "D\333\206\31E\15\63\32\12\64\15vD{Fu\212UNc\243\4\65\13tE\313\320y\243<\22" + "\0\66\12tE\333\310yH\231\6\67\15uD\313\320(g\224\63\312(\2\70\13tE\313\212\62\251" + "(\207\0\71\13tE\313\212r\350<\22\0:\6Q\305I\16;\10b\274Y\246\24\0<\11TM" + "{R\31i\24=\10\64U\313\310h\4>\12TMKF\32%\225\1\77\12tD\312\310eME" + "\0@\17\207\275\334P\31\252\245\252\231\254M\215\10A\15vD{F\32\225\345\210Y\243\0B\14u" + "E\313HY\17\225\365P\0C\15uE\333\320(\243\214\62\312p\4D\16v\305\313\210\71e\244\221" + "F:\215\10E\12tE\313\320y\350<\2F\11t\305\312\320y\350\32G\16v\305\333H\31f\30" + "GF\32\245!H\12u\305K\266\307\310v\0I\6q\305\311\21J\10\223\263i\77\27\0K\13u" + "EK\226\251\324)V\71L\10t\305J\356=\2M\16w\305L\206{\344U\251JU\262\0N\14" + "vELF[E\25e\322[O\17vE\334H\31i\244\221F\32\245\221\0P\15uE\313H\61" + "e\231fF\31\1Q\21\226\65\334H\31i\244\221F\32\245\221a\206\11R\14uE\313HY\246Y" + "\305\224\3S\13t\305\312\320\31i\224G\2T\16uD\313\220\31e\224QF\31E\0U\11u\305" + "K\366\235\26\0V\14vDKF:vk\244\221\4W\17y\304L\316fj\246\316\24u\326%\0" + "X\14uDKN\61\352\214d\324\1Y\15uDKN\61\325:\243\214\42\0Z\13uD\333\310(" + "\327(\347![\7\222\265\311\352K\134\10sDJ\216u,]\7\222\264\211\352k^\11E\334jN" + "\61\325\1_\6\25\64\312\20`\6\42vK\14a\12UD\333\206i\350\64\2b\15uEKF\31" + "\215\224\315\64\22\0c\10S\305\312\210\345\0d\11tE{\36\323\34\2e\11TE\313\212c\217\0" + "f\11t\304\331\212\63\67\1g\14u\264\332H\61\315\214\206N#h\11tEK\316C:\3i\7" + "q\305I\32\2j\11\223\263i\206=\27\0k\12t\305J.U\222\251\14l\6q\305\311\21m\13" + "W\305\314!\243\214\62\312\2n\10TE\313\220\316\0o\10TE\313\220\346\20p\16u\65\313H\61" + "e\231F\312(#\0q\11t\65\313\220\346\320\5r\10SE\312\210M\0s\10S\305\312\310r\4" + "t\10cDZZ\261\24u\10TEKt\16\1v\13U\304JNe\212)G\0w\13XDL" + "tEU:#\0x\11T\305JT\261*\3y\15u\264JNe\212)g\24\65\0z\10T\304" + "\332\216\345\10{\12\223\64j\212U\216u\0|\6\221\66\313\3}\12\223\64\212l\247X)\0~\6" + "\24]\313\10\240\5\0\304\11\241\7q\265I\32\2\242\12tEk\34\271F\63\1\243\14uD\353\312" + "(\217\230Q\36\2\244\10DM\313\220r\10\245\14uDKN\61\312\21\363\210\21\246\6\221\66\313\36" + "\247\12s\305\312\210#\215\70\2\250\6\22v\213\0\251\20xD\354\310\31\225VFR\246\214\362\210\0" + "\252\7C\134\232LC\253\7C\315\332RI\254\7\64M\313\310\5\255\6\23\324\311\0\256\17xD\354" + "\310\31\225K\232\251\215\362\210\0\257\6\25\374\312\20\260\7\63e\212J\13\261\12dE[\216#e<" + "\2\262\7C\334\311Li\263\7C\334\311\222#\264\6\42v\233\2\265\11t\65Kt\216\235\1\266\10" + "\224\275\313\37\322\3\267\6\21\335I\0\270\6\42\64\331\0\271\6A\335\311\10\272\7C\134\332RI\273" + "\11D\314J\212\251R\11\274\15vEL\216\255\254\244\252FF\1\275\15vELN\261k\244\234b" + "\212\3\276\20xD\314\216\62\243z\325(\351\64bN\0\277\12t\64j\246b\235\321\0\300\17\246D" + "k\206\231\235\221Fe\71b\326(\301\17\246D{\206\231\231\221Fe\71b\326(\302\20\246D\253F" + "\65+#\215\312r\304\254Q\0\303\20\246Dk\212I\263\62\322\250,G\314\32\5\304\17\226Dk\312" + "\254\214\64*\313\21\263F\1\305\17\226D\253F\32f\244QY\216\230\65\12\306\20x\304\374\320\32\246" + "\14\323H#\243\230\363\10\307\16\225\65\333\320(\243\214\62\312p\344\22\310\14\244E[\316x\350 OpenSans-Regular_$i.bdf +u8g2/tools/font/bdfconv/bdfconv -f 1 -n OpenSans_Regular_$i -o OpenSans-Regular_$i.h OpenSans-Regular_$i.bdf +done +``` diff --git a/src/fonts/fonts.h b/src/fonts/fonts.h index 9369b56f..98e01fdf 100644 --- a/src/fonts/fonts.h +++ b/src/fonts/fonts.h @@ -1,35 +1,12 @@ -/* - * Copyright (C) 2019-2021 OpenBikeSensor Contributors - * Contact: https://openbikesensor.org - * - * This file is part of the OpenBikeSensor firmware. - * - * The OpenBikeSensor firmware is free software: you can - * redistribute it and/or modify it under the terms of the GNU - * Lesser General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * OpenBikeSensor firmware 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 Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the OpenBikeSensor firmware. If not, - * see . - */ +#ifndef FONTS_H_ +#define FONTS_H_ -#ifndef OPENBIKESENSORFIRMWARE_FONTS_H -#define OPENBIKESENSORFIRMWARE_FONTS_H +#include -#include "opensans8.h" -#include "opensans10.h" -#include "opensans20.h" -#include "opensans34.h" -#include "opensans50.h" +#include "OpenSans-Regular_6.h" +#include "OpenSans-Regular_7.h" +#include "OpenSans-Regular_14.h" +#include "OpenSans-Regular_24.h" +#include "OpenSans-Regular_33.h" -#include "logos.h" - -#endif //OPENBIKESENSORFIRMWARE_FONTS_H +#endif // FONTS_H_ diff --git a/src/fonts/opensans10.h b/src/fonts/opensans10.h deleted file mode 100644 index 820e5f34..00000000 --- a/src/fonts/opensans10.h +++ /dev/null @@ -1,459 +0,0 @@ -// Font table version: 3 -// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator. -// In case of problems make sure that you are using the font file with the correct version! -const uint8_t Open_Sans_Regular_Plain_10[] PROGMEM = { - 0x09, // Width: 9 - 0x0E, // Height: 14 - 0x20, // First Char: 32 - 0xE0, // Numbers of Chars: 224 - - // Jump Table: - 0xFF, 0xFF, 0x00, 0x03, // 32= :65535 - 0x00, 0x00, 0x04, 0x03, // 33=!:0 - 0x00, 0x04, 0x05, 0x04, // 34=":4 - 0x00, 0x09, 0x0B, 0x06, // 35=#:9 - 0x00, 0x14, 0x0A, 0x06, // 36=$:20 - 0x00, 0x1E, 0x0F, 0x08, // 37=%:30 - 0x00, 0x2D, 0x0C, 0x07, // 38=&:45 - 0x00, 0x39, 0x03, 0x02, // 39=':57 - 0x00, 0x3C, 0x04, 0x03, // 40=(:60 - 0x00, 0x40, 0x05, 0x03, // 41=):64 - 0x00, 0x45, 0x09, 0x06, // 42=*:69 - 0x00, 0x4E, 0x09, 0x06, // 43=+:78 - 0x00, 0x57, 0x02, 0x02, // 44=,:87 - 0x00, 0x59, 0x05, 0x03, // 45=-:89 - 0x00, 0x5E, 0x04, 0x03, // 46=.:94 - 0x00, 0x62, 0x07, 0x04, // 47=/:98 - 0x00, 0x69, 0x0A, 0x06, // 48=0:105 - 0x00, 0x73, 0x08, 0x06, // 49=1:115 - 0x00, 0x7B, 0x0A, 0x06, // 50=2:123 - 0x00, 0x85, 0x0A, 0x06, // 51=3:133 - 0x00, 0x8F, 0x0B, 0x06, // 52=4:143 - 0x00, 0x9A, 0x0A, 0x06, // 53=5:154 - 0x00, 0xA4, 0x0A, 0x06, // 54=6:164 - 0x00, 0xAE, 0x09, 0x06, // 55=7:174 - 0x00, 0xB7, 0x0A, 0x06, // 56=8:183 - 0x00, 0xC1, 0x09, 0x06, // 57=9:193 - 0x00, 0xCA, 0x04, 0x03, // 58=::202 - 0x00, 0xCE, 0x04, 0x03, // 59=;:206 - 0x00, 0xD2, 0x09, 0x06, // 60=<:210 - 0x00, 0xDB, 0x09, 0x06, // 61==:219 - 0x00, 0xE4, 0x09, 0x06, // 62=>:228 - 0x00, 0xED, 0x07, 0x04, // 63=?:237 - 0x00, 0xF4, 0x0F, 0x09, // 64=@:244 - 0x01, 0x03, 0x0C, 0x06, // 65=A:259 - 0x01, 0x0F, 0x0A, 0x06, // 66=B:271 - 0x01, 0x19, 0x0B, 0x06, // 67=C:281 - 0x01, 0x24, 0x0B, 0x07, // 68=D:292 - 0x01, 0x2F, 0x0A, 0x06, // 69=E:303 - 0x01, 0x39, 0x09, 0x05, // 70=F:313 - 0x01, 0x42, 0x0C, 0x07, // 71=G:322 - 0x01, 0x4E, 0x0C, 0x07, // 72=H:334 - 0x01, 0x5A, 0x04, 0x03, // 73=I:346 - 0x01, 0x5E, 0x04, 0x03, // 74=J:350 - 0x01, 0x62, 0x0C, 0x06, // 75=K:354 - 0x01, 0x6E, 0x0A, 0x05, // 76=L:366 - 0x01, 0x78, 0x10, 0x09, // 77=M:376 - 0x01, 0x88, 0x0E, 0x08, // 78=N:392 - 0x01, 0x96, 0x0D, 0x08, // 79=O:406 - 0x01, 0xA3, 0x09, 0x06, // 80=P:419 - 0x01, 0xAC, 0x0E, 0x08, // 81=Q:428 - 0x01, 0xBA, 0x0C, 0x06, // 82=R:442 - 0x01, 0xC6, 0x09, 0x05, // 83=S:454 - 0x01, 0xCF, 0x0B, 0x06, // 84=T:463 - 0x01, 0xDA, 0x0B, 0x07, // 85=U:474 - 0x01, 0xE5, 0x0B, 0x06, // 86=V:485 - 0x01, 0xF0, 0x11, 0x09, // 87=W:496 - 0x02, 0x01, 0x0C, 0x06, // 88=X:513 - 0x02, 0x0D, 0x0B, 0x06, // 89=Y:525 - 0x02, 0x18, 0x0C, 0x06, // 90=Z:536 - 0x02, 0x24, 0x06, 0x03, // 91=[:548 - 0x02, 0x2A, 0x08, 0x04, // 92=\:554 - 0x02, 0x32, 0x04, 0x03, // 93=]:562 - 0x02, 0x36, 0x09, 0x05, // 94=^:566 - 0x02, 0x3F, 0x08, 0x04, // 95=_:575 - 0x02, 0x47, 0x07, 0x06, // 96=`:583 - 0x02, 0x4E, 0x0A, 0x06, // 97=a:590 - 0x02, 0x58, 0x0A, 0x06, // 98=b:600 - 0x02, 0x62, 0x0A, 0x05, // 99=c:610 - 0x02, 0x6C, 0x0A, 0x06, // 100=d:620 - 0x02, 0x76, 0x0A, 0x06, // 101=e:630 - 0x02, 0x80, 0x05, 0x03, // 102=f:640 - 0x02, 0x85, 0x0A, 0x05, // 103=g:645 - 0x02, 0x8F, 0x0A, 0x06, // 104=h:655 - 0x02, 0x99, 0x04, 0x03, // 105=i:665 - 0x02, 0x9D, 0x04, 0x03, // 106=j:669 - 0x02, 0xA1, 0x0A, 0x05, // 107=k:673 - 0x02, 0xAB, 0x04, 0x03, // 108=l:683 - 0x02, 0xAF, 0x10, 0x09, // 109=m:687 - 0x02, 0xBF, 0x0A, 0x06, // 110=n:703 - 0x02, 0xC9, 0x0A, 0x06, // 111=o:713 - 0x02, 0xD3, 0x0A, 0x06, // 112=p:723 - 0x02, 0xDD, 0x0A, 0x06, // 113=q:733 - 0x02, 0xE7, 0x07, 0x04, // 114=r:743 - 0x02, 0xEE, 0x09, 0x05, // 115=s:750 - 0x02, 0xF7, 0x08, 0x04, // 116=t:759 - 0x02, 0xFF, 0x0A, 0x06, // 117=u:767 - 0x03, 0x09, 0x09, 0x05, // 118=v:777 - 0x03, 0x12, 0x0F, 0x08, // 119=w:786 - 0x03, 0x21, 0x0A, 0x05, // 120=x:801 - 0x03, 0x2B, 0x09, 0x05, // 121=y:811 - 0x03, 0x34, 0x0A, 0x05, // 122=z:820 - 0x03, 0x3E, 0x08, 0x04, // 123={:830 - 0x03, 0x46, 0x06, 0x06, // 124=|:838 - 0x03, 0x4C, 0x07, 0x04, // 125=}:844 - 0x03, 0x53, 0x09, 0x06, // 126=~:851 - 0x03, 0x5C, 0x0A, 0x06, // 127=:860 - 0x03, 0x66, 0x0A, 0x06, // 128=€:870 - 0x03, 0x70, 0x0A, 0x06, // 129=:880 - 0x03, 0x7A, 0x0A, 0x06, // 130=‚:890 - 0x03, 0x84, 0x0A, 0x06, // 131=ƒ:900 - 0x03, 0x8E, 0x0A, 0x06, // 132=„:910 - 0x03, 0x98, 0x0A, 0x06, // 133=…:920 - 0x03, 0xA2, 0x0A, 0x06, // 134=†:930 - 0x03, 0xAC, 0x0A, 0x06, // 135=‡:940 - 0x03, 0xB6, 0x0A, 0x06, // 136=ˆ:950 - 0x03, 0xC0, 0x0A, 0x06, // 137=‰:960 - 0x03, 0xCA, 0x0A, 0x06, // 138=Š:970 - 0x03, 0xD4, 0x0A, 0x06, // 139=‹:980 - 0x03, 0xDE, 0x0A, 0x06, // 140=Œ:990 - 0x03, 0xE8, 0x0A, 0x06, // 141=:1000 - 0x03, 0xF2, 0x0A, 0x06, // 142=Ž:1010 - 0x03, 0xFC, 0x0A, 0x06, // 143=:1020 - 0x04, 0x06, 0x0A, 0x06, // 144=:1030 - 0x04, 0x10, 0x0A, 0x06, // 145=‘:1040 - 0x04, 0x1A, 0x0A, 0x06, // 146=’:1050 - 0x04, 0x24, 0x0A, 0x06, // 147=“:1060 - 0x04, 0x2E, 0x0A, 0x06, // 148=”:1070 - 0x04, 0x38, 0x0A, 0x06, // 149=•:1080 - 0x04, 0x42, 0x0A, 0x06, // 150=–:1090 - 0x04, 0x4C, 0x0A, 0x06, // 151=—:1100 - 0x04, 0x56, 0x0A, 0x06, // 152=˜:1110 - 0x04, 0x60, 0x0A, 0x06, // 153=™:1120 - 0x04, 0x6A, 0x0A, 0x06, // 154=š:1130 - 0x04, 0x74, 0x0A, 0x06, // 155=›:1140 - 0x04, 0x7E, 0x0A, 0x06, // 156=œ:1150 - 0x04, 0x88, 0x0A, 0x06, // 157=:1160 - 0x04, 0x92, 0x0A, 0x06, // 158=ž:1170 - 0x04, 0x9C, 0x0A, 0x06, // 159=Ÿ:1180 - 0xFF, 0xFF, 0x00, 0x03, // 160= :65535 - 0x04, 0xA6, 0x04, 0x03, // 161=¡:1190 - 0x04, 0xAA, 0x09, 0x06, // 162=¢:1194 - 0x04, 0xB3, 0x0C, 0x06, // 163=£:1203 - 0x04, 0xBF, 0x0C, 0x06, // 8364=€:1215 - 0x04, 0xCB, 0x0B, 0x06, // 165=¥:1227 - 0x04, 0xD6, 0x09, 0x05, // 352=Š:1238 - 0x04, 0xDF, 0x08, 0x05, // 167=§:1247 - 0x04, 0xE7, 0x09, 0x05, // 353=š:1255 - 0x04, 0xF0, 0x0F, 0x08, // 169=©:1264 - 0x04, 0xFF, 0x05, 0x04, // 170=ª:1279 - 0x05, 0x04, 0x09, 0x05, // 171=«:1284 - 0x05, 0x0D, 0x09, 0x06, // 172=¬:1293 - 0x05, 0x16, 0x05, 0x03, // 173=­:1302 - 0x05, 0x1B, 0x0F, 0x08, // 174=®:1307 - 0x05, 0x2A, 0x09, 0x05, // 175=¯:1322 - 0x05, 0x33, 0x05, 0x04, // 176=°:1331 - 0x05, 0x38, 0x0A, 0x06, // 177=±:1336 - 0x05, 0x42, 0x05, 0x03, // 178=²:1346 - 0x05, 0x47, 0x05, 0x03, // 179=³:1351 - 0x05, 0x4C, 0x0C, 0x06, // 381=Ž:1356 - 0x05, 0x58, 0x0A, 0x06, // 181=µ:1368 - 0x05, 0x62, 0x0C, 0x07, // 182=¶:1378 - 0x05, 0x6E, 0x03, 0x03, // 183=·:1390 - 0x05, 0x71, 0x0A, 0x05, // 382=ž:1393 - 0x05, 0x7B, 0x03, 0x03, // 185=¹:1403 - 0x05, 0x7E, 0x07, 0x04, // 186=º:1406 - 0x05, 0x85, 0x07, 0x05, // 187=»:1413 - 0x05, 0x8C, 0x10, 0x09, // 338=Œ:1420 - 0x05, 0x9C, 0x11, 0x09, // 339=œ:1436 - 0x05, 0xAD, 0x0B, 0x06, // 376=Ÿ:1453 - 0x05, 0xB8, 0x08, 0x04, // 191=¿:1464 - 0x05, 0xC0, 0x0C, 0x06, // 192=À:1472 - 0x05, 0xCC, 0x0C, 0x06, // 193=Á:1484 - 0x05, 0xD8, 0x0C, 0x06, // 194=Â:1496 - 0x05, 0xE4, 0x0C, 0x06, // 195=Ã:1508 - 0x05, 0xF0, 0x0C, 0x06, // 196=Ä:1520 - 0x05, 0xFC, 0x0C, 0x06, // 197=Å:1532 - 0x06, 0x08, 0x10, 0x09, // 198=Æ:1544 - 0x06, 0x18, 0x0B, 0x06, // 199=Ç:1560 - 0x06, 0x23, 0x0A, 0x06, // 200=È:1571 - 0x06, 0x2D, 0x0A, 0x06, // 201=É:1581 - 0x06, 0x37, 0x0A, 0x06, // 202=Ê:1591 - 0x06, 0x41, 0x0A, 0x06, // 203=Ë:1601 - 0x06, 0x4B, 0x04, 0x03, // 204=Ì:1611 - 0x06, 0x4F, 0x04, 0x03, // 205=Í:1615 - 0x06, 0x53, 0x04, 0x03, // 206=Î:1619 - 0x06, 0x57, 0x05, 0x03, // 207=Ï:1623 - 0x06, 0x5C, 0x0B, 0x07, // 208=Ð:1628 - 0x06, 0x67, 0x0E, 0x08, // 209=Ñ:1639 - 0x06, 0x75, 0x0D, 0x08, // 210=Ò:1653 - 0x06, 0x82, 0x0D, 0x08, // 211=Ó:1666 - 0x06, 0x8F, 0x0D, 0x08, // 212=Ô:1679 - 0x06, 0x9C, 0x0D, 0x08, // 213=Õ:1692 - 0x06, 0xA9, 0x0D, 0x08, // 214=Ö:1705 - 0x06, 0xB6, 0x09, 0x06, // 215=×:1718 - 0x06, 0xBF, 0x0D, 0x08, // 216=Ø:1727 - 0x06, 0xCC, 0x0B, 0x07, // 217=Ù:1740 - 0x06, 0xD7, 0x0B, 0x07, // 218=Ú:1751 - 0x06, 0xE2, 0x0B, 0x07, // 219=Û:1762 - 0x06, 0xED, 0x0B, 0x07, // 220=Ü:1773 - 0x06, 0xF8, 0x0B, 0x06, // 221=Ý:1784 - 0x07, 0x03, 0x09, 0x06, // 222=Þ:1795 - 0x07, 0x0C, 0x0B, 0x06, // 223=ß:1804 - 0x07, 0x17, 0x0A, 0x06, // 224=à:1815 - 0x07, 0x21, 0x0A, 0x06, // 225=á:1825 - 0x07, 0x2B, 0x0A, 0x06, // 226=â:1835 - 0x07, 0x35, 0x0A, 0x06, // 227=ã:1845 - 0x07, 0x3F, 0x0A, 0x06, // 228=ä:1855 - 0x07, 0x49, 0x0A, 0x06, // 229=å:1865 - 0x07, 0x53, 0x10, 0x09, // 230=æ:1875 - 0x07, 0x63, 0x0A, 0x05, // 231=ç:1891 - 0x07, 0x6D, 0x0A, 0x06, // 232=è:1901 - 0x07, 0x77, 0x0A, 0x06, // 233=é:1911 - 0x07, 0x81, 0x0A, 0x06, // 234=ê:1921 - 0x07, 0x8B, 0x0A, 0x06, // 235=ë:1931 - 0x07, 0x95, 0x04, 0x03, // 236=ì:1941 - 0x07, 0x99, 0x05, 0x03, // 237=í:1945 - 0x07, 0x9E, 0x04, 0x03, // 238=î:1950 - 0x07, 0xA2, 0x04, 0x03, // 239=ï:1954 - 0x07, 0xA6, 0x0B, 0x06, // 240=ð:1958 - 0x07, 0xB1, 0x0A, 0x06, // 241=ñ:1969 - 0x07, 0xBB, 0x0A, 0x06, // 242=ò:1979 - 0x07, 0xC5, 0x0A, 0x06, // 243=ó:1989 - 0x07, 0xCF, 0x0A, 0x06, // 244=ô:1999 - 0x07, 0xD9, 0x0A, 0x06, // 245=õ:2009 - 0x07, 0xE3, 0x0A, 0x06, // 246=ö:2019 - 0x07, 0xED, 0x09, 0x06, // 247=÷:2029 - 0x07, 0xF6, 0x0A, 0x06, // 248=ø:2038 - 0x08, 0x00, 0x0A, 0x06, // 249=ù:2048 - 0x08, 0x0A, 0x0A, 0x06, // 250=ú:2058 - 0x08, 0x14, 0x0A, 0x06, // 251=û:2068 - 0x08, 0x1E, 0x0A, 0x06, // 252=ü:2078 - 0x08, 0x28, 0x09, 0x05, // 253=ý:2088 - 0x08, 0x31, 0x0A, 0x06, // 254=þ:2097 - 0x08, 0x3B, 0x09, 0x05, // 255=ÿ:2107 - - // Font Data: - 0x00,0x00,0x7C,0x01, // 33 - 0x00,0x00,0x1C,0x00,0x1C, // 34 - 0x40,0x00,0xF0,0x01,0x5C,0x00,0xF0,0x01,0x5C,0x00,0x10, // 35 - 0x00,0x00,0x1C,0x01,0xFE,0x03,0x24,0x01,0xC4,0x01, // 36 - 0x18,0x00,0x24,0x00,0xBC,0x01,0x40,0x00,0x30,0x00,0xEC,0x01,0x20,0x01,0xC0, // 37 - 0x00,0x00,0xD8,0x01,0x24,0x01,0x54,0x01,0x88,0x01,0xC0,0x01, // 38 - 0x00,0x00,0x1C, // 39 - 0xE0,0x00,0x1C,0x07, // 40 - 0x00,0x00,0x1C,0x07,0xE0, // 41 - 0x00,0x00,0x28,0x00,0x1C,0x00,0x10,0x00,0x28, // 42 - 0x00,0x00,0x20,0x00,0xF8,0x00,0x20,0x00,0x20, // 43 - 0x00,0x03, // 44 - 0x40,0x00,0x40,0x00,0x40, // 45 - 0x00,0x00,0x00,0x01, // 46 - 0x00,0x01,0xE0,0x00,0x18,0x00,0x04, // 47 - 0x00,0x00,0xFC,0x00,0x04,0x01,0x04,0x01,0xF8,0x01, // 48 - 0x00,0x00,0x08,0x00,0x04,0x00,0xFC,0x01, // 49 - 0x00,0x00,0x84,0x01,0x44,0x01,0x44,0x01,0x3C,0x01, // 50 - 0x00,0x00,0x04,0x01,0x24,0x01,0x24,0x01,0xDC,0x01, // 51 - 0x80,0x00,0xE0,0x00,0x90,0x00,0x8C,0x00,0xFC,0x01,0x80, // 52 - 0x00,0x00,0x3C,0x01,0x24,0x01,0x24,0x01,0xE4,0x01, // 53 - 0x00,0x00,0xF8,0x00,0x24,0x01,0x24,0x01,0xE4,0x01, // 54 - 0x04,0x00,0x04,0x00,0x84,0x01,0x64,0x00,0x1C, // 55 - 0x00,0x00,0xDC,0x01,0x24,0x01,0x24,0x01,0xDC,0x01, // 56 - 0x00,0x00,0x3C,0x01,0x24,0x01,0x24,0x01,0xF8, // 57 - 0x00,0x00,0x10,0x01, // 58 - 0x00,0x02,0x10,0x01, // 59 - 0x00,0x00,0x20,0x00,0x50,0x00,0x50,0x00,0x88, // 60 - 0x00,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x50, // 61 - 0x00,0x00,0x88,0x00,0x50,0x00,0x50,0x00,0x20, // 62 - 0x04,0x00,0x44,0x01,0x24,0x00,0x18, // 63 - 0x00,0x00,0xF8,0x01,0x44,0x02,0xB4,0x02,0x94,0x02,0x74,0x02,0x84,0x00,0xF8, // 64 - 0x00,0x01,0xE0,0x00,0x5C,0x00,0x5C,0x00,0xE0,0x00,0x00,0x01, // 65 - 0x00,0x00,0xFC,0x01,0x24,0x01,0x24,0x01,0xDC,0x01, // 66 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x04,0x01,0x04, // 67 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0xF8, // 68 - 0x00,0x00,0xFC,0x01,0x24,0x01,0x24,0x01,0x24,0x01, // 69 - 0x00,0x00,0xFC,0x01,0x24,0x00,0x24,0x00,0x24, // 70 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x24,0x01,0xE4,0x01, // 71 - 0x00,0x00,0xFC,0x01,0x20,0x00,0x20,0x00,0x20,0x00,0xFC,0x01, // 72 - 0x00,0x00,0xFC,0x01, // 73 - 0x00,0x04,0xFC,0x03, // 74 - 0x00,0x00,0xFC,0x01,0x20,0x00,0x50,0x00,0x8C,0x00,0x00,0x01, // 75 - 0x00,0x00,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01, // 76 - 0x00,0x00,0xFC,0x01,0x18,0x00,0xE0,0x00,0x00,0x01,0xE0,0x00,0x18,0x00,0xFC,0x01, // 77 - 0x00,0x00,0xFC,0x01,0x08,0x00,0x30,0x00,0x60,0x00,0x80,0x00,0xFC,0x01, // 78 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0xF8, // 79 - 0x00,0x00,0xFC,0x01,0x44,0x00,0x44,0x00,0x7C, // 80 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x07,0xF8,0x04, // 81 - 0x00,0x00,0xFC,0x01,0x24,0x00,0x64,0x00,0x9C,0x00,0x00,0x01, // 82 - 0x00,0x01,0x1C,0x01,0x24,0x01,0x24,0x01,0xC0, // 83 - 0x04,0x00,0x04,0x00,0xFC,0x01,0x04,0x00,0x04,0x00,0x04, // 84 - 0x00,0x00,0xFC,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0xFC, // 85 - 0x0C,0x00,0x30,0x00,0xC0,0x01,0xC0,0x01,0x38,0x00,0x04, // 86 - 0x0C,0x00,0x70,0x00,0x80,0x01,0x78,0x00,0x0C,0x00,0x70,0x00,0x80,0x01,0x70,0x00,0x0C, // 87 - 0x00,0x01,0x8C,0x00,0x70,0x00,0x70,0x00,0x8C,0x00,0x00,0x01, // 88 - 0x04,0x00,0x18,0x00,0xE0,0x01,0x20,0x00,0x18,0x00,0x04, // 89 - 0x00,0x01,0x84,0x01,0x64,0x01,0x14,0x01,0x0C,0x01,0x00,0x01, // 90 - 0x00,0x00,0xFC,0x07,0x04,0x04, // 91 - 0x04,0x00,0x18,0x00,0xE0,0x00,0x00,0x01, // 92 - 0x04,0x04,0xFC,0x07, // 93 - 0x20,0x00,0x18,0x00,0x04,0x00,0x18,0x00,0x20, // 94 - 0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04, // 95 - 0x00,0x00,0x00,0x00,0x02,0x00,0x04, // 96 - 0x80,0x00,0x50,0x01,0x50,0x01,0x50,0x01,0xF0,0x01, // 97 - 0x00,0x00,0xFC,0x01,0x10,0x01,0x10,0x01,0xF0,0x01, // 98 - 0x00,0x00,0xF0,0x01,0x10,0x01,0x10,0x01,0x10,0x01, // 99 - 0x00,0x00,0xF0,0x01,0x10,0x01,0x10,0x01,0xFC,0x01, // 100 - 0x00,0x00,0xF0,0x00,0x50,0x01,0x50,0x01,0x70,0x01, // 101 - 0x10,0x00,0xFC,0x01,0x14, // 102 - 0x20,0x06,0xD0,0x05,0x50,0x05,0x70,0x05,0x10,0x02, // 103 - 0x00,0x00,0xFC,0x01,0x10,0x00,0x10,0x00,0xF0,0x01, // 104 - 0x00,0x00,0xF4,0x01, // 105 - 0x00,0x04,0xF4,0x07, // 106 - 0x00,0x00,0xFC,0x01,0x60,0x00,0x90,0x00,0x00,0x01, // 107 - 0x00,0x00,0xFC,0x01, // 108 - 0x00,0x00,0xF0,0x01,0x10,0x00,0x10,0x00,0xE0,0x01,0x10,0x00,0x10,0x00,0xF0,0x01, // 109 - 0x00,0x00,0xF0,0x01,0x10,0x00,0x10,0x00,0xF0,0x01, // 110 - 0x00,0x00,0xF0,0x01,0x10,0x01,0x10,0x01,0xF0,0x01, // 111 - 0x00,0x00,0xF0,0x07,0x10,0x01,0x10,0x01,0xF0,0x01, // 112 - 0x00,0x00,0xF0,0x01,0x10,0x01,0x10,0x01,0xF0,0x07, // 113 - 0x00,0x00,0xF0,0x01,0x10,0x00,0x10, // 114 - 0x00,0x00,0x30,0x01,0x50,0x01,0x50,0x01,0x80, // 115 - 0x10,0x00,0xF8,0x01,0x10,0x01,0x10,0x01, // 116 - 0x00,0x00,0xF0,0x01,0x00,0x01,0x00,0x01,0xF0,0x01, // 117 - 0x10,0x00,0xE0,0x00,0x00,0x01,0xE0,0x00,0x10, // 118 - 0x30,0x00,0xC0,0x01,0x80,0x01,0x70,0x00,0x70,0x00,0x80,0x01,0xC0,0x01,0x30, // 119 - 0x00,0x01,0xB0,0x00,0x40,0x00,0xB0,0x00,0x00,0x01, // 120 - 0x10,0x04,0xE0,0x04,0x00,0x03,0xE0,0x00,0x10, // 121 - 0x00,0x01,0x90,0x01,0x50,0x01,0x30,0x01,0x10,0x01, // 122 - 0x40,0x00,0xB8,0x03,0x04,0x04,0x04,0x04, // 123 - 0x00,0x00,0x00,0x00,0xFC,0x07, // 124 - 0x04,0x04,0xBC,0x07,0x40,0x00,0x40, // 125 - 0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20, // 126 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 127 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 128 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 129 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 130 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 131 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 132 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 133 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 134 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 135 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 136 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 137 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 138 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 139 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 140 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 141 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 142 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 143 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 144 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 145 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 146 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 147 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 148 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 149 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 150 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 151 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 152 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 153 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 154 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 155 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 156 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 157 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 158 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01, // 159 - 0x00,0x00,0xD0,0x07, // 161 - 0x00,0x00,0x70,0x00,0x88,0x00,0x8C,0x01,0x88, // 162 - 0x20,0x01,0xF8,0x01,0x24,0x01,0x24,0x01,0x04,0x01,0x00,0x01, // 163 - 0x50,0x00,0xF8,0x00,0x54,0x01,0x54,0x01,0x14,0x01,0x04,0x01, // 8364 - 0x04,0x00,0xA8,0x00,0xF0,0x01,0xB0,0x00,0xA8,0x00,0x04, // 165 - 0x00,0x01,0x1C,0x01,0x25,0x01,0x25,0x01,0xC0, // 352 - 0x00,0x00,0x7C,0x01,0x54,0x01,0xF4,0x01, // 167 - 0x00,0x00,0x32,0x01,0x54,0x01,0x56,0x01,0x80, // 353 - 0x70,0x00,0x88,0x00,0x24,0x01,0x54,0x01,0x54,0x01,0x04,0x01,0x88,0x00,0x70, // 169 - 0x20,0x00,0x34,0x00,0x3C, // 170 - 0x00,0x00,0x60,0x00,0x90,0x00,0x60,0x00,0x90, // 171 - 0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xE0, // 172 - 0x40,0x00,0x40,0x00,0x40, // 173 - 0x70,0x00,0x88,0x00,0x04,0x01,0x74,0x01,0x34,0x01,0x44,0x01,0x88,0x00,0x70, // 174 - 0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, // 175 - 0x00,0x00,0x1C,0x00,0x1C, // 176 - 0x00,0x00,0x20,0x01,0xF8,0x01,0x20,0x01,0x20,0x01, // 177 - 0x24,0x00,0x34,0x00,0x28, // 178 - 0x24,0x00,0x2C,0x00,0x3C, // 179 - 0x00,0x01,0x84,0x01,0x65,0x01,0x15,0x01,0x0C,0x01,0x00,0x01, // 381 - 0x00,0x00,0xF0,0x07,0x00,0x01,0x00,0x01,0xF0,0x01, // 181 - 0x00,0x00,0x3E,0x00,0x3E,0x00,0xFE,0x03,0x02,0x00,0xFE,0x03, // 182 - 0x00,0x00,0x20, // 183 - 0x02,0x01,0x94,0x01,0x56,0x01,0x30,0x01,0x10,0x01, // 382 - 0x00,0x00,0x3C, // 185 - 0x18,0x00,0x24,0x00,0x24,0x00,0x18, // 186 - 0x90,0x00,0x60,0x00,0x90,0x00,0x60, // 187 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,0x24,0x01,0x24,0x01, // 338 - 0x00,0x00,0xF0,0x01,0x10,0x01,0x10,0x01,0xE0,0x00,0x50,0x01,0x50,0x01,0x70,0x01,0x40, // 339 - 0x04,0x00,0x18,0x00,0xE1,0x01,0x21,0x00,0x18,0x00,0x04, // 376 - 0x00,0x03,0x80,0x04,0x50,0x04,0x00,0x04, // 191 - 0x00,0x01,0xE0,0x00,0x5C,0x00,0x5D,0x00,0xE0,0x00,0x00,0x01, // 192 - 0x00,0x01,0xE0,0x00,0x5C,0x00,0x5D,0x00,0xE0,0x00,0x00,0x01, // 193 - 0x00,0x01,0xE1,0x00,0x5C,0x00,0x5D,0x00,0xE0,0x00,0x00,0x01, // 194 - 0x00,0x01,0xE1,0x00,0x5C,0x00,0x5D,0x00,0xE1,0x00,0x00,0x01, // 195 - 0x00,0x01,0xE0,0x00,0x5D,0x00,0x5D,0x00,0xE0,0x00,0x00,0x01, // 196 - 0x00,0x01,0xE0,0x00,0x5F,0x00,0x5F,0x00,0xE0,0x00,0x00,0x01, // 197 - 0x00,0x01,0xC0,0x00,0x70,0x00,0x4C,0x00,0x44,0x00,0xBC,0x01,0x24,0x01,0x24,0x01, // 198 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x05,0x04,0x07,0x04, // 199 - 0x00,0x00,0xFC,0x01,0x24,0x01,0x25,0x01,0x24,0x01, // 200 - 0x00,0x00,0xFC,0x01,0x25,0x01,0x24,0x01,0x24,0x01, // 201 - 0x00,0x00,0xFD,0x01,0x24,0x01,0x25,0x01,0x24,0x01, // 202 - 0x00,0x00,0xFC,0x01,0x25,0x01,0x25,0x01,0x24,0x01, // 203 - 0x00,0x00,0xFD,0x01, // 204 - 0x00,0x00,0xFD,0x01, // 205 - 0x00,0x00,0xFD,0x01, // 206 - 0x00,0x00,0xFD,0x01,0x01, // 207 - 0x20,0x00,0xFC,0x01,0x24,0x01,0x24,0x01,0x04,0x01,0xF8, // 208 - 0x00,0x00,0xFC,0x01,0x09,0x00,0x30,0x00,0x61,0x00,0x81,0x00,0xFC,0x01, // 209 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x04,0x01,0x05,0x01,0x04,0x01,0xF8, // 210 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x05,0x01,0x04,0x01,0x04,0x01,0xF8, // 211 - 0x00,0x00,0xF8,0x00,0x05,0x01,0x04,0x01,0x05,0x01,0x04,0x01,0xF8, // 212 - 0x00,0x00,0xF8,0x00,0x05,0x01,0x04,0x01,0x05,0x01,0x05,0x01,0xF8, // 213 - 0x00,0x00,0xF8,0x00,0x04,0x01,0x05,0x01,0x05,0x01,0x04,0x01,0xF8, // 214 - 0x00,0x00,0x50,0x00,0x20,0x00,0x20,0x00,0x50, // 215 - 0x00,0x00,0xF8,0x01,0x84,0x01,0x64,0x01,0x14,0x01,0x0C,0x01,0xFC, // 216 - 0x00,0x00,0xFC,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0xFC, // 217 - 0x00,0x00,0xFC,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0xFC, // 218 - 0x00,0x00,0xFC,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0xFC, // 219 - 0x00,0x00,0xFC,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0xFC, // 220 - 0x04,0x00,0x18,0x00,0xE1,0x01,0x20,0x00,0x18,0x00,0x04, // 221 - 0x00,0x00,0xFC,0x01,0x88,0x00,0x88,0x00,0xF8, // 222 - 0x00,0x00,0xFC,0x01,0x04,0x01,0x34,0x01,0x4C,0x01,0x80, // 223 - 0x80,0x00,0x52,0x01,0x54,0x01,0x50,0x01,0xF0,0x01, // 224 - 0x80,0x00,0x50,0x01,0x54,0x01,0x52,0x01,0xF0,0x01, // 225 - 0x80,0x00,0x54,0x01,0x52,0x01,0x56,0x01,0xF0,0x01, // 226 - 0x80,0x00,0x54,0x01,0x52,0x01,0x54,0x01,0xF6,0x01, // 227 - 0x80,0x00,0x50,0x01,0x54,0x01,0x54,0x01,0xF0,0x01, // 228 - 0x80,0x00,0x50,0x01,0x56,0x01,0x56,0x01,0xF0,0x01, // 229 - 0x80,0x00,0x50,0x01,0x50,0x01,0x50,0x01,0xE0,0x00,0x50,0x01,0x50,0x01,0x70,0x01, // 230 - 0x00,0x00,0xF0,0x01,0x10,0x05,0x10,0x07,0x10,0x01, // 231 - 0x00,0x00,0xF0,0x00,0x52,0x01,0x54,0x01,0x70,0x01, // 232 - 0x00,0x00,0xF0,0x00,0x54,0x01,0x52,0x01,0x70,0x01, // 233 - 0x00,0x00,0xF4,0x00,0x52,0x01,0x56,0x01,0x70,0x01, // 234 - 0x00,0x00,0xF0,0x00,0x54,0x01,0x54,0x01,0x70,0x01, // 235 - 0x02,0x00,0xF4,0x01, // 236 - 0x00,0x00,0xF4,0x01,0x02, // 237 - 0x02,0x00,0xF6,0x01, // 238 - 0x04,0x00,0xF4,0x01, // 239 - 0x00,0x00,0xE0,0x01,0x2C,0x01,0x28,0x01,0xB4,0x01,0x40, // 240 - 0x00,0x00,0xF4,0x01,0x12,0x00,0x14,0x00,0xF6,0x01, // 241 - 0x00,0x00,0xF0,0x01,0x12,0x01,0x14,0x01,0xF0,0x01, // 242 - 0x00,0x00,0xF0,0x01,0x14,0x01,0x12,0x01,0xF0,0x01, // 243 - 0x00,0x00,0xF4,0x01,0x12,0x01,0x16,0x01,0xF0,0x01, // 244 - 0x00,0x00,0xF4,0x01,0x12,0x01,0x14,0x01,0xF6,0x01, // 245 - 0x00,0x00,0xF0,0x01,0x14,0x01,0x14,0x01,0xF0,0x01, // 246 - 0x00,0x00,0x20,0x00,0xA8,0x00,0x20,0x00,0x20, // 247 - 0x00,0x00,0xF0,0x01,0x90,0x01,0x50,0x01,0xF0,0x01, // 248 - 0x00,0x00,0xF0,0x01,0x02,0x01,0x04,0x01,0xF0,0x01, // 249 - 0x00,0x00,0xF0,0x01,0x00,0x01,0x04,0x01,0xF2,0x01, // 250 - 0x00,0x00,0xF4,0x01,0x02,0x01,0x06,0x01,0xF0,0x01, // 251 - 0x00,0x00,0xF0,0x01,0x04,0x01,0x04,0x01,0xF0,0x01, // 252 - 0x10,0x04,0xE0,0x04,0x04,0x03,0xE2,0x00,0x10, // 253 - 0x00,0x00,0xFC,0x07,0x10,0x01,0x10,0x01,0xF0,0x01, // 254 - 0x10,0x04,0xE0,0x04,0x04,0x03,0xE4,0x00,0x10 // 255 -}; diff --git a/src/fonts/opensans20.h b/src/fonts/opensans20.h deleted file mode 100644 index 22eb4402..00000000 --- a/src/fonts/opensans20.h +++ /dev/null @@ -1,459 +0,0 @@ -// Font table version: 3 -// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator. -// In case of problems make sure that you are using the font file with the correct version! -const uint8_t Open_Sans_Regular_Plain_20[] PROGMEM = { - 0x13, // Width: 19 - 0x1C, // Height: 28 - 0x20, // First Char: 32 - 0xE0, // Numbers of Chars: 224 - - // Jump Table: - 0xFF, 0xFF, 0x00, 0x05, // 32= :65535 - 0x00, 0x00, 0x0F, 0x05, // 33=!:0 - 0x00, 0x0F, 0x1A, 0x08, // 34=":15 - 0x00, 0x29, 0x2E, 0x0D, // 35=#:41 - 0x00, 0x57, 0x27, 0x0B, // 36=$:87 - 0x00, 0x7E, 0x3B, 0x10, // 37=%:126 - 0x00, 0xB9, 0x37, 0x0F, // 38=&:185 - 0x00, 0xF0, 0x0A, 0x04, // 39=':240 - 0x00, 0xFA, 0x13, 0x06, // 40=(:250 - 0x01, 0x0D, 0x13, 0x06, // 41=):269 - 0x01, 0x20, 0x26, 0x0B, // 42=*:288 - 0x01, 0x46, 0x26, 0x0B, // 43=+:326 - 0x01, 0x6C, 0x0F, 0x05, // 44=,:364 - 0x01, 0x7B, 0x12, 0x06, // 45=-:379 - 0x01, 0x8D, 0x0F, 0x05, // 46=.:397 - 0x01, 0x9C, 0x19, 0x07, // 47=/:412 - 0x01, 0xB5, 0x27, 0x0B, // 48=0:437 - 0x01, 0xDC, 0x1B, 0x0B, // 49=1:476 - 0x01, 0xF7, 0x27, 0x0B, // 50=2:503 - 0x02, 0x1E, 0x27, 0x0B, // 51=3:542 - 0x02, 0x45, 0x2A, 0x0B, // 52=4:581 - 0x02, 0x6F, 0x27, 0x0B, // 53=5:623 - 0x02, 0x96, 0x27, 0x0B, // 54=6:662 - 0x02, 0xBD, 0x25, 0x0B, // 55=7:701 - 0x02, 0xE2, 0x27, 0x0B, // 56=8:738 - 0x03, 0x09, 0x26, 0x0B, // 57=9:777 - 0x03, 0x2F, 0x0F, 0x05, // 58=::815 - 0x03, 0x3E, 0x0E, 0x05, // 59=;:830 - 0x03, 0x4C, 0x27, 0x0B, // 60=<:844 - 0x03, 0x73, 0x26, 0x0B, // 61==:883 - 0x03, 0x99, 0x26, 0x0B, // 62=>:921 - 0x03, 0xBF, 0x1E, 0x09, // 63=?:959 - 0x03, 0xDD, 0x42, 0x12, // 64=@:989 - 0x04, 0x1F, 0x33, 0x0D, // 65=A:1055 - 0x04, 0x52, 0x2F, 0x0D, // 66=B:1106 - 0x04, 0x81, 0x2F, 0x0D, // 67=C:1153 - 0x04, 0xB0, 0x36, 0x0F, // 68=D:1200 - 0x04, 0xE6, 0x27, 0x0B, // 69=E:1254 - 0x05, 0x0D, 0x25, 0x0A, // 70=F:1293 - 0x05, 0x32, 0x33, 0x0F, // 71=G:1330 - 0x05, 0x65, 0x33, 0x0F, // 72=H:1381 - 0x05, 0x98, 0x0F, 0x06, // 73=I:1432 - 0x05, 0xA7, 0x0B, 0x05, // 74=J:1447 - 0x05, 0xB2, 0x2F, 0x0C, // 75=K:1458 - 0x05, 0xE1, 0x27, 0x0A, // 76=L:1505 - 0x06, 0x08, 0x3F, 0x12, // 77=M:1544 - 0x06, 0x47, 0x33, 0x0F, // 78=N:1607 - 0x06, 0x7A, 0x3A, 0x10, // 79=O:1658 - 0x06, 0xB4, 0x2A, 0x0C, // 80=P:1716 - 0x06, 0xDE, 0x3A, 0x10, // 81=Q:1758 - 0x07, 0x18, 0x2B, 0x0C, // 82=R:1816 - 0x07, 0x43, 0x27, 0x0B, // 83=S:1859 - 0x07, 0x6A, 0x29, 0x0B, // 84=T:1898 - 0x07, 0x93, 0x33, 0x0F, // 85=U:1939 - 0x07, 0xC6, 0x2D, 0x0C, // 86=V:1990 - 0x07, 0xF3, 0x49, 0x13, // 87=W:2035 - 0x08, 0x3C, 0x2F, 0x0C, // 88=X:2108 - 0x08, 0x6B, 0x29, 0x0B, // 89=Y:2155 - 0x08, 0x94, 0x27, 0x0B, // 90=Z:2196 - 0x08, 0xBB, 0x17, 0x07, // 91=[:2235 - 0x08, 0xD2, 0x1B, 0x07, // 92=\:2258 - 0x08, 0xED, 0x13, 0x07, // 93=]:2285 - 0x09, 0x00, 0x26, 0x0B, // 94=^:2304 - 0x09, 0x26, 0x23, 0x09, // 95=_:2342 - 0x09, 0x49, 0x1D, 0x0C, // 96=`:2377 - 0x09, 0x66, 0x23, 0x0B, // 97=a:2406 - 0x09, 0x89, 0x2B, 0x0C, // 98=b:2441 - 0x09, 0xB4, 0x23, 0x0A, // 99=c:2484 - 0x09, 0xD7, 0x27, 0x0C, // 100=d:2519 - 0x09, 0xFE, 0x27, 0x0B, // 101=e:2558 - 0x0A, 0x25, 0x1A, 0x07, // 102=f:2597 - 0x0A, 0x3F, 0x2A, 0x0B, // 103=g:2623 - 0x0A, 0x69, 0x27, 0x0C, // 104=h:2665 - 0x0A, 0x90, 0x0B, 0x05, // 105=i:2704 - 0x0A, 0x9B, 0x0B, 0x05, // 106=j:2715 - 0x0A, 0xA6, 0x27, 0x0B, // 107=k:2726 - 0x0A, 0xCD, 0x0B, 0x05, // 108=l:2765 - 0x0A, 0xD8, 0x43, 0x13, // 109=m:2776 - 0x0B, 0x1B, 0x27, 0x0C, // 110=n:2843 - 0x0B, 0x42, 0x2B, 0x0C, // 111=o:2882 - 0x0B, 0x6D, 0x2B, 0x0C, // 112=p:2925 - 0x0B, 0x98, 0x28, 0x0C, // 113=q:2968 - 0x0B, 0xC0, 0x1E, 0x08, // 114=r:3008 - 0x0B, 0xDE, 0x23, 0x0A, // 115=s:3038 - 0x0C, 0x01, 0x1B, 0x07, // 116=t:3073 - 0x0C, 0x1C, 0x27, 0x0C, // 117=u:3100 - 0x0C, 0x43, 0x26, 0x0A, // 118=v:3139 - 0x0C, 0x69, 0x3E, 0x10, // 119=w:3177 - 0x0C, 0xA7, 0x23, 0x0A, // 120=x:3239 - 0x0C, 0xCA, 0x26, 0x0A, // 121=y:3274 - 0x0C, 0xF0, 0x1F, 0x09, // 122=z:3312 - 0x0D, 0x0F, 0x1B, 0x08, // 123={:3343 - 0x0D, 0x2A, 0x18, 0x0B, // 124=|:3370 - 0x0D, 0x42, 0x1A, 0x08, // 125=}:3394 - 0x0D, 0x5C, 0x26, 0x0B, // 126=~:3420 - 0x0D, 0x82, 0x27, 0x0C, // 127=:3458 - 0x0D, 0xA9, 0x27, 0x0C, // 128=€:3497 - 0x0D, 0xD0, 0x27, 0x0C, // 129=:3536 - 0x0D, 0xF7, 0x27, 0x0C, // 130=‚:3575 - 0x0E, 0x1E, 0x27, 0x0C, // 131=ƒ:3614 - 0x0E, 0x45, 0x27, 0x0C, // 132=„:3653 - 0x0E, 0x6C, 0x27, 0x0C, // 133=…:3692 - 0x0E, 0x93, 0x27, 0x0C, // 134=†:3731 - 0x0E, 0xBA, 0x27, 0x0C, // 135=‡:3770 - 0x0E, 0xE1, 0x27, 0x0C, // 136=ˆ:3809 - 0x0F, 0x08, 0x27, 0x0C, // 137=‰:3848 - 0x0F, 0x2F, 0x27, 0x0C, // 138=Š:3887 - 0x0F, 0x56, 0x27, 0x0C, // 139=‹:3926 - 0x0F, 0x7D, 0x27, 0x0C, // 140=Œ:3965 - 0x0F, 0xA4, 0x27, 0x0C, // 141=:4004 - 0x0F, 0xCB, 0x27, 0x0C, // 142=Ž:4043 - 0x0F, 0xF2, 0x27, 0x0C, // 143=:4082 - 0x10, 0x19, 0x27, 0x0C, // 144=:4121 - 0x10, 0x40, 0x27, 0x0C, // 145=‘:4160 - 0x10, 0x67, 0x27, 0x0C, // 146=’:4199 - 0x10, 0x8E, 0x27, 0x0C, // 147=“:4238 - 0x10, 0xB5, 0x27, 0x0C, // 148=”:4277 - 0x10, 0xDC, 0x27, 0x0C, // 149=•:4316 - 0x11, 0x03, 0x27, 0x0C, // 150=–:4355 - 0x11, 0x2A, 0x27, 0x0C, // 151=—:4394 - 0x11, 0x51, 0x27, 0x0C, // 152=˜:4433 - 0x11, 0x78, 0x27, 0x0C, // 153=™:4472 - 0x11, 0x9F, 0x27, 0x0C, // 154=š:4511 - 0x11, 0xC6, 0x27, 0x0C, // 155=›:4550 - 0x11, 0xED, 0x27, 0x0C, // 156=œ:4589 - 0x12, 0x14, 0x27, 0x0C, // 157=:4628 - 0x12, 0x3B, 0x27, 0x0C, // 158=ž:4667 - 0x12, 0x62, 0x27, 0x0C, // 159=Ÿ:4706 - 0xFF, 0xFF, 0x00, 0x05, // 160= :65535 - 0x12, 0x89, 0x0F, 0x05, // 161=¡:4745 - 0x12, 0x98, 0x23, 0x0B, // 162=¢:4760 - 0x12, 0xBB, 0x27, 0x0B, // 163=£:4795 - 0x12, 0xE2, 0x2B, 0x0C, // 8364=€:4834 - 0x13, 0x0D, 0x25, 0x0B, // 165=¥:4877 - 0x13, 0x32, 0x27, 0x0B, // 352=Š:4914 - 0x13, 0x59, 0x23, 0x0A, // 167=§:4953 - 0x13, 0x7C, 0x23, 0x0A, // 353=š:4988 - 0x13, 0x9F, 0x3E, 0x11, // 169=©:5023 - 0x13, 0xDD, 0x16, 0x07, // 170=ª:5085 - 0x13, 0xF3, 0x23, 0x0A, // 171=«:5107 - 0x14, 0x16, 0x27, 0x0B, // 172=¬:5142 - 0x14, 0x3D, 0x12, 0x06, // 173=­:5181 - 0x14, 0x4F, 0x3E, 0x11, // 174=®:5199 - 0x14, 0x8D, 0x25, 0x0A, // 175=¯:5261 - 0x14, 0xB2, 0x1E, 0x09, // 176=°:5298 - 0x14, 0xD0, 0x27, 0x0B, // 177=±:5328 - 0x14, 0xF7, 0x16, 0x07, // 178=²:5367 - 0x15, 0x0D, 0x16, 0x07, // 179=³:5389 - 0x15, 0x23, 0x27, 0x0B, // 381=Ž:5411 - 0x15, 0x4A, 0x27, 0x0C, // 181=µ:5450 - 0x15, 0x71, 0x2B, 0x0D, // 182=¶:5489 - 0x15, 0x9C, 0x0E, 0x05, // 183=·:5532 - 0x15, 0xAA, 0x1F, 0x09, // 382=ž:5546 - 0x15, 0xC9, 0x12, 0x07, // 185=¹:5577 - 0x15, 0xDB, 0x1A, 0x08, // 186=º:5595 - 0x15, 0xF5, 0x22, 0x0A, // 187=»:5621 - 0x16, 0x17, 0x43, 0x12, // 338=Œ:5655 - 0x16, 0x5A, 0x46, 0x13, // 339=œ:5722 - 0x16, 0xA0, 0x29, 0x0B, // 376=Ÿ:5792 - 0x16, 0xC9, 0x1F, 0x09, // 191=¿:5833 - 0x16, 0xE8, 0x33, 0x0D, // 192=À:5864 - 0x17, 0x1B, 0x33, 0x0D, // 193=Á:5915 - 0x17, 0x4E, 0x33, 0x0D, // 194=Â:5966 - 0x17, 0x81, 0x33, 0x0D, // 195=Ã:6017 - 0x17, 0xB4, 0x33, 0x0D, // 196=Ä:6068 - 0x17, 0xE7, 0x33, 0x0D, // 197=Å:6119 - 0x18, 0x1A, 0x3F, 0x11, // 198=Æ:6170 - 0x18, 0x59, 0x2F, 0x0D, // 199=Ç:6233 - 0x18, 0x88, 0x27, 0x0B, // 200=È:6280 - 0x18, 0xAF, 0x27, 0x0B, // 201=É:6319 - 0x18, 0xD6, 0x27, 0x0B, // 202=Ê:6358 - 0x18, 0xFD, 0x27, 0x0B, // 203=Ë:6397 - 0x19, 0x24, 0x0F, 0x06, // 204=Ì:6436 - 0x19, 0x33, 0x15, 0x06, // 205=Í:6451 - 0x19, 0x48, 0x15, 0x06, // 206=Î:6472 - 0x19, 0x5D, 0x15, 0x06, // 207=Ï:6493 - 0x19, 0x72, 0x32, 0x0E, // 208=Ð:6514 - 0x19, 0xA4, 0x33, 0x0F, // 209=Ñ:6564 - 0x19, 0xD7, 0x3A, 0x10, // 210=Ò:6615 - 0x1A, 0x11, 0x3A, 0x10, // 211=Ó:6673 - 0x1A, 0x4B, 0x3A, 0x10, // 212=Ô:6731 - 0x1A, 0x85, 0x3A, 0x10, // 213=Õ:6789 - 0x1A, 0xBF, 0x3A, 0x10, // 214=Ö:6847 - 0x1A, 0xF9, 0x23, 0x0B, // 215=×:6905 - 0x1B, 0x1C, 0x3A, 0x10, // 216=Ø:6940 - 0x1B, 0x56, 0x33, 0x0F, // 217=Ù:6998 - 0x1B, 0x89, 0x33, 0x0F, // 218=Ú:7049 - 0x1B, 0xBC, 0x33, 0x0F, // 219=Û:7100 - 0x1B, 0xEF, 0x33, 0x0F, // 220=Ü:7151 - 0x1C, 0x22, 0x29, 0x0B, // 221=Ý:7202 - 0x1C, 0x4B, 0x2A, 0x0C, // 222=Þ:7243 - 0x1C, 0x75, 0x2B, 0x0C, // 223=ß:7285 - 0x1C, 0xA0, 0x23, 0x0B, // 224=à:7328 - 0x1C, 0xC3, 0x23, 0x0B, // 225=á:7363 - 0x1C, 0xE6, 0x23, 0x0B, // 226=â:7398 - 0x1D, 0x09, 0x23, 0x0B, // 227=ã:7433 - 0x1D, 0x2C, 0x23, 0x0B, // 228=ä:7468 - 0x1D, 0x4F, 0x23, 0x0B, // 229=å:7503 - 0x1D, 0x72, 0x3F, 0x11, // 230=æ:7538 - 0x1D, 0xB1, 0x23, 0x0A, // 231=ç:7601 - 0x1D, 0xD4, 0x27, 0x0B, // 232=è:7636 - 0x1D, 0xFB, 0x27, 0x0B, // 233=é:7675 - 0x1E, 0x22, 0x27, 0x0B, // 234=ê:7714 - 0x1E, 0x49, 0x27, 0x0B, // 235=ë:7753 - 0x1E, 0x70, 0x0D, 0x05, // 236=ì:7792 - 0x1E, 0x7D, 0x11, 0x05, // 237=í:7805 - 0x1E, 0x8E, 0x11, 0x05, // 238=î:7822 - 0x1E, 0x9F, 0x11, 0x05, // 239=ï:7839 - 0x1E, 0xB0, 0x2B, 0x0C, // 240=ð:7856 - 0x1E, 0xDB, 0x27, 0x0C, // 241=ñ:7899 - 0x1F, 0x02, 0x2B, 0x0C, // 242=ò:7938 - 0x1F, 0x2D, 0x2B, 0x0C, // 243=ó:7981 - 0x1F, 0x58, 0x2B, 0x0C, // 244=ô:8024 - 0x1F, 0x83, 0x2B, 0x0C, // 245=õ:8067 - 0x1F, 0xAE, 0x2B, 0x0C, // 246=ö:8110 - 0x1F, 0xD9, 0x26, 0x0B, // 247=÷:8153 - 0x1F, 0xFF, 0x2B, 0x0C, // 248=ø:8191 - 0x20, 0x2A, 0x27, 0x0C, // 249=ù:8234 - 0x20, 0x51, 0x27, 0x0C, // 250=ú:8273 - 0x20, 0x78, 0x27, 0x0C, // 251=û:8312 - 0x20, 0x9F, 0x27, 0x0C, // 252=ü:8351 - 0x20, 0xC6, 0x26, 0x0A, // 253=ý:8390 - 0x20, 0xEC, 0x2B, 0x0C, // 254=þ:8428 - 0x21, 0x17, 0x26, 0x0A, // 255=ÿ:8471 - - // Font Data: - 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x0E,0x00,0xC0,0x00,0x0E, // 33 - 0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x01, // 34 - 0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x08,0x00,0x00,0xC4,0x0F,0x00,0x00,0xFE,0x00,0x00,0xC0,0x87,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x0F,0x00,0x00,0xFC,0x01,0x00,0xC0,0x8F,0x00,0x00,0x40,0x84,0x00,0x00,0x00,0x84, // 35 - 0x00,0x00,0x00,0x00,0x00,0x02,0x06,0x00,0x00,0x0F,0x04,0x00,0x80,0x09,0x04,0x00,0x80,0x10,0x04,0x00,0xE0,0xFF,0x1F,0x00,0x80,0x30,0x04,0x00,0x80,0x20,0x06,0x00,0x80,0xE0,0x03,0x00,0x00,0x80,0x01, // 36 - 0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0xC0,0x71,0x00,0x00,0x40,0x40,0x00,0x00,0x40,0x40,0x0C,0x00,0x80,0x3F,0x07,0x00,0x00,0xCE,0x01,0x00,0x00,0x60,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xCE,0x01,0x00,0x80,0xF3,0x07,0x00,0xC0,0x08,0x08,0x00,0x00,0x08,0x08,0x00,0x00,0x38,0x0E,0x00,0x00,0xE0,0x03, // 37 - 0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0xE0,0x07,0x00,0x80,0x67,0x0C,0x00,0xC0,0x3C,0x08,0x00,0x40,0x18,0x08,0x00,0x40,0x38,0x08,0x00,0x40,0x6C,0x08,0x00,0x80,0xC7,0x0C,0x00,0x00,0x83,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x80,0x07,0x00,0x00,0xE0,0x0D,0x00,0x00,0x60,0x08, // 38 - 0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0xC0,0x07, // 39 - 0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0xFF,0x1F,0x00,0xC0,0x01,0x70,0x00,0x40,0x00,0x40, // 40 - 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0xC0,0x01,0x70,0x00,0x00,0xFF,0x1F,0x00,0x00,0xFC,0x07, // 41 - 0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3B,0x00,0x00,0x00,0x1E,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x3B,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03, // 42 - 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10, // 43 - 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x04, // 44 - 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40, // 45 - 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x0E, // 46 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x78,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x40, // 47 - 0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x80,0xFF,0x07,0x00,0xC0,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x0C,0x00,0x80,0xFF,0x07,0x00,0x00,0xFE,0x01, // 48 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F, // 49 - 0x00,0x00,0x00,0x00,0x80,0x00,0x0C,0x00,0x80,0x00,0x0E,0x00,0x40,0x00,0x0B,0x00,0x40,0x80,0x09,0x00,0x40,0xC0,0x08,0x00,0x40,0x60,0x08,0x00,0xC0,0x38,0x08,0x00,0x80,0x1F,0x08,0x00,0x00,0x00,0x08, // 50 - 0x00,0x00,0x00,0x00,0x80,0x00,0x0C,0x00,0xC0,0x00,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0xC0,0x2C,0x0C,0x00,0x80,0xEF,0x07,0x00,0x00,0xC0,0x03, // 51 - 0x00,0x80,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xB0,0x00,0x00,0x00,0x98,0x00,0x00,0x00,0x8E,0x00,0x00,0x00,0x83,0x00,0x00,0x80,0x81,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x80,0x00,0x00,0x00,0x80, // 52 - 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0xC0,0x0F,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x18,0x04,0x00,0x40,0xF0,0x07,0x00,0x00,0xE0,0x01, // 53 - 0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x11,0x04,0x00,0x80,0x08,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x18,0x0C,0x00,0x40,0xF0,0x07,0x00,0x00,0xE0,0x03, // 54 - 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x0C,0x00,0x40,0x00,0x0F,0x00,0x40,0xE0,0x03,0x00,0x40,0x78,0x00,0x00,0x40,0x1E,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0, // 55 - 0x00,0x00,0x00,0x00,0x00,0xC3,0x03,0x00,0x80,0xEF,0x07,0x00,0xC0,0x28,0x0C,0x00,0x40,0x18,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x30,0x08,0x00,0xC0,0x28,0x0C,0x00,0x80,0xE7,0x07,0x00,0x00,0xC2,0x03, // 56 - 0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x80,0x3F,0x08,0x00,0xC0,0x60,0x08,0x00,0x40,0x40,0x08,0x00,0x40,0x40,0x08,0x00,0x40,0x40,0x04,0x00,0x80,0x20,0x06,0x00,0x80,0xFF,0x03,0x00,0x00,0xFE, // 57 - 0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0x00,0x0E,0x0E,0x00,0x00,0x0E,0x0E, // 58 - 0x00,0x00,0x00,0x00,0x00,0x04,0x7C,0x00,0x00,0x0E,0x1C,0x00,0x00,0x04, // 59 - 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0xCC,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x86,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x03,0x03, // 60 - 0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x84, // 61 - 0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x02,0x01,0x00,0x00,0x86,0x01,0x00,0x00,0x84,0x00,0x00,0x00,0xCC,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x20, // 62 - 0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x40,0x00,0x04,0x00,0x40,0xE0,0x0E,0x00,0x40,0x30,0x0E,0x00,0x40,0x18,0x00,0x00,0xC0,0x1C,0x00,0x00,0x80,0x0F, // 63 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x07,0x0C,0x00,0x00,0x01,0x18,0x00,0x80,0xE0,0x30,0x00,0x80,0xF8,0x31,0x00,0xC0,0x0C,0x23,0x00,0x40,0x04,0x22,0x00,0x40,0x04,0x22,0x00,0x40,0x84,0x21,0x00,0x40,0xFC,0x31,0x00,0xC0,0x00,0x13,0x00,0x80,0x00,0x02,0x00,0x00,0x03,0x03,0x00,0x00,0xFE,0x01,0x00,0x00,0x78, // 64 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x5E,0x00,0x00,0x80,0x47,0x00,0x00,0xC0,0x40,0x00,0x00,0x80,0x47,0x00,0x00,0x00,0x5E,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 65 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0xC0,0x28,0x0C,0x00,0x80,0xEF,0x07,0x00,0x00,0xC0,0x03, // 66 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x03,0x07,0x00,0x80,0x01,0x04,0x00,0xC0,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x08, // 67 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x04,0x00,0x80,0x00,0x06,0x00,0x00,0x03,0x03,0x00,0x00,0xFE,0x01,0x00,0x00,0x78, // 68 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x00,0x08, // 69 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40, // 70 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x03,0x07,0x00,0x80,0x01,0x06,0x00,0x80,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0xC0,0xE0,0x0F, // 71 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F, // 72 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F, // 73 - 0x00,0x00,0x80,0x00,0x00,0x00,0xC0,0x00,0xC0,0xFF,0x7F, // 74 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0xC6,0x01,0x00,0x00,0x83,0x03,0x00,0xC0,0x00,0x06,0x00,0x40,0x00,0x0C,0x00,0x00,0x00,0x08, // 75 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08, // 76 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x00,0xC0,0x03,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F, // 77 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x07,0x00,0xC0,0x7F,0x0C,0x00,0xC0,0xFF,0x0F, // 78 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xC0,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 79 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0xC0,0x10,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x0F, // 80 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xC0,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x18,0x00,0xC0,0x00,0x3C,0x00,0x80,0x00,0x64,0x00,0x80,0x03,0x47,0x00,0x00,0xFF,0x03,0x00,0x00,0x78, // 81 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0x20,0x00,0x00,0x40,0xE0,0x00,0x00,0xC0,0x90,0x03,0x00,0x80,0x1F,0x0F,0x00,0x00,0x06,0x0C, // 82 - 0x00,0x00,0x00,0x00,0x00,0x07,0x0C,0x00,0x80,0x0F,0x08,0x00,0xC0,0x18,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x30,0x08,0x00,0x40,0x30,0x08,0x00,0x40,0x60,0x0C,0x00,0x40,0xE0,0x07,0x00,0x40,0xC0,0x03, // 83 - 0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40, // 84 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x07,0x00,0xC0,0xFF,0x03, // 85 - 0x40,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0xE0,0x03,0x00,0x00,0x78,0x00,0x00,0x00,0x1F,0x00,0x00,0xC0,0x03,0x00,0x00,0x40, // 86 - 0x40,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0xE0,0x03,0x00,0x00,0x7E,0x00,0x00,0xC0,0x07,0x00,0x00,0xC0,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x80,0x0F,0x00,0x00,0xF8,0x01,0x00,0x00,0x3F,0x00,0x00,0xC0,0x03,0x00,0x00,0x40, // 87 - 0x00,0x00,0x08,0x00,0xC0,0x00,0x0C,0x00,0xC0,0x01,0x07,0x00,0x00,0x83,0x03,0x00,0x00,0xEE,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xEE,0x00,0x00,0x00,0x83,0x03,0x00,0xC0,0x01,0x07,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0x08, // 88 - 0x40,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x38,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x07,0x00,0x00,0xC0,0x01,0x00,0x00,0x40, // 89 - 0x00,0x00,0x00,0x00,0x40,0x00,0x0E,0x00,0x40,0x00,0x0F,0x00,0x40,0xC0,0x0B,0x00,0x40,0xE0,0x08,0x00,0x40,0x78,0x08,0x00,0x40,0x1E,0x08,0x00,0x40,0x07,0x08,0x00,0xC0,0x03,0x08,0x00,0xC0,0x00,0x08, // 90 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40, // 91 - 0x40,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 92 - 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xC0,0xFF,0x7F, // 93 - 0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x60, // 94 - 0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40, // 95 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x80, // 96 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x00,0xC2,0x08,0x00,0x00,0x42,0x08,0x00,0x00,0x42,0x08,0x00,0x00,0x42,0x08,0x00,0x00,0x46,0x06,0x00,0x00,0xFC,0x0F, // 97 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x0C,0x06,0x00,0x00,0x06,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x06,0x0C,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 98 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08, // 99 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x06,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x06,0x0C,0x00,0x00,0x0C,0x06,0x00,0xE0,0xFF,0x0F, // 100 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x24,0x06,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x26,0x08,0x00,0x00,0x3C,0x08,0x00,0x00,0x38,0x0C, // 101 - 0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02, // 102 - 0x00,0x00,0x60,0x00,0x00,0x38,0xF8,0x00,0x00,0x7C,0x8B,0x01,0x00,0xC6,0x05,0x01,0x00,0x82,0x04,0x01,0x00,0x82,0x04,0x01,0x00,0x82,0x04,0x01,0x00,0x4E,0x84,0x01,0x00,0x7E,0xCC,0x00,0x00,0x02,0xF8,0x00,0x00,0x02, // 103 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xFC,0x0F, // 104 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xFE,0x0F, // 105 - 0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x01,0x60,0xFE,0xFF, // 106 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0xC0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xD8,0x01,0x00,0x00,0x0C,0x03,0x00,0x00,0x06,0x0E,0x00,0x00,0x02,0x0C, // 107 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F, // 108 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xFC,0x0F,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xFC,0x0F, // 109 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xFC,0x0F, // 110 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x04,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 111 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x0C,0x06,0x00,0x00,0x04,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x06,0x0C,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 112 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x06,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x0C,0x00,0x00,0x0C,0x06,0x00,0x00,0xFE,0xFF,0x01, // 113 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02, // 114 - 0x00,0x00,0x00,0x00,0x00,0x1C,0x0C,0x00,0x00,0x3C,0x08,0x00,0x00,0x62,0x08,0x00,0x00,0x62,0x08,0x00,0x00,0x42,0x08,0x00,0x00,0xC2,0x08,0x00,0x00,0x82,0x07,0x00,0x00,0x82,0x07, // 115 - 0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x02,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08, // 116 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0xFE,0x0F, // 117 - 0x00,0x02,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0x07,0x00,0x00,0xF8,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x02, // 118 - 0x00,0x02,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0x07,0x00,0x00,0xF8,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF8,0x01,0x00,0x00,0x3E,0x00,0x00,0x00,0x02, // 119 - 0x00,0x00,0x00,0x00,0x00,0x02,0x0C,0x00,0x00,0x0E,0x06,0x00,0x00,0x98,0x03,0x00,0x00,0xF0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x98,0x03,0x00,0x00,0x0E,0x06,0x00,0x00,0x02,0x0C, // 120 - 0x00,0x02,0x00,0x01,0x00,0x1E,0x00,0x01,0x00,0xF8,0x00,0x01,0x00,0xC0,0x83,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x1E,0x00,0x00,0xC0,0x07,0x00,0x00,0xF8,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x02, // 121 - 0x00,0x00,0x00,0x00,0x00,0x02,0x0C,0x00,0x00,0x02,0x0F,0x00,0x00,0xC2,0x0B,0x00,0x00,0xE2,0x08,0x00,0x00,0x3A,0x08,0x00,0x00,0x1E,0x08,0x00,0x00,0x06,0x08, // 122 - 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xBF,0x1F,0x00,0x80,0x1F,0x3F,0x00,0xC0,0x00,0x60,0x00,0x40,0x00,0x40, // 123 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x01, // 124 - 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0xC0,0x00,0x60,0x00,0x80,0x1F,0x3F,0x00,0x00,0xBF,0x1F,0x00,0x00,0xE0,0x00,0x00,0x00,0x40, // 125 - 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30, // 126 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 127 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 128 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 129 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 130 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 131 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 132 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 133 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 134 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 135 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 136 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 137 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 138 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 139 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 140 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 141 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 142 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 143 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 144 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 145 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 146 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 147 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 148 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 149 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 150 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 151 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 152 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 153 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 154 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 155 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 156 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 157 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 158 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F, // 159 - 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xEE,0xFF,0x00,0x00,0x0E,0x80, // 161 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xCE,0x01,0x00,0x00,0x03,0x03,0x00,0xC0,0x03,0x0F,0x00,0xC0,0x01,0x0E,0x00,0x00,0x03,0x03,0x00,0x00,0x03,0x03, // 162 - 0x00,0x00,0x00,0x00,0x00,0x20,0x0C,0x00,0x00,0x20,0x0F,0x00,0x80,0xFF,0x0B,0x00,0xC0,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x20,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08, // 163 - 0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x49,0x06,0x00,0xC0,0x48,0x0C,0x00,0x40,0x48,0x08,0x00,0x40,0x48,0x08,0x00,0x40,0x08,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x08, // 8364 - 0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x80,0x23,0x01,0x00,0x00,0x2E,0x01,0x00,0x00,0x38,0x01,0x00,0x00,0xE0,0x0F,0x00,0x00,0x38,0x01,0x00,0x00,0x2E,0x01,0x00,0x80,0x23,0x01,0x00,0xC0, // 165 - 0x00,0x00,0x00,0x00,0x00,0x07,0x0C,0x00,0x80,0x0F,0x08,0x00,0xC4,0x18,0x08,0x00,0x4C,0x10,0x08,0x00,0x58,0x30,0x08,0x00,0x58,0x30,0x08,0x00,0x4C,0x60,0x0C,0x00,0x44,0xE0,0x07,0x00,0x40,0xC0,0x03, // 352 - 0x00,0x00,0x00,0x00,0x80,0x18,0x0C,0x00,0xC0,0x3D,0x08,0x00,0x20,0x67,0x08,0x00,0x20,0x42,0x08,0x00,0x20,0xC6,0x08,0x00,0x20,0xC4,0x08,0x00,0x20,0xFC,0x07,0x00,0x00,0x38,0x03, // 167 - 0x00,0x00,0x00,0x00,0x00,0x1C,0x0C,0x00,0x20,0x3C,0x08,0x00,0x60,0x62,0x08,0x00,0xC0,0x62,0x08,0x00,0xC0,0x42,0x08,0x00,0x60,0xC2,0x08,0x00,0x20,0x82,0x07,0x00,0x00,0x82,0x07, // 353 - 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x86,0x01,0x00,0x00,0x01,0x02,0x00,0x80,0x00,0x04,0x00,0x80,0xF8,0x04,0x00,0x40,0xCC,0x08,0x00,0x40,0x86,0x09,0x00,0x40,0x02,0x09,0x00,0x40,0x02,0x09,0x00,0x40,0x86,0x09,0x00,0x80,0x00,0x04,0x00,0x80,0x00,0x04,0x00,0x00,0x01,0x02,0x00,0x00,0x86,0x01,0x00,0x00,0xFC, // 169 - 0x00,0x00,0x00,0x00,0x40,0x1C,0x00,0x00,0x40,0x12,0x00,0x00,0x40,0x12,0x00,0x00,0x40,0x0A,0x00,0x00,0x80,0x1F, // 170 - 0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x30,0x03,0x00,0x00,0x18,0x06,0x00,0x00,0xC0,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x30,0x03,0x00,0x00,0x18,0x06, // 171 - 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xF0,0x01, // 172 - 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40, // 173 - 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x86,0x01,0x00,0x00,0x01,0x02,0x00,0x80,0x00,0x04,0x00,0x80,0x00,0x04,0x00,0x40,0xFE,0x09,0x00,0x40,0x22,0x08,0x00,0x40,0x22,0x08,0x00,0x40,0x62,0x08,0x00,0x40,0x9E,0x09,0x00,0x80,0x08,0x05,0x00,0x80,0x00,0x04,0x00,0x00,0x01,0x02,0x00,0x00,0x86,0x01,0x00,0x00,0xFC, // 174 - 0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10, // 175 - 0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x80,0x04,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x40,0x08,0x00,0x00,0x80,0x04,0x00,0x00,0x00,0x03, // 176 - 0x00,0x00,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0xFF,0x05,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x04, // 177 - 0x00,0x40,0x00,0x00,0xC0,0x60,0x00,0x00,0x40,0x50,0x00,0x00,0x40,0x48,0x00,0x00,0x40,0x44,0x00,0x00,0x80,0x43, // 178 - 0x00,0x60,0x00,0x00,0xC0,0x40,0x00,0x00,0x40,0x44,0x00,0x00,0x40,0x44,0x00,0x00,0xC0,0x46,0x00,0x00,0x80,0x3B, // 179 - 0x00,0x00,0x00,0x00,0x40,0x00,0x0E,0x00,0x40,0x00,0x0F,0x00,0x44,0xC0,0x0B,0x00,0x4C,0xE0,0x08,0x00,0x58,0x78,0x08,0x00,0x58,0x1E,0x08,0x00,0x4C,0x07,0x08,0x00,0xC4,0x03,0x08,0x00,0xC0,0x00,0x08, // 381 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0xFE,0x0F, // 181 - 0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0xFF,0x7F,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xE0,0xFF,0x7F, // 182 - 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x70, // 183 - 0x00,0x00,0x00,0x00,0x00,0x02,0x0C,0x00,0x20,0x02,0x0F,0x00,0x60,0xC2,0x0B,0x00,0xC0,0xE2,0x08,0x00,0xC0,0x3A,0x08,0x00,0x60,0x1E,0x08,0x00,0x20,0x06,0x08, // 382 - 0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0xC0,0x7F, // 185 - 0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x40,0x10,0x00,0x00,0x40,0x10,0x00,0x00,0x40,0x10,0x00,0x00,0x40,0x10,0x00,0x00,0x80,0x0F, // 186 - 0x00,0x00,0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x30,0x03,0x00,0x00,0xE0,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0x18,0x06,0x00,0x00,0x30,0x03,0x00,0x00,0xE0,0x01,0x00,0x00,0xC0, // 187 - 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x00,0x08, // 338 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x04,0x00,0x00,0xFC,0x03,0x00,0x00,0xFC,0x03,0x00,0x00,0x26,0x06,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x26,0x08,0x00,0x00,0x3C,0x08,0x00,0x00,0x38, // 339 - 0x40,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x80,0x07,0x00,0x00,0x0C,0x0E,0x00,0x00,0x0C,0x38,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x38,0x00,0x00,0x0C,0x0E,0x00,0x00,0x8C,0x07,0x00,0x00,0xC0,0x01,0x00,0x00,0x40, // 376 - 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x83,0x00,0x00,0x8E,0x81,0x00,0x00,0xEE,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xC0, // 191 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x04,0x70,0x00,0x00,0x0C,0x5E,0x00,0x00,0x98,0x47,0x00,0x00,0xD0,0x40,0x00,0x00,0x80,0x47,0x00,0x00,0x00,0x5E,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 192 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x5E,0x00,0x00,0x90,0x47,0x00,0x00,0xD8,0x40,0x00,0x00,0x8C,0x47,0x00,0x00,0x04,0x5E,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 193 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x10,0x70,0x00,0x00,0x18,0x5E,0x00,0x00,0x8C,0x47,0x00,0x00,0xCC,0x40,0x00,0x00,0x98,0x47,0x00,0x00,0x10,0x5E,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 194 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x18,0x70,0x00,0x00,0x04,0x5E,0x00,0x00,0x8C,0x47,0x00,0x00,0xC8,0x40,0x00,0x00,0x90,0x47,0x00,0x00,0x18,0x5E,0x00,0x00,0x0C,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 195 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x70,0x00,0x00,0x0C,0x5E,0x00,0x00,0x8C,0x47,0x00,0x00,0xC0,0x40,0x00,0x00,0x80,0x47,0x00,0x00,0x0C,0x5E,0x00,0x00,0x0C,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 196 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x5E,0x00,0x00,0xF8,0x47,0x00,0x00,0xC8,0x40,0x00,0x00,0xC8,0x47,0x00,0x00,0x78,0x5E,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x08, // 197 - 0x00,0x00,0x08,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x00,0xE0,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x4F,0x00,0x00,0xC0,0x41,0x00,0x00,0x40,0x40,0x00,0x00,0x40,0x40,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x00,0x08, // 198 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x03,0x07,0x00,0x80,0x01,0x04,0x00,0xC0,0x00,0x0C,0x01,0x40,0x00,0x28,0x01,0x40,0x00,0x38,0x01,0x40,0x00,0xE8,0x01,0x40,0x00,0xC8,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x08, // 199 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC4,0xFF,0x0F,0x00,0x4C,0x10,0x08,0x00,0x58,0x10,0x08,0x00,0x50,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x00,0x08, // 200 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x50,0x10,0x08,0x00,0x58,0x10,0x08,0x00,0x4C,0x10,0x08,0x00,0x44,0x10,0x08,0x00,0x40,0x00,0x08, // 201 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xD0,0xFF,0x0F,0x00,0x58,0x10,0x08,0x00,0x4C,0x10,0x08,0x00,0x4C,0x10,0x08,0x00,0x58,0x10,0x08,0x00,0x50,0x10,0x08,0x00,0x40,0x00,0x08, // 202 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xCC,0xFF,0x0F,0x00,0x4C,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x4C,0x10,0x08,0x00,0x4C,0x10,0x08,0x00,0x40,0x00,0x08, // 203 - 0x04,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xD8,0xFF,0x0F,0x00,0xD0,0xFF,0x0F, // 204 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFF,0x0F,0x00,0xD8,0xFF,0x0F,0x00,0x0C,0x00,0x00,0x00,0x04, // 205 - 0x10,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xCC,0xFF,0x0F,0x00,0xCC,0xFF,0x0F,0x00,0x18,0x00,0x00,0x00,0x10, // 206 - 0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x0C,0x00,0x00,0x00,0x0C, // 207 - 0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x10,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x03,0x00,0x00,0x7C, // 208 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0x00,0x00,0x00,0x98,0x03,0x00,0x00,0x04,0x06,0x00,0x00,0x0C,0x1C,0x00,0x00,0x08,0x30,0x00,0x00,0x10,0xE0,0x00,0x00,0x18,0x80,0x01,0x00,0x0C,0x00,0x07,0x00,0xC0,0x7F,0x0C,0x00,0xC0,0xFF,0x0F, // 209 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xC4,0x00,0x0C,0x00,0x4C,0x00,0x08,0x00,0x58,0x00,0x08,0x00,0x50,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0xC0,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 210 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xC0,0x00,0x0C,0x00,0x40,0x00,0x08,0x00,0x50,0x00,0x08,0x00,0x58,0x00,0x08,0x00,0x4C,0x00,0x08,0x00,0xC4,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 211 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xD0,0x00,0x0C,0x00,0x58,0x00,0x08,0x00,0x4C,0x00,0x08,0x00,0x4C,0x00,0x08,0x00,0x58,0x00,0x08,0x00,0xD0,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 212 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xD8,0x00,0x0C,0x00,0x44,0x00,0x08,0x00,0x4C,0x00,0x08,0x00,0x48,0x00,0x08,0x00,0x50,0x00,0x08,0x00,0xD8,0x00,0x0C,0x00,0x8C,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 213 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x03,0x00,0x80,0x03,0x07,0x00,0x80,0x00,0x04,0x00,0xCC,0x00,0x0C,0x00,0x4C,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x40,0x00,0x08,0x00,0x4C,0x00,0x08,0x00,0xCC,0x00,0x0C,0x00,0x80,0x00,0x04,0x00,0x80,0x03,0x07,0x00,0x00,0xFF,0x01,0x00,0x00,0x78, // 214 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x01,0x00,0x00,0xC6,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x83,0x01, // 215 - 0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xFF,0x0B,0x00,0x80,0x03,0x0F,0x00,0x80,0x00,0x07,0x00,0xC0,0x80,0x0F,0x00,0x40,0xC0,0x08,0x00,0x40,0x70,0x08,0x00,0x40,0x18,0x08,0x00,0x40,0x0C,0x08,0x00,0xC0,0x07,0x0C,0x00,0x80,0x01,0x04,0x00,0xC0,0x03,0x07,0x00,0x40,0xFE,0x01,0x00,0x00,0x78, // 216 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x18,0x00,0x08,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x07,0x00,0xC0,0xFF,0x03, // 217 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x08,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x07,0x00,0xC0,0xFF,0x03, // 218 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0xC0,0xFF,0x07,0x00,0x10,0x00,0x04,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x18,0x00,0x08,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x07,0x00,0xC0,0xFF,0x03, // 219 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0xC0,0xFF,0x07,0x00,0x0C,0x00,0x04,0x00,0x0C,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xC0,0xFF,0x07,0x00,0xC0,0xFF,0x03, // 220 - 0x40,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x10,0x38,0x00,0x00,0x18,0xE0,0x0F,0x00,0x0C,0x38,0x00,0x00,0x04,0x0E,0x00,0x00,0x80,0x07,0x00,0x00,0xC0,0x01,0x00,0x00,0x40, // 221 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0xC0,0xFF,0x0F,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x83,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x7C, // 222 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x0F,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x0C,0x00,0x20,0x3C,0x08,0x00,0x20,0x76,0x08,0x00,0xC0,0x63,0x08,0x00,0xC0,0xC1,0x0F,0x00,0x00,0x80,0x07, // 223 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x20,0xC2,0x08,0x00,0x60,0x42,0x08,0x00,0xC0,0x42,0x08,0x00,0x80,0x42,0x08,0x00,0x00,0x46,0x06,0x00,0x00,0xFC,0x0F, // 224 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x00,0xC2,0x08,0x00,0x80,0x42,0x08,0x00,0xC0,0x42,0x08,0x00,0x60,0x42,0x08,0x00,0x20,0x46,0x06,0x00,0x00,0xFC,0x0F, // 225 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x80,0xC2,0x08,0x00,0xC0,0x42,0x08,0x00,0x60,0x42,0x08,0x00,0x60,0x42,0x08,0x00,0xC0,0x46,0x06,0x00,0x80,0xFC,0x0F, // 226 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0xC0,0x84,0x0F,0x00,0x20,0xC2,0x08,0x00,0x60,0x42,0x08,0x00,0x40,0x42,0x08,0x00,0x80,0x42,0x08,0x00,0xC0,0x46,0x06,0x00,0x60,0xFC,0x0F, // 227 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x60,0xC2,0x08,0x00,0x60,0x42,0x08,0x00,0x00,0x42,0x08,0x00,0x00,0x42,0x08,0x00,0x60,0x46,0x06,0x00,0x60,0xFC,0x0F, // 228 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x84,0x0F,0x00,0x00,0xC2,0x08,0x00,0xF0,0x42,0x08,0x00,0x90,0x42,0x08,0x00,0x90,0x42,0x08,0x00,0xF0,0x46,0x06,0x00,0x00,0xFC,0x0F, // 229 - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0xC6,0x0F,0x00,0x00,0x62,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x04,0x00,0x00,0x2E,0x07,0x00,0x00,0xFC,0x03,0x00,0x00,0x2C,0x07,0x00,0x00,0x22,0x0C,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x26,0x08,0x00,0x00,0x3C,0x08,0x00,0x00,0x38,0x04, // 230 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x01,0x00,0x02,0x28,0x01,0x00,0x02,0x38,0x01,0x00,0x02,0xE8,0x01,0x00,0x02,0xC8,0x00,0x00,0x02,0x08, // 231 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x20,0x24,0x06,0x00,0x60,0x22,0x08,0x00,0xC0,0x22,0x08,0x00,0x80,0x22,0x08,0x00,0x00,0x26,0x08,0x00,0x00,0x3C,0x08,0x00,0x00,0x38,0x0C, // 232 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x24,0x06,0x00,0x00,0x22,0x08,0x00,0x80,0x22,0x08,0x00,0xC0,0x22,0x08,0x00,0x60,0x26,0x08,0x00,0x20,0x3C,0x08,0x00,0x00,0x38,0x0C, // 233 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x80,0x24,0x06,0x00,0xC0,0x22,0x08,0x00,0x60,0x22,0x08,0x00,0x60,0x22,0x08,0x00,0xC0,0x26,0x08,0x00,0x80,0x3C,0x08,0x00,0x00,0x38,0x0C, // 234 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x60,0x24,0x06,0x00,0x60,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x00,0x22,0x08,0x00,0x60,0x26,0x08,0x00,0x60,0x3C,0x08,0x00,0x00,0x38,0x0C, // 235 - 0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xC0,0xFE,0x0F,0x00,0x80, // 236 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFE,0x0F,0x00,0xC0,0x00,0x00,0x00,0x60, // 237 - 0x80,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x60,0xFE,0x0F,0x00,0x60,0x00,0x00,0x00,0xC0, // 238 - 0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0x00,0x60, // 239 - 0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0xF0,0x07,0x00,0x00,0x19,0x04,0x00,0x60,0x09,0x08,0x00,0xC0,0x09,0x08,0x00,0xC0,0x08,0x08,0x00,0xC0,0x09,0x08,0x00,0x40,0x13,0x0C,0x00,0x00,0xFE,0x07,0x00,0x00,0xF8,0x01, // 240 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0xC0,0x0C,0x00,0x00,0x20,0x04,0x00,0x00,0x60,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x80,0x02,0x00,0x00,0xC0,0x06,0x00,0x00,0x60,0xFC,0x0F, // 241 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x00,0x20,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0xC0,0x02,0x08,0x00,0x80,0x02,0x08,0x00,0x00,0x04,0x04,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 242 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x00,0x04,0x04,0x00,0x00,0x02,0x08,0x00,0x80,0x02,0x08,0x00,0xC0,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0x20,0x04,0x04,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 243 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x80,0x04,0x04,0x00,0xC0,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0xC0,0x02,0x08,0x00,0x80,0x04,0x04,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 244 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0xC0,0x04,0x04,0x00,0x20,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0x40,0x02,0x08,0x00,0x80,0x02,0x08,0x00,0xC0,0x04,0x04,0x00,0x60,0xFC,0x07,0x00,0x00,0xF0,0x01, // 245 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x07,0x00,0x60,0x04,0x04,0x00,0x60,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x60,0x02,0x08,0x00,0x60,0x04,0x04,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 246 - 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x92,0x00,0x00,0x00,0x93,0x01,0x00,0x00,0x92,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10, // 247 - 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0xFC,0x0F,0x00,0x00,0x04,0x06,0x00,0x00,0x02,0x0B,0x00,0x00,0xC2,0x09,0x00,0x00,0x62,0x08,0x00,0x00,0x3A,0x08,0x00,0x00,0x0C,0x04,0x00,0x00,0xFE,0x07,0x00,0x00,0xF0,0x01, // 248 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x20,0x00,0x0C,0x00,0x60,0x00,0x08,0x00,0xC0,0x00,0x08,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0xFE,0x0F, // 249 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x08,0x00,0x80,0x00,0x08,0x00,0xC0,0x00,0x08,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x00,0xFE,0x0F, // 250 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x80,0x00,0x0C,0x00,0xC0,0x00,0x08,0x00,0x60,0x00,0x08,0x00,0x60,0x00,0x08,0x00,0xC0,0x00,0x04,0x00,0x80,0x00,0x06,0x00,0x00,0xFE,0x0F, // 251 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x60,0x00,0x0C,0x00,0x60,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x60,0x00,0x04,0x00,0x60,0x00,0x06,0x00,0x00,0xFE,0x0F, // 252 - 0x00,0x02,0x00,0x01,0x00,0x1E,0x00,0x01,0x00,0xF8,0x00,0x01,0x00,0xC0,0x83,0x00,0x80,0x00,0x7E,0x00,0xC0,0x00,0x1E,0x00,0x60,0xC0,0x07,0x00,0x20,0xF8,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x02, // 253 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x01,0x00,0x0C,0x06,0x00,0x00,0x04,0x0C,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x02,0x08,0x00,0x00,0x06,0x0C,0x00,0x00,0xFC,0x07,0x00,0x00,0xF0,0x01, // 254 - 0x00,0x02,0x00,0x01,0x00,0x1E,0x00,0x01,0x60,0xF8,0x00,0x01,0x60,0xC0,0x83,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x1E,0x00,0x60,0xC0,0x07,0x00,0x60,0xF8,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x02 // 255 -}; diff --git a/src/fonts/opensans34.h b/src/fonts/opensans34.h deleted file mode 100644 index e39672ea..00000000 --- a/src/fonts/opensans34.h +++ /dev/null @@ -1,459 +0,0 @@ -// Font table version: 3 -// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator. -// In case of problems make sure that you are using the font file with the correct version! -const uint8_t Open_Sans_Regular_Plain_34[] PROGMEM = { - 0x20, // Width: 32 - 0x2F, // Height: 47 - 0x20, // First Char: 32 - 0xE0, // Numbers of Chars: 224 - - // Jump Table: - 0xFF, 0xFF, 0x00, 0x09, // 32= :65535 - 0x00, 0x00, 0x22, 0x09, // 33=!:0 - 0x00, 0x22, 0x44, 0x0E, // 34=":34 - 0x00, 0x66, 0x7A, 0x16, // 35=#:102 - 0x00, 0xE0, 0x63, 0x13, // 36=$:224 - 0x01, 0x43, 0x9A, 0x1C, // 37=%:323 - 0x01, 0xDD, 0x8E, 0x19, // 38=&:477 - 0x02, 0x6B, 0x1A, 0x08, // 39=':619 - 0x02, 0x85, 0x35, 0x0A, // 40=(:645 - 0x02, 0xBA, 0x33, 0x0A, // 41=):698 - 0x02, 0xED, 0x62, 0x13, // 42=*:749 - 0x03, 0x4F, 0x69, 0x13, // 43=+:847 - 0x03, 0xB8, 0x22, 0x08, // 44=,:952 - 0x03, 0xDA, 0x39, 0x0B, // 45=-:986 - 0x04, 0x13, 0x28, 0x09, // 46=.:1043 - 0x04, 0x3B, 0x3E, 0x0C, // 47=/:1083 - 0x04, 0x79, 0x64, 0x13, // 48=0:1145 - 0x04, 0xDD, 0x46, 0x13, // 49=1:1245 - 0x05, 0x23, 0x64, 0x13, // 50=2:1315 - 0x05, 0x87, 0x64, 0x13, // 51=3:1415 - 0x05, 0xEB, 0x69, 0x13, // 52=4:1515 - 0x06, 0x54, 0x64, 0x13, // 53=5:1620 - 0x06, 0xB8, 0x64, 0x13, // 54=6:1720 - 0x07, 0x1C, 0x62, 0x13, // 55=7:1820 - 0x07, 0x7E, 0x64, 0x13, // 56=8:1918 - 0x07, 0xE2, 0x63, 0x13, // 57=9:2018 - 0x08, 0x45, 0x28, 0x09, // 58=::2117 - 0x08, 0x6D, 0x22, 0x09, // 59=;:2157 - 0x08, 0x8F, 0x64, 0x13, // 60=<:2191 - 0x08, 0xF3, 0x63, 0x13, // 61==:2291 - 0x09, 0x56, 0x63, 0x13, // 62=>:2390 - 0x09, 0xB9, 0x50, 0x0F, // 63=?:2489 - 0x0A, 0x09, 0xAB, 0x1F, // 64=@:2569 - 0x0A, 0xB4, 0x82, 0x16, // 65=A:2740 - 0x0B, 0x36, 0x76, 0x16, // 66=B:2870 - 0x0B, 0xAC, 0x73, 0x15, // 67=C:2988 - 0x0C, 0x1F, 0x87, 0x19, // 68=D:3103 - 0x0C, 0xA6, 0x64, 0x13, // 69=E:3238 - 0x0D, 0x0A, 0x63, 0x12, // 70=F:3338 - 0x0D, 0x6D, 0x82, 0x19, // 71=G:3437 - 0x0D, 0xEF, 0x82, 0x19, // 72=H:3567 - 0x0E, 0x71, 0x22, 0x09, // 73=I:3697 - 0x0E, 0x93, 0x22, 0x09, // 74=J:3731 - 0x0E, 0xB5, 0x7C, 0x15, // 75=K:3765 - 0x0F, 0x31, 0x64, 0x12, // 76=L:3889 - 0x0F, 0x95, 0xA6, 0x1F, // 77=M:3989 - 0x10, 0x3B, 0x88, 0x1A, // 78=N:4155 - 0x10, 0xC3, 0x8D, 0x1A, // 79=O:4291 - 0x11, 0x50, 0x68, 0x14, // 80=P:4432 - 0x11, 0xB8, 0x8D, 0x1A, // 81=Q:4536 - 0x12, 0x45, 0x76, 0x15, // 82=R:4677 - 0x12, 0xBB, 0x64, 0x13, // 83=S:4795 - 0x13, 0x1F, 0x6D, 0x13, // 84=T:4895 - 0x13, 0x8C, 0x81, 0x19, // 85=U:5004 - 0x14, 0x0D, 0x73, 0x14, // 86=V:5133 - 0x14, 0x80, 0xB0, 0x1F, // 87=W:5248 - 0x15, 0x30, 0x76, 0x14, // 88=X:5424 - 0x15, 0xA6, 0x6D, 0x13, // 89=Y:5542 - 0x16, 0x13, 0x6A, 0x13, // 90=Z:5651 - 0x16, 0x7D, 0x3B, 0x0B, // 91=[:5757 - 0x16, 0xB8, 0x46, 0x0C, // 92=\:5816 - 0x16, 0xFE, 0x2F, 0x0B, // 93=]:5886 - 0x17, 0x2D, 0x63, 0x12, // 94=^:5933 - 0x17, 0x90, 0x59, 0x0F, // 95=_:6032 - 0x17, 0xE9, 0x4A, 0x14, // 96=`:6121 - 0x18, 0x33, 0x5E, 0x13, // 97=a:6195 - 0x18, 0x91, 0x70, 0x15, // 98=b:6289 - 0x19, 0x01, 0x58, 0x10, // 99=c:6401 - 0x19, 0x59, 0x6A, 0x15, // 100=d:6489 - 0x19, 0xC3, 0x63, 0x13, // 101=e:6595 - 0x1A, 0x26, 0x43, 0x0C, // 102=f:6694 - 0x1A, 0x69, 0x6B, 0x13, // 103=g:6761 - 0x1A, 0xD4, 0x6A, 0x15, // 104=h:6868 - 0x1B, 0x3E, 0x22, 0x09, // 105=i:6974 - 0x1B, 0x60, 0x23, 0x09, // 106=j:7008 - 0x1B, 0x83, 0x64, 0x12, // 107=k:7043 - 0x1B, 0xE7, 0x22, 0x09, // 108=l:7143 - 0x1C, 0x09, 0xAC, 0x20, // 109=m:7177 - 0x1C, 0xB5, 0x6A, 0x15, // 110=n:7349 - 0x1D, 0x1F, 0x6F, 0x15, // 111=o:7455 - 0x1D, 0x8E, 0x70, 0x15, // 112=p:7566 - 0x1D, 0xFE, 0x6B, 0x15, // 113=q:7678 - 0x1E, 0x69, 0x4A, 0x0E, // 114=r:7785 - 0x1E, 0xB3, 0x52, 0x10, // 115=s:7859 - 0x1F, 0x05, 0x40, 0x0C, // 116=t:7941 - 0x1F, 0x45, 0x6A, 0x15, // 117=u:8005 - 0x1F, 0xAF, 0x62, 0x11, // 118=v:8111 - 0x20, 0x11, 0x98, 0x1A, // 119=w:8209 - 0x20, 0xA9, 0x64, 0x12, // 120=x:8361 - 0x21, 0x0D, 0x62, 0x11, // 121=y:8461 - 0x21, 0x6F, 0x58, 0x10, // 122=z:8559 - 0x21, 0xC7, 0x47, 0x0D, // 123={:8647 - 0x22, 0x0E, 0x41, 0x13, // 124=|:8718 - 0x22, 0x4F, 0x45, 0x0D, // 125=}:8783 - 0x22, 0x94, 0x63, 0x13, // 126=~:8852 - 0x22, 0xF7, 0x64, 0x14, // 127=:8951 - 0x23, 0x5B, 0x64, 0x14, // 128=€:9051 - 0x23, 0xBF, 0x64, 0x14, // 129=:9151 - 0x24, 0x23, 0x64, 0x14, // 130=‚:9251 - 0x24, 0x87, 0x64, 0x14, // 131=ƒ:9351 - 0x24, 0xEB, 0x64, 0x14, // 132=„:9451 - 0x25, 0x4F, 0x64, 0x14, // 133=…:9551 - 0x25, 0xB3, 0x64, 0x14, // 134=†:9651 - 0x26, 0x17, 0x64, 0x14, // 135=‡:9751 - 0x26, 0x7B, 0x64, 0x14, // 136=ˆ:9851 - 0x26, 0xDF, 0x64, 0x14, // 137=‰:9951 - 0x27, 0x43, 0x64, 0x14, // 138=Š:10051 - 0x27, 0xA7, 0x64, 0x14, // 139=‹:10151 - 0x28, 0x0B, 0x64, 0x14, // 140=Œ:10251 - 0x28, 0x6F, 0x64, 0x14, // 141=:10351 - 0x28, 0xD3, 0x64, 0x14, // 142=Ž:10451 - 0x29, 0x37, 0x64, 0x14, // 143=:10551 - 0x29, 0x9B, 0x64, 0x14, // 144=:10651 - 0x29, 0xFF, 0x64, 0x14, // 145=‘:10751 - 0x2A, 0x63, 0x64, 0x14, // 146=’:10851 - 0x2A, 0xC7, 0x64, 0x14, // 147=“:10951 - 0x2B, 0x2B, 0x64, 0x14, // 148=”:11051 - 0x2B, 0x8F, 0x64, 0x14, // 149=•:11151 - 0x2B, 0xF3, 0x64, 0x14, // 150=–:11251 - 0x2C, 0x57, 0x64, 0x14, // 151=—:11351 - 0x2C, 0xBB, 0x64, 0x14, // 152=˜:11451 - 0x2D, 0x1F, 0x64, 0x14, // 153=™:11551 - 0x2D, 0x83, 0x64, 0x14, // 154=š:11651 - 0x2D, 0xE7, 0x64, 0x14, // 155=›:11751 - 0x2E, 0x4B, 0x64, 0x14, // 156=œ:11851 - 0x2E, 0xAF, 0x64, 0x14, // 157=:11951 - 0x2F, 0x13, 0x64, 0x14, // 158=ž:12051 - 0x2F, 0x77, 0x64, 0x14, // 159=Ÿ:12151 - 0xFF, 0xFF, 0x00, 0x09, // 160= :65535 - 0x2F, 0xDB, 0x26, 0x09, // 161=¡:12251 - 0x30, 0x01, 0x5E, 0x13, // 162=¢:12289 - 0x30, 0x5F, 0x6A, 0x13, // 163=£:12383 - 0x30, 0xC9, 0x70, 0x14, // 8364=€:12489 - 0x31, 0x39, 0x67, 0x13, // 165=¥:12601 - 0x31, 0xA0, 0x64, 0x13, // 352=Š:12704 - 0x32, 0x04, 0x5E, 0x12, // 167=§:12804 - 0x32, 0x62, 0x52, 0x10, // 353=š:12898 - 0x32, 0xB4, 0x99, 0x1C, // 169=©:12980 - 0x33, 0x4D, 0x39, 0x0C, // 170=ª:13133 - 0x33, 0x86, 0x58, 0x11, // 171=«:13190 - 0x33, 0xDE, 0x64, 0x13, // 172=¬:13278 - 0x34, 0x42, 0x39, 0x0B, // 173=­:13378 - 0x34, 0x7B, 0x99, 0x1C, // 174=®:13435 - 0x35, 0x14, 0x61, 0x11, // 175=¯:13588 - 0x35, 0x75, 0x4A, 0x0F, // 176=°:13685 - 0x35, 0xBF, 0x69, 0x13, // 177=±:13759 - 0x36, 0x28, 0x3F, 0x0C, // 178=²:13864 - 0x36, 0x67, 0x3F, 0x0C, // 179=³:13927 - 0x36, 0xA6, 0x6A, 0x13, // 381=Ž:13990 - 0x37, 0x10, 0x6A, 0x15, // 181=µ:14096 - 0x37, 0x7A, 0x6B, 0x16, // 182=¶:14202 - 0x37, 0xE5, 0x27, 0x09, // 183=·:14309 - 0x38, 0x0C, 0x58, 0x10, // 382=ž:14348 - 0x38, 0x64, 0x2D, 0x0C, // 185=¹:14436 - 0x38, 0x91, 0x44, 0x0D, // 186=º:14481 - 0x38, 0xD5, 0x57, 0x11, // 187=»:14549 - 0x39, 0x2C, 0xAC, 0x1F, // 338=Œ:14636 - 0x39, 0xD8, 0xB1, 0x20, // 339=œ:14808 - 0x3A, 0x89, 0x6D, 0x13, // 376=Ÿ:14985 - 0x3A, 0xF6, 0x53, 0x0F, // 191=¿:15094 - 0x3B, 0x49, 0x82, 0x16, // 192=À:15177 - 0x3B, 0xCB, 0x82, 0x16, // 193=Á:15307 - 0x3C, 0x4D, 0x82, 0x16, // 194=Â:15437 - 0x3C, 0xCF, 0x82, 0x16, // 195=Ã:15567 - 0x3D, 0x51, 0x82, 0x16, // 196=Ä:15697 - 0x3D, 0xD3, 0x82, 0x16, // 197=Å:15827 - 0x3E, 0x55, 0xA6, 0x1E, // 198=Æ:15957 - 0x3E, 0xFB, 0x73, 0x15, // 199=Ç:16123 - 0x3F, 0x6E, 0x64, 0x13, // 200=È:16238 - 0x3F, 0xD2, 0x64, 0x13, // 201=É:16338 - 0x40, 0x36, 0x64, 0x13, // 202=Ê:16438 - 0x40, 0x9A, 0x64, 0x13, // 203=Ë:16538 - 0x40, 0xFE, 0x25, 0x09, // 204=Ì:16638 - 0x41, 0x23, 0x25, 0x09, // 205=Í:16675 - 0x41, 0x48, 0x31, 0x09, // 206=Î:16712 - 0x41, 0x79, 0x31, 0x09, // 207=Ï:16761 - 0x41, 0xAA, 0x87, 0x19, // 208=Ð:16810 - 0x42, 0x31, 0x88, 0x1A, // 209=Ñ:16945 - 0x42, 0xB9, 0x8D, 0x1A, // 210=Ò:17081 - 0x43, 0x46, 0x8D, 0x1A, // 211=Ó:17222 - 0x43, 0xD3, 0x8D, 0x1A, // 212=Ô:17363 - 0x44, 0x60, 0x8D, 0x1A, // 213=Õ:17504 - 0x44, 0xED, 0x8D, 0x1A, // 214=Ö:17645 - 0x45, 0x7A, 0x63, 0x13, // 215=×:17786 - 0x45, 0xDD, 0x8D, 0x1A, // 216=Ø:17885 - 0x46, 0x6A, 0x81, 0x19, // 217=Ù:18026 - 0x46, 0xEB, 0x81, 0x19, // 218=Ú:18155 - 0x47, 0x6C, 0x81, 0x19, // 219=Û:18284 - 0x47, 0xED, 0x81, 0x19, // 220=Ü:18413 - 0x48, 0x6E, 0x6D, 0x13, // 221=Ý:18542 - 0x48, 0xDB, 0x6F, 0x15, // 222=Þ:18651 - 0x49, 0x4A, 0x70, 0x15, // 223=ß:18762 - 0x49, 0xBA, 0x5E, 0x13, // 224=à:18874 - 0x4A, 0x18, 0x5E, 0x13, // 225=á:18968 - 0x4A, 0x76, 0x5E, 0x13, // 226=â:19062 - 0x4A, 0xD4, 0x5E, 0x13, // 227=ã:19156 - 0x4B, 0x32, 0x5E, 0x13, // 228=ä:19250 - 0x4B, 0x90, 0x5E, 0x13, // 229=å:19344 - 0x4B, 0xEE, 0x9F, 0x1D, // 230=æ:19438 - 0x4C, 0x8D, 0x58, 0x10, // 231=ç:19597 - 0x4C, 0xE5, 0x63, 0x13, // 232=è:19685 - 0x4D, 0x48, 0x63, 0x13, // 233=é:19784 - 0x4D, 0xAB, 0x63, 0x13, // 234=ê:19883 - 0x4E, 0x0E, 0x63, 0x13, // 235=ë:19982 - 0x4E, 0x71, 0x22, 0x09, // 236=ì:20081 - 0x4E, 0x93, 0x31, 0x09, // 237=í:20115 - 0x4E, 0xC4, 0x32, 0x09, // 238=î:20164 - 0x4E, 0xF6, 0x32, 0x09, // 239=ï:20214 - 0x4F, 0x28, 0x6A, 0x14, // 240=ð:20264 - 0x4F, 0x92, 0x6A, 0x15, // 241=ñ:20370 - 0x4F, 0xFC, 0x6F, 0x15, // 242=ò:20476 - 0x50, 0x6B, 0x6F, 0x15, // 243=ó:20587 - 0x50, 0xDA, 0x6F, 0x15, // 244=ô:20698 - 0x51, 0x49, 0x6F, 0x15, // 245=õ:20809 - 0x51, 0xB8, 0x6F, 0x15, // 246=ö:20920 - 0x52, 0x27, 0x63, 0x13, // 247=÷:21031 - 0x52, 0x8A, 0x6F, 0x15, // 248=ø:21130 - 0x52, 0xF9, 0x6A, 0x15, // 249=ù:21241 - 0x53, 0x63, 0x6A, 0x15, // 250=ú:21347 - 0x53, 0xCD, 0x6A, 0x15, // 251=û:21453 - 0x54, 0x37, 0x6A, 0x15, // 252=ü:21559 - 0x54, 0xA1, 0x62, 0x11, // 253=ý:21665 - 0x55, 0x03, 0x70, 0x15, // 254=þ:21763 - 0x55, 0x73, 0x62, 0x11, // 255=ÿ:21875 - - // Font Data: - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xC0,0xFF,0x0F,0x3E,0x00,0x00,0xC0,0xFF,0x7F,0x3E,0x00,0x00,0xC0,0xFF,0x1F,0x3E, // 33 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x01, // 34 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x38,0x00,0x00,0x00,0x60,0xE0,0x3F,0x00,0x00,0x00,0x60,0xFF,0x0F,0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x00,0xC0,0xFF,0x63,0x00,0x00,0x00,0xC0,0x7F,0x60,0x00,0x00,0x00,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x30,0x00,0x00,0x00,0x60,0xE0,0x3F,0x00,0x00,0x00,0x60,0xFC,0x3F,0x00,0x00,0x00,0xE0,0xFF,0x01,0x00,0x00,0x00,0xFF,0x67,0x00,0x00,0x00,0xC0,0x7F,0x60,0x00,0x00,0x00,0xC0,0x61,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60, // 35 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x06,0x00,0x00,0x00,0x7E,0x00,0x06,0x00,0x00,0x00,0xFF,0x00,0x0E,0x00,0x00,0x00,0xE7,0x01,0x0C,0x00,0x00,0x80,0x83,0x01,0x0C,0x00,0x00,0x80,0x81,0x01,0x0C,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0x80,0x01,0x06,0x0C,0x00,0x00,0x80,0x01,0x06,0x06,0x00,0x00,0x80,0x03,0x0C,0x07,0x00,0x00,0x00,0x03,0xFC,0x07,0x00,0x00,0x00,0x03,0xF8,0x03,0x00,0x00,0x00,0x00,0xF0, // 36 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x00,0x80,0xFF,0x0F,0x00,0x00,0x00,0xC0,0x03,0x0E,0x00,0x00,0x00,0xC0,0x00,0x18,0x00,0x00,0x00,0xC0,0x00,0x18,0x20,0x00,0x00,0xC0,0x00,0x18,0x38,0x00,0x00,0xC0,0x01,0x1C,0x3C,0x00,0x00,0x80,0xFF,0x0F,0x0F,0x00,0x00,0x00,0xFF,0xC7,0x03,0x00,0x00,0x00,0x70,0xF0,0x01,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0xF8,0xF0,0x01,0x00,0x00,0x00,0x3C,0xFE,0x0F,0x00,0x00,0x00,0x0F,0xFF,0x1F,0x00,0x00,0xC0,0x83,0x03,0x38,0x00,0x00,0xC0,0x81,0x01,0x30,0x00,0x00,0x40,0x80,0x01,0x30,0x00,0x00,0x00,0x80,0x01,0x30,0x00,0x00,0x00,0x00,0x07,0x1C,0x00,0x00,0x00,0x00,0xFF,0x1F,0x00,0x00,0x00,0x00,0xFC,0x07, // 37 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x1E,0xFC,0x1F,0x00,0x00,0x00,0x7F,0x1C,0x1C,0x00,0x00,0x80,0xFF,0x0E,0x38,0x00,0x00,0xC0,0xE1,0x07,0x30,0x00,0x00,0xC0,0xC0,0x07,0x30,0x00,0x00,0xC0,0x80,0x07,0x30,0x00,0x00,0xC0,0x80,0x0F,0x30,0x00,0x00,0xC0,0xC0,0x1F,0x30,0x00,0x00,0xC0,0xE1,0x3C,0x30,0x00,0x00,0x80,0xFF,0x78,0x18,0x00,0x00,0x80,0x7F,0xF0,0x18,0x00,0x00,0x00,0x1F,0xE0,0x1D,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xFC,0x1D,0x00,0x00,0x00,0x00,0x7C,0x38,0x00,0x00,0x00,0x00,0x1C,0x30,0x00,0x00,0x00,0x00,0x00,0x20, // 38 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x7F, // 39 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xFC,0xFF,0x7F,0x00,0x00,0x00,0xFE,0x01,0xFF,0x01,0x00,0x80,0x1F,0x00,0xF0,0x03,0x00,0xC0,0x03,0x00,0x80,0x07,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0x40,0x00,0x00,0x00,0x04, // 40 - 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x04,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x03,0x00,0x80,0x07,0x00,0x80,0x1F,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0xFF,0x01,0x00,0x00,0xFC,0xFF,0x7F,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x7C, // 41 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x0E,0x03,0x00,0x00,0x00,0x00,0x8C,0x03,0x00,0x00,0x00,0x00,0xCC,0x07,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0xF0,0x7F,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xF0,0x7D,0x00,0x00,0x00,0x00,0x00,0xEC,0x01,0x00,0x00,0x00,0x00,0xCC,0x07,0x00,0x00,0x00,0x00,0x8C,0x03,0x00,0x00,0x00,0x00,0x0E,0x02,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x0E, // 42 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06, // 43 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x04, // 44 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70, // 45 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x08, // 46 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xC0,0x01, // 47 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0x00,0x00,0xFF,0xF0,0x0F,0x00,0x00,0x80,0x07,0x00,0x1E,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x07,0x00,0x1E,0x00,0x00,0x00,0xFF,0xFF,0x0F,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0x00,0x00,0xF0,0xFF,0x01, // 48 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 49 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x38,0x00,0x00,0x80,0x03,0x00,0x3C,0x00,0x00,0x80,0x01,0x00,0x3E,0x00,0x00,0x80,0x01,0x00,0x37,0x00,0x00,0xC0,0x00,0x80,0x33,0x00,0x00,0xC0,0x00,0xC0,0x31,0x00,0x00,0xC0,0x00,0xE0,0x30,0x00,0x00,0xC0,0x00,0x70,0x30,0x00,0x00,0xC0,0x00,0x3C,0x30,0x00,0x00,0xC0,0x01,0x1E,0x30,0x00,0x00,0x80,0x01,0x0F,0x30,0x00,0x00,0x80,0xFF,0x07,0x30,0x00,0x00,0x00,0xFF,0x03,0x30,0x00,0x00,0x00,0xFE,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 50 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x38,0x00,0x00,0x80,0x01,0x00,0x30,0x00,0x00,0xC0,0x01,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x80,0x07,0x38,0x00,0x00,0x80,0xC1,0x07,0x18,0x00,0x00,0x80,0xFF,0x0E,0x1C,0x00,0x00,0x00,0x7F,0xFC,0x0F,0x00,0x00,0x00,0x3E,0xF8,0x07,0x00,0x00,0x00,0x00,0xF0,0x03, // 51 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xDF,0x00,0x00,0x00,0x00,0x80,0xC7,0x00,0x00,0x00,0x00,0xC0,0xC3,0x00,0x00,0x00,0x00,0xF0,0xC0,0x00,0x00,0x00,0x00,0x78,0xC0,0x00,0x00,0x00,0x00,0x1E,0xC0,0x00,0x00,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,0x80,0x03,0xC0,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0, // 52 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x80,0xFF,0x01,0x18,0x00,0x00,0xC0,0xFF,0x01,0x38,0x00,0x00,0xC0,0xBF,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x03,0x38,0x00,0x00,0xC0,0x00,0x03,0x18,0x00,0x00,0xC0,0x00,0x07,0x1E,0x00,0x00,0xC0,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0xF8,0x01, // 53 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xFC,0xFF,0x0F,0x00,0x00,0x00,0x1F,0x06,0x1E,0x00,0x00,0x00,0x07,0x03,0x18,0x00,0x00,0x80,0x03,0x03,0x38,0x00,0x00,0x80,0x81,0x01,0x30,0x00,0x00,0xC0,0x81,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x80,0x03,0x38,0x00,0x00,0xC0,0x00,0x03,0x1C,0x00,0x00,0xC0,0x00,0x1F,0x1F,0x00,0x00,0xC0,0x00,0xFE,0x0F,0x00,0x00,0x00,0x00,0xFC,0x03, // 54 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x3C,0x00,0x00,0xC0,0x00,0x80,0x3F,0x00,0x00,0xC0,0x00,0xE0,0x0F,0x00,0x00,0xC0,0x00,0xF8,0x03,0x00,0x00,0xC0,0x00,0xFE,0x00,0x00,0x00,0xC0,0xC0,0x1F,0x00,0x00,0x00,0xC0,0xF0,0x07,0x00,0x00,0x00,0xC0,0xFC,0x01,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xC0,0x03, // 55 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0xF0,0x07,0x00,0x00,0x00,0x7F,0xF8,0x0F,0x00,0x00,0x80,0xFF,0x7C,0x1E,0x00,0x00,0x80,0xE3,0x0C,0x18,0x00,0x00,0xC0,0xC1,0x07,0x38,0x00,0x00,0xC0,0x80,0x07,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x07,0x30,0x00,0x00,0xC0,0x80,0x07,0x30,0x00,0x00,0xC0,0xC1,0x0F,0x38,0x00,0x00,0x80,0xE3,0x1C,0x18,0x00,0x00,0x80,0x7F,0x7C,0x1F,0x00,0x00,0x00,0x3F,0xF8,0x0F,0x00,0x00,0x00,0x08,0xF0,0x07, // 56 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xFF,0x07,0x30,0x00,0x00,0x80,0x9F,0x0F,0x30,0x00,0x00,0x80,0x03,0x0E,0x30,0x00,0x00,0xC0,0x01,0x1C,0x30,0x00,0x00,0xC0,0x00,0x18,0x30,0x00,0x00,0xC0,0x00,0x18,0x30,0x00,0x00,0xC0,0x00,0x18,0x38,0x00,0x00,0xC0,0x00,0x18,0x18,0x00,0x00,0xC0,0x01,0x0C,0x1C,0x00,0x00,0x80,0x01,0x0C,0x0E,0x00,0x00,0x80,0x07,0x86,0x0F,0x00,0x00,0x00,0xFF,0xFF,0x07,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0xF0,0x3F, // 57 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x3E,0x00,0x00,0x00,0xF8,0x00,0x3E,0x00,0x00,0x00,0xF8,0x00,0x3E,0x00,0x00,0x00,0x20,0x00,0x08, // 58 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0xF8,0x03,0x00,0x00,0xF8,0x00,0xFC,0x01,0x00,0x00,0xF8,0x00,0x7C,0x00,0x00,0x00,0xF8,0x00,0x0C, // 59 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x80,0x1D,0x00,0x00,0x00,0x00,0x80,0x19,0x00,0x00,0x00,0x00,0xC0,0x18,0x00,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x00,0x00,0x00,0x60,0x70,0x00,0x00,0x00,0x00,0x30,0x60,0x00,0x00,0x00,0x00,0x38,0xE0,0x00,0x00,0x00,0x00,0x18,0xC0,0x00,0x00,0x00,0x00,0x1C,0xC0,0x01,0x00,0x00,0x00,0x0C,0x80,0x01,0x00,0x00,0x00,0x0E,0x80,0x03, // 60 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x60, // 61 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x80,0x03,0x00,0x00,0x00,0x0C,0x80,0x01,0x00,0x00,0x00,0x1C,0xC0,0x01,0x00,0x00,0x00,0x18,0xC0,0x00,0x00,0x00,0x00,0x30,0xE0,0x00,0x00,0x00,0x00,0x30,0x60,0x00,0x00,0x00,0x00,0x60,0x70,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x00,0xC0,0x18,0x00,0x00,0x00,0x00,0x80,0x19,0x00,0x00,0x00,0x00,0x80,0x1D,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x06, // 62 - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x1C,0x00,0x00,0xC0,0x00,0x78,0x3E,0x00,0x00,0xC0,0x00,0x7C,0x3E,0x00,0x00,0xC0,0x00,0x0E,0x1C,0x00,0x00,0xC0,0x00,0x07,0x00,0x00,0x00,0xC0,0x80,0x03,0x00,0x00,0x00,0x80,0xC1,0x01,0x00,0x00,0x00,0x80,0xFF,0x01,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x3E, // 63 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xF0,0x83,0x1F,0x00,0x00,0x00,0x78,0x00,0x3C,0x00,0x00,0x00,0x1C,0x00,0x70,0x00,0x00,0x00,0x0E,0x00,0x60,0x00,0x00,0x00,0x07,0x00,0xE0,0x00,0x00,0x00,0x03,0x7E,0xC0,0x00,0x00,0x80,0x01,0xFF,0xC0,0x00,0x00,0x80,0x81,0xFF,0xC1,0x01,0x00,0xC0,0xC1,0x81,0x83,0x01,0x00,0xC0,0xE0,0x00,0x83,0x01,0x00,0xC0,0x60,0x00,0x83,0x01,0x00,0xC0,0x60,0x00,0x83,0x01,0x00,0xC0,0x60,0x00,0x83,0x01,0x00,0xC0,0x60,0x80,0x81,0x01,0x00,0xC0,0x60,0xF0,0xC0,0x01,0x00,0xC0,0xE0,0xFF,0xC0,0x00,0x00,0xC0,0xE1,0xFF,0xC1,0x00,0x00,0x80,0x01,0x80,0xC3,0x00,0x00,0x80,0x03,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x07,0x00,0x03,0x00,0x00,0x00,0x1E,0x80,0x01,0x00,0x00,0x00,0xFC,0xF0,0x01,0x00,0x00,0x00,0xF0,0x7F,0x00,0x00,0x00,0x00,0xC0,0x1F, // 64 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x00,0xFE,0x30,0x00,0x00,0x00,0x80,0x3F,0x30,0x00,0x00,0x00,0xC0,0x07,0x30,0x00,0x00,0x00,0xC0,0x07,0x30,0x00,0x00,0x00,0x80,0x1F,0x30,0x00,0x00,0x00,0x00,0xFE,0x30,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 65 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x81,0x07,0x38,0x00,0x00,0x80,0x81,0x07,0x18,0x00,0x00,0x80,0xFF,0x0C,0x1C,0x00,0x00,0x00,0xFF,0xFC,0x0F,0x00,0x00,0x00,0x7E,0xF8,0x0F,0x00,0x00,0x00,0x00,0xF0,0x03, // 66 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x0F,0x00,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x03,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80, // 67 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x07,0x00,0x0E,0x00,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0x00,0x3E,0xE0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x00,0x00,0x00,0x00,0xC0,0x3F, // 68 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 69 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06,0x00,0x00,0x00,0xC0,0x00,0x06, // 70 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0x00,0x07,0x00,0x1E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x01,0x06,0x30,0x00,0x00,0xC0,0x01,0x06,0x18,0x00,0x00,0x80,0x01,0xFE,0x1F,0x00,0x00,0x80,0x00,0xFE,0x1F, // 71 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 72 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 73 - 0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x03,0x00,0xC0,0xFF,0xFF,0xFF, // 74 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xF0,0x3E,0x00,0x00,0x00,0x00,0x78,0x78,0x00,0x00,0x00,0x00,0x3C,0xF0,0x01,0x00,0x00,0x00,0x1E,0xE0,0x03,0x00,0x00,0x00,0x07,0x80,0x07,0x00,0x00,0x80,0x03,0x00,0x0F,0x00,0x00,0xC0,0x01,0x00,0x3E,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x20, // 75 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 76 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 77 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 78 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 79 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x01,0x0E,0x00,0x00,0x00,0xC0,0x01,0x06,0x00,0x00,0x00,0x80,0x03,0x07,0x00,0x00,0x00,0x80,0xFF,0x03,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0xFE, // 80 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x70,0x00,0x00,0xC0,0x00,0x00,0xF0,0x00,0x00,0xC0,0x01,0x00,0xF8,0x01,0x00,0x80,0x01,0x00,0xD8,0x03,0x00,0x80,0x03,0x00,0x9C,0x07,0x00,0x00,0x07,0x00,0x0E,0x07,0x00,0x00,0x3E,0xC0,0x07,0x06,0x00,0x00,0xFC,0xFF,0x03,0x04,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 81 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x1C,0x00,0x00,0x00,0xC0,0x00,0x3C,0x00,0x00,0x00,0xC0,0x01,0xFE,0x00,0x00,0x00,0x80,0x01,0xF6,0x03,0x00,0x00,0x80,0x87,0xC7,0x07,0x00,0x00,0x00,0xFF,0x03,0x1F,0x00,0x00,0x00,0xFE,0x01,0x3E,0x00,0x00,0x00,0x78,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x20, // 82 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x18,0x00,0x00,0x00,0xFF,0x00,0x38,0x00,0x00,0x80,0xFF,0x01,0x38,0x00,0x00,0x80,0xC3,0x03,0x30,0x00,0x00,0xC0,0x81,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x07,0x30,0x00,0x00,0xC0,0x00,0x07,0x30,0x00,0x00,0xC0,0x00,0x0E,0x30,0x00,0x00,0xC0,0x00,0x0E,0x30,0x00,0x00,0xC0,0x00,0x0C,0x18,0x00,0x00,0xC0,0x01,0x1C,0x1C,0x00,0x00,0xC0,0x01,0xF8,0x1F,0x00,0x00,0x80,0x01,0xF8,0x0F,0x00,0x00,0x80,0x00,0xF0,0x07, // 83 - 0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0, // 84 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF, // 85 - 0x40,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x40, // 86 - 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x80,0xFF,0x01,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0x00,0xC0,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xC0,0x03, // 87 - 0x00,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x3C,0x00,0x00,0xC0,0x03,0x00,0x3E,0x00,0x00,0x80,0x0F,0x80,0x0F,0x00,0x00,0x00,0x1E,0xC0,0x03,0x00,0x00,0x00,0x7C,0xF0,0x01,0x00,0x00,0x00,0xF0,0x78,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0xF0,0x78,0x00,0x00,0x00,0x00,0x7C,0xF0,0x01,0x00,0x00,0x00,0x1E,0xC0,0x07,0x00,0x00,0x80,0x0F,0x80,0x0F,0x00,0x00,0xC0,0x03,0x00,0x3E,0x00,0x00,0xC0,0x01,0x00,0x3C,0x00,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x20, // 88 - 0x40,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x40, // 89 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x3C,0x00,0x00,0xC0,0x00,0x00,0x3F,0x00,0x00,0xC0,0x00,0x80,0x3F,0x00,0x00,0xC0,0x00,0xE0,0x37,0x00,0x00,0xC0,0x00,0xF0,0x31,0x00,0x00,0xC0,0x00,0xFC,0x30,0x00,0x00,0xC0,0x00,0x3F,0x30,0x00,0x00,0xC0,0x80,0x1F,0x30,0x00,0x00,0xC0,0xE0,0x07,0x30,0x00,0x00,0xC0,0xF0,0x01,0x30,0x00,0x00,0xC0,0xFC,0x00,0x30,0x00,0x00,0xC0,0x3E,0x00,0x30,0x00,0x00,0xC0,0x1F,0x00,0x30,0x00,0x00,0xC0,0x07,0x00,0x30,0x00,0x00,0xC0,0x03,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 90 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06, // 91 - 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x20, // 92 - 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x07,0x00,0xC0,0xFF,0xFF,0xFF,0x07, // 93 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x10, // 94 - 0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06, // 95 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x01, // 96 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x00,0x30,0x30,0x38,0x00,0x00,0x00,0x38,0x30,0x30,0x00,0x00,0x00,0x18,0x38,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x38,0x18,0x0C,0x00,0x00,0x00,0xF0,0xF9,0x07,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 97 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x07,0x00,0x00,0x00,0x60,0x00,0x0E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0xFF,0x01, // 98 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x10,0x00,0x18, // 99 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x10,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0xF0,0xFF,0xFF,0x07,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F, // 100 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x18,0x1E,0x00,0x00,0x00,0x30,0x18,0x1C,0x00,0x00,0x00,0x38,0x18,0x38,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x38,0x18,0x30,0x00,0x00,0x00,0x70,0x18,0x30,0x00,0x00,0x00,0xE0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 101 - 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x3F,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x00,0x00,0x70,0x18,0x00,0x00,0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x30, // 102 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x80,0x07,0xE0,0x1F,0x00,0x00,0xE0,0x1F,0x67,0x1C,0x00,0x00,0xF0,0xBF,0x3F,0x38,0x00,0x00,0x70,0xF0,0x1F,0x30,0x00,0x00,0x38,0x70,0x18,0x30,0x00,0x00,0x18,0x60,0x18,0x30,0x00,0x00,0x18,0x60,0x18,0x30,0x00,0x00,0x18,0x60,0x18,0x30,0x00,0x00,0x18,0x60,0x18,0x30,0x00,0x00,0x38,0x60,0x18,0x30,0x00,0x00,0x38,0x30,0x18,0x38,0x00,0x00,0xF8,0x3F,0x18,0x18,0x00,0x00,0xF8,0x1F,0x38,0x1C,0x00,0x00,0xD8,0x07,0xF0,0x0F,0x00,0x00,0x18,0x00,0xF0,0x0F,0x00,0x00,0x18,0x00,0xC0,0x03, // 103 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 104 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xFF,0x3F,0x00,0x00,0xF0,0xF8,0xFF,0x3F,0x00,0x00,0xF0,0xF8,0xFF,0x3F, // 105 - 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0xF0,0xF8,0xFF,0xFF,0x1F,0x00,0xF0,0xF8,0xFF,0xFF,0x1F,0x00,0xF0,0xF8,0xFF,0xFF,0x07, // 106 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x80,0xF3,0x01,0x00,0x00,0x00,0xE0,0xC1,0x03,0x00,0x00,0x00,0xF0,0x80,0x0F,0x00,0x00,0x00,0x78,0x00,0x1F,0x00,0x00,0x00,0x38,0x00,0x3C,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x00,0x00,0x08,0x00,0x30, // 107 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0xF0,0xFF,0xFF,0x3F, // 108 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 109 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 110 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 111 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x00,0x00,0x60,0x00,0x0E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0xFF,0x01, // 112 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x10,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0xE0,0x00,0x0C,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0xFF,0x3F, // 113 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18, // 114 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x00,0x00,0x00,0xF0,0x07,0x38,0x00,0x00,0x00,0x70,0x0F,0x30,0x00,0x00,0x00,0x38,0x1C,0x30,0x00,0x00,0x00,0x18,0x1C,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x38,0x30,0x00,0x00,0x00,0x18,0x38,0x30,0x00,0x00,0x00,0x18,0x70,0x38,0x00,0x00,0x00,0x38,0xF0,0x1C,0x00,0x00,0x00,0x30,0xE0,0x1F,0x00,0x00,0x00,0x10,0xC0,0x0F, // 115 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0x00,0x80,0xFF,0xFF,0x1F,0x00,0x00,0x80,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30, // 116 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 117 - 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x08, // 118 - 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0xF0,0x7F,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0x00,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0xF0,0x3F,0x00,0x00,0x00,0x00,0xFF,0x07,0x00,0x00,0x00,0xF0,0x7F,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x08, // 119 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x00,0x00,0x78,0x00,0x3C,0x00,0x00,0x00,0xF0,0x00,0x1F,0x00,0x00,0x00,0xE0,0x83,0x0F,0x00,0x00,0x00,0x80,0xC7,0x03,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0x80,0xC7,0x03,0x00,0x00,0x00,0xE0,0x83,0x0F,0x00,0x00,0x00,0xF8,0x00,0x1F,0x00,0x00,0x00,0x78,0x00,0x3C,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x00,0x00,0x08,0x00,0x20, // 120 - 0x00,0x08,0x00,0x00,0x30,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0x00,0xF8,0x01,0x00,0x30,0x00,0x00,0xF0,0x0F,0x00,0x30,0x00,0x00,0x80,0x7F,0x00,0x38,0x00,0x00,0x00,0xFC,0x01,0x1C,0x00,0x00,0x00,0xF0,0x0F,0x1F,0x00,0x00,0x00,0x80,0xFF,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x08, // 121 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x3C,0x00,0x00,0x00,0x18,0x00,0x3E,0x00,0x00,0x00,0x18,0x80,0x3F,0x00,0x00,0x00,0x18,0xC0,0x37,0x00,0x00,0x00,0x18,0xF0,0x31,0x00,0x00,0x00,0x18,0xF8,0x30,0x00,0x00,0x00,0x18,0x3E,0x30,0x00,0x00,0x00,0x18,0x1F,0x30,0x00,0x00,0x00,0xD8,0x07,0x30,0x00,0x00,0x00,0xF8,0x03,0x30,0x00,0x00,0x00,0xF8,0x00,0x30,0x00,0x00,0x00,0x78,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 122 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x00,0xFE,0xEF,0xFF,0x00,0x00,0x00,0xFF,0xEF,0xFF,0x01,0x00,0x80,0xFF,0x83,0xFF,0x03,0x00,0x80,0x03,0x00,0x00,0x03,0x00,0xC0,0x01,0x00,0x00,0x07,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06, // 123 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0xF0,0xFF,0xFF,0xFF,0x3F, // 124 - 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0xC0,0x01,0x00,0x00,0x07,0x00,0x80,0x03,0x00,0x80,0x03,0x00,0x80,0xFF,0xC3,0xFF,0x03,0x00,0x00,0xFF,0xEF,0xFF,0x01,0x00,0x00,0xFC,0xEF,0xFF,0x00,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x38, // 125 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x07, // 126 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 127 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 128 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 129 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 130 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 131 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 132 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 133 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 134 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 135 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 136 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 137 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 138 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 139 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 140 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 141 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 142 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 143 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 144 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 145 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 146 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 147 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 148 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 149 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 150 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 151 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 152 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 153 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 154 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 155 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 156 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 157 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 158 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 159 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xF8,0xF0,0xFF,0x0F,0x00,0x00,0xF8,0xFC,0xFF,0x0F,0x00,0x00,0xF8,0xE0,0xFF,0x0F,0x00,0x00,0x20, // 161 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0x3C,0xC0,0x03,0x00,0x00,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0xC0,0x0F,0x00,0x3F,0x00,0x00,0xC0,0x07,0x00,0x3F,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x0C,0x00,0x03, // 162 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x38,0x00,0x00,0x00,0x00,0x06,0x38,0x00,0x00,0x00,0x00,0x06,0x3C,0x00,0x00,0x00,0xFC,0xFF,0x3F,0x00,0x00,0x00,0xFF,0xFF,0x37,0x00,0x00,0x80,0xFF,0xFF,0x33,0x00,0x00,0x80,0x03,0x06,0x30,0x00,0x00,0xC0,0x01,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x30,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 163 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0x00,0xF0,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xFE,0xF1,0x0F,0x00,0x00,0x00,0x8F,0x31,0x0E,0x00,0x00,0x80,0x83,0x31,0x1C,0x00,0x00,0x80,0x81,0x31,0x18,0x00,0x00,0xC0,0x81,0x31,0x38,0x00,0x00,0xC0,0x80,0x31,0x30,0x00,0x00,0xC0,0x80,0x31,0x30,0x00,0x00,0xC0,0x80,0x31,0x30,0x00,0x00,0xC0,0x80,0x01,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x18, // 8364 - 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0,0x0F,0x18,0x03,0x00,0x00,0x00,0x3F,0x18,0x03,0x00,0x00,0x00,0xFC,0x18,0x03,0x00,0x00,0x00,0xF0,0x1B,0x03,0x00,0x00,0x00,0xC0,0x1F,0x03,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0xC0,0x1F,0x03,0x00,0x00,0x00,0xF0,0x19,0x03,0x00,0x00,0x00,0xFC,0x18,0x03,0x00,0x00,0x00,0x3F,0x18,0x03,0x00,0x00,0xC0,0x0F,0x18,0x03,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0xC0, // 165 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x18,0x00,0x00,0x00,0xFF,0x00,0x38,0x00,0x00,0x80,0xFF,0x01,0x38,0x00,0x00,0x80,0xC3,0x03,0x30,0x00,0x00,0xC0,0x81,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x07,0x30,0x00,0x00,0xC7,0x00,0x07,0x30,0x00,0x00,0xC7,0x00,0x0E,0x30,0x00,0x00,0xC7,0x00,0x0E,0x30,0x00,0x00,0xC1,0x00,0x0C,0x18,0x00,0x00,0xC0,0x01,0x1C,0x1C,0x00,0x00,0xC0,0x01,0xF8,0x1F,0x00,0x00,0x80,0x01,0xF8,0x0F,0x00,0x00,0x80,0x00,0xF0,0x07, // 352 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x03,0x18,0x00,0x00,0xC0,0xE7,0x07,0x18,0x00,0x00,0xE0,0xEF,0x0F,0x38,0x00,0x00,0x60,0x3E,0x1C,0x30,0x00,0x00,0x30,0x3C,0x18,0x30,0x00,0x00,0x30,0x18,0x38,0x30,0x00,0x00,0x30,0x38,0x30,0x30,0x00,0x00,0x30,0x38,0x70,0x30,0x00,0x00,0x30,0x30,0x70,0x30,0x00,0x00,0x30,0x70,0x70,0x38,0x00,0x00,0x30,0xE0,0xF8,0x18,0x00,0x00,0x70,0xE0,0xDF,0x1F,0x00,0x00,0x60,0xC0,0xCF,0x0F,0x00,0x00,0x00,0x00,0x03,0x03, // 167 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x00,0x00,0x10,0xF0,0x07,0x38,0x00,0x00,0x30,0x70,0x0F,0x30,0x00,0x00,0xE0,0x38,0x1C,0x30,0x00,0x00,0xE0,0x19,0x1C,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0xC0,0x19,0x38,0x30,0x00,0x00,0xE0,0x19,0x38,0x30,0x00,0x00,0x60,0x18,0x70,0x38,0x00,0x00,0x30,0x38,0xF0,0x1C,0x00,0x00,0x10,0x30,0xE0,0x1F,0x00,0x00,0x00,0x10,0xC0,0x0F, // 353 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0xF1,0x00,0x00,0x00,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x80,0x81,0x1F,0x18,0x00,0x00,0x80,0xE1,0x7F,0x18,0x00,0x00,0xC0,0xF0,0xF9,0x30,0x00,0x00,0xC0,0x30,0xC0,0x30,0x00,0x00,0xC0,0x38,0xC0,0x31,0x00,0x00,0xC0,0x18,0x80,0x31,0x00,0x00,0xC0,0x18,0x80,0x31,0x00,0x00,0xC0,0x18,0x80,0x31,0x00,0x00,0xC0,0x18,0x80,0x31,0x00,0x00,0xC0,0x38,0xC0,0x30,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0xF0,0xF9,0x00,0x00,0x00,0x00,0xC0,0x3F, // 169 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x80,0xF8,0x00,0x00,0x00,0x00,0xC0,0x98,0x01,0x00,0x00,0x00,0xC0,0x8C,0x01,0x00,0x00,0x00,0xC0,0x8C,0x01,0x00,0x00,0x00,0xC0,0x8C,0x01,0x00,0x00,0x00,0xC0,0x84,0x00,0x00,0x00,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x80,0xFF,0x01, // 170 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0x87,0x03,0x00,0x00,0x00,0x80,0x03,0x07,0x00,0x00,0x00,0xC0,0x01,0x0E,0x00,0x00,0x00,0x80,0x30,0x04,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0xCE,0x01,0x00,0x00,0x00,0x80,0x87,0x07,0x00,0x00,0x00,0xC0,0x03,0x0F,0x00,0x00,0x00,0xC0,0x01,0x0E, // 171 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x00,0x00,0xFE,0x03, // 172 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x70, // 173 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0xF1,0x00,0x00,0x00,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0xF9,0xFF,0x19,0x00,0x00,0xC0,0xF8,0xFF,0x31,0x00,0x00,0xC0,0xF8,0xFF,0x31,0x00,0x00,0xC0,0x18,0x06,0x30,0x00,0x00,0xC0,0x18,0x06,0x30,0x00,0x00,0xC0,0x18,0x0E,0x30,0x00,0x00,0xC0,0x18,0x1E,0x30,0x00,0x00,0xC0,0xF8,0x7B,0x30,0x00,0x00,0xC0,0xF0,0xF3,0x31,0x00,0x00,0x80,0xE1,0xC1,0x19,0x00,0x00,0x80,0x01,0x00,0x19,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x00,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0xF0,0xF9,0x00,0x00,0x00,0x00,0xC0,0x3F, // 174 - 0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0C, // 175 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x00,0x00,0xC0,0xE0,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x1E, // 176 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0xFC,0xFF,0x33,0x00,0x00,0x00,0xFC,0xFF,0x33,0x00,0x00,0x00,0xFC,0xFF,0x33,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x00,0x00,0x06, // 177 - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x18,0x00,0x00,0x00,0x80,0x01,0x1C,0x00,0x00,0x00,0xC0,0x00,0x1E,0x00,0x00,0x00,0xC0,0x00,0x1B,0x00,0x00,0x00,0xC0,0x80,0x19,0x00,0x00,0x00,0xC0,0xC0,0x18,0x00,0x00,0x00,0xC0,0x60,0x18,0x00,0x00,0x00,0x80,0x3F,0x18,0x00,0x00,0x00,0x80,0x1F,0x18,0x00,0x00,0x00,0x00,0x00,0x18, // 178 - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0C,0x00,0x00,0x00,0x80,0x01,0x18,0x00,0x00,0x00,0xC0,0x30,0x18,0x00,0x00,0x00,0xC0,0x30,0x18,0x00,0x00,0x00,0xC0,0x30,0x18,0x00,0x00,0x00,0xC0,0x30,0x18,0x00,0x00,0x00,0xC0,0x38,0x18,0x00,0x00,0x00,0x80,0x7F,0x0E,0x00,0x00,0x00,0x80,0xCF,0x0F,0x00,0x00,0x00,0x00,0x86,0x07, // 179 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x3C,0x00,0x00,0xC0,0x00,0x00,0x3F,0x00,0x00,0xC0,0x00,0x80,0x3F,0x00,0x00,0xC0,0x00,0xE0,0x37,0x00,0x00,0xC0,0x00,0xF0,0x31,0x00,0x00,0xC3,0x00,0xFC,0x30,0x00,0x00,0xC7,0x00,0x3F,0x30,0x00,0x00,0xC7,0x80,0x1F,0x30,0x00,0x00,0xC7,0xE0,0x07,0x30,0x00,0x00,0xC7,0xF0,0x01,0x30,0x00,0x00,0xC1,0xFC,0x00,0x30,0x00,0x00,0xC0,0x3E,0x00,0x30,0x00,0x00,0xC0,0x1F,0x00,0x30,0x00,0x00,0xC0,0x07,0x00,0x30,0x00,0x00,0xC0,0x03,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 381 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0xF8,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 181 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0xF0,0xFF,0x1F,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x03,0x00,0xF0,0xFF,0xFF,0xFF,0x03,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x03,0x00,0xF0,0xFF,0xFF,0xFF,0x03, // 182 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x04, // 183 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x3C,0x00,0x00,0x10,0x18,0x00,0x3E,0x00,0x00,0x30,0x18,0x80,0x3F,0x00,0x00,0xE0,0x18,0xC0,0x37,0x00,0x00,0xE0,0x19,0xF0,0x31,0x00,0x00,0xC0,0x19,0xF8,0x30,0x00,0x00,0xC0,0x19,0x3E,0x30,0x00,0x00,0xE0,0x19,0x1F,0x30,0x00,0x00,0x60,0xD8,0x07,0x30,0x00,0x00,0x30,0xF8,0x03,0x30,0x00,0x00,0x10,0xF8,0x00,0x30,0x00,0x00,0x00,0x78,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30, // 382 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x1F,0x00,0x00,0x00,0xC0,0xFF,0x1F, // 185 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x80,0xC1,0x00,0x00,0x00,0x00,0xC0,0x80,0x01,0x00,0x00,0x00,0xC0,0x80,0x01,0x00,0x00,0x00,0xC0,0x80,0x01,0x00,0x00,0x00,0xC0,0x80,0x01,0x00,0x00,0x00,0xC0,0x80,0x01,0x00,0x00,0x00,0x80,0xE1,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x3E, // 186 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x0E,0x00,0x00,0x00,0xC0,0x03,0x0F,0x00,0x00,0x00,0x80,0x87,0x07,0x00,0x00,0x00,0x00,0xCE,0x01,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x80,0x30,0x04,0x00,0x00,0x00,0xC0,0x01,0x0E,0x00,0x00,0x00,0x80,0x03,0x07,0x00,0x00,0x00,0x00,0xC7,0x03,0x00,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x78, // 187 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3F,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 338 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0x19,0x0F,0x00,0x00,0x00,0x70,0x18,0x1C,0x00,0x00,0x00,0x38,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x38,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x38,0x18,0x30,0x00,0x00,0x00,0x70,0x18,0x30,0x00,0x00,0x00,0xE0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 339 - 0x40,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x02,0xF8,0x00,0x00,0x00,0x00,0x07,0xF0,0x03,0x00,0x00,0x00,0x07,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x07,0xF0,0x03,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x00,0x02,0x3E,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x40, // 376 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x07,0x06,0x00,0x00,0x00,0x80,0x03,0x0C,0x00,0x00,0x00,0xC0,0x01,0x0C,0x00,0x00,0xF0,0xF0,0x01,0x0C,0x00,0x00,0xF8,0xFC,0x00,0x0C,0x00,0x00,0xF8,0x3C,0x00,0x0C,0x00,0x00,0x70,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06, // 191 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x01,0xFE,0x30,0x00,0x00,0x00,0x83,0x3F,0x30,0x00,0x00,0x00,0xC7,0x07,0x30,0x00,0x00,0x00,0xC4,0x07,0x30,0x00,0x00,0x00,0x80,0x1F,0x30,0x00,0x00,0x00,0x00,0xFE,0x30,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 192 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x00,0xFE,0x30,0x00,0x00,0x00,0x84,0x3F,0x30,0x00,0x00,0x00,0xC7,0x07,0x30,0x00,0x00,0x00,0xC3,0x07,0x30,0x00,0x00,0x00,0x81,0x1F,0x30,0x00,0x00,0x00,0x00,0xFE,0x30,0x00,0x00,0x00,0x00,0xF0,0x37,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 193 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x04,0xC0,0x3F,0x00,0x00,0x00,0x06,0xF0,0x37,0x00,0x00,0x00,0x03,0xFE,0x30,0x00,0x00,0x00,0x83,0x3F,0x30,0x00,0x00,0x00,0xC1,0x07,0x30,0x00,0x00,0x00,0xC1,0x07,0x30,0x00,0x00,0x00,0x83,0x1F,0x30,0x00,0x00,0x00,0x03,0xFE,0x30,0x00,0x00,0x00,0x06,0xF0,0x37,0x00,0x00,0x00,0x04,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 194 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x04,0x00,0xF8,0x03,0x00,0x00,0x07,0x00,0x7E,0x00,0x00,0x00,0x03,0xC0,0x3F,0x00,0x00,0x00,0x01,0xF0,0x37,0x00,0x00,0x00,0x01,0xFE,0x30,0x00,0x00,0x00,0x83,0x3F,0x30,0x00,0x00,0x00,0xC3,0x07,0x30,0x00,0x00,0x00,0xC7,0x07,0x30,0x00,0x00,0x00,0x86,0x1F,0x30,0x00,0x00,0x00,0x06,0xFE,0x30,0x00,0x00,0x00,0x07,0xF0,0x37,0x00,0x00,0x00,0x03,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 195 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x02,0xC0,0x3F,0x00,0x00,0x00,0x07,0xF0,0x37,0x00,0x00,0x00,0x07,0xFE,0x30,0x00,0x00,0x00,0x80,0x3F,0x30,0x00,0x00,0x00,0xC0,0x07,0x30,0x00,0x00,0x00,0xC0,0x07,0x30,0x00,0x00,0x00,0x80,0x1F,0x30,0x00,0x00,0x00,0x07,0xFE,0x30,0x00,0x00,0x00,0x07,0xF0,0x37,0x00,0x00,0x00,0x02,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 196 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x1C,0xF0,0x37,0x00,0x00,0x00,0x3E,0xFE,0x30,0x00,0x00,0x00,0xE3,0x3F,0x30,0x00,0x00,0x00,0xE3,0x07,0x30,0x00,0x00,0x00,0xE3,0x07,0x30,0x00,0x00,0x00,0xE3,0x1F,0x30,0x00,0x00,0x00,0x3E,0xFE,0x30,0x00,0x00,0x00,0x1C,0xF0,0x37,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x20, // 197 - 0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x00,0xE0,0x37,0x00,0x00,0x00,0x00,0xFC,0x30,0x00,0x00,0x00,0x00,0x3F,0x30,0x00,0x00,0x00,0xC0,0x0F,0x30,0x00,0x00,0x00,0xC0,0x03,0x30,0x00,0x00,0x00,0xC0,0x00,0x30,0x00,0x00,0x00,0xC0,0x00,0x30,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 198 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x0F,0x00,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x03,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x30,0x00,0xC0,0x00,0x00,0x30,0x31,0x00,0xC0,0x00,0x00,0xF0,0x31,0x00,0xC0,0x00,0x00,0xF0,0x33,0x00,0xC0,0x00,0x00,0x30,0x1F,0x00,0xC0,0x00,0x00,0x30,0x1E,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80, // 199 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC1,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC4,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 200 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC4,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC1,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 201 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC4,0xFF,0xFF,0x3F,0x00,0x00,0xC6,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC1,0x00,0x03,0x30,0x00,0x00,0xC1,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC3,0x00,0x03,0x30,0x00,0x00,0xC6,0x00,0x03,0x30,0x00,0x00,0xC4,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 202 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC2,0xFF,0xFF,0x3F,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC7,0x00,0x03,0x30,0x00,0x00,0xC2,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x03,0x30,0x00,0x00,0xC0,0x00,0x00,0x30, // 203 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0xFF,0xFF,0x3F,0x00,0x00,0xC3,0xFF,0xFF,0x3F,0x00,0x00,0xC7,0xFF,0xFF,0x3F,0x00,0x00,0x04, // 204 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4,0xFF,0xFF,0x3F,0x00,0x00,0xC7,0xFF,0xFF,0x3F,0x00,0x00,0xC3,0xFF,0xFF,0x3F,0x00,0x00,0x01, // 205 - 0x04,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xC3,0xFF,0xFF,0x3F,0x00,0x00,0xC1,0xFF,0xFF,0x3F,0x00,0x00,0xC1,0xFF,0xFF,0x3F,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x06, // 206 - 0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, // 207 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x06,0x30,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0xC0,0x01,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0x00,0x7E,0xE0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF0,0xFF,0x00,0x00,0x00,0x00,0xC0,0x1F, // 208 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC4,0x07,0x00,0x00,0x00,0x00,0x87,0x0F,0x00,0x00,0x00,0x00,0x03,0x3E,0x00,0x00,0x00,0x00,0x01,0x7C,0x00,0x00,0x00,0x00,0x01,0xF0,0x01,0x00,0x00,0x00,0x03,0xE0,0x03,0x00,0x00,0x00,0x03,0x80,0x0F,0x00,0x00,0x00,0x07,0x00,0x1F,0x00,0x00,0x00,0x06,0x00,0x7C,0x00,0x00,0x00,0x06,0x00,0xF8,0x00,0x00,0x00,0x07,0x00,0xE0,0x03,0x00,0x00,0x03,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F, // 209 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC7,0x00,0x00,0x30,0x00,0x00,0xC4,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 210 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC4,0x00,0x00,0x30,0x00,0x00,0xC7,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x38,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 211 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x84,0x01,0x00,0x18,0x00,0x00,0xC6,0x01,0x00,0x38,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC6,0x01,0x00,0x38,0x00,0x00,0x84,0x01,0x00,0x18,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 212 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x84,0x03,0x00,0x1C,0x00,0x00,0x87,0x01,0x00,0x18,0x00,0x00,0xC3,0x01,0x00,0x38,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC1,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC3,0x00,0x00,0x30,0x00,0x00,0xC7,0x00,0x00,0x30,0x00,0x00,0xC6,0x00,0x00,0x30,0x00,0x00,0xC6,0x01,0x00,0x38,0x00,0x00,0x87,0x01,0x00,0x18,0x00,0x00,0x83,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 213 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x1C,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0xC2,0x01,0x00,0x38,0x00,0x00,0xC7,0x00,0x00,0x30,0x00,0x00,0xC7,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xC7,0x01,0x00,0x38,0x00,0x00,0x87,0x01,0x00,0x18,0x00,0x00,0x82,0x03,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x3E,0xC0,0x07,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 214 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x80,0x00,0x00,0x00,0x00,0x1C,0xC0,0x01,0x00,0x00,0x00,0x38,0xE0,0x00,0x00,0x00,0x00,0x70,0x70,0x00,0x00,0x00,0x00,0xE0,0x38,0x00,0x00,0x00,0x00,0xC0,0x1D,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xC0,0x1D,0x00,0x00,0x00,0x00,0xE0,0x38,0x00,0x00,0x00,0x00,0x70,0x70,0x00,0x00,0x00,0x00,0x38,0xE0,0x00,0x00,0x00,0x00,0x1C,0xC0,0x01,0x00,0x00,0x00,0x08,0x80, // 215 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x00,0xF8,0xFF,0x21,0x00,0x00,0x00,0xFC,0xFF,0x73,0x00,0x00,0x00,0x3E,0xC0,0x3F,0x00,0x00,0x00,0x07,0x00,0x1E,0x00,0x00,0x80,0x03,0x00,0x1F,0x00,0x00,0x80,0x01,0xC0,0x1B,0x00,0x00,0xC0,0x01,0xE0,0x39,0x00,0x00,0xC0,0x00,0x78,0x30,0x00,0x00,0xC0,0x00,0x3C,0x30,0x00,0x00,0xC0,0x00,0x1F,0x30,0x00,0x00,0xC0,0x80,0x07,0x30,0x00,0x00,0xC0,0xC0,0x03,0x30,0x00,0x00,0xC0,0xF0,0x00,0x30,0x00,0x00,0xC0,0x79,0x00,0x38,0x00,0x00,0x80,0x1F,0x00,0x18,0x00,0x00,0x80,0x0F,0x00,0x1C,0x00,0x00,0x80,0x07,0x00,0x0E,0x00,0x00,0xE0,0x3F,0xC0,0x07,0x00,0x00,0xC0,0xFC,0xFF,0x03,0x00,0x00,0x40,0xF8,0xFF,0x01,0x00,0x00,0x00,0xC0,0x3F, // 216 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0x30,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x07,0x00,0x00,0x30,0x00,0x00,0x04,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF, // 217 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x04,0x00,0x00,0x30,0x00,0x00,0x07,0x00,0x00,0x30,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF, // 218 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x04,0x00,0x00,0x1C,0x00,0x00,0x06,0x00,0x00,0x18,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0x30,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x03,0x00,0x00,0x30,0x00,0x00,0x06,0x00,0x00,0x30,0x00,0x00,0x04,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF, // 219 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x02,0x00,0x00,0x18,0x00,0x00,0x07,0x00,0x00,0x30,0x00,0x00,0x07,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x07,0x00,0x00,0x30,0x00,0x00,0x07,0x00,0x00,0x18,0x00,0x00,0x02,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0xC0,0xFF,0xFF,0x03,0x00,0x00,0xC0,0xFF,0xFF, // 220 - 0x40,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x04,0x00,0xFF,0x3F,0x00,0x00,0x07,0x00,0xFC,0x3F,0x00,0x00,0x03,0x00,0xFF,0x3F,0x00,0x00,0x01,0xC0,0x0F,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x40, // 221 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x0C,0xC0,0x00,0x00,0x00,0x00,0x1C,0xE0,0x00,0x00,0x00,0x00,0x18,0x60,0x00,0x00,0x00,0x00,0x38,0x70,0x00,0x00,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xE0,0x0F, // 222 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x3F,0x00,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x00,0xE0,0xFF,0xFF,0x3F,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x38,0x00,0x00,0x30,0xC0,0x03,0x30,0x00,0x00,0x30,0xE0,0x07,0x30,0x00,0x00,0x30,0xF0,0x0F,0x30,0x00,0x00,0x70,0x38,0x1E,0x30,0x00,0x00,0xE0,0x1F,0x1C,0x30,0x00,0x00,0xE0,0x1F,0x38,0x38,0x00,0x00,0xC0,0x07,0xF0,0x1C,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xE0,0x0F, // 223 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x10,0x30,0x30,0x38,0x00,0x00,0x30,0x38,0x30,0x30,0x00,0x00,0x70,0x18,0x38,0x30,0x00,0x00,0xE0,0x18,0x18,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0x00,0x19,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x38,0x18,0x0C,0x00,0x00,0x00,0xF0,0xF9,0x07,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 224 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x00,0x30,0x30,0x38,0x00,0x00,0x00,0x38,0x30,0x30,0x00,0x00,0x00,0x18,0x38,0x30,0x00,0x00,0x00,0x19,0x18,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0xE0,0x18,0x18,0x30,0x00,0x00,0x70,0x18,0x18,0x18,0x00,0x00,0x30,0x38,0x18,0x0C,0x00,0x00,0x10,0xF0,0xF9,0x07,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 225 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x31,0xF0,0x1C,0x00,0x00,0x80,0x31,0x30,0x38,0x00,0x00,0xE0,0x38,0x30,0x30,0x00,0x00,0xF0,0x18,0x38,0x30,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0xF0,0x18,0x18,0x30,0x00,0x00,0xC0,0x18,0x18,0x18,0x00,0x00,0x80,0x39,0x18,0x0C,0x00,0x00,0x00,0xF1,0xF9,0x07,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 226 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x01,0xE0,0x1F,0x00,0x00,0xC0,0x31,0xF0,0x1C,0x00,0x00,0xE0,0x30,0x30,0x38,0x00,0x00,0x60,0x38,0x30,0x30,0x00,0x00,0x60,0x18,0x38,0x30,0x00,0x00,0xE0,0x18,0x18,0x30,0x00,0x00,0xC0,0x18,0x18,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0x80,0x19,0x18,0x18,0x00,0x00,0x80,0x39,0x18,0x0C,0x00,0x00,0xC0,0xF1,0xF9,0x07,0x00,0x00,0xE0,0xF0,0xFF,0x3F,0x00,0x00,0x20,0xC0,0xFF,0x3F, // 227 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x80,0x30,0x30,0x38,0x00,0x00,0xC0,0x39,0x30,0x30,0x00,0x00,0xC0,0x19,0x38,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0xC0,0x39,0x18,0x0C,0x00,0x00,0xC0,0xF1,0xF9,0x07,0x00,0x00,0x80,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 228 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x00,0x30,0x30,0x38,0x00,0x00,0x70,0x38,0x30,0x30,0x00,0x00,0xF8,0x18,0x38,0x30,0x00,0x00,0x8C,0x19,0x18,0x30,0x00,0x00,0x8C,0x19,0x18,0x30,0x00,0x00,0x8C,0x19,0x18,0x30,0x00,0x00,0x8C,0x19,0x18,0x18,0x00,0x00,0xF8,0x38,0x18,0x0C,0x00,0x00,0x70,0xF0,0xF9,0x07,0x00,0x00,0x00,0xF0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 229 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x10,0xE0,0x1F,0x00,0x00,0x00,0x30,0xF0,0x1C,0x00,0x00,0x00,0x30,0x30,0x38,0x00,0x00,0x00,0x18,0x30,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x38,0x18,0x18,0x00,0x00,0x00,0x70,0x18,0x0E,0x00,0x00,0x00,0xF0,0xFF,0x07,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x18,0x1E,0x00,0x00,0x00,0x30,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x38,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x38,0x18,0x30,0x00,0x00,0x00,0x70,0x18,0x30,0x00,0x00,0x00,0xF0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 230 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x30,0x00,0x18,0x30,0x00,0x00,0x38,0x00,0x38,0x31,0x00,0x00,0x18,0x00,0xF0,0x31,0x00,0x00,0x18,0x00,0xF0,0x33,0x00,0x00,0x18,0x00,0x30,0x1F,0x00,0x00,0x18,0x00,0x30,0x1E,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x10,0x00,0x18, // 231 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x18,0x1E,0x00,0x00,0x10,0x30,0x18,0x1C,0x00,0x00,0x30,0x38,0x18,0x38,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0xE0,0x18,0x18,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0x00,0x19,0x18,0x30,0x00,0x00,0x00,0x38,0x18,0x30,0x00,0x00,0x00,0x70,0x18,0x30,0x00,0x00,0x00,0xE0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 232 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x18,0x1E,0x00,0x00,0x00,0x30,0x18,0x1C,0x00,0x00,0x00,0x38,0x18,0x38,0x00,0x00,0x00,0x19,0x18,0x30,0x00,0x00,0xC0,0x19,0x18,0x30,0x00,0x00,0xE0,0x18,0x18,0x30,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0x30,0x38,0x18,0x30,0x00,0x00,0x10,0x70,0x18,0x30,0x00,0x00,0x00,0xE0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 233 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF1,0x18,0x1E,0x00,0x00,0x80,0x31,0x18,0x1C,0x00,0x00,0xE0,0x38,0x18,0x38,0x00,0x00,0xF0,0x18,0x18,0x30,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0x70,0x18,0x18,0x30,0x00,0x00,0xF0,0x18,0x18,0x30,0x00,0x00,0xC0,0x38,0x18,0x30,0x00,0x00,0x80,0x71,0x18,0x30,0x00,0x00,0x00,0xE1,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 234 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x80,0xF0,0x18,0x1E,0x00,0x00,0xC0,0x31,0x18,0x1C,0x00,0x00,0xC0,0x39,0x18,0x38,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0xC0,0x39,0x18,0x30,0x00,0x00,0xC0,0x71,0x18,0x30,0x00,0x00,0x80,0xE0,0x1F,0x38,0x00,0x00,0x00,0xC0,0x1F,0x18,0x00,0x00,0x00,0x80,0x1F, // 235 - 0x10,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0xFF,0x3F,0x00,0x00,0xC0,0xF9,0xFF,0x3F,0x00,0x00,0x00,0xF9,0xFF,0x3F, // 236 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF9,0xFF,0x3F,0x00,0x00,0xC0,0xF9,0xFF,0x3F,0x00,0x00,0xE0,0xF8,0xFF,0x3F,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x10, // 237 - 0x80,0x01,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x70,0xF8,0xFF,0x3F,0x00,0x00,0x70,0xF8,0xFF,0x3F,0x00,0x00,0xF0,0xF8,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x01, // 238 - 0x80,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x01, // 239 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0x00,0x80,0x03,0x1C,0x00,0x00,0x20,0x8E,0x01,0x18,0x00,0x00,0x70,0xC6,0x00,0x38,0x00,0x00,0x60,0xC7,0x00,0x30,0x00,0x00,0xE0,0xC3,0x00,0x30,0x00,0x00,0xC0,0xC1,0x00,0x30,0x00,0x00,0xC0,0xC3,0x00,0x30,0x00,0x00,0xC0,0xC7,0x00,0x30,0x00,0x00,0xE0,0x8F,0x01,0x18,0x00,0x00,0x60,0xBE,0x03,0x1C,0x00,0x00,0x70,0xF8,0x8F,0x0F,0x00,0x00,0x00,0xF0,0xFF,0x07,0x00,0x00,0x00,0x80,0xFF,0x01, // 240 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF9,0xFF,0x3F,0x00,0x00,0xC0,0xE1,0xFF,0x3F,0x00,0x00,0xE0,0x60,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x00,0x00,0x00,0xE0,0x18,0x00,0x00,0x00,0x00,0xC0,0x18,0x00,0x00,0x00,0x00,0xC0,0x19,0x00,0x00,0x00,0x00,0x80,0x19,0x00,0x00,0x00,0x00,0x80,0x19,0x00,0x00,0x00,0x00,0xC0,0x39,0x00,0x00,0x00,0x00,0xE0,0xF0,0xFF,0x3F,0x00,0x00,0x20,0xE0,0xFF,0x3F,0x00,0x00,0x00,0xC0,0xFF,0x3F, // 241 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x10,0x70,0x00,0x1C,0x00,0x00,0x30,0x38,0x00,0x38,0x00,0x00,0x70,0x18,0x00,0x30,0x00,0x00,0xE0,0x18,0x00,0x30,0x00,0x00,0xC0,0x19,0x00,0x30,0x00,0x00,0x00,0x19,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 242 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x19,0x00,0x30,0x00,0x00,0xC0,0x19,0x00,0x30,0x00,0x00,0xE0,0x18,0x00,0x30,0x00,0x00,0x70,0x18,0x00,0x30,0x00,0x00,0x30,0x18,0x00,0x30,0x00,0x00,0x10,0x38,0x00,0x38,0x00,0x00,0x00,0x70,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 243 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xF1,0x00,0x1E,0x00,0x00,0x80,0x71,0x00,0x1C,0x00,0x00,0xE0,0x38,0x00,0x38,0x00,0x00,0xF0,0x18,0x00,0x30,0x00,0x00,0x70,0x18,0x00,0x30,0x00,0x00,0x70,0x18,0x00,0x30,0x00,0x00,0xF0,0x18,0x00,0x30,0x00,0x00,0xC0,0x18,0x00,0x30,0x00,0x00,0x80,0x39,0x00,0x38,0x00,0x00,0x00,0x71,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 244 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE1,0xFF,0x0F,0x00,0x00,0xC0,0xF1,0x00,0x1E,0x00,0x00,0xE0,0x70,0x00,0x1C,0x00,0x00,0x60,0x38,0x00,0x38,0x00,0x00,0x60,0x18,0x00,0x30,0x00,0x00,0xE0,0x18,0x00,0x30,0x00,0x00,0xC0,0x18,0x00,0x30,0x00,0x00,0xC0,0x19,0x00,0x30,0x00,0x00,0x80,0x19,0x00,0x30,0x00,0x00,0x80,0x39,0x00,0x38,0x00,0x00,0xC0,0x71,0x00,0x1C,0x00,0x00,0xE0,0xF0,0x00,0x1E,0x00,0x00,0x20,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 245 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x80,0xF0,0x00,0x1E,0x00,0x00,0xC0,0x71,0x00,0x1C,0x00,0x00,0xC0,0x39,0x00,0x38,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0xC0,0x19,0x00,0x30,0x00,0x00,0xC0,0x39,0x00,0x38,0x00,0x00,0x80,0x70,0x00,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 246 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x3C,0xC6,0x03,0x00,0x00,0x00,0x3C,0xC6,0x03,0x00,0x00,0x00,0x3C,0xC6,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06, // 247 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xC0,0xFF,0x33,0x00,0x00,0x00,0xE0,0xFF,0x7F,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0x70,0x00,0x1F,0x00,0x00,0x00,0x38,0x80,0x3F,0x00,0x00,0x00,0x18,0xE0,0x31,0x00,0x00,0x00,0x18,0xF0,0x30,0x00,0x00,0x00,0x18,0x7C,0x30,0x00,0x00,0x00,0x18,0x1E,0x30,0x00,0x00,0x00,0x18,0x0F,0x30,0x00,0x00,0x00,0xF8,0x03,0x38,0x00,0x00,0x00,0xF0,0x01,0x1C,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xFC,0xFF,0x0F,0x00,0x00,0x00,0x98,0xFF,0x07,0x00,0x00,0x00,0x00,0xFE, // 248 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0x10,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0xE0,0x00,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 249 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x01,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0xE0,0x00,0x00,0x30,0x00,0x00,0x70,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x18,0x00,0x00,0x10,0x00,0x00,0x0E,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 250 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF9,0xFF,0x1F,0x00,0x00,0x80,0x01,0x00,0x38,0x00,0x00,0xE0,0x00,0x00,0x30,0x00,0x00,0xF0,0x00,0x00,0x30,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0xF0,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x18,0x00,0x00,0x80,0x01,0x00,0x18,0x00,0x00,0x00,0x01,0x00,0x0E,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 251 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x00,0x00,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0x80,0x00,0x00,0x38,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0xC0,0x01,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x18,0x00,0x00,0xC0,0x01,0x00,0x0E,0x00,0x00,0x80,0xF8,0xFF,0x0F,0x00,0x00,0x00,0xF8,0xFF,0x3F,0x00,0x00,0x00,0xF8,0xFF,0x3F, // 252 - 0x00,0x08,0x00,0x00,0x30,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0x00,0xF8,0x01,0x00,0x30,0x00,0x00,0xF0,0x0F,0x00,0x30,0x00,0x00,0x80,0x7F,0x00,0x38,0x00,0x00,0x00,0xFC,0x01,0x1C,0x00,0x00,0x00,0xF0,0x0F,0x1F,0x00,0x00,0x01,0x80,0xFF,0x0F,0x00,0xC0,0x01,0x00,0xF8,0x03,0x00,0xE0,0x00,0x00,0x7F,0x00,0x00,0x70,0x00,0xE0,0x1F,0x00,0x00,0x30,0x00,0xFC,0x03,0x00,0x00,0x10,0x80,0x7F,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x08, // 253 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0xF0,0xFF,0xFF,0xFF,0x3F,0x00,0x00,0x60,0x00,0x0E,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0xF0,0x00,0x1E,0x00,0x00,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0xFF,0x01, // 254 - 0x00,0x08,0x00,0x00,0x30,0x00,0x00,0x78,0x00,0x00,0x30,0x00,0x00,0xF8,0x01,0x00,0x30,0x00,0x00,0xF0,0x0F,0x00,0x30,0x00,0x80,0x80,0x7F,0x00,0x38,0x00,0xC0,0x01,0xFC,0x01,0x1C,0x00,0xC0,0x01,0xF0,0x0F,0x1F,0x00,0x00,0x00,0x80,0xFF,0x0F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0xE0,0x1F,0x00,0x00,0xC0,0x01,0xFC,0x03,0x00,0x00,0xC0,0x81,0x7F,0x00,0x00,0x00,0x80,0xF0,0x1F,0x00,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x08 // 255 -}; diff --git a/src/fonts/opensans50.h b/src/fonts/opensans50.h deleted file mode 100644 index 2da7441d..00000000 --- a/src/fonts/opensans50.h +++ /dev/null @@ -1,34 +0,0 @@ -// Font table version: 3 -// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator. -// In case of problems make sure that you are using the font file with the correct version! -// contains "0123456789" -const uint8_t Open_Sans_Regular_Plain_50[] PROGMEM = { - 0x1D, // Width: 29 - 0x45, // Height: 69 - 0x30, // First Char: 48 - 0x0A, // Numbers of Chars: 10 - - // Jump Table: - 0x00, 0x00, 0xE6, 0x1D, // 48=0:0 - 0x00, 0xE6, 0x9F, 0x1D, // 49=1:230 - 0x01, 0x85, 0xE7, 0x1D, // 50=2:389 - 0x02, 0x6C, 0xE6, 0x1D, // 51=3:620 - 0x03, 0x52, 0xF8, 0x1D, // 52=4:850 - 0x04, 0x4A, 0xE6, 0x1D, // 53=5:1098 - 0x05, 0x30, 0xEF, 0x1D, // 54=6:1328 - 0x06, 0x1F, 0xE3, 0x1D, // 55=7:1567 - 0x07, 0x02, 0xE6, 0x1D, // 56=8:1794 - 0x07, 0xE8, 0xE5, 0x1D, // 57=9:2024 - - // Font Data: - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0xF8,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x07, // 48 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F, // 49 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0xF8,0x0F,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0xFC,0x0E,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x7E,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x3F,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x80,0x1F,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0xC0,0x0F,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0xE0,0x07,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0xF0,0x03,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0xF8,0x01,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0xFC,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0x00,0x7E,0x00,0x0E,0x00,0x00,0x00,0x00,0x0E,0x00,0x3F,0x00,0x0E,0x00,0x00,0x00,0x00,0x3E,0xC0,0x1F,0x00,0x0E,0x00,0x00,0x00,0x00,0xFC,0xFC,0x0F,0x00,0x0E,0x00,0x00,0x00,0x00,0xFC,0xFF,0x03,0x00,0x0E,0x00,0x00,0x00,0x00,0xF8,0xFF,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0xE0,0x7F,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E, // 50 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x0E,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x80,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0x80,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x0E,0xC0,0x0D,0x00,0x07,0x00,0x00,0x00,0x00,0x1E,0xE0,0x1D,0x80,0x07,0x00,0x00,0x00,0x00,0x7E,0xF8,0x3C,0xC0,0x03,0x00,0x00,0x00,0x00,0xFC,0xFF,0xFC,0xF0,0x03,0x00,0x00,0x00,0x00,0xF8,0x7F,0xF8,0xFF,0x01,0x00,0x00,0x00,0x00,0xF0,0x3F,0xF0,0xFF,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0xE0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F, // 51 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, // 52 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x80,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0xFF,0xFF,0x03,0x00,0x0F,0x00,0x00,0x00,0x00,0xFF,0xC1,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x80,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x80,0x07,0x80,0x07,0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0xC0,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0x3F,0xF0,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x07,0x00,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F, // 53 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0x1C,0xF8,0x01,0x00,0x00,0x00,0x00,0xF0,0x03,0x0E,0xE0,0x03,0x00,0x00,0x00,0x00,0xF8,0x00,0x07,0x80,0x07,0x00,0x00,0x00,0x00,0x7C,0x80,0x03,0x80,0x07,0x00,0x00,0x00,0x00,0x3C,0x80,0x03,0x00,0x0F,0x00,0x00,0x00,0x00,0x1E,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x0E,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x0E,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x01,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x03,0x00,0x0F,0x00,0x00,0x00,0x00,0x07,0xC0,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x80,0x07,0x80,0x07,0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0xFF,0xFE,0x03,0x00,0x00,0x00,0x00,0x0F,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, // 54 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xF0,0x0F,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xFC,0x0F,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xF0,0x3F,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F, // 55 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xE0,0xFF,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0xF0,0xFF,0x01,0x00,0x00,0x00,0x00,0xFC,0x3F,0xF8,0xFF,0x03,0x00,0x00,0x00,0x00,0xFC,0x7F,0x7C,0xC0,0x07,0x00,0x00,0x00,0x00,0x1E,0xF8,0x1E,0x80,0x07,0x00,0x00,0x00,0x00,0x0E,0xF0,0x0E,0x00,0x07,0x00,0x00,0x00,0x00,0x0F,0xE0,0x0F,0x00,0x0F,0x00,0x00,0x00,0x00,0x07,0xC0,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x80,0x03,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x80,0x03,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x80,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0xE0,0x0F,0x00,0x0F,0x00,0x00,0x00,0x00,0x1E,0xF0,0x1E,0x00,0x07,0x00,0x00,0x00,0x00,0x3E,0x78,0x3C,0x80,0x07,0x00,0x00,0x00,0x00,0xFC,0x7F,0x7C,0xC0,0x03,0x00,0x00,0x00,0x00,0xFC,0x3F,0xF8,0xFF,0x03,0x00,0x00,0x00,0x00,0xF8,0x1F,0xF0,0xFF,0x01,0x00,0x00,0x00,0x00,0xE0,0x07,0xE0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F, // 56 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x07,0x00,0x0F,0x00,0x00,0x00,0x00,0xFC,0xFF,0x0F,0x00,0x0E,0x00,0x00,0x00,0x00,0x7C,0x00,0x1F,0x00,0x0E,0x00,0x00,0x00,0x00,0x1E,0x00,0x1E,0x00,0x0E,0x00,0x00,0x00,0x00,0x0E,0x00,0x3C,0x00,0x0E,0x00,0x00,0x00,0x00,0x0F,0x00,0x3C,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x00,0x0E,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x38,0x80,0x07,0x00,0x00,0x00,0x00,0x0F,0x00,0x1C,0x80,0x03,0x00,0x00,0x00,0x00,0x0E,0x00,0x1C,0xC0,0x03,0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0xF0,0x01,0x00,0x00,0x00,0x00,0x7C,0x00,0x07,0xFC,0x01,0x00,0x00,0x00,0x00,0xF8,0x81,0x83,0xFF,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F // 57 -}; diff --git a/src/fonts/opensans8.h b/src/fonts/opensans8.h deleted file mode 100644 index 248a6116..00000000 --- a/src/fonts/opensans8.h +++ /dev/null @@ -1,458 +0,0 @@ -// Font table version: 3 -// Created by FontCreator (https://github.com/arcao/esp8266-oled-ssd1306-font-creator. -// In case of problems make sure that you are using the font file with the correct version! -const uint8_t Open_Sans_Regular_Plain_8[] PROGMEM = { - 0x07, // Width: 7 - 0x0C, // Height: 12 - 0x20, // First Char: 32 - 0xE0, // Numbers of Chars: 224 - - // Jump Table: - 0xFF, 0xFF, 0x00, 0x02, // 32= :65535 - 0x00, 0x00, 0x04, 0x02, // 33=!:0 - 0x00, 0x04, 0x05, 0x03, // 34=":4 - 0x00, 0x09, 0x07, 0x05, // 35=#:9 - 0x00, 0x10, 0x07, 0x05, // 36=$:16 - 0x00, 0x17, 0x0C, 0x07, // 37=%:23 - 0x00, 0x23, 0x0A, 0x06, // 38=&:35 - 0x00, 0x2D, 0x01, 0x02, // 39=':45 - 0x00, 0x2E, 0x04, 0x02, // 40=(:46 - 0x00, 0x32, 0x04, 0x02, // 41=):50 - 0x00, 0x36, 0x07, 0x04, // 42=*:54 - 0x00, 0x3D, 0x07, 0x05, // 43=+:61 - 0x00, 0x44, 0x02, 0x02, // 44=,:68 - 0x00, 0x46, 0x03, 0x03, // 45=-:70 - 0x00, 0x49, 0x04, 0x02, // 46=.:73 - 0x00, 0x4D, 0x05, 0x03, // 47=/:77 - 0x00, 0x52, 0x08, 0x05, // 48=0:82 - 0x00, 0x5A, 0x06, 0x05, // 49=1:90 - 0x00, 0x60, 0x08, 0x05, // 50=2:96 - 0x00, 0x68, 0x08, 0x05, // 51=3:104 - 0x00, 0x70, 0x08, 0x05, // 52=4:112 - 0x00, 0x78, 0x08, 0x05, // 53=5:120 - 0x00, 0x80, 0x08, 0x05, // 54=6:128 - 0x00, 0x88, 0x07, 0x05, // 55=7:136 - 0x00, 0x8F, 0x08, 0x05, // 56=8:143 - 0x00, 0x97, 0x07, 0x05, // 57=9:151 - 0x00, 0x9E, 0x04, 0x02, // 58=::158 - 0x00, 0xA2, 0x02, 0x02, // 59=;:162 - 0x00, 0xA4, 0x07, 0x05, // 60=<:164 - 0x00, 0xAB, 0x07, 0x05, // 61==:171 - 0x00, 0xB2, 0x07, 0x05, // 62=>:178 - 0x00, 0xB9, 0x05, 0x03, // 63=?:185 - 0x00, 0xBE, 0x0D, 0x07, // 64=@:190 - 0x00, 0xCB, 0x0A, 0x05, // 65=A:203 - 0x00, 0xD5, 0x09, 0x05, // 66=B:213 - 0x00, 0xDE, 0x0A, 0x05, // 67=C:222 - 0x00, 0xE8, 0x09, 0x06, // 68=D:232 - 0x00, 0xF1, 0x08, 0x04, // 69=E:241 - 0x00, 0xF9, 0x07, 0x04, // 70=F:249 - 0x01, 0x00, 0x0A, 0x06, // 71=G:256 - 0x01, 0x0A, 0x0A, 0x06, // 72=H:266 - 0x01, 0x14, 0x04, 0x02, // 73=I:276 - 0x01, 0x18, 0x02, 0x02, // 74=J:280 - 0x01, 0x1A, 0x0A, 0x05, // 75=K:282 - 0x01, 0x24, 0x08, 0x04, // 76=L:292 - 0x01, 0x2C, 0x0C, 0x07, // 77=M:300 - 0x01, 0x38, 0x0A, 0x06, // 78=N:312 - 0x01, 0x42, 0x0B, 0x06, // 79=O:322 - 0x01, 0x4D, 0x07, 0x05, // 80=P:333 - 0x01, 0x54, 0x0B, 0x06, // 81=Q:340 - 0x01, 0x5F, 0x0A, 0x05, // 82=R:351 - 0x01, 0x69, 0x08, 0x04, // 83=S:361 - 0x01, 0x71, 0x07, 0x04, // 84=T:369 - 0x01, 0x78, 0x0A, 0x06, // 85=U:376 - 0x01, 0x82, 0x09, 0x05, // 86=V:386 - 0x01, 0x8B, 0x0D, 0x07, // 87=W:395 - 0x01, 0x98, 0x08, 0x05, // 88=X:408 - 0x01, 0xA0, 0x07, 0x04, // 89=Y:416 - 0x01, 0xA7, 0x08, 0x05, // 90=Z:423 - 0x01, 0xAF, 0x04, 0x03, // 91=[:431 - 0x01, 0xB3, 0x06, 0x03, // 92=\:435 - 0x01, 0xB9, 0x04, 0x03, // 93=]:441 - 0x01, 0xBD, 0x07, 0x04, // 94=^:445 - 0x01, 0xC4, 0x06, 0x04, // 95=_:452 - 0x01, 0xCA, 0x05, 0x05, // 96=`:458 - 0x01, 0xCF, 0x08, 0x04, // 97=a:463 - 0x01, 0xD7, 0x08, 0x05, // 98=b:471 - 0x01, 0xDF, 0x06, 0x04, // 99=c:479 - 0x01, 0xE5, 0x08, 0x05, // 100=d:485 - 0x01, 0xED, 0x08, 0x04, // 101=e:493 - 0x01, 0xF5, 0x05, 0x03, // 102=f:501 - 0x01, 0xFA, 0x08, 0x04, // 103=g:506 - 0x02, 0x02, 0x08, 0x05, // 104=h:514 - 0x02, 0x0A, 0x04, 0x02, // 105=i:522 - 0x02, 0x0E, 0x02, 0x02, // 106=j:526 - 0x02, 0x10, 0x08, 0x04, // 107=k:528 - 0x02, 0x18, 0x04, 0x02, // 108=l:536 - 0x02, 0x1C, 0x0E, 0x07, // 109=m:540 - 0x02, 0x2A, 0x08, 0x05, // 110=n:554 - 0x02, 0x32, 0x08, 0x05, // 111=o:562 - 0x02, 0x3A, 0x08, 0x05, // 112=p:570 - 0x02, 0x42, 0x08, 0x05, // 113=q:578 - 0x02, 0x4A, 0x04, 0x03, // 114=r:586 - 0x02, 0x4E, 0x06, 0x04, // 115=s:590 - 0x02, 0x54, 0x06, 0x03, // 116=t:596 - 0x02, 0x5A, 0x08, 0x05, // 117=u:602 - 0x02, 0x62, 0x07, 0x04, // 118=v:610 - 0x02, 0x69, 0x0B, 0x06, // 119=w:617 - 0x02, 0x74, 0x08, 0x04, // 120=x:628 - 0x02, 0x7C, 0x07, 0x04, // 121=y:636 - 0x02, 0x83, 0x06, 0x04, // 122=z:643 - 0x02, 0x89, 0x05, 0x03, // 123={:649 - 0x02, 0x8E, 0x06, 0x04, // 124=|:654 - 0x02, 0x94, 0x05, 0x03, // 125=}:660 - 0x02, 0x99, 0x07, 0x05, // 126=~:665 - 0x02, 0xA0, 0x08, 0x05, // 127=:672 - 0x02, 0xA8, 0x08, 0x05, // 128=€:680 - 0x02, 0xB0, 0x08, 0x05, // 129=:688 - 0x02, 0xB8, 0x08, 0x05, // 130=‚:696 - 0x02, 0xC0, 0x08, 0x05, // 131=ƒ:704 - 0x02, 0xC8, 0x08, 0x05, // 132=„:712 - 0x02, 0xD0, 0x08, 0x05, // 133=…:720 - 0x02, 0xD8, 0x08, 0x05, // 134=†:728 - 0x02, 0xE0, 0x08, 0x05, // 135=‡:736 - 0x02, 0xE8, 0x08, 0x05, // 136=ˆ:744 - 0x02, 0xF0, 0x08, 0x05, // 137=‰:752 - 0x02, 0xF8, 0x08, 0x05, // 138=Š:760 - 0x03, 0x00, 0x08, 0x05, // 139=‹:768 - 0x03, 0x08, 0x08, 0x05, // 140=Œ:776 - 0x03, 0x10, 0x08, 0x05, // 141=:784 - 0x03, 0x18, 0x08, 0x05, // 142=Ž:792 - 0x03, 0x20, 0x08, 0x05, // 143=:800 - 0x03, 0x28, 0x08, 0x05, // 144=:808 - 0x03, 0x30, 0x08, 0x05, // 145=‘:816 - 0x03, 0x38, 0x08, 0x05, // 146=’:824 - 0x03, 0x40, 0x08, 0x05, // 147=“:832 - 0x03, 0x48, 0x08, 0x05, // 148=”:840 - 0x03, 0x50, 0x08, 0x05, // 149=•:848 - 0x03, 0x58, 0x08, 0x05, // 150=–:856 - 0x03, 0x60, 0x08, 0x05, // 151=—:864 - 0x03, 0x68, 0x08, 0x05, // 152=˜:872 - 0x03, 0x70, 0x08, 0x05, // 153=™:880 - 0x03, 0x78, 0x08, 0x05, // 154=š:888 - 0x03, 0x80, 0x08, 0x05, // 155=›:896 - 0x03, 0x88, 0x08, 0x05, // 156=œ:904 - 0x03, 0x90, 0x08, 0x05, // 157=:912 - 0x03, 0x98, 0x08, 0x05, // 158=ž:920 - 0x03, 0xA0, 0x08, 0x05, // 159=Ÿ:928 - 0xFF, 0xFF, 0x00, 0x02, // 160= :65535 - 0x03, 0xA8, 0x04, 0x02, // 161=¡:936 - 0x03, 0xAC, 0x07, 0x05, // 162=¢:940 - 0x03, 0xB3, 0x08, 0x05, // 163=£:947 - 0x03, 0xBB, 0x08, 0x05, // 8364=€:955 - 0x03, 0xC3, 0x07, 0x05, // 165=¥:963 - 0x03, 0xCA, 0x08, 0x04, // 352=Š:970 - 0x03, 0xD2, 0x07, 0x04, // 167=§:978 - 0x03, 0xD9, 0x06, 0x04, // 353=š:985 - 0x03, 0xDF, 0x0B, 0x07, // 169=©:991 - 0x03, 0xEA, 0x03, 0x03, // 170=ª:1002 - 0x03, 0xED, 0x07, 0x04, // 171=«:1005 - 0x03, 0xF4, 0x07, 0x05, // 172=¬:1012 - 0x03, 0xFB, 0x03, 0x03, // 173=­:1019 - 0x03, 0xFE, 0x0B, 0x07, // 174=®:1022 - 0x04, 0x09, 0x07, 0x04, // 175=¯:1033 - 0x04, 0x10, 0x05, 0x03, // 176=°:1040 - 0x04, 0x15, 0x08, 0x05, // 177=±:1045 - 0x04, 0x1D, 0x05, 0x03, // 178=²:1053 - 0x04, 0x22, 0x05, 0x03, // 179=³:1058 - 0x04, 0x27, 0x08, 0x05, // 381=Ž:1063 - 0x04, 0x2F, 0x08, 0x05, // 181=µ:1071 - 0x04, 0x37, 0x08, 0x05, // 182=¶:1079 - 0xFF, 0xFF, 0x00, 0x02, // 183=·:65535 - 0x04, 0x3F, 0x06, 0x04, // 382=ž:1087 - 0x04, 0x45, 0x03, 0x03, // 185=¹:1093 - 0x04, 0x48, 0x05, 0x03, // 186=º:1096 - 0x04, 0x4D, 0x07, 0x04, // 187=»:1101 - 0x04, 0x54, 0x0E, 0x07, // 338=Œ:1108 - 0x04, 0x62, 0x0E, 0x08, // 339=œ:1122 - 0x04, 0x70, 0x07, 0x04, // 376=Ÿ:1136 - 0x04, 0x77, 0x06, 0x03, // 191=¿:1143 - 0x04, 0x7D, 0x0A, 0x05, // 192=À:1149 - 0x04, 0x87, 0x0A, 0x05, // 193=Á:1159 - 0x04, 0x91, 0x0A, 0x05, // 194=Â:1169 - 0x04, 0x9B, 0x0A, 0x05, // 195=Ã:1179 - 0x04, 0xA5, 0x0A, 0x05, // 196=Ä:1189 - 0x04, 0xAF, 0x0A, 0x05, // 197=Å:1199 - 0x04, 0xB9, 0x0E, 0x07, // 198=Æ:1209 - 0x04, 0xC7, 0x0A, 0x05, // 199=Ç:1223 - 0x04, 0xD1, 0x08, 0x04, // 200=È:1233 - 0x04, 0xD9, 0x08, 0x04, // 201=É:1241 - 0x04, 0xE1, 0x08, 0x04, // 202=Ê:1249 - 0x04, 0xE9, 0x08, 0x04, // 203=Ë:1257 - 0x04, 0xF1, 0x04, 0x02, // 204=Ì:1265 - 0x04, 0xF5, 0x04, 0x02, // 205=Í:1269 - 0x04, 0xF9, 0x04, 0x02, // 206=Î:1273 - 0x04, 0xFD, 0x04, 0x02, // 207=Ï:1277 - 0x05, 0x01, 0x09, 0x06, // 208=Ð:1281 - 0x05, 0x0A, 0x0A, 0x06, // 209=Ñ:1290 - 0x05, 0x14, 0x0B, 0x06, // 210=Ò:1300 - 0x05, 0x1F, 0x0B, 0x06, // 211=Ó:1311 - 0x05, 0x2A, 0x0B, 0x06, // 212=Ô:1322 - 0x05, 0x35, 0x0B, 0x06, // 213=Õ:1333 - 0x05, 0x40, 0x0B, 0x06, // 214=Ö:1344 - 0x05, 0x4B, 0x07, 0x05, // 215=×:1355 - 0x05, 0x52, 0x0B, 0x06, // 216=Ø:1362 - 0x05, 0x5D, 0x0A, 0x06, // 217=Ù:1373 - 0x05, 0x67, 0x0A, 0x06, // 218=Ú:1383 - 0x05, 0x71, 0x0A, 0x06, // 219=Û:1393 - 0x05, 0x7B, 0x0A, 0x06, // 220=Ü:1403 - 0x05, 0x85, 0x07, 0x04, // 221=Ý:1413 - 0x05, 0x8C, 0x07, 0x05, // 222=Þ:1420 - 0x05, 0x93, 0x09, 0x05, // 223=ß:1427 - 0x05, 0x9C, 0x08, 0x04, // 224=à:1436 - 0x05, 0xA4, 0x08, 0x04, // 225=á:1444 - 0x05, 0xAC, 0x08, 0x04, // 226=â:1452 - 0x05, 0xB4, 0x08, 0x04, // 227=ã:1460 - 0x05, 0xBC, 0x08, 0x04, // 228=ä:1468 - 0x05, 0xC4, 0x08, 0x04, // 229=å:1476 - 0x05, 0xCC, 0x0C, 0x07, // 230=æ:1484 - 0x05, 0xD8, 0x06, 0x04, // 231=ç:1496 - 0x05, 0xDE, 0x08, 0x04, // 232=è:1502 - 0x05, 0xE6, 0x08, 0x04, // 233=é:1510 - 0x05, 0xEE, 0x08, 0x04, // 234=ê:1518 - 0x05, 0xF6, 0x08, 0x04, // 235=ë:1526 - 0x05, 0xFE, 0x02, 0x02, // 236=ì:1534 - 0x06, 0x00, 0x04, 0x02, // 237=í:1536 - 0x06, 0x04, 0x04, 0x02, // 238=î:1540 - 0x06, 0x08, 0x04, 0x02, // 239=ï:1544 - 0x06, 0x0C, 0x08, 0x05, // 240=ð:1548 - 0x06, 0x14, 0x08, 0x05, // 241=ñ:1556 - 0x06, 0x1C, 0x08, 0x05, // 242=ò:1564 - 0x06, 0x24, 0x08, 0x05, // 243=ó:1572 - 0x06, 0x2C, 0x08, 0x05, // 244=ô:1580 - 0x06, 0x34, 0x08, 0x05, // 245=õ:1588 - 0x06, 0x3C, 0x08, 0x05, // 246=ö:1596 - 0x06, 0x44, 0x07, 0x05, // 247=÷:1604 - 0x06, 0x4B, 0x08, 0x05, // 248=ø:1611 - 0x06, 0x53, 0x08, 0x05, // 249=ù:1619 - 0x06, 0x5B, 0x08, 0x05, // 250=ú:1627 - 0x06, 0x63, 0x08, 0x05, // 251=û:1635 - 0x06, 0x6B, 0x08, 0x05, // 252=ü:1643 - 0x06, 0x73, 0x07, 0x04, // 253=ý:1651 - 0x06, 0x7A, 0x08, 0x05, // 254=þ:1658 - 0x06, 0x82, 0x07, 0x04, // 255=ÿ:1666 - - // Font Data: - 0x00,0x00,0x70,0x01, // 33 - 0x00,0x00,0x10,0x00,0x18, // 34 - 0x00,0x00,0xE0,0x01,0x90,0x01,0xF0, // 35 - 0x00,0x00,0x30,0x01,0xF8,0x01,0xC0, // 36 - 0x30,0x00,0x48,0x01,0xB0,0x00,0x60,0x00,0xB8,0x01,0xC0,0x01, // 37 - 0x80,0x00,0x78,0x01,0x68,0x01,0x90,0x01,0x80,0x01, // 38 - 0x10, // 39 - 0xE0,0x01,0x18,0x02, // 40 - 0x08,0x00,0xF0,0x03, // 41 - 0x10,0x00,0x30,0x00,0x38,0x00,0x10, // 42 - 0x00,0x00,0x40,0x00,0xF0,0x00,0x40, // 43 - 0x00,0x02, // 44 - 0x00,0x00,0x40, // 45 - 0x00,0x00,0x00,0x01, // 46 - 0x80,0x01,0x60,0x00,0x18, // 47 - 0xF0,0x00,0x08,0x01,0x08,0x01,0xF0,0x01, // 48 - 0x00,0x00,0x10,0x00,0xF8,0x01, // 49 - 0x00,0x01,0x88,0x01,0x48,0x01,0x30,0x01, // 50 - 0x00,0x01,0x08,0x01,0x48,0x01,0xF0,0x01, // 51 - 0xC0,0x00,0xA0,0x00,0x90,0x00,0xF8,0x01, // 52 - 0x00,0x00,0x38,0x01,0x28,0x01,0xC8,0x01, // 53 - 0xE0,0x00,0x50,0x01,0x28,0x01,0xC8,0x01, // 54 - 0x08,0x00,0x08,0x01,0xC8,0x00,0x38, // 55 - 0x90,0x00,0x68,0x01,0x48,0x01,0xF0,0x01, // 56 - 0x30,0x00,0x48,0x01,0x48,0x01,0xF0, // 57 - 0x00,0x00,0x00,0x01, // 58 - 0x00,0x02, // 59 - 0x00,0x00,0x60,0x00,0xA0,0x00,0x90, // 60 - 0x20,0x00,0x60,0x00,0x60,0x00,0x60, // 61 - 0x90,0x00,0x90,0x00,0x60,0x00,0x40, // 62 - 0x08,0x00,0x48,0x01,0x38, // 63 - 0xE0,0x00,0x10,0x01,0xE8,0x02,0xA8,0x02,0xE8,0x02,0x90,0x00,0xE0, // 64 - 0x80,0x01,0x60,0x00,0x58,0x00,0x60,0x00,0x80,0x01, // 65 - 0x00,0x00,0xF8,0x01,0x48,0x01,0x28,0x01,0xD0, // 66 - 0x60,0x00,0x90,0x01,0x08,0x01,0x08,0x01,0x08,0x01, // 67 - 0x00,0x00,0xF8,0x01,0x08,0x01,0x08,0x01,0xF0, // 68 - 0x00,0x00,0xF8,0x01,0x48,0x01,0x08,0x01, // 69 - 0x00,0x00,0xF8,0x01,0x48,0x00,0x48, // 70 - 0x60,0x00,0x90,0x01,0x08,0x01,0x48,0x01,0xC8,0x01, // 71 - 0x00,0x00,0xF0,0x01,0x40,0x00,0x40,0x00,0xF8,0x01, // 72 - 0x00,0x00,0xF0,0x01, // 73 - 0xF0,0x03, // 74 - 0x00,0x00,0xF0,0x01,0x60,0x00,0x90,0x00,0x08,0x01, // 75 - 0x00,0x00,0xF0,0x01,0x00,0x01,0x00,0x01, // 76 - 0x00,0x00,0xF8,0x01,0x60,0x00,0x80,0x01,0x60,0x00,0xF8,0x01, // 77 - 0x00,0x00,0xF8,0x01,0x20,0x00,0xC0,0x00,0xF0,0x01, // 78 - 0x60,0x00,0x90,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0xF0, // 79 - 0x00,0x00,0xF8,0x01,0x48,0x00,0x38, // 80 - 0x60,0x00,0x90,0x01,0x08,0x01,0x08,0x01,0x08,0x03,0xF0, // 81 - 0x00,0x00,0xF8,0x01,0x48,0x00,0xA8,0x00,0x10,0x01, // 82 - 0x10,0x01,0x28,0x01,0x48,0x01,0xC8,0x01, // 83 - 0x08,0x00,0x08,0x00,0xF8,0x01,0x08, // 84 - 0x00,0x00,0xF0,0x01,0x00,0x01,0x00,0x01,0xF8,0x01, // 85 - 0x18,0x00,0xE0,0x00,0x80,0x01,0x70,0x00,0x08, // 86 - 0x18,0x00,0xE0,0x01,0xE0,0x00,0x18,0x00,0xE0,0x00,0x80,0x01,0x70, // 87 - 0x08,0x01,0x90,0x00,0x60,0x00,0x90,0x01, // 88 - 0x08,0x00,0x30,0x00,0xE0,0x01,0x10, // 89 - 0x08,0x01,0x88,0x01,0x68,0x01,0x18,0x01, // 90 - 0x00,0x00,0xF8,0x03, // 91 - 0x18,0x00,0xE0,0x00,0x00,0x01, // 92 - 0x08,0x00,0xF8,0x03, // 93 - 0x40,0x00,0x30,0x00,0x10,0x00,0x60, // 94 - 0x00,0x02,0x00,0x02,0x00,0x02, // 95 - 0x00,0x00,0x00,0x00,0x08, // 96 - 0x80,0x00,0x60,0x01,0x60,0x01,0xE0,0x01, // 97 - 0x00,0x00,0xF8,0x01,0x10,0x01,0xE0,0x01, // 98 - 0xC0,0x00,0x20,0x01,0x20,0x01, // 99 - 0xC0,0x00,0x20,0x01,0x10,0x01,0xF8,0x01, // 100 - 0xC0,0x00,0x60,0x01,0x60,0x01,0x60,0x01, // 101 - 0x00,0x00,0xF8,0x01,0x08, // 102 - 0x60,0x06,0xA0,0x05,0xA0,0x05,0x60,0x07, // 103 - 0x00,0x00,0xF8,0x01,0x10,0x00,0xE0,0x01, // 104 - 0x00,0x00,0xE0,0x01, // 105 - 0xE0,0x07, // 106 - 0x00,0x00,0xF8,0x01,0xA0,0x00,0x10,0x01, // 107 - 0x00,0x00,0xF8,0x01, // 108 - 0x00,0x00,0xE0,0x01,0x20,0x00,0xE0,0x01,0x20,0x00,0x20,0x00,0xE0,0x01, // 109 - 0x00,0x00,0xE0,0x01,0x20,0x00,0xE0,0x01, // 110 - 0xC0,0x00,0x20,0x01,0x20,0x01,0xE0,0x01, // 111 - 0x00,0x00,0xE0,0x03,0x20,0x01,0xE0,0x01, // 112 - 0xC0,0x00,0x20,0x01,0x20,0x01,0xE0,0x03, // 113 - 0x00,0x00,0xE0,0x01, // 114 - 0x20,0x01,0x60,0x01,0xA0,0x01, // 115 - 0x00,0x00,0xF0,0x01,0x00,0x01, // 116 - 0x00,0x00,0xE0,0x01,0x00,0x01,0xE0,0x01, // 117 - 0x20,0x00,0xC0,0x01,0x80,0x01,0x60, // 118 - 0x60,0x00,0x80,0x01,0x40,0x00,0x60,0x00,0x80,0x01,0x60, // 119 - 0x00,0x01,0xE0,0x00,0xC0,0x00,0x20,0x01, // 120 - 0x20,0x04,0xC0,0x06,0x80,0x01,0x60, // 121 - 0x00,0x01,0xA0,0x01,0x60,0x01, // 122 - 0x40,0x00,0xF0,0x03,0x08, // 123 - 0x00,0x00,0x00,0x00,0xF8,0x03, // 124 - 0x08,0x00,0xF0,0x03,0x40, // 125 - 0x40,0x00,0x40,0x00,0x40,0x00,0x40, // 126 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 127 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 128 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 129 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 130 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 131 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 132 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 133 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 134 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 135 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 136 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 137 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 138 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 139 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 140 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 141 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 142 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 143 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 144 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 145 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 146 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 147 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 148 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 149 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 150 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 151 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 152 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 153 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 154 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 155 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 156 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 157 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 158 - 0x00,0x00,0xF8,0x01,0x08,0x01,0xF8,0x01, // 159 - 0x00,0x00,0x80,0x03, // 161 - 0x00,0x00,0xF0,0x00,0x08,0x01,0x10, // 162 - 0x00,0x01,0xF0,0x01,0x48,0x01,0x08,0x01, // 163 - 0x20,0x00,0xF0,0x00,0x68,0x01,0x28,0x01, // 8364 - 0x08,0x00,0xF0,0x00,0xE0,0x01,0xD0, // 165 - 0x10,0x01,0x2C,0x01,0x4C,0x01,0xC8,0x01, // 352 - 0x20,0x01,0x58,0x01,0xA8,0x01,0xE0, // 167 - 0x20,0x01,0x58,0x01,0x98,0x01, // 353 - 0xE0,0x00,0x10,0x01,0xE8,0x01,0x98,0x01,0x08,0x01,0xF0, // 169 - 0x28,0x00,0x38, // 170 - 0x40,0x00,0xA0,0x00,0xC0,0x00,0x20, // 171 - 0x00,0x00,0x40,0x00,0x40,0x00,0x40, // 172 - 0x00,0x00,0x40, // 173 - 0xE0,0x00,0x10,0x01,0xF8,0x01,0x58,0x01,0xA8,0x01,0xF0, // 174 - 0x04,0x00,0x04,0x00,0x04,0x00,0x04, // 175 - 0x10,0x00,0x28,0x00,0x18, // 176 - 0x00,0x01,0x40,0x01,0xF0,0x01,0x40,0x01, // 177 - 0x48,0x00,0x68,0x00,0x50, // 178 - 0x48,0x00,0x58,0x00,0x30, // 179 - 0x08,0x01,0x8C,0x01,0x6C,0x01,0x18,0x01, // 381 - 0x00,0x00,0xE0,0x03,0x00,0x01,0xE0,0x01, // 181 - 0x30,0x00,0x78,0x00,0xF8,0x01,0xF8,0x01, // 182 - 0x00,0x01,0x98,0x01,0x68,0x01, // 382 - 0x00,0x00,0x78, // 185 - 0x30,0x00,0x28,0x00,0x30, // 186 - 0x20,0x00,0xC0,0x00,0xA0,0x00,0x40, // 187 - 0x60,0x00,0x90,0x01,0x08,0x01,0x08,0x01,0xF8,0x01,0x48,0x01,0x08,0x01, // 338 - 0xC0,0x00,0x20,0x01,0x20,0x01,0xA0,0x01,0x60,0x01,0x60,0x01,0x60,0x01, // 339 - 0x08,0x00,0x34,0x00,0xE0,0x01,0x10, // 376 - 0x00,0x03,0x80,0x04,0x00,0x04, // 191 - 0x80,0x01,0x60,0x00,0x5C,0x00,0x60,0x00,0x80,0x01, // 192 - 0x80,0x01,0x60,0x00,0x5C,0x00,0x60,0x00,0x80,0x01, // 193 - 0x80,0x01,0x64,0x00,0x5C,0x00,0x64,0x00,0x80,0x01, // 194 - 0x80,0x01,0x64,0x00,0x5C,0x00,0x64,0x00,0x80,0x01, // 195 - 0x80,0x01,0x60,0x00,0x58,0x00,0x64,0x00,0x80,0x01, // 196 - 0x80,0x01,0x64,0x00,0x5C,0x00,0x64,0x00,0x80,0x01, // 197 - 0x00,0x01,0xE0,0x00,0x50,0x00,0xF8,0x00,0x48,0x01,0x48,0x01,0x08,0x01, // 198 - 0x60,0x00,0x90,0x01,0x08,0x07,0x08,0x05,0x08,0x01, // 199 - 0x00,0x00,0xF8,0x01,0x4C,0x01,0x08,0x01, // 200 - 0x00,0x00,0xF8,0x01,0x4C,0x01,0x08,0x01, // 201 - 0x00,0x00,0xFC,0x01,0x4C,0x01,0x08,0x01, // 202 - 0x00,0x00,0xFC,0x01,0x48,0x01,0x08,0x01, // 203 - 0x00,0x00,0xF0,0x01, // 204 - 0x00,0x00,0xF4,0x01, // 205 - 0x04,0x00,0xF4,0x01, // 206 - 0x04,0x00,0xF0,0x01, // 207 - 0x00,0x00,0xF8,0x01,0x08,0x01,0x08,0x01,0xF0, // 208 - 0x00,0x00,0xF8,0x01,0x24,0x00,0xC4,0x00,0xF0,0x01, // 209 - 0x60,0x00,0x90,0x01,0x0C,0x01,0x08,0x01,0x08,0x01,0xF0, // 210 - 0x60,0x00,0x90,0x01,0x08,0x01,0x0C,0x01,0x08,0x01,0xF0, // 211 - 0x60,0x00,0x90,0x01,0x0C,0x01,0x0C,0x01,0x08,0x01,0xF0, // 212 - 0x60,0x00,0x90,0x01,0x0C,0x01,0x0C,0x01,0x08,0x01,0xF0, // 213 - 0x60,0x00,0x90,0x01,0x0C,0x01,0x08,0x01,0x08,0x01,0xF0, // 214 - 0x00,0x00,0x60,0x00,0x60,0x00,0x80, // 215 - 0x60,0x00,0x90,0x01,0x48,0x01,0x28,0x01,0x10,0x01,0xE0, // 216 - 0x00,0x00,0xF0,0x01,0x04,0x01,0x00,0x01,0xF8,0x01, // 217 - 0x00,0x00,0xF0,0x01,0x04,0x01,0x00,0x01,0xF8,0x01, // 218 - 0x00,0x00,0xF0,0x01,0x04,0x01,0x04,0x01,0xF8,0x01, // 219 - 0x00,0x00,0xF0,0x01,0x00,0x01,0x04,0x01,0xF8,0x01, // 220 - 0x08,0x00,0x30,0x00,0xE4,0x01,0x10, // 221 - 0x00,0x00,0xF0,0x01,0x90,0x00,0xF0, // 222 - 0x00,0x00,0xF8,0x01,0x28,0x01,0x58,0x01,0x80, // 223 - 0x80,0x00,0x68,0x01,0x50,0x01,0xE0,0x01, // 224 - 0x80,0x00,0x60,0x01,0x58,0x01,0xE0,0x01, // 225 - 0x80,0x00,0x68,0x01,0x58,0x01,0xE0,0x01, // 226 - 0x80,0x00,0x68,0x01,0x58,0x01,0xE8,0x01, // 227 - 0x80,0x00,0x68,0x01,0x50,0x01,0xE0,0x01, // 228 - 0x80,0x00,0x68,0x01,0x58,0x01,0xE0,0x01, // 229 - 0x80,0x00,0x60,0x01,0x60,0x01,0xE0,0x00,0x60,0x01,0x60,0x01, // 230 - 0xC0,0x00,0x20,0x05,0x20,0x06, // 231 - 0xC0,0x00,0x60,0x01,0x58,0x01,0x60,0x01, // 232 - 0xC0,0x00,0x60,0x01,0x58,0x01,0x60,0x01, // 233 - 0xC0,0x00,0x60,0x01,0x58,0x01,0x60,0x01, // 234 - 0xC0,0x00,0x68,0x01,0x50,0x01,0x60,0x01, // 235 - 0xE8,0x01, // 236 - 0x00,0x00,0xE8,0x01, // 237 - 0x08,0x00,0xE8,0x01, // 238 - 0x08,0x00,0xE8,0x01, // 239 - 0xC0,0x00,0x30,0x01,0x28,0x01,0xF8,0x01, // 240 - 0x00,0x00,0xE8,0x01,0x18,0x00,0xE8,0x01, // 241 - 0xC0,0x00,0x20,0x01,0x18,0x01,0xE0,0x01, // 242 - 0xC0,0x00,0x20,0x01,0x18,0x01,0xE0,0x01, // 243 - 0xC0,0x00,0x28,0x01,0x18,0x01,0xE0,0x01, // 244 - 0xC0,0x00,0x28,0x01,0x18,0x01,0xE8,0x01, // 245 - 0xC0,0x00,0x28,0x01,0x10,0x01,0xE8,0x01, // 246 - 0x00,0x00,0x40,0x00,0xD0,0x00,0x40, // 247 - 0xC0,0x00,0xA0,0x01,0x50,0x01,0xE0,0x01, // 248 - 0x00,0x00,0xE0,0x01,0x08,0x01,0xE0,0x01, // 249 - 0x00,0x00,0xE0,0x01,0x08,0x01,0xE0,0x01, // 250 - 0x00,0x00,0xE8,0x01,0x08,0x01,0xE0,0x01, // 251 - 0x00,0x00,0xE8,0x01,0x00,0x01,0xE8,0x01, // 252 - 0x20,0x04,0xC0,0x06,0x88,0x01,0x60, // 253 - 0x00,0x00,0xF8,0x03,0x10,0x01,0xE0,0x01, // 254 - 0x20,0x04,0xC8,0x06,0x88,0x01,0x60 // 255 -}; From ad209d0127baab05b2f2b301bed8254903db7c2b Mon Sep 17 00:00:00 2001 From: j000bs Date: Sun, 17 Dec 2023 08:23:55 +0100 Subject: [PATCH 06/34] Switch to U8g2 display library OpenSans fonts were reconverted for U8g2. --- src/fonts/OpenSans-Regular_15.h | 140 +++++++++++++ src/fonts/OpenSans-Regular_26.h | 236 ++++++++++++++++++++++ src/fonts/OpenSans-Regular_37.h | 347 ++++++++++++++++++++++++++++++++ 3 files changed, 723 insertions(+) create mode 100644 src/fonts/OpenSans-Regular_15.h create mode 100644 src/fonts/OpenSans-Regular_26.h create mode 100644 src/fonts/OpenSans-Regular_37.h diff --git a/src/fonts/OpenSans-Regular_15.h b/src/fonts/OpenSans-Regular_15.h new file mode 100644 index 00000000..9665c293 --- /dev/null +++ b/src/fonts/OpenSans-Regular_15.h @@ -0,0 +1,140 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--21-150-100-100-P-107-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_15[4238] U8G2_FONT_SECTION("OpenSans_Regular_15") = + "\277\0\4\3\5\5\4\6\6\25\30\376\373\17\373\17\375\2\237\5_\20q \6\0 X\2!\12\342" + ")h\302\203\211\64\6\42\17\246\244\212\202\10\211D\210D\210DL\0#%\354%\350\222LX\214X" + "\214\224L\314A\215LX\214X\214XL\320\1\215LXPX\214X\214\224L\24\0$ *\346\307" + "\222\240\330I\205H\210T\210\224\204T\35]\225H\224\210\220H\304D\211\235\240\20\0%\64\357%\30" + "\7YP\210\220\214LP\220L\214P\232(\231\20)\231\10\11\222\20\211\220\20\11\12\65a!\62Q" + "\42\62Q\61\62A\62\62AQ!\62b\23\0&#\356%\370\16\345\204`\220\134\220\234\214\234\210$" + "\351\344\204\220\210\214\12)\221\20\61\22\271\231\203\32\233\1'\10\242\244Z\2E\6(\21DfgN" + "\210\204\210H\210\376\215\210\214L\0)\23Dfg\202L\214L\214\210\232\234h\22\42\22\42\2*\26" + "*\345\311\222\240`\324D\210\304\301\314\230\204\224\210PL\14\0+\15J\245\310\222\240F\7C\202:" + "\2,\12\243dW\6\205\212\20\0-\10E$y\302\301\0.\7b(h\202\1/\23\347!\210Z" + "\224\42)\251(UQ\252\242\244\242\244\0\60\26\352%\310\16\225\215\220HX\204\30\77\223\10\13\21\222" + "\261\242\1\61\14\345)\310\216\210\205LP\376\7\62\21\352%\310J\15\305L\224\240\356\364\335\301\201\1" + "\63\27\352%\310J\15\5\241dB\71\241B\312HA\71\211\21\22\33\0\64\35\354!\310\236\250dD" + "\240D\234H\134L\230L\224PT\242\260\230\203\7\203\261i\0\65\30\352%\310\306A\310A\210\240`" + "d\244\221\10\241\244\240:\11&\66\0\66\34\352%\310R\321H\214\234`\240\212\22\222\211)\62\62\211" + "\60\11)\221\211\241\22\0\67\25\352%\310\302\3\303@u\202r\202r\202\202\201\202\201b\0\70\34\352" + "%\310\212\315\310HXHX\210\220\310\210\24\225\215\220\204\30g\22#\63&\0\71\34\352%\310J\321" + "\304L\224\204X\204\30\63\211\21\222\12A\301@\71\231\20\232\42\0:\10\202)h\202\261\1;\14\343" + "eg\206\366p\24*B\0<\15j\245\310f\334\324\62\205,W\6=\13\252d\311\302\301<\374\301" + "\0>\17j\245\310B\344\226\242bDS\353\42\1\77\22\350!\230\206\305A\134fR\232\305\305K\215" + "\311\0@\64\61\246\67\233\345\320\230\240\220\250\210PMH\220\210LH\214\32\232 \31\22!\31\232 " + "\231\10\231 \231\10\31\221\210\20\221 \222\31y\10y\210\241\311+\0A\37\355!\330\232\350\322\10A" + "\11A\21\61\31\61\241\260(\241\3\241\203\21\71\21\71\221HJ\1B\31\352)\350\302A\310\201\204\30" + "W\22\7!\62\24b\354\306\330P\34\204\0C\24\353%\330\226\315A\210\240\244\240\244N%EE\17" + "\202\16D\30\354)\370\302A\320\301\210\330\204\234\204 \177'!\66q s\20\4E\20\350)\310\302" + "\3\62\315\16\16\310tvp F\17\350)\270\302\3\62\235\35\34\220\351\31\0G\33\355%\370\226\325" + "\201\214\250\254\250\254\262\227\22\202\22\202\42r\62\7C\7\21\0H\16\353)\10\203\340\36\36< \334" + "\207\1I\10\342)h\302\17\4J\15f\32g\222\376\377(\242\202\4\0K\42\353)\330\202\230\204\224" + "\210\220\214\42\221!\21)\11\261\62\21)\31!\231\31!\31)\21\61\11\261\1L\14\350)\270\202\230" + "\376\317\16\16\4M)\357)\70\303\244\345\335A\234E\134\4\205\224\4\205T\10\211\214\10\211\214\10M" + "\32\32\11\31\32\211 \242!\242!\252(\1N\34\354)\10\203`\235\231\31\205\24\211\20\211\20\215\14" + "\221\10\221\10\225\4\231\273\272\1O\33\356%\10\223\335\201\220\330\210\240\210$)O%$%\4e\304" + "\206\16\304\214\0P\32\352)\330\302\315\201\204\224\204X\204\30Y\204\224\204\320\304A\10\231\240\16\1Q" + "\34Nf\7\223\335\201\220\330\210\240\210$)O%$%\4e\304\206\16\304\214\267\0R\34\352)\330" + "\302\315\201\204\224\204\30\263\10)\211\203\220\33\215D\244$\244$\304\310\4S\22\351%\310\212\311\301\234" + "B\71\356\4\323\35P\230\0T\14\353!\310\302\7Q\222\372\77\2U\20\353)\370\202\340\376w\22b" + "\22\7B\65\0V\42\354!\330\202\240D\240\204\234\204\230L\230\214\224\214\220\224\214\224L\230\210\234\204" + "\234D \345\244\24\0W\66\363!\70\203\234\230\204\324\230\204\324X\210T\204\220\210\220\204\220\214\222 " + "\31\231\30\231 \231\30\21\251\20\31\21)\11\241\20)\211(\211\60*\272\261\71\271\71E\0X \354" + "!\310\206\230\210\230\214\220\224L\230\210\34\245\250$a\210\230\210\224\220PX\214\230\204\240\0Y\27\353" + "!\310\202`\204\230\204X\214\220\214*\21\261\10\71BI}\4Z\23\352%\310\302\3;A\71\205r" + "\12\345\24\312\35\34\30[\12DjwBM\376\177C\134\25\347!\210\202X\230X\230\224X\230\224X" + "\230X\230\224X\0]\12Dfw\2\211\376\177b^\26*\245\271R\340\134D\230\204TL\220\214L" + "\224\204XD\234\0_\10)`\227\302\201\0`\10dp\313\202\214\2a\23\211%\310J\315\210\240\234" + "\222\213\31*V%\24%\1b\33\12*\330\202\240\206!\64\21\42\252$\304\42\304x\26!%\21!" + "\42\22B\3c\17\210%\250N\211\205X\230\336\311M\310\24d\26\12&\330\242n($F(\244\310" + "\370LBJb\204\206$\0e\27\212%\310\16\225\210\214\220HX\204\330\301\241d\244\344\304\220\5\0" + "f\20\7&x\16\211H\204\224\220\211\224\376#\0g\36+\342\306\316A\210\214*\21)\21)\31U" + "U\222\241\222G\7!q\354$\204fl\0h\17\11*\330\202\234.H\42D\252\370\257\4i\12\2" + "*X\2\321\301\203\1j\16\245\336V\216j\31\375\277\211\221\30\1k\35\10*\270B\134\256\206$b" + "DBd\42\204\42\204$dbDbD\202$\242\246\4l\10\2*X\302\17\10m\42\220)HC" + "\10\15I\204\304\204\304\204\224\24\225\24\225\24\225\24\225\24\225\24\225\24\225\24\225\24\225\2n\16\211)" + "\330B\10I\204H\25\377\225\0o\27\212%\330N\321\304\210\224D\30\335v\21a\22R\42\23C%" + "\0p\34*\352\326B\10M\204\304\210\224\204X\204\30\317\42\244$\42DDBh\4u\10q\27*" + "\346\326\16I\304\210D\204\24\31\237IHI\214\320P\10\352\1r\15\206)\230B\10\305\215\220\376\10" + "\0s\23\210%\250J\211\12\61\261\61\272\71\61\61\232\3\21\0t\17\347!xN\224\232\23)\375\325" + "D\14\1u\16\211)\330B\330\376\214\252\204\242$\0v\33\212!\270\202\134D\230\204\224\204\220L\220" + "\214&R!R\22a\22qsB\0w*\220!\10\203\224\212\250!\11\241\241\20\31\211\30\21\31\211" + "\30\231$j$DD\202$dB\202$\202\250\42\202\250\246\304\324\0x\30\211%\270\202\224\204\214\210" + "\214\12\251\210\260U\22B\22\62*\244\250\4y *\342\266\202\134D\230\204\224\204TL\220\214\242\20" + ")\11)\211\270\210\270\71AurSd\0z\23\210%\250\302A\230\224X\230\224\230\224\62)\261\203" + "\0{\17Ff\207\222\214\42=\231\231\22\322+\5|\7\242\366\306\302\77}\20Ff\207\202\224\42\275" + "\232\31\21\322\33E\0~\14j\244\311\6\225\4\205\24\5\0\240\6\0 X\2\241\13\2*g\202Q" + "D\26\7\7\242\23\350)\310R\134X\305\205\224\230\316\306N\214\342b\0\243\24\352%\310R\315\210\214" + "`dv\7A\221\31\312\35\34\30\244\27\12%\311\202\4\205\304\310\210\220HXHX\210\220\310\12\11" + "\12\1\245\35\352%\310B\340\230DX\210\220LP\220\210TH\30\321A\224\240\324A\224\240\42\0\246" + "\13\242\366\306\302\3\321\203\3\1\247\32\10&\270\212\205\14\235\30\221I\20UDT\304\210H\331\134\334" + "\314\204\5\0\250\11Fl\313\202\10\211\0\251(\357%\30\227\235\224\302\30\31\232\220\30\221 \31A\31" + "A\231H\31A\31\301\210\30\221\240\10\31\232\30A!)A#\0\252\13\345$zBQ\212\32\31\3" + "\253\23(e\250N\22\25\42\42\61!j\322\210\310\210\310$\254\11\252\344\310\302\301d\16\255\10E$" + "y\302\301\0\256*\357%\30\227\235\224\302\30\221\232\220\230\30E\61\212b\24\25\11\205\10\11\205\10E" + "\304\304\310D\210\4\205\304\10\12I\11\32\1\257\10+ \274\302\1\1\260\17\307d\232\312L\12\31\32" + "\211\230\230\21\0\261\16\212%\310\222\240F\7C\202:\77\30\262\15'\241y\312L\262TB\212\242\16" + "\263\17'\241y\6M\262\64dRC!$\0\264\11dp\313\212\204\22\0\265\21)\352\326\202\24\377" + "UI\5\211`\240\234:\0\266,jf\347\312A\204I\204\311A\310A\310A\310A\310AH\204I" + "\204IHIXHXHXHXHXHXHXHXH\0\267\7b\250i\202\1\270\12\244\340" + "VJ\310LL\1\271\12$\245y\12\205HL>\272\16\346$\212\6\205\310\220\242\21\11\12\0\273\23" + ")e\250BL\220\210\220\210\220\210\220\210~\223\10\0\274.\356%\10\213\134\210DXLH\224XT" + "\134\220\134\214`L\214P\210\214PHLDXLH\224\210\204TL\210\220\310M\234L\240\4\0\275" + "'\356%\10\307X\14\225L\204T\230P\234\214\234L\240\210\4\215H\22\25qAbBqAbA" + "bQaQR\6\276,\360!\10\7\235L\262\300(\301\250\260\251\320\30Q\221\30\211\240\20\221\211\232" + "\230\301\230\10\71\21\11\271\230\20\61\221#\71\251@\11\0\277\24\10&\227\216\330\224<`\134\230\224f" + "q\351\16\42,\0\300#m\42\330\222pt<\250\350\322\10A\11A\21\61\31\61\241\260(\241\3\241" + "\203\21\71\21\71\221HJ\1\301#m\42\330\236\250l<\250\350\322\10A\11A\21\61\31\61\241\260(" + "\241\3\241\203\21\71\21\71\221HJ\1\302%m\42\330\326\244\204\234\214<\234\350\322\10A\11A\21\61" + "\31\61\241\260(\241\3\241\203\21\71\21\71\221HJ\1\303&m\42\330\222LXEX\214<\240\350\322" + "\10A\11A\21\61\31\61\241\260(\241\3\241\203\21\71\21\71\221HJ\1\304$M\42\330\222H\240H" + "<\240\350\322\10A\11A\21\61\31\61\241\260(\241\3\241\203\21\71\21\71\221HJ\1\305$M\42\330" + "\326\244H\240H\344\350\322\10A\11A\21\61\31\61\241\260(\241\3\241\203\21\71\21\71\221HJ\1\306" + "'\361!(\337\301\330\1\231\204\254\210\254\210l\214\250\314AP\320A\214\220\344A\340\201\240\224\234\230" + "\234\330\301\334A\0\307\31\213\346\326\226\315A\210\240\244\240\244N%EE\17\202\316BU\312\315\0\310" + "\24h*\310\212\230`\354\301\1\231f\7\7d:;\70\20\311\24h*\310\222\230T\360\301\1\231f" + "\7\7d:;\70\20\312\25h*\310\216\24\215L\344\301\1\231f\7\7d:;\70\20\313\24H*" + "\310\206\210\226\7\7d\232\35\34\220\351\354\340@\0\314\13d\42h\202\214\62\21\375\177\315\14d*h" + "\212\204\62\21\375\177\2\316\16f\42h\212\14E\214\240\220\376\77\1\317\15F\42h\202\10\211\240\220\376" + "\77\1\320$\356!\370\312A\330\201\224\230\220\234\214`\214\340\301\320\301\220\210\240\210\240\210\234\214\234\214" + "\230\320\201\324\25\0\321\42l*\10\317LT\204\242\230y\301:\63\63\12)\22!\22!\32\31\42\21" + "\42\21*\11\62wu\3\322\37n&\10\227\260x<\244\335\201\220\330\210\240\210$)O%$%\4" + "e\304\206\16\304\214\0\323\36n&\10\337\254zH\273\3!\261\21A\21IR\236JHJ\10\312\210" + "\15\35\210\31\1\324 n&\10\233,\245\210<\234\335\201\220\330\210\240\210$)O%$%\4e\304" + "\206\16\304\214\0\325\42n&\10\323L\134\204\262\230y\70\273\3!\261\21A\21IR\236JHJ\10" + "\312\210\15\35\210\31\1\326 N&\10\223\210\240\210<\234\335\201\220\330\210\240\210$)O%$%\4" + "e\304\206\16\304\214\0\327\23(\351\310B\330\220\204\210\14\225\24\215\210\204\320X\0\330&\356%\10\223" + "\205\320\201\220\330\210\30\211\224\10Y\14\225\14\221\20\215\24\215\224\204\62\11\62\31\261\231\203\31\11#\0" + "\331\22k*\370\216\250z\301\375\357$\304$\16\204j\0\332\23k*\370\232\240z\10\301\375\357$\304" + "$\16\204j\0\333\24k*\370\322\134\225\214\264\340\376w\22b\22\7B\65\0\334\24K*\370\216H" + "\230H\270\340\376w\22b\22\7B\65\0\335\33k\42\310\232dz\10\301\10\61\11\261\30!\31U\42" + "b\21r\204\222\372\10\0\336\26\352)\330\202\240\302\233\3\11)\11\61\256$\16B\310\4\25\2\337 " + "\12*\330J\315\310\210\224\204\224\204\220\210\214\22!\21!\221\31\231\21)\11\61.D*,\0\340\25" + "\11&\310\212\240\362\232\21A\71%\27\63T\254J(J\2\341\26\11&\310\226\230\134|\315\210\240\234" + "\222\213\31*V%\24%\1\342\27\11&\310\222\30Q\214p\315\210\240\234\222\213\31*V%\24%\1" + "\343\31\11&\310\312L\204\212\220\230\341\232\21A\71%\27\63T\254J(J\2\344\26\351%\310\212\32" + "\21\341\232\21A\71%\27\63T\254J(J\2\345\31)&\310\16UHTH\24u\315\210\240\234\222" + "\213\31*V%\24%\1\346!\220%(K\15\315\204\305\240T\240\224\234\224\310\301\305\214\234\224\234\224" + "\234\20\331\210\304IQ\5\0\347\24(\346\246N\211\205X\230\336\311M\310\24\305)\23\32\1\350\33\12" + "&\310\216\240h<\10\225\210\214\220HX\204\330\301\241d\244\344\304\220\5\0\351\32\12&\310\326\234z" + "\20*\21\31!\221\260\10\261\203C\311H\311\211!\13\0\352\33\12&\310\222\34\225\210<\225\210\214\220" + "HX\204\330\301\241d\244\344\304\220\5\0\353\32\352%\310\212\42\21y*\21\31!\221\260\10\261\203C" + "\311H\311\211!\13\0\354\14\4\42X\202\214L\234\210\376\7\355\14\4*X\306\204\62\21\375O\0\356" + "\16\6\42X\306\14E\214\240\220\376'\0\357\15\345!X\202\310H\234\214\376\27\0\360\31\12&\330\216" + "L\220\325\12I\65\27#\24Rt\333EHI\214\14\225\0\361\24\11*\330\212LHEH\314h\10" + "I\204H\25\377\225\0\362\33\12&\330\216\244d\10;\60\271(!\221\12\231\21\234\21\234\21\234\21\254\220\274}" + "\20y\20(R'\64'\64'\64'D&s\60q\20qpt ,\256\35\0%U\232&A\357" + "\320\316\231\312\215\14\216\15\315\311M\211\315\211)\24\223\32\24\223\222\24\23\232\24\223\31\25\223\31\251\31" + "\32\31\71\31\32\21\231\31\331DJ\346DFJ\210fdjTfjrfjRhjphjn" + "j\235*\271\71)\71\301\231\261\311;\331\32\0&E\230&A\255\331C\34\210WTO\321\316\315\316" + "\315\316\15O\21\23\215\217\320C\334\303\324\203\330\203P\320\15\321\220\315\214Q\215\320\321\254$\231\31=" + "\210\231\65\32\246\42\265\42<\10:\70\10!:\250\242:\10$'\12D\42c$\234\350\27\0(\30" + "\10\30\265e-Z\65D\64\65\64\265G\274\332gSST\313V\15)\33\10\30\265%\214\255\32\233" + "\32\233\332lj\377#\242\251!\242\251\241\251\241U\0*\42\20$W\252\21O\217\253\223\222:\210\220" + "\70x\20t\20J+\61\71\62G\62\67\64ED\226\10\0+\20\221$\311\352\311\353\207\7\37\330\311" + "\353\207\0,\15E\22\267\244l\61\262Dd\11\0-\10\311\20Q&|`.\13D\61AeH\34" + "\34D\0/\34\214\26\301f\16N.\234\234\224\134\70\271pr\341\344\340\344\302\311\205\223\223\242\0\60" + "+\221&\301jY\36\214\35T\215\321\14\316LN\214N\214N\214N\314\372O'FGDG&G" + "\6\207\306\250\16\350\16$\315\0\61\21\211F\301j\21\325XP\234\330P\215\355\377\177\62\34\221&\301" + "j\31\36P\35\30\315\321\204\216\217\223O\217\257\236\246\336\177}\360\17\4\63(\220&\301*\335\35\320" + "\34\234\14\222\204NS\17\23\17\223\226\35\4\36\4\36L\223O\357q)\305\301\311\201\325\201\24\0\64" + "\61\223\26\301*\317\223W;\236\230\35\231\225\31\235\231\34\32\234\32\234\232\33[\67&\70\65\70\64\71" + "t\360\37\4\317C\314C\314C\314C\314C\14\1\65&\221&\301\252\34\30\35\30\35\30\311\213\357\371" + "\301\334\201\325\201\65\71\371r\352\361\325\24\222$\7\67\7v\7a\0\66-\221&\301*>\20\273\230" + "\42\246^\276\134|\306j\344@fb\246\244\216\202rb\326\333\11\331\211\311\21\302\31\62\242\203\262\203" + "I+\0\67 \221&\301*\374\7\322\343\323\343\323\343\253\307\247\307\247\307\247\307\247\251\307\247\307\247\307" + "\247g\1\70\62\221&\301j\35\36P\225\330\320\315L\216L\216L\216L\216\14\16\215Q\321\320\35\204" + "\36\36\214\21\325\14R\214N\314\372td\220\304\321A\335A\24\0\71\60\221&\301jY\36\214\35\24" + "\221\321\14\216\214N\214N\314J\314J\314\232\236R\14V\230P\214\34\214H\331\214o=>=M%" + "rv x\10:\20\304\64A%L\34T\310#\224\70\70\210\0;\22\6\26\67\245\314\220\260\221\307" + "\315&\63kd\326\0<\25\221$\311\352C\204\17\227\366\343qk\363rk\327\364\20\1=\15P\42" + "\321*\374\200\36\257\16> >\26\221$\311*\304C\214W\233\367\65mi\245\227\305\343\361\20\0\77" + "\37\216\26\301\347\34\35\320\34\224\310\321\16\13\317\312.\235\344t\355\254\260\70\210\207\70\20\5A@\227\6\301\253\316" + "C\315\3\325\303\324\203L\310\203L\314C\210\314\317\214\317LOIO\15O\315\316\215\316M\16N\36" + "\34\4\36\34\304\35\34\310\315\216\315NM\17M\317\214\317\314\217\314O\314C\20B\64\221F\301+\34" + "T\35\334\34\34\204LR\214N\214N\214N\214N\214N\214N\14\222\34\30\35\30\35\34\204LR\214" + "\336\372\351%\305\301\201\304\301\315A\25\0C\71\224&\301k\36D\36\134\35\134Q\12\321\263\207\230\7" + "\231\7\231\207\240\207\230\7\231\7\231\7\231\7\241\207\240\7\231\7\231\7\241\7\241\207\250\207(\215:\70" + "\210;\260<\220\1D/\224FA-\34\24\36\234\35\34\10M\326\314\222\14\217\14SLOL\237\373" + "\327\327\23\323\23\303\24\263$\243%\223\65\7\7B\7g\7\224\0E\26\216FA*\374\203\331\375\366" + "\300\342\300\342\300bv\177{\360\7F\25\216F\301)\374\203\331\375\355\201\305\201\305\201\305\354\376[\0" + "G=\226&Am\36\310\36\234\35\34HUJ\321\203\320\303\314\303\320\303\314\3\315\303\320\303\314\3\215" + "\36\224\36\224\36\330\337O\314O\314O\220\217P\317\20\317\230\16\35\34\220\35\34\10\36\14\1H\17\223" + "F\301-L\373\277>\370_\373\177=I\11\203FA%\374\177\20J\20I\330\62\245\355\377\377\377\325" + "A\305\211\15\0K:\222FA+\314N\214\216L\316\14\322\314\21\215QM\221\15\321\315\20\316L\216" + "\214N\220\36\204\36H\222\20\16\15N\315M\221\215Q\315M\315\21\15\322L\222\214\216\214R\314\22L" + "\15\216F\301)\314\356\377\377\333\203\77ML\231F\301\60\320C\34\314\37\314\37\214\37DL\37D\14" + "O\224\314N\224\314\212\224\214\216\324L\216\324\14\316\324\14\316\24\315\11\25\215\15U-\252\232\222\252\32" + "\232*\233\231*\33\31+\33\31\253\233\220\253\263+\254+$,$\254\34\34N\65\224F\301-\214_" + "\37\4\37\4\37\310V\314\226\214\226P\326L\26\15\26\321U\315\225\215\225Q\325M\325\21\25\322T\316" + "T\222\224\216\324N\324\36\10\37D\77'OC\230&A.\36\204\37\224\36\34\310\25V\21\23\215\317" + "\220\223\314C\214\314CL\320C\34\304\203\330\303\330\303\330\303\330\303\330\303\334CP\314C\214\314C\214" + "\220\323\214\17\21S\25\326\35\34\210\36\224\37\4\2P\42\220FA+\34P\35\330\34\234\14RLN" + "L\236zy\71\61H\61Vr`s@u\71\275\177\15QO\30(\65.\36\204\37\224\36\34\310\25" + "V\21\23\215\317\220\223\314C\214\314CL\320C\34\304\203\330\303\330\303\330\303\330\303\330\303\334CP\314" + "C\214\314C\214\220\323\214\17\21S\25\326\35\34\210\36\224\37\304\203\321\203\321\203\321\203\321\203\321\203\221" + "\0R\71\221FA+\34\220\35\30\35\334\14\222L\216LR\214N\214N\214N\214NL\216\14\222\314" + "\321\34\30\35\220\35\220MQ\215M\315\15\315\321\14\316\14\222L\216\214N\214\336\16S\42\220&Aj" + "\35\204\35\324\34\230\20J\20O\257f\134|\373\326\232\365\216K)\16N\16\254\16\244\0T\67\224\6" + "A*\374\17\10\347A\346A\346A\346A\346A\346A\346A\346A\346A\346A\346A\346A\346A\346" + "A\346A\346A\346A\346A\346A\346A\346A\346A&\1U\32\224\66A-\214\373\377\77\237\30\246" + "\30\36!\245!\244:\270;(=\10\3V\71\225\6\301*\314O\214OLSL\317\14\317\314\16\315" + "N\215NM\216M\316\15\316-$\233\234\242\234\32%\232\235\241\235\231\36\231\236\30\237\230\227\230\257\207" + "\250\7\241\7\231\4W[\240\26\301\60\314\16\233\226N\214\226NP\226\216LJ\210\216\14N\14\316\14" + "N\14\316\320M\14\16\215\315\314\15\215\315\214M\215\315\214\255\222Z\66\64\265lhjhnhlf" + "pdnfpdn\204pdndrDrbTbrb\324rB\326\264\266\61m\61\361\364:" + "\0X\65\224\6\301jL\217\314\316PNM\216\315-\233\234\32\235\231\235\31\236\230\266\257\207\230\207(" + "\67\237\30\36!\245\31\235\32\34\243[\66\71\64:\64;\62|\20=Y\67\224\6A*PO\14\217" + "\320\316\214\16QN\15\216\261\33\233\34\242\34\232\35\241\35\231\66\267\247\207\240\7\231\7\231\7\231\7\231" + "\7\231\7\231\7\231\7\231\7\231\7\31\4Z#\222\26\301j\34\34L\34\34L\34\34\214/'_N" + "\276\234|\71\371\70\65\371\70\65\371\70\371\301\77 [\20\10\70\65&<\250\332\377\377\177u\360`\0" + "\134\35\214\26\301&\210N\216N.\235\34\25\235\34\235\134:\271trTtrtr\351\0]\20\10" + "\30\65&<\220\332\377\377\177u\360\300\0^\42\21\24U\352\311O\27K\310N\214\312H\316\14J\311" + "M\215\215I\315\15\15\12I\216\214\212\310\32\13_\11\220\0\67(\374\200\0`\13\207q\355*\20\15" + "\21M-a\37\317$Aj= *)&\336\325\301\310\201E\331\241\245\303\273\3\212\203\210\203\21\31" + "#\1b'\321\66A+\214\357o\254&\16f\16\42L\352(('(o\375\355\345A\344D\35\305" + "A\204\311\304\301\214\220\25\0c\33\316$\301\250\35\35\220\34\320\214\316\216\316\356\343\331Y\302\220\203\232" + "\3\252\23\0d'\321&A\253\357\257lf\16&F,\16\42\350*&)&o\375\355\304\350\304$" + "\5]\211\305A\314\301\304\224\221\0e \320$A\252U\36HY\24\315\215\14RL\232\232\36\374`" + "z\371\364\70\361\201\325\1\335\15\0f\26\314\26A\246Y\35U\310\20Nnw\60q@\64\271\377\77" + "\3g\71\22\27/j\35\330\34\34\204P\215\315\15\15\16M\316L\316\14N\315MQ\315\35L\36D" + "\216\317\257\207\70 <(:\70\10\31\235\30\366vb\224\204\254\350\300\356 \14\0h\30\320\66A+" + "L\357o\214&\16F\16\42,\352\16\42/M\375\177:i\14\203\66\301d\34P\36\374\7\1j\23" + "\310\350\256\244Im\17>\265\377\377_UP\134\324\0k.\317\66\301)\14\357\17'\346(\306H\246" + "h\206\210f\250F\310&\350&\6\17\342*\306f\250\206\210\246\206\306f\306H\346(\6'&\7l" + "\11\303\66\301$\374\177@m\66\334\64\301\60\314\230\31M\34\310\34\214\34\134\34T\224\331M\20\22N" + "\20RJL\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216Z\216\16n\27" + "\320\64A+\314\334L\34\214\34\34D\324\35D^\232\372\377t\0o#\322$A\253\231\36\214\35X" + "\315\321L\222\214N\314N\14\373\355\310\350\310$\315\34\321\201\335\301\250\31\0p(\21\67/+\314X" + "M\34\314\34\34\204\324QPNP\336\372\333\313\203\310\211:\212\203\10\223\211\203\231\31\253\361\375\71\0" + "q'\21'/k\31\311\34L\214X\34D\320ULRL\336\372\333\211I\212I\12\272\22\213\203\230" + "\203\211)\233\361\375\3r\24\313\64\301'\314\34\204\34H\34X\225\321\15\356\377\20\0s \316$\301" + "\350\34\4\35\224TX\314\256\245-\65\275\264\245\35\236\225\210\234(\261\70(:\10\2t\24\313\25\301" + "\346H*\234;x\62\270\377\313\301\222\240+\3u\25\320\64A+\214\372\377\313\203\270\12\213\203\220\203" + "\211!#\1v'\322\4A)\14O\214\216\214\216\214\316\14\16\15\16\221Q\215m\67\64\70\64\70\64" + "\71\62:\62+\42\354\232\234\16\0wB\332\24A.\14\22\32\22\32\22\332\331M\214\231\215\214\211\210" + "\215L\215L\215L\215L\315\14\311\14\255\31\232\31\232\31\232\231\222\31\232\21\233\30\233\30\233\30\233\30" + "\233\30\233\230\223\20\224\20\354\345\350\24\0x&\321\24\301)P\216\14\322\314M-\243\241\233\231\234\30" + "\65\256\236\256\235\230\244\230\234\231\233ZFC\67\63\71\61Jy\60\22\7/)\14O\214R\214\216P" + "\316\14\16\15N\315M\215m\67\65\67\64\71\63\71\62:\62;\61k\335\232~|~\371\70\245D\351" + "m\65\0z\27\316\24\301h\34X\34\330\216\216\222n;\272\224t\333\321\321\203\17{\32\13\30\65'" + "\216UY\315\321\15\356\317\250\312\12)\7\367\227\203\203f\205\3|\11\2\231/*\374\77\20}\31\14" + "\30\65'L\326YR\356\237N\266\253\252\33\234\334\37R\231\325M\2~\20Q!\325\252T\36\214\35" + "\134\224\35\310\226\0\240\6\0\0\301$\241\21\204\66\63%L\34T\210\213\350\213\375\213\203\0\242!\216" + "\66\301\352\315.\275:\230\71 \241\213 \235\35%\235\335\226v-\323\203\242\203\261\303\331E\0\243\35" + "\222\26\301*^\36\220\35T\321\205\315\357\267\7G\7\207\363{>\77>}\360\17\12\244(\20$\313" + "j\4G\314\224L\34\334\264\231\23\22\34\231\24\231\24\231\24\231\224\21\234\231\23\252\241\71\270\230)\231" + "\10\216\0\245\66\223\26\301*L\33\217\314\216\214\16M\16\15\216\315\215-\234\32\34\32\235\31\35\31\236" + "\220\266<\270:\270\235\207\230\207\30=\270:\270\235\207\230\207\230\207\230\207\30\4\246\13\2\231/*\374" + "\36\342\340\3\247/\316&\301)\35\4\35T\324\220\314\12\317\322\226\236\35\314\14\225\310\35\32N\314M" + "\220\215\324\14\35\10\232\326\322\316\222\36\4Q\34\24\35\4\1\250\13\312P\357j\10\335L\10\15\251I" + "\232&Ao\36\304C\34\24\23R\16\317\215O\215\31\15I\35\10\311H\321\210\211\10\21KH\215S" + "\311S\311\23\315\23\315S\311S\311S\215K\10M\213H\21\205\211L\35D\11\215U-\237\33\236$" + "$>\250\207\70\210\4\252\25\12\23\335\246\330\34\4\16\252\271\70\250\42+\232\70\20!\21\253\36\317\23" + "E\251%\33\32\242\231\32\332\217h\306\206\306\206\306\206\306\206\246h\250\206\306R\0\254\12Q\42\313*" + "\374\300|\77\255\10\311\20Q&|`\256U\232&Ao\36\304C\34\24\23R\16\317\215O\315\34D" + "\15\11\35H\311H\315P\211HM\251\20\233\22#\33\32#\33\32#;\220#;\10$\33\31$\233" + "\231#\233\231\223\220\32\232\22\221\32\232\22\31\232\232\21\232\231\32\231\32\237\33\236$$>\250\207\70\210" + "\4\257\11\222\0y)\374A\0\260\25\313\42\337\347T\335,\21\243c'!&\61\63s\20T\3\261" + "\23Q%\303\352\311\353\207\7\37\330\311\353\367\240\7\37\30\262\26\312\23\327\246\330\34D\14\315\15\312\315" + "\311\215-\223Swp`\263\27\312\23\327\246\230\34HH\15\312\215\221\334X\16*\34;(\261\1\264" + "\13\207q\355\352\220\320,R\5\265\26\20\67/+\214\372\377\313\203\270\203\212\203\3\223F\325\373k\0" + "\266QR(\67l\35\330\34\34\204\34\14I\34\20I\34\20\35\34\35\34\35\34\35\34\35\34\35\34\35" + "\34\35\34I\34\20I\34\20\211\34\14\211\34\14\11\35\4\211\12\211\12\211\12\211\12\211\12\211\12\211\12" + "\211\12\211\12\211\12\211\12\211\12\211\12\211\12\211\12\11\267\13D\61U%L\34TH\0\270\17G\22" + "/\244H\11Q-\32\222\260\240\1\271\17\307\23\327&\315P\34LH\304H\351\77\272\26\13\23]\347" + "T\35\204H\231\321q'!&!\65r\20T\3\273#\316#Ei\204E\15\15\321\20\255\32\232\32" + "\232\32\32\242\31Z\63\64\63\64\63\64C\63\264*,\12\0\274G\231\26A.\15\217\321N\331JQ" + "\210\216\305\210\312J\12\13\16\13J\313M\213\215\213\311K\255\223\222\242\23\232\242\223\231*\226\262\235\222" + "\230\225\22\31\35\32\231\234\222\231\224\22\32\34:(\223:\250\222\36\233\36\23\37\1\275D\231\26A." + "\315\312\225\216M\210\212\215H\12\306\10\16\13J\313M\313\211\213\311K\315K\311C\10\315\330\311\314\34" + "\204\311\310\14M\211\214N\312\16\316\316\15\13\12\13\316J\312J\216J\216j:y\60#z\60\276M" + "\234\6A\356XK\35\310NIMNO\212\17NO\212\36\312\32\316C\214\311\303H\315\303H\311\3" + ")\223\21\233\231\232\71\30\222\242:\32\252\237\222\220\227\22\21\37\32\21\227\222\221\36R<\64$,u" + "P\70uP(-*.\71.\3\277\33\216\26\263\347\215r+\217TX\355(%O\327\356\226\60\344" + "\300\344\240\350\6\0\300M\227\10\301\253\321C\315C\321C\315\203\315\203\315\343l\36j\36\250\36\246\36" + "dB\36db\36Bd~f|fzJzjxjvntnrp\362\340 \360\340 \356\340" + "@nvlvjzhzf|f~d~b\36\202\0\301M\227\10\301+\323\3\315\3\321\3\315" + "\3\315\3\315\343n\36j\36\250\36\246\36dB\36db\36Bd~f|fzJzjxjv" + "ntnrp\362\340 \360\340 \356\340@nvlvjzhzf|f~d~b\36\202\0" + "\302N\227\10\301k\322\3\325\203\330C\214\214\17\15\217\315\343d\36j\36\250\36\246\36dB\36db" + "\36Bd~f|fzJzjxjvntnrp\362\340 \360\340 \356\340@nvlv" + "jzhzf|f~d~b\36\202\0\303MW\10\301\353\215\311\32\211N\34\304\12\331J\321\343" + "f\36j\36\250\36\246\36dB\36db\36Bd~f|fzJzjxjvntnrp" + "\362\340 \360\340 \356\340@nvlvjzhzf|f~d~b\36\202\0\304H\27\10\301" + "\353\11M\323\214\13\315\343\355<\324\61L\61" + "\260:\240\273\1\352*\20'A\352\15\227\36\216\220\15\215\311\311c[y eQ\64\67\62H\61" + "ijz\360\203\351\345\323\343\304\7V\7t\67\0\353'\220&A*I\311\315\220I\311\343\272\362@" + "\312\242hnd\220b\322\324\364\340\7\323\313\247\307\211\17\254\16\350n\0\354\21\7\367\300$\20\21M" + "M\211\311\203\16\355\377\77\355\20\7\67\301\344\320l\244\36vh\377\377\21\0\356\24\13\367\300$\315U" + "\335P\220\14\325\311\243\33\334\377\177\4\357\21\212\6\301$\14I\314\34\311#\237\333\377\177\4\360\62\322" + "&\301j\311\5\322L\36\210\332\236R\20\16M\206\315C\314\317\235\14\35\334X\34\204\20\222\214\336\36" + "\373vbvdt\204p\310\302\354\200\324\14\0\361#\320\66A+\215\11\31\311LT\10\11\31I\321" + "c\66s\63q\60rp\20Qw\20yi\352\377\323\1\362-\22'A+\321\317C\314C\314\317\203" + "\310\343\316\364`\354\300j\216f\222dtbvb\330oGFG&i\346\210\16\354\16F\315\0\363" + "(\22'A\253\216S\223o\217K\323\203\261\3\253\71\232I\222\321\211\331\211a\277\35\31\35\231\244\231" + "#:\260;\30\65\3\364-\22'A\353QW\333\216L\16\315\215\315\343\306\364`\354\300j\216f\222" + "dtbvb\330oGFG&i\346\210\16\354\16F\315\0\365.\322&Ak\215\205\335\210\35\224" + "\311\230\211\315\343\312\364`\354\300j\216f\222dtbvb\330oGFG&i\346\210\16\354\16F" + "\315\0\366*\222&A+\15I\16\15\16\311\343\241\351\301\330\201\325\34\315$\311\350\304\354\304\260\337\216" + "\214\216L\322\314\21\35\330\35\214\232\1\367\23\21$\313\352M\63\237\307\372\340\3{\254\247\231\317\1\370" + "\60R%\77\353\7\232L\35\24\35\34\315\321\314\231\214]\314M,\233\261\32\62\232\62\232\262\31\63\31" + "\33\261\33\61\243!#\262\60:\260\232\70\214\7\371\33\20\67A\353POS\217\257\307r\324\377_\36" + "\304UX\34\204\34L\14\31\11\372\32\20\67Ak\322\22\257V\217\355\250\377\277<\210\253\260\70\10\71" + "\230\30\62\22\373\37\20\67A\253\321\326Z\216\314\15M\215\315c\65\352\377/\17\342*,\16B\16&" + "\206\214\4\374\34\220\66A\353\14\215\15\215\15\315\343n\324\377_\36\304UX\34\204\34L\14\31\11\375" + "\65R\11/\251\222\217\223o\217\223\341\211Q\212\321\21\312\231\301\241\301\251\271\251\261\355\246\346\206&g" + "&GFGf'f\255[\323\217\317/\37\247\224(\275\255\6\376*\21\71/+\214\357o\254&\16" + "f\16\16B\352(('(o\375\355\345A\344D\35\305A\204\311\304\301\314\214\325\370\376\34\0\377\66" + "\322\10/)-\34\32\34\232\307\213\341\211Q\212\321\21\312\231\301\241\301\251\271\251\261\355\246\346\206&g" + "&GFGf'f\255[\323\217\317/\37\247\224(\275\255\6\0\0\0\4\377\377\0"; diff --git a/src/fonts/OpenSans-Regular_37.h b/src/fonts/OpenSans-Regular_37.h new file mode 100644 index 00000000..d68d5f7d --- /dev/null +++ b/src/fonts/OpenSans-Regular_37.h @@ -0,0 +1,347 @@ +/* + Fontname: -FreeType-Open Sans-Medium-R-Normal--51-370-100-100-P-256-ISO10646-1 + Copyright: Digitized data copyright 2010-2011, Google Corporation. + Glyphs: 191/883 + BBX Build Mode: 0 +*/ +const uint8_t OpenSans_Regular_37[10858] U8G2_FONT_SECTION("OpenSans_Regular_37") = + "\277\0\5\4\6\6\5\7\7\62;\374\364$\364$\370\6\241\15\321*M \6\0\0\201M!\27F" + "I\177NPB=A\377'\306\230\337\36\242\204\7\220 \1\0\42$N\63\257TPJVH \205" + "\4RH \205\204aH\30\206\204a\206\30f\210a\206\30f\210aF\0#b\37\31\201a\66\320" + "\200\4\15H\16\201\344\214\70\320\210\3\15H\320\200\344\20H\16\201\3\215\70\320H\17\70\361\200\23\17" + "\270\64\320\210\3\215\70\320\200\344\20H\16\201\3\215\70\320\210\343\220\364\200\23\17\70\361\200K\3\215\70" + "\320\200\344\20H\16\201\3\215\70\320\210\3\15H\16\201\344\20\70\320\210\3\15\6\0$U\227:{]" + "\65\350\134\134\352\201P\36 c\11C\312\30F\214B\306\42e,R\306\42e,R\306*d\260\62" + "\6;a\64\345\226cN\271\305\206\70k\220\262F)j\224\242\206!j\224\242F)j\24\22\306\31" + "\303\204\24\226x\240\220\7DZr\320y\12\0%\223\244\71\177jb:z\4\251F\20!\204\21\64" + "\314X\4\21C\324H\343\220D\322@#\15\65\320@D\15\64\255\201\306!k\240a\10\33h\30\302" + "\6\32\205\264\201F\31n\240A\10\61\204\30B\6A\203\30\62\310Pc\230\61(B\4!d\220\61" + "\314\30jP\206\14D\246C\210!\204\14\64\334(\3\215F\312@\243\15\63\320`\304\14\64\26\71\3" + "\215E\316@C\21\64\251\221\6\32\211\244qH\32\212\30\202\310\32f \302\10!\210\64\205\310C\335" + "\20\0&i\242\71\177\345t\60\253n\242pd\71%\22T Q\4\22E Q\4\226D\42A%" + "\22Dd\61e\226aj\11\346*\214\364\311\352\262U\212\21F\221R\212I\204\224c\20!$\31C" + "HQ\246\20B\230\31\205\20WB)\344%C \62$\232S\240\71\305\245S\30+&\35a\312\3" + "\205\230\362\200\70\246\70eN\222\0'\15E\63\257K\360\2-\14\61_\0(\61\13+q\317C\14" + "\71\304\20S\14\61\305\20S\31b*C\16ej\206\234b\310\241\235b\252C;\305\224C\235r\310" + ")\207\234r\10\42\207 \2)/\13+qO@\20\71\4\221S\16\71\345\220S\16u\212)\207v" + "\212)\207\376L\315\220CLe\310!\246\30b\212!\246\30\352\20C\16\0*\60\330%\241\134E(" + "}+ \202\202(d\224\22\222\20\342\201\17\260T\246\211\350\21A\34\21\244\21BV!%\25SP" + "\61%\221\63X@\341\0+\23X\66\215]\65\352\374\267\36\370\1\246F\235\377\26\0,\23G#s" + "MQ\23DT\202\14J\220A\306 \203\0-\11\14!\231P\360\3\3.\16\306A\177\316\60D\11" + "\17 A\2\0/\62\21\31\201\323FXa\244\21V\30i\204\221FXa\244\21V\30i\204\221F" + "Xa\244\21F\32\305H#\254\60\322\10#\215b\244\21V\30i\244\1\60N\230\71\177]t\336Z" + "\17= NeJ*\205,BH#\203\64\62H+\201<\22\310#\201<\22\310#\201<\22\310#" + "\201\274\374=\22\310#\201<\22\310#\201<\42H+\202\64\62H#\204\254BJ*\246\234\202\36\10" + "\311\255\365N\2\61\34\15Y\201\335D\216\61\247\240\241\204\11$\224\221\10\11\243\220\20\16I\364\377\377" + "\37\62(X)\201]\204ZK\17\10\363\0!&\31\62X)\301\21Z(mV\223P\62\311,\223" + "\314\42\353\377\223\17\374\3\6\63:\230)\177]\204\330;\17\214\362@!&\31\42Z\241e\26J\67" + "\313$\263\310\2\217bL\271\266\336\64\264PB\13\245\67\313$!\304\22\10\63\342\1\63\36(\345\1" + "\261T\2\64C\33\31\201\335X\252E\317D\222\4\42I \221\10\2\311 \220\14\362\10!\216\24\322" + "\210!\215\30\302\310!\213 \262\10\42\212$J\21D\26Ad\221C\30\61\244\21C\32)\17\374\7" + "\206$\227~\5\0\65:W\71\177\335\361\300 \17\20\362\0!\17\20B&}s\320\61\251\220\322\3" + "\302<\60\314\3$\232Y&\231e\322'\213$\262\204\360\212 \313\210\7\312x\200\224\7\202R\11\0" + "\66K\230\71\177]\226\30S.\245\61\220\211E\226IQ\62\313$\224\232\245\234C\6+D\70BB" + "!g\240T\204aD\30VBq$\220G\2y\11b\60\271\22\210#\202\70\42J#\203\260\62\212" + "*\305\234r\36\20\350)\366\16\2\67\63\31)\201]\360\37H\225\320B\11-\224TBI%\224T" + "BI%\264PB\13%\264PB\13%\264PR\11-\224\320B\11-\224\320B\11-\17\0\70[" + "\230\71\177\335\223ZS\17\4\203\6*%\25RV\31\244\221A\32\31\244\221A\32\31\244\221A\32!" + "d\221RR\61\306\24t\204Q\314%\267\326C\206\34S\220!E\231A\32\21\304\225@\36\11\344\221" + "@^z$\220G\2y$\224V\4id\230dH\22\310< \320c\11\1\71@\227\71\177]t" + "\32S\16=\20LA\205\24U\6aD\224F\2q$\220\207\77\247Z\11e\231`\322\21\207\224@" + "\206\23\204\260A\316)d\22I&%\213$\262\304\332!\42!\227\232J\14\0:\25FG\177\316@" + "B\11\17 \61>\364\207(\341\1$H\0;\36\310(s\316AF\31FX\242\220\361a\277\214j" + "\220Q\15B\250A\10!\243\214\2\0<\36X\66\215\335\33\352\230%\236w\357\31h\305\62\313D\22" + "\223Ib\62I$\15%V\0=\17\227\63\227]\360\7\322\207\327\37\370\201\4>\37X\66\215]\20" + "\356\250e\36\211\67\357\246\221\6\36\207\265\324\220C-\71\4\313\34\65\134\0\77,\224\31\177\326\202\222" + "#\17\210\361\300\30#\31\21X\201T$\220<\2\251G^q\365=\12Rp\304\361aE\300\362\214" + "\263=\242\0@\224h:w\356\230\366\3\242>`b\62\351\31gZ\221e\221Z\22\301\344\220L\14" + "\331\244\20\225\322 $\71C\306H\357\14AP\71\344\14ANA\344\220\60\20I\3\221\60\16Q\3" + "\241C\324@\350\214\65\20\62d\15\204\14Q\4\235C\24A\347\20E\320\10\304\20E\320\10\344\14E" + "\16\11\344\20T\316\20\344\220\63\302(d\14T\10\11d\20\62\20\23\213\20\244\10\62D\31T\20\371" + "\240\220\17\14\371\300\220\17\212\371\200\234\67b\62H>p\350\3C\257\7\0AU \11\201`Gx" + "\321\226>\30a\22\210%\202X\42\210%\203PB\10%\244\310R\210$\206Hr\10$\210@\202\212" + "+\211\70\242\210#\252\60\212=`\324\3G=p\324\3\10\21H\20\201\305\24X\14\221\304\20Y\10" + "\241\204\20JF\241E\20K\4\261\11\23BR\31Y\201a\360@H\17\224\362\200!\17\234A\330\21" + "\304\25A^\11\344\225@ \11\4\222@ \11\344\225@\36\21\304\25A\230\31\17\224\362\200@\17\224" + "\362\300\31\244\31A^\11\4\222@`\212x\60\367J \355\204\7\220x\340\214\7Jy@ \0C" + "\66\233\71\177\340\246\334\3!=@\316\3\245 \65\312q\241\30Z\252\251\305\22[Yb\353\277K\335" + "b\313-\266\334b\215=\25-q\36(\350\1\242\36\20m\21\0DJ\35Y\201e\360@h\17\224" + "\364\300\71\17 C\30*\344\31B\240\31$\32Ad\21d\226@f\11\204\222@h^\305\243\71J" + "\2\231%\220Y\2\221E\20Y\4\211e\20h\6q\207\20\206\312\3\310<`\320\3D=\7\0E" + "\36\24Y\201\134\360\17$H\377\301\7Hx\200\204\7Hx\200\4\2\351\377\340\3\177\240\0F\33\24" + "Y\201Z\360\17$H\377\7\37 \341\1\22\36 \341\1\22\10\244\377\17\2GM\236\71\177e\247\342" + "\3b=`\316\3\347 U\214\201\301\230kp\225I\256\62\311\365\332\3\242= \332\3\242= j" + "\252$\220J\2\251$\24JB\241D\224ID\231d\24I\206\211\204\234G\12j\304<\220\320\3G" + "=@\34+\0H\23\34Y\201f@f\376\177\363\201\377\201\60\363\377o\26I\12\4Y\201N\360\377" + "@\2J\26M\313n\316D\377\377\377\377\37*\210\240\22\226X\42\221c\0K_\32Y\201_@`" + "\11\344\25A\134\31\244\25BZ!\204\225BV\61D\225CRA\4\225DNQ\304\224EJa\204" + "\224FFqD\224G\302q$\240\326\332\21\205\31RV)e\221S\24A%\221T\20I\5\21U" + "\16Y\305\20V\12a\245\220V\10qe\220W\4yE\20X\2\211\5L\21\24Y\201Z@ \375" + "\377\377\377\340\3\177\240\0Mu$Y\201npn\263\316>\372@\240\17\210\71\2\12D\222\200\2\221" + "$\240P \21H\20H\4\22\4\22\201\6qd\240A\34\31h\24F\10\42\204\21\202\10a\204\240" + "B\24)\250\20E\12*\5\21\203\14A\304 C\20\61\350\20C\16:\304\220\203N)\3!D\10" + "A\10\21B\20BE\220\204\22\21$\241D\304P\370\324Yh\231\205\226Y\210\21\206\30\5NP\34" + "Y\201fP\246\222J\256\310 \203\355\241P\34\22\304!Q\32\32\205\241Q\30\42e\241R\24*E" + "!S\22:\5\241S\20B\345\240T\14J\305 U\12Z\205\240U\312a\205\234V\306ie\34W" + "\304y%\234W\302\201,nR\315\64\13OX\242\71\177h\246\352\3\1>@\334\3g\35u\222q" + "\346\30XN\221\245\24JJ\241e\24KF\261E\220[\4\301$\24LB\301$\24LB\301\372\60" + "\11\5\23A\60\21\344\26Ql\21\305\22Bj!\205\22Sd\61\6\26d\234IG\235\365\300i\17" + "\220\370lj\0P\63\27Y\201_\360\320\3\243@\334\3g\35u\222q\346\30XN\221\245\24JJ\241e\24KF\261E\220[\4\301$" + "\24LB\301$\24LB\301\372\60\11\5\23A\60\21\344\26Ql\21\305\22Bj!\205\226Rd\61" + "\6\26d\234IG\235\365\300i\17\220\370\354\362U\267o\0R^\31Y\201`\360\324\3\343\34\11\201]P&\11D" + "\226P\42\31\345\225Q\36)\245\25CX\71e\221DTI%\221EPY\345\220FLi\245\220G" + "Hye\220H\4\231$\220\211\352\251\346\226K\60\375\77\6\0Z\70\31)\201\335\360@\12\17\244\360" + "@\12\17 Zf\241\204\226Y(\241e\26Jh\231\205\22Zf\241\204\226Y(\241e\26Jh\231" + "\205\22Zf\241\204\226\371\300\77\240\0[\22\14KqQ\360\3\7\321\377\377\377\377\320\3\37\30\134*" + "\21\31\201S@\32q\244Q\216\64\312\221F\34i\224#\215r\244\21G\32\345H#\255\64\312\221F" + "\71\322H+\215r\244\21]\22\14\33qQ\360\3\343\324\377\377\377\377\316\3\37@^\67\331\25\235\334" + "\65*\251e\232y\42\11#\16A\36\31\343\221A\334(\243\221B\330\70c\221C\324H#Qh," + "b\310\42f\64BH#\204\70\42\310#\202@\24\11_\11\327\0qW\360\7\22`\16\12\242\277]" + "P\212)\305\24C\16\15a\71V'\177\134\224\224\63\17\10s\4*#\25Y$=\305\314\3\201<" + "\60\6:D\224EBa$\220\226c\212\225@\226\11d\231P\20\22G\30\61\204\33c\60\62\12J" + "\0b\71\30J\177_Pf\375\67\211\71\207\14V\210p\204\204\23\320@\310\210\263J\60\254\4\323H" + "(N\275\374\237[\215\4\303J\70\213\10\204\214 \341\4\64\210p\204\14\366\316\1c'T\67\177\330" + "\204\222+\216<\20HI\201\24W\36\201\344U\217@\372\301\2)X=\243\2y \224wZJ\3" + "\0d\77\30:\177_J\377C\247\220\302\6!N\220\201\302\11D\30\204DQ'\24f\2q%\20" + "\247\134z\11\342\17&W\2q%\20WBaF\224e\204Ah\240p\2!N\220\302\6A'\1" + "e\64W\67\177]t\34S\16\235\200L\71\206\24E\10YE\220F\4i$\224\226\134r\17\374\201" + "\61i\263L\62\213,\263L\243Fy`\230\7\304y+\25\0f\37\322\31\201Qu\222:\313\234@" + "\14i\245\21G\217\65\361@\20\17\204C\34\375\377\377\22\0g^\32\32i\134t\342\3\245<`\210" + ")k\224D\20Y\343\224E\14a\304\20F\14a\304\20F\14a\344\220ENI\5\25c\322\3\201" + "\265\246\36\251\304\216;]b\37\10\353\201\201\36 \345\201\63\210+\202@\22H$\201D\22H$\201" + "D\22\10,\202\270\62\316A\345\201\202\36\10l%\0h\37\327I\201_Pd\375\257\34SD\33D" + "\30:i_t\34#\203\70" + "A\6\12'\20a\20\22E\235P\230\11\304\225@\234r\351%\210\277\247\134\11\304\225@\134\11\205\31" + "Q\324\21\6\241\201\302\11\204\70A\12\33\344\240B(\375\17r\31\20G\201U\245\10\33M\270@\16" + "\11\3\235d\224Qe\325\377\177\13\0s,S\67\177X\203\320\33\17\4\201\2\12E\11A\36\355\25" + "g\334iii\14\65\324\314+\217\366JC\252\204#Rx@\210w\224\1t\34\220\30\177\322\62\332" + "\304h\352\201\17\4B\30\375\377\217\25v\302(\313(t\2\0u \27G\177_@\36\376\377\347\222" + "SM\61\23\310:\301 $P\70\201\210'\10a\203\30\224\0vF\331\6\201ZP \11\4\222@" + "^\11\305\221AZ\31\244\21R\30)d\225R\24\71D\221CR\71\5\221D\20I\344\220E\14Y" + "\244\224E\12i\204\220F\6qE\220G\4y$\220\70\2\211(\236ifQ\0wo\346\26\201h" + "@Xi\210\231\245\226YD\220e\26\21D!E\4Q#\220TDI#\220D\10AD\214D\10" + "AD\20D\10Ac\220CJ\61d\220C\14E\210\241\21b\250BC\204\20C\10A\204\20C\10" + "Ad\220CFAd\20D\4QD\20D\4Q$\220D\4Q$\20\65\2a#\20\205\330\10c" + "!vc\306\225f\134u\0xA\330\26\201\333PZ\21\204\225Q\26)%\25CP\71\345\220TJ" + "Q\204\24F\6i%\220\227\340\211f\26y \202$\20GDae\24U\12Q\304\24TN\61%" + "\221R\26!\204\25Q\232z\4yS\331\11iZP \11\4\222@^\11\305\221A\34\31\205\25B" + "\30)d\25C\24\71D\221SPAT\42\210(b\212\42\206\254R\10#\204\64B\210#\242\70\42" + "\310#\202@\24\221<\322LC\13%\264PR\11-\224\320\62K\33\341\70\365\22<\22\0z&\324" + "&\201\330\360\300\20\17\14\361\300\200\344\25W\36\365\212+\217\274\342\312\243^y\324+\256<\352\225G" + "\336\3\77{(\20+qSF\322A\350\240cTY\204\321\177\253,\262\312A\310(\243\320\62\214\260" + "\302\350\177\254\254\302PB\351\254\2|\12\304\314i\134\360\377\17$}(\20+qS@\230Q'!" + "V\30\305\312\252\177\214j\205\241t\224A\310\30U\26Y\365\277EV\71\10!d\24a\0~\27\230" + "\61\237\335qZ\10\14=P\302\12\17\210 \20\23\201\35\2\0\240\6\0\0\201M\241\27FIo\316" + "@B\11\17 \61\366\30\363\67\210\240\177\241~\1\0\242+\224Y\177]\65\342\354\245\344\310\7\302\60" + "I\214\342\312#\257z\4\322\37,\257@\2\313\263\222 \17\204\362\214K\251\215\70w\0\243)Y)" + "\201\335\225\234K\17\210\363\200@%\215S(\251\364\37|\200\230\7\210y\200,R\351G\13%\225P" + "j>\360\17(\244A\227\65\217\335 \242\10\204\34B\2\11+\220\361\0)\226)\210\230\261F!\213" + "\220\321\6\31m\220\321\310\30\215\214\321\6\31m\20\262H\31\213\224\202\210\71\343\224\7\310 a\5\212" + "\34B\202\210\42\0\245J\33\31\201]@&\11$\226P \31\344\21R\34)\244\21S\30\71d\21" + "T\24I\224*\247,rH#\245\64R\310#\203@\62H$\201H\22\310<\356\1\202\36 \350\1" + "\362\212\255\275\7\10z\200\240\7\310+\266\276\5\0\246\17\304\314i\134\360\17\204\17\352\3\177 \0\247" + "I\324\71\201Z\243\320\33\17\10q\310\21\204\205A \5\313\63\357\270\304Tj\206\20\64\310\71\202\244" + "\42\306J\14\61\22\310\42\241(\42\12\42\3\221RP(\207\255\324\320\63\257\300\2\251wX\11\306\234" + "\360\300\20\17\204\263\14\0\250\17N\201\301]\60\316\10\244d\5\235\21\0\251}\246)\177\352\207\366\253" + "\17\220h\224y\345\221F$Y\244\216D\356@C\35\64\314H\313\214\62P;\203\214c\310@\203\10" + "D\344\20\343\220\71\304\70\204\12!\16\251#\210C\352\10\342\220j\16\251\346\220:\202\70\244\216 \16" + "\251#\210C\352\10\303\220*\304\70d\216!\16\231c\214C\244 \343\230\42\320(\343\260\63\235u\306" + "!\350\240\221H\35\213H\322\312#\317\254\42\37 \365i\364\0\252\35N$\251\322q\312\32lMl" + "\254A\224`\241\24\203\314\271\314\3$\244\60\204\31\3\253\65U%\207Y\24RH\304\20SJ\61\244" + "\24CgJ!\246\224\232!\245\30\12\221RN)\345\224RN)\345\20C\20\61\4\221RN)\345" + "\20CPHA\0\254\14X\63\217]\360\7\30\245\377\0\255\11\14!\231P\360\3\3\256\214\246)\177" + "\352\207\366\253\17\220h\224y\345\221F$Y\244\216D\356@\243\254\64\314\60\355\214\62\216;\203\214C" + "J\71\203\10D\16\71C\14D\16\71C\14D\16AB\210D\16A#\210D\14I#\210DJI" + "&\65e\22[#\210\264\330\10\42\21B\326\10\42\21B\326\10\3\221B\224\20\3\221B\322\30\2\21" + "C\320\30\343PG\220q(\63\312\60\4\21\62\316(\4\21\62\16\271#\221:\26\221\244\225G\236Y" + "E>@\352\323\350\1\257\11\332\0\317Z\360\17\14\260!\20\64\253\326bP\62l\24B\306@C\14" + "\64\302P\66u\320\20\3\15Q\10!\254\244d\12\0\261\27\230\67\203]\65\352\374\267\36\370\1\246F" + "\235\377>\340\17\374\0\3\262\27\217\25\237Rr\314\32l\220BF@\203\315-\242\350\237z\340\3\263" + "%\317\25\235Rr\12\23N\14CDH\203\221E\326XD\221\222L\62k\225E\330l\31D\202\13" + "\215\240\2\0\264\15\12\242\277]bH\255\320\314\70\0\265 \327Ii`P\134\376\377\257im\255\206" + "\36X\341\1\63NX\344\214\223\310$\263\310\372\223\0\266}Y;u\341\363\300 \17\230\361\300\21\257" + "\14\361\312\10\17\204\62\302\3\241@\302\3$<@\302\3" + "$\20H\377\7\37\370\3\5\313-T[\201\134\62\314\70\245\20S\12\61\245\220\63\314\370\220}\340\17" + "$H\377\301\7Hx\200\204\7Hx\200\4\2\351\377\340\3\177\240\0\314\30\312\13\201NPLU\212" + ")\206\34\202\306\7\204\30\372\377\377\377_\0\315\24\312K\201\316R\210!U\241\373\300\320\377\377\377\377" + "\25\0\316\37\320\373\200NC\226I\350\250RD\31\205\20Q\14\11C\215\17.a\364\377\377\377\77\3" + "\0\317\30N\13\201\316\60\314\10\245d\205\204a\306\7\237(\372\377\377\377_\1\320`!\31\201e\362" + "@\210\17\20\367\200a\17 E\30J\304\35D\240\71$\226Cd\61D\26Cf)d\226B()" + "\204\222B()\204>\200\324\3H=\200\324\3H\25Bh!\204\222B()d\226Bf)d\22" + "Cd\61$\32Cb\71\344\31D\334Ad\245\364\300Y\17\30\366\0q\317\1\321a\134[\201fT" + "\320X\310\210\305\2Y$\60\65\14Z\3\225\17\365\62\225TrE\6\31l\17\205\342\220 \16\211\322" + "\320(\14\215\302\20)\13\225\242P)\12\231\222\320)\10\235\202\20*\7\245bP*\6\251R\320*" + "\4\255R\16+\344\264\62N+\343\270\42\316+\341\274\22\16dq\223j\246Y\0\322a\42<\177h" + "U\272\351\305\27O>\355\303\202\252\17\4\370\0q\17\234u\324I\306\231c`\71E\226R()\205" + "\226Q,\31\305\26An\21\4\223P\60\11\5\223P\60\11\5\353\303$\24L\4\301D\220[D\261" + "E\24K\10\251\205\24JL\221\305\30X\220q&\35u\326\3\247=@\342\263\251\1\323`\42<\177" + "hYx\351\205W\235\366aD\325\7\2|\200\270\7\316:\352$\343\314\61\260\234\42K)\224\224B" + "\313(\226\214b\213 \267\10\202I(\230\204\202I(\230\204\202\365a\22\12&\202`\42\310-\242\330" + "\42\212%\204\324B\12%\246\310b\14,\310\70\223\216:\353\201\323\36 \361\331\324\0\324h\42<\177" + "hW\370\331G'LD\261\244\20J\16\221$\221\17mU\37\10\360\1\342\36\70\353\250\223\214\63\307" + "\300r\212,\245PR\12-\243X\62\212-\202\334\42\10&\241`\22\12&\241`\22\12\326\207I(" + "\230\10\202\211 \267\210b\213(\226\20R\13)\224\230\42\213\61\260 \343L:\352\254\7N{\200\304" + "gS\3\325h\242;\177\350E\320\210\251\14\310\2\211$\260(\14\212\3\225\17uU\37\10\360\1\342" + "\36\70\353\250\223\214\63\307\300r\212,\245PR\12-\243X\62\212-\202\334\42\10&\241`\22\12&" + "\241`\22\12\326\207I(\230\10\202\211 \267\210b\213(\226\20R\13)\224\230\42\213\61\260 \343L" + ":\352\254\7N{\200\304gS\3\326f\242;\177\350\65\314\250\304\20ZH\241\304\220:\314\370pA" + "\325\7\2|\200\270\7\316:\352$\343\314\61\260\234\42K)\224\224B\313(\226\214b\213 \267\10\202" + "I(\230\204\202I(\230\204\202\365a\22\12&\202`\42\310-\242\330\42\212%\204\324B\12%\246\310" + "b\14,\310\70\223\216:\353\201\323\36 \361\331\324\0\327\67\326E\217\335\31\206x#\220\246V\21%" + "\25RN\61\245\24TFQ%\24\226\334\201\5\36\227X\11E\225QP)\305\224SHIE\224U" + "\2i%\210\67h\20\0\330|\42:}h\36b\62\204\275A\324\3H=\220\322I(\31g\216q" + "\347\24\227Jy$\220R\34\21e\24W\6\31\305\21R\4q\244\24AZ\61$\224F\16\11\205\21" + "DBY\5)U\222RD\251T\224Be)D\230:\244\221PLiD\20C\34\21\244\20WD" + "\31\305\25Q\6y\204\224@^!\352\21\203^\61\347\25d\234AH\235\364@J\17 U\304k\303" + "\244\30:\0\331\63\34\134\177\345Sn\301\25&\231\312\343\303\6\231\371\377\377\67I \223\4\62I " + "\223\204\22\213 \221\214\362\12)\255\224\223\216y\300\240\7\6{\60)\0\332\61\34\134\177eglu" + "ix\372\60Cf\376\377\377M\22\310$\201L\22\310$\241\304\42H$\243\274BJ+\345\244c\36" + "\60\350\201\301\36L\12\0\333:\34\134\177\345E\256\251h\252XD\201\204\24GLaC\221\17q\62" + "\363\377\377o\222@&\11d\222@&\11%\26A\42\31\345\25RZ)'\35\363\200A\17\14\366`" + "R\0\334\67\234[\177\345\63=R\210+\245\70R\310\33g|\330&\63\377\377\377&\11d\222@&" + "\11d\222Pb\21$\222Q^!\245\225r\322\61\17\30\364\300`\17&\5\0\335E\334\13\201\335g" + "luix\372\260R&\11D\226P\42\31\345\225Q\36)\245\25CX\71e\221DTI%\221E" + "PY\345\220FLi\245\220GHye\220H\4\231$\220\211\352\251\346\226K\60\375\77\6\0\336A" + "\30Y\201_@(=\372\322\3\303\216)\207N@\246\34C\212\42\204\254\42H#\202\64\22JK.\271\7\376\300\230\264Y&" + "\231E\226Y\246Q\243<\60\314\3\342\274\225\12\0\352C\27:\177\335T\244\201\310)V\4Y\205\220" + "D\16\225\310\207\344qL\71t\2\62\345\30R\24!d\25A\32\21\244\221PZr\311=\360\7\306" + "\244\315\62\311,\262\314\62\215\32\345\201a\36\20\347\255T\0\353A\227\71\177]\63)bH*\244$" + "b\210\32f|\30;\216)\207N@\246\34C\212\42\204\254\42H#\202\64\22JK.\271\7\376\300" + "\230\264Y&\231E\226Y\246Q\243<\60\314\3\342\274\225\12\0\354\25\312\371\200MPL\61\304T\206" + "\34\352\3WJ\375\377\377\7\355\26\312I\201\315RH)\244\24R\12\355\203WJ\375\377\377W\0\356" + "\33\321\351\200MS\226Y'\245CD)\324 \207\4\222\310\207X\375\377\377\317\0\357\33O\371\200\315" + "\60\316\20\244\220PJ\11\244\20\61\316\370\320,\252\376\377\377+\0\360O\31:\177^\24.\71C\235" + "a\324\11\246\251x`z\213\31Q\226!e\215S*\261\244\22K\24\32\344\64A\312\13\204\244\260\206" + "IG\24v\2q&\220\247^\212\370`\202$\224G\4yD\224F\10a\205\230TL\12\10=\20" + "Vs(\1\361,WI\201_S\220\70\250\14\303\2\61$,\63J\62\3\221\17\331c\310h\203\210" + "'Hx@\4\224J\70k\61\345\362\377\377\34\1\362B\31:\177_S\250\241\245\226J,e\307\207" + "\205\363\332z\350\201q\12\62\245\254\62J#\203\270\42\310#\241<\22\10\314\42>\230\240zD\220G" + "Die\220FHY\245\224T\16\12(\275\325\336I\0\363\77\31:\177\337ffEiu\372\60r" + "^[\17=\60NA\246\224UFid\20W\4y$\224G\2\201Y\304\7\23T\217\10\362\210(" + "\255\14\322\10)\253\224\222\312A\1\245\267\332;\11\0\364G\31:\177_U\246\221(\246GDi\204" + "\224E\16I\324\207\364ym=\364\300\70\5\231RV\31\245\221A\134\21\344\221P\36\11\4f\21\37" + "LP=\42\310#\242\264\62H#\244\254RJ*\7\5\224\336j\357$\0\365H\231\71\177_S\320" + "@\310\10\304\2A$\260\63\14B\3\225\17\361\363\332z\350\201q\12\62\245\254\62J#\203\270\42\310" + "#\241<\22\10\314\42>\230\240zD\220GDie\220FHY\245\224T\16\12(\275\325\336I\0" + "\366F\231\71\177_\63\316X\245\220U\12Y\245\20\66\316\370\60{^[\17=\60NA\246\224UF" + "id\20W\4y$\224G\2\201Y\304\7\23T\217\10\362\210(\255\14\322\10)\253\224\222\312A\1" + "\245\267\332;\11\0\367\31\330\65\217]\65h\231\65:>\314=\360\3\354\303\332\240e\326\350X\0\370" + "X\331\67}\337\32\330!\344\260P\314\3\243<@LA\246\24eFQg\20\225\4Q$\220P\22" + "\21$\220DFBe$D\12:\304 S\14\62\344\240B\20\42\345$B\220\22$\21A\2QD" + "\244T\4R\204\30UJI\305\244\200\314\3\303\220\320\16!\207\205\12\0\371+\27J\177_bd\231" + "e\22J\321Q\307\207!\362\360\377\77\227\234j\212\231@\326\11\6!\201\302\11D Date: Wed, 7 Feb 2024 11:35:05 +0100 Subject: [PATCH 07/34] Added .vscode to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1eb0a35c..7dcc35a0 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ docs/.jekyll-metadata docs/vendor .DS_Store +.vscode From d06a236f13a408bfd91d294c6a50a2ea041f3c84 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Wed, 7 Feb 2024 11:35:36 +0100 Subject: [PATCH 08/34] Set ports and build type in platformio.ini --- platformio.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platformio.ini b/platformio.ini index 9851fbf6..0148b1a5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -45,6 +45,8 @@ monitor_speed = 115200 ; This upload speed is the highest I can get, but I do get reliable uploads ; with it. If uploads fail for you, comment out the following line: upload_speed = 921600 +upload_port = /dev/ttyUSB2 +monitor_port = /dev/ttyUSB2 board_build.partitions = src/sd-partition-table.csv lib_deps = adafruit/Adafruit BusIO @ ^1.13.1 @@ -66,3 +68,4 @@ build_flags = -DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024 ; build number "-dev" will be replaced in github action -DBUILD_NUMBER=\"-dev\" +build_type = debug From 7fa7d61422f102af36da6456b5c23923a275a7c8 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Wed, 7 Feb 2024 12:12:08 +0100 Subject: [PATCH 09/34] Add OBSPro support with button and variant selection --- src/OpenBikeSensorFirmware.cpp | 24 ++++++++++++++++++- src/configServer.cpp | 3 ++- src/displays.h | 9 +++++-- src/globals.h | 3 +++ src/sensor.cpp | 2 +- src/utils/button.cpp | 9 +++++-- src/variant.h | 44 ++++++++++++++++++++++++++++++++++ src/writer.cpp | 2 +- 8 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 src/variant.h diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 315b25d7..04b8120f 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -25,6 +25,7 @@ #include #include #include "OpenBikeSensorFirmware.h" +#include "variant.h" #include "SPIFFS.h" #include @@ -46,6 +47,7 @@ const uint32_t LONG_BUTTON_PRESS_TIME_MS = 2000; // PINs const int PUSHBUTTON_PIN = 2; +const int IP5306_BUTTON = 13; const uint8_t GPS_POWER_PIN = 12; const uint8_t BatterieVoltage_PIN = 34; @@ -195,6 +197,8 @@ void setup() { //############################################################## pinMode(PUSHBUTTON_PIN, INPUT); + pinMode(IP5306_BUTTON, OUTPUT); + digitalWrite(IP5306_BUTTON, LOW); pinMode(BatterieVoltage_PIN, INPUT); pinMode(GPS_POWER_PIN, OUTPUT); digitalWrite(GPS_POWER_PIN,HIGH); @@ -396,7 +400,7 @@ void writeDataset(const uint8_t confirmationSensorID, DataSet *dataset) { } void loop() { - log_v("loop()"); + log_w("loop()"); //specify which sensors value can be confirmed by pressing the button, should be configurable const uint8_t confirmationSensorID = LEFT_SENSOR_ID; auto* currentSet = new DataSet; @@ -441,6 +445,7 @@ void loop() { button.handle(currentTimeMillis); gps.handle(); if (sensorManager->pollDistancesAlternating()) { + log_w("poll"); // if a new minimum on the selected sensor is detected, the value and the time of detection will be stored const uint16_t reading = sensorManager->sensorValues[confirmationSensorID]; if (reading > 0 && reading < minDistanceToConfirm) { @@ -473,6 +478,23 @@ void loop() { } gps.handle(); reportBluetooth(); + +#ifdef OBSPRO + // Soft power-off OBSPro when button is pressed for more than 2 seconds + if(button.getState() && button.getCurrentStateMillis() > 2000) { + log_w("Shutting down OBS"); + digitalWrite(IP5306_BUTTON, HIGH); + delay(300); + digitalWrite(IP5306_BUTTON, LOW); + delay(300); + digitalWrite(IP5306_BUTTON, HIGH); + delay(300); + digitalWrite(IP5306_BUTTON, LOW); + delay(2000); + // TODO: Make sure we don't do anything when the system turns off. + // TODO: Maybe write SD content and umount it? + } +#endif if (button.gotPressed()) { // after button was released, detect long press here // immediate user feedback - we start the action obsDisplay->highlight(); diff --git a/src/configServer.cpp b/src/configServer.cpp index b1a154c0..3afd5bbd 100644 --- a/src/configServer.cpp +++ b/src/configServer.cpp @@ -1054,7 +1054,8 @@ static void handleAbout(HTTPRequest *req, HTTPResponse * res) { page += keyValue("GPS messages", gps.getMessagesHtml()); page += "

Display / Button

"; - page += keyValue("Button State", digitalRead(PUSHBUTTON_PIN)); + + page += keyValue("Button State", button.read()); page += keyValue("Display i2c last error", Wire.getWriteError()); page += keyValue("Display i2c speed", Wire.getClock() / 1000, "KHz"); page += keyValue("Display i2c timeout", Wire.getTimeOut(), "ms"); diff --git a/src/displays.h b/src/displays.h index df979074..5dd280cd 100644 --- a/src/displays.h +++ b/src/displays.h @@ -33,7 +33,7 @@ #include "logo.h" #include "fonts/fonts.h" #include "sensor.h" - +#include "variant.h" #define BLACK 0 #define WHITE 1 @@ -61,7 +61,12 @@ class DisplayDevice { private: void handleHighlight(); void displaySimple(uint16_t value); - U8G2* m_display = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE); // original OBS display +#ifdef OBSPRO + U8G2* m_display = new U8G2_ST7567_JLX12864_F_4W_HW_SPI(U8G2_R0, LCD_CS_PIN, LCD_DC_PIN, LCD_RESET_PIN); // SPI based JHD12864-G156BT for OBSPro +#endif +#ifdef OBSCALSSIC + U8G2* m_display = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE); // original OBSClassic display +#endif String gridText[ 4 ][ 6 ]; uint8_t mLastProgress = 255; uint8_t mCurrentLine = 0; diff --git a/src/globals.h b/src/globals.h index ba2b758e..52ee7898 100644 --- a/src/globals.h +++ b/src/globals.h @@ -36,6 +36,7 @@ class HCSR04SensorManager; #include "displays.h" #include "sensor.h" #include "VoltageMeter.h" +#include "utils/button.h" // This file should contain declarations of all variables that will be used globally. // The variables don't have to be set here, but need to be declared. @@ -58,6 +59,8 @@ extern HCSR04SensorManager* sensorManager; extern VoltageMeter* voltageMeter; +extern Button button; + class Gps; extern Gps gps; diff --git a/src/sensor.cpp b/src/sensor.cpp index faadaa1b..74649369 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -258,7 +258,7 @@ void HCSR04SensorManager::sendTriggerToSensor(uint8_t sensorId) { digitalWrite(sensor->triggerPin, HIGH); // 10us are specified but some sensors are more stable with 20us according // to internet reports - delayMicroseconds(20); + delayMicroseconds(200); digitalWrite(sensor->triggerPin, LOW); } diff --git a/src/utils/button.cpp b/src/utils/button.cpp index cb00e572..224e1db7 100644 --- a/src/utils/button.cpp +++ b/src/utils/button.cpp @@ -23,11 +23,12 @@ #include "button.h" #include "esp32-hal-gpio.h" +#include "variant.h" Button::Button(int pin) : mPin(pin) { pinMode(pin, INPUT); mLastStateChangeMillis = mLastRawReadMillis = millis(); - mLastState = mLastRawState = digitalRead(pin); + mLastState = mLastRawState = read(); } void Button::handle() { @@ -35,7 +36,7 @@ void Button::handle() { } void Button::handle(unsigned long millis) { - const int state = digitalRead(mPin); + const int state = read(); if (state != mLastRawState) { mLastRawReadMillis = millis; @@ -64,7 +65,11 @@ bool Button::gotPressed() { int Button::read() const { // not debounced +#ifdef OBSPRO + return !digitalRead(mPin); +#else return digitalRead(mPin); +#endif } int Button::getState() const { diff --git a/src/variant.h b/src/variant.h new file mode 100644 index 00000000..c8509a4f --- /dev/null +++ b/src/variant.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019-2023 OpenBikeSensor Contributors + * Contact: https://openbikesensor.org + * + * This file is part of the OpenBikeSensor firmware. + * + * The OpenBikeSensor firmware is free software: you can + * redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * OpenBikeSensor firmware 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the OpenBikeSensor firmware. If not, + * see . + */ + +#ifndef VARIANT_H +#define VARIANT_H + +// If set, the firmware is build for the OBSPro hardware variant +// The main differences are: +// - The button is inverted +// - The button is also responsible for soft-power-off +// - The display is a JHD12864-G156BT which is SPI based +// - The ultrasonic sensors are PGA460 based +#define OBSPRO + +// If set, the firmware is build for the OBSClassic +// #define OBSCLASSIC + +#ifdef OBSPRO +#define LCD_CS_PIN 12 +#define LCD_DC_PIN 27 +#define LCD_RESET_PIN 4 +#endif + +#endif diff --git a/src/writer.cpp b/src/writer.cpp index 33860bed..8c1a9a38 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -82,7 +82,7 @@ bool FileWriter::appendString(const String &s) { mBuffer.concat(s); stored = true; } - if (getBufferLength() > 10000 && !(digitalRead(PUSHBUTTON_PIN))) { + if (getBufferLength() > 10000 && !button.read()) { flush(); } if (!stored && getBufferLength() < 11000) { // do not add data if our buffer is full already. We loose data here! From decef39935a9bb3157c92148c154df331a16abdc Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 8 Feb 2024 13:01:54 +0100 Subject: [PATCH 10/34] Switch to fixed u8g2 lib and disable custom build/serial options again (found the buttons for that) --- platformio.ini | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 0148b1a5..5232a1b9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -45,15 +45,14 @@ monitor_speed = 115200 ; This upload speed is the highest I can get, but I do get reliable uploads ; with it. If uploads fail for you, comment out the following line: upload_speed = 921600 -upload_port = /dev/ttyUSB2 -monitor_port = /dev/ttyUSB2 board_build.partitions = src/sd-partition-table.csv lib_deps = adafruit/Adafruit BusIO @ ^1.13.1 ; https://arduinojson.org/v6/api/ bblanchon/ArduinoJson @ ^6.21.2 rlogiacco/CircularBuffer @ ^1.3.3 - olikraus/U8g2 @ ^2.35.9 + ; olikraus/U8g2 @ ^2.35.9 + https://codeberg.org/j000bs/U8g2_Arduino.git#jhd-fix adafruit/Adafruit BMP280 Library@^2.6.8 pololu/VL53L0X@^1.3.1 ; https://github.com/fhessel/esp32_https_server @@ -68,4 +67,3 @@ build_flags = -DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024 ; build number "-dev" will be replaced in github action -DBUILD_NUMBER=\"-dev\" -build_type = debug From baec7e95e33f5b2826dd50b4da111b62294bcd0b Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 8 Feb 2024 13:02:38 +0100 Subject: [PATCH 11/34] Enable display testing only for OBSClassic --- src/OpenBikeSensorFirmware.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 04b8120f..732e82b7 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -206,6 +206,7 @@ void setup() { //############################################################## // Setup display //############################################################## +#ifdef OBSCLASSIC Wire.begin(); Wire.setClock(500000); Wire.beginTransmission(displayAddress); @@ -213,6 +214,7 @@ void setup() { if (displayError != 0) { Serial.println("Display not found"); } +#endif obsDisplay = new DisplayDevice; obsDisplay->showLogo(true); From 75210338e7b8c4ae54b9ffbc057e2c3379e454f2 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 8 Feb 2024 13:02:57 +0100 Subject: [PATCH 12/34] Fix include warning for CircularBuffer.hpp --- src/OpenBikeSensorFirmware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenBikeSensorFirmware.h b/src/OpenBikeSensorFirmware.h index 04ea24e3..efaab3ca 100644 --- a/src/OpenBikeSensorFirmware.h +++ b/src/OpenBikeSensorFirmware.h @@ -26,7 +26,7 @@ #include #define CIRCULAR_BUFFER_INT_SAFE -#include +#include #include "config.h" #include "configServer.h" From 6cf9d117878b09dda53df1d6a67a01a65b6a350d Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 8 Feb 2024 13:03:17 +0100 Subject: [PATCH 13/34] Temporarily disable GPS as it is not working yet and delaying the startup --- src/OpenBikeSensorFirmware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 732e82b7..e5eb6e15 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -295,7 +295,7 @@ void setup() { SPIFFS.end(); WiFiGenericClass::mode(WIFI_OFF); obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Start GPS..."); - gps.begin(); + //gps.begin(); // FIXME: Add GPS support for MAX-M10M if (gps.getValidMessageCount() > 0) { obsDisplay->showTextOnGrid(2, obsDisplay->currentLine(), "Start GPS OK"); } else { From 41ee07af314a6fb3ea5087f5a4022bd3cad3e69a Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 8 Feb 2024 13:03:40 +0100 Subject: [PATCH 14/34] Flip OBSPro display by default --- src/displays.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/displays.h b/src/displays.h index 5dd280cd..8c56b103 100644 --- a/src/displays.h +++ b/src/displays.h @@ -71,7 +71,12 @@ class DisplayDevice { uint8_t mLastProgress = 255; uint8_t mCurrentLine = 0; bool mInverted = false; +#ifdef OBSPRO + bool mFlipped = false; +#endif +#ifdef OBSCLASSIC bool mFlipped = true; +#endif uint32_t mHighlightTill = 0; bool mHighlighted = false; From d8d4fa28215eb40ff80cedb025ddc484476d144c Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Fri, 9 Feb 2024 16:53:46 +0100 Subject: [PATCH 15/34] Added a dummy sensor driver for the PGA460 --- src/OpenBikeSensorFirmware.cpp | 39 ++++++++++--- src/OpenBikeSensorFirmware.h | 1 + src/displays.cpp | 20 ++++--- src/displays.h | 5 +- src/globals.h | 7 ++- src/pgaSensor.cpp | 101 +++++++++++++++++++++++++++++++++ src/pgaSensor.h | 51 +++++++++++++++++ src/sensor.cpp | 2 - src/sensor.h | 6 +- src/variant.h | 11 +++- 10 files changed, 214 insertions(+), 29 deletions(-) create mode 100644 src/pgaSensor.cpp create mode 100644 src/pgaSensor.h diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index e5eb6e15..946705c1 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -60,7 +60,12 @@ Button button(PUSHBUTTON_PIN); Config config; DisplayDevice* obsDisplay; +#ifdef OBSPRO +PGASensorManager* sensorManager; +#endif +#ifdef OBSCLASSIC HCSR04SensorManager* sensorManager; +#endif static BluetoothManager* bluetoothManager; Gps gps; @@ -109,6 +114,14 @@ bool loadConfig(ObsConfig &cfg); void copyCollectedSensorData(DataSet *set); void setupSensors() { +#ifdef OBSPRO + sensorManager = new PGASensorManager; + PGASensorInfo sensor2; + sensor2.io_pin = SENSOR2_IO_PIN; + sensor2.sensorLocation = "Right"; + sensorManager->registerSensor(sensor2, 1); +#endif +#ifdef OBSCLASSIC sensorManager = new HCSR04SensorManager; HCSR04SensorInfo sensorManaged1; @@ -126,6 +139,7 @@ void setupSensors() { sensorManager->setOffsets(config.sensorOffsets); sensorManager->setPrimarySensor(LEFT_SENSOR_ID); +#endif } static void setupBluetooth(const ObsConfig &cfg, const String &trackUniqueIdentifier) { @@ -150,14 +164,18 @@ static void setupBluetooth(const ObsConfig &cfg, const String &trackUniqueIdenti static void reportBluetooth() { const uint32_t currentInterval = currentTimeMillis / BLUETOOTH_INTERVAL_MILLIS; if (bluetoothManager && lastBluetoothInterval != currentInterval) { - log_d("Reporting BT: %d/%d cm", - sensorManager->m_sensors[LEFT_SENSOR_ID].median->median(), - sensorManager->m_sensors[RIGHT_SENSOR_ID].median->median()); +#ifdef OBSPRO + // TODO: Get median values from sensorManager + uint16_t left_median = 0; + uint16_t right_median = 0; +#endif +#ifdef OBSCLASSIC + uint16_t left_median = sensorManager->m_sensors[LEFT_SENSOR_ID].median->median(); + uint16_t right_median = sensorManager->m_sensors[RIGHT_SENSOR_ID].median->median(); +#endif + log_d("Reporting BT: %d/%d cm", left_median, right_median); lastBluetoothInterval = currentInterval; - bluetoothManager->newSensorValues( - currentTimeMillis, - sensorManager->m_sensors[LEFT_SENSOR_ID].median->median(), - sensorManager->m_sensors[RIGHT_SENSOR_ID].median->median()); + bluetoothManager->newSensorValues(currentTimeMillis, left_median, right_median); } } @@ -424,7 +442,10 @@ void loop() { currentSet->batteryLevel = voltageMeter->read(); lastMeasurements = sensorManager->m_sensors[confirmationSensorID].numberOfTriggers; +#ifdef OBSCLASSIC + // TODO: Also required for OBSPro? sensorManager->reset(startTimeMillis); +#endif // if the detected minimum was measured more than 5s ago, it is discarded and cannot be confirmed int timeDelta = (int) (currentTimeMillis - timeOfMinimum); @@ -467,8 +488,8 @@ void loop() { if (lastDisplayInterval != (currentTimeMillis / DISPLAY_INTERVAL_MILLIS)) { lastDisplayInterval = currentTimeMillis / DISPLAY_INTERVAL_MILLIS; obsDisplay->showValues( - sensorManager->m_sensors[LEFT_SENSOR_ID], - sensorManager->m_sensors[RIGHT_SENSOR_ID], + sensorManager->m_sensors[LEFT_SENSOR_ID].minDistance, sensorManager->m_sensors[LEFT_SENSOR_ID].sensorLocation, sensorManager->m_sensors[LEFT_SENSOR_ID].rawDistance, + sensorManager->m_sensors[RIGHT_SENSOR_ID].minDistance, sensorManager->m_sensors[RIGHT_SENSOR_ID].sensorLocation, sensorManager->m_sensors[RIGHT_SENSOR_ID].rawDistance, sensorManager->m_sensors[RIGHT_SENSOR_ID].distance, minDistanceToConfirm, voltageMeter->readPercentage(), (int16_t) TemperatureValue, diff --git a/src/OpenBikeSensorFirmware.h b/src/OpenBikeSensorFirmware.h index efaab3ca..af5c4b11 100644 --- a/src/OpenBikeSensorFirmware.h +++ b/src/OpenBikeSensorFirmware.h @@ -34,6 +34,7 @@ #include "globals.h" #include "gps.h" #include "sensor.h" +#include "pgaSensor.h" #include "writer.h" #include diff --git a/src/displays.cpp b/src/displays.cpp index 0d361844..d3de3444 100644 --- a/src/displays.cpp +++ b/src/displays.cpp @@ -55,13 +55,15 @@ void DisplayDevice::displaySimple(uint16_t value) { } void DisplayDevice::showValues( - HCSR04SensorInfo sensor1, HCSR04SensorInfo sensor2, uint16_t minDistanceToConfirm, int16_t batteryPercentage, + uint16_t sensor1MinDistance, const char* sensor1Location, uint16_t sensor1RawDistance, + uint16_t sensor2MinDistance, const char* sensor2Location, uint16_t sensor2RawDistance, uint16_t sensor2Distance, + uint16_t minDistanceToConfirm, int16_t batteryPercentage, int16_t TemperaturValue, int lastMeasurements, boolean insidePrivacyArea, double speed, uint8_t satellites) { handleHighlight(); - uint16_t value1 = sensor1.minDistance; + uint16_t value1 = sensor1MinDistance; if (minDistanceToConfirm != MAX_SENSOR_VALUE) { value1 = minDistanceToConfirm; } @@ -69,7 +71,7 @@ void DisplayDevice::showValues( displaySimple(value1); } else { if (config.displayConfig & DisplayLeft) { - String loc1 = sensor1.sensorLocation; + String loc1 = sensor1Location; if (insidePrivacyArea) { loc1 = "(" + loc1 + ")"; } @@ -83,8 +85,8 @@ void DisplayDevice::showValues( } // Show sensor2, when DisplayRight is configured if (config.displayConfig & DisplayRight) { - uint16_t value2 = sensor2.distance; - String loc2 = sensor2.sensorLocation; + uint16_t value2 = sensor2Distance; + String loc2 = sensor2Location; this->prepareTextOnGrid(3, 0, loc2); if (value2 == MAX_SENSOR_VALUE || value2 == 0) { this->prepareTextOnGrid(2, 1, "---", LARGE_FONT, 5, 0); @@ -98,15 +100,15 @@ void DisplayDevice::showValues( const int bufSize = 64; char buffer[bufSize]; // #ifdef NERD_SENSOR_DISTANCE - snprintf(buffer, bufSize - 1, "%03d|%02d|%03d", sensor1.rawDistance, - lastMeasurements, sensor2.rawDistance); + snprintf(buffer, bufSize - 1, "%03d|%02d|%03d", sensor1RawDistance, + lastMeasurements, sensor2RawDistance); // #endif #ifdef NERD_HEAP - snprintf(buffer, bufSize - 1, "%03d|%02d|%uk", sensor1.rawDistance, + snprintf(buffer, bufSize - 1, "%03d|%02d|%uk", sensor1RawDistance, lastMeasurements, ESP.getFreeHeap() / 1024); #endif #ifdef NERD_VOLT - snprintf(buffer, bufSize - 1, "%03d|%02d|%3.2fV", sensor1.rawDistance, + snprintf(buffer, bufSize - 1, "%03d|%02d|%3.2fV", sensor1RawDistance, lastMeasurements, voltageMeter->read()); #endif #ifdef NERD_GPS diff --git a/src/displays.h b/src/displays.h index 8c56b103..44af3885 100644 --- a/src/displays.h +++ b/src/displays.h @@ -64,7 +64,7 @@ class DisplayDevice { #ifdef OBSPRO U8G2* m_display = new U8G2_ST7567_JLX12864_F_4W_HW_SPI(U8G2_R0, LCD_CS_PIN, LCD_DC_PIN, LCD_RESET_PIN); // SPI based JHD12864-G156BT for OBSPro #endif -#ifdef OBSCALSSIC +#ifdef OBSCLASSIC U8G2* m_display = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE); // original OBSClassic display #endif String gridText[ 4 ][ 6 ]; @@ -315,7 +315,8 @@ class DisplayDevice { void showNumButtonPressed(); void showValues( - HCSR04SensorInfo sensor1, HCSR04SensorInfo sensor2, + uint16_t sensor1MinDistance, const char* sensor1Location, uint16_t sensor1RawDistance, + uint16_t sensor2MinDistance, const char* sensor2Location, uint16_t sensor2RawDistance, uint16_t sensor2Distance, uint16_t minDistanceToConfirm, int16_t batteryPercentage, int16_t TemperaturValue, int lastMeasurements, boolean insidePrivacyArea, double speed, uint8_t satellites); diff --git a/src/globals.h b/src/globals.h index 52ee7898..d28ec6bc 100644 --- a/src/globals.h +++ b/src/globals.h @@ -35,6 +35,7 @@ class HCSR04SensorManager; #include "config.h" #include "displays.h" #include "sensor.h" +#include "pgaSensor.h" #include "VoltageMeter.h" #include "utils/button.h" @@ -55,7 +56,12 @@ extern Config config; extern DisplayDevice* obsDisplay; +#ifdef OBSPRO +extern PGASensorManager *sensorManager; +#endif +#ifdef OBSCLASSIC extern HCSR04SensorManager* sensorManager; +#endif extern VoltageMeter* voltageMeter; @@ -67,6 +73,5 @@ extern Gps gps; extern const uint32_t MAX_DURATION_MICRO_SEC; extern const uint8_t LEFT_SENSOR_ID; extern const uint8_t RIGHT_SENSOR_ID; -extern const uint16_t MAX_SENSOR_VALUE; #endif diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp new file mode 100644 index 00000000..9c221653 --- /dev/null +++ b/src/pgaSensor.cpp @@ -0,0 +1,101 @@ +#include "pgaSensor.h" + +#ifdef OBSPRO + +PGASensorManager::PGASensorManager() +{ + for(int i = 0; i < NUMBER_OF_TOF_SENSORS; i++) + sensorValues[i] = 0; +} + +PGASensorManager::~PGASensorManager() +{ + +} + +void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t sensor_addr) +{ + if (sensor_addr >= NUMBER_OF_TOF_SENSORS) { + log_e("Can not register sensor for index %d, only %d tof sensors supported", sensor_addr, NUMBER_OF_TOF_SENSORS); + return; + } + m_sensors[sensor_addr] = sensorInfo; + m_sensors[sensor_addr].numberOfTriggers = 0; + setupSensor(sensor_addr); +} + +// Guess: Return true if the last measurement is complete and a new one is triggered? +bool PGASensorManager::pollDistancesAlternating() +{ + return false; +} + +uint16_t PGASensorManager::getCurrentMeasureIndex() +{ + return 1; +} + +uint16_t PGASensorManager::getRawMedianDistance(uint8_t sensorId) +{ + return 30000; +} + +uint32_t PGASensorManager::getMaxDurationUs(uint8_t sensorId) +{ + return 3000000; +} + +uint32_t PGASensorManager::getMinDurationUs(uint8_t sensorId) +{ + return 4000000; +} + +uint32_t PGASensorManager::getLastDelayTillStartUs(uint8_t sensorId) +{ + return 5000000; +} + +uint32_t PGASensorManager::getNoSignalReadings(const uint8_t sensorId) +{ + return 6000000; +} + +uint32_t PGASensorManager::getNumberOfLowAfterMeasurement(const uint8_t sensorId) +{ + return 7000000; +} + +uint32_t PGASensorManager::getNumberOfToLongMeasurement(const uint8_t sensorId) +{ + return 8000000; +} + +uint32_t PGASensorManager::getNumberOfInterruptAdjustments(const uint8_t sensorId) +{ + return 9000000; +} + +void PGASensorManager::setupSensor(int sensor_addr) +{ + PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + // Set pin modes + pinMode(sensorInfo.io_pin, INPUT); // IO pin is open drain + digitalWrite(sensorInfo.io_pin, LOW); + + // Reset the TCI "bus" + tciReset(sensor_addr); + + // Write the UART address using TCI + //tciWriteReg() +} + +// Reset the TCI interface by driving it low for >15 ms +void PGASensorManager::tciReset(int sensor_addr) +{ + PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + pinMode(sensorInfo.io_pin, OUTPUT); + delay(20); + pinMode(sensorInfo.io_pin, INPUT); +} + +#endif // OBSPro diff --git a/src/pgaSensor.h b/src/pgaSensor.h new file mode 100644 index 00000000..7e12241a --- /dev/null +++ b/src/pgaSensor.h @@ -0,0 +1,51 @@ +#include +#include "variant.h" + +#ifndef OBS_PGASENSOR_H +#define OBS_PGASENSOR_H +#ifdef OBSPRO // PGASensor is only available on OBSPro + +struct PGASensorInfo +{ + uint8_t io_pin; + uint16_t numberOfTriggers; + int32_t echoDurationMicroseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; + uint16_t rawDistance = 42; // Current distance value in cm + uint16_t minDistance = MAX_SENSOR_VALUE; + uint16_t distance = MAX_SENSOR_VALUE; + const char* sensorLocation; +}; + +class PGASensorManager +{ +public: + PGASensorManager(); + ~PGASensorManager(); + void registerSensor(const PGASensorInfo &sensorInfo, uint8_t idx); + bool pollDistancesAlternating(); + uint16_t getCurrentMeasureIndex(); + uint16_t getRawMedianDistance(uint8_t sensorId); + uint32_t getMaxDurationUs(uint8_t sensorId); + uint32_t getMinDurationUs(uint8_t sensorId); + uint32_t getLastDelayTillStartUs(uint8_t sensorId); + uint32_t getNoSignalReadings(const uint8_t sensorId); + uint32_t getNumberOfLowAfterMeasurement(const uint8_t sensorId); + uint32_t getNumberOfToLongMeasurement(const uint8_t sensorId); + uint32_t getNumberOfInterruptAdjustments(const uint8_t sensorId); + void detachInterrupts() {}; + void attachInterrupts() {}; + + // TODO: These should not be public! + PGASensorInfo m_sensors[NUMBER_OF_TOF_SENSORS]; + uint16_t sensorValues[NUMBER_OF_TOF_SENSORS]; + uint16_t lastReadingCount = 0; + uint16_t startOffsetMilliseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; + +protected: + + void setupSensor(int idx); + void tciReset(int idx); +}; + +#endif // OBSPRO +#endif // OBS_PGASENSOR_H diff --git a/src/sensor.cpp b/src/sensor.cpp index 74649369..50e54c10 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -38,8 +38,6 @@ * - JSN-SR04T-2.0 = ~1125us */ -const uint16_t MAX_SENSOR_VALUE = 999; - static const uint16_t MIN_DISTANCE_MEASURED_CM = 2; static const uint16_t MAX_DISTANCE_MEASURED_CM = 320; // candidate to check I could not get good readings above 300 diff --git a/src/sensor.h b/src/sensor.h index 443c684b..a3e8da21 100644 --- a/src/sensor.h +++ b/src/sensor.h @@ -27,6 +27,7 @@ #include #include +#include "variant.h" #include "globals.h" #include "utils/median.h" @@ -51,12 +52,7 @@ */ const uint32_t MICRO_SEC_TO_CM_DIVIDER = 58; // sound speed 340M/S, 2 times back and forward - const uint16_t MEDIAN_DISTANCE_MEASURES = 3; -const uint16_t MAX_NUMBER_MEASUREMENTS_PER_INTERVAL = 30; // is 1000/SENSOR_QUIET_PERIOD_AFTER_START_MICRO_SEC/2 -extern const uint16_t MAX_SENSOR_VALUE; - -const uint8_t NUMBER_OF_TOF_SENSORS = 2; struct HCSR04SensorInfo { uint8_t triggerPin = 15; diff --git a/src/variant.h b/src/variant.h index c8509a4f..7327d7b3 100644 --- a/src/variant.h +++ b/src/variant.h @@ -33,12 +33,21 @@ #define OBSPRO // If set, the firmware is build for the OBSClassic -// #define OBSCLASSIC +//#define OBSCLASSIC +// Settings specific to OBSPro #ifdef OBSPRO #define LCD_CS_PIN 12 #define LCD_DC_PIN 27 #define LCD_RESET_PIN 4 + +#define SENSOR2_IO_PIN 35 #endif + +// General settings +#define NUMBER_OF_TOF_SENSORS 2 +#define MAX_SENSOR_VALUE 999 +#define MAX_NUMBER_MEASUREMENTS_PER_INTERVAL 30 // is 1000/SENSOR_QUIET_PERIOD_AFTER_START_MICRO_SEC/2 + #endif From 22c16b6ab1fd29d873de9fdd9ded7bb8c3a84ff4 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Wed, 14 Feb 2024 16:09:21 +0100 Subject: [PATCH 16/34] Implemented TCI and SPI interface, both have a working example --- src/OpenBikeSensorFirmware.cpp | 10 +- src/pgaSensor.cpp | 217 +++++++++++++++++++++++++++++++-- src/pgaSensor.h | 27 +++- src/variant.h | 3 +- 4 files changed, 245 insertions(+), 12 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 946705c1..9cb23c09 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -116,10 +116,16 @@ void copyCollectedSensorData(DataSet *set); void setupSensors() { #ifdef OBSPRO sensorManager = new PGASensorManager; - PGASensorInfo sensor2; + + PGASensorInfo sensor1; + sensor1.io_pin = SENSOR1_IO_PIN; + sensor1.sensorLocation = "Left"; + sensorManager->registerSensor(sensor1, 0); + + /*PGASensorInfo sensor2; sensor2.io_pin = SENSOR2_IO_PIN; sensor2.sensorLocation = "Right"; - sensorManager->registerSensor(sensor2, 1); + sensorManager->registerSensor(sensor2, 1);*/ #endif #ifdef OBSCLASSIC sensorManager = new HCSR04SensorManager; diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index 9c221653..3e565d68 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -79,23 +79,226 @@ void PGASensorManager::setupSensor(int sensor_addr) { PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; // Set pin modes - pinMode(sensorInfo.io_pin, INPUT); // IO pin is open drain digitalWrite(sensorInfo.io_pin, LOW); + pinMode(sensorInfo.io_pin, INPUT); // IO pin is open drain + digitalWrite(sensorInfo.sck_pin, LOW); + pinMode(sensorInfo.sck_pin, OUTPUT); + pinMode(sensorInfo.mosi_pin, OUTPUT); + pinMode(sensorInfo.miso_pin, INPUT); + + while(1) + { + uint8_t reg = spiRegRead(sensor_addr, 0x4c); + Serial.printf("Reg: 0x%02x\n", reg); + delay(100); + } + while(1); - // Reset the TCI "bus" - tciReset(sensor_addr); + // Reset the TCI + //tciReset(sensor_addr); + + /*uint8_t data[1]; + while(1) + { + //tciWriteBit(sensor_addr, true); + //tciWriteBit(sensor_addr, false); + tciReset(sensor_addr); + tciReadData(sensor_addr, 0, data, 8); + safe_usleep(10000); + }*/ - // Write the UART address using TCI - //tciWriteReg() } -// Reset the TCI interface by driving it low for >15 ms +// Reset the TCI interface by driving the IO pin low for >15 ms void PGASensorManager::tciReset(int sensor_addr) { PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; pinMode(sensorInfo.io_pin, OUTPUT); - delay(20); + safe_usleep(20000); + pinMode(sensorInfo.io_pin, INPUT); + safe_usleep(100); +} + +void PGASensorManager::tciWriteBit(int sensor_addr, bool val) +{ + PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + pinMode(sensorInfo.io_pin, OUTPUT); + if(val) + usleep(100-22); + else + usleep(200-22); pinMode(sensorInfo.io_pin, INPUT); + if(val) + usleep(200-22); + else + usleep(100-22); +} + +void PGASensorManager::tciWriteByte(int sensor_addr, uint8_t val) +{ + +} + +bool PGASensorManager::tciReadData(int sensor_addr, uint8_t index, uint8_t *data, int bits) +{ + uint8_t io_pin = m_sensors[sensor_addr].io_pin; + + noInterrupts(); + pinMode(io_pin, OUTPUT); + safe_usleep(1270-22); // tCFG_TCI, Device configuration command period + pinMode(io_pin, INPUT); + safe_usleep(100-22); // tDT_TCI, Command processing dead-time + tciWriteBit(sensor_addr, false); // Read + safe_usleep(100-22); // tDT_TCI, Command processing dead-time + + // Write register index, lower 4 bits, MSB first + for(int i = 0; i < 4; i++) + { + tciWriteBit(sensor_addr, !!(index & 0x08)); + index <<= 1; + } + + // Reset the checksum state + checksum_clear(); + + // Read data bits + int byte_offset = 0; + data[0] = 0; + uint8_t bit_offset = 7; + for(int i = 0; i < bits; i++) + { + uint8_t val = tciReadBit(io_pin); + checksum_append_bit(val); // Update checksum + data[byte_offset] |= val << bit_offset; + if(bit_offset == 0) + { + byte_offset++; + data[byte_offset] = 0; + bit_offset = 7; + } + else + bit_offset--; + } + + // Read checksum + uint8_t checksum = 0; + for(uint8_t i = 0; i < 8; i++) + checksum |= tciReadBit(io_pin) << (7 - i); + interrupts(); + + Serial.printf(", Data: "); + for(int i = 0; i < (bits + 7)/8; i++) + Serial.printf("0x%02x, ", data[i]); + Serial.printf("Checksum (pga): 0x%02x, ", checksum); + Serial.printf("Checksum (local): 0x%02x\n", checksum_get()); + + return checksum == checksum_get(); +} + +uint8_t PGASensorManager::tciReadBit(uint8_t io_pin) +{ + while(!digitalRead(io_pin)); // Wait for high level + while(digitalRead(io_pin)); // Wait for falling edge + safe_usleep(150-10); // Wait for sample time + + uint8_t val = digitalRead(io_pin); // Sample the bit + pinMode(io_pin, OUTPUT); + pinMode(io_pin, INPUT); + + return val; +} + +// A usleep function that also works if interrupts are disabled +void PGASensorManager::safe_usleep(unsigned long us) +{ + unsigned long tstart = micros(); + while(micros() - tstart < us); +} + +uint8_t PGASensorManager::spiTransfer(uint8_t sensor_addr, uint8_t data_out) +{ + PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + uint8_t data_in = 0; + // The bit timing may not be faster than 18 MHz clock signal. The arduino framework is so slow, that this seems to be no problem... + for(uint8_t i = 0; i < 8; i++) + { + digitalWrite(sensorInfo.sck_pin, HIGH); + digitalWrite(sensorInfo.mosi_pin, data_out&0x01); + data_out >>= 1; + digitalWrite(sensorInfo.sck_pin, LOW); + data_in >>= 1; + data_in |= digitalRead(sensorInfo.miso_pin)<<7; + } + return data_in; +} + +// Returns the register value or -1 on checksum error +int PGASensorManager::spiRegRead(uint8_t sensor_addr, uint8_t reg_addr) +{ + PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + + // Transmit + checksum_clear(); + spiTransfer(sensor_addr, 0x55); // Sync byte + spiTransfer(sensor_addr, 0<<5 | 9); // Command: chip address + register read + checksum_append_byte(0<<5 | 9); + spiTransfer(sensor_addr, reg_addr); // Register address + checksum_append_byte(reg_addr); + spiTransfer(sensor_addr, checksum_get()); // Checksum + uint8_t tx_checksum = checksum_get(); + + // Receive + checksum_clear(); + uint8_t diag_data = spiTransfer(sensor_addr, 0x00); + checksum_append_byte(diag_data); + uint8_t reg_val = spiTransfer(sensor_addr, 0x00); + checksum_append_byte(reg_val); + uint8_t checksum = spiTransfer(sensor_addr, 0x00); + + //Serial.printf("Data: 0x%02x, Checksum (pga): 0x%02x, Checksum (local): 0x%02x, Checksum (tx): %02x\n", reg_val, checksum, checksum_get(), tx_checksum); + + if(checksum != checksum_get()) + return -1; + + return reg_val; +} + +void PGASensorManager::checksum_clear() +{ + checksum_sum = 0; + checksum_tmp_data = 0; + checksum_offset = 7; + checksum_carry = 0; +} + +void PGASensorManager::checksum_append_bit(uint8_t val) +{ + checksum_tmp_data |= (val << checksum_offset); + if(!checksum_offset) + { + // Add tmp_data and last carry to sum and calculate new carry + checksum_append_byte(checksum_tmp_data); + } + else + checksum_offset--; +} + +void PGASensorManager::checksum_append_byte(uint8_t val) +{ + // Add tmp_data and last carry to sum and calculate new carry + uint16_t sum = (uint16_t)checksum_sum + (uint16_t)val + (uint16_t)checksum_carry; + checksum_carry = sum >> 8; + checksum_sum = (uint8_t)sum; + checksum_offset = 7; + checksum_tmp_data = 0; +} + +uint8_t PGASensorManager::checksum_get() +{ + // Add zero bits until we added the last padded byte + while(checksum_offset != 7) + checksum_append_bit(0); + return ~(checksum_sum + checksum_carry); // Checksum is the inverted sum + carry } #endif // OBSPro diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 7e12241a..7d3679ac 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -8,6 +8,9 @@ struct PGASensorInfo { uint8_t io_pin; + uint8_t sck_pin; + uint8_t mosi_pin; + uint8_t miso_pin; uint16_t numberOfTriggers; int32_t echoDurationMicroseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; uint16_t rawDistance = 42; // Current distance value in cm @@ -42,9 +45,29 @@ class PGASensorManager uint16_t startOffsetMilliseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; protected: - void setupSensor(int idx); - void tciReset(int idx); + + // TCI Interface + void tciReset(int sensor_addr); + void tciWriteBit(int sensor_addr, bool val); + void tciWriteByte(int sensor_addr, uint8_t val); + bool tciReadData(int sensor_addr, uint8_t index, uint8_t *data, int bits); + uint8_t tciReadBit(uint8_t io_pin); + void safe_usleep(unsigned long us); + + // Synchronous UART mode (aka SPI without chip-select) + uint8_t spiTransfer(uint8_t sensor_addr, uint8_t data_out); + int spiRegRead(uint8_t sensor_addr, uint8_t reg_addr); + + // Checksum + uint8_t checksum_sum; + uint8_t checksum_carry; + uint8_t checksum_tmp_data; + uint8_t checksum_offset; + void checksum_clear(); + void checksum_append_bit(uint8_t val); + void checksum_append_byte(uint8_t val); + uint8_t checksum_get(); }; #endif // OBSPRO diff --git a/src/variant.h b/src/variant.h index 7327d7b3..9b751cf8 100644 --- a/src/variant.h +++ b/src/variant.h @@ -41,7 +41,8 @@ #define LCD_DC_PIN 27 #define LCD_RESET_PIN 4 -#define SENSOR2_IO_PIN 35 +#define SENSOR1_IO_PIN 26 +#define SENSOR2_IO_PIN 22 #endif From 2e7db61923354160c94b03a93eca12bfe3b8b340 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Mon, 19 Feb 2024 15:58:46 +0100 Subject: [PATCH 17/34] PGA460 is working as expected, integration in OBS still missing --- src/OpenBikeSensorFirmware.cpp | 3 + src/pgaSensor.cpp | 326 +++++++++++++++++++++++++++++---- src/pgaSensor.h | 236 +++++++++++++++++++++++- 3 files changed, 523 insertions(+), 42 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 9cb23c09..009ea437 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -119,6 +119,9 @@ void setupSensors() { PGASensorInfo sensor1; sensor1.io_pin = SENSOR1_IO_PIN; + sensor1.sck_pin = 25; + sensor1.mosi_pin = 33; + sensor1.miso_pin = 32; sensor1.sensorLocation = "Left"; sensorManager->registerSensor(sensor1, 0); diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index 3e565d68..bbea9d3c 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -6,6 +6,7 @@ PGASensorManager::PGASensorManager() { for(int i = 0; i < NUMBER_OF_TOF_SENSORS; i++) sensorValues[i] = 0; + lastTriggerTimeMs = millis(); } PGASensorManager::~PGASensorManager() @@ -13,20 +14,82 @@ PGASensorManager::~PGASensorManager() } -void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t sensor_addr) +void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t sensorId) { - if (sensor_addr >= NUMBER_OF_TOF_SENSORS) { - log_e("Can not register sensor for index %d, only %d tof sensors supported", sensor_addr, NUMBER_OF_TOF_SENSORS); + if (sensorId >= NUMBER_OF_TOF_SENSORS) { + log_e("Can not register sensor for index %d, only %d tof sensors supported", sensorId, NUMBER_OF_TOF_SENSORS); return; } - m_sensors[sensor_addr] = sensorInfo; - m_sensors[sensor_addr].numberOfTriggers = 0; - setupSensor(sensor_addr); + m_sensors[sensorId] = sensorInfo; + m_sensors[sensorId].numberOfTriggers = 0; + setupSensor(sensorId); } // Guess: Return true if the last measurement is complete and a new one is triggered? bool PGASensorManager::pollDistancesAlternating() { + unsigned long timeMs = millis(); + static uint8_t param = 0; + static bool isDump = false; // True if a dump has to be triggered (false if the dump result has to be read) + if(timeMs - lastTriggerTimeMs > 200 && param <= 63) + { + // Frequently check stat1 register to make sure there are no errors + // TODO: Set sensorId + uint8_t stat1 = spiRegRead(0, PGA_REG_DEV_STAT1); + if(stat1 != 0x00) + { + log_e("STAT1 register error: 0x%02x", stat1); + // TODO: Set sensorId + spiRegWrite(0, PGA_REG_DEV_STAT1, 0x00); // Clear stat1 register + } + + // Get data dump of last measurement + // TODO: Set sensorId + if(!isDump) + { + // Last measurement was a dump, read and print data + //Serial.print("Get dump\n"); + uint8_t data[128]; + if(!spiDataDump(0, data)) + log_e("Unable to get data dump: Checksum error"); + else + { + //Serial.printf("\"%d\": [", param); + for(int i = 0; i < 128; i++) + { + Serial.printf("%d", data[i]); + if(i+1 != 128) + Serial.print(","); + } + Serial.printf("\n"); + //param++; + } + } + else + { + //Serial.print("Get distance\n"); + // Last measurement was a normal measurement, read and print distance + PGAUSResult usResult[1]; + if(!spiUSResult(0, 1, usResult)) + Serial.print("Unable to get US result: Checksum error\n"); + else + { + Serial.printf("%u, %u, %u\n", usResult[0].tof, usResult[0].width, usResult[0].peakAmplitude); + } + } + + // Set parameter + //spiRegWrite(0, PGA_REG_CURR_LIM_P1, PGA_DIS_CL(0) | PGA_CURR_LIM1(param)); + + // Trigger next sensor + // TODO: Set sensorId + //Serial.printf("Trigger with isDump=%d\n", isDump); + spiRegWrite(0, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN((uint8_t)isDump)); // Enable data dump + spiBurstAndListen(0, 1, 1); + lastTriggerTimeMs = timeMs; + isDump = !isDump; + return true; + } return false; } @@ -75,9 +138,10 @@ uint32_t PGASensorManager::getNumberOfInterruptAdjustments(const uint8_t sensorI return 9000000; } -void PGASensorManager::setupSensor(int sensor_addr) +void PGASensorManager::setupSensor(int sensorId) { - PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + PGASensorInfo &sensorInfo = m_sensors[sensorId]; + // Set pin modes digitalWrite(sensorInfo.io_pin, LOW); pinMode(sensorInfo.io_pin, INPUT); // IO pin is open drain @@ -86,42 +150,93 @@ void PGASensorManager::setupSensor(int sensor_addr) pinMode(sensorInfo.mosi_pin, OUTPUT); pinMode(sensorInfo.miso_pin, INPUT); - while(1) + // Check communication + // Rerad the DEV_STAT0 register, where the upper nibble should be 0x4 + // These are the values for REV_ID (0x2) and OPT_ID (0x0) + if(spiRegRead(sensorId, PGA_REG_DEV_STAT0) & 0xf0 != 0x40) { - uint8_t reg = spiRegRead(sensor_addr, 0x4c); - Serial.printf("Reg: 0x%02x\n", reg); - delay(100); + log_e("Setup of sensor %d failed: Unexpected result in status register read", sensorId); + return; } - while(1); + + // Basic setup + spiRegWrite(sensorId, PGA_REG_INIT_GAIN, PGA_BPF_BW(0) | PGA_GAIN_INIT(0)); // 2 kHz bandwidth, Init_Gain = 0.5 × (GAIN_INIT+1) + value(AFE_GAIN_RNG) [dB] + spiRegWrite(sensorId, PGA_REG_FREQUENCY, 55); // 55 = 41 kHz, Frequency = 0.2 × FREQ + 30 [kHz] + //spiRegWrite(sensorId, PGA_REG_DEADTIME, 0x00); // Deglitch not described in DS, deadtime only relevant for direct drive mode + spiRegWrite(sensorId, PGA_REG_PULSE_P1, PGA_IO_IF_SEL(0) | PGA_UART_DIAG(0) | PGA_IO_DIS(0) | P1_PULSE(17)); // Number of pulses + spiRegWrite(sensorId, PGA_REG_CURR_LIM_P1, PGA_DIS_CL(0) | PGA_CURR_LIM1(0)); // CURR_LIM1*7mA + 50mA + spiRegWrite(sensorId, PGA_REG_CURR_LIM_P2, PGA_LPF_CO(0) | PGA_CURR_LIM2(0)); // CURR_LIM1*7mA + 50mA + spiRegWrite(sensorId, PGA_REG_REC_LENGTH, PGA_P1_REC(8) | PGA_P2_REC(0)); // Record time = 4.096 × (Px_REC + 1) [ms], 8 = 36,9ms = 6m range + spiRegWrite(sensorId, PGA_REG_DECPL_TEMP, PGA_AFE_GAIN_RNG(1) | PGA_LPM_EN(0) | PGA_DECPL_TEMP_SEL(0) | PGA_DECPL_T(0)); // Time = 4096 × (DECPL_T + 1) [μs], 0 = 4ms = 0,66m?!? + spiRegWrite(sensorId, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); // Enable data dump + + // Threshold map, then check DEV_STAT0.THR_CRC_ERR + //th_t = np.array([2000, 2400, 2400, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000]) + //th_l = np.array([200, 80, 16, 16, 24, 32, 40, 48, 56, 56, 56, 56]) + PGAThresholds thresholds( + TH_TIME_DELTA_2000US, 200/8, + TH_TIME_DELTA_5200US, 80/8, + TH_TIME_DELTA_2400US, 16/8, + TH_TIME_DELTA_8000US, 16/8, + TH_TIME_DELTA_8000US, 16/8, + TH_TIME_DELTA_8000US, 24/8, + TH_TIME_DELTA_8000US, 24/8, + TH_TIME_DELTA_8000US, 24/8, + TH_TIME_DELTA_8000US, 24, + TH_TIME_DELTA_8000US, 24, + TH_TIME_DELTA_8000US, 24, + TH_TIME_DELTA_8000US, 24 + ); + spiRegWriteThesholds(sensorId, 1, thresholds); + + spiRegWrite(sensorId, PGA_REG_DEV_STAT1, 0x00); // Clear stat1 register + safe_usleep(1000); // Wait a bit + log_i("DEV_STAT0: 0x%02x", spiRegRead(sensorId, PGA_REG_DEV_STAT0)); + log_i("DEV_STAT1: 0x%02x", spiRegRead(sensorId, PGA_REG_DEV_STAT1)); + + log_i("Setup of sensor %d done", sensorId); + + // Stress test for writing/reading registers + /*uint8_t tmp = 0; + while(1) + { + spiRegWrite(sensorId, PGA_REG_USER_DATA1, tmp); + int reg = spiRegRead(sensorId, PGA_REG_USER_DATA1); + if(reg == -1) + Serial.printf("CHECKSUM WRONG!\n"); + else if(reg != tmp) + Serial.printf("WTF SOMETHING WENT WRONG!\n"); + tmp++; + }*/ // Reset the TCI - //tciReset(sensor_addr); + //tciReset(sensorId); /*uint8_t data[1]; while(1) { - //tciWriteBit(sensor_addr, true); - //tciWriteBit(sensor_addr, false); - tciReset(sensor_addr); - tciReadData(sensor_addr, 0, data, 8); + //tciWriteBit(sensorId, true); + //tciWriteBit(sensorId, false); + tciReset(sensorId); + tciReadData(sensorId, 0, data, 8); safe_usleep(10000); }*/ } // Reset the TCI interface by driving the IO pin low for >15 ms -void PGASensorManager::tciReset(int sensor_addr) +void PGASensorManager::tciReset(int sensorId) { - PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + PGASensorInfo &sensorInfo = m_sensors[sensorId]; pinMode(sensorInfo.io_pin, OUTPUT); safe_usleep(20000); pinMode(sensorInfo.io_pin, INPUT); safe_usleep(100); } -void PGASensorManager::tciWriteBit(int sensor_addr, bool val) +void PGASensorManager::tciWriteBit(int sensorId, bool val) { - PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + PGASensorInfo &sensorInfo = m_sensors[sensorId]; pinMode(sensorInfo.io_pin, OUTPUT); if(val) usleep(100-22); @@ -134,27 +249,27 @@ void PGASensorManager::tciWriteBit(int sensor_addr, bool val) usleep(100-22); } -void PGASensorManager::tciWriteByte(int sensor_addr, uint8_t val) +void PGASensorManager::tciWriteByte(int sensorId, uint8_t val) { } -bool PGASensorManager::tciReadData(int sensor_addr, uint8_t index, uint8_t *data, int bits) +bool PGASensorManager::tciReadData(int sensorId, uint8_t index, uint8_t *data, int bits) { - uint8_t io_pin = m_sensors[sensor_addr].io_pin; + uint8_t io_pin = m_sensors[sensorId].io_pin; noInterrupts(); pinMode(io_pin, OUTPUT); safe_usleep(1270-22); // tCFG_TCI, Device configuration command period pinMode(io_pin, INPUT); safe_usleep(100-22); // tDT_TCI, Command processing dead-time - tciWriteBit(sensor_addr, false); // Read + tciWriteBit(sensorId, false); // Read safe_usleep(100-22); // tDT_TCI, Command processing dead-time // Write register index, lower 4 bits, MSB first for(int i = 0; i < 4; i++) { - tciWriteBit(sensor_addr, !!(index & 0x08)); + tciWriteBit(sensorId, !!(index & 0x08)); index <<= 1; } @@ -215,45 +330,46 @@ void PGASensorManager::safe_usleep(unsigned long us) while(micros() - tstart < us); } -uint8_t PGASensorManager::spiTransfer(uint8_t sensor_addr, uint8_t data_out) +uint8_t PGASensorManager::spiTransfer(uint8_t sensorId, uint8_t data_out) { - PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + PGASensorInfo &sensorInfo = m_sensors[sensorId]; uint8_t data_in = 0; - // The bit timing may not be faster than 18 MHz clock signal. The arduino framework is so slow, that this seems to be no problem... for(uint8_t i = 0; i < 8; i++) { digitalWrite(sensorInfo.sck_pin, HIGH); digitalWrite(sensorInfo.mosi_pin, data_out&0x01); data_out >>= 1; + safe_usleep(2); digitalWrite(sensorInfo.sck_pin, LOW); data_in >>= 1; data_in |= digitalRead(sensorInfo.miso_pin)<<7; + safe_usleep(2); } return data_in; } // Returns the register value or -1 on checksum error -int PGASensorManager::spiRegRead(uint8_t sensor_addr, uint8_t reg_addr) +int PGASensorManager::spiRegRead(uint8_t sensorId, uint8_t reg_addr) { - PGASensorInfo &sensorInfo = m_sensors[sensor_addr]; + PGASensorInfo &sensorInfo = m_sensors[sensorId]; // Transmit checksum_clear(); - spiTransfer(sensor_addr, 0x55); // Sync byte - spiTransfer(sensor_addr, 0<<5 | 9); // Command: chip address + register read - checksum_append_byte(0<<5 | 9); - spiTransfer(sensor_addr, reg_addr); // Register address + spiTransfer(sensorId, 0x55); // Sync byte + spiTransfer(sensorId, 0<<5 | PGA_CMD_REGISTER_READ); // Command: chip address + register read + checksum_append_byte(0<<5 | PGA_CMD_REGISTER_READ); + spiTransfer(sensorId, reg_addr); // Register address checksum_append_byte(reg_addr); - spiTransfer(sensor_addr, checksum_get()); // Checksum + spiTransfer(sensorId, checksum_get()); // Checksum uint8_t tx_checksum = checksum_get(); // Receive checksum_clear(); - uint8_t diag_data = spiTransfer(sensor_addr, 0x00); + uint8_t diag_data = spiTransfer(sensorId, 0x00); checksum_append_byte(diag_data); - uint8_t reg_val = spiTransfer(sensor_addr, 0x00); + uint8_t reg_val = spiTransfer(sensorId, 0x00); checksum_append_byte(reg_val); - uint8_t checksum = spiTransfer(sensor_addr, 0x00); + uint8_t checksum = spiTransfer(sensorId, 0x00); //Serial.printf("Data: 0x%02x, Checksum (pga): 0x%02x, Checksum (local): 0x%02x, Checksum (tx): %02x\n", reg_val, checksum, checksum_get(), tx_checksum); @@ -263,6 +379,136 @@ int PGASensorManager::spiRegRead(uint8_t sensor_addr, uint8_t reg_addr) return reg_val; } +void PGASensorManager::spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t value) +{ + assert(sensorId >= 0 && sensorId <= 1); + + checksum_clear(); + spiTransfer(sensorId, 0x55); // Sync byte + spiTransfer(sensorId, 0<<5 | PGA_CMD_REGISTER_WRITE); // Command: chip address + register write + checksum_append_byte(0<<5 | PGA_CMD_REGISTER_WRITE); + spiTransfer(sensorId, reg_addr); // Register address + checksum_append_byte(reg_addr); + spiTransfer(sensorId, value); // Register address + checksum_append_byte(value); + spiTransfer(sensorId, checksum_get()); // Checksum + + // Wait a bit to apply changes, depending on the register + if(reg_addr == PGA_REG_INIT_GAIN || (reg_addr >= PGA_REG_TVGAIN0 & reg_addr <= PGA_REG_TVGAIN6) || (reg_addr >= PGA_REG_P1_THR_0 && reg_addr <= PGA_REG_P2_THR_15) || + reg_addr == PGA_REG_P1_GAIN_CTRL || reg_addr == PGA_REG_P2_GAIN_CTRL) + safe_usleep(61); + else + safe_usleep(5); +} + +void PGASensorManager::spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds) +{ + assert(sensorId >= 0 && sensorId <= 1); + + uint8_t regOffset = preset == 1 ? 0 : PGA_REG_P2_THR_0 - PGA_REG_P1_THR_0; + spiRegWrite(sensorId, PGA_REG_P1_THR_0 + regOffset, thresholds.t1<<4 | thresholds.t2); + spiRegWrite(sensorId, PGA_REG_P1_THR_1 + regOffset, thresholds.t3<<4 | thresholds.t4); + spiRegWrite(sensorId, PGA_REG_P1_THR_2 + regOffset, thresholds.t5<<4 | thresholds.t6); + spiRegWrite(sensorId, PGA_REG_P1_THR_3 + regOffset, thresholds.t7<<4 | thresholds.t8); + spiRegWrite(sensorId, PGA_REG_P1_THR_4 + regOffset, thresholds.t9<<4 | thresholds.t10); + spiRegWrite(sensorId, PGA_REG_P1_THR_5 + regOffset, thresholds.t11<<4 | thresholds.t12); + // Now it gets messy with the 5 bit level values... + spiRegWrite(sensorId, PGA_REG_P1_THR_6 + regOffset, thresholds.l1<<3 | thresholds.l2>>2); + spiRegWrite(sensorId, PGA_REG_P1_THR_7 + regOffset, thresholds.l2<<6 | thresholds.l3<<1 | thresholds.l4>>4); + spiRegWrite(sensorId, PGA_REG_P1_THR_8 + regOffset, thresholds.l4<<4 | thresholds.l5>>1); + spiRegWrite(sensorId, PGA_REG_P1_THR_9 + regOffset, thresholds.l5<<7 | thresholds.l6<<2 | thresholds.l7>>3); + spiRegWrite(sensorId, PGA_REG_P1_THR_10 + regOffset, thresholds.l7<<5 | thresholds.l8); + // 8 bit level values are easy again... + spiRegWrite(sensorId, PGA_REG_P1_THR_11 + regOffset, thresholds.l9); + spiRegWrite(sensorId, PGA_REG_P1_THR_12 + regOffset, thresholds.l10); + spiRegWrite(sensorId, PGA_REG_P1_THR_13 + regOffset, thresholds.l11); + spiRegWrite(sensorId, PGA_REG_P1_THR_14 + regOffset, thresholds.l12); + // Register 15 is a bit special... + spiRegWrite(sensorId, PGA_REG_P1_THR_15 + regOffset, PGA_TH_P1_OFF(0)); +} + +// Start a burst-and-listen with preset 1 and detect (up to) numberOfObjectsToDetect objects +// preset is 1 or 2 +// numberOfObjectsToDetect must be 1..8 +void PGASensorManager::spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8_t numberOfObjectsToDetect) +{ + assert(sensorId >= 0 && sensorId <= 1); + assert(preset >= 1 && preset <= 2); + assert(numberOfObjectsToDetect >= 1 && numberOfObjectsToDetect <= 8); + + checksum_clear(); + spiTransfer(sensorId, 0x55); // Sync byte + uint8_t cmd = 0<<5 | preset == 1 ? PGA_CMD_BURST_AND_LISTEN_1 : PGA_CMD_BURST_AND_LISTEN_2; + spiTransfer(sensorId, cmd); // Command + checksum_append_byte(cmd); + spiTransfer(sensorId, numberOfObjectsToDetect); + checksum_append_byte(numberOfObjectsToDetect); + spiTransfer(sensorId, checksum_get()); +} + +// Get the last ultrasonic results (triggered by spiBurstAndListen) +// usResults must be an array of at least numberOfObjectsToDetect elements +bool PGASensorManager::spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAUSResult *usResults) +{ + assert(sensorId >= 0 && sensorId <= 1); + assert(numberOfObjectsToDetect >= 1 && numberOfObjectsToDetect <= 8); + + spiTransfer(sensorId, 0x55); // Sync byte + spiTransfer(sensorId, 0<<5 | PGA_CMD_ULTRASONIC_RESULT); // Command + + // Get diag data + checksum_clear(); + uint8_t diag = spiTransfer(sensorId, 0x00); + checksum_append_byte(diag); + + // Read result data of 4 bytes for each object + for(int obj = 0; obj < numberOfObjectsToDetect; obj++) + { + uint8_t data = spiTransfer(sensorId, 0x00); + usResults[obj].tof = ((uint16_t)data)<<8; + checksum_append_byte(data); + data = spiTransfer(sensorId, 0x00); + usResults[obj].tof |= data; + checksum_append_byte(data); + data = spiTransfer(sensorId, 0x00); + usResults[obj].width = data; + checksum_append_byte(data); + data = spiTransfer(sensorId, 0x00); + usResults[obj].peakAmplitude = data; + checksum_append_byte(data); + } + + // Get checksum + uint8_t checksum = spiTransfer(sensorId, 0x00); + return checksum == checksum_get(); +} + +// data must point to at least 128 bytes +// Returns true if checksum was ok, false otherwise +bool PGASensorManager::spiDataDump(const uint8_t sensorId, uint8_t *data) +{ + assert(sensorId >= 0 && sensorId <= 1); + + spiTransfer(sensorId, 0x55); // Sync byte + spiTransfer(sensorId, 0<<5 | PGA_CMD_DATA_DUMP); // Command + + // Get diag data + checksum_clear(); + uint8_t diag = spiTransfer(sensorId, 0x00); + checksum_append_byte(diag); + + // Read data dump of 128 bytes + for(int i = 0; i < 128; i++) + { + data[i] = spiTransfer(sensorId, 0x00); + checksum_append_byte(data[i]); + } + + // Get checksum + uint8_t checksum = spiTransfer(sensorId, 0x00); + return checksum == checksum_get(); +} + void PGASensorManager::checksum_clear() { checksum_sum = 0; diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 7d3679ac..cc91ce2b 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -3,8 +3,139 @@ #ifndef OBS_PGASENSOR_H #define OBS_PGASENSOR_H + #ifdef OBSPRO // PGASensor is only available on OBSPro +#define PGA_CMD_BURST_AND_LISTEN_1 0 +#define PGA_CMD_BURST_AND_LISTEN_2 1 +#define PGA_CMD_ULTRASONIC_RESULT 5 +#define PGA_CMD_DATA_DUMP 7 +#define PGA_CMD_REGISTER_READ 9 +#define PGA_CMD_REGISTER_WRITE 10 + +#define PGA_REG_USER_DATA1 0x00 +#define PGA_REG_USER_DATA2 0x01 +#define PGA_REG_USER_DATA3 0x02 +#define PGA_REG_USER_DATA4 0x03 +#define PGA_REG_USER_DATA5 0x04 +#define PGA_REG_USER_DATA6 0x05 +#define PGA_REG_USER_DATA7 0x06 +#define PGA_REG_USER_DATA8 0x07 +#define PGA_REG_USER_DATA9 0x08 +#define PGA_REG_USER_DATA10 0x09 +#define PGA_REG_USER_DATA11 0x0a +#define PGA_REG_USER_DATA12 0x0b +#define PGA_REG_USER_DATA13 0x0c +#define PGA_REG_USER_DATA14 0x0d +#define PGA_REG_USER_DATA15 0x0e +#define PGA_REG_USER_DATA16 0x0f +#define PGA_REG_USER_DATA17 0x10 +#define PGA_REG_USER_DATA18 0x11 +#define PGA_REG_USER_DATA19 0x12 +#define PGA_REG_USER_DATA20 0x13 + +#define PGA_REG_TVGAIN0 0x14 +#define PGA_REG_TVGAIN1 0x15 +#define PGA_REG_TVGAIN2 0x16 +#define PGA_REG_TVGAIN3 0x17 +#define PGA_REG_TVGAIN4 0x18 +#define PGA_REG_TVGAIN5 0x19 +#define PGA_REG_TVGAIN6 0x1a + +#define PGA_REG_INIT_GAIN 0x1b +#define PGA_BPF_BW(val) ((val&0x3) << 6) +#define PGA_GAIN_INIT(val) (val&0x3f) // Init_Gain = 0.5 × (GAIN_INIT+1) + value(AFE_GAIN_RNG) [dB] +#define PGA_REG_FREQUENCY 0x1c +#define PGA_REG_DEADTIME 0x1d +#define PGA_REG_PULSE_P1 0x1e +#define PGA_IO_IF_SEL(val) ((val&0x01) << 7) +#define PGA_UART_DIAG(val) ((val&0x01) << 6) +#define PGA_IO_DIS(val) ((val&0x01) << 5) +#define P1_PULSE(val) (val&0x1f) +#define PGA_REG_PULSE_P2 0x1f +#define PGA_REG_CURR_LIM_P1 0x20 +#define PGA_DIS_CL(val) ((val&0x01) << 7) // Disable Current Limit for Preset1 and Preset2 +#define PGA_CURR_LIM1(val) (val&0x3f) // Current_Limit = 7 × CURR_LIM1 + 50 [mA] +#define PGA_REG_CURR_LIM_P2 0x21 +#define PGA_LPF_CO(val) ((val&0x03) << 6) // Lowpass filter cutoff frequency = LPF_CO + 1 [kHz] +#define PGA_CURR_LIM2(val) (val&0x3f) // Current limit = 7 × CURR_LIM2 + 50 [mA] +#define PGA_REG_REC_LENGTH 0x22 +#define PGA_P1_REC(val) ((val&0x0f) << 4) // Record time = 4.096 × (P1_REC + 1) [ms] +#define PGA_P2_REC(val) (val&0x0f) // Record time = 4.096 × (P1_REC + 1) [ms] +#define PGA_FREQ_DIAG 0x23 +#define PGA_FDIAG_LEN(val) ((val&0x0f) << 4) +#define PGA_FDIAG_START(val) (val&0x0f) +#define PGA_REG_SAT_FDIAG_TH 0x24 +#define PGA_FDIAG_ERR_TH(val) ((val&0x07) << 5) +#define PGA_SAT_TH(val) ((val&0x0f) << 1) +#define PGA_P1_NLS_EN(val) (val&0x01) +#define PGA_REG_FVOLT_DEC 0x25 +#define PGA_REG_DECPL_TEMP 0x26 +#define PGA_AFE_GAIN_RNG(val) ((val&0x03) << 6) +#define PGA_LPM_EN(val) ((val&0x01) << 5) +#define PGA_DECPL_TEMP_SEL(val) ((val&0x01) << 4) +#define PGA_DECPL_T(val) (val&0x0f) +#define PGA_REG_DSP_SCALE 0x27 +#define PGA_REG_TEMP_TRIM 0x28 +#define PGA_REG_P1_GAIN_CTRL 0x29 +#define PGA_REG_P2_GAIN_CTRL 0x2a +#define PGA_REG_EE_CRC 0x2b +#define PGA_REG_EE_CNTRL 0x40 +#define PGA_DATADUMP_EN(val) ((val&0x01) << 7) + +#define PGA_REG_BPF_A2_MSB 0x41 +#define PGA_REG_BPF_A2_LSB 0x42 +#define PGA_REG_BPF_A3_MSB 0x43 +#define PGA_REG_BPF_A3_LSB 0x44 +#define PGA_REG_BPF_B1_MSB 0x45 +#define PGA_REG_BPF_B1_LSB 0x46 +#define PGA_REG_LPF_A2_MSB 0x47 +#define PGA_REG_LPF_A2_LSB 0x48 +#define PGA_REG_LPF_B1_MSB 0x49 +#define PGA_REG_LPF_B1_LSB 0x4a + +#define PGA_REG_TEST_MUX 0x4b +#define PGA_REG_DEV_STAT0 0x4c +#define PGA_REG_DEV_STAT1 0x4d + +#define PGA_REG_P1_THR_0 0x5f +#define PGA_REG_P1_THR_1 0x60 +#define PGA_REG_P1_THR_2 0x61 +#define PGA_REG_P1_THR_3 0x62 +#define PGA_REG_P1_THR_4 0x63 +#define PGA_REG_P1_THR_5 0x64 +#define PGA_REG_P1_THR_6 0x65 +#define PGA_REG_P1_THR_7 0x66 +#define PGA_REG_P1_THR_8 0x67 +#define PGA_REG_P1_THR_9 0x68 +#define PGA_REG_P1_THR_10 0x69 +#define PGA_REG_P1_THR_11 0x6a +#define PGA_REG_P1_THR_12 0x6b +#define PGA_REG_P1_THR_13 0x6c +#define PGA_REG_P1_THR_14 0x6d +#define PGA_REG_P1_THR_15 0x6e + +#define PGA_REG_P2_THR_0 0x6f +#define PGA_REG_P2_THR_1 0x70 +#define PGA_REG_P2_THR_2 0x71 +#define PGA_REG_P2_THR_3 0x72 +#define PGA_REG_P2_THR_4 0x73 +#define PGA_REG_P2_THR_5 0x74 +#define PGA_REG_P2_THR_6 0x75 +#define PGA_REG_P2_THR_7 0x76 +#define PGA_REG_P2_THR_8 0x77 +#define PGA_REG_P2_THR_9 0x78 +#define PGA_REG_P2_THR_10 0x79 +#define PGA_REG_P2_THR_11 0x7a +#define PGA_REG_P2_THR_12 0x7b +#define PGA_REG_P2_THR_13 0x7c +#define PGA_REG_P2_THR_14 0x7d +#define PGA_REG_P2_THR_15 0x7e +#define PGA_TH_P1_OFF(val) (val&0x0f) // TODO: This conversion is not correct. This bit field uses signed values! + +#define PGA_REG_THR_CRC 0x7f + + struct PGASensorInfo { uint8_t io_pin; @@ -19,6 +150,98 @@ struct PGASensorInfo const char* sensorLocation; }; +struct PGAUSResult +{ + uint16_t tof; // Time of flight [us] + uint8_t width; + uint8_t peakAmplitude; +}; + +#define TH_TIME_DELTA_100US 0x0 +#define TH_TIME_DELTA_200US 0x1 +#define TH_TIME_DELTA_300US 0x2 +#define TH_TIME_DELTA_400US 0x3 +#define TH_TIME_DELTA_600US 0x4 +#define TH_TIME_DELTA_800US 0x5 +#define TH_TIME_DELTA_1000US 0x6 +#define TH_TIME_DELTA_1200US 0x7 +#define TH_TIME_DELTA_1400US 0x8 +#define TH_TIME_DELTA_2000US 0x9 +#define TH_TIME_DELTA_2400US 0xa +#define TH_TIME_DELTA_3200US 0xb +#define TH_TIME_DELTA_4000US 0xc +#define TH_TIME_DELTA_5200US 0xd +#define TH_TIME_DELTA_6400US 0xe +#define TH_TIME_DELTA_8000US 0xf + +struct PGAThresholds +{ + PGAThresholds( + uint8_t t1 = TH_TIME_DELTA_100US, uint8_t l1 = 0, + uint8_t t2 = TH_TIME_DELTA_100US, uint8_t l2 = 0, + uint8_t t3 = TH_TIME_DELTA_100US, uint8_t l3 = 0, + uint8_t t4 = TH_TIME_DELTA_100US, uint8_t l4 = 0, + uint8_t t5 = TH_TIME_DELTA_100US, uint8_t l5 = 0, + uint8_t t6 = TH_TIME_DELTA_100US, uint8_t l6 = 0, + uint8_t t7 = TH_TIME_DELTA_100US, uint8_t l7 = 0, + uint8_t t8 = TH_TIME_DELTA_100US, uint8_t l8 = 0, + uint8_t t9 = TH_TIME_DELTA_100US, uint8_t l9 = 0, + uint8_t t10 = TH_TIME_DELTA_100US, uint8_t l10 = 0, + uint8_t t11 = TH_TIME_DELTA_100US, uint8_t l11 = 0, + uint8_t t12 = TH_TIME_DELTA_100US, uint8_t l12 = 0) + { + this->t1 = t1 & 0x0f; + this->l1 = l1 & 0x1f; + this->t2 = t2 & 0x0f; + this->l2 = l2 & 0x1f; + this->t3 = t3 & 0x0f; + this->l3 = l3 & 0x1f; + this->t4 = t4 & 0x0f; + this->l4 = l4 & 0x1f; + this->t5 = t5 & 0x0f; + this->l5 = l5 & 0x1f; + this->t6 = t6 & 0x0f; + this->l6 = l6 & 0x1f; + this->t7 = t7 & 0x0f; + this->l7 = l7 & 0x1f; + this->t8 = t8 & 0x0f; + this->l8 = l8 & 0x1f; + this->t9 = t9 & 0x0f; + this->l9 = l9 & 0x1f; + this->t10 = t10 & 0x0f; + this->l10 = l10; + this->t11 = t11 & 0x0f; + this->l11 = l11; + this->t12 = t12 & 0x0f; + this->l12 = l12; + } + + uint8_t t1; // 4 bits + uint8_t l1; // 5 bits + uint8_t t2; // 4 bits + uint8_t l2; // 5 bits + uint8_t t3; // 4 bits + uint8_t l3; // 5 bits + uint8_t t4; // 4 bits + uint8_t l4; // 5 bits + uint8_t t5; // 4 bits + uint8_t l5; // 5 bits + uint8_t t6; // 4 bits + uint8_t l6; // 5 bits + uint8_t t7; // 4 bits + uint8_t l7; // 5 bits + uint8_t t8; // 4 bits + uint8_t l8; // 5 bits + uint8_t t9; // 4 bits + uint8_t l9; // 8(!) bits + uint8_t t10; // 4 bits + uint8_t l10; // 8(!) bits + uint8_t t11; // 4 bits + uint8_t l11; // 8(!) bits + uint8_t t12; // 4 bits + uint8_t l12; // 8(!) bits +}; + class PGASensorManager { public: @@ -38,6 +261,8 @@ class PGASensorManager void detachInterrupts() {}; void attachInterrupts() {}; + bool spiDataDump(const uint8_t sensorId, uint8_t *data); + // TODO: These should not be public! PGASensorInfo m_sensors[NUMBER_OF_TOF_SENSORS]; uint16_t sensorValues[NUMBER_OF_TOF_SENSORS]; @@ -56,8 +281,12 @@ class PGASensorManager void safe_usleep(unsigned long us); // Synchronous UART mode (aka SPI without chip-select) - uint8_t spiTransfer(uint8_t sensor_addr, uint8_t data_out); - int spiRegRead(uint8_t sensor_addr, uint8_t reg_addr); + uint8_t spiTransfer(uint8_t sensorId, uint8_t data_out); + int spiRegRead(uint8_t sensorId, uint8_t reg_addr); + void spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t value); + void spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds); + void spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8_t numberOfObjectsToDetect); + bool spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAUSResult *usResults); // Checksum uint8_t checksum_sum; @@ -68,6 +297,9 @@ class PGASensorManager void checksum_append_bit(uint8_t val); void checksum_append_byte(uint8_t val); uint8_t checksum_get(); + + // Alternating state + unsigned long lastTriggerTimeMs; }; #endif // OBSPRO From 0767d3685108316970557317da04f753cdf4321f Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Mon, 19 Feb 2024 16:00:05 +0100 Subject: [PATCH 18/34] Remove TCI, we are using SPI now --- src/pgaSensor.cpp | 126 ---------------------------------------------- src/pgaSensor.h | 6 --- 2 files changed, 132 deletions(-) diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index bbea9d3c..5be4630b 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -195,132 +195,6 @@ void PGASensorManager::setupSensor(int sensorId) log_i("DEV_STAT1: 0x%02x", spiRegRead(sensorId, PGA_REG_DEV_STAT1)); log_i("Setup of sensor %d done", sensorId); - - // Stress test for writing/reading registers - /*uint8_t tmp = 0; - while(1) - { - spiRegWrite(sensorId, PGA_REG_USER_DATA1, tmp); - int reg = spiRegRead(sensorId, PGA_REG_USER_DATA1); - if(reg == -1) - Serial.printf("CHECKSUM WRONG!\n"); - else if(reg != tmp) - Serial.printf("WTF SOMETHING WENT WRONG!\n"); - tmp++; - }*/ - - // Reset the TCI - //tciReset(sensorId); - - /*uint8_t data[1]; - while(1) - { - //tciWriteBit(sensorId, true); - //tciWriteBit(sensorId, false); - tciReset(sensorId); - tciReadData(sensorId, 0, data, 8); - safe_usleep(10000); - }*/ - -} - -// Reset the TCI interface by driving the IO pin low for >15 ms -void PGASensorManager::tciReset(int sensorId) -{ - PGASensorInfo &sensorInfo = m_sensors[sensorId]; - pinMode(sensorInfo.io_pin, OUTPUT); - safe_usleep(20000); - pinMode(sensorInfo.io_pin, INPUT); - safe_usleep(100); -} - -void PGASensorManager::tciWriteBit(int sensorId, bool val) -{ - PGASensorInfo &sensorInfo = m_sensors[sensorId]; - pinMode(sensorInfo.io_pin, OUTPUT); - if(val) - usleep(100-22); - else - usleep(200-22); - pinMode(sensorInfo.io_pin, INPUT); - if(val) - usleep(200-22); - else - usleep(100-22); -} - -void PGASensorManager::tciWriteByte(int sensorId, uint8_t val) -{ - -} - -bool PGASensorManager::tciReadData(int sensorId, uint8_t index, uint8_t *data, int bits) -{ - uint8_t io_pin = m_sensors[sensorId].io_pin; - - noInterrupts(); - pinMode(io_pin, OUTPUT); - safe_usleep(1270-22); // tCFG_TCI, Device configuration command period - pinMode(io_pin, INPUT); - safe_usleep(100-22); // tDT_TCI, Command processing dead-time - tciWriteBit(sensorId, false); // Read - safe_usleep(100-22); // tDT_TCI, Command processing dead-time - - // Write register index, lower 4 bits, MSB first - for(int i = 0; i < 4; i++) - { - tciWriteBit(sensorId, !!(index & 0x08)); - index <<= 1; - } - - // Reset the checksum state - checksum_clear(); - - // Read data bits - int byte_offset = 0; - data[0] = 0; - uint8_t bit_offset = 7; - for(int i = 0; i < bits; i++) - { - uint8_t val = tciReadBit(io_pin); - checksum_append_bit(val); // Update checksum - data[byte_offset] |= val << bit_offset; - if(bit_offset == 0) - { - byte_offset++; - data[byte_offset] = 0; - bit_offset = 7; - } - else - bit_offset--; - } - - // Read checksum - uint8_t checksum = 0; - for(uint8_t i = 0; i < 8; i++) - checksum |= tciReadBit(io_pin) << (7 - i); - interrupts(); - - Serial.printf(", Data: "); - for(int i = 0; i < (bits + 7)/8; i++) - Serial.printf("0x%02x, ", data[i]); - Serial.printf("Checksum (pga): 0x%02x, ", checksum); - Serial.printf("Checksum (local): 0x%02x\n", checksum_get()); - - return checksum == checksum_get(); -} - -uint8_t PGASensorManager::tciReadBit(uint8_t io_pin) -{ - while(!digitalRead(io_pin)); // Wait for high level - while(digitalRead(io_pin)); // Wait for falling edge - safe_usleep(150-10); // Wait for sample time - - uint8_t val = digitalRead(io_pin); // Sample the bit - pinMode(io_pin, OUTPUT); - pinMode(io_pin, INPUT); - - return val; } // A usleep function that also works if interrupts are disabled diff --git a/src/pgaSensor.h b/src/pgaSensor.h index cc91ce2b..223c3a3c 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -272,12 +272,6 @@ class PGASensorManager protected: void setupSensor(int idx); - // TCI Interface - void tciReset(int sensor_addr); - void tciWriteBit(int sensor_addr, bool val); - void tciWriteByte(int sensor_addr, uint8_t val); - bool tciReadData(int sensor_addr, uint8_t index, uint8_t *data, int bits); - uint8_t tciReadBit(uint8_t io_pin); void safe_usleep(unsigned long us); // Synchronous UART mode (aka SPI without chip-select) From 82a96d82080141aa72bf11a210a5ba43ffab9318 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Wed, 21 Feb 2024 09:59:59 +0100 Subject: [PATCH 19/34] Implemented alternating polling --- src/OpenBikeSensorFirmware.cpp | 23 ++-- src/pgaSensor.cpp | 203 +++++++++++++++++++++++++++++++-- src/pgaSensor.h | 26 ++++- src/variant.h | 10 +- 4 files changed, 234 insertions(+), 28 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 009ea437..7b84fb82 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -118,17 +118,18 @@ void setupSensors() { sensorManager = new PGASensorManager; PGASensorInfo sensor1; - sensor1.io_pin = SENSOR1_IO_PIN; - sensor1.sck_pin = 25; - sensor1.mosi_pin = 33; - sensor1.miso_pin = 32; + sensor1.sck_pin = SENSOR1_SCK_PIN; + sensor1.mosi_pin = SENSOR1_MOSI_PIN; + sensor1.miso_pin = SENSOR1_MISO_PIN; sensor1.sensorLocation = "Left"; sensorManager->registerSensor(sensor1, 0); - /*PGASensorInfo sensor2; - sensor2.io_pin = SENSOR2_IO_PIN; - sensor2.sensorLocation = "Right"; - sensorManager->registerSensor(sensor2, 1);*/ + PGASensorInfo sensor2; + sensor1.sck_pin = SENSOR2_SCK_PIN; + sensor1.mosi_pin = SENSOR2_MOSI_PIN; + sensor1.miso_pin = SENSOR2_MISO_PIN; + sensor1.sensorLocation = "Right"; + sensorManager->registerSensor(sensor2, 1); #endif #ifdef OBSCLASSIC sensorManager = new HCSR04SensorManager; @@ -144,11 +145,11 @@ void setupSensors() { sensorManaged2.echoPin = (config.displayConfig & DisplaySwapSensors) ? 4 : 26; sensorManaged2.sensorLocation = (char*) "Left"; // TODO sensorManager->registerSensor(sensorManaged2, 1); +#endif sensorManager->setOffsets(config.sensorOffsets); sensorManager->setPrimarySensor(LEFT_SENSOR_ID); -#endif } static void setupBluetooth(const ObsConfig &cfg, const String &trackUniqueIdentifier) { @@ -451,10 +452,8 @@ void loop() { currentSet->batteryLevel = voltageMeter->read(); lastMeasurements = sensorManager->m_sensors[confirmationSensorID].numberOfTriggers; -#ifdef OBSCLASSIC - // TODO: Also required for OBSPro? + sensorManager->reset(startTimeMillis); -#endif // if the detected minimum was measured more than 5s ago, it is discarded and cannot be confirmed int timeDelta = (int) (currentTimeMillis - timeOfMinimum); diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index 5be4630b..f64e93bf 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -25,10 +25,82 @@ void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t s setupSensor(sensorId); } -// Guess: Return true if the last measurement is complete and a new one is triggered? +// Guess: Returns true if both sensor results are available bool PGASensorManager::pollDistancesAlternating() { - unsigned long timeMs = millis(); + bool newMeasurements = false; + + // If current sensor is not ready, return + if(spiIsBusy(lastSensor)) + return false; + + uint8_t nextSensor = 1 - lastSensor; + + // Check if the next sensor is the primary sensor, which means that all sensors have been + // triggered. Then collect the results of both. + if(nextSensor == primarySensor) + newMeasurements = collectSensorResults(); + + // Trigger next sensor +#if PGA_DUMP_ENABLE + // DEBUG: request a raw data dump from time to time + if(millis() - m_sensors[nextSensor].lastDumpTime > PGA_DUMP_TIME) + { + spiRegWrite(nextSensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); + m_sensors[nextSensor].lastDumpTime = millis(); + m_sensors[nextSensor].lastMeasurementWasDump = true; + } + else + { + spiRegWrite(nextSensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); + m_sensors[nextSensor].lastMeasurementWasDump = false; + } +#endif + spiBurstAndListen(nextSensor, 1, 1); + + lastSensor = nextSensor; + return newMeasurements; + + + /*if (lastSensor == primarySensor && !spiIsBusy(1 - primarySensor)) { + lastSensor = 1 - primarySensor; +#if PGA_DUMP_ENABLE + // DEBUG: request a raw data dump from time to time + if(millis() - m_sensors[1-primarySensor].lastDumpTime > 1000) + { + spiRegWrite(1-primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); + m_sensors[1-primarySensor].lastDumpTime = millis(); + m_sensors[1-primarySensor].lastMeasurementWasDump = true; + } + else + { + spiRegWrite(1-primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); + m_sensors[1-primarySensor].lastMeasurementWasDump = false; + } +#endif + spiBurstAndListen(1 - primarySensor, 1, 1); + } else if (!spiIsBusy(primarySensor)) { + newMeasurements = collectSensorResults(); + lastSensor = primarySensor; +#if PGA_DUMP_ENABLE + // DEBUG: request a raw data dump from time to time + if(millis() - m_sensors[primarySensor].lastDumpTime > 1000) + { + spiRegWrite(primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); + m_sensors[primarySensor].lastDumpTime = millis(); + m_sensors[primarySensor].lastMeasurementWasDump = true; + } + else + { + spiRegWrite(primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); + m_sensors[primarySensor].lastMeasurementWasDump = false; + } +#endif + spiBurstAndListen(primarySensor, 1, 1); + } + return newMeasurements;*/ + + /*unsigned long timeMs = millis(); static uint8_t param = 0; static bool isDump = false; // True if a dump has to be triggered (false if the dump result has to be read) if(timeMs - lastTriggerTimeMs > 200 && param <= 63) @@ -90,12 +162,12 @@ bool PGASensorManager::pollDistancesAlternating() isDump = !isDump; return true; } - return false; + return false;*/ } uint16_t PGASensorManager::getCurrentMeasureIndex() { - return 1; + return lastReadingCount - 1; } uint16_t PGASensorManager::getRawMedianDistance(uint8_t sensorId) @@ -138,13 +210,41 @@ uint32_t PGASensorManager::getNumberOfInterruptAdjustments(const uint8_t sensorI return 9000000; } +void PGASensorManager::setOffsets(std::vector offsets) +{ + for (size_t idx = 0; idx < NUMBER_OF_TOF_SENSORS; ++idx) { + if (idx < offsets.size()) { + m_sensors[idx].offset = offsets[idx]; + } else { + m_sensors[idx].offset = 0; + } + } +} + +/* The primary sensor defines the measurement interval, we trigger a measurement if this + * sensor is ready. + */ +void PGASensorManager::setPrimarySensor(uint8_t idx) { + primarySensor = idx; +} + +void PGASensorManager::reset(uint32_t startMillisTicks) { + for (auto & sensor : m_sensors) { + sensor.minDistance = MAX_SENSOR_VALUE; + memset(&(sensor.echoDurationMicroseconds), 0, sizeof(sensor.echoDurationMicroseconds)); + sensor.numberOfTriggers = 0; + } + lastReadingCount = 0; + lastSensor = 1 - primarySensor; + memset(&(startOffsetMilliseconds), 0, sizeof(startOffsetMilliseconds)); + startReadingMilliseconds = startMillisTicks; +} + void PGASensorManager::setupSensor(int sensorId) { PGASensorInfo &sensorInfo = m_sensors[sensorId]; // Set pin modes - digitalWrite(sensorInfo.io_pin, LOW); - pinMode(sensorInfo.io_pin, INPUT); // IO pin is open drain digitalWrite(sensorInfo.sck_pin, LOW); pinMode(sensorInfo.sck_pin, OUTPUT); pinMode(sensorInfo.mosi_pin, OUTPUT); @@ -168,11 +268,11 @@ void PGASensorManager::setupSensor(int sensorId) spiRegWrite(sensorId, PGA_REG_CURR_LIM_P2, PGA_LPF_CO(0) | PGA_CURR_LIM2(0)); // CURR_LIM1*7mA + 50mA spiRegWrite(sensorId, PGA_REG_REC_LENGTH, PGA_P1_REC(8) | PGA_P2_REC(0)); // Record time = 4.096 × (Px_REC + 1) [ms], 8 = 36,9ms = 6m range spiRegWrite(sensorId, PGA_REG_DECPL_TEMP, PGA_AFE_GAIN_RNG(1) | PGA_LPM_EN(0) | PGA_DECPL_TEMP_SEL(0) | PGA_DECPL_T(0)); // Time = 4096 × (DECPL_T + 1) [μs], 0 = 4ms = 0,66m?!? - spiRegWrite(sensorId, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); // Enable data dump + spiRegWrite(sensorId, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); // Disable data dump // Threshold map, then check DEV_STAT0.THR_CRC_ERR - //th_t = np.array([2000, 2400, 2400, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000]) - //th_l = np.array([200, 80, 16, 16, 24, 32, 40, 48, 56, 56, 56, 56]) + // th_t = np.array([2000, 5200, 2400, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000]) + // th_l = np.array([200, 80, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24]) PGAThresholds thresholds( TH_TIME_DELTA_2000US, 200/8, TH_TIME_DELTA_5200US, 80/8, @@ -223,7 +323,8 @@ uint8_t PGASensorManager::spiTransfer(uint8_t sensorId, uint8_t data_out) } // Returns the register value or -1 on checksum error -int PGASensorManager::spiRegRead(uint8_t sensorId, uint8_t reg_addr) +// pdiag: return the value of the diag byte, can be nullptr +int PGASensorManager::spiRegRead(uint8_t sensorId, uint8_t reg_addr, uint8_t *pdiag) { PGASensorInfo &sensorInfo = m_sensors[sensorId]; @@ -239,8 +340,10 @@ int PGASensorManager::spiRegRead(uint8_t sensorId, uint8_t reg_addr) // Receive checksum_clear(); - uint8_t diag_data = spiTransfer(sensorId, 0x00); - checksum_append_byte(diag_data); + uint8_t diag = spiTransfer(sensorId, 0x00); + checksum_append_byte(diag); + if(pdiag != nullptr) + *pdiag = diag; uint8_t reg_val = spiTransfer(sensorId, 0x00); checksum_append_byte(reg_val); uint8_t checksum = spiTransfer(sensorId, 0x00); @@ -350,6 +453,12 @@ bool PGASensorManager::spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDe data = spiTransfer(sensorId, 0x00); usResults[obj].peakAmplitude = data; checksum_append_byte(data); + + // Convert tof to distance in cm + // TODO: Add temperature compensation by reading tempearture from sensor (somewhere else) + const double tof = usResults[obj].tof*1e-6; + const double v = 343.0; + usResults[obj].distance = (uint16_t)(tof*v/2.0*100.0); } // Get checksum @@ -357,6 +466,15 @@ bool PGASensorManager::spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDe return checksum == checksum_get(); } +bool PGASensorManager::spiIsBusy(uint8_t sensorId) +{ + uint8_t diag; + int res = spiRegRead(sensorId, PGA_REG_USER_DATA1, &diag); + if(res == -1) + return true; + return !!(diag & PGA_DIAG_BUSY_MASK); +} + // data must point to at least 128 bytes // Returns true if checksum was ok, false otherwise bool PGASensorManager::spiDataDump(const uint8_t sensorId, uint8_t *data) @@ -421,4 +539,65 @@ uint8_t PGASensorManager::checksum_get() return ~(checksum_sum + checksum_carry); // Checksum is the inverted sum + carry } +// Gets the distances from the sensors +// Returns true if any of the sensors returned a range < 6m +bool PGASensorManager::collectSensorResults() { + bool validReading = false; + for (size_t idx = 0; idx < NUMBER_OF_TOF_SENSORS; ++idx) { + PGAUSResult usResults[1]; + if(!spiUSResult(idx, 1, usResults)) + continue; +#if PGA_DUMP_ENABLE + if(m_sensors[idx].lastMeasurementWasDump) + { + uint8_t data[128]; + if(!spiDataDump(idx, data)) + log_e("Unable to get data dump: Checksum error"); + else + { + Serial.printf("dump,%d,", idx); + for(int i = 0; i < 128; i++) + { + Serial.printf("%d", data[i]); + if(i+1 != 128) + Serial.print(","); + } + Serial.printf("\n"); + } + } + else + { +#endif + Serial.printf("meas,%d,%d,%d,%d\n", idx, usResults[0].tof, usResults[0].width, usResults[0].peakAmplitude); + if(usResults->distance < 600) + { + sensorValues[idx] = usResults[0].distance; + validReading = true; + } +#if PGA_DUMP_ENABLE + } +#endif + } + if (validReading) { + registerReadings(); + } + return validReading; +} + +// Store the relative times of this reading (a pair of measurements?) +void PGASensorManager::registerReadings() { + startOffsetMilliseconds[lastReadingCount] = millisSince(startReadingMilliseconds); + if (lastReadingCount < MAX_NUMBER_MEASUREMENTS_PER_INTERVAL - 1) { + lastReadingCount++; + } +} + +uint16_t PGASensorManager::millisSince(uint16_t milliseconds) { + uint16_t result = ((uint16_t) millis()) - milliseconds; + if (result & 0x8000) { + result = -result; + } + return result; +} + #endif // OBSPro diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 223c3a3c..45c7e704 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -1,4 +1,5 @@ #include +#include #include "variant.h" #ifndef OBS_PGASENSOR_H @@ -135,10 +136,13 @@ #define PGA_REG_THR_CRC 0x7f +#define PGA_DIAG_BUSY_MASK 0x01 +#define PGA_DUMP_ENABLE 1 +#define PGA_DUMP_TIME 500 + struct PGASensorInfo { - uint8_t io_pin; uint8_t sck_pin; uint8_t mosi_pin; uint8_t miso_pin; @@ -148,6 +152,13 @@ struct PGASensorInfo uint16_t minDistance = MAX_SENSOR_VALUE; uint16_t distance = MAX_SENSOR_VALUE; const char* sensorLocation; + uint16_t offset = 0; // TODO: Apply offset + +#if PGA_DUMP_ENABLE + // DEBUG: send a raw data dump trigger from time to time + uint32_t lastDumpTime = 0; + bool lastMeasurementWasDump = false; +#endif }; struct PGAUSResult @@ -155,6 +166,7 @@ struct PGAUSResult uint16_t tof; // Time of flight [us] uint8_t width; uint8_t peakAmplitude; + uint16_t distance; // [cm] }; #define TH_TIME_DELTA_100US 0x0 @@ -258,6 +270,9 @@ class PGASensorManager uint32_t getNumberOfLowAfterMeasurement(const uint8_t sensorId); uint32_t getNumberOfToLongMeasurement(const uint8_t sensorId); uint32_t getNumberOfInterruptAdjustments(const uint8_t sensorId); + void setOffsets(std::vector offsets); + void setPrimarySensor(uint8_t idx); + void reset(uint32_t startMillisTicks); void detachInterrupts() {}; void attachInterrupts() {}; @@ -276,11 +291,12 @@ class PGASensorManager // Synchronous UART mode (aka SPI without chip-select) uint8_t spiTransfer(uint8_t sensorId, uint8_t data_out); - int spiRegRead(uint8_t sensorId, uint8_t reg_addr); + int spiRegRead(uint8_t sensorId, uint8_t reg_addr, uint8_t *pdiag = nullptr); void spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t value); void spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds); void spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8_t numberOfObjectsToDetect); bool spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAUSResult *usResults); + bool spiIsBusy(uint8_t sensorId); // Checksum uint8_t checksum_sum; @@ -294,6 +310,12 @@ class PGASensorManager // Alternating state unsigned long lastTriggerTimeMs; + uint8_t lastSensor; + uint8_t primarySensor = 1; + uint32_t startReadingMilliseconds = 0; + bool collectSensorResults(); + void registerReadings(); + uint16_t millisSince(uint16_t milliseconds); }; #endif // OBSPRO diff --git a/src/variant.h b/src/variant.h index 9b751cf8..7988f6a0 100644 --- a/src/variant.h +++ b/src/variant.h @@ -41,8 +41,14 @@ #define LCD_DC_PIN 27 #define LCD_RESET_PIN 4 -#define SENSOR1_IO_PIN 26 -#define SENSOR2_IO_PIN 22 +#define SENSOR1_SCK_PIN 25 +#define SENSOR1_MOSI_PIN 33 +#define SENSOR1_MISO_PIN 32 + +#define SENSOR2_SCK_PIN 14 +#define SENSOR2_MOSI_PIN 15 +#define SENSOR2_MISO_PIN 21 + #endif From 3587ffd412ef2cc2e902365f10ce8baf414f8d07 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Wed, 21 Feb 2024 12:31:08 +0100 Subject: [PATCH 20/34] Sensors integration works, but is completely untested --- src/OpenBikeSensorFirmware.cpp | 10 ++- src/globals.h | 2 +- src/pgaSensor.cpp | 129 ++++++++++++++++++++------------- src/pgaSensor.h | 51 ++++++++----- src/sensor.cpp | 6 -- src/sensor.h | 3 - src/variant.h | 13 ++++ 7 files changed, 129 insertions(+), 85 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 7b84fb82..0aa4a7ac 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -125,10 +125,10 @@ void setupSensors() { sensorManager->registerSensor(sensor1, 0); PGASensorInfo sensor2; - sensor1.sck_pin = SENSOR2_SCK_PIN; - sensor1.mosi_pin = SENSOR2_MOSI_PIN; - sensor1.miso_pin = SENSOR2_MISO_PIN; - sensor1.sensorLocation = "Right"; + sensor2.sck_pin = SENSOR2_SCK_PIN; + sensor2.mosi_pin = SENSOR2_MOSI_PIN; + sensor2.miso_pin = SENSOR2_MISO_PIN; + sensor2.sensorLocation = "Right"; sensorManager->registerSensor(sensor2, 1); #endif #ifdef OBSCLASSIC @@ -551,6 +551,8 @@ void loop() { gps.handle(); } // end measureInterval while + log_e("Measurement done"); + currentSet->gpsRecord = gps.getCurrentGpsRecord(); currentSet->isInsidePrivacyArea = gps.isInsidePrivacyArea(); if (currentSet->gpsRecord.getTow() == thisLoopTow) { diff --git a/src/globals.h b/src/globals.h index d28ec6bc..a9cb0e5d 100644 --- a/src/globals.h +++ b/src/globals.h @@ -38,6 +38,7 @@ class HCSR04SensorManager; #include "pgaSensor.h" #include "VoltageMeter.h" #include "utils/button.h" +#include "variant.h" // This file should contain declarations of all variables that will be used globally. // The variables don't have to be set here, but need to be declared. @@ -70,7 +71,6 @@ extern Button button; class Gps; extern Gps gps; -extern const uint32_t MAX_DURATION_MICRO_SEC; extern const uint8_t LEFT_SENSOR_ID; extern const uint8_t RIGHT_SENSOR_ID; diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index f64e93bf..f5a21a53 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -22,6 +22,8 @@ void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t s } m_sensors[sensorId] = sensorInfo; m_sensors[sensorId].numberOfTriggers = 0; + sensorValues[sensorId] = MAX_SENSOR_VALUE; + m_sensors[sensorId].median = new Median(5, MAX_SENSOR_VALUE); setupSensor(sensorId); } @@ -57,6 +59,7 @@ bool PGASensorManager::pollDistancesAlternating() } #endif spiBurstAndListen(nextSensor, 1, 1); + m_sensors[nextSensor].numberOfTriggers++; lastSensor = nextSensor; return newMeasurements; @@ -141,7 +144,7 @@ bool PGASensorManager::pollDistancesAlternating() { //Serial.print("Get distance\n"); // Last measurement was a normal measurement, read and print distance - PGAUSResult usResult[1]; + PGAResult usResult[1]; if(!spiUSResult(0, 1, usResult)) Serial.print("Unable to get US result: Checksum error\n"); else @@ -170,46 +173,6 @@ uint16_t PGASensorManager::getCurrentMeasureIndex() return lastReadingCount - 1; } -uint16_t PGASensorManager::getRawMedianDistance(uint8_t sensorId) -{ - return 30000; -} - -uint32_t PGASensorManager::getMaxDurationUs(uint8_t sensorId) -{ - return 3000000; -} - -uint32_t PGASensorManager::getMinDurationUs(uint8_t sensorId) -{ - return 4000000; -} - -uint32_t PGASensorManager::getLastDelayTillStartUs(uint8_t sensorId) -{ - return 5000000; -} - -uint32_t PGASensorManager::getNoSignalReadings(const uint8_t sensorId) -{ - return 6000000; -} - -uint32_t PGASensorManager::getNumberOfLowAfterMeasurement(const uint8_t sensorId) -{ - return 7000000; -} - -uint32_t PGASensorManager::getNumberOfToLongMeasurement(const uint8_t sensorId) -{ - return 8000000; -} - -uint32_t PGASensorManager::getNumberOfInterruptAdjustments(const uint8_t sensorId) -{ - return 9000000; -} - void PGASensorManager::setOffsets(std::vector offsets) { for (size_t idx = 0; idx < NUMBER_OF_TOF_SENSORS; ++idx) { @@ -425,7 +388,7 @@ void PGASensorManager::spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8 // Get the last ultrasonic results (triggered by spiBurstAndListen) // usResults must be an array of at least numberOfObjectsToDetect elements -bool PGASensorManager::spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAUSResult *usResults) +bool PGASensorManager::spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAResult *usResults) { assert(sensorId >= 0 && sensorId <= 1); assert(numberOfObjectsToDetect >= 1 && numberOfObjectsToDetect <= 8); @@ -543,19 +506,20 @@ uint8_t PGASensorManager::checksum_get() // Returns true if any of the sensors returned a range < 6m bool PGASensorManager::collectSensorResults() { bool validReading = false; - for (size_t idx = 0; idx < NUMBER_OF_TOF_SENSORS; ++idx) { - PGAUSResult usResults[1]; - if(!spiUSResult(idx, 1, usResults)) + for (size_t sensorId = 0; sensorId < NUMBER_OF_TOF_SENSORS; ++sensorId) { + PGASensorInfo* const sensor = &m_sensors[sensorId]; + PGAResult usResults[1]; + if(!spiUSResult(sensorId, 1, usResults)) continue; #if PGA_DUMP_ENABLE - if(m_sensors[idx].lastMeasurementWasDump) + if(sensor->lastMeasurementWasDump) { uint8_t data[128]; - if(!spiDataDump(idx, data)) + if(!spiDataDump(sensorId, data)) log_e("Unable to get data dump: Checksum error"); else { - Serial.printf("dump,%d,", idx); + Serial.printf("dump,%d,", sensorId); for(int i = 0; i < 128; i++) { Serial.printf("%d", data[i]); @@ -568,11 +532,26 @@ bool PGASensorManager::collectSensorResults() { else { #endif - Serial.printf("meas,%d,%d,%d,%d\n", idx, usResults[0].tof, usResults[0].width, usResults[0].peakAmplitude); - if(usResults->distance < 600) - { - sensorValues[idx] = usResults[0].distance; + Serial.printf("meas,%d,%d,%d,%d\n", sensorId, usResults[0].tof, usResults[0].width, usResults[0].peakAmplitude); + + sensor->echoDurationMicroseconds[lastReadingCount] = usResults[0].tof; + uint16_t dist; + if(usResults[0].distance < MIN_DISTANCE_MEASURED_CM || usResults[0].distance >= MAX_DISTANCE_MEASURED_CM) { + dist = MAX_SENSOR_VALUE; + } else { validReading = true; + dist = static_cast(usResults[0].distance); + } + sensor->rawDistance = dist; + sensor->median->addValue(dist); + sensorValues[sensorId] = sensor->distance = correctSensorOffset(medianMeasure(sensor, dist), sensor->offset); + + log_v("Raw sensor[%d] distance read %03u / %03u (%03u, %03u, %03u) -> *%03ucm*, duration: %zu us", + sensorId, sensor->rawDistance, dist, sensor->distances[0], sensor->distances[1], + sensor->distances[2], sensorValues[sensorId], usResults[0].tof); + + if (sensor->distance > 0 && sensor->distance < sensor->minDistance) { + sensor->minDistance = sensor->distance; } #if PGA_DUMP_ENABLE } @@ -600,4 +579,50 @@ uint16_t PGASensorManager::millisSince(uint16_t milliseconds) { return result; } +uint16_t PGASensorManager::correctSensorOffset(uint16_t dist, uint16_t offset) { + uint16_t result; + if (dist == MAX_SENSOR_VALUE) { + result = MAX_SENSOR_VALUE; + } else if (dist > offset) { + result = dist - offset; + } else { + result = 0; // would be negative if corrected + } + return result; +} + +uint16_t PGASensorManager::medianMeasure(PGASensorInfo *const sensor, uint16_t value) { + sensor->distances[sensor->nextMedianDistance] = value; + sensor->nextMedianDistance++; + + // if we got "fantom" measures, they are <= the current measures, so remove + // all values <= the current measure from the median data + for (unsigned short & distance : sensor->distances) { + if (distance < value) { + distance = value; + } + } + if (sensor->nextMedianDistance >= MEDIAN_DISTANCE_MEASURES) { + sensor->nextMedianDistance = 0; + } + return median(sensor->distances[0], sensor->distances[1], sensor->distances[2]); +} + +uint16_t PGASensorManager::median(uint16_t a, uint16_t b, uint16_t c) { + if (a < b) { + if (a >= c) { + return a; + } else if (b < c) { + return b; + } + } else { + if (a < c) { + return a; + } else if (b >= c) { + return b; + } + } + return c; +} + #endif // OBSPro diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 45c7e704..fc7931ba 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -1,6 +1,7 @@ #include #include #include "variant.h" +#include "utils/median.h" #ifndef OBS_PGASENSOR_H #define OBS_PGASENSOR_H @@ -143,17 +144,22 @@ struct PGASensorInfo { - uint8_t sck_pin; - uint8_t mosi_pin; - uint8_t miso_pin; + // General stuff uint16_t numberOfTriggers; int32_t echoDurationMicroseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; - uint16_t rawDistance = 42; // Current distance value in cm + Median*median = nullptr; + uint16_t rawDistance = 0; // Current distance value in cm + uint16_t distances[MEDIAN_DISTANCE_MEASURES] = { MAX_SENSOR_VALUE, MAX_SENSOR_VALUE, MAX_SENSOR_VALUE }; + uint16_t nextMedianDistance = 0; uint16_t minDistance = MAX_SENSOR_VALUE; uint16_t distance = MAX_SENSOR_VALUE; const char* sensorLocation; uint16_t offset = 0; // TODO: Apply offset + // Sensor specific stuff + uint8_t sck_pin; + uint8_t mosi_pin; + uint8_t miso_pin; #if PGA_DUMP_ENABLE // DEBUG: send a raw data dump trigger from time to time uint32_t lastDumpTime = 0; @@ -161,12 +167,12 @@ struct PGASensorInfo #endif }; -struct PGAUSResult +struct PGAResult { uint16_t tof; // Time of flight [us] - uint8_t width; - uint8_t peakAmplitude; - uint16_t distance; // [cm] + uint8_t width; // Width of the target [us], is usually 255 as targets are fairly wide? + uint8_t peakAmplitude; // Highest amplitude of that target [ADC LSB] + uint16_t distance; // First detected target distance [cm] }; #define TH_TIME_DELTA_100US 0x0 @@ -262,23 +268,26 @@ class PGASensorManager void registerSensor(const PGASensorInfo &sensorInfo, uint8_t idx); bool pollDistancesAlternating(); uint16_t getCurrentMeasureIndex(); - uint16_t getRawMedianDistance(uint8_t sensorId); - uint32_t getMaxDurationUs(uint8_t sensorId); - uint32_t getMinDurationUs(uint8_t sensorId); - uint32_t getLastDelayTillStartUs(uint8_t sensorId); - uint32_t getNoSignalReadings(const uint8_t sensorId); - uint32_t getNumberOfLowAfterMeasurement(const uint8_t sensorId); - uint32_t getNumberOfToLongMeasurement(const uint8_t sensorId); - uint32_t getNumberOfInterruptAdjustments(const uint8_t sensorId); + void setOffsets(std::vector offsets); void setPrimarySensor(uint8_t idx); void reset(uint32_t startMillisTicks); + + // TODO: This is just legacy interrupt stuff for the HCSR04 sensor - not required for PGA460 void detachInterrupts() {}; void attachInterrupts() {}; - bool spiDataDump(const uint8_t sensorId, uint8_t *data); + // TODO: This just seem to be debug stuff that is not really required and some is not even valid for PGA460 + uint16_t getRawMedianDistance(uint8_t sensorId) { return 0; }; + uint32_t getMaxDurationUs(uint8_t sensorId) { return 0; }; + uint32_t getMinDurationUs(uint8_t sensorId) { return 0; }; + uint32_t getLastDelayTillStartUs(uint8_t sensorId) { return 0; }; + uint32_t getNoSignalReadings(const uint8_t sensorId) { return 0; }; + uint32_t getNumberOfLowAfterMeasurement(const uint8_t sensorId) { return 0; }; + uint32_t getNumberOfToLongMeasurement(const uint8_t sensorId) { return 0; }; + uint32_t getNumberOfInterruptAdjustments(const uint8_t sensorId) { return 0; }; - // TODO: These should not be public! + // TODO: These variables should not be public! PGASensorInfo m_sensors[NUMBER_OF_TOF_SENSORS]; uint16_t sensorValues[NUMBER_OF_TOF_SENSORS]; uint16_t lastReadingCount = 0; @@ -295,8 +304,9 @@ class PGASensorManager void spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t value); void spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds); void spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8_t numberOfObjectsToDetect); - bool spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAUSResult *usResults); + bool spiUSResult(uint8_t sensorId, uint8_t numberOfObjectsToDetect, PGAResult *usResults); bool spiIsBusy(uint8_t sensorId); + bool spiDataDump(const uint8_t sensorId, uint8_t *data); // Checksum uint8_t checksum_sum; @@ -316,6 +326,9 @@ class PGASensorManager bool collectSensorResults(); void registerReadings(); uint16_t millisSince(uint16_t milliseconds); + uint16_t correctSensorOffset(uint16_t dist, uint16_t offset); + static uint16_t medianMeasure(PGASensorInfo* const sensor, uint16_t value); + static uint16_t median(uint16_t a, uint16_t b, uint16_t c); }; #endif // OBSPRO diff --git a/src/sensor.cpp b/src/sensor.cpp index 50e54c10..2096c2ee 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -38,12 +38,6 @@ * - JSN-SR04T-2.0 = ~1125us */ -static const uint16_t MIN_DISTANCE_MEASURED_CM = 2; -static const uint16_t MAX_DISTANCE_MEASURED_CM = 320; // candidate to check I could not get good readings above 300 - -static const uint32_t MIN_DURATION_MICRO_SEC = MIN_DISTANCE_MEASURED_CM * MICRO_SEC_TO_CM_DIVIDER; -const uint32_t MAX_DURATION_MICRO_SEC = MAX_DISTANCE_MEASURED_CM * MICRO_SEC_TO_CM_DIVIDER; - /* This time is maximum echo pin high time if the sensor gets no response * HC-SR04: observed 71ms, docu 60ms * JSN-SR04T: observed 58ms diff --git a/src/sensor.h b/src/sensor.h index a3e8da21..6dfe00bc 100644 --- a/src/sensor.h +++ b/src/sensor.h @@ -50,9 +50,6 @@ −10 325.4 −15 322.3 */ -const uint32_t MICRO_SEC_TO_CM_DIVIDER = 58; // sound speed 340M/S, 2 times back and forward - -const uint16_t MEDIAN_DISTANCE_MEASURES = 3; struct HCSR04SensorInfo { uint8_t triggerPin = 15; diff --git a/src/variant.h b/src/variant.h index 7988f6a0..af86592c 100644 --- a/src/variant.h +++ b/src/variant.h @@ -56,5 +56,18 @@ #define NUMBER_OF_TOF_SENSORS 2 #define MAX_SENSOR_VALUE 999 #define MAX_NUMBER_MEASUREMENTS_PER_INTERVAL 30 // is 1000/SENSOR_QUIET_PERIOD_AFTER_START_MICRO_SEC/2 +#define MEDIAN_DISTANCE_MEASURES 3 + +#define MIN_DISTANCE_MEASURED_CM 2 +#ifdef OBSPRO + #define MAX_DISTANCE_MEASURED_CM 600 +#else + #define MAX_DISTANCE_MEASURED_CM 320 // candidate to check I could not get good readings above 300 +#endif + +#define MICRO_SEC_TO_CM_DIVIDER 58 // sound speed 340M/S, 2 times back and forward + +#define MIN_DURATION_MICRO_SEC (MIN_DISTANCE_MEASURED_CM * MICRO_SEC_TO_CM_DIVIDER) +#define MAX_DURATION_MICRO_SEC (MAX_DISTANCE_MEASURED_CM * MICRO_SEC_TO_CM_DIVIDER) #endif From f9a694d334c83f6c5ccd588076b3d5c9ac6932d4 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 22 Feb 2024 17:13:39 +0100 Subject: [PATCH 21/34] Added support for u-blox M10 modules --- src/OpenBikeSensorFirmware.cpp | 9 +- src/gps.cpp | 178 +++++++++++++++++++++++++++++++-- src/gps.h | 82 +++++++++++++-- src/pgaSensor.cpp | 103 ------------------- src/variant.h | 5 + src/writer.h | 2 +- 6 files changed, 255 insertions(+), 124 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 0aa4a7ac..5d512d7b 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -48,7 +48,9 @@ const uint32_t LONG_BUTTON_PRESS_TIME_MS = 2000; // PINs const int PUSHBUTTON_PIN = 2; const int IP5306_BUTTON = 13; +#ifdef OBSCLASSIC const uint8_t GPS_POWER_PIN = 12; +#endif const uint8_t BatterieVoltage_PIN = 34; int confirmedMeasurements = 0; @@ -228,8 +230,10 @@ void setup() { pinMode(IP5306_BUTTON, OUTPUT); digitalWrite(IP5306_BUTTON, LOW); pinMode(BatterieVoltage_PIN, INPUT); + #ifdef OBSCLASSIC pinMode(GPS_POWER_PIN, OUTPUT); digitalWrite(GPS_POWER_PIN,HIGH); + #endif //############################################################## // Setup display @@ -323,7 +327,7 @@ void setup() { SPIFFS.end(); WiFiGenericClass::mode(WIFI_OFF); obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Start GPS..."); - //gps.begin(); // FIXME: Add GPS support for MAX-M10M + gps.begin(); if (gps.getValidMessageCount() > 0) { obsDisplay->showTextOnGrid(2, obsDisplay->currentLine(), "Start GPS OK"); } else { @@ -546,13 +550,12 @@ void loop() { minDistanceToConfirm = MAX_SENSOR_VALUE; // ready for next confirmation } + // TODO: Add support for temperature reading from PGA460 if(BMP280_active == true) TemperatureValue = bmp280.readTemperature(); gps.handle(); } // end measureInterval while - log_e("Measurement done"); - currentSet->gpsRecord = gps.getCurrentGpsRecord(); currentSet->isInsidePrivacyArea = gps.isInsidePrivacyArea(); if (currentSet->gpsRecord.getTow() == thisLoopTow) { diff --git a/src/gps.cpp b/src/gps.cpp index 271dfc64..87826435 100644 --- a/src/gps.cpp +++ b/src/gps.cpp @@ -40,9 +40,19 @@ void Gps::begin() { enableAlpIfDataIsAvailable(); pollStatistics(); if (mLastTimeTimeSet == 0) { +#ifdef UBX_M10 + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 1); +#endif +#ifdef UBX_M6 setMessageInterval(UBX_MSG::NAV_TIMEGPS, 1); +#endif } else { +#ifdef UBX_M10 + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 240); +#endif +#ifdef UBX_M6 setMessageInterval(UBX_MSG::NAV_TIMEGPS, 240); +#endif } } @@ -76,6 +86,24 @@ void Gps::sendUbx(uint16_t ubxMsgId, const uint8_t payload[], uint16_t length) { mSerial.write(buffer, length + 8); } +// Send a CFG_VALSET ubx command to write a configuration +// Only available in M10 devices +void Gps::sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value) +{ + uint8_t ubxCfgMsg[] = {0x00, layer, 0x00, 0x00, + (uint8_t)((uint32_t)keyId), (uint8_t)(((uint32_t)keyId)>>8), (uint8_t)(((uint32_t)keyId)>>16), (uint8_t)(((uint32_t)keyId)>>24), + (uint8_t)((uint32_t)value), (uint8_t)(((uint32_t)value)>>8), (uint8_t)(((uint32_t)value)>>16), (uint8_t)(((uint32_t)value)>>24)}; + uint16_t length = 0; + uint8_t lengthId = (((uint32_t)keyId)>>28)&0x07; + if(lengthId == 0x01 || lengthId == 0x02) + length = 1; + else if(lengthId == 0x03) + length = 2; + else if(lengthId == 0x04) + length = 4; + sendUbx(UBX_MSG::CFG_VALSET, ubxCfgMsg, length + 8); +} + /* Method sends the message in the receive buffer! */ void Gps::sendUbxDirect() { const uint16_t length = mGpsBuffer.ubxHeader.length; @@ -99,10 +127,17 @@ void Gps::configureGpsModule() { 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x03 }; +#ifdef UBX_M10 + // It is fairly stupid to reset the config here, as the baud rate will be reset (at least for M10) + //sendUbx(UBX_MSG::CFG_CFG, UBX_CFG_CFG_CLR, sizeof(UBX_CFG_CFG_CLR)); // Newer devices will not answer this request +#endif +#ifdef UBX_M6 sendAndWaitForAck(UBX_MSG::CFG_CFG, UBX_CFG_CFG_CLR, sizeof(UBX_CFG_CFG_CLR)); +#endif handle(300); log_d("Start CFG"); +#ifdef UBX_M6 // INF messages via UBX only const uint8_t UBX_CFG_INF_UBX[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, @@ -114,24 +149,43 @@ void Gps::configureGpsModule() { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; sendAndWaitForAck(UBX_MSG::CFG_INF, UBX_CFG_INF_NMEA, sizeof(UBX_CFG_INF_NMEA)); +#endif +#ifdef UBX_M6 + // Only required for M6 modules, NMEA is globally deactivated for M10 during begin() setMessageInterval(UBX_MSG::NMEA_GGA, 0); setMessageInterval(UBX_MSG::NMEA_RMC, 0); setMessageInterval(UBX_MSG::NMEA_GLL, 0); setMessageInterval(UBX_MSG::NMEA_GSA, 0); setMessageInterval(UBX_MSG::NMEA_GSV, 0); setMessageInterval(UBX_MSG::NMEA_VTG, 0); +#endif setStatisticsIntervalInSeconds(0); +#ifdef UBX_M6 + // AID is not available on M10 modules? At least I could not find it setMessageInterval(UBX_MSG::AID_ALPSRV, 0); +#endif enableSbas(); - setMessageInterval(UBX_MSG::NAV_SBAS, 59); +#ifdef UBX_M6 + setMessageInterval(UBX_MSG::NAV_SBAS, 59); setMessageInterval(UBX_MSG::NAV_POSLLH, 1); setMessageInterval(UBX_MSG::NAV_DOP, 1); setMessageInterval(UBX_MSG::NAV_SOL, 1); setMessageInterval(UBX_MSG::NAV_VELNED, 1); setMessageInterval(UBX_MSG::NAV_TIMEGPS, 1); +#endif +#ifdef UBX_M10 + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_SBAS_UART1, 59); + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_POSLLH_UART1, 1); + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_DOP_UART1, 1); + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_VELNED_UART1, 1); + // SOL not available in M10, the message NAV-PVT is used instead + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_PVT_UART1, 1); + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 1); +#endif +#ifdef UBX_M6 // "dynModel" - "3: pedestrian" // "static hold" - 80cm/s == 2.88 km/h // "staticHoldMaxDist" - 20m (not supported by our GPS receivers) @@ -143,7 +197,11 @@ void Gps::configureGpsModule() { 0x00, 0x00, 0x00, 0x00 }; sendAndWaitForAck(UBX_MSG::CFG_NAV5, UBX_CFG_NAV5, sizeof(UBX_CFG_NAV5)); +#endif + // TODO: Set dynModel for M10, static hold stuff does not seem to be available any more +#ifdef UBX_M6 + // Not used for M10, as OBSPro does not have a GPS LED // "timepulse" - affecting the led, switching to 10ms pulse every 10sec, // to be clearly differentiable from the default (100ms each second) const uint8_t UBX_CFG_TP[] = { @@ -152,20 +210,35 @@ void Gps::configureGpsModule() { 0x00, 0x00, 0x00, 0x00 }; sendAndWaitForAck(UBX_MSG::CFG_TP, UBX_CFG_TP, sizeof(UBX_CFG_TP)); +#endif +#ifdef UBX_M6 + // What is this good for? Not bothering implementing that for OBSPro // Leave some info in the GPS module String inv = String("\x01openbikesensor.org/") + OBSVersion; sendAndWaitForAck(UBX_MSG::CFG_RINV, reinterpret_cast(inv.c_str()), inv.length()); +#endif +#ifdef UBX_M6 + // AID only available in M6 modules // Used to store GPS AID data every 3 minutes+ setMessageInterval(UBX_MSG::AID_INI, 185); +#endif // Persist configuration +#ifdef UBX_M6 const uint8_t UBX_CFG_CFG_SAVE[] = { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17 }; +#endif +#ifdef UBX_M10 + const uint8_t UBX_CFG_CFG_SAVE[] = { + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x03 + }; +#endif // write cfg takes longer. if (sendAndWaitForAck(UBX_MSG::CFG_CFG, UBX_CFG_CFG_SAVE, sizeof(UBX_CFG_CFG_SAVE), 3000)) { addStatisticsMessage("OBS: Did update GPS settings."); @@ -183,7 +256,13 @@ void Gps::softResetGps() { // const uint8_t UBX_CFG_RST[] = {0xFF, 0xFF, 0x02, 0x00}; // Cold START // we had the case where the reset took several seconds // see https://github.com/openbikesensor/OpenBikeSensorFirmware/issues/309 +#ifdef UBX_M6 sendAndWaitForAck(UBX_MSG::CFG_RST, UBX_CFG_RST, 4, 5000); +#endif +#ifdef UBX_M10 + // Newer firmware (like M10) will not ack this message + sendUbx(UBX_MSG::CFG_RST, UBX_CFG_RST, 4); +#endif handle(200); } @@ -211,6 +290,7 @@ void Gps::enableSbas() {// Enable SBAS subsystem! } void Gps::enableAlpIfDataIsAvailable() { +#ifdef UBX_M6 if (AlpData::available()) { log_i("Enable ALP"); // don't wait for ack - newer modules do not support this old ALPSRV @@ -220,7 +300,7 @@ void Gps::enableAlpIfDataIsAvailable() { log_w("Disable ALP - no data!"); setMessageInterval(UBX_MSG::AID_ALPSRV, 0); } - +#endif } /* Poll or refresh one time statistics, also spends some time @@ -248,10 +328,17 @@ void Gps::pollStatistics() { * Zero seconds means never. */ void Gps::setStatisticsIntervalInSeconds(uint16_t seconds) { +#ifdef UBX_M6 setMessageInterval(UBX_MSG::NAV_STATUS, seconds); setMessageInterval(UBX_MSG::MON_HW, seconds); +#endif +#ifdef UBX_M10 + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_STATUS_UART1, seconds); + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_MON_HW_UART1, seconds); +#endif } +#ifdef UBX_M6 bool Gps::setMessageInterval(UBX_MSG msgId, uint8_t seconds, bool waitForAck) { uint8_t ubxCfgMsg[] = { 0x0A, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 @@ -261,8 +348,7 @@ bool Gps::setMessageInterval(UBX_MSG msgId, uint8_t seconds, bool waitForAck) { ubxCfgMsg[3] = seconds; bool result; if (waitForAck) { - result = sendAndWaitForAck( - UBX_MSG::CFG_MSG, ubxCfgMsg, sizeof(ubxCfgMsg)); + result = sendAndWaitForAck(UBX_MSG::CFG_MSG, ubxCfgMsg, sizeof(ubxCfgMsg)); } else { result = true; sendUbx(UBX_MSG::CFG_MSG, ubxCfgMsg, sizeof(ubxCfgMsg)); @@ -272,6 +358,23 @@ bool Gps::setMessageInterval(UBX_MSG msgId, uint8_t seconds, bool waitForAck) { } return result; } +#endif + +#ifdef UBX_M10 +bool Gps::setMessageInterval(UBX_CFG_KEY_ID msgId, uint8_t seconds, bool waitForAck) { + bool result; + if (waitForAck) { + result = sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, msgId, seconds); + } else { + result = true; + sendUbxCfg(UBX_CFG_LAYER::RAM, msgId, seconds); + } + if (!result) { + log_e("Failed for sendUbxCfg of 0x%08x!", msgId); + } + return result; +} +#endif /* Initialize the GPS module to talk 115200. * If 115200 is not on by default the module is also configured, @@ -290,12 +393,19 @@ bool Gps::setBaud() { mSerial.updateBaudRate(9600); // switch to 115200 "blind", switch off NMEA +#ifdef UBX_M6 const uint8_t UBX_CFG_PRT[] = { 0x01, 0x00, 0x00, 0x00, 0xd0, 0x08, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; sendUbx(UBX_MSG::CFG_PRT, UBX_CFG_PRT, sizeof(UBX_CFG_PRT)); +#endif +#ifdef UBX_M10 + sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_UART1OUTPROT_NMEA, 0); // Disable NMEA + sendUbxCfg(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_UART1_BAUDRATE, 115200); // Blindly set baudrate + log_i("Blindly switched to 115200 baud rate"); +#endif mSerial.flush(); mSerial.updateBaudRate(115200); @@ -310,11 +420,15 @@ bool Gps::setBaud() { log_e("NO GPS????"); delay(5000); } + else + log_i("Connected to GPS"); if (connected && mSerial.baudRate() / 10 != 115200 / 10) { log_e("Reported rate: %d", mSerial.baudRate()); +#ifdef UBX_M6 if (sendAndWaitForAck(UBX_MSG::CFG_PRT, UBX_CFG_PRT, sizeof(UBX_CFG_PRT))) { mSerial.updateBaudRate(115200); } +#endif } if (checkCommunication()) { configureGpsModule(); @@ -356,9 +470,43 @@ bool Gps::sendAndWaitForAck(UBX_MSG ubxMsgId, const uint8_t *buffer, size_t size log_w("Retry to send 0x%04x after %dms.", ubxMsgId, millis() - loopStart); } if (result) { - log_d("Success in sending cfg. 0x%04x took %dms", ubxMsgId, millis() - start); + log_d("Success in sending. 0x%04x took %dms", ubxMsgId, millis() - start); } else { - log_e("Failed to send cfg. 0x%04x NAK: %d after %dms", ubxMsgId, mNakReceived, millis() - start); + log_e("Failed to send. 0x%04x NAK: %d after %dms", ubxMsgId, mNakReceived, millis() - start); + } + return result; +} + +bool Gps::sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs) { + const int tries = 2; + auto start = millis(); + + bool result = false; + for (int i = 0; i < tries; i++) { + handle(); + auto const loopStart = millis(); + mNakReceived = false; + mAckReceived = false; + mLastAckMsgId = 0; + + sendUbxCfg(layer, keyId, value); + mSerial.flush(); + handle(); + while (mLastAckMsgId != (uint16_t) UBX_MSG::CFG_VALSET && millis() - loopStart < timeoutMs) { + if (!handle()) { + delay(1); + } + } + if (mAckReceived || mNakReceived) { + result = mAckReceived; + break; + } + log_w("Retry to send cfg 0x%08x after %dms.", keyId, millis() - loopStart); + } + if (result) { + log_d("Success in sending cfg. 0x%08x took %dms", keyId, millis() - start); + } else { + log_e("Failed to send cfg. 0x%08x NAK: %d after %dms", keyId, mNakReceived, millis() - start); } return result; } @@ -934,12 +1082,20 @@ void Gps::parseUbxMessage() { mIncomingGpsRecord.setInfo(mGpsBuffer.navSol.numSv, mGpsBuffer.navSol.gpsFix, mGpsBuffer.navSol.flags); } break; + case (uint16_t) UBX_MSG::NAV_PVT: { + log_v("PVT: iTOW: %u, gpsFix: %d, flags: %02x, numSV: %d, pDop: %04d.", + mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.gpsFix, mGpsBuffer.navPvt.flags, + mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDop); + prepareGpsData(mGpsBuffer.navPvt.iTow, mMessageStarted); + mIncomingGpsRecord.setInfo(mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags); + } + break; case (uint16_t) UBX_MSG::NAV_VELNED: { log_v("VELNED: iTOW: %u, speed: %d cm/s, gSpeed: %d cm/s, heading: %d," " speedAcc: %d, cAcc: %d", mGpsBuffer.navVelned.iTow, mGpsBuffer.navVelned.speed, mGpsBuffer.navVelned.gSpeed, mGpsBuffer.navVelned.heading, mGpsBuffer.navVelned.sAcc, mGpsBuffer.navVelned.cAcc); - prepareGpsData(mGpsBuffer.navDop.iTow, mMessageStarted); + prepareGpsData(mGpsBuffer.navVelned.iTow, mMessageStarted); mIncomingGpsRecord.setVelocity(mGpsBuffer.navVelned.gSpeed, mGpsBuffer.navVelned.heading); } break; @@ -948,7 +1104,7 @@ void Gps::parseUbxMessage() { mGpsBuffer.navPosllh.iTow, mGpsBuffer.navPosllh.lon, mGpsBuffer.navPosllh.lat, mGpsBuffer.navPosllh.height, mGpsBuffer.navPosllh.hMsl, mGpsBuffer.navPosllh.hAcc, mGpsBuffer.navPosllh.vAcc, delayMs); - prepareGpsData(mGpsBuffer.navDop.iTow, mMessageStarted); + prepareGpsData(mGpsBuffer.navPosllh.iTow, mMessageStarted); mIncomingGpsRecord.setPosition(mGpsBuffer.navPosllh.lon, mGpsBuffer.navPosllh.lat, mGpsBuffer.navPosllh.hMsl); } break; @@ -1087,6 +1243,7 @@ void Gps::handleUbxNavTimeGps(const GpsBuffer::UbxNavTimeGps &message, const uin + mLastGpsWeek + " -> " + message.week); } mLastGpsWeek = message.week; + mIncomingGpsRecord.setWeek(mLastGpsWeek); } if ((message.valid & 0x03) == 0x03 // WEEK && TOW && delayMs < 20 @@ -1105,7 +1262,12 @@ void Gps::handleUbxNavTimeGps(const GpsBuffer::UbxNavTimeGps &message, const uin if (mLastTimeTimeSet == 0) { mLastTimeTimeSet = receivedMs; // This triggers another NAV-TIMEGPS message! +#ifdef UBX_M6 setMessageInterval(UBX_MSG::NAV_TIMEGPS, 240, false); // every 4 minutes +#endif +#ifdef UBX_M10 + setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 240, false); // every 4 minutes +#endif } else { mLastTimeTimeSet = receivedMs; } diff --git a/src/gps.h b/src/gps.h index 34403f44..7b2902c1 100644 --- a/src/gps.h +++ b/src/gps.h @@ -127,7 +127,8 @@ class Gps { NAV_POSLLH = 0x0201, NAV_STATUS = 0x0301, NAV_DOP = 0x0401, - NAV_SOL = 0x0601, + NAV_SOL = 0x0601, // Only available in M6 + NAV_PVT = 0x0701, // Only available in M10 NAV_VELNED = 0x1201, NAV_TIMEGPS = 0x2001, NAV_TIMEUTC = 0x2101, @@ -148,9 +149,10 @@ class Gps { ACK_NAK = 0x0005, // ACK 0x06 - CFG_PRT = 0x0006, - CFG_MSG = 0x0106, - CFG_INF = 0x0206, + CFG_PRT = 0x0006, // Only available in M6 + CFG_MSG = 0x0106, // Only available in M6, replaced with CFG-MSGOUT-UBX* + CFG_INF = 0x0206, // Only available in M6 + CFG_VALSET = 0x8a06, // Only available in M10 CFG_RST = 0x0406, CFG_TP = 0x0706, CFG_CFG = 0x0906, @@ -161,13 +163,13 @@ class Gps { // MON 0x0A MON_VER = 0x040a, - MON_HW = 0x090a, + MON_HW = 0x090a, // Only available in M6 // AID 0x0B - AID_INI = 0x010B, - AID_HUI = 0x020B, - AID_ALPSRV = 0x320B, - AID_ALP = 0x500B, + AID_INI = 0x010B, // Only available in M6 + AID_HUI = 0x020B, // Only available in M6 + AID_ALPSRV = 0x320B, // Only available in M6 + AID_ALP = 0x500B, // Only available in M6 // TIM 0x0D // ESF 0x10 @@ -183,6 +185,25 @@ class Gps { // UBX, special 0xf1 }; + // Key-ID pairs are only available in M10, they are used for the configuration + enum class UBX_CFG_KEY_ID { + CFG_UART1_BAUDRATE = 0x40520001, // Type: U4 + CFG_UART1OUTPROT_NMEA = 0x10740002, // Type: L + CFG_MSGOUT_UBX_MON_HW_UART1 = 0x209101b5, // Type: U1, Output rate of the UBX-MON-HW message on port UART1 + CFG_MSGOUT_UBX_NAV_STATUS_UART1 = 0x2091001b, // Type: U1, Output rate of the UBX-NAV-STATUS message on port UART1 + CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1 = 0x20910048, // Type: U1, Output rate of the UBX-NAV-TIMEGPS message on port UART1 + CFG_MSGOUT_UBX_NAV_SBAS_UART1 = 0x2091006b, // Type: U1, Output rate of the UBX-NAV-SBAS message on port UART1 + CFG_MSGOUT_UBX_NAV_POSLLH_UART1 = 0x2091002a, // Type: U1, Output rate of the UBX-NAV-POSLLH message on port UART1 + CFG_MSGOUT_UBX_NAV_DOP_UART1 = 0x20910039, // Type: U1, Output rate of the UBX-NAV-DOP message on port UART1 + CFG_MSGOUT_UBX_NAV_VELNED_UART1 = 0x20910043, // Type: U1, Output rate of the UBX-NAV-VELNED message on port UART1 + CFG_MSGOUT_UBX_NAV_PVT_UART1 = 0x20910007, // Type: U1, Output rate of the UBX-NAV-PVT message on port UART1 + }; + // CFG Layers are only available in M10, they are used for selecting wehere to store a configuration + enum UBX_CFG_LAYER : uint8_t { + RAM = 1, + BBR = 2, + FLASH = 4 + } aStatus; union GpsBuffer { uint8_t u1Data[MAX_MESSAGE_LENGTH]; char charData[MAX_MESSAGE_LENGTH]; @@ -328,6 +349,42 @@ class Gps { uint8_t numSv; uint32_t reserved2; } navSol; + struct __attribute__((__packed__)) { + UBX_HEADER ubxHeader; + uint32_t iTow; + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t valid; // bit0: validDate, bit1: validTime, bit2: fullResolved, bit3: validMag + uint32_t tAcc; + int32_t nano; + GpsRecord::GPS_FIX fixType; + uint8_t flags; + uint8_t flags2; + uint8_t numSV; + int32_t lon; + int32_t lat; + int32_t height; + int32_t hMSL; + uint32_t hAcc; + uint32_t vAcc; + int32_t velN; + int32_t velE; + int32_t velD; + int32_t gSpeed; + int32_t headMot; + uint32_t sAcc; + uint32_t headAcc; + uint16_t pDOP; + uint16_t flags3; + uint8_t reserved0[4]; + int32_t headVeh; + int16_t magDec; + uint16_t magAcc; + } navPvt; struct __attribute__((__packed__)) { UBX_HEADER ubxHeader; uint32_t iTow; @@ -511,8 +568,10 @@ class Gps { void sendUbx(uint16_t ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0); void sendUbx(UBX_MSG ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0); + void sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value); // Only available in M10 bool sendAndWaitForAck(UBX_MSG ubxMsgId, const uint8_t *buffer = {}, size_t size = 0, const uint16_t timeoutMs = 200); + bool sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs = 200); void parseUbxMessage(); @@ -534,7 +593,12 @@ class Gps { static bool validNmeaMessageChar(uint8_t chr); +#ifdef UBX_M6 bool setMessageInterval(UBX_MSG msgId, uint8_t seconds, bool waitForAck = true); +#endif +#ifdef UBX_M10 + bool setMessageInterval(UBX_CFG_KEY_ID msgId, uint8_t seconds, bool waitForAck = true); +#endif /* Make sure fresh GPS data can be added to the current internal record. * Add TOW and millis ticks to the record if not already set, diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index f5a21a53..615f359c 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -63,109 +63,6 @@ bool PGASensorManager::pollDistancesAlternating() lastSensor = nextSensor; return newMeasurements; - - - /*if (lastSensor == primarySensor && !spiIsBusy(1 - primarySensor)) { - lastSensor = 1 - primarySensor; -#if PGA_DUMP_ENABLE - // DEBUG: request a raw data dump from time to time - if(millis() - m_sensors[1-primarySensor].lastDumpTime > 1000) - { - spiRegWrite(1-primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); - m_sensors[1-primarySensor].lastDumpTime = millis(); - m_sensors[1-primarySensor].lastMeasurementWasDump = true; - } - else - { - spiRegWrite(1-primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); - m_sensors[1-primarySensor].lastMeasurementWasDump = false; - } -#endif - spiBurstAndListen(1 - primarySensor, 1, 1); - } else if (!spiIsBusy(primarySensor)) { - newMeasurements = collectSensorResults(); - lastSensor = primarySensor; -#if PGA_DUMP_ENABLE - // DEBUG: request a raw data dump from time to time - if(millis() - m_sensors[primarySensor].lastDumpTime > 1000) - { - spiRegWrite(primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(1)); - m_sensors[primarySensor].lastDumpTime = millis(); - m_sensors[primarySensor].lastMeasurementWasDump = true; - } - else - { - spiRegWrite(primarySensor, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN(0)); - m_sensors[primarySensor].lastMeasurementWasDump = false; - } -#endif - spiBurstAndListen(primarySensor, 1, 1); - } - return newMeasurements;*/ - - /*unsigned long timeMs = millis(); - static uint8_t param = 0; - static bool isDump = false; // True if a dump has to be triggered (false if the dump result has to be read) - if(timeMs - lastTriggerTimeMs > 200 && param <= 63) - { - // Frequently check stat1 register to make sure there are no errors - // TODO: Set sensorId - uint8_t stat1 = spiRegRead(0, PGA_REG_DEV_STAT1); - if(stat1 != 0x00) - { - log_e("STAT1 register error: 0x%02x", stat1); - // TODO: Set sensorId - spiRegWrite(0, PGA_REG_DEV_STAT1, 0x00); // Clear stat1 register - } - - // Get data dump of last measurement - // TODO: Set sensorId - if(!isDump) - { - // Last measurement was a dump, read and print data - //Serial.print("Get dump\n"); - uint8_t data[128]; - if(!spiDataDump(0, data)) - log_e("Unable to get data dump: Checksum error"); - else - { - //Serial.printf("\"%d\": [", param); - for(int i = 0; i < 128; i++) - { - Serial.printf("%d", data[i]); - if(i+1 != 128) - Serial.print(","); - } - Serial.printf("\n"); - //param++; - } - } - else - { - //Serial.print("Get distance\n"); - // Last measurement was a normal measurement, read and print distance - PGAResult usResult[1]; - if(!spiUSResult(0, 1, usResult)) - Serial.print("Unable to get US result: Checksum error\n"); - else - { - Serial.printf("%u, %u, %u\n", usResult[0].tof, usResult[0].width, usResult[0].peakAmplitude); - } - } - - // Set parameter - //spiRegWrite(0, PGA_REG_CURR_LIM_P1, PGA_DIS_CL(0) | PGA_CURR_LIM1(param)); - - // Trigger next sensor - // TODO: Set sensorId - //Serial.printf("Trigger with isDump=%d\n", isDump); - spiRegWrite(0, PGA_REG_EE_CNTRL, PGA_DATADUMP_EN((uint8_t)isDump)); // Enable data dump - spiBurstAndListen(0, 1, 1); - lastTriggerTimeMs = timeMs; - isDump = !isDump; - return true; - } - return false;*/ } uint16_t PGASensorManager::getCurrentMeasureIndex() diff --git a/src/variant.h b/src/variant.h index af86592c..9233ae46 100644 --- a/src/variant.h +++ b/src/variant.h @@ -48,7 +48,12 @@ #define SENSOR2_SCK_PIN 14 #define SENSOR2_MOSI_PIN 15 #define SENSOR2_MISO_PIN 21 +#define UBX_M10 +#endif +// Settings specific to OBSClassic +#if OBSCLASSIC +#define UBS_M6 #endif diff --git a/src/writer.h b/src/writer.h index 34af049f..134ad88d 100644 --- a/src/writer.h +++ b/src/writer.h @@ -28,7 +28,7 @@ #include #include #include - +#include "gps.h" #include "globals.h" From 2ba9e96463a2123c638ac0f297bdabf0c0d50e96 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 22 Feb 2024 18:53:05 +0100 Subject: [PATCH 22/34] Moved power management into an interrupt, works nor everywhere --- src/OpenBikeSensorFirmware.cpp | 93 +++++++++++++++++++++++++++------- src/variant.h | 2 + 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 5d512d7b..90c188e2 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -53,6 +53,8 @@ const uint8_t GPS_POWER_PIN = 12; #endif const uint8_t BatterieVoltage_PIN = 34; +hw_timer_t *timer0_powermanagement_cfg = NULL; + int confirmedMeasurements = 0; int numButtonReleased = 0; DataSet *datasetToConfirm = nullptr; @@ -102,6 +104,7 @@ FileWriter* writer; const uint8_t displayAddress = 0x3c; + // Enable dev-mode. Allows to // - set wifi config // - prints more detailed log messages to serial (WIFI password) @@ -218,6 +221,71 @@ static void buttonBluetooth(const DataSet *dataSet, uint16_t measureIndex) { } } +#ifdef OBSPRO +// Power-management keep alive timer +// This function is called every 100 ms +static unsigned long timeOfLastPowerKeepAlive = 0; +static uint8_t shutdownState = 0; +static uint8_t buttonPressedCounter = 0; +static void powerKeepAliveTimerISR() +{ + // Send "keep alive" trigger to power management module + // This is done by toggling the pin every 300 ms or more + if(shutdownState == 0) + { + if(!digitalRead(IP5306_BUTTON) && millis() - timeOfLastPowerKeepAlive > POWER_KEEP_ALIVE_INTERVAL_MS) + { + timeOfLastPowerKeepAlive = millis(); + digitalWrite(IP5306_BUTTON, HIGH); + } + else if(digitalRead(IP5306_BUTTON) && millis() - timeOfLastPowerKeepAlive > 300) + { + timeOfLastPowerKeepAlive = millis(); + digitalWrite(IP5306_BUTTON, LOW); + } + } + + // Soft power-off OBSPro when button is pressed for more than 2 seconds + if(button.read()) + { + if(buttonPressedCounter < 255) + buttonPressedCounter++; + } + else + buttonPressedCounter = 0; + + if(shutdownState == 0 && buttonPressedCounter >= 20) { + shutdownState = 1; + } + switch(shutdownState) + { + case 1: + digitalWrite(IP5306_BUTTON, LOW); + break; + case 4: + digitalWrite(IP5306_BUTTON, HIGH); + break; + case 7: + digitalWrite(IP5306_BUTTON, LOW); + break; + case 10: + digitalWrite(IP5306_BUTTON, HIGH); + break; + case 13: + digitalWrite(IP5306_BUTTON, LOW); + noInterrupts(); + while(1) + NOP(); + break; + default: + break; + } + if(shutdownState != 0 && shutdownState < 13) + shutdownState++; +} + +#endif + void setup() { Serial.begin(115200); log_i("openbikesensor.org - OBS/%s", OBSVersion); @@ -235,6 +303,14 @@ void setup() { digitalWrite(GPS_POWER_PIN,HIGH); #endif +#ifdef OBSPRO + // Setup power management timer to trigger every 100ms (clock is 80 MHz) + timer0_powermanagement_cfg = timerBegin(0, 1000, true); + timerAttachInterrupt(timer0_powermanagement_cfg, &powerKeepAliveTimerISR, true); + timerAlarmWrite(timer0_powermanagement_cfg, 8000, true); + timerAlarmEnable(timer0_powermanagement_cfg); +#endif + //############################################################## // Setup display //############################################################## @@ -434,7 +510,6 @@ void writeDataset(const uint8_t confirmationSensorID, DataSet *dataset) { } void loop() { - log_w("loop()"); //specify which sensors value can be confirmed by pressing the button, should be configurable const uint8_t confirmationSensorID = LEFT_SENSOR_ID; auto* currentSet = new DataSet; @@ -514,22 +589,6 @@ void loop() { gps.handle(); reportBluetooth(); -#ifdef OBSPRO - // Soft power-off OBSPro when button is pressed for more than 2 seconds - if(button.getState() && button.getCurrentStateMillis() > 2000) { - log_w("Shutting down OBS"); - digitalWrite(IP5306_BUTTON, HIGH); - delay(300); - digitalWrite(IP5306_BUTTON, LOW); - delay(300); - digitalWrite(IP5306_BUTTON, HIGH); - delay(300); - digitalWrite(IP5306_BUTTON, LOW); - delay(2000); - // TODO: Make sure we don't do anything when the system turns off. - // TODO: Maybe write SD content and umount it? - } -#endif if (button.gotPressed()) { // after button was released, detect long press here // immediate user feedback - we start the action obsDisplay->highlight(); diff --git a/src/variant.h b/src/variant.h index 9233ae46..75c8ae67 100644 --- a/src/variant.h +++ b/src/variant.h @@ -49,6 +49,8 @@ #define SENSOR2_MOSI_PIN 15 #define SENSOR2_MISO_PIN 21 #define UBX_M10 + +#define POWER_KEEP_ALIVE_INTERVAL_MS 5000UL #endif // Settings specific to OBSClassic From e713af6b54d3540a0c4dbfe3c7610fb81c6c4ca0 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Thu, 22 Feb 2024 19:37:22 +0100 Subject: [PATCH 23/34] Fixed un-initialized variable causing crashes if not 0 or 1 --- src/pgaSensor.cpp | 1 + src/pgaSensor.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index 615f359c..cf43d3f1 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -166,6 +166,7 @@ void PGASensorManager::safe_usleep(unsigned long us) uint8_t PGASensorManager::spiTransfer(uint8_t sensorId, uint8_t data_out) { + assert(sensorId >= 0 && sensorId <= 1); PGASensorInfo &sensorInfo = m_sensors[sensorId]; uint8_t data_in = 0; for(uint8_t i = 0; i < 8; i++) diff --git a/src/pgaSensor.h b/src/pgaSensor.h index fc7931ba..65a629c9 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -294,7 +294,7 @@ class PGASensorManager uint16_t startOffsetMilliseconds[MAX_NUMBER_MEASUREMENTS_PER_INTERVAL + 1]; protected: - void setupSensor(int idx); + void setupSensor(int sensorId); void safe_usleep(unsigned long us); @@ -320,7 +320,7 @@ class PGASensorManager // Alternating state unsigned long lastTriggerTimeMs; - uint8_t lastSensor; + uint8_t lastSensor = 1; uint8_t primarySensor = 1; uint32_t startReadingMilliseconds = 0; bool collectSensorResults(); From c12d9cdfd3b9dc65f488a8e767ca2c6acc9f44b1 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Fri, 23 Feb 2024 18:21:05 +0100 Subject: [PATCH 24/34] Disable dump --- src/OpenBikeSensorFirmware.cpp | 4 ++-- src/gps.h | 2 +- src/pgaSensor.cpp | 2 +- src/pgaSensor.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 90c188e2..b623abb2 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -433,8 +433,8 @@ void setup() { //############################################################## BMP280_active = TemperatureValue = bmp280.begin(BMP280_ADDRESS_ALT,BMP280_CHIPID); - if(BMP280_active == true) TemperatureValue = bmp280.readTemperature(); - + if(BMP280_active == true) + TemperatureValue = bmp280.readTemperature(); gps.handle(); diff --git a/src/gps.h b/src/gps.h index 7b2902c1..49221574 100644 --- a/src/gps.h +++ b/src/gps.h @@ -163,7 +163,7 @@ class Gps { // MON 0x0A MON_VER = 0x040a, - MON_HW = 0x090a, // Only available in M6 + MON_HW = 0x090a, // AID 0x0B AID_INI = 0x010B, // Only available in M6 diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index cf43d3f1..b5f9c52a 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -429,8 +429,8 @@ bool PGASensorManager::collectSensorResults() { } else { + Serial.printf("meas,%d,%d,%d,%d\n", sensorId, usResults[0].tof, usResults[0].width, usResults[0].peakAmplitude); #endif - Serial.printf("meas,%d,%d,%d,%d\n", sensorId, usResults[0].tof, usResults[0].width, usResults[0].peakAmplitude); sensor->echoDurationMicroseconds[lastReadingCount] = usResults[0].tof; uint16_t dist; diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 65a629c9..954832ac 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -138,7 +138,7 @@ #define PGA_REG_THR_CRC 0x7f #define PGA_DIAG_BUSY_MASK 0x01 -#define PGA_DUMP_ENABLE 1 +#define PGA_DUMP_ENABLE 0 // Prints raw data of the measurements, for debugging or calibration of a new transducer #define PGA_DUMP_TIME 500 From c3052b0215832759fdb64a84749c15d84a396040 Mon Sep 17 00:00:00 2001 From: Fabian Schwartau Date: Mon, 15 Apr 2024 19:04:52 +0200 Subject: [PATCH 25/34] Smaller optimizations of pga and gps software --- src/OpenBikeSensorFirmware.cpp | 9 +++++- src/gps.cpp | 43 ++++++++++++++++++++++--- src/gps.h | 15 ++++++++- src/pgaSensor.cpp | 59 +++++++++++++++++++++++++--------- src/pgaSensor.h | 2 +- src/writer.cpp | 11 ++++++- 6 files changed, 116 insertions(+), 23 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index b623abb2..ca0f4a9d 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -515,6 +515,12 @@ void loop() { auto* currentSet = new DataSet; uint32_t thisLoopTow; + if(shutdownState != 0) { + obsDisplay->clear(); + while(1) + delay(1); + } + if (gps.hasTowTicks()) { /* only Timeinfo is reliably set until now! */ GpsRecord incoming = gps.getIncomingGpsRecord(); @@ -555,7 +561,6 @@ void loop() { button.handle(currentTimeMillis); gps.handle(); if (sensorManager->pollDistancesAlternating()) { - log_w("poll"); // if a new minimum on the selected sensor is detected, the value and the time of detection will be stored const uint16_t reading = sensorManager->sensorValues[confirmationSensorID]; if (reading > 0 && reading < minDistanceToConfirm) { @@ -707,6 +712,8 @@ bool loadConfig(ObsConfig &cfg) { } } + SPI.begin(18, 19, 23, 5); + SPI.setDataMode(SPI_MODE0); if (SD.begin() && SD.exists("/obs.json")) { obsDisplay->showTextOnGrid(2, obsDisplay->currentLine(), "Init from SD."); log_i("Configuration init from SD."); diff --git a/src/gps.cpp b/src/gps.cpp index 87826435..94afff3a 100644 --- a/src/gps.cpp +++ b/src/gps.cpp @@ -54,6 +54,21 @@ void Gps::begin() { setMessageInterval(UBX_MSG::NAV_TIMEGPS, 240); #endif } + + //Serial.updateBaudRate(9600); + //mSerial.begin(9600, SERIAL_8N1); + // Debug - forward gps serial to normal serial + /* + log_e("--------_STARTING LOOP"); + while(1) + { + int val = mSerial.read(); + if(val >= 0) + Serial.write(val); + val = Serial.read(); + if(val >= 0) + mSerial.write(val); + }*/ } void Gps::sendUbx(UBX_MSG ubxMsgId, const uint8_t payload[], uint16_t length) { @@ -167,6 +182,11 @@ void Gps::configureGpsModule() { #endif enableSbas(); +#ifdef UBX_M10 + // Enable Glonass for M10, GPS and Galileo are enabled by default + sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_SIGNAL_GLO_ENA, 1); +#endif + #ifdef UBX_M6 setMessageInterval(UBX_MSG::NAV_SBAS, 59); setMessageInterval(UBX_MSG::NAV_POSLLH, 1); @@ -198,7 +218,9 @@ void Gps::configureGpsModule() { }; sendAndWaitForAck(UBX_MSG::CFG_NAV5, UBX_CFG_NAV5, sizeof(UBX_CFG_NAV5)); #endif - // TODO: Set dynModel for M10, static hold stuff does not seem to be available any more +#ifdef UBX_M10 + sendCfgAndWaitForAck(UBX_CFG_LAYER::RAM, UBX_CFG_KEY_ID::CFG_NAVSPG_DYNMODEL, 4); // Set dynamic model to 4 (automotive) +#endif #ifdef UBX_M6 // Not used for M10, as OBSPro does not have a GPS LED @@ -383,6 +405,7 @@ bool Gps::setMessageInterval(UBX_CFG_KEY_ID msgId, uint8_t seconds, bool waitFor bool Gps::setBaud() { mSerial.end(); mSerial.setRxBufferSize(512); + mSerial.begin(115200, SERIAL_8N1); while(mSerial.read() >= 0) ; @@ -392,6 +415,7 @@ bool Gps::setBaud() { } mSerial.updateBaudRate(9600); + // switch to 115200 "blind", switch off NMEA #ifdef UBX_M6 const uint8_t UBX_CFG_PRT[] = { @@ -544,8 +568,19 @@ bool Gps::handle() { boolean gotGpsData = false; int bytesProcessed = 0; int data; +#ifdef GPS_TRANSPARENT_UART + // Redicrect data to GPS + while((data = Serial.read()) >= 0) + mSerial.write(data); +#endif while ((data = mSerial.read()) >= 0) { bytesProcessed++; + +#ifdef GPS_TRANSPARENT_UART + // Redicrect data from GPS + Serial.write(data); +#endif + #ifdef GPS_LOW_LEVEL_DEBUGGING log_w("GPS in: 0x%02x", data); #endif @@ -1083,9 +1118,9 @@ void Gps::parseUbxMessage() { } break; case (uint16_t) UBX_MSG::NAV_PVT: { - log_v("PVT: iTOW: %u, gpsFix: %d, flags: %02x, numSV: %d, pDop: %04d.", - mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.gpsFix, mGpsBuffer.navPvt.flags, - mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDop); + log_v("PVT: iTOW: %u, fixType: %d, flags: %02x, numSV: %d, pDop: %04d.", + mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags, + mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDOP); prepareGpsData(mGpsBuffer.navPvt.iTow, mMessageStarted); mIncomingGpsRecord.setInfo(mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags); } diff --git a/src/gps.h b/src/gps.h index 49221574..0c4f9086 100644 --- a/src/gps.h +++ b/src/gps.h @@ -30,6 +30,11 @@ #include "config.h" // PrivacyArea #include "displays.h" #include "gpsrecord.h" +#include "variant.h" + +// Connects both UARTs together to directly talkt to the GPS with the USB interface +// If set, also disable serial logging (DCORE_DEBUG_LEVEL=0 in platformio.ini) +//#define GPS_TRANSPARENT_UART class DisplayDevice; @@ -185,6 +190,7 @@ class Gps { // UBX, special 0xf1 }; +#ifdef UBX_M10 // Key-ID pairs are only available in M10, they are used for the configuration enum class UBX_CFG_KEY_ID { CFG_UART1_BAUDRATE = 0x40520001, // Type: U4 @@ -197,7 +203,10 @@ class Gps { CFG_MSGOUT_UBX_NAV_DOP_UART1 = 0x20910039, // Type: U1, Output rate of the UBX-NAV-DOP message on port UART1 CFG_MSGOUT_UBX_NAV_VELNED_UART1 = 0x20910043, // Type: U1, Output rate of the UBX-NAV-VELNED message on port UART1 CFG_MSGOUT_UBX_NAV_PVT_UART1 = 0x20910007, // Type: U1, Output rate of the UBX-NAV-PVT message on port UART1 + CFG_SIGNAL_GLO_ENA = 0x10310025, // Type: L, GLONASS enable + CFG_NAVSPG_DYNMODEL = 0x20110021, // Type: E1, Dynamic platform model, 0=portable, 2=stationary, 3=pedestrian, 4=automotive, 5=sea, 6..8=airborne, ... }; +#endif // CFG Layers are only available in M10, they are used for selecting wehere to store a configuration enum UBX_CFG_LAYER : uint8_t { RAM = 1, @@ -568,10 +577,14 @@ class Gps { void sendUbx(uint16_t ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0); void sendUbx(UBX_MSG ubxMsgId, const uint8_t *payload = {}, uint16_t length = 0); +#ifdef UBX_M10 void sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value); // Only available in M10 +#endif bool sendAndWaitForAck(UBX_MSG ubxMsgId, const uint8_t *buffer = {}, size_t size = 0, const uint16_t timeoutMs = 200); - bool sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs = 200); +#ifdef UBX_M10 + bool sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs = 200); // Only available in M10 +#endif void parseUbxMessage(); diff --git a/src/pgaSensor.cpp b/src/pgaSensor.cpp index b5f9c52a..81bce5f1 100644 --- a/src/pgaSensor.cpp +++ b/src/pgaSensor.cpp @@ -25,6 +25,29 @@ void PGASensorManager::registerSensor(const PGASensorInfo &sensorInfo, uint8_t s sensorValues[sensorId] = MAX_SENSOR_VALUE; m_sensors[sensorId].median = new Median(5, MAX_SENSOR_VALUE); setupSensor(sensorId); + + // DEBUG: Dump complete config register map + /*Serial.printf("Register dump for sensor %d\n", sensorId); + uint8_t dump_regs[] = {0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F}; + for(int i = 0; i < sizeof(dump_regs); i++) + Serial.printf("Reg 0x%02x: 0x%02x\n", dump_regs[i], spiRegRead(sensorId, dump_regs[i]));*/ + + // DEBUG: Stress test writing/reading user register + /*uint8_t test = 0; + uint32_t count = 0; + log_e("Starting pga stress test"); + while(1) + { + spiRegWrite(sensorId, PGA_REG_USER_DATA1, test); + uint8_t readback = spiRegRead(sensorId, PGA_REG_USER_DATA1); + if(test != readback) + { + log_e("Failed on %d after %d tests", test, count); + count = 0; + } + count++; + test++; + }*/ } // Guess: Returns true if both sensor results are available @@ -110,6 +133,9 @@ void PGASensorManager::setupSensor(int sensorId) pinMode(sensorInfo.mosi_pin, OUTPUT); pinMode(sensorInfo.miso_pin, INPUT); + // Wait at least 15 ms to sync the synchronous UART + safe_usleep(20000); + // Check communication // Rerad the DEV_STAT0 register, where the upper nibble should be 0x4 // These are the values for REV_ID (0x2) and OPT_ID (0x0) @@ -134,20 +160,21 @@ void PGASensorManager::setupSensor(int sensorId) // th_t = np.array([2000, 5200, 2400, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000]) // th_l = np.array([200, 80, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24]) PGAThresholds thresholds( - TH_TIME_DELTA_2000US, 200/8, - TH_TIME_DELTA_5200US, 80/8, - TH_TIME_DELTA_2400US, 16/8, - TH_TIME_DELTA_8000US, 16/8, - TH_TIME_DELTA_8000US, 16/8, - TH_TIME_DELTA_8000US, 24/8, + TH_TIME_DELTA_2000US, 255/8, + TH_TIME_DELTA_4000US, 80/8, + TH_TIME_DELTA_2400US, 24/8, TH_TIME_DELTA_8000US, 24/8, TH_TIME_DELTA_8000US, 24/8, - TH_TIME_DELTA_8000US, 24, - TH_TIME_DELTA_8000US, 24, - TH_TIME_DELTA_8000US, 24, - TH_TIME_DELTA_8000US, 24 + TH_TIME_DELTA_8000US, 32/8, + TH_TIME_DELTA_8000US, 32/8, + TH_TIME_DELTA_8000US, 32/8, + TH_TIME_DELTA_8000US, 32, + TH_TIME_DELTA_8000US, 32, + TH_TIME_DELTA_8000US, 32, + TH_TIME_DELTA_8000US, 32 ); spiRegWriteThesholds(sensorId, 1, thresholds); + spiRegWriteThesholds(sensorId, 2, thresholds); spiRegWrite(sensorId, PGA_REG_DEV_STAT1, 0x00); // Clear stat1 register safe_usleep(1000); // Wait a bit @@ -171,14 +198,15 @@ uint8_t PGASensorManager::spiTransfer(uint8_t sensorId, uint8_t data_out) uint8_t data_in = 0; for(uint8_t i = 0; i < 8; i++) { - digitalWrite(sensorInfo.sck_pin, HIGH); + // It seems that the datasheet is wrong about the SPI mode... + // It says: ... with data set on the rising edge of the clock and sampled on the falling edge of the clock + // But we have to set the data before the rising edge. digitalWrite(sensorInfo.mosi_pin, data_out&0x01); data_out >>= 1; - safe_usleep(2); - digitalWrite(sensorInfo.sck_pin, LOW); + digitalWrite(sensorInfo.sck_pin, HIGH); data_in >>= 1; data_in |= digitalRead(sensorInfo.miso_pin)<<7; - safe_usleep(2); + digitalWrite(sensorInfo.sck_pin, LOW); } return data_in; } @@ -242,6 +270,7 @@ void PGASensorManager::spiRegWrite(uint8_t sensorId, uint8_t reg_addr, uint8_t v void PGASensorManager::spiRegWriteThesholds(uint8_t sensorId, uint8_t preset, PGAThresholds &thresholds) { assert(sensorId >= 0 && sensorId <= 1); + assert(preset >= 1 && preset <= 2); uint8_t regOffset = preset == 1 ? 0 : PGA_REG_P2_THR_0 - PGA_REG_P1_THR_0; spiRegWrite(sensorId, PGA_REG_P1_THR_0 + regOffset, thresholds.t1<<4 | thresholds.t2); @@ -276,7 +305,7 @@ void PGASensorManager::spiBurstAndListen(uint8_t sensorId, uint8_t preset, uint8 checksum_clear(); spiTransfer(sensorId, 0x55); // Sync byte - uint8_t cmd = 0<<5 | preset == 1 ? PGA_CMD_BURST_AND_LISTEN_1 : PGA_CMD_BURST_AND_LISTEN_2; + uint8_t cmd = 0<<5 | (preset == 1 ? PGA_CMD_BURST_AND_LISTEN_1 : PGA_CMD_BURST_AND_LISTEN_2); spiTransfer(sensorId, cmd); // Command checksum_append_byte(cmd); spiTransfer(sensorId, numberOfObjectsToDetect); diff --git a/src/pgaSensor.h b/src/pgaSensor.h index 954832ac..09ff14f2 100644 --- a/src/pgaSensor.h +++ b/src/pgaSensor.h @@ -139,7 +139,7 @@ #define PGA_DIAG_BUSY_MASK 0x01 #define PGA_DUMP_ENABLE 0 // Prints raw data of the measurements, for debugging or calibration of a new transducer -#define PGA_DUMP_TIME 500 +#define PGA_DUMP_TIME 500 // Period for dumping a complete raw data measurement (RX amplitude over time) struct PGASensorInfo diff --git a/src/writer.cpp b/src/writer.cpp index 8c1a9a38..dc51cc1e 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -107,12 +107,13 @@ bool FileWriter::flush() { log_v("Writing to concrete file."); const auto start = millis(); result = FileUtil::appendFile(SD, mFileName.c_str(), mBuffer.c_str() ); + const unsigned int fileAppendSize = mBuffer.length(); mBuffer.clear(); mWriteTimeMillis = millis() - start; if (!mFinalFileName) { correctFilename(); } - log_v("Writing to concrete file done took %lums.", mWriteTimeMillis); + log_e("Writing %u bytes to concrete file done took %lums.", fileAppendSize, mWriteTimeMillis); return result; } @@ -124,6 +125,14 @@ bool CSVFileWriter::writeHeader(String trackId) { String header; header += "OBSDataFormat=2&"; header += "OBSFirmwareVersion=" + String(OBSVersion) + "&"; +#ifdef OBSPRO + header += "HardwareType=OBSPro&"; + header += "HardwareRev=v2.1&"; // TODO: Use hardware revision detection +#endif +#ifdef OBSCLASSIC + header += "HardwareType=OBSClassic&"; + //header += "HardwareRev=?" // TODO: Auto detect hardware revision not available in OBSClassic +#endif header += "DeviceId=" + String((uint16_t)(ESP.getEfuseMac() >> 32), 16) + "&"; header += "DataPerMeasurement=3&"; header += "MaximumMeasurementsPerLine=" + String(MAX_NUMBER_MEASUREMENTS_PER_INTERVAL) + "&"; From c3cf661de452a855c3b10f6d8a18b4783e22c87d Mon Sep 17 00:00:00 2001 From: amandel Date: Wed, 22 May 2024 12:52:56 +0200 Subject: [PATCH 26/34] Move selection of OBS Variant to ini file --- custom_config.ini.example | 3 +++ platformio.ini | 3 +++ src/variant.h | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/custom_config.ini.example b/custom_config.ini.example index 074f99f0..8591e399 100644 --- a/custom_config.ini.example +++ b/custom_config.ini.example @@ -18,6 +18,9 @@ build_flags = -DDEVELOP ; http lib loglevel -DHTTPS_LOGLEVEL=3 +; select OBS Variant + -DOBSCLASSIC +; -DOBSPRO ; === upload_port === diff --git a/platformio.ini b/platformio.ini index a8e1dacf..c6af935d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -69,3 +69,6 @@ build_flags = -DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024 ; build number "-dev" will be replaced in github action -DBUILD_NUMBER=\"-dev\" + ; Select variant here + -DOBSPRO +; -DOBSCLASSIC diff --git a/src/variant.h b/src/variant.h index 75c8ae67..7dbad516 100644 --- a/src/variant.h +++ b/src/variant.h @@ -24,13 +24,15 @@ #ifndef VARIANT_H #define VARIANT_H + +// Use custom_config.ini to set the needed variant! // If set, the firmware is build for the OBSPro hardware variant // The main differences are: // - The button is inverted // - The button is also responsible for soft-power-off // - The display is a JHD12864-G156BT which is SPI based // - The ultrasonic sensors are PGA460 based -#define OBSPRO +//#define OBSPRO // If set, the firmware is build for the OBSClassic //#define OBSCLASSIC From e9eab2a77a5c02f352e5eb1ee10fd1419c8bfa65 Mon Sep 17 00:00:00 2001 From: amandel Date: Wed, 22 May 2024 15:34:53 +0200 Subject: [PATCH 27/34] Make sure code compiles for `OBSCLASSIC` --- src/OpenBikeSensorFirmware.cpp | 3 ++- src/gps.cpp | 5 +++++ src/variant.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index a945a2c2..4f42773a 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -221,11 +221,12 @@ static void buttonBluetooth(const DataSet *dataSet, uint16_t measureIndex) { } } +static uint8_t shutdownState = 0; + #ifdef OBSPRO // Power-management keep alive timer // This function is called every 100 ms static unsigned long timeOfLastPowerKeepAlive = 0; -static uint8_t shutdownState = 0; static uint8_t buttonPressedCounter = 0; static void powerKeepAliveTimerISR() { diff --git a/src/gps.cpp b/src/gps.cpp index 94afff3a..a1afda0a 100644 --- a/src/gps.cpp +++ b/src/gps.cpp @@ -101,6 +101,7 @@ void Gps::sendUbx(uint16_t ubxMsgId, const uint8_t payload[], uint16_t length) { mSerial.write(buffer, length + 8); } +#ifdef UBX_M10 // Send a CFG_VALSET ubx command to write a configuration // Only available in M10 devices void Gps::sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value) @@ -118,6 +119,7 @@ void Gps::sendUbxCfg(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t va length = 4; sendUbx(UBX_MSG::CFG_VALSET, ubxCfgMsg, length + 8); } +#endif /* Method sends the message in the receive buffer! */ void Gps::sendUbxDirect() { @@ -501,6 +503,7 @@ bool Gps::sendAndWaitForAck(UBX_MSG ubxMsgId, const uint8_t *buffer, size_t size return result; } +#ifdef UBX_M10 bool Gps::sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, uint32_t value, const uint16_t timeoutMs) { const int tries = 2; auto start = millis(); @@ -534,6 +537,8 @@ bool Gps::sendCfgAndWaitForAck(enum UBX_CFG_LAYER layer, UBX_CFG_KEY_ID keyId, u } return result; } +#endif + /* Will delay for the given number of ms and handle GPS if needed. */ void Gps::handle(uint32_t milliSeconds) { diff --git a/src/variant.h b/src/variant.h index 7dbad516..7ee270ca 100644 --- a/src/variant.h +++ b/src/variant.h @@ -57,7 +57,7 @@ // Settings specific to OBSClassic #if OBSCLASSIC -#define UBS_M6 +#define UBX_M6 #endif From e96626508fc23961453b6a7b145b65aa625f66c1 Mon Sep 17 00:00:00 2001 From: amandel Date: Sat, 17 Aug 2024 12:44:02 +0200 Subject: [PATCH 28/34] CI build for classic and pro variant --- .github/workflows/ci.yml | 157 +++++++++++++++++++++++++++++++++----- custom_config.ini.example | 9 +-- platformio.ini | 13 +++- 3 files changed, 150 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8aa51ba..1222c8c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,11 +97,13 @@ jobs: run: | mkdir sonarqube-out ./sonarqube/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir sonarqube-out \ - platformio ci --build-dir="./bin" --keep-build-dir --project-conf=platformio.ini ./src/ + platformio ci --environment obspro --environment obs --build-dir ./bin --keep-build-dir --project-conf platformio.ini ./src/ - - name: Package firmware + - name: Package firmware OBS classic run: | set -eux + mkdir -p obs-classic + cd obs-classic if [ -f "/github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.elf" ]; then cp /github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.elf 0x01000.elf elif [ -f "/github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin" ]; then @@ -112,10 +114,10 @@ jobs: find /github/home/.platformio/ -name "bootloader*.elf" exit 1 fi - cp bin/.pio/build/esp32dev/partitions.bin 0x08000.bin + cp ../bin/.pio/build/obs/partitions.bin 0x08000.bin cp /github/home/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x0e000.bin - cp bin/.pio/build/esp32dev/firmware.bin 0x10000.bin - cp bin/.pio/build/esp32dev/firmware.bin firmware.bin + cp ../bin/.pio/build/obs/firmware.bin 0x10000.bin + cp ../bin/.pio/build/obs/firmware.bin firmware.bin ESPTOOL=/github/home/.platformio/packages/tool-esptoolpy/esptool.py chmod +x ${ESPTOOL} # CMD to create a merged binary (still missing flash.app) @@ -138,16 +140,73 @@ jobs: 0x01000 0x01000.bin.org echo OpenBikeSensor bootloader params ${ESPTOOL} --chip esp32 image_info --version 2 0x01000.bin || echo image_info failed - cp src/fonts/LICENSE.txt LICENSE-OpenSans.txt + cp ../src/fonts/LICENSE.txt LICENSE-OpenSans.txt wget --no-verbose -O COPYRIGHT-ESP.html https://docs.espressif.com/projects/esp-idf/en/latest/esp32/COPYRIGHT.html wget --no-verbose -O LICENSE-ARDUINO-ESP32.md https://github.com/espressif/arduino-esp32/raw/master/LICENSE.md - zip --junk-paths obs-${{ env.OBS_VERSION }}-initial-flash.zip \ + zip --junk-paths ../obs-${{ env.OBS_VERSION }}-initial-flash.zip \ 0x*.bin \ COPYRIGHT-ESP.html \ LICENSE-ARDUINO-ESP32.md \ LICENSE-OpenSans.txt \ LICENSE - zip --junk-paths obs-${{ env.OBS_VERSION }}.zip \ + zip --junk-paths ../obs-${{ env.OBS_VERSION }}.zip \ + firmware.bin \ + COPYRIGHT-ESP.html \ + LICENSE-ARDUINO-ESP32.md \ + LICENSE-OpenSans.txt \ + LICENSE + + - name: Package firmware OBS pro + run: | + set -eux + mkdir -p obs-pro + cd obs-pro + if [ -f "/github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.elf" ]; then + cp /github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.elf 0x01000.elf + elif [ -f "/github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin" ]; then + cp /github/home/.platformio/packages/framework-arduinoespressif32/tools/sdk/bin/bootloader_dio_40m.bin 0x01000.bin + else + echo could not find bootloader_dio_40m.bin, new location? + find /github/home/.platformio/ -name "bootloader*.bin" + find /github/home/.platformio/ -name "bootloader*.elf" + exit 1 + fi + cp ../bin/.pio/build/obspro/partitions.bin 0x08000.bin + cp /github/home/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x0e000.bin + cp ../bin/.pio/build/obspro/firmware.bin 0x10000.bin + cp ../bin/.pio/build/obspro/firmware.bin firmware.bin + ESPTOOL=/github/home/.platformio/packages/tool-esptoolpy/esptool.py + chmod +x ${ESPTOOL} + # CMD to create a merged binary (still missing flash.app) + # ${ESPTOOL} --trace --chip esp32 merge_bin --output merged.bin \ + # --flash_freq keep --flash_mode dio --flash_size 4MB \ + # 0x01000 0x01000.bin \ + # 0x08000 0x08000.bin \ + # 0x0e000 0x0e000.bin \ + # 0x10000 0x10000.bin + ${ESPTOOL} --trace --chip esp32 elf2image \ + --dont-append-digest \ + --flash_freq 40m --flash_mode dio \ + 0x01000.elf + echo Original bootloader params after elf2image + ${ESPTOOL} --chip esp32 image_info --version 2 0x01000.bin || echo image_info for converted bootloader failed + mv 0x01000.bin 0x01000.bin.org + ${ESPTOOL} --trace --chip esp32 merge_bin --output 0x01000.bin \ + --flash_freq 40m --flash_mode dio --flash_size 4MB \ + --target-offset 0x01000 \ + 0x01000 0x01000.bin.org + echo OpenBikeSensor bootloader params + ${ESPTOOL} --chip esp32 image_info --version 2 0x01000.bin || echo image_info failed + cp ../src/fonts/LICENSE.txt LICENSE-OpenSans.txt + wget --no-verbose -O COPYRIGHT-ESP.html https://docs.espressif.com/projects/esp-idf/en/latest/esp32/COPYRIGHT.html + wget --no-verbose -O LICENSE-ARDUINO-ESP32.md https://github.com/espressif/arduino-esp32/raw/master/LICENSE.md + zip --junk-paths ../obspro-${{ env.OBS_VERSION }}-initial-flash.zip \ + 0x*.bin \ + COPYRIGHT-ESP.html \ + LICENSE-ARDUINO-ESP32.md \ + LICENSE-OpenSans.txt \ + LICENSE + zip --junk-paths ../obspro-${{ env.OBS_VERSION }}.zip \ firmware.bin \ COPYRIGHT-ESP.html \ LICENSE-ARDUINO-ESP32.md \ @@ -186,11 +245,11 @@ jobs: with: name: obs-${{ env.OBS_VERSION }} path: | - firmware.bin - COPYRIGHT-ESP.html - LICENSE-ARDUINO-ESP32.md - LICENSE-OpenSans.txt - LICENSE + obs-classic/firmware.bin + obs-classic/COPYRIGHT-ESP.html + obs-classic/LICENSE-ARDUINO-ESP32.md + obs-classic/LICENSE-OpenSans.txt + obs-classic/LICENSE if-no-files-found: error - name: Upload Build Asset Initial Flash @@ -198,14 +257,38 @@ jobs: with: name: obs-${{ env.OBS_VERSION }}-initial-flash path: | - 0x*.bin - COPYRIGHT-ESP.html - LICENSE-ARDUINO-ESP32.md - LICENSE-OpenSans.txt - LICENSE + obs-classic/0x*.bin + obs-classic/COPYRIGHT-ESP.html + obs-classic/LICENSE-ARDUINO-ESP32.md + obs-classic/LICENSE-OpenSans.txt + obs-classic/LICENSE sonarqube-out/build-wrapper-dump.json if-no-files-found: error + - name: Upload Build Asset obspro + uses: actions/upload-artifact@v4 + with: + name: obspro-${{ env.OBS_VERSION }} + path: | + obs-pro/firmware.bin + obs-pro/COPYRIGHT-ESP.html + obs-pro/LICENSE-ARDUINO-ESP32.md + obs-pro/LICENSE-OpenSans.txt + obs-pro/LICENSE + if-no-files-found: error + + - name: Upload Build Asset Initial Flash obspro + uses: actions/upload-artifact@v4 + with: + name: obspro-${{ env.OBS_VERSION }}-initial-flash + path: | + obs-pro/0x*.bin + obs-pro/COPYRIGHT-ESP.html + obs-pro/LICENSE-ARDUINO-ESP32.md + obs-pro/LICENSE-OpenSans.txt + obs-pro/LICENSE + if-no-files-found: error + - name: Generate changelog id: changelog if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} @@ -275,6 +358,42 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/.pio/build/esp32dev/firmware.bin + asset_path: ./bin/.pio/build/obs/firmware.bin asset_name: firmware.bin asset_content_type: application/x-esp32 + + - name: Upload Release Asset obspro + id: upload-release-asset + if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./obspro-${{ env.OBS_VERSION }}.zip + asset_name: obspro-${{ env.OBS_VERSION }}.zip + asset_content_type: application/zip + + - name: Upload Release Asset Initial Flash pro + id: upload-release-asset-initial-flash + if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./obspro-${{ env.OBS_VERSION }}-initial-flash.zip + asset_name: obspro-${{ env.OBS_VERSION }}-initial-flash.zip + asset_content_type: application/zip + + - name: Upload Release Asset app bin pro + id: upload-release-asset-app-bin + if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/.pio/build/obspro/firmware.bin + asset_name: obspro-firmware.bin + asset_content_type: application/x-esp32 diff --git a/custom_config.ini.example b/custom_config.ini.example index 8591e399..51eb805a 100644 --- a/custom_config.ini.example +++ b/custom_config.ini.example @@ -1,13 +1,8 @@ ; This file should contain your local modifications to the PlatformIO.ini file. -[env:esp32dev] +[env:myObs] build_flags = -; settings needed by the build - -DHTTPS_REQUEST_MAX_REQUEST_LENGTH=1024 -; reduce probability of https://github.com/fhessel/esp32_https_server/pull/123 - -DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024 -; custom default configuration -; + ${env.build_flags} ; you can specify a custom config json (see docs/software/firmware/obs_cfg.md) ; here which will be used for fresh installs based on this firmware -DCUSTOM_OBS_DEFAULT_CONFIG='"{ obs: [ { displayConfig: 15, offset: [ 30, 30 ], httpPin: \\"12345678\\", wifiSsid: \\"SID\\", wifiPassword: \\"87654321\\" } ] }"' diff --git a/platformio.ini b/platformio.ini index c6af935d..c6d9d84f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -37,7 +37,7 @@ src_dir = src extra_configs = custom_config.ini -[env:esp32dev] +[env] platform = espressif32 @ 6.6.0 ; 5.4.0 board = esp32dev @@ -69,6 +69,13 @@ build_flags = -DHTTPS_CONNECTION_DATA_CHUNK_SIZE=1024 ; build number "-dev" will be replaced in github action -DBUILD_NUMBER=\"-dev\" - ; Select variant here + +[env:obs] +build_flags = + ${env.build_flags} + -DOBSCLASSIC + +[env:obspro] +build_flags = + ${env.build_flags} -DOBSPRO -; -DOBSCLASSIC From 85466de828255b2b21f24ce71b898f1fa25a4f69 Mon Sep 17 00:00:00 2001 From: amandel Date: Sat, 17 Aug 2024 12:54:52 +0200 Subject: [PATCH 29/34] Make ids unique again --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1222c8c0..c3456e34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -363,7 +363,7 @@ jobs: asset_content_type: application/x-esp32 - name: Upload Release Asset obspro - id: upload-release-asset + id: upload-obspro-release-asset if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} uses: actions/upload-release-asset@v1 env: @@ -375,7 +375,7 @@ jobs: asset_content_type: application/zip - name: Upload Release Asset Initial Flash pro - id: upload-release-asset-initial-flash + id: upload-obspro-release-asset-initial-flash if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} uses: actions/upload-release-asset@v1 env: @@ -387,7 +387,7 @@ jobs: asset_content_type: application/zip - name: Upload Release Asset app bin pro - id: upload-release-asset-app-bin + id: upload-obspro-release-asset-app-bin if: ${{ env.OBS_PREPARE_RELEASE == 'true' }} uses: actions/upload-release-asset@v1 env: From 69bf0b1bcfd85d041207cf3385ebac2590fae2c7 Mon Sep 17 00:00:00 2001 From: amandel Date: Sat, 17 Aug 2024 13:05:24 +0200 Subject: [PATCH 30/34] No SQ for now --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3456e34..30f00fda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -214,6 +214,7 @@ jobs: LICENSE - name: Analyze with SonarCloud + if: false env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ee7119f27a7fd97229a643296f61b199c7978cdb Mon Sep 17 00:00:00 2001 From: amandel Date: Sat, 17 Aug 2024 14:03:03 +0200 Subject: [PATCH 31/34] Next release is 0.21 which includes obs classic and obs pro --- src/OpenBikeSensorFirmware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenBikeSensorFirmware.cpp b/src/OpenBikeSensorFirmware.cpp index 4f42773a..9a213ac6 100644 --- a/src/OpenBikeSensorFirmware.cpp +++ b/src/OpenBikeSensorFirmware.cpp @@ -37,7 +37,7 @@ // --- Global variables --- // Version only change the "vN.M" part if needed. -const char *OBSVersion = "v0.20" BUILD_NUMBER; +const char *OBSVersion = "v0.21" BUILD_NUMBER; const uint8_t LEFT_SENSOR_ID = 1; const uint8_t RIGHT_SENSOR_ID = 0; From 01ec00e397e226c24b09550b8a402894272d55ff Mon Sep 17 00:00:00 2001 From: amandel Date: Sat, 17 Aug 2024 14:43:27 +0200 Subject: [PATCH 32/34] untested - specific firmware update path --- .github/workflows/ci.yml | 2 +- src/configServer.cpp | 114 ++++++++++++++++++++------------------- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30f00fda..224d8dcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -396,5 +396,5 @@ jobs: with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./bin/.pio/build/obspro/firmware.bin - asset_name: obspro-firmware.bin + asset_name: firmware-obspro.bin asset_content_type: application/x-esp32 diff --git a/src/configServer.cpp b/src/configServer.cpp index 7a67810a..6edc0727 100644 --- a/src/configServer.cpp +++ b/src/configServer.cpp @@ -245,60 +245,66 @@ static const char* const backupIndex = "" "

Restore

"; -static const char* const updateSdIndex = R""""( -

{description}

-

From Github (preferred)

-List also pre-releases
-Ignore TLS Errors (see documentation)
- - - - -If the upgrade via the button above does not work
download firmware.bin
and upload manually below. -

File Upload

-)""""; +static const char* const updateSdIndex = + "

{description}

\n" + "

From Github (preferred)

\n" + "List also pre-releases
\n" + "Ignore TLS Errors (see documentation)
\n" + "\n" + "\n" + "\n" + "\n" + "If the upgrade via the button above does not work
download firmware.bin
and upload manually below.\n" + "

File Upload

"; // ######################################### // Config From 23a2de598f130f938d3ce7f8382bd932bb1b003d Mon Sep 17 00:00:00 2001 From: amandel Date: Sun, 18 Aug 2024 13:32:58 +0200 Subject: [PATCH 33/34] fix - specific firmware update path --- src/configServer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/configServer.cpp b/src/configServer.cpp index 6edc0727..e0227154 100644 --- a/src/configServer.cpp +++ b/src/configServer.cpp @@ -271,7 +271,6 @@ static const char* const updateSdIndex = " || asset.name.endsWith(\"firmware-obspro.bin\") " #endif " ).forEach(\n" - " release.assets.filter(asset => asset.name.endsWith(\"flash.bin\") asset.name.endsWith(\"firmware.bin\")).forEach(\n" " asset => {\n" " if (!url) {\n" " version = release.name;\n" From aa4699c6d8b3f59e536ddeface304cf537dad82a Mon Sep 17 00:00:00 2001 From: amandel Date: Sun, 18 Aug 2024 13:33:58 +0200 Subject: [PATCH 34/34] update espressif32 lib --- platformio.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index c6d9d84f..ed32000c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,8 +38,7 @@ src_dir = src extra_configs = custom_config.ini [env] -platform = espressif32 @ 6.6.0 -; 5.4.0 +platform = espressif32 @ 6.8.1 board = esp32dev framework = arduino monitor_speed = 115200