[
  {
    "path": ".editorconfig",
    "content": "# This file is for unifying the coding style for different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\nmax_line_length = 120\ncurly_bracket_next_line = false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Do this '....'\n3. Do that '....'\n4. See error\n\n**Sample code**\nProvide a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) below.\n```c\n# your code goes here\n```\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Versions (please complete the following information):**\n - Library: [e.g. 4.2]\n - Platform [e.g. ESP266 Arduino Core 2.5.x]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/support-request.md",
    "content": "---\nname: Support request\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\nWe offer support to our customers at https://support.thingpulse.com/. Send us an email if you don't have an account yet.\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 180\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 14\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "# documentation at https://docs.platformio.org/en/latest/integration/ci/github-actions.html\n\nname: PlatformIO CI\n\non: [push, pull_request]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        example: [examples/SSD1306UiDemo, examples/SSD1306SimpleDemo, examples/SSD1306DrawingDemo, examples/SSD1306OTADemo, examples/SSD1306ClockDemo, examples/SSD1306TwoScreenDemo]\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache pip\n      uses: actions/cache@v3\n      with:\n        path: ~/.cache/pip\n        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}\n        restore-keys: ${{ runner.os }}-pip-\n    - name: Cache PlatformIO\n      uses: actions/cache@v3\n      with:\n        path: ~/.platformio\n        key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}\n    - name: Set up Python\n      uses: actions/setup-python@v5\n    - name: Install PlatformIO\n      run: |\n        python -m pip install --upgrade pip\n        pip install --upgrade platformio intelhex\n    - name: Install library dependencies\n      run: pio pkg install -g -l \"paulstoffregen/Time@^1.6\"\n    - name: Run PlatformIO\n      run: pio ci --lib=\".\" --board=nodemcuv2 --board=d1_mini --board=esp-wrover-kit --board=esp32doit-devkit-v1\n      env:\n        PLATFORMIO_CI_SRC: ${{ matrix.example }}\n"
  },
  {
    "path": ".gitignore",
    "content": ".vscode\n.pio\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "set(COMPONENT_ADD_INCLUDEDIRS src)\nset(COMPONENT_PRIV_REQUIRES arduino-esp32)\nset(COMPONENT_SRCDIRS src)\nregister_component()\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to ThingPulse OLED SSD1306\n\n:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:\n\nThe following is a set of guidelines for contributing to the ThingPulse OLED SSD1306 library on GitHub. These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.\n\nIt is appreciated if you raise an issue _before_ you start changing the code, discussing the proposed change; emphasizing that you are proposing to develop the patch yourself, and outlining the strategy for implementation. This type of discussion is what we should be doing on the issues list and it is better to do this before or in parallel to developing the patch rather than having \"you should have done it this way\" type of feedback on the PR itself.\n\n### Table Of Contents\n* [General remarks](#general-remarks)\n* [Writing Documentation](#writing-documentation)\n* [Working with Git and GitHub](#working-with-git-and-github)\n  * [General flow](#general-flow)\n  * [Keeping your fork in sync](#keeping-your-fork-in-sync)\n  * [Commit messages](#commit-messages)\n\n## General remarks\nWe are a friendly and welcoming community and look forward to your contributions. Once your contribution is integrated into this repository we feel responsible for it. Therefore, be prepared for constructive feedback. Before we merge anything we need to ensure that it fits in and is consistent with the rest of code.\nIf you made something really cool but won't spend the time to integrate it into this upstream project please still share it in your fork on GitHub. If you mention it in an issue we'll take a look at it anyway.\n\n## Writing Documentation\nThingPulse maintains documentation for its products at [https://github.com/thingpulse/docs/](https://github.com/thingpulse/docs/). If you contribute features for this project that require altering the respective product guide then we ask you to prepare a pull request with the necessary documentation changes as well.\n\n## Working with Git and GitHub\n\nAvoid intermediate merge commits. [Rebase](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) your feature branch onto `master` to pull updates and verify your local changes against them before placing the pull request.\n\n### General flow\n1. [Fork](https://help.github.com/articles/fork-a-repo) this repository on GitHub.\n1. [Create a branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/#creating-a-branch) in your fork on GitHub **based on the `master` branch**.\n1. Clone the fork on your machine with `git clone https://github.com/<your-account>/<esp8266-oled-ssd1306>.git`\n1. `cd <weather-station-fork>` then run `git remote add upstream https://github.com/ThingPulse/esp8266-oled-ssd1306`\n1. `git checkout <branch-name>`\n1. Make changes to the code base and commit them using e.g. `git commit -a -m 'Look ma, I did it'`\n1. When you're done bring your fork up-to-date with the upstream repo ([see below](#keeping-your-fork-in-sync)). Then rebase your branch on `master` running `git rebase master`.\n1. `git push`\n1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) (PR) on GitHub.\n\nThis is just one way of doing things. If you're proficient in Git matters you're free to choose your own. If you want to read more then the [GitHub chapter in the Git book](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project#The-GitHub-Flow) is a way to start. [GitHub's own documentation](https://help.github.com/categories/collaborating/) contains a wealth of information as well.\n\n### Keeping your fork in sync\nYou need to sync your fork with the upstream repository from time to time, latest before you rebase (see flow above).\n\n1. `git fetch upstream`\n1. `git checkout master`\n1. `git merge upstream/master`\n\n### Commit messages\n\nFrom: [http://git-scm.com/book/ch5-2.html](http://git-scm.com/book/ch5-2.html)\n<pre>\nShort (50 chars or less) summary of changes\n\nMore detailed explanatory text, if necessary.  Wrap it to about 72\ncharacters or so.  In some contexts, the first line is treated as the\nsubject of an email and the rest of the text as the body.  The blank\nline separating the summary from the body is critical (unless you omit\nthe body entirely); tools like rebase can get confused if you run the\ntwo together.\n\nFurther paragraphs come after blank lines.\n\n- Bullet points are okay, too\n- Typically a hyphen or asterisk is used for the bullet, preceded by a\n   single space, with blank lines in between, but conventions vary here\n</pre>\n\nDon't forget to [reference affected issues](https://help.github.com/articles/closing-issues-via-commit-messages/) in the commit message to have them closed automatically on GitHub.\n\n[Amend](https://help.github.com/articles/changing-a-commit-message/) your commit messages if necessary to make sure what the world sees on GitHub is as expressive and meaningful as possible.\n"
  },
  {
    "path": "README.md",
    "content": "# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)\n\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/thingpulse/library/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays.svg)](https://registry.platformio.org/libraries/thingpulse/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays)\n[![Build Status](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions/workflows/main.yml/badge.svg)](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions)\n\nThis is a driver for SSD1306 and SH1106 128x64, 128x32, 64x48 and 64x32 OLED displays running on the Arduino/ESP8266 & ESP32 and mbed-os platforms.\nCan be used with either the I2C or SPI version of the display.\n\nThis library drives the OLED display included in the [ThingPulse IoT starter kit](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/) aka classic kit aka weather station kit.\n\n[![ThingPulse ESP8266 WeatherStation Classic Kit](https://github.com/ThingPulse/esp8266-weather-station/blob/master/resources/ThingPulse-ESP8266-Weather-Station.jpeg?raw=true)](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/)\n\nYou can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under \"ESP8266 and ESP32 Oled Driver for SSD1306 display\". For mbed-os a copy of the files are available as an mbed-os library.\n\nIt is also available as a [PlatformIO library](https://platformio.org/lib/show/2978/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays/examples). Just execute the following command:\n```\nplatformio lib install 2978\n```\n\n## Service level promise\n\n<table><tr><td><img src=\"https://thingpulse.com/assets/ThingPulse-open-source-prime.png\" width=\"150\">\n</td><td>This is a ThingPulse <em>prime</em> project. See our <a href=\"https://thingpulse.com/about/open-source-commitment/\">open-source commitment declaration</a> for what this means.</td></tr></table>\n\n## Credits\n\nThis library has initially been written by [Daniel Eichhorn](https://github.com/squix78). Many thanks go to [Fabrice Weinberg](https://github.com/FWeinb) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs. Mbed-OS support and other improvements were contributed by [Helmut Tschemernjak](https://github.com/helmut64).\n\nThe init sequence for the SSD1306 was inspired by Adafruit's library for the same display.\n\n## mbed-os\nThis library has been adopted to support the ARM mbed-os environment. A copy of this library is available in mbed-os under the name OLED_SSD1306 by Helmut Tschemernjak. An alternate installation option is to copy the following files into your mbed-os project: OLEDDisplay.cpp OLEDDisplay.h OLEDDisplayFonts.h OLEDDisplayUi.cpp OLEDDisplayUi.h SSD1306I2C.h\n\n## Usage\n\nCheck out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the [ESP8266 Weather Station](https://github.com/ThingPulse/esp8266-weather-station) library which uses the OLED library to display beautiful weather information.\n\n## Upgrade\n\nThe API changed a lot with the 3.0 release. If you were using this library with older versions please have a look at the [Upgrade Guide](UPGRADE-3.0.md).\n\nGoing from 3.x version to 4.0 a lot of internals changed and compatibility for more displays was added. Please read the [Upgrade Guide](UPGRADE-4.0.md).\n\n## Features\n\n* Draw pixels at given coordinates\n* Draw lines from given coordinates to given coordinates\n* Draw or fill a rectangle with given dimensions\n* Draw Text at given coordinates:\n * Define Alignment: Left, Right and Center\n * Set the Fontface you want to use (see section Fonts below)\n * Limit the width of the text by an amount of pixels. Before this widths will be reached, the renderer will wrap the text to a new line if possible\n* Display content in automatically side scrolling carousel\n * Define transition cycles\n * Define how long one frame will be displayed\n * Draw the different frames in callback methods\n * One indicator per frame will be automatically displayed. The active frame will be displayed from inactive once\n\n## Fonts\n\nFonts are defined in a proprietary but open format. You can create new font files by choosing from a given list\nof open sourced Fonts from this web app: http://oleddisplay.squix.ch\nChoose the font family, style and size, check the preview image and if you like what you see click the \"Create\" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file.\n\n\n![FontTool](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/FontTool.png)\n\n## Hardware Abstraction\n\nThe library supports different protocols to access the OLED display. Currently there is support for I2C using the built in Wire.h library, I2C by using the much faster [BRZO I2C library](https://github.com/pasko-zh/brzo_i2c) written in assembler and it also supports displays which come with the SPI interface.\n\n### I2C with Wire.h\n\n```C++\n#include <Wire.h>\n#include \"SSD1306Wire.h\"\n\n// for 128x64 displays:\nSSD1306Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n// for 128x32 displays:\n// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32);  // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)\n// for using 2nd Hardware I2C (if available)\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_TWO); //default value is I2C_ONE if not mentioned\n// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency\n```\n\nfor a SH1106:\n```C++\n#include <Wire.h>\n#include \"SH1106Wire.h\"\n\nSH1106Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n// By default SH1106Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value\n// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz\n// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency\n```\n\n### I2C with brzo_i2c\n\n```C++\n#include <brzo_i2c.h>\n#include \"SSD1306Brzo.h\"\n\nSSD1306Brzo display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n```\nor for the SH1106:\n```C++\n#include <brzo_i2c.h>\n#include \"SH1106Brzo.h\"\n\nSH1106Brzo display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n```\n\n### SPI\n\n```C++\n#include <SPI.h>\n#include \"SSD1306Spi.h\"\n\nSSD1306Spi display(D0, D2, D8);  // RES, DC, CS\n```\nor for the SH1106:\n```C++\n#include <SPI.h>\n#include \"SH1106Spi.h\"\n\nSH1106Spi display(D0, D2, CS);  // RES, DC, CS\n```\n\nIn case the CS pin is not used (hard wired to ground), pass CS as -1.\n\n## API\n\n### Display Control\n\n```C++\n// Initialize the display\nvoid init();\n\n// Free the memory used by the display\nvoid end();\n\n// Cycle through the initialization\nvoid resetDisplay(void);\n\n// Connect again to the display through I2C\nvoid reconnect(void);\n\n// Turn the display on\nvoid displayOn(void);\n\n// Turn the display offs\nvoid displayOff(void);\n\n// Clear the local pixel buffer\nvoid clear(void);\n\n// Write the buffer to the display memory\nvoid display(void);\n\n// Inverted display mode\nvoid invertDisplay(void);\n\n// Normal display mode\nvoid normalDisplay(void);\n\n// Set display contrast\n// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0\n// normal brightness & contrast:  contrast = 100\nvoid setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);\n\n// Convenience method to access setContrast with only brightness parameter\nvoid setBrightness(uint8_t);\n\n// Turn the display upside down\nvoid flipScreenVertically();\n\n// Draw the screen mirrored\nvoid mirrorScreen();\n```\n\n## Pixel drawing\n\n```C++\n\n/* Drawing functions */\n// Sets the color of all pixel operations\n// color : BLACK, WHITE, INVERSE\nvoid setColor(OLEDDISPLAY_COLOR color);\n\n// Draw a pixel at given position\nvoid setPixel(int16_t x, int16_t y);\n\n// Draw a line from position 0 to position 1\nvoid drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);\n\n// Draw the border of a rectangle at the given location\nvoid drawRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n// Fill the rectangle\nvoid fillRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n// Draw the border of a circle\nvoid drawCircle(int16_t x, int16_t y, int16_t radius);\n\n// Fill circle\nvoid fillCircle(int16_t x, int16_t y, int16_t radius);\n\n// Draw an empty triangle i.e. only the outline\nvoid drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n// Draw a solid triangle i.e. filled\nvoid fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n// Draw a line horizontally\nvoid drawHorizontalLine(int16_t x, int16_t y, int16_t length);\n\n// Draw a lin vertically\nvoid drawVerticalLine(int16_t x, int16_t y, int16_t length);\n\n// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is\n// a unsigned byte value between 0 and 100\nvoid drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);\n\n// Draw a bitmap in the internal image format\nvoid drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);\n\n// Draw a XBM\nvoid drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);\n```\n\n## Text operations\n\n``` C++\n// Draws a string at the given location, returns how many chars have been written\nuint16_t drawString(int16_t x, int16_t y, const String &text);\n\n// Draws a String with a maximum width at the given location.\n// If the given String is wider than the specified width\n// The text will be wrapped to the next line at a space or dash\n// returns 0 if everything fits on the screen or the numbers of characters in the\n// first line if not\nuint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text);\n\n// Returns the width of the const char* with the current\n// font settings\nuint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false);\n\n// Convencience method for the const char version\nuint16_t getStringWidth(const String &text);\n\n// Specifies relative to which anchor point\n// the text is rendered. Available constants:\n// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH\nvoid setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);\n\n// Sets the current font. Available default fonts\n// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24\n// Or create one with the font tool at http://oleddisplay.squix.ch\nvoid setFont(const uint8_t* fontData);\n```\n\n## Arduino `Print` functionality\n\nBecause this class has been \"derived\" from Arduino's `Print` class, you can use the functions it provides. In plain language, this means that you can use `print`, `println` and `printf` to the display. Internally, a buffer holds the text that was printed to the display previously (that would still fit on the display) and every time you print something, this buffer is put on the screen, using the functions from the previous section.\n\nWhat that means is that printing using `print` and \"manually\" putting things on the display are somewhat mutually exclusive: as soon as you print, everything that was on the display already is gone and only what you put there before with `print`, `println` or `printf` remains. Still, using `print` is a very simple way to put something on the display quickly.\n\nOne extra function is provided: `cls()`\n```cpp\n// cls() will clear the display immediately and empty the logBuffer, meaning\n// the next print statement will print at the top of the display again.\n// cls() should not be confused with clear(), which only clears the internal\n// graphics buffer, which can then be shown on the display with display().\nvoid cls();\n\n> _Note that printing to the display, contrary to what you might expect, does not wrap your lines, so everything on a line that doesn't fit on the screen is cut off._\n```\n\n&nbsp;\n\n<hr>\n\n## Ui Library (OLEDDisplayUi)\n\nThe Ui Library is used to provide a basic set of user interface elements called `Frames` and `Overlays`. A `Frame` is used to provide\ninformation to the user. The default behaviour is to display a `Frame` for a defined time and than move to the next `Frame`. The library also\nprovides an `Indicator` element that will be updated accordingly. An `Overlay` on the other hand is a piece of information (e.g. a clock) that\nis always displayed at the same position.\n\n```C++\n/**\n * Initialise the display\n */\nvoid init();\n\n/**\n * Configure the internal used target FPS\n */\nvoid setTargetFPS(uint8_t fps);\n\n/**\n * Enable automatic transition to next frame after the some time can be configured with\n * `setTimePerFrame` and `setTimePerTransition`.\n */\nvoid enableAutoTransition();\n\n/**\n * Disable automatic transition to next frame.\n */\nvoid disableAutoTransition();\n\n/**\n * Set the direction if the automatic transitioning\n */\nvoid setAutoTransitionForwards();\nvoid setAutoTransitionBackwards();\n\n/**\n *  Set the approx. time a frame is displayed\n */\nvoid setTimePerFrame(uint16_t time);\n\n/**\n * Set the approx. time a transition will take\n */\nvoid setTimePerTransition(uint16_t time);\n\n/**\n * Draw the indicator.\n * This is the default state for all frames if\n * the indicator was hidden on the previous frame\n * it will be slided in.\n */\nvoid enableIndicator();\n\n/**\n * Don't draw the indicator.\n * This will slide out the indicator\n * when transitioning to the next frame.\n */\nvoid disableIndicator();\n\n/**\n * Enable drawing of all indicators.\n */\nvoid enableAllIndicators();\n\n/**\n * Disable drawing of all indicators.\n */\nvoid disableAllIndicators();\n\n/**\n * Set the position of the indicator bar.\n */\nvoid setIndicatorPosition(IndicatorPosition pos);\n\n/**\n * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING\n */\nvoid setIndicatorDirection(IndicatorDirection dir);\n\n/**\n * Set the symbol to indicate an active frame in the indicator bar.\n */\nvoid setActiveSymbol(const uint8_t* symbol);\n\n/**\n * Set the symbol to indicate an inactive frame in the indicator bar.\n */\nvoid setInactiveSymbol(const uint8_t* symbol);\n\n/**\n * Configure what animation is used to transition from one frame to another\n */\nvoid setFrameAnimation(AnimationDirection dir);\n\n/**\n * Add frame drawing functions\n */\nvoid setFrames(FrameCallback* frameFunctions, uint8_t frameCount);\n\n/**\n * Add overlays drawing functions that are draw independent of the Frames\n */\nvoid setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);\n\n/**\n * Set the function that will draw each step\n * in the loading animation\n */\nvoid setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);\n\n/**\n * Run the loading process\n */\nvoid runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);\n\n// Manual control\nvoid nextFrame();\nvoid previousFrame();\n\n/**\n * Switch without transition to frame `frame`.\n */\nvoid switchToFrame(uint8_t frame);\n\n/**\n * Transition to frame `frame`. When the `frame` number is bigger than the current\n * frame the forward animation will be used, otherwise the backwards animation is used.\n */\nvoid transitionToFrame(uint8_t frame);\n\n// State Info\nOLEDDisplayUiState* getUiState();\n\n// This needs to be called in the main loop\n// the returned value is the remaining time (in ms)\n// you have to draw after drawing to keep the frame budget.\nint8_t update();\n```\n\n## Creating and using XBM bitmaps\n\nIf you want to display your own images with this library, the best way to do this is using a bitmap.\n\nThere are two options to convert an image to a compatible bitmap:\n1. **Using Gimp.**\n   In this case exporting the bitmap in an 1-bit XBM format is sufficient.\n2. **Using a converter website.**\n   You could also use online converter services like e.g. [https://javl.github.io/image2cpp/](https://javl.github.io/image2cpp/). The uploaded image should have the same dimension as the screen (e.g. 128x64). The following output settings should be set:\n    - Draw Mode: Horizontal - 1 bit per pixel\n    - Swap bits in byte: swap checkbox should be checked.\n\nThe resulting bitmap can be put into a header file:\n```C++\nconst unsigned char epd_example [] PROGMEM = {\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ... \n    ...\n};\n```\n\nSubsequently, it can be used like this:\n```C++\ndisplay.clear();\ndisplay.drawXbm(0, 0, 128, 64, epd_example); // assuming your bitmap is 128x64\ndisplay.display();\n```\n\n## Example: SSD1306Demo\n\n### Frame 1\n![DemoFrame1](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame1.jpg)\n\nThis frame shows three things:\n * How to draw an XMB image\n * How to draw static text which is not moved by the frame transition\n * The active/inactive frame indicators\n\n### Frame 2\n![DemoFrame2](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame2.jpg)\n\nCurrently there are one fontface with three sizes included in the library: Arial 10, 16 and 24. Once the converter is published you will be able to convert any ttf font into the used format.\n\n### Frame 3\n\n![DemoFrame3](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame3.jpg)\n\nThis frame demonstrates the text alignment. The coordinates in the frame show relative to which position the texts have been rendered.\n\n### Frame 4\n\n![DemoFrame4](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame4.jpg)\n\nThis shows how to use define a maximum width after which the driver automatically wraps a word to the next line. This comes in very handy if you have longer texts to display.\n\n### SPI version\n\n![SPIVersion](https://github.com/neptune2/esp8266-oled-ssd1306/raw/master/resources/SPI_version.jpg)\n\nThis shows the code working on the SPI version of the display. See demo code for ESP8266 pins used.\n\n## Selection of projects using this library\n\n * [QRCode ESP8266](https://github.com/anunpanya/ESP8266_QRcode) (by @anunpanya)\n * [Scan I2C](https://github.com/hallard/Scan-I2C-WiFi) (by @hallard)\n * [ThingPulse Weather Station](https://github.com/ThingPulse/esp8266-weather-station)\n * [Meshtastic](https://www.meshtastic.org/) - an open source GPS communicator mesh radio\n * [OpenMQTTGateway](https://docs.openmqttgateway.com) - OpenMQTTGateway aims to unify various technologies and protocols into a single firmware. This reduces the need for multiple physical bridges and streamlines diverse technologies under the widely-used MQTT protocol.\n * [OpenAstroTracker](https://openastrotech.com) - Open source hardware and software for Astrophotography. The firmware for the mounts supports displays and uses this library to drive them.\n * Yours?\n"
  },
  {
    "path": "README_GEOMETRY_64_48.md",
    "content": "# GEOMETRY_64_48\n\nThe 64x48 geometry setting are working with the `Wire.h` and `brzo_i2c` libraries.\n\nI've tested it successfully with a WEMOS D1 mini Lite and a WEMOS OLED shield\n\nInitialization code:\n\n- Wire\n```\n#include <Wire.h>\n#include <SSD1306Wire.h>\nSSD1306Wire display(0x3c, D2, D1, GEOMETRY_64_48 ); // WEMOS OLED shield\n```\n\n- BRZO i2c\n```\n#include <SSD1306Brzo.h>\nSSD1306Brzo display(0x3c, D2, D1, GEOMETRY_64_48 ); // WEMOS OLED Shield\n```\n"
  },
  {
    "path": "UPGRADE-3.0.md",
    "content": "# Upgrade from 2.0 to 3.0\n\nWhile developing version 3.0 we made some breaking changes to the public\nAPI of this library. This document will help you update your code to work with\nversion 3.0\n\n## Font Definitions\n\nTo get better performance and a smaller font definition format, we change the memory\nlayout of the font definition format. If you are using custom fonts not included in\nthis library we updated the font generator [here](http://oleddisplay.squix.ch/#/home).\nPlease update your fonts to be working with 3.0 by selecting the respective version in the dropdown.\n\n\n## Architectural Changes\n\nTo become a more versatile library for the SSD1306 chipset we abstracted the\nhardware connection into subclasses of the base display class now called `OLEDDisplay`.\nThis library is currently shipping with three implementations:\n\n  * `SSD1306Wire` implementing the I2C protocol using the Wire Library.    \n  * `SSD1306Brzo` implementing the I2C protocol using the faster [`brzo_i2c`](https://github.com/pasko-zh/brzo_i2c) library.\n  * `SSD1306Spi` implementing the SPI protocol.\n\nTo keep backwards compatiblity with the old API `SSD1306` is an alias of `SSD1306Wire`.\nIf you are not using the UI components you don't have to change anything to keep your code working.\n\n## Name Changes\n\n[Naming things is hard](http://martinfowler.com/bliki/TwoHardThings.html), to better reflect our intention with this library\nwe changed the name of the base class to `OLEDDisplay` and the UI library accordingly to `OLEDDisplayUi`.\nAs a consequence the type definitions of all frame and overlay related functions changed.\nThis means that you have to update all your frame drawing callbacks from:\n\n```c\nbool frame1(SSD1306 *display,  SSD1306UiState* state, int x, int y);\n```\n\ntoo\n\n```c\nvoid frame1(OLEDDisplay *display,  OLEDDisplayUiState* state, int16_t x, int16_t y);\n```\n\nAnd your overlay drawing functions from:\n\n```c\nbool overlay1(SSD1306 *display,  SSD1306UiState* state);\n```\n\ntoo\n\n```c\nvoid overlay1(OLEDDisplay *display,  OLEDDisplayUiState* state);\n```\n\n## New Features\n\n### Loading Animation\n\nWhile using this library ourself we noticed a pattern emerging. We want to drawing\na loading progress while connecting to WiFi and updating weather data etc.\n\nThe simplest thing was to add the function `drawProgressBar(x, y, width,  height, progress)`\n,where `progress` is between `0` and `100`, right to the `OLEDDisplay` class.\n\nBut we didn't stop there. We added a new feature to the `OLEDDisplayUi` called `LoadingStages`.\nYou can define your loading process like this:\n\n```c++\nLoadingStage loadingStages[] = {\n  {\n    .process = \"Connect to WiFi\",\n    .callback = []() {\n      // Connect to WiFi\n    }\n  },\n  {\n    .process = \"Get time from NTP\",\n    .callback = []() {\n      // Get current time via NTP\n    }\n  }\n  // more steps\n};\n\nint LOADING_STAGES_COUNT = sizeof(loadingStages) / sizeof(LoadingStage);\n```\n\nAfter defining your array of `LoadingStages` you can then run the loading process by using\n`ui.runLoadingProcess(loadingStages, LOADING_STAGES_COUNT)`. This will give you a\nnice little loading animation you can see in the beginning of [this](https://vimeo.com/168362918)\nvideo.\n\nTo further customize this you are free to define your own `LoadingDrawFunction` like this:\n\n```c\nvoid myLoadingDraw(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {\n  display->setTextAlignment(TEXT_ALIGN_CENTER);\n  display->setFont(ArialMT_Plain_10);\n  // stage->process contains the text of the current progress e.q. \"Connect to WiFi\"\n  display->drawString(64, 18, stage->process);\n  // you could just print the current process without the progress bar\n  display->drawString(64, 28, progress);\n}\n```\n\nAfter defining a function like that, you can pass it to the Ui library by use\n`ui.setLoadingDrawFunction(myLoadingDraw)`.\n\n\n### Text Logging\n\nIt is always useful to display some text on the display without worrying to much\nwhere it goes and managing it. In 3.0 we made the `OLEDDisplay` class implement\n[`Print`](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h)\nso you can use it like you would use `Serial`. We calls this feature `LogBuffer`\nand the only thing you have to do is to define how many lines you want to display\nand how many characters there are on average on each. This is done by calling\n`setLogBuffer(lines, chars);`. If there is not enough memory the function will\nreturn false.\n\nAfter that you can draw the `LogBuffer` anywhere you want by calling `drawLogBuffer(x, y)`.\n(Note: You have to call `display()` to update the screen)\nWe made a [video](https://www.youtube.com/watch?v=8Fiss77A3TE) showing this feature in action.\n"
  },
  {
    "path": "UPGRADE-4.0.md",
    "content": "# Upgrade from 3.x to 4.0\n\nThere are changes that breaks compatibility with older versions.\n\n1. You'll have to change data type for all your binary resources such as images and fonts from\n    \n    ```c\n    const char MySymbol[] PROGMEM = {\n    ```\n    \n    to\n    \n    ```c\n    const uint8_t MySymbol[] PROGMEM = {\n    ```\n\n1. Arguments of `setContrast` from `char` to `uint8_t`\n    \n    ```c++\n    void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect);\n    ```\n    \n    to\n    \n    ```c++\n    void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect);\n    ```\n"
  },
  {
    "path": "component.mk",
    "content": "COMPONENT_ADD_INCLUDEDIRS := src\nCOMPONENT_SRCDIRS := src\nCXXFLAGS += -Wno-ignored-qualifiers\n"
  },
  {
    "path": "examples/SSD1306ClockDemo/SSD1306ClockDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n// Install https://github.com/PaulStoffregen/Time\n#include <TimeLib.h>\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106SPi.h\"\n\n// Include the UI lib\n#include \"OLEDDisplayUi.h\"\n\n// Include custom images\n#include \"images.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\nOLEDDisplayUi ui ( &display );\n\nint screenW = 128;\nint screenH = 64;\nint clockCenterX = screenW / 2;\nint clockCenterY = ((screenH - 16) / 2) + 16; // top yellow part is 16 px height\nint clockRadius = 23;\n\n// utility function for digital clock display: prints leading 0\nString twoDigits(int digits) {\n  if (digits < 10) {\n    String i = '0' + String(digits);\n    return i;\n  }\n  else {\n    return String(digits);\n  }\n}\n\nvoid clockOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {\n\n}\n\nvoid analogClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  //  ui.disableIndicator();\n\n  // Draw the clock face\n  //  display->drawCircle(clockCenterX + x, clockCenterY + y, clockRadius);\n  display->drawCircle(clockCenterX + x, clockCenterY + y, 2);\n  //\n  //hour ticks\n  for ( int z = 0; z < 360; z = z + 30 ) {\n    //Begin at 0° and stop at 360°\n    float angle = z ;\n    angle = ( angle / 57.29577951 ) ; //Convert degrees to radians\n    int x2 = ( clockCenterX + ( sin(angle) * clockRadius ) );\n    int y2 = ( clockCenterY - ( cos(angle) * clockRadius ) );\n    int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) );\n    int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) );\n    display->drawLine( x2 + x , y2 + y , x3 + x , y3 + y);\n  }\n\n  // display second hand\n  float angle = second() * 6 ;\n  angle = ( angle / 57.29577951 ) ; //Convert degrees to radians\n  int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) );\n  int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) );\n  display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);\n  //\n  // display minute hand\n  angle = minute() * 6 ;\n  angle = ( angle / 57.29577951 ) ; //Convert degrees to radians\n  x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) );\n  y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) );\n  display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);\n  //\n  // display hour hand\n  angle = hour() * 30 + int( ( minute() / 12 ) * 6 )   ;\n  angle = ( angle / 57.29577951 ) ; //Convert degrees to radians\n  x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) );\n  y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) );\n  display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);\n}\n\nvoid digitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  String timenow = String(hour()) + \":\" + twoDigits(minute()) + \":\" + twoDigits(second());\n  display->setTextAlignment(TEXT_ALIGN_CENTER);\n  display->setFont(ArialMT_Plain_24);\n  display->drawString(clockCenterX + x , clockCenterY + y, timenow );\n}\n\n// This array keeps function pointers to all frames\n// frames are the single views that slide in\nFrameCallback frames[] = { analogClockFrame, digitalClockFrame };\n\n// how many frames are there?\nint frameCount = 2;\n\n// Overlays are statically drawn on top of a frame eg. a clock\nOverlayCallback overlays[] = { clockOverlay };\nint overlaysCount = 1;\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println();\n\n  // The ESP is capable of rendering 60fps in 80Mhz mode\n  // but that won't give you much time for anything else\n  // run it in 160Mhz mode or just set it to 30 fps\n  ui.setTargetFPS(60);\n\n  // Customize the active and inactive symbol\n  ui.setActiveSymbol(activeSymbol);\n  ui.setInactiveSymbol(inactiveSymbol);\n\n  // You can change this to\n  // TOP, LEFT, BOTTOM, RIGHT\n  ui.setIndicatorPosition(TOP);\n\n  // Defines where the first frame is located in the bar.\n  ui.setIndicatorDirection(LEFT_RIGHT);\n\n  // You can change the transition that is used\n  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN\n  ui.setFrameAnimation(SLIDE_LEFT);\n\n  // Add frames\n  ui.setFrames(frames, frameCount);\n\n  // Add overlays\n  ui.setOverlays(overlays, overlaysCount);\n\n  // Initialising the UI will init the display too.\n  ui.init();\n\n  display.flipScreenVertically();\n\n  unsigned long secsSinceStart = millis();\n  // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:\n  const unsigned long seventyYears = 2208988800UL;\n  // subtract seventy years:\n  unsigned long epoch = secsSinceStart - seventyYears * SECS_PER_HOUR;\n  setTime(epoch);\n\n}\n\n\nvoid loop() {\n  int remainingTimeBudget = ui.update();\n\n  if (remainingTimeBudget > 0) {\n    // You can do some work here\n    // Don't do stuff if you are below your\n    // time budget.\n    delay(remainingTimeBudget);\n  }\n}\n"
  },
  {
    "path": "examples/SSD1306ClockDemo/images.h",
    "content": "const uint8_t activeSymbol[] PROGMEM = {\n    B00000000,\n    B00000000,\n    B00011000,\n    B00100100,\n    B01000010,\n    B01000010,\n    B00100100,\n    B00011000\n};\n\nconst uint8_t inactiveSymbol[] PROGMEM = {\n    B00000000,\n    B00000000,\n    B00000000,\n    B00000000,\n    B00011000,\n    B00011000,\n    B00000000,\n    B00000000\n};\n"
  },
  {
    "path": "examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n   Copyright (c) 2018 by Fabrice Weinberg\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106SPi.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\n// Adapted from Adafruit_SSD1306\nvoid drawLines() {\n  for (int16_t i = 0; i < display.getWidth(); i += 4) {\n    display.drawLine(0, 0, i, display.getHeight() - 1);\n    display.display();\n    delay(10);\n  }\n  for (int16_t i = 0; i < display.getHeight(); i += 4) {\n    display.drawLine(0, 0, display.getWidth() - 1, i);\n    display.display();\n    delay(10);\n  }\n  delay(250);\n\n  display.clear();\n  for (int16_t i = 0; i < display.getWidth(); i += 4) {\n    display.drawLine(0, display.getHeight() - 1, i, 0);\n    display.display();\n    delay(10);\n  }\n  for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4) {\n    display.drawLine(0, display.getHeight() - 1, display.getWidth() - 1, i);\n    display.display();\n    delay(10);\n  }\n  delay(250);\n\n  display.clear();\n  for (int16_t i = display.getWidth() - 1; i >= 0; i -= 4) {\n    display.drawLine(display.getWidth() - 1, display.getHeight() - 1, i, 0);\n    display.display();\n    delay(10);\n  }\n  for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4) {\n    display.drawLine(display.getWidth() - 1, display.getHeight() - 1, 0, i);\n    display.display();\n    delay(10);\n  }\n  delay(250);\n  display.clear();\n  for (int16_t i = 0; i < display.getHeight(); i += 4) {\n    display.drawLine(display.getWidth() - 1, 0, 0, i);\n    display.display();\n    delay(10);\n  }\n  for (int16_t i = 0; i < display.getWidth(); i += 4) {\n    display.drawLine(display.getWidth() - 1, 0, i, display.getHeight() - 1);\n    display.display();\n    delay(10);\n  }\n  delay(250);\n}\n\n// Adapted from Adafruit_SSD1306\nvoid drawRect(void) {\n  for (int16_t i = 0; i < display.getHeight() / 2; i += 2) {\n    display.drawRect(i, i, display.getWidth() - 2 * i, display.getHeight() - 2 * i);\n    display.display();\n    delay(10);\n  }\n}\n\n// Adapted from Adafruit_SSD1306\nvoid fillRect(void) {\n  uint8_t color = 1;\n  for (int16_t i = 0; i < display.getHeight() / 2; i += 3) {\n    display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors\n    display.fillRect(i, i, display.getWidth() - i * 2, display.getHeight() - i * 2);\n    display.display();\n    delay(10);\n    color++;\n  }\n  // Reset back to WHITE\n  display.setColor(WHITE);\n}\n\n// Adapted from Adafruit_SSD1306\nvoid drawCircle(void) {\n  for (int16_t i = 0; i < display.getHeight(); i += 2) {\n    display.drawCircle(display.getWidth() / 2, display.getHeight() / 2, i);\n    display.display();\n    delay(10);\n  }\n  delay(1000);\n  display.clear();\n\n  // This will draw the part of the circel in quadrant 1\n  // Quadrants are numberd like this:\n  //   0010 | 0001\n  //  ------|-----\n  //   0100 | 1000\n  //\n  display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000001);\n  display.display();\n  delay(200);\n  display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000011);\n  display.display();\n  delay(200);\n  display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000111);\n  display.display();\n  delay(200);\n  display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00001111);\n  display.display();\n}\n\nvoid printBuffer(void) {\n  // Some test data\n  const char* test[] = {\n    \"Hello\",\n    \"World\" ,\n    \"----\",\n    \"Show off\",\n    \"how\",\n    \"the log buffer\",\n    \"is\",\n    \"working.\",\n    \"Even\",\n    \"scrolling is\",\n    \"working\"\n  };\n  display.clear();\n  for (uint8_t i = 0; i < 11; i++) {\n    // Print to the screen\n    display.println(test[i]);\n    delay(500);\n  }\n}\n\nvoid setup() {\n  display.init();\n\n  // display.flipScreenVertically();\n\n  display.setContrast(255);\n\n  drawLines();\n  delay(1000);\n  display.clear();\n\n  drawRect();\n  delay(1000);\n  display.clear();\n\n  fillRect();\n  delay(1000);\n  display.clear();\n\n  drawCircle();\n  delay(1000);\n  display.clear();\n\n  printBuffer();\n  delay(1000);\n  display.clear();\n}\n\nvoid loop() { }\n"
  },
  {
    "path": "examples/SSD1306FontTryout/Dialog_plain_6.h",
    "content": "// Created by http://oleddisplay.squix.ch/ Consider a donation\n// In case of problems make sure that you are using the font file with the correct version!\nconst char Dialog_plain_6[] PROGMEM = {\n\t0x06, // Width: 6\n\t0x08, // Height: 8\n\t0x20, // First Char: 32\n\t0xE0, // Numbers of Chars: 224\n\n\t// Jump Table:\n\t0xFF, 0xFF, 0x00, 0x02,  // 32:65535\n\t0x00, 0x00, 0x02, 0x02,  // 33:0\n\t0x00, 0x02, 0x02, 0x03,  // 34:2\n\t0x00, 0x04, 0x05, 0x05,  // 35:4\n\t0x00, 0x09, 0x04, 0x04,  // 36:9\n\t0x00, 0x0D, 0x06, 0x06,  // 37:13\n\t0x00, 0x13, 0x05, 0x05,  // 38:19\n\t0x00, 0x18, 0x02, 0x02,  // 39:24\n\t0x00, 0x1A, 0x02, 0x02,  // 40:26\n\t0x00, 0x1C, 0x02, 0x02,  // 41:28\n\t0x00, 0x1E, 0x03, 0x03,  // 42:30\n\t0x00, 0x21, 0x05, 0x05,  // 43:33\n\t0x00, 0x26, 0x02, 0x02,  // 44:38\n\t0x00, 0x28, 0x02, 0x02,  // 45:40\n\t0x00, 0x2A, 0x02, 0x02,  // 46:42\n\t0x00, 0x2C, 0x02, 0x02,  // 47:44\n\t0x00, 0x2E, 0x04, 0x04,  // 48:46\n\t0x00, 0x32, 0x04, 0x04,  // 49:50\n\t0x00, 0x36, 0x04, 0x04,  // 50:54\n\t0x00, 0x3A, 0x04, 0x04,  // 51:58\n\t0x00, 0x3E, 0x04, 0x04,  // 52:62\n\t0x00, 0x42, 0x04, 0x04,  // 53:66\n\t0x00, 0x46, 0x04, 0x04,  // 54:70\n\t0x00, 0x4A, 0x04, 0x04,  // 55:74\n\t0x00, 0x4E, 0x04, 0x04,  // 56:78\n\t0x00, 0x52, 0x04, 0x04,  // 57:82\n\t0x00, 0x56, 0x02, 0x02,  // 58:86\n\t0x00, 0x58, 0x02, 0x02,  // 59:88\n\t0x00, 0x5A, 0x05, 0x05,  // 60:90\n\t0x00, 0x5F, 0x05, 0x05,  // 61:95\n\t0x00, 0x64, 0x05, 0x05,  // 62:100\n\t0x00, 0x69, 0x03, 0x03,  // 63:105\n\t0x00, 0x6C, 0x06, 0x06,  // 64:108\n\t0x00, 0x72, 0x04, 0x04,  // 65:114\n\t0x00, 0x76, 0x04, 0x04,  // 66:118\n\t0x00, 0x7A, 0x04, 0x04,  // 67:122\n\t0x00, 0x7E, 0x05, 0x05,  // 68:126\n\t0x00, 0x83, 0x04, 0x04,  // 69:131\n\t0x00, 0x87, 0x03, 0x03,  // 70:135\n\t0x00, 0x8A, 0x05, 0x05,  // 71:138\n\t0x00, 0x8F, 0x04, 0x05,  // 72:143\n\t0x00, 0x93, 0x02, 0x02,  // 73:147\n\t0x00, 0x95, 0x02, 0x02,  // 74:149\n\t0x00, 0x97, 0x04, 0x04,  // 75:151\n\t0x00, 0x9B, 0x03, 0x03,  // 76:155\n\t0x00, 0x9E, 0x05, 0x05,  // 77:158\n\t0x00, 0xA3, 0x04, 0x04,  // 78:163\n\t0x00, 0xA7, 0x05, 0x05,  // 79:167\n\t0x00, 0xAC, 0x04, 0x04,  // 80:172\n\t0x00, 0xB0, 0x05, 0x05,  // 81:176\n\t0x00, 0xB5, 0x04, 0x04,  // 82:181\n\t0x00, 0xB9, 0x04, 0x04,  // 83:185\n\t0x00, 0xBD, 0x04, 0x04,  // 84:189\n\t0x00, 0xC1, 0x04, 0x04,  // 85:193\n\t0x00, 0xC5, 0x04, 0x04,  // 86:197\n\t0x00, 0xC9, 0x06, 0x06,  // 87:201\n\t0x00, 0xCF, 0x04, 0x04,  // 88:207\n\t0x00, 0xD3, 0x04, 0x04,  // 89:211\n\t0x00, 0xD7, 0x04, 0x04,  // 90:215\n\t0x00, 0xDB, 0x02, 0x02,  // 91:219\n\t0x00, 0xDD, 0x02, 0x02,  // 92:221\n\t0x00, 0xDF, 0x02, 0x02,  // 93:223\n\t0x00, 0xE1, 0x05, 0x05,  // 94:225\n\t0x00, 0xE6, 0x03, 0x03,  // 95:230\n\t0x00, 0xE9, 0x02, 0x03,  // 96:233\n\t0x00, 0xEB, 0x04, 0x04,  // 97:235\n\t0x00, 0xEF, 0x04, 0x04,  // 98:239\n\t0x00, 0xF3, 0x03, 0x03,  // 99:243\n\t0x00, 0xF6, 0x04, 0x04,  // 100:246\n\t0x00, 0xFA, 0x04, 0x04,  // 101:250\n\t0x00, 0xFE, 0x02, 0x02,  // 102:254\n\t0x01, 0x00, 0x04, 0x04,  // 103:256\n\t0x01, 0x04, 0x04, 0x04,  // 104:260\n\t0x01, 0x08, 0x02, 0x02,  // 105:264\n\t0x01, 0x0A, 0x02, 0x02,  // 106:266\n\t0x01, 0x0C, 0x03, 0x03,  // 107:268\n\t0x01, 0x0F, 0x02, 0x02,  // 108:271\n\t0x01, 0x11, 0x06, 0x06,  // 109:273\n\t0x01, 0x17, 0x04, 0x04,  // 110:279\n\t0x01, 0x1B, 0x04, 0x04,  // 111:283\n\t0x01, 0x1F, 0x04, 0x04,  // 112:287\n\t0x01, 0x23, 0x04, 0x04,  // 113:291\n\t0x01, 0x27, 0x02, 0x02,  // 114:295\n\t0x01, 0x29, 0x03, 0x03,  // 115:297\n\t0x01, 0x2C, 0x02, 0x02,  // 116:300\n\t0x01, 0x2E, 0x04, 0x04,  // 117:302\n\t0x01, 0x32, 0x03, 0x04,  // 118:306\n\t0x01, 0x35, 0x04, 0x05,  // 119:309\n\t0x01, 0x39, 0x03, 0x04,  // 120:313\n\t0x01, 0x3C, 0x03, 0x04,  // 121:316\n\t0x01, 0x3F, 0x03, 0x03,  // 122:319\n\t0x01, 0x42, 0x04, 0x04,  // 123:322\n\t0x01, 0x46, 0x02, 0x02,  // 124:326\n\t0x01, 0x48, 0x04, 0x04,  // 125:328\n\t0x01, 0x4C, 0x05, 0x05,  // 126:332\n\t0x01, 0x51, 0x03, 0x04,  // 127:337\n\t0x01, 0x54, 0x03, 0x04,  // 128:340\n\t0x01, 0x57, 0x03, 0x04,  // 129:343\n\t0x01, 0x5A, 0x03, 0x04,  // 130:346\n\t0x01, 0x5D, 0x03, 0x04,  // 131:349\n\t0x01, 0x60, 0x03, 0x04,  // 132:352\n\t0x01, 0x63, 0x03, 0x04,  // 133:355\n\t0x01, 0x66, 0x03, 0x04,  // 134:358\n\t0x01, 0x69, 0x03, 0x04,  // 135:361\n\t0x01, 0x6C, 0x03, 0x04,  // 136:364\n\t0x01, 0x6F, 0x03, 0x04,  // 137:367\n\t0x01, 0x72, 0x03, 0x04,  // 138:370\n\t0x01, 0x75, 0x03, 0x04,  // 139:373\n\t0x01, 0x78, 0x03, 0x04,  // 140:376\n\t0x01, 0x7B, 0x03, 0x04,  // 141:379\n\t0x01, 0x7E, 0x03, 0x04,  // 142:382\n\t0x01, 0x81, 0x03, 0x04,  // 143:385\n\t0x01, 0x84, 0x03, 0x04,  // 144:388\n\t0x01, 0x87, 0x03, 0x04,  // 145:391\n\t0x01, 0x8A, 0x03, 0x04,  // 146:394\n\t0x01, 0x8D, 0x03, 0x04,  // 147:397\n\t0x01, 0x90, 0x03, 0x04,  // 148:400\n\t0x01, 0x93, 0x03, 0x04,  // 149:403\n\t0x01, 0x96, 0x03, 0x04,  // 150:406\n\t0x01, 0x99, 0x03, 0x04,  // 151:409\n\t0x01, 0x9C, 0x03, 0x04,  // 152:412\n\t0x01, 0x9F, 0x03, 0x04,  // 153:415\n\t0x01, 0xA2, 0x03, 0x04,  // 154:418\n\t0x01, 0xA5, 0x03, 0x04,  // 155:421\n\t0x01, 0xA8, 0x03, 0x04,  // 156:424\n\t0x01, 0xAB, 0x03, 0x04,  // 157:427\n\t0x01, 0xAE, 0x03, 0x04,  // 158:430\n\t0x01, 0xB1, 0x03, 0x04,  // 159:433\n\t0xFF, 0xFF, 0x00, 0x02,  // 160:65535\n\t0x01, 0xB4, 0x02, 0x02,  // 161:436\n\t0x01, 0xB6, 0x04, 0x04,  // 162:438\n\t0x01, 0xBA, 0x04, 0x04,  // 163:442\n\t0x01, 0xBE, 0x04, 0x04,  // 164:446\n\t0x01, 0xC2, 0x04, 0x04,  // 165:450\n\t0x01, 0xC6, 0x02, 0x02,  // 166:454\n\t0x01, 0xC8, 0x03, 0x03,  // 167:456\n\t0x01, 0xCB, 0x02, 0x03,  // 168:459\n\t0x01, 0xCD, 0x05, 0x06,  // 169:461\n\t0x01, 0xD2, 0x03, 0x03,  // 170:466\n\t0x01, 0xD5, 0x03, 0x04,  // 171:469\n\t0x01, 0xD8, 0x05, 0x05,  // 172:472\n\t0x01, 0xDD, 0x02, 0x02,  // 173:477\n\t0x01, 0xDF, 0x05, 0x06,  // 174:479\n\t0x01, 0xE4, 0x03, 0x03,  // 175:484\n\t0x01, 0xE7, 0x03, 0x03,  // 176:487\n\t0x01, 0xEA, 0x05, 0x05,  // 177:490\n\t0x01, 0xEF, 0x02, 0x02,  // 178:495\n\t0x01, 0xF1, 0x02, 0x02,  // 179:497\n\t0x01, 0xF3, 0x02, 0x03,  // 180:499\n\t0x01, 0xF5, 0x04, 0x04,  // 181:501\n\t0x01, 0xF9, 0x03, 0x04,  // 182:505\n\t0x01, 0xFC, 0x02, 0x02,  // 183:508\n\t0x01, 0xFE, 0x02, 0x03,  // 184:510\n\t0x02, 0x00, 0x02, 0x02,  // 185:512\n\t0x02, 0x02, 0x03, 0x03,  // 186:514\n\t0x02, 0x05, 0x03, 0x04,  // 187:517\n\t0x02, 0x08, 0x06, 0x06,  // 188:520\n\t0x02, 0x0E, 0x06, 0x06,  // 189:526\n\t0x02, 0x14, 0x06, 0x06,  // 190:532\n\t0x02, 0x1A, 0x03, 0x03,  // 191:538\n\t0x02, 0x1D, 0x04, 0x04,  // 192:541\n\t0x02, 0x21, 0x04, 0x04,  // 193:545\n\t0x02, 0x25, 0x04, 0x04,  // 194:549\n\t0x02, 0x29, 0x04, 0x04,  // 195:553\n\t0x02, 0x2D, 0x04, 0x04,  // 196:557\n\t0x02, 0x31, 0x04, 0x04,  // 197:561\n\t0x02, 0x35, 0x06, 0x06,  // 198:565\n\t0x02, 0x3B, 0x04, 0x04,  // 199:571\n\t0x02, 0x3F, 0x04, 0x04,  // 200:575\n\t0x02, 0x43, 0x04, 0x04,  // 201:579\n\t0x02, 0x47, 0x04, 0x04,  // 202:583\n\t0x02, 0x4B, 0x04, 0x04,  // 203:587\n\t0x02, 0x4F, 0x02, 0x02,  // 204:591\n\t0x02, 0x51, 0x02, 0x02,  // 205:593\n\t0x02, 0x53, 0x02, 0x02,  // 206:595\n\t0x02, 0x55, 0x02, 0x02,  // 207:597\n\t0x02, 0x57, 0x05, 0x05,  // 208:599\n\t0x02, 0x5C, 0x04, 0x04,  // 209:604\n\t0x02, 0x60, 0x05, 0x05,  // 210:608\n\t0x02, 0x65, 0x05, 0x05,  // 211:613\n\t0x02, 0x6A, 0x05, 0x05,  // 212:618\n\t0x02, 0x6F, 0x05, 0x05,  // 213:623\n\t0x02, 0x74, 0x05, 0x05,  // 214:628\n\t0x02, 0x79, 0x04, 0x05,  // 215:633\n\t0x02, 0x7D, 0x05, 0x05,  // 216:637\n\t0x02, 0x82, 0x04, 0x04,  // 217:642\n\t0x02, 0x86, 0x04, 0x04,  // 218:646\n\t0x02, 0x8A, 0x04, 0x04,  // 219:650\n\t0x02, 0x8E, 0x04, 0x04,  // 220:654\n\t0x02, 0x92, 0x04, 0x04,  // 221:658\n\t0x02, 0x96, 0x04, 0x04,  // 222:662\n\t0x02, 0x9A, 0x04, 0x04,  // 223:666\n\t0x02, 0x9E, 0x04, 0x04,  // 224:670\n\t0x02, 0xA2, 0x04, 0x04,  // 225:674\n\t0x02, 0xA6, 0x04, 0x04,  // 226:678\n\t0x02, 0xAA, 0x04, 0x04,  // 227:682\n\t0x02, 0xAE, 0x04, 0x04,  // 228:686\n\t0x02, 0xB2, 0x04, 0x04,  // 229:690\n\t0x02, 0xB6, 0x06, 0x06,  // 230:694\n\t0x02, 0xBC, 0x03, 0x03,  // 231:700\n\t0x02, 0xBF, 0x04, 0x04,  // 232:703\n\t0x02, 0xC3, 0x04, 0x04,  // 233:707\n\t0x02, 0xC7, 0x04, 0x04,  // 234:711\n\t0x02, 0xCB, 0x04, 0x04,  // 235:715\n\t0x02, 0xCF, 0x02, 0x02,  // 236:719\n\t0x02, 0xD1, 0x02, 0x02,  // 237:721\n\t0x02, 0xD3, 0x02, 0x02,  // 238:723\n\t0x02, 0xD5, 0x02, 0x02,  // 239:725\n\t0x02, 0xD7, 0x04, 0x04,  // 240:727\n\t0x02, 0xDB, 0x04, 0x04,  // 241:731\n\t0x02, 0xDF, 0x04, 0x04,  // 242:735\n\t0x02, 0xE3, 0x04, 0x04,  // 243:739\n\t0x02, 0xE7, 0x04, 0x04,  // 244:743\n\t0x02, 0xEB, 0x04, 0x04,  // 245:747\n\t0x02, 0xEF, 0x04, 0x04,  // 246:751\n\t0x02, 0xF3, 0x05, 0x05,  // 247:755\n\t0x02, 0xF8, 0x04, 0x04,  // 248:760\n\t0x02, 0xFC, 0x04, 0x04,  // 249:764\n\t0x03, 0x00, 0x04, 0x04,  // 250:768\n\t0x03, 0x04, 0x04, 0x04,  // 251:772\n\t0x03, 0x08, 0x04, 0x04,  // 252:776\n\t0x03, 0x0C, 0x03, 0x04,  // 253:780\n\t0x03, 0x0F, 0x04, 0x04,  // 254:783\n\t0x03, 0x13, 0x03, 0x04,  // 255:787\n\n\t// Font Data:\n\t0x00,0x2C,\t// 33\n\t0x00,0x0C,\t// 34\n\t0x00,0x18,0x1C,0x38,0x18,\t// 35\n\t0x00,0x2C,0x7E,0x3C,\t// 36\n\t0x00,0x0C,0x2C,0x18,0x34,0x30,\t// 37\n\t0x00,0x30,0x3C,0x34,0x30,\t// 38\n\t0x00,0x0C,\t// 39\n\t0x00,0x1C,\t// 40\n\t0x00,0x1C,\t// 41\n\t0x0C,0x0C,0x0C,\t// 42\n\t0x00,0x08,0x08,0x3E,0x08,\t// 43\n\t0x00,0x20,\t// 44\n\t0x00,0x10,\t// 45\n\t0x00,0x20,\t// 46\n\t0x70,0x1C,\t// 47\n\t0x00,0x3C,0x24,0x3C,\t// 48\n\t0x00,0x24,0x3C,0x20,\t// 49\n\t0x00,0x24,0x34,0x3C,\t// 50\n\t0x00,0x24,0x2C,0x34,\t// 51\n\t0x00,0x10,0x18,0x3C,\t// 52\n\t0x00,0x2C,0x2C,0x3C,\t// 53\n\t0x00,0x38,0x34,0x34,\t// 54\n\t0x00,0x04,0x34,0x0C,\t// 55\n\t0x00,0x34,0x2C,0x34,\t// 56\n\t0x00,0x2C,0x2C,0x1C,\t// 57\n\t0x00,0x28,\t// 58\n\t0x00,0x28,\t// 59\n\t0x00,0x08,0x08,0x1C,0x14,\t// 60\n\t0x00,0x14,0x14,0x14,0x14,\t// 61\n\t0x00,0x14,0x1C,0x08,0x08,\t// 62\n\t0x00,0x04,0x24,\t// 63\n\t0x00,0x38,0x54,0x74,0x14,0x08,\t// 64\n\t0x20,0x1C,0x1C,0x20,\t// 65\n\t0x00,0x3C,0x2C,0x34,\t// 66\n\t0x00,0x18,0x24,0x24,\t// 67\n\t0x00,0x3C,0x24,0x24,0x18,\t// 68\n\t0x00,0x3C,0x2C,0x2C,\t// 69\n\t0x00,0x3C,0x0C,\t// 70\n\t0x00,0x18,0x24,0x2C,0x3C,\t// 71\n\t0x00,0x3C,0x08,0x3C,\t// 72\n\t0x00,0x3C,\t// 73\n\t0x40,0x7C,\t// 74\n\t0x00,0x3C,0x3C,0x24,\t// 75\n\t0x00,0x3C,0x20,\t// 76\n\t0x00,0x3C,0x1C,0x0C,0x3C,\t// 77\n\t0x00,0x3C,0x1C,0x3C,\t// 78\n\t0x00,0x18,0x24,0x24,0x18,\t// 79\n\t0x00,0x3C,0x14,0x1C,\t// 80\n\t0x00,0x18,0x24,0x64,0x18,\t// 81\n\t0x00,0x3C,0x34,0x2C,\t// 82\n\t0x00,0x2C,0x2C,0x3C,\t// 83\n\t0x04,0x04,0x3C,0x04,\t// 84\n\t0x00,0x3C,0x20,0x3C,\t// 85\n\t0x04,0x38,0x38,0x04,\t// 86\n\t0x0C,0x30,0x0C,0x0C,0x30,0x0C,\t// 87\n\t0x24,0x3C,0x3C,0x24,\t// 88\n\t0x04,0x0C,0x38,0x0C,\t// 89\n\t0x00,0x24,0x3C,0x2C,\t// 90\n\t0x00,0x3E,\t// 91\n\t0x1C,0x70,\t// 92\n\t0x00,0x22,\t// 93\n\t0x00,0x08,0x04,0x04,0x08,\t// 94\n\t0x40,0x40,0x40,\t// 95\n\t0x00,0x02,\t// 96\n\t0x00,0x30,0x38,0x38,\t// 97\n\t0x00,0x3E,0x28,0x38,\t// 98\n\t0x00,0x38,0x28,\t// 99\n\t0x00,0x38,0x28,0x3E,\t// 100\n\t0x00,0x38,0x38,0x38,\t// 101\n\t0x08,0x3E,\t// 102\n\t0x00,0x78,0x68,0x78,\t// 103\n\t0x00,0x3E,0x08,0x38,\t// 104\n\t0x00,0x3A,\t// 105\n\t0x40,0x7A,\t// 106\n\t0x00,0x3E,0x38,\t// 107\n\t0x00,0x3E,\t// 108\n\t0x00,0x38,0x08,0x38,0x08,0x38,\t// 109\n\t0x00,0x38,0x08,0x38,\t// 110\n\t0x00,0x38,0x28,0x38,\t// 111\n\t0x00,0x78,0x28,0x38,\t// 112\n\t0x00,0x38,0x28,0x78,\t// 113\n\t0x00,0x38,\t// 114\n\t0x00,0x28,0x38,\t// 115\n\t0x00,0x3C,\t// 116\n\t0x00,0x38,0x20,0x38,\t// 117\n\t0x08,0x30,0x08,\t// 118\n\t0x38,0x18,0x38,0x18,\t// 119\n\t0x28,0x38,0x28,\t// 120\n\t0x68,0x30,0x08,\t// 121\n\t0x00,0x28,0x38,\t// 122\n\t0x00,0x08,0x76,0x42,\t// 123\n\t0x00,0x7E,\t// 124\n\t0x00,0x42,0x76,0x08,\t// 125\n\t0x00,0x08,0x08,0x08,0x08,\t// 126\n\t0x7C,0x44,0x7C,\t// 127\n\t0x7C,0x44,0x7C,\t// 128\n\t0x7C,0x44,0x7C,\t// 129\n\t0x7C,0x44,0x7C,\t// 130\n\t0x7C,0x44,0x7C,\t// 131\n\t0x7C,0x44,0x7C,\t// 132\n\t0x7C,0x44,0x7C,\t// 133\n\t0x7C,0x44,0x7C,\t// 134\n\t0x7C,0x44,0x7C,\t// 135\n\t0x7C,0x44,0x7C,\t// 136\n\t0x7C,0x44,0x7C,\t// 137\n\t0x7C,0x44,0x7C,\t// 138\n\t0x7C,0x44,0x7C,\t// 139\n\t0x7C,0x44,0x7C,\t// 140\n\t0x7C,0x44,0x7C,\t// 141\n\t0x7C,0x44,0x7C,\t// 142\n\t0x7C,0x44,0x7C,\t// 143\n\t0x7C,0x44,0x7C,\t// 144\n\t0x7C,0x44,0x7C,\t// 145\n\t0x7C,0x44,0x7C,\t// 146\n\t0x7C,0x44,0x7C,\t// 147\n\t0x7C,0x44,0x7C,\t// 148\n\t0x7C,0x44,0x7C,\t// 149\n\t0x7C,0x44,0x7C,\t// 150\n\t0x7C,0x44,0x7C,\t// 151\n\t0x7C,0x44,0x7C,\t// 152\n\t0x7C,0x44,0x7C,\t// 153\n\t0x7C,0x44,0x7C,\t// 154\n\t0x7C,0x44,0x7C,\t// 155\n\t0x7C,0x44,0x7C,\t// 156\n\t0x7C,0x44,0x7C,\t// 157\n\t0x7C,0x44,0x7C,\t// 158\n\t0x7C,0x44,0x7C,\t// 159\n\t0x00,0x68,\t// 161\n\t0x00,0x38,0x7C,0x28,\t// 162\n\t0x28,0x3C,0x2C,0x24,\t// 163\n\t0x00,0x38,0x28,0x38,\t// 164\n\t0x00,0x2C,0x38,0x2C,\t// 165\n\t0x00,0x6C,\t// 166\n\t0x00,0x5C,0x74,\t// 167\n\t0x00,0x02,\t// 168\n\t0x00,0x18,0x24,0x3C,0x18,\t// 169\n\t0x00,0x2C,0x2C,\t// 170\n\t0x00,0x10,0x10,\t// 171\n\t0x00,0x08,0x08,0x08,0x18,\t// 172\n\t0x00,0x10,\t// 173\n\t0x00,0x18,0x34,0x34,0x18,\t// 174\n\t0x00,0x04,0x04,\t// 175\n\t0x00,0x0C,0x0C,\t// 176\n\t0x28,0x28,0x3C,0x28,0x28,\t// 177\n\t0x00,0x0C,\t// 178\n\t0x00,0x0C,\t// 179\n\t0x00,0x02,\t// 180\n\t0x00,0x78,0x20,0x38,\t// 181\n\t0x7C,0x04,0x7C,\t// 182\n\t0x00,0x10,\t// 183\n\t0x00,0x40,\t// 184\n\t0x00,0x0C,\t// 185\n\t0x00,0x2C,0x2C,\t// 186\n\t0x00,0x10,0x10,\t// 187\n\t0x00,0x2C,0x1C,0x0C,0x20,0x30,\t// 188\n\t0x00,0x2C,0x1C,0x0C,0x30,0x30,\t// 189\n\t0x00,0x2C,0x18,0x04,0x20,0x30,\t// 190\n\t0x00,0x48,0x40,\t// 191\n\t0x20,0x1C,0x1D,0x21,\t// 192\n\t0x20,0x1C,0x1D,0x20,\t// 193\n\t0x20,0x1D,0x1D,0x20,\t// 194\n\t0x20,0x1D,0x1D,0x20,\t// 195\n\t0x20,0x1D,0x1D,0x20,\t// 196\n\t0x20,0x1E,0x1A,0x20,\t// 197\n\t0x20,0x18,0x14,0x3C,0x2C,0x2C,\t// 198\n\t0x00,0x18,0x64,0x24,\t// 199\n\t0x00,0x3D,0x2D,0x2C,\t// 200\n\t0x00,0x3D,0x2C,0x2C,\t// 201\n\t0x00,0x3D,0x2D,0x2C,\t// 202\n\t0x00,0x3D,0x2C,0x2D,\t// 203\n\t0x01,0x3D,\t// 204\n\t0x01,0x3C,\t// 205\n\t0x01,0x3D,\t// 206\n\t0x01,0x3C,\t// 207\n\t0x10,0x3C,0x34,0x24,0x18,\t// 208\n\t0x00,0x3C,0x1D,0x3C,\t// 209\n\t0x00,0x18,0x25,0x25,0x18,\t// 210\n\t0x00,0x18,0x25,0x24,0x18,\t// 211\n\t0x00,0x18,0x25,0x25,0x18,\t// 212\n\t0x00,0x18,0x25,0x25,0x18,\t// 213\n\t0x00,0x19,0x24,0x24,0x19,\t// 214\n\t0x00,0x14,0x1C,0x14,\t// 215\n\t0x00,0x3C,0x34,0x2C,0x3C,\t// 216\n\t0x00,0x3C,0x21,0x3D,\t// 217\n\t0x00,0x3C,0x21,0x3C,\t// 218\n\t0x00,0x3C,0x20,0x3C,\t// 219\n\t0x00,0x3D,0x20,0x3D,\t// 220\n\t0x04,0x0D,0x38,0x0C,\t// 221\n\t0x00,0x3C,0x28,0x38,\t// 222\n\t0x00,0x3E,0x0A,0x36,\t// 223\n\t0x00,0x32,0x38,0x38,\t// 224\n\t0x00,0x32,0x38,0x38,\t// 225\n\t0x00,0x30,0x38,0x38,\t// 226\n\t0x00,0x30,0x3A,0x38,\t// 227\n\t0x00,0x32,0x38,0x3A,\t// 228\n\t0x00,0x30,0x3B,0x3B,\t// 229\n\t0x00,0x30,0x38,0x10,0x38,0x38,\t// 230\n\t0x00,0x78,0x28,\t// 231\n\t0x00,0x3A,0x38,0x38,\t// 232\n\t0x00,0x3A,0x38,0x38,\t// 233\n\t0x00,0x3A,0x3A,0x38,\t// 234\n\t0x00,0x3A,0x38,0x3A,\t// 235\n\t0x02,0x38,\t// 236\n\t0x02,0x38,\t// 237\n\t0x02,0x3A,\t// 238\n\t0x02,0x38,\t// 239\n\t0x00,0x38,0x2E,0x3C,\t// 240\n\t0x02,0x3A,0x08,0x38,\t// 241\n\t0x00,0x3A,0x28,0x38,\t// 242\n\t0x00,0x3A,0x28,0x38,\t// 243\n\t0x00,0x38,0x28,0x38,\t// 244\n\t0x00,0x38,0x2A,0x38,\t// 245\n\t0x00,0x3A,0x28,0x3A,\t// 246\n\t0x00,0x08,0x08,0x1C,0x08,\t// 247\n\t0x00,0x38,0x38,0x38,\t// 248\n\t0x00,0x3A,0x20,0x38,\t// 249\n\t0x00,0x3A,0x20,0x38,\t// 250\n\t0x00,0x38,0x20,0x38,\t// 251\n\t0x00,0x3A,0x20,0x3A,\t// 252\n\t0x68,0x32,0x08,\t// 253\n\t0x00,0x7E,0x28,0x38,\t// 254\n\t0x68,0x32,0x0A\t// 255\n};"
  },
  {
    "path": "examples/SSD1306FontTryout/Dialog_plain_7.h",
    "content": "// Created by http://oleddisplay.squix.ch/ Consider a donation\n// In case of problems make sure that you are using the font file with the correct version!\nconst char Dialog_plain_7[] PROGMEM = {\n\t0x07, // Width: 7\n\t0x09, // Height: 9\n\t0x20, // First Char: 32\n\t0xE0, // Numbers of Chars: 224\n\n\t// Jump Table:\n\t0xFF, 0xFF, 0x00, 0x02,  // 32:65535\n\t0x00, 0x00, 0x03, 0x03,  // 33:0\n\t0x00, 0x03, 0x03, 0x03,  // 34:3\n\t0x00, 0x06, 0x0B, 0x06,  // 35:6\n\t0x00, 0x11, 0x07, 0x04,  // 36:17\n\t0x00, 0x18, 0x0D, 0x07,  // 37:24\n\t0x00, 0x25, 0x09, 0x05,  // 38:37\n\t0x00, 0x2E, 0x03, 0x02,  // 39:46\n\t0x00, 0x31, 0x05, 0x03,  // 40:49\n\t0x00, 0x36, 0x05, 0x03,  // 41:54\n\t0x00, 0x3B, 0x07, 0x04,  // 42:59\n\t0x00, 0x42, 0x0B, 0x06,  // 43:66\n\t0x00, 0x4D, 0x03, 0x02,  // 44:77\n\t0x00, 0x50, 0x05, 0x03,  // 45:80\n\t0x00, 0x55, 0x03, 0x02,  // 46:85\n\t0x00, 0x58, 0x03, 0x02,  // 47:88\n\t0x00, 0x5B, 0x07, 0x04,  // 48:91\n\t0x00, 0x62, 0x07, 0x04,  // 49:98\n\t0x00, 0x69, 0x07, 0x04,  // 50:105\n\t0x00, 0x70, 0x07, 0x04,  // 51:112\n\t0x00, 0x77, 0x07, 0x04,  // 52:119\n\t0x00, 0x7E, 0x07, 0x04,  // 53:126\n\t0x00, 0x85, 0x07, 0x04,  // 54:133\n\t0x00, 0x8C, 0x07, 0x04,  // 55:140\n\t0x00, 0x93, 0x07, 0x04,  // 56:147\n\t0x00, 0x9A, 0x07, 0x04,  // 57:154\n\t0x00, 0xA1, 0x03, 0x02,  // 58:161\n\t0x00, 0xA4, 0x03, 0x02,  // 59:164\n\t0x00, 0xA7, 0x09, 0x06,  // 60:167\n\t0x00, 0xB0, 0x09, 0x06,  // 61:176\n\t0x00, 0xB9, 0x09, 0x06,  // 62:185\n\t0x00, 0xC2, 0x07, 0x04,  // 63:194\n\t0x00, 0xC9, 0x0D, 0x07,  // 64:201\n\t0x00, 0xD6, 0x09, 0x05,  // 65:214\n\t0x00, 0xDF, 0x09, 0x05,  // 66:223\n\t0x00, 0xE8, 0x09, 0x05,  // 67:232\n\t0x00, 0xF1, 0x09, 0x05,  // 68:241\n\t0x00, 0xFA, 0x07, 0x04,  // 69:250\n\t0x01, 0x01, 0x07, 0x04,  // 70:257\n\t0x01, 0x08, 0x09, 0x05,  // 71:264\n\t0x01, 0x11, 0x09, 0x05,  // 72:273\n\t0x01, 0x1A, 0x03, 0x02,  // 73:282\n\t0x01, 0x1D, 0x03, 0x02,  // 74:285\n\t0x01, 0x20, 0x09, 0x05,  // 75:288\n\t0x01, 0x29, 0x07, 0x04,  // 76:297\n\t0x01, 0x30, 0x0B, 0x06,  // 77:304\n\t0x01, 0x3B, 0x09, 0x05,  // 78:315\n\t0x01, 0x44, 0x09, 0x06,  // 79:324\n\t0x01, 0x4D, 0x07, 0x04,  // 80:333\n\t0x01, 0x54, 0x09, 0x06,  // 81:340\n\t0x01, 0x5D, 0x09, 0x05,  // 82:349\n\t0x01, 0x66, 0x07, 0x04,  // 83:358\n\t0x01, 0x6D, 0x07, 0x04,  // 84:365\n\t0x01, 0x74, 0x09, 0x05,  // 85:372\n\t0x01, 0x7D, 0x09, 0x05,  // 86:381\n\t0x01, 0x86, 0x0B, 0x07,  // 87:390\n\t0x01, 0x91, 0x07, 0x04,  // 88:401\n\t0x01, 0x98, 0x07, 0x04,  // 89:408\n\t0x01, 0x9F, 0x09, 0x05,  // 90:415\n\t0x01, 0xA8, 0x05, 0x03,  // 91:424\n\t0x01, 0xAD, 0x03, 0x02,  // 92:429\n\t0x01, 0xB0, 0x05, 0x03,  // 93:432\n\t0x01, 0xB5, 0x09, 0x06,  // 94:437\n\t0x01, 0xBE, 0x08, 0x04,  // 95:446\n\t0x01, 0xC6, 0x01, 0x04,  // 96:454\n\t0x01, 0xC7, 0x07, 0x04,  // 97:455\n\t0x01, 0xCE, 0x07, 0x04,  // 98:462\n\t0x01, 0xD5, 0x07, 0x04,  // 99:469\n\t0x01, 0xDC, 0x07, 0x04,  // 100:476\n\t0x01, 0xE3, 0x07, 0x04,  // 101:483\n\t0x01, 0xEA, 0x03, 0x02,  // 102:490\n\t0x01, 0xED, 0x07, 0x04,  // 103:493\n\t0x01, 0xF4, 0x07, 0x04,  // 104:500\n\t0x01, 0xFB, 0x03, 0x02,  // 105:507\n\t0x01, 0xFE, 0x03, 0x02,  // 106:510\n\t0x02, 0x01, 0x07, 0x04,  // 107:513\n\t0x02, 0x08, 0x03, 0x02,  // 108:520\n\t0x02, 0x0B, 0x0B, 0x07,  // 109:523\n\t0x02, 0x16, 0x07, 0x04,  // 110:534\n\t0x02, 0x1D, 0x07, 0x04,  // 111:541\n\t0x02, 0x24, 0x07, 0x04,  // 112:548\n\t0x02, 0x2B, 0x07, 0x04,  // 113:555\n\t0x02, 0x32, 0x05, 0x03,  // 114:562\n\t0x02, 0x37, 0x07, 0x04,  // 115:567\n\t0x02, 0x3E, 0x05, 0x03,  // 116:574\n\t0x02, 0x43, 0x07, 0x04,  // 117:579\n\t0x02, 0x4A, 0x07, 0x04,  // 118:586\n\t0x02, 0x51, 0x09, 0x06,  // 119:593\n\t0x02, 0x5A, 0x07, 0x04,  // 120:602\n\t0x02, 0x61, 0x07, 0x04,  // 121:609\n\t0x02, 0x68, 0x07, 0x04,  // 122:616\n\t0x02, 0x6F, 0x07, 0x04,  // 123:623\n\t0x02, 0x76, 0x04, 0x02,  // 124:630\n\t0x02, 0x7A, 0x07, 0x04,  // 125:634\n\t0x02, 0x81, 0x09, 0x06,  // 126:641\n\t0x02, 0x8A, 0x07, 0x04,  // 127:650\n\t0x02, 0x91, 0x07, 0x04,  // 128:657\n\t0x02, 0x98, 0x07, 0x04,  // 129:664\n\t0x02, 0x9F, 0x07, 0x04,  // 130:671\n\t0x02, 0xA6, 0x07, 0x04,  // 131:678\n\t0x02, 0xAD, 0x07, 0x04,  // 132:685\n\t0x02, 0xB4, 0x07, 0x04,  // 133:692\n\t0x02, 0xBB, 0x07, 0x04,  // 134:699\n\t0x02, 0xC2, 0x07, 0x04,  // 135:706\n\t0x02, 0xC9, 0x07, 0x04,  // 136:713\n\t0x02, 0xD0, 0x07, 0x04,  // 137:720\n\t0x02, 0xD7, 0x07, 0x04,  // 138:727\n\t0x02, 0xDE, 0x07, 0x04,  // 139:734\n\t0x02, 0xE5, 0x07, 0x04,  // 140:741\n\t0x02, 0xEC, 0x07, 0x04,  // 141:748\n\t0x02, 0xF3, 0x07, 0x04,  // 142:755\n\t0x02, 0xFA, 0x07, 0x04,  // 143:762\n\t0x03, 0x01, 0x07, 0x04,  // 144:769\n\t0x03, 0x08, 0x07, 0x04,  // 145:776\n\t0x03, 0x0F, 0x07, 0x04,  // 146:783\n\t0x03, 0x16, 0x07, 0x04,  // 147:790\n\t0x03, 0x1D, 0x07, 0x04,  // 148:797\n\t0x03, 0x24, 0x07, 0x04,  // 149:804\n\t0x03, 0x2B, 0x07, 0x04,  // 150:811\n\t0x03, 0x32, 0x07, 0x04,  // 151:818\n\t0x03, 0x39, 0x07, 0x04,  // 152:825\n\t0x03, 0x40, 0x07, 0x04,  // 153:832\n\t0x03, 0x47, 0x07, 0x04,  // 154:839\n\t0x03, 0x4E, 0x07, 0x04,  // 155:846\n\t0x03, 0x55, 0x07, 0x04,  // 156:853\n\t0x03, 0x5C, 0x07, 0x04,  // 157:860\n\t0x03, 0x63, 0x07, 0x04,  // 158:867\n\t0x03, 0x6A, 0x07, 0x04,  // 159:874\n\t0xFF, 0xFF, 0x00, 0x02,  // 160:65535\n\t0x03, 0x71, 0x03, 0x03,  // 161:881\n\t0x03, 0x74, 0x07, 0x04,  // 162:884\n\t0x03, 0x7B, 0x07, 0x04,  // 163:891\n\t0x03, 0x82, 0x07, 0x04,  // 164:898\n\t0x03, 0x89, 0x07, 0x04,  // 165:905\n\t0x03, 0x90, 0x04, 0x02,  // 166:912\n\t0x03, 0x94, 0x07, 0x04,  // 167:916\n\t0x03, 0x9B, 0x07, 0x04,  // 168:923\n\t0x03, 0xA2, 0x0B, 0x07,  // 169:930\n\t0x03, 0xAD, 0x05, 0x03,  // 170:941\n\t0x03, 0xB2, 0x07, 0x04,  // 171:946\n\t0x03, 0xB9, 0x09, 0x06,  // 172:953\n\t0x03, 0xC2, 0x05, 0x03,  // 173:962\n\t0x03, 0xC7, 0x0B, 0x07,  // 174:967\n\t0x03, 0xD2, 0x05, 0x04,  // 175:978\n\t0x03, 0xD7, 0x05, 0x04,  // 176:983\n\t0x03, 0xDC, 0x0B, 0x06,  // 177:988\n\t0x03, 0xE7, 0x05, 0x03,  // 178:999\n\t0x03, 0xEC, 0x05, 0x03,  // 179:1004\n\t0x03, 0xF1, 0x03, 0x04,  // 180:1009\n\t0x03, 0xF4, 0x07, 0x04,  // 181:1012\n\t0x03, 0xFB, 0x07, 0x04,  // 182:1019\n\t0x04, 0x02, 0x03, 0x02,  // 183:1026\n\t0x04, 0x05, 0x03, 0x04,  // 184:1029\n\t0x04, 0x08, 0x05, 0x03,  // 185:1032\n\t0x04, 0x0D, 0x05, 0x03,  // 186:1037\n\t0x04, 0x12, 0x07, 0x04,  // 187:1042\n\t0x04, 0x19, 0x0D, 0x07,  // 188:1049\n\t0x04, 0x26, 0x0D, 0x07,  // 189:1062\n\t0x04, 0x33, 0x0D, 0x07,  // 190:1075\n\t0x04, 0x40, 0x07, 0x04,  // 191:1088\n\t0x04, 0x47, 0x09, 0x05,  // 192:1095\n\t0x04, 0x50, 0x09, 0x05,  // 193:1104\n\t0x04, 0x59, 0x09, 0x05,  // 194:1113\n\t0x04, 0x62, 0x09, 0x05,  // 195:1122\n\t0x04, 0x6B, 0x09, 0x05,  // 196:1131\n\t0x04, 0x74, 0x09, 0x05,  // 197:1140\n\t0x04, 0x7D, 0x0B, 0x07,  // 198:1149\n\t0x04, 0x88, 0x09, 0x05,  // 199:1160\n\t0x04, 0x91, 0x07, 0x04,  // 200:1169\n\t0x04, 0x98, 0x07, 0x04,  // 201:1176\n\t0x04, 0x9F, 0x07, 0x04,  // 202:1183\n\t0x04, 0xA6, 0x07, 0x04,  // 203:1190\n\t0x04, 0xAD, 0x03, 0x02,  // 204:1197\n\t0x04, 0xB0, 0x03, 0x02,  // 205:1200\n\t0x04, 0xB3, 0x03, 0x02,  // 206:1203\n\t0x04, 0xB6, 0x03, 0x02,  // 207:1206\n\t0x04, 0xB9, 0x09, 0x05,  // 208:1209\n\t0x04, 0xC2, 0x09, 0x05,  // 209:1218\n\t0x04, 0xCB, 0x09, 0x06,  // 210:1227\n\t0x04, 0xD4, 0x09, 0x06,  // 211:1236\n\t0x04, 0xDD, 0x09, 0x06,  // 212:1245\n\t0x04, 0xE6, 0x09, 0x06,  // 213:1254\n\t0x04, 0xEF, 0x09, 0x06,  // 214:1263\n\t0x04, 0xF8, 0x09, 0x06,  // 215:1272\n\t0x05, 0x01, 0x09, 0x06,  // 216:1281\n\t0x05, 0x0A, 0x09, 0x05,  // 217:1290\n\t0x05, 0x13, 0x09, 0x05,  // 218:1299\n\t0x05, 0x1C, 0x09, 0x05,  // 219:1308\n\t0x05, 0x25, 0x09, 0x05,  // 220:1317\n\t0x05, 0x2E, 0x07, 0x04,  // 221:1326\n\t0x05, 0x35, 0x07, 0x04,  // 222:1333\n\t0x05, 0x3C, 0x07, 0x04,  // 223:1340\n\t0x05, 0x43, 0x07, 0x04,  // 224:1347\n\t0x05, 0x4A, 0x07, 0x04,  // 225:1354\n\t0x05, 0x51, 0x07, 0x04,  // 226:1361\n\t0x05, 0x58, 0x07, 0x04,  // 227:1368\n\t0x05, 0x5F, 0x07, 0x04,  // 228:1375\n\t0x05, 0x66, 0x07, 0x04,  // 229:1382\n\t0x05, 0x6D, 0x0B, 0x07,  // 230:1389\n\t0x05, 0x78, 0x07, 0x04,  // 231:1400\n\t0x05, 0x7F, 0x07, 0x04,  // 232:1407\n\t0x05, 0x86, 0x07, 0x04,  // 233:1414\n\t0x05, 0x8D, 0x07, 0x04,  // 234:1421\n\t0x05, 0x94, 0x07, 0x04,  // 235:1428\n\t0x05, 0x9B, 0x03, 0x02,  // 236:1435\n\t0x05, 0x9E, 0x03, 0x02,  // 237:1438\n\t0x05, 0xA1, 0x03, 0x02,  // 238:1441\n\t0x05, 0xA4, 0x03, 0x02,  // 239:1444\n\t0x05, 0xA7, 0x07, 0x04,  // 240:1447\n\t0x05, 0xAE, 0x07, 0x04,  // 241:1454\n\t0x05, 0xB5, 0x07, 0x04,  // 242:1461\n\t0x05, 0xBC, 0x07, 0x04,  // 243:1468\n\t0x05, 0xC3, 0x07, 0x04,  // 244:1475\n\t0x05, 0xCA, 0x07, 0x04,  // 245:1482\n\t0x05, 0xD1, 0x07, 0x04,  // 246:1489\n\t0x05, 0xD8, 0x0B, 0x06,  // 247:1496\n\t0x05, 0xE3, 0x07, 0x04,  // 248:1507\n\t0x05, 0xEA, 0x07, 0x04,  // 249:1514\n\t0x05, 0xF1, 0x07, 0x04,  // 250:1521\n\t0x05, 0xF8, 0x07, 0x04,  // 251:1528\n\t0x05, 0xFF, 0x07, 0x04,  // 252:1535\n\t0x06, 0x06, 0x07, 0x04,  // 253:1542\n\t0x06, 0x0D, 0x07, 0x04,  // 254:1549\n\t0x06, 0x14, 0x07, 0x04,  // 255:1556\n\n\t// Font Data:\n\t0x00,0x00,0x5C,\t// 33\n\t0x00,0x00,0x0C,\t// 34\n\t0x00,0x00,0x28,0x00,0x7C,0x00,0x68,0x00,0x3C,0x00,0x28,\t// 35\n\t0x00,0x00,0x5C,0x00,0xFE,0x00,0x74,\t// 36\n\t0x00,0x00,0x1C,0x00,0x5C,0x00,0x30,0x00,0x18,0x00,0x74,0x00,0x70,\t// 37\n\t0x00,0x00,0x30,0x00,0x5C,0x00,0x74,0x00,0x64,\t// 38\n\t0x00,0x00,0x0C,\t// 39\n\t0x00,0x00,0x3C,0x00,0x42,\t// 40\n\t0x00,0x00,0x42,0x00,0x3C,\t// 41\n\t0x00,0x00,0x28,0x00,0x3C,0x00,0x28,\t// 42\n\t0x00,0x00,0x10,0x00,0x10,0x00,0x7C,0x00,0x10,0x00,0x10,\t// 43\n\t0x00,0x00,0xC0,\t// 44\n\t0x00,0x00,0x10,0x00,0x10,\t// 45\n\t0x00,0x00,0x40,\t// 46\n\t0xE0,0x00,0x1C,\t// 47\n\t0x00,0x00,0x7C,0x00,0x44,0x00,0x7C,\t// 48\n\t0x00,0x00,0x44,0x00,0x7C,0x00,0x40,\t// 49\n\t0x00,0x00,0x44,0x00,0x64,0x00,0x5C,\t// 50\n\t0x00,0x00,0x44,0x00,0x54,0x00,0x6C,\t// 51\n\t0x00,0x00,0x20,0x00,0x38,0x00,0x7C,\t// 52\n\t0x00,0x00,0x5C,0x00,0x54,0x00,0x74,\t// 53\n\t0x00,0x00,0x78,0x00,0x54,0x00,0x74,\t// 54\n\t0x00,0x00,0x04,0x00,0x64,0x00,0x1C,\t// 55\n\t0x00,0x00,0x6C,0x00,0x54,0x00,0x6C,\t// 56\n\t0x00,0x00,0x5C,0x00,0x54,0x00,0x3C,\t// 57\n\t0x00,0x00,0x48,\t// 58\n\t0x00,0x00,0xC8,\t// 59\n\t0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x48,\t// 60\n\t0x00,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,\t// 61\n\t0x00,0x00,0x48,0x00,0x30,0x00,0x30,0x00,0x30,\t// 62\n\t0x00,0x00,0x04,0x00,0x54,0x00,0x0C,\t// 63\n\t0x00,0x00,0x78,0x00,0xCC,0x00,0xB4,0x00,0xB4,0x00,0x24,0x00,0x18,\t// 64\n\t0x40,0x00,0x38,0x00,0x2C,0x00,0x38,0x00,0x40,\t// 65\n\t0x00,0x00,0x7C,0x00,0x54,0x00,0x54,0x00,0x6C,\t// 66\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,\t// 67\n\t0x00,0x00,0x7C,0x00,0x44,0x00,0x44,0x00,0x38,\t// 68\n\t0x00,0x00,0x7C,0x00,0x54,0x00,0x54,\t// 69\n\t0x00,0x00,0x7C,0x00,0x14,0x00,0x14,\t// 70\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x54,0x00,0x74,\t// 71\n\t0x00,0x00,0x7C,0x00,0x10,0x00,0x10,0x00,0x7C,\t// 72\n\t0x00,0x00,0x7C,\t// 73\n\t0x80,0x00,0xFC,\t// 74\n\t0x00,0x00,0x7C,0x00,0x38,0x00,0x64,0x00,0x40,\t// 75\n\t0x00,0x00,0x7C,0x00,0x40,0x00,0x40,\t// 76\n\t0x00,0x00,0x7C,0x00,0x0C,0x00,0x30,0x00,0x0C,0x00,0x7C,\t// 77\n\t0x00,0x00,0x7C,0x00,0x1C,0x00,0x30,0x00,0x7C,\t// 78\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x38,\t// 79\n\t0x00,0x00,0x7C,0x00,0x14,0x00,0x1C,\t// 80\n\t0x00,0x00,0x38,0x00,0x44,0x00,0xC4,0x00,0x38,\t// 81\n\t0x00,0x00,0x7C,0x00,0x14,0x00,0x6C,0x00,0x40,\t// 82\n\t0x00,0x00,0x4C,0x00,0x54,0x00,0x54,\t// 83\n\t0x04,0x00,0x04,0x00,0x7C,0x00,0x04,\t// 84\n\t0x00,0x00,0x3C,0x00,0x40,0x00,0x40,0x00,0x3C,\t// 85\n\t0x04,0x00,0x38,0x00,0x60,0x00,0x38,0x00,0x04,\t// 86\n\t0x0C,0x00,0x70,0x00,0x1C,0x00,0x1C,0x00,0x70,0x00,0x0C,\t// 87\n\t0x44,0x00,0x38,0x00,0x38,0x00,0x44,\t// 88\n\t0x04,0x00,0x0C,0x00,0x70,0x00,0x0C,\t// 89\n\t0x00,0x00,0x44,0x00,0x74,0x00,0x5C,0x00,0x44,\t// 90\n\t0x00,0x00,0xFC,0x00,0x84,\t// 91\n\t0x1C,0x00,0xE0,\t// 92\n\t0x00,0x00,0x84,0x00,0xFC,\t// 93\n\t0x00,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x08,\t// 94\n\t0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,\t// 95\n\t0x02,\t// 96\n\t0x00,0x00,0x60,0x00,0x68,0x00,0x78,\t// 97\n\t0x00,0x00,0x7E,0x00,0x48,0x00,0x78,\t// 98\n\t0x00,0x00,0x30,0x00,0x48,0x00,0x48,\t// 99\n\t0x00,0x00,0x78,0x00,0x48,0x00,0x7E,\t// 100\n\t0x00,0x00,0x78,0x00,0x58,0x00,0x58,\t// 101\n\t0x08,0x00,0x7E,\t// 102\n\t0x00,0x00,0xF8,0x00,0xC8,0x00,0xF8,\t// 103\n\t0x00,0x00,0x7E,0x00,0x08,0x00,0x78,\t// 104\n\t0x00,0x00,0x7C,\t// 105\n\t0x80,0x00,0xFC,\t// 106\n\t0x00,0x00,0x7E,0x00,0x78,0x00,0x48,\t// 107\n\t0x00,0x00,0x7E,\t// 108\n\t0x00,0x00,0x78,0x00,0x08,0x00,0x78,0x00,0x08,0x00,0x78,\t// 109\n\t0x00,0x00,0x78,0x00,0x08,0x00,0x78,\t// 110\n\t0x00,0x00,0x78,0x00,0x48,0x00,0x78,\t// 111\n\t0x00,0x00,0xF8,0x00,0x48,0x00,0x78,\t// 112\n\t0x00,0x00,0x78,0x00,0x48,0x00,0xF8,\t// 113\n\t0x00,0x00,0x78,0x00,0x08,\t// 114\n\t0x00,0x00,0x58,0x00,0x58,0x00,0x68,\t// 115\n\t0x00,0x00,0x7C,0x00,0x48,\t// 116\n\t0x00,0x00,0x78,0x00,0x40,0x00,0x78,\t// 117\n\t0x08,0x00,0x70,0x00,0x70,0x00,0x08,\t// 118\n\t0x18,0x00,0x70,0x00,0x08,0x00,0x70,0x00,0x18,\t// 119\n\t0x48,0x00,0x78,0x00,0x78,0x00,0x48,\t// 120\n\t0x88,0x00,0xF0,0x00,0x30,0x00,0x08,\t// 121\n\t0x00,0x00,0x48,0x00,0x78,0x00,0x58,\t// 122\n\t0x00,0x00,0x10,0x00,0xEC,0x00,0x84,\t// 123\n\t0x00,0x00,0xFC,0x01,\t// 124\n\t0x00,0x00,0x84,0x00,0xEC,0x00,0x10,\t// 125\n\t0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,\t// 126\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 127\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 128\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 129\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 130\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 131\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 132\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 133\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 134\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 135\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 136\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 137\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 138\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 139\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 140\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 141\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 142\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 143\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 144\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 145\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 146\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 147\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 148\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 149\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 150\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 151\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 152\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 153\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 154\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 155\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 156\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 157\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 158\n\t0xFC,0x00,0x84,0x00,0x84,0x00,0xFC,\t// 159\n\t0x00,0x00,0xE8,\t// 161\n\t0x00,0x00,0x78,0x00,0xFC,0x00,0x48,\t// 162\n\t0x50,0x00,0x7C,0x00,0x54,0x00,0x44,\t// 163\n\t0x00,0x00,0x38,0x00,0x28,0x00,0x38,\t// 164\n\t0x00,0x00,0x2C,0x00,0x70,0x00,0x2C,\t// 165\n\t0x00,0x00,0xDC,0x01,\t// 166\n\t0x00,0x00,0xBC,0x00,0xB4,0x00,0xF4,\t// 167\n\t0x00,0x00,0x04,0x00,0x00,0x00,0x04,\t// 168\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x54,0x00,0x44,0x00,0x38,\t// 169\n\t0x00,0x00,0x58,0x00,0x5C,\t// 170\n\t0x00,0x00,0x10,0x00,0x38,0x00,0x10,\t// 171\n\t0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x30,\t// 172\n\t0x00,0x00,0x10,0x00,0x10,\t// 173\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x74,0x00,0x44,0x00,0x38,\t// 174\n\t0x00,0x00,0x04,0x00,0x04,\t// 175\n\t0x00,0x00,0x0C,0x00,0x0C,\t// 176\n\t0x00,0x00,0x50,0x00,0x50,0x00,0x78,0x00,0x50,0x00,0x50,\t// 177\n\t0x00,0x00,0x14,0x00,0x1C,\t// 178\n\t0x00,0x00,0x1C,0x00,0x14,\t// 179\n\t0x00,0x00,0x02,\t// 180\n\t0x00,0x00,0xF8,0x00,0x40,0x00,0x78,\t// 181\n\t0x00,0x00,0xFC,0x00,0x04,0x00,0xFC,\t// 182\n\t0x00,0x00,0x10,\t// 183\n\t0x00,0x00,0x80,\t// 184\n\t0x00,0x00,0x14,0x00,0x1C,\t// 185\n\t0x00,0x00,0x5C,0x00,0x54,\t// 186\n\t0x00,0x00,0x38,0x00,0x10,0x00,0x38,\t// 187\n\t0x00,0x00,0x14,0x00,0x5C,0x00,0x30,0x00,0x18,0x00,0x64,0x00,0x70,\t// 188\n\t0x00,0x00,0x14,0x00,0x5C,0x00,0x30,0x00,0x18,0x00,0x54,0x00,0x70,\t// 189\n\t0x00,0x00,0x1C,0x00,0x54,0x00,0x30,0x00,0x18,0x00,0x64,0x00,0x70,\t// 190\n\t0x00,0x00,0xC0,0x00,0xA8,0x00,0x80,\t// 191\n\t0x40,0x00,0x3A,0x00,0x2E,0x00,0x38,0x00,0x40,\t// 192\n\t0x40,0x00,0x38,0x00,0x2E,0x00,0x3A,0x00,0x40,\t// 193\n\t0x40,0x00,0x38,0x00,0x2C,0x00,0x38,0x00,0x40,\t// 194\n\t0x40,0x00,0x38,0x00,0x2E,0x00,0x38,0x00,0x40,\t// 195\n\t0x40,0x00,0x3A,0x00,0x2C,0x00,0x3A,0x00,0x40,\t// 196\n\t0x40,0x00,0x3A,0x00,0x2E,0x00,0x3A,0x00,0x40,\t// 197\n\t0x40,0x00,0x38,0x00,0x2C,0x00,0x7C,0x00,0x54,0x00,0x54,\t// 198\n\t0x00,0x00,0x38,0x00,0xC4,0x00,0x44,0x00,0x44,\t// 199\n\t0x00,0x00,0x7E,0x00,0x56,0x00,0x54,\t// 200\n\t0x00,0x00,0x7C,0x00,0x56,0x00,0x56,\t// 201\n\t0x00,0x00,0x7E,0x00,0x56,0x00,0x54,\t// 202\n\t0x00,0x00,0x7E,0x00,0x54,0x00,0x56,\t// 203\n\t0x02,0x00,0x7E,\t// 204\n\t0x00,0x00,0x7E,\t// 205\n\t0x02,0x00,0x7E,\t// 206\n\t0x02,0x00,0x7C,\t// 207\n\t0x10,0x00,0x7C,0x00,0x54,0x00,0x44,0x00,0x38,\t// 208\n\t0x00,0x00,0x7C,0x00,0x1E,0x00,0x32,0x00,0x7C,\t// 209\n\t0x00,0x00,0x38,0x00,0x46,0x00,0x46,0x00,0x38,\t// 210\n\t0x00,0x00,0x38,0x00,0x44,0x00,0x46,0x00,0x3A,\t// 211\n\t0x00,0x00,0x38,0x00,0x46,0x00,0x46,0x00,0x38,\t// 212\n\t0x00,0x00,0x38,0x00,0x46,0x00,0x46,0x00,0x38,\t// 213\n\t0x00,0x00,0x3A,0x00,0x44,0x00,0x44,0x00,0x3A,\t// 214\n\t0x00,0x00,0x48,0x00,0x30,0x00,0x30,0x00,0x48,\t// 215\n\t0x00,0x00,0x78,0x00,0x54,0x00,0x54,0x00,0x3C,\t// 216\n\t0x00,0x00,0x3E,0x00,0x42,0x00,0x40,0x00,0x3C,\t// 217\n\t0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x3C,\t// 218\n\t0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x3C,\t// 219\n\t0x00,0x00,0x3E,0x00,0x40,0x00,0x40,0x00,0x3E,\t// 220\n\t0x04,0x00,0x0C,0x00,0x72,0x00,0x0E,\t// 221\n\t0x00,0x00,0x7C,0x00,0x28,0x00,0x38,\t// 222\n\t0x00,0x00,0x7E,0x00,0x1A,0x00,0x66,\t// 223\n\t0x02,0x00,0x60,0x00,0x68,0x00,0x78,\t// 224\n\t0x00,0x00,0x62,0x00,0x68,0x00,0x78,\t// 225\n\t0x00,0x00,0x60,0x00,0x68,0x00,0x78,\t// 226\n\t0x00,0x00,0x6C,0x00,0x6C,0x00,0x7C,\t// 227\n\t0x00,0x00,0x64,0x00,0x68,0x00,0x7C,\t// 228\n\t0x00,0x00,0x60,0x00,0x6E,0x00,0x7E,\t// 229\n\t0x00,0x00,0x60,0x00,0x68,0x00,0x30,0x00,0x58,0x00,0x58,\t// 230\n\t0x00,0x00,0xB0,0x00,0x48,0x00,0x48,\t// 231\n\t0x02,0x00,0x78,0x00,0x58,0x00,0x58,\t// 232\n\t0x00,0x00,0x7A,0x00,0x58,0x00,0x58,\t// 233\n\t0x00,0x00,0x7A,0x00,0x5A,0x00,0x58,\t// 234\n\t0x00,0x00,0x7C,0x00,0x58,0x00,0x5C,\t// 235\n\t0x00,0x00,0x78,\t// 236\n\t0x02,0x00,0x78,\t// 237\n\t0x02,0x00,0x7A,\t// 238\n\t0x04,0x00,0x78,\t// 239\n\t0x00,0x00,0x78,0x00,0x4C,0x00,0x78,\t// 240\n\t0x00,0x00,0x7C,0x00,0x0C,0x00,0x7C,\t// 241\n\t0x02,0x00,0x78,0x00,0x48,0x00,0x78,\t// 242\n\t0x00,0x00,0x7A,0x00,0x48,0x00,0x78,\t// 243\n\t0x00,0x00,0x78,0x00,0x48,0x00,0x78,\t// 244\n\t0x00,0x00,0x7C,0x00,0x4C,0x00,0x7C,\t// 245\n\t0x00,0x00,0x7C,0x00,0x48,0x00,0x7C,\t// 246\n\t0x00,0x00,0x10,0x00,0x10,0x00,0x54,0x00,0x10,0x00,0x10,\t// 247\n\t0x00,0x00,0x78,0x00,0x68,0x00,0x78,\t// 248\n\t0x02,0x00,0x78,0x00,0x40,0x00,0x78,\t// 249\n\t0x00,0x00,0x7A,0x00,0x40,0x00,0x78,\t// 250\n\t0x00,0x00,0x78,0x00,0x40,0x00,0x78,\t// 251\n\t0x00,0x00,0x7C,0x00,0x40,0x00,0x7C,\t// 252\n\t0x88,0x00,0xF2,0x00,0x30,0x00,0x08,\t// 253\n\t0x00,0x00,0xFE,0x00,0x48,0x00,0x78,\t// 254\n\t0x88,0x00,0xF4,0x00,0x34,0x00,0x08\t// 255\n};"
  },
  {
    "path": "examples/SSD1306FontTryout/Dialog_plain_8.h",
    "content": "// Created by http://oleddisplay.squix.ch/ Consider a donation\n// In case of problems make sure that you are using the font file with the correct version!\nconst char Dialog_plain_8[] PROGMEM = {\n\t0x08, // Width: 8\n\t0x0A, // Height: 10\n\t0x20, // First Char: 32\n\t0xE0, // Numbers of Chars: 224\n\n\t// Jump Table:\n\t0xFF, 0xFF, 0x00, 0x03,  // 32:65535\n\t0x00, 0x00, 0x03, 0x03,  // 33:0\n\t0x00, 0x03, 0x07, 0x04,  // 34:3\n\t0x00, 0x0A, 0x0B, 0x07,  // 35:10\n\t0x00, 0x15, 0x09, 0x05,  // 36:21\n\t0x00, 0x1E, 0x0F, 0x08,  // 37:30\n\t0x00, 0x2D, 0x0B, 0x06,  // 38:45\n\t0x00, 0x38, 0x03, 0x02,  // 39:56\n\t0x00, 0x3B, 0x05, 0x03,  // 40:59\n\t0x00, 0x40, 0x05, 0x03,  // 41:64\n\t0x00, 0x45, 0x07, 0x04,  // 42:69\n\t0x00, 0x4C, 0x0B, 0x07,  // 43:76\n\t0x00, 0x57, 0x04, 0x03,  // 44:87\n\t0x00, 0x5B, 0x05, 0x03,  // 45:91\n\t0x00, 0x60, 0x03, 0x03,  // 46:96\n\t0x00, 0x63, 0x05, 0x03,  // 47:99\n\t0x00, 0x68, 0x09, 0x05,  // 48:104\n\t0x00, 0x71, 0x07, 0x05,  // 49:113\n\t0x00, 0x78, 0x09, 0x05,  // 50:120\n\t0x00, 0x81, 0x09, 0x05,  // 51:129\n\t0x00, 0x8A, 0x09, 0x05,  // 52:138\n\t0x00, 0x93, 0x09, 0x05,  // 53:147\n\t0x00, 0x9C, 0x09, 0x05,  // 54:156\n\t0x00, 0xA5, 0x09, 0x05,  // 55:165\n\t0x00, 0xAE, 0x09, 0x05,  // 56:174\n\t0x00, 0xB7, 0x09, 0x05,  // 57:183\n\t0x00, 0xC0, 0x03, 0x03,  // 58:192\n\t0x00, 0xC3, 0x04, 0x03,  // 59:195\n\t0x00, 0xC7, 0x0B, 0x07,  // 60:199\n\t0x00, 0xD2, 0x0B, 0x07,  // 61:210\n\t0x00, 0xDD, 0x0B, 0x07,  // 62:221\n\t0x00, 0xE8, 0x07, 0x04,  // 63:232\n\t0x00, 0xEF, 0x0F, 0x08,  // 64:239\n\t0x00, 0xFE, 0x09, 0x05,  // 65:254\n\t0x01, 0x07, 0x09, 0x05,  // 66:263\n\t0x01, 0x10, 0x0B, 0x06,  // 67:272\n\t0x01, 0x1B, 0x0B, 0x06,  // 68:283\n\t0x01, 0x26, 0x09, 0x05,  // 69:294\n\t0x01, 0x2F, 0x07, 0x05,  // 70:303\n\t0x01, 0x36, 0x0B, 0x06,  // 71:310\n\t0x01, 0x41, 0x09, 0x06,  // 72:321\n\t0x01, 0x4A, 0x03, 0x02,  // 73:330\n\t0x01, 0x4D, 0x04, 0x02,  // 74:333\n\t0x01, 0x51, 0x09, 0x05,  // 75:337\n\t0x01, 0x5A, 0x07, 0x04,  // 76:346\n\t0x01, 0x61, 0x0B, 0x07,  // 77:353\n\t0x01, 0x6C, 0x09, 0x06,  // 78:364\n\t0x01, 0x75, 0x0B, 0x06,  // 79:373\n\t0x01, 0x80, 0x09, 0x05,  // 80:384\n\t0x01, 0x89, 0x0B, 0x06,  // 81:393\n\t0x01, 0x94, 0x0B, 0x06,  // 82:404\n\t0x01, 0x9F, 0x09, 0x05,  // 83:415\n\t0x01, 0xA8, 0x09, 0x05,  // 84:424\n\t0x01, 0xB1, 0x09, 0x06,  // 85:433\n\t0x01, 0xBA, 0x09, 0x05,  // 86:442\n\t0x01, 0xC3, 0x0D, 0x08,  // 87:451\n\t0x01, 0xD0, 0x09, 0x05,  // 88:464\n\t0x01, 0xD9, 0x09, 0x05,  // 89:473\n\t0x01, 0xE2, 0x09, 0x05,  // 90:482\n\t0x01, 0xEB, 0x06, 0x03,  // 91:491\n\t0x01, 0xF1, 0x06, 0x03,  // 92:497\n\t0x01, 0xF7, 0x06, 0x03,  // 93:503\n\t0x01, 0xFD, 0x09, 0x07,  // 94:509\n\t0x02, 0x06, 0x08, 0x04,  // 95:518\n\t0x02, 0x0E, 0x03, 0x04,  // 96:526\n\t0x02, 0x11, 0x09, 0x05,  // 97:529\n\t0x02, 0x1A, 0x09, 0x05,  // 98:538\n\t0x02, 0x23, 0x07, 0x04,  // 99:547\n\t0x02, 0x2A, 0x09, 0x05,  // 100:554\n\t0x02, 0x33, 0x09, 0x05,  // 101:563\n\t0x02, 0x3C, 0x05, 0x03,  // 102:572\n\t0x02, 0x41, 0x0A, 0x05,  // 103:577\n\t0x02, 0x4B, 0x09, 0x05,  // 104:587\n\t0x02, 0x54, 0x03, 0x02,  // 105:596\n\t0x02, 0x57, 0x04, 0x02,  // 106:599\n\t0x02, 0x5B, 0x07, 0x05,  // 107:603\n\t0x02, 0x62, 0x03, 0x02,  // 108:610\n\t0x02, 0x65, 0x0F, 0x08,  // 109:613\n\t0x02, 0x74, 0x09, 0x05,  // 110:628\n\t0x02, 0x7D, 0x09, 0x05,  // 111:637\n\t0x02, 0x86, 0x09, 0x05,  // 112:646\n\t0x02, 0x8F, 0x0A, 0x05,  // 113:655\n\t0x02, 0x99, 0x05, 0x03,  // 114:665\n\t0x02, 0x9E, 0x07, 0x04,  // 115:670\n\t0x02, 0xA5, 0x05, 0x03,  // 116:677\n\t0x02, 0xAA, 0x09, 0x05,  // 117:682\n\t0x02, 0xB3, 0x07, 0x05,  // 118:691\n\t0x02, 0xBA, 0x0B, 0x07,  // 119:698\n\t0x02, 0xC5, 0x07, 0x05,  // 120:709\n\t0x02, 0xCC, 0x09, 0x05,  // 121:716\n\t0x02, 0xD5, 0x07, 0x04,  // 122:725\n\t0x02, 0xDC, 0x08, 0x05,  // 123:732\n\t0x02, 0xE4, 0x04, 0x03,  // 124:740\n\t0x02, 0xE8, 0x07, 0x05,  // 125:744\n\t0x02, 0xEF, 0x0B, 0x07,  // 126:751\n\t0x02, 0xFA, 0x08, 0x05,  // 127:762\n\t0x03, 0x02, 0x08, 0x05,  // 128:770\n\t0x03, 0x0A, 0x08, 0x05,  // 129:778\n\t0x03, 0x12, 0x08, 0x05,  // 130:786\n\t0x03, 0x1A, 0x08, 0x05,  // 131:794\n\t0x03, 0x22, 0x08, 0x05,  // 132:802\n\t0x03, 0x2A, 0x08, 0x05,  // 133:810\n\t0x03, 0x32, 0x08, 0x05,  // 134:818\n\t0x03, 0x3A, 0x08, 0x05,  // 135:826\n\t0x03, 0x42, 0x08, 0x05,  // 136:834\n\t0x03, 0x4A, 0x08, 0x05,  // 137:842\n\t0x03, 0x52, 0x08, 0x05,  // 138:850\n\t0x03, 0x5A, 0x08, 0x05,  // 139:858\n\t0x03, 0x62, 0x08, 0x05,  // 140:866\n\t0x03, 0x6A, 0x08, 0x05,  // 141:874\n\t0x03, 0x72, 0x08, 0x05,  // 142:882\n\t0x03, 0x7A, 0x08, 0x05,  // 143:890\n\t0x03, 0x82, 0x08, 0x05,  // 144:898\n\t0x03, 0x8A, 0x08, 0x05,  // 145:906\n\t0x03, 0x92, 0x08, 0x05,  // 146:914\n\t0x03, 0x9A, 0x08, 0x05,  // 147:922\n\t0x03, 0xA2, 0x08, 0x05,  // 148:930\n\t0x03, 0xAA, 0x08, 0x05,  // 149:938\n\t0x03, 0xB2, 0x08, 0x05,  // 150:946\n\t0x03, 0xBA, 0x08, 0x05,  // 151:954\n\t0x03, 0xC2, 0x08, 0x05,  // 152:962\n\t0x03, 0xCA, 0x08, 0x05,  // 153:970\n\t0x03, 0xD2, 0x08, 0x05,  // 154:978\n\t0x03, 0xDA, 0x08, 0x05,  // 155:986\n\t0x03, 0xE2, 0x08, 0x05,  // 156:994\n\t0x03, 0xEA, 0x08, 0x05,  // 157:1002\n\t0x03, 0xF2, 0x08, 0x05,  // 158:1010\n\t0x03, 0xFA, 0x08, 0x05,  // 159:1018\n\t0xFF, 0xFF, 0x00, 0x03,  // 160:65535\n\t0x04, 0x02, 0x04, 0x03,  // 161:1026\n\t0x04, 0x06, 0x07, 0x05,  // 162:1030\n\t0x04, 0x0D, 0x07, 0x05,  // 163:1037\n\t0x04, 0x14, 0x09, 0x05,  // 164:1044\n\t0x04, 0x1D, 0x09, 0x05,  // 165:1053\n\t0x04, 0x26, 0x04, 0x03,  // 166:1062\n\t0x04, 0x2A, 0x08, 0x04,  // 167:1066\n\t0x04, 0x32, 0x07, 0x04,  // 168:1074\n\t0x04, 0x39, 0x0D, 0x08,  // 169:1081\n\t0x04, 0x46, 0x07, 0x04,  // 170:1094\n\t0x04, 0x4D, 0x09, 0x05,  // 171:1101\n\t0x04, 0x56, 0x0B, 0x07,  // 172:1110\n\t0x04, 0x61, 0x05, 0x03,  // 173:1121\n\t0x04, 0x66, 0x0D, 0x08,  // 174:1126\n\t0x04, 0x73, 0x05, 0x04,  // 175:1139\n\t0x04, 0x78, 0x05, 0x04,  // 176:1144\n\t0x04, 0x7D, 0x0B, 0x07,  // 177:1149\n\t0x04, 0x88, 0x05, 0x03,  // 178:1160\n\t0x04, 0x8D, 0x05, 0x03,  // 179:1165\n\t0x04, 0x92, 0x03, 0x04,  // 180:1170\n\t0x04, 0x95, 0x09, 0x05,  // 181:1173\n\t0x04, 0x9E, 0x0A, 0x05,  // 182:1182\n\t0x04, 0xA8, 0x03, 0x03,  // 183:1192\n\t0x04, 0xAB, 0x06, 0x04,  // 184:1195\n\t0x04, 0xB1, 0x05, 0x03,  // 185:1201\n\t0x04, 0xB6, 0x07, 0x04,  // 186:1206\n\t0x04, 0xBD, 0x09, 0x05,  // 187:1213\n\t0x04, 0xC6, 0x0F, 0x08,  // 188:1222\n\t0x04, 0xD5, 0x0F, 0x08,  // 189:1237\n\t0x04, 0xE4, 0x0F, 0x08,  // 190:1252\n\t0x04, 0xF3, 0x08, 0x04,  // 191:1267\n\t0x04, 0xFB, 0x09, 0x05,  // 192:1275\n\t0x05, 0x04, 0x09, 0x05,  // 193:1284\n\t0x05, 0x0D, 0x09, 0x05,  // 194:1293\n\t0x05, 0x16, 0x09, 0x05,  // 195:1302\n\t0x05, 0x1F, 0x09, 0x05,  // 196:1311\n\t0x05, 0x28, 0x09, 0x05,  // 197:1320\n\t0x05, 0x31, 0x0D, 0x08,  // 198:1329\n\t0x05, 0x3E, 0x0B, 0x06,  // 199:1342\n\t0x05, 0x49, 0x09, 0x05,  // 200:1353\n\t0x05, 0x52, 0x09, 0x05,  // 201:1362\n\t0x05, 0x5B, 0x09, 0x05,  // 202:1371\n\t0x05, 0x64, 0x09, 0x05,  // 203:1380\n\t0x05, 0x6D, 0x03, 0x02,  // 204:1389\n\t0x05, 0x70, 0x03, 0x02,  // 205:1392\n\t0x05, 0x73, 0x03, 0x02,  // 206:1395\n\t0x05, 0x76, 0x03, 0x02,  // 207:1398\n\t0x05, 0x79, 0x0B, 0x06,  // 208:1401\n\t0x05, 0x84, 0x09, 0x06,  // 209:1412\n\t0x05, 0x8D, 0x0B, 0x06,  // 210:1421\n\t0x05, 0x98, 0x0B, 0x06,  // 211:1432\n\t0x05, 0xA3, 0x0B, 0x06,  // 212:1443\n\t0x05, 0xAE, 0x0B, 0x06,  // 213:1454\n\t0x05, 0xB9, 0x0B, 0x06,  // 214:1465\n\t0x05, 0xC4, 0x0B, 0x07,  // 215:1476\n\t0x05, 0xCF, 0x0B, 0x06,  // 216:1487\n\t0x05, 0xDA, 0x09, 0x06,  // 217:1498\n\t0x05, 0xE3, 0x09, 0x06,  // 218:1507\n\t0x05, 0xEC, 0x09, 0x06,  // 219:1516\n\t0x05, 0xF5, 0x09, 0x06,  // 220:1525\n\t0x05, 0xFE, 0x09, 0x05,  // 221:1534\n\t0x06, 0x07, 0x09, 0x05,  // 222:1543\n\t0x06, 0x10, 0x09, 0x05,  // 223:1552\n\t0x06, 0x19, 0x09, 0x05,  // 224:1561\n\t0x06, 0x22, 0x09, 0x05,  // 225:1570\n\t0x06, 0x2B, 0x09, 0x05,  // 226:1579\n\t0x06, 0x34, 0x09, 0x05,  // 227:1588\n\t0x06, 0x3D, 0x09, 0x05,  // 228:1597\n\t0x06, 0x46, 0x09, 0x05,  // 229:1606\n\t0x06, 0x4F, 0x0F, 0x08,  // 230:1615\n\t0x06, 0x5E, 0x08, 0x04,  // 231:1630\n\t0x06, 0x66, 0x09, 0x05,  // 232:1638\n\t0x06, 0x6F, 0x09, 0x05,  // 233:1647\n\t0x06, 0x78, 0x09, 0x05,  // 234:1656\n\t0x06, 0x81, 0x09, 0x05,  // 235:1665\n\t0x06, 0x8A, 0x03, 0x02,  // 236:1674\n\t0x06, 0x8D, 0x03, 0x02,  // 237:1677\n\t0x06, 0x90, 0x03, 0x02,  // 238:1680\n\t0x06, 0x93, 0x03, 0x02,  // 239:1683\n\t0x06, 0x96, 0x09, 0x05,  // 240:1686\n\t0x06, 0x9F, 0x09, 0x05,  // 241:1695\n\t0x06, 0xA8, 0x09, 0x05,  // 242:1704\n\t0x06, 0xB1, 0x09, 0x05,  // 243:1713\n\t0x06, 0xBA, 0x09, 0x05,  // 244:1722\n\t0x06, 0xC3, 0x09, 0x05,  // 245:1731\n\t0x06, 0xCC, 0x09, 0x05,  // 246:1740\n\t0x06, 0xD5, 0x0B, 0x07,  // 247:1749\n\t0x06, 0xE0, 0x09, 0x05,  // 248:1760\n\t0x06, 0xE9, 0x09, 0x05,  // 249:1769\n\t0x06, 0xF2, 0x09, 0x05,  // 250:1778\n\t0x06, 0xFB, 0x09, 0x05,  // 251:1787\n\t0x07, 0x04, 0x09, 0x05,  // 252:1796\n\t0x07, 0x0D, 0x09, 0x05,  // 253:1805\n\t0x07, 0x16, 0x09, 0x05,  // 254:1814\n\t0x07, 0x1F, 0x09, 0x05,  // 255:1823\n\n\t// Font Data:\n\t0x00,0x00,0xBC,\t// 33\n\t0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,\t// 34\n\t0x00,0x00,0xA8,0x00,0x7C,0x00,0xEA,0x00,0x3E,0x00,0x28,\t// 35\n\t0x00,0x00,0x98,0x00,0xA8,0x00,0xFC,0x01,0xA8,\t// 36\n\t0x00,0x00,0x1C,0x00,0x14,0x00,0xDC,0x00,0x30,0x00,0xEC,0x00,0xA0,0x00,0xE0,\t// 37\n\t0x00,0x00,0x60,0x00,0xBC,0x00,0xF4,0x00,0xC4,0x00,0xA0,\t// 38\n\t0x00,0x00,0x0C,\t// 39\n\t0x00,0x00,0x7C,0x00,0x82,\t// 40\n\t0x00,0x00,0x82,0x00,0x7C,\t// 41\n\t0x24,0x00,0x18,0x00,0x3C,0x00,0x18,\t// 42\n\t0x00,0x00,0x20,0x00,0x20,0x00,0xF8,0x00,0x20,0x00,0x20,\t// 43\n\t0x00,0x00,0x80,0x01,\t// 44\n\t0x00,0x00,0x20,0x00,0x20,\t// 45\n\t0x00,0x00,0x80,\t// 46\n\t0x80,0x01,0x70,0x00,0x0C,\t// 47\n\t0x00,0x00,0x78,0x00,0x84,0x00,0x84,0x00,0x78,\t// 48\n\t0x00,0x00,0x84,0x00,0xFC,0x00,0x80,\t// 49\n\t0x00,0x00,0x84,0x00,0xC4,0x00,0xA4,0x00,0x98,\t// 50\n\t0x00,0x00,0x84,0x00,0xA4,0x00,0xA4,0x00,0xD8,\t// 51\n\t0x00,0x00,0x60,0x00,0x58,0x00,0xFC,0x00,0x40,\t// 52\n\t0x00,0x00,0x9C,0x00,0x94,0x00,0x94,0x00,0x64,\t// 53\n\t0x00,0x00,0x78,0x00,0xAC,0x00,0xA4,0x00,0xE4,\t// 54\n\t0x00,0x00,0x04,0x00,0x84,0x00,0x74,0x00,0x0C,\t// 55\n\t0x00,0x00,0xD8,0x00,0xA4,0x00,0xA4,0x00,0xD8,\t// 56\n\t0x00,0x00,0x9C,0x00,0x94,0x00,0xD4,0x00,0x78,\t// 57\n\t0x00,0x00,0x90,\t// 58\n\t0x00,0x00,0x90,0x01,\t// 59\n\t0x00,0x00,0x20,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x48,\t// 60\n\t0x00,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x50,\t// 61\n\t0x00,0x00,0x48,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x20,\t// 62\n\t0x00,0x00,0x04,0x00,0xB4,0x00,0x0C,\t// 63\n\t0x00,0x00,0x70,0x00,0x88,0x00,0x74,0x01,0x54,0x01,0x74,0x01,0x4C,0x00,0x38,\t// 64\n\t0x80,0x00,0x70,0x00,0x4C,0x00,0x70,0x00,0x80,\t// 65\n\t0x00,0x00,0xFC,0x00,0xA4,0x00,0xA4,0x00,0xDC,\t// 66\n\t0x00,0x00,0x78,0x00,0xCC,0x00,0x84,0x00,0x84,0x00,0x88,\t// 67\n\t0x00,0x00,0xFC,0x00,0x84,0x00,0x84,0x00,0x84,0x00,0x78,\t// 68\n\t0x00,0x00,0xFC,0x00,0xA4,0x00,0xA4,0x00,0xA4,\t// 69\n\t0x00,0x00,0xFC,0x00,0x24,0x00,0x24,\t// 70\n\t0x00,0x00,0x78,0x00,0x8C,0x00,0x84,0x00,0x94,0x00,0x78,\t// 71\n\t0x00,0x00,0xFC,0x00,0x20,0x00,0x20,0x00,0xFC,\t// 72\n\t0x00,0x00,0xFC,\t// 73\n\t0x00,0x02,0xFC,0x03,\t// 74\n\t0x00,0x00,0xFC,0x00,0x30,0x00,0x68,0x00,0xC4,\t// 75\n\t0x00,0x00,0xFC,0x00,0x80,0x00,0x80,\t// 76\n\t0x00,0x00,0xFC,0x00,0x1C,0x00,0x70,0x00,0x1C,0x00,0xFC,\t// 77\n\t0x00,0x00,0xFC,0x00,0x18,0x00,0x60,0x00,0xFC,\t// 78\n\t0x00,0x00,0x78,0x00,0x84,0x00,0x84,0x00,0x84,0x00,0x78,\t// 79\n\t0x00,0x00,0xFC,0x00,0x14,0x00,0x14,0x00,0x1C,\t// 80\n\t0x00,0x00,0x78,0x00,0x84,0x00,0x84,0x00,0x84,0x01,0x78,\t// 81\n\t0x00,0x00,0xFC,0x00,0x14,0x00,0x34,0x00,0x6C,0x00,0x80,\t// 82\n\t0x00,0x00,0x98,0x00,0x94,0x00,0xB4,0x00,0xE4,\t// 83\n\t0x04,0x00,0x04,0x00,0xFC,0x00,0x04,0x00,0x04,\t// 84\n\t0x00,0x00,0x7C,0x00,0x80,0x00,0x80,0x00,0x7C,\t// 85\n\t0x04,0x00,0x38,0x00,0xC0,0x00,0x38,0x00,0x04,\t// 86\n\t0x0C,0x00,0xF0,0x00,0x78,0x00,0x04,0x00,0x78,0x00,0xF0,0x00,0x0C,\t// 87\n\t0x84,0x00,0x4C,0x00,0x30,0x00,0x4C,0x00,0x84,\t// 88\n\t0x04,0x00,0x0C,0x00,0xF0,0x00,0x0C,0x00,0x04,\t// 89\n\t0x00,0x00,0x84,0x00,0xE4,0x00,0xB4,0x00,0x8C,\t// 90\n\t0x00,0x00,0xFC,0x01,0x04,0x01,\t// 91\n\t0x0C,0x00,0x70,0x00,0x80,0x01,\t// 92\n\t0x00,0x00,0x04,0x01,0xFC,0x01,\t// 93\n\t0x00,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x08,\t// 94\n\t0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,\t// 95\n\t0x00,0x00,0x04,\t// 96\n\t0x00,0x00,0xE0,0x00,0xB0,0x00,0xB0,0x00,0xF0,\t// 97\n\t0x00,0x00,0xFE,0x00,0x90,0x00,0x90,0x00,0x60,\t// 98\n\t0x00,0x00,0x60,0x00,0x90,0x00,0x90,\t// 99\n\t0x00,0x00,0x60,0x00,0x90,0x00,0x90,0x00,0xFE,\t// 100\n\t0x00,0x00,0x60,0x00,0xB0,0x00,0xB0,0x00,0xB0,\t// 101\n\t0x10,0x00,0xFE,0x00,0x12,\t// 102\n\t0x00,0x00,0x60,0x00,0x90,0x02,0x90,0x02,0xF0,0x01,\t// 103\n\t0x00,0x00,0xFE,0x00,0x10,0x00,0x10,0x00,0xF0,\t// 104\n\t0x00,0x00,0xF4,\t// 105\n\t0x00,0x02,0xF4,0x03,\t// 106\n\t0x00,0x00,0xFE,0x00,0x60,0x00,0x90,\t// 107\n\t0x00,0x00,0xFE,\t// 108\n\t0x00,0x00,0xF0,0x00,0x10,0x00,0x10,0x00,0xF0,0x00,0x10,0x00,0x10,0x00,0xF0,\t// 109\n\t0x00,0x00,0xF0,0x00,0x10,0x00,0x10,0x00,0xF0,\t// 110\n\t0x00,0x00,0x60,0x00,0x90,0x00,0x90,0x00,0x60,\t// 111\n\t0x00,0x00,0xF0,0x03,0x90,0x00,0x90,0x00,0x60,\t// 112\n\t0x00,0x00,0x60,0x00,0x90,0x00,0x90,0x00,0xF0,0x03,\t// 113\n\t0x00,0x00,0xF0,0x00,0x10,\t// 114\n\t0x00,0x00,0xB0,0x00,0xB0,0x00,0xD0,\t// 115\n\t0x10,0x00,0xF8,0x00,0x90,\t// 116\n\t0x00,0x00,0xF0,0x00,0x80,0x00,0x80,0x00,0xF0,\t// 117\n\t0x10,0x00,0xE0,0x00,0xE0,0x00,0x10,\t// 118\n\t0x30,0x00,0xC0,0x00,0x30,0x00,0x30,0x00,0xC0,0x00,0x30,\t// 119\n\t0x90,0x00,0xF0,0x00,0xF0,0x00,0x90,\t// 120\n\t0x00,0x00,0x10,0x02,0xE0,0x03,0x60,0x00,0x10,\t// 121\n\t0x00,0x00,0x90,0x00,0xD0,0x00,0xF0,\t// 122\n\t0x00,0x00,0x20,0x00,0xDC,0x01,0x04,0x01,\t// 123\n\t0x00,0x00,0xFC,0x03,\t// 124\n\t0x00,0x00,0x04,0x01,0xDC,0x01,0x20,\t// 125\n\t0x00,0x00,0x20,0x00,0x20,0x00,0x60,0x00,0x40,0x00,0x40,\t// 126\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 127\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 128\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 129\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 130\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 131\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 132\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 133\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 134\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 135\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 136\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 137\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 138\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 139\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 140\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 141\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 142\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 143\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 144\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 145\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 146\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 147\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 148\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 149\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 150\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 151\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 152\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 153\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 154\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 155\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 156\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 157\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 158\n\t0xFC,0x01,0x04,0x01,0x04,0x01,0xFC,0x01,\t// 159\n\t0x00,0x00,0xD0,0x03,\t// 161\n\t0x00,0x00,0xF0,0x00,0xF8,0x01,0x90,\t// 162\n\t0xA0,0x00,0xFC,0x00,0xA4,0x00,0xA4,\t// 163\n\t0x88,0x00,0x70,0x00,0x50,0x00,0x70,0x00,0x88,\t// 164\n\t0x54,0x00,0x58,0x00,0xE0,0x00,0x58,0x00,0x54,\t// 165\n\t0x00,0x00,0xDC,0x01,\t// 166\n\t0x00,0x00,0x3C,0x01,0x54,0x01,0xE4,0x01,\t// 167\n\t0x00,0x00,0x04,0x00,0x00,0x00,0x04,\t// 168\n\t0x00,0x00,0x78,0x00,0xCC,0x00,0xB4,0x00,0xB4,0x00,0xCC,0x00,0x78,\t// 169\n\t0x00,0x00,0x58,0x00,0x5C,0x00,0x5C,\t// 170\n\t0x00,0x00,0x60,0x00,0xF0,0x00,0x60,0x00,0xF0,\t// 171\n\t0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x60,\t// 172\n\t0x00,0x00,0x20,0x00,0x20,\t// 173\n\t0x00,0x00,0x78,0x00,0xCC,0x00,0xB4,0x00,0xB4,0x00,0xCC,0x00,0x78,\t// 174\n\t0x00,0x00,0x04,0x00,0x04,\t// 175\n\t0x00,0x00,0x0C,0x00,0x0C,\t// 176\n\t0x00,0x00,0x90,0x00,0x90,0x00,0xFC,0x00,0x90,0x00,0x90,\t// 177\n\t0x00,0x00,0x14,0x00,0x1C,\t// 178\n\t0x00,0x00,0x1C,0x00,0x14,\t// 179\n\t0x00,0x00,0x04,\t// 180\n\t0x00,0x00,0xF0,0x03,0x80,0x00,0x80,0x00,0xF0,\t// 181\n\t0x00,0x00,0x3C,0x00,0xFC,0x01,0x04,0x00,0xFC,0x01,\t// 182\n\t0x00,0x00,0x20,\t// 183\n\t0x00,0x00,0x00,0x02,0x00,0x03,\t// 184\n\t0x00,0x00,0x14,0x00,0x1C,\t// 185\n\t0x00,0x00,0x5C,0x00,0x54,0x00,0x5C,\t// 186\n\t0x00,0x00,0xF0,0x00,0x60,0x00,0xF0,0x00,0x60,\t// 187\n\t0x00,0x00,0x14,0x00,0x9C,0x00,0x70,0x00,0x18,0x00,0x04,0x00,0xC0,0x00,0xE0,\t// 188\n\t0x00,0x00,0x14,0x00,0x9C,0x00,0x70,0x00,0x18,0x00,0x04,0x00,0xA0,0x00,0xE0,\t// 189\n\t0x00,0x00,0x1C,0x00,0x94,0x00,0x60,0x00,0x18,0x00,0x04,0x00,0xC0,0x00,0xE0,\t// 190\n\t0x00,0x00,0x00,0x03,0xD0,0x02,0x00,0x02,\t// 191\n\t0x80,0x00,0x70,0x00,0x4E,0x00,0x72,0x00,0x80,\t// 192\n\t0x80,0x00,0x70,0x00,0x4E,0x00,0x72,0x00,0x80,\t// 193\n\t0x80,0x00,0x70,0x00,0x4C,0x00,0x70,0x00,0x80,\t// 194\n\t0x80,0x00,0x72,0x00,0x4E,0x00,0x72,0x00,0x80,\t// 195\n\t0x80,0x00,0x72,0x00,0x4C,0x00,0x72,0x00,0x80,\t// 196\n\t0x80,0x00,0x60,0x00,0x5F,0x00,0x60,0x00,0x80,\t// 197\n\t0x80,0x00,0x70,0x00,0x4C,0x00,0xFC,0x00,0xA4,0x00,0xA4,0x00,0xA4,\t// 198\n\t0x00,0x00,0x78,0x00,0xCC,0x02,0x84,0x03,0x84,0x00,0x88,\t// 199\n\t0x00,0x00,0xFC,0x00,0xA6,0x00,0xA6,0x00,0xA4,\t// 200\n\t0x00,0x00,0xFC,0x00,0xA6,0x00,0xA6,0x00,0xA4,\t// 201\n\t0x00,0x00,0xFC,0x00,0xA6,0x00,0xA6,0x00,0xA4,\t// 202\n\t0x00,0x00,0xFC,0x00,0xA6,0x00,0xA4,0x00,0xA6,\t// 203\n\t0x02,0x00,0xFE,\t// 204\n\t0x02,0x00,0xFE,\t// 205\n\t0x02,0x00,0xFE,\t// 206\n\t0x02,0x00,0xFC,\t// 207\n\t0x20,0x00,0xFC,0x00,0xA4,0x00,0x84,0x00,0xCC,0x00,0x78,\t// 208\n\t0x00,0x00,0xFC,0x00,0x1A,0x00,0x62,0x00,0xFC,\t// 209\n\t0x00,0x00,0x78,0x00,0x86,0x00,0x86,0x00,0x84,0x00,0x78,\t// 210\n\t0x00,0x00,0x78,0x00,0x86,0x00,0x86,0x00,0x84,0x00,0x78,\t// 211\n\t0x00,0x00,0x78,0x00,0x84,0x00,0x84,0x00,0x84,0x00,0x78,\t// 212\n\t0x00,0x00,0x78,0x00,0x86,0x00,0x86,0x00,0x86,0x00,0x78,\t// 213\n\t0x00,0x00,0x78,0x00,0x86,0x00,0x84,0x00,0x86,0x00,0x78,\t// 214\n\t0x00,0x00,0x88,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x88,\t// 215\n\t0x00,0x00,0xB8,0x00,0xE4,0x00,0x94,0x00,0x8C,0x00,0x74,\t// 216\n\t0x00,0x00,0x7C,0x00,0x82,0x00,0x82,0x00,0x7C,\t// 217\n\t0x00,0x00,0x7C,0x00,0x82,0x00,0x82,0x00,0x7C,\t// 218\n\t0x00,0x00,0x7C,0x00,0x82,0x00,0x82,0x00,0x7C,\t// 219\n\t0x00,0x00,0x7E,0x00,0x80,0x00,0x80,0x00,0x7E,\t// 220\n\t0x04,0x00,0x0E,0x00,0xF2,0x00,0x0C,0x00,0x04,\t// 221\n\t0x00,0x00,0xFC,0x00,0x28,0x00,0x28,0x00,0x38,\t// 222\n\t0x00,0x00,0xFC,0x00,0x02,0x00,0x9A,0x00,0xE4,\t// 223\n\t0x00,0x00,0xE4,0x00,0xB0,0x00,0xB0,0x00,0xF0,\t// 224\n\t0x00,0x00,0xE4,0x00,0xB0,0x00,0xB0,0x00,0xF0,\t// 225\n\t0x00,0x00,0xE0,0x00,0xB4,0x00,0xB4,0x00,0xF0,\t// 226\n\t0x00,0x00,0xE0,0x00,0xBC,0x00,0xBC,0x00,0xF0,\t// 227\n\t0x00,0x00,0xE0,0x00,0xB4,0x00,0xB4,0x00,0xF0,\t// 228\n\t0x00,0x00,0xE0,0x00,0xB6,0x00,0xB6,0x00,0xF0,\t// 229\n\t0x00,0x00,0xE0,0x00,0xB0,0x00,0xB0,0x00,0x60,0x00,0xB0,0x00,0xB0,0x00,0xB0,\t// 230\n\t0x00,0x00,0x60,0x00,0x90,0x02,0x90,0x03,\t// 231\n\t0x00,0x00,0x60,0x00,0xB4,0x00,0xB0,0x00,0xB0,\t// 232\n\t0x00,0x00,0x60,0x00,0xB4,0x00,0xB0,0x00,0xB0,\t// 233\n\t0x00,0x00,0x60,0x00,0xB4,0x00,0xB4,0x00,0xB0,\t// 234\n\t0x00,0x00,0x60,0x00,0xB4,0x00,0xB0,0x00,0xB4,\t// 235\n\t0x04,0x00,0xF0,\t// 236\n\t0x04,0x00,0xF0,\t// 237\n\t0x04,0x00,0xF4,\t// 238\n\t0x04,0x00,0xF0,\t// 239\n\t0x00,0x00,0x60,0x00,0x94,0x00,0x9C,0x00,0x70,\t// 240\n\t0x00,0x00,0xFC,0x00,0x1C,0x00,0x1C,0x00,0xF0,\t// 241\n\t0x00,0x00,0x64,0x00,0x90,0x00,0x90,0x00,0x60,\t// 242\n\t0x00,0x00,0x64,0x00,0x90,0x00,0x90,0x00,0x60,\t// 243\n\t0x00,0x00,0x60,0x00,0x94,0x00,0x94,0x00,0x60,\t// 244\n\t0x00,0x00,0x60,0x00,0x9C,0x00,0x9C,0x00,0x60,\t// 245\n\t0x00,0x00,0x64,0x00,0x90,0x00,0x90,0x00,0x64,\t// 246\n\t0x00,0x00,0x20,0x00,0x20,0x00,0xA8,0x00,0x20,0x00,0x20,\t// 247\n\t0x00,0x00,0xF0,0x00,0xD0,0x00,0xB0,0x00,0xF0,\t// 248\n\t0x00,0x00,0xF4,0x00,0x80,0x00,0x80,0x00,0xF0,\t// 249\n\t0x00,0x00,0xF4,0x00,0x80,0x00,0x80,0x00,0xF0,\t// 250\n\t0x00,0x00,0xF0,0x00,0x84,0x00,0x84,0x00,0xF0,\t// 251\n\t0x00,0x00,0xF0,0x00,0x84,0x00,0x84,0x00,0xF0,\t// 252\n\t0x00,0x00,0x14,0x02,0xE0,0x03,0x60,0x00,0x10,\t// 253\n\t0x00,0x00,0xFE,0x03,0x90,0x00,0x90,0x00,0x60,\t// 254\n\t0x00,0x00,0x14,0x02,0xE0,0x03,0x64,0x00,0x10\t// 255\n};"
  },
  {
    "path": "examples/SSD1306FontTryout/SSD1306FontTryout.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n/**\n   Using this sketch, you can try out the fonts. Simply generate new font files\n   at https://oleddisplay.squix.ch/ , download them and add to your sketch with\n   \"Sketch / Add file\" in the Arduino IDE. Then include them and add their names\n   to loop(). You'll see the name of the font on the serial monitor as the\n   sketch cycles through them.\n*/\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106SPi.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\n// Include all the font files you add to the Sketch\n#include \"Dialog_plain_8.h\"\n#include \"Dialog_plain_7.h\"\n#include \"Dialog_plain_6.h\"\n\n\n// This will call the function doPrint() with the name;\n// once without and once with quotes.\n#define DO_PRINT(a) doPrint(a, #a); \n\n\nvoid setup() {\n  display.init();\n\n  // display.flipScreenVertically();\n\n  display.setContrast(255);\n}\n\nvoid loop() {\n  \n  // These three fonts come with the display driver\n  DO_PRINT(ArialMT_Plain_10);\n  DO_PRINT(ArialMT_Plain_16);\n  DO_PRINT(ArialMT_Plain_24);\n\n  // These three I had generated and added as files\n  DO_PRINT(Dialog_plain_6);\n  DO_PRINT(Dialog_plain_7);\n  DO_PRINT(Dialog_plain_8);\n\n}\n\n\nvoid doPrint(const uint8_t* font, String fontname) {\n  Serial.println(fontname);\n\n  display.cls();\n  display.setFont(font);\n\n  display.println(\"Lorem ipsum dolor sit amet, consectetur\");\n  display.println(\"adipiscing elit, sed do eiusmod tempor\");\n  display.println(\"incididunt ut labore et dolore magna aliqua.\");\n  display.println(\"Ut enim ad minim veniam, quis nostrud exercitation\");\n  display.println(\"ullamco laboris nisi ut aliquip ex ea commodo\");\n  display.println(\"consequat. Duis aute irure dolor in reprehenderit\");\n  display.println(\"in voluptate velit esse cillum dolore eu fugiat\");\n  display.println(\"nulla pariatur. Excepteur sint occaecat cupidatat\");\n  display.println(\"non proident, sunt in culpa qui officia deserunt.\");\n\n  delay(5000);\n\n}\n\n// The library comes with fonts as a const uint8_t array, the site at\n// https://oleddisplay.squix.ch/ generates them as const char array. This code\n// converts one in the other to make sure both work here.\nvoid doPrint(const char* font, String fontname) {\n  doPrint(static_cast<const uint8_t*>(reinterpret_cast<const void*>(font)), fontname);\n}\n"
  },
  {
    "path": "examples/SSD1306OTADemo/SSD1306OTADemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n   Copyright (c) 2018 by Fabrice Weinberg\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n#if defined(ESP8266)\n#include <ESP8266WiFi.h>\n#include <ESP8266mDNS.h>\n#elif defined(ESP32)\n#include <WiFi.h>\n#include <ESPmDNS.h>\n#include <WiFiUdp.h>\n#endif\n\n#include <ArduinoOTA.h>\n\nconst char *ssid         = \"[Your SSID]\";\nconst char *password     = \"[Your Password]\";\n\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106SPi.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\n\nvoid setup() {\n  WiFi.begin ( ssid, password );\n\n  // Wait for connection\n  while ( WiFi.status() != WL_CONNECTED ) {\n    delay ( 10 );\n  }\n\n  display.init();\n  display.flipScreenVertically();\n  display.setContrast(255);\n\n  ArduinoOTA.begin();\n  ArduinoOTA.onStart([]() {\n    display.clear();\n    display.setFont(ArialMT_Plain_10);\n    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);\n    display.drawString(display.getWidth() / 2, display.getHeight() / 2 - 10, \"OTA Update\");\n    display.display();\n  });\n\n  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {\n    display.drawProgressBar(4, 32, 120, 8, progress / (total / 100) );\n    display.display();\n  });\n\n  ArduinoOTA.onEnd([]() {\n    display.clear();\n    display.setFont(ArialMT_Plain_10);\n    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);\n    display.drawString(display.getWidth() / 2, display.getHeight() / 2, \"Restart\");\n    display.display();\n  });\n\n  // Align text vertical/horizontal center\n  display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);\n  display.setFont(ArialMT_Plain_10);\n  display.drawString(display.getWidth() / 2, display.getHeight() / 2, \"Ready for OTA:\\n\" + WiFi.localIP().toString());\n  display.display();\n}\n\nvoid loop() {\n  ArduinoOTA.handle();\n}\n"
  },
  {
    "path": "examples/SSD1306ScrollVerticalDemo/SSD1306ScrollVerticalDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2022 by Stefan Seyfried\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n*/\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106Spi.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\n// UTF-8 sprinkled within, because it tests special conditions in the char-counting code\nconst String loremipsum = \"Lorem ipsum dolor sit ämet, \"\n  \"consetetur sadipscing elitr, sed diam nonümy eirmöd \"\n  \"tempor invidunt ut labore et dolore mägnä aliquyam erat, \"\n  \"sed diam voluptua. At vero eos et accusam et justo duo \"\n  \"dolores et ea rebum. Stet clita kasd gubergren, no sea \"\n  \"takimata sanctus est Lorem ipsum dolor sit amet. \"\n  \"äöü-ÄÖÜ/ß€é/çØ.\";\n\nvoid setup() {\n  display.init();\n  display.setContrast(255);\n  display.setTextAlignment(TEXT_ALIGN_LEFT);\n  display.setFont(ArialMT_Plain_16);\n  display.display();\n}\n\nvoid loop() {\n  static uint16_t start_at = 0;\n  display.clear();\n  uint16_t firstline = display.drawStringMaxWidth(0, 0, 128, loremipsum.substring(start_at));\n  display.display();\n  if (firstline != 0) {\n    start_at += firstline;\n  } else {\n    start_at = 0;\n    delay(1000); // additional pause before going back to start\n  }\n  delay(1000);\n}\n"
  },
  {
    "path": "examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n   Copyright (c) 2018 by Fabrice Weinberg\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n// Include the correct display library\n\n// For a connection via I2C using the Arduino Wire include:\n#include <Wire.h>               // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\"        // legacy: #include \"SSD1306.h\"\n// OR #include \"SH1106Wire.h\"   // legacy: #include \"SH1106.h\"\n\n// For a connection via I2C using brzo_i2c (must be installed) include:\n// #include <brzo_i2c.h>        // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// OR #include \"SH1106Brzo.h\"\n\n// For a connection via SPI include:\n// #include <SPI.h>             // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// OR #include \"SH1106SPi.h\"\n\n\n// Optionally include custom images\n#include \"images.h\"\n\n\n// Initialize the OLED display using Arduino Wire:\nSSD1306Wire display(0x3c, SDA, SCL);   // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SSD1306Wire display(0x3c, D3, D5);  // ADDRESS, SDA, SCL  -  If not, they can be specified manually.\n// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32);  // ADDRESS, SDA, SCL, OLEDDISPLAY_GEOMETRY  -  Extra param required for 128x32 displays.\n// SH1106Wire display(0x3c, SDA, SCL);     // ADDRESS, SDA, SCL\n\n// Initialize the OLED display using brzo_i2c:\n// SSD1306Brzo display(0x3c, D3, D5);  // ADDRESS, SDA, SCL\n// or\n// SH1106Brzo display(0x3c, D3, D5);   // ADDRESS, SDA, SCL\n\n// Initialize the OLED display using SPI:\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi display(D0, D2, D8);  // RES, DC, CS\n// or\n// SH1106Spi display(D0, D2);       // RES, DC\n\n\n#define DEMO_DURATION 3000\ntypedef void (*Demo)(void);\n\nint demoMode = 0;\nint counter = 1;\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println();\n  Serial.println();\n\n\n  // Initialising the UI will init the display too.\n  display.init();\n\n  display.flipScreenVertically();\n  display.setFont(ArialMT_Plain_10);\n\n}\n\nvoid drawFontFaceDemo() {\n  // Font Demo1\n  // create more fonts at http://oleddisplay.squix.ch/\n  display.setTextAlignment(TEXT_ALIGN_LEFT);\n  display.setFont(ArialMT_Plain_10);\n  display.drawString(0, 0, \"Hello world\");\n  display.setFont(ArialMT_Plain_16);\n  display.drawString(0, 10, \"Hello world\");\n  display.setFont(ArialMT_Plain_24);\n  display.drawString(0, 26, \"Hello world\");\n}\n\nvoid drawTextFlowDemo() {\n  display.setFont(ArialMT_Plain_10);\n  display.setTextAlignment(TEXT_ALIGN_LEFT);\n  display.drawStringMaxWidth(0, 0, 128,\n                             \"Lorem ipsum\\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.\" );\n}\n\nvoid drawTextAlignmentDemo() {\n  // Text alignment demo\n  display.setFont(ArialMT_Plain_10);\n\n  // The coordinates define the left starting point of the text\n  display.setTextAlignment(TEXT_ALIGN_LEFT);\n  display.drawString(0, 10, \"Left aligned (0,10)\");\n\n  // The coordinates define the center of the text\n  display.setTextAlignment(TEXT_ALIGN_CENTER);\n  display.drawString(64, 22, \"Center aligned (64,22)\");\n\n  // The coordinates define the right end of the text\n  display.setTextAlignment(TEXT_ALIGN_RIGHT);\n  display.drawString(128, 33, \"Right aligned (128,33)\");\n}\n\nvoid drawRectDemo() {\n  // Draw a pixel at given position\n  for (int i = 0; i < 10; i++) {\n    display.setPixel(i, i);\n    display.setPixel(10 - i, i);\n  }\n  display.drawRect(12, 12, 20, 20);\n\n  // Fill the rectangle\n  display.fillRect(14, 14, 17, 17);\n\n  // Draw a line horizontally\n  display.drawHorizontalLine(0, 40, 20);\n\n  // Draw a line horizontally\n  display.drawVerticalLine(40, 0, 20);\n}\n\nvoid drawCircleDemo() {\n  for (int i = 1; i < 8; i++) {\n    display.setColor(WHITE);\n    display.drawCircle(32, 32, i * 3);\n    if (i % 2 == 0) {\n      display.setColor(BLACK);\n    }\n    display.fillCircle(96, 32, 32 - i * 3);\n  }\n}\n\nvoid drawProgressBarDemo() {\n  int progress = (counter / 5) % 100;\n  // draw the progress bar\n  display.drawProgressBar(0, 32, 120, 10, progress);\n\n  // draw the percentage as String\n  display.setTextAlignment(TEXT_ALIGN_CENTER);\n  display.drawString(64, 15, String(progress) + \"%\");\n}\n\nvoid drawImageDemo() {\n  // see http://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html\n  // on how to create xbm files\n  display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);\n}\n\nDemo demos[] = {drawFontFaceDemo, drawTextFlowDemo, drawTextAlignmentDemo, drawRectDemo, drawCircleDemo, drawProgressBarDemo, drawImageDemo};\nint demoLength = (sizeof(demos) / sizeof(Demo));\nlong timeSinceLastModeSwitch = 0;\n\nvoid loop() {\n  // clear the display\n  display.clear();\n  // draw the current demo method\n  demos[demoMode]();\n\n  display.setFont(ArialMT_Plain_10);\n  display.setTextAlignment(TEXT_ALIGN_RIGHT);\n  display.drawString(128, 54, String(millis()));\n  // write the buffer to the display\n  display.display();\n\n  if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) {\n    demoMode = (demoMode + 1)  % demoLength;\n    timeSinceLastModeSwitch = millis();\n  }\n  counter++;\n  delay(10);\n}\n"
  },
  {
    "path": "examples/SSD1306SimpleDemo/images.h",
    "content": "#define WiFi_Logo_width 60\n#define WiFi_Logo_height 36\nconst uint8_t WiFi_Logo_bits[] PROGMEM = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,\n  0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,\n  0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,\n  0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,\n  0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,\n  0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,\n  0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,\n  0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,\n  0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,\n  0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,\n  0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,\n  0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,\n  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  };\n"
  },
  {
    "path": "examples/SSD1306TwoScreenDemo/SSD1306TwoScreenDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n#include \"images.h\"\n\n// Initialize the OLED display using Wire library\n//\n// GOTCHA!\n//\n// Pay attention if you work with ESP32 as some have two I2C buses.\n// You need to set the 'i2cBus' constructor parameter accordingly.\n// See https://github.com/ThingPulse/esp8266-oled-ssd1306/issues/387#issuecomment-2874437238 for a discussion.\nSSD1306Wire  display(0x3c, 0, 14);\nSSD1306Wire  display2(0x3c, 5, 4);\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println();\n  Serial.println();\n\n\n  // Initialising the UI will init the display too.\n  display.init();\n  display2.init();\n\n  // This will make sure that multiple instances of a display driver\n  // running on different ports will work together transparently\n  display.setI2cAutoInit(true);\n  display2.setI2cAutoInit(true);\n\n  display.flipScreenVertically();\n  display.setFont(ArialMT_Plain_10);\n  display.setTextAlignment(TEXT_ALIGN_LEFT);\n\n  display2.flipScreenVertically();\n  display2.setFont(ArialMT_Plain_10);\n  display2.setTextAlignment(TEXT_ALIGN_LEFT);\n\n}\n\nvoid loop() {\n  display.clear();\n  display.drawString(0, 0, \"Hello world: \" + String(millis()));\n  display.display();\n\n  display2.clear();\n  display2.drawString(0, 0, \"Hello world: \" + String(millis()));\n  display2.display();\n\n  delay(10);\n}\n"
  },
  {
    "path": "examples/SSD1306TwoScreenDemo/images.h",
    "content": "#define WiFi_Logo_width 60\n#define WiFi_Logo_height 36\nconst uint8_t WiFi_Logo_bits[] PROGMEM = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,\n  0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,\n  0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,\n  0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,\n  0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,\n  0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,\n  0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,\n  0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,\n  0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,\n  0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,\n  0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,\n  0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,\n  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  };\n"
  },
  {
    "path": "examples/SSD1306UiDemo/SSD1306UiDemo.ino",
    "content": "/**\n   The MIT License (MIT)\n\n   Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n   Copyright (c) 2018 by Fabrice Weinberg\n\n   Permission is hereby granted, free of charge, to any person obtaining a copy\n   of this software and associated documentation files (the \"Software\"), to deal\n   in the Software without restriction, including without limitation the rights\n   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n   copies of the Software, and to permit persons to whom the Software is\n   furnished to do so, subject to the following conditions:\n\n   The above copyright notice and this permission notice shall be included in all\n   copies or substantial portions of the Software.\n\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n   SOFTWARE.\n\n   ThingPulse invests considerable time and money to develop these open source libraries.\n   Please support us by buying our products (and not the clones) from\n   https://thingpulse.com\n\n*/\n\n// Include the correct display library\n// For a connection via I2C using Wire include\n#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier\n#include \"SSD1306Wire.h\" // legacy include: `#include \"SSD1306.h\"`\n// or #include \"SH1106Wire.h\", legacy include: `#include \"SH1106.h\"`\n// For a connection via I2C using brzo_i2c (must be installed) include\n// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Brzo.h\"\n// #include \"SH1106Brzo.h\"\n// For a connection via SPI include\n// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier\n// #include \"SSD1306Spi.h\"\n// #include \"SH1106SPi.h\"\n\n// Include the UI lib\n#include \"OLEDDisplayUi.h\"\n\n// Include custom images\n\n#include \"images.h\"\n\n// Use the corresponding display class:\n\n// Initialize the OLED display using SPI\n// D5 -> CLK\n// D7 -> MOSI (DOUT)\n// D0 -> RES\n// D2 -> DC\n// D8 -> CS\n// SSD1306Spi        display(D0, D2, D8);\n// or\n// SH1106Spi         display(D0, D2);\n\n// Initialize the OLED display using brzo_i2c\n// D3 -> SDA\n// D5 -> SCL\n// SSD1306Brzo display(0x3c, D3, D5);\n// or\n// SH1106Brzo  display(0x3c, D3, D5);\n\n// Initialize the OLED display using Wire library\nSSD1306Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL  -  SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h\n// SH1106Wire display(0x3c, SDA, SCL);\n\nOLEDDisplayUi ui     ( &display );\n\nvoid msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {\n  display->setTextAlignment(TEXT_ALIGN_RIGHT);\n  display->setFont(ArialMT_Plain_10);\n  display->drawString(128, 0, String(millis()));\n}\n\nvoid drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  // draw an xbm image.\n  // Please note that everything that should be transitioned\n  // needs to be drawn relative to x and y\n\n  display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);\n}\n\nvoid drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file\n  // Besides the default fonts there will be a program to convert TrueType fonts into this format\n  display->setTextAlignment(TEXT_ALIGN_LEFT);\n  display->setFont(ArialMT_Plain_10);\n  display->drawString(0 + x, 10 + y, \"Arial 10\");\n\n  display->setFont(ArialMT_Plain_16);\n  display->drawString(0 + x, 20 + y, \"Arial 16\");\n\n  display->setFont(ArialMT_Plain_24);\n  display->drawString(0 + x, 34 + y, \"Arial 24\");\n}\n\nvoid drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  // Text alignment demo\n  display->setFont(ArialMT_Plain_10);\n\n  // The coordinates define the left starting point of the text\n  display->setTextAlignment(TEXT_ALIGN_LEFT);\n  display->drawString(0 + x, 11 + y, \"Left aligned (0,10)\");\n\n  // The coordinates define the center of the text\n  display->setTextAlignment(TEXT_ALIGN_CENTER);\n  display->drawString(64 + x, 22 + y, \"Center aligned (64,22)\");\n\n  // The coordinates define the right end of the text\n  display->setTextAlignment(TEXT_ALIGN_RIGHT);\n  display->drawString(128 + x, 33 + y, \"Right aligned (128,33)\");\n}\n\nvoid drawFrame4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n  // Demo for drawStringMaxWidth:\n  // with the third parameter you can define the width after which words will be wrapped.\n  // Currently only spaces and \"-\" are allowed for wrapping\n  display->setTextAlignment(TEXT_ALIGN_LEFT);\n  display->setFont(ArialMT_Plain_10);\n  display->drawStringMaxWidth(0 + x, 10 + y, 128, \"Lorem ipsum\\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.\");\n}\n\nvoid drawFrame5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\n\n}\n\n// This array keeps function pointers to all frames\n// frames are the single views that slide in\nFrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5 };\n\n// how many frames are there?\nint frameCount = 5;\n\n// Overlays are statically drawn on top of a frame eg. a clock\nOverlayCallback overlays[] = { msOverlay };\nint overlaysCount = 1;\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println();\n  Serial.println();\n\n  // The ESP is capable of rendering 60fps in 80Mhz mode\n  // but that won't give you much time for anything else\n  // run it in 160Mhz mode or just set it to 30 fps\n  ui.setTargetFPS(60);\n\n  // Customize the active and inactive symbol\n  ui.setActiveSymbol(activeSymbol);\n  ui.setInactiveSymbol(inactiveSymbol);\n\n  // You can change this to\n  // TOP, LEFT, BOTTOM, RIGHT\n  ui.setIndicatorPosition(BOTTOM);\n\n  // Defines where the first frame is located in the bar.\n  ui.setIndicatorDirection(LEFT_RIGHT);\n\n  // You can change the transition that is used\n  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN\n  ui.setFrameAnimation(SLIDE_LEFT);\n\n  // Add frames\n  ui.setFrames(frames, frameCount);\n\n  // Add overlays\n  ui.setOverlays(overlays, overlaysCount);\n\n  // Initialising the UI will init the display too.\n  ui.init();\n\n  display.flipScreenVertically();\n\n}\n\n\nvoid loop() {\n  int remainingTimeBudget = ui.update();\n\n  if (remainingTimeBudget > 0) {\n    // You can do some work here\n    // Don't do stuff if you are below your\n    // time budget.\n    delay(remainingTimeBudget);\n  }\n}\n"
  },
  {
    "path": "examples/SSD1306UiDemo/images.h",
    "content": "#define WiFi_Logo_width 60\n#define WiFi_Logo_height 36\nconst uint8_t WiFi_Logo_bits[] PROGMEM = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,\n  0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,\n  0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,\n  0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,\n  0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,\n  0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,\n  0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,\n  0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,\n  0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,\n  0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,\n  0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,\n  0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,\n  0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,\n  0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,\n  0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,\n  0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  };\n\nconst uint8_t activeSymbol[] PROGMEM = {\n    B00000000,\n    B00000000,\n    B00011000,\n    B00100100,\n    B01000010,\n    B01000010,\n    B00100100,\n    B00011000\n};\n\nconst uint8_t inactiveSymbol[] PROGMEM = {\n    B00000000,\n    B00000000,\n    B00000000,\n    B00000000,\n    B00011000,\n    B00011000,\n    B00000000,\n    B00000000\n};\n"
  },
  {
    "path": "keywords.txt",
    "content": "#######################################\n# Syntax Coloring Map List\n#######################################\n\n\n#######################################\n# Constants (LITERAL1)\n#######################################\nINVERSE    LITERAL1\n\nTEXT_ALIGN_LEFT    LITERAL1\nTEXT_ALIGN_RIGHT    LITERAL1\nTEXT_ALIGN_CENTER    LITERAL1\nTEXT_ALIGN_CENTER_BOTH    LITERAL1\n\nGEOMETRY_128_64    LITERAL1\nGEOMETRY_128_32    LITERAL1\nGEOMETRY_RAWMODE    LITERAL1\n\nArialMT_Plain_10    LITERAL1\nArialMT_Plain_16    LITERAL1\nArialMT_Plain_24    LITERAL1\n\nSLIDE_UP    LITERAL1\nSLIDE_DOWN    LITERAL1\nSLIDE_LEFT    LITERAL1\nSLIDE_RIGHT    LITERAL1\n\nTOP    LITERAL1\nRIGHT    LITERAL1\nBOTTOM    LITERAL1\nLEFT    LITERAL1\n\nLEFT_RIGHT    LITERAL1\nRIGHT_LEFT    LITERAL1\n\nIN_TRANSITION    LITERAL1\nFIXED    LITERAL1\n\n\n#######################################\n# Datatypes (KEYWORD1)\n#######################################\nOLEDDisplay    KEYWORD1\nOLEDDisplayUi    KEYWORD1\n\nSH1106Wire    KEYWORD1\nSH1106Brzo    KEYWORD1\nSH1106Spi    KEYWORD1\n\nSSD1306Wire    KEYWORD1\nSSD1306Brzo    KEYWORD1\nSSD1306I2C    KEYWORD1\nSSD1306Spi    KEYWORD1\n\n\n#######################################\n# Methods and Functions (KEYWORD2)\n#######################################\nallocateBuffer    KEYWORD2\ninit    KEYWORD2\nresetDisplay    KEYWORD2\nsetColor    KEYWORD2\ngetColor    KEYWORD2\nsetPixel    KEYWORD2\nsetPixelColor    KEYWORD2\nclearPixel    KEYWORD2\ndrawLine    KEYWORD2\ndrawRect    KEYWORD2\nfillRect    KEYWORD2\ndrawCircle    KEYWORD2\ndrawCircleQuads    KEYWORD2\nfillCircle    KEYWORD2\nfillRing    KEYWORD2\ndrawHorizontalLine    KEYWORD2\ndrawVerticalLine    KEYWORD2\ndrawProgressBar    KEYWORD2\ndrawFastImage    KEYWORD2\ndrawXbm    KEYWORD2\ndrawIco16x16    KEYWORD2\ndrawString    KEYWORD2\ndrawStringMaxWidth    KEYWORD2\ngetStringWidth    KEYWORD2\nsetTextAlignment    KEYWORD2\nsetFont    KEYWORD2\nsetFontTableLookupFunction    KEYWORD2\ndisplayOn    KEYWORD2\ndisplayOff    KEYWORD2\ninvertDisplay    KEYWORD2\nnormalDisplay    KEYWORD2\nsetContrast    KEYWORD2\nsetBrightness    KEYWORD2\nresetOrientation    KEYWORD2\nflipScreenVertically    KEYWORD2\nmirrorScreen    KEYWORD2\ndisplay    KEYWORD2\nsetLogBuffer    KEYWORD2\ndrawLogBuffer    KEYWORD2\ngetWidth    KEYWORD2\ngetHeight    KEYWORD2\n"
  },
  {
    "path": "library.json",
    "content": "{\n  \"name\": \"ESP8266 and ESP32 OLED driver for SSD1306 displays\",\n  \"version\": \"4.6.2\",\n  \"keywords\": \"ssd1306, oled, display, i2c\",\n  \"description\": \"I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS\",\n  \"license\": \"MIT\",\n  \"repository\":\n  {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/ThingPulse/esp8266-oled-ssd1306\"\n  },\n  \"authors\":\n  [\n    {\n        \"name\": \"Daniel Eichhorn, ThingPulse\",\n        \"email\": \"squix78@gmail.com\",\n        \"url\": \"https://thingpulse.com\"\n    },\n    {\n        \"name\": \"Fabrice Weinberg\",\n        \"email\": \"fabrice@weinberg.me\"\n    }\n  ],\n  \"frameworks\": \"arduino\",\n  \"platforms\": [\n    \"espressif8266\",\n    \"espressif32\",\n    \"nordicnrf52\"\n  ]\n}\n"
  },
  {
    "path": "library.properties",
    "content": "name=ESP8266 and ESP32 OLED driver for SSD1306 displays\nversion=4.6.2\nauthor=ThingPulse, Fabrice Weinberg\nmaintainer=ThingPulse <info@thingpulse.com>\nsentence=I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS\nparagraph=The following geometries are currently supported: 128x64, 128x32, 64x48. The init sequence was inspired by Adafruit's library for the same display.\ncategory=Display\nurl=https://github.com/ThingPulse/esp8266-oled-ssd1306\narchitectures=esp8266,esp32\nlicense=MIT\n"
  },
  {
    "path": "license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 by Daniel Eichhorn\nCopyright (c) 2016 by Fabrice Weinberg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nSee more at http://blog.squix.ch\n"
  },
  {
    "path": "platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; http://docs.platformio.org/page/projectconf.html\n\n[env:d1_mini]\nplatform = espressif8266\nboard = d1_mini\nframework = arduino\nupload_speed = 921600\nboard_build.f_cpu = 160000000L\nupload_port = /dev/cu.SLAB_USBtoUART\nmonitor_port = /dev/cu.SLAB_USBtoUART\nlib_deps =\n"
  },
  {
    "path": "resources/glyphEditor.html",
    "content": "<!--The MIT License (MIT)\n\nCopyright (c) 2017 by Xavier Grosjean\n\nBased on work \nCopyright (c) 2016 by Daniel Eichhorn\nCopyright (c) 2016 by Fabrice Weinberg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n-->\n<!--\n Standalone page to draw icons in matrix and generates the map definition with the format required by \n library for OLED SD1306 screen: https://github.com/squix78/esp8266-oled-ssd1306\n 100% quick and dirty vanilla ECS6, no framework or library was injured for this project.\n\n-->\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <style>\n      #form, #chars table {\n        user-select: none; \n        -moz-user-select: none; \n        margin-top: 5px;\n      }\n      #chars table, tr, td, th {\n        border-collapse: collapse;\n      }\n      #chars td, th {\n        border: 1px solid #CCC;\n        width: 12px;\n        height: 15px;\n      }\n      #chars th[action] {\n        cursor:pointer;\n      }\n      #chars th[action=\"up\"], #chars th[action=\"down\"], #chars th[action=\"left\"], #chars th[action=\"right\"] {\n        font-size: 10px;\n      }\n      #chars td.on {\n        background-color: #00F;\n      }\n      \n      #addChar, #generate {\n        display: none;\n      }\n      body.started #addChar, body.started #generate {\n        display: inline;\n      }\n      body.started #create {\n        display: none;\n      }\n      #page {\n        position:relative;\n      }\n      #page>div {\n        position: relative;\n        float: left;\n      }\n\n      #output {\n        margin-left: 20px;\n        margin-top: 12px;\n        font-size:12px;\n        user-select: all;\n        -moz-user-select: all;\n        max-width:60%;\n      }\n      \n      #header {\n        margin-top: 10px;\n      }\n      #inputText {\n        width: 100%;\n        height:120px;\n      }\n      \n    </style>\n  </head>\n  <body>\n    <div id=\"form\">\n      <table width=\"100%\">\n        <tr>\n          <td>Font array name:</td><td><input placeholder=\"Font array name\" type=\"text\" id=\"name\" value=\"My_Font\"/></td>\n          <td width=\"75%\" rowspan=\"5\">\n            <textarea id=\"inputText\" placeholder=\"Or paste a char array font definition here\">\nconst uint8_t My_Font[] PROGMEM = {\n  0x0A, // Width: 10\n  0x0D, // Height: 13\n  0x01, // First char: 1\n  0x02, // Number of chars: 2\n  // Jump Table:\n  0x00, 0x00, 0x13, 0x0A, // 1\n  0x00, 0x13, 0x14, 0x0A, // 2\n  // Font Data:\n  0xF0, 0x03, 0x10, 0x02, 0xF0, 0x03, 0x10, 0x02, 0xF0, 0x03, 0x10, 0x02, 0xF0, 0x03, 0x10, 0x02, 0xF0, 0x03, 0xC0, // 1\n  0x00, 0x0C, 0x80, 0x0B, 0x70, 0x08, 0x0C, 0x08, 0xF3, 0x0A, 0xF3, 0x0A, 0x0C, 0x08, 0x70, 0x08, 0x80, 0x0B, 0x00, 0x0C, // 2\n};              \n            </textarea></td>\n        </tr>\n        <tr>\n          <td>First char code:</td><td><input placeholder=\"First char code\" type=\"number\" id=\"code\" value=\"1\" min=\"1\"/></td>\n        </tr>\n        <tr>\n          <td>Width:</td><td><input placeholder=\"Font width\" type=\"number\" id=\"width\" value=\"10\"/></td>\n        </tr>\n        <tr>\n          <td>Height:</td><td><input placeholder=\"Font height\" type=\"number\" id=\"height\" value=\"13\" max=\"64\"/></td>\n        </tr>\n        <tr>\n          <td>NewWidth:</td><td><input placeholder=\"New Font width\" type=\"number\" id=\"newwidth\" value=\"0\"/></td>\n        </tr>\n        <tr>\n          <td>NewHeight:</td><td><input placeholder=\"New Font height\" type=\"number\" id=\"newheight\" value=\"0\" max=\"64\"/></td>\n        </tr>\n        <tr>\n          <td colspan=\"3\"> </td>     <!--slightly improves layout-->\n        </tr>\n        <tr>\n          <td colspan=\"2\">\n            <button id=\"create\">Create</button>\n            <br/>Shift all\n            <button id=\"shiftUp\">Up</button>\n            <button id=\"shiftDown\">Down</button>\n            <button id=\"shiftLeft\">Left</button>\n            <button id=\"shiftRight\">Right</button><br/>\n            <button id=\"generate\">Generate</button>\n            <button id=\"savetoFile\">Save To File</button>\n          </td>\n          <td><input type=\"file\" id=\"fileinput\" />  <button id=\"parse\">Parse</button></td>\n        </tr>\n      </table>\n      <br/>\n    </div>\n    <div id=\"page\">\n      <div id=\"charxContainer\" ondragstart=\"return false;\">\n        <div id=\"chars\"></div><br/>\n        <button id=\"addChar\">Add a character</button>\n      </div>\n      <div id=\"output\">\n        <div class=\"output\" id=\"header\"> </div>\n        <div class=\"output\" id=\"jump\"> </div>\n        <div class=\"output\" id=\"data\"> </div>\n      </div>\n    </div>\n    <script>\n    (function() {\n      let font;\n      \n      class Font {\n        constructor() {\n          this.height = parseInt(document.getElementById('height').value);\n          this.width = parseInt(document.getElementById('width').value);\n          this.currentCharCode = parseInt(document.getElementById('code').value);\n          this.fontContainer = document.getElementById('chars');\n          this.bytesForHeight = (1 + ((this.height - 1) >> 3));  // number of bytes needed for this font height\n          document.body.className = \"started\";\n          document.getElementById('height').disabled = true;\n          document.getElementById('width').disabled = true;          \n        }\n        \n        // Should we have a Char and a Pixel class ? not sure it's worth it.\n        // Let's use the DOM to store everything for now\n        \n        static updateCaption(element, code) {\n          element.textContent = `Char #${code} [`+String.fromCharCode(code)+']';\n        }\n        \n        // Add a pixel matrix to draw a new character\n        // jumpaData not used for now: some day, use the last byte for optimisation \n        addChar(jumpData, charData) {\n          let charContainer = this.fontContainer.appendChild(document.createElement(\"table\"));\n          charContainer.setAttribute(\"code\", this.currentCharCode);\n          let caption = charContainer.appendChild(document.createElement(\"caption\"));\n          Font.updateCaption(caption, this.currentCharCode);\n          let header = charContainer.appendChild(document.createElement(\"tr\"));\n          header.innerHTML = '<th  title=\"Delete this char\" action=\"delete\">&cross;</th>'\n              + '<th title=\"Add a char above\" action=\"add\">+</th>'\n              + '<th title=\"Shift pixels to the left\" action=\"left\">&larr;</th>'\n              + '<th title=\"Shift pixels down\" action=\"down\">&darr;</th>'\n              + '<th title=\"Shift pixels up\" action=\"up\">&uarr;</th>'\n              + '<th title=\"Shift pixels to the right\" action=\"right\">&rarr;</th>'\n              + '<th title=\"Copy from another character\" action=\"copy\">&copy;</th>'\n              + '<th title=\"Reset all pixels\" action=\"clean\">&empty;</th>';\n          // If data is provided, decode it to pixel initialization friendly structure\n          let pixelInit = [];\n          if (charData && charData.length) {\n            // charData byte count needs to be a multiple of bytesForHeight. End bytes with value 0 may have been trimmed\n            let missingBytes = charData.length % this.bytesForHeight;\n            for(let b = 0; b < missingBytes ; b++) {\n              charData.push(0);\n            }\n            while(charData.length) {\n              let row = charData.splice(0, this.bytesForHeight).reverse();\n              let pixelRow = [];\n              for (let b = 0; b < row.length; b++) {\n                let mask = 0x80;\n                let byte = row[b];\n                for (let bit = 0; bit < 8; bit++) {\n                  if (byte & mask) {\n                    pixelRow.push(1);\n                  } else {\n                    pixelRow.push(0);\n                  }\n                  mask = mask >> 1;\n                }\n              }\n              pixelRow.splice(0, pixelRow.length - this.height);\n              //Font.output('data', pixelRow);\n              pixelInit.push(pixelRow.reverse());\n            }\n          }\n          \n          for(let r = 0; r < this.height; r++) {\n          \tlet rowContainer = charContainer.appendChild(document.createElement(\"tr\"));\n            for(let c = 0; c < this.width; c++) {\n          \t\tlet pixContainer = rowContainer.appendChild(document.createElement(\"td\"));\n              pixContainer.setAttribute('action', 'toggle');\n          \t\t// If there is some init data, set the pixel accordingly\n              if (pixelInit.length && pixelInit[c]) {\n                if (pixelInit[c][r]) {\n                  pixContainer.className = 'on';\n                }\n              }          \t\t\n            }\n          }\n          this.currentCharCode++;\n          return charContainer;\n        }\n        \n        static togglePixel(pixel) {\n          pixel.className = pixel.className === 'on' ? '': 'on';\n        }\n        \n        // Return anInt as hex string\n        static toHexString(aByte) {\n          let zero = aByte < 16?'0':'';\n          return `0x${zero}${aByte.toString(16).toUpperCase()}`\n        }\n        \n        // Return least significant byte as hex string\n        static getLsB(anInt) {\n          return Font.toHexString(anInt & 0xFF);      \n        }\n        // Return most significant byte as hex string\n        static getMsB(anInt) {\n          return Font.toHexString(anInt>>>8);      \n        }\n       \n        static output(targetId, msg) {\n          let output = document.getElementById(targetId);\n          let line = output.appendChild(document.createElement('div'));\n          line.textContent = msg;\n        }\n        static emptyChars() {\n          document.getElementById('chars').textContent = '';\n        }\n        static emptyOutput() {\n          document.getElementById('header').textContent = '';\n          document.getElementById('jump').textContent = '';\n          document.getElementById('data').textContent = '';\n        }\n\t\t\n        saveFile() {\n          let filename = document.getElementById('name').value.replace(/[^a-zA-Z0-9_$]/g, '_') + \".h\";\n          let data = document.getElementById(\"output\").innerText;\n          if(data.length < 10) return;\n          let blobObject = new Blob([data], {type:'text/plain'}); \n    \n          if(window.navigator.msSaveBlob) {\n            window.navigator.msSaveBlob(blobObject, filename);\n          } else {\n            let a = document.createElement(\"a\");\n            a.setAttribute(\"href\", URL.createObjectURL(blobObject));\n            a.setAttribute(\"download\", filename);\n            if (document.createEvent) {\n              let event = document.createEvent('MouseEvents');\n              event.initEvent('click', true, true);\n              a.dispatchEvent(event);\n            } else {\n              a.click();\n            }\n          }  \n        }\n\t\t\t\n        // Read from the <td> css class the pixels that need to be on\n        // generates the jump table and font data \n        generate() {\n          // this.width -= 3;  // hack to narrow an existing font\n          var newheight = parseInt(document.getElementById('newheight').value);\n          if(newheight){\n            this.height = newheight;\n            this.bytesForHeight = (1 + ((this.height - 1) >> 3));\n          }\n          var newwidth = parseInt(document.getElementById('newwidth').value);\n          if(newwidth){\n             this.width = newwidth;\t\n          }\n\n          Font.emptyOutput();\n          let chars = this.fontContainer.getElementsByTagName('table');\n          let firstCharCode = parseInt(document.getElementById('code').value);\n          let name = document.getElementById('name').value.replace(/[^a-zA-Z0-9_$]/g, '_');\n          \n          let bits2add = this.bytesForHeight*8 - this.height;  // number of missing bits to fill leftmost byte\n          let charCount = chars.length;\n          let charAddr = 0;\n          // Comments are used when parsing back a generated font\n          Font.output('jump', '  // Jump Table:');\n          Font.output('data', '  // Font Data:');\n          // Browse each character\n          for(let ch = 0; ch < charCount; ch++) {\n            // Fix renumbering in case first char code was modified  \n            Font.updateCaption(chars[ch].getElementsByTagName('caption')[0], ch + firstCharCode);\n            let charBytes = [];\n            let charCode = ch + firstCharCode;\n            let rows = chars[ch].getElementsByTagName('tr');\n            let charNotZero = false;\n            // Browse each column\n            for(let col = 0; col < this.width ; col++) {\n              let bits = \"\"; // using string because js uses 32b ints when performing bit operations\n              // Browse each row starting from the bottom one, going up, and accumulate pixels in\n              // a string: this rotates the glyph\n              // Beware, row 0 is table headers.\n          //for(let r = rows.length-1; r >=1 ; r--) {\n\n              for(let r = this.height; r >=1 ; r--) {\n                let pixelState = rows[r].children[col].className;\n                bits += (pixelState === 'on' ? '1': '0');           \n              }\n              // Need to complete missing bits to have a sizeof byte multiple number of bits\n              for(let b = 0; b < bits2add; b++) {\n                bits =  '0' + bits;\n              }\n              // Font.output('data', `  // ${bits}`);  // Debugging help: rotated bitmap\n\n              // read bytes from the end\n              for(let b = bits.length - 1; b >= 7; b -= 8) {\n                //Font.output('data', `  // ${bits.substr(b-7, 8)}`);  // Debugging help: rotated bitmap\n                let byte = parseInt(bits.substr(b-7, 8), 2);\n                if (byte !== 0) {\n                  charNotZero = true;\n                }\n                charBytes.push(Font.toHexString(byte));\n              } \n            }\n            // Compute the used width of the character:  \n            // rightmost column with pixels plus one\n            // one column is spread over several bytes...\n            let charWidth = 0;\n            for(let i=charBytes.length - 1; i >= 0; i-=this.bytesForHeight) {\n              let sum = 0;\n              for(let j=0; j < this.bytesForHeight; j++) {\n                sum += parseInt(charBytes[i - j], 16);\n              }\n              if(sum !== 0) {\n                charWidth = (i + 1)/this.bytesForHeight + 1;\n                break;\n              }\n            }\n\n            // Memory optim: Remove bytes with value 0 at the end of the array.\n            while(parseInt(charBytes[charBytes.length-1], 16) === 0 && charBytes.length > 1) {\n              charBytes.pop();\n            }\n            if (charNotZero) {\n              Font.output('data', `  ${charBytes.join(', ')},  // ${charCode}`);\n              Font.output('jump', `  ${Font.getMsB(charAddr)}, ${Font.getLsB(charAddr)}, ${Font.toHexString(charBytes.length)}, ${Font.toHexString(charWidth)},  // ${charCode} `);\n              charAddr += charBytes.length;\n            } else {\n              Font.output('jump', `  0xFF, 0xFF, 0x00, ${Font.toHexString(this.width)},  // ${charCode} `);\n            }\n          }\n          Font.output('data', '};');\n          \n          Font.output('header', \"// Font generated or edited with the glyphEditor\");\n          Font.output('header', `const uint8_t ${name}[] PROGMEM = {`);\n          // Comments are used when parsing back a generated font\n          Font.output('header', `  ${Font.toHexString(this.width)}, // Width: ${this.width}`);\n          Font.output('header', `  ${Font.toHexString(this.height)}, // Height: ${this.height}`);          \n          Font.output('header', `  ${Font.toHexString(firstCharCode)}, // First char: ${firstCharCode}`);\n          Font.output('header', `  ${Font.toHexString(charCount)}, // Number of chars: ${charCount}`);\n        }\n      }\n\t  \n      document.getElementById('fileinput').addEventListener('change', function(e) {\n        let f = e.target.files[0]; \n        if (f) {\n          let r = new FileReader();\n          r.onload = function(e) { \n            let contents = e.target.result;\n                alert( \"Got the file.\\n\" \n                +\"name: \" + f.name + \"\\n\"\n                +\"type: \" + f.type + \"\\n\"\n                +\"size: \" + f.size + \" bytes\\n\"\n                +\"starts with: \" + contents.substr(0, contents.indexOf(\"\\n\")) \n            );\n              document.getElementById(\"inputText\").value = contents;\n          };\n          r.readAsText(f);\n        } else { \n          alert(\"Failed to load file\");\n        }\n        });\n      \n      document.getElementById('savetoFile').addEventListener('click', function() {\n        font.saveFile();\n      });\n      \n      document.getElementById('shiftUp').addEventListener('click', function() {\n        var chars = document.getElementById(\"chars\");\n        var tables = chars.getElementsByTagName(\"table\");\n        for(var i=0; i< tables.length; i++) {\n          shiftUp(tables[i]);\n        }\n      });\n      \n      document.getElementById('shiftDown').addEventListener('click', function() {\n        var chars = document.getElementById(\"chars\");\n        var tables = chars.getElementsByTagName(\"table\");\n        for(var i=0; i< tables.length; i++) {\n          shiftDown(tables[i]);\n        }\n      });\n      document.getElementById('shiftLeft').addEventListener('click', function() {\n        var chars = document.getElementById(\"chars\");\n        var tables = chars.getElementsByTagName(\"table\");\n        for(var i=0; i< tables.length; i++) {\n          shiftLeft(tables[i]);\n        }\n      });\n      document.getElementById('shiftRight').addEventListener('click', function() {\n        var chars = document.getElementById(\"chars\");\n        var tables = chars.getElementsByTagName(\"table\");\n        for(var i=0; i< tables.length; i++) {\n          shiftRight(tables[i]);\n        }\n      });\n      \n      document.getElementById('generate').addEventListener('click', function() {\n        font.generate();\n      });\n      document.getElementById('addChar').addEventListener('click', function() {\n        font.addChar();\n      });\n      document.getElementById('inputText').addEventListener('click', function(e) {\n        let target = e.target;\n        target.select();\n      });\n      document.getElementById('chars').addEventListener('mousedown', function(e) {\n        if (e.button !== 0) return;\n        let target = e.target;\n        let action = target.getAttribute('action') || '';\n        if (action === '') return;\n        let result, code, nextContainer, previousContainer, pixels ;\n        let currentContainer = target.parentNode.parentNode;\n        switch(action) {\n          case 'add':\n            code = currentContainer.getAttribute('code');\n            nextContainer = font.addChar();\n            currentContainer.parentNode.insertBefore(nextContainer, currentContainer);\n            do {\n              nextContainer.setAttribute('code', code);\n              Font.updateCaption(nextContainer.getElementsByTagName('caption')[0], code);\n              code ++;\n            } while (nextContainer = nextContainer.nextSibling);\n            break;\n\n          case 'delete':\n            result = confirm(\"Delete this character ?\");\n            if (!result) return;\n            code = currentContainer.getAttribute('code');\n            nextContainer = currentContainer;\n            while (nextContainer = nextContainer.nextSibling) {\n              nextContainer.setAttribute('code', code);\n              Font.updateCaption(nextContainer.getElementsByTagName('caption')[0], code);\n              code ++;\n            }\n            currentContainer.parentNode.removeChild(currentContainer);\n            break;\n\n          // Shift pixels to the left  \n          case 'left':\n            shiftLeft(currentContainer);\n            break;\n          \n          // Shift pixels to the right\n          case 'right':\n            shiftRight(currentContainer);\n            break;\n\n          // Shift pixels down\n          case 'down':\n            shiftDown(currentContainer);\n\t\t\tbreak;\n\n          // Shift pixels up\n          case 'up':\n            shiftUp(currentContainer);\n            break;\n\n          case 'toggle':\n            Font.togglePixel(target);\n            break;\n\n          case 'clean':\n            result = confirm(\"Delete the pixels ?\");\n            if (!result) return;\n            pixels = currentContainer.getElementsByTagName('td');\n            for (let p = 0; p < pixels.length; p++) {\n              pixels[p].className = '';\n            }\n            break;\n          \n          case 'copy':\n             let charNumber = parseInt(prompt(\"Source char #: \"));\n             let chars = font.fontContainer.getElementsByTagName('table');\n             let tableOffset = charNumber - parseInt(document.getElementById('code').value);\n             let srcPixels = chars[tableOffset].getElementsByTagName('td');\n             let targetPixels = currentContainer.getElementsByTagName('td');\n             for(let i=0; i < srcPixels.length; i++) {\n               // First tds are in the th row, for editing actions. Skip them\n               if (targetPixels[i].parentNode.localName === 'th') continue; // In case we give them css at some point...\n               targetPixels[i].className = srcPixels[i].className;\n             }\n            break;\n          default:\n            // no.\n        }\n        \n      });\n      function shiftUp(container) {\n        var pixels = container.getElementsByTagName('td');\n        for(p = 0; p < pixels.length; p++) {\n          if(p < font.width*(font.height -1)) {\n            pixels[p].className = pixels[p + font.width].className;\n          } else {\n            pixels[p].className = '';\n          }\n        }  \n      }\n      function shiftDown(container) {\n        var pixels = container.getElementsByTagName('td');\n        for(p = pixels.length-1; p >=0 ; p--) {\n          if(p >= font.width) {\n           pixels[p].className = pixels[p - font.width].className;\n          } else {\n           pixels[p].className = '';\n          }\n        } \n      }\n      function shiftLeft(container) {\n        var pixels = container.getElementsByTagName('td');\n        for(p = 0; p < pixels.length; p++) {\n          if((p + 1) % font.width) {\n             pixels[p].className = pixels[p + 1].className;\n          } else {\n             pixels[p].className = '';\n          }\n        }\n      }\n      \n      function shiftRight(container) {\n        var pixels = container.getElementsByTagName('td');\n        for(p = pixels.length-1; p >=0 ; p--) {\n          if(p % font.width) {\n            pixels[p].className = pixels[p - 1].className;\n          } else {\n            pixels[p].className = '';\n          }\n        }\n      }\n      \n      document.getElementById('chars').addEventListener('mouseover', function(e) {\n        let target = e.target;\n        let action = target.getAttribute('action');\n        if (action !== 'toggle' || e.buttons !== 1) return;\n        Font.togglePixel(target);\n      });\n      document.getElementById('chars').addEventListener('dragstart', function() {\n        return false;\n      });\n\n      document.getElementById('create').addEventListener('click', function() {\n      \tfont = new Font();\n        font.addChar();\n      });\n\n      // parse a char array declaration for an existing font.\n      // parsing heavily relies on comments.\n      document.getElementById('parse').addEventListener('click', function() {\n        if (document.getElementById('chars').childElementCount) {\n          let result = confirm(\"Confirm you want to overwrite the existing grids ?\");\n          if (!result) return;          \n        } \n        let lines = document.getElementById('inputText').value.split('\\n');\n        let name = '';\n        let height = 0;\n        let width = 0;\n        let firstCharCode = 0;\n        let jumpTable = [];\n        let charData = [];\n        let readingJumpTable = false;\n        let readingData = false;\n        \n        for(let l = 0 ; l < lines.length; l++) {\n          // TODO ? keep C compilation directives to copy them (not lowercased :)) to newly generated char array\n          let line = lines[l].trim();\n          //alert(line);\n          let fields;\n\n          // Declaration line: grab the name\n          if (line.indexOf('PROGMEM') > 0) {\n            fields = line.split(' ');\n            name = fields[2].replace(/[\\[\\]]/g, '');\n            continue;\n          }\n          line = line.toLowerCase();\n          // Todo: could rely on line order...\n          // width line: grab the width\n          if (line.indexOf('width') > 0) {\n            fields = line.split(',');\n            width = fields[0];\n            continue;\n          }\n          // height line: grab the height \n          if (line.indexOf('height') > 0) {\n            fields = line.split(',');\n            height = fields[0];\n            continue;\n          }\n          // first char code line: grab the first char code \n          if (line.indexOf('first char') > 0) {\n            fields = line.split(',');\n            firstCharCode = fields[0];\n            continue;\n          }\n          // End of array declaration\n          // TODO warn if more lines: next fonts are ignored\n          if (line.indexOf('};') === 0) {\n            break;\n          }\n          \n          if (readingJumpTable || readingData) {\n            if (line.indexOf('#') !== 0 && line.length !== 0 && line.indexOf('//') !== 0) {\n              line = line.replace(/\\/\\/.*/, ''); // get rid of end of line comments\n              fields = line.split(',');\n              let newEntry = [];\n              for(let f=0; f < fields.length; f++) {\n                let value = parseInt(fields[f]);\n                if (isNaN(value)) continue;\n                if (readingData) {\n                  charData.push(value);\n                }\n                if (readingJumpTable) {\n                  newEntry.push(value);\n                }\n              }\n              if (readingJumpTable) {\n                jumpTable.push(newEntry);\n              }\n            }            \n          }\n          \n          // Begining of data\n          if (line.indexOf('font data') > 0) {\n            readingData = true;\n            readingJumpTable = false;\n          }\n          // Begining of jump table\n          if (line.indexOf('jump table') > 0) {\n            readingJumpTable = true;\n          }\n        }\n        if (!name || !height || !width || !firstCharCode) {\n          alert(\"Does not look like a parsable font. Try again.\");\n          return;\n        }\n        \n        Font.emptyChars();\n        Font.emptyOutput();\n        document.getElementById('name').value = name;\n        document.getElementById('height').value = parseInt(height);\n        document.getElementById('width').value = parseInt(width);\n        document.getElementById('code').value = parseInt(firstCharCode);\n      \tfont = new Font();\n      \tfor(let c = 0 ; c < jumpTable.length; c++) {\n      \t  let jumpEntry = jumpTable[c];\n      \t  let charEntry = [];\n      \t  // displayable character \n      \t  if (jumpEntry[0] !== 255 || jumpEntry[1] !== 255) {\n      \t    charEntry = charData.splice(0, jumpEntry[2]);\n          }\n      \t  font.addChar(jumpEntry, charEntry);\n        }\n        document.body.className = \"started\";\n      });        \n      \n      })();\n    </script>  \n  </body>\n</html>\n"
  },
  {
    "path": "src/OLEDDisplay.cpp",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n /*\n  * TODO Helmut\n  * - test/finish dislplay.printf() on mbed-os\n  */\n\n#include \"OLEDDisplay.h\"\n\nOLEDDisplay::OLEDDisplay() {\n\n\tdisplayWidth = 128;\n\tdisplayHeight = 64;\n\tdisplayBufferSize = displayWidth * displayHeight / 8;\n  inhibitDrawLogBuffer = false;\n\tcolor = WHITE;\n\tgeometry = GEOMETRY_128_64;\n\ttextAlignment = TEXT_ALIGN_LEFT;\n\tfontData = ArialMT_Plain_10;\n\tfontTableLookupFunction = DefaultFontTableLookup;\n\tbuffer = NULL;\n#ifdef OLEDDISPLAY_DOUBLE_BUFFER\n\tbuffer_back = NULL;\n#endif\n}\n\nOLEDDisplay::~OLEDDisplay() {\n  end();\n}\n\nbool OLEDDisplay::allocateBuffer() {\n\n  logBufferSize = 0;\n  logBufferFilled = 0;\n  logBufferLine = 0;\n  logBufferMaxLines = 0;\n  logBuffer = NULL;\n\n  if (!connect()) {\n    DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][init] Can't establish connection to display\\n\");\n    return false;\n  }\n\n  if(this->buffer==NULL) {\n    this->buffer = (uint8_t*) malloc((sizeof(uint8_t) * displayBufferSize) + BufferOffset);\n    this->buffer += BufferOffset;\n\n    if(!this->buffer) {\n      DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][init] Not enough memory to create display\\n\");\n      return false;\n    }\n  }\n\n  #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n  if(this->buffer_back==NULL) {\n    this->buffer_back = (uint8_t*) malloc((sizeof(uint8_t) * displayBufferSize) + BufferOffset);\n    this->buffer_back += BufferOffset;\n\n    if(!this->buffer_back) {\n      DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][init] Not enough memory to create back buffer\\n\");\n      free(this->buffer - BufferOffset);\n      return false;\n    }\n  }\n  #endif\n\n  return true;\n}\n\nbool OLEDDisplay::init() {\n\n  BufferOffset = getBufferOffset();\n\n  if(!allocateBuffer()) {\n    return false;\n  }\n\n  sendInitCommands();\n  resetDisplay();\n\n  return true;\n}\n\nvoid OLEDDisplay::end() {\n  if (this->buffer) { free(this->buffer - BufferOffset); this->buffer = NULL; }\n  #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n  if (this->buffer_back) { free(this->buffer_back - BufferOffset); this->buffer_back = NULL; }\n  #endif\n  if (this->logBuffer != NULL) { free(this->logBuffer); this->logBuffer = NULL; }\n}\n\nvoid OLEDDisplay::resetDisplay(void) {\n  clear();\n  #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n  memset(buffer_back, 1, displayBufferSize);\n  #endif\n  display();\n}\n\nvoid OLEDDisplay::setColor(OLEDDISPLAY_COLOR color) {\n  this->color = color;\n}\n\nOLEDDISPLAY_COLOR OLEDDisplay::getColor() {\n  return this->color;\n}\n\nvoid OLEDDisplay::setPixel(int16_t x, int16_t y) {\n  if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {\n    switch (color) {\n      case WHITE:   buffer[x + (y / 8) * this->width()] |=  (1 << (y & 7)); break;\n      case BLACK:   buffer[x + (y / 8) * this->width()] &= ~(1 << (y & 7)); break;\n      case INVERSE: buffer[x + (y / 8) * this->width()] ^=  (1 << (y & 7)); break;\n    }\n  }\n}\n\nvoid OLEDDisplay::setPixelColor(int16_t x, int16_t y, OLEDDISPLAY_COLOR color) {\n  if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {\n    switch (color) {\n      case WHITE:   buffer[x + (y / 8) * this->width()] |=  (1 << (y & 7)); break;\n      case BLACK:   buffer[x + (y / 8) * this->width()] &= ~(1 << (y & 7)); break;\n      case INVERSE: buffer[x + (y / 8) * this->width()] ^=  (1 << (y & 7)); break;\n    }\n  }\n}\n\nvoid OLEDDisplay::clearPixel(int16_t x, int16_t y) {\n  if (x >= 0 && x < this->width() && y >= 0 && y < this->height()) {\n    switch (color) {\n      case BLACK:   buffer[x + (y >> 3) * this->width()] |=  (1 << (y & 7)); break;\n      case WHITE:   buffer[x + (y >> 3) * this->width()] &= ~(1 << (y & 7)); break;\n      case INVERSE: buffer[x + (y >> 3) * this->width()] ^=  (1 << (y & 7)); break;\n    }\n  }\n}\n\n\n// Bresenham's algorithm - thx wikipedia and Adafruit_GFX\nvoid OLEDDisplay::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {\n  int16_t steep = abs(y1 - y0) > abs(x1 - x0);\n  if (steep) {\n    _swap_int16_t(x0, y0);\n    _swap_int16_t(x1, y1);\n  }\n\n  if (x0 > x1) {\n    _swap_int16_t(x0, x1);\n    _swap_int16_t(y0, y1);\n  }\n\n  int16_t dx, dy;\n  dx = x1 - x0;\n  dy = abs(y1 - y0);\n\n  int16_t err = dx / 2;\n  int16_t ystep;\n\n  if (y0 < y1) {\n    ystep = 1;\n  } else {\n    ystep = -1;\n  }\n\n  for (; x0<=x1; x0++) {\n    if (steep) {\n      setPixel(y0, x0);\n    } else {\n      setPixel(x0, y0);\n    }\n    err -= dy;\n    if (err < 0) {\n      y0 += ystep;\n      err += dx;\n    }\n  }\n}\n\nvoid OLEDDisplay::drawRect(int16_t x, int16_t y, int16_t width, int16_t height) {\n  drawHorizontalLine(x, y, width);\n  drawVerticalLine(x, y, height);\n  drawVerticalLine(x + width - 1, y, height);\n  drawHorizontalLine(x, y + height - 1, width);\n}\n\nvoid OLEDDisplay::fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t height) {\n  for (int16_t x = xMove; x < xMove + width; x++) {\n    drawVerticalLine(x, yMove, height);\n  }\n}\n\nvoid OLEDDisplay::drawCircle(int16_t x0, int16_t y0, int16_t radius) {\n  int16_t x = 0, y = radius;\n\tint16_t dp = 1 - radius;\n\tdo {\n\t\tif (dp < 0)\n\t\t\tdp = dp + (x++) * 2 + 3;\n\t\telse\n\t\t\tdp = dp + (x++) * 2 - (y--) * 2 + 5;\n\n\t\tsetPixel(x0 + x, y0 + y);     //For the 8 octants\n\t\tsetPixel(x0 - x, y0 + y);\n\t\tsetPixel(x0 + x, y0 - y);\n\t\tsetPixel(x0 - x, y0 - y);\n\t\tsetPixel(x0 + y, y0 + x);\n\t\tsetPixel(x0 - y, y0 + x);\n\t\tsetPixel(x0 + y, y0 - x);\n\t\tsetPixel(x0 - y, y0 - x);\n\n\t} while (x < y);\n\n  setPixel(x0 + radius, y0);\n  setPixel(x0, y0 + radius);\n  setPixel(x0 - radius, y0);\n  setPixel(x0, y0 - radius);\n}\n\nvoid OLEDDisplay::drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads) {\n  int16_t x = 0, y = radius;\n  int16_t dp = 1 - radius;\n  while (x < y) {\n    if (dp < 0)\n      dp = dp + (x++) * 2 + 3;\n    else\n      dp = dp + (x++) * 2 - (y--) * 2 + 5;\n    if (quads & 0x1) {\n      setPixel(x0 + x, y0 - y);\n      setPixel(x0 + y, y0 - x);\n    }\n    if (quads & 0x2) {\n      setPixel(x0 - y, y0 - x);\n      setPixel(x0 - x, y0 - y);\n    }\n    if (quads & 0x4) {\n      setPixel(x0 - y, y0 + x);\n      setPixel(x0 - x, y0 + y);\n    }\n    if (quads & 0x8) {\n      setPixel(x0 + x, y0 + y);\n      setPixel(x0 + y, y0 + x);\n    }\n  }\n  if (quads & 0x1 && quads & 0x8) {\n    setPixel(x0 + radius, y0);\n  }\n  if (quads & 0x4 && quads & 0x8) {\n    setPixel(x0, y0 + radius);\n  }\n  if (quads & 0x2 && quads & 0x4) {\n    setPixel(x0 - radius, y0);\n  }\n  if (quads & 0x1 && quads & 0x2) {\n    setPixel(x0, y0 - radius);\n  }\n}\n\n\nvoid OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {\n  int16_t x = 0, y = radius;\n\tint16_t dp = 1 - radius;\n\tdo {\n\t\tif (dp < 0)\n      dp = dp + (x++) * 2 + 3;\n    else\n      dp = dp + (x++) * 2 - (y--) * 2 + 5;\n\n    drawHorizontalLine(x0 - x, y0 - y, 2*x);\n    drawHorizontalLine(x0 - x, y0 + y, 2*x);\n    drawHorizontalLine(x0 - y, y0 - x, 2*y);\n    drawHorizontalLine(x0 - y, y0 + x, 2*y);\n\n\n\t} while (x < y);\n  drawHorizontalLine(x0 - radius, y0, 2 * radius);\n\n}\n\nvoid OLEDDisplay::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,\n                               int16_t x2, int16_t y2) {\n  drawLine(x0, y0, x1, y1);\n  drawLine(x1, y1, x2, y2);\n  drawLine(x2, y2, x0, y0);\n}\n\nvoid OLEDDisplay::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,\n                               int16_t x2, int16_t y2) {\n  int16_t a, b, y, last;\n\n  if (y0 > y1) {\n    _swap_int16_t(y0, y1);\n    _swap_int16_t(x0, x1);\n  }\n  if (y1 > y2) {\n    _swap_int16_t(y2, y1);\n    _swap_int16_t(x2, x1);\n  }\n  if (y0 > y1) {\n    _swap_int16_t(y0, y1);\n    _swap_int16_t(x0, x1);\n  }\n\n  if (y0 == y2) {\n    a = b = x0;\n    if (x1 < a) {\n      a = x1;\n    } else if (x1 > b) {\n      b = x1;\n    }\n    if (x2 < a) {\n      a = x2;\n    } else if (x2 > b) {\n      b = x2;\n    }\n    drawHorizontalLine(a, y0, b - a + 1);\n    return;\n  }\n\n  int16_t\n    dx01 = x1 - x0,\n    dy01 = y1 - y0,\n    dx02 = x2 - x0,\n    dy02 = y2 - y0,\n    dx12 = x2 - x1,\n    dy12 = y2 - y1;\n  int32_t\n    sa   = 0,\n    sb   = 0;\n\n  if (y1 == y2) {\n    last = y1; // Include y1 scanline\n  } else {\n    last = y1 - 1; // Skip it\n  }\n\n  for (y = y0; y <= last; y++) {\n    a = x0 + sa / dy01;\n    b = x0 + sb / dy02;\n    sa += dx01;\n    sb += dx02;\n\n    if (a > b) {\n      _swap_int16_t(a, b);\n    }\n    drawHorizontalLine(a, y, b - a + 1);\n  }\n\n  sa = dx12 * (y - y1);\n  sb = dx02 * (y - y0);\n  for (; y <= y2; y++) {\n    a = x1 + sa / dy12;\n    b = x0 + sb / dy02;\n    sa += dx12;\n    sb += dx02;\n\n    if (a > b) {\n      _swap_int16_t(a, b);\n    }\n    drawHorizontalLine(a, y, b - a + 1);\n  }\n}\n\nvoid OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {\n  if (y < 0 || y >= this->height()) { return; }\n\n  if (x < 0) {\n    length += x;\n    x = 0;\n  }\n\n  if ( (x + length) > this->width()) {\n    length = (this->width() - x);\n  }\n\n  if (length <= 0) { return; }\n\n  uint8_t * bufferPtr = buffer;\n  bufferPtr += (y >> 3) * this->width();\n  bufferPtr += x;\n\n  uint8_t drawBit = 1 << (y & 7);\n\n  switch (color) {\n    case WHITE:   while (length--) {\n        *bufferPtr++ |= drawBit;\n      }; break;\n    case BLACK:   drawBit = ~drawBit;   while (length--) {\n        *bufferPtr++ &= drawBit;\n      }; break;\n    case INVERSE: while (length--) {\n        *bufferPtr++ ^= drawBit;\n      }; break;\n  }\n}\n\nvoid OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) {\n  if (x < 0 || x >= this->width()) return;\n\n  if (y < 0) {\n    length += y;\n    y = 0;\n  }\n\n  if ( (y + length) > this->height()) {\n    length = (this->height() - y);\n  }\n\n  if (length <= 0) return;\n\n\n  uint8_t yOffset = y & 7;\n  uint8_t drawBit;\n  uint8_t *bufferPtr = buffer;\n\n  bufferPtr += (y >> 3) * this->width();\n  bufferPtr += x;\n\n  if (yOffset) {\n    yOffset = 8 - yOffset;\n    drawBit = ~(0xFF >> (yOffset));\n\n    if (length < yOffset) {\n      drawBit &= (0xFF >> (yOffset - length));\n    }\n\n    switch (color) {\n      case WHITE:   *bufferPtr |=  drawBit; break;\n      case BLACK:   *bufferPtr &= ~drawBit; break;\n      case INVERSE: *bufferPtr ^=  drawBit; break;\n    }\n\n    if (length < yOffset) return;\n\n    length -= yOffset;\n    bufferPtr += this->width();\n  }\n\n  if (length >= 8) {\n    switch (color) {\n      case WHITE:\n      case BLACK:\n        drawBit = (color == WHITE) ? 0xFF : 0x00;\n        do {\n          *bufferPtr = drawBit;\n          bufferPtr += this->width();\n          length -= 8;\n        } while (length >= 8);\n        break;\n      case INVERSE:\n        do {\n          *bufferPtr = ~(*bufferPtr);\n          bufferPtr += this->width();\n          length -= 8;\n        } while (length >= 8);\n        break;\n    }\n  }\n\n  if (length > 0) {\n    drawBit = (1 << (length & 7)) - 1;\n    switch (color) {\n      case WHITE:   *bufferPtr |=  drawBit; break;\n      case BLACK:   *bufferPtr &= ~drawBit; break;\n      case INVERSE: *bufferPtr ^=  drawBit; break;\n    }\n  }\n}\n\nvoid OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress) {\n  uint16_t radius = height / 2;\n  uint16_t xRadius = x + radius;\n  uint16_t yRadius = y + radius;\n  uint16_t doubleRadius = 2 * radius;\n  uint16_t innerRadius = radius - 2;\n\n  setColor(WHITE);\n  drawCircleQuads(xRadius, yRadius, radius, 0b00000110);\n  drawHorizontalLine(xRadius, y, width - doubleRadius + 1);\n  drawHorizontalLine(xRadius, y + height, width - doubleRadius + 1);\n  drawCircleQuads(x + width - radius, yRadius, radius, 0b00001001);\n\n  uint16_t maxProgressWidth = (width - doubleRadius + 1) * progress / 100;\n\n  fillCircle(xRadius, yRadius, innerRadius);\n  fillRect(xRadius + 1, y + 2, maxProgressWidth, height - 3);\n  fillCircle(xRadius + maxProgressWidth, yRadius, innerRadius);\n}\n\nvoid OLEDDisplay::drawFastImage(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *image) {\n  drawInternal(xMove, yMove, width, height, image, 0, 0);\n}\n\nvoid OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *xbm) {\n  int16_t widthInXbm = (width + 7) / 8;\n  uint8_t data = 0;\n\n  for(int16_t y = 0; y < height; y++) {\n    for(int16_t x = 0; x < width; x++ ) {\n      if (x & 7) {\n        data >>= 1; // Move a bit\n      } else {  // Read new data every 8 bit\n        data = pgm_read_byte(xbm + (x / 8) + y * widthInXbm);\n      }\n      // if there is a bit draw it\n      if (data & 0x01) {\n        setPixel(xMove + x, yMove + y);\n      }\n    }\n  }\n}\n\nvoid OLEDDisplay::drawIco16x16(int16_t xMove, int16_t yMove, const uint8_t *ico, bool inverse) {\n  uint16_t data;\n\n  for(int16_t y = 0; y < 16; y++) {\n    data = pgm_read_byte(ico + (y << 1)) + (pgm_read_byte(ico + (y << 1) + 1) << 8);\n    for(int16_t x = 0; x < 16; x++ ) {\n      if ((data & 0x01) ^ inverse) {\n        setPixelColor(xMove + x, yMove + y, WHITE);\n      } else {\n        setPixelColor(xMove + x, yMove + y, BLACK);\n      }\n      data >>= 1; // Move a bit\n    }\n  }\n}\n\nuint16_t OLEDDisplay::drawStringInternal(int16_t xMove, int16_t yMove, const char* text, uint16_t textLength, uint16_t textWidth, bool utf8) {\n  uint8_t textHeight       = pgm_read_byte(fontData + HEIGHT_POS);\n  uint8_t firstChar        = pgm_read_byte(fontData + FIRST_CHAR_POS);\n  uint16_t sizeOfJumpTable = pgm_read_byte(fontData + CHAR_NUM_POS)  * JUMPTABLE_BYTES;\n\n  uint16_t cursorX         = 0;\n  uint16_t cursorY         = 0;\n  uint16_t charCount       = 0;\n\n  switch (textAlignment) {\n    case TEXT_ALIGN_CENTER_BOTH:\n      yMove -= textHeight >> 1;\n    // Fallthrough\n    case TEXT_ALIGN_CENTER:\n      xMove -= textWidth >> 1; // divide by 2\n      break;\n    case TEXT_ALIGN_RIGHT:\n      xMove -= textWidth;\n      break;\n    case TEXT_ALIGN_LEFT:\n      break;\n  }\n\n  // Don't draw anything if it is not on the screen.\n  if (xMove + textWidth  < 0 || xMove >= this->width() ) {return 0;}\n  if (yMove + textHeight < 0 || yMove >= this->height()) {return 0;}\n\n  for (uint16_t j = 0; j < textLength; j++) {\n    int16_t xPos = xMove + cursorX;\n    int16_t yPos = yMove + cursorY;\n    if (xPos > this->width())\n      break; // no need to continue\n    charCount++;\n\n    uint8_t code;\n    if (utf8) {\n      code = (this->fontTableLookupFunction)(text[j]);\n      if (code == 0)\n        continue;\n    } else\n      code = text[j];\n    if (code >= firstChar) {\n      uint8_t charCode = code - firstChar;\n\n      // 4 Bytes per char code\n      uint8_t msbJumpToChar    = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES );                  // MSB  \\ JumpAddress\n      uint8_t lsbJumpToChar    = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB);   // LSB /\n      uint8_t charByteSize     = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE);  // Size\n      uint8_t currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH); // Width\n\n      // Test if the char is drawable\n      if (!(msbJumpToChar == 255 && lsbJumpToChar == 255)) {\n        // Get the position of the char data\n        uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ((msbJumpToChar << 8) + lsbJumpToChar);\n        drawInternal(xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize);\n      }\n\n      cursorX += currentCharWidth;\n    }\n  }\n  return charCount;\n}\n\n\nuint16_t OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String &strUser) {\n  uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);\n\n  // char* text must be freed!\n  char* text = strdup(strUser.c_str());\n  if (!text) {\n    DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][drawString] Can't allocate char array.\\n\");\n    return 0;\n  }\n\n  uint16_t yOffset = 0;\n  // If the string should be centered vertically too\n  // we need to now how heigh the string is.\n  if (textAlignment == TEXT_ALIGN_CENTER_BOTH) {\n    uint16_t lb = 0;\n    // Find number of linebreaks in text\n    for (uint16_t i=0;text[i] != 0; i++) {\n      lb += (text[i] == 10);\n    }\n    // Calculate center\n    yOffset = (lb * lineHeight) / 2;\n  }\n\n  uint16_t charDrawn = 0;\n  uint16_t line = 0;\n  char* textPart = strtok(text,\"\\n\");\n  while (textPart != NULL) {\n    uint16_t length = strlen(textPart);\n    charDrawn += drawStringInternal(xMove, yMove - yOffset + (line++) * lineHeight, textPart, length, getStringWidth(textPart, length, true), true);\n    textPart = strtok(NULL, \"\\n\");\n  }\n  free(text);\n  return charDrawn;\n}\n\nvoid OLEDDisplay::drawStringf( int16_t x, int16_t y, char* buffer, String format, ... )\n{\n  va_list myargs;\n  va_start(myargs, format);\n  vsprintf(buffer, format.c_str(), myargs);\n  va_end(myargs);\n  drawString( x, y, buffer );\n}\n\nuint16_t OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxLineWidth, const String &strUser) {\n  uint16_t firstChar  = pgm_read_byte(fontData + FIRST_CHAR_POS);\n  uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);\n\n  const char* text = strUser.c_str();\n\n  uint16_t length = strlen(text);\n  uint16_t lastDrawnPos = 0;\n  uint16_t lineNumber = 0;\n  uint16_t strWidth = 0;\n\n  uint16_t preferredBreakpoint = 0;\n  uint16_t widthAtBreakpoint = 0;\n  uint16_t firstLineChars = 0;\n  uint16_t drawStringResult = 1; // later tested for 0 == error, so initialize to 1\n\n  for (uint16_t i = 0; i < length; i++) {\n    char c = (this->fontTableLookupFunction)(text[i]);\n    if (c == 0)\n      continue;\n    strWidth += pgm_read_byte(fontData + JUMPTABLE_START + (c - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH);\n\n    // Always try to break on a space, dash or slash\n    if (text[i] == ' ' || text[i]== '-' || text[i] == '/') {\n      preferredBreakpoint = i + 1;\n      widthAtBreakpoint = strWidth;\n    }\n\n    if (strWidth >= maxLineWidth) {\n      if (preferredBreakpoint == 0) {\n        preferredBreakpoint = i;\n        widthAtBreakpoint = strWidth;\n      }\n      drawStringResult = drawStringInternal(xMove, yMove + (lineNumber++) * lineHeight , &text[lastDrawnPos], preferredBreakpoint - lastDrawnPos, widthAtBreakpoint, true);\n      if (firstLineChars == 0)\n        firstLineChars = preferredBreakpoint;\n      lastDrawnPos = preferredBreakpoint;\n      // It is possible that we did not draw all letters to i so we need\n      // to account for the width of the chars from `i - preferredBreakpoint`\n      // by calculating the width we did not draw yet.\n      strWidth = strWidth - widthAtBreakpoint;\n      preferredBreakpoint = 0;\n      if (drawStringResult == 0) // we are past the display already?\n        break;\n    }\n  }\n\n  // Draw last part if needed\n  if (drawStringResult != 0 && lastDrawnPos < length) {\n    drawStringResult = drawStringInternal(xMove, yMove + (lineNumber++) * lineHeight , &text[lastDrawnPos], length - lastDrawnPos, getStringWidth(&text[lastDrawnPos], length - lastDrawnPos, true), true);\n  }\n\n  if (drawStringResult == 0 || (yMove + lineNumber * lineHeight) >= this->height()) // text did not fit on screen\n    return firstLineChars;\n  return 0; // everything was drawn\n}\n\nuint16_t OLEDDisplay::getStringWidth(const char* text, uint16_t length, bool utf8) {\n  uint16_t firstChar        = pgm_read_byte(fontData + FIRST_CHAR_POS);\n\n  uint16_t stringWidth = 0;\n  uint16_t maxWidth = 0;\n\n  for (uint16_t i = 0; i < length; i++) {\n    char c = text[i];\n    if (utf8) {\n      c = (this->fontTableLookupFunction)(c);\n      if (c == 0)\n        continue;\n    }\n    stringWidth += pgm_read_byte(fontData + JUMPTABLE_START + (c - firstChar) * JUMPTABLE_BYTES + JUMPTABLE_WIDTH);\n    if (c == 10) {\n      maxWidth = max(maxWidth, stringWidth);\n      stringWidth = 0;\n    }\n  }\n\n  return max(maxWidth, stringWidth);\n}\n\nuint16_t OLEDDisplay::getStringWidth(const String &strUser) {\n  uint16_t width = getStringWidth(strUser.c_str(), strUser.length());\n  return width;\n}\n\nvoid OLEDDisplay::setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment) {\n  this->textAlignment = textAlignment;\n}\n\nvoid OLEDDisplay::setFont(const uint8_t *fontData) {\n  this->fontData = fontData;\n  // New font, so must recalculate. Whatever was there is gone at next print.\n  setLogBuffer();\n}\n\nvoid OLEDDisplay::setFont(const char *fontData) {\n  setFont(static_cast<const uint8_t*>(reinterpret_cast<const void*>(fontData)));\n}\n\nvoid OLEDDisplay::displayOn(void) {\n  sendCommand(DISPLAYON);\n}\n\nvoid OLEDDisplay::displayOff(void) {\n  sendCommand(DISPLAYOFF);\n}\n\nvoid OLEDDisplay::invertDisplay(void) {\n  sendCommand(INVERTDISPLAY);\n}\n\nvoid OLEDDisplay::normalDisplay(void) {\n  sendCommand(NORMALDISPLAY);\n}\n\nvoid OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect) {\n  sendCommand(SETPRECHARGE); //0xD9\n  sendCommand(precharge); //0xF1 default, to lower the contrast, put 1-1F\n  sendCommand(SETCONTRAST);\n  sendCommand(contrast); // 0-255\n  sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)\n  sendCommand(comdetect);\t//0x40 default, to lower the contrast, put 0\n  sendCommand(DISPLAYALLON_RESUME);\n  sendCommand(DISPLAYON);\n}\n\nvoid OLEDDisplay::setBrightness(uint8_t brightness) {\n  uint8_t contrast = brightness;\n  if (brightness < 128) {\n    // Magic values to get a smooth/ step-free transition\n    contrast = brightness * 1.171;\n  } else {\n    contrast = brightness * 1.171 - 43;\n  }\n\n  uint8_t precharge = 241;\n  if (brightness == 0) {\n    precharge = 0;\n  }\n  uint8_t comdetect = brightness / 8;\n\n  setContrast(contrast, precharge, comdetect);\n}\n\nvoid OLEDDisplay::resetOrientation() {\n  sendCommand(SEGREMAP);\n  sendCommand(COMSCANINC);           //Reset screen rotation or mirroring\n}\n\nvoid OLEDDisplay::flipScreenVertically() {\n  sendCommand(SEGREMAP | 0x01);\n  sendCommand(COMSCANDEC);           //Rotate screen 180 Deg\n}\n\nvoid OLEDDisplay::mirrorScreen() {\n  sendCommand(SEGREMAP);\n  sendCommand(COMSCANDEC);           //Mirror screen\n}\n\nvoid OLEDDisplay::clear(void) {\n  memset(buffer, 0, displayBufferSize);\n}\n\nvoid OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {\n#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)\n  Serial.println(\"[deprecated] Print functionality now handles buffer management automatically. This is a no-op.\");\n#endif\n}\n\nvoid OLEDDisplay::drawLogBuffer() {\n  uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);\n  // Always align left\n  setTextAlignment(TEXT_ALIGN_LEFT);\n\n  // State values\n  uint16_t length   = 0;\n  uint16_t line     = 0;\n  uint16_t lastPos  = 0;\n\n  // If the lineHeight and the display height are not cleanly divisible, we need\n  // to start off the screen when the buffer has logBufferMaxLines so that the\n  // first line, and not the last line, drops off.\n  uint16_t shiftUp = (this->logBufferLine == this->logBufferMaxLines) ? (lineHeight - (displayHeight % lineHeight)) % lineHeight : 0;\n\n  for (uint16_t i=0;i<this->logBufferFilled;i++){\n    length++;\n    // Everytime we have a \\n print\n    if (this->logBuffer[i] == 10) {\n      // Draw string on line `line` from lastPos to length\n      // Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT\n      drawStringInternal(0, 0 - shiftUp + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0, false);\n      // Remember last pos\n      lastPos = i;\n      // Reset length\n      length = 0;\n    }\n  }\n  // Draw the remaining string\n  if (length > 0) {\n    drawStringInternal(0, 0 - shiftUp + line * lineHeight, &this->logBuffer[lastPos], length, 0, false);\n  }\n}\n\nuint16_t OLEDDisplay::getWidth(void) {\n  return displayWidth;\n}\n\nuint16_t OLEDDisplay::getHeight(void) {\n  return displayHeight;\n}\n\nvoid OLEDDisplay::cls() {\n  clear();\n  this->logBufferFilled = 0;\n  this->logBufferLine = 0;\n  display();\n}\n\nbool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars) {\n#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)\n  Serial.println(\"[deprecated] Print functionality now handles buffer management automatically. This is a no-op.\");\n#endif\n  return true;\n}\n\nbool OLEDDisplay::setLogBuffer(){\n  // don't know how big we need it without a font set.\n  if (!fontData)\n\t\treturn false;\n  \n  // we're always starting over\n  if (logBuffer != NULL)\n    free(logBuffer);\n\n  // figure out how big it needs to be\n  uint8_t textHeight = pgm_read_byte(fontData + HEIGHT_POS);\n  if (!textHeight)\n    return false;  // Prevent division by zero crashes\n  uint16_t lines =  this->displayHeight / textHeight + (this->displayHeight % textHeight ? 1 : 0);\n  uint16_t chars =   5 * (this->displayWidth / textHeight);\n  uint16_t size = lines * (chars + 1);  // +1 is for \\n\n\n  // Something weird must have happened\n  if (size == 0) \n    return false;\n\n  // All good, initialize logBuffer\n  this->logBufferLine     = 0;      // Lines printed\n  this->logBufferFilled   = 0;      // Nothing stored yet\n  this->logBufferMaxLines = lines;  // Lines max printable\n  this->logBufferLineLen  = chars;  // Chars per line\n  this->logBufferSize     = size;   // Total number of characters the buffer can hold\n  this->logBuffer         = (char *) malloc(size * sizeof(uint8_t));\n  if(!this->logBuffer) {\n    DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\\n\");\n    return false;\n  }\n\n  return true;\n}\n\nsize_t OLEDDisplay::write(uint8_t c) {\n  if (!fontData)\n\t\treturn 1;\n    \n  // Create a logBuffer if there isn't one\n\tif (!logBufferSize) {\n    // Give up if we can't create a logBuffer somehow\n\t\tif (!setLogBuffer())\n      return 1;\n\t}\n\n  // Don't waste space on \\r\\n line endings, dropping \\r\n  if (c == 13) return 1;\n\n  // convert UTF-8 character to font table index\n  c = (this->fontTableLookupFunction)(c);\n  // drop unknown character\n  if (c == 0) return 1;\n\n  bool maxLineReached = this->logBufferLine >= this->logBufferMaxLines;\n  bool bufferFull = this->logBufferFilled >= this->logBufferSize;\n\n  // Can we write to the buffer? If not, make space.\n  if (bufferFull || maxLineReached) {\n    // See if we can chop off the first line\n    uint16_t firstLineEnd = 0;\n    for (uint16_t i = 0; i < this->logBufferFilled; i++) {\n      if (this->logBuffer[i] == 10){\n        // Include last char too\n        firstLineEnd = i + 1;\n        // Calculate the new logBufferFilled value\n        this->logBufferFilled = logBufferFilled - firstLineEnd;\n        // Now move other lines to front of the buffer\n        memcpy(this->logBuffer, &this->logBuffer[firstLineEnd], logBufferFilled);\n        // And voila, buffer one line shorter\n        this->logBufferLine--;\n        break;\n      }\n    }\n    // In we can't take off first line, we just empty the buffer\n    if (!firstLineEnd) {\n      this->logBufferFilled = 0;\n      this->logBufferLine = 0;\n    }\n  }\n\n  // So now we know for sure we have space in the buffer\n\n  // Find the length of the last line\n  uint16_t lastLineLen= 0;\n  for (uint16_t i = 0; i < this->logBufferFilled; i++) {\n    lastLineLen++;\n    if (this->logBuffer[i] == 10) lastLineLen = 0;\n  }\n  // if last line is max length, ignore anything but linebreaks\n  if (lastLineLen >= this->logBufferLineLen) {\n    if (c != 10) return 1;\n  }\n\n  // Write to buffer\n  this->logBuffer[this->logBufferFilled++] = c;\n  // Keep track of lines written\n  if (c == 10) this->logBufferLine++;\n\n  // Draw to screen unless we're writing a whole string at a time\n  if (!this->inhibitDrawLogBuffer) {\n    clear();\n    drawLogBuffer();\n    display();\n  }\n\n  // We always claim we printed it all\n  return 1;\n}\n\nsize_t OLEDDisplay::write(const char* str) {\n  if (str == NULL) return 0;\n  size_t length = strlen(str);\n  // If we write a string, only do the drawLogBuffer at the end, not every time we write a char\n  this->inhibitDrawLogBuffer = true;\n  for (size_t i = 0; i < length; i++) {\n    write(str[i]);\n  }\n  this->inhibitDrawLogBuffer = false;\n  clear();\n  drawLogBuffer();\n  display();\n  return length;\n}\n\n#ifdef __MBED__\nint OLEDDisplay::_putc(int c) {\n\treturn this->write((uint8_t)c);\n}\n#endif\n\n// Private functions\nvoid OLEDDisplay::setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) {\n  this->geometry = g;\n\n  switch (g) {\n    case GEOMETRY_128_64:\n      this->displayWidth = 128;\n      this->displayHeight = 64;\n      break;\n    case GEOMETRY_128_32:\n      this->displayWidth = 128;\n      this->displayHeight = 32;\n      break;\n    case GEOMETRY_64_48:\n      this->displayWidth = 64;\n      this->displayHeight = 48;\n      break;\n    case GEOMETRY_64_32:\n      this->displayWidth = 64;\n      this->displayHeight = 32;\n      break;\n    case GEOMETRY_RAWMODE:\n      this->displayWidth = width > 0 ? width : 128;\n      this->displayHeight = height > 0 ? height : 64;\n      break;\n  }\n  this->displayBufferSize = displayWidth * displayHeight / 8;\n}\n\nvoid OLEDDisplay::sendInitCommands(void) {\n  if (geometry == GEOMETRY_RAWMODE)\n  \treturn;\n  sendCommand(DISPLAYOFF);\n  sendCommand(SETDISPLAYCLOCKDIV);\n  sendCommand(0xF0); // Increase speed of the display max ~96Hz\n  sendCommand(SETMULTIPLEX);\n  sendCommand(this->height() - 1);\n  sendCommand(SETDISPLAYOFFSET);\n  sendCommand(0x00);\n  if(geometry == GEOMETRY_64_32)\n    sendCommand(0x00);\n  else\n    sendCommand(SETSTARTLINE);\n  sendCommand(CHARGEPUMP);\n  sendCommand(0x14);\n  sendCommand(MEMORYMODE);\n  sendCommand(0x00);\n  sendCommand(SEGREMAP);\n  sendCommand(COMSCANINC);\n  sendCommand(SETCOMPINS);\n\n  if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) {\n    sendCommand(0x12);\n  } else if (geometry == GEOMETRY_128_32) {\n    sendCommand(0x02);\n  }\n\n  sendCommand(SETCONTRAST);\n\n  if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) {\n    sendCommand(0xCF);\n  } else if (geometry == GEOMETRY_128_32) {\n    sendCommand(0x8F);\n  }\n\n  sendCommand(SETPRECHARGE);\n  sendCommand(0xF1);\n  sendCommand(SETVCOMDETECT); //0xDB, (additionally needed to lower the contrast)\n  sendCommand(0x40);\t        //0x40 default, to lower the contrast, put 0\n  sendCommand(DISPLAYALLON_RESUME);\n  sendCommand(NORMALDISPLAY);\n  sendCommand(0x2e);            // stop scroll\n  sendCommand(DISPLAYON);\n}\n\nvoid inline OLEDDisplay::drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) {\n  if (width < 0 || height < 0) return;\n  if (yMove + height < 0 || yMove > this->height())  return;\n  if (xMove + width  < 0 || xMove > this->width())   return;\n\n  uint8_t  rasterHeight = 1 + ((height - 1) >> 3); // fast ceil(height / 8.0)\n  int8_t   yOffset      = yMove & 7;\n\n  bytesInData = bytesInData == 0 ? width * rasterHeight : bytesInData;\n\n  int16_t initYMove   = yMove;\n  int8_t  initYOffset = yOffset;\n\n\n  for (uint16_t i = 0; i < bytesInData; i++) {\n\n    // Reset if next horizontal drawing phase is started.\n    if ( i % rasterHeight == 0) {\n      yMove   = initYMove;\n      yOffset = initYOffset;\n    }\n\n    uint8_t currentByte = pgm_read_byte(data + offset + i);\n\n    int16_t xPos = xMove + (i / rasterHeight);\n    int16_t yPos = ((yMove >> 3) + (i % rasterHeight)) * this->width();\n\n//    int16_t yScreenPos = yMove + yOffset;\n    int16_t dataPos    = xPos  + yPos;\n\n    if (dataPos >=  0  && dataPos < displayBufferSize &&\n        xPos    >=  0  && xPos    < this->width() ) {\n\n      if (yOffset >= 0) {\n        switch (this->color) {\n          case WHITE:   buffer[dataPos] |= currentByte << yOffset; break;\n          case BLACK:   buffer[dataPos] &= ~(currentByte << yOffset); break;\n          case INVERSE: buffer[dataPos] ^= currentByte << yOffset; break;\n        }\n\n        if (dataPos < (displayBufferSize - this->width())) {\n          switch (this->color) {\n            case WHITE:   buffer[dataPos + this->width()] |= currentByte >> (8 - yOffset); break;\n            case BLACK:   buffer[dataPos + this->width()] &= ~(currentByte >> (8 - yOffset)); break;\n            case INVERSE: buffer[dataPos + this->width()] ^= currentByte >> (8 - yOffset); break;\n          }\n        }\n      } else {\n        // Make new offset position\n        yOffset = -yOffset;\n\n        switch (this->color) {\n          case WHITE:   buffer[dataPos] |= currentByte >> yOffset; break;\n          case BLACK:   buffer[dataPos] &= ~(currentByte >> yOffset); break;\n          case INVERSE: buffer[dataPos] ^= currentByte >> yOffset; break;\n        }\n\n        // Prepare for next iteration by moving one block up\n        yMove -= 8;\n\n        // and setting the new yOffset\n        yOffset = 8 - yOffset;\n      }\n#ifndef __MBED__\n      yield();\n#endif\n    }\n  }\n}\n\n// You need to free the char!\nchar* OLEDDisplay::utf8ascii(const String &str) {\n  uint16_t k = 0;\n  uint16_t length = str.length() + 1;\n\n  // Copy the string into a char array\n  char* s = (char*) malloc(length * sizeof(char));\n  if(!s) {\n    DEBUG_OLEDDISPLAY(\"[OLEDDISPLAY][utf8ascii] Can't allocate another char array. Drop support for UTF-8.\\n\");\n    return (char*) str.c_str();\n  }\n  str.toCharArray(s, length);\n\n  length--;\n\n  for (uint16_t i=0; i < length; i++) {\n    char c = (this->fontTableLookupFunction)(s[i]);\n    if (c!=0) {\n      s[k++]=c;\n    }\n  }\n\n  s[k]=0;\n\n  // This will leak 's' be sure to free it in the calling function.\n  return s;\n}\n\nvoid OLEDDisplay::setFontTableLookupFunction(FontTableLookupFunction function) {\n  this->fontTableLookupFunction = function;\n}\n\n\nchar DefaultFontTableLookup(const uint8_t ch) {\n    // UTF-8 to font table index converter\n    // Code form http://playground.arduino.cc/Main/Utf8ascii\n\tstatic uint8_t LASTCHAR;\n\n\tif (ch < 128) { // Standard ASCII-set 0..0x7F handling\n\t\tLASTCHAR = 0;\n\t\treturn ch;\n\t}\n\n\tuint8_t last = LASTCHAR;   // get last char\n\tLASTCHAR = ch;\n\n\tswitch (last) {    // conversion depnding on first UTF8-character\n\t\tcase 0xC2: return (uint8_t) ch;\n\t\tcase 0xC3: return (uint8_t) (ch | 0xC0);\n\t\tcase 0x82: if (ch == 0xAC) return (uint8_t) 0x80;    // special case Euro-symbol\n\t}\n\n\treturn (uint8_t) 0; // otherwise: return zero, if character has to be ignored\n}\n"
  },
  {
    "path": "src/OLEDDisplay.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef OLEDDISPLAY_h\n#define OLEDDISPLAY_h\n\n#ifdef ARDUINO\n#include <Arduino.h>\n#elif __MBED__\n#define pgm_read_byte(addr)   (*(const unsigned char *)(addr))\n\n#include <mbed.h>\n#define delay(x)\twait_ms(x)\n#define yield()\t\tvoid()\n\n/*\n * This is a little Arduino String emulation to keep the OLEDDisplay\n * library code in common between Arduino and mbed-os\n */\nclass String {\npublic:\n\tString(const char *s) { _str = s; };\n\tint length() { return strlen(_str); };\n\tconst char *c_str() { return _str; };\n    void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {\n\t\tmemcpy(buf, _str + index,  std::min(bufsize, strlen(_str)));\n\t};\nprivate:\n\tconst char *_str;\n};\n\n#else\n#error \"Unkown operating system\"\n#endif\n\n#include \"OLEDDisplayFonts.h\"\n\n//#define DEBUG_OLEDDISPLAY(...) Serial.printf( __VA_ARGS__ )\n//#define DEBUG_OLEDDISPLAY(...) dprintf(\"%s\",  __VA_ARGS__ )\n\n#ifndef DEBUG_OLEDDISPLAY\n#define DEBUG_OLEDDISPLAY(...)\n#endif\n\n// Use DOUBLE BUFFERING by default\n#ifndef OLEDDISPLAY_REDUCE_MEMORY\n#define OLEDDISPLAY_DOUBLE_BUFFER\n#endif\n\n// Header Values\n#define JUMPTABLE_BYTES 4\n\n#define JUMPTABLE_LSB   1\n#define JUMPTABLE_SIZE  2\n#define JUMPTABLE_WIDTH 3\n#define JUMPTABLE_START 4\n\n#define WIDTH_POS 0\n#define HEIGHT_POS 1\n#define FIRST_CHAR_POS 2\n#define CHAR_NUM_POS 3\n\n\n// Display commands\n#define CHARGEPUMP 0x8D\n#define COLUMNADDR 0x21\n#define COMSCANDEC 0xC8\n#define COMSCANINC 0xC0\n#define DISPLAYALLON 0xA5\n#define DISPLAYALLON_RESUME 0xA4\n#define DISPLAYOFF 0xAE\n#define DISPLAYON 0xAF\n#define EXTERNALVCC 0x1\n#define INVERTDISPLAY 0xA7\n#define MEMORYMODE 0x20\n#define NORMALDISPLAY 0xA6\n#define PAGEADDR 0x22\n#define SEGREMAP 0xA0\n#define SETCOMPINS 0xDA\n#define SETCONTRAST 0x81\n#define SETDISPLAYCLOCKDIV 0xD5\n#define SETDISPLAYOFFSET 0xD3\n#define SETHIGHCOLUMN 0x10\n#define SETLOWCOLUMN 0x00\n#define SETMULTIPLEX 0xA8\n#define SETPRECHARGE 0xD9\n#define SETSEGMENTREMAP 0xA1\n#define SETSTARTLINE 0x40\n#define SETVCOMDETECT 0xDB\n#define SWITCHCAPVCC 0x2\n\n#ifndef _swap_int16_t\n#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }\n#endif\n\nenum OLEDDISPLAY_COLOR {\n  BLACK = 0,\n  WHITE = 1,\n  INVERSE = 2\n};\n\nenum OLEDDISPLAY_TEXT_ALIGNMENT {\n  TEXT_ALIGN_LEFT = 0,\n  TEXT_ALIGN_RIGHT = 1,\n  TEXT_ALIGN_CENTER = 2,\n  TEXT_ALIGN_CENTER_BOTH = 3\n};\n\n\nenum OLEDDISPLAY_GEOMETRY {\n  GEOMETRY_128_64   = 0,\n  GEOMETRY_128_32   = 1,\n  GEOMETRY_64_48    = 2,\n  GEOMETRY_64_32    = 3,\n  GEOMETRY_RAWMODE  = 4\n};\n\nenum HW_I2C {\n  I2C_ONE,\n  I2C_TWO\n};\n\ntypedef char (*FontTableLookupFunction)(const uint8_t ch);\nchar DefaultFontTableLookup(const uint8_t ch);\n\n\n#ifdef ARDUINO\nclass OLEDDisplay : public Print  {\n#elif __MBED__\nclass OLEDDisplay : public Stream {\n#else\n#error \"Unkown operating system\"\n#endif\n\n  public:\n\tOLEDDisplay();\n    virtual ~OLEDDisplay();\n\n\tuint16_t width(void) const { return displayWidth; };\n\tuint16_t height(void) const { return displayHeight; };\n\n    // Use this to resume after a deep sleep without resetting the display (what init() would do).\n    // Returns true if connection to the display was established and the buffer allocated, false otherwise.\n    bool allocateBuffer();\n\n    // Allocates the buffer and initializes the driver & display. Resets the display!\n    // Returns false if buffer allocation failed, true otherwise.\n    bool init();\n\n    // Free the memory used by the display\n    void end();\n\n    // Cycle through the initialization\n    void resetDisplay(void);\n\n    /* Drawing functions */\n    // Sets the color of all pixel operations\n    void setColor(OLEDDISPLAY_COLOR color);\n\n    // Returns the current color.\n    OLEDDISPLAY_COLOR getColor();\n\n    // Draw a pixel at given position\n    void setPixel(int16_t x, int16_t y);\n\n    // Draw a pixel at given position and color\n    void setPixelColor(int16_t x, int16_t y, OLEDDISPLAY_COLOR color);\n\n    // Clear a pixel at given position FIXME: INVERSE is untested with this function\n    void clearPixel(int16_t x, int16_t y);\n\n    // Draw a line from position 0 to position 1\n    void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);\n\n    // Draw the border of a rectangle at the given location\n    void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n    // Fill the rectangle\n    void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n    // Draw the border of a circle\n    void drawCircle(int16_t x, int16_t y, int16_t radius);\n\n    // Draw all Quadrants specified in the quads bit mask\n    void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads);\n\n    // Fill circle\n    void fillCircle(int16_t x, int16_t y, int16_t radius);\n\n    // Draw an empty triangle i.e. only the outline\n    void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n    // Draw a solid triangle i.e. filled\n    void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n    // Draw a line horizontally\n    void drawHorizontalLine(int16_t x, int16_t y, int16_t length);\n\n    // Draw a line vertically\n    void drawVerticalLine(int16_t x, int16_t y, int16_t length);\n\n    // Draws a rounded progress bar with the outer dimensions given by width and height. Progress is\n    // a unsigned byte value between 0 and 100\n    void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);\n\n    // Draw a bitmap in the internal image format\n    void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);\n\n    // Draw a XBM\n    void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);\n\n    // Draw icon 16x16 xbm format\n    void drawIco16x16(int16_t x, int16_t y, const uint8_t *ico, bool inverse = false);\n\n    /* Text functions */\n\n    // Draws a string at the given location, returns how many chars have been written\n    uint16_t drawString(int16_t x, int16_t y, const String &text);\n\n    // Draws a formatted string (like printf) at the given location\n    void drawStringf(int16_t x, int16_t y, char* buffer, String format, ... );\n\n    // Draws a String with a maximum width at the given location.\n    // If the given String is wider than the specified width\n    // The text will be wrapped to the next line at a space or dash\n    // returns 0 if everything fits on the screen or the numbers of characters in the\n    // first line if not\n    uint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text);\n\n    // Returns the width of the const char* with the current\n    // font settings\n    uint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false);\n\n    // Convencience method for the const char version\n    uint16_t getStringWidth(const String &text);\n\n    // Specifies relative to which anchor point\n    // the text is rendered. Available constants:\n    // TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH\n    void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);\n\n    // Sets the current font. Available default fonts\n    // ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24\n    void setFont(const uint8_t *fontData);\n\n    // Set the current font when supplied as a char* instead of a uint8_t*\n    void setFont(const char *fontData);\n\n    // Set the function that will convert utf-8 to font table index\n    void setFontTableLookupFunction(FontTableLookupFunction function);\n\n    /* Display functions */\n\n    // Turn the display on\n    void displayOn(void);\n\n    // Turn the display offs\n    void displayOff(void);\n\n    // Inverted display mode\n    void invertDisplay(void);\n\n    // Normal display mode\n    void normalDisplay(void);\n\n    // Set display contrast\n    // really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0\n    // normal brightness & contrast:  contrast = 100\n    void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);\n\n    // Convenience method to access setContrast with only brightness parameter\n    void setBrightness(uint8_t);\n\n    // Reset display rotation or mirroring\n    void resetOrientation();\n\n    // Turn the display upside down\n    void flipScreenVertically();\n\n    // Mirror the display (to be used in a mirror or as a projector)\n    void mirrorScreen();\n\n    // Write the buffer to the display memory\n    virtual void display(void) = 0;\n\n    // Clear the local pixel buffer\n    void clear(void);\n\n    // Print class device\n\n    // Because this display class is \"derived\" from Arduino's Print class,\n    // various function that work on it also work here. These functions include\n    // print, println and printf. \n\n    // cls() will clear the display immediately and empty the logBuffer, meaning\n    // the next print statement will print at the top of the display again.\n    // cls() should not be confused with clear(), which only clears the internal\n    // graphics buffer, which can then be shown on the display with display().\n    void cls();\n\n    // Replaced by setLogBuffer() , which is protected\n    bool setLogBuffer(uint16_t lines, uint16_t chars);\n\n    // Draw the log buffer at position (x, y)\n    //\n    // (Automatically called with you use print, println or printf)\n    void drawLogBuffer(uint16_t x, uint16_t y);\n\n    // Get screen geometry\n    uint16_t getWidth(void);\n    uint16_t getHeight(void);\n\n    // Implement needed function to be compatible with Print class\n    size_t write(uint8_t c);\n    size_t write(const char* s);\n\n    // Implement needed function to be compatible with Stream class\n#ifdef __MBED__\n\tint _putc(int c);\n\tint _getc() { return -1; };\n#endif\n\n\n    uint8_t            *buffer;\n\n    #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n    uint8_t            *buffer_back;\n    #endif\n\n  protected:\n\n    OLEDDISPLAY_GEOMETRY geometry;\n\n    uint16_t  displayWidth;\n    uint16_t  displayHeight;\n    uint16_t  displayBufferSize;\n\n    // Set the correct height, width and buffer for the geometry\n    void setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width = 0, uint16_t height = 0);\n\n    OLEDDISPLAY_TEXT_ALIGNMENT   textAlignment;\n    OLEDDISPLAY_COLOR            color;\n\n    const uint8_t\t *fontData;\n\n    // State values for logBuffer\n    uint16_t   logBufferSize;\n    uint16_t   logBufferFilled;\n    uint16_t   logBufferLine;\n    uint16_t   logBufferMaxLines;\n    uint16_t   logBufferLineLen;\n    char      *logBuffer;\n    bool      inhibitDrawLogBuffer;\n\n\n\t// the header size of the buffer used, e.g. for the SPI command header\n  int BufferOffset;\n\tvirtual int getBufferOffset(void) = 0;\n\n    // Send a command to the display (low level function)\n    virtual void sendCommand(uint8_t com) {(void)com;};\n\n    // Connect to the display\n    virtual bool connect() { return false; };\n\n    // Send all the init commands\n    void sendInitCommands();\n\n    // converts utf8 characters to extended ascii\n    char* utf8ascii(const String &s);\n\n    void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));\n\n    uint16_t drawStringInternal(int16_t xMove, int16_t yMove, const char* text, uint16_t textLength, uint16_t textWidth, bool utf8);\n\n    // (re)creates the logBuffer that printing uses to remember what was on the\n    // screen already \n    bool setLogBuffer();\n\n    // Draws the contents of the logBuffer to the screen\n    void drawLogBuffer();\n\n\tFontTableLookupFunction fontTableLookupFunction;\n};\n\n#endif\n"
  },
  {
    "path": "src/OLEDDisplayFonts.h",
    "content": "#ifndef OLEDDISPLAYFONTS_h\n#define OLEDDISPLAYFONTS_h\n\n#ifdef __MBED__\n#define PROGMEM\n#endif\n\nconst uint8_t ArialMT_Plain_10[] PROGMEM = {\n  0x0A, // Width: 10\n  0x0D, // Height: 13\n  0x20, // First Char: 32\n  0xE0, // Numbers of Chars: 224\n\n  // Jump Table:\n  0xFF, 0xFF, 0x00, 0x03,  // 32:65535\n  0x00, 0x00, 0x04, 0x03,  // 33:0\n  0x00, 0x04, 0x05, 0x04,  // 34:4\n  0x00, 0x09, 0x09, 0x06,  // 35:9\n  0x00, 0x12, 0x0A, 0x06,  // 36:18\n  0x00, 0x1C, 0x10, 0x09,  // 37:28\n  0x00, 0x2C, 0x0E, 0x07,  // 38:44\n  0x00, 0x3A, 0x01, 0x02,  // 39:58\n  0x00, 0x3B, 0x06, 0x03,  // 40:59\n  0x00, 0x41, 0x06, 0x03,  // 41:65\n  0x00, 0x47, 0x05, 0x04,  // 42:71\n  0x00, 0x4C, 0x09, 0x06,  // 43:76\n  0x00, 0x55, 0x04, 0x03,  // 44:85\n  0x00, 0x59, 0x03, 0x03,  // 45:89\n  0x00, 0x5C, 0x04, 0x03,  // 46:92\n  0x00, 0x60, 0x05, 0x03,  // 47:96\n  0x00, 0x65, 0x0A, 0x06,  // 48:101\n  0x00, 0x6F, 0x08, 0x06,  // 49:111\n  0x00, 0x77, 0x0A, 0x06,  // 50:119\n  0x00, 0x81, 0x0A, 0x06,  // 51:129\n  0x00, 0x8B, 0x0B, 0x06,  // 52:139\n  0x00, 0x96, 0x0A, 0x06,  // 53:150\n  0x00, 0xA0, 0x0A, 0x06,  // 54:160\n  0x00, 0xAA, 0x09, 0x06,  // 55:170\n  0x00, 0xB3, 0x0A, 0x06,  // 56:179\n  0x00, 0xBD, 0x0A, 0x06,  // 57:189\n  0x00, 0xC7, 0x04, 0x03,  // 58:199\n  0x00, 0xCB, 0x04, 0x03,  // 59:203\n  0x00, 0xCF, 0x0A, 0x06,  // 60:207\n  0x00, 0xD9, 0x09, 0x06,  // 61:217\n  0x00, 0xE2, 0x09, 0x06,  // 62:226\n  0x00, 0xEB, 0x0B, 0x06,  // 63:235\n  0x00, 0xF6, 0x14, 0x0A,  // 64:246\n  0x01, 0x0A, 0x0E, 0x07,  // 65:266\n  0x01, 0x18, 0x0C, 0x07,  // 66:280\n  0x01, 0x24, 0x0C, 0x07,  // 67:292\n  0x01, 0x30, 0x0B, 0x07,  // 68:304\n  0x01, 0x3B, 0x0C, 0x07,  // 69:315\n  0x01, 0x47, 0x09, 0x06,  // 70:327\n  0x01, 0x50, 0x0D, 0x08,  // 71:336\n  0x01, 0x5D, 0x0C, 0x07,  // 72:349\n  0x01, 0x69, 0x04, 0x03,  // 73:361\n  0x01, 0x6D, 0x08, 0x05,  // 74:365\n  0x01, 0x75, 0x0E, 0x07,  // 75:373\n  0x01, 0x83, 0x0C, 0x06,  // 76:387\n  0x01, 0x8F, 0x10, 0x08,  // 77:399\n  0x01, 0x9F, 0x0C, 0x07,  // 78:415\n  0x01, 0xAB, 0x0E, 0x08,  // 79:427\n  0x01, 0xB9, 0x0B, 0x07,  // 80:441\n  0x01, 0xC4, 0x0E, 0x08,  // 81:452\n  0x01, 0xD2, 0x0C, 0x07,  // 82:466\n  0x01, 0xDE, 0x0C, 0x07,  // 83:478\n  0x01, 0xEA, 0x0B, 0x06,  // 84:490\n  0x01, 0xF5, 0x0C, 0x07,  // 85:501\n  0x02, 0x01, 0x0D, 0x07,  // 86:513\n  0x02, 0x0E, 0x11, 0x09,  // 87:526\n  0x02, 0x1F, 0x0E, 0x07,  // 88:543\n  0x02, 0x2D, 0x0D, 0x07,  // 89:557\n  0x02, 0x3A, 0x0C, 0x06,  // 90:570\n  0x02, 0x46, 0x06, 0x03,  // 91:582\n  0x02, 0x4C, 0x06, 0x03,  // 92:588\n  0x02, 0x52, 0x04, 0x03,  // 93:594\n  0x02, 0x56, 0x09, 0x05,  // 94:598\n  0x02, 0x5F, 0x0C, 0x06,  // 95:607\n  0x02, 0x6B, 0x03, 0x03,  // 96:619\n  0x02, 0x6E, 0x0A, 0x06,  // 97:622\n  0x02, 0x78, 0x0A, 0x06,  // 98:632\n  0x02, 0x82, 0x0A, 0x05,  // 99:642\n  0x02, 0x8C, 0x0A, 0x06,  // 100:652\n  0x02, 0x96, 0x0A, 0x06,  // 101:662\n  0x02, 0xA0, 0x05, 0x03,  // 102:672\n  0x02, 0xA5, 0x0A, 0x06,  // 103:677\n  0x02, 0xAF, 0x0A, 0x06,  // 104:687\n  0x02, 0xB9, 0x04, 0x02,  // 105:697\n  0x02, 0xBD, 0x04, 0x02,  // 106:701\n  0x02, 0xC1, 0x08, 0x05,  // 107:705\n  0x02, 0xC9, 0x04, 0x02,  // 108:713\n  0x02, 0xCD, 0x10, 0x08,  // 109:717\n  0x02, 0xDD, 0x0A, 0x06,  // 110:733\n  0x02, 0xE7, 0x0A, 0x06,  // 111:743\n  0x02, 0xF1, 0x0A, 0x06,  // 112:753\n  0x02, 0xFB, 0x0A, 0x06,  // 113:763\n  0x03, 0x05, 0x05, 0x03,  // 114:773\n  0x03, 0x0A, 0x08, 0x05,  // 115:778\n  0x03, 0x12, 0x06, 0x03,  // 116:786\n  0x03, 0x18, 0x0A, 0x06,  // 117:792\n  0x03, 0x22, 0x09, 0x05,  // 118:802\n  0x03, 0x2B, 0x0E, 0x07,  // 119:811\n  0x03, 0x39, 0x0A, 0x05,  // 120:825\n  0x03, 0x43, 0x09, 0x05,  // 121:835\n  0x03, 0x4C, 0x0A, 0x05,  // 122:844\n  0x03, 0x56, 0x06, 0x03,  // 123:854\n  0x03, 0x5C, 0x04, 0x03,  // 124:860\n  0x03, 0x60, 0x05, 0x03,  // 125:864\n  0x03, 0x65, 0x09, 0x06,  // 126:869\n  0xFF, 0xFF, 0x00, 0x00,  // 127:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 128:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 129:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 130:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 131:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 132:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 133:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 134:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 135:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 136:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 137:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 138:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 139:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 140:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 141:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 142:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 143:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 144:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 145:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 146:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 147:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 148:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 149:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 150:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 151:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 152:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 153:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 154:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 155:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 156:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 157:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 158:65535\n  0xFF, 0xFF, 0x00, 0x0A,  // 159:65535\n  0xFF, 0xFF, 0x00, 0x03,  // 160:65535\n  0x03, 0x6E, 0x04, 0x03,  // 161:878\n  0x03, 0x72, 0x0A, 0x06,  // 162:882\n  0x03, 0x7C, 0x0C, 0x06,  // 163:892\n  0x03, 0x88, 0x0A, 0x06,  // 164:904\n  0x03, 0x92, 0x0A, 0x06,  // 165:914\n  0x03, 0x9C, 0x04, 0x03,  // 166:924\n  0x03, 0xA0, 0x0A, 0x06,  // 167:928\n  0x03, 0xAA, 0x05, 0x03,  // 168:938\n  0x03, 0xAF, 0x0D, 0x07,  // 169:943\n  0x03, 0xBC, 0x07, 0x04,  // 170:956\n  0x03, 0xC3, 0x0A, 0x06,  // 171:963\n  0x03, 0xCD, 0x09, 0x06,  // 172:973\n  0x03, 0xD6, 0x03, 0x03,  // 173:982\n  0x03, 0xD9, 0x0D, 0x07,  // 174:985\n  0x03, 0xE6, 0x0B, 0x06,  // 175:998\n  0x03, 0xF1, 0x07, 0x04,  // 176:1009\n  0x03, 0xF8, 0x0A, 0x05,  // 177:1016\n  0x04, 0x02, 0x05, 0x03,  // 178:1026\n  0x04, 0x07, 0x05, 0x03,  // 179:1031\n  0x04, 0x0C, 0x05, 0x03,  // 180:1036\n  0x04, 0x11, 0x0A, 0x06,  // 181:1041\n  0x04, 0x1B, 0x09, 0x05,  // 182:1051\n  0x04, 0x24, 0x03, 0x03,  // 183:1060\n  0x04, 0x27, 0x06, 0x03,  // 184:1063\n  0x04, 0x2D, 0x05, 0x03,  // 185:1069\n  0x04, 0x32, 0x07, 0x04,  // 186:1074\n  0x04, 0x39, 0x0A, 0x06,  // 187:1081\n  0x04, 0x43, 0x10, 0x08,  // 188:1091\n  0x04, 0x53, 0x10, 0x08,  // 189:1107\n  0x04, 0x63, 0x10, 0x08,  // 190:1123\n  0x04, 0x73, 0x0A, 0x06,  // 191:1139\n  0x04, 0x7D, 0x0E, 0x07,  // 192:1149\n  0x04, 0x8B, 0x0E, 0x07,  // 193:1163\n  0x04, 0x99, 0x0E, 0x07,  // 194:1177\n  0x04, 0xA7, 0x0E, 0x07,  // 195:1191\n  0x04, 0xB5, 0x0E, 0x07,  // 196:1205\n  0x04, 0xC3, 0x0E, 0x07,  // 197:1219\n  0x04, 0xD1, 0x12, 0x0A,  // 198:1233\n  0x04, 0xE3, 0x0C, 0x07,  // 199:1251\n  0x04, 0xEF, 0x0C, 0x07,  // 200:1263\n  0x04, 0xFB, 0x0C, 0x07,  // 201:1275\n  0x05, 0x07, 0x0C, 0x07,  // 202:1287\n  0x05, 0x13, 0x0C, 0x07,  // 203:1299\n  0x05, 0x1F, 0x05, 0x03,  // 204:1311\n  0x05, 0x24, 0x04, 0x03,  // 205:1316\n  0x05, 0x28, 0x04, 0x03,  // 206:1320\n  0x05, 0x2C, 0x05, 0x03,  // 207:1324\n  0x05, 0x31, 0x0B, 0x07,  // 208:1329\n  0x05, 0x3C, 0x0C, 0x07,  // 209:1340\n  0x05, 0x48, 0x0E, 0x08,  // 210:1352\n  0x05, 0x56, 0x0E, 0x08,  // 211:1366\n  0x05, 0x64, 0x0E, 0x08,  // 212:1380\n  0x05, 0x72, 0x0E, 0x08,  // 213:1394\n  0x05, 0x80, 0x0E, 0x08,  // 214:1408\n  0x05, 0x8E, 0x0A, 0x06,  // 215:1422\n  0x05, 0x98, 0x0D, 0x08,  // 216:1432\n  0x05, 0xA5, 0x0C, 0x07,  // 217:1445\n  0x05, 0xB1, 0x0C, 0x07,  // 218:1457\n  0x05, 0xBD, 0x0C, 0x07,  // 219:1469\n  0x05, 0xC9, 0x0C, 0x07,  // 220:1481\n  0x05, 0xD5, 0x0D, 0x07,  // 221:1493\n  0x05, 0xE2, 0x0B, 0x07,  // 222:1506\n  0x05, 0xED, 0x0C, 0x06,  // 223:1517\n  0x05, 0xF9, 0x0A, 0x06,  // 224:1529\n  0x06, 0x03, 0x0A, 0x06,  // 225:1539\n  0x06, 0x0D, 0x0A, 0x06,  // 226:1549\n  0x06, 0x17, 0x0A, 0x06,  // 227:1559\n  0x06, 0x21, 0x0A, 0x06,  // 228:1569\n  0x06, 0x2B, 0x0A, 0x06,  // 229:1579\n  0x06, 0x35, 0x10, 0x09,  // 230:1589\n  0x06, 0x45, 0x0A, 0x05,  // 231:1605\n  0x06, 0x4F, 0x0A, 0x06,  // 232:1615\n  0x06, 0x59, 0x0A, 0x06,  // 233:1625\n  0x06, 0x63, 0x0A, 0x06,  // 234:1635\n  0x06, 0x6D, 0x0A, 0x06,  // 235:1645\n  0x06, 0x77, 0x05, 0x03,  // 236:1655\n  0x06, 0x7C, 0x04, 0x03,  // 237:1660\n  0x06, 0x80, 0x05, 0x03,  // 238:1664\n  0x06, 0x85, 0x05, 0x03,  // 239:1669\n  0x06, 0x8A, 0x0A, 0x06,  // 240:1674\n  0x06, 0x94, 0x0A, 0x06,  // 241:1684\n  0x06, 0x9E, 0x0A, 0x06,  // 242:1694\n  0x06, 0xA8, 0x0A, 0x06,  // 243:1704\n  0x06, 0xB2, 0x0A, 0x06,  // 244:1714\n  0x06, 0xBC, 0x0A, 0x06,  // 245:1724\n  0x06, 0xC6, 0x0A, 0x06,  // 246:1734\n  0x06, 0xD0, 0x09, 0x05,  // 247:1744\n  0x06, 0xD9, 0x0A, 0x06,  // 248:1753\n  0x06, 0xE3, 0x0A, 0x06,  // 249:1763\n  0x06, 0xED, 0x0A, 0x06,  // 250:1773\n  0x06, 0xF7, 0x0A, 0x06,  // 251:1783\n  0x07, 0x01, 0x0A, 0x06,  // 252:1793\n  0x07, 0x0B, 0x09, 0x05,  // 253:1803\n  0x07, 0x14, 0x0A, 0x06,  // 254:1812\n  0x07, 0x1E, 0x09, 0x05,  // 255:1822\n\n  // Font Data:\n  0x00,0x00,0xF8,0x02,  // 33\n  0x38,0x00,0x00,0x00,0x38, // 34\n  0xA0,0x03,0xE0,0x00,0xB8,0x03,0xE0,0x00,0xB8, // 35\n  0x30,0x01,0x28,0x02,0xF8,0x07,0x48,0x02,0x90,0x01,  // 36\n  0x00,0x00,0x30,0x00,0x48,0x00,0x30,0x03,0xC0,0x00,0xB0,0x01,0x48,0x02,0x80,0x01,  // 37\n  0x80,0x01,0x50,0x02,0x68,0x02,0xA8,0x02,0x18,0x01,0x80,0x03,0x80,0x02,  // 38\n  0x38, // 39\n  0xE0,0x03,0x10,0x04,0x08,0x08,  // 40\n  0x08,0x08,0x10,0x04,0xE0,0x03,  // 41\n  0x28,0x00,0x18,0x00,0x28, // 42\n  0x40,0x00,0x40,0x00,0xF0,0x01,0x40,0x00,0x40, // 43\n  0x00,0x00,0x00,0x06,  // 44\n  0x80,0x00,0x80, // 45\n  0x00,0x00,0x00,0x02,  // 46\n  0x00,0x03,0xE0,0x00,0x18, // 47\n  0xF0,0x01,0x08,0x02,0x08,0x02,0x08,0x02,0xF0,0x01,  // 48\n  0x00,0x00,0x20,0x00,0x10,0x00,0xF8,0x03,  // 49\n  0x10,0x02,0x08,0x03,0x88,0x02,0x48,0x02,0x30,0x02,  // 50\n  0x10,0x01,0x08,0x02,0x48,0x02,0x48,0x02,0xB0,0x01,  // 51\n  0xC0,0x00,0xA0,0x00,0x90,0x00,0x88,0x00,0xF8,0x03,0x80, // 52\n  0x60,0x01,0x38,0x02,0x28,0x02,0x28,0x02,0xC8,0x01,  // 53\n  0xF0,0x01,0x28,0x02,0x28,0x02,0x28,0x02,0xD0,0x01,  // 54\n  0x08,0x00,0x08,0x03,0xC8,0x00,0x38,0x00,0x08, // 55\n  0xB0,0x01,0x48,0x02,0x48,0x02,0x48,0x02,0xB0,0x01,  // 56\n  0x70,0x01,0x88,0x02,0x88,0x02,0x88,0x02,0xF0,0x01,  // 57\n  0x00,0x00,0x20,0x02,  // 58\n  0x00,0x00,0x20,0x06,  // 59\n  0x00,0x00,0x40,0x00,0xA0,0x00,0xA0,0x00,0x10,0x01,  // 60\n  0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0, // 61\n  0x00,0x00,0x10,0x01,0xA0,0x00,0xA0,0x00,0x40, // 62\n  0x10,0x00,0x08,0x00,0x08,0x00,0xC8,0x02,0x48,0x00,0x30, // 63\n  0x00,0x00,0xC0,0x03,0x30,0x04,0xD0,0x09,0x28,0x0A,0x28,0x0A,0xC8,0x0B,0x68,0x0A,0x10,0x05,0xE0,0x04,  // 64\n  0x00,0x02,0xC0,0x01,0xB0,0x00,0x88,0x00,0xB0,0x00,0xC0,0x01,0x00,0x02,  // 65\n  0x00,0x00,0xF8,0x03,0x48,0x02,0x48,0x02,0x48,0x02,0xF0,0x01,  // 66\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x08,0x02,0x08,0x02,0x10,0x01,  // 67\n  0x00,0x00,0xF8,0x03,0x08,0x02,0x08,0x02,0x10,0x01,0xE0, // 68\n  0x00,0x00,0xF8,0x03,0x48,0x02,0x48,0x02,0x48,0x02,0x48,0x02,  // 69\n  0x00,0x00,0xF8,0x03,0x48,0x00,0x48,0x00,0x08, // 70\n  0x00,0x00,0xE0,0x00,0x10,0x01,0x08,0x02,0x48,0x02,0x50,0x01,0xC0, // 71\n  0x00,0x00,0xF8,0x03,0x40,0x00,0x40,0x00,0x40,0x00,0xF8,0x03,  // 72\n  0x00,0x00,0xF8,0x03,  // 73\n  0x00,0x03,0x00,0x02,0x00,0x02,0xF8,0x01,  // 74\n  0x00,0x00,0xF8,0x03,0x80,0x00,0x60,0x00,0x90,0x00,0x08,0x01,0x00,0x02,  // 75\n  0x00,0x00,0xF8,0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,  // 76\n  0x00,0x00,0xF8,0x03,0x30,0x00,0xC0,0x01,0x00,0x02,0xC0,0x01,0x30,0x00,0xF8,0x03,  // 77\n  0x00,0x00,0xF8,0x03,0x30,0x00,0x40,0x00,0x80,0x01,0xF8,0x03,  // 78\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x08,0x02,0x08,0x02,0x08,0x02,0xF0,0x01,  // 79\n  0x00,0x00,0xF8,0x03,0x48,0x00,0x48,0x00,0x48,0x00,0x30, // 80\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x08,0x02,0x08,0x03,0x08,0x03,0xF0,0x02,  // 81\n  0x00,0x00,0xF8,0x03,0x48,0x00,0x48,0x00,0xC8,0x00,0x30,0x03,  // 82\n  0x00,0x00,0x30,0x01,0x48,0x02,0x48,0x02,0x48,0x02,0x90,0x01,  // 83\n  0x00,0x00,0x08,0x00,0x08,0x00,0xF8,0x03,0x08,0x00,0x08, // 84\n  0x00,0x00,0xF8,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0xF8,0x01,  // 85\n  0x08,0x00,0x70,0x00,0x80,0x01,0x00,0x02,0x80,0x01,0x70,0x00,0x08, // 86\n  0x18,0x00,0xE0,0x01,0x00,0x02,0xF0,0x01,0x08,0x00,0xF0,0x01,0x00,0x02,0xE0,0x01,0x18, // 87\n  0x00,0x02,0x08,0x01,0x90,0x00,0x60,0x00,0x90,0x00,0x08,0x01,0x00,0x02,  // 88\n  0x08,0x00,0x10,0x00,0x20,0x00,0xC0,0x03,0x20,0x00,0x10,0x00,0x08, // 89\n  0x08,0x03,0x88,0x02,0xC8,0x02,0x68,0x02,0x38,0x02,0x18,0x02,  // 90\n  0x00,0x00,0xF8,0x0F,0x08,0x08,  // 91\n  0x18,0x00,0xE0,0x00,0x00,0x03,  // 92\n  0x08,0x08,0xF8,0x0F,  // 93\n  0x40,0x00,0x30,0x00,0x08,0x00,0x30,0x00,0x40, // 94\n  0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,  // 95\n  0x08,0x00,0x10, // 96\n  0x00,0x00,0x00,0x03,0xA0,0x02,0xA0,0x02,0xE0,0x03,  // 97\n  0x00,0x00,0xF8,0x03,0x20,0x02,0x20,0x02,0xC0,0x01,  // 98\n  0x00,0x00,0xC0,0x01,0x20,0x02,0x20,0x02,0x40,0x01,  // 99\n  0x00,0x00,0xC0,0x01,0x20,0x02,0x20,0x02,0xF8,0x03,  // 100\n  0x00,0x00,0xC0,0x01,0xA0,0x02,0xA0,0x02,0xC0,0x02,  // 101\n  0x20,0x00,0xF0,0x03,0x28, // 102\n  0x00,0x00,0xC0,0x05,0x20,0x0A,0x20,0x0A,0xE0,0x07,  // 103\n  0x00,0x00,0xF8,0x03,0x20,0x00,0x20,0x00,0xC0,0x03,  // 104\n  0x00,0x00,0xE8,0x03,  // 105\n  0x00,0x08,0xE8,0x07,  // 106\n  0xF8,0x03,0x80,0x00,0xC0,0x01,0x20,0x02,  // 107\n  0x00,0x00,0xF8,0x03,  // 108\n  0x00,0x00,0xE0,0x03,0x20,0x00,0x20,0x00,0xE0,0x03,0x20,0x00,0x20,0x00,0xC0,0x03,  // 109\n  0x00,0x00,0xE0,0x03,0x20,0x00,0x20,0x00,0xC0,0x03,  // 110\n  0x00,0x00,0xC0,0x01,0x20,0x02,0x20,0x02,0xC0,0x01,  // 111\n  0x00,0x00,0xE0,0x0F,0x20,0x02,0x20,0x02,0xC0,0x01,  // 112\n  0x00,0x00,0xC0,0x01,0x20,0x02,0x20,0x02,0xE0,0x0F,  // 113\n  0x00,0x00,0xE0,0x03,0x20, // 114\n  0x40,0x02,0xA0,0x02,0xA0,0x02,0x20,0x01,  // 115\n  0x20,0x00,0xF8,0x03,0x20,0x02,  // 116\n  0x00,0x00,0xE0,0x01,0x00,0x02,0x00,0x02,0xE0,0x03,  // 117\n  0x20,0x00,0xC0,0x01,0x00,0x02,0xC0,0x01,0x20, // 118\n  0xE0,0x01,0x00,0x02,0xC0,0x01,0x20,0x00,0xC0,0x01,0x00,0x02,0xE0,0x01,  // 119\n  0x20,0x02,0x40,0x01,0x80,0x00,0x40,0x01,0x20,0x02,  // 120\n  0x20,0x00,0xC0,0x09,0x00,0x06,0xC0,0x01,0x20, // 121\n  0x20,0x02,0x20,0x03,0xA0,0x02,0x60,0x02,0x20,0x02,  // 122\n  0x80,0x00,0x78,0x0F,0x08,0x08,  // 123\n  0x00,0x00,0xF8,0x0F,  // 124\n  0x08,0x08,0x78,0x0F,0x80, // 125\n  0xC0,0x00,0x40,0x00,0xC0,0x00,0x80,0x00,0xC0, // 126\n  0x00,0x00,0xA0,0x0F,  // 161\n  0x00,0x00,0xC0,0x01,0xA0,0x0F,0x78,0x02,0x40,0x01,  // 162\n  0x40,0x02,0x70,0x03,0xC8,0x02,0x48,0x02,0x08,0x02,0x10,0x02,  // 163\n  0x00,0x00,0xE0,0x01,0x20,0x01,0x20,0x01,0xE0,0x01,  // 164\n  0x48,0x01,0x70,0x01,0xC0,0x03,0x70,0x01,0x48,0x01,  // 165\n  0x00,0x00,0x38,0x0F,  // 166\n  0xD0,0x04,0x28,0x09,0x48,0x09,0x48,0x0A,0x90,0x05,  // 167\n  0x08,0x00,0x00,0x00,0x08, // 168\n  0xE0,0x00,0x10,0x01,0x48,0x02,0xA8,0x02,0xA8,0x02,0x10,0x01,0xE0, // 169\n  0x68,0x00,0x68,0x00,0x68,0x00,0x78, // 170\n  0x00,0x00,0x80,0x01,0x40,0x02,0x80,0x01,0x40,0x02,  // 171\n  0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xE0, // 172\n  0x80,0x00,0x80, // 173\n  0xE0,0x00,0x10,0x01,0xE8,0x02,0x68,0x02,0xC8,0x02,0x10,0x01,0xE0, // 174\n  0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, // 175\n  0x00,0x00,0x38,0x00,0x28,0x00,0x38, // 176\n  0x40,0x02,0x40,0x02,0xF0,0x03,0x40,0x02,0x40,0x02,  // 177\n  0x48,0x00,0x68,0x00,0x58, // 178\n  0x48,0x00,0x58,0x00,0x68, // 179\n  0x00,0x00,0x10,0x00,0x08, // 180\n  0x00,0x00,0xE0,0x0F,0x00,0x02,0x00,0x02,0xE0,0x03,  // 181\n  0x70,0x00,0xF8,0x0F,0x08,0x00,0xF8,0x0F,0x08, // 182\n  0x00,0x00,0x40, // 183\n  0x00,0x00,0x00,0x14,0x00,0x18,  // 184\n  0x00,0x00,0x10,0x00,0x78, // 185\n  0x30,0x00,0x48,0x00,0x48,0x00,0x30, // 186\n  0x00,0x00,0x40,0x02,0x80,0x01,0x40,0x02,0x80,0x01,  // 187\n  0x00,0x00,0x10,0x02,0x78,0x01,0xC0,0x00,0x20,0x01,0x90,0x01,0xC8,0x03,0x00,0x01,  // 188\n  0x00,0x00,0x10,0x02,0x78,0x01,0x80,0x00,0x60,0x00,0x50,0x02,0x48,0x03,0xC0,0x02,  // 189\n  0x48,0x00,0x58,0x00,0x68,0x03,0x80,0x00,0x60,0x01,0x90,0x01,0xC8,0x03,0x00,0x01,  // 190\n  0x00,0x00,0x00,0x06,0x00,0x09,0xA0,0x09,0x00,0x04,  // 191\n  0x00,0x02,0xC0,0x01,0xB0,0x00,0x89,0x00,0xB2,0x00,0xC0,0x01,0x00,0x02,  // 192\n  0x00,0x02,0xC0,0x01,0xB0,0x00,0x8A,0x00,0xB1,0x00,0xC0,0x01,0x00,0x02,  // 193\n  0x00,0x02,0xC0,0x01,0xB2,0x00,0x89,0x00,0xB2,0x00,0xC0,0x01,0x00,0x02,  // 194\n  0x00,0x02,0xC2,0x01,0xB1,0x00,0x8A,0x00,0xB1,0x00,0xC0,0x01,0x00,0x02,  // 195\n  0x00,0x02,0xC0,0x01,0xB2,0x00,0x88,0x00,0xB2,0x00,0xC0,0x01,0x00,0x02,  // 196\n  0x00,0x02,0xC0,0x01,0xBE,0x00,0x8A,0x00,0xBE,0x00,0xC0,0x01,0x00,0x02,  // 197\n  0x00,0x03,0xC0,0x00,0xE0,0x00,0x98,0x00,0x88,0x00,0xF8,0x03,0x48,0x02,0x48,0x02,0x48,0x02,  // 198\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x08,0x16,0x08,0x1A,0x10,0x01,  // 199\n  0x00,0x00,0xF8,0x03,0x49,0x02,0x4A,0x02,0x48,0x02,0x48,0x02,  // 200\n  0x00,0x00,0xF8,0x03,0x48,0x02,0x4A,0x02,0x49,0x02,0x48,0x02,  // 201\n  0x00,0x00,0xFA,0x03,0x49,0x02,0x4A,0x02,0x48,0x02,0x48,0x02,  // 202\n  0x00,0x00,0xF8,0x03,0x4A,0x02,0x48,0x02,0x4A,0x02,0x48,0x02,  // 203\n  0x00,0x00,0xF9,0x03,0x02, // 204\n  0x02,0x00,0xF9,0x03,  // 205\n  0x01,0x00,0xFA,0x03,  // 206\n  0x02,0x00,0xF8,0x03,0x02, // 207\n  0x40,0x00,0xF8,0x03,0x48,0x02,0x48,0x02,0x10,0x01,0xE0, // 208\n  0x00,0x00,0xFA,0x03,0x31,0x00,0x42,0x00,0x81,0x01,0xF8,0x03,  // 209\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x09,0x02,0x0A,0x02,0x08,0x02,0xF0,0x01,  // 210\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x0A,0x02,0x09,0x02,0x08,0x02,0xF0,0x01,  // 211\n  0x00,0x00,0xF0,0x01,0x08,0x02,0x0A,0x02,0x09,0x02,0x0A,0x02,0xF0,0x01,  // 212\n  0x00,0x00,0xF0,0x01,0x0A,0x02,0x09,0x02,0x0A,0x02,0x09,0x02,0xF0,0x01,  // 213\n  0x00,0x00,0xF0,0x01,0x0A,0x02,0x08,0x02,0x0A,0x02,0x08,0x02,0xF0,0x01,  // 214\n  0x10,0x01,0xA0,0x00,0xE0,0x00,0xA0,0x00,0x10,0x01,  // 215\n  0x00,0x00,0xF0,0x02,0x08,0x03,0xC8,0x02,0x28,0x02,0x18,0x03,0xE8, // 216\n  0x00,0x00,0xF8,0x01,0x01,0x02,0x02,0x02,0x00,0x02,0xF8,0x01,  // 217\n  0x00,0x00,0xF8,0x01,0x02,0x02,0x01,0x02,0x00,0x02,0xF8,0x01,  // 218\n  0x00,0x00,0xF8,0x01,0x02,0x02,0x01,0x02,0x02,0x02,0xF8,0x01,  // 219\n  0x00,0x00,0xF8,0x01,0x02,0x02,0x00,0x02,0x02,0x02,0xF8,0x01,  // 220\n  0x08,0x00,0x10,0x00,0x20,0x00,0xC2,0x03,0x21,0x00,0x10,0x00,0x08, // 221\n  0x00,0x00,0xF8,0x03,0x10,0x01,0x10,0x01,0x10,0x01,0xE0, // 222\n  0x00,0x00,0xF0,0x03,0x08,0x01,0x48,0x02,0xB0,0x02,0x80,0x01,  // 223\n  0x00,0x00,0x00,0x03,0xA4,0x02,0xA8,0x02,0xE0,0x03,  // 224\n  0x00,0x00,0x00,0x03,0xA8,0x02,0xA4,0x02,0xE0,0x03,  // 225\n  0x00,0x00,0x00,0x03,0xA8,0x02,0xA4,0x02,0xE8,0x03,  // 226\n  0x00,0x00,0x08,0x03,0xA4,0x02,0xA8,0x02,0xE4,0x03,  // 227\n  0x00,0x00,0x00,0x03,0xA8,0x02,0xA0,0x02,0xE8,0x03,  // 228\n  0x00,0x00,0x00,0x03,0xAE,0x02,0xAA,0x02,0xEE,0x03,  // 229\n  0x00,0x00,0x40,0x03,0xA0,0x02,0xA0,0x02,0xC0,0x01,0xA0,0x02,0xA0,0x02,0xC0,0x02,  // 230\n  0x00,0x00,0xC0,0x01,0x20,0x16,0x20,0x1A,0x40,0x01,  // 231\n  0x00,0x00,0xC0,0x01,0xA4,0x02,0xA8,0x02,0xC0,0x02,  // 232\n  0x00,0x00,0xC0,0x01,0xA8,0x02,0xA4,0x02,0xC0,0x02,  // 233\n  0x00,0x00,0xC0,0x01,0xA8,0x02,0xA4,0x02,0xC8,0x02,  // 234\n  0x00,0x00,0xC0,0x01,0xA8,0x02,0xA0,0x02,0xC8,0x02,  // 235\n  0x00,0x00,0xE4,0x03,0x08, // 236\n  0x08,0x00,0xE4,0x03,  // 237\n  0x08,0x00,0xE4,0x03,0x08, // 238\n  0x08,0x00,0xE0,0x03,0x08, // 239\n  0x00,0x00,0xC0,0x01,0x28,0x02,0x38,0x02,0xE0,0x01,  // 240\n  0x00,0x00,0xE8,0x03,0x24,0x00,0x28,0x00,0xC4,0x03,  // 241\n  0x00,0x00,0xC0,0x01,0x24,0x02,0x28,0x02,0xC0,0x01,  // 242\n  0x00,0x00,0xC0,0x01,0x28,0x02,0x24,0x02,0xC0,0x01,  // 243\n  0x00,0x00,0xC0,0x01,0x28,0x02,0x24,0x02,0xC8,0x01,  // 244\n  0x00,0x00,0xC8,0x01,0x24,0x02,0x28,0x02,0xC4,0x01,  // 245\n  0x00,0x00,0xC0,0x01,0x28,0x02,0x20,0x02,0xC8,0x01,  // 246\n  0x40,0x00,0x40,0x00,0x50,0x01,0x40,0x00,0x40, // 247\n  0x00,0x00,0xC0,0x02,0xA0,0x03,0x60,0x02,0xA0,0x01,  // 248\n  0x00,0x00,0xE0,0x01,0x04,0x02,0x08,0x02,0xE0,0x03,  // 249\n  0x00,0x00,0xE0,0x01,0x08,0x02,0x04,0x02,0xE0,0x03,  // 250\n  0x00,0x00,0xE8,0x01,0x04,0x02,0x08,0x02,0xE0,0x03,  // 251\n  0x00,0x00,0xE0,0x01,0x08,0x02,0x00,0x02,0xE8,0x03,  // 252\n  0x20,0x00,0xC0,0x09,0x08,0x06,0xC4,0x01,0x20, // 253\n  0x00,0x00,0xF8,0x0F,0x20,0x02,0x20,0x02,0xC0,0x01,  // 254\n  0x20,0x00,0xC8,0x09,0x00,0x06,0xC8,0x01,0x20  // 255\n};\n\nconst uint8_t ArialMT_Plain_16[] PROGMEM = {\n  0x10, // Width: 16\n  0x13, // Height: 19\n  0x20, // First Char: 32\n  0xE0, // Numbers of Chars: 224\n\n  // Jump Table:\n  0xFF, 0xFF, 0x00, 0x04,  // 32:65535\n  0x00, 0x00, 0x08, 0x04,  // 33:0\n  0x00, 0x08, 0x0D, 0x06,  // 34:8\n  0x00, 0x15, 0x1A, 0x09,  // 35:21\n  0x00, 0x2F, 0x17, 0x09,  // 36:47\n  0x00, 0x46, 0x26, 0x0E,  // 37:70\n  0x00, 0x6C, 0x1D, 0x0B,  // 38:108\n  0x00, 0x89, 0x04, 0x03,  // 39:137\n  0x00, 0x8D, 0x0C, 0x05,  // 40:141\n  0x00, 0x99, 0x0B, 0x05,  // 41:153\n  0x00, 0xA4, 0x0D, 0x06,  // 42:164\n  0x00, 0xB1, 0x17, 0x09,  // 43:177\n  0x00, 0xC8, 0x09, 0x04,  // 44:200\n  0x00, 0xD1, 0x0B, 0x05,  // 45:209\n  0x00, 0xDC, 0x08, 0x04,  // 46:220\n  0x00, 0xE4, 0x0A, 0x04,  // 47:228\n  0x00, 0xEE, 0x17, 0x09,  // 48:238\n  0x01, 0x05, 0x11, 0x09,  // 49:261\n  0x01, 0x16, 0x17, 0x09,  // 50:278\n  0x01, 0x2D, 0x17, 0x09,  // 51:301\n  0x01, 0x44, 0x17, 0x09,  // 52:324\n  0x01, 0x5B, 0x17, 0x09,  // 53:347\n  0x01, 0x72, 0x17, 0x09,  // 54:370\n  0x01, 0x89, 0x16, 0x09,  // 55:393\n  0x01, 0x9F, 0x17, 0x09,  // 56:415\n  0x01, 0xB6, 0x17, 0x09,  // 57:438\n  0x01, 0xCD, 0x05, 0x04,  // 58:461\n  0x01, 0xD2, 0x06, 0x04,  // 59:466\n  0x01, 0xD8, 0x17, 0x09,  // 60:472\n  0x01, 0xEF, 0x17, 0x09,  // 61:495\n  0x02, 0x06, 0x17, 0x09,  // 62:518\n  0x02, 0x1D, 0x16, 0x09,  // 63:541\n  0x02, 0x33, 0x2F, 0x10,  // 64:563\n  0x02, 0x62, 0x1D, 0x0B,  // 65:610\n  0x02, 0x7F, 0x1D, 0x0B,  // 66:639\n  0x02, 0x9C, 0x20, 0x0C,  // 67:668\n  0x02, 0xBC, 0x20, 0x0C,  // 68:700\n  0x02, 0xDC, 0x1D, 0x0B,  // 69:732\n  0x02, 0xF9, 0x19, 0x0A,  // 70:761\n  0x03, 0x12, 0x20, 0x0C,  // 71:786\n  0x03, 0x32, 0x1D, 0x0C,  // 72:818\n  0x03, 0x4F, 0x05, 0x04,  // 73:847\n  0x03, 0x54, 0x14, 0x08,  // 74:852\n  0x03, 0x68, 0x1D, 0x0B,  // 75:872\n  0x03, 0x85, 0x17, 0x09,  // 76:901\n  0x03, 0x9C, 0x23, 0x0D,  // 77:924\n  0x03, 0xBF, 0x1D, 0x0C,  // 78:959\n  0x03, 0xDC, 0x20, 0x0C,  // 79:988\n  0x03, 0xFC, 0x1C, 0x0B,  // 80:1020\n  0x04, 0x18, 0x20, 0x0C,  // 81:1048\n  0x04, 0x38, 0x1D, 0x0C,  // 82:1080\n  0x04, 0x55, 0x1D, 0x0B,  // 83:1109\n  0x04, 0x72, 0x19, 0x0A,  // 84:1138\n  0x04, 0x8B, 0x1D, 0x0C,  // 85:1163\n  0x04, 0xA8, 0x1C, 0x0B,  // 86:1192\n  0x04, 0xC4, 0x2B, 0x0F,  // 87:1220\n  0x04, 0xEF, 0x20, 0x0B,  // 88:1263\n  0x05, 0x0F, 0x19, 0x0B,  // 89:1295\n  0x05, 0x28, 0x1A, 0x0A,  // 90:1320\n  0x05, 0x42, 0x0C, 0x04,  // 91:1346\n  0x05, 0x4E, 0x0B, 0x04,  // 92:1358\n  0x05, 0x59, 0x09, 0x04,  // 93:1369\n  0x05, 0x62, 0x14, 0x08,  // 94:1378\n  0x05, 0x76, 0x1B, 0x09,  // 95:1398\n  0x05, 0x91, 0x07, 0x05,  // 96:1425\n  0x05, 0x98, 0x17, 0x09,  // 97:1432\n  0x05, 0xAF, 0x17, 0x09,  // 98:1455\n  0x05, 0xC6, 0x14, 0x08,  // 99:1478\n  0x05, 0xDA, 0x17, 0x09,  // 100:1498\n  0x05, 0xF1, 0x17, 0x09,  // 101:1521\n  0x06, 0x08, 0x0A, 0x04,  // 102:1544\n  0x06, 0x12, 0x17, 0x09,  // 103:1554\n  0x06, 0x29, 0x14, 0x09,  // 104:1577\n  0x06, 0x3D, 0x05, 0x04,  // 105:1597\n  0x06, 0x42, 0x06, 0x04,  // 106:1602\n  0x06, 0x48, 0x17, 0x08,  // 107:1608\n  0x06, 0x5F, 0x05, 0x04,  // 108:1631\n  0x06, 0x64, 0x23, 0x0D,  // 109:1636\n  0x06, 0x87, 0x14, 0x09,  // 110:1671\n  0x06, 0x9B, 0x17, 0x09,  // 111:1691\n  0x06, 0xB2, 0x17, 0x09,  // 112:1714\n  0x06, 0xC9, 0x18, 0x09,  // 113:1737\n  0x06, 0xE1, 0x0D, 0x05,  // 114:1761\n  0x06, 0xEE, 0x14, 0x08,  // 115:1774\n  0x07, 0x02, 0x0B, 0x04,  // 116:1794\n  0x07, 0x0D, 0x14, 0x09,  // 117:1805\n  0x07, 0x21, 0x13, 0x08,  // 118:1825\n  0x07, 0x34, 0x1F, 0x0C,  // 119:1844\n  0x07, 0x53, 0x14, 0x08,  // 120:1875\n  0x07, 0x67, 0x13, 0x08,  // 121:1895\n  0x07, 0x7A, 0x14, 0x08,  // 122:1914\n  0x07, 0x8E, 0x0F, 0x05,  // 123:1934\n  0x07, 0x9D, 0x06, 0x04,  // 124:1949\n  0x07, 0xA3, 0x0E, 0x05,  // 125:1955\n  0x07, 0xB1, 0x17, 0x09,  // 126:1969\n  0xFF, 0xFF, 0x00, 0x00,  // 127:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 128:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 129:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 130:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 131:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 132:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 133:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 134:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 135:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 136:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 137:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 138:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 139:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 140:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 141:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 142:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 143:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 144:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 145:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 146:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 147:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 148:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 149:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 150:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 151:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 152:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 153:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 154:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 155:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 156:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 157:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 158:65535\n  0xFF, 0xFF, 0x00, 0x10,  // 159:65535\n  0xFF, 0xFF, 0x00, 0x04,  // 160:65535\n  0x07, 0xC8, 0x09, 0x05,  // 161:1992\n  0x07, 0xD1, 0x17, 0x09,  // 162:2001\n  0x07, 0xE8, 0x17, 0x09,  // 163:2024\n  0x07, 0xFF, 0x14, 0x09,  // 164:2047\n  0x08, 0x13, 0x1A, 0x09,  // 165:2067\n  0x08, 0x2D, 0x06, 0x04,  // 166:2093\n  0x08, 0x33, 0x17, 0x09,  // 167:2099\n  0x08, 0x4A, 0x07, 0x05,  // 168:2122\n  0x08, 0x51, 0x23, 0x0C,  // 169:2129\n  0x08, 0x74, 0x0E, 0x06,  // 170:2164\n  0x08, 0x82, 0x14, 0x09,  // 171:2178\n  0x08, 0x96, 0x17, 0x09,  // 172:2198\n  0x08, 0xAD, 0x0B, 0x05,  // 173:2221\n  0x08, 0xB8, 0x23, 0x0C,  // 174:2232\n  0x08, 0xDB, 0x19, 0x09,  // 175:2267\n  0x08, 0xF4, 0x0D, 0x06,  // 176:2292\n  0x09, 0x01, 0x17, 0x09,  // 177:2305\n  0x09, 0x18, 0x0E, 0x05,  // 178:2328\n  0x09, 0x26, 0x0D, 0x05,  // 179:2342\n  0x09, 0x33, 0x0A, 0x05,  // 180:2355\n  0x09, 0x3D, 0x17, 0x09,  // 181:2365\n  0x09, 0x54, 0x19, 0x09,  // 182:2388\n  0x09, 0x6D, 0x08, 0x05,  // 183:2413\n  0x09, 0x75, 0x0C, 0x05,  // 184:2421\n  0x09, 0x81, 0x0B, 0x05,  // 185:2433\n  0x09, 0x8C, 0x0D, 0x06,  // 186:2444\n  0x09, 0x99, 0x17, 0x09,  // 187:2457\n  0x09, 0xB0, 0x26, 0x0D,  // 188:2480\n  0x09, 0xD6, 0x26, 0x0D,  // 189:2518\n  0x09, 0xFC, 0x26, 0x0D,  // 190:2556\n  0x0A, 0x22, 0x1A, 0x0A,  // 191:2594\n  0x0A, 0x3C, 0x1D, 0x0B,  // 192:2620\n  0x0A, 0x59, 0x1D, 0x0B,  // 193:2649\n  0x0A, 0x76, 0x1D, 0x0B,  // 194:2678\n  0x0A, 0x93, 0x1D, 0x0B,  // 195:2707\n  0x0A, 0xB0, 0x1D, 0x0B,  // 196:2736\n  0x0A, 0xCD, 0x1D, 0x0B,  // 197:2765\n  0x0A, 0xEA, 0x2C, 0x10,  // 198:2794\n  0x0B, 0x16, 0x20, 0x0C,  // 199:2838\n  0x0B, 0x36, 0x1D, 0x0B,  // 200:2870\n  0x0B, 0x53, 0x1D, 0x0B,  // 201:2899\n  0x0B, 0x70, 0x1D, 0x0B,  // 202:2928\n  0x0B, 0x8D, 0x1D, 0x0B,  // 203:2957\n  0x0B, 0xAA, 0x05, 0x04,  // 204:2986\n  0x0B, 0xAF, 0x07, 0x04,  // 205:2991\n  0x0B, 0xB6, 0x0A, 0x04,  // 206:2998\n  0x0B, 0xC0, 0x07, 0x04,  // 207:3008\n  0x0B, 0xC7, 0x20, 0x0C,  // 208:3015\n  0x0B, 0xE7, 0x1D, 0x0C,  // 209:3047\n  0x0C, 0x04, 0x20, 0x0C,  // 210:3076\n  0x0C, 0x24, 0x20, 0x0C,  // 211:3108\n  0x0C, 0x44, 0x20, 0x0C,  // 212:3140\n  0x0C, 0x64, 0x20, 0x0C,  // 213:3172\n  0x0C, 0x84, 0x20, 0x0C,  // 214:3204\n  0x0C, 0xA4, 0x17, 0x09,  // 215:3236\n  0x0C, 0xBB, 0x20, 0x0C,  // 216:3259\n  0x0C, 0xDB, 0x1D, 0x0C,  // 217:3291\n  0x0C, 0xF8, 0x1D, 0x0C,  // 218:3320\n  0x0D, 0x15, 0x1D, 0x0C,  // 219:3349\n  0x0D, 0x32, 0x1D, 0x0C,  // 220:3378\n  0x0D, 0x4F, 0x19, 0x0B,  // 221:3407\n  0x0D, 0x68, 0x1D, 0x0B,  // 222:3432\n  0x0D, 0x85, 0x17, 0x0A,  // 223:3461\n  0x0D, 0x9C, 0x17, 0x09,  // 224:3484\n  0x0D, 0xB3, 0x17, 0x09,  // 225:3507\n  0x0D, 0xCA, 0x17, 0x09,  // 226:3530\n  0x0D, 0xE1, 0x17, 0x09,  // 227:3553\n  0x0D, 0xF8, 0x17, 0x09,  // 228:3576\n  0x0E, 0x0F, 0x17, 0x09,  // 229:3599\n  0x0E, 0x26, 0x29, 0x0E,  // 230:3622\n  0x0E, 0x4F, 0x14, 0x08,  // 231:3663\n  0x0E, 0x63, 0x17, 0x09,  // 232:3683\n  0x0E, 0x7A, 0x17, 0x09,  // 233:3706\n  0x0E, 0x91, 0x17, 0x09,  // 234:3729\n  0x0E, 0xA8, 0x17, 0x09,  // 235:3752\n  0x0E, 0xBF, 0x05, 0x04,  // 236:3775\n  0x0E, 0xC4, 0x07, 0x04,  // 237:3780\n  0x0E, 0xCB, 0x0A, 0x04,  // 238:3787\n  0x0E, 0xD5, 0x07, 0x04,  // 239:3797\n  0x0E, 0xDC, 0x17, 0x09,  // 240:3804\n  0x0E, 0xF3, 0x14, 0x09,  // 241:3827\n  0x0F, 0x07, 0x17, 0x09,  // 242:3847\n  0x0F, 0x1E, 0x17, 0x09,  // 243:3870\n  0x0F, 0x35, 0x17, 0x09,  // 244:3893\n  0x0F, 0x4C, 0x17, 0x09,  // 245:3916\n  0x0F, 0x63, 0x17, 0x09,  // 246:3939\n  0x0F, 0x7A, 0x17, 0x09,  // 247:3962\n  0x0F, 0x91, 0x17, 0x0A,  // 248:3985\n  0x0F, 0xA8, 0x14, 0x09,  // 249:4008\n  0x0F, 0xBC, 0x14, 0x09,  // 250:4028\n  0x0F, 0xD0, 0x14, 0x09,  // 251:4048\n  0x0F, 0xE4, 0x14, 0x09,  // 252:4068\n  0x0F, 0xF8, 0x13, 0x08,  // 253:4088\n  0x10, 0x0B, 0x17, 0x09,  // 254:4107\n  0x10, 0x22, 0x13, 0x08,  // 255:4130\n\n  // Font Data:\n  0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x5F,  // 33\n  0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78, // 34\n  0x80,0x08,0x00,0x80,0x78,0x00,0xC0,0x0F,0x00,0xB8,0x08,0x00,0x80,0x08,0x00,0x80,0x78,0x00,0xC0,0x0F,0x00,0xB8,0x08,0x00,0x80,0x08,  // 35\n  0x00,0x00,0x00,0xE0,0x10,0x00,0x10,0x21,0x00,0x08,0x41,0x00,0xFC,0xFF,0x00,0x08,0x42,0x00,0x10,0x22,0x00,0x20,0x1C, // 36\n  0x00,0x00,0x00,0xF0,0x00,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x61,0x00,0xF0,0x18,0x00,0x00,0x06,0x00,0xC0,0x01,0x00,0x30,0x3C,0x00,0x08,0x42,0x00,0x00,0x42,0x00,0x00,0x42,0x00,0x00,0x3C,  // 37\n  0x00,0x00,0x00,0x00,0x1C,0x00,0x70,0x22,0x00,0x88,0x41,0x00,0x08,0x43,0x00,0x88,0x44,0x00,0x70,0x28,0x00,0x00,0x10,0x00,0x00,0x28,0x00,0x00,0x44, // 38\n  0x00,0x00,0x00,0x78,  // 39\n  0x00,0x00,0x00,0x80,0x3F,0x00,0x70,0xC0,0x01,0x08,0x00,0x02,  // 40\n  0x00,0x00,0x00,0x08,0x00,0x02,0x70,0xC0,0x01,0x80,0x3F, // 41\n  0x10,0x00,0x00,0xD0,0x00,0x00,0x38,0x00,0x00,0xD0,0x00,0x00,0x10, // 42\n  0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0xC0,0x1F,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02, // 43\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01, // 44\n  0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08, // 45\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,  // 46\n  0x00,0x60,0x00,0x00,0x1E,0x00,0xE0,0x01,0x00,0x18,  // 47\n  0x00,0x00,0x00,0xE0,0x1F,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0xE0,0x1F, // 48\n  0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0xF8,0x7F, // 49\n  0x00,0x00,0x00,0x20,0x40,0x00,0x10,0x60,0x00,0x08,0x50,0x00,0x08,0x48,0x00,0x08,0x44,0x00,0x10,0x43,0x00,0xE0,0x40, // 50\n  0x00,0x00,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x88,0x41,0x00,0xF0,0x22,0x00,0x00,0x1C, // 51\n  0x00,0x0C,0x00,0x00,0x0A,0x00,0x00,0x09,0x00,0xC0,0x08,0x00,0x20,0x08,0x00,0x10,0x08,0x00,0xF8,0x7F,0x00,0x00,0x08, // 52\n  0x00,0x00,0x00,0xC0,0x11,0x00,0xB8,0x20,0x00,0x88,0x40,0x00,0x88,0x40,0x00,0x88,0x40,0x00,0x08,0x21,0x00,0x08,0x1E, // 53\n  0x00,0x00,0x00,0xE0,0x1F,0x00,0x10,0x21,0x00,0x88,0x40,0x00,0x88,0x40,0x00,0x88,0x40,0x00,0x10,0x21,0x00,0x20,0x1E, // 54\n  0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x78,0x00,0x08,0x07,0x00,0xC8,0x00,0x00,0x28,0x00,0x00,0x18,  // 55\n  0x00,0x00,0x00,0x60,0x1C,0x00,0x90,0x22,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x90,0x22,0x00,0x60,0x1C, // 56\n  0x00,0x00,0x00,0xE0,0x11,0x00,0x10,0x22,0x00,0x08,0x44,0x00,0x08,0x44,0x00,0x08,0x44,0x00,0x10,0x22,0x00,0xE0,0x1F, // 57\n  0x00,0x00,0x00,0x40,0x40, // 58\n  0x00,0x00,0x00,0x40,0xC0,0x01,  // 59\n  0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x05,0x00,0x00,0x05,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x40,0x10, // 60\n  0x00,0x00,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08, // 61\n  0x00,0x00,0x00,0x40,0x10,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x00,0x05,0x00,0x00,0x05,0x00,0x00,0x02, // 62\n  0x00,0x00,0x00,0x60,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x08,0x5C,0x00,0x08,0x02,0x00,0x10,0x01,0x00,0xE0,  // 63\n  0x00,0x00,0x00,0x00,0x3F,0x00,0xC0,0x40,0x00,0x20,0x80,0x00,0x10,0x1E,0x01,0x10,0x21,0x01,0x88,0x40,0x02,0x48,0x40,0x02,0x48,0x40,0x02,0x48,0x20,0x02,0x88,0x7C,0x02,0xC8,0x43,0x02,0x10,0x40,0x02,0x10,0x20,0x01,0x60,0x10,0x01,0x80,0x8F, // 64\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x70,0x04,0x00,0x08,0x04,0x00,0x70,0x04,0x00,0x80,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 65\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x90,0x22,0x00,0x60,0x1C, // 66\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,  // 67\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 68\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x40, // 69\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08, // 70\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x42,0x00,0x08,0x42,0x00,0x10,0x22,0x00,0x20,0x12,0x00,0x00,0x0E,  // 71\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0xF8,0x7F, // 72\n  0x00,0x00,0x00,0xF8,0x7F, // 73\n  0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0xF8,0x3F,  // 74\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0x80,0x03,0x00,0x40,0x04,0x00,0x20,0x18,0x00,0x10,0x20,0x00,0x08,0x40, // 75\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40, // 76\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x00,0x03,0x00,0x00,0x1C,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x00,0x03,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0xF8,0x7F, // 77\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x10,0x00,0x00,0x60,0x00,0x00,0x80,0x00,0x00,0x00,0x03,0x00,0x00,0x04,0x00,0x00,0x18,0x00,0x00,0x20,0x00,0xF8,0x7F, // 78\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 79\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x10,0x01,0x00,0xE0,  // 80\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x08,0x50,0x00,0x08,0x50,0x00,0x10,0x20,0x00,0x20,0x70,0x00,0xC0,0x4F,  // 81\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x02,0x00,0x08,0x06,0x00,0x08,0x1A,0x00,0x10,0x21,0x00,0xE0,0x40, // 82\n  0x00,0x00,0x00,0x60,0x10,0x00,0x90,0x20,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x42,0x00,0x08,0x42,0x00,0x10,0x22,0x00,0x20,0x1C, // 83\n  0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0xF8,0x7F,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08, // 84\n  0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xF8,0x1F, // 85\n  0x00,0x00,0x00,0x18,0x00,0x00,0xE0,0x00,0x00,0x00,0x07,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x07,0x00,0xE0,0x00,0x00,0x18,  // 86\n  0x18,0x00,0x00,0xE0,0x01,0x00,0x00,0x1E,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x03,0x00,0x70,0x00,0x00,0x08,0x00,0x00,0x70,0x00,0x00,0x80,0x03,0x00,0x00,0x1C,0x00,0x00,0x60,0x00,0x00,0x1E,0x00,0xE0,0x01,0x00,0x18, // 87\n  0x00,0x40,0x00,0x08,0x20,0x00,0x10,0x10,0x00,0x60,0x0C,0x00,0x80,0x02,0x00,0x00,0x01,0x00,0x80,0x02,0x00,0x60,0x0C,0x00,0x10,0x10,0x00,0x08,0x20,0x00,0x00,0x40,  // 88\n  0x08,0x00,0x00,0x30,0x00,0x00,0x40,0x00,0x00,0x80,0x01,0x00,0x00,0x7E,0x00,0x80,0x01,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0x08, // 89\n  0x00,0x40,0x00,0x08,0x60,0x00,0x08,0x58,0x00,0x08,0x44,0x00,0x08,0x43,0x00,0x88,0x40,0x00,0x68,0x40,0x00,0x18,0x40,0x00,0x08,0x40,  // 90\n  0x00,0x00,0x00,0xF8,0xFF,0x03,0x08,0x00,0x02,0x08,0x00,0x02,  // 91\n  0x18,0x00,0x00,0xE0,0x01,0x00,0x00,0x1E,0x00,0x00,0x60, // 92\n  0x08,0x00,0x02,0x08,0x00,0x02,0xF8,0xFF,0x03, // 93\n  0x00,0x01,0x00,0xC0,0x00,0x00,0x30,0x00,0x00,0x08,0x00,0x00,0x30,0x00,0x00,0xC0,0x00,0x00,0x00,0x01,  // 94\n  0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02, // 95\n  0x00,0x00,0x00,0x08,0x00,0x00,0x10, // 96\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x42,0x00,0x40,0x22,0x00,0x80,0x7F, // 97\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 98\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,  // 99\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0xF8,0x7F, // 100\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x24,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x80,0x24,0x00,0x00,0x17, // 101\n  0x40,0x00,0x00,0xF0,0x7F,0x00,0x48,0x00,0x00,0x48,  // 102\n  0x00,0x00,0x00,0x00,0x1F,0x01,0x80,0x20,0x02,0x40,0x40,0x02,0x40,0x40,0x02,0x40,0x40,0x02,0x80,0x20,0x01,0xC0,0xFF, // 103\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x7F,  // 104\n  0x00,0x00,0x00,0xC8,0x7F, // 105\n  0x00,0x00,0x02,0xC8,0xFF,0x01,  // 106\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x19,0x00,0x80,0x20,0x00,0x40,0x40, // 107\n  0x00,0x00,0x00,0xF8,0x7F, // 108\n  0x00,0x00,0x00,0xC0,0x7F,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x7F,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x7F, // 109\n  0x00,0x00,0x00,0xC0,0x7F,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x80,0x7F,  // 110\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 111\n  0x00,0x00,0x00,0xC0,0xFF,0x03,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 112\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0xC0,0xFF,0x03,  // 113\n  0x00,0x00,0x00,0xC0,0x7F,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x40, // 114\n  0x00,0x00,0x00,0x80,0x23,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x80,0x38,  // 115\n  0x40,0x00,0x00,0xF0,0x7F,0x00,0x40,0x40,0x00,0x40,0x40, // 116\n  0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xC0,0x7F,  // 117\n  0xC0,0x00,0x00,0x00,0x03,0x00,0x00,0x1C,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x00,0x03,0x00,0xC0, // 118\n  0xC0,0x00,0x00,0x00,0x1F,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x00,0x03,0x00,0xC0,0x00,0x00,0x00,0x03,0x00,0x00,0x1C,0x00,0x00,0x60,0x00,0x00,0x1F,0x00,0xC0, // 119\n  0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1B,0x00,0x00,0x04,0x00,0x00,0x1B,0x00,0x80,0x20,0x00,0x40,0x40,  // 120\n  0xC0,0x01,0x00,0x00,0x06,0x02,0x00,0x38,0x02,0x00,0xE0,0x01,0x00,0x38,0x00,0x00,0x07,0x00,0xC0, // 121\n  0x40,0x40,0x00,0x40,0x60,0x00,0x40,0x58,0x00,0x40,0x44,0x00,0x40,0x43,0x00,0xC0,0x40,0x00,0x40,0x40,  // 122\n  0x00,0x04,0x00,0x00,0x04,0x00,0xF0,0xFB,0x01,0x08,0x00,0x02,0x08,0x00,0x02, // 123\n  0x00,0x00,0x00,0xF8,0xFF,0x03,  // 124\n  0x08,0x00,0x02,0x08,0x00,0x02,0xF0,0xFB,0x01,0x00,0x04,0x00,0x00,0x04,  // 125\n  0x00,0x02,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x01, // 126\n  0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xFF,0x03, // 161\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x03,0x40,0xF0,0x00,0x40,0x4E,0x00,0xC0,0x41,0x00,0xB8,0x20,0x00,0x00,0x11, // 162\n  0x00,0x41,0x00,0xE0,0x31,0x00,0x10,0x2F,0x00,0x08,0x21,0x00,0x08,0x21,0x00,0x08,0x40,0x00,0x10,0x40,0x00,0x20,0x20, // 163\n  0x00,0x00,0x00,0x40,0x0B,0x00,0x80,0x04,0x00,0x40,0x08,0x00,0x40,0x08,0x00,0x80,0x04,0x00,0x40,0x0B,  // 164\n  0x08,0x0A,0x00,0x10,0x0A,0x00,0x60,0x0A,0x00,0x80,0x0B,0x00,0x00,0x7E,0x00,0x80,0x0B,0x00,0x60,0x0A,0x00,0x10,0x0A,0x00,0x08,0x0A,  // 165\n  0x00,0x00,0x00,0xF8,0xF1,0x03,  // 166\n  0x00,0x86,0x00,0x70,0x09,0x01,0xC8,0x10,0x02,0x88,0x10,0x02,0x08,0x21,0x02,0x08,0x61,0x02,0x30,0xD2,0x01,0x00,0x0C, // 167\n  0x08,0x00,0x00,0x00,0x00,0x00,0x08, // 168\n  0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0xC8,0x47,0x00,0x28,0x48,0x00,0x28,0x48,0x00,0x28,0x48,0x00,0x28,0x48,0x00,0x48,0x44,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F, // 169\n  0xD0,0x00,0x00,0x48,0x01,0x00,0x28,0x01,0x00,0x28,0x01,0x00,0xF0,0x01,  // 170\n  0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x1B,0x00,0x80,0x20,0x00,0x00,0x04,0x00,0x00,0x1B,0x00,0x80,0x20,  // 171\n  0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x80,0x0F, // 172\n  0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08, // 173\n  0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0xE8,0x4F,0x00,0x28,0x41,0x00,0x28,0x41,0x00,0x28,0x43,0x00,0x28,0x45,0x00,0xC8,0x48,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F, // 174\n  0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04, // 175\n  0x00,0x00,0x00,0x30,0x00,0x00,0x48,0x00,0x00,0x48,0x00,0x00,0x30, // 176\n  0x00,0x00,0x00,0x00,0x41,0x00,0x00,0x41,0x00,0x00,0x41,0x00,0xE0,0x4F,0x00,0x00,0x41,0x00,0x00,0x41,0x00,0x00,0x41, // 177\n  0x10,0x01,0x00,0x88,0x01,0x00,0x48,0x01,0x00,0x48,0x01,0x00,0x30,0x01,  // 178\n  0x90,0x00,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x28,0x01,0x00,0xD8, // 179\n  0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x08,  // 180\n  0x00,0x00,0x00,0xC0,0xFF,0x03,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xC0,0x7F, // 181\n  0xF0,0x00,0x00,0xF8,0x00,0x00,0xF8,0x01,0x00,0xF8,0x01,0x00,0xF8,0xFF,0x03,0x08,0x00,0x00,0x08,0x00,0x00,0xF8,0xFF,0x03,0x08, // 182\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,  // 183\n  0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x02,0x00,0x00,0x03,  // 184\n  0x00,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0xF8,0x01, // 185\n  0xF0,0x00,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0xF0, // 186\n  0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x1B,0x00,0x00,0x04,0x00,0x80,0x20,0x00,0x00,0x1B,0x00,0x00,0x04, // 187\n  0x00,0x00,0x00,0x10,0x00,0x00,0x08,0x40,0x00,0xF8,0x21,0x00,0x00,0x10,0x00,0x00,0x0C,0x00,0x00,0x02,0x00,0x80,0x01,0x00,0x40,0x30,0x00,0x30,0x28,0x00,0x08,0x24,0x00,0x00,0x7E,0x00,0x00,0x20,  // 188\n  0x00,0x00,0x00,0x10,0x00,0x00,0x08,0x40,0x00,0xF8,0x31,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x03,0x00,0x80,0x00,0x00,0x60,0x44,0x00,0x10,0x62,0x00,0x08,0x52,0x00,0x00,0x52,0x00,0x00,0x4C,  // 189\n  0x90,0x00,0x00,0x08,0x01,0x00,0x08,0x41,0x00,0x28,0x21,0x00,0xD8,0x18,0x00,0x00,0x04,0x00,0x00,0x03,0x00,0x80,0x00,0x00,0x40,0x30,0x00,0x30,0x28,0x00,0x08,0x24,0x00,0x00,0x7E,0x00,0x00,0x20,  // 190\n  0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x10,0x01,0x00,0x08,0x02,0x40,0x07,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x01,0x00,0xC0,  // 191\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x71,0x04,0x00,0x0A,0x04,0x00,0x70,0x04,0x00,0x80,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 192\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x70,0x04,0x00,0x0A,0x04,0x00,0x71,0x04,0x00,0x80,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 193\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x72,0x04,0x00,0x09,0x04,0x00,0x71,0x04,0x00,0x82,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 194\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x72,0x04,0x00,0x09,0x04,0x00,0x72,0x04,0x00,0x81,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 195\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x72,0x04,0x00,0x08,0x04,0x00,0x72,0x04,0x00,0x80,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 196\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x1C,0x00,0x80,0x07,0x00,0x7E,0x04,0x00,0x0A,0x04,0x00,0x7E,0x04,0x00,0x80,0x07,0x00,0x00,0x1C,0x00,0x00,0x60, // 197\n  0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x06,0x00,0x80,0x05,0x00,0x60,0x04,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,  // 198\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x08,0x40,0x02,0x08,0xC0,0x02,0x08,0x40,0x03,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,  // 199\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x09,0x41,0x00,0x0A,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x40, // 200\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x0A,0x41,0x00,0x09,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x40, // 201\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x0A,0x41,0x00,0x09,0x41,0x00,0x09,0x41,0x00,0x0A,0x41,0x00,0x08,0x41,0x00,0x08,0x40, // 202\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x0A,0x41,0x00,0x08,0x41,0x00,0x0A,0x41,0x00,0x08,0x41,0x00,0x08,0x41,0x00,0x08,0x40, // 203\n  0x01,0x00,0x00,0xFA,0x7F, // 204\n  0x00,0x00,0x00,0xFA,0x7F,0x00,0x01, // 205\n  0x02,0x00,0x00,0xF9,0x7F,0x00,0x01,0x00,0x00,0x02,  // 206\n  0x02,0x00,0x00,0xF8,0x7F,0x00,0x02, // 207\n  0x00,0x02,0x00,0xF8,0x7F,0x00,0x08,0x42,0x00,0x08,0x42,0x00,0x08,0x42,0x00,0x08,0x42,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 208\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x10,0x00,0x00,0x60,0x00,0x00,0x82,0x00,0x00,0x01,0x03,0x00,0x02,0x04,0x00,0x01,0x18,0x00,0x00,0x20,0x00,0xF8,0x7F, // 209\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x09,0x40,0x00,0x0A,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 210\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x0A,0x40,0x00,0x09,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 211\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x0A,0x40,0x00,0x09,0x40,0x00,0x09,0x40,0x00,0x0A,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 212\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x0A,0x40,0x00,0x09,0x40,0x00,0x0A,0x40,0x00,0x09,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 213\n  0x00,0x00,0x00,0xC0,0x0F,0x00,0x20,0x10,0x00,0x10,0x20,0x00,0x08,0x40,0x00,0x0A,0x40,0x00,0x08,0x40,0x00,0x0A,0x40,0x00,0x10,0x20,0x00,0x20,0x10,0x00,0xC0,0x0F,  // 214\n  0x00,0x00,0x00,0x40,0x10,0x00,0x80,0x08,0x00,0x00,0x05,0x00,0x00,0x07,0x00,0x00,0x05,0x00,0x80,0x08,0x00,0x40,0x10, // 215\n  0x00,0x00,0x00,0xC0,0x4F,0x00,0x20,0x30,0x00,0x10,0x30,0x00,0x08,0x4C,0x00,0x08,0x42,0x00,0x08,0x41,0x00,0xC8,0x40,0x00,0x30,0x20,0x00,0x30,0x10,0x00,0xC8,0x0F,  // 216\n  0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x01,0x40,0x00,0x02,0x40,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xF8,0x1F, // 217\n  0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x02,0x40,0x00,0x01,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xF8,0x1F, // 218\n  0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x02,0x40,0x00,0x01,0x40,0x00,0x01,0x40,0x00,0x02,0x40,0x00,0x00,0x20,0x00,0xF8,0x1F, // 219\n  0x00,0x00,0x00,0xF8,0x1F,0x00,0x00,0x20,0x00,0x00,0x40,0x00,0x02,0x40,0x00,0x00,0x40,0x00,0x02,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xF8,0x1F, // 220\n  0x08,0x00,0x00,0x30,0x00,0x00,0x40,0x00,0x00,0x80,0x01,0x00,0x02,0x7E,0x00,0x81,0x01,0x00,0x40,0x00,0x00,0x30,0x00,0x00,0x08, // 221\n  0x00,0x00,0x00,0xF8,0x7F,0x00,0x20,0x10,0x00,0x20,0x10,0x00,0x20,0x10,0x00,0x20,0x10,0x00,0x20,0x10,0x00,0x20,0x10,0x00,0x40,0x08,0x00,0x80,0x07, // 222\n  0x00,0x00,0x00,0xE0,0x7F,0x00,0x10,0x00,0x00,0x08,0x20,0x00,0x88,0x43,0x00,0x70,0x42,0x00,0x00,0x44,0x00,0x00,0x38, // 223\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x40,0x44,0x00,0x48,0x44,0x00,0x50,0x42,0x00,0x40,0x22,0x00,0x80,0x7F, // 224\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x40,0x44,0x00,0x50,0x44,0x00,0x48,0x42,0x00,0x40,0x22,0x00,0x80,0x7F, // 225\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x50,0x44,0x00,0x48,0x44,0x00,0x48,0x42,0x00,0x50,0x22,0x00,0x80,0x7F, // 226\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x50,0x44,0x00,0x48,0x44,0x00,0x50,0x42,0x00,0x48,0x22,0x00,0x80,0x7F, // 227\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x50,0x44,0x00,0x40,0x44,0x00,0x50,0x42,0x00,0x40,0x22,0x00,0x80,0x7F, // 228\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x5C,0x44,0x00,0x54,0x44,0x00,0x5C,0x42,0x00,0x40,0x22,0x00,0x80,0x7F, // 229\n  0x00,0x00,0x00,0x00,0x39,0x00,0x80,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x42,0x00,0x40,0x22,0x00,0x80,0x3F,0x00,0x80,0x24,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x40,0x44,0x00,0x80,0x24,0x00,0x00,0x17, // 230\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x02,0x40,0xC0,0x02,0x40,0x40,0x03,0x80,0x20,  // 231\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x24,0x00,0x48,0x44,0x00,0x50,0x44,0x00,0x40,0x44,0x00,0x80,0x24,0x00,0x00,0x17, // 232\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x24,0x00,0x40,0x44,0x00,0x50,0x44,0x00,0x48,0x44,0x00,0x80,0x24,0x00,0x00,0x17, // 233\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x24,0x00,0x50,0x44,0x00,0x48,0x44,0x00,0x48,0x44,0x00,0x90,0x24,0x00,0x00,0x17, // 234\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x24,0x00,0x50,0x44,0x00,0x40,0x44,0x00,0x50,0x44,0x00,0x80,0x24,0x00,0x00,0x17, // 235\n  0x08,0x00,0x00,0xD0,0x7F, // 236\n  0x00,0x00,0x00,0xD0,0x7F,0x00,0x08, // 237\n  0x10,0x00,0x00,0xC8,0x7F,0x00,0x08,0x00,0x00,0x10,  // 238\n  0x10,0x00,0x00,0xC0,0x7F,0x00,0x10, // 239\n  0x00,0x00,0x00,0x00,0x1F,0x00,0xA0,0x20,0x00,0x68,0x40,0x00,0x58,0x40,0x00,0x70,0x40,0x00,0xE8,0x20,0x00,0x00,0x1F, // 240\n  0x00,0x00,0x00,0xC0,0x7F,0x00,0x90,0x00,0x00,0x48,0x00,0x00,0x50,0x00,0x00,0x48,0x00,0x00,0x80,0x7F,  // 241\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x48,0x40,0x00,0x50,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 242\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x40,0x40,0x00,0x50,0x40,0x00,0x48,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 243\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x50,0x40,0x00,0x48,0x40,0x00,0x48,0x40,0x00,0x90,0x20,0x00,0x00,0x1F, // 244\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x50,0x40,0x00,0x48,0x40,0x00,0x50,0x40,0x00,0x88,0x20,0x00,0x00,0x1F, // 245\n  0x00,0x00,0x00,0x00,0x1F,0x00,0x80,0x20,0x00,0x50,0x40,0x00,0x40,0x40,0x00,0x50,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 246\n  0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x80,0x0A,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x02, // 247\n  0x00,0x00,0x00,0x00,0x5F,0x00,0x80,0x30,0x00,0x40,0x48,0x00,0x40,0x44,0x00,0x40,0x42,0x00,0x80,0x21,0x00,0x40,0x1F, // 248\n  0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x40,0x00,0x08,0x40,0x00,0x10,0x40,0x00,0x00,0x20,0x00,0xC0,0x7F,  // 249\n  0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x10,0x40,0x00,0x08,0x20,0x00,0xC0,0x7F,  // 250\n  0x00,0x00,0x00,0xC0,0x3F,0x00,0x10,0x40,0x00,0x08,0x40,0x00,0x08,0x40,0x00,0x10,0x20,0x00,0xC0,0x7F,  // 251\n  0x00,0x00,0x00,0xD0,0x3F,0x00,0x00,0x40,0x00,0x10,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0xC0,0x7F,  // 252\n  0xC0,0x01,0x00,0x00,0x06,0x02,0x00,0x38,0x02,0x10,0xE0,0x01,0x08,0x38,0x00,0x00,0x07,0x00,0xC0, // 253\n  0x00,0x00,0x00,0xF8,0xFF,0x03,0x80,0x20,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x80,0x20,0x00,0x00,0x1F, // 254\n  0xC0,0x01,0x00,0x00,0x06,0x02,0x10,0x38,0x02,0x00,0xE0,0x01,0x10,0x38,0x00,0x00,0x07,0x00,0xC0  // 255\n};\nconst uint8_t ArialMT_Plain_24[] PROGMEM = {\n  0x18, // Width: 24\n  0x1C, // Height: 28\n  0x20, // First Char: 32\n  0xE0, // Numbers of Chars: 224\n\n  // Jump Table:\n  0xFF, 0xFF, 0x00, 0x07,  // 32:65535\n  0x00, 0x00, 0x13, 0x07,  // 33:0\n  0x00, 0x13, 0x1A, 0x09,  // 34:19\n  0x00, 0x2D, 0x33, 0x0D,  // 35:45\n  0x00, 0x60, 0x2F, 0x0D,  // 36:96\n  0x00, 0x8F, 0x4F, 0x15,  // 37:143\n  0x00, 0xDE, 0x3B, 0x10,  // 38:222\n  0x01, 0x19, 0x0A, 0x05,  // 39:281\n  0x01, 0x23, 0x1C, 0x08,  // 40:291\n  0x01, 0x3F, 0x1B, 0x08,  // 41:319\n  0x01, 0x5A, 0x21, 0x09,  // 42:346\n  0x01, 0x7B, 0x32, 0x0E,  // 43:379\n  0x01, 0xAD, 0x10, 0x07,  // 44:429\n  0x01, 0xBD, 0x1B, 0x08,  // 45:445\n  0x01, 0xD8, 0x0F, 0x07,  // 46:472\n  0x01, 0xE7, 0x19, 0x07,  // 47:487\n  0x02, 0x00, 0x2F, 0x0D,  // 48:512\n  0x02, 0x2F, 0x23, 0x0D,  // 49:559\n  0x02, 0x52, 0x2F, 0x0D,  // 50:594\n  0x02, 0x81, 0x2F, 0x0D,  // 51:641\n  0x02, 0xB0, 0x2F, 0x0D,  // 52:688\n  0x02, 0xDF, 0x2F, 0x0D,  // 53:735\n  0x03, 0x0E, 0x2F, 0x0D,  // 54:782\n  0x03, 0x3D, 0x2D, 0x0D,  // 55:829\n  0x03, 0x6A, 0x2F, 0x0D,  // 56:874\n  0x03, 0x99, 0x2F, 0x0D,  // 57:921\n  0x03, 0xC8, 0x0F, 0x07,  // 58:968\n  0x03, 0xD7, 0x10, 0x07,  // 59:983\n  0x03, 0xE7, 0x2F, 0x0E,  // 60:999\n  0x04, 0x16, 0x2F, 0x0E,  // 61:1046\n  0x04, 0x45, 0x2E, 0x0E,  // 62:1093\n  0x04, 0x73, 0x2E, 0x0D,  // 63:1139\n  0x04, 0xA1, 0x5B, 0x18,  // 64:1185\n  0x04, 0xFC, 0x3B, 0x10,  // 65:1276\n  0x05, 0x37, 0x3B, 0x10,  // 66:1335\n  0x05, 0x72, 0x3F, 0x11,  // 67:1394\n  0x05, 0xB1, 0x3F, 0x11,  // 68:1457\n  0x05, 0xF0, 0x3B, 0x10,  // 69:1520\n  0x06, 0x2B, 0x35, 0x0F,  // 70:1579\n  0x06, 0x60, 0x43, 0x13,  // 71:1632\n  0x06, 0xA3, 0x3B, 0x11,  // 72:1699\n  0x06, 0xDE, 0x0F, 0x07,  // 73:1758\n  0x06, 0xED, 0x27, 0x0C,  // 74:1773\n  0x07, 0x14, 0x3F, 0x10,  // 75:1812\n  0x07, 0x53, 0x2F, 0x0D,  // 76:1875\n  0x07, 0x82, 0x43, 0x14,  // 77:1922\n  0x07, 0xC5, 0x3B, 0x11,  // 78:1989\n  0x08, 0x00, 0x47, 0x13,  // 79:2048\n  0x08, 0x47, 0x3A, 0x10,  // 80:2119\n  0x08, 0x81, 0x47, 0x13,  // 81:2177\n  0x08, 0xC8, 0x3F, 0x11,  // 82:2248\n  0x09, 0x07, 0x3B, 0x10,  // 83:2311\n  0x09, 0x42, 0x35, 0x0F,  // 84:2370\n  0x09, 0x77, 0x3B, 0x11,  // 85:2423\n  0x09, 0xB2, 0x39, 0x10,  // 86:2482\n  0x09, 0xEB, 0x59, 0x17,  // 87:2539\n  0x0A, 0x44, 0x3B, 0x10,  // 88:2628\n  0x0A, 0x7F, 0x3D, 0x10,  // 89:2687\n  0x0A, 0xBC, 0x37, 0x0F,  // 90:2748\n  0x0A, 0xF3, 0x14, 0x07,  // 91:2803\n  0x0B, 0x07, 0x1B, 0x07,  // 92:2823\n  0x0B, 0x22, 0x18, 0x07,  // 93:2850\n  0x0B, 0x3A, 0x2A, 0x0B,  // 94:2874\n  0x0B, 0x64, 0x34, 0x0D,  // 95:2916\n  0x0B, 0x98, 0x11, 0x08,  // 96:2968\n  0x0B, 0xA9, 0x2F, 0x0D,  // 97:2985\n  0x0B, 0xD8, 0x33, 0x0D,  // 98:3032\n  0x0C, 0x0B, 0x2B, 0x0C,  // 99:3083\n  0x0C, 0x36, 0x2F, 0x0D,  // 100:3126\n  0x0C, 0x65, 0x2F, 0x0D,  // 101:3173\n  0x0C, 0x94, 0x1A, 0x07,  // 102:3220\n  0x0C, 0xAE, 0x2F, 0x0D,  // 103:3246\n  0x0C, 0xDD, 0x2F, 0x0D,  // 104:3293\n  0x0D, 0x0C, 0x0F, 0x05,  // 105:3340\n  0x0D, 0x1B, 0x10, 0x05,  // 106:3355\n  0x0D, 0x2B, 0x2F, 0x0C,  // 107:3371\n  0x0D, 0x5A, 0x0F, 0x05,  // 108:3418\n  0x0D, 0x69, 0x47, 0x14,  // 109:3433\n  0x0D, 0xB0, 0x2F, 0x0D,  // 110:3504\n  0x0D, 0xDF, 0x2F, 0x0D,  // 111:3551\n  0x0E, 0x0E, 0x33, 0x0D,  // 112:3598\n  0x0E, 0x41, 0x30, 0x0D,  // 113:3649\n  0x0E, 0x71, 0x1E, 0x08,  // 114:3697\n  0x0E, 0x8F, 0x2B, 0x0C,  // 115:3727\n  0x0E, 0xBA, 0x1B, 0x07,  // 116:3770\n  0x0E, 0xD5, 0x2F, 0x0D,  // 117:3797\n  0x0F, 0x04, 0x2A, 0x0C,  // 118:3844\n  0x0F, 0x2E, 0x42, 0x11,  // 119:3886\n  0x0F, 0x70, 0x2B, 0x0C,  // 120:3952\n  0x0F, 0x9B, 0x2A, 0x0C,  // 121:3995\n  0x0F, 0xC5, 0x2B, 0x0C,  // 122:4037\n  0x0F, 0xF0, 0x1C, 0x08,  // 123:4080\n  0x10, 0x0C, 0x10, 0x06,  // 124:4108\n  0x10, 0x1C, 0x1B, 0x08,  // 125:4124\n  0x10, 0x37, 0x32, 0x0E,  // 126:4151\n  0xFF, 0xFF, 0x00, 0x00,  // 127:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 128:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 129:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 130:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 131:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 132:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 133:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 134:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 135:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 136:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 137:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 138:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 139:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 140:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 141:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 142:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 143:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 144:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 145:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 146:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 147:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 148:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 149:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 150:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 151:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 152:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 153:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 154:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 155:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 156:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 157:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 158:65535\n  0xFF, 0xFF, 0x00, 0x18,  // 159:65535\n  0xFF, 0xFF, 0x00, 0x07,  // 160:65535\n  0x10, 0x69, 0x14, 0x08,  // 161:4201\n  0x10, 0x7D, 0x2B, 0x0D,  // 162:4221\n  0x10, 0xA8, 0x2F, 0x0D,  // 163:4264\n  0x10, 0xD7, 0x33, 0x0D,  // 164:4311\n  0x11, 0x0A, 0x31, 0x0D,  // 165:4362\n  0x11, 0x3B, 0x10, 0x06,  // 166:4411\n  0x11, 0x4B, 0x2F, 0x0D,  // 167:4427\n  0x11, 0x7A, 0x19, 0x08,  // 168:4474\n  0x11, 0x93, 0x46, 0x12,  // 169:4499\n  0x11, 0xD9, 0x1A, 0x09,  // 170:4569\n  0x11, 0xF3, 0x27, 0x0D,  // 171:4595\n  0x12, 0x1A, 0x2F, 0x0E,  // 172:4634\n  0x12, 0x49, 0x1B, 0x08,  // 173:4681\n  0x12, 0x64, 0x46, 0x12,  // 174:4708\n  0x12, 0xAA, 0x31, 0x0D,  // 175:4778\n  0x12, 0xDB, 0x1E, 0x0A,  // 176:4827\n  0x12, 0xF9, 0x33, 0x0D,  // 177:4857\n  0x13, 0x2C, 0x1A, 0x08,  // 178:4908\n  0x13, 0x46, 0x1A, 0x08,  // 179:4934\n  0x13, 0x60, 0x19, 0x08,  // 180:4960\n  0x13, 0x79, 0x2F, 0x0E,  // 181:4985\n  0x13, 0xA8, 0x31, 0x0D,  // 182:5032\n  0x13, 0xD9, 0x12, 0x08,  // 183:5081\n  0x13, 0xEB, 0x18, 0x08,  // 184:5099\n  0x14, 0x03, 0x16, 0x08,  // 185:5123\n  0x14, 0x19, 0x1E, 0x09,  // 186:5145\n  0x14, 0x37, 0x2E, 0x0D,  // 187:5175\n  0x14, 0x65, 0x4F, 0x14,  // 188:5221\n  0x14, 0xB4, 0x4B, 0x14,  // 189:5300\n  0x14, 0xFF, 0x4B, 0x14,  // 190:5375\n  0x15, 0x4A, 0x33, 0x0F,  // 191:5450\n  0x15, 0x7D, 0x3B, 0x10,  // 192:5501\n  0x15, 0xB8, 0x3B, 0x10,  // 193:5560\n  0x15, 0xF3, 0x3B, 0x10,  // 194:5619\n  0x16, 0x2E, 0x3B, 0x10,  // 195:5678\n  0x16, 0x69, 0x3B, 0x10,  // 196:5737\n  0x16, 0xA4, 0x3B, 0x10,  // 197:5796\n  0x16, 0xDF, 0x5B, 0x18,  // 198:5855\n  0x17, 0x3A, 0x3F, 0x11,  // 199:5946\n  0x17, 0x79, 0x3B, 0x10,  // 200:6009\n  0x17, 0xB4, 0x3B, 0x10,  // 201:6068\n  0x17, 0xEF, 0x3B, 0x10,  // 202:6127\n  0x18, 0x2A, 0x3B, 0x10,  // 203:6186\n  0x18, 0x65, 0x11, 0x07,  // 204:6245\n  0x18, 0x76, 0x11, 0x07,  // 205:6262\n  0x18, 0x87, 0x15, 0x07,  // 206:6279\n  0x18, 0x9C, 0x15, 0x07,  // 207:6300\n  0x18, 0xB1, 0x3F, 0x11,  // 208:6321\n  0x18, 0xF0, 0x3B, 0x11,  // 209:6384\n  0x19, 0x2B, 0x47, 0x13,  // 210:6443\n  0x19, 0x72, 0x47, 0x13,  // 211:6514\n  0x19, 0xB9, 0x47, 0x13,  // 212:6585\n  0x1A, 0x00, 0x47, 0x13,  // 213:6656\n  0x1A, 0x47, 0x47, 0x13,  // 214:6727\n  0x1A, 0x8E, 0x2B, 0x0E,  // 215:6798\n  0x1A, 0xB9, 0x47, 0x13,  // 216:6841\n  0x1B, 0x00, 0x3B, 0x11,  // 217:6912\n  0x1B, 0x3B, 0x3B, 0x11,  // 218:6971\n  0x1B, 0x76, 0x3B, 0x11,  // 219:7030\n  0x1B, 0xB1, 0x3B, 0x11,  // 220:7089\n  0x1B, 0xEC, 0x3D, 0x10,  // 221:7148\n  0x1C, 0x29, 0x3A, 0x10,  // 222:7209\n  0x1C, 0x63, 0x37, 0x0F,  // 223:7267\n  0x1C, 0x9A, 0x2F, 0x0D,  // 224:7322\n  0x1C, 0xC9, 0x2F, 0x0D,  // 225:7369\n  0x1C, 0xF8, 0x2F, 0x0D,  // 226:7416\n  0x1D, 0x27, 0x2F, 0x0D,  // 227:7463\n  0x1D, 0x56, 0x2F, 0x0D,  // 228:7510\n  0x1D, 0x85, 0x2F, 0x0D,  // 229:7557\n  0x1D, 0xB4, 0x53, 0x15,  // 230:7604\n  0x1E, 0x07, 0x2B, 0x0C,  // 231:7687\n  0x1E, 0x32, 0x2F, 0x0D,  // 232:7730\n  0x1E, 0x61, 0x2F, 0x0D,  // 233:7777\n  0x1E, 0x90, 0x2F, 0x0D,  // 234:7824\n  0x1E, 0xBF, 0x2F, 0x0D,  // 235:7871\n  0x1E, 0xEE, 0x11, 0x07,  // 236:7918\n  0x1E, 0xFF, 0x11, 0x07,  // 237:7935\n  0x1F, 0x10, 0x15, 0x07,  // 238:7952\n  0x1F, 0x25, 0x15, 0x07,  // 239:7973\n  0x1F, 0x3A, 0x2F, 0x0D,  // 240:7994\n  0x1F, 0x69, 0x2F, 0x0D,  // 241:8041\n  0x1F, 0x98, 0x2F, 0x0D,  // 242:8088\n  0x1F, 0xC7, 0x2F, 0x0D,  // 243:8135\n  0x1F, 0xF6, 0x2F, 0x0D,  // 244:8182\n  0x20, 0x25, 0x2F, 0x0D,  // 245:8229\n  0x20, 0x54, 0x2F, 0x0D,  // 246:8276\n  0x20, 0x83, 0x32, 0x0D,  // 247:8323\n  0x20, 0xB5, 0x33, 0x0F,  // 248:8373\n  0x20, 0xE8, 0x2F, 0x0D,  // 249:8424\n  0x21, 0x17, 0x2F, 0x0D,  // 250:8471\n  0x21, 0x46, 0x2F, 0x0D,  // 251:8518\n  0x21, 0x75, 0x2F, 0x0D,  // 252:8565\n  0x21, 0xA4, 0x2A, 0x0C,  // 253:8612\n  0x21, 0xCE, 0x2F, 0x0D,  // 254:8654\n  0x21, 0xFD, 0x2A, 0x0C,  // 255:8701\n\n  // Font Data:\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x33,0x00,0xE0,0xFF,0x33, // 33\n  0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,  // 34\n  0x00,0x0C,0x03,0x00,0x00,0x0C,0x33,0x00,0x00,0x0C,0x3F,0x00,0x00,0xFC,0x0F,0x00,0x80,0xFF,0x03,0x00,0xE0,0x0F,0x03,0x00,0x60,0x0C,0x33,0x00,0x00,0x0C,0x3F,0x00,0x00,0xFC,0x0F,0x00,0x80,0xFF,0x03,0x00,0xE0,0x0F,0x03,0x00,0x60,0x0C,0x03,0x00,0x00,0x0C,0x03, // 35\n  0x00,0x00,0x00,0x00,0x80,0x07,0x06,0x00,0xC0,0x0F,0x1E,0x00,0xC0,0x18,0x1C,0x00,0x60,0x18,0x38,0x00,0x60,0x30,0x30,0x00,0xF0,0xFF,0xFF,0x00,0x60,0x30,0x30,0x00,0x60,0x60,0x38,0x00,0xC0,0x60,0x18,0x00,0xC0,0xC1,0x1F,0x00,0x00,0x81,0x07, // 36\n  0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x1F,0x00,0x00,0x60,0x30,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x00,0x60,0x30,0x38,0x00,0xC0,0x1F,0x1E,0x00,0x80,0x8F,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0xF0,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x8F,0x0F,0x00,0xC0,0xC3,0x1F,0x00,0xE0,0x60,0x30,0x00,0x20,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00,0x60,0x30,0x00,0x00,0xC0,0x1F,0x00,0x00,0x80,0x0F, // 37\n  0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0xC0,0x0F,0x00,0x80,0xE3,0x1C,0x00,0xC0,0x77,0x38,0x00,0xE0,0x3C,0x30,0x00,0x60,0x38,0x30,0x00,0x60,0x78,0x30,0x00,0xE0,0xEC,0x38,0x00,0xC0,0x8F,0x1B,0x00,0x80,0x03,0x1F,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x1F,0x00,0x00,0xC0,0x38,0x00,0x00,0x00,0x10, // 38\n  0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x07,  // 39\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0x00,0x00,0xFE,0x7F,0x00,0x80,0x0F,0xF0,0x01,0xC0,0x01,0x80,0x03,0x60,0x00,0x00,0x06,0x20,0x00,0x00,0x04,  // 40\n  0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x04,0x60,0x00,0x00,0x06,0xC0,0x01,0x80,0x03,0x80,0x0F,0xF0,0x01,0x00,0xFE,0x7F,0x00,0x00,0xF0,0x0F, // 41\n  0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x04,0x00,0x00,0x80,0x0F,0x00,0x00,0xE0,0x03,0x00,0x00,0xE0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x80,0x04,0x00,0x00,0x80, // 42\n  0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,  // 43\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x03,0x00,0x00,0xF0,0x01,  // 44\n  0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01, // 45\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30, // 46\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0xE0,0x0F,0x00,0x00,0xFC,0x01,0x00,0x80,0x3F,0x00,0x00,0xE0,0x03,0x00,0x00,0x60, // 47\n  0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0x00,0x80,0xFF,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xE0,0x00,0x38,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x38,0x00,0xC0,0x01,0x1C,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFE,0x03, // 48\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x03,0x00,0x00,0x80,0x01,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 49\n  0x00,0x00,0x00,0x00,0x00,0x03,0x30,0x00,0xC0,0x03,0x38,0x00,0xC0,0x00,0x3C,0x00,0x60,0x00,0x36,0x00,0x60,0x00,0x33,0x00,0x60,0x80,0x31,0x00,0x60,0xC0,0x30,0x00,0x60,0x60,0x30,0x00,0xC0,0x30,0x30,0x00,0xC0,0x1F,0x30,0x00,0x00,0x0F,0x30, // 50\n  0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0xC0,0x01,0x0E,0x00,0xC0,0x00,0x1C,0x00,0x60,0x00,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0xC0,0x38,0x30,0x00,0xC0,0x6F,0x18,0x00,0x80,0xC7,0x0F,0x00,0x00,0x80,0x07, // 51\n  0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0xC0,0x03,0x00,0x00,0xF0,0x03,0x00,0x00,0x3C,0x03,0x00,0x00,0x0E,0x03,0x00,0x80,0x07,0x03,0x00,0xC0,0x01,0x03,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03, // 52\n  0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x00,0x80,0x3F,0x0E,0x00,0xE0,0x1F,0x18,0x00,0x60,0x08,0x30,0x00,0x60,0x0C,0x30,0x00,0x60,0x0C,0x30,0x00,0x60,0x0C,0x30,0x00,0x60,0x0C,0x30,0x00,0x60,0x18,0x1C,0x00,0x60,0xF0,0x0F,0x00,0x00,0xE0,0x03, // 53\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x80,0xFF,0x0F,0x00,0xC0,0x63,0x1C,0x00,0xC0,0x30,0x38,0x00,0x60,0x18,0x30,0x00,0x60,0x18,0x30,0x00,0x60,0x18,0x30,0x00,0x60,0x18,0x30,0x00,0xE0,0x30,0x18,0x00,0xC0,0xF1,0x0F,0x00,0x80,0xC1,0x07, // 54\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x3C,0x00,0x60,0x80,0x3F,0x00,0x60,0xE0,0x03,0x00,0x60,0x78,0x00,0x00,0x60,0x0E,0x00,0x00,0x60,0x03,0x00,0x00,0xE0,0x01,0x00,0x00,0x60, // 55\n  0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x80,0xC7,0x1F,0x00,0xC0,0x6F,0x18,0x00,0xE0,0x38,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0xE0,0x38,0x30,0x00,0xC0,0x6F,0x18,0x00,0x80,0xC7,0x1F,0x00,0x00,0x80,0x07, // 56\n  0x00,0x00,0x00,0x00,0x00,0x1F,0x0C,0x00,0x80,0x7F,0x1C,0x00,0xC0,0x61,0x38,0x00,0x60,0xC0,0x30,0x00,0x60,0xC0,0x30,0x00,0x60,0xC0,0x30,0x00,0x60,0xC0,0x30,0x00,0x60,0x60,0x18,0x00,0xC0,0x31,0x1E,0x00,0x80,0xFF,0x0F,0x00,0x00,0xFE,0x01, // 57\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30, // 58\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x30,0x03,0x00,0x06,0xF0,0x01,  // 59\n  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0xD8,0x00,0x00,0x00,0xD8,0x00,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x04,0x01,0x00,0x00,0x06,0x03,0x00,0x00,0x06,0x03,0x00,0x00,0x03,0x06, // 60\n  0x00,0x00,0x00,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01, // 61\n  0x00,0x00,0x00,0x00,0x00,0x03,0x06,0x00,0x00,0x06,0x03,0x00,0x00,0x06,0x03,0x00,0x00,0x04,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0x8C,0x01,0x00,0x00,0xD8,0x00,0x00,0x00,0xD8,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x20,  // 62\n  0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x80,0x03,0x00,0x00,0xC0,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x60,0x80,0x33,0x00,0x60,0xC0,0x33,0x00,0x60,0xE0,0x00,0x00,0x60,0x30,0x00,0x00,0xC0,0x38,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x07,  // 63\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x1E,0xF0,0x00,0x00,0x07,0xC0,0x01,0x80,0xC3,0x87,0x01,0xC0,0xF1,0x9F,0x03,0xC0,0x38,0x18,0x03,0xC0,0x0C,0x30,0x03,0x60,0x0E,0x30,0x06,0x60,0x06,0x30,0x06,0x60,0x06,0x18,0x06,0x60,0x06,0x0C,0x06,0x60,0x0C,0x1E,0x06,0x60,0xF8,0x3F,0x06,0xE0,0xFE,0x31,0x06,0xC0,0x0E,0x30,0x06,0xC0,0x01,0x18,0x03,0x80,0x03,0x1C,0x03,0x00,0x07,0x8F,0x01,0x00,0xFE,0x87,0x01,0x00,0xF8,0xC1,0x00,0x00,0x00,0x40, // 64\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x80,0x8F,0x01,0x00,0xE0,0x83,0x01,0x00,0x60,0x80,0x01,0x00,0xE0,0x83,0x01,0x00,0x80,0x8F,0x01,0x00,0x00,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 65\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0xC0,0x78,0x30,0x00,0xC0,0xFF,0x18,0x00,0x80,0xC7,0x1F,0x00,0x00,0x80,0x07, // 66\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x03,0x0F,0x00,0x00,0x02,0x03, // 67\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x03,0x0E,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 68\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 69\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60, // 70\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x18,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x60,0x30,0x00,0x60,0x60,0x30,0x00,0xE0,0x60,0x38,0x00,0xC0,0x60,0x18,0x00,0xC0,0x61,0x18,0x00,0x80,0xE3,0x0F,0x00,0x00,0xE2,0x0F, // 71\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 72\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 73\n  0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0xE0,0xFF,0x1F,0x00,0xE0,0xFF,0x0F, // 74\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0xE0,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xE7,0x01,0x00,0x80,0x83,0x07,0x00,0xC0,0x01,0x0F,0x00,0xE0,0x00,0x1E,0x00,0x60,0x00,0x38,0x00,0x20,0x00,0x30,0x00,0x00,0x00,0x20, // 75\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30, // 76\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0x01,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3F,0x00,0x00,0xE0,0x07,0x00,0x00,0xFE,0x00,0x00,0xC0,0x0F,0x00,0x00,0xE0,0x01,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 77\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0xC0,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 78\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x38,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 79\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00,0xC0,0x30,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0x0F,  // 80\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x0C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x18,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x36,0x00,0x60,0x00,0x36,0x00,0xE0,0x00,0x3C,0x00,0xC0,0x00,0x1C,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x3F,0x00,0x00,0xFF,0x77,0x00,0x00,0xFC,0x61, // 81\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x70,0x00,0x00,0x60,0xF0,0x00,0x00,0x60,0xF0,0x03,0x00,0x60,0xB0,0x07,0x00,0xE0,0x18,0x1F,0x00,0xC0,0x1F,0x3C,0x00,0x80,0x0F,0x30,0x00,0x00,0x00,0x20, // 82\n  0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x07,0x0F,0x00,0xC0,0x1F,0x1C,0x00,0xC0,0x18,0x18,0x00,0x60,0x38,0x38,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x70,0x30,0x00,0xC0,0x60,0x18,0x00,0xC0,0xE1,0x18,0x00,0x80,0xC3,0x0F,0x00,0x00,0x83,0x07, // 83\n  0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60, // 84\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x0F,0x00,0xE0,0xFF,0x03, // 85\n  0x20,0x00,0x00,0x00,0xE0,0x01,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0xF8,0x01,0x00,0x00,0xC0,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x3E,0x00,0x00,0xC0,0x0F,0x00,0x00,0xF8,0x01,0x00,0x00,0x3E,0x00,0x00,0xC0,0x0F,0x00,0x00,0xE0,0x01,0x00,0x00,0x20, // 86\n  0x60,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0x80,0xFF,0x00,0x00,0x00,0xF8,0x0F,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3F,0x00,0x00,0xE0,0x0F,0x00,0x00,0xFC,0x01,0x00,0x80,0x1F,0x00,0x00,0xE0,0x03,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x30,0x00,0x00,0x80,0x3F,0x00,0x00,0xF8,0x0F,0x00,0x80,0xFF,0x00,0x00,0xE0,0x07,0x00,0x00,0x60, // 87\n  0x00,0x00,0x20,0x00,0x20,0x00,0x30,0x00,0x60,0x00,0x3C,0x00,0xE0,0x01,0x1E,0x00,0xC0,0x83,0x07,0x00,0x00,0xCF,0x03,0x00,0x00,0xFE,0x01,0x00,0x00,0x38,0x00,0x00,0x00,0xFE,0x01,0x00,0x00,0xCF,0x03,0x00,0xC0,0x03,0x07,0x00,0xE0,0x01,0x1E,0x00,0x60,0x00,0x3C,0x00,0x20,0x00,0x30,0x00,0x00,0x00,0x20, // 88\n  0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0xF0,0x3F,0x00,0x00,0xF0,0x3F,0x00,0x00,0x3C,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x07,0x00,0x00,0xC0,0x03,0x00,0x00,0xE0,0x01,0x00,0x00,0x60,0x00,0x00,0x00,0x20, // 89\n  0x00,0x00,0x30,0x00,0x60,0x00,0x38,0x00,0x60,0x00,0x3C,0x00,0x60,0x00,0x37,0x00,0x60,0x80,0x33,0x00,0x60,0xC0,0x31,0x00,0x60,0xE0,0x30,0x00,0x60,0x38,0x30,0x00,0x60,0x1C,0x30,0x00,0x60,0x0E,0x30,0x00,0x60,0x07,0x30,0x00,0xE0,0x01,0x30,0x00,0xE0,0x00,0x30,0x00,0x60,0x00,0x30, // 90\n  0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x07,0xE0,0xFF,0xFF,0x07,0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x06,  // 91\n  0x60,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 92\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0xE0,0xFF,0xFF,0x07,0xE0,0xFF,0xFF,0x07,  // 93\n  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1F,0x00,0x00,0xC0,0x07,0x00,0x00,0xE0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x20,  // 94\n  0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,  // 95\n  0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x80, // 96\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0x00,0x8C,0x39,0x00,0x00,0x86,0x31,0x00,0x00,0x86,0x31,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x18,0x00,0x00,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 97\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x18,0x0C,0x00,0x00,0x0C,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xE0,0x03, // 98\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0x18,0x0C, // 99\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0C,0x18,0x00,0x00,0x18,0x0C,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 100\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0xDC,0x1C,0x00,0x00,0xCE,0x38,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xCE,0x38,0x00,0x00,0xDC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xF0,0x04, // 101\n  0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0xC0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x06,0x00,0x00,0x60,0x06,0x00,0x00,0x60,0x06,  // 102\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x83,0x01,0x00,0xF8,0x8F,0x03,0x00,0x1C,0x1C,0x07,0x00,0x0E,0x38,0x06,0x00,0x06,0x30,0x06,0x00,0x06,0x30,0x06,0x00,0x06,0x30,0x06,0x00,0x0C,0x18,0x07,0x00,0x18,0x8C,0x03,0x00,0xFE,0xFF,0x01,0x00,0xFE,0xFF, // 103\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0xF8,0x3F, // 104\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xFE,0x3F,0x00,0x60,0xFE,0x3F, // 105\n  0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x60,0xFE,0xFF,0x07,0x60,0xFE,0xFF,0x03,  // 106\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0xC0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xF0,0x01,0x00,0x00,0x98,0x07,0x00,0x00,0x0C,0x0E,0x00,0x00,0x06,0x3C,0x00,0x00,0x02,0x30,0x00,0x00,0x00,0x20, // 107\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 108\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0xF8,0x3F, // 109\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0xFC,0x3F,0x00,0x00,0xF8,0x3F, // 110\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 111\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0xFE,0xFF,0x07,0x00,0x18,0x0C,0x00,0x00,0x0C,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xE0,0x03, // 112\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0C,0x18,0x00,0x00,0x18,0x0C,0x00,0x00,0xFE,0xFF,0x07,0x00,0xFE,0xFF,0x07,  // 113\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,  // 114\n  0x00,0x00,0x00,0x00,0x00,0x38,0x0C,0x00,0x00,0x7C,0x1C,0x00,0x00,0xEE,0x38,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x31,0x00,0x00,0xC6,0x31,0x00,0x00,0x8E,0x39,0x00,0x00,0x9C,0x1F,0x00,0x00,0x18,0x0F, // 115\n  0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0xC0,0xFF,0x1F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30, // 116\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 117\n  0x00,0x06,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xC0,0x07,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1F,0x00,0x00,0xC0,0x07,0x00,0x00,0xF8,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x06,  // 118\n  0x00,0x0E,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x80,0x1F,0x00,0x00,0xE0,0x03,0x00,0x00,0x7C,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x80,0x1F,0x00,0x00,0xF0,0x03,0x00,0x00,0x7E,0x00,0x00,0x00,0x0E,  // 119\n  0x00,0x02,0x20,0x00,0x00,0x06,0x30,0x00,0x00,0x1E,0x3C,0x00,0x00,0x38,0x0E,0x00,0x00,0xF0,0x07,0x00,0x00,0xC0,0x01,0x00,0x00,0xE0,0x07,0x00,0x00,0x38,0x0E,0x00,0x00,0x1C,0x3C,0x00,0x00,0x0E,0x30,0x00,0x00,0x02,0x20, // 120\n  0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x7E,0x00,0x06,0x00,0xF0,0x01,0x06,0x00,0x80,0x0F,0x07,0x00,0x00,0xFE,0x03,0x00,0x00,0xFC,0x00,0x00,0xC0,0x1F,0x00,0x00,0xF8,0x03,0x00,0x00,0x3E,0x00,0x00,0x00,0x06,  // 121\n  0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x06,0x3C,0x00,0x00,0x06,0x3E,0x00,0x00,0x06,0x37,0x00,0x00,0xC6,0x33,0x00,0x00,0xE6,0x30,0x00,0x00,0x76,0x30,0x00,0x00,0x3E,0x30,0x00,0x00,0x1E,0x30,0x00,0x00,0x06,0x30, // 122\n  0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0xC0,0x03,0x00,0xC0,0x7F,0xFE,0x03,0xE0,0x3F,0xFC,0x07,0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x06,  // 123\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x0F,0xE0,0xFF,0xFF,0x0F,  // 124\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0xE0,0x3F,0xFC,0x07,0xC0,0x7F,0xFF,0x03,0x00,0xC0,0x03,0x00,0x00,0x80,0x01, // 125\n  0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x60,  // 126\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE6,0xFF,0x07,0x00,0xE6,0xFF,0x07,  // 161\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x9C,0x07,0x00,0x0E,0x78,0x00,0x00,0x06,0x3F,0x00,0x00,0xF6,0x30,0x00,0x00,0x0E,0x30,0x00,0xE0,0x0D,0x1C,0x00,0x00,0x1C,0x0E,0x00,0x00,0x10,0x06, // 162\n  0x00,0x60,0x10,0x00,0x00,0x60,0x38,0x00,0x00,0x7F,0x1C,0x00,0xC0,0xFF,0x1F,0x00,0xE0,0xE0,0x19,0x00,0x60,0x60,0x18,0x00,0x60,0x60,0x18,0x00,0x60,0x60,0x30,0x00,0xE0,0x00,0x30,0x00,0xC0,0x01,0x30,0x00,0x80,0x01,0x38,0x00,0x00,0x00,0x10, // 163\n  0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x00,0x00,0xF7,0x0E,0x00,0x00,0xFE,0x07,0x00,0x00,0x0C,0x03,0x00,0x00,0x06,0x06,0x00,0x00,0x06,0x06,0x00,0x00,0x06,0x06,0x00,0x00,0x06,0x06,0x00,0x00,0x0C,0x03,0x00,0x00,0xFE,0x07,0x00,0x00,0xF7,0x0E,0x00,0x00,0x02,0x04, // 164\n  0xE0,0x60,0x06,0x00,0xC0,0x61,0x06,0x00,0x80,0x67,0x06,0x00,0x00,0x7E,0x06,0x00,0x00,0x7C,0x06,0x00,0x00,0xF0,0x3F,0x00,0x00,0xF0,0x3F,0x00,0x00,0x7C,0x06,0x00,0x00,0x7E,0x06,0x00,0x80,0x67,0x06,0x00,0xC0,0x61,0x06,0x00,0xE0,0x60,0x06,0x00,0x20, // 165\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x7F,0xF8,0x0F,0xE0,0x7F,0xF8,0x0F,  // 166\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x80,0xF3,0xC1,0x00,0xC0,0x1F,0xC3,0x03,0xE0,0x0C,0x07,0x03,0x60,0x1C,0x06,0x06,0x60,0x18,0x0C,0x06,0x60,0x30,0x1C,0x06,0xE0,0x70,0x38,0x07,0xC0,0xE1,0xF4,0x03,0x80,0xC1,0xE7,0x01,0x00,0x80,0x03, // 167\n  0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60, // 168\n  0x00,0xF8,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x07,0x07,0x00,0x80,0x01,0x0C,0x00,0xC0,0x79,0x1C,0x00,0xC0,0xFE,0x19,0x00,0x60,0x86,0x31,0x00,0x60,0x03,0x33,0x00,0x60,0x03,0x33,0x00,0x60,0x03,0x33,0x00,0x60,0x03,0x33,0x00,0x60,0x87,0x33,0x00,0xC0,0x86,0x19,0x00,0xC0,0x85,0x1C,0x00,0x80,0x01,0x0C,0x00,0x00,0x07,0x07,0x00,0x00,0xFE,0x03,0x00,0x00,0xF8,  // 169\n  0x00,0x00,0x00,0x00,0xC0,0x1C,0x00,0x00,0xE0,0x3E,0x00,0x00,0x60,0x32,0x00,0x00,0x60,0x32,0x00,0x00,0xE0,0x3F,0x00,0x00,0xC0,0x3F,  // 170\n  0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x78,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x84,0x10,0x00,0x00,0xE0,0x03,0x00,0x00,0x78,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x04,0x10, // 171\n  0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFC,0x01, // 172\n  0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01,0x00,0x00,0x80,0x01, // 173\n  0x00,0xF8,0x00,0x00,0x00,0xFE,0x03,0x00,0x00,0x07,0x07,0x00,0x80,0x01,0x0C,0x00,0xC0,0x01,0x1C,0x00,0xC0,0xFE,0x1B,0x00,0x60,0xFE,0x33,0x00,0x60,0x66,0x30,0x00,0x60,0x66,0x30,0x00,0x60,0xE6,0x30,0x00,0x60,0xFE,0x31,0x00,0x60,0x3C,0x33,0x00,0xC0,0x00,0x1A,0x00,0xC0,0x01,0x1C,0x00,0x80,0x01,0x0C,0x00,0x00,0x07,0x07,0x00,0x00,0xFE,0x03,0x00,0x00,0xF8,  // 174\n  0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C, // 175\n  0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x40,0x04,0x00,0x00,0x20,0x08,0x00,0x00,0x20,0x08,0x00,0x00,0x20,0x08,0x00,0x00,0x40,0x04,0x00,0x00,0x80,0x03,  // 176\n  0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0xFF,0x3F,0x00,0x00,0xFF,0x3F,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30,0x00,0x00,0x60,0x30, // 177\n  0x40,0x20,0x00,0x00,0x60,0x30,0x00,0x00,0x20,0x38,0x00,0x00,0x20,0x2C,0x00,0x00,0x20,0x26,0x00,0x00,0xE0,0x23,0x00,0x00,0xC0,0x21,  // 178\n  0x40,0x10,0x00,0x00,0x60,0x30,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x22,0x00,0x00,0x20,0x22,0x00,0x00,0xE0,0x3D,0x00,0x00,0xC0,0x1D,  // 179\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x20, // 180\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x07,0x00,0xFE,0xFF,0x07,0x00,0x00,0x1C,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x1C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 181\n  0x00,0x0F,0x00,0x00,0xC0,0x3F,0x00,0x00,0xC0,0x3F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0x7F,0x00,0x00,0xE0,0xFF,0xFF,0x07,0xE0,0xFF,0xFF,0x07,0x60,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x07,0xE0,0xFF,0xFF,0x07,0x60,0x00,0x00,0x00,0x60, // 182\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x60,  // 183\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0xC0,0x02,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x01,  // 184\n  0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xE0,0x3F,0x00,0x00,0xE0,0x3F,  // 185\n  0x00,0x00,0x00,0x00,0x80,0x0F,0x00,0x00,0xC0,0x1F,0x00,0x00,0xE0,0x38,0x00,0x00,0x60,0x30,0x00,0x00,0xE0,0x38,0x00,0x00,0xC0,0x1F,0x00,0x00,0x80,0x0F,  // 186\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x00,0x00,0x1C,0x1C,0x00,0x00,0x78,0x0F,0x00,0x00,0xE0,0x03,0x00,0x00,0x84,0x10,0x00,0x00,0x1C,0x1C,0x00,0x00,0x78,0x0F,0x00,0x00,0xE0,0x03,0x00,0x00,0x80,  // 187\n  0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x20,0x00,0xE0,0x3F,0x38,0x00,0xE0,0x3F,0x1C,0x00,0x00,0x00,0x0E,0x00,0x00,0x80,0x03,0x00,0x00,0xC0,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x07,0x0C,0x00,0xC0,0x01,0x0E,0x00,0xE0,0x80,0x0B,0x00,0x60,0xC0,0x08,0x00,0x00,0xE0,0x3F,0x00,0x00,0xE0,0x3F,0x00,0x00,0x00,0x08, // 188\n  0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0xC0,0x00,0x00,0x00,0xC0,0x00,0x20,0x00,0xE0,0x3F,0x30,0x00,0xE0,0x3F,0x1C,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x07,0x00,0x00,0xC0,0x01,0x00,0x00,0xE0,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x4E,0x20,0x00,0x00,0x67,0x30,0x00,0xC0,0x21,0x38,0x00,0xE0,0x20,0x2C,0x00,0x60,0x20,0x26,0x00,0x00,0xE0,0x27,0x00,0x00,0xC0,0x21, // 189\n  0x40,0x10,0x00,0x00,0x60,0x30,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x22,0x20,0x00,0x20,0x22,0x30,0x00,0xE0,0x3D,0x38,0x00,0xC0,0x1D,0x0E,0x00,0x00,0x00,0x07,0x00,0x00,0x80,0x03,0x00,0x00,0xE0,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x0E,0x0C,0x00,0x00,0x07,0x0E,0x00,0x80,0x83,0x0B,0x00,0xE0,0xC0,0x08,0x00,0x60,0xE0,0x3F,0x00,0x20,0xE0,0x3F,0x00,0x00,0x00,0x08, // 190\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF8,0x03,0x00,0x00,0x1E,0x03,0x00,0x00,0x07,0x07,0x00,0xE6,0x03,0x06,0x00,0xE6,0x01,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x80,0x03,0x00,0x00,0xC0,0x01,0x00,0x00,0xC0, // 191\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x82,0x8F,0x01,0x00,0xE6,0x83,0x01,0x00,0x6E,0x80,0x01,0x00,0xE8,0x83,0x01,0x00,0x80,0x8F,0x01,0x00,0x00,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 192\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x80,0x8F,0x01,0x00,0xE8,0x83,0x01,0x00,0x6E,0x80,0x01,0x00,0xE6,0x83,0x01,0x00,0x82,0x8F,0x01,0x00,0x00,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 193\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x88,0x8F,0x01,0x00,0xEC,0x83,0x01,0x00,0x66,0x80,0x01,0x00,0xE6,0x83,0x01,0x00,0x8C,0x8F,0x01,0x00,0x08,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 194\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x0C,0xFE,0x01,0x00,0x8E,0x8F,0x01,0x00,0xE6,0x83,0x01,0x00,0x66,0x80,0x01,0x00,0xEC,0x83,0x01,0x00,0x8C,0x8F,0x01,0x00,0x0E,0xFE,0x01,0x00,0x06,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 195\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x8C,0x8F,0x01,0x00,0xEC,0x83,0x01,0x00,0x60,0x80,0x01,0x00,0xE0,0x83,0x01,0x00,0x8C,0x8F,0x01,0x00,0x0C,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 196\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3E,0x00,0x00,0x80,0x0F,0x00,0x00,0xF0,0x03,0x00,0x00,0xFE,0x01,0x00,0x9C,0x8F,0x01,0x00,0xE2,0x83,0x01,0x00,0x62,0x80,0x01,0x00,0xE2,0x83,0x01,0x00,0x9C,0x8F,0x01,0x00,0x00,0xFE,0x01,0x00,0x00,0xF0,0x03,0x00,0x00,0x80,0x0F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x30, // 197\n  0x00,0x00,0x30,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x0F,0x00,0x00,0xC0,0x03,0x00,0x00,0xF0,0x01,0x00,0x00,0xBC,0x01,0x00,0x00,0x8F,0x01,0x00,0xC0,0x83,0x01,0x00,0xE0,0x80,0x01,0x00,0x60,0x80,0x01,0x00,0x60,0x80,0x01,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 198\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0x60,0x00,0x30,0x02,0x60,0x00,0x30,0x02,0x60,0x00,0xF0,0x02,0x60,0x00,0xB0,0x03,0x60,0x00,0x30,0x01,0x60,0x00,0x30,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x03,0x0F,0x00,0x00,0x02,0x03, // 199\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x62,0x30,0x30,0x00,0x66,0x30,0x30,0x00,0x6E,0x30,0x30,0x00,0x68,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 200\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x68,0x30,0x30,0x00,0x6E,0x30,0x30,0x00,0x66,0x30,0x30,0x00,0x62,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 201\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x68,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x66,0x30,0x30,0x00,0x66,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x68,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 202\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x6C,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30, // 203\n  0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0xE6,0xFF,0x3F,0x00,0xEE,0xFF,0x3F,0x00,0x08, // 204\n  0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xEE,0xFF,0x3F,0x00,0xE6,0xFF,0x3F,0x00,0x02, // 205\n  0x08,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xE6,0xFF,0x3F,0x00,0xE6,0xFF,0x3F,0x00,0x0C,0x00,0x00,0x00,0x08, // 206\n  0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x0C,0x00,0x00,0x00,0x0C, // 207\n  0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x30,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x03,0x0E,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 208\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0xC0,0x01,0x00,0x00,0x8C,0x03,0x00,0x00,0x0E,0x0E,0x00,0x00,0x06,0x3C,0x00,0x00,0x06,0x70,0x00,0x00,0x0C,0xE0,0x01,0x00,0x0C,0x80,0x03,0x00,0x0E,0x00,0x0F,0x00,0x06,0x00,0x1C,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F, // 209\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x38,0x00,0x62,0x00,0x30,0x00,0x66,0x00,0x30,0x00,0x6E,0x00,0x30,0x00,0x68,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 210\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x38,0x00,0x60,0x00,0x30,0x00,0x68,0x00,0x30,0x00,0x6E,0x00,0x30,0x00,0x66,0x00,0x30,0x00,0x62,0x00,0x30,0x00,0xE0,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 211\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x38,0x00,0x68,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0x66,0x00,0x30,0x00,0x66,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0xE8,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 212\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xCC,0x00,0x18,0x00,0xEE,0x00,0x38,0x00,0x66,0x00,0x30,0x00,0x66,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0x6E,0x00,0x30,0x00,0xE6,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 213\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0xFF,0x07,0x00,0x80,0x07,0x0F,0x00,0xC0,0x01,0x1C,0x00,0xC0,0x00,0x18,0x00,0xE0,0x00,0x38,0x00,0x6C,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x6C,0x00,0x30,0x00,0xEC,0x00,0x38,0x00,0xC0,0x00,0x18,0x00,0xC0,0x01,0x1C,0x00,0x80,0x07,0x0F,0x00,0x00,0xFF,0x07,0x00,0x00,0xFC,0x01, // 214\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x00,0x00,0x8E,0x03,0x00,0x00,0xDC,0x01,0x00,0x00,0xF8,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xDC,0x01,0x00,0x00,0x8E,0x03,0x00,0x00,0x06,0x03, // 215\n  0x00,0x00,0x00,0x00,0x00,0xFC,0x21,0x00,0x00,0xFF,0x77,0x00,0x80,0x07,0x3F,0x00,0xC0,0x01,0x1E,0x00,0xC0,0x00,0x1F,0x00,0xE0,0x80,0x3B,0x00,0x60,0xC0,0x31,0x00,0x60,0xE0,0x30,0x00,0x60,0x70,0x30,0x00,0x60,0x38,0x30,0x00,0x60,0x1C,0x30,0x00,0xE0,0x0E,0x38,0x00,0xC0,0x07,0x18,0x00,0xC0,0x03,0x1C,0x00,0xE0,0x07,0x0F,0x00,0x70,0xFF,0x07,0x00,0x20,0xFC,0x01, // 216\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x02,0x00,0x30,0x00,0x06,0x00,0x30,0x00,0x0E,0x00,0x30,0x00,0x08,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x0F,0x00,0xE0,0xFF,0x03, // 217\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x30,0x00,0x0E,0x00,0x30,0x00,0x06,0x00,0x30,0x00,0x02,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x0F,0x00,0xE0,0xFF,0x03, // 218\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x08,0x00,0x30,0x00,0x0C,0x00,0x30,0x00,0x06,0x00,0x30,0x00,0x06,0x00,0x30,0x00,0x0C,0x00,0x30,0x00,0x08,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x0F,0x00,0xE0,0xFF,0x03, // 219\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x03,0x00,0xE0,0xFF,0x0F,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x38,0x00,0x0C,0x00,0x30,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x30,0x00,0x0C,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0xE0,0xFF,0x0F,0x00,0xE0,0xFF,0x03, // 220\n  0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x3C,0x00,0x00,0x08,0xF0,0x3F,0x00,0x0E,0xF0,0x3F,0x00,0x06,0x3C,0x00,0x00,0x02,0x1E,0x00,0x00,0x00,0x07,0x00,0x00,0xC0,0x03,0x00,0x00,0xE0,0x01,0x00,0x00,0x60,0x00,0x00,0x00,0x20, // 221\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x00,0xE0,0xFF,0x3F,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x06,0x00,0x00,0x03,0x07,0x00,0x00,0x86,0x03,0x00,0x00,0xFE,0x01,0x00,0x00,0xF8,  // 222\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x3F,0x00,0xC0,0xFF,0x3F,0x00,0xC0,0x00,0x00,0x00,0x60,0x00,0x08,0x00,0x60,0x00,0x1C,0x00,0x60,0x00,0x38,0x00,0xE0,0x78,0x30,0x00,0xC0,0x7F,0x30,0x00,0x80,0xC7,0x30,0x00,0x00,0x80,0x39,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x0F, // 223\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0x00,0x8C,0x39,0x00,0x20,0x86,0x31,0x00,0x60,0x86,0x31,0x00,0xE0,0xC6,0x30,0x00,0x80,0xC6,0x18,0x00,0x00,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 224\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0x00,0x8C,0x39,0x00,0x00,0x86,0x31,0x00,0x80,0x86,0x31,0x00,0xE0,0xC6,0x30,0x00,0x60,0xC6,0x18,0x00,0x20,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 225\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0x80,0x8C,0x39,0x00,0xC0,0x86,0x31,0x00,0x60,0x86,0x31,0x00,0x60,0xC6,0x30,0x00,0xC0,0xC6,0x18,0x00,0x80,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 226\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0xC0,0x1C,0x1F,0x00,0xE0,0x8C,0x39,0x00,0x60,0x86,0x31,0x00,0x60,0x86,0x31,0x00,0xC0,0xC6,0x30,0x00,0xC0,0xC6,0x18,0x00,0xE0,0xCE,0x0C,0x00,0x60,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 227\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0xC0,0x8C,0x39,0x00,0xC0,0x86,0x31,0x00,0x00,0x86,0x31,0x00,0x00,0xC6,0x30,0x00,0xC0,0xC6,0x18,0x00,0xC0,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 228\n  0x00,0x00,0x00,0x00,0x00,0x18,0x0E,0x00,0x00,0x1C,0x1F,0x00,0x00,0x8C,0x39,0x00,0x70,0x86,0x31,0x00,0x88,0x86,0x31,0x00,0x88,0xC6,0x30,0x00,0x88,0xC6,0x18,0x00,0x70,0xCE,0x0C,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0x00,0x20, // 229\n  0x00,0x00,0x00,0x00,0x00,0x10,0x0F,0x00,0x00,0x9C,0x1F,0x00,0x00,0xCC,0x39,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0x66,0x18,0x00,0x00,0x6E,0x1C,0x00,0x00,0xFC,0x0F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xCC,0x1C,0x00,0x00,0xCE,0x38,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xCC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xE0,0x04, // 230\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x02,0x00,0x06,0x30,0x02,0x00,0x06,0xF0,0x02,0x00,0x06,0xB0,0x03,0x00,0x0E,0x38,0x01,0x00,0x1C,0x1C,0x00,0x00,0x18,0x0C, // 231\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0xDC,0x1C,0x00,0x20,0xCE,0x38,0x00,0x60,0xC6,0x30,0x00,0xE0,0xC6,0x30,0x00,0x80,0xC6,0x30,0x00,0x00,0xCE,0x38,0x00,0x00,0xDC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xF0,0x04, // 232\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0xDC,0x1C,0x00,0x00,0xCE,0x38,0x00,0x80,0xC6,0x30,0x00,0xE0,0xC6,0x30,0x00,0x60,0xC6,0x30,0x00,0x20,0xCE,0x38,0x00,0x00,0xDC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xF0,0x04, // 233\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0xDC,0x1C,0x00,0x80,0xCE,0x38,0x00,0xC0,0xC6,0x30,0x00,0x60,0xC6,0x30,0x00,0x60,0xC6,0x30,0x00,0xC0,0xCE,0x38,0x00,0x80,0xDC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xF0,0x04, // 234\n  0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0xDC,0x1C,0x00,0xC0,0xCE,0x38,0x00,0xC0,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0x00,0xC6,0x30,0x00,0xC0,0xCE,0x38,0x00,0xC0,0xDC,0x18,0x00,0x00,0xF8,0x0C,0x00,0x00,0xF0,0x04, // 235\n  0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0xFE,0x3F,0x00,0xE0,0xFE,0x3F,0x00,0x80, // 236\n  0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xE0,0xFE,0x3F,0x00,0x60,0xFE,0x3F,0x00,0x20, // 237\n  0x80,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x60,0xFE,0x3F,0x00,0x60,0xFE,0x3F,0x00,0xC0,0x00,0x00,0x00,0x80, // 238\n  0xC0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F,0x00,0xC0,0x00,0x00,0x00,0xC0, // 239\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1D,0x1C,0x00,0xA0,0x0F,0x38,0x00,0xA0,0x06,0x30,0x00,0xE0,0x06,0x30,0x00,0xC0,0x06,0x30,0x00,0xC0,0x0F,0x38,0x00,0x20,0x1F,0x1C,0x00,0x00,0xFC,0x0F,0x00,0x00,0xE0,0x07, // 240\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0xC0,0xFE,0x3F,0x00,0xE0,0x18,0x00,0x00,0x60,0x0C,0x00,0x00,0x60,0x06,0x00,0x00,0xC0,0x06,0x00,0x00,0xC0,0x06,0x00,0x00,0xE0,0x0E,0x00,0x00,0x60,0xFC,0x3F,0x00,0x00,0xF8,0x3F, // 241\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x20,0x0E,0x38,0x00,0x60,0x06,0x30,0x00,0xE0,0x06,0x30,0x00,0x80,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 242\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x38,0x00,0x80,0x06,0x30,0x00,0xE0,0x06,0x30,0x00,0x60,0x06,0x30,0x00,0x20,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 243\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0x80,0x0E,0x38,0x00,0xC0,0x06,0x30,0x00,0x60,0x06,0x30,0x00,0x60,0x06,0x30,0x00,0xC0,0x0E,0x38,0x00,0x80,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 244\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0xC0,0x1C,0x1C,0x00,0xE0,0x0E,0x38,0x00,0x60,0x06,0x30,0x00,0x60,0x06,0x30,0x00,0xC0,0x06,0x30,0x00,0xC0,0x0E,0x38,0x00,0xE0,0x1C,0x1C,0x00,0x60,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 245\n  0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0xF8,0x0F,0x00,0x00,0x1C,0x1C,0x00,0xC0,0x0E,0x38,0x00,0xC0,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0xC0,0x0E,0x38,0x00,0xC0,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x07, // 246\n  0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0xB6,0x01,0x00,0x00,0xB6,0x01,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,  // 247\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x67,0x00,0x00,0xF8,0x7F,0x00,0x00,0x1C,0x1C,0x00,0x00,0x0E,0x3F,0x00,0x00,0x86,0x33,0x00,0x00,0xE6,0x31,0x00,0x00,0x76,0x30,0x00,0x00,0x3E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xFF,0x0F,0x00,0x00,0xF3,0x07, // 248\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x20,0x00,0x38,0x00,0x60,0x00,0x30,0x00,0xE0,0x00,0x30,0x00,0x80,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 249\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x30,0x00,0x80,0x00,0x30,0x00,0xE0,0x00,0x30,0x00,0x60,0x00,0x18,0x00,0x20,0x00,0x0C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 250\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x1F,0x00,0x80,0x00,0x38,0x00,0xC0,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x30,0x00,0xC0,0x00,0x18,0x00,0x80,0x00,0x0C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 251\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0x00,0x00,0xFE,0x1F,0x00,0xC0,0x00,0x38,0x00,0xC0,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0xC0,0x00,0x18,0x00,0xC0,0x00,0x0C,0x00,0x00,0xFE,0x3F,0x00,0x00,0xFE,0x3F, // 252\n  0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x7E,0x00,0x06,0x00,0xF0,0x01,0x06,0x00,0x80,0x0F,0x07,0x80,0x00,0xFE,0x03,0xE0,0x00,0xFC,0x00,0x60,0xC0,0x1F,0x00,0x20,0xF8,0x03,0x00,0x00,0x3E,0x00,0x00,0x00,0x06,  // 253\n  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0x07,0xE0,0xFF,0xFF,0x07,0x00,0x1C,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x1C,0x1C,0x00,0x00,0xF8,0x0F,0x00,0x00,0xF0,0x03, // 254\n  0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x7E,0x00,0x06,0xC0,0xF0,0x01,0x06,0xC0,0x80,0x0F,0x07,0x00,0x00,0xFE,0x03,0x00,0x00,0xFC,0x00,0xC0,0xC0,0x1F,0x00,0xC0,0xF8,0x03,0x00,0x00,0x3E,0x00,0x00,0x00,0x06 // 255\n};\n#endif\n"
  },
  {
    "path": "src/OLEDDisplayUi.cpp",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#include \"OLEDDisplayUi.h\"\n\nvoid LoadingDrawDefault(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {\n      display->setTextAlignment(TEXT_ALIGN_CENTER);\n      display->setFont(ArialMT_Plain_10);\n      display->drawString(64, 18, stage->process);\n      display->drawProgressBar(4, 32, 120, 8, progress);\n};\n\n\nOLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {\n  this->display = display;\n\n  indicatorPosition = BOTTOM;\n  indicatorDirection = LEFT_RIGHT;\n  activeSymbol = ANIMATION_activeSymbol;\n  inactiveSymbol = ANIMATION_inactiveSymbol;\n  frameAnimationDirection   = SLIDE_RIGHT;\n  lastTransitionDirection = 1;\n  frameCount = 0;\n  nextFrameNumber = -1;\n  overlayCount = 0;\n  indicatorDrawState = 1;\n  loadingDrawFunction = LoadingDrawDefault;\n  updateInterval = 33;\n  state.lastUpdate = 0;\n  state.ticksSinceLastStateSwitch = 0;\n  state.frameState = FIXED;\n  state.currentFrame = 0;\n  state.frameTransitionDirection = 1;\n  state.isIndicatorDrawn = true;\n  state.manualControl = false;\n  state.userData = NULL;\n  shouldDrawIndicators = true;\n  autoTransition = true;\n  setTimePerFrame(5000);\n  setTimePerTransition(500);\n}\n\nvoid OLEDDisplayUi::init() {\n  this->display->init();\n}\n\nvoid OLEDDisplayUi::setTargetFPS(uint8_t fps){\n  this->updateInterval = ((float) 1.0 / (float) fps) * 1000;\n\n  this->ticksPerFrame = timePerFrame / updateInterval;\n  this->ticksPerTransition = timePerTransition / updateInterval;\n}\n\n// -/------ Automatic controll ------\\-\n\nvoid OLEDDisplayUi::enableAutoTransition(){\n  this->autoTransition = true;\n}\nvoid OLEDDisplayUi::disableAutoTransition(){\n  this->autoTransition = false;\n}\nvoid OLEDDisplayUi::setAutoTransitionForwards(){\n  this->state.frameTransitionDirection = 1;\n  this->lastTransitionDirection = 1;\n}\nvoid OLEDDisplayUi::setAutoTransitionBackwards(){\n  this->state.frameTransitionDirection = -1;\n  this->lastTransitionDirection = -1;\n}\nvoid OLEDDisplayUi::setTimePerFrame(uint16_t time){\n  this->timePerFrame = time;\n  this->ticksPerFrame = timePerFrame / updateInterval;\n}\nvoid OLEDDisplayUi::setTimePerTransition(uint16_t time){\n  this->timePerTransition = time;\n  this->ticksPerTransition = timePerTransition / updateInterval;\n}\n\n// -/------ Customize indicator position and style -------\\-\nvoid OLEDDisplayUi::enableIndicator(){\n  this->state.isIndicatorDrawn = true;\n}\n\nvoid OLEDDisplayUi::disableIndicator(){\n  this->state.isIndicatorDrawn = false;\n}\n\nvoid OLEDDisplayUi::enableAllIndicators(){\n  this->shouldDrawIndicators = true;\n}\n\nvoid OLEDDisplayUi::disableAllIndicators(){\n  this->shouldDrawIndicators = false;\n}\n\nvoid OLEDDisplayUi::setIndicatorPosition(IndicatorPosition pos) {\n  this->indicatorPosition = pos;\n}\nvoid OLEDDisplayUi::setIndicatorDirection(IndicatorDirection dir) {\n  this->indicatorDirection = dir;\n}\nvoid OLEDDisplayUi::setActiveSymbol(const uint8_t* symbol) {\n  this->activeSymbol = symbol;\n}\nvoid OLEDDisplayUi::setInactiveSymbol(const uint8_t* symbol) {\n  this->inactiveSymbol = symbol;\n}\n\n\n// -/----- Frame settings -----\\-\nvoid OLEDDisplayUi::setFrameAnimation(AnimationDirection dir) {\n  this->frameAnimationDirection = dir;\n}\nvoid OLEDDisplayUi::setFrames(FrameCallback* frameFunctions, uint8_t frameCount) {\n  this->frameFunctions = frameFunctions;\n  this->frameCount     = frameCount;\n  this->resetState();\n}\n\n// -/----- Overlays ------\\-\nvoid OLEDDisplayUi::setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount){\n  this->overlayFunctions = overlayFunctions;\n  this->overlayCount     = overlayCount;\n}\n\n// -/----- Loading Process -----\\-\n\nvoid OLEDDisplayUi::setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction) {\n  this->loadingDrawFunction = loadingDrawFunction;\n}\n\nvoid OLEDDisplayUi::runLoadingProcess(LoadingStage* stages, uint8_t stagesCount) {\n  uint8_t progress = 0;\n  uint8_t increment = 100 / stagesCount;\n\n  for (uint8_t i = 0; i < stagesCount; i++) {\n    display->clear();\n    this->loadingDrawFunction(this->display, &stages[i], progress);\n    display->display();\n\n    stages[i].callback();\n\n    progress += increment;\n    yield();\n  }\n\n  display->clear();\n  this->loadingDrawFunction(this->display, &stages[stagesCount-1], progress);\n  display->display();\n\n  delay(150);\n}\n\n// -/----- Manual control -----\\-\nvoid OLEDDisplayUi::nextFrame() {\n  if (this->state.frameState != IN_TRANSITION) {\n    this->state.manualControl = true;\n    this->state.frameState = IN_TRANSITION;\n    this->state.ticksSinceLastStateSwitch = 0;\n    this->lastTransitionDirection = this->state.frameTransitionDirection;\n    this->state.frameTransitionDirection = 1;\n  }\n}\nvoid OLEDDisplayUi::previousFrame() {\n  if (this->state.frameState != IN_TRANSITION) {\n    this->state.manualControl = true;\n    this->state.frameState = IN_TRANSITION;\n    this->state.ticksSinceLastStateSwitch = 0;\n    this->lastTransitionDirection = this->state.frameTransitionDirection;\n    this->state.frameTransitionDirection = -1;\n  }\n}\n\nvoid OLEDDisplayUi::switchToFrame(uint8_t frame) {\n  if (frame >= this->frameCount) return;\n  this->state.ticksSinceLastStateSwitch = 0;\n  if (frame == this->state.currentFrame) return;\n  this->state.frameState = FIXED;\n  this->state.currentFrame = frame;\n  this->state.isIndicatorDrawn = true;\n}\n\nvoid OLEDDisplayUi::transitionToFrame(uint8_t frame) {\n  if (frame >= this->frameCount) return;\n  this->state.ticksSinceLastStateSwitch = 0;\n  if (frame == this->state.currentFrame) return;\n  this->nextFrameNumber = frame;\n  this->lastTransitionDirection = this->state.frameTransitionDirection;\n  this->state.manualControl = true;\n  this->state.frameState = IN_TRANSITION;\n  this->state.frameTransitionDirection = frame < this->state.currentFrame ? -1 : 1;\n}\n\n\n// -/----- State information -----\\-\nOLEDDisplayUiState* OLEDDisplayUi::getUiState(){\n  return &this->state;\n}\n\nint16_t OLEDDisplayUi::update(){\n#ifdef ARDUINO\n  unsigned long frameStart = millis();\n#elif __MBED__\n\tTimer t;\n\tt.start();\n\tunsigned long frameStart = t.read_ms();\n#else\n#error \"Unkown operating system\"\n#endif\n  int32_t timeBudget = this->updateInterval - (frameStart - this->state.lastUpdate);\n  if ( timeBudget <= 0) {\n    // Implement frame skipping to ensure time budget is kept\n    if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil((double)-timeBudget / (double)this->updateInterval);\n\n    this->state.lastUpdate = frameStart;\n    this->tick();\n  }\n#ifdef ARDUINO\n  return this->updateInterval - (millis() - frameStart);\n#elif __MBED__\n  return this->updateInterval - (t.read_ms() - frameStart);\n#else\n#error \"Unkown operating system\"\n#endif\n}\n\n\nvoid OLEDDisplayUi::tick() {\n  this->state.ticksSinceLastStateSwitch++;\n\n  switch (this->state.frameState) {\n    case IN_TRANSITION:\n        if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){\n          this->state.frameState = FIXED;\n          this->state.currentFrame = getNextFrameNumber();\n          this->state.ticksSinceLastStateSwitch = 0;\n          this->nextFrameNumber = -1;\n        }\n      break;\n    case FIXED:\n      // Revert manualControl\n      if (this->state.manualControl) {\n        this->state.frameTransitionDirection = this->lastTransitionDirection;\n        this->state.manualControl = false;\n      }\n      if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){\n          if (this->autoTransition){\n            this->state.frameState = IN_TRANSITION;\n          }\n          this->state.ticksSinceLastStateSwitch = 0;\n      }\n      break;\n  }\n\n  this->display->clear();\n  this->drawFrame();\n  if (shouldDrawIndicators) {\n    this->drawIndicator();\n  }\n  this->drawOverlays();\n  this->display->display();\n}\n\nvoid OLEDDisplayUi::resetState() {\n  this->state.lastUpdate = 0;\n  this->state.ticksSinceLastStateSwitch = 0;\n  this->state.frameState = FIXED;\n  this->state.currentFrame = 0;\n  this->state.isIndicatorDrawn = true;\n}\n\nvoid OLEDDisplayUi::drawFrame(){\n  switch (this->state.frameState){\n     case IN_TRANSITION: {\n       float progress = 0.f;\n       if (this->ticksPerTransition > 0u) {\n         progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;\n       }\n       int16_t x = 0, y = 0, x1 = 0, y1 = 0;\n       switch(this->frameAnimationDirection){\n        case SLIDE_LEFT:\n          x = -this->display->width() * progress;\n          y = 0;\n          x1 = x + this->display->width();\n          y1 = 0;\n          break;\n        case SLIDE_RIGHT:\n          x = this->display->width() * progress;\n          y = 0;\n          x1 = x - this->display->width();\n          y1 = 0;\n          break;\n        case SLIDE_UP:\n          x = 0;\n          y = -this->display->height() * progress;\n          x1 = 0;\n          y1 = y + this->display->height();\n          break;\n        case SLIDE_DOWN:\n        default:\n          x = 0;\n          y = this->display->height() * progress;\n          x1 = 0;\n          y1 = y - this->display->height();\n          break;\n       }\n\n       // Invert animation if direction is reversed.\n       int8_t dir = this->state.frameTransitionDirection >= 0 ? 1 : -1;\n       x *= dir; y *= dir; x1 *= dir; y1 *= dir;\n\n       bool drawnCurrentFrame;\n\n\n       // Probe each frameFunction for the indicator drawn state\n       this->enableIndicator();\n       (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);\n       drawnCurrentFrame = this->state.isIndicatorDrawn;\n\n       this->enableIndicator();\n       (this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);\n\n       // Build up the indicatorDrawState\n       if (drawnCurrentFrame && !this->state.isIndicatorDrawn) {\n         // Drawn now but not next\n         this->indicatorDrawState = 2;\n       } else if (!drawnCurrentFrame && this->state.isIndicatorDrawn) {\n         // Not drawn now but next\n         this->indicatorDrawState = 1;\n       } else if (!drawnCurrentFrame && !this->state.isIndicatorDrawn) {\n         // Not drawn in both frames\n         this->indicatorDrawState = 3;\n       }\n\n       // If the indicator isn't draw in the current frame\n       // reflect it in state.isIndicatorDrawn\n       if (!drawnCurrentFrame) this->state.isIndicatorDrawn = false;\n\n       break;\n     }\n     case FIXED:\n      // Always assume that the indicator is drawn!\n      // And set indicatorDrawState to \"not known yet\"\n      this->indicatorDrawState = 0;\n      this->enableIndicator();\n      (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);\n      break;\n  }\n}\n\nvoid OLEDDisplayUi::drawIndicator() {\n\n    // Only draw if the indicator is invisible\n    // for both frames or\n    // the indiactor is shown and we are IN_TRANSITION\n    if (this->indicatorDrawState == 3 || (!this->state.isIndicatorDrawn && this->state.frameState != IN_TRANSITION)) {\n      return;\n    }\n\n    uint8_t posOfHighlightFrame = 0;\n    float indicatorFadeProgress = 0;\n\n    // if the indicator needs to be slided in we want to\n    // highlight the next frame in the transition\n    uint8_t frameToHighlight = this->indicatorDrawState == 1 ? this->getNextFrameNumber() : this->state.currentFrame;\n\n    // Calculate the frame that needs to be highlighted\n    // based on the Direction the indiactor is drawn\n    switch (this->indicatorDirection){\n      case LEFT_RIGHT:\n        posOfHighlightFrame = frameToHighlight;\n        break;\n      case RIGHT_LEFT:\n      default:\n        posOfHighlightFrame = this->frameCount - frameToHighlight;\n        break;\n    }\n\n    switch (this->indicatorDrawState) {\n      case 1: // Indicator was not drawn in this frame but will be in next\n        // Slide IN\n        indicatorFadeProgress = 1 - ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);\n        break;\n      case 2: // Indicator was drawn in this frame but not in next\n        // Slide OUT\n        indicatorFadeProgress = ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);\n        break;\n    }\n\n    //Space between indicators - reduce for small screen sizes\n    uint16_t indicatorSpacing = 12;\n    if (this->display->getHeight() < 64 && (this->indicatorPosition == RIGHT || this->indicatorPosition == LEFT)) {\n      indicatorSpacing = 6;\n    }\n\n    uint16_t frameStartPos = (indicatorSpacing * frameCount / 2);\n    const uint8_t *image;\n\n    uint16_t x = 0,y = 0;\n\n\n    for (uint8_t i = 0; i < this->frameCount; i++) {\n\n      switch (this->indicatorPosition){\n        case TOP:\n          y = 0 - (8 * indicatorFadeProgress);\n          x = (this->display->width() / 2) - frameStartPos + 12 * i;\n          break;\n        case BOTTOM:\n          y = (this->display->height() - 8) + (8 * indicatorFadeProgress);\n          x = (this->display->width() / 2) - frameStartPos + 12 * i;\n          break;\n        case RIGHT:\n          x = (this->display->width() - 8) + (8 * indicatorFadeProgress);\n          y = (this->display->height() / 2) - frameStartPos + 2 + 12 * i;\n          break;\n        case LEFT:\n        default:\n          x = 0 - (8 * indicatorFadeProgress);\n          y = (this->display->height() / 2) - frameStartPos + 2 + indicatorSpacing * i;\n          break;\n      }\n\n      if (posOfHighlightFrame == i) {\n         image = this->activeSymbol;\n      } else {\n         image = this->inactiveSymbol;\n      }\n\n      this->display->drawFastImage(x, y, 8, 8, image);\n    }\n}\n\nvoid OLEDDisplayUi::drawOverlays() {\n for (uint8_t i=0;i<this->overlayCount;i++){\n    (this->overlayFunctions[i])(this->display, &this->state);\n }\n}\n\nuint8_t OLEDDisplayUi::getNextFrameNumber(){\n  if (this->nextFrameNumber != -1) return this->nextFrameNumber;\n  return (this->state.currentFrame + this->frameCount + this->state.frameTransitionDirection) % this->frameCount;\n}\n"
  },
  {
    "path": "src/OLEDDisplayUi.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef OLEDDISPLAYUI_h\n#define OLEDDISPLAYUI_h\n\n#ifdef ARDUINO\n#include <Arduino.h>\n#elif __MBED__\n#include <mbed.h>\n#else\n#error \"Unkown operating system\"\n#endif\n\n#include \"OLEDDisplay.h\"\n\n//#define DEBUG_OLEDDISPLAYUI(...) Serial.printf( __VA_ARGS__ )\n\n#ifndef DEBUG_OLEDDISPLAYUI\n#define DEBUG_OLEDDISPLAYUI(...)\n#endif\n\nenum AnimationDirection {\n  SLIDE_UP,\n  SLIDE_DOWN,\n  SLIDE_LEFT,\n  SLIDE_RIGHT\n};\n\nenum IndicatorPosition {\n  TOP,\n  RIGHT,\n  BOTTOM,\n  LEFT\n};\n\nenum IndicatorDirection {\n  LEFT_RIGHT,\n  RIGHT_LEFT\n};\n\nenum FrameState {\n  IN_TRANSITION,\n  FIXED\n};\n\n\nconst uint8_t ANIMATION_activeSymbol[] PROGMEM = {\n  0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00\n};\n\nconst uint8_t ANIMATION_inactiveSymbol[] PROGMEM = {\n  0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00\n};\n\n\n// Structure of the UiState\nstruct OLEDDisplayUiState {\n  uint64_t     lastUpdate;\n  uint16_t      ticksSinceLastStateSwitch;\n\n  FrameState    frameState;\n  uint8_t       currentFrame;\n\n  bool          isIndicatorDrawn;\n\n  // Normal = 1, Inverse = -1;\n  int8_t        frameTransitionDirection;\n\n  bool          manualControl;\n\n  // Custom data that can be used by the user\n  void*         userData;\n};\n\nstruct LoadingStage {\n  const char* process;\n  void (*callback)();\n};\n\ntypedef void (*FrameCallback)(OLEDDisplay *display,  OLEDDisplayUiState* state, int16_t x, int16_t y);\ntypedef void (*OverlayCallback)(OLEDDisplay *display,  OLEDDisplayUiState* state);\ntypedef void (*LoadingDrawFunction)(OLEDDisplay *display, LoadingStage* stage, uint8_t progress);\n\nclass OLEDDisplayUi {\n  private:\n    OLEDDisplay             *display;\n\n    // Symbols for the Indicator\n    IndicatorPosition   indicatorPosition;\n    IndicatorDirection  indicatorDirection;\n\n    const uint8_t*         activeSymbol;\n    const uint8_t*         inactiveSymbol;\n\n    bool                shouldDrawIndicators;\n\n    // Values for the Frames\n    AnimationDirection  frameAnimationDirection;\n\n    int8_t              lastTransitionDirection;\n\n    uint16_t            ticksPerFrame; \t\t// ~ 5000ms at 30 FPS\n    uint16_t            ticksPerTransition;\t// ~  500ms at 30 FPS\n\n    bool                autoTransition;\n\n    FrameCallback*      frameFunctions;\n    uint8_t             frameCount;\n\n    // Internally used to transition to a specific frame\n    int8_t              nextFrameNumber;\n\n    // Values for Overlays\n    OverlayCallback*    overlayFunctions;\n    uint8_t             overlayCount;\n\n    // Will the Indicator be drawn\n    // 3 Not drawn in both frames\n    // 2 Drawn this frame but not next\n    // 1 Not drawn this frame but next\n    // 0 Not known yet\n    uint8_t                indicatorDrawState;\n\n    // Loading screen\n    LoadingDrawFunction loadingDrawFunction;\n\t\n    // UI State\n    OLEDDisplayUiState      state;\n\n    // Bookeeping for update\n    uint16_t            updateInterval            = 33;\n\n    uint16_t            timePerFrame;\n    uint16_t            timePerTransition;\n\n    uint8_t             getNextFrameNumber();\n    void                drawIndicator();\n    void                drawFrame();\n    void                drawOverlays();\n    void                tick();\n    void                resetState();\n\n  public:\n\n    OLEDDisplayUi(OLEDDisplay *display);\n\n    /**\n     * Initialise the display\n     */\n    void init();\n\n    /**\n     * Configure the internal used target FPS\n     */\n    void setTargetFPS(uint8_t fps);\n\n    // Automatic Control\n    /**\n     * Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`.\n     */\n    void enableAutoTransition();\n\n    /**\n     * Disable automatic transition to next frame.\n     */\n    void disableAutoTransition();\n\n    /**\n     * Set the direction if the automatic transitioning\n     */\n    void setAutoTransitionForwards();\n    void setAutoTransitionBackwards();\n\n    /**\n     *  Set the approximate time a frame is displayed\n     */\n    void setTimePerFrame(uint16_t time);\n\n    /**\n     * Set the approximate time a transition will take\n     */\n    void setTimePerTransition(uint16_t time);\n\n    // Customize indicator position and style\n\n    /**\n     * Draw the indicator.\n     * This is the defaut state for all frames if\n     * the indicator was hidden on the previous frame\n     * it will be slided in.\n     */\n    void enableIndicator();\n\n    /**\n     * Don't draw the indicator.\n     * This will slide out the indicator\n     * when transitioning to the next frame.\n     */\n    void disableIndicator();\n\n    /**\n     * Enable drawing of indicators\n     */\n    void enableAllIndicators();\n\n    /**\n     * Disable draw of indicators.\n     */\n    void disableAllIndicators();\n\n    /**\n     * Set the position of the indicator bar.\n     */\n    void setIndicatorPosition(IndicatorPosition pos);\n\n    /**\n     * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING\n     */\n    void setIndicatorDirection(IndicatorDirection dir);\n\n    /**\n     * Set the symbol to indicate an active frame in the indicator bar.\n     */\n    void setActiveSymbol(const uint8_t* symbol);\n\n    /**\n     * Set the symbol to indicate an inactive frame in the indicator bar.\n     */\n    void setInactiveSymbol(const uint8_t* symbol);\n\n\n    // Frame settings\n\n    /**\n     * Configure what animation is used to transition from one frame to another\n     */\n    void setFrameAnimation(AnimationDirection dir);\n\n    /**\n     * Add frame drawing functions\n     */\n    void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);\n\n    // Overlay\n\n    /**\n     * Add overlays drawing functions that are draw independent of the Frames\n     */\n    void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);\n\n\n    // Loading animation\n    /**\n     * Set the function that will draw each step\n     * in the loading animation\n     */\n    void setLoadingDrawFunction(LoadingDrawFunction loadingFunction);\n\n\n    /**\n     * Run the loading process\n     */\n    void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);\n\n\n    // Manual Control\n    void nextFrame();\n    void previousFrame();\n\n    /**\n     * Switch without transition to frame `frame`.\n     */\n    void switchToFrame(uint8_t frame);\n\n    /**\n     * Transition to frame `frame`, when the `frame` number is bigger than the current\n     * frame the forward animation will be used, otherwise the backwards animation is used.\n     */\n    void transitionToFrame(uint8_t frame);\n\n    // State Info\n    OLEDDisplayUiState* getUiState();\n\n    int16_t update();\n};\n#endif\n"
  },
  {
    "path": "src/SH1106.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SH1106_h\n#define SH1106_h\n#include \"SH1106Wire.h\"\n\n// For make SH1106 an alias for SH1106Wire\ntypedef SH1106Wire SH1106;\n\n\n#endif\n"
  },
  {
    "path": "src/SH1106Brzo.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SH1106Brzo_h\n#define SH1106Brzo_h\n\n#include \"OLEDDisplay.h\"\n#include <brzo_i2c.h>\n\n#if F_CPU == 160000000L\n  #define BRZO_I2C_SPEED 1000\n#else\n  #define BRZO_I2C_SPEED 800\n#endif\n\nclass SH1106Brzo : public OLEDDisplay {\n  private:\n      uint8_t             _address;\n      uint8_t             _sda;\n      uint8_t             _scl;\n\n  public:\n\tSH1106Brzo(uint8_t address, uint8_t sda, uint8_t scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {\n\t\tsetGeometry(g);\n\n      this->_address = address;\n      this->_sda = sda;\n      this->_scl = scl;\n    }\n\n    bool connect(){\n      brzo_i2c_setup(_sda, _scl, 0);\n      return true;\n    }\n\n    void display(void) {\n    #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n       uint8_t minBoundY = UINT8_MAX;\n       uint8_t maxBoundY = 0;\n\n       uint8_t minBoundX = UINT8_MAX;\n       uint8_t maxBoundX = 0;\n       uint8_t x, y;\n\n       // Calculate the Y bounding box of changes\n       // and copy buffer[pos] to buffer_back[pos];\n       for (y = 0; y < (displayHeight / 8); y++) {\n         for (x = 0; x < displayWidth; x++) {\n          uint16_t pos = x + y * displayWidth;\n          if (buffer[pos] != buffer_back[pos]) {\n            minBoundY = _min(minBoundY, y);\n            maxBoundY = _max(maxBoundY, y);\n            minBoundX = _min(minBoundX, x);\n            maxBoundX = _max(maxBoundX, x);\n          }\n          buffer_back[pos] = buffer[pos];\n        }\n        yield();\n       }\n\n       // If the minBoundY wasn't updated\n       // we can savely assume that buffer_back[pos] == buffer[pos]\n       // holdes true for all values of pos\n       if (minBoundY == UINT8_MAX) return;\n\n       uint8_t k = 0;\n       uint8_t sendBuffer[17];\n       sendBuffer[0] = 0x40;\n\n       // Calculate the colum offset\n       uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;\n       uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );\n\n       brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);\n\n       for (y = minBoundY; y <= maxBoundY; y++) {\n         sendCommand(0xB0 + y);\n         sendCommand(minBoundXp2H);\n         sendCommand(minBoundXp2L);\n         for (x = minBoundX; x <= maxBoundX; x++) {\n             k++;\n             sendBuffer[k] = buffer[x + y * displayWidth];\n             if (k == 16)  {\n               brzo_i2c_write(sendBuffer, 17, true);\n               k = 0;\n             }\n         }\n         if (k != 0) {\n           brzo_i2c_write(sendBuffer, k + 1, true);\n           k = 0;\n         }\n         yield();\n       }\n       if (k != 0) {\n         brzo_i2c_write(sendBuffer, k + 1, true);\n       }\n       brzo_i2c_end_transaction();\n     #else\n     #endif\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void sendCommand(uint8_t com) __attribute__((always_inline)){\n      uint8_t command[2] = {0x80 /* command mode */, com};\n      brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);\n      brzo_i2c_write(command, 2, true);\n      brzo_i2c_end_transaction();\n    }\n};\n\n#endif\n"
  },
  {
    "path": "src/SH1106Spi.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SH1106Spi_h\n#define SH1106Spi_h\n\n#include \"OLEDDisplay.h\"\n#include <SPI.h>\n\nclass SH1106Spi : public OLEDDisplay {\n  private:\n      uint8_t             _rst;\n      uint8_t             _dc;\n      uint8_t             _cs;\n\n  public:\n    /* pass _cs as -1 to indicate \"do not use CS pin\", for cases where it is hard wired low */\n    SH1106Spi(uint8_t rst, uint8_t dc, uint8_t cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {\n        setGeometry(g);\n\n      this->_rst = rst;\n      this->_dc  = dc;\n      this->_cs  = cs;\n    }\n\n    bool connect(){\n      pinMode(_dc, OUTPUT);\n      if (_cs != (uint8_t) -1) {\n        pinMode(_cs, OUTPUT);\n      }  \n      pinMode(_rst, OUTPUT);\n\n      SPI.begin ();\n      SPI.setClockDivider (SPI_CLOCK_DIV2);\n\n      // Pulse Reset low for 10ms\n      digitalWrite(_rst, HIGH);\n      delay(1);\n      digitalWrite(_rst, LOW);\n      delay(10);\n      digitalWrite(_rst, HIGH);\n      return true;\n    }\n\n    void display(void) {\n    #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n       uint8_t minBoundY = UINT8_MAX;\n       uint8_t maxBoundY = 0;\n\n       uint8_t minBoundX = UINT8_MAX;\n       uint8_t maxBoundX = 0;\n\n       uint8_t x, y;\n\n       // Calculate the Y bounding box of changes\n       // and copy buffer[pos] to buffer_back[pos];\n       for (y = 0; y < (displayHeight / 8); y++) {\n         for (x = 0; x < displayWidth; x++) {\n          uint16_t pos = x + y * displayWidth;\n          if (buffer[pos] != buffer_back[pos]) {\n            minBoundY = _min(minBoundY, y);\n            maxBoundY = _max(maxBoundY, y);\n            minBoundX = _min(minBoundX, x);\n            maxBoundX = _max(maxBoundX, x);\n          }\n          buffer_back[pos] = buffer[pos];\n        }\n        yield();\n       }\n\n       // If the minBoundY wasn't updated\n       // we can savely assume that buffer_back[pos] == buffer[pos]\n       // holdes true for all values of pos\n       if (minBoundY == UINT8_MAX) return;\n\n       // Calculate the colum offset\n       uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;\n       uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );\n\n       for (y = minBoundY; y <= maxBoundY; y++) {\n         sendCommand(0xB0 + y);\n         sendCommand(minBoundXp2H);\n         sendCommand(minBoundXp2L);\n         set_CS(HIGH);\n         digitalWrite(_dc, HIGH);   // data mode\n         set_CS(LOW);\n         for (x = minBoundX; x <= maxBoundX; x++) {\n           SPI.transfer(buffer[x + y * displayWidth]);\n         }\n         set_CS(HIGH);\n         yield();\n       }\n     #else\n      for (uint8_t y=0; y<displayHeight/8; y++) {\n        sendCommand(0xB0 + y);\n        sendCommand(0x02);\n        sendCommand(0x10);\n        set_CS(HIGH);\n        digitalWrite(_dc, HIGH);   // data mode\n        set_CS(LOW);\n        for( uint8_t x=0; x < displayWidth; x++) {\n          SPI.transfer(buffer[x + y * displayWidth]);\n        }\n        set_CS(HIGH);\n        yield();\n      }\n     #endif\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void set_CS(bool level) {\n      if (_cs != (uint8_t) -1) {\n        digitalWrite(_cs, level);\n      }\n    };\n    inline void sendCommand(uint8_t com) __attribute__((always_inline)){\n      set_CS(HIGH);\n      digitalWrite(_dc, LOW);\n      set_CS(LOW);\n      SPI.transfer(com);\n      set_CS(HIGH);\n    }\n};\n\n#endif\n"
  },
  {
    "path": "src/SH1106Wire.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SH1106Wire_h\n#define SH1106Wire_h\n\n#include \"OLEDDisplay.h\"\n#include <Wire.h>\n\n#if defined(ARDUINO_ARCH_ESP32)\n#define I2C_OLED_TRANSFER_BYTE 64 /** ESP32 can Transfer Max 128 bytes */\n#else\n#define I2C_OLED_TRANSFER_BYTE 16\n#endif\n\n#define SH1106_SET_PUMP_VOLTAGE 0X30\n#define SH1106_SET_PUMP_MODE 0XAD\n#define SH1106_PUMP_ON 0X8B\n#define SH1106_PUMP_OFF 0X8A\n//--------------------------------------\n\nclass SH1106Wire : public OLEDDisplay {\n  private:\n      uint8_t             _address;\n      int             _sda;\n      int             _scl;\n      bool                _doI2cAutoInit = false;\n      TwoWire*            _wire = NULL;\n      long                _frequency;\n\n  public:\n    /**\n     * Create and initialize the Display using Wire library\n     *\n     * Beware for retro-compatibility default values are provided for all parameters see below.\n     * Please note that if you don't wan't SD1306Wire to initialize and change frequency speed ot need to\n     * ensure -1 value are specified for all 3 parameters. This can be usefull to control TwoWire with multiple\n     * device on the same bus.\n     *\n     * @param address I2C Display address\n     * @param sda I2C SDA pin number, default to -1 to skip Wire begin call\n     * @param scl I2C SCL pin number, default to -1 (only SDA = -1 is considered to skip Wire begin call)\n     * @param g display geometry dafault to generic GEOMETRY_128_64, see OLEDDISPLAY_GEOMETRY definition for other options\n     * @param i2cBus on ESP32 with 2 I2C HW buses, I2C_ONE for 1st Bus, I2C_TWO fot 2nd bus, default I2C_ONE\n     * @param frequency for Frequency by default Let's use ~700khz if ESP8266 is in 160Mhz mode, this will be limited to ~400khz if the ESP8266 in 80Mhz mode\n     */\n    SH1106Wire(uint8_t address, int sda = -1, int scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C i2cBus = I2C_ONE, long frequency = 700000) {\n      setGeometry(g);\n\n      this->_address = address;\n      this->_sda = sda;\n      this->_scl = scl;\n#if !defined(ARDUINO_ARCH_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)\n      this->_wire = &Wire;\n#else\n      this->_wire = (i2cBus==I2C_ONE) ? &Wire : &Wire1;\n#endif\n      this->_frequency = frequency;\n    }\n\n    bool connect() {\n#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP8266)\n      _wire->begin();\n#else\n      // On ESP32 arduino, -1 means 'don't change pins', someone else has called begin for us.\n      if(this->_sda != -1)\n        _wire->begin(this->_sda, this->_scl);\n#endif\n      // Let's use ~700khz if ESP8266 is in 160Mhz mode\n      // this will be limited to ~400khz if the ESP8266 in 80Mhz mode.\n      if(this->_frequency != -1)\n        _wire->setClock(this->_frequency);\n      return true;\n    }\n\n    void display(void) {\n      initI2cIfNeccesary();\n      #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n        uint8_t minBoundY = UINT8_MAX;\n        uint8_t maxBoundY = 0;\n\n        uint8_t minBoundX = UINT8_MAX;\n        uint8_t maxBoundX = 0;\n\n        uint8_t x, y;\n\n        // Calculate the Y bounding box of changes\n        // and copy buffer[pos] to buffer_back[pos];\n        for (y = 0; y < (displayHeight / 8); y++) {\n          for (x = 0; x < displayWidth; x++) {\n           uint16_t pos = x + y * displayWidth;\n           if (buffer[pos] != buffer_back[pos]) {\n             minBoundY = _min(minBoundY, y);\n             maxBoundY = _max(maxBoundY, y);\n             minBoundX = _min(minBoundX, x);\n             maxBoundX = _max(maxBoundX, x);\n           }\n           buffer_back[pos] = buffer[pos];\n         }\n         yield();\n        }\n\n        // If the minBoundY wasn't updated\n        // we can savely assume that buffer_back[pos] == buffer[pos]\n        // holdes true for all values of pos\n        if (minBoundY == UINT8_MAX) return;\n\n        // Calculate the colum offset\n        uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;\n        uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );\n\n        uint8_t k = 0;\n        for (y = minBoundY; y <= maxBoundY; y++) {\n          sendCommand(0xB0 + y);\n          sendCommand(minBoundXp2H);\n          sendCommand(minBoundXp2L);\n          for (x = minBoundX; x <= maxBoundX; x++) {\n            if (k == 0) {\n              _wire->beginTransmission(_address);\n              _wire->write(0x40);\n            }\n            _wire->write(buffer[x + y * displayWidth]);\n            k++;\n            if (k == I2C_OLED_TRANSFER_BYTE)  {\n              _wire->endTransmission();\n              k = 0;\n            }\n          }\n          if (k != 0)  {\n            _wire->endTransmission();\n            k = 0;\n          }\n          yield();\n        }\n\n        if (k != 0) {\n          _wire->endTransmission();\n        }\n      #else\n        uint8_t * p = &buffer[0];\n        for (uint8_t y=0; y<8; y++) {\n          sendCommand(0xB0+y);\n          sendCommand(0x02);\n          sendCommand(0x10);\n          for( uint8_t x=0; x<(128/I2C_OLED_TRANSFER_BYTE); x++) {\n            _wire->beginTransmission(_address);\n            _wire->write(0x40);\n            for (uint8_t k = 0; k < I2C_OLED_TRANSFER_BYTE; k++) {\n              _wire->write(*p++);\n            }\n            _wire->endTransmission();\n          }\n        }\n      #endif\n    }\n\n    void setI2cAutoInit(bool doI2cAutoInit) {\n      _doI2cAutoInit = doI2cAutoInit;\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void sendCommand(uint8_t command) __attribute__((always_inline)){\n      _wire->beginTransmission(_address);\n      _wire->write(0x80);\n      _wire->write(command);\n      _wire->endTransmission();\n    }\n\n    void initI2cIfNeccesary() {\n      if (_doI2cAutoInit) {\n#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP8266)\n        _wire->begin();\n#else\n        _wire->begin(this->_sda, this->_scl);\n#endif\n      }\n    }\n\n};\n\n#endif\n"
  },
  {
    "path": "src/SSD1306.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SSD1306_h\n#define SSD1306_h\n#include \"SSD1306Wire.h\"\n\n// For legacy support make SSD1306 an alias for SSD1306\ntypedef SSD1306Wire SSD1306;\n\n\n#endif\n"
  },
  {
    "path": "src/SSD1306Brzo.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SSD1306Brzo_h\n#define SSD1306Brzo_h\n\n#include \"OLEDDisplay.h\"\n#include <brzo_i2c.h>\n\n#if F_CPU == 160000000L\n  #define BRZO_I2C_SPEED 1000\n#else\n  #define BRZO_I2C_SPEED 800\n#endif\n\nclass SSD1306Brzo : public OLEDDisplay {\n  private:\n      uint8_t             _address;\n      uint8_t             _sda;\n      uint8_t             _scl;\n\n  public:\n    SSD1306Brzo(uint8_t address, uint8_t sda, uint8_t scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {\n      setGeometry(g);\n\n      this->_address = address;\n      this->_sda = sda;\n      this->_scl = scl;\n    }\n\n    bool connect(){\n      brzo_i2c_setup(_sda, _scl, 0);\n      return true;\n    }\n\n    void display(void) {\n      const int x_offset = (128 - this->width()) / 2;\n\n    #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n       uint8_t minBoundY = UINT8_MAX;\n       uint8_t maxBoundY = 0;\n\n       uint8_t minBoundX = UINT8_MAX;\n       uint8_t maxBoundX = 0;\n\n       uint8_t x, y;\n\n       // Calculate the Y bounding box of changes\n       // and copy buffer[pos] to buffer_back[pos];\n       for (y = 0; y < (this->height() / 8); y++) {\n         for (x = 0; x < this->width(); x++) {\n          uint16_t pos = x + y * this->width();\n          if (buffer[pos] != buffer_back[pos]) {\n            minBoundY = _min(minBoundY, y);\n            maxBoundY = _max(maxBoundY, y);\n            minBoundX = _min(minBoundX, x);\n            maxBoundX = _max(maxBoundX, x);\n          }\n          buffer_back[pos] = buffer[pos];\n        }\n        yield();\n       }\n\n       // If the minBoundY wasn't updated\n       // we can savely assume that buffer_back[pos] == buffer[pos]\n       // holdes true for all values of pos\n       if (minBoundY == UINT8_MAX) return;\n\n       sendCommand(COLUMNADDR);\n       sendCommand(x_offset + minBoundX);\n       sendCommand(x_offset + maxBoundX);\n\n       sendCommand(PAGEADDR);\n       sendCommand(minBoundY);\n       sendCommand(maxBoundY);\n\n       uint8_t k = 0;\n\n       int buflen = ( this->width() / 8 ) + 1;\n\n       uint8_t sendBuffer[buflen];\n       sendBuffer[0] = 0x40;\n       brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);\n       for (y = minBoundY; y <= maxBoundY; y++) {\n           for (x = minBoundX; x <= maxBoundX; x++) {\n               k++;\n               sendBuffer[k] = buffer[x + y * this->width()];\n               if (k == (buflen-1))  {\n                 brzo_i2c_write(sendBuffer, buflen, true);\n                 k = 0;\n               }\n           }\n           yield();\n       }\n       brzo_i2c_write(sendBuffer, k + 1, true);\n       brzo_i2c_end_transaction();\n     #else\n       // No double buffering\n       sendCommand(COLUMNADDR);\n\n       sendCommand(x_offset);\n       sendCommand(x_offset + (this->width() - 1));\n\n       sendCommand(PAGEADDR);\n       sendCommand(0x0);\n       sendCommand((this->height() / 8) - 1);\n\n       int buflen = ( this->width() / 8 ) + 1;\n\n       uint8_t sendBuffer[buflen];\n       sendBuffer[0] = 0x40;\n\n       brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);\n\n       for (uint16_t i=0; i<displayBufferSize; i++) {\n         for (uint8_t x=1; x<buflen; x++) {\n           sendBuffer[x] = buffer[i];\n           i++;\n         }\n         i--;\n         brzo_i2c_write(sendBuffer,  buflen,  true);\n         yield();\n       }\n       brzo_i2c_end_transaction();\n     #endif\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void sendCommand(uint8_t com) __attribute__((always_inline)){\n      uint8_t command[2] = {0x80 /* command mode */, com};\n      brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);\n      brzo_i2c_write(command, 2, true);\n      brzo_i2c_end_transaction();\n    }\n};\n\n#endif\n"
  },
  {
    "path": "src/SSD1306I2C.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SSD1306I2C_h\n#define SSD1306I2C_h\n\n\n#ifdef __MBED__\n\n#include \"OLEDDisplay.h\"\n#include <mbed.h>\n\n#ifndef UINT8_MAX\n #define UINT8_MAX 0xff\n#endif\n\nclass SSD1306I2C : public OLEDDisplay {\npublic:\n    SSD1306I2C(uint8_t address, PinName sda, PinName scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {\n      setGeometry(g);\n\n      this->_address = address << 1;  // convert from 7 to 8 bit for mbed.\n      this->_sda = sda;\n      this->_scl = scl;\n\t  _i2c = new I2C(sda, scl);\n    }\n\n    bool connect() {\n\t\t// mbed supports 100k and 400k some device maybe 1000k\n#ifdef TARGET_STM32L4\n\t  _i2c->frequency(1000000);\n#else\n\t  _i2c->frequency(400000);\n#endif\n      return true;\n    }\n\n    void display(void) {\n      const int x_offset = (128 - this->width()) / 2;\n#ifdef OLEDDISPLAY_DOUBLE_BUFFER\n        uint8_t minBoundY = UINT8_MAX;\n        uint8_t maxBoundY = 0;\n\n        uint8_t minBoundX = UINT8_MAX;\n        uint8_t maxBoundX = 0;\n        uint8_t x, y;\n\n        // Calculate the Y bounding box of changes\n        // and copy buffer[pos] to buffer_back[pos];\n        for (y = 0; y < (this->height() / 8); y++) {\n          for (x = 0; x < this->width(); x++) {\n           uint16_t pos = x + y * this->width();\n           if (buffer[pos] != buffer_back[pos]) {\n             minBoundY = std::min(minBoundY, y);\n             maxBoundY = std::max(maxBoundY, y);\n             minBoundX = std::min(minBoundX, x);\n             maxBoundX = std::max(maxBoundX, x);\n           }\n           buffer_back[pos] = buffer[pos];\n         }\n         yield();\n        }\n\n        // If the minBoundY wasn't updated\n        // we can savely assume that buffer_back[pos] == buffer[pos]\n        // holdes true for all values of pos\n\n        if (minBoundY == UINT8_MAX) return;\n\n        sendCommand(COLUMNADDR);\n        sendCommand(x_offset + minBoundX);\t// column start address (0 = reset)\n        sendCommand(x_offset + maxBoundX);\t// column end address (127 = reset)\n\n        sendCommand(PAGEADDR);\n        sendCommand(minBoundY);\t\t\t\t// page start address\n        sendCommand(maxBoundY);\t\t\t\t// page end address\n\n        for (y = minBoundY; y <= maxBoundY; y++) {\n\t\t\tuint8_t *start = &buffer[(minBoundX + y * this->width())-1];\n\t\t\tuint8_t save = *start;\n\t\t\t\n\t\t\t*start = 0x40; // control\n\t\t\t_i2c->write(_address, (char *)start, (maxBoundX-minBoundX) + 1 + 1);\n\t\t\t*start = save;\n\t\t}\n#else\n\n        sendCommand(COLUMNADDR);\n        sendCommand(x_offset);\t\t\t\t\t\t// column start address (0 = reset)\n        sendCommand(x_offset + (this->width() - 1));// column end address (127 = reset)\n\n        sendCommand(PAGEADDR);\n        sendCommand(0x0);\t\t\t\t\t\t\t// page start address (0 = reset)\n\n        if (geometry == GEOMETRY_128_64) {\n          sendCommand(0x7);\n        } else if (geometry == GEOMETRY_128_32) {\n          sendCommand(0x3);\n        }\n\n\t\tbuffer[-1] = 0x40; // control\n\t\t_i2c->write(_address, (char *)&buffer[-1], displayBufferSize + 1);\n#endif\n    }\n\nprivate:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n\n    inline void sendCommand(uint8_t command) __attribute__((always_inline)) {\n\t\tchar _data[2];\n\t  \t_data[0] = 0x80; // control\n\t  \t_data[1] = command;\n\t  \t_i2c->write(_address, _data, sizeof(_data));\n    }\n\n\tuint8_t             _address;\n\tPinName             _sda;\n\tPinName             _scl;\n\tI2C *_i2c;\n};\n\n#endif\n\n#endif\n"
  },
  {
    "path": "src/SSD1306Spi.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SSD1306Spi_h\n#define SSD1306Spi_h\n\n#include \"OLEDDisplay.h\"\n#include <SPI.h>\n\n#if F_CPU == 160000000L\n  #define BRZO_I2C_SPEED 1000\n#else\n  #define BRZO_I2C_SPEED 800\n#endif\n\nclass SSD1306Spi : public OLEDDisplay {\n  private:\n      uint8_t             _rst;\n      uint8_t             _dc;\n      uint8_t             _cs;\n\n  public:\n    /* pass _cs as -1 to indicate \"do not use CS pin\", for cases where it is hard wired low */\n    SSD1306Spi(uint8_t rst, uint8_t dc, uint8_t cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {\n        setGeometry(g);\n\n      this->_rst = rst;\n      this->_dc  = dc;\n      this->_cs  = cs;\n    }\n\n    bool connect(){\n      pinMode(_dc, OUTPUT);\n      if (_cs != (uint8_t) -1) {\n        pinMode(_cs, OUTPUT);\n      }  \n      pinMode(_rst, OUTPUT);\n\n      SPI.begin ();\n      SPI.setClockDivider (SPI_CLOCK_DIV2);\n\n      // Pulse Reset low for 10ms\n      digitalWrite(_rst, HIGH);\n      delay(1);\n      digitalWrite(_rst, LOW);\n      delay(10);\n      digitalWrite(_rst, HIGH);\n      return true;\n    }\n\n    void display(void) {\n    #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n       uint8_t minBoundY = UINT8_MAX;\n       uint8_t maxBoundY = 0;\n\n       uint8_t minBoundX = UINT8_MAX;\n       uint8_t maxBoundX = 0;\n\n       uint8_t x, y;\n\n       // Calculate the Y bounding box of changes\n       // and copy buffer[pos] to buffer_back[pos];\n       for (y = 0; y < (displayHeight / 8); y++) {\n         for (x = 0; x < displayWidth; x++) {\n          uint16_t pos = x + y * displayWidth;\n          if (buffer[pos] != buffer_back[pos]) {\n            minBoundY = _min(minBoundY, y);\n            maxBoundY = _max(maxBoundY, y);\n            minBoundX = _min(minBoundX, x);\n            maxBoundX = _max(maxBoundX, x);\n          }\n          buffer_back[pos] = buffer[pos];\n        }\n        yield();\n       }\n\n       // If the minBoundY wasn't updated\n       // we can savely assume that buffer_back[pos] == buffer[pos]\n       // holdes true for all values of pos\n       if (minBoundY == UINT8_MAX) return;\n\n       sendCommand(COLUMNADDR);\n       sendCommand(minBoundX);\n       sendCommand(maxBoundX);\n\n       sendCommand(PAGEADDR);\n       sendCommand(minBoundY);\n       sendCommand(maxBoundY);\n\n       set_CS(HIGH);\n       digitalWrite(_dc, HIGH);   // data mode\n       set_CS(LOW);\n       for (y = minBoundY; y <= maxBoundY; y++) {\n         for (x = minBoundX; x <= maxBoundX; x++) {\n           SPI.transfer(buffer[x + y * displayWidth]);\n         }\n         yield();\n       }\n       set_CS(HIGH);\n     #else\n       // No double buffering\n       sendCommand(COLUMNADDR);\n       sendCommand(0x0);\n       sendCommand(0x7F);\n\n       sendCommand(PAGEADDR);\n       sendCommand(0x0);\n\n       if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32 ) {\n         sendCommand(0x7);\n       } else if (geometry == GEOMETRY_128_32) {\n         sendCommand(0x3);\n       }\n\n        set_CS(HIGH);\n        digitalWrite(_dc, HIGH);   // data mode\n        set_CS(LOW);\n        for (uint16_t i=0; i<displayBufferSize; i++) {\n          SPI.transfer(buffer[i]);\n          yield();\n        }\n        set_CS(HIGH);\n     #endif\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void set_CS(bool level) {\n      if (_cs != (uint8_t) -1) {\n        digitalWrite(_cs, level);\n      }\n    };\n    inline void sendCommand(uint8_t com) __attribute__((always_inline)){\n      set_CS(HIGH);\n      digitalWrite(_dc, LOW);\n      set_CS(LOW);\n      SPI.transfer(com);\n      set_CS(HIGH);\n    }\n};\n\n#endif\n"
  },
  {
    "path": "src/SSD1306Wire.h",
    "content": "/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn\n * Copyright (c) 2018 by Fabrice Weinberg\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * ThingPulse invests considerable time and money to develop these open source libraries.\n * Please support us by buying our products (and not the clones) from\n * https://thingpulse.com\n *\n */\n\n#ifndef SSD1306Wire_h\n#define SSD1306Wire_h\n\n#include \"OLEDDisplay.h\"\n#include <Wire.h>\n#include <algorithm>\n\n#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_STM32)\n#define _min\tmin\n#define _max\tmax\n#endif\n#if defined(ARDUINO_ARCH_ESP32)\n#define I2C_MAX_TRANSFER_BYTE 128 /** ESP32 can Transfer 128 bytes */\n#else\n#define I2C_MAX_TRANSFER_BYTE 17\n#endif\n//--------------------------------------\n\nclass SSD1306Wire : public OLEDDisplay {\n  private:\n      uint8_t             _address;\n      int                 _sda;\n      int                 _scl;\n      bool                _doI2cAutoInit = false;\n      TwoWire*            _wire = NULL;\n      long                _frequency;\n\n  public:\n\n    /**\n     * Create and initialize the Display using Wire library\n     *\n     * Beware for retro-compatibility default values are provided for all parameters see below.\n     * Please note that if you don't wan't SD1306Wire to initialize and change frequency speed ot need to\n     * ensure -1 value are specified for all 3 parameters. This can be usefull to control TwoWire with multiple\n     * device on the same bus.\n     *\n     * @param address I2C Display address\n     * @param sda I2C SDA pin number, default to -1 to skip Wire begin call\n     * @param scl I2C SCL pin number, default to -1 (only SDA = -1 is considered to skip Wire begin call)\n     * @param g display geometry dafault to generic GEOMETRY_128_64, see OLEDDISPLAY_GEOMETRY definition for other options\n     * @param i2cBus on ESP32 with 2 I2C HW buses, I2C_ONE for 1st Bus, I2C_TWO fot 2nd bus, default I2C_ONE\n     * @param frequency for Frequency by default Let's use ~700khz if ESP8266 is in 160Mhz mode, this will be limited to ~400khz if the ESP8266 in 80Mhz mode\n     */\n    SSD1306Wire(uint8_t address, int sda = -1, int scl = -1, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64, HW_I2C i2cBus = I2C_ONE, long  frequency = 700000) {\n      setGeometry(g);\n\n      this->_address = address;\n      this->_sda = sda;\n      this->_scl = scl;\n#if !defined(ARDUINO_ARCH_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)\n      this->_wire = &Wire;\n#else\n      this->_wire = (i2cBus == I2C_ONE) ? &Wire : &Wire1;\n#endif\n      this->_frequency = frequency;\n    }\n\n    bool connect() {\n#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP8266)\n      _wire->begin();\n#else\n      // On ESP32 arduino, -1 means 'don't change pins', someone else has called begin for us.\n      if(this->_sda != -1)\n        _wire->begin(this->_sda, this->_scl);\n#endif\n      // Let's use ~700khz if ESP8266 is in 160Mhz mode\n      // this will be limited to ~400khz if the ESP8266 in 80Mhz mode.\n      if(this->_frequency != -1)\n        _wire->setClock(this->_frequency);\n      return true;\n    }\n\n    void display(void) {\n      initI2cIfNeccesary();\n      const int x_offset = (128 - this->width()) / 2;\n      #ifdef OLEDDISPLAY_DOUBLE_BUFFER\n        uint8_t minBoundY = UINT8_MAX;\n        uint8_t maxBoundY = 0;\n\n        uint8_t minBoundX = UINT8_MAX;\n        uint8_t maxBoundX = 0;\n        uint8_t x, y;\n\n        // Calculate the Y bounding box of changes\n        // and copy buffer[pos] to buffer_back[pos];\n        for (y = 0; y < (this->height() / 8); y++) {\n          for (x = 0; x < this->width(); x++) {\n           uint16_t pos = x + y * this->width();\n           if (buffer[pos] != buffer_back[pos]) {\n             minBoundY = std::min(minBoundY, y);\n             maxBoundY = std::max(maxBoundY, y);\n             minBoundX = std::min(minBoundX, x);\n             maxBoundX = std::max(maxBoundX, x);\n           }\n           buffer_back[pos] = buffer[pos];\n         }\n         yield();\n        }\n\n        // If the minBoundY wasn't updated\n        // we can savely assume that buffer_back[pos] == buffer[pos]\n        // holdes true for all values of pos\n\n        if (minBoundY == UINT8_MAX) return;\n\n        sendCommand(COLUMNADDR);\n        sendCommand(x_offset + minBoundX);\n        sendCommand(x_offset + maxBoundX);\n\n        sendCommand(PAGEADDR);\n        sendCommand(minBoundY);\n        sendCommand(maxBoundY);\n\n        uint8_t k = 0;\n        for (y = minBoundY; y <= maxBoundY; y++) {\n          for (x = minBoundX; x <= maxBoundX; x++) {\n            if (k == 0) {\n              _wire->beginTransmission(_address);\n              _wire->write(0x40);\n            }\n\n            _wire->write(buffer[x + y * this->width()]);\n            k++;\n            if (k == (I2C_MAX_TRANSFER_BYTE - 1))  {\n              _wire->endTransmission();\n              k = 0;\n            }\n          }\n          yield();\n        }\n\n        if (k != 0) {\n          _wire->endTransmission();\n        }\n      #else\n\n        sendCommand(COLUMNADDR);\n        sendCommand(x_offset);\n        sendCommand(x_offset + (this->width() - 1));\n\n        sendCommand(PAGEADDR);\n        sendCommand(0x0);\n\n        for (uint16_t i=0; i < displayBufferSize; i++) {\n          _wire->beginTransmission(this->_address);\n          _wire->write(0x40);\n          for (uint8_t x = 0; x < (I2C_MAX_TRANSFER_BYTE - 1); x++) {\n            _wire->write(buffer[i]);\n            i++;\n          }\n          i--;\n          _wire->endTransmission();\n        }\n      #endif\n    }\n\n    void setI2cAutoInit(bool doI2cAutoInit) {\n      _doI2cAutoInit = doI2cAutoInit;\n    }\n\n  private:\n\tint getBufferOffset(void) {\n\t\treturn 0;\n\t}\n    inline void sendCommand(uint8_t command) __attribute__((always_inline)){\n      initI2cIfNeccesary();\n      _wire->beginTransmission(_address);\n      _wire->write(0x80);\n      _wire->write(command);\n      _wire->endTransmission();\n    }\n\n    void initI2cIfNeccesary() {\n      if (_doI2cAutoInit) {\n#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP8266)\n      \t_wire->begin();\n#else\n      \t_wire->begin(this->_sda, this->_scl);\n#endif\n      }\n    }\n\n};\n\n#endif\n"
  }
]