Compare commits

...

14 Commits

Author SHA1 Message Date
74b967392d Cleanup.
Some checks failed
continuous-integration/drone/push Build is failing
2019-06-18 18:18:07 +02:00
8c9e9e2e2e MQTT: Use new effect structure and logging. 2019-06-18 18:17:48 +02:00
f1424d0277 Extended http server to list files in SPIFFS and allow you to upload and delete files. 2019-06-18 18:17:20 +02:00
e52d7c750d Define flash layout in platformio.ini in order to have space for a SPIFFS file system. 2019-06-18 18:16:31 +02:00
d1a49fe625 Added missing library. 2019-06-18 18:15:59 +02:00
0941ad8349 Effects are now constructed when needed instead of having global objects of every effect flying around. 2019-06-18 18:14:59 +02:00
5a02050680 Log using printf with a String stored in PROGMEM. Always. 2019-06-18 18:13:37 +02:00
5af7c6337d Enable CYCLE_MODE_RANOM by default. 2019-06-18 18:12:36 +02:00
ae02509712 Updated .gitignore 2019-06-18 18:12:16 +02:00
3c0e7a116a Animation now uses .pia files from SPIFFS instead of hardcoded C stuff. 2019-06-18 18:10:58 +02:00
1912772da3 Effects now use Constructor and Destructor to initialize or delete their data, instead of using start() and stop(). 2019-06-18 18:09:05 +02:00
72cdb46451 .gitignore: Ignore MacOS' .DS_Store. 2019-06-18 18:05:20 +02:00
f0509de411 PixelClockEffect is now being displayed correctly. 2019-06-16 12:43:34 +02:00
e8f3ea3281 Extended MatrixEffect to also get RainbowMatrixEffect and RandomMatrixEffect.
Side note: You know you understand C++ when you understand the meaning 
and reason for "MatrixEffect** _columns". ;-)
2019-06-16 12:43:05 +02:00
36 changed files with 565 additions and 506 deletions

3
.gitignore vendored
View File

@ -3,6 +3,9 @@
.gcc-flags.json .gcc-flags.json
src/config.h src/config.h
src/tools/*.gif src/tools/*.gif
src/tools/*.pia
src/tools/*.pia.debug
include/config.h include/config.h
.piolibdeps .piolibdeps
.pioenvs .pioenvs
.DS_Store

BIN
data/bell.pia Normal file

Binary file not shown.

BIN
data/cake.pia Normal file

Binary file not shown.

BIN
data/koopa.pia Normal file

Binary file not shown.

View File

@ -38,24 +38,33 @@ it contains only one entry and .individual_delays will be false.
class Animation { class Animation {
protected: protected:
AnimationData* data;
unsigned long currentFrameSince; unsigned long currentFrameSince;
uint8_t currentFrame = 0; uint8_t currentFrame = 0;
uint8_t* animation_data; uint8_t* animation_data;
CRGB* colors; CRGB** _colors;
CRGB* fgColor = NULL; CRGB* fgColor = NULL;
CRGB* bgColor = new CRGB(0x000000); CRGB* bgColor = new CRGB(0x000000);
int8_t xOffset = 0; int8_t xOffset = 0;
int8_t yOffset = 0; int8_t yOffset = 0;
uint8_t startFrame = 0; uint8_t _startFrame = 0;
uint8_t endFrame = 0; uint8_t _endFrame = 0;
Window* _window;
uint8_t _width;
uint8_t _height;
uint8_t _frame_count;
uint8_t _color_count;
uint16_t* _frame_times;
uint16_t* _frame_data_lengths;
uint8_t** _frame_data;
bool _data_valid = false;
virtual CRGB* getColor(uint8_t color_index); virtual CRGB* getColor(uint8_t color_index);
void drawFrame(Window* w, uint8_t frame_index);
void drawPixel(Window* w, int index, CRGB* color); void drawPixel(int index, CRGB* color);
uint16_t getFrameDelay(int frame); uint16_t getFrameDelay(int frame);
bool _load_from_file(const char* c);
public: public:
Animation(AnimationData* d); Animation(const char* filename, Window* win);
void setFgColor(CRGB*); void setFgColor(CRGB*);
void setBgColor(CRGB* bg_color); void setBgColor(CRGB* bg_color);
bool invert(); bool invert();
@ -65,7 +74,8 @@ public:
void setFrameRange(uint8_t sf, uint8_t ef); void setFrameRange(uint8_t sf, uint8_t ef);
void setSingleFrame(uint8_t frame); void setSingleFrame(uint8_t frame);
virtual ~Animation(); virtual ~Animation();
void draw(Window* w); void draw();
void drawFrame(Window* w); void drawFrame();
void drawFrame(uint8_t frame_index);
virtual bool advance(); virtual bool advance();
}; };

View File

@ -9,6 +9,7 @@ class Effect {
protected: protected:
Window* window = Window::getFullWindow(); // Use a full screen window per default. Window* window = Window::getFullWindow(); // Use a full screen window per default.
public: public:
virtual ~Effect() {};
virtual void loop() = 0; virtual void loop() = 0;
boolean supports_window = false; boolean supports_window = false;
virtual boolean can_be_shown_with_clock() { return false; }; virtual boolean can_be_shown_with_clock() { return false; };
@ -16,8 +17,6 @@ public:
void setWindow(Window* win) { void setWindow(Window* win) {
window = win; window = win;
}; };
virtual void start() {}
virtual void stop() {}
}; };
#endif #endif

View File

@ -1,11 +0,0 @@
#ifndef EffectEntry_H
#define EffectEntry_H
#include "Effect.h"
typedef struct {
const char* name;
Effect* effect;
} EffectEntry;
#endif

View File

@ -1,42 +0,0 @@
/**
Animations are structured in AnimationData as follows:
.colors contains .color_count*3 uint8_t values for R, G and B.
.offsets contains the frame start offsets within .data + the length of the data. (So
you can always do something like `for (int i=anim.offsets[i]; i<anim.offsets[i+1]; i++)`.
Accordingly it has a length of .frame_count+1.
.data contains all frames data with a run-length compression with escape char 255.
This data references the index of one or multiple pixels in .colors. It starts at the
top left pixel and walks each row to the right before starting the next row.
To decode it: Start at a frame (indicated by .offsets). Get one byte as x.
If x is <255: This is a single pixel of color x.
if x is 255: Run-length-encoding. The next byte indicates of often the byte after that
will be repeated. So, {255, 4, 10} is equal to {10, 10, 10, 10}.
A special case that may happen in larger GIFs is that there are more than 255 repetitions
of a color. Those will be split, so 355*color #10 will be: {255, 255, 10, 255, 100, 10},
e.g. 255*10 + 100*10. Usually this shouldn't need special handling within a decoder.
Regarding colors in .data:
Color 0 means "keep the color from the previous frame". This color should never appear on frame #0.
Color 1 means "show the background color".
All other color values point to a color in .colors - with an offset of 2.
So if in .data there's a color 3, paint this pixel in .colors[1].
.individual_delays contains either 1 or .frame_count delays. They are given in ms and
indicate how long the matching frame should be displayed. If all times are equal, then
it contains only one entry and .individual_delays will be false.
.w and .h contain the dimensions of the image.
**/
#pragma once
#include <Arduino.h>
#include "prototypes.h"
extern AnimationData animation_koopa;
extern AnimationData animation_couple_rain;
extern AnimationData animation_couple_snow;
extern AnimationData animation_heart;
extern AnimationData animation_weather_icons;
extern AnimationData animation_cake;

View File

@ -47,7 +47,7 @@
#define MONITOR_LOOP_TIME_COUNT_MAX 10 #define MONITOR_LOOP_TIME_COUNT_MAX 10
#define EFFECT_CYCLE_TIME 300 // Time in seconds between cycling effects. #define EFFECT_CYCLE_TIME 300 // Time in seconds between cycling effects.
#define EFFECT_CYCLE_RANDOM false #define EFFECT_CYCLE_RANDOM true
#define EFFECT_MATRIX_LENGTH_MIN 4 #define EFFECT_MATRIX_LENGTH_MIN 4
#define EFFECT_MATRIX_LENGTH_MAX 20 #define EFFECT_MATRIX_LENGTH_MAX 20
@ -72,21 +72,39 @@
#define EFFECT_GOL_START_PERCENTAGE 90 #define EFFECT_GOL_START_PERCENTAGE 90
#define EFFECT_GOL_BLEND_SPEED 10 #define EFFECT_GOL_BLEND_SPEED 10
#define EFFECT_GOL_RESTART_AFTER_STEPS 100 #define EFFECT_GOL_RESTART_AFTER_STEPS 100
// Stop editing here // Stop editing here
#ifdef DEBUG #ifdef DEBUG
#ifdef MQTT_ENABLE #ifdef MQTT_ENABLE
#include "my_mqtt.h" #include "my_mqtt.h"
#define LOG(x) mqtt_log(x); Serial.print(x); #define LOG(msg, ...) do { \
#define LOGln(x) mqtt_log_ln(x); Serial.println(x); char buffer[128]; \
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
mqtt_log(buffer);\
Serial.print(buffer);\
} while (0);
#define LOGln(msg, ...) do {\
char buffer[128]; \
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
mqtt_log_ln(buffer);\
Serial.println(buffer);\
} while (0);
#else #else
#define LOG(x) Serial.print(x); #define LOG(msg, ...) do { \
#define LOGln(x) Serial.println(x); char buffer[128]; \
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
Serial.print(buffer);\
} while (0);
#define LOGln(msg, ...) do { \
char buffer[128]; \
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
Serial.println(buffer);\
} while (0);
#endif #endif
#else #else
#define LOG(x) do {} while(0); #define LOG(msg, ...) do {} while(0);
#define LOGln(x) do {} while(0); #define LOGln(msg, ...) do {} while(0);
#endif #endif
#if !defined( ESP8266 ) && !defined( ESP32 ) #if !defined( ESP8266 ) && !defined( ESP32 )

View File

@ -8,15 +8,13 @@
class AnimationEffect : public Effect { class AnimationEffect : public Effect {
private: private:
Animation *animation; Animation *animation;
AnimationData *animation_data;
CRGB *bg_color; CRGB *bg_color;
uint16_t xOffset; uint16_t xOffset;
uint16_t yOffset; uint16_t yOffset;
public: public:
AnimationEffect(AnimationData* anim) : AnimationEffect(anim, new CRGB(0x000000), 0, 0) {} AnimationEffect(const char* name) : AnimationEffect(name, new CRGB(0x000000), 0, 0) {}
AnimationEffect(AnimationData* anim, CRGB* background_color) : AnimationEffect(anim, background_color, 0, 0) {} AnimationEffect(const char* name, CRGB* background_color) : AnimationEffect(name, background_color, 0, 0) {}
AnimationEffect(AnimationData* anim, CRGB* bg_color, int x, int y); AnimationEffect(const char* name, CRGB* bg_color, int x, int y);
void start(); ~AnimationEffect();
void stop();
void loop(); void loop();
}; };

View File

@ -6,13 +6,13 @@
class CycleEffect : public Effect { class CycleEffect : public Effect {
private: private:
Effect* effect; Effect* effect = NULL;
uint16_t effect_id = -1; uint16_t effect_id = -1;
unsigned long effectSince = 0; unsigned long effectSince = 0;
public: public:
CycleEffect();
~CycleEffect();
void changeEffect(); void changeEffect();
void start();
void stop();
boolean can_be_shown_with_clock(); boolean can_be_shown_with_clock();
boolean clock_as_mask(); boolean clock_as_mask();

View File

@ -13,7 +13,7 @@ private:
static CRGBPalette16 palette; static CRGBPalette16 palette;
public: public:
void start(); FireEffect();
void stop(); ~FireEffect();
void loop(); void loop();
}; };

View File

@ -16,8 +16,7 @@ private:
public: public:
GolEffect(); GolEffect();
void start(); ~GolEffect();
void stop();
void loop(); void loop();
bool can_be_shown_with_clock(); bool can_be_shown_with_clock();
}; };

View File

@ -1,5 +1,4 @@
#ifndef effect_matrix_H #pragma once
#define effect_matrix_H
#include "prototypes.h" #include "prototypes.h"
#include "Effect.h" #include "Effect.h"
@ -8,35 +7,57 @@
#include "my_color_palettes.h" #include "my_color_palettes.h"
class MatrixEffectColumn { class MatrixEffectColumn {
private: protected:
int x, y;
int length;
Window* window; Window* window;
int x, y;
int length = 1;
virtual CRGB _getColor(uint8_t height);
virtual void restart();
private:
uint16_t speed; uint16_t speed;
boolean running; boolean running;
unsigned long last_move = 0; unsigned long last_move = 0;
public: public:
MatrixEffectColumn();
MatrixEffectColumn(Window* win, int xPos); MatrixEffectColumn(Window* win, int xPos);
virtual ~MatrixEffectColumn() {};
void start();
void advance(); void advance();
void draw(); void draw();
void loop(); void loop();
}; };
class RainbowMatrixEffectColumn : public MatrixEffectColumn {
protected:
CRGB _getColor(uint8_t height) override;
public:
RainbowMatrixEffectColumn(Window* win, int xPos) : MatrixEffectColumn(win, xPos) {};
};
class RandomMatrixEffectColumn : public MatrixEffectColumn {
protected:
uint8_t _hue = 42;
CRGB _getColor(uint8_t height) override;
void restart() override;
public:
RandomMatrixEffectColumn(Window* win, int xPos) : MatrixEffectColumn(win, xPos) {};
};
class MatrixEffect : public Effect { class MatrixEffect : public Effect {
private: protected:
MatrixEffectColumn* _columns; MatrixEffectColumn** _columns;
virtual void _init();
public: public:
boolean can_be_shown_with_clock(); boolean can_be_shown_with_clock();
void start();
void stop();
MatrixEffect(); MatrixEffect();
virtual ~MatrixEffect();
void loop(); void loop();
}; };
#endif class RainbowMatrixEffect : public MatrixEffect {
private:
void _init() override;
};
class RandomMatrixEffect : public MatrixEffect {
private:
void _init() override;
};

View File

@ -9,8 +9,7 @@ private:
CRGB* _color_minutes; CRGB* _color_minutes;
public: public:
PixelClockEffect(); PixelClockEffect();
void start(); ~PixelClockEffect();
void stop();
void loop(); void loop();
bool can_be_shown_with_clock(); bool can_be_shown_with_clock();
}; };

View File

@ -2,16 +2,17 @@
#define effects_H #define effects_H
#include <SimpleList.h> #include <SimpleList.h>
#include "EffectEntry.h"
#include "Effect.h" #include "Effect.h"
#include "effect_clock.h" #include "effect_clock.h"
extern SimpleList<EffectEntry>* effects; extern const char* cycle_effects[];
extern SimpleList<Effect*>* cycle_effects; extern uint8_t cycle_effects_count;
extern Effect* current_effect; extern Effect* current_effect;
extern ClockEffect effect_clock; extern ClockEffect effect_clock;
Effect* string_to_effect(String s);
bool change_current_effect(String s);
void setup_effects(); void setup_effects();
#endif #endif

View File

@ -4,6 +4,7 @@
#ifdef HTTP_SERVER_ENABLE #ifdef HTTP_SERVER_ENABLE
#include "my_wifi.h" #include "my_wifi.h"
#include <FS.h>
#if defined ( ESP8266 ) #if defined ( ESP8266 )
extern ESP8266WebServer http_server; extern ESP8266WebServer http_server;
@ -11,6 +12,8 @@ extern ESP8266WebServer http_server;
extern ESP32WebServer http_server; extern ESP32WebServer http_server;
#endif #endif
extern File upload_file;
void http_server_setup(); void http_server_setup();
void http_server_loop(); void http_server_loop();
#endif #endif

View File

@ -23,12 +23,14 @@ void mqtt_log(const char* message);
void mqtt_log(int number); void mqtt_log(int number);
void mqtt_log(long unsigned int number); void mqtt_log(long unsigned int number);
void mqtt_log(long int number); void mqtt_log(long int number);
void mqtt_log(size_t number);
void mqtt_log(String str); void mqtt_log(String str);
void mqtt_log_ln(const char* message); void mqtt_log_ln(const char* message);
void mqtt_log_ln(int number); void mqtt_log_ln(int number);
void mqtt_log_ln(long unsigned int number); void mqtt_log_ln(long unsigned int number);
void mqtt_log_ln(long int number); void mqtt_log_ln(long int number);
void mqtt_log_ln(size_t number);
void mqtt_log_ln(String str); void mqtt_log_ln(String str);

View File

@ -2,18 +2,6 @@
#include <Arduino.h> #include <Arduino.h>
typedef struct {
uint8_t *colors;
uint8_t *data;
uint16_t *offsets;
uint16_t *delays;
boolean individual_delays;
int color_count;
int frame_count;
int w;
int h;
} AnimationData;
typedef struct { typedef struct {
uint8_t width; uint8_t width;
uint8_t height; uint8_t height;

View File

@ -19,6 +19,7 @@ lib_deps =
https://github.com/fabianonline/simplelist.git https://github.com/fabianonline/simplelist.git
https://github.com/fabianonline/NTPClient.git https://github.com/fabianonline/NTPClient.git
ESP8266WebServer ESP8266WebServer
ErriezCRC32
[env:ota] [env:ota]
upload_port = 10.10.2.78 upload_port = 10.10.2.78
@ -28,6 +29,7 @@ board = esp07
framework = arduino framework = arduino
lib_deps = ${extra.lib_deps} lib_deps = ${extra.lib_deps}
lib_ldf_mode = chain+ lib_ldf_mode = chain+
build_flags = -Wl,-Teagle.flash.2m512.ld
[env:local] [env:local]
upload_port = /dev/cu.wchusbserial1420 upload_port = /dev/cu.wchusbserial1420
@ -36,6 +38,7 @@ board = esp07
framework = arduino framework = arduino
lib_deps = ${extra.lib_deps} lib_deps = ${extra.lib_deps}
lib_ldf_mode = chain+ lib_ldf_mode = chain+
build_flags = -Wl,-Teagle.flash.2m512.ld
[env:esp32] [env:esp32]
platform = espressif32 platform = espressif32

2
src/.gitignore vendored
View File

@ -1,2 +0,0 @@
config.h
tools/*.gif

View File

@ -33,19 +33,131 @@ it contains only one entry and .individual_delays will be false.
#include "Animation.h" #include "Animation.h"
#include "functions.h" #include "functions.h"
#include "Window.h" #include "Window.h"
#include <FS.h>
Animation::Animation(AnimationData *d) { bool Animation::_load_from_file(const char* filename) {
this->data = d; LOGln("Animation * Loading animation %s...", filename);
if (!SPIFFS.begin()) {
LOGln("Animation * Could not mount SPIFFS file system.");
return false;
}
File file = SPIFFS.open(filename, "r");
if (!file) {
LOGln("Animation * Could not open file.");
return false;
}
this->endFrame = d->frame_count-1; size_t size = file.size();
this->colors = new CRGB[this->data->color_count]; LOGln("Animation * Opened %s with %d bytes.", filename, size);
uint8_t *color_data = new uint8_t[this->data->color_count * 3];
memcpy_P(color_data, this->data->colors, this->data->color_count * 3); if (file.available() < 6) {
for (int i = 0; i<this->data->color_count; i++) colors[i] = CRGB(color_data[i * 3], color_data[i * 3 + 1], color_data[i * 3 + 2]); LOGln("Animation * Less than 6 bytes available. Stopping.");
delete color_data; file.close();
int length = this->data->offsets[this->data->frame_count]; return false;
this->animation_data = new uint8_t[length]; }
memcpy_P(this->animation_data, this->data->data, length);
if (file.read() != 'P' || file.read() != 'I' || file.read() != 'A') {
LOGln("Animation * Magic number not found");
file.close();
return false;
}
uint8_t version = file.read();
if (version!=1) {
LOGln("Animation * Unexpected version %d, expected version 1.", version);
return false;
}
uint16_t expected_size = (file.read() << 8) | file.read();
if (expected_size != size) {
LOGln("Animation * Expected file to have %d bytes, but found %d bytes.", expected_size, size);
file.close();
return false;
}
if (file.available() != size - 6) {
LOGln("Animation * Expected file to have %d bytes available, but found %d bytes available.", size - 6, file.available());
file.close();
return false;
}
// Now we can be sure to have the right amount of bytes available for reading
_width = file.read();
LOGln("Animation * width: %d", _width);
_height = file.read();
LOGln("Animation * height: %d", _height);
_frame_count = file.read();
LOGln("Animation * frame_count: %d", _frame_count);
_color_count = file.read();
LOGln("Animation * color_count: %d", _color_count);
LOGln("Animation * Loading colors...");
_colors = new CRGB*[_color_count];
char* temp = new char[_color_count*3];
int bytes_read = file.readBytes(temp, _color_count*3);
LOGln("Animation * Read %d bytes.", bytes_read);
for (int i=0; i<_color_count; i++) {
_colors[i] = new CRGB(temp[i*3], temp[i*3+1], temp[i*3+2]);
}
delete [] temp;
LOGln("Animation * Color loading done.");
LOG("Animation * Loading frame times...");
_frame_times = new uint16_t[_frame_count];
for (int i=0; i<_frame_count; i++) {
_frame_times[i] = (file.read() << 8) | file.read();
}
LOGln(" done.");
LOGln("Animation * Loading frame lengths...");
_frame_data_lengths = new uint16_t[_frame_count];
temp = new char[_frame_count*2];
bytes_read = file.readBytes(temp, _frame_count*2);
LOGln("Animation * Read %d bytes.", bytes_read);
for (int i=0; i<_frame_count; i++) {
//LOGln("Animation * Raw frame lengths: %d, %d", temp[i*2], temp[i*2+1]);
_frame_data_lengths[i] = (temp[i*2]<<8) | temp[i*2+1];
}
delete [] temp;
LOGln("Animation * Frame length loading done.");
LOGln("Animation * Loading frame data...");
_frame_data = new uint8_t*[_frame_count];
for (int i=0; i<_frame_count; i++) {
uint16_t fl = _frame_data_lengths[i];
LOGln("Animation * Loading frame %d with %d bytes...", i, fl);
_frame_data[i] = new uint8_t[fl];
/*for (int b=0; b<fl; b++) {
_frame_data[i][b] = file.read();
}*/
file.readBytes((char*)_frame_data[i], fl);
}
LOGln("Animation * Frame data loaded.");
if (file.position() != size) {
LOGln("Animation * Expected position to be %d, but are at %d.", size, file.position());
file.close();
return false;
}
file.close();
LOGln("Animation * Loading completed successfully.");
return true;
}
Animation::Animation(const char* filename, Window* win) {
_window = win;
if (_load_from_file(filename)) {
_endFrame = _frame_count-1;
_data_valid = true;
} else {
_endFrame = 0;
_data_valid = false;
}
} }
void Animation::setFgColor(CRGB* fg_color) { void Animation::setFgColor(CRGB* fg_color) {
@ -70,87 +182,103 @@ void Animation::setOffsets(int8_t x, int8_t y) {
} }
void Animation::setStartFrame(uint8_t sf) { void Animation::setStartFrame(uint8_t sf) {
if (sf <= this->endFrame && sf < this->data->frame_count ) this->startFrame = sf; if (_data_valid && sf <= _endFrame && sf < _frame_count ) _startFrame = sf;
} }
void Animation::setEndFrame(uint8_t ef) { void Animation::setEndFrame(uint8_t ef) {
if (ef >= this->startFrame && ef < this->data->frame_count) this->endFrame = ef; if (_data_valid && ef >= _startFrame && ef < _frame_count) _endFrame = ef;
} }
void Animation::setFrameRange(uint8_t sf, uint8_t ef) { void Animation::setFrameRange(uint8_t sf, uint8_t ef) {
if (sf<=ef && ef < this->data->frame_count) { if (_data_valid && sf<=ef && ef < _frame_count) {
this->startFrame = sf; _startFrame = sf;
this->endFrame = ef; _endFrame = ef;
} }
} }
void Animation::setSingleFrame(uint8_t frame) { void Animation::setSingleFrame(uint8_t frame) {
if (frame < this->data->frame_count) { if (_data_valid && frame < _frame_count) {
this->startFrame = frame; _startFrame = frame;
this->endFrame = frame; _endFrame = frame;
} }
} }
Animation::~Animation() { Animation::~Animation() {
delete this->colors; for (int i=0; i<_color_count; i++) delete _colors[i];
delete this->animation_data; delete [] _colors;
if (fgColor) delete fgColor;
delete bgColor;
delete [] _frame_data_lengths;
delete [] _frame_times;
for (int i=0; i<_frame_count; i++) {
delete [] _frame_data[i];
}
delete [] _frame_data;
} }
void Animation::draw(Window* win) { void Animation::draw() {
for (uint16_t i=0; i<this->currentFrame; i++) this->drawFrame(win, i); for (uint16_t i=0; i<this->currentFrame; i++) this->drawFrame(i);
} }
void Animation::drawFrame(Window* win) { void Animation::drawFrame() {
this->drawFrame(win, currentFrame); this->drawFrame(currentFrame);
} }
void Animation::drawFrame(Window* win, uint8_t frame_index) { void Animation::drawFrame(uint8_t frame_index) {
uint16_t led_index = 0; uint16_t led_index = 0;
for (uint16_t i=this->data->offsets[frame_index]; i<this->data->offsets[frame_index + 1]; i++) { if (!_data_valid) {
CRGB red(0xFF0000);
CRGB black(0x000000);
for (int x=0; x<_window->width; x++) for (int y=0; y<_window->height; y++) {
_window->setPixel(x, y, (y*_window->width+x) % 2 ? &red : &black);
}
return;
}
for (uint16_t i=0; i<_frame_data_lengths[frame_index]; i++) {
uint8_t color_index; uint8_t color_index;
uint8_t count = 1; uint8_t count = 1;
if (this->animation_data[i]==255) { // Run-length encoded data if (_frame_data[frame_index][i]==255) { // Run-length encoded data
color_index = this->animation_data[i + 2]; color_index = _frame_data[frame_index][i+2];
count = this->animation_data[i + 1]; count = _frame_data[frame_index][i+1];
i += 2; i += 2;
} else { } else {
color_index = this->animation_data[i]; color_index = _frame_data[frame_index][i];
} }
if (color_index == 0) { // color #0 = skip this pixels if (color_index == 0) { // color #0 = skip this pixels
led_index += count; led_index += count;
} else { } else {
CRGB* color = this->getColor(color_index); CRGB* color = this->getColor(color_index);
for (int j=0; j<count; j++) this->drawPixel(win, led_index++, color); for (int j=0; j<count; j++) this->drawPixel(led_index++, color);
} }
} }
} }
bool Animation::advance() { bool Animation::advance() {
if (!_data_valid) return false;
if (this->currentFrameSince == 0) { if (this->currentFrameSince == 0) {
this->currentFrameSince = millis(); this->currentFrameSince = millis();
} else if (this->currentFrameSince + this->getFrameDelay(currentFrame) < millis() || this->currentFrameSince > millis()) { } else if (this->currentFrameSince + this->getFrameDelay(currentFrame) < millis() || this->currentFrameSince > millis()) {
currentFrame++; currentFrame++;
if (currentFrame > endFrame) currentFrame = startFrame; if (currentFrame > _endFrame) currentFrame = _startFrame;
this->currentFrameSince = millis(); this->currentFrameSince = millis();
return true; return true;
} }
return false; return false;
} }
void Animation::drawPixel(Window* win, int index, CRGB* color) { void Animation::drawPixel(int index, CRGB* color) {
uint8_t x = this->xOffset + (index % this->data->w); uint8_t x = this->xOffset + (index % _width);
uint8_t y = this->yOffset + (index / this->data->h); uint8_t y = this->yOffset + (index / _height);
win->setPixel(x, y, color); _window->setPixel(x, y, color);
} }
uint16_t Animation::getFrameDelay(int frame) { uint16_t Animation::getFrameDelay(int frame) {
if (this->data->individual_delays) return this->data->delays[frame]; return _frame_times[frame];
return this->data->delays[0];
} }
CRGB* Animation::getColor(uint8_t index) { CRGB* Animation::getColor(uint8_t index) {
if (index==1) return this->bgColor; if (index==1) return this->bgColor;
else if (this->fgColor != NULL) return this->fgColor; else if (this->fgColor != NULL) return this->fgColor;
else return &(this->colors[index - 2]); else return _colors[index - 2];
} }

View File

@ -1,165 +0,0 @@
#include "animations.h"
#include "prototypes.h"
uint8_t animation_koopa_colors[] PROGMEM = {182, 154, 17, 0, 0, 0, 48, 48, 48, 142, 4, 6, 254, 252, 255, 3, 1, 138, 17, 239, 18};
uint8_t animation_koopa_data[] PROGMEM = {
255, 4, 1, 6, 255, 14, 1, 6, 6, 6, 255, 12, 1, 2, 6, 6, 6, 255, 11, 1, 2, 2, 3, 6, 6, 2, 255, 10, 1, 2, 2, 3, 6, 6, 2, 1, 1, 8, 8, 8, 6, 1, 1, 1, 2, 3, 2, 6, 6, 2, 2, 1, 8, 3, 8, 8, 3, 6, 1, 1, 255, 7, 2, 1, 8, 8, 3, 3, 8, 8, 6, 1, 2, 2, 2, 4, 2, 2, 4, 8, 8, 3, 8, 8, 3, 8, 6, 1, 2, 2, 4, 2, 2, 2, 7, 8, 3, 255, 4, 8, 3, 8, 1, 1, 1, 255, 4, 2, 7, 3, 8, 3, 8, 8, 3, 8, 3, 2, 1, 1, 1, 2, 2, 2, 7, 8, 8, 8, 3, 3, 8, 8, 8, 255, 5, 1, 2, 2, 7, 7, 8, 3, 8, 8, 3, 8, 7, 7, 1, 1, 1, 255, 4, 5, 7, 7, 255, 4, 8, 7, 7, 1, 1, 1, 5, 5, 5, 4, 2, 2, 255, 6, 7, 2, 255, 6, 1, 255, 4, 2, 1, 5, 5, 5, 2, 2, 255, 6, 1, 2, 2, 2, 255, 4, 1, 2, 2, 2, 1,
255, 4, 0, 1, 255, 14, 0, 1, 0, 1, 255, 12, 0, 1, 255, 14, 0, 1, 0, 6, 0, 0, 1, 255, 18, 0, 255, 4, 1, 0, 0, 0, 1, 2, 0, 3, 0, 6, 0, 0, 1, 8, 0, 0, 6, 1, 0, 0, 0, 3, 0, 6, 6, 255, 4, 0, 3, 8, 8, 3, 6, 1, 255, 4, 0, 2, 0, 0, 2, 1, 0, 8, 3, 3, 8, 255, 5, 0, 2, 4, 0, 0, 4, 0, 8, 3, 0, 0, 3, 8, 6, 0, 2, 2, 4, 255, 4, 0, 8, 3, 8, 0, 0, 8, 3, 8, 1, 0, 0, 2, 255, 4, 0, 3, 0, 3, 8, 8, 3, 0, 3, 2, 0, 0, 0, 2, 0, 0, 0, 8, 0, 8, 3, 3, 8, 0, 8, 1, 0, 0, 0, 1, 2, 2, 7, 0, 8, 3, 0, 0, 3, 8, 0, 7, 0, 0, 255, 4, 1, 5, 7, 0, 255, 4, 8, 0, 7, 255, 6, 0, 5, 0, 0, 255, 6, 7, 255, 6, 0, 5, 5, 0, 0, 2, 2, 0, 5, 5, 0, 0, 2,
255, 4, 0, 6, 255, 14, 0, 6, 0, 6, 255, 12, 0, 2, 255, 14, 0, 2, 0, 3, 0, 0, 2, 255, 25, 0, 2, 3, 0, 6, 0, 2, 255, 11, 0, 2, 0, 2, 2, 255, 17, 0, 1, 255, 11, 0, 1, 1, 0, 0, 1, 255, 9, 0, 255, 4, 1, 255, 14, 0, 1, 1, 255, 14, 0, 2, 255, 35, 0, 2, 255, 14, 0, 2, 255, 14, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 255, 3, 0,
255, 73, 0, 8, 8, 8, 6, 255, 11, 0, 8, 3, 0, 0, 3, 6, 255, 11, 0, 8, 3, 3, 8, 8, 6, 255, 4, 0, 4, 0, 0, 4, 8, 0, 3, 8, 8, 3, 255, 5, 0, 4, 2, 0, 0, 7, 0, 3, 8, 0, 0, 8, 3, 8, 0, 0, 0, 2, 2, 0, 0, 0, 3, 8, 3, 0, 0, 3, 8, 3, 2, 0, 0, 0, 2, 0, 0, 0, 8, 0, 8, 3, 3, 8, 0, 8, 1, 0, 0, 1, 1, 0, 0, 0, 7, 0, 3, 8, 8, 3, 0, 7, 7, 255, 4, 0, 1, 1, 2, 0, 7, 8, 0, 0, 8, 7, 0, 1, 255, 4, 0, 2, 2, 0, 2, 0, 255, 4, 7, 0, 2, 255, 4, 0, 2, 2, 0, 0, 5, 5, 1, 1, 2, 2, 2, 5, 5, 255, 4, 0, 1, 1, 5, 5, 5, 255, 4, 0, 255, 3, 5,
255, 4, 0, 1, 255, 14, 0, 1, 0, 1, 255, 12, 0, 1, 255, 14, 0, 1, 0, 6, 0, 0, 1, 255, 18, 0, 255, 4, 1, 0, 0, 0, 1, 2, 0, 3, 0, 6, 0, 0, 1, 8, 0, 0, 6, 1, 0, 0, 0, 3, 0, 6, 6, 255, 4, 0, 3, 8, 8, 3, 6, 1, 255, 4, 0, 2, 0, 0, 2, 1, 0, 8, 3, 3, 8, 255, 5, 0, 2, 4, 0, 0, 4, 0, 8, 3, 0, 0, 3, 8, 6, 0, 2, 2, 4, 255, 4, 0, 8, 3, 8, 0, 0, 8, 3, 8, 1, 0, 0, 2, 255, 4, 0, 3, 0, 3, 8, 8, 3, 0, 3, 2, 0, 0, 0, 2, 0, 0, 0, 8, 0, 8, 3, 3, 8, 0, 8, 8, 255, 4, 0, 2, 2, 7, 0, 8, 3, 0, 0, 3, 8, 0, 7, 255, 4, 0, 1, 1, 0, 7, 0, 255, 4, 8, 0, 7, 255, 4, 0, 1, 0, 0, 0, 2, 255, 6, 7, 2, 255, 4, 0, 255, 4, 2, 255, 4, 0, 2, 2, 2, 0, 0,
255, 4, 0, 6, 255, 14, 0, 6, 0, 6, 255, 12, 0, 2, 255, 14, 0, 2, 0, 3, 0, 0, 2, 255, 25, 0, 2, 3, 0, 6, 0, 2, 255, 11, 0, 2, 0, 2, 2, 255, 17, 0, 1, 255, 11, 0, 1, 1, 0, 0, 1, 255, 9, 0, 255, 4, 1, 255, 14, 0, 1, 1, 255, 14, 0, 2, 255, 12, 0, 1, 255, 36, 0, 1, 255, 10, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 1, 0, 0, 1, 1, 0, 2, 2
};
uint16_t animation_koopa_delays[] = {100, 100, 100, 100, 100, 100};
uint16_t animation_koopa_offsets[] = {0, 199, 390, 479, 640, 832, 926};
AnimationData animation_koopa = {&animation_koopa_colors[0], &animation_koopa_data[0], &animation_koopa_offsets[0], &animation_koopa_delays[0], false, 7, 6, 16, 16};
uint8_t animation_couple_rain_colors[] PROGMEM = {0, 0, 0, 2, 139, 218, 181, 171, 255, 255, 255, 255, 255, 76, 11, 220, 206, 180, 49, 49, 49, 21, 1, 175, 100, 27, 0, 81, 66, 37, 51, 25, 253, 46, 12, 0, 218, 2, 86, 37, 175, 253, 128, 104, 60};
uint8_t animation_couple_rain_data[] PROGMEM = {
255, 6, 2, 3, 255, 7, 2, 3, 255, 14, 2, 3, 255, 8, 2, 3, 255, 7, 2, 3, 255, 14, 2, 3, 255, 25, 2, 3, 255, 5, 2, 3, 255, 12, 2, 3, 255, 12, 2, 3, 255, 18, 2, 3, 255, 12, 2, 3, 255, 18, 2, 3, 255, 12, 2, 3, 255, 18, 2, 3, 255, 12, 2, 3, 255, 10, 2, 3, 255, 7, 2, 3, 255, 23, 2, 3, 255, 11, 2, 3, 255, 19, 2, 3, 255, 11, 2, 3, 255, 15, 2, 3, 2, 2, 2, 3, 255, 11, 2, 3, 255, 5, 2, 15, 255, 9, 2, 3, 2, 2, 2, 3, 255, 11, 2, 3, 2, 2, 2, 3, 255, 11, 2, 3, 255, 15, 2, 3, 5, 2, 15, 3, 255, 7, 2, 3, 2, 2, 2, 3, 255, 8, 2, 3, 255, 4, 2, 255, 7, 5, 255, 7, 2, 3, 2, 2, 2, 3, 255, 8, 2, 3, 2, 2, 2, 5, 5, 12, 12, 5, 12, 12, 5, 5, 255, 6, 2, 3, 255, 12, 2, 3, 2, 2, 5, 5, 12, 12, 5, 5, 5, 12, 12, 5, 5, 255, 5, 2, 3, 255, 12, 2, 3, 2, 4, 4, 9, 9, 12, 5, 5, 5, 12, 9, 9, 4, 4, 255, 4, 2, 3, 255, 8, 2, 3, 2, 2, 2, 3, 2, 4, 4, 9, 9, 9, 4, 4, 4, 9, 9, 9, 4, 4, 255, 13, 2, 3, 255, 11, 2, 9, 255, 6, 2, 3, 255, 12, 2, 3, 255, 7, 2, 6, 6, 6, 2, 9, 255, 6, 2, 3, 255, 12, 2, 3, 255, 7, 2, 6, 6, 6, 2, 9, 2, 10, 10, 10, 2, 2, 3, 255, 12, 2, 3, 255, 7, 2, 10, 10, 10, 2, 9, 255, 5, 10, 2, 3, 255, 19, 2, 255, 5, 6, 12, 10, 7, 7, 7, 10, 2, 3, 255, 6, 2, 3, 255, 13, 2, 11, 7, 11, 2, 12, 10, 11, 7, 11, 10, 255, 8, 2, 3, 255, 13, 2, 7, 7, 7, 2, 7, 10, 7, 7, 7, 10, 255, 8, 2, 3, 255, 6, 2, 3, 255, 6, 2, 255, 5, 6, 13, 13, 16, 13, 13, 255, 8, 2, 3, 255, 6, 2, 3, 255, 5, 2, 255, 4, 6, 2, 2, 2, 14, 14, 14, 255, 9, 2, 3, 255, 6, 2, 3, 255, 5, 2, 7, 10, 10, 10, 2, 2, 7, 14, 14, 14, 7, 255, 15, 2, 3, 255, 6, 2, 6, 6, 6, 2, 2, 255, 5, 14, 2, 2, 2, 15, 255, 11, 2, 3, 255, 6, 2, 6, 2, 6, 2, 2, 2, 7, 2, 7, 255, 6, 2, 15, 255, 15, 2, 8, 8, 2, 8, 8, 2, 2, 8, 2, 8, 255, 6, 2, 3, 255, 37, 2,
255, 19, 0, 3, 255, 31, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 255, 8, 0, 2, 255, 5, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 8, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 2, 255, 21, 0, 2, 15, 255, 8, 0, 2, 255, 14, 0, 15, 0, 0, 0, 15, 2, 255, 15, 0, 3, 255, 14, 0, 2, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 36, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 25, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 50, 0, 15, 255, 5, 0, 3, 255, 5, 0, 15, 255, 20, 0, 2, 0, 15, 0, 0, 3, 255, 7, 0, 15, 255, 20, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 37, 0,
255, 6, 0, 2, 255, 7, 0, 2, 255, 14, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 31, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 255, 8, 0, 2, 255, 5, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 7, 0, 3, 0, 15, 0, 2, 15, 0, 15, 0, 0, 0, 2, 0, 3, 255, 18, 0, 3, 0, 0, 2, 2, 0, 0, 2, 255, 4, 0, 15, 255, 7, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 36, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 25, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 11, 0, 15, 0, 2, 255, 18, 0, 2, 0, 0, 15, 255, 8, 0, 2, 2, 0, 15, 255, 19, 0, 2, 255, 10, 0, 2, 255, 23, 0, 3, 255, 31, 0, 3, 255, 34, 0,
0, 0, 3, 255, 16, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 255, 7, 0, 2, 255, 14, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 31, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 255, 8, 0, 2, 255, 5, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 255, 18, 0, 15, 255, 26, 0, 15, 2, 0, 0, 2, 0, 2, 255, 16, 0, 2, 255, 19, 0, 2, 3, 255, 10, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 8, 0, 3, 255, 18, 0, 3, 255, 19, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 36, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 23, 0, 15, 0, 2, 0, 0, 0, 15, 2, 3, 255, 18, 0, 3, 0, 0, 0, 2, 0, 0, 2, 255, 8, 0, 2, 15, 255, 14, 0, 3, 255, 5, 0, 15, 255, 7, 0, 2, 255, 25, 0, 15, 255, 5, 0, 2, 255, 59, 0,
255, 10, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 255, 7, 0, 2, 255, 14, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 31, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 2, 15, 255, 5, 0, 2, 255, 5, 0, 3, 255, 12, 0, 15, 2, 255, 17, 0, 3, 255, 45, 0, 15, 255, 22, 0, 2, 255, 6, 0, 15, 255, 13, 0, 3, 255, 10, 0, 2, 255, 7, 0, 3, 255, 12, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 36, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 36, 0, 2, 255, 5, 0, 2, 255, 26, 0, 15, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 2, 2, 15, 255, 4, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 2, 255, 23, 0, 3, 255, 41, 0,
0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 255, 7, 0, 2, 255, 14, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 29, 0, 2, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 15, 255, 4, 0, 2, 255, 14, 0, 3, 0, 0, 15, 2, 0, 15, 0, 3, 255, 8, 0, 2, 255, 5, 0, 3, 255, 12, 0, 15, 2, 255, 17, 0, 3, 255, 10, 0, 15, 2, 255, 56, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 36, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 15, 255, 11, 0, 3, 255, 14, 0, 2, 255, 5, 0, 2, 0, 0, 15, 255, 4, 0, 15, 255, 25, 0, 2, 0, 0, 0, 15, 255, 20, 0, 15, 255, 11, 0, 3, 255, 25, 0, 2, 255, 34, 0,
255, 6, 0, 3, 0, 0, 0, 2, 255, 5, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 10, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 255, 7, 0, 2, 255, 14, 0, 2, 255, 31, 0, 2, 255, 20, 0, 2, 3, 255, 21, 0, 2, 15, 0, 2, 15, 255, 5, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 0, 2, 0, 2, 255, 12, 0, 2, 255, 5, 0, 3, 255, 9, 0, 15, 0, 0, 2, 255, 18, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 12, 0, 2, 255, 22, 0, 3, 255, 31, 0, 3, 255, 28, 0, 2, 255, 7, 0, 2, 15, 255, 21, 0, 3, 255, 4, 0, 2, 0, 15, 0, 2, 2, 0, 0, 3, 255, 14, 0, 2, 0, 15, 0, 3, 255, 7, 0, 2, 255, 4, 0, 3, 255, 14, 0, 15, 2, 255, 72, 0,
255, 23, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 2, 255, 5, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 10, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 0, 0, 0, 15, 0, 15, 0, 2, 15, 255, 13, 0, 2, 255, 12, 0, 2, 0, 0, 2, 255, 15, 0, 2, 255, 21, 0, 3, 255, 31, 0, 3, 255, 18, 0, 3, 2, 255, 15, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 255, 23, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 10, 0, 15, 0, 2, 255, 22, 0, 3, 255, 5, 0, 2, 255, 20, 0, 15, 255, 4, 0, 3, 0, 15, 2, 255, 4, 0, 15, 255, 15, 0, 15, 0, 2, 255, 10, 0, 2, 255, 4, 0, 15, 255, 13, 0, 2, 0, 0, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 37, 0,
255, 16, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 2, 255, 5, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 10, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 7, 0, 2, 0, 2, 0, 0, 2, 0, 0, 0, 2, 255, 7, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 7, 0, 2, 255, 12, 0, 3, 255, 10, 0, 2, 255, 7, 0, 2, 255, 5, 0, 15, 255, 8, 0, 2, 255, 31, 0, 2, 255, 72, 0, 3, 255, 16, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 35, 0, 3, 0, 0, 2, 255, 20, 0, 2, 255, 7, 0, 3, 0, 0, 15, 0, 2, 255, 14, 0, 15, 0, 0, 2, 2, 255, 5, 0, 2, 255, 5, 0, 2, 15, 255, 14, 0, 2, 255, 7, 0, 3, 255, 9, 0, 2, 255, 16, 0, 15, 255, 4, 0, 3, 255, 65, 0,
0, 0, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 9, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 17, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 2, 255, 5, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 10, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 7, 0, 15, 2, 0, 15, 255, 12, 0, 3, 255, 16, 0, 2, 2, 255, 6, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 72, 0, 3, 255, 16, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 38, 0, 2, 255, 31, 0, 2, 255, 5, 0, 15, 2, 0, 15, 255, 14, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 255, 16, 0, 15, 0, 2, 0, 0, 15, 255, 4, 0, 3, 255, 4, 0, 2, 255, 17, 0, 2, 2, 15, 0, 0, 0, 15, 255, 7, 0, 2, 255, 22, 0, 3, 255, 33, 0,
255, 11, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 255, 15, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 9, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 17, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 2, 255, 5, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 10, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 14, 0, 15, 255, 5, 0, 3, 0, 0, 0, 2, 255, 22, 0, 2, 0, 0, 2, 15, 3, 255, 18, 0, 3, 255, 31, 0, 3, 255, 8, 0, 2, 255, 14, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 72, 0, 3, 255, 16, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 4, 0, 15, 255, 15, 0, 3, 255, 12, 0, 2, 0, 0, 2, 255, 21, 0, 15, 2, 255, 4, 0, 15, 255, 19, 0, 15, 2, 0, 0, 0, 15, 2, 2, 15, 0, 15, 255, 25, 0, 2, 0, 0, 0, 2, 0, 0, 3, 255, 23, 0, 2, 255, 37, 0,
255, 17, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 255, 15, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 9, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 17, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 2, 255, 5, 0, 15, 2, 255, 12, 0, 3, 0, 0, 0, 2, 255, 13, 0, 3, 255, 5, 0, 2, 255, 4, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 8, 0, 15, 255, 11, 0, 3, 0, 0, 0, 2, 255, 13, 0, 15, 255, 13, 0, 3, 255, 18, 0, 3, 255, 55, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 72, 0, 3, 255, 16, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 41, 0, 2, 255, 20, 0, 15, 255, 5, 0, 2, 15, 255, 19, 0, 3, 255, 5, 0, 2, 0, 0, 0, 15, 2, 2, 255, 19, 0, 3, 255, 4, 0, 2, 15, 0, 2, 0, 2, 255, 28, 0, 2, 255, 31, 0, 2, 255, 33, 0,
0, 0, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 13, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 255, 15, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 9, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 17, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 24, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 0, 0, 0, 2, 0, 15, 255, 4, 0, 15, 255, 20, 0, 3, 0, 15, 0, 2, 2, 255, 4, 0, 3, 255, 13, 0, 3, 0, 0, 0, 2, 255, 6, 0, 2, 255, 17, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 74, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 72, 0, 3, 255, 16, 0, 2, 255, 14, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 6, 0, 15, 255, 22, 0, 15, 2, 3, 0, 0, 15, 0, 0, 2, 255, 29, 0, 2, 255, 27, 0, 2, 255, 4, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 20, 0, 3, 255, 40, 0,
0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 13, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 255, 15, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 9, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 16, 0, 15, 2, 0, 15, 0, 0, 3, 255, 8, 0, 2, 255, 13, 0, 2, 15, 0, 0, 0, 2, 255, 5, 0, 2, 255, 15, 0, 15, 2, 255, 14, 0, 2, 255, 14, 0, 3, 0, 0, 0, 15, 255, 27, 0, 3, 0, 0, 0, 2, 255, 19, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 74, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 70, 0, 2, 15, 3, 255, 16, 0, 2, 0, 0, 0, 2, 255, 4, 0, 2, 255, 5, 0, 3, 255, 16, 0, 2, 15, 255, 4, 0, 3, 255, 31, 0, 3, 255, 24, 0, 15, 255, 73, 0,
255, 14, 0, 3, 0, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 15, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 13, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 21, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 15, 255, 12, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 8, 0, 2, 0, 0, 2, 15, 255, 7, 0, 3, 255, 10, 0, 2, 255, 6, 0, 2, 0, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 8, 0, 2, 0, 0, 15, 255, 5, 0, 2, 255, 4, 0, 3, 255, 8, 0, 2, 255, 11, 0, 2, 255, 12, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 255, 23, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 74, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 7, 0, 2, 255, 19, 0, 15, 255, 30, 0, 2, 255, 13, 0, 3, 255, 15, 0, 15, 2, 255, 14, 0, 3, 255, 15, 0, 2, 2, 255, 5, 0, 3, 255, 31, 0, 3, 255, 34, 0,
255, 7, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 15, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 13, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 255, 23, 0, 15, 2, 255, 6, 0, 2, 255, 21, 0, 3, 255, 7, 0, 2, 255, 15, 0, 3, 255, 7, 0, 3, 255, 8, 0, 15, 255, 6, 0, 3, 255, 7, 0, 3, 0, 0, 2, 0, 0, 0, 2, 255, 16, 0, 3, 255, 10, 0, 2, 255, 14, 0, 3, 255, 8, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 255, 23, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 74, 0, 3, 255, 24, 0, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 18, 0, 2, 15, 0, 0, 2, 255, 24, 0, 15, 255, 6, 0, 2, 255, 24, 0, 2, 255, 16, 0, 15, 255, 20, 0, 15, 255, 9, 0, 3, 255, 16, 0, 2, 255, 40, 0,
0, 2, 255, 19, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 15, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 255, 30, 0, 2, 2, 255, 21, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 255, 8, 0, 15, 255, 6, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 14, 0, 3, 255, 8, 0, 2, 255, 31, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 255, 23, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 74, 0, 3, 255, 23, 0, 2, 3, 255, 6, 0, 3, 0, 0, 0, 2, 255, 15, 0, 2, 255, 4, 0, 3, 255, 9, 0, 15, 2, 15, 255, 19, 0, 15, 0, 2, 255, 9, 0, 2, 255, 20, 0, 2, 15, 255, 66, 0,
255, 10, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 6, 0, 2, 255, 11, 0, 2, 255, 19, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 15, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 15, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 13, 0, 3, 255, 9, 0, 2, 255, 21, 0, 3, 0, 0, 15, 2, 255, 30, 0, 2, 2, 15, 255, 44, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 23, 0, 2, 255, 31, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 255, 23, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 27, 0, 3, 255, 44, 0, 15, 0, 0, 15, 255, 26, 0, 3, 0, 0, 2, 0, 2, 255, 18, 0, 15, 3, 0, 15, 255, 4, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 2, 255, 8, 0, 2, 255, 22, 0, 2, 255, 34, 0,
255, 4, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 6, 0, 2, 255, 11, 0, 2, 255, 19, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 15, 0, 2, 0, 0, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 0, 0, 0, 2, 255, 6, 0, 15, 0, 15, 255, 9, 0, 3, 255, 4, 0, 2, 255, 7, 0, 2, 255, 8, 0, 2, 0, 0, 15, 0, 0, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 18, 0, 2, 255, 4, 0, 2, 255, 25, 0, 2, 255, 31, 0, 2, 255, 45, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 23, 0, 2, 255, 31, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 255, 23, 0, 3, 0, 0, 0, 2, 255, 24, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 5, 0, 15, 255, 14, 0, 3, 0, 0, 0, 2, 255, 7, 0, 15, 2, 0, 0, 2, 255, 15, 0, 3, 255, 5, 0, 15, 255, 27, 0, 15, 2, 0, 0, 2, 255, 5, 0, 15, 255, 24, 0, 15, 255, 5, 0, 3, 255, 24, 0, 3, 255, 36, 0,
255, 29, 0, 3, 255, 19, 0, 3, 255, 18, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 6, 0, 2, 255, 11, 0, 2, 255, 19, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 2, 15, 0, 0, 3, 255, 11, 0, 3, 255, 14, 0, 15, 2, 2, 0, 2, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 15, 0, 2, 15, 255, 14, 0, 3, 0, 0, 0, 2, 255, 18, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 103, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 23, 0, 2, 255, 31, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 14, 0, 3, 255, 31, 0, 3, 0, 2, 255, 21, 0, 3, 0, 0, 0, 2, 2, 255, 23, 0, 2, 0, 2, 3, 0, 0, 0, 15, 15, 255, 19, 0, 3, 0, 2, 0, 15, 0, 15, 255, 5, 0, 2, 255, 19, 0, 3, 255, 4, 0, 2, 255, 67, 0,
255, 4, 0, 2, 255, 5, 0, 2, 255, 31, 0, 2, 255, 18, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 18, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 6, 0, 2, 255, 11, 0, 2, 255, 19, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 11, 0, 15, 255, 6, 0, 3, 255, 12, 0, 2, 255, 8, 0, 15, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 15, 0, 3, 0, 2, 255, 13, 0, 2, 255, 15, 0, 3, 0, 0, 2, 0, 0, 0, 3, 0, 0, 2, 255, 8, 0, 3, 255, 19, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 103, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 23, 0, 2, 255, 31, 0, 2, 255, 24, 0, 2, 255, 31, 0, 2, 255, 10, 0, 15, 0, 15, 0, 3, 255, 20, 0, 15, 255, 6, 0, 2, 2, 0, 0, 3, 255, 17, 0, 15, 0, 0, 2, 0, 2, 3, 0, 0, 0, 2, 255, 19, 0, 15, 255, 4, 0, 2, 0, 0, 3, 0, 0, 0, 2, 255, 20, 0, 3, 0, 0, 0, 2, 255, 36, 0,
255, 17, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 12, 0, 2, 255, 18, 0, 2, 255, 5, 0, 2, 255, 31, 0, 2, 255, 18, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 18, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 255, 15, 0, 2, 255, 15, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 15, 0, 0, 0, 2, 0, 2, 255, 11, 0, 2, 255, 14, 0, 2, 255, 4, 0, 2, 255, 11, 0, 2, 255, 5, 0, 2, 255, 5, 0, 15, 255, 12, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 22, 0, 3, 255, 11, 0, 3, 255, 19, 0, 3, 255, 11, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 103, 0, 3, 255, 23, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 23, 0, 2, 0, 0, 0, 15, 255, 23, 0, 15, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 15, 255, 17, 0, 2, 15, 0, 0, 2, 255, 26, 0, 15, 2, 2, 255, 13, 0, 3, 255, 15, 0, 2, 255, 6, 0, 15, 255, 8, 0, 3, 255, 23, 0, 3, 255, 33, 0,
0, 0, 0, 3, 255, 8, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 8, 0, 3, 255, 9, 0, 3, 255, 6, 0, 2, 255, 19, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 12, 0, 2, 255, 18, 0, 2, 255, 5, 0, 2, 255, 31, 0, 2, 255, 18, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 18, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 0, 0, 0, 15, 2, 255, 10, 0, 2, 255, 15, 0, 3, 0, 15, 0, 2, 255, 30, 0, 2, 15, 255, 6, 0, 2, 255, 11, 0, 2, 255, 19, 0, 15, 255, 11, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 34, 0, 3, 255, 31, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 103, 0, 3, 255, 23, 0, 3, 255, 6, 0, 2, 3, 0, 0, 2, 255, 18, 0, 15, 2, 3, 255, 9, 0, 2, 2, 255, 15, 0, 15, 0, 2, 255, 5, 0, 15, 255, 23, 0, 2, 255, 5, 0, 15, 0, 2, 255, 8, 0, 15, 255, 15, 0, 2, 255, 5, 0, 2, 255, 25, 0, 2, 255, 40, 0,
255, 67, 0, 3, 255, 8, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 8, 0, 3, 255, 9, 0, 3, 255, 6, 0, 2, 255, 19, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 12, 0, 2, 255, 18, 0, 2, 255, 5, 0, 2, 255, 31, 0, 2, 255, 18, 0, 3, 255, 31, 0, 3, 255, 16, 0, 2, 0, 0, 3, 255, 18, 0, 3, 255, 6, 0, 15, 2, 0, 0, 15, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 0, 0, 0, 2, 255, 6, 0, 15, 255, 4, 0, 2, 255, 15, 0, 3, 0, 0, 0, 2, 255, 6, 0, 2, 255, 31, 0, 2, 255, 11, 0, 2, 255, 19, 0, 2, 15, 255, 10, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 34, 0, 3, 255, 31, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 93, 0, 2, 15, 0, 0, 0, 15, 255, 4, 0, 3, 255, 18, 0, 2, 255, 4, 0, 3, 0, 0, 2, 255, 4, 0, 3, 0, 0, 2, 15, 255, 19, 0, 3, 2, 255, 9, 0, 15, 2, 255, 22, 0, 2, 255, 31, 0, 2, 255, 33, 0,
0, 0, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 8, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 8, 0, 3, 255, 9, 0, 3, 255, 6, 0, 2, 255, 19, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 12, 0, 2, 255, 18, 0, 2, 255, 5, 0, 2, 255, 31, 0, 2, 255, 5, 0, 15, 255, 12, 0, 3, 255, 13, 0, 2, 0, 0, 0, 2, 255, 5, 0, 15, 255, 7, 0, 3, 255, 12, 0, 15, 255, 6, 0, 3, 0, 0, 0, 2, 255, 14, 0, 3, 255, 12, 0, 3, 255, 8, 0, 2, 255, 9, 0, 3, 255, 5, 0, 3, 255, 12, 0, 15, 0, 0, 2, 255, 15, 0, 3, 255, 11, 0, 2, 255, 30, 0, 2, 255, 11, 0, 2, 255, 31, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 34, 0, 3, 255, 31, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 255, 30, 0, 2, 0, 0, 0, 2, 255, 9, 0, 15, 255, 29, 0, 15, 2, 255, 27, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 7, 0, 3, 0, 0, 2, 255, 20, 0, 3, 255, 36, 0,
255, 18, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 255, 5, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 8, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 8, 0, 3, 255, 9, 0, 3, 255, 6, 0, 2, 255, 19, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 11, 0, 2, 2, 255, 18, 0, 2, 255, 5, 0, 2, 255, 10, 0, 2, 255, 26, 0, 15, 255, 12, 0, 3, 255, 31, 0, 3, 255, 11, 0, 15, 255, 13, 0, 2, 15, 255, 11, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 70, 0, 2, 255, 31, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 34, 0, 3, 255, 31, 0, 3, 255, 5, 0, 3, 255, 31, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 0, 15, 255, 21, 0, 2, 0, 0, 3, 255, 4, 0, 15, 255, 4, 0, 2, 255, 17, 0, 15, 2, 255, 10, 0, 2, 255, 29, 0, 15, 255, 23, 0, 15, 255, 67, 0,
255, 7, 0, 2, 255, 6, 0, 3, 255, 15, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 255, 5, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 8, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 8, 0, 3, 255, 9, 0, 3, 255, 6, 0, 2, 255, 12, 0, 15, 255, 4, 0, 15, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 5, 0, 2, 255, 5, 0, 2, 15, 255, 18, 0, 2, 0, 0, 0, 15, 0, 2, 15, 255, 29, 0, 2, 2, 255, 13, 0, 2, 255, 4, 0, 3, 255, 27, 0, 15, 0, 0, 0, 3, 255, 38, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 70, 0, 2, 255, 31, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 31, 0, 2, 255, 34, 0, 3, 255, 31, 0, 3, 0, 15, 0, 2, 0, 3, 255, 17, 0, 15, 255, 9, 0, 2, 0, 0, 0, 3, 255, 18, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 0, 15, 255, 21, 0, 2, 15, 0, 3, 255, 4, 0, 2, 2, 255, 22, 0, 2, 2, 255, 67, 0,
0, 0, 3, 255, 15, 0, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 6, 0, 3, 255, 11, 0, 2, 255, 12, 0, 2, 255, 6, 0, 3, 255, 15, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 255, 5, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 51, 0, 15, 255, 24, 0, 3, 255, 6, 0, 2, 0, 3, 0, 15, 2, 0, 0, 15, 255, 10, 0, 2, 255, 5, 0, 3, 255, 8, 0, 15, 255, 4, 0, 2, 255, 4, 0, 3, 255, 6, 0, 2, 255, 9, 0, 15, 2, 0, 0, 2, 255, 5, 0, 2, 255, 4, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 5, 0, 2, 255, 14, 0, 2, 255, 35, 0, 3, 255, 31, 0, 3, 255, 38, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 70, 0, 2, 255, 31, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 4, 0, 15, 255, 26, 0, 2, 255, 4, 0, 2, 255, 20, 0, 15, 2, 255, 7, 0, 3, 255, 26, 0, 15, 255, 4, 0, 3, 0, 0, 0, 2, 15, 3, 255, 20, 0, 2, 255, 10, 0, 3, 255, 22, 0, 3, 255, 4, 0, 2, 255, 23, 0, 2, 0, 0, 3, 255, 33, 0,
255, 30, 0, 2, 255, 19, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 6, 0, 3, 255, 11, 0, 2, 255, 12, 0, 2, 255, 6, 0, 3, 255, 15, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 255, 5, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 0, 0, 2, 255, 11, 0, 2, 255, 23, 0, 2, 0, 0, 0, 2, 15, 255, 23, 0, 15, 3, 15, 255, 21, 0, 3, 0, 0, 15, 2, 255, 4, 0, 3, 255, 16, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 56, 0, 3, 255, 31, 0, 3, 255, 38, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 70, 0, 2, 255, 31, 0, 2, 0, 2, 0, 0, 0, 2, 255, 18, 0, 3, 255, 12, 0, 2, 255, 16, 0, 2, 0, 3, 0, 0, 15, 2, 255, 29, 0, 2, 0, 2, 255, 7, 0, 2, 0, 15, 255, 24, 0, 3, 255, 4, 0, 15, 255, 24, 0, 15, 0, 3, 255, 5, 0, 3, 255, 56, 0,
0, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 8, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 2, 255, 31, 0, 2, 255, 19, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 6, 0, 3, 255, 11, 0, 2, 255, 12, 0, 2, 255, 6, 0, 3, 255, 15, 0, 3, 255, 31, 0, 3, 255, 19, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 255, 5, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 0, 0, 15, 0, 15, 255, 6, 0, 2, 0, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 0, 0, 0, 2, 0, 2, 255, 8, 0, 2, 255, 15, 0, 2, 255, 60, 0, 3, 255, 25, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 56, 0, 3, 255, 31, 0, 3, 255, 38, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 70, 0, 2, 255, 27, 0, 2, 0, 0, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 255, 10, 0, 15, 0, 15, 2, 255, 17, 0, 3, 0, 0, 0, 2, 15, 255, 6, 0, 2, 255, 23, 0, 15, 2, 255, 64, 0,
255, 34, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 8, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 2, 255, 31, 0, 2, 255, 19, 0, 2, 255, 15, 0, 3, 255, 15, 0, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 6, 0, 3, 255, 11, 0, 2, 255, 12, 0, 2, 255, 6, 0, 3, 255, 15, 0, 3, 255, 13, 0, 15, 255, 17, 0, 3, 255, 10, 0, 15, 2, 0, 2, 255, 5, 0, 3, 255, 16, 0, 2, 255, 8, 0, 2, 15, 255, 4, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 9, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 25, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 56, 0, 3, 255, 31, 0, 3, 255, 38, 0, 3, 255, 21, 0, 2, 255, 9, 0, 3, 255, 21, 0, 2, 255, 44, 0, 15, 255, 25, 0, 2, 0, 0, 15, 2, 0, 2, 255, 21, 0, 15, 0, 2, 0, 2, 255, 5, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 8, 0, 2, 255, 18, 0, 3, 0, 0, 0, 2, 255, 33, 0,
255, 10, 0, 2, 255, 18, 0, 3, 255, 68, 0, 2, 255, 20, 0, 3, 255, 10, 0, 2, 255, 7, 0, 3, 0, 0, 0, 2, 255, 8, 0, 3, 255, 18, 0, 3, 0, 0, 0, 2, 255, 15, 0, 2, 255, 31, 0, 2, 255, 19, 0, 2, 255, 15, 0, 3, 255, 8, 0, 15, 255, 6, 0, 2, 255, 7, 0, 2, 255, 7, 0, 3, 255, 4, 0, 2, 255, 4, 0, 2, 0, 3, 255, 11, 0, 2, 255, 12, 0, 2, 0, 2, 255, 4, 0, 15, 255, 15, 0, 3, 255, 14, 0, 2, 255, 5, 0, 15, 255, 10, 0, 3, 255, 19, 0, 3, 255, 16, 0, 2, 255, 22, 0, 3, 255, 8, 0, 2, 0, 0, 0, 3, 255, 14, 0, 2, 0, 0, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 76, 0, 3, 255, 25, 0, 2, 255, 5, 0, 3, 255, 18, 0, 3, 255, 6, 0, 2, 255, 24, 0, 3, 255, 13, 0, 2, 255, 31, 0, 2, 255, 56, 0, 3, 255, 31, 0, 3, 255, 38, 0, 3, 0, 0, 15, 255, 18, 0, 2, 255, 9, 0, 3, 0, 0, 2, 255, 18, 0, 2, 255, 9, 0, 2, 255, 23, 0, 15, 2, 255, 5, 0, 15, 255, 21, 0, 15, 255, 7, 0, 2, 255, 62, 0
};
uint16_t animation_couple_rain_delays[] = {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60};
uint16_t animation_couple_rain_offsets[] = {0, 475, 718, 961, 1222, 1476, 1734, 2002, 2276, 2528, 2787, 3050, 3304, 3567, 3824, 4106, 4382, 4650, 4916, 5208, 5459, 5731, 5988, 6243, 6497, 6769, 7004, 7263, 7543, 7790, 8035, 8288, 8522};
AnimationData animation_couple_rain = {&animation_couple_rain_colors[0], &animation_couple_rain_data[0], &animation_couple_rain_offsets[0], &animation_couple_rain_delays[0], false, 15, 32, 32, 32};
uint8_t animation_couple_snow_colors[] PROGMEM = {0, 0, 0, 255, 255, 255, 255, 60, 0, 248, 230, 196, 67, 47, 9, 34, 178, 10, 0, 142, 246, 246, 0, 73, 92, 0, 0, 27, 0, 255};
uint8_t animation_couple_snow_data[] PROGMEM = {
2, 3, 255, 39, 2, 3, 255, 14, 2, 3, 255, 11, 2, 3, 255, 10, 2, 3, 255, 45, 2, 3, 255, 24, 2, 3, 255, 47, 2, 3, 255, 6, 2, 3, 255, 36, 2, 3, 255, 10, 2, 3, 255, 4, 2, 3, 255, 21, 2, 3, 255, 16, 2, 3, 255, 84, 2, 3, 255, 20, 2, 3, 255, 18, 2, 3, 255, 7, 2, 3, 255, 40, 2, 3, 255, 42, 2, 3, 255, 25, 2, 3, 255, 12, 2, 3, 255, 9, 2, 3, 255, 27, 2, 3, 255, 8, 2, 3, 255, 6, 2, 3, 2, 2, 2, 3, 255, 9, 2, 5, 2, 2, 2, 5, 255, 25, 2, 4, 4, 4, 2, 2, 2, 9, 9, 9, 255, 22, 2, 255, 5, 4, 2, 255, 5, 9, 255, 4, 2, 3, 255, 16, 2, 255, 5, 4, 2, 9, 10, 10, 5, 9, 255, 16, 2, 3, 255, 4, 2, 4, 6, 5, 6, 4, 2, 9, 6, 5, 6, 9, 255, 12, 2, 3, 255, 9, 2, 5, 5, 5, 2, 2, 10, 5, 5, 5, 10, 255, 7, 2, 3, 255, 14, 2, 7, 7, 7, 2, 2, 2, 11, 11, 11, 255, 22, 2, 4, 4, 7, 4, 4, 2, 9, 9, 11, 9, 255, 4, 2, 3, 255, 17, 2, 4, 4, 7, 4, 4, 9, 9, 9, 11, 9, 9, 255, 8, 2, 3, 2, 2, 2, 3, 255, 8, 2, 5, 8, 8, 8, 2, 5, 2, 9, 9, 9, 5, 255, 18, 2, 3, 2, 2, 2, 8, 2, 8, 2, 2, 2, 8, 2, 8, 255, 22, 2, 6, 6, 2, 6, 6, 2, 2, 6, 2, 6, 255, 12, 2, 255, 32, 3,
0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 56, 0,
255, 15, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 56, 0,
255, 7, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 255, 34, 0,
0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 255, 34, 0,
0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 39, 0,
255, 12, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 35, 0,
255, 24, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 35, 0,
0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 58, 0,
0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 31, 0, 3, 255, 38, 0,
255, 5, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 53, 0, 2, 255, 38, 0,
255, 11, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 60, 0,
255, 11, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 20, 0, 3, 255, 6, 0, 3, 255, 32, 0,
0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 12, 0, 3, 255, 14, 0, 2, 255, 6, 0, 2, 255, 32, 0,
0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 5, 255, 24, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 18, 0, 3, 255, 35, 0,
255, 9, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 35, 0,
0, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 31, 0, 3, 255, 40, 0,
0, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 31, 0, 3, 255, 16, 0, 2, 255, 40, 0,
255, 23, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 7, 0, 2, 255, 57, 0,
255, 6, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 31, 0, 3, 255, 33, 0,
255, 6, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 33, 0,
255, 19, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 13, 0, 3, 255, 10, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 54, 0,
255, 30, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 26, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 39, 0,
255, 9, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 12, 0, 2, 255, 37, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 4, 0, 2, 255, 21, 0, 2, 255, 4, 0, 3, 255, 34, 0,
0, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 10, 0, 3, 255, 16, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 31, 0, 3, 255, 22, 0, 2, 255, 34, 0,
0, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 19, 0, 2, 255, 11, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 57, 0,
255, 6, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 41, 0,
255, 6, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 5, 0, 5, 255, 8, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 34, 0,
255, 22, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 13, 0, 3, 255, 8, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 11, 0, 3, 255, 24, 0, 2, 255, 34, 0,
255, 22, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 13, 0, 2, 255, 13, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 11, 0, 2, 255, 4, 0, 3, 255, 14, 0, 3, 255, 39, 0,
255, 4, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 17, 0, 3, 0, 0, 3, 255, 10, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 7, 0, 2, 255, 14, 0, 2, 255, 39, 0,
255, 4, 0, 2, 255, 4, 0, 3, 255, 5, 0, 2, 255, 8, 0, 3, 255, 11, 0, 3, 255, 10, 0, 3, 255, 13, 0, 2, 255, 24, 0, 2, 255, 6, 0, 3, 255, 24, 0, 3, 255, 15, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 6, 0, 3, 255, 4, 0, 2, 255, 10, 0, 2, 255, 4, 0, 2, 255, 15, 0, 3, 255, 5, 0, 2, 255, 4, 0, 3, 255, 4, 0, 3, 255, 6, 0, 2, 255, 14, 0, 3, 255, 16, 0, 3, 255, 52, 0, 2, 255, 20, 0, 2, 255, 10, 0, 3, 255, 7, 0, 2, 255, 7, 0, 2, 255, 4, 0, 3, 255, 18, 0, 3, 255, 7, 0, 3, 255, 8, 0, 2, 255, 31, 0, 3, 255, 10, 0, 2, 255, 25, 0, 2, 255, 5, 0, 3, 255, 6, 0, 2, 255, 9, 0, 2, 255, 8, 0, 3, 255, 12, 0, 3, 255, 5, 0, 2, 0, 0, 0, 3, 255, 4, 0, 2, 255, 6, 0, 2, 0, 0, 0, 2, 255, 11, 0, 3, 255, 8, 0, 3, 255, 6, 0, 3, 0, 0, 0, 3, 255, 39, 0, 2, 0, 0, 2, 255, 10, 0, 2, 255, 31, 0, 3, 255, 11, 0, 2, 255, 27, 0, 2, 0, 0, 0, 3, 255, 22, 0, 2, 255, 4, 0, 3, 255, 26, 0, 3, 255, 27, 0, 2, 255, 31, 0, 3, 255, 4, 0, 2, 0, 0, 0, 2, 255, 27, 0, 3, 0, 0, 0, 3, 255, 5, 0, 2, 255, 31, 0, 3, 255, 50, 0, 2, 255, 6, 0, 2, 255, 24, 0, 3, 255, 37, 0
};
uint16_t animation_couple_snow_delays[] = {110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110};
uint16_t animation_couple_snow_offsets[] = {0, 291, 580, 875, 1162, 1443, 1728, 2023, 2310, 2583, 2864, 3151, 3445, 3746, 4035, 4320, 4609, 4905, 5205, 5502, 5803, 6108, 6417, 6722, 7011, 7295, 7583, 7884, 8189, 8486, 8779, 9068, 9354};
AnimationData animation_couple_snow = {&animation_couple_snow_colors[0], &animation_couple_snow_data[0], &animation_couple_snow_offsets[0], &animation_couple_snow_delays[0], false, 10, 32, 32, 32};
uint8_t animation_heart_colors[] PROGMEM = {255, 0, 43, 255, 141, 174, 255, 174, 206, 255, 255, 255, 255, 100, 138, 255, 122, 149};
uint8_t animation_heart_data[] PROGMEM = {
255,24,1,2,2,1,2,2,255,10,1,2,5,4,2,7,6,2,255,9,1,2,4,3,7,7,6,2,255,10,1,2,2,6,2,2,255,13,1,2,255,38,1,2,2,2,1,1,1,2,2,2,255,6,1,2,3,4,3,2,1,2,7,7,6,2,255,5,1,2,4,5,4,3,2,3,3,7,6,2,255,5,1,2,3,4,255,4,3,7,7,6,2,255,6,1,2,6,6,7,7,7,6,6,2,255,8,1,2,2,6,7,6,2,2,255,11,1,2,6,2,255,14,1,2,255,10,1,
255,6,0,2,2,2,0,0,0,2,2,2,255,6,0,2,3,4,3,0,0,0,7,7,6,2,255,5,0,2,4,5,4,3,0,3,3,7,6,2,255,5,0,2,3,4,3,0,3,3,7,7,6,2,255,6,0,2,6,6,7,7,7,6,6,2,255,8,0,2,2,6,7,6,2,2,255,11,0,2,6,2,255,14,0,2,255,6,0,1,1,1,0,0,0,1,1,1,255,6,0,255,5,1,0,255,5,1,255,5,0,1,1,1,2,2,1,2,2,1,1,1,255,5,0,1,1,2,5,4,2,7,6,2,1,1,255,6,0,1,2,4,3,0,0,0,2,1,255,8,0,1,0,2,6,2,0,1,255,11,0,1,2,1,255,14,0,1,255,10,0
};
uint16_t animation_heart_delays[] = {500,500};
uint16_t animation_heart_offsets[] = {0,128,299};
AnimationData animation_heart = {&animation_heart_colors[0], &animation_heart_data[0], &animation_heart_offsets[0], &animation_heart_delays[0], false, 6, 2, 16, 16};
uint8_t animation_weather_icons_colors[] PROGMEM = {255, 255, 255, 216, 216, 216, 45, 79, 255, 165, 153, 1, 100, 124, 251, 255, 236, 0, 255, 157, 0, 217, 212, 144, 163, 159, 109, 129, 129, 129, 67, 67, 67, 255, 0, 0, 189, 0, 0, 36, 42, 242, 5, 10, 176};
uint8_t animation_weather_icons_data[] PROGMEM = {
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,113,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,5,1,4,1,4,1,4,1,4,1,4,255,7,1,4,1,4,1,4,1,4,1,4,255,7,1,4,1,4,1,4,1,4,1,4,255,23,1,4,1,4,1,4,1,4,1,4,255,7,1,4,1,4,1,4,1,4,1,4,255,7,1,4,1,4,1,4,1,4,1,4,255,3,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,5,1,4,1,4,1,1,5,1,1,1,5,255,6,1,4,1,4,1,1,5,5,1,1,5,255,6,1,4,1,4,1,1,1,5,1,5,255,13,1,5,5,5,255,7,1,4,1,4,255,4,1,5,5,255,7,1,4,1,4,255,4,1,5,255,8,1,4,1,4,255,4,1,5,255,4,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,5,1,4,1,4,1,1,5,255,10,1,4,1,4,1,1,5,5,255,9,1,4,1,4,1,1,1,5,255,15,1,5,5,5,255,7,1,4,1,4,255,5,1,5,255,7,1,4,1,4,1,1,1,5,5,255,8,1,4,1,4,1,1,1,5,255,5,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,5,1,4,1,4,1,1,5,255,10,1,4,1,4,1,1,5,5,255,9,1,4,1,4,1,1,1,5,255,15,1,5,255,9,1,4,1,4,1,1,1,5,255,9,1,4,1,4,255,4,1,5,255,8,1,4,1,4,255,4,1,5,255,4,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,7,1,4,1,1,1,4,255,11,1,4,1,1,1,4,255,13,1,4,255,15,1,4,255,13,1,4,1,1,1,4,255,11,1,4,1,1,1,4,255,13,1,4,255,7,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,35,1,255,12,3,255,19,1,255,14,3,255,20,1,255,10,3,255,3,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,23,1,6,1,6,1,4,255,12,1,6,6,6,255,12,1,255,4,6,4,255,12,1,6,6,4,255,12,1,4,1,4,1,4,255,21,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,11,1,6,1,6,1,4,1,1,6,1,6,1,4,255,5,1,6,6,6,255,4,1,6,6,6,255,5,1,255,4,6,4,1,1,255,4,6,4,255,5,1,6,6,4,255,4,1,6,6,4,255,5,1,4,1,4,1,4,1,1,4,1,4,1,4,255,26,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,4,1,4,1,4,1,4,1,1,6,1,6,1,4,1,1,6,1,6,1,4,255,5,1,6,6,6,255,4,1,6,6,6,255,5,1,255,4,6,4,1,1,255,4,6,4,255,5,1,6,6,4,255,4,1,6,6,4,255,5,1,4,1,4,1,4,1,1,4,1,4,1,4,1,6,1,6,1,4,255,12,1,6,6,6,255,5,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,10,1,4,1,1,1,4,1,1,1,6,1,6,1,4,1,1,1,4,1,1,1,4,255,4,1,6,6,6,255,12,1,255,4,6,4,1,1,1,4,1,1,1,4,255,4,1,6,6,4,255,4,1,4,1,1,1,4,1,1,1,4,1,4,1,4,255,19,1,4,1,1,1,4,1,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,11,1,4,255,6,1,6,1,6,1,4,255,4,1,4,255,7,1,6,6,6,255,12,1,255,4,6,4,255,12,1,6,6,4,255,5,1,4,255,6,1,4,1,4,1,4,255,4,1,4,255,21,1,
255,8,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,8,1,4,1,1,4,1,1,4,1,1,1,6,1,6,1,4,1,4,1,1,4,1,1,4,255,4,1,6,6,6,255,12,1,255,4,6,4,1,4,1,1,4,1,1,4,255,4,1,6,6,4,1,1,4,1,1,4,1,1,4,1,1,1,4,1,4,1,4,255,17,1,4,1,1,4,1,1,4,1,1,
255,7,1,7,7,255,14,1,7,7,255,8,1,7,7,1,1,255,6,7,1,1,7,7,1,1,255,14,7,1,1,1,255,4,7,255,4,8,255,4,7,255,4,1,7,7,7,255,6,8,7,7,7,255,4,1,7,7,255,8,8,7,7,1,1,255,4,7,255,8,8,255,8,7,255,8,8,255,4,7,1,1,7,7,255,8,8,7,7,255,4,1,7,7,7,255,6,8,7,7,7,255,4,1,255,4,7,255,4,8,255,4,7,1,1,1,255,14,7,1,1,7,7,1,1,255,6,7,1,1,7,7,255,8,1,7,7,255,14,1,7,7,255,7,1,
255,88,1,2,2,2,255,9,1,2,1,255,7,2,255,5,1,255,11,2,3,3,1,1,255,12,2,3,3,3,1,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,33,1,
255,32,1,7,1,1,7,7,1,1,7,255,9,1,255,6,7,255,10,1,7,7,8,8,7,7,255,9,1,7,7,255,4,8,7,7,255,8,1,7,7,255,4,8,7,7,255,9,1,7,7,8,8,7,7,1,2,2,2,255,6,1,255,5,7,255,7,2,3,1,1,7,1,1,7,7,1,255,6,2,3,3,3,255,6,1,255,7,2,255,4,3,255,5,1,255,6,2,255,4,3,255,5,1,255,5,2,255,7,3,255,48,1,
255,32,1,7,1,1,7,7,1,1,7,255,9,1,255,6,7,255,10,1,7,7,8,8,7,7,255,9,1,7,7,255,4,8,7,255,4,2,255,5,1,7,7,255,4,8,255,7,2,255,4,1,7,7,255,10,2,3,3,1,1,255,12,2,3,3,3,7,255,11,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,33,1,
255,34,1,9,9,11,11,255,11,1,9,9,11,11,12,11,255,9,1,9,10,9,255,5,11,255,8,1,9,9,11,11,12,11,11,255,4,2,255,5,1,9,10,255,4,11,255,7,2,1,1,1,9,9,9,255,10,2,3,3,1,1,255,12,2,3,3,3,255,12,2,255,4,3,255,12,2,255,4,3,1,255,10,2,255,4,3,1,1,255,8,2,255,7,3,1,1,255,5,2,255,8,3,255,33,1,
255,21,1,255,4,9,11,11,255,9,1,9,9,9,255,5,11,255,7,1,9,10,9,255,5,11,12,11,255,5,1,255,4,9,255,8,11,1,1,1,9,10,9,9,255,10,11,1,1,9,10,9,9,255,4,11,12,255,5,11,1,1,255,4,9,255,9,11,12,1,1,255,4,9,255,9,11,12,1,1,9,9,10,10,255,5,11,12,12,11,11,11,1,1,10,9,9,10,255,10,11,1,1,1,255,4,9,255,8,11,255,5,1,9,9,9,255,5,11,12,11,255,7,1,9,9,9,255,5,11,255,9,1,9,9,10,9,11,11,255,21,1,
255,34,1,9,9,11,11,255,11,1,9,9,11,11,12,11,255,9,1,9,10,9,255,5,11,255,8,1,9,9,11,12,12,11,11,11,255,8,1,9,10,255,5,11,12,255,8,1,9,9,9,11,12,12,11,255,4,2,255,6,1,9,9,11,11,11,255,7,2,3,255,4,1,10,9,12,11,255,6,2,3,3,3,255,6,1,255,7,2,255,4,3,255,5,1,255,6,2,255,4,3,255,5,1,255,5,2,255,7,3,255,48,1,
255,6,1,2,2,255,13,1,2,1,1,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,12,1,2,13,13,2,255,11,1,2,2,13,13,2,2,255,9,1,2,2,13,13,13,14,2,2,255,8,1,2,255,4,13,14,14,2,255,8,1,2,255,4,13,14,14,2,255,8,1,2,2,13,13,14,14,2,2,255,9,1,2,2,14,14,2,2,255,11,1,255,4,2,255,7,1,
255,6,1,2,2,255,13,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,1,1,2,255,12,1,2,15,15,2,255,11,1,2,2,15,15,2,2,255,9,1,2,2,15,15,15,16,2,2,255,8,1,2,255,4,15,16,16,2,255,8,1,2,255,4,15,16,16,2,255,8,1,2,2,15,15,16,16,2,2,255,9,1,2,2,16,16,2,2,255,11,1,255,4,2,255,7,1,
255,20,1,14,2,1,1,14,2,255,8,1,11,12,14,2,14,2,14,2,14,2,255,6,1,11,1,14,2,14,2,255,10,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,13,1,
255,20,1,14,2,14,2,255,10,1,11,12,14,2,14,2,14,2,14,2,255,6,1,11,1,14,2,1,1,14,2,255,8,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,13,1,
255,20,1,14,2,14,2,255,10,1,11,12,14,2,14,2,14,2,14,2,255,6,1,11,1,14,2,1,1,14,2,255,8,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,13,1,
255,20,1,14,2,14,2,255,10,1,11,12,14,2,14,2,14,2,255,8,1,11,1,14,2,1,1,14,2,14,2,255,6,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,13,1,
255,20,1,14,2,1,1,14,2,255,8,1,11,12,14,2,14,2,14,2,255,8,1,11,1,14,2,14,2,1,1,14,2,255,6,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,15,1,11,255,13,1
};
uint16_t animation_weather_icons_delays[] = {0};
uint16_t animation_weather_icons_offsets[] = {0,69,210,354,489,621,734,821,925,1061,1216,1359,1479,1627,1772,1841,1954,2060,2166,2308,2421,2551,2681,2763,2845,2927,3009,3093};
AnimationData animation_weather_icons = {&animation_weather_icons_colors[0], &animation_weather_icons_data[0], &animation_weather_icons_offsets[0], &animation_weather_icons_delays[0], false, 15, 27, 16, 16};
uint8_t animation_cake_colors[] PROGMEM = {91, 61, 0, 225, 225, 225, 184, 184, 113, 183, 123, 61, 255, 255, 142, 255, 174, 91, 255, 91, 91, 174, 174, 174, 255, 91, 174, 255, 40, 40, 255, 113, 40, 255, 40, 113, 174, 91, 255, 122, 82, 0, 255, 189, 122, 255, 255, 173};
uint8_t animation_cake_data[] PROGMEM = {
1,1,1,2,255,7,1,15,255,6,1,2,7,2,1,1,2,1,1,2,7,2,255,5,1,2,8,2,1,2,12,2,1,2,8,2,255,6,1,2,1,1,2,11,2,1,1,2,255,6,1,2,9,2,1,1,2,1,1,2,9,2,255,5,1,2,10,2,1,2,13,2,1,2,10,2,255,5,1,2,9,5,2,5,14,5,2,5,9,2,255,4,1,2,7,10,7,3,7,13,7,3,7,10,7,2,1,1,2,3,4,4,4,3,7,14,7,3,4,4,4,3,2,1,2,255,5,3,4,13,4,255,5,3,2,1,2,4,255,11,3,4,2,1,2,5,255,7,4,6,4,4,6,5,2,1,2,6,255,6,5,4,6,5,4,6,6,2,1,2,5,6,11,7,6,11,7,6,11,7,4,6,5,2,1,1,2,255,11,5,2,255,4,1,255,11,2,255,3,1,
255,11,0,2,255,23,0,11,0,0,0,7,0,0,0,11,255,11,0,12,255,200,0,
0,0,0,1,255,14,0,1,2,1,255,6,0,12,255,7,0,7,255,220,0,
0,0,0,2,255,7,0,1,255,6,0,2,0,2,255,5,0,1,2,1,255,10,0,5,0,0,0,7,255,11,0,7,255,200,0,
255,22,0,2,255,14,0,2,7,255,14,0,2,7,255,201,0,
255,39,0,2,1,255,12,0,1,2,255,201,0,
255,6,0,2,255,15,0,7,255,14,0,1,255,17,0,16,255,149,0,17,255,50,0,
255,6,0,1,255,15,0,1,255,15,0,2,5,2,0,0,2,255,11,0,5,255,149,0,6,255,50,0,
255,43,0,7,255,7,0,15,0,0,0,7,255,200,0
};
uint16_t animation_cake_delays[] = {80};
uint16_t animation_cake_offsets[] = {0,200,223,244,279,296,309,332,360,375};
AnimationData animation_cake = {
&animation_cake_colors[0],
&animation_cake_data[0],
&animation_cake_offsets[0],
&animation_cake_delays[0],
false, /* individual_frame_times */
16, /* color_count */
9, /* frames_count */
16, 16 /* width, height */
};

View File

@ -1,24 +1,21 @@
#include "effect_animation.h" #include "effect_animation.h"
#include "functions.h" #include "functions.h"
AnimationEffect::AnimationEffect(AnimationData* anim, CRGB* bg, int x, int y) { AnimationEffect::AnimationEffect(const char* name, CRGB* bg, int x, int y) {
this->animation_data = anim;
this->bg_color = bg; this->bg_color = bg;
this->xOffset = x; this->xOffset = x;
this->yOffset = y; this->yOffset = y;
}
void AnimationEffect::start() { this->animation = new Animation(name, window);
this->animation = new Animation(this->animation_data);
this->animation->setBgColor(this->bg_color); this->animation->setBgColor(this->bg_color);
this->animation->setOffsets(this->xOffset, this->yOffset); this->animation->setOffsets(this->xOffset, this->yOffset);
} }
void AnimationEffect::stop() { AnimationEffect::~AnimationEffect() {
delete this->animation; delete this->animation;
} }
void AnimationEffect::loop() { void AnimationEffect::loop() {
this->animation->drawFrame(this->window); this->animation->drawFrame();
this->animation->advance(); this->animation->advance();
} }

View File

@ -1,32 +1,33 @@
#include "effect_cycle.h" #include "effect_cycle.h"
#include "effects.h"
CycleEffect::CycleEffect() {
changeEffect();
}
CycleEffect::~CycleEffect() {
delete effect;
}
void CycleEffect::changeEffect() { void CycleEffect::changeEffect() {
int new_id; int new_id;
if (EFFECT_CYCLE_RANDOM) { if (EFFECT_CYCLE_RANDOM) {
do { do {
new_id = random8(cycle_effects->size()); new_id = random8(cycle_effects_count);
} while (new_id == effect_id); } while (new_id == effect_id);
} else { } else {
new_id = (effect_id + 1) % cycle_effects->size(); new_id = (effect_id + 1) % cycle_effects_count;
} }
LOG("CycleEffect * Changing effect from #"); LOG(effect_id); LOG(" to #"); LOGln(new_id); LOGln("CycleEffect * Changing effect from #%d to #%d", effect_id, new_id);
if (effect) effect->stop(); delay(25);
effect = cycle_effects->get(new_id); if (effect) delete effect;
effect->start(); LOGln("CycleEffect * Searching for new effect '%s'", cycle_effects[new_id]);
delay(25);
effect = string_to_effect(cycle_effects[new_id]);
effect_id = new_id; effect_id = new_id;
effectSince = millis(); effectSince = millis();
} }
void CycleEffect::start() {
if (!effect) changeEffect();
else effect->start();
}
void CycleEffect::stop() {
effect_id = -1;
if (effect) effect->stop();
}
boolean CycleEffect::can_be_shown_with_clock() { boolean CycleEffect::can_be_shown_with_clock() {
return effect->can_be_shown_with_clock(); return effect->can_be_shown_with_clock();
}; };

View File

@ -4,13 +4,13 @@
#include "my_fastled.h" #include "my_fastled.h"
#include "functions.h" #include "functions.h"
void FireEffect::start() { FireEffect::FireEffect() {
this->data = new uint8_t[this->window->width * this->window->height]; this->data = new uint8_t[this->window->width * this->window->height];
for (int i=0; i<(this->window->width * this->window->height); i++) this->data[i]=0; for (int i=0; i<(this->window->width * this->window->height); i++) this->data[i]=0;
for (int i=0; i<this->window->width; i++) this->data[i]=this->spark_temp(); for (int i=0; i<this->window->width; i++) this->data[i]=this->spark_temp();
} }
void FireEffect::stop() { FireEffect::~FireEffect() {
delete [] this->data; delete [] this->data;
} }

View File

@ -3,11 +3,7 @@
GolEffect::GolEffect() { GolEffect::GolEffect() {
this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6); this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
}
bool GolEffect::can_be_shown_with_clock() { return true; }
void GolEffect::start() {
_data = new uint8_t[this->window->count]; _data = new uint8_t[this->window->count];
_old = new uint8_t[this->window->count]; _old = new uint8_t[this->window->count];
for(uint16_t i=0; i<this->window->count; i++) { for(uint16_t i=0; i<this->window->count; i++) {
@ -16,6 +12,8 @@ void GolEffect::start() {
_initialize(); _initialize();
} }
bool GolEffect::can_be_shown_with_clock() { return true; }
void GolEffect::_initialize() { void GolEffect::_initialize() {
for(uint16_t i=0; i<this->window->count; i++) { for(uint16_t i=0; i<this->window->count; i++) {
_data[i] = random8() < EFFECT_GOL_START_PERCENTAGE ? 1 : 0; _data[i] = random8() < EFFECT_GOL_START_PERCENTAGE ? 1 : 0;
@ -25,7 +23,7 @@ void GolEffect::_initialize() {
_step = 0; _step = 0;
} }
void GolEffect::stop() { GolEffect::~GolEffect() {
delete[] _data; delete[] _data;
delete[] _old; delete[] _old;
} }

View File

@ -2,17 +2,14 @@
#include "my_color_palettes.h" #include "my_color_palettes.h"
#include "functions.h" #include "functions.h"
MatrixEffectColumn::MatrixEffectColumn() { MatrixEffectColumn::MatrixEffectColumn(Window* win, int xPos) {
}
MatrixEffectColumn::MatrixEffectColumn(Window* win, int xPos) : MatrixEffectColumn() {
window = win; window = win;
x = xPos; x = xPos;
start(); restart();
y = random8(0, window->height); y = random8(0, window->height);
} }
void MatrixEffectColumn::start() { void MatrixEffectColumn::restart() {
y=-1; y=-1;
length = random8(EFFECT_MATRIX_LENGTH_MIN, EFFECT_MATRIX_LENGTH_MAX); length = random8(EFFECT_MATRIX_LENGTH_MIN, EFFECT_MATRIX_LENGTH_MAX);
running = true; running = true;
@ -26,12 +23,7 @@ void MatrixEffectColumn::advance() {
void MatrixEffectColumn::draw() { void MatrixEffectColumn::draw() {
for(int i=0; i<length; i++) { for(int i=0; i<length; i++) {
CRGB color; CRGB color = _getColor(i);
if (i==0) {
color = CRGB(255, 255, 255);
} else {
color = ColorFromPalette((CRGBPalette16)palette_matrix, 255 * (length - i) / length);
}
window->setPixel(x, y-i, &color); window->setPixel(x, y-i, &color);
} }
} }
@ -40,7 +32,7 @@ void MatrixEffectColumn::loop() {
if (!running) { if (!running) {
if (random8() < 20) { if (random8() < 20) {
// Start the column again. // Start the column again.
start(); restart();
} }
} else { } else {
if (millis() - last_move > speed) { if (millis() - last_move > speed) {
@ -52,21 +44,78 @@ void MatrixEffectColumn::loop() {
} }
} }
CRGB MatrixEffectColumn::_getColor(uint8_t i) {
CRGB color;
if (i==0) {
color = CRGB(255, 255, 255);
} else {
color = CHSV(83, 255, 255 * (length - i) / length);
}
return color;
}
CRGB RainbowMatrixEffectColumn::_getColor(uint8_t i) {
CRGB color;
if (i==0) {
color = CRGB(255, 255, 255);
} else {
color = CHSV(255 * x / window->width, 255, 255 * (length - i) / length);
}
return color;
}
CRGB RandomMatrixEffectColumn::_getColor(uint8_t i) {
CRGB color;
//Serial.print("RandomMatrixEffectColumn::_getColor, hue="); Serial.println(_hue);
if (i==0) {
color = CRGB(255, 255, 255);
} else {
color = CHSV(_hue, 255, 255 * (length - i) / length);
}
return color;
}
void RandomMatrixEffectColumn::restart() {
MatrixEffectColumn::restart();
_hue = random8();
}
boolean MatrixEffect::can_be_shown_with_clock() { return true; }; boolean MatrixEffect::can_be_shown_with_clock() { return true; };
MatrixEffect::MatrixEffect() { MatrixEffect::MatrixEffect() {
_columns = new MatrixEffectColumn* [window->width];
_init();
} }
void MatrixEffect::start() { void MatrixEffect::_init() {
_columns = new MatrixEffectColumn[LED_WIDTH]; for (int i=0; i<window->width; i++) _columns[i] = new MatrixEffectColumn(window, i);
for (int i=0; i<LED_WIDTH; i++) _columns[i] = MatrixEffectColumn(window, i);
} }
void MatrixEffect::stop() { void RandomMatrixEffect::_init() {
for (int i=0; i<window->width; i++) _columns[i] = new RandomMatrixEffectColumn(window, i);
}
void RainbowMatrixEffect::_init() {
for (int i=0; i<window->width; i++) _columns[i] = new RainbowMatrixEffectColumn(window, i);
}
MatrixEffect::~MatrixEffect() {
for (int i=0; i<window->width; i++) {
delete _columns[i];
}
delete[] _columns; delete[] _columns;
} }
void MatrixEffect::loop() { void MatrixEffect::loop() {
window->clear(); window->clear();
for (int i=0; i<window->width; i++) _columns[i].loop(); for (int i=0; i<window->width; i++) _columns[i]->loop();
} }

View File

@ -2,15 +2,12 @@
#include "ntp.h" #include "ntp.h"
PixelClockEffect::PixelClockEffect() { PixelClockEffect::PixelClockEffect() {
window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-7); window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
}
void PixelClockEffect::start() {
_color_seconds = new CRGB(0x00FF00); _color_seconds = new CRGB(0x00FF00);
_color_minutes = new CRGB(0xFFFF00); _color_minutes = new CRGB(0xFFFF00);
} }
void PixelClockEffect::stop() { PixelClockEffect::~PixelClockEffect() {
delete _color_seconds; delete _color_seconds;
delete _color_minutes; delete _color_minutes;
} }
@ -23,14 +20,14 @@ void PixelClockEffect::loop() {
for (uint8_t s=0; s<60; s++) { for (uint8_t s=0; s<60; s++) {
x = window->width - 1 - s/10; x = window->width - 1 - s/10;
y = window->height - 1 - (s % 10); y = window->height - 1 - (s % 10);
if (s<=seconds) window->setPixel(x, y, _color_seconds); if (s<seconds) window->setPixel(x, y, _color_seconds);
} }
uint8_t minutes = ntpClient.getMinutes(); uint8_t minutes = ntpClient.getMinutes();
for (uint8_t m=0; m<60; m++) { for (uint8_t m=0; m<60; m++) {
x = 6 - m/10; x = 6 - m/10;
y = window->height - 1 - (m % 10); y = window->height - 1 - (m % 10);
if (m<=minutes) window->setPixel(x, y, _color_seconds); if (m<minutes) window->setPixel(x, y, _color_minutes);
} }
} }

View File

@ -1,7 +1,6 @@
#include "effects.h" #include "effects.h"
#include "animations.h"
#include "my_fastled.h" #include "my_fastled.h"
#include "EffectEntry.h" #include <ErriezCRC32.h>
#include "effect_bell.h" #include "effect_bell.h"
#include "effect_sinematrix3.h" #include "effect_sinematrix3.h"
#include "effect_big_clock.h" #include "effect_big_clock.h"
@ -19,65 +18,51 @@
#include "effect_gol.h" #include "effect_gol.h"
#include "effect_pixelclock.h" #include "effect_pixelclock.h"
SimpleList<EffectEntry>* effects;
SimpleList<Effect*>* cycle_effects;
ClockEffect effect_clock;
Sinematrix3Effect effect_sinematrix3;
BigClockEffect effect_big_clock;
//ClockEffect effect_clock; <-- generated as global variable in effects.h
BellEffect effect_bell;
StaticEffect effect_off(CRGB(0x000000));
AnimationEffect effect_anim_koopa(&animation_koopa, new CRGB(0x000000), 0, 0);
AnimationEffect effect_anim_couple_rain(&animation_couple_rain, new CRGB(0x000000), -8, -16);
AnimationEffect effect_anim_heart(&animation_heart, new CRGB(0x000000), 0, 0);
AnimationEffect effect_anim_cake(&animation_cake, new CRGB(0x000000), 0, 0);
SingleDynamicEffect effect_single_dynamic;
MultiDynamicEffect effect_multi_dynamic;
MatrixEffect effect_matrix;
CycleEffect effect_cycle;
TwirlEffect effect_twirl;
ConfettiEffect effect_confetti;
SnakeEffect effect_snake;
FireEffect effect_fire;
FireworkEffect effect_firework;
GolEffect effect_gol;
PixelClockEffect effect_pixelclock;
Effect* current_effect; Effect* current_effect;
void setup_effects() { ClockEffect effect_clock;
effects = new SimpleList<EffectEntry>();
cycle_effects = new SimpleList<Effect*>();
effects->add((EffectEntry){"sinematrix3", (Effect *)&effect_sinematrix3}); Effect* string_to_effect(String name) {
effects->add((EffectEntry){"big_clock", (Effect *)&effect_big_clock}); uint32_t crc = crc32String(name.c_str());
effects->add((EffectEntry){"clock", (Effect *)&effect_clock}); switch (crc) {
effects->add((EffectEntry){"bell", (Effect *)&effect_bell}); // use e.g. https://crccalc.com/ for the conversion of name to crc.
effects->add((EffectEntry){"off", (Effect *)&effect_off}); case 0xD682E3C8 /* sinematrix3 */ : return new Sinematrix3Effect();
effects->add((EffectEntry){"koopa", (Effect *)&effect_anim_koopa}); case 0x90A887DA /* big_clock */ : return new BigClockEffect();
effects->add((EffectEntry){"couple_rain", (Effect *)&effect_anim_couple_rain}); case 0xBE7BBE92 /* clock */ : return new ClockEffect();
effects->add((EffectEntry){"single_dynamic", (Effect *)&effect_single_dynamic}); case 0x733BE087 /* bell */ : return new BellEffect();
effects->add((EffectEntry){"multi_dynamic", (Effect *)&effect_multi_dynamic}); case 0x2BBC5D43 /* off */ : return new StaticEffect(0x000000);
effects->add((EffectEntry){"matrix", (Effect *)&effect_matrix}); case 0x1D84F231 /* koopa */ : return new AnimationEffect("/koopa.pia", new CRGB(0x000000), 0, 0);
effects->add((EffectEntry){"cycle", (Effect *)&effect_cycle}); case 0xAC43BCF1 /* couple_rain */ : return new AnimationEffect("/couple_rain.pia", new CRGB(0x000000), -8, -16);
effects->add((EffectEntry){"twirl", (Effect *)&effect_twirl}); case 0xF1B117F7 /* single_dynamic */ : return new SingleDynamicEffect();
effects->add((EffectEntry){"heart", (Effect*)&effect_anim_heart}); case 0xF52F2804 /* multi_dynamic */ : return new MultiDynamicEffect();
effects->add((EffectEntry){"confetti", (Effect *)&effect_confetti}); case 0xF83341CF /* matrix */ : return new MatrixEffect();
effects->add((EffectEntry){"snake", (Effect *)&effect_snake}); case 0xD2B79DD0 /* rainbow_matrix */ : return new RainbowMatrixEffect();
effects->add((EffectEntry){"fire", (Effect *)&effect_fire}); case 0xE8DD3433 /* random_matrix */ : return new RandomMatrixEffect();
effects->add((EffectEntry){"firework", (Effect *)&effect_firework}); case 0xB086D193 /* cycle */ : return new CycleEffect();
effects->add((EffectEntry){"gol", (Effect *)&effect_gol}); case 0x2293EF9F /* twirl */ : return new TwirlEffect();
effects->add((EffectEntry){"cake", (Effect *)&effect_anim_cake}); case 0x60ECC3E6 /* heart */ : return new AnimationEffect("/heart.pia", new CRGB(0x000000), 0, 0);
effects->add((EffectEntry){"pixel_clock", (Effect *)&effect_pixelclock}); case 0x42090A49 /* confetti */ : return new ConfettiEffect();
case 0x516D6B9E /* snake */ : return new SnakeEffect();
cycle_effects->add(&effect_sinematrix3); case 0x58DE09CF /* fire */ : return new FireEffect();
cycle_effects->add(&effect_multi_dynamic); case 0x08BA9C08 /* firework */ : return new FireworkEffect();
cycle_effects->add(&effect_matrix); case 0x14B85EAC /* gol */ : return new GolEffect();
cycle_effects->add(&effect_confetti); case 0xFA13015D /* cake */ : return new AnimationEffect("/cake.pia", new CRGB(0x000000), 0, 0);
cycle_effects->add(&effect_single_dynamic); case 0xA2B0D68B /* pixel_clock */ : return new PixelClockEffect();
cycle_effects->add(&effect_snake); default : return NULL;
cycle_effects->add(&effect_gol); };
}
current_effect = &effect_cycle;
bool change_current_effect(String name) {
Effect* new_effect = string_to_effect(name);
if (new_effect == NULL) return false;
delete current_effect;
current_effect = new_effect;
return true;
}
const char* cycle_effects[] = {"sinematrix3", "multi_dynamic", "matrix", "confetti", "single_dynamic", "snake", "gol"};
uint8_t cycle_effects_count = 7;
void setup_effects() {
current_effect = new CycleEffect();
} }

View File

@ -6,6 +6,7 @@
#include "effects.h" #include "effects.h"
#include "my_wifi.h" #include "my_wifi.h"
#include "prototypes.h" #include "prototypes.h"
#include <FS.h>
#if defined( ESP8266 ) #if defined( ESP8266 )
ESP8266WebServer http_server(HTTP_SERVER_PORT); ESP8266WebServer http_server(HTTP_SERVER_PORT);
@ -13,6 +14,26 @@ ESP8266WebServer http_server(HTTP_SERVER_PORT);
ESP32WebServer http_server(HTTP_SERVER_PORT); ESP32WebServer http_server(HTTP_SERVER_PORT);
#endif #endif
File upload_file;
void http_server_handle_file_upload() {
if (http_server.uri() != "/upload") return;
HTTPUpload upload = http_server.upload();
if (upload.status == UPLOAD_FILE_START) {
String filename = upload.filename;
if (!filename.startsWith("/")) filename = "/" + filename;
LOGln("HTTP * Upload of %s starting...", upload.filename.c_str());
upload_file = SPIFFS.open(filename, "w");
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (upload_file) upload_file.write(upload.buf, upload.currentSize);
} else if (upload.status == UPLOAD_FILE_END) {
if (upload_file) upload_file.close();
LOGln("HTTP * Upload of %s with %d bytes done.", upload.filename.c_str(), upload.totalSize);
}
}
void http_server_400() { void http_server_400() {
http_server.send(400); http_server.send(400);
} }
@ -21,8 +42,43 @@ void http_server_setup() {
PGM_P text_plain = PSTR("text/plain"); PGM_P text_plain = PSTR("text/plain");
http_server.on("/", HTTP_GET, [&](){ http_server.on("/", HTTP_GET, [&](){
LOGln("HTTP * GET /"); LOGln("HTTP * GET /");
http_server.send_P(200, text_plain, PSTR("Welcome to pitrix.")); String message = "<html><head><title>Pitrix</title></head><body><h1>Pitrix</h1><p>Known animations:</p>";
if (!SPIFFS.begin()) {
message += "<strong>No SPIFFS file system found.</strong>";
} else {
message += "<ul>";
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
message += "<li>" + dir.fileName() + " (<a href='/delete?" + dir.fileName() + "'>delete</a>)</li>";
}
message += "</ul>";
message += "<form action='/upload' method='POST'><input type='file' name='file' /><input type='submit' value='Upload file' /></form>";
}
message += "</body></html>";
http_server.send(200, "text/html", message);
}); });
http_server.on("/delete", HTTP_GET, [&]() {
LOGln("HTTP * GET /delete");
if (http_server.args()==0) {
http_server.send_P(400, text_plain, PSTR("No filename given"));
return;
}
String file = http_server.arg(0);
if (file == "/") {
http_server.send_P(400, text_plain, PSTR("Invalid path"));
return;
}
if (!SPIFFS.exists(file)) {
http_server.send_P(400, text_plain, PSTR("File does not exist."));
return;
}
SPIFFS.remove(file);
http_server.send_P(200, text_plain, PSTR("OK"));
});
http_server.on("/upload", HTTP_POST, []() {
LOGln("HTTP * POST /upload");
http_server.send(200, "text/plain", "OK");
}, http_server_handle_file_upload);
http_server.on("/free_heap", HTTP_GET, [&](){ http_server.on("/free_heap", HTTP_GET, [&](){
LOGln("HTTP * GET /free_heap"); LOGln("HTTP * GET /free_heap");
http_server.send(200, "text/plain", String(ESP.getFreeHeap())); http_server.send(200, "text/plain", String(ESP.getFreeHeap()));
@ -40,7 +96,7 @@ void http_server_setup() {
ESP.restart(); ESP.restart();
}); });
http_server.on("/brightness", HTTP_POST, [&](){ http_server.on("/brightness", HTTP_POST, [&](){
LOG("HTTP * POST /brightness with value "); LOGln(http_server.arg("plain")); LOGln("HTTP * POST /brightness with value %s", http_server.arg("plain").c_str());
if (!http_server.hasArg("plain")) { if (!http_server.hasArg("plain")) {
http_server.send_P(400, text_plain, PSTR("No brightness given")); http_server.send_P(400, text_plain, PSTR("No brightness given"));
return; return;
@ -54,23 +110,17 @@ void http_server_setup() {
http_server.send(200, "text/plain", "OK"); http_server.send(200, "text/plain", "OK");
}); });
http_server.on("/mode", HTTP_POST, [&](){ http_server.on("/mode", HTTP_POST, [&](){
LOGln("HTTP * POST /mode with value "); LOGln(http_server.arg("plain")); LOGln("HTTP * POST /mode with value %s", http_server.arg("plain").c_str());
if (!http_server.hasArg("plain")) { if (!http_server.hasArg("plain")) {
http_server.send_P(400, text_plain, PSTR("No effect given.")); http_server.send_P(400, text_plain, PSTR("No effect given."));
return; return;
} }
String val = http_server.arg("plain"); String val = http_server.arg("plain");
for (int i=0; i<effects->size(); i++) { if (change_current_effect(val)) {
EffectEntry e = effects->get(i); http_server.send(200, "text/plain", "OK");
if (val.compareTo(e.name)==0) { } else {
current_effect->stop(); http_server.send_P(400, text_plain, PSTR("Unknown effect."));
current_effect = e.effect;
current_effect->start();
http_server.send(200, "text/plain", "OK");
return;
}
} }
http_server.send_P(400, text_plain, PSTR("Unknown effect."));
}); });
http_server.begin(); http_server.begin();

View File

@ -7,7 +7,6 @@
#include "my_wifi.h" #include "my_wifi.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#include "EffectEntry.h"
#include "Effect.h" #include "Effect.h"
#include "effects.h" #include "effects.h"
#include "functions.h" #include "functions.h"
@ -24,11 +23,11 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
String payload((char*)pl); String payload((char*)pl);
String topic (original_topic); String topic (original_topic);
if (topic.compareTo(MQTT_TOPIC "log")==0) return; if (topic.compareTo(MQTT_TOPIC "log")==0) return;
LOG("MQTT * Received data for topic "); LOG(topic); LOG(" with payload "); LOGln(payload); LOGln("MQTT * In: %s = %s", topic.c_str(), payload.c_str());
if (topic.startsWith(MQTT_TOPIC_WEATHER)) { if (topic.startsWith(MQTT_TOPIC_WEATHER)) {
// Weather stuff // Weather stuff
topic.remove(0, strlen(MQTT_TOPIC_WEATHER)); topic.remove(0, strlen(MQTT_TOPIC_WEATHER));
LOG("MQTT * Weather stuff. Remaining topic: "); LOGln(topic.c_str()); LOGln("MQTT * Weather stuff.");
if (topic.startsWith("icons/")) { if (topic.startsWith("icons/")) {
topic.remove(0, 6); topic.remove(0, 6);
uint8_t id = topic.toInt(); uint8_t id = topic.toInt();
@ -36,7 +35,7 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
uint8_t val = payload.toInt(); uint8_t val = payload.toInt();
if (val==0) return; if (val==0) return;
weather_icon_ids[id] = val; weather_icon_ids[id] = val;
LOG("Set weather_icon_ids["); LOG(id); LOG("] to value "); LOGln(val); LOGln("Set weather_icon_ids[%d] to value %d", id, val);
} else if (topic.startsWith("temperatures/")) { } else if (topic.startsWith("temperatures/")) {
topic.remove(0, 13); topic.remove(0, 13);
uint8_t id = topic.toInt(); uint8_t id = topic.toInt();
@ -44,14 +43,13 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
uint8_t val = payload.toInt(); uint8_t val = payload.toInt();
if (val==0) return; if (val==0) return;
weather_temperatures[id] = val; weather_temperatures[id] = val;
LOG("Set weather_temperatures["); LOG(id); LOG("] to value "); LOGln(val); LOGln("Set weather_temperatures[%d] to value %d", id, val);
} }
return; return;
} }
topic.remove(0, strlen(MQTT_TOPIC)); // Strip MQTT_TOPIC from the beginning topic.remove(0, strlen(MQTT_TOPIC)); // Strip MQTT_TOPIC from the beginning
LOG("MQTT * Remaining topic is: "); LOGln(topic.c_str());
if (topic.compareTo("free_heap")==0 || topic.compareTo("uptime")==0 || topic.compareTo("status")==0 || topic.compareTo("fps")==0) { if (topic.compareTo("free_heap")==0 || topic.compareTo("uptime")==0 || topic.compareTo("status")==0 || topic.compareTo("fps")==0) {
// Ignore our own messages. // Ignore our own messages.
return; return;
@ -59,38 +57,34 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
if(topic.compareTo("mode")==0) { if(topic.compareTo("mode")==0) {
LOGln("MQTT * Changing mode..."); LOGln("MQTT * Changing mode...");
for (int i=0; i<effects->size(); i++) { change_current_effect(payload);
EffectEntry e = effects->get(i); return;
if (payload.compareTo(e.name)==0) {
//Serial.printf("Effect found in mqtt_callback: %p\n", (void *)&e->effect);
current_effect->stop();
current_effect = e.effect;
current_effect->start();
return;
}
}
} else if (topic.compareTo("reboot")==0) { } else if (topic.compareTo("reboot")==0) {
LOGln("MQTT * Rebooting"); LOGln("MQTT * Rebooting");
ESP.restart(); ESP.restart();
return; // Will never be reached, but anyway...
} }
long value = payload.toInt(); long value = payload.toInt();
LOG("MQTT * payload after converting to a number: "); LOGln(value); LOGln("MQTT * Payload as number: %d", value);
if (topic.compareTo("brightness")==0) { if (topic.compareTo("brightness")==0) {
if (value > 0 && value <= 255) { if (value > 0 && value <= 255) {
LOGln("MQTT * Changing brightness..."); LOGln("MQTT * Changing brightness...");
FastLED.setBrightness(value); FastLED.setBrightness(value);
} else { } else {
LOG("MQTT * Ignoring brightness change: Value "); LOG(value); LOGln(" is out of bounds (0<x<=255)."); LOGln("MQTT * Ignoring brightness change: Value %d is out of bounds (0<x<=255).", value);
} }
return;
} }
LOGln("MQTT * Topic was not processed.");
} }
boolean mqtt_connect() { boolean mqtt_connect() {
LOG("MQTT * Connecting to MQTT server with client id "); LOGln(hostname); LOG("MQTT * Connecting to MQTT server with client id %s", hostname);
if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) { if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
LOGln("MQTT * Connected."); LOGln("MQTT * Connected.");
mqtt_client.publish(MQTT_TOPIC "status", "ONLINE"); mqtt_client.publish(MQTT_TOPIC "status", "ONLINE", true);
mqtt_client.subscribe(MQTT_TOPIC "+"); mqtt_client.subscribe(MQTT_TOPIC "+");
mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#"); mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#");
} }
@ -137,6 +131,7 @@ void mqtt_log(int number) {
void mqtt_log(long unsigned int number) { mqtt_log(String(number).c_str()); } void mqtt_log(long unsigned int number) { mqtt_log(String(number).c_str()); }
void mqtt_log(long int number) { mqtt_log(String(number).c_str()); } void mqtt_log(long int number) { mqtt_log(String(number).c_str()); }
void mqtt_log(size_t number) { mqtt_log(String(number).c_str()); }
void mqtt_log(String str) { mqtt_log(str.c_str()); } void mqtt_log(String str) { mqtt_log(str.c_str()); }
@ -146,6 +141,7 @@ void mqtt_log_ln(int number) {
void mqtt_log_ln(long unsigned int number) { mqtt_log_ln(String(number).c_str()); } void mqtt_log_ln(long unsigned int number) { mqtt_log_ln(String(number).c_str()); }
void mqtt_log_ln(long int number) { mqtt_log_ln(String(number).c_str()); } void mqtt_log_ln(long int number) { mqtt_log_ln(String(number).c_str()); }
void mqtt_log_ln(size_t number) { mqtt_log_ln(String(number).c_str()); }
void mqtt_log_ln(String str) { mqtt_log_ln(str.c_str()); } void mqtt_log_ln(String str) { mqtt_log_ln(str.c_str()); }

View File

@ -31,7 +31,7 @@ void ota_setup() {
else if (error == OTA_END_ERROR) Serial.println("End Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed");
}); });
LOG("OTA * Starting OTA with client_id "); LOGln(hostname); LOGln("OTA * Starting OTA with client_id %s", hostname);
ArduinoOTA.setHostname(hostname); ArduinoOTA.setHostname(hostname);
ArduinoOTA.begin(); ArduinoOTA.begin();
} }

View File

@ -3,11 +3,9 @@
#include "ntp.h" #include "ntp.h"
#include "config.h" #include "config.h"
#include "animations.h"
#include "my_wifi.h" #include "my_wifi.h"
#include "ota.h" #include "ota.h"
#include "my_fastled.h" #include "my_fastled.h"
#include "EffectEntry.h"
#include "my_mqtt.h" #include "my_mqtt.h"
#include "functions.h" #include "functions.h"
#include "effects.h" #include "effects.h"
@ -43,9 +41,8 @@ void setup() {
#ifdef MQTT_ENABLE #ifdef MQTT_ENABLE
mqtt_setup(); mqtt_setup();
#endif #endif
SPIFFS.begin();
LOGln("Core * Setup complete"); LOGln("Core * Setup complete");
current_effect->start();
} }
void loop() { void loop() {
@ -100,9 +97,9 @@ void loop() {
if (MONITOR_LOOP_TIMES && millis()-loop_started_at>=MONITOR_LOOP_TIME_THRESHOLD) { if (MONITOR_LOOP_TIMES && millis()-loop_started_at>=MONITOR_LOOP_TIME_THRESHOLD) {
LOG("Core * Loop took "); LOG(millis()-loop_started_at); LOGln("ms."); //LOG("Core * Loop took "); LOG(millis()-loop_started_at); LOGln("ms.");
loop_timeouts++; loop_timeouts++;
LOG("Core * Timeout counter is now "); LOGln(loop_timeouts); //LOG("Core * Timeout counter is now "); LOGln(loop_timeouts);
if (loop_timeouts >= MONITOR_LOOP_TIME_COUNT_MAX) { if (loop_timeouts >= MONITOR_LOOP_TIME_COUNT_MAX) {
ESP.restart(); ESP.restart();
} }

View File

@ -21,7 +21,7 @@ def compress(data, use_cutoff=true)
if x == last if x == last
count += 1 count += 1
end end
if x!=last || count==255 if x!=last || count==255
if use_cutoff if use_cutoff
if count <= cutoff if count <= cutoff
@ -47,7 +47,7 @@ def compress(data, use_cutoff=true)
end end
return result return result
end end
unless ARGV[0] unless ARGV[0]
puts "Usage:" puts "Usage:"
puts "#{$0} <gif_file> [OPTIONS]" puts "#{$0} <gif_file> [OPTIONS]"
@ -58,7 +58,7 @@ unless ARGV[0]
puts puts
puts "Resulting data format is described in animations.h" puts "Resulting data format is described in animations.h"
exit 1 exit 1
end end
image_file=ARGV[0] image_file=ARGV[0]
full_frames = ARGV.include?("--full-frames") full_frames = ARGV.include?("--full-frames")
@ -99,8 +99,6 @@ STDERR.puts "Using #{colors.count} colors."
raise "Number of colors has to be 255 or less!" if colors.count>255 raise "Number of colors has to be 255 or less!" if colors.count>255
STDERR.puts STDERR.puts
puts
puts "uint8_t animation_#{name}_colors[] PROGMEM = {#{colors[2..-1].map{|c| [c>>24 & 0xFF, c>>16 & 0xFF, c>>8 & 0xFF]}.flatten.join(", ")}};"
p_frame = nil p_frame = nil
frames_data = [] frames_data = []
@ -124,7 +122,7 @@ frames.each_with_index do |frame, index|
frame.columns.times do |x| frame.columns.times do |x|
color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)[1,8].to_i(16) color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)[1,8].to_i(16)
p_color = p_frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)[1,8].to_i(16) p_color = p_frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)[1,8].to_i(16)
if color==p_color && !full_frames if color==p_color && !full_frames
data << 0 data << 0
elsif transparent.include? color elsif transparent.include? color
@ -144,7 +142,7 @@ frames.each_with_index do |frame, index|
times << old_time + time times << old_time + time
end end
p_frame = frame p_frame = frame
if DEBUG if DEBUG
STDERR.puts "Frame ##{index}:" STDERR.puts "Frame ##{index}:"
total_y.times do |y| total_y.times do |y|
@ -158,25 +156,27 @@ end
data = frames_data.map{|d| compress(d, true)} data = frames_data.map{|d| compress(d, true)}
individual_frame_times = times.uniq.count>1
times = [times[0]] unless individual_frame_times
puts "uint8_t animation_#{name}_data[] PROGMEM = {\n #{data.map{|d| d.join(",")}.join(",\n ")}\n};"
puts "uint16_t animation_#{name}_delays[] = {#{times.join(",")}};"
s=0 s=0
puts "uint16_t animation_#{name}_offsets[] = {#{(data.map{|d| t=s; s+=d.count; t} + [s]).join(",")}};" d = "PIA\x01__" +
[total_x, total_y].pack("C*") +
[frames_data.count, colors.count-2].pack("C*") +
colors[2..-1].map{|c| [c>>24 & 0xFF, c>>16 & 0xFF, c>>8 & 0xFF]}.flatten.pack("C*") +
times.pack("n*") +
(data.map{|d| d.count}).pack("n*") +
data.flatten.pack("C*")
dd = "PIA\x01__" +
"XY:" + [total_x, total_y].pack("C*") +
"FC,CC:" + [frames_data.count, colors.count-2].pack("C*") +
"COLORS:" + colors[2..-1].map{|c| [c>>24 & 0xFF, c>>16 & 0xFF, c>>8 & 0xFF]}.flatten.pack("C*") +
"TIME:" + times.pack("n*") +
"LENGTHS:" + (data.map{|d| d.count}).pack("n*") +
"DATA:" + data.flatten.pack("C*")
size = d.length
d[4] = (size >> 8 & 0xFF).chr
d[5] = (size & 0xFF).chr
puts "AnimationData animation_#{name} = {"
puts " &animation_#{name}_colors[0],"
puts " &animation_#{name}_data[0],"
puts " &animation_#{name}_offsets[0],"
puts " &animation_#{name}_delays[0],"
puts " #{individual_frame_times}, /* individual_frame_times */"
puts " #{colors.count-2}, /* color_count */"
puts " #{frames_data.count}, /* frames_count */"
puts " #{total_x}, #{total_y} /* width, height */"
puts "};"
puts
STDERR.puts STDERR.puts
STDERR.puts "Space usage:" STDERR.puts "Space usage:"
STDERR.puts " Colors: %6d bytes." % [s1=(colors.count-2) * 3] # colors are 3-bytes, but we have to use uint32_t, which takes up 4 bytes. STDERR.puts " Colors: %6d bytes." % [s1=(colors.count-2) * 3] # colors are 3-bytes, but we have to use uint32_t, which takes up 4 bytes.
@ -184,5 +184,24 @@ STDERR.puts " Data: %6d bytes." % [s2=data.flatten.count]
STDERR.puts " Delays: %6d bytes." % [s5=times.count * 2 + 1] STDERR.puts " Delays: %6d bytes." % [s5=times.count * 2 + 1]
STDERR.puts " Offsets: %6d bytes." % [s3=data.count * 2] STDERR.puts " Offsets: %6d bytes." % [s3=data.count * 2]
STDERR.puts " TOTAL: %6d bytes." % [s1+s2+s3+s5] STDERR.puts " TOTAL: %6d bytes." % [s1+s2+s3+s5]
STDERR.puts " REALLY: %6d bytes." % d.size
STDERR.puts "Original size: %6d bytes." % [s4=File.new(image_file).size] STDERR.puts "Original size: %6d bytes." % [s4=File.new(image_file).size]
STDERR.puts "Difference: %6d bytes." % [s1+s2+s3+s5 - s4] STDERR.puts "Difference: %6d bytes." % [s1+s2+s3+s5 - s4]
STDERR.puts
# File format
# Bytes 0-2: P I A (magic number)
# Byte 3: Version (currently 1)
# Bytes 4-5: Total file size
# Byte 6: width
# Byte 7: height
# Byte 8: frame_count
# Byte 9: color_count
# Color data, 3*color_count bytes
# Frame times, 2*frame_count bytes
# frame offsets, 2*frame_count bytes
STDERR.puts "Writing data to #{name}.pia..."
File.new("#{name}.pia", "w").write(d)
File.new("#{name}.pia.debug", "w").write(dd)

18
test.txt Normal file
View File

@ -0,0 +1,18 @@
Original:
DATA: [==== ] 40.5% (used 33164 bytes from 81920 bytes)
PROGRAM: [==== ] 36.0% (used 375664 bytes from 1044464 bytes)
lots of compares:
DATA: [==== ] 38.6% (used 31640 bytes from 81920 bytes)
PROGRAM: [==== ] 35.6% (used 371740 bytes from 1044464 bytes)
crc32:
DATA: [==== ] 38.5% (used 31532 bytes from 81920 bytes)
PROGRAM: [==== ] 35.6% (used 371456 bytes from 1044464 bytes)
original:
DATA: [==== ] 39.4% (used 32256 bytes from 81920 bytes) │pitrix_dev/log MQTT * Received data for topic pitrix_dev/uptime with payload 391
PROGRAM: [==== ] 37.4% (used 390380 bytes from 1044464 bytes)
DATA: [==== ] 37.4% (used 30608 bytes from 81920 bytes) │pitrix_dev/free_heap 43624
PROGRAM: [==== ] 37.4% (used 390556 bytes from 1044464 bytes)