diff --git a/tools/cdata.js b/tools/cdata.js index d01c3e35f..bf5a65e84 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -220,6 +220,7 @@ function writeChunks(srcDir, specs, resultFile) { writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index'); writeHtmlGzipped("wled00/data/simple.htm", "wled00/html_simple.h", 'simple'); +writeHtmlGzipped("wled00/data/pixart/pixart.htm", "wled00/html_pixart.h", 'pixart'); /* writeChunks( "wled00/data", diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 14c563c07..f44d26059 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -281,10 +281,12 @@ static const char _data_FX_MODE_RANDOM_COLOR[] PROGMEM = "Random Colors@!,Fade t * Lights every LED in a random color. Changes all LED at the same time * to new random colors. */ -uint16_t dynamic(boolean smooth=false) { +uint16_t mode_dynamic(void) { if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed if(SEGENV.call == 0) { + //SEGMENT.setUpLeds(); //lossless getPixelColor() + //SEGMENT.fill(BLACK); for (int i = 0; i < SEGLEN; i++) SEGENV.data[i] = random8(); } @@ -293,14 +295,14 @@ uint16_t dynamic(boolean smooth=false) { if (it != SEGENV.step && SEGMENT.speed != 0) //new color { for (int i = 0; i < SEGLEN; i++) { - if (random8() <= SEGMENT.intensity) SEGENV.data[i] = random8(); + if (random8() <= SEGMENT.intensity) SEGENV.data[i] = random8(); // random color index } SEGENV.step = it; } - if (smooth) { + if (SEGMENT.check1) { for (int i = 0; i < SEGLEN; i++) { - SEGMENT.blendPixelColor(i, SEGMENT.color_wheel(SEGENV.data[i]),16); // TODO + SEGMENT.blendPixelColor(i, SEGMENT.color_wheel(SEGENV.data[i]), 16); } } else { for (int i = 0; i < SEGLEN; i++) { @@ -309,22 +311,18 @@ uint16_t dynamic(boolean smooth=false) { } return FRAMETIME; } +static const char _data_FX_MODE_DYNAMIC[] PROGMEM = "Dynamic@!,!,,,,Smooth;;!"; /* - * Original effect "Dynamic" - */ -uint16_t mode_dynamic(void) { - return dynamic(false); -} -static const char _data_FX_MODE_DYNAMIC[] PROGMEM = "Dynamic@!,!;;!"; - - -/* - * effect "Dynamic" with smoth color-fading + * effect "Dynamic" with smooth color-fading */ uint16_t mode_dynamic_smooth(void) { - return dynamic(true); + bool old = SEGMENT.check1; + SEGMENT.check1 = true; + mode_dynamic(); + SEGMENT.check1 = old; + return FRAMETIME; } static const char _data_FX_MODE_DYNAMIC_SMOOTH[] PROGMEM = "Dynamic Smooth@!,!;;!"; @@ -603,33 +601,38 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; * Dissolve function */ uint16_t dissolve(uint32_t color) { - bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness + //bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness + if (SEGENV.call == 0) { + SEGMENT.setUpLeds(); //lossless getPixelColor() + SEGMENT.fill(SEGCOLOR(1)); + } - for (int j = 0; j <= SEGLEN / 15; j++) - { + for (int j = 0; j <= SEGLEN / 15; j++) { if (random8() <= SEGMENT.intensity) { - for (size_t times = 0; times < 10; times++) //attempt to spawn a new pixel 5 times + for (size_t times = 0; times < 10; times++) //attempt to spawn a new pixel 10 times { uint16_t i = random16(SEGLEN); if (SEGENV.aux0) { //dissolve to primary/palette - if (SEGMENT.getPixelColor(i) == SEGCOLOR(1) || wa) { // TODO - if (color == SEGCOLOR(0)) - { + if (SEGMENT.getPixelColor(i) == SEGCOLOR(1) /*|| wa*/) { + if (color == SEGCOLOR(0)) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } else { SEGMENT.setPixelColor(i, color); } + } else { + SEGMENT.setPixelColor(i, color); + } break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (SEGMENT.getPixelColor(i) != SEGCOLOR(1)) { SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; } // TODO + if (SEGMENT.getPixelColor(i) != SEGCOLOR(1)) { SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; } } } } } - if (SEGENV.call > (255 - SEGMENT.speed) + 15U) - { + if (SEGENV.step > (255 - SEGMENT.speed) + 15U) { SEGENV.aux0 = !SEGENV.aux0; - SEGENV.call = 0; + SEGENV.step = 0; + } else { + SEGENV.step++; } return FRAMETIME; @@ -640,9 +643,9 @@ uint16_t dissolve(uint32_t color) { * Blink several LEDs on and then off */ uint16_t mode_dissolve(void) { - return dissolve(SEGCOLOR(0)); + return dissolve(SEGMENT.check1 ? SEGMENT.color_wheel(random8()) : SEGCOLOR(0)); } -static const char _data_FX_MODE_DISSOLVE[] PROGMEM = "Dissolve@Repeat speed,Dissolve speed;!,!;!"; +static const char _data_FX_MODE_DISSOLVE[] PROGMEM = "Dissolve@Repeat speed,Dissolve speed,,,,Random;!,!;!"; /* @@ -1193,17 +1196,19 @@ uint16_t mode_fireworks() { const uint16_t width = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t height = SEGMENT.virtualHeight(); - SEGMENT.fade_out(0); - if (SEGENV.call == 0) { + SEGMENT.setUpLeds(); //lossless getPixelColor() + SEGMENT.fill(SEGCOLOR(1)); SEGENV.aux0 = UINT16_MAX; SEGENV.aux1 = UINT16_MAX; } + SEGMENT.fade_out(128); + bool valid1 = (SEGENV.aux0 < width*height); bool valid2 = (SEGENV.aux1 < width*height); uint32_t sv1 = 0, sv2 = 0; - if (valid1) sv1 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // TODO get spark color - if (valid2) sv2 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1); // TODO + if (valid1) sv1 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color + if (valid2) sv2 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1); if (!SEGENV.step) SEGMENT.blur(16); if (valid1) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur if (valid2) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur @@ -1230,7 +1235,7 @@ uint16_t mode_rain() const uint16_t width = SEGMENT.virtualWidth(); const uint16_t height = SEGMENT.virtualHeight(); SEGENV.step += FRAMETIME; - if (SEGENV.step > SPEED_FORMULA_L) { + if (SEGENV.call && SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 1; if (strip.isMatrix) { uint32_t ctemp[width]; @@ -1241,9 +1246,9 @@ uint16_t mode_rain() SEGENV.aux1 = (SEGENV.aux1 % width) + (SEGENV.aux1 / width + 1) * width; } else { //shift all leds left - uint32_t ctemp = SEGMENT.getPixelColor(0); // TODO + uint32_t ctemp = SEGMENT.getPixelColor(0); for (int i = 0; i < SEGLEN - 1; i++) { - SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // TODO + SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); } SEGMENT.setPixelColor(SEGLEN -1, ctemp); // wrap around SEGENV.aux0++; // increase spark index @@ -1585,8 +1590,7 @@ static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!,,,,,Overlay;!,!;!"; /* * Custom mode by Aircoookie. Color Wipe, but with 3 colors */ -uint16_t mode_tricolor_wipe(void) -{ +uint16_t mode_tricolor_wipe(void) { uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200; uint32_t perc = strip.now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; @@ -1628,8 +1632,7 @@ static const char _data_FX_MODE_TRICOLOR_WIPE[] PROGMEM = "Tri Wipe@!;1,2,3;!"; * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/TriFade.h * Modified by Aircoookie */ -uint16_t mode_tricolor_fade(void) -{ +uint16_t mode_tricolor_fade(void) { uint16_t counter = strip.now * ((SEGMENT.speed >> 3) +1); uint32_t prog = (counter * 768) >> 16; @@ -1672,8 +1675,7 @@ static const char _data_FX_MODE_TRICOLOR_FADE[] PROGMEM = "Tri Fade@!;1,2,3;!"; * Creates random comets * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/MultiComet.h */ -uint16_t mode_multi_comet(void) -{ +uint16_t mode_multi_comet(void) { uint32_t cycleTime = 10 + (uint32_t)(255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; if (SEGENV.step == it) return FRAMETIME; @@ -1711,8 +1713,7 @@ static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = "Multi Comet"; * Running random pixels ("Stream 2") * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/RandomChase.h */ -uint16_t mode_random_chase(void) -{ +uint16_t mode_random_chase(void) { if (SEGENV.call == 0) { SEGENV.step = RGBW32(random8(), random8(), random8(), 0); SEGENV.aux0 = random16(); @@ -1754,8 +1755,7 @@ typedef struct Oscillator { /* / Oscillating bars of color, updated with standard framerate */ -uint16_t mode_oscillate(void) -{ +uint16_t mode_oscillate(void) { uint8_t numOscillators = 3; uint16_t dataSize = sizeof(oscillator) * numOscillators; @@ -1807,8 +1807,7 @@ static const char _data_FX_MODE_OSCILLATE[] PROGMEM = "Oscillate"; //TODO -uint16_t mode_lightning(void) -{ +uint16_t mode_lightning(void) { uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash uint16_t ledlen = 1 + random16(SEGLEN -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/random8(1, 3); @@ -1853,8 +1852,7 @@ static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!,,,,,Overlay // Pride2015 // Animated, ever-changing rainbows. // by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5 -uint16_t mode_pride_2015(void) -{ +uint16_t mode_pride_2015(void) { uint16_t duration = 10 + SEGMENT.speed; uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; @@ -1883,11 +1881,8 @@ uint16_t mode_pride_2015(void) uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; bri8 += (255 - brightdepth); - CRGB newcolor = CHSV( hue8, sat8, bri8); - fastled_col = CRGB(SEGMENT.getPixelColor(i)); // TODO - - nblend(fastled_col, newcolor, 64); - SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + CRGB newcolor = CHSV(hue8, sat8, bri8); + SEGMENT.blendPixelColor(i, newcolor, 64); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; @@ -1898,24 +1893,29 @@ static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;"; //eight colored dots, weaving in and out of sync with each other -uint16_t mode_juggle(void){ - SEGMENT.fade_out(SEGMENT.intensity); +uint16_t mode_juggle(void) { + if (SEGENV.call == 0) { + SEGMENT.setUpLeds(); //lossless getPixelColor() + SEGMENT.fill(BLACK); + } + + SEGMENT.fadeToBlackBy(192 - (3*SEGMENT.intensity/4)); + CRGB fastled_col; byte dothue = 0; for (int i = 0; i < 8; i++) { - uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); - fastled_col = CRGB(SEGMENT.getPixelColor(index)); // TODO + uint16_t index = 0 + beatsin88((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); + fastled_col = CRGB(SEGMENT.getPixelColor(index)); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255); - SEGMENT.setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(index, fastled_col); dothue += 32; } return FRAMETIME; } -static const char _data_FX_MODE_JUGGLE[] PROGMEM = "Juggle@!,Trail;;!;;sx=16,ix=240"; +static const char _data_FX_MODE_JUGGLE[] PROGMEM = "Juggle@!,Trail;;!;;sx=64,ix=128"; -uint16_t mode_palette() -{ +uint16_t mode_palette() { uint16_t counter = 0; if (SEGMENT.speed != 0) { @@ -1963,8 +1963,7 @@ static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!;;c3= // There are two main parameters you can play with to control the look and // feel of your fire: COOLING (used in step 1 above) (Speed = COOLING), and SPARKING (used // in step 3 above) (Effect Intensity = Sparking). -uint16_t mode_fire_2012() -{ +uint16_t mode_fire_2012() { uint16_t strips = SEGMENT.nrOfVStrips(); if (!SEGENV.allocateData(strips * SEGLEN)) return mode_static(); //allocation failed byte* heat = SEGENV.data; @@ -2023,8 +2022,7 @@ static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark r // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // This function draws color waves with an ever-changing, // widely-varying set of parameters, using a color palette. -uint16_t mode_colorwaves() -{ +uint16_t mode_colorwaves() { uint16_t duration = 10 + SEGMENT.speed; uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; @@ -2034,15 +2032,11 @@ uint16_t mode_colorwaves() uint8_t msmultiplier = beatsin88(147, 23, 60); uint16_t hue16 = sHue16;//gHue * 256; - // uint16_t hueinc16 = beatsin88(113, 300, 1500); uint16_t hueinc16 = beatsin88(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues sPseudotime += duration * msmultiplier; sHue16 += duration * beatsin88(400, 5, 9); uint16_t brightnesstheta16 = sPseudotime; - //CRGB fastled_col; - - if (SEGENV.call == 0) SEGMENT.fill(BLACK); for (int i = 0 ; i < SEGLEN; i++) { hue16 += hueinc16; @@ -2055,17 +2049,12 @@ uint16_t mode_colorwaves() } brightnesstheta16 += brightnessthetainc16; - uint16_t b16 = sin16( brightnesstheta16 ) + 32768; + uint16_t b16 = sin16(brightnesstheta16) + 32768; uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; bri8 += (255 - brightdepth); - //CRGB newcolor = ColorFromPalette(SEGPALETTE, hue8, bri8); - //fastled_col = SEGMENT.getPixelColor(i); // TODO - - //nblend(fastled_col, newcolor, 128); - //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); SEGMENT.blendPixelColor(i, SEGMENT.color_from_palette(hue8, false, PALETTE_SOLID_WRAP, 0, bri8), 128); // 50/50 mix } SEGENV.step = sPseudotime; @@ -2077,8 +2066,7 @@ static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!"; // colored stripes pulsing at a defined Beats-Per-Minute (BPM) -uint16_t mode_bpm() -{ +uint16_t mode_bpm() { //CRGB fastled_col; uint32_t stp = (strip.now / 20) & 0xFF; uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); @@ -2093,8 +2081,7 @@ uint16_t mode_bpm() static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64"; -uint16_t mode_fillnoise8() -{ +uint16_t mode_fillnoise8() { if (SEGENV.call == 0) SEGENV.step = random16(12345); //CRGB fastled_col; for (int i = 0; i < SEGLEN; i++) { @@ -2110,8 +2097,7 @@ uint16_t mode_fillnoise8() static const char _data_FX_MODE_FILLNOISE8[] PROGMEM = "Fill Noise@!;!;!"; -uint16_t mode_noise16_1() -{ +uint16_t mode_noise16_1() { uint16_t scale = 320; // the "zoom factor" for the noise //CRGB fastled_col; SEGENV.step += (1 + SEGMENT.speed/16); @@ -2135,8 +2121,7 @@ uint16_t mode_noise16_1() static const char _data_FX_MODE_NOISE16_1[] PROGMEM = "Noise 1@!;!;!"; -uint16_t mode_noise16_2() -{ +uint16_t mode_noise16_2() { uint16_t scale = 1000; // the "zoom factor" for the noise //CRGB fastled_col; SEGENV.step += (1 + (SEGMENT.speed >> 1)); @@ -2157,8 +2142,7 @@ uint16_t mode_noise16_2() static const char _data_FX_MODE_NOISE16_2[] PROGMEM = "Noise 2@!;!;!"; -uint16_t mode_noise16_3() -{ +uint16_t mode_noise16_3() { uint16_t scale = 800; // the "zoom factor" for the noise //CRGB fastled_col; SEGENV.step += (1 + SEGMENT.speed); @@ -2183,8 +2167,7 @@ static const char _data_FX_MODE_NOISE16_3[] PROGMEM = "Noise 3@!;!;!"; //https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino -uint16_t mode_noise16_4() -{ +uint16_t mode_noise16_4() { //CRGB fastled_col; uint32_t stp = (strip.now * SEGMENT.speed) >> 7; for (int i = 0; i < SEGLEN; i++) { @@ -2199,8 +2182,7 @@ static const char _data_FX_MODE_NOISE16_4[] PROGMEM = "Noise 4@!;!;!"; //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e -uint16_t mode_colortwinkle() -{ +uint16_t mode_colortwinkle() { uint16_t dataSize = (SEGLEN+7) >> 3; //1 bit per LED if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -2353,8 +2335,7 @@ static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail //Railway Crossing / Christmas Fairy lights -uint16_t mode_railway() -{ +uint16_t mode_railway() { uint16_t dur = (256 - SEGMENT.speed) * 40; uint16_t rampdur = (dur * SEGMENT.intensity) >> 8; if (SEGENV.step > dur) @@ -2829,7 +2810,7 @@ uint16_t mode_bouncing_balls(void) { balls[i].lastBounceTime = time; if (balls[i].impactVelocity < 0.015f) { - float impactVelocityStart = sqrt(-2 * gravity) * random8(5,11)/10.0f; // randomize impact velocity + float impactVelocityStart = sqrtf(-2.0f * gravity) * random8(5,11)/10.0f; // randomize impact velocity balls[i].impactVelocity = impactVelocityStart; } } else if (balls[i].height > 1.0f) { @@ -2987,7 +2968,7 @@ uint16_t mode_popcorn(void) { uint16_t peakHeight = 128 + random8(128); //0-255 peakHeight = (peakHeight * (SEGLEN -1)) >> 8; - popcorn[i].vel = sqrt(-2.0 * gravity * peakHeight); + popcorn[i].vel = sqrtf(-2.0f * gravity * peakHeight); if (SEGMENT.palette) { @@ -3286,7 +3267,7 @@ uint16_t mode_exploding_fireworks(void) flare->posX = strip.isMatrix ? random16(2,cols-1) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D uint16_t peakHeight = 75 + random8(180); //0-255 peakHeight = (peakHeight * (rows -1)) >> 8; - flare->vel = sqrt(-2.0f * gravity * peakHeight); + flare->vel = sqrtf(-2.0f * gravity * peakHeight); flare->velX = strip.isMatrix ? (random8(8)-4)/32.f : 0; // no X velocity on 1D flare->col = 255; //brightness SEGENV.aux0 = 1; @@ -4844,7 +4825,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled - const uint16_t crcBufferLen = (SEGMENT.width() + SEGMENT.height())*71/100; // roughly sqrt(2)/2 for better repetition detection (Ewowi) + const uint16_t crcBufferLen = 2; //(SEGMENT.width() + SEGMENT.height())*71/100; // roughly sqrt(2)/2 for better repetition detection (Ewowi) if (!SEGENV.allocateData(dataSize + sizeof(uint16_t)*crcBufferLen)) return mode_static(); //allocation failed CRGB *prevLeds = reinterpret_cast(SEGENV.data); @@ -4852,7 +4833,9 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: CRGB backgroundColor = SEGCOLOR(1); - if (SEGENV.call == 0 || strip.now - SEGMENT.step > 5000) { + if (SEGENV.call == 0) SEGMENT.setUpLeds(); + + if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) { SEGENV.step = strip.now; SEGENV.aux0 = 0; random16_set_seed(millis()>>2); //seed the random generator @@ -4879,20 +4862,22 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: //calculate new leds for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) { - colorCount colorsCount[9];//count the different colors in the 9*9 matrix - for (int i=0; i<9; i++) colorsCount[i] = {backgroundColor, 0}; //init colorsCount - //iterate through neighbors and count them and their different colors + colorCount colorsCount[9]; // count the different colors in the 3*3 matrix + for (int i=0; i<9; i++) colorsCount[i] = {backgroundColor, 0}; // init colorsCount + + // iterate through neighbors and count them and their different colors int neighbors = 0; - for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { //iterate through 9*9 matrix + for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { // iterate through 3*3 matrix + if (i==0 && j==0) continue; // ignore itself // wrap around segment int16_t xx = x+i, yy = y+j; - if (x+i < 0) xx = cols-1; else if (x+i >= cols) xx = 0; + if (x+i < 0) xx = cols-1; else if (x+i >= cols) xx = 0; if (y+j < 0) yy = rows-1; else if (y+j >= rows) yy = 0; - uint16_t xy = XY(xx, yy); // previous cell xy to check - // count different neighbours and colors, except the centre cell - if (xy != XY(x,y) && prevLeds[xy] != backgroundColor) { + uint16_t xy = XY(xx, yy); // previous cell xy to check + // count different neighbours and colors + if (prevLeds[xy] != backgroundColor) { neighbors++; bool colorFound = false; int k; @@ -4901,22 +4886,24 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: colorsCount[k].count++; colorFound = true; } - if (!colorFound) colorsCount[k] = {prevLeds[xy], 1}; //add new color found in the array } } // i,j // Rules of Life - uint32_t col = SEGMENT.getPixelColorXY(x,y); + uint32_t col = prevLeds[XY(x,y)]; uint32_t bgc = RGBW32(backgroundColor.r, backgroundColor.g, backgroundColor.b, 0); if ((col != bgc) && (neighbors < 2)) SEGMENT.setPixelColorXY(x,y, bgc); // Loneliness else if ((col != bgc) && (neighbors > 3)) SEGMENT.setPixelColorXY(x,y, bgc); // Overpopulation else if ((col == bgc) && (neighbors == 3)) { // Reproduction - //find dominant color and assign to cell + // find dominant color and assign it to a cell colorCount dominantColorCount = {backgroundColor, 0}; for (int i=0; i<9 && colorsCount[i].count != 0; i++) if (colorsCount[i].count > dominantColorCount.count) dominantColorCount = colorsCount[i]; - if (dominantColorCount.count > 0) SEGMENT.setPixelColorXY(x,y, dominantColorCount.color); //assign the dominant color + // assign the dominant color w/ a bit of randomness to avoid "gliders" + if (dominantColorCount.count > 0 && random8(128)) SEGMENT.setPixelColorXY(x,y, dominantColorCount.color); + } else if ((col == bgc) && (neighbors == 2) && !random8(128)) { // Mutation + SEGMENT.setPixelColorXY(x,y, SEGMENT.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 255)); } // else do nothing! } //x,y @@ -5310,7 +5297,7 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https SEGENV.step = 0; } - float adjustHeight = (float)map(rows, 8, 32, 28, 12); + float adjustHeight = (float)map(rows, 8, 32, 28, 12); // maybe use mapf() ??? uint16_t adjScale = map(cols, 8, 64, 310, 63); /* if (SEGENV.aux1 != SEGMENT.custom1/12) { // Hacky palette rotation. We need that black. @@ -5336,7 +5323,7 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https SEGMENT.setPixelColorXY(x, y, ColorFromPalette(auroraPalette, qsub8( inoise8((SEGENV.step%2) + x * _scale, y * 16 + SEGENV.step % 16, SEGENV.step / _speed), - fabs((float)rows / 2 - (float)y) * adjustHeight))); + fabsf((float)rows / 2.0f - (float)y) * adjustHeight))); } } @@ -5351,7 +5338,7 @@ static const char _data_FX_MODE_2DPOLARLIGHTS[] PROGMEM = "Polar Lights@!,Scale; uint16_t mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline if (!strip.isMatrix) return mode_static(); // not a 2D set-up - //const uint16_t cols = SEGMENT.virtualWidth(); + const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); if (SEGENV.call == 0) { @@ -5361,8 +5348,8 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi SEGMENT.fadeToBlackBy(8 - (SEGMENT.intensity>>5)); - uint16_t a = strip.now / (18 - SEGMENT.speed / 16); - uint16_t x = (a / 14); + uint32_t a = strip.now / (18 - SEGMENT.speed / 16); + uint16_t x = (a / 14) % cols; uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0); SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND)); @@ -5788,13 +5775,13 @@ uint16_t mode_2Dfloatingblobs(void) { // change radius if needed if (blob->grow[i]) { // enlarge radius until it is >= 4 - blob->r[i] += (fabs(blob->sX[i]) > fabs(blob->sY[i]) ? fabs(blob->sX[i]) : fabs(blob->sY[i])) * 0.05f; + blob->r[i] += (fabsf(blob->sX[i]) > fabsf(blob->sY[i]) ? fabsf(blob->sX[i]) : fabsf(blob->sY[i])) * 0.05f; if (blob->r[i] >= MIN(cols/4.f,2.f)) { blob->grow[i] = false; } } else { // reduce radius until it is < 1 - blob->r[i] -= (fabs(blob->sX[i]) > fabs(blob->sY[i]) ? fabs(blob->sX[i]) : fabs(blob->sY[i])) * 0.05f; + blob->r[i] -= (fabsf(blob->sX[i]) > fabsf(blob->sY[i]) ? fabsf(blob->sX[i]) : fabsf(blob->sY[i])) * 0.05f; if (blob->r[i] < 1.f) { blob->grow[i] = true; } @@ -6715,11 +6702,10 @@ uint16_t mode_DJLight(void) { // Written by ??? Adapted by Wil if (SEGENV.aux0 != secondHand) { // Triggered millis timing. SEGENV.aux0 = secondHand; - SEGMENT.setPixelColor(mid, CRGB(fftResult[15]/2, fftResult[5]/2, fftResult[0]/2)); // 16-> 15 as 16 is out of bounds - CRGB color = SEGMENT.getPixelColor(mid); - SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[1*4], 0, 255, 255, 10))); // TODO - Update + CRGB color = CRGB(fftResult[15]/2, fftResult[5]/2, fftResult[0]/2); // 16-> 15 as 16 is out of bounds + SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[4], 0, 255, 255, 4))); // TODO - Update - for (int i = SEGLEN - 1; i > mid; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left + for (int i = SEGLEN - 1; i > mid; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); // move to the left for (int i = 0; i < mid; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right } @@ -6740,8 +6726,8 @@ uint16_t mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. // add support for no audio um_data = simulateSound(SEGMENT.soundSim); } - float FFT_MajorPeak = *(float*) um_data->u_data[4]; - float my_magnitude = *(float*) um_data->u_data[5] / 4.0f; + float FFT_MajorPeak = *(float*)um_data->u_data[4]; + float my_magnitude = *(float*)um_data->u_data[5] / 4.0f; if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception) if (SEGENV.call == 0) SEGMENT.fill(BLACK); @@ -6774,7 +6760,7 @@ uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Plesch um_data = simulateSound(SEGMENT.soundSim); } float FFT_MajorPeak = *(float*)um_data->u_data[4]; - float volumeSmth = *(float*) um_data->u_data[0]; + float volumeSmth = *(float*)um_data->u_data[0]; if (SEGENV.call == 0) { SEGMENT.setUpLeds(); @@ -6811,7 +6797,7 @@ uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Plesch // shift the pixels one pixel up SEGMENT.setPixelColor(0, color); - for (int i = SEGLEN - 1; i > 0; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left + for (int i = SEGLEN - 1; i > 0; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left } return FRAMETIME; @@ -6832,8 +6818,8 @@ uint16_t mode_freqpixels(void) { // Freqpixel. By Andrew Tuline. // add support for no audio um_data = simulateSound(SEGMENT.soundSim); } - float FFT_MajorPeak = *(float*) um_data->u_data[4]; - float my_magnitude = *(float*) um_data->u_data[5] / 16.0f; + float FFT_MajorPeak = *(float*)um_data->u_data[4]; + float my_magnitude = *(float*)um_data->u_data[5] / 16.0f; if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception) uint16_t fadeRate = 2*SEGMENT.speed - SEGMENT.speed*SEGMENT.speed/255; // Get to 255 as quick as you can. @@ -6875,8 +6861,8 @@ uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschun // add support for no audio um_data = simulateSound(SEGMENT.soundSim); } - float FFT_MajorPeak = *(float*) um_data->u_data[4]; - float volumeSmth = *(float*) um_data->u_data[0]; + float FFT_MajorPeak = *(float*)um_data->u_data[4]; + float volumeSmth = *(float*)um_data->u_data[0]; if (SEGENV.call == 0) { SEGMENT.setUpLeds(); @@ -6937,16 +6923,16 @@ uint16_t mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. // add support for no audio um_data = simulateSound(SEGMENT.soundSim); } - float FFT_MajorPeak = *(float*) um_data->u_data[4]; - float volumeSmth = *(float*) um_data->u_data[0]; + float FFT_MajorPeak = *(float*)um_data->u_data[4]; + float volumeSmth = *(float*)um_data->u_data[0]; if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception) SEGMENT.fade_out(250); - float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0; + float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivty" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0, 0,32, 0, (float)SEGLEN/2.0); // map to pixels availeable in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0,32, 0, (float)SEGLEN/2.0); // map to pixels availeable in current segment int tempsamp = constrain(mySampleAvg,0,SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -7032,7 +7018,7 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac } frTemp -=132; // This should give us a base musical note of C3 - frTemp = fabs(frTemp * 2.1); // Fudge factors to compress octave range starting at 0 and going to 255; + frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255; uint16_t i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1); i = constrain(i, 0, SEGLEN-1); diff --git a/wled00/FX.h b/wled00/FX.h index 8db9e2552..430957803 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -143,7 +143,7 @@ #define FX_MODE_SAW 16 #define FX_MODE_TWINKLE 17 #define FX_MODE_DISSOLVE 18 -#define FX_MODE_DISSOLVE_RANDOM 19 +#define FX_MODE_DISSOLVE_RANDOM 19 // candidate for removal (use Dissolve with with check 3) #define FX_MODE_SPARKLE 20 #define FX_MODE_FLASH_SPARKLE 21 #define FX_MODE_HYPER_SPARKLE 22 @@ -227,7 +227,7 @@ #define FX_MODE_HEARTBEAT 100 #define FX_MODE_PACIFICA 101 #define FX_MODE_CANDLE_MULTI 102 -#define FX_MODE_SOLID_GLITTER 103 +#define FX_MODE_SOLID_GLITTER 103 // candidate for removal (use glitter) #define FX_MODE_SUNRISE 104 #define FX_MODE_PHASED 105 #define FX_MODE_TWINKLEUP 106 @@ -241,7 +241,7 @@ // #define FX_MODE_CANDY_CANE 114 // removed in 0.14! #define FX_MODE_BLENDS 115 #define FX_MODE_TV_SIMULATOR 116 -#define FX_MODE_DYNAMIC_SMOOTH 117 +#define FX_MODE_DYNAMIC_SMOOTH 117 // candidate for removal (check3 in dynamic) // new 0.14 2D effects #define FX_MODE_2DSPACESHIPS 118 //gap fill diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 147f625bf..235c61d0f 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -893,7 +893,7 @@ void Segment::blur(uint8_t blur_amount) * The colours are a transition r -> g -> b -> back to r * Inspired by the Adafruit examples. */ -uint32_t Segment::color_wheel(uint8_t pos) { // TODO +uint32_t Segment::color_wheel(uint8_t pos) { if (palette) return color_from_palette(pos, false, true, 0); pos = 255 - pos; if(pos < 85) { diff --git a/wled00/data/pixart/boxdraw.js b/wled00/data/pixart/boxdraw.js new file mode 100644 index 000000000..c000c2e61 --- /dev/null +++ b/wled00/data/pixart/boxdraw.js @@ -0,0 +1,62 @@ +function drawBoxes(inputPixelArray, widthPixels, heightPixels) { + + var w = window; + + // Get the canvas context + var ctx = canvas.getContext('2d', { willReadFrequently: true }); + + // Set the width and height of the canvas + if (w.innerHeight < w.innerWidth) { + canvas.width = Math.floor(w.innerHeight * 0.98); + } + else{ + canvas.width = Math.floor(w.innerWidth * 0.98); + } + //canvas.height = w.innerWidth; + + let pixelSize = Math.floor(canvas.width/widthPixels); + + let xOffset = (w.innerWidth - (widthPixels * pixelSize))/2 + + //Set the canvas height to fit the right number of pixelrows + canvas.height = (pixelSize * heightPixels) + 10 + + //Iterate through the matrix + for (let y = 0; y < heightPixels; y++) { + for (let x = 0; x < widthPixels; x++) { + + // Calculate the index of the current pixel + let i = (y*widthPixels) + x; + + //Gets the RGB of the current pixel + let pixel = inputPixelArray[i]; + + let pixelColor = 'rgb(' + pixel[0] + ', ' + pixel[1] + ', ' + pixel[2] + ')'; + + let textColor = 'rgb(128,128,128)'; + + // Set the fill style to the pixel color + ctx.fillStyle = pixelColor; + + //Draw the rectangle + ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize); + + // Draw a border on the box + ctx.strokeStyle = '#888888'; + ctx.lineWidth = 1; + ctx.strokeRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize); + + //Write text to box + ctx.font = "10px Arial"; + ctx.fillStyle = textColor; + ctx.textAlign = "center"; + ctx.textBaseline = 'middle'; + ctx.fillText((pixel[4] + 1), (x * pixelSize) + (pixelSize /2), (y * pixelSize) + (pixelSize /2)); + } + } + var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + ctx.clearRect(0, 0, canvas.width, canvas.height); + canvas.width = w.innerWidth; + ctx.putImageData(imageData, xOffset, 0); +} + diff --git a/wled00/data/pixart/favicon-16x16.png b/wled00/data/pixart/favicon-16x16.png new file mode 100644 index 000000000..feb51ca09 Binary files /dev/null and b/wled00/data/pixart/favicon-16x16.png differ diff --git a/wled00/data/pixart/favicon-32x32.png b/wled00/data/pixart/favicon-32x32.png new file mode 100644 index 000000000..a3b5cceb1 Binary files /dev/null and b/wled00/data/pixart/favicon-32x32.png differ diff --git a/wled00/data/pixart/favicon.ico b/wled00/data/pixart/favicon.ico new file mode 100644 index 000000000..bde8945e5 Binary files /dev/null and b/wled00/data/pixart/favicon.ico differ diff --git a/wled00/data/pixart/getPixelValues.js b/wled00/data/pixart/getPixelValues.js new file mode 100644 index 000000000..ffbf94a70 --- /dev/null +++ b/wled00/data/pixart/getPixelValues.js @@ -0,0 +1,320 @@ +function getPixelRGBValues(base64Image) { + httpArray = []; + fileJSON = `{"on":true,"bri":${brgh.value},"seg":{"id":${tSg.value},"i":[`; + + //Which object holds the secret to the segment ID + + let segID = 0; + if(tSg.style.display == "flex"){ + segID = tSg.value + } else { + segID = sID.value; + } + + + //const copyJSONledbutton = gId('copyJSONledbutton'); + const maxNoOfColorsInCommandSting = parseInt(cLN.value); + + let hybridAddressing = false; + let selectedIndex = -1; + + selectedIndex = frm.selectedIndex; + const formatSelection = frm.options[selectedIndex].value; + + + selectedIndex = lSS.selectedIndex; + const ledSetupSelection = lSS.options[selectedIndex].value; + + selectedIndex = cFS.selectedIndex; + let hexValueCheck = true; + if (cFS.options[selectedIndex].value == 'dec'){ + hexValueCheck = false + } + + selectedIndex = aS.selectedIndex; + let segmentValueCheck = true; //If Range or Hybrid + if (aS.options[selectedIndex].value == 'single'){ + segmentValueCheck = false + } else if (aS.options[selectedIndex].value == 'hybrid'){ + hybridAddressing = true; + } + + let curlString = '' + let haString = '' + + let colorSeparatorStart = '"'; + let colorSeparatorEnd = '"'; + if (!hexValueCheck){ + colorSeparatorStart = '['; + colorSeparatorEnd = ']'; + } + // Warnings + let hasTransparency = false; //If alpha < 255 is detected on any pixel, this is set to true in code below + let imageInfo = ''; + + // Create an off-screen canvas + var canvas = cE('canvas'); + var context = canvas.getContext('2d', { willReadFrequently: true }); + + // Create an image element and set its src to the base64 image + var image = new Image(); + image.src = base64Image; + + // Wait for the image to load before drawing it onto the canvas + image.onload = function() { + + let scalePath = scDiv.children[0].children[0]; + let color = scalePath.getAttribute("fill"); + let sizeX = szX.value; + let sizeY = szY.value; + + if (color != accentColor || sizeX < 1 || sizeY < 1){ + //image will not be rezised Set desitred size to original size + sizeX = image.width; + sizeY = image.height; + //failsafe for not generating huge images automatically + if (image.width > 512 || image.height > 512) + { + sizeX = 16; + sizeY = 16; + } + } + + // Set the canvas size to the same as the desired image size + canvas.width = sizeX; + canvas.height = sizeY; + + imageInfo = '

Width: ' + sizeX + ', Height: ' + sizeY + ' (make sure this matches your led matrix setup)

' + + // Draw the image onto the canvas + context.drawImage(image, 0, 0, sizeX, sizeY); + + // Get the pixel data from the canvas + var pixelData = context.getImageData(0, 0, sizeX, sizeY).data; + + // Create an array to hold the RGB values of each pixel + var pixelRGBValues = []; + + // If the first row of the led matrix is right -> left + let right2leftAdjust = 1; + + if (ledSetupSelection == 'l2r'){ + right2leftAdjust = 0; + } + + // Loop through the pixel data and get the RGB values of each pixel + for (var i = 0; i < pixelData.length; i += 4) { + var r = pixelData[i]; + var g = pixelData[i + 1]; + var b = pixelData[i + 2]; + var a = pixelData[i + 3]; + + let pixel = i/4 + let row = Math.floor(pixel/sizeX); + let led = pixel; + if (ledSetupSelection == 'matrix'){ + //Do nothing, the matrix is set upp like the index in the image + //Every row starts from the left, i.e. no zigzagging + } + else if ((row + right2leftAdjust) % 2 === 0) { + //Setup is traditional zigzag + //right2leftAdjust basically flips the row order if = 1 + //Row is left to right + //Leave led index as pixel index + + } else { + //Setup is traditional zigzag + //Row is right to left + //Invert index of row for led + let indexOnRow = led - (row * sizeX); + let maxIndexOnRow = sizeX - 1; + let reversedIndexOnRow = maxIndexOnRow - indexOnRow; + led = (row * sizeX) + reversedIndexOnRow; + } + + // Add the RGB values to the pixel RGB values array + pixelRGBValues.push([r, g, b, a, led, pixel, row]); + } + + pixelRGBValues.sort((a, b) => a[5] - b[5]); + + //Copy the values to a new array for resorting + let ledRGBValues = [... pixelRGBValues]; + + //Sort the array based on led index + ledRGBValues.sort((a, b) => a[4] - b[4]); + + //Generate JSON in WLED format + let JSONledString = ''; + + //Set starting values for the segment check to something that is no color + let segmentStart = -1; + let maxi = ledRGBValues.length; + let curentColorIndex = 0 + let commandArray = []; + + //For evry pixel in the LED array + for (let i = 0; i < maxi; i++) { + let pixel = ledRGBValues[i]; + let r = pixel[0]; + let g = pixel[1]; + let b = pixel[2]; + let a = pixel[3]; + let segmentString = ''; + let segmentEnd = -1; + + if(segmentValueCheck){ + if (segmentStart < 0){ + //This is the first led of a new segment + segmentStart = i; + } //Else we allready have a start index + + if (i < maxi - 1){ + + let iNext = i + 1; + let nextPixel = ledRGBValues[iNext]; + + if (nextPixel[0] != r || nextPixel[1] != g || nextPixel[2] != b ){ + //Next pixel has new color + //The current segment ends with this pixel + segmentEnd = i + 1 //WLED wants the NEXT LED as the stop led... + if (segmentStart == i && hybridAddressing){ + //If only one led/pixel, no segment info needed + if (JSONledString == ''){ + //If addressing is single, we need to start every command with a starting possition + segmentString = '' + i + ','; + //Fixed to b2 + } else{ + segmentString = '' + } + } + else { + segmentString = segmentStart + ',' + segmentEnd + ','; + } + } + + } else { + //This is the last pixel, so the segment must end + segmentEnd = i + 1; + + if (segmentStart + 1 == segmentEnd && hybridAddressing){ + //If only one led/pixel, no segment info needed + if (JSONledString == ''){ + //If addressing is single, we need to start every command with a starting possition + segmentString = '' + i + ','; + //Fixed to b2 + } else{ + segmentString = '' + } + } + else { + segmentString = segmentStart + ',' + segmentEnd + ','; + } + } + } else{ + //Write every pixel + if (JSONledString == ''){ + //If addressing is single, we need to start every command with a starting possition + JSONledString = i + //Fixed to b2 + } + + segmentStart = i + segmentEnd = i + //Segment string should be empty for when addressing single. So no need to set it again. + } + + if (a < 255){ + hasTransparency = true; //If ANY pixel has alpha < 255 then this is set to true to warn the user + } + + if (segmentEnd > -1){ + //This is the last pixel in the segment, write to the JSONledString + //Return color value in selected format + let colorValueString = r + ',' + g + ',' + b ; + + if (hexValueCheck){ + const [red, green, blue] = [r, g, b]; + colorValueString = `${[red, green, blue].map(x => x.toString(16).padStart(2, '0')).join('')}`; + } else{ + //do nothing, allready set + } + + // Check if start and end is the same, in which case remove + + JSONledString += segmentString + colorSeparatorStart + colorValueString + colorSeparatorEnd; + fileJSON = JSONledString + segmentString + colorSeparatorStart + colorValueString + colorSeparatorEnd; + + curentColorIndex = curentColorIndex + 1; // We've just added a new color to the string so up the count with one + + if (curentColorIndex % maxNoOfColorsInCommandSting === 0 || i == maxi - 1) { + + //If we have accumulated the max number of colors to send in a single command or if this is the last pixel, we should write the current colorstring to the array + commandArray.push(JSONledString); + JSONledString = ''; //Start on an new command string + } else + { + //Add a comma to continue the command string + JSONledString = JSONledString + ',' + } + //Reset segment values + segmentStart = - 1; + } + } + + JSONledString = '' + + //For every commandString in the array + for (let i = 0; i < commandArray.length; i++) { + let thisJSONledString = `{"on":true,"bri":${brgh.value},"seg":{"id":${segID},"i":[${commandArray[i]}]}}`; + httpArray.push(thisJSONledString); + + let thiscurlString = `curl -X POST "http://${gurl.value}/json/state" -d \'${thisJSONledString}\' -H "Content-Type: application/json"`; + + //Aggregated Strings That should be returned to the user + if (i > 0){ + JSONledString = JSONledString + '\n'; + curlString = curlString + ' && '; + } + JSONledString += thisJSONledString; + curlString += thiscurlString; + } + + + haString = `#Uncomment if you don\'t allready have these defined in your switch section of your configuration.yaml +#- platform: command_line + #switches: + ${haIDe.value} + friendly_name: ${haNe.value} + unique_id: ${haUe.value} + command_on: > + ${curlString} + command_off: > + curl -X POST "http://${gurl.value}/json/state" -d \'{"on":false}\' -H "Content-Type: application/json"`; + + if (formatSelection == 'wled'){ + JLD.value = JSONledString; + } else if (formatSelection == 'curl'){ + JLD.value = curlString; + } else if (formatSelection == 'ha'){ + JLD.value = haString; + } else { + JLD.value = 'ERROR!/n' + formatSelection + ' is an unknown format.' + } + + fileJSON += ']}}'; + + let infoDiv = imin; + let canvasDiv = imin; + if (hasTransparency){ + imageInfo = imageInfo + '

WARNING! Transparency info detected in image. Transparency (alpha) has been ignored. To ensure you get the result you desire, use only solid colors in your image.

' + } + + infoDiv.innerHTML = imageInfo; + canvasDiv.style.display = "block" + + + //Drawing the image + drawBoxes(pixelRGBValues, sizeX, sizeY); + } +} \ No newline at end of file diff --git a/wled00/data/pixart/pixart.css b/wled00/data/pixart/pixart.css new file mode 100644 index 000000000..39ba1f283 --- /dev/null +++ b/wled00/data/pixart/pixart.css @@ -0,0 +1,324 @@ + +.box { + border: 2px solid #fff; +} +body { + font-family: Arial, sans-serif; + background-color: #111; +} + +.top-part { + width: 600px; + margin: 0 auto; +} +.container { + max-width: 100% -40px; + border-radius: 0px; + padding: 20px; + text-align: center; +} +h1 { + font-size: 2.3em; + color: #ddd; + margin: 1px 0; + font-family: Arial, sans-serif; + line-height: 0.5; + /*text-align: center;*/ +} +h2 { + font-size: 1.1em; + color: rgba(221, 221, 221, 0.61); + margin: 1px 0; + font-family: Arial, sans-serif; + line-height: 0.5; + text-align: center; +} +h3 { + font-size: 0.7em; + color: rgba(221, 221, 221, 0.61); + margin: 1px 0; + font-family: Arial, sans-serif; + line-height: 1.4; + text-align: center; + align-items: center; + justify-content: center; + display: flex; +} + +p { + font-size: 1em; + color: #777; + line-height: 1.5; + font-family: Arial, sans-serif; +} + +#fieldTable { + font-size: 1 em; + color: #777; + line-height: 1; + font-family: Arial, sans-serif; +} + +#scaleTable { + font-size: 1 em; + color: #777; + line-height: 1; + font-family: Arial, sans-serif; +} + +#drop-zone { + display: block; + width: 100%-40px; + border: 3px dashed #ddd; + border-radius: 0px; + text-align: center; + padding: 20px; + margin: 0px; + cursor: pointer; + font-family: Arial, sans-serif; + font-size: 15px; + color: #777; +} + +#file-picker { + display: none; +} +.adaptiveTD{ + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + +} + +.mainSelector { + background-color: #222; + color: #ddd; + border: 1px solid #333; + margin-top: 4px; + margin-bottom: 4px; + padding: 0 8px; + height: 28px; + font-size: 15px; + border-radius: 7px; + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.adaptiveSelector { + background-color: #222; + color: #ddd; + border: 1px solid #333; + margin-top: 4px; + margin-bottom: 4px; + padding: 0 8px; + height: 28px; + font-size: 15px; + border-radius: 7px; + flex-grow: 1; + display: none; +} + +.segmentsDiv{ + width: 36px; + padding-left: 5px; +} + +* input[type=range] { + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + flex-grow: 1; + padding: 0; + margin: 4px 8px 4px 0; + background-color: transparent; + cursor: pointer; + background: linear-gradient(to right, #bbb 50%, #333 50%); + border-radius: 7px; +} + +input[type=range]:focus { + outline: none; +} +input[type=range]::-webkit-slider-runnable-track { + height: 28px; + cursor: pointer; + background: transparent; + border-radius: 7px; +} +input[type=range]::-webkit-slider-thumb { + height: 16px; + width: 16px; + border-radius: 50%; + background: #fff; + cursor: pointer; + -webkit-appearance: none; + margin-top: 4px; + border-radius: 7px; +} +input[type=range]::-moz-range-track { + height: 28px; + background-color: rgba(0, 0, 0, 0); + border-radius: 7px; +} +input[type=range]::-moz-range-thumb { + border: 0px solid rgba(0, 0, 0, 0); + height: 16px; + width: 16px; + border-radius: 7px; + background: #fff; +} + +.rangeNumber{ + width: 20px; + vertical-align: middle; +} + +.fullTextField[type=text] { + background-color: #222; + border: 1px solid #333; + padding-inline-start: 5px; + margin-top: 4px; + margin-bottom: 4px; + height: 24px; + border-radius: 0px; + font-family: Arial, sans-serif; + font-size: 15px; + color: #ddd; + border-radius: 7px; + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; +} +.flxTFld{ + background-color: #222; + border: 1px solid #333; + padding-inline-start: 5px; + height: 24px; + border-radius: 0px; + font-family: Arial, sans-serif; + font-size: 15px; + color: #ddd; + border-radius: 7px; + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; +} + +* input[type=submit] { + background-color: #222; + border: 1px solid #333; + padding: 0.5em; + width: 100%; + border-radius: 24px; + font-family: Arial, sans-serif; + font-size: 1.3em; + color: #ddd; +} + +* button { + background-color: #222; + border: 1px solid #333; + padding-inline: 5px; + width: 100%; + border-radius: 24px; + font-family: Arial, sans-serif; + font-size: 1em; + color: #ddd; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +#scaleDiv { + display: flex; + align-items: center; + vertical-align: middle; +} + +textarea { + grid-row: 1 / 2; + width: 100%; + height: 200px; + background-color: #222; + border: 1px solid #333; + color: #ddd; +} +.hide { + display: none; +} + +.svg-icon { + vertical-align: middle; +} +#image-container { + display: grid; + grid-template-rows: 1fr 1fr; +} +#button-container { + display: flex; + padding-bottom: 10px; + padding-top: 10px; +} + +.buttonclass { + flex: 1; + padding-top: 5px; + padding-bottom: 5px; +} + +.gap { + width: 10px; +} + +#submitConvert::before { + content: ""; + display: inline-block; + background-image: url('data:image/svg+xml;utf8, '); + width: 36px; + height: 36px; +} + +#sizeDiv * { + display: inline-block; +} +.sizeInputFields{ + width: 50px; + background-color: #222; + border: 1px solid #333; + padding-inline-start: 5px; + margin-top: -5px; + height: 24px; + border-radius: 7px; + font-family: Arial, sans-serif; + font-size: 15px; + color: #ddd; +} +a:link { + color: rgba(221, 221, 221, 0.61); + background-color: transparent; + text-decoration: none; +} + +a:visited { + color: rgba(221, 221, 221, 0.61); + background-color: transparent; + text-decoration: none; +} + +a:hover { + color: #ddd; + background-color: transparent; + text-decoration: none; +} + +a:active { + color: rgba(221, 221, 221, 0.61); + background-color: transparent; + text-decoration: none; +} \ No newline at end of file diff --git a/wled00/data/pixart/pixart.htm b/wled00/data/pixart/pixart.htm new file mode 100644 index 000000000..889bd37da --- /dev/null +++ b/wled00/data/pixart/pixart.htm @@ -0,0 +1,210 @@ + + + + + + + WLED Pixel Art Converter + + + + + + +
+
+

+ + + + + + + WLED Pixel Art Converter +

+
+

Convert image to WLED JSON (pixel art on WLED matrix)

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + 128 +
+ + + + 256 +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + +
+
+ + + + + +
+
+ + + +  Scale image +
+
+ +
+

+ +

+

+ Drop image here
or
+ Click to select a file +
+ +

+ +

+ +

+ +
+ + + +

+ + + + +
+

Version 1.0.7
 -  Help/About

+
+
+ + + + + + + + + \ No newline at end of file diff --git a/wled00/data/pixart/pixart.js b/wled00/data/pixart/pixart.js new file mode 100644 index 000000000..a1c67aa99 --- /dev/null +++ b/wled00/data/pixart/pixart.js @@ -0,0 +1,364 @@ +//Start up code +//if (window.location.protocol == "file:") { +// let locip = prompt("File Mode. Please enter WLED IP!"); +// gId('curlUrl').value = locip; +//} else +// +//Start up code +let devMode = false; //Remove +gurl.value = location.host; + +const urlParams = new URLSearchParams(window.location.search); +if (gurl.value.length < 1){ + gurl.value = "Missing_Host"; +} + +function gen(){ + //Generate image if enough info is in place + //Is host non empty + //Is image loaded + //is scale > 0 + if (((szX.value > 0 && szY.value > 0) || szDiv.style.display == 'none') && gurl.value.length > 0 && prw.style.display != 'none'){ + //regenerate + let base64Image = prw.src; + if (isValidBase64Gif(base64Image)) { + im.src = base64Image; + getPixelRGBValues(base64Image); + imcn.style.display = "block"; + bcn.style.display = ""; + } else { + let imageInfo = '

WARNING! File does not appear to be a valid image

'; + imin.innerHTML = imageInfo; + imin.style.display = "block"; + imcn.style.display = "none"; + JLD.value = ''; + if (devMode) console.log("The string '" + base64Image + "' is not a valid base64 image."); + } + } + + if(gurl.value.length > 0){ + gId("sSg").setAttribute("fill", accentColor); + } else{ + gId("sSg").setAttribute("fill", accentTextColor); + let ts = tSg; + ts.style.display = "none"; + ts.innerHTML = ""; + sID.style.display = "flex"; + } +} + + +// Code for copying the generated string to clipboard + +cjb.addEventListener('click', async () => { + let JSONled = JLD; + JSONled.select(); + try { + await navigator.clipboard.writeText(JSONled.value); + } catch (err) { + try { + await d.execCommand("copy"); + } catch (err) { + console.error('Failed to copy text: ', err); + } + } +}); + +// Event listeners ======================= + +lSS.addEventListener("change", gen); +szY.addEventListener("change", gen); +szX.addEventListener("change", gen); +//frm.addEventListener("change", gen); +cFS.addEventListener("change", gen); +aS.addEventListener("change", gen); +brgh.addEventListener("change", gen); +cLN.addEventListener("change", gen); +haIDe.addEventListener("change", gen); +haUe.addEventListener("change", gen); +haNe.addEventListener("change", gen); +gurl.addEventListener("change", gen); +sID.addEventListener("change", gen); +prw.addEventListener("load", gen); +//gId("convertbutton").addEventListener("click", gen); + +tSg.addEventListener("change", () => { + sop = tSg.options[tSg.selectedIndex]; + szX.value = sop.dataset.x; + szY.value = sop.dataset.y; + gen(); +}); + +gId("sendJSONledbutton").addEventListener('click', async () => { + if (window.location.protocol === "https:") { + alert('Will only be available when served over http (or WLED is run over https)'); + } else { + postPixels(); + } +}); + +brgh.oninput = () => { + brgV.textContent = brgh.value; + let perc = parseInt(brgh.value)*100/255; + var val = `linear-gradient(90deg, #bbb ${perc}%, #333 ${perc}%)`; + brgh.style.backgroundImage = val; +} + +cLN.oninput = () => { + let cln = cLN; + cLV.textContent = cln.value; + let perc = parseInt(cln.value)*100/512; + var val = `linear-gradient(90deg, #bbb ${perc}%, #333 ${perc}%)`; + cln.style.backgroundImage = val; +} + +frm.addEventListener("change", () => { + for (var i = 0; i < hideableRows.length; i++) { + hideableRows[i].classList.toggle("hide", frm.value !== "ha"); + } +}); + +async function postPixels() { + let ss = gId("sendSvgP"); + ss.setAttribute("fill", prsCol); + let er = false; + for (let i of httpArray) { + try { + if (devMode) console.log(i); + if (devMode) console.log(i.length); + const response = await fetch('http://'+gId('curlUrl').value+'/json/state', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + //'Content-Type': 'text/html; charset=UTF-8' + }, + body: i + }); + const data = await response.json(); + if (devMode) console.log(data); + } catch (error) { + console.error(error); + er = true; + } + } + if(er){ + //Something went wrong + ss.setAttribute("fill", redColor); + setTimeout(function(){ + ss.setAttribute("fill", accentTextColor); + }, 1000); + } else { + // A, OK + ss.setAttribute("fill", greenColor); + setTimeout(function(){ + ss.setAttribute("fill", accentColor); + }, 1000); + } +} + +//File uploader code +const dropZone = gId('drop-zone'); +const filePicker = gId('file-picker'); +const preview = prw; + +// Listen for dragenter, dragover, and drop events +dropZone.addEventListener('dragenter', dragEnter); +dropZone.addEventListener('dragover', dragOver); +dropZone.addEventListener('drop', dropped); +dropZone.addEventListener('click', zoneClicked); + +// Listen for change event on file picker +filePicker.addEventListener('change', filePicked); + +// Handle zone click +function zoneClicked(e) { + e.preventDefault(); + //this.classList.add('drag-over'); + //alert('Hej'); + filePicker.click(); +} + +// Handle dragenter +function dragEnter(e) { + e.preventDefault(); + this.classList.add('drag-over'); +} + +// Handle dragover +function dragOver(e) { + e.preventDefault(); +} + +// Handle drop +function dropped(e) { + e.preventDefault(); + this.classList.remove('drag-over'); + + // Get the dropped file + const file = e.dataTransfer.files[0]; + updatePreview(file) +} + +// Handle file picked +function filePicked(e) { + // Get the picked file + const file = e.target.files[0]; + updatePreview(file) +} + +// Update the preview image +function updatePreview(file) { + // Use FileReader to read the file + const reader = new FileReader(); + reader.onload = () => { + // Update the preview image + preview.src = reader.result; + //gId("submitConvertDiv").style.display = ""; + prw.style.display = ""; + }; + reader.readAsDataURL(file); +} + +function isValidBase64Gif(string) { + // Use a regular expression to check that the string is a valid base64 string + /* + const base64gifPattern = /^data:image\/gif;base64,([A-Za-z0-9+/:]{4})*([A-Za-z0-9+/:]{3}=|[A-Za-z0-9+/:]{2}==)?$/; + const base64pngPattern = /^data:image\/png;base64,([A-Za-z0-9+/:]{4})*([A-Za-z0-9+/:]{3}=|[A-Za-z0-9+/:]{2}==)?$/; + const base64jpgPattern = /^data:image\/jpg;base64,([A-Za-z0-9+/:]{4})*([A-Za-z0-9+/:]{3}=|[A-Za-z0-9+/:]{2}==)?$/; + const base64webpPattern = /^data:image\/webp;base64,([A-Za-z0-9+/:]{4})*([A-Za-z0-9+/:]{3}=|[A-Za-z0-9+/:]{2}==)?$/; + */ + //REMOVED, Any image appear to work as long as it can be drawn to the canvas. Leaving code in for future use, possibly + if (1==1 || base64gifPattern.test(string) || base64pngPattern.test(string) || base64jpgPattern.test(string) || base64webpPattern.test(string)) { + return true; + } else { + //Not OK + return false; + } +} + +var hideableRows = d.querySelectorAll(".ha-hide"); +for (var i = 0; i < hideableRows.length; i++) { + hideableRows[i].classList.add("hide"); +} +frm.addEventListener("change", () => { + for (var i = 0; i < hideableRows.length; i++) { + hideableRows[i].classList.toggle("hide", frm.value !== "ha"); + } +}); + +function switchScale() { + //let scalePath = gId("scaleDiv").children[1].children[0] + let scaleTogglePath = scDiv.children[0].children[0] + let color = scaleTogglePath.getAttribute("fill"); + let d = ''; + if (color === accentColor) { + color = accentTextColor; + d = scaleToggleOffd; + szDiv.style.display = "none"; + // Set values to actual XY of image, if possible + } else { + color = accentColor; + d = scaleToggleOnd; + szDiv.style.display = ""; + } + //scalePath.setAttribute("fill", color); + scaleTogglePath.setAttribute("fill", color); + scaleTogglePath.setAttribute("d", d); + gen(); +} + +function generateSegmentOptions(array) { + //This function is prepared for a name property on each segment for easier selection + //Currently the name is generated generically based on index + tSg.innerHTML = ""; + for (var i = 0; i < array.length; i++) { + var option = cE("option"); + option.value = array[i].value; + option.text = array[i].text; + option.dataset.x = array[i].x; + option.dataset.y = array[i].y; + tSg.appendChild(option); + if(i === 0) { + option.selected = true; + szX.value = option.dataset.x; + szY.value = option.dataset.y; + } + } +} + +// Get segments from device +async function getSegments() { + cv = gurl.value; + if (cv.length > 0 ){ + try { + var arr = []; + const response = await fetch('http://'+cv+'/json/state'); + const json = await response.json(); + let ids = json.seg.map(sg => ({id: sg.id, n: sg.n, xs: sg.start, xe: sg.stop, ys: sg.startY, ye: sg.stopY})); + for (var i = 0; i < ids.length; i++) { + arr.push({ + value: ids[i]["id"], + text: ids[i]["n"] + ' (index: ' + ids[i]["id"] + ')', + x: ids[i]["xe"] - ids[i]["xs"], + y: ids[i]["ye"] - ids[i]["ys"] + }); + } + generateSegmentOptions(arr); + tSg.style.display = "flex"; + sID.style.display = "none"; + gId("sSg").setAttribute("fill", greenColor); + setTimeout(function(){ + gId("sSg").setAttribute("fill", accentColor); + }, 1000); + + } catch (error) { + console.error(error); + gId("sSg").setAttribute("fill", redColor); + setTimeout(function(){ + gId("sSg").setAttribute("fill", accentColor); + }, 1000); + tSg.style.display = "none"; + sID.style.display = "flex"; + } + } else{ + gId("sSg").setAttribute("fill", redColor); + setTimeout(function(){ + gId("sSg").setAttribute("fill", accentTextColor); + }, 1000); + tSg.style.display = "none"; + sID.style.display = "flex"; + } +} + +//Initial population of segment selection +function generateSegmentArray(noOfSegments) { + var arr = []; + for (var i = 0; i < noOfSegments; i++) { + arr.push({ + value: i, + text: "Segment index " + i + }); + } + return arr; +} + +var segmentData = generateSegmentArray(10); + +generateSegmentOptions(segmentData); + +seDiv.innerHTML = +'' +/*gId("convertbutton").innerHTML = +'   Convert to WLED JSON '; +*/ +cjb.innerHTML = +'   Copy to clipboard'; +gId("sendJSONledbutton").innerHTML = +'   Send to device'; + +//After everything is loaded, check if we have a possible IP/host + +if(gurl.value.length > 0){ + // Needs to be addressed directly here so the object actually exists + gId("sSg").setAttribute("fill", accentColor); +} diff --git a/wled00/data/pixart/site.webmanifest b/wled00/data/pixart/site.webmanifest new file mode 100644 index 000000000..82452af2e --- /dev/null +++ b/wled00/data/pixart/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "WLED Pixel Art Convertor", + "short_name": "ledconv", + "icons": [ + { + "src": "/favicon-32x32.png", + "sizes": "32x322", + "type": "image/png" + }, + { + "src": "/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" + } \ No newline at end of file diff --git a/wled00/data/pixart/statics.js b/wled00/data/pixart/statics.js new file mode 100644 index 000000000..b4f3c4071 --- /dev/null +++ b/wled00/data/pixart/statics.js @@ -0,0 +1,51 @@ +//elements +var gurl = gId('curlUrl'); +var szX = gId("sizeX"); +var szY = gId("sizeY"); +var szDiv = gId("sizeDiv"); +var prw = gId("preview"); +var sID = gId('segID'); +var JLD = gId('JSONled'); +var tSg = gId('targetSegment'); +var brgh = gId("brightnessNumber"); + +var seDiv = gId("getSegmentsDiv") +var cjb = gId("copyJSONledbutton"); +var frm = gId("formatSelector"); +var cLN = gId("colorLimitNumber"); +var haIDe = gId("haID"); +var haUe = gId("haUID"); +var haNe = gId("haName"); +var aS = gId("addressingSelector"); +var cFS = gId("colorFormatSelector"); +var lSS = gId("ledSetupSelector"); +var imin = gId('image-info'); +var imcn = gId('image-container'); +var bcn = gId("button-container"); +var im = gId('image'); +//var ss = gId("sendSvgP"); +var scDiv = gId("scaleDiv"); +var w = window; +var canvas = gId('pixelCanvas'); +var brgV = gId("brightnessValue"); +var cLV = gId("colorLimitValue") + +//vars +var httpArray = []; +var fileJSON = ''; + +var hideableRows = d.querySelectorAll(".ha-hide"); +for (var i = 0; i < hideableRows.length; i++) { + hideableRows[i].classList.add("hide"); +} + +var accentColor = '#eee'; +var accentTextColor = '#777'; +var prsCol = '#ccc'; +var greenColor = '#056b0a'; +var redColor = '#6b050c'; + +var scaleToggleOffd = "M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M7,15A3,3 0 0,1 4,12A3,3 0 0,1 7,9A3,3 0 0,1 10,12A3,3 0 0,1 7,15Z"; +var scaleToggleOnd = "M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M17,15A3,3 0 0,1 14,12A3,3 0 0,1 17,9A3,3 0 0,1 20,12A3,3 0 0,1 17,15Z"; + +var sSg = gId("getSegmentsSVGpath"); \ No newline at end of file diff --git a/wled00/html_pixart.h b/wled00/html_pixart.h new file mode 100644 index 000000000..29f5fffc9 --- /dev/null +++ b/wled00/html_pixart.h @@ -0,0 +1,532 @@ +/* + * Binary array for the Web UI. + * gzip is used for smaller size and improved speeds. + * + * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui + * to find out how to easily modify the web UI source! + */ + +// Autogenerated from wled00/data/pixart/pixart.htm, do not edit!! +const uint16_t PAGE_pixart_L = 8313; +const uint8_t PAGE_pixart[] PROGMEM = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0x3c, 0x6b, 0x7b, 0xda, 0x38, + 0xb3, 0xdf, 0xf3, 0x2b, 0x54, 0xb7, 0xdb, 0xe2, 0xc5, 0x18, 0xdb, 0x5c, 0x03, 0x71, 0xfa, 0x10, + 0x72, 0x21, 0xdb, 0x5c, 0x21, 0x49, 0x93, 0xe6, 0xcd, 0xd3, 0x1a, 0x2c, 0xc0, 0x89, 0xb1, 0xa9, + 0x6d, 0x20, 0x84, 0xf2, 0xdf, 0xcf, 0x8c, 0x64, 0x83, 0xb9, 0xa4, 0x49, 0x7b, 0xba, 0xef, 0x73, + 0xce, 0x76, 0x83, 0x6d, 0x69, 0x24, 0x8d, 0xe6, 0x3e, 0x23, 0xc3, 0xd6, 0x9b, 0xdd, 0xd3, 0xea, + 0xc5, 0xcd, 0xd9, 0x1e, 0xe9, 0x06, 0x3d, 0x7b, 0x9b, 0x6c, 0x45, 0x17, 0x6a, 0x98, 0x70, 0xe9, + 0xd1, 0xc0, 0x80, 0x9e, 0xa0, 0x9f, 0xa2, 0xdf, 0x07, 0xd6, 0x50, 0x17, 0xaa, 0x46, 0xab, 0x4b, + 0x53, 0x55, 0xd7, 0x09, 0x3c, 0xd7, 0x16, 0xc8, 0x46, 0x0b, 0xee, 0xa8, 0x13, 0xe8, 0x82, 0xe3, + 0xa6, 0x5a, 0xd8, 0x27, 0x11, 0xb8, 0xf3, 0x03, 0xd7, 0x83, 0xbb, 0xde, 0xc0, 0x0f, 0x52, 0x1e, + 0x1d, 0x1a, 0xb6, 0x65, 0x1a, 0x01, 0x15, 0xd6, 0x4d, 0x78, 0xe6, 0x19, 0x9d, 0x9e, 0xb1, 0x6e, + 0xa6, 0xb5, 0xe0, 0x7b, 0x8f, 0x7d, 0xcb, 0xa3, 0xbe, 0x40, 0x66, 0xe0, 0x0a, 0xc2, 0x05, 0x56, + 0x60, 0xd3, 0xed, 0x8d, 0xcf, 0x47, 0x7b, 0xbb, 0xe4, 0xcc, 0x7a, 0xa4, 0x36, 0xa9, 0x78, 0x01, + 0x01, 0x34, 0x87, 0xd4, 0x0b, 0xa8, 0xb7, 0x95, 0xe6, 0x00, 0x64, 0xcb, 0x0f, 0xc6, 0x08, 0x28, + 0x37, 0xdd, 0xc7, 0x49, 0xd3, 0xf5, 0x4c, 0xea, 0x95, 0xb4, 0xfe, 0x23, 0xf1, 0x5d, 0x40, 0x91, + 0xbc, 0x6d, 0xb7, 0xdb, 0xd3, 0xa6, 0x6b, 0x8e, 0x27, 0x6d, 0x98, 0x3d, 0xd5, 0x36, 0x7a, 0x96, + 0x3d, 0x2e, 0x55, 0x3c, 0xcb, 0xb0, 0x25, 0xdf, 0x70, 0xfc, 0x94, 0x4f, 0x3d, 0xab, 0x5d, 0x6e, + 0x1a, 0xad, 0x87, 0x8e, 0xe7, 0x0e, 0x1c, 0x33, 0xd5, 0x72, 0x6d, 0xd7, 0x2b, 0xbd, 0x55, 0x55, + 0x75, 0x2a, 0x07, 0x6e, 0x3f, 0xd5, 0x37, 0xbc, 0x60, 0x32, 0xb2, 0xcc, 0xa0, 0x5b, 0xca, 0x2b, + 0x4a, 0xff, 0xb1, 0xdc, 0x33, 0xbc, 0x8e, 0xe5, 0x94, 0x14, 0x62, 0x0c, 0x02, 0x77, 0x2a, 0x23, + 0xd6, 0x86, 0xe5, 0x50, 0x6f, 0xd2, 0x33, 0x1e, 0x53, 0x1c, 0x50, 0x55, 0x94, 0xbf, 0x48, 0x2a, + 0x8b, 0xd0, 0x1c, 0xa3, 0x94, 0x67, 0x98, 0xd6, 0xc0, 0x2f, 0x29, 0xe5, 0xbe, 0x61, 0x9a, 0x96, + 0xd3, 0x29, 0x69, 0xd8, 0x19, 0xd0, 0xc7, 0x20, 0x05, 0xa4, 0xec, 0x38, 0xa5, 0x16, 0xec, 0x9c, + 0x7a, 0xd3, 0xae, 0xca, 0x11, 0xf5, 0xad, 0x27, 0x5a, 0xd2, 0xe4, 0x0c, 0xed, 0x95, 0x43, 0x84, + 0x4c, 0xd3, 0x8c, 0x96, 0x56, 0x61, 0x7b, 0x4a, 0xf9, 0xa7, 0x1b, 0xb2, 0x01, 0xa3, 0x54, 0x97, + 0x5a, 0x9d, 0x6e, 0x50, 0x92, 0x73, 0xd3, 0xae, 0x16, 0x9b, 0x56, 0x95, 0xd5, 0xd9, 0xb4, 0x5e, + 0xa7, 0x69, 0x24, 0x34, 0x4d, 0x95, 0xa2, 0x3f, 0x39, 0xaf, 0x8a, 0xbf, 0xbd, 0xce, 0xba, 0x0d, + 0x65, 0x62, 0x2b, 0xcb, 0x85, 0x7f, 0x65, 0x61, 0x55, 0xce, 0xae, 0xae, 0x5c, 0x66, 0x0f, 0x29, + 0x2b, 0xa0, 0x3d, 0x3f, 0x6a, 0xba, 0x07, 0xe9, 0xb5, 0xda, 0xe3, 0x54, 0x28, 0x69, 0x51, 0xb3, + 0x69, 0xf9, 0x7d, 0xdb, 0x18, 0x97, 0xda, 0x36, 0x7d, 0x9c, 0xf6, 0xe3, 0x94, 0x9a, 0x93, 0xbf, + 0x50, 0x28, 0x2c, 0xad, 0x99, 0xfb, 0x29, 0x82, 0xd3, 0xb7, 0x6d, 0x8b, 0xda, 0xe6, 0x85, 0xd1, + 0xb4, 0x69, 0x7c, 0x46, 0xf2, 0x93, 0x29, 0x5f, 0x98, 0xd0, 0x6f, 0x19, 0x36, 0xfd, 0x93, 0x13, + 0x9a, 0x1e, 0xc8, 0xf7, 0x93, 0xeb, 0xd0, 0x49, 0x44, 0x81, 0xa6, 0xed, 0xb6, 0x1e, 0xca, 0x73, + 0x21, 0x8e, 0xcb, 0x70, 0x29, 0x03, 0x5c, 0x31, 0x0d, 0xbf, 0x4b, 0x41, 0xad, 0x50, 0x1a, 0x97, + 0x45, 0x7b, 0x95, 0x05, 0x0b, 0xc2, 0x1e, 0xe9, 0x4d, 0xb9, 0x35, 0xf0, 0x7c, 0x40, 0xb7, 0xef, + 0x5a, 0x0c, 0xe8, 0xa7, 0x6c, 0x8e, 0x6d, 0x34, 0x07, 0x73, 0xcc, 0x37, 0x8a, 0xf4, 0xb5, 0x69, + 0xaa, 0x6f, 0xb5, 0x1e, 0x40, 0xf5, 0x22, 0xfc, 0x1d, 0xd8, 0xcc, 0x54, 0x36, 0x4c, 0xa3, 0x1f, + 0x58, 0x43, 0x7a, 0xb1, 0x3b, 0x89, 0xb3, 0xb6, 0x8c, 0x1f, 0x29, 0x13, 0x8c, 0x4d, 0x2b, 0xb0, + 0x5c, 0xa7, 0xe4, 0xb9, 0x23, 0xde, 0x34, 0xf2, 0x8c, 0x3e, 0x0c, 0xc5, 0xcb, 0x1a, 0xa9, 0x99, + 0xca, 0x3d, 0xd0, 0xef, 0x06, 0xb5, 0x61, 0x98, 0xeb, 0x4d, 0x56, 0x4d, 0x85, 0xa6, 0x69, 0x71, + 0x25, 0x0d, 0xa9, 0xa5, 0xce, 0x6d, 0x50, 0x26, 0x93, 0x09, 0x77, 0x9f, 0x02, 0x8b, 0x52, 0xca, + 0xce, 0x88, 0x91, 0x6a, 0xba, 0x41, 0xe0, 0xf6, 0x58, 0x4b, 0x44, 0x2b, 0x85, 0x14, 0xe1, 0x29, + 0xe4, 0xa0, 0x86, 0xf7, 0x4b, 0x34, 0x58, 0x24, 0x7b, 0xa1, 0x1f, 0xee, 0x0b, 0x70, 0x1a, 0x01, + 0xc7, 0x17, 0x36, 0xfc, 0x6a, 0x15, 0x98, 0xd3, 0xec, 0xff, 0xdb, 0x3e, 0x39, 0xc7, 0x7d, 0xda, + 0xe9, 0xc1, 0x46, 0xfc, 0x5d, 0x6b, 0x18, 0xda, 0xea, 0x4c, 0x7e, 0xbe, 0x56, 0xca, 0xa6, 0xed, + 0xa0, 0x04, 0x73, 0x4e, 0xff, 0x26, 0x96, 0xd3, 0x1f, 0x04, 0xb7, 0xc1, 0xb8, 0x4f, 0x75, 0xcf, + 0x70, 0x3a, 0xf4, 0x6e, 0x62, 0xf4, 0xfb, 0xd4, 0x80, 0xfb, 0x16, 0x65, 0x93, 0x95, 0x53, 0x3d, + 0xf7, 0x29, 0xb5, 0xd2, 0x38, 0xa2, 0xcd, 0x07, 0x2b, 0x58, 0x69, 0x8f, 0xa3, 0x34, 0xdb, 0x59, + 0x24, 0xea, 0xb0, 0x5d, 0xdc, 0x24, 0xc9, 0x32, 0x73, 0xb6, 0x42, 0xd0, 0x00, 0xe6, 0xf1, 0xc1, + 0xbd, 0x00, 0xe2, 0xcb, 0x3a, 0x31, 0x87, 0x2d, 0xa1, 0x42, 0x1b, 0x1e, 0xac, 0x01, 0x74, 0x00, + 0xc8, 0x44, 0xe0, 0x12, 0x0f, 0x69, 0x26, 0xbd, 0x6d, 0x36, 0x9b, 0x24, 0xa7, 0xfc, 0x25, 0x21, + 0xdd, 0xf1, 0x46, 0x5c, 0x25, 0xd9, 0x74, 0x65, 0xbb, 0xa5, 0xb6, 0xdb, 0x1a, 0xf8, 0x13, 0x77, + 0x10, 0xe0, 0xc4, 0x25, 0x65, 0x0d, 0x44, 0x29, 0xda, 0xac, 0x0f, 0x5c, 0xc5, 0xe9, 0x06, 0x8e, + 0x83, 0x56, 0x27, 0x05, 0x08, 0xb7, 0x1e, 0x26, 0x71, 0x96, 0x3d, 0x8f, 0xb6, 0x82, 0x3b, 0x7e, + 0x05, 0x3a, 0xcb, 0x8b, 0x05, 0xdd, 0x41, 0xaf, 0x19, 0xad, 0xa1, 0x22, 0x13, 0x43, 0x6b, 0x94, + 0x5f, 0x11, 0x09, 0xd8, 0x72, 0x7c, 0x45, 0x74, 0xf5, 0xcb, 0x08, 0x3d, 0xc7, 0xb6, 0x25, 0x29, + 0x7d, 0x1d, 0xa2, 0x28, 0x17, 0xec, 0x61, 0x0d, 0x21, 0x56, 0x98, 0xcb, 0xfc, 0x9b, 0x22, 0xb1, + 0x7f, 0xe2, 0xaf, 0x2f, 0xc0, 0xa8, 0x10, 0x6a, 0x98, 0x12, 0xea, 0x57, 0x5c, 0x5e, 0x5e, 0x45, + 0xa0, 0xc2, 0x02, 0x62, 0x8c, 0x40, 0x53, 0x99, 0x2d, 0x70, 0x02, 0xd3, 0x83, 0xd9, 0xe4, 0x23, + 0x99, 0x75, 0xc6, 0xa8, 0xca, 0x02, 0x07, 0x13, 0x1a, 0xf0, 0x9e, 0x65, 0x9a, 0x36, 0x28, 0x56, + 0x7b, 0x60, 0xdb, 0x17, 0x60, 0xd7, 0xf7, 0xd1, 0x99, 0x71, 0x74, 0xd1, 0xcc, 0xdf, 0x3d, 0x63, + 0x1e, 0xd6, 0xdb, 0x84, 0x48, 0x0d, 0x2d, 0x87, 0x79, 0x27, 0x3f, 0x80, 0x90, 0x0a, 0xd5, 0xf1, + 0x65, 0x63, 0x11, 0x91, 0x38, 0xbb, 0x26, 0x92, 0xfa, 0x0d, 0xbf, 0xb1, 0xea, 0xb5, 0xfe, 0x94, + 0xf9, 0x6c, 0xdb, 0x8f, 0x17, 0xfb, 0xb6, 0xf9, 0x67, 0xc8, 0xf2, 0xff, 0x65, 0xd7, 0x0b, 0xd6, + 0xd4, 0x1f, 0x34, 0x7b, 0xd6, 0xef, 0x09, 0x06, 0x44, 0x8e, 0x10, 0xc4, 0xcc, 0xa3, 0x8e, 0x25, + 0x6c, 0x19, 0x1d, 0x5e, 0xbb, 0xef, 0xa5, 0x90, 0x19, 0x70, 0x6c, 0x0e, 0x40, 0x9c, 0x9c, 0xff, + 0x05, 0x67, 0x18, 0x4f, 0xfe, 0x0c, 0x76, 0x8b, 0xe1, 0xfc, 0xef, 0x91, 0x7d, 0xc9, 0xc6, 0x85, + 0x71, 0x21, 0x7a, 0xbe, 0x97, 0xe6, 0x5b, 0xaf, 0xe3, 0xa8, 0xcf, 0x60, 0x54, 0x8c, 0x49, 0xc7, + 0xb3, 0xcc, 0x14, 0x13, 0x88, 0xb4, 0x16, 0xdf, 0x6f, 0x24, 0x8e, 0x2c, 0xfb, 0xf9, 0x15, 0x32, + 0xc6, 0xd8, 0x20, 0x77, 0xc1, 0xba, 0x2f, 0x85, 0x69, 0xfe, 0x10, 0x28, 0x0c, 0x7b, 0x9b, 0xac, + 0xc7, 0xeb, 0xad, 0xd5, 0x33, 0xc0, 0x14, 0xce, 0xf3, 0xab, 0x68, 0x34, 0xe2, 0x59, 0x66, 0xc8, + 0xc2, 0xe6, 0xa0, 0x25, 0xa0, 0x88, 0xb5, 0x5f, 0x52, 0xdb, 0x1e, 0x81, 0xbf, 0xe9, 0x5b, 0xce, + 0xf1, 0x35, 0x23, 0x19, 0x61, 0x22, 0xe6, 0x86, 0x66, 0x46, 0x55, 0x62, 0x81, 0x02, 0x5a, 0x22, + 0x6c, 0x98, 0xca, 0x7c, 0x8e, 0x96, 0x6d, 0xf8, 0xfe, 0x04, 0x87, 0xcd, 0xfd, 0x3b, 0x03, 0xca, + 0xf5, 0x57, 0x26, 0xc2, 0xf8, 0x42, 0xee, 0x18, 0xfd, 0x49, 0x44, 0x3a, 0x78, 0x7e, 0xcb, 0xb5, + 0x22, 0xcc, 0x5a, 0x4b, 0xa5, 0x26, 0x6d, 0x43, 0x1a, 0x3d, 0x89, 0x18, 0x2a, 0x08, 0x33, 0x19, + 0x08, 0x8d, 0x00, 0x0f, 0xc0, 0x63, 0x44, 0x66, 0x44, 0x28, 0x0d, 0x3c, 0x3b, 0xf1, 0x01, 0x12, + 0x6e, 0xa3, 0xc4, 0x9e, 0xd3, 0x40, 0xba, 0xe4, 0x63, 0xcf, 0x2e, 0x0f, 0x82, 0x76, 0x51, 0x82, + 0x14, 0x78, 0xd8, 0x21, 0x2c, 0x0d, 0xd6, 0x85, 0xd0, 0xa4, 0x2f, 0x19, 0x4f, 0x81, 0x0c, 0x2d, + 0x3a, 0xda, 0x71, 0x1f, 0x21, 0xb9, 0x26, 0x0a, 0xd1, 0xb2, 0xf0, 0xbf, 0x40, 0xb6, 0xfa, 0x46, + 0xd0, 0x25, 0x10, 0x47, 0xdb, 0xba, 0x00, 0x42, 0x85, 0x8e, 0xa5, 0x8a, 0x2c, 0x13, 0x88, 0xa9, + 0x0b, 0xc7, 0xaa, 0x26, 0xe5, 0xaf, 0x36, 0x8f, 0xd4, 0xbc, 0x94, 0x3b, 0x82, 0x7b, 0xf5, 0x2a, + 0x5b, 0x29, 0x4a, 0x45, 0x18, 0x0d, 0x1e, 0x8d, 0x64, 0x25, 0x55, 0xab, 0xc2, 0x47, 0x46, 0xce, + 0x15, 0x48, 0x56, 0xce, 0xe6, 0x25, 0x35, 0x27, 0x2b, 0x10, 0x86, 0xc8, 0x1a, 0xb4, 0xe6, 0x65, + 0x2d, 0x7f, 0x94, 0x97, 0x0b, 0x92, 0x9a, 0x95, 0x8b, 0x55, 0x78, 0xca, 0x21, 0xe4, 0x66, 0x81, + 0x00, 0x58, 0x06, 0x3f, 0xb4, 0x4a, 0x5e, 0xca, 0xb3, 0xa9, 0x54, 0x82, 0xeb, 0x1c, 0xab, 0x45, + 0xb9, 0x90, 0x97, 0x0a, 0x72, 0x21, 0x7b, 0xa4, 0x16, 0xe4, 0x8c, 0xb4, 0x29, 0x6b, 0x55, 0x15, + 0x1f, 0x25, 0x55, 0x91, 0x95, 0x2c, 0x51, 0x8b, 0x92, 0xaa, 0xb2, 0xcf, 0xa5, 0xa1, 0x6a, 0xf1, + 0x4a, 0xcd, 0x1d, 0x41, 0xfb, 0x26, 0x22, 0xa9, 0x65, 0xae, 0x34, 0x25, 0x86, 0xa6, 0xa6, 0x20, + 0x9e, 0xf8, 0xa9, 0xc8, 0xd9, 0x0c, 0x51, 0x37, 0xe5, 0x5c, 0x56, 0x2a, 0x22, 0x26, 0xf3, 0x05, + 0xbf, 0x08, 0x24, 0xbd, 0xbd, 0x85, 0x24, 0xdd, 0xfe, 0x20, 0x96, 0x63, 0xd1, 0x63, 0x48, 0x3f, + 0xbc, 0x07, 0x46, 0x82, 0xfe, 0x82, 0x8e, 0x91, 0xbf, 0x27, 0xeb, 0x38, 0x06, 0xc2, 0x0c, 0xfd, + 0x87, 0x68, 0x0d, 0x99, 0xa7, 0xf4, 0x43, 0x21, 0xc8, 0xfd, 0xaa, 0xca, 0xbc, 0xc6, 0x55, 0xa6, + 0x7e, 0xee, 0x23, 0x0a, 0xbf, 0x60, 0x8f, 0x16, 0xbd, 0xc4, 0xd4, 0xc0, 0x68, 0xf3, 0x61, 0xf2, + 0xb3, 0x0c, 0xfd, 0xa7, 0x51, 0x2c, 0xcb, 0x00, 0x4d, 0xda, 0x72, 0x3d, 0x83, 0x65, 0x58, 0x4c, + 0xcf, 0x8d, 0xd2, 0xd0, 0xf2, 0xc1, 0x0e, 0x99, 0x7f, 0x7c, 0xde, 0xae, 0x0b, 0x5a, 0x35, 0x89, + 0x7b, 0xb9, 0xdf, 0x98, 0xc4, 0x68, 0x61, 0xda, 0xf3, 0x87, 0x71, 0xdb, 0x00, 0x79, 0x62, 0x65, + 0x29, 0xb2, 0x85, 0x14, 0x25, 0x1e, 0x05, 0x15, 0xf3, 0xbb, 0xae, 0x17, 0xb4, 0x06, 0x01, 0x41, + 0xa3, 0x27, 0x90, 0x8d, 0xae, 0x47, 0xdb, 0xba, 0x10, 0xd3, 0xea, 0xbe, 0xd3, 0x81, 0xb5, 0x7c, + 0x9a, 0xcf, 0x4a, 0xd6, 0xd5, 0xce, 0x69, 0x7d, 0xa4, 0x7c, 0x3a, 0xe8, 0xb8, 0x15, 0xf8, 0xef, + 0xa4, 0x71, 0xd9, 0xdd, 0xbb, 0xec, 0xc0, 0xdd, 0x0e, 0x3e, 0x56, 0xce, 0xab, 0x95, 0x1b, 0xbc, + 0xb6, 0x8b, 0xe9, 0xcd, 0x2e, 0x6b, 0xb9, 0x3e, 0x69, 0xd4, 0x95, 0xc3, 0x8a, 0xe7, 0x67, 0x5b, + 0xf9, 0x73, 0x78, 0x7e, 0x38, 0xf9, 0xa7, 0xbe, 0xb7, 0x7f, 0x79, 0xba, 0x97, 0xb4, 0x2f, 0xfd, + 0xe0, 0x54, 0x53, 0x2b, 0x97, 0x4e, 0xed, 0xc4, 0xdf, 0x57, 0xae, 0x92, 0xca, 0xde, 0xf5, 0x95, + 0x35, 0xac, 0x5c, 0xb7, 0x2b, 0xb4, 0xf0, 0xdd, 0x3e, 0x2a, 0xec, 0x7d, 0xd9, 0x6b, 0x9d, 0xe7, + 0x5a, 0xe7, 0x45, 0xa7, 0x7a, 0x58, 0x6d, 0xee, 0xfe, 0xb3, 0x5f, 0xb8, 0xf0, 0x86, 0x5d, 0xc3, + 0xcf, 0xdf, 0x34, 0xc7, 0xbb, 0xe6, 0xce, 0x40, 0xeb, 0x36, 0x1e, 0x0a, 0x0f, 0x56, 0xd7, 0x6f, + 0x7d, 0x52, 0xdb, 0x97, 0x9b, 0x6a, 0xad, 0xfe, 0xe9, 0x93, 0xb1, 0xdf, 0x56, 0x1f, 0xbb, 0xde, + 0x59, 0x91, 0xde, 0x1f, 0x3b, 0xd5, 0x5a, 0x31, 0xa7, 0x9c, 0xa5, 0x93, 0xc3, 0x74, 0xab, 0xaa, + 0x7d, 0x6f, 0x7d, 0x1f, 0x65, 0x3b, 0xfe, 0xc1, 0x6e, 0xa6, 0xf6, 0x90, 0x3e, 0xd0, 0x32, 0xc9, + 0xe6, 0xb0, 0x61, 0x8e, 0x0a, 0xce, 0x83, 0xfa, 0xa9, 0x58, 0x2c, 0xec, 0xd0, 0xea, 0x79, 0xb6, + 0x72, 0x70, 0x5c, 0xb1, 0xf6, 0xee, 0x5b, 0x07, 0xc6, 0x4e, 0xa1, 0xe3, 0x98, 0x7b, 0xed, 0x6e, + 0xfd, 0xbb, 0x59, 0x3f, 0x6f, 0x54, 0x37, 0x9d, 0xd6, 0xb9, 0xf5, 0x50, 0xb9, 0xb2, 0xfc, 0xca, + 0xe7, 0x83, 0x9d, 0xfd, 0x4e, 0xa7, 0x9e, 0x3b, 0x1f, 0x9e, 0x17, 0x2e, 0x5b, 0x17, 0x27, 0xe6, + 0x66, 0xef, 0x68, 0xb8, 0x6b, 0x56, 0xb5, 0xbe, 0xe6, 0x75, 0x0f, 0x4f, 0xb4, 0x83, 0xec, 0x65, + 0x7a, 0x58, 0x6f, 0x3a, 0x74, 0x3c, 0x76, 0x9e, 0xba, 0x7d, 0xbf, 0xa0, 0xb8, 0x95, 0x33, 0xbb, + 0x7b, 0x72, 0x76, 0x74, 0xff, 0xc5, 0x31, 0xd4, 0x61, 0x36, 0xfd, 0x78, 0xd5, 0x0b, 0xce, 0x6b, + 0x97, 0xc5, 0xe0, 0xe9, 0xfc, 0xfa, 0x34, 0x53, 0xad, 0x3e, 0x64, 0x1d, 0xef, 0x6c, 0xb7, 0x78, + 0x7c, 0x74, 0x92, 0xcc, 0x7f, 0x37, 0x8b, 0xb4, 0x5d, 0xa4, 0xde, 0x68, 0xe7, 0xd3, 0xb0, 0x56, + 0xc8, 0x29, 0xd7, 0x9f, 0xd4, 0xeb, 0x71, 0xd6, 0xb6, 0x36, 0xd3, 0xed, 0xf3, 0x7d, 0x6f, 0xb4, + 0x79, 0x56, 0x39, 0x68, 0xec, 0x76, 0x8a, 0xc6, 0xd3, 0x60, 0xf4, 0xcf, 0xee, 0x49, 0xfe, 0xbe, + 0x39, 0xa0, 0xfd, 0x82, 0x91, 0x3c, 0xd8, 0xdf, 0xcf, 0xd0, 0xa7, 0x13, 0x85, 0x3a, 0xb9, 0xf6, + 0xee, 0xf7, 0xe2, 0x79, 0xdb, 0x49, 0x5e, 0x7e, 0xbf, 0xea, 0xdc, 0x77, 0x3f, 0xe7, 0x9a, 0xf4, + 0xac, 0x3f, 0xaa, 0x7e, 0x1a, 0x5d, 0xd6, 0xee, 0xf3, 0x86, 0x56, 0xa9, 0xde, 0x14, 0x9e, 0xbc, + 0xaa, 0x59, 0xad, 0x66, 0xb2, 0x97, 0xf7, 0xde, 0xd3, 0x20, 0xb8, 0x3f, 0xfa, 0x62, 0x9d, 0x57, + 0xd3, 0x0f, 0x5d, 0xa5, 0x66, 0x8f, 0xcf, 0xc6, 0x83, 0xcd, 0xe0, 0xd3, 0xd3, 0x71, 0xd6, 0x3a, + 0x38, 0x6b, 0x17, 0x06, 0x07, 0x39, 0x7f, 0x77, 0x6f, 0xf4, 0xb9, 0x7f, 0xf3, 0x79, 0xe8, 0x75, + 0x8b, 0xb9, 0xfa, 0x97, 0x1b, 0xe0, 0xee, 0x61, 0xbf, 0x90, 0xbc, 0x36, 0xc6, 0x27, 0xc1, 0xf7, + 0x71, 0x70, 0x4d, 0x8f, 0xbe, 0x7f, 0x6e, 0xde, 0x5f, 0x5e, 0x9e, 0xb4, 0x8e, 0xaa, 0xc9, 0xf6, + 0xe0, 0x40, 0xeb, 0xf5, 0x8f, 0x06, 0x85, 0xe0, 0xcc, 0xce, 0xf9, 0x5f, 0x76, 0x2b, 0x4e, 0xff, + 0xe8, 0x41, 0xe9, 0x3d, 0xed, 0xef, 0x5a, 0x5e, 0x72, 0x67, 0xff, 0x1f, 0xfb, 0xa1, 0xba, 0x57, + 0x35, 0x3e, 0xed, 0x0f, 0x1a, 0x3b, 0x37, 0x0d, 0xbb, 0x92, 0xed, 0x1f, 0x7d, 0x0e, 0xac, 0xfa, + 0xfd, 0xde, 0xb8, 0x73, 0x38, 0xde, 0xf3, 0xf6, 0x9f, 0xc6, 0x87, 0x9f, 0xee, 0x3d, 0x7a, 0x73, + 0x61, 0x37, 0xbf, 0x7c, 0xea, 0x18, 0x35, 0xaf, 0x6e, 0x3f, 0xb9, 0x35, 0x37, 0x18, 0xd1, 0x6b, + 0x5a, 0xe9, 0xee, 0x75, 0x0f, 0x1f, 0xcf, 0x76, 0x2e, 0x76, 0x77, 0xba, 0xe7, 0x37, 0x9d, 0xbd, + 0x9b, 0xee, 0x49, 0x73, 0xdc, 0x3c, 0x3c, 0xe9, 0x3e, 0xde, 0xa8, 0x7e, 0xb3, 0x31, 0x1a, 0x3d, + 0x34, 0x6b, 0xa7, 0x5f, 0xbc, 0x27, 0x3f, 0x73, 0x55, 0xef, 0xdd, 0xf7, 0x9c, 0xd3, 0x87, 0x7c, + 0xf3, 0xf4, 0xc1, 0xfb, 0xfe, 0x78, 0x5c, 0xbb, 0xd8, 0x1c, 0x57, 0xbf, 0x8f, 0x1f, 0x4f, 0xc6, + 0xcd, 0xca, 0xfe, 0x71, 0x47, 0xed, 0x7d, 0xae, 0xef, 0x1c, 0xdc, 0xd8, 0x1d, 0x8d, 0x36, 0xdd, + 0xd3, 0xc6, 0xfe, 0x81, 0x79, 0x91, 0x3c, 0x1c, 0x1d, 0x67, 0xf6, 0x2c, 0x3b, 0xff, 0xb4, 0x33, + 0xba, 0xfe, 0xb2, 0xaf, 0x3e, 0x3e, 0x34, 0x3e, 0x3f, 0x9c, 0x1a, 0xf9, 0xef, 0x41, 0xcd, 0xa6, + 0x2d, 0x3a, 0x38, 0x1f, 0x56, 0x93, 0x9d, 0x6c, 0xff, 0xcb, 0xb5, 0x65, 0x9c, 0x06, 0x9b, 0xf7, + 0xe3, 0xdd, 0xa6, 0x96, 0x3d, 0xd7, 0xbe, 0x7f, 0xaa, 0xe6, 0xae, 0x2f, 0x1a, 0x43, 0xcf, 0xfe, + 0x94, 0xf9, 0x52, 0x3b, 0xfe, 0xac, 0x64, 0x9d, 0x23, 0xf3, 0xf8, 0xec, 0x53, 0x70, 0x7e, 0x7a, + 0xfc, 0xe4, 0x1e, 0x5c, 0x3c, 0x9d, 0x3d, 0xe5, 0x37, 0x6f, 0x4e, 0xce, 0xb4, 0xa1, 0x55, 0xd8, + 0x55, 0xd5, 0x76, 0x30, 0x3c, 0xff, 0x7c, 0x53, 0x7d, 0x1a, 0x07, 0x85, 0xfb, 0xf6, 0xe8, 0x54, + 0x55, 0x2e, 0xce, 0x3b, 0x47, 0xb9, 0xee, 0x05, 0xd3, 0x89, 0xca, 0xce, 0x3f, 0xf5, 0xcb, 0xdc, + 0x9e, 0xf7, 0xf0, 0x4f, 0xa7, 0xd3, 0xd1, 0x75, 0x61, 0x7b, 0x03, 0x5c, 0x67, 0xcb, 0xb3, 0xfa, + 0x01, 0x61, 0x21, 0xac, 0x80, 0xba, 0x9c, 0xbe, 0x37, 0x86, 0x06, 0x6f, 0x05, 0x80, 0xf6, 0xc0, + 0x61, 0xc5, 0x22, 0xd2, 0x39, 0x34, 0x13, 0x54, 0x9c, 0x78, 0x34, 0x18, 0x78, 0x0e, 0x31, 0xe5, + 0x0e, 0x0d, 0xf6, 0x6c, 0x8a, 0x45, 0x87, 0x9d, 0x31, 0xeb, 0x9a, 0xce, 0x40, 0x5b, 0x7b, 0x0b, + 0x90, 0x2d, 0x88, 0xad, 0x02, 0x1a, 0x02, 0x23, 0xe0, 0xd0, 0xf0, 0xc0, 0xc1, 0x9a, 0x90, 0x87, + 0x63, 0x0b, 0x9a, 0x0a, 0xb6, 0x1a, 0xd8, 0x8a, 0x74, 0x58, 0xa3, 0xc7, 0x82, 0xf5, 0xfc, 0x62, + 0x82, 0xdb, 0x61, 0x81, 0x08, 0x20, 0x18, 0x16, 0xa4, 0x85, 0xb0, 0x79, 0x23, 0xf4, 0xfa, 0x0b, + 0x01, 0xce, 0xfa, 0xb0, 0x11, 0x87, 0x74, 0xd5, 0xf5, 0x23, 0x56, 0x63, 0x45, 0x84, 0xc6, 0xa8, + 0x62, 0x63, 0x21, 0xac, 0x58, 0x76, 0x8b, 0x91, 0x57, 0x62, 0x05, 0x89, 0x52, 0x7e, 0x25, 0xce, + 0xc8, 0x68, 0xf0, 0xbf, 0xb0, 0xcd, 0xe3, 0x8c, 0x0d, 0x1e, 0x68, 0xbc, 0x55, 0x94, 0x0c, 0x24, + 0xa2, 0x3c, 0xc6, 0xc8, 0x13, 0x4d, 0xeb, 0x16, 0x87, 0xd9, 0x5a, 0xfe, 0xe9, 0x58, 0x05, 0x2f, + 0x9f, 0xed, 0x66, 0x87, 0xc5, 0x6e, 0x2a, 0x0b, 0x4f, 0x45, 0xa2, 0x2a, 0xb3, 0x27, 0x4d, 0x23, + 0x79, 0x84, 0xeb, 0xa6, 0x8a, 0x4f, 0x42, 0xe4, 0xad, 0x37, 0xc8, 0x73, 0x87, 0x03, 0x48, 0x49, + 0x15, 0xe9, 0x09, 0x34, 0xc2, 0x6d, 0x6b, 0xdb, 0x1b, 0x61, 0x1f, 0x61, 0x96, 0x96, 0x04, 0x2e, + 0x1f, 0xfb, 0x4f, 0xe3, 0xf4, 0x84, 0x24, 0xfa, 0x6c, 0x06, 0x20, 0x2b, 0x01, 0xee, 0xb1, 0xf6, + 0x9e, 0x11, 0x78, 0xd6, 0xa3, 0x08, 0xd3, 0x68, 0x30, 0xbe, 0x8f, 0xc7, 0x11, 0x58, 0x01, 0x21, + 0x1b, 0x16, 0x60, 0x3d, 0x2f, 0xec, 0x0a, 0x8b, 0x51, 0x17, 0x8b, 0x96, 0x19, 0x60, 0x0a, 0x48, + 0xeb, 0x0e, 0x82, 0x52, 0x1b, 0x66, 0x36, 0x43, 0xf2, 0xae, 0xb2, 0x23, 0xf0, 0x50, 0x02, 0x03, + 0x33, 0x9a, 0x65, 0x6d, 0x1c, 0x8c, 0x80, 0xb6, 0xd1, 0x04, 0x04, 0x21, 0x74, 0xd4, 0x05, 0x9b, + 0x9a, 0x0d, 0x90, 0xac, 0x7e, 0x54, 0xa7, 0x13, 0xb6, 0x8f, 0x28, 0x4c, 0x80, 0x4d, 0x25, 0x10, + 0x25, 0x06, 0x89, 0x3b, 0x0f, 0x50, 0x8e, 0x60, 0xea, 0x50, 0x70, 0xe6, 0x25, 0x51, 0xc6, 0x59, + 0x36, 0x98, 0xe0, 0x66, 0x56, 0xe6, 0x23, 0x1b, 0xe1, 0x90, 0x78, 0xd5, 0x13, 0x07, 0xb9, 0x7d, + 0x26, 0xdd, 0x43, 0xc3, 0x1e, 0x50, 0xec, 0x45, 0x0a, 0x01, 0x01, 0x18, 0x04, 0x85, 0x99, 0xa2, + 0x3b, 0x61, 0x5b, 0xdb, 0x25, 0xc7, 0xac, 0x1b, 0x10, 0xe2, 0xa3, 0x56, 0x86, 0x7b, 0x9a, 0x2d, + 0x6c, 0x37, 0xa8, 0xd7, 0x07, 0x62, 0x40, 0xa0, 0x23, 0x41, 0x14, 0xea, 0xf9, 0x01, 0x81, 0x38, + 0x9e, 0x57, 0xb7, 0x90, 0x43, 0x58, 0xb5, 0x23, 0xef, 0xed, 0xa0, 0x9c, 0x9a, 0x4d, 0xb3, 0xb1, + 0x3c, 0x8f, 0xad, 0x79, 0xcf, 0xcd, 0xc3, 0x86, 0x47, 0xd5, 0x32, 0x92, 0x7a, 0xdf, 0x09, 0xca, + 0x73, 0x74, 0x50, 0xeb, 0x18, 0xbe, 0x33, 0x5a, 0xa5, 0x81, 0x1b, 0x8c, 0x25, 0xbf, 0xc0, 0x91, + 0x0d, 0xc6, 0x12, 0xf8, 0x00, 0x6a, 0xcc, 0x49, 0x75, 0x3a, 0x08, 0x20, 0x0e, 0x24, 0xbc, 0xb9, + 0xf4, 0x4a, 0x9e, 0x6c, 0xc4, 0x99, 0xb2, 0x34, 0x23, 0x79, 0x15, 0x47, 0x46, 0xc0, 0x4a, 0xe0, + 0xde, 0x3a, 0x86, 0xcc, 0x64, 0xfd, 0x59, 0x7e, 0x40, 0xf8, 0x0f, 0x0c, 0xa9, 0x5e, 0xd6, 0x8f, + 0xe2, 0x34, 0x5a, 0x84, 0xe9, 0x1a, 0xc2, 0x76, 0xcd, 0xed, 0x51, 0x52, 0xf1, 0x7d, 0x0b, 0x22, + 0x53, 0x27, 0x20, 0x37, 0x95, 0xe3, 0xd8, 0x80, 0x17, 0x68, 0xba, 0xf1, 0x0b, 0x62, 0xce, 0xe2, + 0xac, 0xfd, 0x25, 0xc2, 0x6e, 0xb0, 0xec, 0x84, 0xb4, 0x5c, 0x93, 0xfe, 0x22, 0x75, 0x23, 0xe2, + 0x32, 0xfd, 0x5d, 0x37, 0xf7, 0xeb, 0x48, 0xdc, 0xa5, 0x8f, 0xcf, 0x50, 0xb8, 0xb6, 0x77, 0x4d, + 0x12, 0x6f, 0xdb, 0x59, 0xfc, 0x27, 0x3e, 0x4b, 0x65, 0x08, 0x13, 0x85, 0xed, 0xdd, 0xbd, 0x2a, + 0x49, 0x68, 0xd9, 0xac, 0x14, 0xfe, 0x89, 0x1b, 0xaf, 0xa6, 0xe0, 0xaf, 0x48, 0x25, 0x24, 0x12, + 0x1e, 0x05, 0x46, 0x39, 0x9d, 0xf9, 0x7e, 0x2a, 0xb3, 0xb6, 0xdf, 0x12, 0xcb, 0x35, 0x53, 0xbe, + 0x92, 0x6e, 0xe3, 0x26, 0xa4, 0xeb, 0xcf, 0x91, 0x8e, 0x75, 0x22, 0xf5, 0x14, 0xfc, 0x07, 0xa9, + 0x9a, 0x44, 0xd4, 0x82, 0x44, 0x9e, 0xa7, 0xe6, 0x46, 0x64, 0x44, 0xb0, 0x94, 0x29, 0x6c, 0xd7, + 0xf1, 0x42, 0x12, 0x2f, 0x8f, 0x0b, 0x87, 0xe1, 0x06, 0x90, 0x5e, 0x1b, 0x0d, 0x76, 0xb3, 0x96, + 0x6f, 0x7f, 0x4e, 0x92, 0x9b, 0xcc, 0xfe, 0x38, 0x40, 0x37, 0x5e, 0x74, 0x15, 0xb6, 0x77, 0x66, + 0x2d, 0x33, 0x2e, 0x6c, 0xc4, 0xd8, 0xf0, 0xb3, 0xb9, 0xcb, 0xaf, 0x70, 0xdb, 0xac, 0x26, 0xb7, + 0x11, 0x46, 0x34, 0x9c, 0x44, 0x8c, 0x7b, 0x2b, 0x88, 0x90, 0x9e, 0xe5, 0xe8, 0x82, 0x0a, 0x57, + 0x03, 0xfc, 0xb5, 0x96, 0xcb, 0x09, 0x11, 0x85, 0x54, 0xad, 0xc8, 0x94, 0xa6, 0x6f, 0x38, 0x5c, + 0x65, 0xe6, 0x63, 0xaf, 0x10, 0x42, 0xd8, 0x06, 0x08, 0xa0, 0x11, 0xf4, 0xff, 0x29, 0x5d, 0x3f, + 0xb2, 0x7a, 0x56, 0x10, 0x51, 0x68, 0xe3, 0xd8, 0x78, 0x24, 0x8e, 0x4b, 0xdc, 0x36, 0x61, 0x9d, + 0x7e, 0x1a, 0x8d, 0xd7, 0x3a, 0x99, 0xdd, 0xf8, 0x23, 0xd4, 0x22, 0x1b, 0x2b, 0xd4, 0x5a, 0x41, + 0x6a, 0x91, 0x5a, 0x39, 0x55, 0x9b, 0x51, 0x4b, 0xcb, 0xe5, 0x17, 0xa9, 0x35, 0x1f, 0x1b, 0x52, + 0x0b, 0x20, 0x9e, 0xa1, 0x56, 0xa4, 0x3f, 0x5d, 0x23, 0x85, 0x15, 0x32, 0xe1, 0xd7, 0xa9, 0xd7, + 0x35, 0x0e, 0x41, 0x51, 0x6b, 0x15, 0xb2, 0x4b, 0x87, 0x56, 0x8b, 0x92, 0xc3, 0xdd, 0x35, 0x74, + 0xda, 0x58, 0x6f, 0x15, 0xf9, 0xe6, 0xc3, 0xae, 0x85, 0x52, 0xbf, 0x10, 0x8b, 0x88, 0x39, 0x41, + 0xd8, 0x3a, 0x33, 0xd5, 0x63, 0x21, 0xd3, 0x57, 0x08, 0x99, 0xbe, 0xb6, 0xf8, 0x8b, 0x23, 0x36, + 0xf5, 0xbe, 0x2a, 0x8a, 0x2a, 0xfc, 0x2b, 0x3b, 0xbc, 0x5c, 0xdc, 0xe2, 0xa5, 0x63, 0x7d, 0x1f, + 0x2c, 0xee, 0x74, 0xe3, 0x05, 0xfb, 0xff, 0xda, 0x9d, 0x6e, 0xf0, 0xad, 0xe2, 0x82, 0xe4, 0x85, + 0xad, 0x1a, 0xaf, 0xd9, 0xeb, 0xc6, 0x2f, 0x86, 0x77, 0x5d, 0xe3, 0xc4, 0xe8, 0xd1, 0xf8, 0x66, + 0xf1, 0xf9, 0x5f, 0xdb, 0x27, 0x5b, 0x2c, 0xda, 0xe8, 0x3c, 0x90, 0xfe, 0x64, 0x05, 0xad, 0x2e, + 0x75, 0x84, 0x3f, 0xa1, 0xdc, 0x10, 0x58, 0x5c, 0x62, 0x6c, 0x11, 0x89, 0xe7, 0x59, 0xba, 0xeb, + 0x42, 0x84, 0xe6, 0xc4, 0xb7, 0xb5, 0x41, 0xfe, 0xe4, 0xb6, 0xa2, 0x25, 0xf9, 0xbe, 0xfe, 0x80, + 0x2b, 0x0d, 0x20, 0xcb, 0xa1, 0x10, 0x2b, 0xb0, 0x33, 0x66, 0x61, 0xfb, 0x82, 0x3d, 0x92, 0xf0, + 0xcc, 0x19, 0x94, 0xe3, 0xf5, 0xce, 0x74, 0x71, 0x1f, 0xfc, 0xcc, 0x28, 0xda, 0x81, 0x13, 0xda, + 0x19, 0x8b, 0x79, 0xc7, 0x4e, 0x4c, 0x02, 0x95, 0xd0, 0xf8, 0x28, 0xa1, 0xf1, 0xc9, 0x67, 0x96, + 0x3d, 0xf3, 0x22, 0x86, 0xcb, 0x8b, 0xc7, 0x1d, 0xf3, 0xdc, 0xb1, 0xb1, 0xfc, 0x11, 0x07, 0xcf, + 0x47, 0xe2, 0xf9, 0xf9, 0x6c, 0x74, 0xec, 0x4c, 0x1d, 0x52, 0xb8, 0x30, 0x95, 0x8a, 0x93, 0x32, + 0xcd, 0x52, 0x9d, 0x79, 0x6e, 0x14, 0x8d, 0x9b, 0xbd, 0xa6, 0x52, 0xc5, 0x86, 0x70, 0x43, 0xb3, + 0x46, 0x61, 0x29, 0xa7, 0xfc, 0x8d, 0xa4, 0xe9, 0x75, 0x42, 0x88, 0xfb, 0x9b, 0x2d, 0xcd, 0x36, + 0xf1, 0x9a, 0x94, 0x76, 0x7d, 0xa5, 0x1c, 0x4f, 0x02, 0xac, 0xd6, 0x03, 0x4c, 0x36, 0x42, 0xd5, + 0x68, 0xe0, 0x94, 0x09, 0x11, 0x73, 0x25, 0x76, 0x16, 0x03, 0x46, 0x82, 0x1f, 0xc6, 0x44, 0xb9, + 0xee, 0xba, 0x9a, 0xfa, 0x06, 0x2b, 0xaa, 0x17, 0x48, 0xa1, 0x56, 0x30, 0x72, 0x24, 0x87, 0x15, + 0x6a, 0xa2, 0xa4, 0xf0, 0x6e, 0xf6, 0x84, 0x77, 0x5d, 0x55, 0x31, 0x62, 0x0d, 0xa9, 0x58, 0x77, + 0x0a, 0x9e, 0x8e, 0x0b, 0x44, 0xcd, 0x19, 0x19, 0x92, 0x61, 0x4d, 0x6a, 0x2a, 0x93, 0xc2, 0xfb, + 0xf0, 0x89, 0x2c, 0x3d, 0x91, 0xd8, 0x13, 0xf6, 0x60, 0xee, 0xbc, 0xc1, 0x93, 0x67, 0xf2, 0xde, + 0x69, 0xfa, 0xfd, 0x32, 0xdb, 0x49, 0x98, 0x14, 0x2f, 0xf2, 0xf8, 0x15, 0x3a, 0x32, 0x93, 0xa0, + 0xb0, 0x38, 0x3e, 0x4b, 0x87, 0xe3, 0xe7, 0x3c, 0x4b, 0xf6, 0x00, 0x41, 0xaf, 0x21, 0x23, 0x21, + 0x25, 0x32, 0xd3, 0x1a, 0x8e, 0x4a, 0xe4, 0x8a, 0x23, 0x31, 0x5a, 0x2c, 0xa8, 0xaf, 0xd5, 0x12, + 0x36, 0xd7, 0xcc, 0x31, 0x47, 0xc1, 0x4b, 0x1e, 0x0b, 0x3b, 0x7c, 0xce, 0xf8, 0xe7, 0x0a, 0x1a, + 0x37, 0x60, 0x66, 0xff, 0x14, 0x1a, 0x37, 0x6b, 0xd1, 0x88, 0x48, 0xba, 0xb1, 0x5e, 0x6f, 0xd2, + 0xfd, 0xb0, 0xb8, 0x10, 0x43, 0x2c, 0xf6, 0x56, 0x53, 0x5c, 0x88, 0x67, 0xaf, 0x6a, 0xe1, 0xde, + 0x76, 0xe1, 0x21, 0xe4, 0x59, 0x97, 0x7a, 0xc0, 0xb8, 0xa6, 0xb7, 0x0d, 0x79, 0x11, 0x5e, 0x48, + 0x15, 0xe5, 0x14, 0xd3, 0xde, 0xd0, 0x3a, 0x18, 0x28, 0x8b, 0x31, 0xde, 0xce, 0x0c, 0x55, 0xb8, + 0x76, 0x64, 0x93, 0xf8, 0xb6, 0x10, 0x96, 0x6f, 0x2a, 0x8e, 0xc7, 0x73, 0x6c, 0x85, 0x39, 0x16, + 0xaa, 0x50, 0x71, 0x85, 0x5e, 0x7e, 0x17, 0x8c, 0x59, 0xf1, 0x5e, 0x87, 0xcd, 0xdd, 0xf7, 0x28, + 0x2a, 0x99, 0xb0, 0x52, 0x8c, 0x8a, 0xbd, 0x9b, 0x11, 0xbe, 0x5f, 0x09, 0x6b, 0x7b, 0xad, 0xb0, + 0x48, 0xce, 0xaa, 0x73, 0xf8, 0x32, 0x6b, 0x54, 0x24, 0x9f, 0x13, 0x78, 0x2e, 0x8a, 0x9e, 0x31, + 0x4a, 0x2d, 0x1d, 0x1c, 0x3e, 0x8b, 0x7f, 0x84, 0x0f, 0x83, 0x47, 0x6c, 0x7e, 0xb2, 0x14, 0x31, + 0xec, 0x40, 0x17, 0xea, 0xc6, 0xe8, 0x90, 0xd1, 0x9d, 0x0f, 0x99, 0xaf, 0x0f, 0x94, 0x60, 0x14, + 0x9d, 0xe1, 0xf1, 0x5a, 0x1c, 0x22, 0x06, 0x73, 0x78, 0xcb, 0x69, 0xbb, 0xeb, 0xc9, 0x32, 0x37, + 0xc1, 0xd1, 0x79, 0x2d, 0x1b, 0x86, 0x71, 0x31, 0xcb, 0xfb, 0xa1, 0xc1, 0x74, 0x1d, 0x7b, 0x0c, + 0x14, 0x08, 0xef, 0x04, 0x54, 0xf5, 0x08, 0x78, 0x91, 0x52, 0x2c, 0xa4, 0x5f, 0x3a, 0x24, 0x7d, + 0x16, 0x43, 0x0e, 0x18, 0x45, 0xb6, 0xfd, 0x71, 0xb8, 0x24, 0x6f, 0x9e, 0x79, 0x8b, 0xd8, 0x79, + 0x29, 0xa2, 0xca, 0x1f, 0x63, 0xcb, 0x75, 0x8c, 0xbe, 0x3a, 0x03, 0x86, 0x07, 0x86, 0x1d, 0xc7, + 0x28, 0x5c, 0x80, 0xfb, 0x3d, 0xc7, 0xfc, 0xb5, 0xf9, 0xe7, 0xbb, 0xc2, 0x28, 0xa2, 0x9b, 0xd9, + 0x9e, 0xad, 0x08, 0x66, 0xcb, 0x87, 0x64, 0x4e, 0xd8, 0xbe, 0xe2, 0x37, 0x44, 0x95, 0x15, 0xb9, + 0xc0, 0x07, 0x70, 0x55, 0x4f, 0x45, 0x86, 0xc1, 0x88, 0x0e, 0x63, 0xf0, 0xbd, 0x64, 0xbf, 0x94, + 0x4e, 0x77, 0xac, 0xa0, 0x3b, 0x68, 0xca, 0x2d, 0xb7, 0x97, 0x1e, 0x51, 0xef, 0xc1, 0x87, 0xb0, + 0xaf, 0x97, 0xc6, 0x2a, 0x4a, 0x8a, 0x05, 0x49, 0x10, 0x23, 0xcd, 0x6a, 0x8d, 0xe9, 0xa6, 0xed, + 0x36, 0xd3, 0x98, 0xff, 0xa6, 0xeb, 0x7b, 0x95, 0xdd, 0xe3, 0x3d, 0xb9, 0x87, 0x99, 0x2e, 0xf7, + 0xc8, 0xba, 0xf0, 0xb5, 0x69, 0x1b, 0xce, 0x03, 0x58, 0x1a, 0x6a, 0xf7, 0xd3, 0x95, 0x26, 0xf8, + 0xb7, 0xad, 0xb4, 0x01, 0x1b, 0x00, 0x4c, 0xe7, 0x4a, 0xb9, 0xc4, 0x19, 0x76, 0x9e, 0xcc, 0xeb, + 0xbc, 0xeb, 0x65, 0x61, 0x46, 0x94, 0x18, 0xe4, 0x4c, 0x3e, 0x5a, 0x86, 0x33, 0x34, 0x7c, 0xae, + 0x68, 0x88, 0x6c, 0x95, 0x3d, 0x33, 0x7a, 0xf3, 0xae, 0xed, 0x97, 0xab, 0xde, 0xae, 0x97, 0xc0, + 0x2a, 0x75, 0x07, 0x22, 0x29, 0x1d, 0x2b, 0xdf, 0xb3, 0x98, 0x4a, 0x94, 0xfc, 0xa7, 0x6b, 0xde, + 0xc4, 0xad, 0x2f, 0x36, 0xdc, 0xcc, 0x1b, 0x6e, 0x58, 0x03, 0xf8, 0x82, 0x79, 0x13, 0x3a, 0x06, + 0x51, 0xea, 0x7b, 0x23, 0xde, 0x14, 0x29, 0x3f, 0xc0, 0x1d, 0xee, 0x86, 0x50, 0x2c, 0xda, 0x11, + 0xa5, 0x7f, 0x8e, 0xc2, 0x86, 0x48, 0xaa, 0x45, 0x29, 0x68, 0x74, 0x78, 0xd3, 0x62, 0x84, 0x23, + 0x4a, 0x4d, 0xaf, 0xd3, 0xe5, 0x3d, 0x2b, 0x79, 0x2d, 0xcc, 0x4c, 0x67, 0x18, 0x2c, 0x05, 0x37, + 0xa2, 0xd4, 0xba, 0x6f, 0x86, 0x5b, 0x5a, 0x91, 0x65, 0x51, 0x6a, 0x7b, 0x3d, 0xde, 0xb9, 0x54, + 0x81, 0x83, 0x61, 0x47, 0x27, 0xd1, 0xb0, 0xa5, 0xc4, 0x50, 0x94, 0x30, 0x35, 0xa2, 0xbc, 0x97, + 0x65, 0x49, 0xd8, 0x72, 0x39, 0x6b, 0xb8, 0x0c, 0x5b, 0x4e, 0x66, 0x2d, 0x2c, 0xea, 0x16, 0x25, + 0xa3, 0xc1, 0x1b, 0xd6, 0x94, 0x55, 0x60, 0xbd, 0xfd, 0x46, 0x6c, 0xbd, 0xfd, 0x65, 0x74, 0xec, + 0x46, 0xd8, 0xbd, 0x52, 0xbf, 0x15, 0x25, 0x0b, 0x3d, 0x11, 0xeb, 0x8c, 0x19, 0x15, 0x6c, 0x6e, + 0x2d, 0x34, 0xcf, 0x35, 0x1f, 0xa8, 0x19, 0x75, 0xad, 0x58, 0x05, 0x1c, 0x17, 0x1b, 0x85, 0xc4, + 0x6d, 0xcd, 0xd9, 0x1b, 0x85, 0x56, 0xa2, 0x34, 0xd2, 0x47, 0x96, 0x63, 0xba, 0x23, 0x89, 0xcb, + 0x58, 0xc8, 0xeb, 0x98, 0xfc, 0x31, 0x96, 0x5d, 0x2d, 0xb3, 0x8c, 0x27, 0xc8, 0x48, 0xde, 0xab, + 0x65, 0xf2, 0x46, 0x5d, 0xa8, 0x93, 0x15, 0xcf, 0x33, 0xc6, 0xfa, 0xed, 0x9d, 0x84, 0x6e, 0x09, + 0x99, 0xa6, 0x0b, 0x82, 0x84, 0x29, 0x16, 0x7a, 0xd2, 0xba, 0x3b, 0xf2, 0x75, 0x53, 0x86, 0x94, + 0xd0, 0x1b, 0x47, 0x64, 0xa8, 0xd8, 0x76, 0x42, 0x90, 0xa3, 0x3c, 0x0c, 0x36, 0xa1, 0x2b, 0x65, + 0x6b, 0x2b, 0x3e, 0x42, 0xb6, 0xa9, 0xd3, 0x09, 0xba, 0x65, 0x2b, 0x99, 0x14, 0xe3, 0xed, 0xb7, + 0xd6, 0x9d, 0xcc, 0xd4, 0xeb, 0xc8, 0xf2, 0x03, 0x19, 0x78, 0x03, 0x1c, 0x63, 0x73, 0x94, 0x51, + 0x23, 0x8c, 0x56, 0x2b, 0x8a, 0xe8, 0x74, 0xe1, 0x2d, 0xa5, 0x54, 0x90, 0x78, 0x13, 0x26, 0x24, + 0x51, 0x73, 0xa1, 0x50, 0x10, 0x40, 0xe0, 0x7d, 0x78, 0x86, 0xa7, 0x56, 0xab, 0x25, 0x48, 0x1d, + 0x8f, 0x52, 0x27, 0xea, 0x57, 0x72, 0xf9, 0xa6, 0x62, 0x08, 0x92, 0x47, 0xcd, 0xa8, 0x09, 0x1a, + 0x72, 0x0a, 0xc0, 0xf1, 0x38, 0xd9, 0xed, 0x74, 0x6c, 0x7a, 0xda, 0x6e, 0xf3, 0x88, 0x51, 0x82, + 0x88, 0xb1, 0x92, 0x93, 0x72, 0xd1, 0x3b, 0x0d, 0xf8, 0x0e, 0xc4, 0xfc, 0xb1, 0x20, 0xa9, 0x85, + 0x9a, 0xba, 0x00, 0xb0, 0x04, 0x81, 0x33, 0x1c, 0x03, 0x58, 0xae, 0x92, 0x91, 0x32, 0xe1, 0x9b, + 0x13, 0xf8, 0xfe, 0x46, 0xec, 0xb1, 0x20, 0x6d, 0xc6, 0x9e, 0x54, 0x65, 0xb9, 0x57, 0xcd, 0x7d, + 0x59, 0xc4, 0xcd, 0xf9, 0x83, 0xa8, 0xa9, 0x4b, 0xb8, 0xa9, 0x4b, 0xc8, 0xa9, 0x8b, 0xd8, 0x69, + 0xca, 0x4a, 0x37, 0x47, 0x2f, 0x32, 0x15, 0x31, 0x95, 0x6f, 0x5c, 0x1d, 0x60, 0x3c, 0x2e, 0x88, + 0xf1, 0x53, 0xb6, 0x57, 0x1f, 0xf9, 0xd1, 0x80, 0x59, 0xfb, 0xfa, 0xc1, 0x0e, 0x93, 0x45, 0x1f, + 0x8f, 0xf5, 0xd6, 0x4b, 0xe3, 0xb7, 0x89, 0x00, 0xf6, 0xa3, 0x14, 0x78, 0x03, 0x2a, 0xa1, 0x74, + 0x0b, 0xa5, 0x77, 0x13, 0xb4, 0x50, 0x32, 0x0b, 0x06, 0xa7, 0x12, 0x9a, 0x38, 0xa1, 0x34, 0x11, + 0x2c, 0x13, 0x7b, 0xc0, 0xa8, 0xcd, 0x3a, 0x00, 0xf4, 0xf6, 0x5b, 0xd9, 0x86, 0x7c, 0x32, 0x00, + 0x11, 0x0d, 0x30, 0x2b, 0xa4, 0x8f, 0x82, 0xae, 0x23, 0x0c, 0x33, 0xfd, 0x72, 0x68, 0xf9, 0x3f, + 0xce, 0x46, 0x95, 0xc0, 0x70, 0xf2, 0xbb, 0x32, 0xe8, 0x29, 0xe4, 0xd2, 0xb6, 0x0e, 0x1e, 0xc0, + 0x87, 0x30, 0x35, 0x48, 0x80, 0x99, 0xe2, 0x5d, 0x22, 0x9b, 0xd3, 0xd1, 0xdf, 0xa8, 0x92, 0xa1, + 0xa7, 0xd4, 0xb2, 0xa1, 0x83, 0x6d, 0x93, 0xa3, 0xaa, 0xeb, 0xa1, 0x63, 0xd2, 0xc7, 0x70, 0xb4, + 0xc5, 0x7a, 0x78, 0xe5, 0xd3, 0xbf, 0x35, 0xee, 0xc2, 0xa9, 0x0d, 0x1d, 0x6c, 0xcc, 0xda, 0x01, + 0x2e, 0xeb, 0x59, 0x33, 0x00, 0x6c, 0xd6, 0xd2, 0x00, 0xc4, 0xc1, 0xd7, 0xdf, 0x28, 0x65, 0x56, + 0xfa, 0xd6, 0x19, 0xc4, 0xf2, 0xc0, 0xf7, 0xef, 0x13, 0x00, 0xa2, 0x82, 0x3d, 0xd4, 0x8d, 0x75, + 0xe3, 0x3d, 0x36, 0x3e, 0x2c, 0xda, 0xea, 0x08, 0xb3, 0x3c, 0xc3, 0x47, 0x00, 0x51, 0x4b, 0x51, + 0x95, 0x79, 0x2d, 0x08, 0x2c, 0x02, 0xb4, 0x50, 0x38, 0x55, 0x06, 0x68, 0x3d, 0x4c, 0xfc, 0x68, + 0xe9, 0x1f, 0x84, 0x0f, 0x52, 0x17, 0x3f, 0xcb, 0xfe, 0x8f, 0x1f, 0x09, 0x88, 0xff, 0x6e, 0xc1, + 0xb0, 0xe8, 0xc2, 0x9d, 0xc0, 0x41, 0xfb, 0x48, 0x40, 0x08, 0x0c, 0x04, 0xa6, 0xfd, 0x1d, 0xbd, + 0xb5, 0x07, 0x26, 0x2a, 0x32, 0x68, 0x60, 0x18, 0xf1, 0x1c, 0x18, 0xbf, 0x3a, 0x05, 0x52, 0x94, + 0x10, 0x34, 0x53, 0x90, 0x26, 0x23, 0x48, 0xfd, 0xea, 0x10, 0x82, 0xed, 0x7b, 0x14, 0x2c, 0x92, + 0x13, 0xd8, 0xe3, 0xd2, 0x1b, 0x65, 0x2a, 0x4a, 0x43, 0xdd, 0xa1, 0x23, 0xc2, 0xa2, 0xc7, 0xf2, + 0x50, 0xc6, 0x50, 0x93, 0x4a, 0x43, 0x19, 0x02, 0x35, 0xd7, 0x30, 0xf5, 0x48, 0xe6, 0x12, 0xe2, + 0x04, 0x57, 0xa5, 0x3a, 0x33, 0xb2, 0x72, 0xab, 0x6b, 0xd9, 0xe0, 0x1b, 0x9c, 0x5b, 0xe5, 0x6e, + 0xe1, 0x1e, 0x16, 0xad, 0x04, 0x81, 0x67, 0x81, 0xb5, 0xa6, 0x09, 0x0c, 0xd5, 0xd1, 0x31, 0x1b, + 0x3a, 0xb8, 0x66, 0xbe, 0x5b, 0x69, 0x0c, 0xf7, 0x37, 0x21, 0x5f, 0x12, 0xf4, 0x8d, 0x1e, 0x33, + 0x5b, 0x3f, 0x7e, 0x18, 0x5b, 0xea, 0x8f, 0x1f, 0xe3, 0x2d, 0x55, 0x04, 0xa2, 0x18, 0xfa, 0x50, + 0x66, 0x61, 0x3b, 0x0c, 0x19, 0xca, 0x3c, 0x0f, 0x96, 0x12, 0x61, 0xdb, 0x76, 0x4e, 0xd5, 0x7e, + 0xfc, 0x88, 0x9a, 0xf1, 0x89, 0x0f, 0x51, 0xf3, 0x00, 0xad, 0xe6, 0x45, 0x51, 0xea, 0x70, 0x40, + 0xdd, 0x80, 0x3b, 0x0e, 0xa5, 0x8f, 0x91, 0x5c, 0x10, 0x0f, 0x7f, 0x66, 0xc9, 0x00, 0x11, 0x92, + 0x46, 0x52, 0x90, 0x48, 0x8d, 0x67, 0xd8, 0xf0, 0x38, 0x4e, 0x0a, 0x24, 0xd1, 0x33, 0x1e, 0x28, + 0xf1, 0x07, 0x90, 0xbb, 0x04, 0x5d, 0xcb, 0xc7, 0xe3, 0xd6, 0x56, 0x97, 0xfa, 0x04, 0xd2, 0x7f, + 0x8f, 0x80, 0x47, 0x0b, 0xcf, 0x5f, 0xf9, 0xb1, 0xa6, 0x88, 0x91, 0xb5, 0x20, 0xf5, 0x64, 0xd3, + 0x0b, 0xa3, 0xef, 0xc4, 0x90, 0xbd, 0x57, 0x6d, 0x48, 0x63, 0x6e, 0x94, 0x1b, 0x7a, 0x0f, 0x49, + 0xc2, 0xfa, 0x76, 0x21, 0x7c, 0x4f, 0x44, 0xbd, 0x32, 0x06, 0xf3, 0xd2, 0x3b, 0x50, 0x55, 0xc6, + 0xcc, 0x91, 0xae, 0x96, 0xd9, 0x89, 0xa1, 0xae, 0xbb, 0xb0, 0x91, 0x91, 0x0e, 0xf2, 0x10, 0x85, + 0x3a, 0x87, 0xa0, 0x7d, 0x87, 0x5b, 0x8d, 0xc8, 0x2b, 0x1c, 0x26, 0xf5, 0xac, 0x38, 0xc1, 0x8e, + 0xa6, 0xde, 0xb8, 0x3d, 0xbc, 0x93, 0x1e, 0xf1, 0x92, 0x54, 0xef, 0xa4, 0x0b, 0x76, 0xa3, 0xdd, + 0x49, 0x27, 0xec, 0x26, 0xc3, 0xa7, 0xa6, 0xfa, 0x61, 0x3a, 0x2b, 0x05, 0xfa, 0x31, 0x58, 0x1b, + 0xb9, 0x6d, 0xbb, 0x30, 0x2b, 0x4d, 0x1b, 0xe0, 0xa7, 0x75, 0x5a, 0xb6, 0xda, 0x89, 0xe8, 0xb8, + 0x14, 0x16, 0x16, 0xcb, 0xd4, 0xf6, 0x21, 0x81, 0x68, 0x27, 0x12, 0x41, 0x72, 0x24, 0xfe, 0xa5, + 0xe9, 0x88, 0x06, 0xb6, 0x4d, 0x6c, 0x3d, 0xf8, 0xdb, 0x48, 0x26, 0x8c, 0x94, 0x9a, 0x4a, 0xd8, + 0x29, 0xb8, 0x17, 0xc5, 0xe9, 0x3b, 0xb9, 0x3f, 0xf0, 0xbb, 0x89, 0xdb, 0xa6, 0xf4, 0x28, 0x5d, + 0x48, 0x27, 0x92, 0x2d, 0x51, 0x29, 0xb8, 0xc3, 0x76, 0xdf, 0xf5, 0x82, 0x44, 0x02, 0x9e, 0x44, + 0x7d, 0x9b, 0xde, 0xe6, 0xee, 0x52, 0x01, 0x7c, 0x70, 0xa9, 0x3d, 0xd5, 0x6f, 0x65, 0x59, 0x7e, + 0x77, 0x57, 0x3e, 0x5d, 0x82, 0xca, 0x22, 0x54, 0x36, 0x84, 0xaa, 0xa3, 0x06, 0xdc, 0x83, 0x71, + 0x90, 0x76, 0xf5, 0xd3, 0x70, 0xe3, 0xd2, 0x57, 0x5d, 0x91, 0x2a, 0x48, 0x30, 0x24, 0x0c, 0xdf, + 0x99, 0x52, 0xa6, 0x5b, 0xbb, 0x65, 0x0a, 0x7e, 0x72, 0xc2, 0xed, 0xd4, 0xe9, 0x2d, 0xbd, 0x03, + 0x71, 0x0b, 0x40, 0x14, 0xc1, 0xb1, 0x06, 0xb7, 0x40, 0x15, 0x17, 0x2e, 0x40, 0x93, 0x01, 0x5c, + 0x32, 0x77, 0x5c, 0xb7, 0xda, 0x68, 0x76, 0x60, 0x9b, 0x9e, 0x08, 0x1f, 0xf7, 0x5b, 0x0a, 0x50, + 0xfc, 0x5e, 0xa7, 0xa2, 0x04, 0x93, 0xa5, 0xd4, 0xd8, 0x54, 0x40, 0xd4, 0x32, 0x4e, 0x05, 0x7a, + 0xfb, 0xfe, 0x3d, 0x4e, 0xa6, 0xeb, 0x16, 0xde, 0x68, 0x70, 0xe3, 0x82, 0x4e, 0xb6, 0x75, 0x00, + 0x81, 0x29, 0xef, 0x75, 0x1d, 0xd4, 0xd8, 0xf9, 0x28, 0x00, 0x15, 0xeb, 0x1f, 0x29, 0x48, 0x95, + 0x50, 0x12, 0x84, 0xd2, 0x3d, 0xde, 0x24, 0xdb, 0xf8, 0x29, 0x4e, 0x19, 0x69, 0x67, 0x03, 0x92, + 0xaa, 0xae, 0xb7, 0x7f, 0x3e, 0x84, 0x11, 0x9e, 0x75, 0x03, 0x7a, 0x75, 0x44, 0x0f, 0x70, 0x04, + 0xd4, 0x19, 0xd7, 0x06, 0x5b, 0x5a, 0x2e, 0x07, 0xed, 0x7d, 0xb4, 0x1c, 0x52, 0x7b, 0x7b, 0x8e, + 0xb6, 0xc1, 0x66, 0xb0, 0xd8, 0xa7, 0x8b, 0xa0, 0xbe, 0x38, 0x61, 0xc6, 0xf1, 0x96, 0x02, 0x87, + 0x9c, 0x3b, 0xfd, 0xd6, 0x90, 0x2c, 0xc9, 0xbd, 0x43, 0x83, 0x2e, 0x24, 0xc3, 0x46, 0xb9, 0x67, + 0xf4, 0x13, 0x14, 0xd8, 0x20, 0x07, 0x6e, 0x03, 0xc4, 0xc1, 0xe9, 0x24, 0x40, 0x89, 0xe4, 0xbe, + 0x61, 0x36, 0xf0, 0x35, 0xbf, 0x84, 0x26, 0x09, 0x8a, 0x20, 0x8a, 0xf2, 0xbd, 0x6b, 0x39, 0x09, + 0x01, 0x76, 0x53, 0x4f, 0xea, 0x66, 0xb2, 0x95, 0x0c, 0x92, 0xdd, 0xb9, 0xa7, 0xa9, 0x27, 0xa3, + 0xa6, 0xaf, 0x49, 0x5d, 0x95, 0xbe, 0xfe, 0x65, 0x83, 0xfc, 0xfc, 0xf8, 0x41, 0x75, 0x1d, 0xa8, + 0xfa, 0x31, 0x51, 0xe1, 0xe2, 0x52, 0x17, 0x25, 0xe4, 0xae, 0x58, 0x82, 0x29, 0x00, 0x47, 0xc6, + 0xe5, 0xe9, 0x14, 0x9b, 0x96, 0xf8, 0x5a, 0x89, 0x04, 0x7e, 0xc6, 0x5e, 0xfb, 0x57, 0x9d, 0x59, + 0xe8, 0xc4, 0xde, 0x4d, 0x2a, 0x20, 0x16, 0xd3, 0xbb, 0xe9, 0xf4, 0x5b, 0x79, 0xe6, 0x24, 0x39, + 0x36, 0x76, 0xe4, 0x8c, 0xbe, 0x61, 0x1a, 0x41, 0x52, 0xd7, 0xe4, 0xec, 0xb4, 0x71, 0x41, 0x58, + 0xb6, 0x05, 0xc9, 0xd6, 0xbb, 0x09, 0xe6, 0x19, 0xe1, 0xec, 0xe9, 0x7b, 0xdf, 0x75, 0xd2, 0x7e, + 0x80, 0x5f, 0x2e, 0x25, 0x29, 0x93, 0x7c, 0x78, 0x37, 0xb1, 0xa7, 0x1f, 0x48, 0xaa, 0x46, 0x84, + 0x2a, 0xaf, 0x05, 0xa6, 0x2e, 0xc0, 0x71, 0x97, 0x88, 0xd1, 0xef, 0xdb, 0x56, 0x8b, 0xbd, 0x73, + 0xc7, 0xc6, 0x08, 0xdf, 0xca, 0x74, 0x1b, 0x85, 0x0c, 0xb7, 0xfc, 0x1f, 0x47, 0x90, 0x06, 0x70, + 0x25, 0xef, 0xdf, 0x13, 0x30, 0x8d, 0xd0, 0x64, 0xe3, 0xb3, 0x33, 0x35, 0xf5, 0x6f, 0x6f, 0x2f, + 0x1d, 0xc8, 0xeb, 0x78, 0xe9, 0xb6, 0x8d, 0x26, 0x87, 0x40, 0xba, 0xfc, 0x21, 0x80, 0x04, 0xdf, + 0xc6, 0xd4, 0x79, 0x4c, 0xba, 0xc6, 0x10, 0xed, 0x12, 0x05, 0x51, 0x32, 0x69, 0x1b, 0xa2, 0x60, + 0x93, 0x58, 0x0e, 0xb7, 0x4d, 0xbc, 0xfc, 0x07, 0x76, 0x89, 0x47, 0x08, 0x6e, 0x9b, 0x37, 0x03, + 0xeb, 0xdb, 0x16, 0x6c, 0x82, 0x61, 0x23, 0x8f, 0x8d, 0x9e, 0xfd, 0x1f, 0xe7, 0x6d, 0x8a, 0xe0, + 0xbb, 0xc9, 0x98, 0x48, 0x94, 0x08, 0x2e, 0x68, 0x38, 0xe6, 0x57, 0x7c, 0xa9, 0xf3, 0x3f, 0x0e, + 0x21, 0x6f, 0xf9, 0x44, 0xd4, 0x2f, 0xe1, 0x13, 0x21, 0xef, 0x26, 0x2c, 0x87, 0x08, 0x69, 0xc0, + 0xdb, 0x08, 0x69, 0x7b, 0x16, 0xe4, 0xc3, 0xf6, 0xf8, 0x2b, 0x2b, 0x96, 0x33, 0xa0, 0x93, 0x65, + 0x98, 0x01, 0x3b, 0x0b, 0xf9, 0x6a, 0x99, 0xbc, 0xff, 0x72, 0xb9, 0x3f, 0x5a, 0xd9, 0x75, 0x4a, + 0x64, 0x3b, 0x6a, 0xc4, 0x05, 0x07, 0xab, 0x20, 0xed, 0xf6, 0x02, 0xcc, 0x6f, 0x30, 0x8b, 0x4b, + 0x4e, 0xdb, 0x00, 0xa5, 0x7a, 0x25, 0xd3, 0x30, 0xe9, 0x93, 0xe3, 0x6f, 0x30, 0x80, 0xf6, 0x7f, + 0xac, 0x97, 0xf8, 0x0b, 0x09, 0x78, 0x3f, 0x28, 0xe1, 0x8b, 0x07, 0x78, 0x67, 0x96, 0x84, 0xbd, + 0x7a, 0xfd, 0xb4, 0xfe, 0x26, 0xed, 0x30, 0xdd, 0x23, 0xe0, 0x39, 0x0c, 0x07, 0x28, 0xf0, 0xe0, + 0xb8, 0x23, 0x27, 0x7c, 0x23, 0x40, 0x16, 0x66, 0xba, 0x02, 0xfc, 0x07, 0x69, 0x14, 0x98, 0xec, + 0x55, 0x75, 0xcc, 0x8a, 0xa4, 0x1a, 0xbb, 0x94, 0xfb, 0x20, 0x26, 0xed, 0x24, 0x73, 0x53, 0x5b, + 0xcd, 0xed, 0xcf, 0x95, 0xfa, 0xc9, 0xe1, 0xc9, 0xc1, 0x9b, 0xad, 0x74, 0x73, 0x9b, 0x5c, 0xcc, + 0x5e, 0xed, 0x6c, 0x8d, 0x09, 0x66, 0x4e, 0x20, 0x03, 0x01, 0x8b, 0x48, 0x50, 0x08, 0x58, 0x0e, + 0x24, 0x2f, 0x02, 0x25, 0x0c, 0xbb, 0xdf, 0x35, 0x44, 0x10, 0x1b, 0x9f, 0x34, 0x21, 0xca, 0x27, + 0x56, 0xc7, 0x71, 0x21, 0xb4, 0x07, 0x30, 0x97, 0x50, 0x87, 0x79, 0x39, 0x94, 0x32, 0x3c, 0x33, + 0x00, 0xa9, 0x22, 0x90, 0xeb, 0x0d, 0xec, 0x80, 0x0b, 0x1e, 0xf5, 0x2d, 0xfc, 0x56, 0xf5, 0x00, + 0x44, 0x0d, 0x4b, 0x36, 0xe1, 0x9b, 0xc0, 0xfc, 0xcc, 0x73, 0x26, 0x74, 0x7c, 0x51, 0xe6, 0x05, + 0x45, 0xa9, 0x2a, 0x5b, 0x0e, 0xe4, 0x65, 0xb5, 0x8b, 0xe3, 0x23, 0xbd, 0x2d, 0xd5, 0x16, 0x63, + 0x44, 0x5d, 0x60, 0x6f, 0x23, 0x43, 0x70, 0x03, 0xae, 0x72, 0xc7, 0x7d, 0x84, 0x90, 0xf5, 0x1d, + 0x73, 0x84, 0xd3, 0xe9, 0xef, 0x04, 0xc0, 0xf3, 0x59, 0x02, 0xf0, 0x3a, 0x06, 0xf7, 0x87, 0x56, + 0x94, 0xe8, 0x39, 0x3a, 0x0f, 0x84, 0x5e, 0x1d, 0x02, 0x95, 0xad, 0x10, 0x77, 0x16, 0x0b, 0x6c, + 0x85, 0x4f, 0x2c, 0x4e, 0xf8, 0x18, 0x4e, 0xc5, 0xa3, 0x89, 0x98, 0x13, 0x95, 0x37, 0x8b, 0x7f, + 0x2f, 0x0c, 0x13, 0x4b, 0xaf, 0x00, 0x65, 0x73, 0x72, 0xa3, 0x63, 0xc7, 0x41, 0xe2, 0x43, 0xd3, + 0x60, 0xeb, 0xbb, 0x7a, 0x22, 0x3e, 0x22, 0x45, 0xff, 0xb6, 0xc5, 0xb4, 0x56, 0x0e, 0xc1, 0xc2, + 0x80, 0xc6, 0x06, 0x9f, 0xac, 0x2a, 0x33, 0xbb, 0xc9, 0x33, 0x49, 0x83, 0xe5, 0x8d, 0x51, 0x9b, + 0x01, 0x6d, 0xc6, 0x16, 0x84, 0xc0, 0x91, 0x11, 0xed, 0x82, 0x1f, 0xb4, 0xfe, 0xa6, 0x49, 0xe3, + 0x4e, 0x82, 0xec, 0xce, 0xeb, 0x34, 0x13, 0x42, 0xb2, 0x0b, 0x3e, 0x0e, 0x43, 0x21, 0xbc, 0x53, + 0x67, 0x77, 0x1a, 0xdc, 0x89, 0x2c, 0x1a, 0x45, 0x28, 0x55, 0xc3, 0x37, 0xdc, 0xd9, 0x9f, 0x28, + 0x94, 0x1d, 0x19, 0x43, 0xbb, 0x06, 0x2b, 0x00, 0x79, 0x12, 0x7f, 0xaa, 0x83, 0x2c, 0x26, 0x8c, + 0xbf, 0x6d, 0xc9, 0x82, 0x3f, 0xf8, 0x27, 0x42, 0x3b, 0x96, 0xa7, 0x1e, 0x28, 0x87, 0x13, 0xde, + 0x16, 0xd9, 0x7f, 0x02, 0xb4, 0xa3, 0xb5, 0x61, 0x1b, 0x03, 0x47, 0x11, 0x41, 0xad, 0x1b, 0x8f, + 0x2f, 0x84, 0xeb, 0x02, 0x7e, 0x61, 0x81, 0xb0, 0x97, 0xc5, 0x05, 0x29, 0xbe, 0xb2, 0x09, 0x4f, + 0xc8, 0xdc, 0x0a, 0x56, 0x73, 0x75, 0x21, 0x2c, 0xe7, 0x86, 0x8d, 0x3b, 0x06, 0x04, 0xec, 0xb0, + 0x8c, 0x2e, 0x84, 0xc7, 0x02, 0xe1, 0x50, 0x4c, 0x87, 0x13, 0x5d, 0x08, 0x35, 0xc0, 0x13, 0xc3, + 0x6a, 0x49, 0x3b, 0xad, 0xe1, 0x8a, 0x78, 0xe5, 0x2f, 0x40, 0x7a, 0xba, 0xb3, 0x1a, 0xb3, 0xc5, + 0xf9, 0x23, 0x2d, 0x70, 0x41, 0x04, 0x62, 0xb4, 0x6c, 0x6a, 0x78, 0x0c, 0xff, 0x17, 0x60, 0x17, + 0xfa, 0xf4, 0x38, 0x87, 0x01, 0xbb, 0xfe, 0x20, 0xb6, 0xa8, 0x27, 0x75, 0x25, 0x45, 0xfc, 0x15, + 0xe5, 0x40, 0xee, 0x9a, 0x74, 0x78, 0xec, 0x9a, 0x14, 0x52, 0x83, 0xf2, 0xdc, 0x18, 0xea, 0xa0, + 0x79, 0xdc, 0xfe, 0xe3, 0xf9, 0x66, 0x98, 0x2a, 0x41, 0xef, 0x99, 0xe1, 0x19, 0x3d, 0x9f, 0x05, + 0xff, 0x97, 0xf5, 0xa3, 0x06, 0x6c, 0xa1, 0xd5, 0xe5, 0x6d, 0x09, 0xae, 0x48, 0xf2, 0x6c, 0xa0, + 0xcf, 0x3a, 0x21, 0x26, 0x9d, 0x67, 0xa0, 0x98, 0x11, 0x60, 0xa8, 0x38, 0x0b, 0xed, 0xd1, 0xc5, + 0xcd, 0x62, 0xfb, 0x6d, 0xf0, 0xfc, 0x02, 0xab, 0x08, 0xea, 0x3a, 0xab, 0xba, 0x2d, 0x9a, 0x03, + 0x88, 0xd6, 0xe7, 0xf8, 0x85, 0x8e, 0x1e, 0xc7, 0xf3, 0x21, 0x6f, 0xf4, 0xbe, 0x37, 0x5a, 0x1a, + 0x10, 0x66, 0x1f, 0xac, 0xc3, 0x6b, 0x61, 0x60, 0x63, 0x61, 0x89, 0xc6, 0x32, 0x77, 0x58, 0x19, + 0xfc, 0x00, 0x1a, 0xa8, 0x28, 0x5a, 0xbd, 0x30, 0x7f, 0x59, 0x97, 0x21, 0xb3, 0x3a, 0xd3, 0x33, + 0x66, 0xa9, 0xb9, 0xda, 0x23, 0x84, 0xa1, 0x2f, 0x0b, 0xab, 0xd6, 0x19, 0xe4, 0x7d, 0x3c, 0xbe, + 0x30, 0x5d, 0xc8, 0x0e, 0x1c, 0x37, 0x20, 0xfc, 0x8b, 0x9c, 0x78, 0xbe, 0xd1, 0xa4, 0xc4, 0x20, + 0xec, 0x77, 0x28, 0xb8, 0x81, 0x64, 0xf6, 0xb1, 0x8c, 0xe6, 0x3d, 0x66, 0x21, 0x03, 0x56, 0x0c, + 0x7b, 0x06, 0x9b, 0x75, 0x88, 0x32, 0xca, 0xc4, 0x7d, 0x12, 0xa8, 0x26, 0xe7, 0xf6, 0xfb, 0xf7, + 0xc8, 0x52, 0x17, 0x80, 0x6d, 0xb7, 0x93, 0x10, 0x2e, 0xc0, 0x92, 0xfb, 0x2c, 0x88, 0x23, 0x1f, + 0x84, 0x24, 0x84, 0x96, 0x1f, 0xd0, 0x1d, 0x31, 0x14, 0x43, 0xac, 0xf8, 0xc9, 0x41, 0x68, 0xbd, + 0x21, 0x9a, 0x9b, 0x02, 0xf1, 0xd6, 0xb0, 0x43, 0xe4, 0x95, 0xb4, 0x46, 0x47, 0x10, 0x41, 0x00, + 0x56, 0xf2, 0x3a, 0x29, 0x96, 0xba, 0x85, 0x69, 0xc2, 0xab, 0x06, 0xcc, 0xea, 0x51, 0x62, 0x98, + 0x9f, 0x04, 0x8d, 0x4e, 0x99, 0xae, 0xdf, 0x2e, 0x8d, 0x51, 0x0c, 0x36, 0x8c, 0xe5, 0x85, 0x25, + 0x38, 0x56, 0x94, 0x98, 0x4e, 0x0d, 0x7f, 0xec, 0xb4, 0xc8, 0x4c, 0x3c, 0xfb, 0x20, 0xe8, 0x8c, + 0xff, 0xfe, 0x2c, 0x6f, 0x0d, 0xeb, 0xb9, 0x8e, 0xd9, 0x18, 0x76, 0xce, 0x20, 0x87, 0xa6, 0x6b, + 0x51, 0xe4, 0xb5, 0x31, 0x31, 0x2c, 0x7b, 0xbc, 0x51, 0xe7, 0x41, 0x29, 0x86, 0x54, 0xb3, 0xe8, + 0x51, 0x0c, 0xbc, 0xf1, 0x64, 0x2d, 0xf9, 0x41, 0xcc, 0xd6, 0xb7, 0x87, 0x64, 0x15, 0x43, 0xfd, + 0x83, 0x48, 0x7d, 0x64, 0x58, 0x01, 0x69, 0x53, 0x88, 0xb6, 0x12, 0x51, 0x0c, 0x23, 0x24, 0x17, + 0x6b, 0xda, 0x9c, 0x23, 0x49, 0x21, 0x1e, 0xce, 0x48, 0x93, 0x1e, 0x0d, 0xba, 0x2e, 0xc4, 0x1c, + 0x18, 0xfe, 0x08, 0x12, 0xbe, 0x99, 0x4d, 0x3d, 0x1f, 0xc2, 0xde, 0x78, 0x44, 0x03, 0xe9, 0xc4, + 0x4a, 0x48, 0x33, 0x95, 0xf0, 0xbd, 0xed, 0x12, 0x85, 0x9c, 0xdf, 0x09, 0x97, 0x0f, 0x64, 0xec, + 0x49, 0x88, 0xe5, 0xb5, 0x48, 0x3b, 0xe2, 0xb4, 0x85, 0x09, 0x30, 0x96, 0x97, 0xa2, 0x76, 0xea, + 0x79, 0x98, 0x42, 0x8a, 0x90, 0x52, 0x82, 0xeb, 0x0c, 0x3e, 0x26, 0xd6, 0x13, 0x32, 0xaa, 0x20, + 0x62, 0xc9, 0x3b, 0xb8, 0xb0, 0x7a, 0xd4, 0x1d, 0x40, 0xb6, 0x17, 0xab, 0x26, 0xd0, 0x57, 0x89, + 0x08, 0xa0, 0xaa, 0xd2, 0x8c, 0x28, 0x96, 0x9e, 0x59, 0x66, 0x5e, 0xbd, 0xfc, 0xad, 0x85, 0x16, + 0x17, 0x99, 0xae, 0x28, 0xc1, 0x96, 0x0a, 0xf1, 0x58, 0xcc, 0x92, 0x0a, 0xc7, 0x16, 0x2b, 0x87, + 0x7f, 0xad, 0x81, 0x80, 0xf1, 0x92, 0x3d, 0x16, 0x62, 0xf7, 0x86, 0x30, 0x17, 0x56, 0x65, 0x29, + 0x08, 0x2b, 0xb0, 0x0f, 0x4f, 0x3a, 0x61, 0x09, 0x94, 0xc9, 0x04, 0x64, 0xb7, 0xa1, 0x04, 0x82, + 0xee, 0x32, 0xa9, 0xc3, 0x32, 0x12, 0x50, 0x1c, 0x45, 0x88, 0x33, 0xc1, 0x31, 0x86, 0x56, 0xc7, + 0x08, 0x5c, 0x0f, 0x1c, 0x89, 0xd5, 0x6f, 0xba, 0x86, 0x67, 0xca, 0x23, 0xcf, 0x0a, 0x28, 0xf3, + 0x55, 0x61, 0xdc, 0x1c, 0x63, 0xc5, 0x7c, 0xa4, 0x29, 0xd3, 0x47, 0xda, 0xaa, 0xf2, 0x30, 0x99, + 0x1f, 0x1c, 0x08, 0xcf, 0xf2, 0x4c, 0xd8, 0x37, 0x2c, 0x2c, 0x61, 0x80, 0x89, 0x42, 0x40, 0x82, + 0x2e, 0xa4, 0x44, 0x40, 0xc9, 0xc0, 0x02, 0x4c, 0x59, 0xe1, 0x7e, 0xdd, 0x5e, 0xba, 0xec, 0xcd, + 0x33, 0x30, 0xa8, 0x0e, 0x3b, 0x50, 0x79, 0x19, 0xe4, 0xfa, 0x25, 0x10, 0x2c, 0xb5, 0xbd, 0x00, + 0x62, 0xbc, 0x08, 0xc1, 0xd2, 0xbe, 0x97, 0x16, 0x3a, 0x3a, 0x79, 0x09, 0x84, 0x27, 0x37, 0x2f, + 0x02, 0x5d, 0xbe, 0x02, 0xe6, 0xe4, 0x45, 0x18, 0x26, 0x48, 0x2f, 0xd1, 0x0f, 0x4c, 0xdc, 0x0b, + 0x20, 0xe8, 0x03, 0x57, 0x41, 0xb0, 0x5a, 0x17, 0x02, 0x60, 0x3d, 0xf6, 0xf9, 0x39, 0x98, 0x44, + 0xfa, 0x6e, 0x9f, 0x15, 0x72, 0xa3, 0x6a, 0x24, 0x2b, 0xea, 0xc6, 0x0b, 0x9c, 0x77, 0xd2, 0xcc, + 0xb1, 0xeb, 0x00, 0xcc, 0xea, 0x55, 0xa0, 0x47, 0xf2, 0xa3, 0x34, 0xf3, 0xf1, 0x0b, 0xed, 0x63, + 0x89, 0x85, 0x04, 0x20, 0x47, 0x33, 0x43, 0xbb, 0x74, 0x84, 0xf5, 0x1a, 0x45, 0x09, 0x8f, 0x39, + 0x21, 0x68, 0xd0, 0x97, 0x43, 0x90, 0xbe, 0xe7, 0x06, 0x2e, 0xe4, 0x1f, 0x1f, 0x0d, 0x9b, 0x7a, + 0x10, 0xcf, 0x7f, 0x06, 0x35, 0xe6, 0xa9, 0x09, 0xfa, 0xdb, 0x21, 0x88, 0x36, 0x7b, 0xd7, 0x67, + 0xd4, 0x85, 0x3c, 0xc7, 0xa7, 0xde, 0x10, 0x04, 0x1d, 0xbf, 0x84, 0xc7, 0x6c, 0x36, 0x49, 0xb8, + 0x1e, 0xff, 0xfa, 0x04, 0x78, 0x42, 0x6f, 0xe0, 0xcc, 0x7b, 0x7c, 0x51, 0x10, 0x4b, 0x71, 0x6f, + 0x31, 0x0d, 0x45, 0xcb, 0x75, 0xd8, 0xdb, 0x07, 0x3a, 0x43, 0x0b, 0xcf, 0x87, 0x58, 0x50, 0x19, + 0x5a, 0x58, 0x7d, 0x5e, 0x74, 0x08, 0x7d, 0x98, 0xaa, 0x28, 0x7f, 0xcf, 0x4a, 0xdd, 0xf3, 0x5e, + 0x88, 0xd9, 0x73, 0x39, 0x56, 0x09, 0x0c, 0xf4, 0x6f, 0xcb, 0xbf, 0x97, 0xb1, 0xa9, 0x98, 0xb4, + 0x23, 0x11, 0xf6, 0x6b, 0x19, 0xef, 0x26, 0x74, 0xfa, 0x97, 0xc4, 0xbe, 0x69, 0xc9, 0xef, 0xc5, + 0x6f, 0x65, 0x36, 0x0d, 0x77, 0x77, 0xf3, 0xef, 0xf9, 0xb1, 0x08, 0x51, 0x0f, 0xa6, 0x4c, 0xb8, + 0x17, 0x90, 0xe4, 0x88, 0x40, 0x73, 0xb9, 0x75, 0xb4, 0x88, 0x2d, 0x8d, 0xa1, 0x1a, 0x2c, 0xa2, + 0x1a, 0x19, 0x97, 0x74, 0x4e, 0xd5, 0x18, 0x9e, 0xce, 0x4b, 0x78, 0x06, 0x31, 0x3c, 0x03, 0x86, + 0x27, 0x7d, 0x06, 0x49, 0x67, 0x8a, 0xa7, 0x96, 0x2f, 0x49, 0x62, 0x54, 0xe6, 0xe4, 0x55, 0x9f, + 0x75, 0xe7, 0x60, 0x74, 0xf9, 0x1c, 0x8c, 0xc6, 0xcf, 0xc1, 0x02, 0x76, 0xec, 0x13, 0x1e, 0x85, + 0x49, 0x98, 0x91, 0xbf, 0xd1, 0xd9, 0xb9, 0x41, 0x68, 0x35, 0x23, 0x87, 0x8b, 0xef, 0xa9, 0x7c, + 0x81, 0xa0, 0x82, 0x07, 0x02, 0xf3, 0xb7, 0x56, 0x44, 0x96, 0x95, 0x9f, 0xb1, 0xf7, 0x49, 0xc2, + 0x13, 0xd6, 0xd8, 0x0b, 0x26, 0xa8, 0x6d, 0xec, 0x54, 0x18, 0x23, 0xcf, 0x79, 0xf8, 0x8b, 0x23, + 0xd9, 0xfb, 0x2c, 0x94, 0x7d, 0xf7, 0x8a, 0xca, 0x08, 0x05, 0x7b, 0xdc, 0xa5, 0x6d, 0x03, 0x52, + 0xe8, 0x44, 0x7c, 0x52, 0x99, 0x49, 0x79, 0x22, 0xf6, 0x35, 0x2c, 0xc8, 0x5e, 0x3b, 0x7b, 0x98, + 0xab, 0x3c, 0x33, 0x16, 0x2b, 0xcf, 0xcb, 0x27, 0x7d, 0x38, 0x26, 0x85, 0x62, 0x2b, 0x2c, 0x4d, + 0x74, 0x3a, 0x7c, 0x6e, 0x9e, 0x38, 0x9c, 0x0b, 0xd1, 0xa9, 0xf9, 0xba, 0xe5, 0x3c, 0xda, 0x83, + 0x75, 0x16, 0x56, 0x2c, 0x0f, 0xfa, 0xf8, 0x9b, 0x6a, 0x67, 0x9c, 0x14, 0x20, 0x34, 0xa8, 0xf5, + 0xac, 0xd4, 0xd0, 0x86, 0xfd, 0xe1, 0x56, 0x7d, 0x48, 0x21, 0x63, 0x0b, 0xce, 0x76, 0xcf, 0xd6, + 0x5c, 0x1e, 0xcd, 0x4f, 0xcc, 0xd7, 0x8d, 0x5b, 0x82, 0x0c, 0x4b, 0x97, 0x20, 0xb4, 0x98, 0xa4, + 0x60, 0xbc, 0x5d, 0x67, 0xc1, 0x4e, 0x39, 0x88, 0x8e, 0x27, 0x98, 0x08, 0x85, 0x2c, 0x62, 0xa1, + 0x3f, 0xe2, 0x8f, 0x55, 0x0c, 0x69, 0x25, 0x85, 0x80, 0x00, 0x72, 0x2a, 0x61, 0xb7, 0x61, 0x56, + 0x7c, 0xcc, 0xb1, 0x20, 0xe9, 0x59, 0xf8, 0x76, 0xdc, 0x9a, 0x84, 0x22, 0xfc, 0xae, 0x1c, 0x04, + 0x3a, 0x91, 0xf8, 0xac, 0x11, 0x67, 0x24, 0x54, 0x98, 0x7a, 0xce, 0x38, 0x0b, 0x51, 0xe0, 0xcf, + 0x07, 0x30, 0xc2, 0x4a, 0x11, 0x03, 0x5f, 0x00, 0x77, 0xfb, 0x82, 0x14, 0xf2, 0xf0, 0xa7, 0x90, + 0xa1, 0x3d, 0x8d, 0x49, 0xe7, 0x82, 0x20, 0x3e, 0xaf, 0x89, 0x73, 0x7e, 0xcd, 0xcf, 0x1d, 0xfe, + 0xdb, 0x87, 0xd8, 0x33, 0x3e, 0x2c, 0xbc, 0xc9, 0xf8, 0x9a, 0x53, 0x27, 0x09, 0x4d, 0xdc, 0xda, + 0x93, 0x27, 0x07, 0xd3, 0xb8, 0x00, 0xbc, 0x49, 0x2c, 0xdc, 0xfb, 0x98, 0x08, 0xf4, 0xa5, 0x30, + 0x13, 0xe0, 0x96, 0x8e, 0xb7, 0xa5, 0x35, 0x49, 0x6b, 0x98, 0x94, 0x40, 0x2c, 0x1a, 0xc4, 0xe7, + 0x5b, 0x1a, 0xec, 0x3c, 0x33, 0x16, 0xb0, 0x59, 0x1f, 0x89, 0x06, 0xab, 0x1d, 0xe0, 0xc8, 0x31, + 0x5c, 0x60, 0x0e, 0x35, 0x9e, 0x72, 0x53, 0x0f, 0xb4, 0x23, 0x3c, 0x41, 0x3e, 0xe5, 0x9e, 0x9b, + 0xc5, 0x83, 0xe0, 0xbc, 0xe3, 0x79, 0xd2, 0x8c, 0x85, 0xec, 0xe0, 0x76, 0x2b, 0x0a, 0x66, 0xcb, + 0x01, 0x16, 0x81, 0xb8, 0x91, 0xc7, 0xd3, 0x42, 0xee, 0xfb, 0x05, 0x2c, 0x60, 0x70, 0x7f, 0x4e, + 0x6f, 0x83, 0xf0, 0x50, 0x32, 0xac, 0xa1, 0xf0, 0x16, 0xbc, 0x83, 0x86, 0x59, 0x04, 0xc0, 0x5b, + 0x1f, 0x63, 0x4d, 0x63, 0xde, 0x34, 0xe6, 0x91, 0x07, 0x88, 0xa9, 0x63, 0x56, 0x91, 0x3d, 0x90, + 0x40, 0x48, 0x0a, 0x50, 0x3f, 0xc0, 0x43, 0xce, 0x59, 0x7c, 0x01, 0x79, 0x43, 0x2c, 0xb8, 0x70, + 0xd6, 0x86, 0x16, 0xb1, 0xb9, 0xc5, 0x95, 0xec, 0x2e, 0x76, 0x8c, 0xce, 0x8b, 0x10, 0xad, 0xa1, + 0x3e, 0x0f, 0xd2, 0xa5, 0xd6, 0x70, 0x9e, 0xc2, 0x62, 0xa8, 0xcc, 0xbd, 0xcb, 0xed, 0x5d, 0xe8, + 0x08, 0x9c, 0x67, 0x32, 0xaf, 0xd6, 0x70, 0x31, 0xcf, 0x8a, 0xaa, 0x74, 0x89, 0x30, 0x48, 0x0f, + 0x33, 0x25, 0x4c, 0x6d, 0x3b, 0xd1, 0x81, 0x49, 0x62, 0x62, 0x99, 0x25, 0x48, 0x52, 0x4d, 0xc9, + 0x81, 0x8b, 0x23, 0x3d, 0xfa, 0x25, 0xf4, 0x86, 0x86, 0x17, 0x48, 0x8f, 0x94, 0xdd, 0xba, 0x7d, + 0x69, 0x3c, 0x6b, 0xbc, 0x91, 0xc6, 0x51, 0xeb, 0xcd, 0x54, 0x14, 0x97, 0xf8, 0x64, 0xc7, 0xf9, + 0x44, 0xf9, 0x01, 0xc5, 0x84, 0x9f, 0xab, 0xdb, 0x48, 0x5e, 0x58, 0x85, 0x85, 0xec, 0xec, 0xc1, + 0xc1, 0xc3, 0x4a, 0x0b, 0x23, 0x35, 0x3c, 0xba, 0x0c, 0xfb, 0x59, 0xc1, 0xee, 0x91, 0x03, 0x3c, + 0xd2, 0x14, 0xbf, 0xfa, 0xd2, 0x98, 0xb7, 0x8c, 0xc3, 0x96, 0xb1, 0x0f, 0x4e, 0xf1, 0x59, 0x69, + 0x92, 0x56, 0xce, 0xf7, 0xc3, 0x24, 0x7b, 0x5d, 0xf6, 0xcd, 0xb3, 0xf4, 0x17, 0xd2, 0xfe, 0x57, + 0xe4, 0x68, 0xbf, 0x50, 0x69, 0x08, 0x93, 0xb5, 0x9f, 0x24, 0xa6, 0x2f, 0x4c, 0xf6, 0x62, 0x66, + 0xfa, 0xeb, 0xc8, 0xac, 0xa3, 0x19, 0x27, 0xcd, 0xb3, 0x15, 0x0b, 0x76, 0x1e, 0xf8, 0x5f, 0xc1, + 0x74, 0x25, 0x99, 0xfe, 0x0d, 0x6c, 0x9f, 0x33, 0x42, 0xac, 0x18, 0x82, 0x4c, 0x98, 0x4b, 0xf2, + 0xed, 0x1d, 0x18, 0x44, 0xa5, 0xec, 0x6c, 0xd1, 0xb2, 0x03, 0x72, 0x1c, 0x2c, 0xc8, 0xb1, 0xc3, + 0x25, 0x58, 0x68, 0x44, 0xdf, 0x50, 0x40, 0x01, 0x06, 0xf9, 0x75, 0x40, 0x22, 0xc3, 0xaf, 0xa5, + 0x07, 0xd3, 0xff, 0x13, 0x41, 0x23, 0xce, 0x1e, 0x7e, 0xcf, 0x00, 0x63, 0x05, 0x7d, 0xed, 0xc6, + 0x55, 0xe5, 0x59, 0x45, 0x8a, 0x8d, 0x0d, 0xdf, 0xfa, 0x8b, 0x99, 0xe8, 0x0f, 0xec, 0x75, 0x7f, + 0xcb, 0xd4, 0x17, 0x5f, 0x08, 0x22, 0x3f, 0xff, 0x4a, 0xfb, 0xe2, 0xaf, 0x2b, 0xbd, 0xf0, 0x75, + 0x80, 0x05, 0x1b, 0x19, 0xbd, 0xfc, 0x0f, 0x2b, 0x82, 0xb4, 0x3c, 0xfb, 0xbb, 0x3a, 0x79, 0x39, + 0x47, 0x34, 0xe5, 0x3c, 0x2b, 0x6b, 0x1a, 0x5c, 0x89, 0x26, 0xe7, 0xf1, 0x87, 0x6d, 0xd8, 0xcf, + 0xd3, 0x10, 0x35, 0x2f, 0x17, 0x73, 0x78, 0xcd, 0xca, 0xb9, 0x22, 0x5e, 0xa1, 0x37, 0x03, 0x20, + 0x6a, 0x81, 0xa8, 0xaa, 0xac, 0x92, 0x8c, 0x9c, 0xc9, 0x91, 0x4d, 0xfc, 0xcd, 0x9d, 0x9c, 0xac, + 0xe1, 0x9d, 0x9a, 0x83, 0xbb, 0x7c, 0x91, 0x14, 0xb0, 0x03, 0x3e, 0x8a, 0xf0, 0x58, 0xc8, 0x40, + 0x87, 0x82, 0x3f, 0xcb, 0x03, 0x13, 0xa8, 0xe1, 0x45, 0x2e, 0x66, 0xf8, 0x9d, 0x26, 0x67, 0xb1, + 0x2d, 0xbf, 0x49, 0x54, 0xf6, 0x73, 0x3d, 0x45, 0xbc, 0xe6, 0x65, 0xf5, 0x0a, 0x7a, 0xd4, 0xdc, + 0x11, 0xac, 0x9c, 0x27, 0xaa, 0x22, 0xe7, 0x8f, 0x54, 0xb8, 0x6a, 0x47, 0xaa, 0x06, 0x48, 0x1d, + 0x15, 0xf1, 0x76, 0x53, 0xce, 0x86, 0x3d, 0x6c, 0x1a, 0x35, 0x77, 0x05, 0xc3, 0xce, 0x01, 0x07, + 0x18, 0x9e, 0xcd, 0x91, 0xa2, 0xac, 0x20, 0x0a, 0x9b, 0x59, 0x52, 0x80, 0xf5, 0x61, 0x3b, 0x88, + 0x73, 0x0d, 0x76, 0x7b, 0x9e, 0xc3, 0x1e, 0x86, 0x89, 0x92, 0xc1, 0x91, 0x0a, 0x7e, 0x29, 0x41, + 0xcd, 0x60, 0x6b, 0x86, 0x6d, 0x15, 0x2f, 0x39, 0x79, 0x33, 0x17, 0x42, 0xe0, 0xee, 0x70, 0x44, + 0x91, 0x20, 0xad, 0xd4, 0x62, 0x0d, 0xc8, 0x93, 0x3b, 0xc7, 0x1f, 0xef, 0x61, 0x8d, 0x9a, 0x22, + 0x6b, 0x30, 0x77, 0x01, 0x3f, 0x35, 0x46, 0x33, 0x68, 0xc7, 0x9b, 0x9c, 0xcc, 0xaf, 0x59, 0x44, + 0x27, 0x84, 0xca, 0x20, 0x39, 0xc2, 0xa1, 0x19, 0xa4, 0x33, 0x5e, 0x6b, 0x6a, 0xe1, 0x4a, 0x55, + 0xcf, 0x55, 0x44, 0xb4, 0x88, 0x13, 0x30, 0xf4, 0x0b, 0x79, 0x86, 0x05, 0xec, 0x01, 0x87, 0xc0, + 0x5e, 0xae, 0x80, 0x16, 0xc5, 0x73, 0xce, 0x93, 0x1c, 0x9b, 0x01, 0xb6, 0x07, 0xfb, 0x92, 0x35, + 0x80, 0xdc, 0x24, 0x9b, 0xf8, 0xa1, 0xe2, 0x0b, 0x69, 0x6c, 0x80, 0x2a, 0x03, 0x3f, 0x81, 0xce, + 0x48, 0x36, 0x44, 0x84, 0x6d, 0xb1, 0x50, 0x64, 0x37, 0xb9, 0xb0, 0x81, 0x71, 0x08, 0x80, 0x90, + 0xfa, 0x45, 0xfc, 0x84, 0xb1, 0xd8, 0xa2, 0x70, 0xcc, 0x34, 0xe5, 0x18, 0xe9, 0xad, 0xc2, 0xee, + 0xe3, 0xbf, 0x4a, 0xc4, 0x0a, 0x60, 0xcb, 0x72, 0x1d, 0x7d, 0x3f, 0x21, 0xfc, 0x11, 0x2d, 0x81, + 0xfc, 0xfa, 0xd7, 0x5a, 0xb6, 0x5f, 0xfa, 0x05, 0xa8, 0x4d, 0x49, 0x53, 0x6b, 0xc5, 0xab, 0x42, + 0x4d, 0xdd, 0xc4, 0x87, 0x5c, 0xad, 0x58, 0xd1, 0x24, 0x2d, 0x7c, 0x77, 0x2f, 0x2f, 0x15, 0xae, + 0x34, 0x35, 0xd6, 0x50, 0x94, 0x34, 0xa0, 0xec, 0x66, 0xac, 0x05, 0x7f, 0x44, 0x47, 0xbd, 0x2a, + 0xc4, 0x5a, 0x70, 0x96, 0x63, 0x35, 0x2f, 0xa9, 0xb5, 0x6c, 0x1c, 0x4e, 0xca, 0x5c, 0xa9, 0x85, + 0x5a, 0xf6, 0x0a, 0xc6, 0xe7, 0xaf, 0x54, 0xb6, 0x77, 0xc2, 0x37, 0x1f, 0xbe, 0xa2, 0x5d, 0x65, + 0xa5, 0x34, 0x97, 0xcc, 0x4a, 0x77, 0x1f, 0x9e, 0xaf, 0x80, 0xfc, 0x8b, 0x94, 0x42, 0xd5, 0x0e, + 0x8b, 0xdb, 0xff, 0x45, 0xfd, 0x2e, 0xa2, 0x22, 0x14, 0x51, 0xb9, 0x0a, 0xf8, 0x98, 0x45, 0xfd, + 0x86, 0x61, 0xa0, 0x8d, 0x1a, 0x7e, 0x64, 0x51, 0x28, 0xb3, 0x38, 0xf7, 0x66, 0x1e, 0x00, 0xf1, + 0xd7, 0xb2, 0x36, 0x51, 0x1b, 0x0b, 0xff, 0x82, 0x7c, 0xd6, 0xd4, 0xcc, 0x39, 0xea, 0x3e, 0x6f, + 0x53, 0xe5, 0x1c, 0x2a, 0x01, 0x5a, 0x14, 0xf6, 0xeb, 0x5c, 0x68, 0x64, 0xd8, 0x0d, 0x1a, 0x93, + 0x62, 0x8e, 0x5b, 0x0c, 0xd0, 0x46, 0xb4, 0x1f, 0x19, 0x34, 0x25, 0x9b, 0xcc, 0xaa, 0x64, 0x42, + 0x2b, 0x83, 0x3d, 0x2a, 0xb3, 0x08, 0xc5, 0xdc, 0xd5, 0xbf, 0xaa, 0xe6, 0x45, 0x24, 0x11, 0x0e, + 0x04, 0xe3, 0x24, 0x67, 0xd9, 0xd2, 0x0a, 0x10, 0x15, 0x09, 0x98, 0x07, 0x62, 0x42, 0x67, 0x1e, + 0x60, 0xa0, 0x83, 0xf5, 0x86, 0xf0, 0x7f, 0xce, 0x7e, 0x6d, 0x5e, 0x85, 0x9a, 0x9d, 0x59, 0x23, + 0xda, 0x0d, 0x10, 0x28, 0x14, 0x6d, 0x93, 0x7d, 0x41, 0xf2, 0x83, 0xb4, 0xf6, 0xc8, 0xee, 0x17, + 0xa2, 0xa5, 0x85, 0x1f, 0x94, 0x09, 0x7f, 0x42, 0x86, 0x5f, 0xb7, 0xd8, 0x57, 0x5a, 0xb6, 0xff, + 0x07, 0x16, 0x4c, 0xe9, 0xef, 0x21, 0x5e, 0x00, 0x00 +}; diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index d235b61ed..9fd64b555 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -6,6 +6,9 @@ #endif #include "html_settings.h" #include "html_other.h" +#ifdef WLED_ENABLE_PIXART + #include "html_pixart.h" +#endif /* * Integrated HTTP web server page declarations @@ -345,6 +348,17 @@ void initServer() serveIndexOrWelcome(request); }); + #ifdef WLED_ENABLE_PIXART + server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request){ + if (handleFileRead(request, "/pixart.htm")) return; + if (handleIfNoneMatchCacheHeader(request)) return; + AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pixart, PAGE_pixart_L); + response->addHeader(FPSTR(s_content_enc),"gzip"); + setStaticContentCacheHeaders(response); + request->send(response); + }); + #endif + #ifdef WLED_ENABLE_WEBSOCKETS server.addHandler(&ws); #endif