ESP32 `dram0_0_seg' overflowed

I am building Dynamic QR generator using ESP32 Wroom and TFT display ILI9341 and for audio i am using DAC module . The code is pretty lengthy i divided it separate cpp files. i ll provide the libraries i use .

#ifndef HEADER_H
#define HEADER_H

#define GIF_IMAGE paysucces

// #include "ESPWEBCONFIG.h"
// #include "Arduino.h"
#include <LittleFS.h>
#include <Audio.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <TFT_eSPI.h>  // Hardware-specific library
#include "SPI.h"
#include <PNGdec.h>
#include "logo.h"


#include <qrcode.h>
#include <AnimatedGIF.h>
#include "../test_images/grapes.h"

#define I2S_DOUT 23
#define I2S_BCLK 27
#define I2S_LRC 26



#define DISPLAY_WIDTH tft.width()
#define DISPLAY_HEIGHT tft.height()
#define BUFFER_SIZE 256  // Optimum is >= GIF width or integral division of width


// TFT Setup
#define TFT_GREY 0x5AEB
#define MAX_IMAGE_WIDTH 240

#define FileSys LittleFS

// #define USE_DMA
#define NORMAL_SPEED

extern const char *ssid;
extern const char *password;

extern AsyncWebServer server;
extern AnimatedGIF gif;
extern AsyncWebSocket ws;


extern IPAddress local_ip;  // Static IP
extern IPAddress gateway;   // Gateway IP
extern IPAddress subnet;    // Subnet Mask
extern IPAddress dns;       // Primary DNS (e.g., Google DNS)
extern IPAddress dns_secondary;


// NTP Server and Time Zone
// extern const char *ntpServer;
// extern const long utcOffsetInSeconds;  // Indian Standard Time (IST) UTC+5:30


extern uint16_t color;
extern PNG png;


extern TFT_eSPI tft;  // Invoke custom library

extern uint32_t targetTime;  // for next 1 second timeout
extern WiFiUDP ntpUDP;
extern NTPClient timeClient;  // Update every minute

extern uint8_t omm, oss;
extern uint8_t xcolon, xsecs;
extern bool isPM;  // Track whether it's PM

extern int16_t bgxpos;
extern int16_t bgypos;

enum VIEWMODE {
  NORMAL,
  QR,
  PAYMENT_SUCCESS
};

extern Audio audio;

extern VIEWMODE state;
extern QueueHandle_t numberQueue;

extern unsigned long previousMillis;           // To store last time function was called
extern const unsigned long interval;           // Interval for the function switch (1 second)
extern unsigned long qrDisplayStartMillis;     // To track when the QR should stop
extern const unsigned long qrDisplayDuration;  // 1 minute in milliseconds
// extern bool functionSwitch;                    // Flag to toggle between functions
// extern bool isQRDisplayed;                     // Flag to check if QR is currently displayed
// extern bool qrsuccess;



// Functions

void background();
void textDisp(int x, int y, int font);
void tft_time_loop();
float extractAmountFromUPI(String url);

// QR

void dispQR(const String &name, int mrnumber, const String &url);



// Dfplayer
// void audio_begin();
void audioInit();
void audioTask(void *parameter);
void playNumber(float num);
void playAudioFile(const char *filename);


// Websocket


void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
void websockethandle(AsyncWebSocketClient *client, void *arg, uint8_t *data, size_t len);
void handlejson(const char *json);


void successPAy(const String &message, bool sda);
void setup_codes();



#endif

The Output

c:/users/user/appdata/local/arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: C:\Users\user\AppData\Local\arduino\sketches\782C4FD3F46C097DC41D0ED66202A2BD/display_i2c_audio.ino.elf section `.dram0.bss' will not fit in region `dram0_0_seg'
c:/users/user/appdata/local/arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: DRAM segment data does not fit.
c:/users/user/appdata/local/arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: DRAM segment data does not fit.
c:/users/user/appdata/local/arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: region `dram0_0_seg' overflowed by 856 bytes

I tried to reduce some global variables , All my declarations global

#include "header.h"


const char* ssid = "ssid";
const char* password = "password";

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

IPAddress local_ip(192, 168, 1, 65);  // Static IP
IPAddress gateway(192, 168, 1, 1);    // Gateway IP
IPAddress subnet(255, 255, 255, 0);   // Subnet Mask
IPAddress dns(8, 8, 8, 8);            // Primary DNS (e.g., Google DNS)
IPAddress dns_secondary(8, 8, 4, 4);  // Secondary DNS (optional, e.g., Googl


PNG png;
AnimatedGIF gif;
TFT_eSPI tft = TFT_eSPI();  // Invoke custom library

// NTP Server and Time Zone

uint16_t color = 0x500a;
uint32_t targetTime = 0;  // for next 1 second timeout

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800, 60000);  // Update every minute

uint8_t  omm = 99, oss = 99;
uint8_t  xcolon = 0, xsecs = 0;
bool isPM = false;  // Track whether it's PM


int16_t bgxpos = 0;
int16_t bgypos = 0;

VIEWMODE state = NORMAL;
QueueHandle_t numberQueue = NULL;
Audio audio;


unsigned long previousMillis = 0;              // To store last time function was called
const unsigned long interval = 1000;           // Interval for the function switch (1 second)
unsigned long qrDisplayStartMillis = 0;        // To track when the QR should stop
const unsigned long qrDisplayDuration = 5000;  // 10 second in milliseconds






float extractAmountFromUPI(String url) {
  float amount = 0.0;

  // Find the position of "am=" in the URL
  int startIndex = url.indexOf("am=");

  // If "am=" is found, extract the amount
  if (startIndex != -1) {
    startIndex += 3;                              // Skip "am=" part
    int endIndex = url.indexOf("&", startIndex);  // Find the end of the amount

    // If no "&" is found, the amount goes till the end of the string
    if (endIndex == -1) {
      endIndex = url.length();
    }

    // Extract the amount as a substring
    String amountString = url.substring(startIndex, endIndex);

    // Convert the extracted string to a float
    amount = amountString.toFloat();
  }

  Serial.print("Amount: ");
  Serial.println(amount);
  return amount;
}




But still it shows

overflowed by 856 bytes

Is there a way to fix this and run in this board or should i upgrade my ESP32 wroom to ESP32 wrover or something more powerful.

My need : To run display,Qr,Image and gif , Play audio using I2c Dac converter.

ino file

#include "header.h"
#include "esp_task_wdt.h"

esp_task_wdt_user_handle_t gif_watchdog_handle = NULL;
bool wdt_initialized = false;

File pngfile;

File f;

void setup() {
  Serial.begin(115200);
  setup_codes();
  // esp_task_wdt_init(WDT_TIMEOUT, true);  // enable panic so ESP32 restarts
  // esp_task_wdt_add(NULL);
}

void loop() {
  // Check if serial input is available
  unsigned long currentMillis;

  switch (state) {

    case NORMAL:

      tft_time_loop();
      break;

    case QR:

      // playAudioQueue();
      break;

    case PAYMENT_SUCCESS:

      currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;

        if (currentMillis - qrDisplayStartMillis >= qrDisplayDuration) {
          state = NORMAL;
        }
      }
      break;

    default:

      state = NORMAL;
      break;
  }
}

void background() {
  if (LittleFS.begin()) {
    return;
  }
  fs::File root = LittleFS.open("/", "r");

  // Check if the directory is opened successfully
  if (!root) {
    Serial.println("Failed to open directory!");
    return;
  }

  // Iterate through the files in the directory
  while (fs::File file = root.openNextFile()) {
    String strname = file.name();
    strname = "/" + strname;

    // Print the filename to serial for debugging
    Serial.println(file.name());

    // Check if the file is named "bg.png" (case-sensitive check)
    if (!file.isDirectory() && strname.endsWith(".png")) {
      // Attempt to open the PNG file using the appropriate callback functions
      int16_t rc = png.open(strname.c_str(), pngOpen, pngClose, pngRead, pngSeek, pngDraw);
      if (rc == PNG_SUCCESS) {
        tft.startWrite();  // Start writing to the TFT screen

        // Print image details to the serial monitor
        Serial.printf("Image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
        uint32_t dt = millis();
        // Check if the image width exceeds the max allowed width
        if (png.getWidth() > MAX_IMAGE_WIDTH) {
          Serial.println("Image too wide for allocated line buffer size!");
        } else {
          // Decode and display the PNG image
          rc = png.decode(NULL, 0);
          png.close();  // Close the PNG file after decoding
        }

        tft.endWrite();  // End writing to the TFT screen

        // Log how long the rendering took
        Serial.print("Rendering took: ");
        Serial.print(millis() - dt);
        Serial.println("ms");

      } else {
        // Print error if PNG decoding failed
        Serial.println("Error decoding PNG: " + String(rc));
      }
      break;  // Exit after displaying bg.png
    }
  }

  // Close the root directory
  root.close();
}


void pngDraw(PNGDRAW *pDraw) {
  int16_t xpos = 0;
  int16_t ypos = 0;
  uint16_t lineBuffer[MAX_IMAGE_WIDTH];
  png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
  tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
}




void gifdisp(bool fds) {

  const char *item = fds ? "/grapes.gif" : "/failed.gif";
  if (gif.open((uint8_t *)GIF_IMAGE, sizeof(GIF_IMAGE), GIFDraw)) {
    Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
    tft.startWrite();  // Lock the TFT chip select

    // Check if TWDT has been initialized already
    if (!wdt_initialized) {
      esp_task_wdt_config_t wdt_config = {
        .timeout_ms = 15000,  // Timeout value for the watchdog (in milliseconds)
      };

      // Initialize the TWDT with the configuration
      esp_task_wdt_init(&wdt_config);
      wdt_initialized = true;  // Set the flag indicating that TWDT is initialized
    }

    // Add the current task to the TWDT if it's not already added
    if (esp_task_wdt_add(NULL) != ESP_OK) {
      Serial.println("Task already subscribed to TWDT.");
    }

    // Add a user to the TWDT to monitor specific code (provide user name as string)
    const char *user_name = "GIF_WATCHDOG";  // Provide a user name string
    if (esp_task_wdt_add_user(user_name, &gif_watchdog_handle) != ESP_OK) {
      Serial.println("User already subscribed to TWDT.");
    }

    unsigned long previousMillis = millis();  // Track the interval for watchdog reset
    unsigned long interval = 50;              // Interval in milliseconds to reset the TWDT

    // Play GIF frames
    while (gif.playFrame(true, NULL)) {
      // Feed the watchdog periodically to avoid a reset
      if (millis() - previousMillis >= interval) {
        previousMillis = millis();
        esp_task_wdt_reset();  // Feed the TWDT to avoid timeout

        // Optionally, feed the specific user (if you've used esp_task_wdt_add_user)
        esp_task_wdt_reset_user(gif_watchdog_handle);
      }

      yield();  // Allow other tasks to run and avoid blocking
    }

    // Close the GIF file after playback
    gif.close();
    tft.endWrite();  // Release TFT chip select

    // Unsubscribe from the TWDT for the current task
    esp_task_wdt_delete(NULL);

    // Unsubscribe the user from the TWDT
    esp_task_wdt_delete_user(gif_watchdog_handle);
  } else {
    Serial.println("Could not open gif");
  }
}



void successPAy(const String &message, bool sda) {
  tft.fillScreen(TFT_WHITE);
  int textYPosition = 220 + 30;  // Position the text 10 pixels below the GIF
  tft.setFreeFont(&FreeSansBold9pt7b);
  tft.setTextColor(TFT_BLACK);  // Set text color to black
  tft.setTextSize(1);           // Set text size (you can adjust the size)

  // You can set any message you'd like to display here
  tft.setCursor((DISPLAY_WIDTH - tft.textWidth("Payment Successful")) / 2, textYPosition);
  tft.println(message);  // Print the text
  if (sda) {
    playAudioFile("/audio/SUCCESSFUL.mp3");
  } else {
    playAudioFile("/audio/FAILED.mp3");
  }

  gifdisp(sda);
  state = PAYMENT_SUCCESS;
  qrDisplayStartMillis = millis();
}




void *pngOpen(const char *filename, int32_t *size) {
  Serial.printf("Attempting to open %s\n", filename);
  pngfile = FileSys.open(filename, "r");
  *size = pngfile.size();
  return &pngfile;
}

void pngClose(void *handle) {
  File pngfile = *((File *)handle);
  if (pngfile) pngfile.close();
}

int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
  if (!pngfile) return 0;
  page = page;  // Avoid warning
  return pngfile.read(buffer, length);
}

int32_t pngSeek(PNGFILE *page, int32_t position) {
  if (!pngfile) return 0;
  page = page;  // Avoid warning
  return pngfile.seek(position);
}






bool dmaBuf = 0;

// Draw a line of image directly on the LCD
void GIFDraw(GIFDRAW *pDraw) {

#ifdef USE_DMA
  uint16_t usTemp[2][BUFFER_SIZE];  // Global to support DMA use
#else
  uint16_t usTemp[1][BUFFER_SIZE];                        // Global to support DMA use
#endif

  uint8_t *s;
  uint16_t *d, *usPalette;
  int x, y, iWidth, iCount;

  // Calculate the shift to center the GIF on the screen
  int gifWidth = pDraw->iWidth;    // GIF width
  int gifHeight = pDraw->iHeight;  // GIF height

  // Calculate the horizontal and vertical offset to center the GIF
  int shiftX = (DISPLAY_WIDTH - gifWidth) / 2;    // Center horizontally
  int shiftY = (DISPLAY_HEIGHT - gifHeight) / 2;  // Center vertically

  // Display bounds check and cropping
  iWidth = pDraw->iWidth;
  if (iWidth + pDraw->iX + shiftX > DISPLAY_WIDTH)
    iWidth = DISPLAY_WIDTH - (pDraw->iX + shiftX);  // Adjust width if it goes beyond the screen

  usPalette = pDraw->pPalette;
  y = pDraw->iY + pDraw->y + shiftY;  // Apply vertical shift to the y-coordinate
  if (y >= DISPLAY_HEIGHT || pDraw->iX + shiftX >= DISPLAY_WIDTH || iWidth < 1)
    return;

  // Old image disposal (restore background color)
  s = pDraw->pPixels;
  if (pDraw->ucDisposalMethod == 2) {  // restore to background color
    for (x = 0; x < iWidth; x++) {
      if (s[x] == pDraw->ucTransparent)
        s[x] = pDraw->ucBackground;
    }
    pDraw->ucHasTransparency = 0;
  }

  // Apply the new pixels to the main image
  if (pDraw->ucHasTransparency) {  // if transparency is used
    uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
    pEnd = s + iWidth;
    x = 0;
    iCount = 0;  // count non-transparent pixels
    while (x < iWidth) {
      c = ucTransparent - 1;
      d = &usTemp[0][0];
      while (c != ucTransparent && s < pEnd && iCount < BUFFER_SIZE) {
        c = *s++;
        if (c == ucTransparent) {  // done, stop
          s--;                     // back up to treat it like transparent
        } else {                   // opaque
          *d++ = usPalette[c];
          iCount++;
        }
      }
      if (iCount) {  // any opaque pixels?
        // Adjust the horizontal position based on shiftX
        tft.setAddrWindow(pDraw->iX + x + shiftX, y, iCount, 1);
        tft.pushPixels(usTemp, iCount);
        x += iCount;
        iCount = 0;
      }
      // Skip transparent pixels
      c = ucTransparent;
      while (c == ucTransparent && s < pEnd) {
        c = *s++;
        if (c == ucTransparent)
          x++;
        else
          s--;
      }
    }
  } else {  // No transparency
    s = pDraw->pPixels;
    // Translate the 8-bit pixels through the RGB565 palette
    if (iWidth <= BUFFER_SIZE)
      for (iCount = 0; iCount < iWidth; iCount++) usTemp[dmaBuf][iCount] = usPalette[*s++];
    else
      for (iCount = 0; iCount < BUFFER_SIZE; iCount++) usTemp[dmaBuf][iCount] = usPalette[*s++];

        // Push the pixels to the screen
#ifdef USE_DMA
    tft.dmaWait();
    tft.setAddrWindow(pDraw->iX + shiftX, y, iWidth, 1);  // Adjust position with shiftX
    tft.pushPixelsDMA(&usTemp[dmaBuf][0], iCount);
    dmaBuf = !dmaBuf;
#else
    tft.setAddrWindow(pDraw->iX + shiftX, y, iWidth, 1);  // Adjust position with shiftX
    tft.pushPixels(&usTemp[0][0], iCount);
#endif

    iWidth -= iCount;
    while (iWidth > 0) {
      if (iWidth <= BUFFER_SIZE)
        for (iCount = 0; iCount < iWidth; iCount++) usTemp[dmaBuf][iCount] = usPalette[*s++];
      else
        for (iCount = 0; iCount < BUFFER_SIZE; iCount++) usTemp[dmaBuf][iCount] = usPalette[*s++];

#ifdef USE_DMA
      tft.dmaWait();
      tft.pushPixelsDMA(&usTemp[dmaBuf][0], iCount);
      dmaBuf = !dmaBuf;
#else
      tft.pushPixels(&usTemp[0][0], iCount);
#endif
      iWidth -= iCount;
    }
  }
}



// void *GIFOpenFile(const char *fname, int32_t *pSize) {
//   f = FileSys.open(fname, "r");
//   if (f) {
//     *pSize = f.size();
//     return (void *)&f;
//   }
//   return NULL;
// } /* GIFOpenFile() */

// void GIFCloseFile(void *pHandle) {
//   File *f = static_cast<File *>(pHandle);
//   if (f != NULL)
//     f->close();
// } /* GIFCloseFile() */

// int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) {
//   int32_t iBytesRead;
//   iBytesRead = iLen;
//   File *f = static_cast<File *>(pFile->fHandle);
//   // Note: If you read a file all the way to the last byte, seek() stops working
//   if ((pFile->iSize - pFile->iPos) < iLen)
//     iBytesRead = pFile->iSize - pFile->iPos - 1;  // <-- ugly work-around
//   if (iBytesRead <= 0)
//     return 0;
//   iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
//   pFile->iPos = f->position();
//   return iBytesRead;
// } /* GIFReadFile() */

// int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition) {
//   int i = micros();
//   File *f = static_cast<File *>(pFile->fHandle);
//   f->seek(iPosition);
//   pFile->iPos = (int32_t)f->position();
//   i = micros() - i;
//   //  Serial.printf("Seek time = %d us\n", i);
//   return pFile->iPos;
// } /* GIFSeekFile() */

config.cpp

#include "header.h"


void setup_codes() {

  if (!WiFi.config(local_ip, gateway, subnet,dns, dns_secondary)) {
    Serial.println("STA Failed to configure");
  }

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to WiFi");
  Serial.print("IP :");
  Serial.println(WiFi.localIP());

  timeClient.begin();
  timeClient.update();
  targetTime = millis() + 1000;

  softwareSerial.begin(9600);
  if (player.begin(softwareSerial)) {
    Serial.println("DFPlayer Mini is ready.");
    player.volume(30);  // Set volume (0-30)
  } else {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }

  ws.onEvent(onEvent);
  server.addHandler(&ws);
  server.begin();

  LittleFS.begin();




  tft.begin();
  tft.setRotation(0);  // Set the rotation to 0 (portrait mode)
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&FreeSansBold9pt7b);
  tft.setTextColor(TFT_BLACK);
  background();
  logodraw(170, 245);
  textDisp(20, 290, 1);

  gif.begin(BIG_ENDIAN_PIXELS);
}

music.cpp

#include "header.h"


  void storeNumberAudio(float number) {
    long int integerPart = (long int)number;   // Extract integer part
    float dec = (number - integerPart) * 100;  // Get the first two digits of the decimal part (up to two decimal places)
    int decimalPart = round(dec);

    // Store the integer part
    storeIntegerPart(integerPart);

    // Store the decimal point and the decimal digits
    storeDecimalPart(decimalPart);
    // audio = true;
  }

  // Function to store the integer part in the playQueue array
  void storeIntegerPart(long int number) {
    if (number <= 0) return;  // Nothing to store for zero or negative numbers

    // Handle numbers <= 100 (treating them as a single case)
    if (number <= 100) {
      playQueue[queueSize++] = number + 1;  // Add the number directly (1 to 100)
    } else if (number <= 1000) {
      storeHundreds(number);
    } else if (number <= 10000) {
      storeThousands(number);
    } else if (number < 100000) {
      storeTenThousands(number);
    } else {
      storeLargeNumbers(number);
    }
  }

  // Function to store numbers in the hundreds range
  void storeHundreds(long int number) {
    int num = number / 100;
    playQueue[queueSize++] = num + 100;  // Store the hundreds place
    number -= num * 100;                 // Subtract the hundreds part

    // Now store the remainder (tens and ones)
    storeIntegerPart(number);
  }

  // Function to store numbers in the thousands range
  void storeThousands(long int number) {
    int num = number / 1000;
    playQueue[queueSize++] = num + 109;  // Store the thousands place
    number -= num * 1000;

    // Now store the remainder (hundreds, tens, and ones)
    storeIntegerPart(number);
  }

  // Function to store numbers in the ten-thousands range
  void storeTenThousands(long int number) {
    int num = number / 1000;
    playQueue[queueSize++] = num + 1;  // Store the ten-thousands place
    playQueue[queueSize++] = 121;      // Store the word "thousand" or similar
    number -= num * 1000;

    // Now store the remainder (hundreds, tens, and ones)
    storeIntegerPart(number);
  }

  // Function to handle very large numbers (greater than 100000)
  void storeLargeNumbers(long int number) {
    int num = number / 100000;
    playQueue[queueSize++] = num + 1;  // Store the hundreds of thousands place
    playQueue[queueSize++] = 120;      // Store the word "hundred thousand" or similar
    number -= num * 100000;

    // Now store the remainder (thousands, hundreds, etc.)
    storeIntegerPart(number);
  }

  // Function to store the decimal part in the playQueue array
  void storeDecimalPart(int decimalPart) {
    // Store the decimal point
    playQueue[queueSize++] = 122;  // Assuming '122' corresponds to the "point" sound

    // Store the first and second digits of the decimal part
    if (decimalPart >= 0) {
      int firstDigit = decimalPart / 10;         // Get the first digit
      int secondDigit = decimalPart % 10;        // Get the second digit
      playQueue[queueSize++] = firstDigit + 1;   // Store the first digit
      playQueue[queueSize++] = secondDigit + 1;  // Store the second digit
    }
    playQueue[queueSize++] = 123;
  }

  // Function to play the audio queue with non-blocking timing
  void playAudioQueue() {
    if (queueSize > 0 && (millis() - lastPlayTime >= playInterval)) {
      player.play(playQueue[0]);  // Play the first item in the queue
      lastPlayTime = millis();    // Update the last play time

      // Shift the queue
      for (int i = 1; i < queueSize; i++) {
        playQueue[i - 1] = playQueue[i];  // Shift each element left
      }
      queueSize--;  // Decrease the queue size
    }
  }

logo.h

#define ASSET_1_HEIGHT 34
#define ASSET_1_WIDTH 60

// array size is 4080
const uint16_t logo[] PROGMEM = {
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4809, 0x480b, 0x4809, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x4008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x480a, 0x500a, 0x500b, 0x500a, 0x500b, 0x500a, 0x500b, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x480b, 0x500a, 0x500a, 0x500a, 0x480b, 0x4008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x4008, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x500a, 0x500a, 0x500b, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x4008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500b, 0x500a, 0x400a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x480a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x4008, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x500b, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x480b, 0x500a, 0x500a, 0x500a, 0x480b, 0x0000, 0x4809, 0x0000,
  0x0000, 0x500b, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x0000, 0x500a, 0x500b, 0x500a, 0x500b, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500b, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000,
  0x0000, 0x500a, 0x500b, 0x500b, 0x500b, 0x4809, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x0000, 0x400a, 0x500a, 0x500b, 0x0000, 0x0000, 0x0000, 0x8010, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x480a, 0x3006, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4809, 0x500a, 0x500b, 0x480a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x0000,
  0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x4809, 0x400a, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x0000, 0x4008, 0x500a, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x480b, 0x500b, 0x500a, 0x4008, 0x0000, 0x0000, 0x0000, 0x480a, 0x500a, 0x280a,
  0x0000, 0x0000, 0x480a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500b, 0x500b, 0x500a, 0x500b, 0x8010, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x500b, 0x500b, 0x500b, 0x500a, 0x4008, 0x500b, 0x500a, 0x4809, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000,
  0x0000, 0x500b, 0x500a, 0x500b, 0x0000, 0x500a, 0x480a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x4008, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x000a, 0x0000, 0x0000, 0x0000, 0x500b, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x0000, 0x0000, 0x400a, 0x500b, 0x500b, 0x0000, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x500b, 0x500a, 0x400b,
  0x4809, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4809, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x480b, 0x500b, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a,
  0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x580b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4809, 0x500b, 0x500a, 0x480b, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500b, 0x500b, 0x500a, 0x500a, 0x500b, 0x4809, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b,
  0x4809, 0x500a, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500b, 0x3006, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x500a, 0x500b, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x480a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x480a, 0x500a, 0x500a,
  0x0000, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4809, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a,
  0x0000, 0x500a, 0x500b, 0x480a, 0x500b, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x3006, 0x3006, 0x3006, 0x0000, 0x380a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x0000,
  0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4008, 0x4809, 0x500a, 0x500b, 0x500b, 0x500a, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x4008, 0x4008, 0x4809, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x500b, 0x0000, 0x0000, 0x500b, 0x500a, 0x500a, 0x480a, 0x500a, 0x500a, 0x480b, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x4008, 0x0000, 0x0000,
  0x500a, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500a, 0x500b, 0x500b, 0x500a, 0x4809, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x480a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x480b, 0x500b, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x500a, 0x500a, 0x500b, 0x500a, 0x500a, 0x4008, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x500a, 0x500a, 0x500a, 0x500a, 0x500b, 0x500b, 0x500a, 0x500b, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500a, 0x580b, 0x500a, 0x500a, 0x500a, 0x3006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500a, 0x4809, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x500a, 0x500b, 0x500b, 0x500b, 0x500a, 0x500a, 0x500a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4008, 0x4809, 0x4809, 0x4809, 0x4809, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};


#define ICON_HEIGHT 60
#define ICON_WIDTH 60

// array size is 7200
const uint16_t icon[] PROGMEM = {
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef7d, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xe71c, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x5aeb, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x31a6, 0x39c7, 0xef7d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xa514, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18e3, 0xad75, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xe73c, 0x4a69, 0x39e7, 0x39e7, 0x39e7, 0x2965, 0x18e3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x39c7, 0x39e7, 0x39e7, 0x39e7, 0x632c, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf7be, 0xc618, 0x630c, 0x2104, 0x18c3, 0x18c3, 0x18c3, 0x8c71, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf7be, 0xad55, 0x18e3, 0x18c3, 0x18c3, 0x2104, 0xe73c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdefb, 0xce79, 0xce79, 0xce79, 0xce79, 0xce79, 0xce79, 0xce59, 0x31a6, 0x18c3, 0x18c3, 0x18c3, 0x9492, 0xce79, 0xce79, 0xce79, 0xce79, 0xf79e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x4208, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x18e3, 0x18c3, 0x18c3, 0x18c3, 0x2104, 0x2124, 0x2124, 0x2124, 0x39c7, 0xf79e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x7bcf, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x2104, 0xd69a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef5d, 0x7bcf, 0x73ae, 0x73ae, 0x73ae, 0x73ae, 0x73ae, 0x73ae, 0x73ae, 0x73ae, 0x5aeb, 0x18c3, 0x18c3, 0x18c3, 0x4a49, 0x73ae, 0x73ae, 0x9492, 0xffdf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xad55, 0x18c3, 0x18c3, 0x18c3, 0xb596, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x52aa, 0x18c3, 0x18c3, 0x2124, 0xef7d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xce59, 0x2104, 0x18c3, 0x18c3, 0x9492, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xad55, 0x2965, 0x18c3, 0x18c3, 0x31a6, 0xef7d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf79e, 0xce79, 0xd69a, 0xce79, 0xc638, 0xa514, 0x528a, 0x18c3, 0x18c3, 0x18c3, 0x4a49, 0xef5d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xce79, 0x2124, 0x2124, 0x2124, 0x18e3, 0x18c3, 0x18c3, 0x18c3, 0x18e3, 0x8c51, 0xe73c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xce79, 0x18c3, 0x18c3, 0x18c3, 0x18e3, 0x39e7, 0x4a49, 0x8430, 0xdefb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xe71c, 0x2104, 0x18c3, 0x18c3, 0x2104, 0xc618, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x8410, 0x18c3, 0x18c3, 0x18c3, 0x4208, 0xef7d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xf79e, 0x4a69, 0x18c3, 0x18c3, 0x18c3, 0x73ae, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd6ba, 0x2945, 0x18c3, 0x18c3, 0x18c3, 0xb596, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0xad75, 0x18c3, 0x18c3, 0x18c3, 0x3186, 0xef5d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b4d, 0x18c3, 0x18c3, 0x18c3, 0x4a49, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xe73c, 0x39c7, 0x18c3, 0x18c3, 0x18e3, 0x94b2, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xce79, 0x2124, 0x18c3, 0x18c3, 0x18c3, 0xc618, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x94b2, 0x18c3, 0x18c3, 0x18c3, 0x39e7, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x5aeb, 0x18c3, 0x18c3, 0x18c3, 0x5acb, 0xf7be, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdefb, 0x2945, 0x18c3, 0x18c3, 0x18c3, 0xad55, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc618, 0x2104, 0x18c3, 0x18c3, 0x2104, 0xce79, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x73ae, 0x18c3, 0x18c3, 0x18c3, 0x4a49, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffdf, 0x5acb, 0x31a6, 0x31a6, 0x31a6, 0x94b2, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xef7d, 0xe71c, 0xe71c, 0xe71c, 0xe73c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};

tft.cpp

#include "header.h"



void logodraw(int logoX, int logoY) {
  int logoSize = ASSET_1_WIDTH;
  int logoHeight = ASSET_1_HEIGHT;  // Example logo size

  // Draw the logo over the QR code
  for (int y = 0; y < logoHeight; y++) {
    for (int x = 0; x < logoSize; x++) {
      uint16_t color = logo[y * logoSize + x];
      if (color != 0x0000) {
        // color = 0xFFFF;  // Change black to white
        tft.drawPixel(logoX + x, logoY + y, color);
      }

      // Draw the logo pixel at the desired (logoX, logoY) position
      // Adjust position by logoX and logoY
    }
  }
}

void textDisp(int x, int y, int font) {
  tft.setTextSize(font);
  tft.setTextColor(TFT_WHITE);
  tft.drawString("QR Scanner", x, y);
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(1);
}



void tft_time_loop() {
  if (targetTime < millis()) {
    // Set next update for 1 second later
    targetTime = millis() + 1000;

    // Update NTP time once per second
    timeClient.update();

    // Get hours, minutes, and seconds from NTP
    int hh = timeClient.getHours();
    int mm = timeClient.getMinutes();
    int ss = timeClient.getSeconds();

    // Convert 24-hour format to 12-hour format
    int displayHour = hh;
    if (displayHour >= 12) {
      isPM = true;
      if (displayHour > 12) {
        displayHour -= 12;  // Convert to 12-hour format
      }
    } else {
      isPM = false;
      if (displayHour == 0) {
        displayHour = 12;  // Midnight case (12 AM)
      }
    }

    int xpos = 0;
    int ypos = 10;  // Top left corner of clock text, about halfway down

    if (omm != mm) {  // Redraw hours and minutes time every minute
      omm = mm;
      // tft.fillScreen(TFT_BLACK);   // Clear the screen before redrawing time
      background();
      logodraw(170, 245);
      textDisp(20, 290, 1);
      // Draw hours and minutes
      xpos = 10;
      if (displayHour < 10) xpos += tft.drawChar('0', xpos, ypos, 7);
      xpos += tft.drawNumber(displayHour, xpos, ypos, 7);     // Draw hours
      xcolon = xpos;                                          // Save colon coordinate for later to flash on/off later
      xpos += tft.drawChar(':', xpos, ypos, 7);               // Draw colon
      if (mm < 10) xpos += tft.drawChar('0', xpos, ypos, 7);  // Add leading zero for minutes
      xpos += tft.drawNumber(mm, xpos, ypos, 7);              // Draw minutes

      // Draw AM/PM
      if (isPM) {
        tft.setTextSize(2);
        xpos += tft.drawString("pm", xpos + 5, ypos + 10);
      } else {
        tft.setTextSize(2);
        xpos += tft.drawString("am", xpos + 5, ypos + 10);
      }
      tft.setTextSize(1);
    }
  }
}

qr.cpp

#include "header.h"

void dispQR(const String &name, int mrnumber, const String &url) {
  tft.fillScreen(TFT_WHITE);  // Set the screen to white
  String mrnumberStr = String(mrnumber);
  tft.setFreeFont(&FreeSansBold9pt7b);
  tft.setTextSize(1);           // Set the text size for the label
  tft.setTextColor(TFT_BLACK);  // Set the text color to black

  int nameWidth = tft.textWidth(name);                   // Width of the name text
  int numberWidth = tft.textWidth(mrnumberStr.c_str());  // Width of the mrnumber text
  // int pricewidth = tft.textWidth(price, 2);

  // Calculate the starting position dynamically
  int nameX = (DISPLAY_WIDTH - nameWidth) / 2;      // Center the name horizontally
  int numberX = (DISPLAY_WIDTH - numberWidth) / 2;  // Center the number horizontally
  // int priceX = (tft.width() - pricewidth) / 2;

  // Set the Y position as desired
  int nameY = 10;
  int numberY = 40;

  // Print the name and mrnumber at the dynamically calculated positions
  tft.drawString(name, nameX, nameY);
  tft.drawNumber(mrnumber, numberX, numberY, 1);

  // Start timing QR code generation
  unsigned long startTime = millis();

  // Create the QR code
  QRCode qrcode;
  uint8_t qrcodeData[qrcode_getBufferSize(15)];
  qrcode_initText(&qrcode, qrcodeData, 15, 1, url.c_str());

  // Calculate QR code size
  int qrSize = qrcode.size;
  int scale = 2;  // Size of each module (QR block)

  // Calculate offset (position the QR code to the center of the screen)
  int xOffset = (240 - (qrSize * scale)) / 2;
  int yOffset = (320 - (qrSize * scale)) / 2;  // Adjust the Y offset to leave space for the label

  // Display the QR code on the TFT screen
  for (uint8_t y = 0; y < qrSize; y++) {
    for (uint8_t x = 0; x < qrSize; x++) {
      // Get module value: black (filled) or white (empty)
      if (qrcode_getModule(&qrcode, x, y)) {
        tft.fillRect(xOffset + x * scale, yOffset + y * scale, scale, scale, TFT_BLACK);  // Draw black block
      } else {
        tft.fillRect(xOffset + x * scale, yOffset + y * scale, scale, scale, TFT_WHITE);  // Draw white block
      }
    }
  }

  // Add a border around the QR code
  uint16_t borderColor = TFT_BLACK;  // You can change this to any color you want for the border
  int borderWidth = 5;               // Border thickness

  // Draw the border
  tft.drawRect(xOffset - borderWidth, yOffset - borderWidth, (qrSize * scale) + (2 * borderWidth), (qrSize * scale) + (2 * borderWidth), borderColor);

  // Add the logo in the center of the QR code
  int logoSize = ASSET_1_WIDTH;
  int logoHeight = ASSET_1_HEIGHT;                        // Example logo size
  int logoX = xOffset + (qrSize * scale - logoSize) / 2;  // Center the logo
  int logoY = yOffset + (qrSize * scale - logoHeight) / 2;

  // Draw the logo over the QR code
  for (int y = 0; y < logoHeight; y++) {
    for (int x = 0; x < logoSize; x++) {
      uint16_t color = logo[y * logoSize + x];
      if (color == 0x0000) {
        color = 0xFFFF;  // Change black to white
      }

      tft.drawPixel(logoX + x, logoY + y, color);  // Draw the modified pixel
    }
  }

  // Add the price text
  tft.setTextSize(2);
  tft.drawString("Rs:" + extractAmountFromUPI(url), 30, 270);
  tft.setTextSize(1);

  // End timing and calculate duration
  unsigned long endTime = millis();
  unsigned long duration = endTime - startTime;  // Time taken to generate QR code

  // Print the time taken to serial monitor
  Serial.print("QR Code Generation Time: ");
  Serial.print(duration);
  Serial.println(" ms");
  storeNumberAudio(extractAmountFromUPI(url).toFloat());

  state = QR;
}




void drawScaledImage(int startX, int startY) {
  int targetWidth = 32;  // Target size for the image
  int targetHeight = 32;

  int scaleX = 60 / targetWidth;   // Scaling factor in X direction
  int scaleY = 60 / targetHeight;  // Scaling factor in Y direction

  // Draw the 24x24 scaled image
  for (int y = 0; y < targetHeight; y++) {
    for (int x = 0; x < targetWidth; x++) {
      // Calculate the corresponding pixel in the original 60x60 image
      int originalX = x * scaleX;
      int originalY = y * scaleY;

      // Calculate the 1D index for the pixel in the original array
      int index = originalY * 60 + originalX;

      // Get the pixel color from the original image
      uint16_t color = icon[index];

      if (color != 0xFFFF) {  // If it's not white, draw the pixel
        tft.drawPixel(startX + x, startY + y, 0x0000);
      }
    }
  }
}

websocket.cpp

#include "header.h"



void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      client->text("Welcome");
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      websockethandle(client, arg, data, len);
      break;
    case WS_EVT_PONG:
      Serial.printf("WebSocket client #%u ponged\n", client->id());
      break;
    case WS_EVT_ERROR:
      Serial.printf("WebSocket client #%u error(%u): %s\n", client->id(), *((uint16_t *)arg), (char *)data);
      break;
  }
}


void websockethandle(AsyncWebSocketClient *client, void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo *)arg;

  if (info->final && info->index == 0 && info->len == len) {
    // Null-terminate the received data
    data[len] = 0;  // Null-terminate the C-string

    // Use const char* for the message
    const char *message = (const char *)data;

    // Print the received message for debugging
    // Web .print("Received: ");
    Serial.println(message);
    client->text("Message Received");
    // if (message[0] == '{' && message[len - 1] == '}') {
    handlejson(message);
    // Serial.print("Received: Json data ");
    // }
  }
}




void handlejson(const char *json) {
  DynamicJsonDocument doc(1024);
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    Serial.print("Failed to parse JSON: ");
    Serial.println(error.f_str());
    return;
  }

  // Check the status of the JSON and handle accordingly
  int status = doc["status"];  // Get the status field

  // Handle the first JSON (File 1) - expects "status", "url", "name", "mrnumber"
  if (status == 300) {
    const char *url = doc["url"];
    const char *name = doc["name"];
    int mrnumber = doc["mrnumber"];


    /*
    Serial.print("Status: ");
    Serial.println(status);
    Serial.print("URL: ");
    Serial.println(url);
    Serial.print("Name: ");
    Serial.println(name);
    Serial.print("MR Number: ");
    Serial.println(mrnumber);
    */
    dispQR(name, mrnumber, url);
  }
  // Handle the second JSON (File 2) - expects "status" and "message"
  else if (status == 200) {
    const char *message = doc["message"];

    // Serial.print("Status: ");
    // Serial.println(status);
    // Serial.print("Message: ");
    // Serial.println(message);
    successPAy(message,true);
  } else if (status == 400) {
    const char *message = doc["message"];
    successPAy(message,false);

  } else {
    Serial.println("Unknown status");
  }
}

  1. Does not compile.
  2. Does not compile.

huh...

i dont get what you are trying to say . It does not compile and it shows this error and am asking for help to fix the issue

You should supply compilable code. Is this the fifteenth time you have been requested to do this?

Ok ill paste whole code, Updated the source code

Awesome. Now post #2 makes no sense.

did i make things worse

Update : If i change my device from Esp32 wroom to ESP32-S3 or other varients of ESP32 which has PSRAM can it solve my issue .Any idea ? ..

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.