Added touch screen features, calibration and a few more screens

This commit is contained in:
Daniel Eichhorn
2017-07-09 18:21:47 +02:00
parent 3f51a3d6ff
commit 836109eecc
5 changed files with 538 additions and 34 deletions

106
TouchController.cpp Normal file
View File

@@ -0,0 +1,106 @@
#include "TouchController.h"
TouchController::TouchController(XPT2046_Touchscreen *touchScreen) {
this->touchScreen = touchScreen;
}
bool TouchController::loadCalibration() {
// always use this to "mount" the filesystem
bool result = SPIFFS.begin();
Serial.println("SPIFFS opened: " + result);
// this opens the file "f.txt" in read-mode
File f = SPIFFS.open("/calibration.txt", "r");
if (!f) {
return false;
} else {
//Lets read line by line from the file
String dxStr = f.readStringUntil('\n');
String dyStr = f.readStringUntil('\n');
String axStr = f.readStringUntil('\n');
String ayStr = f.readStringUntil('\n');
dx = dxStr.toFloat();
dy = dyStr.toFloat();
ax = axStr.toInt();
ay = ayStr.toInt();
}
f.close();
}
bool TouchController::saveCalibration() {
bool result = SPIFFS.begin();
// open the file in write mode
File f = SPIFFS.open("/calibration.txt", "w");
if (!f) {
Serial.println("file creation failed");
}
// now write two lines in key/value style with end-of-line characters
f.println(dx);
f.println(dy);
f.println(ax);
f.println(ay);
f.close();
}
void TouchController::startCalibration(CalibrationCallback *calibrationCallback) {
state = 0;
this->calibrationCallback = calibrationCallback;
}
void TouchController::continueCalibration() {
TS_Point p = touchScreen->getPoint();
if (state == 0) {
(*calibrationCallback)(10, 10);
if (touchScreen->touched()) {
p1 = p;
state++;
lastStateChange = millis();
}
} else if (state == 1) {
(*calibrationCallback)(230, 310);
if (touchScreen->touched() && (millis() - lastStateChange > 1000)) {
p2 = p;
state++;
lastStateChange = millis();
dx = 240.0 / abs(p1.y - p2.y);
dy = 320.0 / abs(p1.x - p2.x);
ax = p1.y < p2.y ? p1.y : p2.y;
ay = p1.x < p2.x ? p1.x : p2.x;
}
}
}
bool TouchController::isCalibrationFinished() {
return state == 2;
}
bool TouchController::isTouched() {
touchScreen->touched();
}
bool TouchController::isTouched(int16_t debounceMillis) {
if (touchScreen->touched() && millis() - lastTouched > debounceMillis) {
lastTouched = millis();
return true;
}
return false;
}
TS_Point TouchController::getPoint() {
TS_Point p = touchScreen->getPoint();
int x = (p.y - ax) * dx;
int y = 320 - (p.x - ay) * dy;
p.x = x;
p.y = y;
return p;
}

36
TouchController.h Normal file
View File

@@ -0,0 +1,36 @@
#include <FS.h>
#include <XPT2046_Touchscreen.h>
#ifndef _TOUCH_CONTROLLERH_
#define _TOUCH_CONTROLLERH_
typedef void (*CalibrationCallback)(int16_t x, int16_t y);
class TouchController {
public:
TouchController(XPT2046_Touchscreen *touchScreen);
bool loadCalibration();
bool saveCalibration();
void startCalibration(CalibrationCallback *callback);
void continueCalibration();
bool isCalibrationFinished();
bool isTouched();
bool isTouched(int16_t debounceMillis);
TS_Point getPoint();
private:
XPT2046_Touchscreen *touchScreen;
float dx = 0.0;
float dy = 0.0;
int ax = 0;
int ay = 0;
int state = 0;
long lastStateChange = 0;
long lastTouched = 0;
CalibrationCallback *calibrationCallback;
TS_Point p1, p2;
};
#endif

View File

@@ -21,6 +21,8 @@ See more at https://blog.squix.org
#include <Arduino.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <XPT2046_Touchscreen.h>
#include "TouchController.h"
/***
* Install the following libraries through Arduino Library Manager
@@ -34,6 +36,7 @@ See more at https://blog.squix.org
#include <WundergroundConditions.h>
#include <WundergroundForecast.h>
#include <WundergroundAstronomy.h>
#include <WundergroundAlerts.h>
#include <MiniGrafx.h>
#include <Carousel.h>
#include <ILI9341_SPI.h>
@@ -54,6 +57,7 @@ See more at https://blog.squix.org
#define MINI_BLUE 3
#define MAX_FORECASTS 12
#define MAX_ALERTS 1
// defines the colors usable in the paletted 16 color frame buffer
uint16_t palette[] = {ILI9341_BLACK, // 0
@@ -66,6 +70,8 @@ int SCREEN_HEIGHT = 320;
// Limited to 4 colors due to memory constraints
int BITS_PER_PIXEL = 2; // 2^2 = 4 colors
ADC_MODE(ADC_VCC);
// HOSTNAME for OTA update
#define HOSTNAME "ESP8266-OTA-"
@@ -74,9 +80,13 @@ ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC);
MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette);
Carousel carousel(&gfx, 0, 0, 240, 100);
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);
TouchController touchController(&ts);
WGConditions conditions;
WGForecast forecasts[MAX_FORECASTS];
WGAstronomy astronomy;
WGAlert alerts[MAX_ALERTS];
// Setup simpleDSTadjust Library rules
simpleDSTadjust dstAdjusted(StartRule, EndRule);
@@ -88,18 +98,27 @@ void drawCurrentWeather();
void drawForecast();
void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex);
void drawAstronomy();
void drawAlert();
void drawCurrentWeatherDetail();
void drawLabelValue(uint8_t line, String label, String value);
void drawForecastTable(uint8_t start);
void drawAbout();
void drawSeparator(uint16_t y);
const char* getMeteoconIconFromProgmem(String iconText);
const char* getMiniMeteoconIconFromProgmem(String iconText);
void drawForecast1(MiniGrafx *display, CarouselState* state, int16_t x, int16_t y);
void drawForecast2(MiniGrafx *display, CarouselState* state, int16_t x, int16_t y);
FrameCallback frames[] = { drawForecast1, drawForecast2 };
void calibrationCallback(int16_t x, int16_t y);
CalibrationCallback calibration = &calibrationCallback;
int frameCount = 2;
// how many different screens do we have?
int screenCount = 5;
long lastDownloadUpdate = millis();
void updateCalendar();
String moonAgeImage = "";
uint16_t screen = 0;
void setup() {
Serial.begin(115200);
@@ -111,6 +130,29 @@ void setup() {
digitalWrite(TFT_LED, HIGH);
gfx.init();
gfx.fillBuffer(MINI_BLACK);
gfx.commit();
ts.begin();
SPIFFS.begin();
//SPIFFS.remove("/calibration.txt");
boolean isCalibrationAvailable = touchController.loadCalibration();
if (!isCalibrationAvailable) {
Serial.println("Calibration not available");
touchController.startCalibration(&calibration);
while (!touchController.isCalibrationFinished()) {
gfx.fillBuffer(0);
gfx.setColor(MINI_YELLOW);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.drawString(120, 160, "Please calibrate\ntouch screen by\ntouch point");
touchController.continueCalibration();
gfx.commit();
yield();
}
touchController.saveCalibration();
}
gfx.fillBuffer(MINI_BLACK);
gfx.setFont(ArialRoundedMTBold_14);
gfx.setColor(MINI_YELLOW);
@@ -135,21 +177,41 @@ void setup() {
long lastDrew = 0;
void loop() {
gfx.fillBuffer(MINI_BLACK);
drawTime();
drawCurrentWeather();
int remainingTimeBudget = carousel.update();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
delay(remainingTimeBudget);
if (touchController.isTouched(500)) {
TS_Point p = touchController.getPoint();
if (p.y < 80) {
IS_STYLE_12HR = !IS_STYLE_12HR;
} else {
screen = (screen + 1) % screenCount;
}
}
gfx.fillBuffer(MINI_BLACK);
if (screen == 0) {
drawTime();
int remainingTimeBudget = carousel.update();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
delay(remainingTimeBudget);
}
drawCurrentWeather();
drawAstronomy();
} else if (screen == 1) {
drawCurrentWeatherDetail();
} else if (screen == 2) {
drawForecastTable(0);
} else if (screen == 3) {
drawForecastTable(6);
} else if (screen == 4) {
drawAbout();
}
drawAstronomy();
gfx.commit();
// Check if we should update weather information
if (millis() - lastDownloadUpdate > 1000 * UPDATE_INTERVAL_SECS) {
updateData();
@@ -177,22 +239,33 @@ void updateData() {
forecastClient->updateForecast(forecasts, MAX_FORECASTS, WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
delete forecastClient;
forecastClient = nullptr;
drawProgress(80, "Updating astronomy...");
WundergroundAstronomy *astronomyClient = new WundergroundAstronomy(STYLE_12HR);
WundergroundAstronomy *astronomyClient = new WundergroundAstronomy(IS_STYLE_12HR);
astronomyClient->updateAstronomy(&astronomy, WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
delete astronomyClient;
astronomyClient = nullptr;
moonAgeImage = String((char) (65 + 26 * (((15 + astronomy.moonAge.toInt()) % 30) / 30.0)));
drawProgress(90, "Updating alerts...");
WundergroundAlerts *alertClient = new WundergroundAlerts();
alertClient->updateAlerts(alerts, MAX_ALERTS, WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
delete alertClient;
alertClient = nullptr;
delay(1000);
}
// Progress bar helper
void drawProgress(uint8_t percentage, String text) {
gfx.fillBuffer(MINI_BLACK);
gfx.drawPalettedBitmapFromPgm(23, 30, SquixLogo);
gfx.setFont(ArialRoundedMTBold_14);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.drawString(120, 80, "https://blog.squix.org");
gfx.setColor(MINI_YELLOW);
gfx.drawString(120, 146, text);
@@ -207,15 +280,6 @@ void drawProgress(uint8_t percentage, String text) {
// draws the clock
void drawTime() {
/*gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.setFont(ArialRoundedMTBold_14);
String date = conditions.date;
gfx.drawString(120, 6, date);
gfx.setFont(ArialRoundedMTBold_36);
String time = timeClient.getHours() + ":" + timeClient.getMinutes() + ":" + timeClient.getSeconds();
gfx.drawString(120, 20, time);*/
char *dstAbbrev;
char time_str[11];
time_t now = dstAdjusted.time(&dstAbbrev);
@@ -223,13 +287,14 @@ void drawTime() {
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setFont(ArialRoundedMTBold_14);
gfx.setColor(MINI_WHITE);
String date = ctime(&now);
date = date.substring(0,11) + String(1900 + timeinfo->tm_year);
gfx.drawString(120, 6, date);
gfx.setFont(ArialRoundedMTBold_36);
if (STYLE_12HR) {
if (IS_STYLE_12HR) {
int hour = (timeinfo->tm_hour+11)%12+1; // take care of noon and midnight
sprintf(time_str, "%2d:%02d:%02d\n",hour, timeinfo->tm_min, timeinfo->tm_sec);
gfx.drawString(120, 20, time_str);
@@ -241,7 +306,7 @@ void drawTime() {
gfx.setTextAlignment(TEXT_ALIGN_LEFT);
gfx.setFont(ArialMT_Plain_10);
gfx.setColor(MINI_BLUE);
if (STYLE_12HR) {
if (IS_STYLE_12HR) {
sprintf(time_str, "%s\n%s", dstAbbrev, timeinfo->tm_hour>=12?"PM":"AM");
gfx.drawString(195, 27, time_str);
} else {
@@ -255,10 +320,11 @@ void drawCurrentWeather() {
gfx.setTransparentColor(MINI_BLACK);
gfx.drawPalettedBitmapFromPgm(0, 55, getMeteoconIconFromProgmem(conditions.weatherIcon));
// Weather Text
gfx.setFont(ArialRoundedMTBold_14);
gfx.setColor(MINI_YELLOW);
gfx.setColor(MINI_BLUE);
gfx.setTextAlignment(TEXT_ALIGN_RIGHT);
gfx.drawString(220, 76, conditions.weatherText);
gfx.drawString(220, 65, DISPLAYED_CITY_NAME);
gfx.setFont(ArialRoundedMTBold_36);
gfx.setColor(MINI_WHITE);
@@ -268,7 +334,12 @@ void drawCurrentWeather() {
degreeSign = "°C";
}
String temp = conditions.currentTemp + degreeSign;
gfx.drawString(220, 89, temp);
gfx.drawString(220, 78, temp);
gfx.setFont(ArialRoundedMTBold_14);
gfx.setColor(MINI_YELLOW);
gfx.setTextAlignment(TEXT_ALIGN_RIGHT);
gfx.drawString(220, 118, conditions.weatherText);
}
@@ -331,6 +402,121 @@ void drawAstronomy() {
}
void drawAlert() {
}
void drawCurrentWeatherDetail() {
gfx.setFont(ArialRoundedMTBold_14);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.drawString(120, 2, "Current Conditions");
//gfx.setTransparentColor(MINI_BLACK);
//gfx.drawPalettedBitmapFromPgm(0, 20, getMeteoconIconFromProgmem(conditions.weatherIcon));
String degreeSign = "°F";
if (IS_METRIC) {
degreeSign = "°C";
}
// String weatherIcon;
// String weatherText;
drawLabelValue(0, "Temperature:", conditions.currentTemp + degreeSign);
drawLabelValue(1, "Feels Like:", conditions.feelslike + degreeSign);
drawLabelValue(2, "Dew Point:", conditions.dewPoint + degreeSign);
drawLabelValue(3, "Wind Speed:", conditions.windSpeed);
drawLabelValue(4, "Wind Dir:", conditions.windDir);
drawLabelValue(5, "Humidity:", conditions.humidity);
drawLabelValue(6, "Pressure:", conditions.pressure);
drawLabelValue(7, "Precipitation:", conditions.precipitationToday);
drawLabelValue(8, "UV:", conditions.UV);
gfx.setTextAlignment(TEXT_ALIGN_LEFT);
gfx.setColor(MINI_YELLOW);
gfx.drawString(15, 185, "Description: ");
gfx.setColor(MINI_WHITE);
gfx.drawStringMaxWidth(15, 200, 240 - 2 * 15, forecasts[0].forecastText);
}
void drawLabelValue(uint8_t line, String label, String value) {
const uint8_t labelX = 15;
const uint8_t valueX = 150;
gfx.setTextAlignment(TEXT_ALIGN_LEFT);
gfx.setColor(MINI_YELLOW);
gfx.drawString(labelX, 30 + line * 15, label);
gfx.setColor(MINI_WHITE);
gfx.drawString(valueX, 30 + line * 15, value);
}
void drawForecastTable(uint8_t start) {
gfx.setFont(ArialRoundedMTBold_14);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.drawString(120, 2, "Forecasts");
uint16_t y = 0;
String degreeSign = "°F";
if (IS_METRIC) {
degreeSign = "°C";
}
for (uint8_t i = start; i < start + 6; i++) {
gfx.setTextAlignment(TEXT_ALIGN_LEFT);
y = 30 + (i - start) * 45;
if (y > 320) {
break;
}
gfx.drawPalettedBitmapFromPgm(0, y, getMiniMeteoconIconFromProgmem(forecasts[i].forecastIcon));
gfx.setColor(MINI_YELLOW);
gfx.setFont(ArialRoundedMTBold_14);
gfx.drawString(50, y, forecasts[i].forecastTitle);
gfx.setColor(MINI_WHITE);
gfx.drawString(50, y + 15, getShortText(forecasts[i].forecastIcon));
gfx.setColor(MINI_WHITE);
gfx.setTextAlignment(TEXT_ALIGN_RIGHT);
String temp = "";
if (i % 2 == 0) {
temp = forecasts[i].forecastHighTemp;
} else {
temp = forecasts[i - 1].forecastLowTemp;
}
gfx.drawString(235, y, temp + degreeSign);
/*gfx.setColor(MINI_WHITE);
gfx.drawString(x + 25, y, forecasts[dayIndex].forecastLowTemp + "|" + forecasts[dayIndex].forecastHighTemp);
gfx.drawPalettedBitmapFromPgm(x, y + 15, getMiniMeteoconIconFromProgmem(forecasts[dayIndex].forecastIcon));*/
gfx.setColor(MINI_BLUE);
gfx.drawString(235, y + 15, forecasts[i].PoP + "%");
}
}
void drawAbout() {
gfx.fillBuffer(MINI_BLACK);
gfx.drawPalettedBitmapFromPgm(23, 30, SquixLogo);
gfx.setFont(ArialRoundedMTBold_14);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.drawString(120, 80, "https://blog.squix.org");
gfx.setFont(ArialRoundedMTBold_14);
gfx.setTextAlignment(TEXT_ALIGN_CENTER);
gfx.setColor(MINI_WHITE);
gfx.drawString(120, 115, "About");
drawLabelValue(8, "Heap Mem:", String(ESP.getFreeHeap() / 1024)+"kb");
drawLabelValue(9, "Flash Mem:", String(ESP.getFlashChipRealSize() / 1024 / 1024) + "MB");
drawLabelValue(10, "WiFi Strength:", String(WiFi.RSSI()) + "dB");
drawLabelValue(11, "Chip ID:", String(ESP.getChipId()));
drawLabelValue(12, "VCC: ", String(ESP.getVcc() / 1024.0) +"V");
drawLabelValue(13, "CPU Freq.: ", String(ESP.getCpuFreqMHz()) + "MHz");
}
void calibrationCallback(int16_t x, int16_t y) {
gfx.setColor(1);
gfx.fillCircle(x, y, 10);
}
// Helper function, should be part of the weather station library and should disappear soon
const char* getMeteoconIconFromProgmem(String iconText) {
@@ -339,7 +525,7 @@ const char* getMeteoconIconFromProgmem(String iconText) {
if (iconText == "chancesleet") return chancesleet;
if (iconText == "chancesnow") return chancesnow;
if (iconText == "chancetstorms") return chancestorms;
if (iconText == "cloudy") return clear;
if (iconText == "clear") return clear;
if (iconText == "cloudy") return cloudy;
if (iconText == "flurries") return flurries;
if (iconText == "fog") return fog;
@@ -381,5 +567,31 @@ const char* getMiniMeteoconIconFromProgmem(String iconText) {
return miniunknown;
}
// Helper function, should be part of the weather station library and should disappear soon
const String getShortText(String iconText) {
if (iconText == "chanceflurries") return "Chance of Flurries";
if (iconText == "chancerain") return "Chance of Rain";
if (iconText == "chancesleet") return "Chance of Sleet";
if (iconText == "chancesnow") return "Chance of Snow";
if (iconText == "chancetstorms") return "Chance of Storms";
if (iconText == "clear") return "Clear";
if (iconText == "cloudy") return "Cloudy";
if (iconText == "flurries") return "Flurries";
if (iconText == "fog") return "Fog";
if (iconText == "hazy") return "Hazy";
if (iconText == "mostlycloudy") return "Mostly Cloudy";
if (iconText == "mostlysunny") return "Mostly Sunny";
if (iconText == "partlycloudy") return "Partly Couldy";
if (iconText == "partlysunny") return "Partly Sunny";
if (iconText == "sleet") return "Sleet";
if (iconText == "rain") return "Rain";
if (iconText == "snow") return "Snow";
if (iconText == "sunny") return "Sunny";
if (iconText == "tstorms") return "Storms";
return "-";
}

View File

@@ -28,7 +28,9 @@ const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes
#define TFT_CS D1
#define TFT_LED D8
// touch screen pins
#define TOUCH_CS D3
#define TOUCH_IRQ D4
// Wunderground Settings
@@ -37,7 +39,8 @@ const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes
// e.g. http://api.wunderground.com/api/808ba87ed77c4511/conditions/q/CH/Zurich.json
// e.g. http://api.wunderground.com/api/808ba87ed77c4511/conditions/q/CA/SAN_FRANCISCO.json <- note that in the US you use the state instead of country code
const String WUNDERGRROUND_API_KEY = "WUNDERGROUND_API_KEY";
const String DISPLAYED_CITY_NAME = "Zürich";
const String WUNDERGRROUND_API_KEY = "808ba87ed77c4501";
const String WUNDERGRROUND_LANGUAGE = "EN";
const String WUNDERGROUND_COUNTRY = "CH";
const String WUNDERGROUND_CITY = "Zurich";
@@ -52,10 +55,10 @@ struct dstRule EndRule = {"CET", Last, Sun, Oct, 2, 0}; // Central Europea
// struct dstRule EndRule = {"EST", First, Sun, Nov, 1, 0}; // Eastern Standard time = UTC/GMT -5 hour
// values in metric or imperial system?
const boolean IS_METRIC = true;
bool IS_METRIC = true;
// Change for 12 Hour/ 24 hour style clock
#define STYLE_12HR false
bool IS_STYLE_12HR = false;
// change for different ntp (time servers)
#define NTP_SERVERS "0.ch.pool.ntp.org", "1.ch.pool.ntp.org", "2.ch.pool.ntp.org"

View File

@@ -1,3 +1,150 @@
const char SquixLogo[] PROGMEM = {
0x01, // Version: 1
0x02, // BitDepth: 2
0x00, 0xC1, // Width: 193
0x00, 0x38, // Height: 56
// Round width to next byte: 200
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, 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, 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, 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, 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,
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, 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, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50,
0x15, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x05, 0x55, 0x55, 0x40, 0x00, 0x00, 0x01, 0x55, 0x55, 0x50, 0x00,
0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x54, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x01, 0x55,
0x55, 0x50, 0x00, 0x00, 0x05, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x55, 0x55, 0x50, 0x00, 0x00, 0x15, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00,
0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x15, 0x55, 0x54,
0x00, 0x00, 0x15, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x05, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40,
0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x05, 0x55, 0x55, 0x40, 0x01,
0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x15, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54,
0x05, 0x55, 0x50, 0x00, 0x01, 0x55, 0x55, 0x50, 0x05, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x50, 0x15, 0x55,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x55, 0x55, 0x54, 0x15, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55,
0x50, 0x00, 0x00, 0x15, 0x55, 0x54, 0x15, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x00,
0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00,
0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x15, 0x55, 0x55, 0x55, 0x00, 0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x55, 0x55, 0x00, 0x15, 0x55, 0x55, 0x55, 0x40,
0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00,
0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40,
0x00, 0x55, 0x55, 0x00, 0x15, 0x05, 0x55, 0x55, 0x50, 0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x55, 0x55, 0x00, 0x14, 0x01, 0x55, 0x55, 0x54, 0x01, 0x55,
0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x55,
0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x55,
0x55, 0x00, 0x14, 0x01, 0x55, 0x55, 0x55, 0x01, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55,
0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, 0x55, 0x00, 0x15, 0x05, 0x55, 0x55, 0x55, 0x41, 0x55, 0x50, 0x15,
0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, 0x55, 0x00,
0x15, 0x55, 0x55, 0x55, 0x55, 0x50, 0x55, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05,
0x55, 0x50, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x55, 0x55, 0x00, 0x15, 0x54, 0x15, 0x55, 0x55, 0x54, 0x15, 0x50, 0x15, 0x55, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x55, 0x55, 0x00, 0x15, 0x51,
0x40, 0x00, 0x00, 0x00, 0x05, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50,
0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x15, 0x55, 0x40, 0x55, 0x55, 0x00, 0x15, 0x51, 0x45, 0x55, 0x55, 0x55, 0x41, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x55, 0x55, 0x00, 0x15, 0x54, 0x14, 0x15,
0x55, 0x55, 0x50, 0x50, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00,
0x05, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
0x55, 0x40, 0x55, 0x55, 0x00, 0x15, 0x55, 0x51, 0x40, 0x00, 0x00, 0x00, 0x10, 0x15, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x40, 0x55, 0x55, 0x40, 0x15, 0x55, 0x51, 0x45, 0x55, 0x55,
0x55, 0x00, 0x05, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x00, 0x55, 0x55,
0x54, 0x15, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x40,
0x15, 0x55, 0x50, 0x15, 0x55, 0x54, 0x15, 0x55, 0x55, 0x55, 0x40, 0x05, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x01, 0x55, 0x55, 0x50, 0x05, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x15, 0x55, 0x54, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50,
0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x05, 0x55, 0x50, 0x00, 0x05, 0x55, 0x55, 0x40, 0x01,
0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x15, 0x55,
0x54, 0x15, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50,
0x05, 0x55, 0x50, 0x00, 0x05, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x05, 0x55, 0x55, 0x05, 0x55, 0x55, 0x55, 0x15, 0x55, 0x55, 0x55, 0x01, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x05, 0x55, 0x50, 0x00, 0x15, 0x55, 0x54, 0x00, 0x00, 0x15, 0x55,
0x54, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x01, 0x55, 0x55, 0x41,
0x55, 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x41, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x05, 0x55,
0x50, 0x00, 0x55, 0x55, 0x54, 0x00, 0x00, 0x15, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x55, 0x55, 0x50, 0x55, 0x54, 0x11, 0x41, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x05, 0x55, 0x50, 0x01, 0x55, 0x55, 0x50, 0x00, 0x00, 0x05, 0x55, 0x55, 0x40,
0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x00, 0x15, 0x55, 0x54, 0x15, 0x51,
0x45, 0x14, 0x55, 0x55, 0x55, 0x50, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x05, 0x55, 0x50, 0x05,
0x55, 0x55, 0x40, 0x00, 0x00, 0x01, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x05, 0x51, 0x45, 0x14, 0x55, 0x05, 0x55, 0x40, 0x05, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x50, 0x00, 0x05, 0x55, 0x50, 0x15, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x54, 0x00, 0x00,
0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x01, 0x54, 0x15, 0x41,
0x54, 0x50, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x01, 0x55, 0x50, 0x15, 0x55, 0x54,
0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x54, 0x51, 0x54, 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, 0x15, 0x55, 0x55, 0x55, 0x05,
0x50, 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, 0x05, 0x55, 0x55, 0x55, 0x55, 0x40, 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, 0x01, 0x55, 0x55, 0x55, 0x55, 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, 0x55, 0x55, 0x55, 0x54, 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, 0x15, 0x55, 0x55, 0x50, 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, 0x05, 0x55, 0x55, 0x40, 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, 0x01, 0x55, 0x55, 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,
0x55, 0x54, 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, 0x15, 0x50, 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, 0x05, 0x40,
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, 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, 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, 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, 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,
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,
};
const char chanceflurries[] PROGMEM = {
0x01, // Version: 1
0x02, // BitDepth: 2