Compare commits

...

146 Commits

Author SHA1 Message Date
pelgraine 6360a167c5 Merge branch 'dev' 2026-04-19 21:04:09 +10:00
pelgraine ca5283af4f update readme, particularly licence section 2026-04-19 21:03:31 +10:00
pelgraine b42291c5fc fix bubble display t5s3 for channel picker 2026-04-19 21:02:47 +10:00
pelgraine 8f0d961048 update readme for v1.7 updates 2026-04-19 20:54:13 +10:00
pelgraine 27e8b8422b Merge branch 'dev' 2026-04-19 20:42:45 +10:00
pelgraine b57e000496 fix: remove BLE sync marking channels as read (regression from Feb).
The markChannelReadFromBLE() calls in the CMD_SYNC_NEXT_MESSAGE handler were marking channels and DMs as read the moment the BLE companion app synced them from the offline queue. Since the app drains the entire queue automatically on connect, this had the effect of clearing all unread indicators on the device as soon as BLE connected — before the user had actually read anything in either the app or on the device.
The MeshCore BLE protocol has no "user opened this channel" command from the app side; CMD_SYNC_NEXT_MESSAGE is an automatic bulk pull, so "synced to app" ≠ "read by user." Removed the channel and DM mark-read calls so unread counts only clear when the user navigates to that channel on the device itself. The msgRead() progress counter (syncing X messages) is unaffected.
2026-04-19 20:41:06 +10:00
pelgraine f449385e8f Merge branch 'dev' :) 2026-04-19 20:30:15 +10:00
pelgraine 31ac732f08 fix bug where channels imported from older config files displayed gibberish in channel scope under settingsscreen even when region scope not set; fix bug where after device clock sync advert times last heard weren't displaying correctly (ie showed 16895h) 2026-04-19 20:23:12 +10:00
pelgraine 46413b9858 add serial command support for regions, update serial settings guide 2026-04-19 19:53:45 +10:00
pelgraine ce6acdfd34 temp cmd 54 support 2026-04-19 19:40:03 +10:00
pelgraine 81b3cd2591 try and improve key responsiveness/debounce in compose mode; fix crowding in channel screen navbar text in tiny font mode 2026-04-19 18:36:25 +10:00
pelgraine 5c275a8c23 Regions - including settings nudge to remind user if no default nor channel region set. Set region by typing custom entry 2026-04-19 18:17:25 +10:00
pelgraine b536e24f8e fix word wrapping ereader for larger custom font selection 2026-04-19 17:57:29 +10:00
pelgraine 5b38b713da fix home screen ui display when montserrat or notosans selected; fix word wrap display for other fonts in tiny mode for ereader 2026-04-19 17:27:48 +10:00
pelgraine 3e6bcfb031 updated loading splash screen for spiffs failure message first time flashers 2026-04-19 16:03:37 +10:00
pelgraine 49f1d91c15 tdpro - fixed notes screen touch recog and file open bug 2026-04-19 15:55:47 +10:00
pelgraine 8e3a09e3b1 added channel picker screen as messages home screen view; fixed battery curve reading to better reflect actual charge state (4200 to 4160); patched clock sync to throw out garbage rtc when device has been powered off for a while & now syncs on ble app connection: more font style customisation; nav bar hint text reduced when larger fonts are selected; ensured font style persists across reboots 2026-04-19 15:37:52 +10:00
pelgraine 1c4d5a0daa updated readme for clarity, esp re meck remote wifi repeaters functionality 2026-04-12 23:20:11 +10:00
pelgraine df6c977ee4 updated readme 2026-04-12 23:13:27 +10:00
pelgraine 7e9e69dd67 renamed WIP folders 2026-04-12 23:06:31 +10:00
pelgraine 6d7fd54b83 reordered emojis and improved scrolling in tdpro emojipicker; build emoji picker functionality into vkb for t5s3 2026-04-12 22:01:17 +10:00
pelgraine d2ce070a3f fix wifi companion builds sync bug & add planning for future 1000+ contacts load 2026-04-12 21:04:35 +10:00
pelgraine 44b68c40af tdpro platformio - removed unncessary helpers/esp32/SerialBLEInterface.cpp from build filters for wifi and standalone envs 2026-04-12 20:52:31 +10:00
pelgraine a4e8c31a16 fiiiiixed the contacts add and delete and toggle fav issues for real this time 2026-04-12 20:42:45 +10:00
pelgraine 8d69b69e1f fix contact limits in readme 2026-04-12 18:22:35 +10:00
pelgraine 0c032429eb Added new emoji to emoji picker; bug fixes for larger battery capacities recognition regression; updated readme for clarity on contacts add; updated firmware version; fix stupid blob storage size & buffer issue so now you can add contacts from last heard finally!!! Updated readme accordingly 2026-04-12 18:15:33 +10:00
pelgraine c578dcadc8 T5S3 - fixed touch selector fav contacts bug
TDPro - Update firmware build date

Contactsscreen.h — five changes:

- EPOCH_2026 = 1735689600UL constant added (Jan 1 2026 UTC), used in sort
  and formatAge.

- typeChar replaced by typeStr returning const char*, with "RS" for room
  servers (previously "S", easily confused with sensors). prefix buffer
  bumped to [5], all three snprintf calls updated to %s.

- Hop display: out_path_len == 0xFF branch now performs a live lookup
  against the 12 most recently heard advert paths (via
  getRecentlyHeard). Matches on first 7 bytes of pub_key, extracts hop
  count with a bph-aware sanity cap (64/bph max) to reject impossible
  values. Shows "~D" for direct flood neighbours, "~N" for N-hop flood
  path, "?" if not in the recent-heard cache. Resets to "?" on reboot
  until each contact re-advertises — intentional, ensures hop count is
  always fresh.

- Sort: _filteredTs now stores contact.lastmod (our local receive time)
  instead of contact.last_advert_timestamp (sender's claimed time).
  lastmod values below EPOCH_2026 are stored as 0 so stale repeaters
  with unsynced clocks and contacts received before our own timesync
  sink to the bottom of the list.

- formatAge rewritten: rejects timestamp == 0, timestamp < EPOCH_2026,
  and now < timestamp (all show "--" instead of wrapping or displaying
  garbage). Arithmetic changed from int to uint32_t, eliminating the
  signed overflow path that produced negative hour values. Age display
  call site switched from last_advert_timestamp to lastmod, so display
  self-corrects after a GPS or 4G timesync.
2026-04-12 12:44:10 +10:00
pelgraine ec42ac73a8 removed non-Meck v4 build 2026-04-12 09:25:38 +10:00
pelgraine aacf8c777f prelim techo card WIP files while I wait for hardware to arrive. claude putting excessive comments in platformio descriptors 2026-04-12 09:24:37 +10:00
pelgraine 570776478c merge tdeck pro max WIP variant into dev 2026-04-12 09:01:22 +10:00
pelgraine 4c654c99c6 remote wifi repeater updates - removed unnecessary envs for v4; setup v3 for remote wifi repeater role 2026-04-11 09:58:50 +10:00
pelgraine f436f5ba50 t5s3 contact limit fix 2026-04-09 12:18:29 +10:00
pelgraine 0252204d73 cpu fix for heltec v4 remote repeater build headless 2026-04-08 20:51:44 +10:00
pelgraine 9c4c4d2e03 Merge pull request #6 from pelgraine/dev
Dev
2026-04-07 20:06:51 +10:00
pelgraine 595f0073f9 TDeckBoard.cpp — both * 3 / 2 thresholds changed to > designCapacity_mAh, so FCC=3000 with DC=2500 now triggers the Qmax + stored FCC correction.
SerialBLEInterface.cpp — added esp_bt.h include and three esp_ble_tx_power_set calls at +9 dBm after BLEDevice::init(), covering default, advertising, and scan power types.

MyMesh.h — FIRMWARE_VER_CODE bumped from 10 → 11.
MyMesh.cpp — The RESP_CODE_DEVICE_INFO frame construction now:
Byte 2: sends 0xFF (sentinel) when MAX_CONTACTS > 510, otherwise the normal MAX_CONTACTS / 2. Older apps interpret 0xFF as 510 contacts — completely harmless.
Bytes 80-81 (new, appended after the version string): uint16_t little-endian with the true MAX_CONTACTS value. Apps that understand v11+ read it here. Apps < v11 ignore trailing bytes — the BLE/serial frame protocol is length-delimited, so extra bytes at the tail are safe.

platformio.ini — Both BLE builds (meck_audio_ble, meck_4g_ble) bumped from 510 → 2000.

mymesh.cpp: writeContactRespFrame return type change (return _serial->writeFrame() result)
checkSerialInterface() batch-fill loop.
2026-04-07 20:04:36 +10:00
pelgraine 8aa0f0388e meck wifi remote repeater heltec v4 2026-04-05 21:14:52 +10:00
pelgraine b070af39cc t5s3 wifi remote repeater 2026-04-05 08:57:47 +10:00
pelgraine c939aa577b fix prior env sensor manager build filter for remote repeater envs 2026-04-04 12:38:06 +11:00
pelgraine abccfe154e improve remote wifi repeater compile time 2026-04-04 12:16:52 +11:00
pelgraine 23733ca555 improve tdpro all builds compilation time but esp for remote repeater envs 2026-04-04 12:08:17 +11:00
pelgraine 9d45ac52eb fix wifi repeater and remote repeater ota process, update firmware version platiformio 2026-04-04 11:40:25 +11:00
pelgraine 424e152d4b simple remote wifi repeater v0.2 & remote repeater path hash mode improvements 2026-04-04 10:51:48 +11:00
pelgraine c687133b05 tdpro refined file export contacts selection json 2026-03-31 02:49:57 +11:00
pelgraine c7d0449181 remove sleep for remote repeater 2026-03-30 13:20:31 +11:00
pelgraine 9ddb692806 fix mqttsubscribe 2026-03-30 13:11:54 +11:00
pelgraine 0cab2ddfa7 fix tdpro remote admin display and lora init sd card mix 2026-03-30 13:02:31 +11:00
pelgraine d07ad71d5d tdpro remote 4g repeater admin via web app 2026-03-30 12:23:02 +11:00
pelgraine b4983e48f0 set custom contact paths 2026-03-29 17:06:45 +11:00
pelgraine b991eb0fe7 bumped up max contacts for BLE companions to 510 2026-03-29 16:15:55 +11:00
pelgraine c15b30079c update f send key for previously recorded voice notes 2026-03-29 14:49:31 +11:00
pelgraine 9d7cbd4866 tdpro audio only - voice notes over lora - 5 seconds stage 1 2026-03-29 14:04:54 +11:00
pelgraine b9283af7fc update serial settings guide 2026-03-28 01:41:40 +11:00
pelgraine 39cd30890b update readme for new v1.5 features 2026-03-28 01:41:16 +11:00
pelgraine 902577ed10 update build date 2026-03-28 01:11:26 +11:00
pelgraine ce93cfa033 sd file manager ota system 2026-03-27 03:36:20 +11:00
pelgraine 2be399f65a undo accidental battery size change commit 2026-03-27 02:59:51 +11:00
pelgraine 5679cda38e tdpro touch paches - dialpad touch system conflict fix and longpress changed to 750ms 2026-03-27 02:43:06 +11:00
pelgraine 1ea883783c update firmware version for incoming ota file handler updates 2026-03-27 02:29:09 +11:00
pelgraine bf8cf32bc2 speed up ble sync time; fix version in tdpro platformio 2026-03-27 01:56:17 +11:00
pelgraine 465a29bb23 fix bootindex method so ereader subdirectory files are recognised and pre-cache is completed properly 2026-03-27 00:58:02 +11:00
pelgraine 81eca29b69 implement meshcore PR 2151 changes 2026-03-27 00:43:10 +11:00
pelgraine 342cf4e745 tdpro large font pref option; various large font ui fixes; fix fcc recognition in t5s3 to match 1500 2026-03-26 15:34:09 +11:00
pelgraine c52a190ace update build date 2026-03-26 00:56:20 +11:00
pelgraine a7bc7a4733 t5s3 only lightsleep mode 2026-03-25 20:17:42 +11:00
pelgraine 47a0d2cc95 Update README.md
Made it really stupidly clear that this is vibecoded
2026-03-25 19:57:47 +11:00
pelgraine 5dda0b686e Incorporate PR 2044 and 2141; tdpro alarm screen - needs 44khz mp3 for sounds 2026-03-25 19:57:35 +11:00
pelgraine 60dcd6a89e tdpro - remove hint after boot for non-first time flash 2026-03-25 07:25:48 +11:00
pelgraine 19efb52521 udpate readme 2026-03-23 15:16:57 +11:00
pelgraine 81ef3ea3c5 update hint text for nav hint for first-time flashers; fix spiffs failure for first-time flash boot 2026-03-23 14:59:31 +11:00
pelgraine 6f07b7a372 update readme to do 2026-03-23 13:36:54 +11:00
pelgraine b0f74b101a tdpro - update firmware build date; improve keyboard responsiveness after boot 2026-03-23 13:33:23 +11:00
pelgraine 06a064538e fix lock screen bug cpupowermanager issue 2026-03-22 22:56:28 +11:00
pelgraine 166a433353 td pro - fix missing F discover prompt on home screen for standalone variants 2026-03-22 19:58:12 +11:00
pelgraine 735fefd203 update readme 2026-03-22 18:50:59 +11:00
pelgraine ed5cda4f44 readme update for v1.3 2026-03-22 18:49:38 +11:00
pelgraine b208af83f6 t5s3 ota 2026-03-22 16:11:37 +11:00
pelgraine bad821ac4b tdpro ota update firmware functionality implemented; roomserver ui sender name display fix and speed up delivery time 2026-03-22 13:16:25 +11:00
pelgraine 8839012153 firmware build date 2026-03-22 11:49:47 +11:00
pelgraine 0958ef079e Fix T5S3 word wrap regression ereader; persist dark mode, portrait mode, baudrate, and auto lock timer in data store 2026-03-22 11:48:57 +11:00
pelgraine 0bf2826110 roomserver additions stage 2 and dm ui functionality updates 2026-03-22 10:51:59 +11:00
pelgraine c2840a43aa roomserver additions stage 1; dms ui functionality improvements; removed t-deck plus device variant 2026-03-21 21:27:20 +11:00
pelgraine e8a8be521a update firmware version and build date 2026-03-21 18:39:06 +11:00
pelgraine a627fbe0e9 t5s3 - fix for del channel ui and touch function 2026-03-20 23:20:20 +11:00
pelgraine 17f8233402 fix readme typo in last heard 2026-03-20 21:36:08 +11:00
pelgraine 1c9e9079f0 Merge branch 'dev' 2026-03-20 21:31:03 +11:00
pelgraine 69dc62fa78 update readme and txt reader guides for Meck v1.2 2026-03-20 21:17:18 +11:00
pelgraine f118a0949f fix td pro platformio version whioops; tdpro reader screen ui fix - press enter to go to page 2026-03-20 20:52:39 +11:00
pelgraine f78824cdc4 tdpro & t5s3 pro - lock screen power saving improvements; fix stupid stupid merged firmware - bug 2026-03-20 20:22:07 +11:00
pelgraine f81de07830 t5s3 - improved cardkb notes rendering; fix notes generic filename save type 2026-03-20 08:05:23 +11:00
pelgraine 3ae988c0bb t5s3 cardkb support; update firmware build date 2026-03-20 06:23:05 +11:00
pelgraine 5bed26cb72 mostly t5s3 and some tdpro fixes - chunked save infrastructure, chunked save implementation, non-blocking lazy save, favourite contacts edit double confirmation added, hibernate 4g modem properly 2026-03-20 05:27:20 +11:00
pelgraine c28d22e6cc Update README.md
Add discord link
2026-03-20 03:41:43 +11:00
pelgraine 8e1f2a3a87 t5s3 - last heard touch fix; lock screen 15 min refresh fix; update firmware build date 2026-03-19 17:05:40 +11:00
pelgraine 6d1447a45c fix accidental battery size commit from tdeckboard.h 2026-03-18 22:29:26 +11:00
pelgraine 77c92b3567 td pro: footer consistency text updates; improve key polling responsiveness; Add Last Heard screen, access by pressing h key; update mymesh firmware version and date 2026-03-18 22:22:11 +11:00
pelgraine 6db7b672ca t5s3 - improvements for page navigation to text reader 2026-03-17 19:17:51 +11:00
pelgraine 046cce6f43 tdpro - bugfix for slow responsiveness occurring if key is pressed during toaster popup message 2026-03-17 18:55:10 +11:00
pelgraine c2c2d8cf21 tdpro - reduce occurrences of slow key responsiveness on boot 2026-03-17 18:42:12 +11:00
pelgraine 148f8cea4f tdpro lock screen stage 2 - auto lock settings preferences implemented 2026-03-17 17:42:10 +11:00
pelgraine cd69ea546f tdpro lock screen stage 1 - double click user/boot to lock/unlock screen 2026-03-17 16:56:55 +11:00
pelgraine 7780a0d76e tdpro intial touch file selector implementation stage 1 2026-03-17 16:35:44 +11:00
pelgraine 33a3352692 tdpro - improved cpu usage for maps and increased key responsiveness after boot; updated firmware date and build 2026-03-17 15:46:42 +11:00
pelgraine 4004acf15d tdpro darkmode regression bugfixes; update readme 2026-03-15 15:36:18 +11:00
pelgraine 0b9402b530 updated readme for v.1.1 changes 2026-03-15 14:50:24 +11:00
pelgraine e55799f8a5 tdpro settings screen updates and ui changes; gps baudrate selector kept to settings screen only; firmware version and build date updated 2026-03-15 14:41:03 +11:00
pelgraine 0549efa627 tdpro v1.0 gps debug fix 2026-03-15 14:17:05 +11:00
pelgraine a52cf166cb update firmware build date 2026-03-14 20:14:38 +11:00
pelgraine facffe9f07 t5s3 settings screen fix for add channels; t5s3 home screen new message screen refresh fix 2026-03-14 20:14:13 +11:00
pelgraine 148fb7f001 t5s3 minor ui settings screen channel delete fixes 2026-03-14 15:36:40 +11:00
pelgraine 509411630b update readme 2026-03-13 23:20:22 +11:00
pelgraine a1ce8ca4d4 Has gps flag for tdpro to fix audio standalone compile bug 2026-03-13 22:50:24 +11:00
pelgraine b77059706b tdpro dark mode 2026-03-13 22:50:24 +11:00
pelgraine a6f0052b89 t5s3 standalone clock sync over serial 2026-03-13 22:50:24 +11:00
pelgraine 120c0a739b update firmware build date; t5s3 home ui fix for standalone build 2026-03-13 22:50:24 +11:00
pelgraine 816e41d63a tdpro - reduced redundant offline queue size to free up kb in standalone builds only 2026-03-13 22:50:24 +11:00
pelgraine 68d10f088f t5s3 standalone env, no wifi, no ble, no gps 2026-03-13 22:50:24 +11:00
pelgraine 2f0c8909b9 t5s3 webreader screen ui fixes 2026-03-13 22:50:24 +11:00
pelgraine c60255a44d fix repeater admin screen timeout buffer t5s3; minor ui fixes web reader screen t5s3 2026-03-13 22:50:24 +11:00
pelgraine 9040873526 script to create merged firmware automatically 2026-03-13 22:50:24 +11:00
pelgraine a564957a82 t5s3 portrait mode text fix 2026-03-13 22:50:24 +11:00
pelgraine b55892431d t5s3 portrait mode and dark mode 2026-03-13 22:50:24 +11:00
pelgraine dc5331702d 55s3 ghosting improvement 2026-03-13 22:50:24 +11:00
pelgraine 88a887eba2 t5s3 text reader screen 2026-03-13 22:50:24 +11:00
pelgraine b1218223e6 reader screen word wrap fixes t5s3 2026-03-13 22:50:24 +11:00
pelgraine 0971cd6015 t5s3 removed battery icon and replaced with text because it's ugly 2026-03-13 22:50:24 +11:00
pelgraine 81eb558868 t5s3 web reader ui fixes 2026-03-13 22:50:24 +11:00
pelgraine 74b24f1222 t5s3 wifi companion 2026-03-13 22:50:24 +11:00
pelgraine 182231deeb home ui icons t5s3; repeater path view tap method 2026-03-13 22:50:24 +11:00
pelgraine 3372c4aa1d t5s3 ui, screen refresh and ghosting fixes 2026-03-13 22:50:24 +11:00
pelgraine 467773366b t5s3 keyboard bug fix 2026-03-13 22:50:23 +11:00
pelgraine 753d125384 t5s3 touch mapping fix; ui fixed for repeateradminscreen; highlighting fixed for notes and discovery screen; t5s3 initial virtual keyboard implementation 2026-03-13 22:50:23 +11:00
pelgraine 8b78eac17f lock screen and lock screen clock t5s3 2026-03-13 22:50:23 +11:00
pelgraine 565c2a4c9b ui fixes including discover screen; clock fix 2026-03-13 22:50:23 +11:00
pelgraine 7ae9c47006 t5s3 ui fixes; t5s3 initial ble and wifi companion build envs 2026-03-13 22:50:23 +11:00
pelgraine 2a0497e5ba lower brightness to 4 for best darkroom reading; first prelim touch implementation; ui improvements 2026-03-13 22:50:23 +11:00
pelgraine 479673e90f LilyGo T5 S3 Epaper Pro No GPS version implementation stage 1 - H752-B; set backlight double click boot to 153 full brightness on, triple click to 40 brightness, double click off 2026-03-13 22:50:23 +11:00
pelgraine 9b15458927 Update README.md 2026-03-08 00:41:51 +11:00
pelgraine 85ccdf526e Update README.md 2026-03-08 00:40:47 +11:00
pelgraine c0dd59834c updated firmware version and date 2026-03-07 15:56:16 +11:00
pelgraine 90a4f5f881 multi.acks 1 set default for new firmware installs; can set rxdelay, int.thresh, gps.baud and multi.acks prefs over serial; adjust preamble length dependant on SF setting; updated serial settings guide and Meck Readme accordingly 2026-03-07 15:53:50 +11:00
pelgraine b27acb3252 multi-byte path implementation to bring Meck up to speed with Meshcore v1.14; fix regression of ui display in last msg rcd repeater hop count view and also update it for 2 byte nodes 2026-03-07 05:02:22 +11:00
pelgraine 580484e0ad update firmware version and date to v0.9.9 in prep for multibyte testing 2026-03-07 03:21:10 +11:00
pelgraine 9d7fbc3134 updated photo sizes in Launcher flash guide 2026-03-06 22:15:17 +11:00
pelgraine b859f8f168 Added guide to flashing Meck via Launcher 2026-03-06 22:10:38 +11:00
pelgraine 190b40c2ce fixed regression with previously committed missing code from webreaderscreen h 2026-03-06 18:26:32 +11:00
pelgraine 859919348d fix serial settings loop regression argh 2026-03-05 19:13:29 +11:00
166 changed files with 39142 additions and 3904 deletions
+64
View File
@@ -0,0 +1,64 @@
# PlatformIO monitor filter: automatic clock sync for Meck devices
#
# When a Meck device boots with no valid RTC time, it prints "MECK_CLOCK_REQ"
# over serial. This filter watches for that line and responds immediately
# with "clock sync <epoch>\r\n", setting the device's real-time clock to
# the host computer's current time.
#
# The sync is completely transparent — the user just sees it happen in the
# boot log. If the RTC already has valid time, the device never sends the
# request and this filter does nothing.
#
# Install: place this file in <project>/monitor/filter_clock_sync.py
# Enable: add "clock_sync" to monitor_filters in platformio.ini
#
# Works with: PlatformIO Core >= 6.0
import time
from platformio.device.monitor.filters.base import DeviceFilter
class ClockSync(DeviceFilter):
NAME = "clock_sync"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._buf = bytearray()
self._synced = False
def rx(self, text):
"""Called with each chunk of data received from the device."""
if self._synced:
return text
# Accumulate into a line buffer to detect MECK_CLOCK_REQ
if isinstance(text, str):
self._buf.extend(text.encode("utf-8", errors="replace"))
else:
self._buf.extend(text)
if b"MECK_CLOCK_REQ" in self._buf:
epoch = int(time.time())
response = "clock sync {}\r\n".format(epoch)
try:
# Write directly to the serial port
self.miniterm.serial.write(response.encode("utf-8"))
except Exception as e:
# Fallback: shouldn't happen, but don't crash the monitor
import sys
print(
"\n[clock_sync] Failed to auto-sync: {}".format(e),
file=sys.stderr,
)
self._synced = True
self._buf = bytearray()
elif len(self._buf) > 2048:
# Prevent unbounded growth — keep tail only
self._buf = self._buf[-256:]
return text
def tx(self, text):
"""Called with each chunk of data sent from terminal to device."""
return text
+863 -55
View File
File diff suppressed because it is too large Load Diff
+283 -5
View File
@@ -59,10 +59,21 @@ All commands follow a simple pattern: `get` to read, `set` to write.
| `get notify` | Keyboard flash notification (on/off) |
| `get gps` | GPS status and interval |
| `get pin` | BLE pairing PIN |
| `get channels` | List all channels with index numbers |
| `get path.hash.mode` | Path hash size (0=1-byte, 1=2-byte, 2=3-byte) |
| `get rxdelay` | Rx delay base (0=disabled) |
| `get af` | Airtime factor |
| `get multi.acks` | Redundant ACKs (0 or 1) |
| `get int.thresh` | Interference threshold (0=disabled) |
| `get tx.fail.threshold` | TX fail reset threshold (0=disabled, default 3) |
| `get rx.fail.threshold` | RX stuck reboot threshold (0=disabled, default 3) |
| `get gps.baud` | GPS baud rate (0=compile-time default) |
| `get region` | Default region scope (e.g. `au-nsw`, or `none`) |
| `get channels` | List all channels with index numbers and region scopes |
| `get channel.scope <idx>` | Show region scope for a specific channel |
| `get presets` | List all radio presets with parameters |
| `get pubkey` | Device public key (hex) |
| `get firmware` | Firmware version string |
| `clock` | Current RTC time (UTC + epoch) |
**4G variant only:**
@@ -163,6 +174,112 @@ set notify off
set pin 123456
```
#### Path Hash Mode
Controls the byte size of each repeater's identity stamp in forwarded flood packets. Larger hashes reduce collisions at the cost of fewer maximum hops.
```
set path.hash.mode 1
```
| Mode | Bytes/hop | Max hops | Notes |
|------|-----------|----------|-------|
| 0 | 1 | 64 | Legacy — prone to hash collisions in larger networks |
| 1 | 2 | 32 | Recommended — effectively eliminates collisions |
| 2 | 3 | 21 | Maximum precision, rarely needed |
Nodes with different modes can coexist — the mode only affects packets your node originates. The hash size is encoded in each packet's header, so receiving nodes adapt automatically.
### Mesh Tuning
These settings control how the device participates in the mesh network. They take effect immediately — no reboot required (except `gps.baud`).
#### Rx Delay (rxdelay)
Delays processing of flood packets based on signal quality. Stronger signals are processed first; weaker copies wait longer and are typically discarded as duplicates. Direct messages are always processed immediately.
```
set rxdelay 3
```
Range: 020 (0 = disabled, default). Higher values create larger timing differences between strong and weak signals. Values below 1.0 have no practical effect. See the [MeshSydney wiki](https://meshsydney.com/wiki) for detailed tuning profiles.
#### Airtime Factor (af)
Adjusts how long certain internal timing windows remain open. Does not change the LoRa radio parameters (SF, BW, CR) — those remain as configured.
```
set af 1.0
```
Range: 09 (default: 1.0). Keep this value consistent across nodes in your mesh for best coherence.
#### Multiple Acknowledgments (multi.acks)
Sends redundant ACK packets for direct messages. When enabled, two ACKs are sent (a multi-ack first, then the standard ACK), improving delivery confirmation reliability.
```
set multi.acks 1
```
Values: 0 (single ACK) or 1 (redundant ACKs, default).
#### Interference Threshold (int.thresh)
Enables channel activity scanning before transmitting. Not recommended unless your device is in a high RF interference environment — specifically where the noise floor is low but shows significant fluctuations indicating interference. Enabling this adds approximately 4 seconds of receive delay per packet.
```
set int.thresh 14
set int.thresh 0
```
Values: 0 (disabled, default) or 14+ (14 is the typical setting). Values between 113 are not functional and will be rejected.
#### TX Fail Reset Threshold (tx.fail.reset)
Automatically resets the radio hardware after this many consecutive failed transmission attempts. This recovers from "zombie radio" states where the SX1262 stops responding to send commands.
```
set tx.fail.threshold 3
set tx.fail.threshold 0
```
Values: 0 (disabled) or 110 (default: 3). After the threshold is reached, the radio is reset and the failed packet is re-queued.
#### RX Stuck Reboot Threshold (rx.fail.reboot)
Automatically reboots the device after this many consecutive RX-stuck recovery failures. An RX-stuck event occurs when the radio is not in receive mode for 8 seconds despite automatic recovery attempts.
```
set rx.fail.threshold 3
set rx.fail.threshold 0
```
Values: 0 (disabled) or 110 (default: 3). A full device reboot is a last resort — this should only trigger in rare cases of persistent radio hardware malfunction.
#### GPS Baud Rate (gps.baud)
Override the GPS serial baud rate. The default (0) uses the compile-time value of 38400. **Requires a reboot to take effect** — the GPS serial port is only configured at startup.
```
set gps.baud 9600
set gps.baud 0
```
Valid rates: 0 (default), 4800, 9600, 19200, 38400, 57600, 115200.
#### Backlight (T5S3 E-Paper Pro Only)
Control the front-light on the T5S3 display:
```
set backlight on
set backlight off
set backlight 128
```
Values: `on`, `off`, or a brightness level from 0255.
### Channel Management
#### List Channels
@@ -174,11 +291,13 @@ get channels
Output:
```
[0] #public
[1] #meck-test
[2] #local-group
[0] #public [*]
[1] #meck-test [au-nsw]
[2] #local-group [*]
```
Each channel shows its region scope in brackets. `[*]` means the channel uses the device default region (or unscoped if no default is set). A specific name like `[au-nsw]` means that channel has its own region override.
#### Add a Hashtag Channel
```
@@ -195,6 +314,82 @@ set channel.del 2
Channels are referenced by their index number (shown in `get channels`). Channel 0 (public) cannot be deleted. Remaining channels are automatically compacted after deletion.
### Region Scope
Regions limit how far your flood messages propagate through the mesh. When you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.
Meck does not pre-set any region on a fresh flash. Region names are determined by your local mesh community — check with your local group for the names in use. Common patterns follow ISO 3166 country/subdivision codes (e.g. `au` for Australia, `gb-eng` for England, `us-ca` for California), but communities may also use custom names for their area.
Region names must be lowercase alphanumeric characters and hyphens only, max 29 characters.
#### View Default Region
```
get region
```
Output:
```
> au-nsw
```
Or if no region is set:
```
> (none — unscoped)
```
#### Set Default Region
```
set region au-nsw
```
This applies to all channels and DMs unless a channel has its own region override.
#### Clear Default Region
```
set region none
```
Returns to unscoped mode — messages reach all repeaters.
#### View Channel Region
```
get channel.scope 2
```
Output:
```
> #local-group scope: au-syd
```
Or if the channel uses the device default:
```
> #local-group scope: (device default)
```
#### Set Channel Region
```
set channel.scope 2 au-syd
```
This overrides the device default for that specific channel.
#### Clear Channel Region
```
set channel.scope 2 none
```
Returns the channel to using the device default region.
### 4G Modem (4G Variant Only)
#### Enable / Disable Modem
@@ -216,6 +411,68 @@ To clear a custom APN and revert to auto-detection on next boot:
set apn
```
### Clock Sync
Set the device's real-time clock from a Unix timestamp. This is especially important for the T5S3 E-Paper Pro which has no GPS to auto-set the clock. These are standalone commands (not `get`/`set` prefixed) — matching the same `clock sync` command used on MeshCore repeaters.
#### View Current Time
```
clock
```
Output:
```
> 2026-03-13 04:22:15 UTC (epoch: 1773554535)
```
If the clock has never been set:
```
> not set (epoch: 0)
```
#### Sync Clock from Serial
```
clock sync 1773554535
```
The value must be a Unix epoch timestamp in the 20242036 range.
**Quick one-liner from your terminal (macOS / Linux / WSL):**
```
echo "clock sync $(date +%s)" > /dev/ttyACM0
```
Or paste directly into the Arduino IDE Serial Monitor:
```
clock sync 1773554535
```
**Tip:** On macOS/Linux, run `date +%s` to get the current epoch. On Windows PowerShell: `[int](Get-Date -UFormat %s)`.
#### Boot-Time Auto-Sync (T5S3)
When the T5S3 boots with no valid RTC time and detects a USB serial host is connected, it sends a `MECK_CLOCK_REQ` handshake over serial. If you're using PlatformIO's serial monitor (`pio device monitor`), the built-in `clock_sync` monitor filter responds automatically with the host computer's current time — no user action required. The sync appears transparently in the boot log:
```
MECK_CLOCK_REQ
(Waiting 3s for clock sync from host...)
> Clock synced to 1773554535
```
If no USB host is connected (e.g. running on battery), the sync window is skipped entirely with no boot delay.
**Manual fallback:** If you're using a serial terminal that doesn't have the filter (e.g. `screen`, PuTTY), you can paste a `clock sync` command during the 3-second window, or any time after boot:
```
clock sync $(date +%s)
```
### System Commands
| Command | Description |
@@ -245,7 +502,7 @@ set channel.add local-group
get all
```
### Switching to a New Region
### Switching to a Different Radio Preset
Moving from Australia to the US? One command:
@@ -259,6 +516,27 @@ Verify with:
get radio
```
### Setting Up Regions
Check with your local mesh community for the region names in use, then set your device default:
```
set region au-nsw
```
If you want a specific channel to use a different region (e.g. a nationwide channel):
```
set channel.scope 1 au
```
Verify everything:
```
get region
get channels
```
### Custom Radio Configuration
If none of the presets match your local group or you need specific parameters, set them directly. You can do it all in one command:
+16 -6
View File
@@ -2,7 +2,7 @@
## Overview
This adds a text reader accessible via the **R** key from the home screen.
This adds a text reader accessible via the **E** key from the home screen.
**Features:**
- Browse `.txt` and `.epub` files from `/books/` folder on SD card
@@ -13,17 +13,27 @@ This adds a text reader accessible via the **R** key from the home screen.
- Index files cached to SD for instant re-opens
- Bookmark indicator (`*`) on files with saved positions
**Key Mapping:**
**Key Mapping (T-Deck Pro):**
| Context | Key | Action |
|---------|-----|--------|
| Home screen | E | Open text reader |
| File list | W/S | Navigate up/down |
| File list | Enter | Open selected file |
| File list | Tap / Enter | Open selected file |
| File list | Q | Back to home screen |
| Reading | W/A | Previous page |
| Reading | S/D/Space/Enter | Next page |
| Reading | S/D/Space | Next page |
| Reading | Enter | Go to page number (type digits, Enter to confirm, Q to cancel) |
| Reading | Q | Close book → file list |
| Reading | C | Enter compose mode |
**Touch Gestures (T5S3):**
| Context | Gesture | Action |
|---------|---------|--------|
| File list | Swipe up/down | Scroll file list |
| File list | Tap | Open selected book |
| Reading | Tap | Next page |
| Reading | Swipe left/right | Next / previous page |
| Reading | Tap footer | Go to page number (via virtual keyboard) |
| Reading | Long press | Close book → file list |
---
@@ -113,4 +123,4 @@ The conversion is handled by three components:
- Page content is pre-read from SD into a memory buffer during `handleInput()`, then rendered from buffer during `render()` — this avoids SPI bus conflicts during display refresh
- Layout metrics (chars per line, lines per page) are calculated dynamically from the display driver's font metrics on first entry
- EPUB conversion runs synchronously in `openBook()` — the e-ink splash screen keeps the user informed while the ESP32 processes the archive
- ZIP extraction uses the ESP32-S3's hardware-optimised ROM `tinfl` inflate, avoiding external compression library dependencies and the linker conflicts they cause
- ZIP extraction uses the ESP32-S3's hardware-optimised ROM `tinfl` inflate, avoiding external compression library dependencies and the linker conflicts they cause
+48
View File
@@ -0,0 +1,48 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": [
"-DARDUINO_NRF52840_TECHO_CARD",
"-DNRF52840_XXAA",
"-DNRF52_SERIES"
],
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x8029"]],
"mcu": "nrf52840",
"variant": "lilygo_techo_card",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"usb_product": "T-Echo Card"
},
"connectivity": ["bluetooth", "lora"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"openocd_target": "nrf52840"
},
"frameworks": ["arduino"],
"name": "LilyGo T-Echo Card (nRF52840, SX1262, 4MB Flash)",
"upload": {
"flash_size": "796KB",
"maximum_ram_size": 248832,
"maximum_size": 815104,
"native_usb": true,
"protocol": "nrfutil",
"protocols": ["nrfutil", "jlink", "cmsis-dap"],
"require_upload_port": true,
"speed": 115200,
"use_1200bps_touch": true,
"wait_for_upload_port": true
},
"url": "https://github.com/Xinyuan-LilyGO/T-Echo-Card",
"vendor": "LILYGO"
}
+40
View File
@@ -0,0 +1,40 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_qspi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "LilyGo T-Deck Pro MAX (16MB Flash 8MB QSPI PSRAM)",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.lilygo.cc/products/t-deck-pro",
"vendor": "LilyGo"
}
+38
View File
@@ -0,0 +1,38 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "LilyGo T5S3 E-Paper Pro",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "https://lilygo.cc/products/t5-e-paper-s3-pro",
"vendor": "LILYGO"
}
+5
View File
@@ -0,0 +1,5 @@
6818ce5f77dd45bb90facf753ba81d81.s1.eu.hivemq.cloud
8883
meckremote
yourpassword
heltec-wifi-1
+2
View File
@@ -0,0 +1,2 @@
SSID
Password
+101
View File
@@ -0,0 +1,101 @@
# How to Flash Meck Firmware Using Launcher over WiFi
## How to Install Launcher on Your T-Deck Pro
First, ensure your SD card is inserted into your T-Deck Pro. Your SD card should already have been formatted as FAT32.
1. Plug your T-Deck Pro into your computer via USB-C.
2. Go to [https://bmorcelli.github.io/Launcher/webflasher.html](https://bmorcelli.github.io/Launcher/webflasher.html) in Chrome browser.
3. Click on **LilyGo** under Choose a Vendor.
4. Click on **T-Deck Pro**.
5. Click on **Connect**.
6. In the serial connect popup, click on your device in the list (likely starts with "USB JTAG/serial debug unit"), and click **Connect**. Wait a few seconds for it to connect.
7. Click the **Install T-Deck Pro** popup.
8. Click **Next**. (Don't worry about ticking the Erase Device checkbox.)
9. Click **Install**.
### If You Don't Already Have a Meck Firmware File
Download one from [https://github.com/pelgraine/Meck/releases](https://github.com/pelgraine/Meck/releases).
## How to Install a New Meck Firmware .bin File via Launcher
After flashing using [https://bmorcelli.github.io/Launcher/webflasher.html](https://bmorcelli.github.io/Launcher/webflasher.html), your Pro will reboot itself automatically and display the main Launcher home screen, with the SD card option highlighted.
<img src="images/01_launcher_home.jpg" alt="Launcher home screen" width="200">
Either tap **NEXT** on the device screen twice or tap on the WUI button, and tap **SEL**.
<img src="images/02_wui_selected.jpg" alt="WUI selected" width="200">
Tap on **My Network** on the pop-up menu. Press **NEXT/SEL** as needed to highlight and select your WiFi SSID.
Enter your WiFi SSID details.
Once connected, your device will display the WebUI connection screen with the T-Deck Pro IP address.
Open a browser on your computer — Chrome, Firefox, or Safari will do, but Firefox tends to be easiest — and type in the IP address displayed on your T-Deck Pro into your computer browser address bar, and press enter.
<img src="images/03_webui_ip.jpg" alt="WebUI IP address screen" width="200">
In this instance, for example, I would type `192.168.1.118`, and once I've pressed enter, the address bar now displays `http://192.168.1.118/` (as per the photo). If you're having trouble loading the IP address page, double check your browser hasn't automatically changed it to `https`. If it has, delete the `s` out of the URL and hit enter to load the page.
Login to the browser page with the username **admin** and password **launcher**, and click **Login**. The browser will refresh and display your SD card file list.
<img src="images/04_browser_login.jpg" alt="Browser login" width="450">
<img src="images/05_send_files.png" alt="SD card file list with Send Files button" width="450">
Scroll down to the bottom of the browser page, and click the **Send Files** button.
Your computer/device will load the file browser. Navigate to wherever you've previously saved your new Meck firmware `.bin` file, select the bin file, and click **Open**.
Wait for the blue loading bar on the bottom of the browser page to finish, and then check you can see the file name in the list in green. Also worth checking the file is at least 1.2MB — if it is under 1MB, the file hasn't uploaded properly and you will need to go through the **Send Files** button to try uploading it again.
<img src="images/06_check_file_uploaded.png" alt="Check file uploaded" width="450">
You can then either close the browser window or just leave it. Go back to your T-Deck Pro and press **SEL** to disconnect the WUI mode.
<img src="images/07_disconnect_wui.png" alt="Disconnect WUI" width="200">
Either press **PREV** twice to navigate to it and then press **SEL** again to open, or tap right on the **SD** button to open the SD card menu.
<img src="images/08_sd_button.jpg" alt="SD button on Launcher home" width="200">
The Launcher SD file browser will open. You will most likely have to tap **Page Down** at least twice to scroll to where the name of your new file is.
<img src="images/09_sd_file_list.png" alt="SD file list page 1" width="200">
<img src="images/10_page_down.png" alt="Page Down to find file" width="200">
Either press **NEXT** to navigate until the new file is highlighted with the `>`, or just tap right on the file name, and press **SEL** to bring up the file menu.
<img src="images/11_select_file.png" alt="Select the firmware file" width="200">
The first option on the file menu list will be **>Install**. You can either tap right on **Install** or tap **SEL**.
<img src="images/12_install_option.png" alt="Install option" width="200">
**Wait for the firmware to finish installing.** It will reboot itself automatically.
<img src="images/13_installing_fw.jpg" alt="Installing firmware" width="200">
> **Note:** On first flash of a new firmware version, the "Loading…" screen will most likely display for about 70 seconds. This is a known bug. **Please be patient** if this is the first time loading your new Meck firmware.
<img src="images/14_loading_screen.png" alt="Loading screen" width="200">
On every boot, the firmware will scan your SD card and `/books` folder for any new `.txt` or `.epub` files that haven't yet been cached. It's usually very quick even if you have a lot of ebook files, and even faster after the first boot.
<img src="images/15_indexing_pages.jpg" alt="Indexing pages" width="200">
You'll then see the firmware version splash screen for a split second.
<img src="images/16_version_splash.jpg" alt="Version splash screen" width="200">
Then the Meck home screen will display, and you're good to go. Here's an example of what the Meck 4G WiFi companion firmware home screen looks like:
<img src="images/17_meck_home.jpg" alt="Meck home screen" width="200">
> **Tip:** Every time you reset the device, the Launcher splash screen will display. Wait about six seconds if you just want the Meck firmware to boot by default. Otherwise, tap the **LAUNCHER** text at the bottom to boot back into the Launcher home screen, to get access to the SD menu and WUI menu again.
<img src="images/18_launcher_boot.jpg" alt="Launcher boot screen" width="200">
Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

+1 -1
View File
@@ -41,7 +41,7 @@ public:
void disableSerial() { _serial->disable(); }
virtual void msgRead(int msgcount) = 0;
virtual void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount,
const uint8_t* path = nullptr) = 0;
const uint8_t* path = nullptr, int8_t snr = 0) = 0;
virtual void notify(UIEventType t = UIEventType::none) = 0;
virtual void loop() = 0;
virtual void showAlert(const char* text, int duration_millis) {}
+248 -10
View File
@@ -242,6 +242,72 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
if (_prefs.kb_flash_notify > 1) _prefs.kb_flash_notify = 0;
if (_prefs.ringtone_enabled > 1) _prefs.ringtone_enabled = 0;
// v1.14+ fields — may not exist in older prefs files
if (file.read((uint8_t *)&_prefs.path_hash_mode, sizeof(_prefs.path_hash_mode)) != sizeof(_prefs.path_hash_mode)) {
_prefs.path_hash_mode = 0; // default: legacy 1-byte
}
if (file.read((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)) != sizeof(_prefs.autoadd_max_hops)) {
_prefs.autoadd_max_hops = 0; // default: no limit
}
if (_prefs.path_hash_mode > 2) _prefs.path_hash_mode = 0;
if (_prefs.autoadd_max_hops > 64) _prefs.autoadd_max_hops = 0;
// v1.1+ Meck fields — may not exist in older prefs files
if (file.read((uint8_t *)&_prefs.gps_baudrate, sizeof(_prefs.gps_baudrate)) != sizeof(_prefs.gps_baudrate)) {
_prefs.gps_baudrate = 0; // default: use compile-time GPS_BAUDRATE
}
if (file.read((uint8_t *)&_prefs.interference_threshold, sizeof(_prefs.interference_threshold)) != sizeof(_prefs.interference_threshold)) {
_prefs.interference_threshold = 0; // default: disabled
}
if (file.read((uint8_t *)&_prefs.dark_mode, sizeof(_prefs.dark_mode)) != sizeof(_prefs.dark_mode)) {
_prefs.dark_mode = 0; // default: light mode
}
if (file.read((uint8_t *)&_prefs.portrait_mode, sizeof(_prefs.portrait_mode)) != sizeof(_prefs.portrait_mode)) {
_prefs.portrait_mode = 0; // default: landscape
}
if (file.read((uint8_t *)&_prefs.auto_lock_minutes, sizeof(_prefs.auto_lock_minutes)) != sizeof(_prefs.auto_lock_minutes)) {
_prefs.auto_lock_minutes = 0; // default: disabled
}
if (file.read((uint8_t *)&_prefs.hint_shown, sizeof(_prefs.hint_shown)) != sizeof(_prefs.hint_shown)) {
_prefs.hint_shown = 0; // default: show boot hint
}
if (file.read((uint8_t *)&_prefs.large_font, sizeof(_prefs.large_font)) != sizeof(_prefs.large_font)) {
_prefs.large_font = 0; // default: tiny font
}
if (file.read((uint8_t *)&_prefs.ui_font_style, sizeof(_prefs.ui_font_style)) != sizeof(_prefs.ui_font_style)) {
_prefs.ui_font_style = 0; // default: Classic (FreeSans)
}
if (file.read((uint8_t *)&_prefs.tx_fail_reset_threshold, sizeof(_prefs.tx_fail_reset_threshold)) != sizeof(_prefs.tx_fail_reset_threshold)) {
_prefs.tx_fail_reset_threshold = 3; // default: 3
}
if (file.read((uint8_t *)&_prefs.rx_fail_reboot_threshold, sizeof(_prefs.rx_fail_reboot_threshold)) != sizeof(_prefs.rx_fail_reboot_threshold)) {
_prefs.rx_fail_reboot_threshold = 3; // default: 3
}
// v1.7+ Meck region scope fields — may not exist in older prefs files
if (file.read((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)) != sizeof(_prefs.default_scope_name)) {
memset(_prefs.default_scope_name, 0, sizeof(_prefs.default_scope_name)); // default: unscoped
}
if (file.read((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)) != sizeof(_prefs.default_scope_key)) {
memset(_prefs.default_scope_key, 0, sizeof(_prefs.default_scope_key)); // default: null key
}
// Clamp to valid ranges
if (_prefs.dark_mode > 1) _prefs.dark_mode = 0;
if (_prefs.portrait_mode > 1) _prefs.portrait_mode = 0;
if (_prefs.hint_shown > 1) _prefs.hint_shown = 0;
if (_prefs.large_font > 1) _prefs.large_font = 0;
if (_prefs.ui_font_style >= 3) _prefs.ui_font_style = 0;
if (_prefs.tx_fail_reset_threshold > 10) _prefs.tx_fail_reset_threshold = 3;
if (_prefs.rx_fail_reboot_threshold > 10) _prefs.rx_fail_reboot_threshold = 3;
// auto_lock_minutes: only accept known options (0, 2, 5, 10, 15, 30)
{
uint8_t alm = _prefs.auto_lock_minutes;
if (alm != 0 && alm != 2 && alm != 5 && alm != 10 && alm != 15 && alm != 30) {
_prefs.auto_lock_minutes = 0;
}
}
file.close();
}
}
@@ -279,6 +345,20 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
file.write((uint8_t *)&_prefs.utc_offset_hours, sizeof(_prefs.utc_offset_hours)); // 88
file.write((uint8_t *)&_prefs.kb_flash_notify, sizeof(_prefs.kb_flash_notify)); // 89
file.write((uint8_t *)&_prefs.ringtone_enabled, sizeof(_prefs.ringtone_enabled)); // 90
file.write((uint8_t *)&_prefs.path_hash_mode, sizeof(_prefs.path_hash_mode)); // 91
file.write((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 92
file.write((uint8_t *)&_prefs.gps_baudrate, sizeof(_prefs.gps_baudrate)); // 93
file.write((uint8_t *)&_prefs.interference_threshold, sizeof(_prefs.interference_threshold)); // 97
file.write((uint8_t *)&_prefs.dark_mode, sizeof(_prefs.dark_mode)); // 98
file.write((uint8_t *)&_prefs.portrait_mode, sizeof(_prefs.portrait_mode)); // 99
file.write((uint8_t *)&_prefs.auto_lock_minutes, sizeof(_prefs.auto_lock_minutes)); // 100
file.write((uint8_t *)&_prefs.hint_shown, sizeof(_prefs.hint_shown)); // 101
file.write((uint8_t *)&_prefs.large_font, sizeof(_prefs.large_font)); // 102
file.write((uint8_t *)&_prefs.ui_font_style, sizeof(_prefs.ui_font_style)); // 103
file.write((uint8_t *)&_prefs.tx_fail_reset_threshold, sizeof(_prefs.tx_fail_reset_threshold)); // 104
file.write((uint8_t *)&_prefs.rx_fail_reboot_threshold, sizeof(_prefs.rx_fail_reboot_threshold)); // 105
file.write((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 106
file.write((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 137
file.close();
}
@@ -431,12 +511,156 @@ void DataStore::saveContacts(DataStoreHost* host) {
}
}
// =========================================================================
// Chunked contact save — non-blocking across multiple loop iterations
// =========================================================================
bool DataStore::beginSaveContacts(DataStoreHost* host) {
if (_saveInProgress) return false; // Already saving
FILESYSTEM* fs = _getContactsChannelsFS();
_saveFile = openWrite(fs, "/contacts3.tmp");
if (!_saveFile) {
Serial.println("DataStore: chunked save FAILED — cannot open tmp file");
return false;
}
_saveHost = host;
_saveIdx = 0;
_saveRecordsWritten = 0;
_saveWriteOk = true;
_saveInProgress = true;
Serial.println("DataStore: chunked save started");
return true;
}
bool DataStore::saveContactsChunk(int batchSize) {
if (!_saveInProgress || !_saveWriteOk) return false;
ContactInfo c;
uint8_t unused = 0;
int written = 0;
while (written < batchSize && _saveHost->getContactForSave(_saveIdx, c)) {
bool success = (_saveFile.write(c.id.pub_key, 32) == 32);
success = success && (_saveFile.write((uint8_t *)&c.name, 32) == 32);
success = success && (_saveFile.write(&c.type, 1) == 1);
success = success && (_saveFile.write(&c.flags, 1) == 1);
success = success && (_saveFile.write(&unused, 1) == 1);
success = success && (_saveFile.write((uint8_t *)&c.sync_since, 4) == 4);
success = success && (_saveFile.write((uint8_t *)&c.out_path_len, 1) == 1);
success = success && (_saveFile.write((uint8_t *)&c.last_advert_timestamp, 4) == 4);
success = success && (_saveFile.write(c.out_path, 64) == 64);
success = success && (_saveFile.write((uint8_t *)&c.lastmod, 4) == 4);
success = success && (_saveFile.write((uint8_t *)&c.gps_lat, 4) == 4);
success = success && (_saveFile.write((uint8_t *)&c.gps_lon, 4) == 4);
if (!success) {
_saveWriteOk = false;
Serial.printf("DataStore: chunked save write error at record %d\n", _saveIdx);
return false; // Error — finishSaveContacts will clean up
}
_saveRecordsWritten++;
_saveIdx++;
written++;
}
// Check if there are more contacts to write
ContactInfo peek;
if (_saveHost->getContactForSave(_saveIdx, peek)) {
return true; // More to write
}
return false; // Done
}
void DataStore::finishSaveContacts() {
if (!_saveInProgress) return;
_saveFile.close();
_saveInProgress = false;
FILESYSTEM* fs = _getContactsChannelsFS();
const char* finalPath = "/contacts3";
const char* tmpPath = "/contacts3.tmp";
// Verify
size_t expectedBytes = _saveRecordsWritten * 152;
File verify = openRead(fs, tmpPath);
size_t bytesWritten = verify ? verify.size() : 0;
if (verify) verify.close();
if (!_saveWriteOk || bytesWritten != expectedBytes) {
Serial.printf("DataStore: chunked save ABORTED — wrote %d bytes, expected %d (%d records)\n",
(int)bytesWritten, (int)expectedBytes, _saveRecordsWritten);
fs->remove(tmpPath);
return;
}
fs->remove(finalPath);
if (fs->rename(tmpPath, finalPath)) {
Serial.printf("DataStore: saved %d contacts (%d bytes, chunked)\n",
_saveRecordsWritten, (int)bytesWritten);
} else {
Serial.println("DataStore: rename failed, tmp file preserved");
}
}
void DataStore::loadChannels(DataStoreHost* host) {
FILESYSTEM* fs = _getContactsChannelsFS();
// Crash recovery (same pattern as contacts)
if (!fs->exists("/channels3") && fs->exists("/channels3.tmp")) {
Serial.println("DataStore: recovering channels3 from .tmp file");
fs->rename("/channels3.tmp", "/channels3");
}
if (fs->exists("/channels3.tmp")) {
fs->remove("/channels3.tmp");
}
// Try channels3 (new format with scope_name) first
if (fs->exists("/channels3")) {
File file = openRead(fs, "/channels3");
if (file) {
bool full = false;
uint8_t channel_idx = 0;
while (!full) {
ChannelDetails ch;
memset(ch.scope_name, 0, sizeof(ch.scope_name));
uint8_t unused[4];
bool success = (file.read(unused, 4) == 4);
success = success && (file.read((uint8_t *)ch.name, 32) == 32);
success = success && (file.read((uint8_t *)ch.channel.secret, 32) == 32);
success = success && (file.read((uint8_t *)ch.scope_name, 31) == 31);
if (!success) break; // EOF
// Sanitize scope_name — reject if it contains non-region characters
// (catches garbage from uninitialised memory in early channels3 files)
ch.scope_name[30] = '\0'; // force null-terminate
for (int s = 0; ch.scope_name[s]; s++) {
char sc = ch.scope_name[s];
if (!((sc >= 'a' && sc <= 'z') || (sc >= '0' && sc <= '9') || sc == '-')) {
memset(ch.scope_name, 0, sizeof(ch.scope_name)); // invalid — clear
break;
}
}
if (host->onChannelLoaded(channel_idx, ch)) {
channel_idx++;
} else {
full = true;
}
}
file.close();
return; // channels3 loaded successfully
}
}
// Fall back to channels2 (legacy format without scope_name)
if (!fs->exists("/channels2") && fs->exists("/channels2.tmp")) {
Serial.println("DataStore: recovering channels from .tmp file");
Serial.println("DataStore: recovering channels2 from .tmp file");
fs->rename("/channels2.tmp", "/channels2");
}
if (fs->exists("/channels2.tmp")) {
@@ -449,6 +673,7 @@ void DataStore::loadChannels(DataStoreHost* host) {
uint8_t channel_idx = 0;
while (!full) {
ChannelDetails ch;
memset(ch.scope_name, 0, sizeof(ch.scope_name)); // default: no scope
uint8_t unused[4];
bool success = (file.read(unused, 4) == 4);
@@ -464,13 +689,18 @@ void DataStore::loadChannels(DataStoreHost* host) {
}
}
file.close();
// Migrate: save as channels3 and remove channels2
Serial.println("DataStore: migrating channels2 → channels3");
saveChannels(host);
fs->remove("/channels2");
}
}
void DataStore::saveChannels(DataStoreHost* host) {
FILESYSTEM* fs = _getContactsChannelsFS();
const char* finalPath = "/channels2";
const char* tmpPath = "/channels2.tmp";
const char* finalPath = "/channels3";
const char* tmpPath = "/channels3.tmp";
File file = openWrite(fs, tmpPath);
if (!file) {
@@ -488,6 +718,7 @@ void DataStore::saveChannels(DataStoreHost* host) {
bool success = (file.write(unused, 4) == 4);
success = success && (file.write((uint8_t *)ch.name, 32) == 32);
success = success && (file.write((uint8_t *)ch.channel.secret, 32) == 32);
success = success && (file.write((uint8_t *)ch.scope_name, 31) == 31);
if (!success) {
writeOk = false;
@@ -500,7 +731,7 @@ void DataStore::saveChannels(DataStoreHost* host) {
file.close();
// Reopen read-only to get true on-disk size (SPIFFS file.size() is unreliable before close)
size_t expectedBytes = channel_idx * 68; // 4 + 32 + 32 = 68 bytes per channel
size_t expectedBytes = channel_idx * 99; // 4 + 32 + 32 + 31 = 99 bytes per channel
File verify = openRead(fs, tmpPath);
size_t bytesWritten = verify ? verify.size() : 0;
if (verify) verify.close();
@@ -545,7 +776,7 @@ void DataStore::checkAdvBlobFile() {
}
void DataStore::migrateToSecondaryFS() {
// migrate old adv_blobs, contacts3 and channels2 files to secondary FS if they don't already exist
// migrate old adv_blobs, contacts3 and channels3/channels2 files to secondary FS if they don't already exist
if (!_fsExtra->exists("/adv_blobs")) {
if (_fs->exists("/adv_blobs")) {
File oldAdvBlobs = openRead(_fs, "/adv_blobs");
@@ -584,10 +815,14 @@ void DataStore::migrateToSecondaryFS() {
_fs->remove("/contacts3");
}
}
if (!_fsExtra->exists("/channels2")) {
if (_fs->exists("/channels2")) {
File oldFile = openRead(_fs, "/channels2");
File newFile = openWrite(_fsExtra, "/channels2");
if (!_fsExtra->exists("/channels3") && !_fsExtra->exists("/channels2")) {
// Migrate channels3 (preferred) or channels2 (legacy) to secondary FS
const char* srcName = _fs->exists("/channels3") ? "/channels3"
: _fs->exists("/channels2") ? "/channels2"
: nullptr;
if (srcName) {
File oldFile = openRead(_fs, srcName);
File newFile = openWrite(_fsExtra, srcName);
if (oldFile && newFile) {
uint8_t buf[64];
@@ -598,7 +833,7 @@ void DataStore::migrateToSecondaryFS() {
}
if (oldFile) oldFile.close();
if (newFile) newFile.close();
_fs->remove("/channels2");
_fs->remove(srcName);
}
}
// cleanup nodes which have been testing the extra fs, copy _main.id and new_prefs back to primary
@@ -641,6 +876,9 @@ void DataStore::migrateToSecondaryFS() {
if (_fs->exists("/contacts3")) {
_fs->remove("/contacts3");
}
if (_fs->exists("/channels3")) {
_fs->remove("/channels3");
}
if (_fs->exists("/channels2")) {
_fs->remove("/channels2");
}
+17 -1
View File
@@ -24,6 +24,14 @@ class DataStore {
void checkAdvBlobFile();
#endif
// Chunked save state
File _saveFile;
DataStoreHost* _saveHost = nullptr;
uint32_t _saveIdx = 0;
uint32_t _saveRecordsWritten = 0;
bool _saveInProgress = false;
bool _saveWriteOk = true;
public:
DataStore(FILESYSTEM& fs, mesh::RTCClock& clock);
DataStore(FILESYSTEM& fs, FILESYSTEM& fsExtra, mesh::RTCClock& clock);
@@ -37,6 +45,14 @@ public:
void savePrefs(const NodePrefs& prefs, double node_lat, double node_lon);
void loadContacts(DataStoreHost* host);
void saveContacts(DataStoreHost* host);
// Chunked save — splits contact write across multiple loop iterations
// to prevent blocking the main loop for 500ms+ on large contact lists.
// Call beginSaveContacts(), then saveContactsChunk() each loop until it
// returns false (done), then finishSaveContacts() to verify and commit.
bool beginSaveContacts(DataStoreHost* host);
bool saveContactsChunk(int batchSize = 20); // returns true if more to write
void finishSaveContacts();
bool isSaveInProgress() const { return _saveInProgress; }
void loadChannels(DataStoreHost* host);
void saveChannels(DataStoreHost* host);
void migrateToSecondaryFS();
@@ -51,4 +67,4 @@ public:
private:
FILESYSTEM* _getContactsChannelsFS() const { if (_fsExtra) return _fsExtra; return _fs;};
};
};
File diff suppressed because it is too large Load Diff
+65 -7
View File
@@ -5,14 +5,14 @@
#include "AbstractUITask.h"
/*------------ Frame Protocol --------------*/
#define FIRMWARE_VER_CODE 8
#define FIRMWARE_VER_CODE 11
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "5 March 2026"
#define FIRMWARE_BUILD_DATE "19 April 2026"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "Meck v0.9.8.1"
#define FIRMWARE_VERSION "Meck v1.7"
#endif
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
@@ -70,6 +70,11 @@
#include <helpers/BaseChatMesh.h>
#include <helpers/TransportKeyStore.h>
// Custom path lock flag — bit 7 of ContactInfo.flags
// When set, onContactPathRecv skips auto-updating this contact's out_path.
// Bits 0-6 remain available (bit 0 = favourite, bits 1-3 = telemetry perms).
#define CONTACT_FLAG_CUSTOM_PATH 0x80
/* -------------------------------------------------------------------------------------- */
#define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
@@ -77,8 +82,9 @@
#define REQ_TYPE_GET_TELEMETRY_DATA 0x03
struct AdvertPath {
uint8_t pubkey_prefix[7];
uint8_t pubkey_prefix[8];
uint8_t path_len;
uint8_t type; // ADV_TYPE_* (Chat/Repeater/Room/Sensor)
char name[32];
uint32_t recv_timestamp;
uint8_t path[MAX_PATH_SIZE];
@@ -119,6 +125,15 @@ public:
int getDiscoveredCount() const { return _discoveredCount; }
const DiscoveredNode& getDiscovered(int idx) const { return _discovered[idx]; }
bool addDiscoveredToContacts(int idx); // promote a discovered node into contacts
// Last Heard — public wrappers for contact add/remove from UI
void scheduleLazyContactSave();
int getContactBlob(const uint8_t key[], int key_len, uint8_t dest_buf[]) {
return getBlobByKey(key, key_len, dest_buf);
}
// Force-add a contact from a raw advert blob, bypassing auto-add settings.
// Used by Last Heard and Discovery when the user explicitly selects a node to add.
bool forceImportContact(const uint8_t* blob, uint8_t len);
// Queue a sent channel message for BLE app sync
void queueSentChannelMessage(uint8_t channel_idx, uint32_t timestamp, const char* sender, const char* text);
@@ -126,22 +141,61 @@ public:
// Send a direct message from the UI (no BLE dependency)
bool uiSendDirectMessage(uint32_t contact_idx, const char* text);
// Send raw binary data to a contact (PAYLOAD_TYPE_RAW_CUSTOM, direct route only)
// Used for dz0ny VE3 voice protocol: voice packets (0x56) and fetch requests (0x72)
bool uiSendRawToContact(uint32_t contact_idx, const uint8_t* data, uint8_t len);
// Voice-over-LoRa: callback for incoming raw voice packets (dz0ny VE3 protocol)
// magic 0x56 = voice data packet, 0x72 = fetch request
typedef void (*VoiceRawHandler)(uint8_t magic, const uint8_t* payload, uint8_t len);
void setVoiceHandler(VoiceRawHandler h) { _voiceHandler = h; }
// Voice-over-LoRa: callback for incoming VE3 envelope in a DM
// Called with sender name and the VE3 text (e.g. "VE3:a:1:3:2")
typedef void (*VoiceEnvelopeHandler)(const char* senderName, const char* ve3Text);
void setVoiceEnvelopeHandler(VoiceEnvelopeHandler h) { _voiceEnvHandler = h; }
// Defer contact saves while voice packets are being received
// (SD writes block SPI bus shared with LoRa radio)
void setDeferSaves(bool defer) { _deferSaves = defer; }
bool isDeferSaves() const { return _deferSaves; }
// Repeater admin - UI-initiated operations
bool uiLoginToRepeater(uint32_t contact_idx, const char* password, uint32_t& est_timeout_ms);
bool uiSendCliCommand(uint32_t contact_idx, const char* command);
bool uiSendTelemetryRequest(uint32_t contact_idx);
int getAdminContactIdx() const { return _admin_contact_idx; }
// Custom path editor — set or clear a manually configured path for a contact
// When locked, automatic path discovery will not overwrite this contact's path.
bool setCustomPath(int contactIdx, const uint8_t* path, uint8_t pathLen, bool lock);
void clearCustomPath(int contactIdx);
// Region scope helpers (public — used by SettingsScreen)
// Derive a TransportKey from a region scope name (e.g. "au-nsw" → "#au-nsw" → SHA256 → key).
// Returns true if name is non-empty and key was derived; false if name is empty (unscoped).
bool deriveScopeKey(const char* scopeName, TransportKey& keyOut);
// Look up per-channel scope name by GroupChannel secret match. Returns nullptr if no scope set.
const char* getChannelScopeName(const mesh::GroupChannel& channel);
protected:
float getAirtimeBudgetFactor() const override;
int getInterferenceThreshold() const override;
uint8_t getTxFailResetThreshold() const override;
uint8_t getRxFailRebootThreshold() const override;
void onRxUnrecoverable() override;
int calcRxDelay(float score, uint32_t air_time) const override;
uint32_t getRetransmitDelay(const mesh::Packet *packet) override;
uint32_t getDirectRetransmitDelay(const mesh::Packet *packet) override;
uint8_t getExtraAckTransmitCount() const override;
uint8_t getAutoAddMaxHops() const override;
bool filterRecvFloodPacket(mesh::Packet* packet) override;
uint8_t getPathHashSize() const override { return _prefs.path_hash_mode + 1; }
void sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis=0) override;
void sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis=0) override;
void sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint32_t delay_millis=0);
void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override;
bool isAutoAddEnabled() const override;
@@ -200,7 +254,7 @@ private:
void writeOKFrame();
void writeErrFrame(uint8_t err_code);
void writeDisabledFrame();
void writeContactRespFrame(uint8_t code, const ContactInfo &contact);
size_t writeContactRespFrame(uint8_t code, const ContactInfo &contact);
void updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len);
void addToOfflineQueue(const uint8_t frame[], int len);
int getFromOfflineQueue(uint8_t frame[]);
@@ -216,6 +270,10 @@ private:
DataStore* _store;
NodePrefs _prefs;
VoiceRawHandler _voiceHandler = nullptr;
VoiceEnvelopeHandler _voiceEnvHandler = nullptr;
mutable bool _forceNextImport = false;
bool _deferSaves = false;
uint32_t pending_login;
uint32_t pending_status;
uint32_t pending_telemetry, pending_discovery; // pending _TELEMETRY_REQ
@@ -259,8 +317,8 @@ private:
AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table
int next_ack_idx;
#define ADVERT_PATH_TABLE_SIZE 16
AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
#define ADVERT_PATH_TABLE_SIZE 1000
AdvertPath* advert_paths; // PSRAM-allocated in begin(), size = ADVERT_PATH_TABLE_SIZE
// Sent message repeat tracking
#define SENT_TRACK_SIZE 4
+60
View File
@@ -31,4 +31,64 @@ struct NodePrefs { // persisted to file
int8_t utc_offset_hours; // UTC offset in hours (-12 to +14), default 0
uint8_t kb_flash_notify; // Keyboard backlight flash on new message (0=off, 1=on)
uint8_t ringtone_enabled; // Ringtone on incoming call (0=off, 1=on) — 4G only
uint8_t path_hash_mode; // 0=1-byte (legacy), 1=2-byte, 2=3-byte path hashes
uint8_t autoadd_max_hops; // 0=no limit, N=up to N-1 hops (max 64)
uint32_t gps_baudrate; // GPS baud rate (0 = use compile-time GPS_BAUDRATE default)
uint8_t interference_threshold; // Interference threshold in dB (0=disabled, 14+=enabled)
uint8_t dark_mode; // 0=off (white bg), 1=on (black bg)
uint8_t portrait_mode; // 0=landscape, 1=portrait — T5S3 only
uint8_t auto_lock_minutes; // 0=disabled, 2/5/10/15/30=auto-lock after idle
uint8_t hint_shown; // 0=show nav hint on boot, 1=already shown (dismiss permanently)
uint8_t large_font; // 0=tiny (built-in 6x8), 1=larger (FreeSans9pt) — T-Deck Pro only
uint8_t ui_font_style; // 0=Classic (FreeSans), 1=Noto Sans, 2=Montserrat
uint8_t tx_fail_reset_threshold; // 0=disabled, 1-10, default 3
uint8_t rx_fail_reboot_threshold; // 0=disabled, 1-10, default 3
// --- Region scope (MeshCore v1.15+ compatibility) ---
// Device-wide default region for flood messages.
// Empty default_scope_name = unscoped (legacy flood, reaches all repeaters).
// When set, all flood sends use ROUTE_TYPE_TRANSPORT_FLOOD with transport
// codes derived from this key. Per-channel scope (in ChannelDetails) takes
// priority when set.
char default_scope_name[31]; // e.g. "au-nsw", empty = unscoped
uint8_t default_scope_key[16]; // TransportKey derived from "#" + name
// --- Font helpers (inline, no overhead) ---
// Returns the DisplayDriver text-size index for "small/body" text.
// T-Deck Pro: 0 = built-in 6×8 (or 7pt with custom fonts), 1 = 9pt.
// T5S3: both 0 and 1 are 12pt fonts (regular vs bold) with identical line
// height, so large_font has no layout effect there.
inline uint8_t smallTextSize() const {
return large_font ? 1 : 0;
}
// Returns the virtual-coordinate line height matching smallTextSize().
// T-Deck Pro size 0 → 9 (6×8 + 1px gap), size 1 → 11 (9pt ascent+descent).
// With custom fonts (Noto 7pt, Montserrat 7pt), size 0 is slightly taller
// than built-in 6×8 but fits within the 9-unit virtual grid.
// T5S3 size 0/1 → same 12pt height → always 9 in virtual coords.
inline int smallLineH() const {
#if defined(LilyGo_T5S3_EPaper_Pro)
return 9;
#else
return large_font ? 11 : 9;
#endif
}
// Returns the Y offset for selection highlight fillRect (T-Deck Pro only).
// Size 0 (built-in font): cursor positions at top-left, +5 offset in
// setCursor places text below → fillRect at y+5 aligns with text.
// Size 0 (custom 7pt fonts): baseline fonts, same behaviour as size 1.
// Size 1 (9pt): cursor positions at baseline, ascenders render
// upward → fillRect must start above baseline to cover ascenders.
// T5S3: always 0 (both sizes use baseline fonts with highlight at y).
inline int smallHighlightOff() const {
#if defined(LilyGo_T5S3_EPaper_Pro)
return 0;
#else
// Custom 7pt fonts at textSize 0 use GFXfont (baseline rendering), not built-in
if (ui_font_style > 0 && !large_font) return -2;
return large_font ? -2 : 5;
#endif
}
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -43,6 +43,8 @@
// JPEG decoder for cover art — JPEGDEC by bitbank2
#include <JPEGDEC.h>
#include "../NodePrefs.h"
// Forward declarations
class UITask;
@@ -151,6 +153,7 @@ public:
private:
UITask* _task;
NodePrefs* _prefs;
Audio* _audio;
Mode _mode;
bool _sdReady;
@@ -1193,10 +1196,10 @@ private:
}
// Switch to tiny font for file list (6x8 built-in)
display.setTextSize(0);
display.setTextSize(_prefs ? _prefs->smallTextSize() : 0);
// Calculate visible items — tiny font uses ~8 virtual units per line
int itemHeight = 8;
// Calculate visible items
int itemHeight = (_prefs ? _prefs->smallLineH() : 9) - 1;
int listTop = 13;
int listBottom = display.height() - 14; // Reserve footer space
int visibleItems = (listBottom - listTop) / itemHeight;
@@ -1208,7 +1211,7 @@ private:
_scrollOffset = _selectedFile - visibleItems + 1;
}
// Approx chars that fit in tiny font (~36 on 128 virtual width)
// Approx chars for suffix/type tag sizing (still needed for type tag assembly)
const int charsPerLine = 36;
// Draw file list
@@ -1218,9 +1221,7 @@ private:
if (fileIdx == _selectedFile) {
display.setColor(DisplayDriver::LIGHT);
// setCursor adds +5 to y internally, but fillRect does not.
// Offset fillRect by +5 to align highlight bar with text.
display.fillRect(0, y + 5, display.width(), itemHeight - 1);
display.fillRect(0, y + (_prefs ? _prefs->smallHighlightOff() : 5), display.width(), itemHeight - 1);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -1231,29 +1232,15 @@ private:
char fullLine[96];
if (fe.isDir) {
// Directory entry: show as "/ FolderName" or just ".."
if (fe.name == "..") {
snprintf(fullLine, sizeof(fullLine), ".. (up)");
} else {
snprintf(fullLine, sizeof(fullLine), "/%s", fe.name.c_str());
// Truncate if needed
if ((int)strlen(fullLine) > charsPerLine - 1) {
fullLine[charsPerLine - 4] = '.';
fullLine[charsPerLine - 3] = '.';
fullLine[charsPerLine - 2] = '.';
fullLine[charsPerLine - 1] = '\0';
}
}
} else {
// Audio file: "Title - Author [TYPE]"
char lineBuf[80];
// Reserve space for type tag and bookmark indicator
int suffixLen = fe.fileType.length() + 3; // " [M4B]" or " [MP3]"
int bmkLen = fe.hasBookmark ? 2 : 0; // " >"
int availChars = charsPerLine - suffixLen - bmkLen;
if (availChars < 10) availChars = 10;
if (fe.displayAuthor.length() > 0) {
snprintf(lineBuf, sizeof(lineBuf), "%s - %s",
fe.displayTitle.c_str(), fe.displayAuthor.c_str());
@@ -1261,24 +1248,13 @@ private:
snprintf(lineBuf, sizeof(lineBuf), "%s", fe.displayTitle.c_str());
}
// Truncate with ellipsis if needed
if ((int)strlen(lineBuf) > availChars) {
if (availChars > 3) {
lineBuf[availChars - 3] = '.';
lineBuf[availChars - 2] = '.';
lineBuf[availChars - 1] = '.';
lineBuf[availChars] = '\0';
} else {
lineBuf[availChars] = '\0';
}
}
// Append file type tag
snprintf(fullLine, sizeof(fullLine), "%s [%s]", lineBuf, fe.fileType.c_str());
}
display.setCursor(2, y);
display.print(fullLine);
// Pixel-aware ellipsis — reserve space for bookmark indicator
int reserveRight = (!fe.isDir && fe.hasBookmark) ? 10 : 2;
display.drawTextEllipsized(2, y, display.width() - reserveRight, fullLine);
// Bookmark indicator (right-aligned, files only)
if (!fe.isDir && fe.hasBookmark) {
@@ -1464,8 +1440,8 @@ private:
}
public:
AudiobookPlayerScreen(UITask* task, Audio* audio)
: _task(task), _audio(audio), _mode(FILE_LIST),
AudiobookPlayerScreen(UITask* task, Audio* audio, NodePrefs* prefs = nullptr)
: _task(task), _prefs(prefs), _audio(audio), _mode(FILE_LIST),
_sdReady(false), _i2sInitialized(false), _dacPowered(false),
_displayRef(nullptr),
_selectedFile(0), _scrollOffset(0),
@@ -0,0 +1,122 @@
#pragma once
// =============================================================================
// CardKBKeyboard — M5Stack CardKB (or compatible) I2C keyboard driver
//
// Polls 0x5F on the shared I2C bus via QWIIC connector.
// Maps CardKB special key codes to Meck key constants.
//
// Usage:
// CardKBKeyboard cardkb;
// if (cardkb.begin()) { /* detected */ }
// char key = cardkb.readKey(); // returns 0 if no key
// =============================================================================
#if defined(LilyGo_T5S3_EPaper_Pro) && defined(MECK_CARDKB)
#ifndef CARDKB_KEYBOARD_H
#define CARDKB_KEYBOARD_H
#include <Arduino.h>
#include <Wire.h>
#include "variant.h" // For I2C_SDA, I2C_SCL (bus recovery)
// I2C address (defined in variant.h, fallback here)
#ifndef CARDKB_I2C_ADDR
#define CARDKB_I2C_ADDR 0x5F
#endif
// CardKB special key codes (from M5Stack documentation)
#define CARDKB_KEY_UP 0xB5
#define CARDKB_KEY_DOWN 0xB6
#define CARDKB_KEY_LEFT 0xB4
#define CARDKB_KEY_RIGHT 0xB7
#define CARDKB_KEY_TAB 0x09
#define CARDKB_KEY_ESC 0x1B
#define CARDKB_KEY_BS 0x08
#define CARDKB_KEY_ENTER 0x0D
#define CARDKB_KEY_DEL 0x7F
#define CARDKB_KEY_FN 0x00 // Fn modifier (swallowed by CardKB internally)
class CardKBKeyboard {
public:
CardKBKeyboard() : _detected(false) {}
// Probe for CardKB on the I2C bus. Call after Wire.begin().
bool begin() {
Wire.beginTransmission(CARDKB_I2C_ADDR);
_detected = (Wire.endTransmission() == 0);
if (_detected) {
Serial.println("[CardKB] Detected at 0x5F");
}
return _detected;
}
// Re-probe (e.g. for hot-plug detection every few seconds)
bool probe() {
Wire.beginTransmission(CARDKB_I2C_ADDR);
_detected = (Wire.endTransmission() == 0);
return _detected;
}
bool isDetected() const { return _detected; }
// Poll for a keypress. Returns 0 if no key available.
// Returns raw ASCII for printable chars, or Meck KEY_* constants for nav keys.
// Throttled to avoid flooding I2C bus — polls at most every 50ms.
// On read failure, backs off 500ms and re-inits Wire to recover bus state.
char readKey() {
if (!_detected) return 0;
unsigned long now = millis();
if (now - _lastPoll < _pollInterval) return 0;
_lastPoll = now;
Wire.requestFrom((uint8_t)CARDKB_I2C_ADDR, (uint8_t)1);
if (!Wire.available()) {
_errorCount++;
if (_errorCount >= 3) {
// I2C bus may be stuck — re-init to recover
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(100000);
_pollInterval = 500; // Back off for 500ms
_errorCount = 0;
Serial.println("[CardKB] I2C error recovery — bus re-init");
}
return 0;
}
_errorCount = 0;
_pollInterval = 50; // Normal polling rate
uint8_t raw = Wire.read();
if (raw == 0) return 0;
// Map CardKB special keys to Meck constants
switch (raw) {
case CARDKB_KEY_UP: return 0xF2; // KEY_PREV
case CARDKB_KEY_DOWN: return 0xF1; // KEY_NEXT
case CARDKB_KEY_LEFT: return 0xF3; // KEY_LEFT
case CARDKB_KEY_RIGHT: return 0xF4; // KEY_RIGHT
case CARDKB_KEY_ENTER: return '\r';
case CARDKB_KEY_BS: return '\b';
case CARDKB_KEY_DEL: return '\b'; // Treat delete same as backspace
case CARDKB_KEY_ESC: return 0x1B; // ESC — handled by caller
case CARDKB_KEY_TAB: return 0x09; // Tab — available for future use
default:
// Printable ASCII — pass through unchanged
if (raw >= 0x20 && raw <= 0x7E) {
return (char)raw;
}
// Unknown code — ignore
return 0;
}
}
private:
bool _detected;
unsigned long _lastPoll = 0;
unsigned long _pollInterval = 50; // ms between polls (increases on error)
uint8_t _errorCount = 0;
};
#endif // CARDKB_KEYBOARD_H
#endif // LilyGo_T5S3_EPaper_Pro && MECK_CARDKB
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,436 @@
#pragma once
#include <helpers/ui/UIScreen.h>
#include <helpers/ui/DisplayDriver.h>
#include <helpers/ChannelDetails.h>
#include <MeshCore.h>
#include "ChannelScreen.h"
#ifndef MAX_GROUP_CHANNELS
#define MAX_GROUP_CHANNELS 20
#endif
class UITask; // Forward declaration
class MyMesh; // Forward declaration
extern MyMesh the_mesh;
// ---------------------------------------------------------------------------
// ChannelPickerScreen
// ---------------------------------------------------------------------------
// A directory-style screen that lists every group channel + the DM inbox,
// each with an unread-message badge. Selecting an entry jumps to the channel
// messages screen pre-targeted at that channel.
//
// Replaces the A/D channel-cycling model in ChannelScreen. Pressing A or D
// (or swiping left/right on T5S3) from the messages screen now opens the
// picker instead of paging one channel at a time.
//
// Rendering:
// T5S3 E-Paper Pro : vertical list of outlined "bubble" rows (full-width,
// name left-aligned, unread badge right-aligned).
// Matches the P4 channel picker aesthetic. 1-tap opens.
// T-Deck Pro / MAX : vertical list with "> " cursor, unread badge, right-
// aligned. Same highlight/tap convention as Contacts.
//
// Navigation signals use a wantsExit() flag (same pattern as PathEditor) —
// UITask is only forward-declared, so the picker cannot call UITask methods
// directly. main.cpp / UITask.cpp check the flag after injectKey().
// ---------------------------------------------------------------------------
class ChannelPickerScreen : public UIScreen {
UITask* _task;
ChannelScreen* _channelScreen;
// Ordered list of items.
// Index 0 is always the DM inbox (channel_idx == 0xFF).
// Remaining entries are populated group channels in ascending slot order.
uint8_t _items[MAX_GROUP_CHANNELS + 1];
int _itemCount;
int _cursor;
int _scrollTop; // Scroll offset (T-Deck Pro list only)
// Grid layout cache (T5S3) — set in render(), consumed by touch hit test
int _cellW;
int _cellH;
int _gridTop;
int _gridCols;
// Rebuild the items list from MyMesh. O(20), safe every render.
void rebuildItems() {
int n = 0;
uint8_t tmp[MAX_GROUP_CHANNELS + 1];
tmp[n++] = 0xFF; // DM inbox always first
for (uint8_t i = 0; i < MAX_GROUP_CHANNELS; i++) {
ChannelDetails ch;
if (the_mesh.getChannel(i, ch) && ch.name[0] != '\0') {
if (n < MAX_GROUP_CHANNELS + 1) tmp[n++] = i;
}
}
memcpy(_items, tmp, n);
_itemCount = n;
if (_cursor >= _itemCount) _cursor = _itemCount - 1;
if (_cursor < 0) _cursor = 0;
}
void getItemName(int idx, char* buf, size_t bufLen) const {
if (idx < 0 || idx >= _itemCount || bufLen == 0) { if (bufLen) buf[0] = '\0'; return; }
uint8_t c = _items[idx];
if (c == 0xFF) {
strncpy(buf, "Direct Messages", bufLen - 1);
buf[bufLen - 1] = '\0';
return;
}
ChannelDetails ch;
if (the_mesh.getChannel(c, ch) && ch.name[0] != '\0') {
strncpy(buf, ch.name, bufLen - 1);
buf[bufLen - 1] = '\0';
} else {
snprintf(buf, bufLen, "Ch %d", (int)c);
}
}
int getItemUnread(int idx) const {
if (idx < 0 || idx >= _itemCount || !_channelScreen) return 0;
return _channelScreen->getUnreadForChannel(_items[idx]);
}
public:
ChannelPickerScreen(UITask* task)
: _task(task), _channelScreen(nullptr),
_itemCount(0), _cursor(0), _scrollTop(0),
_cellW(40), _cellH(12), _gridTop(14), _gridCols(3),
_wantExit(false) {
_items[0] = 0xFF;
}
void setChannelScreen(ChannelScreen* cs) { _channelScreen = cs; }
// --- wantsExit flag — checked by main.cpp / UITask after injectKey() ---
bool _wantExit;
bool wantsExit() const { return _wantExit; }
// Called by UITask::gotoChannelPickerScreen().
void enter(uint8_t currentChannelIdx) {
rebuildItems();
_cursor = 0;
for (int i = 0; i < _itemCount; i++) {
if (_items[i] == currentChannelIdx) { _cursor = i; break; }
}
_scrollTop = 0;
_wantExit = false;
}
uint8_t getSelectedChannel() const {
if (_cursor >= 0 && _cursor < _itemCount) return _items[_cursor];
return 0xFF;
}
// -----------------------------------------------------------------------
// Render
// -----------------------------------------------------------------------
int render(DisplayDriver& display) override {
rebuildItems();
// === Header ===
display.setCursor(0, 0);
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.print("Channels");
int totalUnread = 0;
for (int i = 0; i < _itemCount; i++) totalUnread += getItemUnread(i);
char tmp[24];
if (totalUnread > 0) {
snprintf(tmp, sizeof(tmp), "*%d", totalUnread);
} else {
snprintf(tmp, sizeof(tmp), "[%d]", _itemCount);
}
display.setCursor(display.width() - display.getTextWidth(tmp) - 2, 0);
display.print(tmp);
display.drawRect(0, 11, display.width(), 1);
#if defined(LilyGo_T5S3_EPaper_Pro)
// =================================================================
// T5S3: Vertical bubble list (matches P4 channel picker aesthetic)
// Full-width outlined bubbles with channel name left-aligned and
// unread badge right-aligned. 1-tap opens the channel.
// =================================================================
const int headerH = 14;
const int footerH = 14;
const int bodyH = display.height() - headerH - footerH;
const int bubbleH = 11; // Bubble height in virtual coords
const int gap = 2; // Gap between bubbles
const int padX = 3; // Horizontal padding from screen edge
const int bubbleW = display.width() - 2 * padX;
int maxVisible = bodyH / (bubbleH + gap);
if (maxVisible < 3) maxVisible = 3;
if (maxVisible > _itemCount) maxVisible = _itemCount;
// Cache layout for touch hit test
_cellW = bubbleW;
_cellH = bubbleH + gap;
_gridTop = headerH;
_gridCols = 1; // Single column — list mode
// Centre scroll window on cursor
_scrollTop = max(0, min(_cursor - maxVisible / 2, _itemCount - maxVisible));
if (_scrollTop < 0) _scrollTop = 0;
int endIdx = min(_itemCount, _scrollTop + maxVisible);
for (int i = _scrollTop; i < endIdx; i++) {
int row = i - _scrollTop;
int x = padX;
int y = headerH + row * (bubbleH + gap) + 1;
int w = bubbleW;
int h = bubbleH;
bool selected = (i == _cursor);
int unread = getItemUnread(i);
// Bubble: filled if selected, outlined otherwise
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(x, y, w, h);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
display.drawRect(x, y, w, h);
// Draw a second outline 1px inset for a bolder border
display.drawRect(x + 1, y + 1, w - 2, h - 2);
}
// Channel name — left-aligned with inner padding
char name[32];
getItemName(i, name, sizeof(name));
char filtered[32];
display.translateUTF8ToBlocks(filtered, name, sizeof(filtered));
int textY = y + (h - 9) / 2;
if (textY < y + 1) textY = y + 1;
int textX = x + 4;
// Badge width reservation
int badgeW = 0;
char badge[8];
if (unread > 0) {
if (unread > 99) snprintf(badge, sizeof(badge), "99+");
else snprintf(badge, sizeof(badge), "*%d", unread);
badgeW = display.getTextWidth(badge) + 4;
}
int nameMaxW = w - 8 - badgeW;
if (nameMaxW < 8) nameMaxW = 8;
int nameW = display.getTextWidth(filtered);
if (nameW <= nameMaxW) {
display.setCursor(textX, textY);
display.print(filtered);
} else {
display.drawTextEllipsized(textX, textY, nameMaxW, filtered);
}
// Unread badge — right-aligned inside bubble
if (unread > 0) {
int bx = x + w - badgeW;
display.setCursor(bx, textY);
display.print(badge);
}
display.setColor(DisplayDriver::LIGHT);
}
// Scroll indicator (if more items than visible)
if (_itemCount > maxVisible) {
const int sbW = 3;
int sbX = display.width() - sbW;
int sbTop = headerH;
int sbHeight = bodyH;
display.setColor(DisplayDriver::LIGHT);
display.drawRect(sbX, sbTop, sbW, sbHeight);
int thumbH = (maxVisible * sbHeight) / _itemCount;
if (thumbH < 4) thumbH = 4;
int maxScroll = _itemCount - maxVisible;
if (maxScroll < 1) maxScroll = 1;
int thumbY = sbTop + (_scrollTop * (sbHeight - thumbH)) / maxScroll;
display.fillRect(sbX + 1, thumbY + 1, sbW - 2, thumbH - 2);
}
#else
// =================================================================
// T-Deck Pro / MAX: Vertical list
// Uses NodePrefs font helpers for large_font compatibility.
// =================================================================
NodePrefs* prefs = the_mesh.getNodePrefs();
int lineH = prefs->smallLineH();
const int headerH = 14;
const int footerH = 14;
int maxY = display.height() - footerH;
int y = headerH;
int maxVisible = (maxY - headerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
// Centre scroll window on cursor
_scrollTop = max(0, min(_cursor - maxVisible / 2, _itemCount - maxVisible));
if (_scrollTop < 0) _scrollTop = 0;
int endIdx = min(_itemCount, _scrollTop + maxVisible);
display.setTextSize(prefs->smallTextSize());
for (int i = _scrollTop; i < endIdx && y + lineH <= maxY; i++) {
bool selected = (i == _cursor);
int unread = getItemUnread(i);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + prefs->smallHighlightOff(), display.width(), lineH);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(0, y);
// Prefix: "> " for selected, " " otherwise. "*N" badge if unread.
char prefix[8];
if (unread > 0) {
snprintf(prefix, sizeof(prefix), "%s*%d ", selected ? ">" : " ", unread);
} else {
snprintf(prefix, sizeof(prefix), "%s ", selected ? ">" : " ");
}
display.print(prefix);
// Name
char name[32];
getItemName(i, name, sizeof(name));
char filtered[32];
display.translateUTF8ToBlocks(filtered, name, sizeof(filtered));
int nameX = display.getTextWidth(prefix) + 2;
int nameMaxW = display.width() - nameX - 2;
display.drawTextEllipsized(nameX, y, nameMaxW, filtered);
y += lineH;
}
// Scroll indicator
if (_itemCount > maxVisible) {
const int sbW = 3;
int sbX = display.width() - sbW;
int sbTop = headerH;
int sbHeight = maxY - headerH;
display.setColor(DisplayDriver::LIGHT);
display.drawRect(sbX, sbTop, sbW, sbHeight);
int thumbH = (maxVisible * sbHeight) / _itemCount;
if (thumbH < 4) thumbH = 4;
int maxScroll = _itemCount - maxVisible;
if (maxScroll < 1) maxScroll = 1;
int thumbY = sbTop + (_scrollTop * (sbHeight - thumbH)) / maxScroll;
display.fillRect(sbX + 1, thumbY + 1, sbW - 2, thumbH - 2);
}
#endif
// === Footer ===
display.setTextSize(1);
int footerY = display.height() - 12;
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap:Open");
const char* rt = "Boot:Back";
display.setCursor(display.width() - display.getTextWidth(rt) - 2, footerY);
display.print(rt);
#else
display.print("W/S:Nav Q:Back");
const char* rt = "Ent:Open";
display.setCursor(display.width() - display.getTextWidth(rt) - 2, footerY);
display.print(rt);
#endif
#ifdef USE_EINK
return 5000;
#else
return 1000;
#endif
}
// -----------------------------------------------------------------------
// Input
// -----------------------------------------------------------------------
bool handleInput(char c) override {
// W / UP
if (c == 'w' || c == 'W' || c == 0xF2 || c == KEY_UP) {
if (_cursor > 0) { _cursor--; return true; }
return false;
}
// S / DOWN
if (c == 's' || c == 'S' || c == 0xF1 || c == KEY_DOWN) {
if (_cursor < _itemCount - 1) { _cursor++; return true; }
return false;
}
// A / D — consumed (no channel cycling from picker)
if (c == 'a' || c == 'A' || c == KEY_LEFT) {
return true;
}
if (c == 'd' || c == 'D' || c == KEY_RIGHT) {
return true;
}
// Enter — select the highlighted channel and signal exit
if (c == '\r' || c == 13 || c == KEY_ENTER || c == KEY_SELECT) {
if (_channelScreen && _cursor >= 0 && _cursor < _itemCount) {
_channelScreen->setViewChannelIdx(_items[_cursor]);
}
_wantExit = true;
return true; // Consumed — caller checks wantsExit() and navigates
}
// Q / backspace — cancel without changing channel, signal exit
if (c == 'q' || c == 'Q' || c == '\b' || c == KEY_CANCEL) {
_wantExit = true;
return true;
}
return false;
}
// -----------------------------------------------------------------------
// Touch hit test (virtual coordinates)
// Returns: 0=miss, 1=cursor moved, 2=activate.
// T5S3 bubbles: any tap on a bubble → 2 (direct open).
// T-Deck Pro list: 1st tap → 1 (highlight), 2nd tap same row → 2.
// -----------------------------------------------------------------------
int selectAtVxVy(int vx, int vy) {
#if defined(LilyGo_T5S3_EPaper_Pro)
// Vertical bubble list hit test
if (vy < _gridTop || _cellH == 0) return 0;
int footerY = 128 - 14;
if (vy >= footerY) return 0;
int row = (vy - _gridTop) / _cellH;
int idx = _scrollTop + row;
if (idx < 0 || idx >= _itemCount) return 0;
_cursor = idx;
return 2; // Direct open on tap
#else
// T-Deck Pro / MAX list hit test — uses NodePrefs for large_font compatibility
NodePrefs* prefs = the_mesh.getNodePrefs();
int lineH = prefs->smallLineH();
const int headerH = 14;
const int footerH = 14;
int bodyTop = headerH + prefs->smallHighlightOff();
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_cursor - maxVisible / 2, _itemCount - maxVisible));
if (startIdx < 0) startIdx = 0;
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= _itemCount) return 0;
if (tappedRow == _cursor) return 2;
_cursor = tappedRow;
return 1;
#endif
}
};
+239 -46
View File
@@ -4,7 +4,11 @@
#include <helpers/ui/DisplayDriver.h>
#include <MeshCore.h>
// Forward declarations
// Timestamps before this (Jan 1 2026 UTC) are treated as invalid/unsynced
#define EPOCH_2026 1735689600UL
// Forward declarations — MyMesh.h (which defines AdvertPath) is always
// included by the translation unit before this header.
class UITask;
class MyMesh;
extern MyMesh the_mesh;
@@ -33,13 +37,22 @@ private:
// We rebuild this on filter change or when entering the screen
// Arrays allocated in PSRAM when available (supports 1000+ contacts)
uint16_t* _filteredIdx; // indices into contact table
uint32_t* _filteredTs; // cached last_advert_timestamp for sorting
uint32_t* _filteredTs; // cached lastmod for sorting
int _filteredCount; // how many contacts match current filter
AdvertPath _hopBuf[40]; // recently heard advert paths for hop-count display
int _hopBufCount;
bool _cacheValid;
// How many rows fit on screen (computed during render)
int _rowsPerPage;
// Pointer to per-contact DM unread array (owned by UITask, set via setter)
const uint8_t* _dmUnread = nullptr;
// --- Select mode state ---
bool _selectMode;
uint8_t* _selectedBits; // Bitfield: 1 bit per MAX_CONTACTS raw index
// --- helpers ---
static const char* filterLabel(FilterMode f) {
@@ -54,12 +67,12 @@ private:
}
}
static char typeChar(uint8_t adv_type) {
static const char* typeStr(uint8_t adv_type) {
switch (adv_type) {
case ADV_TYPE_CHAT: return 'C';
case ADV_TYPE_REPEATER: return 'R';
case ADV_TYPE_ROOM: return 'S'; // Server
default: return '?';
case ADV_TYPE_CHAT: return "C";
case ADV_TYPE_REPEATER: return "R";
case ADV_TYPE_ROOM: return "RS";
default: return "?";
}
}
@@ -85,12 +98,13 @@ private:
if (the_mesh.getContactByIdx(i, contact)) {
if (matchesFilter(contact.type, contact.flags)) {
_filteredIdx[_filteredCount] = (uint16_t)i;
_filteredTs[_filteredCount] = contact.last_advert_timestamp;
// Use lastmod (our receive time) for sort/age; pre-2026 or zero → 0 sinks to bottom
_filteredTs[_filteredCount] = (contact.lastmod >= EPOCH_2026) ? contact.lastmod : 0;
_filteredCount++;
}
}
}
// Sort by last_advert_timestamp descending (most recently seen first)
// Sort by lastmod descending (most recently heard first; pre-2026/unsynced sink to bottom)
// Insertion sort — fine for up to ~1000 entries on ESP32
for (int i = 1; i < _filteredCount; i++) {
uint16_t tmpIdx = _filteredIdx[i];
@@ -105,46 +119,64 @@ private:
_filteredTs[j + 1] = tmpTs;
}
_cacheValid = true;
// Refresh hop-count cache from the 12 most recently heard adverts
_hopBufCount = the_mesh.getRecentlyHeard(_hopBuf, 40);
// Clamp scroll position
if (_scrollPos >= _filteredCount) {
_scrollPos = (_filteredCount > 0) ? _filteredCount - 1 : 0;
}
}
// Format seconds-ago as compact string: "3s" "5m" "2h" "4d" "??"
// Format seconds-ago as compact string: "3s" "5m" "2h" "4d" "--"
static void formatAge(char* buf, size_t bufLen, uint32_t now, uint32_t timestamp) {
if (timestamp == 0) {
if (timestamp == 0 || timestamp < EPOCH_2026 || now < timestamp) {
strncpy(buf, "--", bufLen);
return;
}
int secs = (int)(now - timestamp);
if (secs < 0) secs = 0;
uint32_t secs = now - timestamp;
if (secs < 60) {
snprintf(buf, bufLen, "%ds", secs);
snprintf(buf, bufLen, "%ds", (int)secs);
} else if (secs < 3600) {
snprintf(buf, bufLen, "%dm", secs / 60);
snprintf(buf, bufLen, "%dm", (int)(secs / 60));
} else if (secs < 86400) {
snprintf(buf, bufLen, "%dh", secs / 3600);
snprintf(buf, bufLen, "%dh", (int)(secs / 3600));
} else {
snprintf(buf, bufLen, "%dd", secs / 86400);
snprintf(buf, bufLen, "%dd", (int)(secs / 86400));
}
}
// --- Bitfield helpers ---
bool isSelectedRaw(int rawIdx) const {
if (rawIdx < 0 || rawIdx >= MAX_CONTACTS) return false;
return (_selectedBits[rawIdx / 8] & (1 << (rawIdx % 8))) != 0;
}
void setSelectedRaw(int rawIdx, bool sel) {
if (rawIdx < 0 || rawIdx >= MAX_CONTACTS) return;
if (sel) _selectedBits[rawIdx / 8] |= (1 << (rawIdx % 8));
else _selectedBits[rawIdx / 8] &= ~(1 << (rawIdx % 8));
}
public:
ContactsScreen(UITask* task, mesh::RTCClock* rtc)
: _task(task), _rtc(rtc), _scrollPos(0), _filter(FILTER_ALL),
_filteredCount(0), _cacheValid(false), _rowsPerPage(5) {
_filteredCount(0), _cacheValid(false), _rowsPerPage(5),
_selectMode(false), _hopBufCount(0) {
#if defined(ESP32) && defined(BOARD_HAS_PSRAM)
_filteredIdx = (uint16_t*)ps_calloc(MAX_CONTACTS, sizeof(uint16_t));
_filteredTs = (uint32_t*)ps_calloc(MAX_CONTACTS, sizeof(uint32_t));
_selectedBits = (uint8_t*)ps_calloc((MAX_CONTACTS + 7) / 8, 1);
#else
_filteredIdx = new uint16_t[MAX_CONTACTS]();
_filteredTs = new uint32_t[MAX_CONTACTS]();
_selectedBits = new uint8_t[(MAX_CONTACTS + 7) / 8]();
#endif
}
void invalidateCache() { _cacheValid = false; }
// Set pointer to per-contact DM unread array (called by UITask after allocation)
void setDMUnreadPtr(const uint8_t* ptr) { _dmUnread = ptr; }
void resetScroll() {
_scrollPos = 0;
_cacheValid = false;
@@ -152,6 +184,83 @@ public:
FilterMode getFilter() const { return _filter; }
// --- Select mode API ---
bool isInSelectMode() const { return _selectMode; }
void enterSelectMode() {
_selectMode = true;
memset(_selectedBits, 0, (MAX_CONTACTS + 7) / 8);
// Pre-select the currently highlighted contact
if (_filteredCount > 0 && _scrollPos < _filteredCount) {
setSelectedRaw(_filteredIdx[_scrollPos], true);
}
}
void exitSelectMode() {
_selectMode = false;
memset(_selectedBits, 0, (MAX_CONTACTS + 7) / 8);
}
void toggleSelected() {
if (_filteredCount == 0 || _scrollPos >= _filteredCount) return;
int rawIdx = _filteredIdx[_scrollPos];
setSelectedRaw(rawIdx, !isSelectedRaw(rawIdx));
}
void selectAll() {
for (int i = 0; i < _filteredCount; i++) {
setSelectedRaw(_filteredIdx[i], true);
}
}
void deselectAll() {
memset(_selectedBits, 0, (MAX_CONTACTS + 7) / 8);
}
int getSelectedCount() const {
int count = 0;
for (int i = 0; i < _filteredCount; i++) {
if (isSelectedRaw(_filteredIdx[i])) count++;
}
return count;
}
// Fill outBuf with raw contact table indices of selected contacts
int getSelectedRawIndices(uint16_t* outBuf, int maxOut) const {
int count = 0;
for (int i = 0; i < _filteredCount && count < maxOut; i++) {
if (isSelectedRaw(_filteredIdx[i])) {
outBuf[count++] = _filteredIdx[i];
}
}
return count;
}
// Tap-to-select: given virtual Y, select contact row.
// Returns: 0=miss, 1=moved, 2=tapped current row.
int selectRowAtVY(int vy) {
if (_filteredCount == 0) return 0;
const int headerH = 14, footerH = 14, lineH = the_mesh.getNodePrefs()->smallLineH();
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = headerH;
#else
const int bodyTop = headerH + the_mesh.getNodePrefs()->smallHighlightOff();
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_scrollPos - maxVisible / 2,
_filteredCount - maxVisible));
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= _filteredCount) return 0;
if (tappedRow == _scrollPos) return 2;
_scrollPos = tappedRow;
return 1;
}
// Get the raw contact table index for the currently highlighted item
// Returns -1 if no valid selection
int getSelectedContactIdx() const {
@@ -188,7 +297,12 @@ public:
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
snprintf(tmp, sizeof(tmp), "Contacts [%s]", filterLabel(_filter));
if (_selectMode) {
int selCount = getSelectedCount();
snprintf(tmp, sizeof(tmp), "%d Selected [%s]", selCount, filterLabel(_filter));
} else {
snprintf(tmp, sizeof(tmp), "Contacts [%s]", filterLabel(_filter));
}
display.print(tmp);
// Count on right: All → total/max, filtered → matched/total
@@ -204,8 +318,8 @@ public:
display.drawRect(0, 11, display.width(), 1);
// === Body - contact rows ===
display.setTextSize(0); // tiny font for compact rows
int lineHeight = 9; // 8px font + 1px gap
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize()); // tiny font for compact rows
int lineHeight = the_mesh.getNodePrefs()->smallLineH(); // 8px font + 1px gap
int headerHeight = 14;
int footerHeight = 14;
int maxY = display.height() - footerHeight;
@@ -219,7 +333,11 @@ public:
display.setCursor(0, y);
display.print("No contacts");
display.setCursor(0, y + lineHeight);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe to change filter");
#else
display.print("A/D: Change filter");
#endif
} else {
// Center visible window around selected item (TextReaderScreen pattern)
int maxVisible = (maxY - headerHeight) / lineHeight;
@@ -233,11 +351,16 @@ public:
if (!the_mesh.getContactByIdx(_filteredIdx[i], contact)) continue;
bool selected = (i == _scrollPos);
bool sel = _selectMode && isSelectedRaw(_filteredIdx[i]);
// Highlight: fill LIGHT rect first, then draw DARK text on top
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width(), lineHeight);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineHeight);
#else
display.fillRect(0, y + the_mesh.getNodePrefs()->smallHighlightOff(), display.width(), lineHeight);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -246,12 +369,16 @@ public:
// Set cursor AFTER fillRect so text draws on top of highlight
display.setCursor(0, y);
// Prefix: "> " for selected, type char + space for others
char prefix[4];
if (selected) {
snprintf(prefix, sizeof(prefix), ">%c", typeChar(contact.type));
// Prefix: select mode uses * for selected, normal uses > for cursor
char prefix[5];
if (_selectMode) {
snprintf(prefix, sizeof(prefix), "%c%s",
sel ? '*' : (selected ? '>' : ' '),
typeStr(contact.type));
} else if (selected) {
snprintf(prefix, sizeof(prefix), ">%s", typeStr(contact.type));
} else {
snprintf(prefix, sizeof(prefix), " %c", typeChar(contact.type));
snprintf(prefix, sizeof(prefix), " %s", typeStr(contact.type));
}
display.print(prefix);
@@ -261,18 +388,47 @@ public:
// Reserve space for hops + age on right side
char hopStr[6];
if (contact.out_path_len == 0xFF || contact.out_path_len == 0) {
strcpy(hopStr, "D"); // direct
if (contact.out_path_len == 0xFF) {
// No confirmed direct path — look up flood hop estimate from recent advert cache
hopStr[0] = '?'; hopStr[1] = '\0'; // default
for (int h = 0; h < _hopBufCount; h++) {
if (memcmp(contact.id.pub_key, _hopBuf[h].pubkey_prefix, 7) == 0) {
uint8_t bph = (_hopBuf[h].path_len >> 6) + 1;
uint8_t hops = _hopBuf[h].path_len & 0x3F;
uint8_t max_hops = 64 / bph; // sanity cap based on path encoding
if (hops <= max_hops) {
if (hops == 0)
strcpy(hopStr, "~D");
else
snprintf(hopStr, sizeof(hopStr), "~%d", (int)hops);
}
break;
}
}
} else if (contact.out_path_len == 0) {
bool customDirect = (contact.flags & CONTACT_FLAG_CUSTOM_PATH) != 0;
strcpy(hopStr, customDirect ? "D*" : "D");
} else {
snprintf(hopStr, sizeof(hopStr), "%d", contact.out_path_len);
int hops = contact.out_path_len & 0x3F; // lower 6 bits = hop count
bool customPath = (contact.flags & CONTACT_FLAG_CUSTOM_PATH) != 0;
if (customPath) {
snprintf(hopStr, sizeof(hopStr), "%d*", hops); // asterisk = custom/locked path
} else {
snprintf(hopStr, sizeof(hopStr), "%d", hops);
}
}
char ageStr[6];
formatAge(ageStr, sizeof(ageStr), now, contact.last_advert_timestamp);
formatAge(ageStr, sizeof(ageStr), now, contact.lastmod);
// Build right-side string: "hops age"
char rightStr[14];
snprintf(rightStr, sizeof(rightStr), "%sh %s", hopStr, ageStr);
// Build right-side string: "*N hops age" if unread, else "hops age"
int dmCount = (_dmUnread && _filteredIdx[i] < MAX_CONTACTS) ? _dmUnread[_filteredIdx[i]] : 0;
char rightStr[20];
if (dmCount > 0) {
snprintf(rightStr, sizeof(rightStr), "*%d %sh %s", dmCount, hopStr, ageStr);
} else {
snprintf(rightStr, sizeof(rightStr), "%sh %s", hopStr, ageStr);
}
int rightWidth = display.getTextWidth(rightStr) + 2;
// Name region: after prefix + small gap, before right info
@@ -297,19 +453,33 @@ public:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
// Left: Q:Bk
#if defined(LilyGo_T5S3_EPaper_Pro)
display.setCursor(0, footerY);
display.print("Q:Bk");
// Center: A/D:Filter
const char* mid = "A/D:Filtr";
display.setCursor((display.width() - display.getTextWidth(mid)) / 2, footerY);
display.print(mid);
// Right: F:Dscvr
const char* right = "F:Dscvr";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
if (_selectMode) {
display.print("Swipe:All/Clr");
const char* right = "Tap:Tog Hold:Exit";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
} else {
display.print("Swipe:Filter");
const char* right = "Hold:DM/Admin";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
#else
display.setCursor(0, footerY);
if (_selectMode) {
display.print("A:All D:Clr");
const char* right = "X:Exp F:Fav Q:Done";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
} else {
display.print("Q:Bk A/D:Filter");
const char* right = "P:Path Ent:Sel";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
#endif
return 5000; // e-ink: next render after 5s
}
@@ -331,6 +501,29 @@ public:
}
}
// --- Select mode key handling ---
if (_selectMode) {
// Enter/tap: toggle selection on current contact
if (c == 13 || c == KEY_ENTER) {
toggleSelected();
return true;
}
// A: select all in current filter
if (c == 'a' || c == 'A') {
selectAll();
return true;
}
// D: deselect all
if (c == 'd' || c == 'D') {
deselectAll();
return true;
}
// Q, X, F, Backspace — handled by main.cpp (needs mesh/SD access)
return false;
}
// --- Normal mode key handling ---
// A - previous filter
if (c == 'a' || c == 'A') {
_filter = (FilterMode)(((int)_filter + FILTER_COUNT - 1) % FILTER_COUNT);
@@ -44,6 +44,32 @@ public:
int getSelectedIdx() const { return _scrollPos; }
// Tap-to-select: given virtual Y, select discovered node row.
// Returns: 0=miss, 1=moved, 2=tapped current row.
int selectRowAtVY(int vy) {
int count = the_mesh.getDiscoveredCount();
if (count == 0) return 0;
const int headerH = 14, footerH = 14, lineH = the_mesh.getNodePrefs()->smallLineH();
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = headerH;
#else
const int bodyTop = headerH + the_mesh.getNodePrefs()->smallHighlightOff();
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_scrollPos - maxVisible / 2,
count - maxVisible));
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= count) return 0;
if (tappedRow == _scrollPos) return 2;
_scrollPos = tappedRow;
return 1;
}
int render(DisplayDriver& display) override {
int count = the_mesh.getDiscoveredCount();
bool active = the_mesh.isDiscoveryActive();
@@ -65,8 +91,8 @@ public:
display.drawRect(0, 11, display.width(), 1);
// === Body — discovered node rows ===
display.setTextSize(0); // tiny font for compact rows
int lineHeight = 9;
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize()); // tiny font for compact rows
int lineHeight = the_mesh.getNodePrefs()->smallLineH();
int headerHeight = 14;
int footerHeight = 14;
int maxY = display.height() - footerHeight;
@@ -79,7 +105,11 @@ public:
display.print(active ? "Listening for adverts..." : "No nodes found");
if (!active) {
display.setCursor(4, 38);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Long press: Rescan");
#else
display.print("F: Scan again Q: Back");
#endif
}
} else {
// Center visible window around selected item
@@ -96,7 +126,11 @@ public:
// Highlight selected row
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width(), lineHeight);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineHeight);
#else
display.fillRect(0, y + the_mesh.getNodePrefs()->smallHighlightOff(), display.width(), lineHeight);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -126,9 +160,9 @@ public:
} else {
// Pre-seeded from cache — show hop count
if (node.already_in_contacts) {
snprintf(rightStr, sizeof(rightStr), "%dh [+]", node.path_len);
snprintf(rightStr, sizeof(rightStr), "%dh [+]", node.path_len & 63);
} else {
snprintf(rightStr, sizeof(rightStr), "%dh", node.path_len);
snprintf(rightStr, sizeof(rightStr), "%dh", node.path_len & 63);
}
}
int rightWidth = display.getTextWidth(rightStr) + 2;
@@ -158,15 +192,23 @@ public:
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
display.print("Q:Back");
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe:Scroll");
const char* mid = "Ent:Add";
const char* mid = "Tap:Add";
display.setCursor((display.width() - display.getTextWidth(mid)) / 2, footerY);
display.print(mid);
const char* right = "F:Rescan";
const char* right = "Hold:Rescan";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#else
display.print("Q:Bk F:Rescan");
const char* right = "Tap/Ent:Add";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#endif
// Faster refresh while actively scanning
return active ? 1000 : 5000;
+195 -76
View File
@@ -3,7 +3,7 @@
// Emoji sprites for e-ink display - dual size
// Large (12x12) for compose/picker, Small (10x10) for channel view
// MSB-first, 2 bytes per row
// 65 total emoji: joy/thumbsup/frown first, then 43 original, then 19 new
// 76 total emoji: joy/thumbsup/frown first, then 43 original, then 19 new, then 11 newest
#include <stdint.h>
#ifdef ESP32
@@ -15,11 +15,11 @@
#define EMOJI_SM_W 10
#define EMOJI_SM_H 10
#define EMOJI_COUNT 65
#define EMOJI_COUNT 76
// Escape codes in 0x80+ range - safe from keyboard ASCII (32-126)
#define EMOJI_ESCAPE_START 0x80
#define EMOJI_ESCAPE_END 0xC0 // 0x80 + 64
#define EMOJI_ESCAPE_END 0xCB // 0x80 + 75
#define EMOJI_PAD_BYTE 0x7F // DEL, not typeable (key < 127 guard)
// ======== LARGE 12x12 SPRITES ========
@@ -36,6 +36,14 @@ static const uint8_t emoji_lg_thumbsup[] PROGMEM = {
static const uint8_t emoji_lg_frown[] PROGMEM = {
0x1F,0x80, 0x20,0x40, 0x59,0xA0, 0x59,0xA0, 0x80,0x10, 0x9F,0x90, 0xA0,0x50, 0x40,0x20, 0x20,0x40, 0x1F,0x80, 0x00,0x00, 0x00,0x00,
};
// [65] loudly_crying 😭
static const uint8_t emoji_lg_loudly_crying[] PROGMEM = {
0x1F,0x80, 0x20,0x40, 0x5B,0x40, 0x5B,0x20, 0x80,0x10, 0x9F,0x10, 0xA0,0x90, 0x60,0xC0, 0xA0,0xA0, 0x1F,0x00, 0x40,0x40, 0x00,0x00,
};
// [66] heart ♥️
static const uint8_t emoji_lg_heart[] PROGMEM = {
0x00,0x00, 0x73,0x80, 0xFF,0xC0, 0xFF,0xC0, 0xFF,0xC0, 0x7F,0x80, 0x3F,0x00, 0x1E,0x00, 0x0C,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
};
// [3] wireless
static const uint8_t emoji_lg_wireless[] PROGMEM = {
0x00,0x00, 0x3F,0xC0, 0x60,0x60, 0xC0,0x30, 0x0F,0x00, 0x19,0x80, 0x30,0xC0, 0x00,0x00, 0x06,0x00, 0x0F,0x00, 0x06,0x00, 0x00,0x00,
@@ -284,23 +292,68 @@ static const uint8_t emoji_lg_tipping[] PROGMEM = {
static const uint8_t emoji_lg_hedgehog[] PROGMEM = {
0x00,0x00, 0x0A,0x80, 0x15,0x40, 0x2A,0xA0, 0x55,0x60, 0x7E,0xF0, 0xDB,0x90, 0xFF,0xD0, 0x7F,0xE0, 0x3F,0xC0, 0x24,0x80, 0x00,0x00,
};
// [67] diamond_suit ♦️
static const uint8_t emoji_lg_diamond_suit[] PROGMEM = {
0x00,0x00, 0x04,0x00, 0x0E,0x00, 0x1F,0x00, 0x3F,0x80, 0x7F,0xC0, 0x3F,0x80, 0x1F,0x00, 0x0E,0x00, 0x04,0x00, 0x00,0x00, 0x00,0x00,
};
// [68] spade_suit ♠️
static const uint8_t emoji_lg_spade_suit[] PROGMEM = {
0x04,0x00, 0x0E,0x00, 0x1F,0x00, 0x3F,0x80, 0x7F,0xC0, 0xFF,0xE0, 0xFF,0xE0, 0x7F,0xC0, 0x15,0x00, 0x04,0x00, 0x0E,0x00, 0x00,0x00,
};
// [69] pizza 🍕
static const uint8_t emoji_lg_pizza[] PROGMEM = {
0x02,0x00, 0x06,0x00, 0x0F,0x00, 0x0B,0x00, 0x1F,0x80, 0x1D,0x80, 0x3F,0xC0, 0x2F,0x40, 0x7F,0xE0, 0x7F,0xE0, 0xFF,0xF0, 0x00,0x00,
};
// [70] four_leaf_clover 🍀
static const uint8_t emoji_lg_four_leaf_clover[] PROGMEM = {
0x0C,0x00, 0x1E,0x00, 0x1E,0x00, 0x6D,0x80, 0xF3,0xC0, 0xF3,0xC0, 0x6D,0x80, 0x1E,0x00, 0x1E,0x00, 0x0C,0x00, 0x06,0x00, 0x00,0x00,
};
// [71] cloud ☁️
static const uint8_t emoji_lg_cloud[] PROGMEM = {
0x00,0x00, 0x1C,0x00, 0x3E,0x00, 0x7F,0x80, 0xFF,0xC0, 0xFF,0xE0, 0xFF,0xE0, 0x7F,0xC0, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
};
// [72] rocket 🚀
static const uint8_t emoji_lg_rocket[] PROGMEM = {
0x04,0x00, 0x0E,0x00, 0x1F,0x00, 0x1B,0x00, 0x1B,0x00, 0x3F,0x80, 0x7F,0xC0, 0x5F,0x40, 0x9F,0x20, 0x0E,0x00, 0x15,0x00, 0x00,0x00,
};
// [73] passport_control 🛂
static const uint8_t emoji_lg_passport_control[] PROGMEM = {
0x3F,0xC0, 0x40,0x20, 0x46,0x20, 0x4F,0x20, 0x46,0x20, 0x40,0x20, 0x44,0x20, 0x4E,0x20, 0x5F,0x20, 0x40,0x20, 0x3F,0xC0, 0x00,0x00,
};
// [74] eight_spoked_asterisk ✳️
static const uint8_t emoji_lg_eight_spoked_asterisk[] PROGMEM = {
0x7F,0xE0, 0x84,0x10, 0xA4,0x90, 0x95,0x10, 0x8E,0x10, 0xFF,0xD0, 0x8E,0x10, 0x95,0x10, 0xA4,0x90, 0x84,0x10, 0x7F,0xE0, 0x00,0x00,
};
// [75] signal_strength 📶
static const uint8_t emoji_lg_signal_strength[] PROGMEM = {
0x00,0x20, 0x00,0x20, 0x00,0xA0, 0x00,0xA0, 0x02,0xA0, 0x02,0xA0, 0x0A,0xA0, 0x0A,0xA0, 0x2A,0xA0, 0x2A,0xA0, 0xAA,0xA0, 0xAA,0xA0,
};
static const uint8_t* const EMOJI_SPRITES_LG[] PROGMEM = {
emoji_lg_joy, emoji_lg_thumbsup, emoji_lg_frown,
// Faces/emotion first
emoji_lg_joy, emoji_lg_frown, emoji_lg_loudly_crying,
emoji_lg_grimace, emoji_lg_zany_face, emoji_lg_cowboy,
// Thumbsup + heart
emoji_lg_thumbsup, emoji_lg_heart,
// Everything else in original relative order
emoji_lg_wireless, emoji_lg_infinity, emoji_lg_trex, emoji_lg_skull, emoji_lg_cross,
emoji_lg_lightning, emoji_lg_tophat, emoji_lg_motorcycle, emoji_lg_seedling, emoji_lg_flag_au,
emoji_lg_umbrella, emoji_lg_nazar, emoji_lg_globe, emoji_lg_radioactive, emoji_lg_cow,
emoji_lg_alien, emoji_lg_invader, emoji_lg_dagger, emoji_lg_grimace,
emoji_lg_alien, emoji_lg_invader, emoji_lg_dagger,
emoji_lg_mountain, emoji_lg_end_arrow, emoji_lg_hollow_circle, emoji_lg_dragon, emoji_lg_globe_meridians,
emoji_lg_eggplant, emoji_lg_shield, emoji_lg_goggles, emoji_lg_lizard, emoji_lg_zany_face,
emoji_lg_eggplant, emoji_lg_shield, emoji_lg_goggles, emoji_lg_lizard,
emoji_lg_kangaroo, emoji_lg_feather, emoji_lg_bright, emoji_lg_part_alt, emoji_lg_motorboat,
emoji_lg_domino, emoji_lg_satellite, emoji_lg_customs, emoji_lg_cowboy, emoji_lg_wheel,
emoji_lg_domino, emoji_lg_satellite, emoji_lg_customs, emoji_lg_wheel,
emoji_lg_koala, emoji_lg_control_knobs, emoji_lg_peach, emoji_lg_racing_car,
emoji_lg_mouse, emoji_lg_mushroom, emoji_lg_biohazard, emoji_lg_panda,
emoji_lg_anger, emoji_lg_dragon_face, emoji_lg_pager, emoji_lg_bee,
emoji_lg_bulb, emoji_lg_cat, emoji_lg_fleur, emoji_lg_moon,
emoji_lg_coffee, emoji_lg_tooth, emoji_lg_pretzel, emoji_lg_abacus,
emoji_lg_moai, emoji_lg_tipping, emoji_lg_hedgehog,
emoji_lg_diamond_suit, emoji_lg_spade_suit, emoji_lg_pizza, emoji_lg_four_leaf_clover,
emoji_lg_cloud, emoji_lg_rocket, emoji_lg_passport_control,
emoji_lg_eight_spoked_asterisk, emoji_lg_signal_strength,
};
// ======== SMALL 10x10 SPRITES ========
@@ -519,94 +572,160 @@ static const uint8_t emoji_sm_tipping[] PROGMEM = {
static const uint8_t emoji_sm_hedgehog[] PROGMEM = {
0x15,0x00, 0x2A,0x80, 0x55,0x40, 0xFF,0xC0, 0xDB,0x40, 0xFF,0x80, 0x7F,0x80, 0x3F,0x00, 0x24,0x00, 0x00,0x00,
};
// [65] loudly_crying 😭
static const uint8_t emoji_sm_loudly_crying[] PROGMEM = {
0x3E,0x00, 0x41,0x00, 0xB6,0x80, 0x80,0x40, 0xBE,0x40, 0x81,0x40, 0x63,0x00, 0x9C,0x80, 0x00,0x00, 0x00,0x00,
};
// [66] heart ♥️
static const uint8_t emoji_sm_heart[] PROGMEM = {
0x00,0x00, 0x6C,0x00, 0xFE,0x00, 0xFE,0x00, 0x7C,0x00, 0x38,0x00, 0x10,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
};
// [67] diamond_suit ♦️
static const uint8_t emoji_sm_diamond_suit[] PROGMEM = {
0x00,0x00, 0x08,0x00, 0x1C,0x00, 0x3E,0x00, 0x7F,0x00, 0x3E,0x00, 0x1C,0x00, 0x08,0x00, 0x00,0x00, 0x00,0x00,
};
// [68] spade_suit ♠️
static const uint8_t emoji_sm_spade_suit[] PROGMEM = {
0x08,0x00, 0x1C,0x00, 0x3E,0x00, 0x7F,0x00, 0xFF,0x80, 0xFF,0x80, 0x2A,0x00, 0x08,0x00, 0x1C,0x00, 0x00,0x00,
};
// [69] pizza 🍕
static const uint8_t emoji_sm_pizza[] PROGMEM = {
0x08,0x00, 0x1C,0x00, 0x14,0x00, 0x3E,0x00, 0x36,0x00, 0x6D,0x00, 0x7F,0x00, 0xFF,0x80, 0xFF,0x80, 0x00,0x00,
};
// [70] four_leaf_clover 🍀
static const uint8_t emoji_sm_four_leaf_clover[] PROGMEM = {
0x18,0x00, 0x3C,0x00, 0xDB,0x00, 0xE7,0x00, 0xE7,0x00, 0xDB,0x00, 0x3C,0x00, 0x18,0x00, 0x0C,0x00, 0x00,0x00,
};
// [71] cloud ☁️
static const uint8_t emoji_sm_cloud[] PROGMEM = {
0x00,0x00, 0x38,0x00, 0x7E,0x00, 0xFF,0x00, 0xFF,0x80, 0xFF,0x80, 0x7F,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,
};
// [72] rocket 🚀
static const uint8_t emoji_sm_rocket[] PROGMEM = {
0x08,0x00, 0x1C,0x00, 0x36,0x00, 0x36,0x00, 0x7F,0x00, 0xBE,0x80, 0x3E,0x00, 0x1C,0x00, 0x2A,0x00, 0x00,0x00,
};
// [73] passport_control 🛂
static const uint8_t emoji_sm_passport_control[] PROGMEM = {
0x7F,0x80, 0x80,0x40, 0x8C,0x40, 0x9E,0x40, 0x8C,0x40, 0x80,0x40, 0x9C,0x40, 0xBE,0x40, 0x80,0x40, 0x7F,0x80,
};
// [74] eight_spoked_asterisk ✳️
static const uint8_t emoji_sm_eight_spoked_asterisk[] PROGMEM = {
0x7F,0x80, 0x84,0x40, 0xA5,0x40, 0x9E,0x40, 0xFF,0xC0, 0x9E,0x40, 0xA5,0x40, 0x84,0x40, 0x7F,0x80, 0x00,0x00,
};
// [75] signal_strength 📶
static const uint8_t emoji_sm_signal_strength[] PROGMEM = {
0x00,0x80, 0x00,0x80, 0x02,0x80, 0x02,0x80, 0x0A,0x80, 0x0A,0x80, 0x2A,0x80, 0x2A,0x80, 0xAA,0x80, 0xAA,0x80,
};
static const uint8_t* const EMOJI_SPRITES_SM[] PROGMEM = {
emoji_sm_joy, emoji_sm_thumbsup, emoji_sm_frown,
// Faces/emotion first
emoji_sm_joy, emoji_sm_frown, emoji_sm_loudly_crying,
emoji_sm_grimace, emoji_sm_zany_face, emoji_sm_cowboy,
// Thumbsup + heart
emoji_sm_thumbsup, emoji_sm_heart,
// Everything else in original relative order
emoji_sm_wireless, emoji_sm_infinity, emoji_sm_trex, emoji_sm_skull, emoji_sm_cross,
emoji_sm_lightning, emoji_sm_tophat, emoji_sm_motorcycle, emoji_sm_seedling, emoji_sm_flag_au,
emoji_sm_umbrella, emoji_sm_nazar, emoji_sm_globe, emoji_sm_radioactive, emoji_sm_cow,
emoji_sm_alien, emoji_sm_invader, emoji_sm_dagger, emoji_sm_grimace,
emoji_sm_alien, emoji_sm_invader, emoji_sm_dagger,
emoji_sm_mountain, emoji_sm_end_arrow, emoji_sm_hollow_circle, emoji_sm_dragon, emoji_sm_globe_meridians,
emoji_sm_eggplant, emoji_sm_shield, emoji_sm_goggles, emoji_sm_lizard, emoji_sm_zany_face,
emoji_sm_eggplant, emoji_sm_shield, emoji_sm_goggles, emoji_sm_lizard,
emoji_sm_kangaroo, emoji_sm_feather, emoji_sm_bright, emoji_sm_part_alt, emoji_sm_motorboat,
emoji_sm_domino, emoji_sm_satellite, emoji_sm_customs, emoji_sm_cowboy, emoji_sm_wheel,
emoji_sm_domino, emoji_sm_satellite, emoji_sm_customs, emoji_sm_wheel,
emoji_sm_koala, emoji_sm_control_knobs, emoji_sm_peach, emoji_sm_racing_car,
emoji_sm_mouse, emoji_sm_mushroom, emoji_sm_biohazard, emoji_sm_panda,
emoji_sm_anger, emoji_sm_dragon_face, emoji_sm_pager, emoji_sm_bee,
emoji_sm_bulb, emoji_sm_cat, emoji_sm_fleur, emoji_sm_moon,
emoji_sm_coffee, emoji_sm_tooth, emoji_sm_pretzel, emoji_sm_abacus,
emoji_sm_moai, emoji_sm_tipping, emoji_sm_hedgehog,
emoji_sm_diamond_suit, emoji_sm_spade_suit, emoji_sm_pizza, emoji_sm_four_leaf_clover,
emoji_sm_cloud, emoji_sm_rocket, emoji_sm_passport_control,
emoji_sm_eight_spoked_asterisk, emoji_sm_signal_strength,
};
// ---- Codepoint lookup for UTF-8 conversion ----
struct EmojiCodepoint { uint32_t cp; uint32_t cp2; uint8_t escape; };
static const EmojiCodepoint EMOJI_CODEPOINTS[EMOJI_COUNT] = {
// Faces/emotion first
{ 0x1F602, 0x0000, 0x80 }, // joy
{ 0x1F44D, 0x0000, 0x81 }, // thumbsup
{ 0x2639, 0x0000, 0x82 }, // frown
{ 0x1F6DC, 0x0000, 0x83 }, // wireless
{ 0x267E, 0x0000, 0x84 }, // infinity
{ 0x1F996, 0x0000, 0x85 }, // trex
{ 0x2620, 0x0000, 0x86 }, // skull
{ 0x271D, 0x0000, 0x87 }, // cross
{ 0x26A1, 0x0000, 0x88 }, // lightning
{ 0x1F3A9, 0x0000, 0x89 }, // tophat
{ 0x1F3CD, 0x0000, 0x8A }, // motorcycle
{ 0x1F331, 0x0000, 0x8B }, // seedling
{ 0x1F1E6, 0x1F1FA, 0x8C }, // flag_au
{ 0x2602, 0x0000, 0x8D }, // umbrella
{ 0x1F9FF, 0x0000, 0x8E }, // nazar
{ 0x1F30F, 0x0000, 0x8F }, // globe
{ 0x2622, 0x0000, 0x90 }, // radioactive
{ 0x1F404, 0x0000, 0x91 }, // cow
{ 0x1F47D, 0x0000, 0x92 }, // alien
{ 0x1F47E, 0x0000, 0x93 }, // invader
{ 0x1F5E1, 0x0000, 0x94 }, // dagger
{ 0x1F62C, 0x0000, 0x95 }, // grimace
{ 0x26F0, 0x0000, 0x96 }, // mountain
{ 0x1F51A, 0x0000, 0x97 }, // end_arrow
{ 0x2B55, 0x0000, 0x98 }, // hollow_circle
{ 0x1F409, 0x0000, 0x99 }, // dragon
{ 0x1F310, 0x0000, 0x9A }, // globe_meridians
{ 0x1F346, 0x0000, 0x9B }, // eggplant
{ 0x1F6E1, 0x0000, 0x9C }, // shield
{ 0x1F97D, 0x0000, 0x9D }, // goggles
{ 0x1F98E, 0x0000, 0x9E }, // lizard
{ 0x1F92A, 0x0000, 0x9F }, // zany_face
{ 0x1F998, 0x0000, 0xA0 }, // kangaroo
{ 0x1FAB6, 0x0000, 0xA1 }, // feather
{ 0x1F506, 0x0000, 0xA2 }, // bright
{ 0x303D, 0x0000, 0xA3 }, // part_alt
{ 0x1F6E5, 0x0000, 0xA4 }, // motorboat
{ 0x1F030, 0x0000, 0xA5 }, // domino
{ 0x1F4E1, 0x0000, 0xA6 }, // satellite
{ 0x1F6C3, 0x0000, 0xA7 }, // customs
{ 0x1F920, 0x0000, 0xA8 }, // cowboy
{ 0x1F6DE, 0x0000, 0xA9 }, // wheel
{ 0x1F428, 0x0000, 0xAA }, // koala
{ 0x1F39B, 0x0000, 0xAB }, // control_knobs
{ 0x1F351, 0x0000, 0xAC }, // peach
{ 0x1F3CE, 0x0000, 0xAD }, // racing_car
{ 0x1F42D, 0x0000, 0xAE }, // mouse
{ 0x1F344, 0x0000, 0xAF }, // mushroom
{ 0x2623, 0x0000, 0xB0 }, // biohazard
{ 0x1F43C, 0x0000, 0xB1 }, // panda
{ 0x1F4A2, 0x0000, 0xB2 }, // anger
{ 0x1F432, 0x0000, 0xB3 }, // dragon_face
{ 0x1F4DF, 0x0000, 0xB4 }, // pager
{ 0x1F41D, 0x0000, 0xB5 }, // bee
{ 0x1F4A1, 0x0000, 0xB6 }, // bulb
{ 0x1F431, 0x0000, 0xB7 }, // cat
{ 0x269C, 0x0000, 0xB8 }, // fleur
{ 0x1F314, 0x0000, 0xB9 }, // moon
{ 0x2615, 0x0000, 0xBA }, // coffee
{ 0x1F9B7, 0x0000, 0xBB }, // tooth
{ 0x1F968, 0x0000, 0xBC }, // pretzel
{ 0x1F9EE, 0x0000, 0xBD }, // abacus
{ 0x1F5FF, 0x0000, 0xBE }, // moai
{ 0x1F481, 0x0000, 0xBF }, // tipping
{ 0x1F994, 0x0000, 0xC0 }, // hedgehog
{ 0x2639, 0x0000, 0x81 }, // frown
{ 0x1F62D, 0x0000, 0x82 }, // loudly_crying
{ 0x1F62C, 0x0000, 0x83 }, // grimace
{ 0x1F92A, 0x0000, 0x84 }, // zany_face
{ 0x1F920, 0x0000, 0x85 }, // cowboy
// Thumbsup + heart
{ 0x1F44D, 0x0000, 0x86 }, // thumbsup
{ 0x2665, 0x0000, 0x87 }, // heart
// Everything else in original relative order
{ 0x1F6DC, 0x0000, 0x88 }, // wireless
{ 0x267E, 0x0000, 0x89 }, // infinity
{ 0x1F996, 0x0000, 0x8A }, // trex
{ 0x2620, 0x0000, 0x8B }, // skull
{ 0x271D, 0x0000, 0x8C }, // cross
{ 0x26A1, 0x0000, 0x8D }, // lightning
{ 0x1F3A9, 0x0000, 0x8E }, // tophat
{ 0x1F3CD, 0x0000, 0x8F }, // motorcycle
{ 0x1F331, 0x0000, 0x90 }, // seedling
{ 0x1F1E6, 0x1F1FA, 0x91 }, // flag_au
{ 0x2602, 0x0000, 0x92 }, // umbrella
{ 0x1F9FF, 0x0000, 0x93 }, // nazar
{ 0x1F30F, 0x0000, 0x94 }, // globe
{ 0x2622, 0x0000, 0x95 }, // radioactive
{ 0x1F404, 0x0000, 0x96 }, // cow
{ 0x1F47D, 0x0000, 0x97 }, // alien
{ 0x1F47E, 0x0000, 0x98 }, // invader
{ 0x1F5E1, 0x0000, 0x99 }, // dagger
{ 0x26F0, 0x0000, 0x9A }, // mountain
{ 0x1F51A, 0x0000, 0x9B }, // end_arrow
{ 0x2B55, 0x0000, 0x9C }, // hollow_circle
{ 0x1F409, 0x0000, 0x9D }, // dragon
{ 0x1F310, 0x0000, 0x9E }, // globe_meridians
{ 0x1F346, 0x0000, 0x9F }, // eggplant
{ 0x1F6E1, 0x0000, 0xA0 }, // shield
{ 0x1F97D, 0x0000, 0xA1 }, // goggles
{ 0x1F98E, 0x0000, 0xA2 }, // lizard
{ 0x1F998, 0x0000, 0xA3 }, // kangaroo
{ 0x1FAB6, 0x0000, 0xA4 }, // feather
{ 0x1F506, 0x0000, 0xA5 }, // bright
{ 0x303D, 0x0000, 0xA6 }, // part_alt
{ 0x1F6E5, 0x0000, 0xA7 }, // motorboat
{ 0x1F030, 0x0000, 0xA8 }, // domino
{ 0x1F4E1, 0x0000, 0xA9 }, // satellite
{ 0x1F6C3, 0x0000, 0xAA }, // customs
{ 0x1F6DE, 0x0000, 0xAB }, // wheel
{ 0x1F428, 0x0000, 0xAC }, // koala
{ 0x1F39B, 0x0000, 0xAD }, // control_knobs
{ 0x1F351, 0x0000, 0xAE }, // peach
{ 0x1F3CE, 0x0000, 0xAF }, // racing_car
{ 0x1F42D, 0x0000, 0xB0 }, // mouse
{ 0x1F344, 0x0000, 0xB1 }, // mushroom
{ 0x2623, 0x0000, 0xB2 }, // biohazard
{ 0x1F43C, 0x0000, 0xB3 }, // panda
{ 0x1F4A2, 0x0000, 0xB4 }, // anger
{ 0x1F432, 0x0000, 0xB5 }, // dragon_face
{ 0x1F4DF, 0x0000, 0xB6 }, // pager
{ 0x1F41D, 0x0000, 0xB7 }, // bee
{ 0x1F4A1, 0x0000, 0xB8 }, // bulb
{ 0x1F431, 0x0000, 0xB9 }, // cat
{ 0x269C, 0x0000, 0xBA }, // fleur
{ 0x1F314, 0x0000, 0xBB }, // moon
{ 0x2615, 0x0000, 0xBC }, // coffee
{ 0x1F9B7, 0x0000, 0xBD }, // tooth
{ 0x1F968, 0x0000, 0xBE }, // pretzel
{ 0x1F9EE, 0x0000, 0xBF }, // abacus
{ 0x1F5FF, 0x0000, 0xC0 }, // moai
{ 0x1F481, 0x0000, 0xC1 }, // tipping
{ 0x1F994, 0x0000, 0xC2 }, // hedgehog
{ 0x2666, 0x0000, 0xC3 }, // diamond_suit
{ 0x2660, 0x0000, 0xC4 }, // spade_suit
{ 0x1F355, 0x0000, 0xC5 }, // pizza
{ 0x1F340, 0x0000, 0xC6 }, // four_leaf_clover
{ 0x2601, 0x0000, 0xC7 }, // cloud
{ 0x1F680, 0x0000, 0xC8 }, // rocket
{ 0x1F6C2, 0x0000, 0xC9 }, // passport_control
{ 0x2733, 0x0000, 0xCA }, // eight_spoked_asterisk
{ 0x1F4F6, 0x0000, 0xCB }, // signal_strength
};
// ---- Helper functions ----
@@ -616,7 +735,7 @@ static const EmojiCodepoint EMOJI_CODEPOINTS[EMOJI_COUNT] = {
struct EmojiAlias { uint32_t cp; uint8_t escape; };
#define EMOJI_ALIAS_COUNT 1
static const EmojiAlias EMOJI_ALIASES[EMOJI_ALIAS_COUNT] = {
{ 0x1F08E, 0xA5 }, // domino tile (MWD node signifier) -> domino sprite
{ 0x1F08E, 0xA8 }, // domino tile (MWD node signifier) -> domino sprite
};
static uint32_t emojiDecodeUtf8(const uint8_t* s, int remaining, int* bytes_consumed) {
@@ -0,0 +1,214 @@
#pragma once
#include <helpers/ui/UIScreen.h>
#include <helpers/ui/DisplayDriver.h>
#include <MeshCore.h>
#include "../NodePrefs.h"
#include "MeckFonts.h"
// Forward declarations
class UITask;
class MyMesh;
extern MyMesh the_mesh;
// ---------------------------------------------------------------------------
// FontPreviewScreen
// ---------------------------------------------------------------------------
// Subscreen opened from Settings → Font Style. Shows a live preview of each
// font style (Classic, Noto Sans, Montserrat) with sample body and title text.
// The user cycles through styles with W/S (or swipe on T5S3), previews the
// actual rendering on-screen, and applies with Enter or cancels with Q.
//
// The preview works by temporarily calling display.setFontStyle() for each
// sample block during render(), then restoring the original style.
// ---------------------------------------------------------------------------
class FontPreviewScreen : public UIScreen {
UITask* _task;
NodePrefs* _prefs;
uint8_t _cursor; // Currently highlighted style (0, 1, 2)
uint8_t _originalStyle; // Style when screen was opened (for cancel)
bool _wantExit;
bool _applied; // True if user pressed Enter (vs Q cancel)
public:
FontPreviewScreen(UITask* task, NodePrefs* prefs)
: _task(task), _prefs(prefs),
_cursor(0), _originalStyle(0),
_wantExit(false), _applied(false) {}
// Called when entering the screen from Settings
void enter() {
_originalStyle = _prefs->ui_font_style;
_cursor = _originalStyle;
_wantExit = false;
_applied = false;
}
bool wantsExit() const { return _wantExit; }
bool wasApplied() const { return _applied; }
// -----------------------------------------------------------------------
// Render
// -----------------------------------------------------------------------
int render(DisplayDriver& display) override {
// === Header ===
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
display.print("Font Style Preview");
display.drawRect(0, 11, display.width(), 1);
// === Size mode indicator ===
{
const char* sizeLabel = _prefs->large_font ? "[LARGER]" : "[TINY]";
display.setCursor(display.width() - display.getTextWidth(sizeLabel) - 2, 0);
display.print(sizeLabel);
}
// === Style preview rows ===
// Each style gets a block showing: style name + sample text rendered in
// that style. The selected style is highlighted.
const int headerH = 14;
const int footerH = 14;
const int bodyH = display.height() - headerH - footerH;
const int rowH = bodyH / MECK_FONT_STYLE_COUNT;
uint8_t savedStyle = display.getFontStyle();
for (int i = 0; i < MECK_FONT_STYLE_COUNT; i++) {
int y = headerH + i * rowH;
bool selected = (i == _cursor);
// Highlight selected row
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y, display.width(), rowH);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
// Style name — rendered in default font (size 1)
display.setFontStyle(MECK_FONT_CLASSIC); // Name label always in Classic
display.setTextSize(1);
display.setCursor(2, y + 1);
const char* name = meckFontStyleName(i);
// Prefix with selection indicator
char label[32];
if (selected) {
snprintf(label, sizeof(label), "> %s", name);
} else {
snprintf(label, sizeof(label), " %s", name);
}
display.print(label);
// Sample text — rendered in the preview style
display.setFontStyle(i);
// Body text sample (textSize = smallTextSize based on current size pref)
display.setTextSize(_prefs->smallTextSize());
int sampleY = y + (rowH / 2) - 2;
display.setCursor(4, sampleY);
display.print("The quick brown fox 0123");
// Title sample (textSize 3) — only if row is tall enough
if (rowH > 22) {
display.setTextSize(3);
int titleY = y + rowH - 6;
display.setCursor(4, titleY);
display.print("Meck");
}
}
// Restore original font style
display.setFontStyle(savedStyle);
// === Footer ===
display.setTextSize(1);
display.setColor(DisplayDriver::YELLOW);
int footerY = display.height() - 12;
display.drawRect(0, footerY - 2, display.width(), 1);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe:Pick");
const char* rt = "Boot:Back Tap:Apply";
#else
display.print("W/S:Pick Q:Back");
const char* rt = "Enter:Apply";
#endif
display.setCursor(display.width() - display.getTextWidth(rt) - 2, footerY);
display.print(rt);
#ifdef USE_EINK
return 5000;
#else
return 1000;
#endif
}
// -----------------------------------------------------------------------
// Input
// -----------------------------------------------------------------------
bool handleInput(char c) override {
// W / UP — previous style
if (c == 'w' || c == 'W' || c == 0xF2 || c == KEY_UP) {
if (_cursor > 0) {
_cursor--;
return true;
}
return false;
}
// S / DOWN — next style
if (c == 's' || c == 'S' || c == 0xF1 || c == KEY_DOWN) {
if (_cursor < MECK_FONT_STYLE_COUNT - 1) {
_cursor++;
return true;
}
return false;
}
// Enter — apply selected style and exit
if (c == '\r' || c == 13 || c == KEY_ENTER || c == KEY_SELECT) {
_prefs->ui_font_style = _cursor;
the_mesh.savePrefs();
_applied = true;
_wantExit = true;
Serial.printf("FontPreview: Applied style = %s (%d)\n",
meckFontStyleName(_cursor), _cursor);
return true;
}
// Q / backspace — cancel, restore original style
if (c == 'q' || c == 'Q' || c == '\b' || c == KEY_CANCEL) {
_prefs->ui_font_style = _originalStyle;
_wantExit = true;
return true;
}
return false;
}
// -----------------------------------------------------------------------
// Touch hit test (virtual coordinates)
// Returns: 0=miss, 1=cursor moved, 2=activate (apply).
// -----------------------------------------------------------------------
int selectAtVxVy(int vx, int vy) {
const int headerH = 14;
const int footerH = 14;
const int bodyH = 128 - headerH - footerH; // virtual 128×128
const int rowH = bodyH / MECK_FONT_STYLE_COUNT;
if (vy < headerH || vy >= 128 - footerH) return 0;
int tapped = (vy - headerH) / rowH;
if (tapped < 0 || tapped >= MECK_FONT_STYLE_COUNT) return 0;
if (tapped == _cursor) return 2; // Tap same row = apply
_cursor = tapped;
return 1; // Moved cursor
}
};
@@ -0,0 +1,242 @@
#pragma once
#include <helpers/ui/UIScreen.h>
#include <helpers/ui/DisplayDriver.h>
#include <helpers/AdvertDataHelpers.h>
#include <MeshCore.h>
extern MyMesh the_mesh;
// ==========================================================================
// Last Heard Screen — passive advert list
// Shows all recently heard nodes from the advert path table, sorted by
// recency. Unlike Discovery (active zero-hop scan), this is purely passive
// — it shows nodes whose adverts have been received over time.
// ==========================================================================
// Display cap — we never need to show all 200 storage entries at once
#define LAST_HEARD_DISPLAY_SIZE 100
class LastHeardScreen : public UIScreen {
mesh::RTCClock* _rtc;
int _scrollPos;
// Local sorted copy of advert paths (PSRAM-allocated, refreshed each render)
AdvertPath* _entries;
int _count;
static char typeChar(uint8_t adv_type) {
switch (adv_type) {
case ADV_TYPE_CHAT: return 'C';
case ADV_TYPE_REPEATER: return 'R';
case ADV_TYPE_ROOM: return 'S';
case ADV_TYPE_SENSOR: return 'N';
default: return '?';
}
}
// Format age as human-readable string (e.g. "2m", "1h", "3d")
static void formatAge(uint32_t now, uint32_t timestamp, char* buf, int bufLen) {
if (timestamp == 0 || now < timestamp) {
snprintf(buf, bufLen, "---");
return;
}
uint32_t age = now - timestamp;
if (age < 60) snprintf(buf, bufLen, "%ds", age);
else if (age < 3600) snprintf(buf, bufLen, "%dm", age / 60);
else if (age < 86400) snprintf(buf, bufLen, "%dh", age / 3600);
else snprintf(buf, bufLen, "%dd", age / 86400);
}
public:
LastHeardScreen(mesh::RTCClock* rtc)
: _rtc(rtc), _scrollPos(0), _count(0) {
_entries = (AdvertPath*)ps_calloc(LAST_HEARD_DISPLAY_SIZE, sizeof(AdvertPath));
}
void resetScroll() { _scrollPos = 0; }
int getSelectedIdx() const { return _scrollPos; }
// Check if selected node is already in contacts
bool isSelectedInContacts() const {
if (_scrollPos < 0 || _scrollPos >= _count) return false;
return the_mesh.lookupContactByPubKey(_entries[_scrollPos].pubkey_prefix, 8) != nullptr;
}
// Get selected entry (for add/delete operations)
const AdvertPath* getSelectedEntry() const {
if (_scrollPos < 0 || _scrollPos >= _count) return nullptr;
return &_entries[_scrollPos];
}
// Tap-to-select: given virtual Y, select row.
// Returns: 0=miss, 1=moved, 2=tapped current row.
int selectRowAtVY(int vy) {
if (_count == 0) return 0;
const int headerH = 14, footerH = 14, lineH = the_mesh.getNodePrefs()->smallLineH();
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = headerH;
#else
const int bodyTop = headerH + the_mesh.getNodePrefs()->smallHighlightOff();
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_scrollPos - maxVisible / 2,
_count - maxVisible));
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= _count) return 0;
if (tappedRow == _scrollPos) return 2;
_scrollPos = tappedRow;
return 1;
}
int render(DisplayDriver& display) override {
// Refresh sorted list from mesh
_count = the_mesh.getRecentlyHeard(_entries, LAST_HEARD_DISPLAY_SIZE);
// Filter out empty entries (recv_timestamp == 0)
int validCount = 0;
for (int i = 0; i < _count; i++) {
if (_entries[i].recv_timestamp > 0) validCount++;
else break; // sorted by recency, so first zero means rest are empty
}
_count = validCount;
if (_scrollPos >= _count) _scrollPos = max(0, _count - 1);
uint32_t now = _rtc->getCurrentTime();
// === Header ===
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
char hdr[32];
snprintf(hdr, sizeof(hdr), "Last Heard: %d nodes", _count);
display.print(hdr);
display.drawRect(0, 11, display.width(), 1);
// === Body — node rows ===
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize());
int lineHeight = the_mesh.getNodePrefs()->smallLineH();
int headerHeight = 14;
int footerHeight = 14;
int maxY = display.height() - footerHeight;
int y = headerHeight;
if (_count == 0) {
display.setColor(DisplayDriver::LIGHT);
display.setCursor(4, 28);
display.print("No adverts received yet");
display.setCursor(4, 38);
display.print("Nodes appear as adverts arrive");
} else {
int maxVisible = (maxY - headerHeight) / lineHeight;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_scrollPos - maxVisible / 2,
_count - maxVisible));
int endIdx = min(_count, startIdx + maxVisible);
for (int i = startIdx; i < endIdx && y + lineHeight <= maxY; i++) {
const AdvertPath& entry = _entries[i];
bool selected = (i == _scrollPos);
// Highlight selected row
if (selected) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineHeight);
#else
display.fillRect(0, y + the_mesh.getNodePrefs()->smallHighlightOff(), display.width(), lineHeight);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(0, y);
// Prefix: cursor + type char
char prefix[4];
snprintf(prefix, sizeof(prefix), "%c%c",
selected ? '>' : ' ', typeChar(entry.type));
display.print(prefix);
// Right side: age + hops + [★] for favourites, [+] for other contacts
char rightStr[20];
char ageBuf[8];
formatAge(now, entry.recv_timestamp, ageBuf, sizeof(ageBuf));
ContactInfo* ci = the_mesh.lookupContactByPubKey(entry.pubkey_prefix, 8);
bool inContacts = (ci != nullptr);
bool isFav = inContacts && (ci->flags & 0x01);
if (isFav) {
snprintf(rightStr, sizeof(rightStr), "%s %dh [*]", ageBuf, entry.path_len & 63);
} else if (inContacts) {
snprintf(rightStr, sizeof(rightStr), "%s %dh [+]", ageBuf, entry.path_len & 63);
} else {
snprintf(rightStr, sizeof(rightStr), "%s %dh", ageBuf, entry.path_len & 63);
}
int rightWidth = display.getTextWidth(rightStr) + 2;
// Name (truncated with ellipsis)
char filteredName[32];
display.translateUTF8ToBlocks(filteredName, entry.name, sizeof(filteredName));
int nameX = display.getTextWidth(prefix) + 2;
int nameMaxW = display.width() - nameX - rightWidth - 2;
display.drawTextEllipsized(nameX, y, nameMaxW, filteredName);
// Right-aligned info
display.setCursor(display.width() - rightWidth, y);
display.print(rightStr);
y += lineHeight;
}
}
display.setTextSize(1);
// === Footer ===
int footerY = display.height() - 12;
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe:Scroll");
const char* right = "Tap:Add/Del";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#else
display.print("Q:Bk");
const char* right = "Tap/Ent:Add/Del";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#endif
return 5000; // refresh every 5s to update ages
}
bool handleInput(char c) override {
// Scroll up
if (c == 'w' || c == 'W' || c == 0xF2) {
if (_scrollPos > 0) { _scrollPos--; return true; }
return false;
}
// Scroll down
if (c == 's' || c == 'S' || c == 0xF1) {
if (_scrollPos < _count - 1) { _scrollPos++; return true; }
return false;
}
// Enter — handled by main.cpp (needs access to private MyMesh methods)
// Q — handled by main.cpp (navigation)
return false;
}
};
+46 -16
View File
@@ -137,22 +137,18 @@ public:
_zoomMin(MAP_MIN_ZOOM),
_zoomMax(MAP_MAX_ZOOM),
_pngBuf(nullptr),
_lineBuf(nullptr),
_tileFound(false)
{
// Allocate marker array in PSRAM at construction (~20KB)
// so addMarker() works before enter() is called
_markers = (MapMarker*)ps_calloc(MAP_MAX_MARKERS, sizeof(MapMarker));
if (_markers) {
Serial.printf("MapScreen: markers allocated (%d × %d = %d bytes PSRAM)\n",
MAP_MAX_MARKERS, (int)sizeof(MapMarker),
MAP_MAX_MARKERS * (int)sizeof(MapMarker));
} else {
Serial.println("MapScreen: marker PSRAM alloc FAILED");
}
// Marker array and PNG buffers are deferred to enter() to avoid
// consuming 20KB+ PSRAM at boot when the map may never be opened.
_markers = nullptr;
_numMarkers = 0;
}
~MapScreen() {
if (_pngBuf) { free(_pngBuf); _pngBuf = nullptr; }
if (_lineBuf) { free(_lineBuf); _lineBuf = nullptr; }
if (_markers) { free(_markers); _markers = nullptr; }
}
@@ -184,7 +180,12 @@ public:
// Add a location marker (call once per contact before entering map)
void clearMarkers() { _numMarkers = 0; }
void addMarker(double lat, double lon, const char* name = "", uint8_t type = 0) {
if (!_markers || _numMarkers >= MAP_MAX_MARKERS) return;
// Lazy-allocate markers on first use (deferred from constructor)
if (!_markers) {
_markers = (MapMarker*)ps_calloc(MAP_MAX_MARKERS, sizeof(MapMarker));
if (!_markers) return; // Alloc failed — skip silently
}
if (_numMarkers >= MAP_MAX_MARKERS) return;
if (lat == 0.0 && lon == 0.0) return; // Skip no-location contacts
_markers[_numMarkers].lat = lat;
_markers[_numMarkers].lon = lon;
@@ -203,6 +204,18 @@ public:
_einkDisplay = static_cast<GxEPDDisplay*>(&display);
_needsRedraw = true;
// Allocate marker array in PSRAM on first use (~20KB)
if (!_markers) {
_markers = (MapMarker*)ps_calloc(MAP_MAX_MARKERS, sizeof(MapMarker));
if (_markers) {
Serial.printf("MapScreen: markers allocated (%d × %d = %d bytes PSRAM)\n",
MAP_MAX_MARKERS, (int)sizeof(MapMarker),
MAP_MAX_MARKERS * (int)sizeof(MapMarker));
} else {
Serial.println("MapScreen: marker PSRAM alloc FAILED");
}
}
// Allocate PNG read buffer in PSRAM on first use
if (!_pngBuf) {
_pngBuf = (uint8_t*)ps_malloc(MAP_PNG_BUF_SIZE);
@@ -217,6 +230,20 @@ public:
}
}
// Allocate scanline decode buffer in PSRAM (512 bytes — avoids stack
// allocation inside the PNGdec callback which is called 256× per tile)
if (!_lineBuf) {
_lineBuf = (uint16_t*)ps_malloc(MAP_TILE_SIZE * sizeof(uint16_t));
if (!_lineBuf) {
_lineBuf = (uint16_t*)malloc(MAP_TILE_SIZE * sizeof(uint16_t));
}
if (_lineBuf) {
Serial.println("MapScreen: lineBuf allocated");
} else {
Serial.println("MapScreen: lineBuf alloc FAILED");
}
}
// Detect available zoom levels from SD card directories
detectZoomRange();
}
@@ -356,6 +383,7 @@ private:
// PNG decode buffer (PSRAM)
uint8_t* _pngBuf;
uint16_t* _lineBuf; // Scanline RGB565 buffer for PNG decode (PSRAM)
bool _tileFound; // Did last tile load succeed?
// PNGdec instance
@@ -381,6 +409,7 @@ private:
int offsetY; // Screen Y offset for this tile
int viewportY; // Top of viewport (MAP_VIEWPORT_Y)
int viewportH; // Height of viewport (MAP_VIEWPORT_H)
uint16_t* lineBuf; // Scanline decode buffer (PSRAM-allocated, avoids 512B stack usage per callback)
};
DrawContext _drawCtx;
@@ -487,7 +516,7 @@ private:
// Load a PNG tile from SD and decode it directly to the display
// screenX, screenY = top-left corner on display where this tile goes
bool loadAndRenderTile(int tileX, int tileY, int screenX, int screenY) {
if (!_pngBuf || !_einkDisplay) return false;
if (!_pngBuf || !_lineBuf || !_einkDisplay) return false;
char path[64];
buildTilePath(path, sizeof(path), _zoom, tileX, tileY);
@@ -521,6 +550,7 @@ private:
_drawCtx.offsetY = screenY;
_drawCtx.viewportY = MAP_VIEWPORT_Y;
_drawCtx.viewportH = MAP_VIEWPORT_H;
_drawCtx.lineBuf = _lineBuf;
// Open PNG from memory buffer
int rc = _png.openRAM(_pngBuf, fileSize, pngDrawCallback);
@@ -547,7 +577,7 @@ private:
// Uses getLineAsRGB565 with correct (little) endianness for ESP32.
static int pngDrawCallback(PNGDRAW* pDraw) {
DrawContext* ctx = (DrawContext*)pDraw->pUser;
if (!ctx || !ctx->display || !ctx->png) return 0;
if (!ctx || !ctx->display || !ctx->png || !ctx->lineBuf) return 0;
int screenY = ctx->offsetY + pDraw->y;
@@ -564,9 +594,8 @@ private:
}
uint16_t lineWidth = pDraw->iWidth;
uint16_t lineBuf[MAP_TILE_SIZE];
if (lineWidth > MAP_TILE_SIZE) lineWidth = MAP_TILE_SIZE;
ctx->png->getLineAsRGB565(pDraw, lineBuf, PNG_RGB565_LITTLE_ENDIAN, 0xFFFFFFFF);
ctx->png->getLineAsRGB565(pDraw, ctx->lineBuf, PNG_RGB565_LITTLE_ENDIAN, 0xFFFFFFFF);
for (int x = 0; x < lineWidth; x++) {
int screenX = ctx->offsetX + x;
@@ -574,7 +603,7 @@ private:
// RGB565 little-endian on ESP32: standard bit layout
// R[15:11] G[10:5] B[4:0]
uint16_t pixel = lineBuf[x];
uint16_t pixel = ctx->lineBuf[x];
// For B&W tiles this is 0x0000 (black) or 0xFFFF (white)
// Simple threshold on full 16-bit value handles both cleanly
@@ -639,6 +668,7 @@ private:
} else {
missing++;
}
yield(); // Feed WDT between tiles — each tile can take 1-2s at 80MHz
}
}
+168
View File
@@ -0,0 +1,168 @@
#pragma once
// ---------------------------------------------------------------------------
// MeckFonts.h — Font style system for Meck
// ---------------------------------------------------------------------------
// Defines font styles (Classic, Noto Sans, Montserrat) and provides lookup
// tables for each display driver's setTextSize() method.
//
// Place this file in: examples/companion_radio/ui-new/
// Place font .h files in: examples/companion_radio/ui-new/fonts/
//
// Both GxEPDDisplay.h and FastEPDDisplay.h include this file.
// The -I examples/companion_radio/ui-new flag (already in platformio.ini)
// makes everything resolve.
// ---------------------------------------------------------------------------
#include <Adafruit_GFX.h> // GFXfont type
// ---------------------------------------------------------------------------
// Font style IDs — stored in NodePrefs.ui_font_style
// ---------------------------------------------------------------------------
#define MECK_FONT_CLASSIC 0 // FreeSans (original Meck look)
#define MECK_FONT_NOTO 1 // Noto Sans — clean, excellent Latin Extended
#define MECK_FONT_MONTSERRAT 2 // Montserrat — geometric, distinctive
#define MECK_FONT_STYLE_COUNT 3
static inline const char* meckFontStyleName(uint8_t style) {
switch (style) {
case MECK_FONT_CLASSIC: return "Classic";
case MECK_FONT_NOTO: return "Noto Sans";
case MECK_FONT_MONTSERRAT: return "Montserrat";
default: return "Classic";
}
}
// ---------------------------------------------------------------------------
// Font includes — Noto Sans family
// ---------------------------------------------------------------------------
#include "fonts/NotoSans7pt7b.h"
#include "fonts/NotoSans9pt7b.h"
#include "fonts/NotoSans12pt7b.h"
#include "fonts/NotoSansBold7pt7b.h"
#include "fonts/NotoSansBold9pt7b.h"
#include "fonts/NotoSansBold12pt7b.h"
#include "fonts/NotoSansBold18pt7b.h"
#include "fonts/NotoSansBold24pt7b.h"
// ---------------------------------------------------------------------------
// Font includes — Montserrat family
// ---------------------------------------------------------------------------
#include "fonts/Montserrat7pt7b.h"
#include "fonts/Montserrat9pt7b.h"
#include "fonts/Montserrat12pt7b.h"
#include "fonts/MontserratBold7pt7b.h"
#include "fonts/MontserratBold9pt7b.h"
#include "fonts/MontserratBold12pt7b.h"
#include "fonts/MontserratBold18pt7b.h"
#include "fonts/MontserratBold24pt7b.h"
// ---------------------------------------------------------------------------
// T-Deck Pro font lookup (240×320, GxEPD2)
// ---------------------------------------------------------------------------
// Maps (fontStyle, textSize) → GFXfont*.
// Returns NULL for textSize 0 with Classic (built-in 6×8 font).
//
// textSize values used by Meck screens:
// 0 = tiny body (built-in 6×8 or 7pt with custom fonts)
// 1 = body (9pt)
// 2 = medium (9pt, same as body in current layout)
// 3 = title (12pt bold)
// 5 = clock face (12pt bold ×2 scaling — caller handles setTextSize(2))
//
// yAdvance reference (physical pixels):
// Classic 9pt=22, Noto 9pt=24, Montserrat 9pt=21 — close enough
// Classic 12ptB=29, Noto 12ptB=32, Montserrat 12ptB=29 — close
// ---------------------------------------------------------------------------
#if !defined(LilyGo_T5S3_EPaper_Pro)
static inline const GFXfont* meckGetFont_TDeckPro(uint8_t style, int textSize) {
// Classic — return NULL to let display driver use its defaults
if (style == MECK_FONT_CLASSIC) return nullptr;
if (style == MECK_FONT_NOTO) {
switch (textSize) {
case 0: return &NotoSans_Regular7pt7b;
case 1: return &NotoSans_Regular9pt7b;
case 2: return &NotoSans_Regular9pt7b;
case 3: return &NotoSans_Bold12pt7b;
case 5: return &NotoSans_Bold12pt7b; // caller applies ×2 scale
default: return &NotoSans_Regular9pt7b;
}
}
// MECK_FONT_MONTSERRAT
switch (textSize) {
case 0: return &Montserrat_Regular7pt7b;
case 1: return &Montserrat_Regular9pt7b;
case 2: return &Montserrat_Regular9pt7b;
case 3: return &Montserrat_Bold12pt7b;
case 5: return &Montserrat_Bold12pt7b; // caller applies ×2 scale
default: return &Montserrat_Regular9pt7b;
}
}
#endif // !LilyGo_T5S3_EPaper_Pro
// ---------------------------------------------------------------------------
// T5S3 font lookup (960×540, FastEPD)
// ---------------------------------------------------------------------------
// Metric-matched to existing FreeSans sizes so virtual-coordinate layouts
// stay intact. The larger Noto/Montserrat sizes (18-26pt) are available in
// the fonts/ directory for a future T5S3 layout rework.
//
// textSize values used by Meck screens:
// 0 = body (12pt regular)
// 1 = heading (12pt bold)
// 2 = large bold (18pt bold)
// 3 = extra large (24pt bold)
// 5 = clock face (24pt bold ×5 scaling)
//
// yAdvance reference (physical pixels):
// FreeSans12pt=29, Noto12pt=32, Montserrat12pt=29
// FreeSansBold18pt=42, NotoBold18pt=48, MontBold18pt=43
// FreeSansBold24pt=56, NotoBold24pt=64, MontBold24pt=57
// ---------------------------------------------------------------------------
#if defined(LilyGo_T5S3_EPaper_Pro)
static inline const GFXfont* meckGetFont_T5S3(uint8_t style, int textSize) {
if (style == MECK_FONT_CLASSIC) return nullptr;
if (style == MECK_FONT_NOTO) {
switch (textSize) {
case 0: return &NotoSans_Regular12pt7b;
case 1: return &NotoSans_Bold12pt7b;
case 2: return &NotoSans_Bold18pt7b;
case 3: return &NotoSans_Bold24pt7b;
case 5: return &NotoSans_Bold24pt7b; // caller applies ×5 scale
default: return &NotoSans_Regular12pt7b;
}
}
// MECK_FONT_MONTSERRAT
switch (textSize) {
case 0: return &Montserrat_Regular12pt7b;
case 1: return &Montserrat_Bold12pt7b;
case 2: return &Montserrat_Bold18pt7b;
case 3: return &Montserrat_Bold24pt7b;
case 5: return &Montserrat_Bold24pt7b; // caller applies ×5 scale
default: return &Montserrat_Regular12pt7b;
}
}
#endif // LilyGo_T5S3_EPaper_Pro
// ---------------------------------------------------------------------------
// Unified lookup — called from display driver setTextSize()
// ---------------------------------------------------------------------------
// Returns the GFXfont* for the given style and textSize.
// If nullptr is returned, the display driver should use its built-in default
// (FreeSans for Classic style, or built-in 6×8 for textSize 0).
// ---------------------------------------------------------------------------
static inline const GFXfont* meckGetFont(uint8_t style, int textSize) {
#if defined(LilyGo_T5S3_EPaper_Pro)
return meckGetFont_T5S3(style, textSize);
#else
return meckGetFont_TDeckPro(style, textSize);
#endif
}
+136 -35
View File
@@ -5,6 +5,7 @@
#include <SD.h>
#include <vector>
#include "Utf8CP437.h"
#include "../NodePrefs.h"
// Forward declarations
class UITask;
@@ -52,9 +53,11 @@ public:
private:
UITask* _task;
NodePrefs* _prefs;
Mode _mode;
bool _sdReady;
bool _initialized;
uint8_t _lastFontPref;
DisplayDriver* _display;
// Display layout (calculated once from display metrics)
@@ -102,6 +105,10 @@ private:
uint32_t _rtcTime; // Unix timestamp (0 = unavailable)
int8_t _utcOffset; // UTC offset in hours
// Callback to get fresh RTC time (set by UITask at init)
typedef uint32_t (*TimeGetterFn)();
TimeGetterFn _getTimeFn = nullptr;
// ---- Helpers ----
String getFullPath(const String& filename) {
@@ -496,7 +503,11 @@ private:
int rightX = display.width() - display.getTextWidth(tmp) - 2;
if (_selectedFile >= 1 && _selectedFile <= (int)_fileList.size()) {
#if defined(LilyGo_T5S3_EPaper_Pro)
const char* hint = "[Hold:Rename]";
#else
const char* hint = "[R:Rename]";
#endif
int hintX = rightX - display.getTextWidth(hint) - 4;
display.setCursor(hintX, 0);
display.setColor(DisplayDriver::YELLOW);
@@ -510,8 +521,8 @@ private:
display.drawRect(0, 11, display.width(), 1);
// File list with "+ New Note" at index 0
display.setTextSize(0);
int listLineH = 8;
display.setTextSize(_prefs->smallTextSize());
int listLineH = _prefs->smallLineH();
int startY = 14;
int totalItems = 1 + (int)_fileList.size();
int maxVisible = (display.height() - startY - _footerHeight) / listLineH;
@@ -528,26 +539,24 @@ private:
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width(), listLineH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), listLineH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), display.width(), listLineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(0, y);
if (i == 0) {
display.setColor(selected ? DisplayDriver::DARK : DisplayDriver::GREEN);
display.print(selected ? "> + New Note" : " + New Note");
display.drawTextEllipsized(0, y, display.width() - 4,
selected ? "> + New Note" : " + New Note");
} else {
String line = selected ? "> " : " ";
String name = _fileList[i - 1];
int maxLen = _charsPerLine - 4;
if ((int)name.length() > maxLen) {
name = name.substring(0, maxLen - 3) + "...";
}
line += name;
display.print(line.c_str());
line += _fileList[i - 1];
display.drawTextEllipsized(0, y, display.width() - 4, line.c_str());
}
y += listLineH;
}
@@ -558,9 +567,13 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setCursor(0, footerY);
display.setColor(DisplayDriver::YELLOW);
display.print("Q:Back W/S:Nav");
const char* right = "Ent:Open";
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe:Nav");
const char* right = "Tap:Open";
#else
display.print("Q:Bk");
const char* right = "Tap/Ent:Open";
#endif
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
@@ -576,16 +589,20 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
display.print("Q:Bck Ent:Edit");
const char* right = "Sh+Del:Del";
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap:Edit");
const char* right = "Hold:Delete";
#else
display.print("Q:Bk Ent:Edit");
const char* right = "X:Delete";
#endif
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
return;
}
// Render current page using tiny font
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
int pageStart = _pageOffsets[_currentPage];
@@ -663,9 +680,15 @@ private:
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
display.print("Q:Bck Ent:Edit");
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe:Page");
const char* right = "Sh+Del:Del";
const char* right = "Tap:Edit";
#else
display.print("Q:Bk Ent:Edit");
const char* right = "X:Delete";
#endif
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
@@ -696,7 +719,7 @@ private:
int textAreaTop = 14;
int textAreaBottom = display.height() - 16;
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
// Find cursor line
int cursorLine = lineForPos(_cursorPos);
@@ -745,7 +768,7 @@ private:
// If buffer is empty, show cursor at top
if (_bufLen == 0) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, textAreaTop);
display.print("|");
@@ -766,11 +789,25 @@ private:
snprintf(status, sizeof(status), "Pg %d/%d", curPage, totalPg);
display.print(status);
#if defined(LilyGo_T5S3_EPaper_Pro)
const char* mid = "Tap:Type";
display.setCursor((display.width() - display.getTextWidth(mid)) / 2, footerY);
display.print(mid);
#endif
const char* right;
if (_bufLen == 0 || !_dirty) {
#if defined(LilyGo_T5S3_EPaper_Pro)
right = "Back";
#else
right = "Q:Back";
#endif
} else {
#if defined(LilyGo_T5S3_EPaper_Pro)
right = "Hold:Save";
#else
right = "Sh+Del:Save";
#endif
}
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
@@ -789,7 +826,7 @@ private:
display.setCursor(0, 20);
display.setColor(DisplayDriver::LIGHT);
display.print("From: ");
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
String origDisplay = _renameOriginal;
if (origDisplay.length() > 30) origDisplay = origDisplay.substring(0, 27) + "...";
display.print(origDisplay.c_str());
@@ -800,7 +837,7 @@ private:
display.setColor(DisplayDriver::LIGHT);
display.print("To: ");
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::GREEN);
char displayName[NOTES_RENAME_MAX + 2];
snprintf(displayName, sizeof(displayName), "%s|", _renameBuf);
@@ -817,9 +854,13 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel");
const char* right = "Tap:Confirm";
#else
display.print("Q:Cancel");
const char* right = "Ent:Confirm";
#endif
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
@@ -836,7 +877,7 @@ private:
display.setCursor(0, 25);
display.print("File:");
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setCursor(0, 38);
String nameDisplay = _deleteTarget;
if (nameDisplay.length() > 35) nameDisplay = nameDisplay.substring(0, 32) + "...";
@@ -852,9 +893,13 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel");
const char* right = "Tap:Delete";
#else
display.print("Q:Cancel");
const char* right = "Ent:Delete";
#endif
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
}
@@ -1033,6 +1078,10 @@ private:
// ---- Note Creation ----
void createNewNote() {
// Refresh timestamp at creation time for accurate filenames
if (_getTimeFn) {
_rtcTime = _getTimeFn();
}
_currentFile = generateFilename();
_buf[0] = '\0';
_bufLen = 0;
@@ -1044,9 +1093,9 @@ private:
}
public:
NotesScreen(UITask* task)
: _task(task), _mode(FILE_LIST),
_sdReady(false), _initialized(false), _display(nullptr),
NotesScreen(UITask* task, NodePrefs* prefs = nullptr)
: _task(task), _prefs(prefs), _mode(FILE_LIST),
_sdReady(false), _initialized(false), _lastFontPref(0), _display(nullptr),
_charsPerLine(38), _linesPerPage(22), _lineHeight(5), _footerHeight(14),
_editCharsPerLine(20), _editLineHeight(12), _editMaxLines(8),
_selectedFile(0), _buf(nullptr), _bufLen(0), _cursorPos(0),
@@ -1081,15 +1130,31 @@ public:
// ---- Layout Init ----
void initLayout(DisplayDriver& display) {
// Re-init if font preference changed since last layout
uint8_t curFont = _prefs ? _prefs->large_font : 0;
if (_initialized && curFont != _lastFontPref) {
_initialized = false;
Serial.println("Notes: font changed, recalculating layout");
}
if (_initialized) return;
_lastFontPref = curFont;
_display = &display;
// Tiny font metrics (for read mode)
display.setTextSize(0);
// Font metrics (for read mode)
display.setTextSize(_prefs->smallTextSize());
uint16_t tenCharsW = display.getTextWidth("MMMMMMMMMM");
if (tenCharsW > 0) {
_charsPerLine = (display.width() * 10) / tenCharsW;
}
// Proportional font: use average-width measurement instead of M-width
if (_prefs && _prefs->large_font) {
const char* sample = "the quick brown fox jumps over lazy dog";
uint16_t sampleW = display.getTextWidth(sample);
int sampleLen = strlen(sample);
if (sampleW > 0 && sampleLen > 0) {
_charsPerLine = (display.width() * sampleLen * 70) / ((int)sampleW * 100);
}
}
if (_charsPerLine < 15) _charsPerLine = 15;
if (_charsPerLine > 60) _charsPerLine = 60;
@@ -1099,6 +1164,10 @@ public:
} else {
_lineHeight = 5;
}
// Large font: formula above assumes built-in 6x8 ratio — too small for 9pt
if (_prefs && _prefs->large_font) {
_lineHeight = _prefs->smallLineH();
}
_footerHeight = 14;
int textAreaHeight = display.height() - _footerHeight;
@@ -1124,12 +1193,16 @@ public:
void setSDReady(bool ready) { _sdReady = ready; }
bool isSDReady() const { return _sdReady; }
bool isDirty() const { return _dirty; }
void triggerSaveAndExit() { saveAndExit(); }
void setTimestamp(uint32_t rtcTime, int8_t utcOffset) {
_rtcTime = rtcTime;
_utcOffset = utcOffset;
}
void setTimeGetter(TimeGetterFn fn) { _getTimeFn = fn; }
void enter(DisplayDriver& display) {
initLayout(display);
scanFiles();
@@ -1145,9 +1218,37 @@ public:
bool isInFileList() const { return _mode == FILE_LIST; }
bool isRenaming() const { return _mode == RENAMING; }
bool isConfirmingDelete() const { return _mode == CONFIRM_DELETE; }
bool isDirty() const { return _dirty; }
bool isEmpty() const { return _bufLen == 0; }
// Touch: select file list row by virtual Y coordinate
// Returns: 0 = outside list, 1 = moved selection, 2 = tapped same row (open)
int selectRowAtVY(int vy) {
if (_mode != FILE_LIST) return 0;
const int startY = 14, footerH = 14;
const int listLineH = _prefs ? _prefs->smallLineH() : 9;
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = startY;
#else
const int bodyTop = startY + (_prefs ? _prefs->smallHighlightOff() : 5);
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int totalItems = 1 + (int)_fileList.size();
if (totalItems == 0) return 0;
int maxVisible = (128 - startY - footerH) / listLineH;
if (maxVisible < 3) maxVisible = 3;
if (maxVisible > 15) maxVisible = 15;
int startIdx = max(0, min(_selectedFile - maxVisible / 2,
totalItems - maxVisible));
int tappedRow = startIdx + (vy - bodyTop) / listLineH;
if (tappedRow < 0 || tappedRow >= totalItems) return 0;
if (tappedRow == _selectedFile) return 2;
_selectedFile = tappedRow;
return 1;
}
// ---- Cursor Navigation (called from main.cpp) ----
void moveCursorLeft() {
@@ -0,0 +1,805 @@
#pragma once
#include <helpers/ui/UIScreen.h>
#include <helpers/ui/DisplayDriver.h>
#include <MeshCore.h>
#include <Packet.h>
// Forward declarations
class UITask;
class MyMesh;
extern MyMesh the_mesh;
class PathEditorScreen : public UIScreen {
public:
enum EditorState {
STATE_MAIN,
STATE_PICK_HOP
};
// Main-state menu items (dynamic, built each render)
enum MenuItem {
MENU_MODE = 0, // "Mode: 1B/hop" or "Mode: 2B/hop"
// After mode: hop lines (MENU_HOP_BASE + i)
// Then: action items
MENU_HOP_BASE = 1,
// Dynamic items after hops:
MENU_ADD_HOP = 100,
MENU_SET_DIRECT,
MENU_REMOVE_LAST,
MENU_CLEAR_PATH,
MENU_SAVE_EXIT
};
private:
UITask* _task;
mesh::RTCClock* _rtc;
int _contactIdx; // Index into contact table
char _contactName[32]; // Contact name for header
EditorState _state;
int _menuSel; // Selected menu item index (0-based in visible list)
int _menuCount; // Total visible menu items
// Path being edited (working copy)
uint8_t _pathBuf[MAX_PATH_SIZE];
uint8_t _pathLen; // Encoded: bits[7:6]=mode, bits[5:0]=hops
int _hopCount; // Decoded hop count
int _bytesPerHop; // 1 or 2
// Repeater picker state
static const int MAX_REPEATERS = 200;
uint16_t* _repIdx; // Indices into contact table (PSRAM)
int _repCount; // Number of repeaters found
int _repSel; // Selected repeater in picker
int _repScroll; // Scroll offset in picker
bool _dirty; // Path has been modified
bool _wantExit; // Set by Save & Exit — caller should navigate back
bool _directLocked; // True = path is explicitly set to direct (0 hops, locked)
// --- helpers ---
void decodePath() {
_hopCount = _pathLen & 0x3F;
uint8_t mode = (_pathLen >> 6) & 0x03;
_bytesPerHop = mode + 1;
}
uint8_t encodePath() const {
uint8_t mode = (_bytesPerHop - 1) & 0x03;
return (mode << 6) | (_hopCount & 0x3F);
}
void buildRepeaterList() {
_repCount = 0;
uint32_t numContacts = the_mesh.getNumContacts();
ContactInfo c;
for (uint32_t i = 0; i < numContacts && _repCount < MAX_REPEATERS; i++) {
if (the_mesh.getContactByIdx(i, c)) {
if (c.type == ADV_TYPE_REPEATER) {
_repIdx[_repCount++] = (uint16_t)i;
}
}
}
}
// Look up a contact name by matching pub_key prefix bytes
bool findNameForHop(int hopIndex, char* name, size_t nameLen) const {
if (hopIndex < 0 || hopIndex >= _hopCount) return false;
int offset = hopIndex * _bytesPerHop;
uint32_t numContacts = the_mesh.getNumContacts();
ContactInfo c;
for (uint32_t i = 0; i < numContacts; i++) {
if (the_mesh.getContactByIdx(i, c)) {
bool match = true;
for (int b = 0; b < _bytesPerHop; b++) {
if (c.id.pub_key[b] != _pathBuf[offset + b]) {
match = false;
break;
}
}
if (match) {
strncpy(name, c.name, nameLen);
name[nameLen - 1] = '\0';
return true;
}
}
}
return false;
}
// Build the visible menu items list and return count
// Menu layout:
// 0: Mode selector
// 1..hopCount: each hop
// hopCount+1: Add hop
// hopCount+2: Remove last (only if hops > 0)
// hopCount+2 or +3: Clear path (only if custom path flag set or hops > 0)
// last: Save & Exit
int buildMenuCount() const {
int count = 1; // Mode selector
count += _hopCount; // One per hop
if (_hopCount < 8) count++; // Add hop (max 8 hops)
count++; // Set Direct (always visible)
if (_hopCount > 0) count++; // Remove last
if (_hopCount > 0 || _directLocked || isCustomPathSet()) count++; // Clear path
count++; // Save & Exit
return count;
}
// Map a menu index to a MenuItem enum
MenuItem menuItemAt(int idx) const {
if (idx == 0) return MENU_MODE;
int pos = 1;
// Hop lines
for (int h = 0; h < _hopCount; h++) {
if (idx == pos) return (MenuItem)(MENU_HOP_BASE + h);
pos++;
}
// Add hop
if (_hopCount < 8) {
if (idx == pos) return MENU_ADD_HOP;
pos++;
}
// Set Direct
if (idx == pos) return MENU_SET_DIRECT;
pos++;
// Remove last
if (_hopCount > 0) {
if (idx == pos) return MENU_REMOVE_LAST;
pos++;
}
// Clear path
if (_hopCount > 0 || _directLocked || isCustomPathSet()) {
if (idx == pos) return MENU_CLEAR_PATH;
pos++;
}
// Save & Exit
return MENU_SAVE_EXIT;
}
bool isCustomPathSet() const {
ContactInfo c;
if (!the_mesh.getContactByIdx(_contactIdx, c)) return false;
return (c.flags & CONTACT_FLAG_CUSTOM_PATH) != 0;
}
public:
PathEditorScreen(UITask* task, mesh::RTCClock* rtc)
: _task(task), _rtc(rtc), _contactIdx(-1), _state(STATE_MAIN),
_menuSel(0), _menuCount(1), _pathLen(0), _hopCount(0),
_bytesPerHop(1), _repCount(0), _repSel(0), _repScroll(0),
_dirty(false), _wantExit(false), _directLocked(false) {
memset(_contactName, 0, sizeof(_contactName));
memset(_pathBuf, 0, sizeof(_pathBuf));
#if defined(ESP32) && defined(BOARD_HAS_PSRAM)
_repIdx = (uint16_t*)ps_calloc(MAX_REPEATERS, sizeof(uint16_t));
#else
_repIdx = new uint16_t[MAX_REPEATERS]();
#endif
}
void openForContact(int contactIdx) {
_contactIdx = contactIdx;
_state = STATE_MAIN;
_menuSel = 0;
_repSel = 0;
_repScroll = 0;
_dirty = false;
_wantExit = false;
_directLocked = false;
// Load contact info
ContactInfo c;
if (the_mesh.getContactByIdx(contactIdx, c)) {
strncpy(_contactName, c.name, sizeof(_contactName) - 1);
_contactName[sizeof(_contactName) - 1] = '\0';
// Copy current path
if (c.out_path_len != OUT_PATH_UNKNOWN) {
_pathLen = c.out_path_len;
decodePath();
int byteLen = _hopCount * _bytesPerHop;
if (byteLen > MAX_PATH_SIZE) byteLen = MAX_PATH_SIZE;
memcpy(_pathBuf, c.out_path, byteLen);
// Detect existing direct-locked path
if (_hopCount == 0 && (c.flags & CONTACT_FLAG_CUSTOM_PATH)) {
_directLocked = true;
}
} else {
_pathLen = 0;
_hopCount = 0;
_bytesPerHop = 1;
memset(_pathBuf, 0, sizeof(_pathBuf));
}
} else {
strcpy(_contactName, "Unknown");
_pathLen = 0;
_hopCount = 0;
_bytesPerHop = 1;
}
_menuCount = buildMenuCount();
}
int render(DisplayDriver& display) override {
if (_state == STATE_PICK_HOP) {
return renderPicker(display);
}
return renderMain(display);
}
int renderMain(DisplayDriver& display) {
char tmp[64];
// === Header ===
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
snprintf(tmp, sizeof(tmp), "Path: %s", _contactName);
// Truncate if too long
if (display.getTextWidth(tmp) > display.width() - 4) {
snprintf(tmp, sizeof(tmp), "Path: %.12s..", _contactName);
}
display.print(tmp);
// Show lock icon or dirty indicator on right
if (_dirty) {
const char* mod = "[*]";
display.setCursor(display.width() - display.getTextWidth(mod) - 2, 0);
display.print(mod);
} else if (isCustomPathSet()) {
const char* lock = "[L]";
display.setCursor(display.width() - display.getTextWidth(lock) - 2, 0);
display.print(lock);
}
display.drawRect(0, 11, display.width(), 1);
// === Body ===
display.setTextSize(0);
int lineH = 9;
int headerH = 14;
int footerH = 14;
int maxY = display.height() - footerH;
int y = headerH;
_menuCount = buildMenuCount();
// Center visible window around selected item
int maxVisible = (maxY - headerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_menuSel - maxVisible / 2, _menuCount - maxVisible));
if (startIdx < 0) startIdx = 0;
int endIdx = min(_menuCount, startIdx + maxVisible);
for (int i = startIdx; i < endIdx && y + lineH <= maxY; i++) {
bool selected = (i == _menuSel);
MenuItem item = menuItemAt(i);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineH);
#else
display.fillRect(0, y + 5, display.width(), lineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(2, y);
char prefix = selected ? '>' : ' ';
switch (item) {
case MENU_MODE:
if (_directLocked) {
snprintf(tmp, sizeof(tmp), "%c Mode: DIRECT", prefix);
} else {
snprintf(tmp, sizeof(tmp), "%c Mode: %dB/hop", prefix, _bytesPerHop);
}
display.print(tmp);
// Show hint on right
if (!_directLocked) {
const char* hint = "(A/D)";
display.setCursor(display.width() - display.getTextWidth(hint) - 4, y);
display.print(hint);
}
break;
case MENU_ADD_HOP:
snprintf(tmp, sizeof(tmp), "%c + Add hop...", prefix);
display.print(tmp);
break;
case MENU_SET_DIRECT:
if (_directLocked) {
snprintf(tmp, sizeof(tmp), "%c * Direct (set)", prefix);
} else {
snprintf(tmp, sizeof(tmp), "%c * Set Direct", prefix);
}
display.print(tmp);
break;
case MENU_REMOVE_LAST:
snprintf(tmp, sizeof(tmp), "%c - Remove last hop", prefix);
display.print(tmp);
break;
case MENU_CLEAR_PATH:
snprintf(tmp, sizeof(tmp), "%c Clear custom path", prefix);
display.print(tmp);
break;
case MENU_SAVE_EXIT:
snprintf(tmp, sizeof(tmp), "%c Save & Exit", prefix);
display.print(tmp);
break;
default:
// Hop line: MENU_HOP_BASE + hopIndex
if (item >= MENU_HOP_BASE && item < MENU_HOP_BASE + 64) {
int hopIdx = item - MENU_HOP_BASE;
char hopName[24];
int offset = hopIdx * _bytesPerHop;
if (findNameForHop(hopIdx, hopName, sizeof(hopName))) {
if (_bytesPerHop == 1) {
snprintf(tmp, sizeof(tmp), "%c %d: %s (%02X)", prefix, hopIdx + 1,
hopName, _pathBuf[offset]);
} else {
snprintf(tmp, sizeof(tmp), "%c %d: %s (%02X%02X)", prefix, hopIdx + 1,
hopName, _pathBuf[offset], _pathBuf[offset + 1]);
}
} else {
if (_bytesPerHop == 1) {
snprintf(tmp, sizeof(tmp), "%c %d: ??? (%02X)", prefix, hopIdx + 1,
_pathBuf[offset]);
} else {
snprintf(tmp, sizeof(tmp), "%c %d: ??? (%02X%02X)", prefix, hopIdx + 1,
_pathBuf[offset], _pathBuf[offset + 1]);
}
}
display.drawTextEllipsized(2, y, display.width() - 4, tmp);
}
break;
}
y += lineH;
}
// === Footer ===
display.setTextSize(1);
int footerY = display.height() - 12;
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.setCursor(0, footerY);
display.print("Swipe:Nav");
const char* right = "Hold:Select";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#else
display.setCursor(0, footerY);
display.print("Q:Bk W/S:Nav");
const char* right = "Enter:Sel";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#endif
return 5000;
}
int renderPicker(DisplayDriver& display) {
char tmp[64];
// === Header ===
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
snprintf(tmp, sizeof(tmp), "Select Repeater (%d)", _repCount);
display.print(tmp);
display.drawRect(0, 11, display.width(), 1);
// === Body ===
display.setTextSize(0);
int lineH = 9;
int headerH = 14;
int footerH = 14;
int maxY = display.height() - footerH;
int y = headerH;
if (_repCount == 0) {
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, y);
display.print("No repeaters in contacts");
display.setCursor(0, y + lineH);
display.print("Add repeaters first");
} else {
int maxVisible = (maxY - headerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_repSel - maxVisible / 2, _repCount - maxVisible));
if (startIdx < 0) startIdx = 0;
int endIdx = min(_repCount, startIdx + maxVisible);
for (int i = startIdx; i < endIdx && y + lineH <= maxY; i++) {
ContactInfo c;
if (!the_mesh.getContactByIdx(_repIdx[i], c)) continue;
bool selected = (i == _repSel);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineH);
#else
display.fillRect(0, y + 5, display.width(), lineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(2, y);
char prefix = selected ? '>' : ' ';
if (_bytesPerHop == 1) {
snprintf(tmp, sizeof(tmp), "%c %s (%02X)", prefix, c.name, c.id.pub_key[0]);
} else {
snprintf(tmp, sizeof(tmp), "%c %s (%02X%02X)", prefix, c.name,
c.id.pub_key[0], c.id.pub_key[1]);
}
display.drawTextEllipsized(2, y, display.width() - 4, tmp);
y += lineH;
}
}
// === Footer ===
display.setTextSize(1);
int footerY = display.height() - 12;
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.setCursor(0, footerY);
display.print("Swipe:Scroll");
const char* right = "Hold:Add Back:Cancel";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#else
display.setCursor(0, footerY);
display.print("Q:Cancel W/S:Scroll");
const char* right = "Enter:Add";
display.setCursor(display.width() - display.getTextWidth(right) - 2, footerY);
display.print(right);
#endif
return 5000;
}
bool handleInput(char c) override {
if (_state == STATE_PICK_HOP) {
return handlePickerInput(c);
}
return handleMainInput(c);
}
bool handleMainInput(char c) {
// W - scroll up
if (c == 'w' || c == 'W' || c == 0xF2) {
if (_menuSel > 0) {
_menuSel--;
return true;
}
return false;
}
// S - scroll down
if (c == 's' || c == 'S' || c == 0xF1) {
if (_menuSel < _menuCount - 1) {
_menuSel++;
return true;
}
return false;
}
// A/D — toggle mode (only when Mode item is selected and not direct-locked)
if (c == 'a' || c == 'A' || c == 'd' || c == 'D') {
MenuItem item = menuItemAt(_menuSel);
if (item == MENU_MODE && !_directLocked) {
// Toggle between 1-byte and 2-byte
if (_bytesPerHop == 1) {
switchMode(2);
} else {
switchMode(1);
}
_dirty = true;
_menuCount = buildMenuCount();
return true;
}
return false;
}
// Enter - select
if (c == 13 || c == KEY_ENTER || c == '\r') {
MenuItem item = menuItemAt(_menuSel);
switch (item) {
case MENU_MODE:
// Toggle mode on Enter too (no-op if direct locked)
if (!_directLocked) {
if (_bytesPerHop == 1) {
switchMode(2);
} else {
switchMode(1);
}
_dirty = true;
_menuCount = buildMenuCount();
}
return true;
case MENU_ADD_HOP:
// Enter picker mode — adding a hop clears direct lock
_directLocked = false;
buildRepeaterList();
_repSel = 0;
_repScroll = 0;
_state = STATE_PICK_HOP;
return true;
case MENU_SET_DIRECT:
// Set path to direct (0 hops, locked)
_hopCount = 0;
_pathLen = 0;
memset(_pathBuf, 0, sizeof(_pathBuf));
_directLocked = true;
_dirty = true;
_menuCount = buildMenuCount();
return true;
case MENU_REMOVE_LAST:
if (_hopCount > 0) {
_hopCount--;
_pathLen = encodePath();
_dirty = true;
_menuCount = buildMenuCount();
// Clamp selection
if (_menuSel >= _menuCount) _menuSel = _menuCount - 1;
}
return true;
case MENU_CLEAR_PATH:
_hopCount = 0;
_pathLen = 0;
_directLocked = false;
memset(_pathBuf, 0, sizeof(_pathBuf));
_dirty = true;
_menuCount = buildMenuCount();
_menuSel = 0;
return true;
case MENU_SAVE_EXIT:
savePath();
_wantExit = true; // Signal to main.cpp to navigate back to contacts
return true;
default:
// Hop line — no action (could add remove-specific-hop later)
break;
}
return true;
}
// Q - back (discard changes or prompt?)
// For simplicity, just go back without saving
if (c == 'q' || c == 'Q') {
// Return to contacts screen without saving
// The UITask will handle this via the key falling through
return false; // Let UITask handle Q as back
}
return false;
}
bool handlePickerInput(char c) {
// W - scroll up
if (c == 'w' || c == 'W' || c == 0xF2) {
if (_repSel > 0) {
_repSel--;
return true;
}
return false;
}
// S - scroll down
if (c == 's' || c == 'S' || c == 0xF1) {
if (_repSel < _repCount - 1) {
_repSel++;
return true;
}
return false;
}
// Enter - add selected repeater as hop
if (c == 13 || c == KEY_ENTER || c == '\r') {
if (_repCount > 0 && _repSel >= 0 && _repSel < _repCount) {
addHopFromContact(_repIdx[_repSel]);
}
_state = STATE_MAIN;
_menuCount = buildMenuCount();
return true;
}
// Q - cancel picker, return to main
if (c == 'q' || c == 'Q') {
_state = STATE_MAIN;
return true;
}
return false;
}
// Tap-to-select for T5S3 touch
int selectRowAtVY(int vy) {
if (_state == STATE_PICK_HOP) {
return selectPickerRowAtVY(vy);
}
return selectMainRowAtVY(vy);
}
int selectMainRowAtVY(int vy) {
if (_menuCount == 0) return 0;
const int headerH = 14, footerH = 14, lineH = 9;
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = headerH;
#else
const int bodyTop = headerH + 5;
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_menuSel - maxVisible / 2, _menuCount - maxVisible));
if (startIdx < 0) startIdx = 0;
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= _menuCount) return 0;
if (tappedRow == _menuSel) return 2;
_menuSel = tappedRow;
return 1;
}
int selectPickerRowAtVY(int vy) {
if (_repCount == 0) return 0;
const int headerH = 14, footerH = 14, lineH = 9;
#if defined(LilyGo_T5S3_EPaper_Pro)
const int bodyTop = headerH;
#else
const int bodyTop = headerH + 5;
#endif
if (vy < bodyTop || vy >= 128 - footerH) return 0;
int maxVisible = (128 - headerH - footerH) / lineH;
if (maxVisible < 3) maxVisible = 3;
int startIdx = max(0, min(_repSel - maxVisible / 2, _repCount - maxVisible));
if (startIdx < 0) startIdx = 0;
int tappedRow = startIdx + (vy - bodyTop) / lineH;
if (tappedRow < 0 || tappedRow >= _repCount) return 0;
if (tappedRow == _repSel) return 2;
_repSel = tappedRow;
return 1;
}
EditorState getState() const { return _state; }
bool isDirty() const { return _dirty; }
bool wantsExit() const { return _wantExit; }
private:
void switchMode(int newBytesPerHop) {
if (newBytesPerHop == _bytesPerHop) return;
if (_hopCount > 0) {
// Rebuild path buffer for new mode
// We need the full pub_keys to re-extract the right prefix bytes
uint8_t newBuf[MAX_PATH_SIZE];
memset(newBuf, 0, sizeof(newBuf));
int newHopCount = 0;
for (int h = 0; h < _hopCount && newHopCount < 8; h++) {
int oldOffset = h * _bytesPerHop;
// Try to find the contact that matches this hop
uint32_t numContacts = the_mesh.getNumContacts();
ContactInfo c;
bool found = false;
for (uint32_t i = 0; i < numContacts; i++) {
if (the_mesh.getContactByIdx(i, c)) {
bool match = true;
for (int b = 0; b < _bytesPerHop; b++) {
if (c.id.pub_key[b] != _pathBuf[oldOffset + b]) {
match = false;
break;
}
}
if (match) {
// Found the contact — copy new prefix size
int newOffset = newHopCount * newBytesPerHop;
for (int b = 0; b < newBytesPerHop; b++) {
newBuf[newOffset + b] = c.id.pub_key[b];
}
newHopCount++;
found = true;
break;
}
}
}
if (!found) {
// Contact not found — copy what we can
int newOffset = newHopCount * newBytesPerHop;
int oldOff = h * _bytesPerHop;
for (int b = 0; b < newBytesPerHop; b++) {
if (b < _bytesPerHop) {
newBuf[newOffset + b] = _pathBuf[oldOff + b];
} else {
newBuf[newOffset + b] = 0x00; // pad with zero
}
}
newHopCount++;
}
}
_hopCount = newHopCount;
memcpy(_pathBuf, newBuf, sizeof(newBuf));
}
_bytesPerHop = newBytesPerHop;
_pathLen = encodePath();
}
void addHopFromContact(uint16_t contactTableIdx) {
if (_hopCount >= 8) return;
ContactInfo c;
if (!the_mesh.getContactByIdx(contactTableIdx, c)) return;
int offset = _hopCount * _bytesPerHop;
if (offset + _bytesPerHop > MAX_PATH_SIZE) return;
for (int b = 0; b < _bytesPerHop; b++) {
_pathBuf[offset + b] = c.id.pub_key[b];
}
_hopCount++;
_pathLen = encodePath();
_dirty = true;
}
void savePath() {
if (_contactIdx < 0) return;
if (_directLocked) {
// Set as direct (0 hops) with lock — prevents flood routing
the_mesh.setCustomPath(_contactIdx, _pathBuf, 0, true);
Serial.printf("PathEditor: set DIRECT path for contact %d (%s)\n",
_contactIdx, _contactName);
} else if (_hopCount > 0) {
// Set custom path with lock
the_mesh.setCustomPath(_contactIdx, _pathBuf, encodePath(), true);
Serial.printf("PathEditor: saved %d-hop %dB/hop path for contact %d (%s)\n",
_hopCount, _bytesPerHop, _contactIdx, _contactName);
} else {
// Clear custom path — revert to auto-discovery
the_mesh.clearCustomPath(_contactIdx);
Serial.printf("PathEditor: cleared custom path for contact %d (%s)\n",
_contactIdx, _contactName);
}
// Trigger contact save to SD
the_mesh.saveContacts();
_dirty = false;
}
};
@@ -475,6 +475,7 @@ public:
int getContactIdx() const { return _contactIdx; }
AdminState getState() const { return _state; }
uint8_t getPermissions() const { return _permissions; }
void onLoginResult(bool success, uint8_t permissions, uint32_t server_time) {
_waitingForLogin = false;
@@ -561,7 +562,9 @@ public:
display.setTextSize(1);
display.setColor(DisplayDriver::GREEN);
display.setCursor(0, 0);
snprintf(tmp, sizeof(tmp), "Admin: %.16s", _repeaterName);
const char* hdrPrefix = (_state == STATE_PASSWORD_ENTRY || _state == STATE_LOGGING_IN)
? "Login" : "Admin";
snprintf(tmp, sizeof(tmp), "%s: %.16s", hdrPrefix, _repeaterName);
display.print(tmp);
if (_state >= STATE_CATEGORY_MENU && _state <= STATE_RESPONSE_VIEW) {
@@ -598,41 +601,77 @@ public:
switch (_state) {
case STATE_PASSWORD_ENTRY:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Exit");
renderFooterRight(display, footerY, "Hold:Type");
#else
display.print("Sh+Del:Exit");
renderFooterRight(display, footerY, "Ent:Login");
#endif
break;
case STATE_LOGGING_IN:
case STATE_COMMAND_PENDING:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel");
#else
display.print("Sh+Del:Cancel");
#endif
break;
case STATE_CATEGORY_MENU:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Exit");
renderFooterMidRight(display, footerY, "Back:Exit", "Tap:Open", "Swipe:Sel");
#else
display.print("Sh+Del:Exit");
renderFooterMidRight(display, footerY, "Sh+Del:Exit", "Ent:Open", "W/S:Sel");
#endif
break;
case STATE_COMMAND_MENU:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Back");
renderFooterMidRight(display, footerY, "Back:Back", "Tap:Run", "Swipe:Sel");
#else
display.print("Sh+Del:Back");
renderFooterMidRight(display, footerY, "Sh+Del:Back", "Ent:Run", "W/S:Sel");
#endif
break;
case STATE_PARAM_ENTRY:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Cancel");
renderFooterRight(display, footerY, "Tap:Send");
#else
display.print("Sh+Del:Cancel");
renderFooterRight(display, footerY, "Ent:Send");
#endif
break;
case STATE_CONFIRM:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:No");
renderFooterRight(display, footerY, "Tap:Yes");
#else
display.print("Sh+Del:No");
renderFooterRight(display, footerY, "Ent:Yes");
#endif
break;
case STATE_RESPONSE_VIEW:
case STATE_ERROR:
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Boot:Back");
if (_responseTotalLines > bodyHeight / 9) {
renderFooterRight(display, footerY, "Swipe:Scroll");
}
#else
display.print("Sh+Del:Back");
if (_responseTotalLines > bodyHeight / 9) {
renderFooterRight(display, footerY, "W/S:Scrll");
}
#endif
break;
}
@@ -738,8 +777,8 @@ private:
// =====================================================================
void renderCategoryMenu(DisplayDriver& display, int y, int bodyHeight) {
display.setTextSize(0);
int lineHeight = 9;
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize());
int lineHeight = the_mesh.getNodePrefs()->smallLineH();
// Clock drift info line
if (_serverTime > 0) {
@@ -823,8 +862,8 @@ private:
// =====================================================================
void renderCommandMenu(DisplayDriver& display, int y, int bodyHeight) {
display.setTextSize(0);
int lineHeight = 9;
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize());
int lineHeight = the_mesh.getNodePrefs()->smallLineH();
const AdminCategoryDef& cat = CATEGORIES[_catSel];
// Category title
@@ -986,7 +1025,7 @@ private:
if (_pendingCmd) display.print(_pendingCmd->label);
y += 14;
display.setTextSize(0);
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize());
display.setCursor(0, y);
// Show the param value if one was collected
@@ -994,14 +1033,18 @@ private:
char preview[80];
snprintf(preview, sizeof(preview), "Value: %s", _paramBuf);
display.print(preview);
y += 10;
y += the_mesh.getNodePrefs()->smallLineH() + 1;
display.setCursor(0, y);
}
if (_pendingCmd && (_pendingCmd->flags & CMDF_EXPECT_TIMEOUT)) {
display.print("Timeout response is normal.");
} else {
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap=Yes Back=No");
#else
display.print("Enter=Yes Sh+Del=No");
#endif
}
display.setTextSize(1);
@@ -1028,8 +1071,8 @@ private:
// =====================================================================
void renderResponse(DisplayDriver& display, int y, int bodyHeight) {
display.setTextSize(0);
int lineHeight = 9;
display.setTextSize(the_mesh.getNodePrefs()->smallTextSize());
int lineHeight = the_mesh.getNodePrefs()->smallLineH();
display.setColor((_state == STATE_ERROR) ? DisplayDriver::YELLOW : DisplayDriver::LIGHT);
@@ -1120,7 +1163,11 @@ private:
bool selected, const char* label, bool warn) {
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width(), lineHeight);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineHeight);
#else
display.fillRect(0, y + the_mesh.getNodePrefs()->smallHighlightOff(), display.width(), lineHeight);
#endif
display.setColor(DisplayDriver::DARK);
} else if (warn) {
display.setColor(DisplayDriver::YELLOW);
@@ -1169,9 +1216,10 @@ inline bool RepeaterAdminScreen::doLogin() {
if (the_mesh.uiLoginToRepeater(_contactIdx, _password, timeout_ms)) {
_state = STATE_LOGGING_IN;
_cmdSentAt = millis();
// Add a 1.5s buffer over the mesh estimate; fall back to ADMIN_TIMEOUT_MS
// if the estimate came back zero for any reason.
_loginTimeoutMs = (timeout_ms > 0) ? timeout_ms + 1500 : ADMIN_TIMEOUT_MS;
// Add a 5s buffer over the mesh estimate to account for blocking e-ink
// refreshes (FastEPD ~1-2s per frame, VKB dismiss + login render = 2-3 frames).
// Fall back to ADMIN_TIMEOUT_MS if the estimate came back zero.
_loginTimeoutMs = (timeout_ms > 0) ? timeout_ms + 5000 : ADMIN_TIMEOUT_MS;
_waitingForLogin = true;
return true;
} else {
+24 -21
View File
@@ -36,6 +36,7 @@
#include "ModemManager.h"
#include "SMSStore.h"
#include "SMSContacts.h"
#include "../NodePrefs.h"
// Limits
#define SMS_INBOX_PAGE_SIZE 4
@@ -51,6 +52,7 @@ public:
private:
UITask* _task;
NodePrefs* _prefs;
SubView _view;
// App menu state
@@ -117,8 +119,8 @@ private:
}
public:
SMSScreen(UITask* task)
: _task(task), _view(APP_MENU)
SMSScreen(UITask* task, NodePrefs* prefs = nullptr)
: _task(task), _prefs(prefs), _view(APP_MENU)
, _menuCursor(0)
, _convCount(0), _inboxCursor(0), _inboxScrollTop(0)
, _msgCount(0), _msgScrollPos(0)
@@ -276,7 +278,7 @@ public:
// Show modem state text if not ready
if (ms != ModemState::READY && ms != ModemState::SENDING_SMS) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::YELLOW);
const char* label = ModemManager::stateToString(ms);
uint16_t labelW = display.getTextWidth(label);
@@ -356,7 +358,7 @@ public:
// Modem status indicator
ModemState ms = modemManager.getState();
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setCursor(4, y + lineHeight + 8);
if (ms == ModemState::OFF || ms == ModemState::POWERING_ON ||
ms == ModemState::INITIALIZING) {
@@ -483,7 +485,7 @@ public:
bool isAction = (row == 4); // Bottom row has action buttons
if (isAction) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
if (col == 2 && _phoneInputPos > 0) {
display.setColor(DisplayDriver::GREEN); // CALL
} else if (col == 1) {
@@ -544,7 +546,7 @@ public:
display.drawRect(0, 11, display.width(), 1);
if (_convCount == 0) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 20);
display.print("No conversations");
@@ -560,8 +562,8 @@ public:
}
display.setTextSize(1);
} else {
display.setTextSize(0);
int lineHeight = 10;
display.setTextSize(_prefs->smallTextSize());
int lineHeight = _prefs->smallLineH() + 1;
int y = 14;
int visibleCount = (display.height() - 14 - 14) / (lineHeight * 2 + 2);
@@ -643,14 +645,14 @@ public:
display.drawRect(0, 11, display.width(), 1);
if (_msgCount == 0) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 25);
display.print("No messages");
display.setTextSize(1);
} else {
display.setTextSize(0);
int lineHeight = 10;
display.setTextSize(_prefs->smallTextSize());
int lineHeight = _prefs->smallLineH() + 1;
int headerHeight = 14;
int footerHeight = 14;
@@ -764,12 +766,13 @@ public:
// Message body
display.setCursor(0, 14);
display.setColor(DisplayDriver::LIGHT);
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
uint16_t testWidth = display.getTextWidth("MMMMMMMMMM");
int charsPerLine = (testWidth > 0) ? (display.width() * 10) / testWidth : 20;
if (charsPerLine < 12) charsPerLine = 12;
int composeLH = _prefs->smallLineH() + 1;
int y = 14;
int x = 0;
char cs[2] = {0, 0};
@@ -780,7 +783,7 @@ public:
x++;
if (x >= charsPerLine) {
x = 0;
y += 10;
y += composeLH;
}
}
@@ -827,7 +830,7 @@ public:
int cnt = smsContacts.count();
if (cnt == 0) {
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 25);
display.print("No contacts saved");
@@ -837,8 +840,8 @@ public:
display.print("and press A to add");
display.setTextSize(1);
} else {
display.setTextSize(0);
int lineHeight = 10;
display.setTextSize(_prefs->smallTextSize());
int lineHeight = _prefs->smallLineH() + 1;
int y = 14;
int visibleCount = (display.height() - 14 - 14) / (lineHeight * 2 + 2);
@@ -900,7 +903,7 @@ public:
display.drawRect(0, 11, display.width(), 1);
// Phone number (read-only)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 16);
display.print("Phone: ");
@@ -956,7 +959,7 @@ public:
display.print(dispName);
// Phone number below name (smaller, dimmer)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(4, 36);
display.print(_callPhone);
@@ -1011,7 +1014,7 @@ public:
display.print(dispName);
// Phone number below name (smaller, dimmer)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(4, 36);
display.print(_callPhone);
@@ -1070,7 +1073,7 @@ public:
display.print(dispName);
// Phone number below name (smaller, dimmer)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(4, 36);
display.print(_callPhone);
@@ -1090,7 +1093,7 @@ public:
display.print(timeBuf);
// Volume (left-aligned)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
char volLabel[12];
snprintf(volLabel, sizeof(volLabel), "Vol: %d/5", _callVolume);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+136 -2
View File
@@ -30,6 +30,14 @@
#include "WebReaderScreen.h"
#endif
#ifdef MECK_AUDIO_VARIANT
#include "AlarmScreen.h"
#endif
#if defined(LilyGo_T5S3_EPaper_Pro)
#include "VirtualKeyboard.h"
#endif
// MapScreen.h included in UITask.cpp and main.cpp only (PNGdec headers
// conflict with BLE if pulled into the global include chain)
@@ -52,6 +60,9 @@ class UITask : public AbstractUITask {
NodePrefs* _node_prefs;
char _alert[80];
unsigned long _alert_expiry;
bool _hintActive = false; // Boot navigation hint overlay
unsigned long _hintExpiry = 0; // Auto-dismiss time for hint
bool _pendingBootHint = false; // Deferred hint — show after splash screen
int _msgcount;
unsigned long ui_started_at, next_batt_chck;
uint8_t _low_batt_count = 0; // Consecutive low-voltage readings for debounce
@@ -70,21 +81,78 @@ class UITask : public AbstractUITask {
UIScreen* home;
UIScreen* msg_preview;
UIScreen* channel_screen; // Channel message history screen
UIScreen* channel_picker_screen; // Channel picker (bubble/list view)
UIScreen* contacts_screen; // Contacts list screen
UIScreen* text_reader; // *** NEW: Text reader screen ***
UIScreen* notes_screen; // Notes editor screen
UIScreen* settings_screen; // Settings/onboarding screen
UIScreen* audiobook_screen; // Audiobook player screen (null if not available)
#ifdef MECK_AUDIO_VARIANT
UIScreen* alarm_screen; // Alarm clock screen (audio variant only)
UIScreen* voice_screen; // Voice message screen (audio variant only)
#endif
#ifdef HAS_4G_MODEM
UIScreen* sms_screen; // SMS messaging screen (4G variant only)
#endif
UIScreen* repeater_admin; // Repeater admin screen
UIScreen* path_editor; // Custom path editor screen (lazy-init)
UIScreen* discovery_screen; // Node discovery scan screen
UIScreen* last_heard_screen; // Last heard passive advert list
#ifdef MECK_WEB_READER
UIScreen* web_reader; // Web reader screen (lazy-init, WiFi required)
#endif
UIScreen* map_screen; // Map tile screen (GPS + SD card tiles)
UIScreen* curr;
bool _homeShowingTiles = false; // Set by HomeScreen render when tile grid is visible
int _tileGridVY = 44; // Virtual Y of tile grid top (updated each render)
#if defined(LilyGo_T5S3_EPaper_Pro)
UIScreen* lock_screen; // Lock screen (big clock + battery + unread)
UIScreen* _screenBeforeLock = nullptr;
bool _locked = false;
unsigned long _lastInputMillis = 0; // Auto-lock idle tracking
unsigned long _lastLockRefresh = 0; // Periodic lock screen clock update
VirtualKeyboard _vkb;
bool _vkbActive = false;
UIScreen* _screenBeforeVKB = nullptr;
unsigned long _vkbOpenedAt = 0;
// Powersaving: light sleep when locked + idle (standalone only — no BLE/WiFi)
// Wakes on LoRa packet (DIO1), boot button (GPIO0), or 30-min timer
#if !defined(BLE_PIN_CODE) && !defined(MECK_WIFI_COMPANION)
unsigned long _psLastActive = 0; // millis() at last wake or lock entry
unsigned long _psNextSleepSecs = 60; // Seconds before first sleep (60s), then 5s cycles
#endif
#ifdef MECK_CARDKB
bool _cardkbDetected = false;
#endif
#elif defined(LilyGo_TDeck_Pro)
UIScreen* lock_screen; // Lock screen (big clock + battery + unread)
UIScreen* _screenBeforeLock = nullptr;
bool _locked = false;
unsigned long _lastInputMillis = 0; // Auto-lock idle tracking
unsigned long _lastLockRefresh = 0; // Periodic lock screen clock update
#endif
// --- Message dedup ring buffer (suppress retry spam at UI level) ---
#define MSG_DEDUP_SIZE 8
#define MSG_DEDUP_WINDOW_MS 60000 // 60 seconds
struct MsgDedup {
uint32_t name_hash;
uint32_t text_hash;
unsigned long millis;
};
MsgDedup _dedup[MSG_DEDUP_SIZE];
int _dedupIdx = 0;
// --- Per-contact DM unread tracking ---
uint8_t* _dmUnread = nullptr; // PSRAM-allocated, MAX_CONTACTS entries
static uint32_t simpleHash(const char* s) {
uint32_t h = 5381;
while (*s) { h = ((h << 5) + h) ^ (uint8_t)*s++; }
return h;
}
void userLedHandler();
@@ -112,16 +180,28 @@ public:
void begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs);
void gotoHomeScreen();
void gotoChannelScreen(); // Navigate to channel message screen
void gotoChannelScreen(bool resetDmView = true); // Navigate to channel message screen
void gotoChannelPickerScreen(); // Navigate to channel picker (bubble/list)
void gotoDMTab(); // Navigate directly to DM tab on channel screen
void gotoDMConversation(const char* contactName, int contactIdx = -1, uint8_t perms = 0);
void gotoContactsScreen(); // Navigate to contacts list
void gotoTextReader(); // *** NEW: Navigate to text reader ***
void gotoNotesScreen(); // Navigate to notes editor
void gotoSettingsScreen(); // Navigate to settings
void gotoOnboarding(); // Navigate to settings in onboarding mode
void gotoAudiobookPlayer(); // Navigate to audiobook player
#ifdef MECK_AUDIO_VARIANT
void gotoAlarmScreen(); // Navigate to alarm clock
void gotoVoiceScreen(); // Navigate to voice message recorder
#endif
void gotoRepeaterAdmin(int contactIdx); // Navigate to repeater admin
void gotoRepeaterAdminDirect(int contactIdx); // Auto-login admin (L key from conversation)
void gotoPathEditor(int contactIdx); // Navigate to custom path editor
void gotoDiscoveryScreen(); // Navigate to node discovery scan
void gotoLastHeardScreen(); // Navigate to last heard passive list
#if HAS_GPS
void gotoMapScreen(); // Navigate to map tile screen
#endif
#ifdef MECK_WEB_READER
void gotoWebReader(); // Navigate to web reader (browser)
#endif
@@ -132,6 +212,9 @@ public:
#endif
void showAlert(const char* text, int duration_millis) override;
void forceRefresh() override { _next_refresh = 100; }
void showBootHint(bool immediate = false); // Show navigation hint overlay on first boot
void dismissBootHint(); // Dismiss hint and save preference
bool isHintActive() const { return _hintActive; }
// Wake display and extend auto-off timer. Call this when handling keys
// outside of injectKey() to prevent display auto-off during direct input.
void keepAlive() {
@@ -140,17 +223,55 @@ public:
}
int getMsgCount() const { return _msgcount; }
int getUnreadMsgCount() const; // Per-channel unread tracking (standalone)
// Per-contact DM unread tracking
bool hasDMUnread(int contactIdx) const;
int getDMUnreadCount(int contactIdx) const;
void clearDMUnread(int contactIdx);
// Flag: suppress room→conversation redirect on next login (L key admin access)
bool _skipRoomRedirect = false;
bool hasDisplay() const { return _display != NULL; }
bool isButtonPressed() const;
bool isOnChannelScreen() const { return curr == channel_screen; }
bool isOnChannelPickerScreen() const { return curr == channel_picker_screen; }
bool isOnContactsScreen() const { return curr == contacts_screen; }
bool isOnTextReader() const { return curr == text_reader; } // *** NEW ***
bool isOnHomeScreen() const { return curr == home; }
bool isHomeShowingTiles() const { return _homeShowingTiles; }
void setHomeShowingTiles(bool v) { _homeShowingTiles = v; }
int getTileGridVY() const { return _tileGridVY; }
void setTileGridVY(int vy) { _tileGridVY = vy; }
bool isOnNotesScreen() const { return curr == notes_screen; }
bool isOnSettingsScreen() const { return curr == settings_screen; }
bool isOnAudiobookPlayer() const { return curr == audiobook_screen; }
#ifdef MECK_AUDIO_VARIANT
bool isOnAlarmScreen() const { return curr == alarm_screen; }
bool isOnVoiceScreen() const { return curr == voice_screen; }
#endif
bool isOnRepeaterAdmin() const { return curr == repeater_admin; }
bool isOnPathEditor() const { return curr == path_editor; }
bool isOnDiscoveryScreen() const { return curr == discovery_screen; }
bool isOnLastHeardScreen() const { return curr == last_heard_screen; }
bool isOnMapScreen() const { return curr == map_screen; }
#if defined(LilyGo_T5S3_EPaper_Pro) || defined(LilyGo_TDeck_Pro)
bool isLocked() const { return _locked; }
void lockScreen();
void unlockScreen();
#endif
#if defined(LilyGo_T5S3_EPaper_Pro)
bool isVKBActive() const { return _vkbActive; }
unsigned long vkbOpenedAt() const { return _vkbOpenedAt; }
VirtualKeyboard& getVKB() { return _vkb; }
void showVirtualKeyboard(VKBPurpose purpose, const char* label, const char* initial, int maxLen, int contextIdx = 0);
void onVKBSubmit();
void onVKBCancel();
#ifdef MECK_CARDKB
void setCardKBDetected(bool v) { _cardkbDetected = v; }
bool hasCardKB() const { return _cardkbDetected; }
void feedCardKBChar(char c);
#endif
#endif
#ifdef MECK_WEB_READER
bool isOnWebReader() const { return curr == web_reader; }
#endif
@@ -168,12 +289,15 @@ public:
// Check if home screen is in an editing mode (e.g. UTC offset editor)
bool isEditingHomeScreen() const;
// Check if home screen is showing the Recent Adverts page
bool isHomeOnRecentPage() const;
// Inject a key press from external source (e.g., keyboard)
void injectKey(char c);
// Add a sent message to the channel screen history
void addSentChannelMessage(uint8_t channel_idx, const char* sender, const char* text) override;
void addSentDM(const char* recipientName, const char* sender, const char* text);
// Mark channel as read when BLE companion app syncs messages
void markChannelReadFromBLE(uint8_t channel_idx) override;
@@ -190,11 +314,21 @@ public:
UIScreen* getNotesScreen() const { return notes_screen; }
UIScreen* getContactsScreen() const { return contacts_screen; }
UIScreen* getChannelScreen() const { return channel_screen; }
UIScreen* getChannelPickerScreen() const { return channel_picker_screen; }
UIScreen* getSettingsScreen() const { return settings_screen; }
NodePrefs* getNodePrefs() const { return _node_prefs; }
UIScreen* getAudiobookScreen() const { return audiobook_screen; }
void setAudiobookScreen(UIScreen* s) { audiobook_screen = s; }
#ifdef MECK_AUDIO_VARIANT
UIScreen* getAlarmScreen() const { return alarm_screen; }
void setAlarmScreen(UIScreen* s) { alarm_screen = s; }
UIScreen* getVoiceScreen() const { return voice_screen; }
void setVoiceScreen(UIScreen* s) { voice_screen = s; }
#endif
UIScreen* getRepeaterAdminScreen() const { return repeater_admin; }
UIScreen* getPathEditorScreen() const { return path_editor; }
UIScreen* getDiscoveryScreen() const { return discovery_screen; }
UIScreen* getLastHeardScreen() const { return last_heard_screen; }
UIScreen* getMapScreen() const { return map_screen; }
#ifdef MECK_WEB_READER
UIScreen* getWebReaderScreen() const { return web_reader; }
@@ -203,7 +337,7 @@ public:
// from AbstractUITask
void msgRead(int msgcount) override;
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount,
const uint8_t* path = nullptr) override;
const uint8_t* path = nullptr, int8_t snr = 0) override;
void notify(UIEventType t = UIEventType::none) override;
void loop() override;
File diff suppressed because it is too large Load Diff
+364 -46
View File
@@ -39,6 +39,7 @@
#include "ModemManager.h"
#endif
#include "Utf8CP437.h"
#include "../NodePrefs.h"
// Forward declarations
class UITask;
@@ -1030,8 +1031,10 @@ public:
private:
UITask* _task;
NodePrefs* _prefs;
Mode _mode;
bool _initialized;
uint8_t _lastFontPref;
DisplayDriver* _display;
// Display layout (calculated once)
@@ -1072,9 +1075,12 @@ private:
// Bookmarks & History
std::vector<String> _bookmarks;
std::vector<String> _history;
int _homeSelected; // Selected item in home view (0=URL bar, then bookmarks, then history)
int _homeSelected; // Selected item in home view (0=IRC, 1=URL, 2=Search, then bookmarks, then history)
int _homeScrollY; // Pixel scroll offset for home view
bool _urlEditing; // True when URL bar is active for text entry
bool _searchEditing; // True when search bar is active for text entry
char _searchBuffer[128]; // Search query text
int _searchLen;
// Link selection
int _linkInput; // Accumulated link number digits
@@ -1421,7 +1427,7 @@ private:
_display->print("WiFi Setup");
_display->drawRect(0, 11, _display->width(), 1);
_display->setColor(DisplayDriver::LIGHT);
_display->setTextSize(0);
_display->setTextSize(_prefs->smallTextSize());
_display->setCursor(0, 18);
_display->print("Scanning for networks...");
_display->endFrame();
@@ -1521,7 +1527,7 @@ private:
_display->print("Web Reader");
_display->drawRect(0, 11, _display->width(), 1);
_display->setTextSize(0);
_display->setTextSize(_prefs->smallTextSize());
_display->setCursor(0, 18);
_display->print("Connected!");
_display->setCursor(0, 30);
@@ -2149,6 +2155,8 @@ private:
needsFreshTls = true; // Recreate at top of next iteration (after http destructor)
// After 2 failures, try WiFi reconnect — the lwIP stack may be wedged
// Skip on WiFi companion variant — disconnect kills the companion TCP server
#ifndef MECK_WIFI_COMPANION
if (totalRetries == 2 && isWiFiConnected()) {
Serial.println("WebReader: WiFi reconnect after persistent failures");
// Destroy TLS before WiFi teardown
@@ -2167,6 +2175,7 @@ private:
Serial.printf("WebReader: WiFi reconnected, IP: %s\n",
WiFi.localIP().toString().c_str());
}
#endif
int retryDelay = 1000 + totalRetries * 1000; // 2s, 3s, 4s, 5s
Serial.printf("WebReader: Connection error %d, retrying in %dms... (attempt %d/4)\n",
@@ -2243,6 +2252,8 @@ private:
clearCloudflareCookies(domain);
// WiFi reconnect after 2 total failures (same logic as conn errors)
// Skip on WiFi companion variant — disconnect kills the companion TCP server
#ifndef MECK_WIFI_COMPANION
if (totalRetries == 2 && isWiFiConnected()) {
Serial.println("WebReader: WiFi reconnect after persistent failures");
if (_tlsClient) { delete _tlsClient; _tlsClient = nullptr; }
@@ -2259,6 +2270,7 @@ private:
Serial.printf("WebReader: WiFi reconnected, IP: %s\n",
WiFi.localIP().toString().c_str());
}
#endif
int retryDelay = 1000 + totalRetries * 1000; // 2s, 3s, 4s, 5s
Serial.printf("WebReader: Server error %d, retrying in %dms... (attempt %d/4)\n",
@@ -2297,7 +2309,7 @@ private:
_display->print("Web Reader");
_display->drawRect(0, 11, _display->width(), 1);
_display->setColor(DisplayDriver::YELLOW);
_display->setTextSize(0);
_display->setTextSize(_prefs->smallTextSize());
_display->setCursor(0, 18);
_display->print("Fetch failed:");
_display->setColor(DisplayDriver::LIGHT);
@@ -2433,7 +2445,7 @@ private:
_display->setTextSize(2);
_display->setCursor(10, 20);
_display->print("Logging in...");
_display->setTextSize(0);
_display->setTextSize(_prefs->smallTextSize());
_display->setColor(DisplayDriver::LIGHT);
_display->setCursor(10, 45);
_display->print("Refreshing session...");
@@ -2647,19 +2659,23 @@ private:
display.drawRect(0, 11, display.width(), 1);
display.setColor(DisplayDriver::LIGHT);
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
if (_wifiState == WIFI_SCANNING) {
display.setCursor(0, 18);
display.print("Scanning for networks...");
} else if (_wifiState == WIFI_SCAN_DONE) {
int y = 14;
int listLineH = 8;
int listLineH = _prefs ? _prefs->smallLineH() : 9;
for (int i = 0; i < _ssidCount && y < display.height() - 24; i++) {
bool selected = (i == _selectedSSID);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width(), listLineH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), listLineH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), display.width(), listLineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -2682,7 +2698,7 @@ private:
y += 12;
display.setCursor(0, y);
display.print("Password:");
y += 10;
y += _prefs->smallLineH() + 1;
display.setCursor(0, y);
// Show masked password with brief reveal of last char
char passBuf[WEB_WIFI_PASS_LEN + 2];
@@ -2727,7 +2743,11 @@ private:
}
display.setCursor(0, 80);
display.setColor(DisplayDriver::GREEN);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap: Retry");
#else
display.print("Enter: Retry Q: Back");
#endif
}
// Footer
@@ -2736,7 +2756,14 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setCursor(0, footerY);
display.setColor(DisplayDriver::YELLOW);
#if defined(LilyGo_T5S3_EPaper_Pro)
if (_wifiState == WIFI_ENTERING_PASS)
display.print("Tap: Enter Password Hold: Back");
else
display.print("Swipe: Navigate Tap: Select");
#else
display.print("Q:Back W/S:Nav Ent:Select");
#endif
}
void renderHome(DisplayDriver& display) {
@@ -2747,7 +2774,7 @@ private:
if (isNetworkAvailable()) {
display.print("Web Reader");
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::GREEN);
if (isWiFiConnected()) {
IPAddress ip = WiFi.localIP();
@@ -2773,12 +2800,12 @@ private:
const int footerY = display.height() - 12;
const int viewportH = display.height() - headerY - footerH;
const int scrollbarW = 4;
const int listLineH = 8;
const int listLineH = _prefs ? _prefs->smallLineH() : 9;
const int sepH = 8; // Separator between IRC and web sections
const int sectionH = listLineH; // Section header height
int maxChars = _charsPerLine - 2; // Account for "> " prefix
if (maxChars < 10) maxChars = 10;
int totalItems = 2 + (int)_bookmarks.size() + (int)_history.size();
int totalItems = 3 + (int)_bookmarks.size() + (int)_history.size();
// ---- Layout pass: compute virtual Y extent of each item ----
// We track: for each selectable item, its (virtualY, height).
@@ -2804,6 +2831,12 @@ private:
virtualY += urlBarH;
itemIdx++;
// Item 2: Search bar
int searchBarH = listLineH + 2;
if (itemIdx == _homeSelected) { selectedTop = virtualY; selectedBot = virtualY + searchBarH; }
virtualY += searchBarH;
itemIdx++;
// Bookmarks
if (_bookmarks.size() > 0) {
virtualY += sectionH; // "-- Bookmarks --" header
@@ -2845,7 +2878,7 @@ private:
if (totalContentH <= viewportH) _homeScrollY = 0;
// ---- Render pass (with scroll offset) ----
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
int y = headerY - _homeScrollY; // Start Y in screen coords
itemIdx = 0;
bool needsScroll = (totalContentH > viewportH);
@@ -2862,7 +2895,11 @@ private:
if (HOME_VISIBLE(y, ircH)) {
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::GREEN);
@@ -2897,7 +2934,11 @@ private:
if (HOME_VISIBLE(y, urlBarH)) {
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -2924,6 +2965,43 @@ private:
itemIdx++;
}
// Item 2: Search bar
{
bool selected = (_homeSelected == itemIdx);
if (HOME_VISIBLE(y, searchBarH)) {
if (selected) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), display.width() - (needsScroll ? scrollbarW + 1 : 0), listLineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
}
display.setCursor(0, y);
if (_searchEditing) {
char searchDisp[140];
int maxShow = maxChars - 8; // "Search: " prefix + cursor
int start = 0;
if (_searchLen > maxShow) start = _searchLen - maxShow;
snprintf(searchDisp, sizeof(searchDisp), "Search: %s_", _searchBuffer + start);
display.print(searchDisp);
} else if (_searchLen > 0) {
char searchDisp[140];
int maxShow = maxChars - 7;
snprintf(searchDisp, sizeof(searchDisp), "Search: %s",
_searchLen > maxShow ? (_searchBuffer + _searchLen - maxShow) : _searchBuffer);
display.print(searchDisp);
} else {
display.print("Search: [DuckDuckGo Lite]");
}
}
y += searchBarH;
itemIdx++;
}
// Bookmarks section
if (_bookmarks.size() > 0) {
// Section header
@@ -2946,7 +3024,11 @@ private:
int contentW = display.width() - (needsScroll ? scrollbarW + 1 : 0);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, contentW, itemH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, contentW, itemH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), contentW, itemH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -2994,7 +3076,11 @@ private:
int contentW = display.width() - (needsScroll ? scrollbarW + 1 : 0);
if (selected) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(0, y + 5, contentW, itemH);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, contentW, itemH);
#else
display.fillRect(0, y + _prefs->smallHighlightOff(), contentW, itemH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -3056,15 +3142,57 @@ private:
display.setColor(DisplayDriver::YELLOW);
if (_urlEditing) {
display.print("Type URL Ent:Go");
} else if (_searchEditing) {
display.print("Type query Ent:Search");
} else {
char footerBuf[48];
#if defined(LilyGo_T5S3_EPaper_Pro)
bool onBookmark = (_homeSelected >= 3 && _homeSelected < 3 + (int)_bookmarks.size());
bool onUrl = (_homeSelected == 1);
bool onSearch = (_homeSelected == 2);
if (onUrl)
snprintf(footerBuf, sizeof(footerBuf), "Tap: Enter URL Hold: Back");
else if (onSearch)
snprintf(footerBuf, sizeof(footerBuf), "Tap: Search Hold: Back");
else if (onBookmark)
snprintf(footerBuf, sizeof(footerBuf), "Swipe: Navigate Tap: Open Hold: Delete");
else
snprintf(footerBuf, sizeof(footerBuf), "Swipe: Navigate Tap: Open Hold: Exit");
#else
bool hasData = (_cookieCount > 0 || !_history.empty());
if (hasData)
snprintf(footerBuf, sizeof(footerBuf), "Q:Bk W/S Ent:Go X:Clr");
bool onBookmark = (_homeSelected >= 3 && _homeSelected < 3 + (int)_bookmarks.size());
if (onBookmark && hasData)
snprintf(footerBuf, sizeof(footerBuf), "Ent:Go Del:Del Bkmk X:Clr Ckies");
else if (onBookmark)
snprintf(footerBuf, sizeof(footerBuf), "Q:Bk Ent:Go Del:Del Bkmk");
else if (hasData)
snprintf(footerBuf, sizeof(footerBuf), "Q:Bk W/S Ent:Go X:Clr Ckies");
else
snprintf(footerBuf, sizeof(footerBuf), "Q:Bk W/S:Nav Ent:Go");
#endif
display.print(footerBuf);
}
// Toast notification overlay (for bookmark deleted, etc.)
if (_toastMsg[0] && (millis() - _toastTime < 1500)) {
display.setTextSize(1);
int tw = display.getTextWidth(_toastMsg);
int bw = tw + 16;
int bh = 20;
int bx = (display.width() - bw) / 2;
int by = (display.height() - bh) / 2;
display.setColor(DisplayDriver::DARK);
display.fillRect(bx, by, bw, bh);
display.setColor(DisplayDriver::LIGHT);
display.drawRect(bx, by, bw, 1);
display.drawRect(bx, by + bh - 1, bw, 1);
display.drawRect(bx, by, 1, bh);
display.drawRect(bx + bw - 1, by, 1, bh);
display.setCursor(bx + 8, by + 5);
display.print(_toastMsg);
} else if (_toastMsg[0]) {
_toastMsg[0] = '\0';
}
}
void renderFetching(DisplayDriver& display) {
@@ -3073,17 +3201,27 @@ private:
display.setCursor(10, 20);
display.print("Loading...");
display.setTextSize(1);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(10, 45);
// Show truncated URL
char urlDisp[40];
strncpy(urlDisp, _urlBuffer, 38);
urlDisp[38] = '\0';
display.print(urlDisp);
// Word-wrap the URL across multiple lines
int urlLen = strlen(_urlBuffer);
int y = 45;
int off = 0;
int maxChars = _charsPerLine > 2 ? _charsPerLine - 2 : 30; // small margin
while (off < urlLen && y < 85) {
int lineLen = urlLen - off;
if (lineLen > maxChars) lineLen = maxChars;
char lineBuf[128];
snprintf(lineBuf, sizeof(lineBuf), "%.*s", lineLen, _urlBuffer + off);
display.setCursor(10, y);
display.print(lineBuf);
off += lineLen;
y += 8;
}
display.setCursor(10, 60);
display.setCursor(10, y + 4);
display.setTextSize(1);
char progBuf[48];
int elapsed = (int)((millis() - _fetchStartTime) / 1000);
if (_fetchRetryCount > 0) {
@@ -3108,7 +3246,7 @@ private:
display.print("Download Complete");
display.drawRect(0, 11, display.width(), 1);
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 16);
display.print("Saved to /books/:");
@@ -3130,15 +3268,19 @@ private:
display.setCursor(0, y + 6);
display.setColor(DisplayDriver::GREEN);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap: Open in Reader");
#else
display.print("Ent: Open in Reader");
display.setCursor(0, y + 16);
display.print("Q: Back to browser");
#endif
} else {
display.setColor(DisplayDriver::YELLOW);
display.print("Download Failed");
display.drawRect(0, 11, display.width(), 1);
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, 18);
display.print(_fetchError.c_str());
@@ -3147,7 +3289,11 @@ private:
display.setCursor(0, 56);
display.setColor(DisplayDriver::GREEN);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap: Back to browser");
#else
display.print("Q: Back to browser");
#endif
}
// Footer
@@ -3156,7 +3302,11 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setCursor(0, footerY);
display.setColor(DisplayDriver::YELLOW);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print(_downloadOk ? "Tap: Open in Reader" : "Tap: Back");
#else
display.print(_downloadOk ? "Ent:Read Q:Back" : "Q:Back");
#endif
}
void renderReading(DisplayDriver& display) {
@@ -3167,7 +3317,7 @@ private:
return;
}
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
// Determine page bounds
@@ -3284,6 +3434,13 @@ private:
if (_linkInputActive) {
snprintf(linkBuf, sizeof(linkBuf), "#%d_ Ent:Go", _linkInput);
hint = linkBuf;
#if defined(LilyGo_T5S3_EPaper_Pro)
} else if (_linkCount > 0) {
hint = "Tap: Page | Tap Footer Bar: Enter Link # | Hold: Back";
} else {
hint = "Tap: Page Hold: Back";
}
#else
} else if (_formCount > 0 && _linkCount > 0) {
hint = "L:Lnk F:Frm B:Bk Q:X";
} else if (_formCount > 0) {
@@ -3293,6 +3450,7 @@ private:
} else {
hint = "B:Bk Q:X";
}
#endif
display.setCursor(display.width() - display.getTextWidth(hint) - 2, footerY);
display.print(hint);
@@ -3321,9 +3479,16 @@ private:
// ---- Layout Initialization ----
void initLayout(DisplayDriver& display) {
// Re-init if font preference changed since last layout
uint8_t curFont = _prefs ? _prefs->large_font : 0;
if (_initialized && curFont != _lastFontPref) {
_initialized = false;
Serial.println("WebReader: font changed, recalculating layout");
}
if (_initialized) return;
_lastFontPref = curFont;
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
uint16_t mWidth = display.getTextWidth("M");
if (mWidth > 0) {
_charsPerLine = display.width() / mWidth;
@@ -3332,6 +3497,19 @@ private:
_charsPerLine = 40;
_lineHeight = 5;
}
// Proportional font: use average-width measurement instead of M-width
if (_prefs && _prefs->large_font && mWidth > 0) {
const char* sample = "the quick brown fox jumps over lazy dog";
uint16_t sampleW = display.getTextWidth(sample);
int sampleLen = strlen(sample);
if (sampleW > 0 && sampleLen > 0) {
_charsPerLine = (display.width() * sampleLen * 70) / ((int)sampleW * 100);
}
}
// Large font: formula above assumes built-in 6x8 ratio — too small for 9pt
if (_prefs && _prefs->large_font) {
_lineHeight = _prefs->smallLineH();
}
_footerHeight = 14;
int textAreaHeight = display.height() - _footerHeight;
@@ -3409,7 +3587,7 @@ private:
}
bool handleHomeInput(char c) {
int totalItems = 2 + _bookmarks.size() + _history.size(); // IRC + URL + bookmarks + history
int totalItems = 3 + _bookmarks.size() + _history.size(); // IRC + URL + Search + bookmarks + history
if (_urlEditing) {
// URL text entry mode
@@ -3464,6 +3642,67 @@ private:
return true; // Consume all keys in editing mode
}
// Search text entry mode
if (_searchEditing) {
if (c == '\r' || c == 13) {
if (_searchLen > 0) {
_searchEditing = false;
// Build DuckDuckGo Lite search URL
// URL-encode the query: spaces become +, special chars become %XX
char encoded[256];
int ei = 0;
for (int i = 0; i < _searchLen && ei < (int)sizeof(encoded) - 4; i++) {
char ch = _searchBuffer[i];
if (ch == ' ') {
encoded[ei++] = '+';
} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') || ch == '-' || ch == '_' || ch == '.' || ch == '~') {
encoded[ei++] = ch;
} else {
if (ei < (int)sizeof(encoded) - 4) {
snprintf(encoded + ei, 4, "%%%02X", (unsigned char)ch);
ei += 3;
}
}
}
encoded[ei] = '\0';
snprintf(_urlBuffer, WEB_MAX_URL_LEN, "https://html.duckduckgo.com/lite/?q=%s", encoded);
_urlLen = strlen(_urlBuffer);
if (!isNetworkAvailable()) {
_mode = WIFI_SETUP;
if (!loadAndAutoConnect()) {
startWifiScan();
} else {
fetchWithSelfRef(_urlBuffer);
}
} else {
fetchWithSelfRef(_urlBuffer);
}
}
return true;
}
if (c == '\b' || c == 127) {
if (_searchLen > 0) {
_searchBuffer[--_searchLen] = '\0';
}
return true;
}
if (c == 'q' && _searchLen == 0) {
_searchEditing = false;
return true;
}
if (c == 0x1B) { // ESC
_searchEditing = false;
return true;
}
if (c >= 32 && c < 127 && _searchLen < (int)sizeof(_searchBuffer) - 1) {
_searchBuffer[_searchLen++] = c;
_searchBuffer[_searchLen] = '\0';
return true;
}
return true; // Consume all keys in search editing mode
}
// Normal navigation
if (c == 'w' || c == 'W' || c == 0xF2) {
if (_homeSelected > 0) _homeSelected--;
@@ -3494,9 +3733,14 @@ private:
_urlEditing = true;
return true;
}
// Bookmark or history item selected (offset by 2 for IRC + URL)
if (_homeSelected == 2) {
// Activate search editing
_searchEditing = true;
return true;
}
// Bookmark or history item selected (offset by 3 for IRC + URL + Search)
const char* selectedUrl = nullptr;
int bmIdx = _homeSelected - 2;
int bmIdx = _homeSelected - 3;
if (bmIdx < (int)_bookmarks.size()) {
selectedUrl = _bookmarks[bmIdx].c_str();
} else {
@@ -3522,6 +3766,25 @@ private:
return true;
}
// Delete/Backspace - remove selected bookmark
if (c == '\b' || c == 127) {
int bmIdx = _homeSelected - 3;
if (bmIdx >= 0 && bmIdx < (int)_bookmarks.size()) {
_bookmarks.erase(_bookmarks.begin() + bmIdx);
saveBookmarks();
// Adjust selection if we deleted the last item
int newTotal = 3 + _bookmarks.size() + _history.size();
if (_homeSelected >= newTotal && _homeSelected > 0) {
_homeSelected--;
}
strncpy(_toastMsg, "Bookmark deleted", sizeof(_toastMsg));
_toastTime = millis();
Serial.printf("WebReader: Deleted bookmark %d\n", bmIdx);
return true;
}
return false;
}
// X - clear all cookies
if (c == 'x' || c == 'X') {
bool hadData = (_cookieCount > 0 || !_history.empty());
@@ -3691,7 +3954,7 @@ private:
if (_activeForm < 0 || _activeForm >= _formCount) return;
WebForm& form = _forms[_activeForm];
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
// Header
display.setColor(DisplayDriver::GREEN);
@@ -3714,7 +3977,7 @@ private:
display.drawRect(0, 9, display.width(), 1);
int y = 12;
int lineH = 10; // Taller lines for form fields
int lineH = _prefs->smallLineH() + 1; // Taller lines for form fields
int visCount = getVisibleFieldCount(form);
// Render each visible field
@@ -3734,7 +3997,11 @@ private:
// Field value
if (isActive) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), 9);
#else
display.fillRect(0, y + 4, display.width(), 9);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -3804,10 +4071,14 @@ private:
display.print("Type text Ent:Next Q:Undo");
} else {
const char* hint;
#if defined(LilyGo_T5S3_EPaper_Pro)
hint = "Swipe: Navigate Tap: Edit Hold: Back";
#else
if (_formCount > 1)
hint = "W/S:Nav Ent:Edit </>:Form Q:Back";
else
hint = "W/S:Nav Ent:Edit/Go Q:Back";
#endif
display.print(hint);
}
}
@@ -4414,9 +4685,9 @@ private:
display.print("IRC Setup");
display.drawRect(0, 11, display.width(), 1);
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
int y = 16;
int lineH = 10;
int lineH = _prefs->smallLineH() + 1;
const char* labels[] = {"Server:", "Port:", "Nick:", "Channel:", "[ Connect ]"};
const char* chanDisp = (_ircChannel[0] != '\0') ? _ircChannel : "(none)";
@@ -4428,7 +4699,11 @@ private:
bool sel = (_ircSetupField == i);
if (sel) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(0, y, display.width(), lineH);
#else
display.fillRect(0, y + 4, display.width(), lineH);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -4476,7 +4751,11 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setCursor(0, footerY);
display.setColor(DisplayDriver::YELLOW);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Swipe: Navigate Tap: Edit Hold: Back");
#else
display.print("W/S:Nav Ent:Edit/Go Q:Back");
#endif
}
bool handleIRCSetupInput(char c) {
@@ -4566,7 +4845,7 @@ private:
display.print(header);
// Connection indicator on right
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
if (!_ircConnected) {
display.setColor(DisplayDriver::YELLOW);
display.setCursor(display.width() - 42, -3);
@@ -4592,7 +4871,7 @@ private:
if (_ircComposing) {
// Compose text just above separator (tiny font to match messages)
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
display.setColor(DisplayDriver::LIGHT);
display.setCursor(0, footerY - 12);
char compDisp[IRC_COMPOSE_MAX + 4];
@@ -4606,18 +4885,26 @@ private:
display.setTextSize(1);
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap: Send Hold: Exit");
#else
display.print("Ent:Send Del:Exit");
#endif
} else {
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, footerY);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.print("Tap: Compose Swipe: Scroll Hold: Back");
#else
display.print("Ent:Msg W/S:Scrl Q:Bk");
#endif
}
// Message area
display.setTextSize(0);
display.setTextSize(_prefs->smallTextSize());
int msgAreaTop = 14;
int msgAreaBottom = _ircComposing ? footerY - 16 : footerY - 4;
int lineH = 8;
int lineH = _prefs->smallLineH() - 1;
int scrollBarW = 4;
int lineW = _charsPerLine - 1; // Reserve space for scroll bar
_ircLinesPerPage = (msgAreaBottom - msgAreaTop) / lineH;
@@ -4801,14 +5088,15 @@ private:
}
public:
WebReaderScreen(UITask* task)
: _task(task), _mode(HOME), _initialized(false), _display(nullptr),
WebReaderScreen(UITask* task, NodePrefs* prefs = nullptr)
: _task(task), _prefs(prefs), _mode(HOME), _initialized(false), _lastFontPref(0), _display(nullptr),
_charsPerLine(40), _linesPerPage(15), _lineHeight(5), _footerHeight(14),
_wifiState(WIFI_IDLE), _ssidCount(0), _selectedSSID(0), _wifiPassLen(0),
_urlLen(0), _urlCursor(0),
_textBuffer(nullptr), _textLen(0), _links(nullptr), _linkCount(0),
_currentPage(0), _totalPages(0),
_homeSelected(0), _homeScrollY(0), _urlEditing(false),
_searchEditing(false), _searchLen(0),
_linkInput(0), _linkInputActive(false),
_formCount(0), _forms(nullptr), _activeForm(-1), _activeField(0),
_formFieldEditing(false), _formEditLen(0), _formLastCharAt(0),
@@ -4825,6 +5113,7 @@ public:
_ircLastDataTime(0), _ircReconnectAt(0),
_ircDirty(false), _ircLastRender(0) {
_urlBuffer[0] = '\0';
_searchBuffer[0] = '\0';
_wifiPass[0] = '\0';
_pageTitle[0] = '\0';
_currentUrl[0] = '\0';
@@ -4860,6 +5149,7 @@ public:
// Called when entering the web reader screen
void enter(DisplayDriver& display) {
_display = &display;
_fetchError = ""; // Clear stale errors from previous session
initLayout(display);
loadBookmarks();
loadHistory();
@@ -4883,7 +5173,7 @@ public:
_display->print("Web Reader");
_display->drawRect(0, 11, _display->width(), 1);
_display->setColor(DisplayDriver::LIGHT);
_display->setTextSize(0);
_display->setTextSize(_prefs->smallTextSize());
_display->setCursor(0, 18);
_display->print("Connecting to WiFi...");
_display->endFrame();
@@ -4969,6 +5259,7 @@ public:
_homeSelected = 0;
_homeScrollY = 0;
_urlEditing = false;
_searchEditing = false;
Serial.printf("WebReader: exitReader - heap after: %d, largest: %d\n",
ESP.getFreeHeap(), ESP.getMaxAllocHeap());
@@ -4987,13 +5278,40 @@ public:
return _mode == FORM_FILL && _formFieldEditing;
}
bool isSearchEditing() const {
return false; // TODO: page text search not yet implemented
return _searchEditing && _mode == HOME;
}
bool isIRCMode() const { return _mode == IRC_CHAT || _mode == IRC_SETUP; }
bool isIRCTextEntry() const {
return (_mode == IRC_CHAT && _ircComposing) ||
(_mode == IRC_SETUP && _ircSetupEditing);
}
// ---- Accessors for T5S3 touch mapping and VKB integration ----
int getHomeSelected() const { return _homeSelected; }
int getLinkCount() const { return _linkCount; }
int getBookmarkCount() const { return (int)_bookmarks.size(); }
const char* getUrlText() const { return _urlBuffer; }
// Set URL text and activate editing mode (for VKB submit)
void setUrlText(const char* text) {
strncpy(_urlBuffer, text, WEB_MAX_URL_LEN - 1);
_urlBuffer[WEB_MAX_URL_LEN - 1] = '\0';
_urlLen = strlen(_urlBuffer);
_urlEditing = true;
}
// Set search text and activate editing mode (for VKB submit)
void setSearchText(const char* text) {
strncpy(_searchBuffer, text, sizeof(_searchBuffer) - 1);
_searchBuffer[sizeof(_searchBuffer) - 1] = '\0';
_searchLen = strlen(_searchBuffer);
_searchEditing = true;
}
// Set WiFi password text (for VKB submit)
void setWifiPassText(const char* text) {
strncpy(_wifiPass, text, WEB_WIFI_PASS_LEN - 1);
_wifiPass[WEB_WIFI_PASS_LEN - 1] = '\0';
_wifiPassLen = strlen(_wifiPass);
}
// Returns true if a password reveal is active and needs a refresh after expiry
bool needsRevealRefresh() const {
if (_formLastCharAt > 0 && (millis() - _formLastCharAt) < 900) {
+92 -68
View File
@@ -1,7 +1,7 @@
#pragma once
// Emoji Picker with scrolling grid and scroll bar
// 5 columns, 4 visible rows, scrollable through all 65 emoji
// 5 columns, 4 visible rows, scrollable through all 76 emoji
// WASD navigation, Enter to select, $/Q/Backspace to cancel
#include <helpers/ui/DisplayDriver.h>
@@ -12,71 +12,85 @@
#define EMOJI_PICKER_TOTAL_ROWS ((EMOJI_COUNT + EMOJI_PICKER_COLS - 1) / EMOJI_PICKER_COLS)
static const char* EMOJI_LABELS[EMOJI_COUNT] = {
// Faces/emotion
"Lol", // 0 joy
"Like", // 1 thumbsup
"Sad", // 2 frown
"WiFi", // 3 wireless
"Inf", // 4 infinity
"Rex", // 5 trex
"Skul", // 6 skull
"Cros", // 7 cross
"Bolt", // 8 lightning
"Hat", // 9 tophat
"Moto", // 10 motorcycle
"Leaf", // 11 seedling
"AU", // 12 flag_au
"Umbr", // 13 umbrella
"Eye", // 14 nazar
"Glob", // 15 globe
"Rad", // 16 radioactive
"Cow", // 17 cow
"ET", // 18 alien
"Inv", // 19 invader
"Dagr", // 20 dagger
"Grim", // 21 grimace
"Mtn", // 22 mountain
"End", // 23 end_arrow
"Ring", // 24 hollow_circle
"Drag", // 25 dragon
"Web", // 26 globe_meridians
"Eggp", // 27 eggplant
"Shld", // 28 shield
"Gogl", // 29 goggles
"Lzrd", // 30 lizard
"Zany", // 31 zany_face
"Roo", // 32 kangaroo
"Fthr", // 33 feather
"Sun", // 34 bright
"Wave", // 35 part_alt
"Boat", // 36 motorboat
"Domi", // 37 domino
"Dish", // 38 satellite
"Pass", // 39 customs
"Cowb", // 40 cowboy
"Whl", // 41 wheel
"Koal", // 42 koala
"Knob", // 43 control_knobs
"Pch", // 44 peach
"Race", // 45 racing_car
"Mous", // 46 mouse
"Shrm", // 47 mushroom
"Bio", // 48 biohazard
"Pnda", // 49 panda
"Bang", // 50 anger
"DrgF", // 51 dragon_face
"Pagr", // 52 pager
"Bee", // 53 bee
"Bulb", // 54 bulb
"Cat", // 55 cat
"Flur", // 56 fleur
"Moon", // 57 moon
"Cafe", // 58 coffee
"Toth", // 59 tooth
"Prtz", // 60 pretzel
"Abac", // 61 abacus
"Moai", // 62 moai
"Hiii", // 63 tipping
"Hedg", // 64 hedgehog
"Sad", // 1 frown
"Cry", // 2 loudly_crying
"Grim", // 3 grimace
"Zany", // 4 zany_face
"Cowb", // 5 cowboy
// Thumbsup + heart
"Like", // 6 thumbsup
"Love", // 7 heart
// Everything else
"WiFi", // 8 wireless
"Inf", // 9 infinity
"Rex", // 10 trex
"Skul", // 11 skull
"Cros", // 12 cross
"Bolt", // 13 lightning
"Hat", // 14 tophat
"Moto", // 15 motorcycle
"Leaf", // 16 seedling
"AU", // 17 flag_au
"Umbr", // 18 umbrella
"Eye", // 19 nazar
"Glob", // 20 globe
"Rad", // 21 radioactive
"Cow", // 22 cow
"ET", // 23 alien
"Inv", // 24 invader
"Dagr", // 25 dagger
"Mtn", // 26 mountain
"End", // 27 end_arrow
"Ring", // 28 hollow_circle
"Drag", // 29 dragon
"Web", // 30 globe_meridians
"Eggp", // 31 eggplant
"Shld", // 32 shield
"Gogl", // 33 goggles
"Lzrd", // 34 lizard
"Roo", // 35 kangaroo
"Fthr", // 36 feather
"Sun", // 37 bright
"Wave", // 38 part_alt
"Boat", // 39 motorboat
"Domi", // 40 domino
"Dish", // 41 satellite
"Pass", // 42 customs
"Whl", // 43 wheel
"Koal", // 44 koala
"Knob", // 45 control_knobs
"Pch", // 46 peach
"Race", // 47 racing_car
"Mous", // 48 mouse
"Shrm", // 49 mushroom
"Bio", // 50 biohazard
"Pnda", // 51 panda
"Bang", // 52 anger
"DrgF", // 53 dragon_face
"Pagr", // 54 pager
"Bee", // 55 bee
"Bulb", // 56 bulb
"Cat", // 57 cat
"Flur", // 58 fleur
"Moon", // 59 moon
"Cafe", // 60 coffee
"Toth", // 61 tooth
"Prtz", // 62 pretzel
"Abac", // 63 abacus
"Moai", // 64 moai
"Hiii", // 65 tipping
"Hedg", // 66 hedgehog
"Diam", // 67 diamond_suit
"Spde", // 68 spade_suit
"Piza", // 69 pizza
"Luck", // 70 four_leaf_clover
"Cld", // 71 cloud
"Rckt", // 72 rocket
"HFC", // 73 passport_control
"Star", // 74 eight_spoked_asterisk
"Sig", // 75 signal_strength
};
struct EmojiPicker {
@@ -105,13 +119,23 @@ struct EmojiPicker {
switch (key) {
case 'w': case 'W': case 0xF2:
if (row > 0) cursor -= EMOJI_PICKER_COLS;
if (row > 0) {
cursor -= EMOJI_PICKER_COLS;
} else {
// Wrap to last row, same column
int target = (EMOJI_PICKER_TOTAL_ROWS - 1) * EMOJI_PICKER_COLS + col;
cursor = (target >= EMOJI_COUNT) ? EMOJI_COUNT - 1 : target;
}
break;
case 's': case 'S': case 0xF1:
if (cursor + EMOJI_PICKER_COLS < EMOJI_COUNT)
if (cursor + EMOJI_PICKER_COLS < EMOJI_COUNT) {
cursor += EMOJI_PICKER_COLS;
else if (row < EMOJI_PICKER_TOTAL_ROWS - 1)
} else if (row < EMOJI_PICKER_TOTAL_ROWS - 1) {
cursor = EMOJI_COUNT - 1;
} else {
// Wrap to first row, same column
cursor = col;
}
break;
case 'a': case 'A':
if (cursor > 0) cursor--;
@@ -0,0 +1,288 @@
#ifndef MONTSERRAT12PT7B_H
#define MONTSERRAT12PT7B_H
const uint8_t Montserrat_Regular12pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x8C, 0x63, 0x18, 0xC6, 0x20, 0x04,
0x10, 0x18, 0x20, 0x30, 0x40, 0x61, 0x80, 0x83, 0x1F, 0xFF, 0xC2, 0x08,
0x04, 0x10, 0x08, 0x20, 0x30, 0x40, 0x60, 0x87, 0xFF, 0xE1, 0x06, 0x02,
0x0C, 0x04, 0x10, 0x08, 0x20, 0x10, 0x40, 0x02, 0x00, 0x10, 0x00, 0x80,
0x1F, 0x83, 0xFF, 0x31, 0x09, 0x88, 0x08, 0x40, 0x42, 0x03, 0x10, 0x0E,
0x80, 0x3F, 0x00, 0x3E, 0x01, 0x18, 0x08, 0x60, 0x43, 0x02, 0x1E, 0x11,
0x9E, 0xF8, 0x3F, 0x80, 0x20, 0x01, 0x00, 0x08, 0x00, 0x3C, 0x02, 0x19,
0x81, 0x8C, 0x20, 0xC2, 0x08, 0x20, 0x83, 0x10, 0x20, 0xCC, 0x08, 0x22,
0x01, 0x19, 0x00, 0x3C, 0xCF, 0x00, 0x26, 0x60, 0x11, 0x0C, 0x0C, 0xC1,
0x02, 0x30, 0x41, 0x0C, 0x10, 0xC1, 0x0C, 0x20, 0x62, 0x10, 0x0F, 0x00,
0x0F, 0x80, 0x3B, 0x80, 0xC1, 0x01, 0x82, 0x03, 0x04, 0x03, 0x18, 0x06,
0xE0, 0x07, 0x00, 0x1E, 0x00, 0x66, 0x11, 0x86, 0x36, 0x06, 0x4C, 0x07,
0x98, 0x06, 0x18, 0x0E, 0x3C, 0x76, 0x1F, 0x84, 0xFE, 0x18, 0x8C, 0x46,
0x31, 0x88, 0x42, 0x31, 0x84, 0x21, 0x08, 0x63, 0x18, 0x43, 0x08, 0x60,
0xC4, 0x66, 0x23, 0x33, 0x11, 0x11, 0x11, 0x13, 0x33, 0x26, 0x64, 0xC0,
0x10, 0x10, 0x93, 0x7E, 0x38, 0x7C, 0x93, 0x10, 0x10, 0x0C, 0x03, 0x00,
0xC0, 0x30, 0xFF, 0xC3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x1D, 0xA4,
0xB0, 0xFE, 0x1F, 0x80, 0x00, 0xC0, 0x20, 0x18, 0x06, 0x01, 0x00, 0xC0,
0x30, 0x08, 0x06, 0x01, 0x00, 0x40, 0x30, 0x08, 0x02, 0x01, 0x80, 0x40,
0x30, 0x0C, 0x02, 0x01, 0x80, 0x60, 0x10, 0x00, 0x07, 0x80, 0x7F, 0x83,
0x03, 0x18, 0x06, 0x60, 0x19, 0x00, 0x6C, 0x00, 0xF0, 0x03, 0xC0, 0x0F,
0x00, 0x3C, 0x00, 0xD0, 0x02, 0x60, 0x19, 0x80, 0x63, 0x03, 0x07, 0xF8,
0x0F, 0xC0, 0xFF, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x0C, 0x1F, 0x83, 0xFF, 0x38, 0x18, 0x00, 0x60, 0x03, 0x00,
0x18, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xC0,
0x0C, 0x00, 0xC0, 0x0F, 0xFF, 0x7F, 0xF8, 0x7F, 0xF7, 0xFF, 0x00, 0x60,
0x0C, 0x01, 0x80, 0x30, 0x03, 0x00, 0x60, 0x07, 0xE0, 0x07, 0x00, 0x30,
0x01, 0x00, 0x10, 0x03, 0x40, 0x37, 0xDE, 0x1F, 0xC0, 0x00, 0x60, 0x01,
0x80, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x30,
0x30, 0x60, 0xC0, 0xC1, 0x81, 0x87, 0xFF, 0xFF, 0xFF, 0xE0, 0x0C, 0x00,
0x18, 0x00, 0x30, 0x00, 0x60, 0x3F, 0xE7, 0xFE, 0x60, 0x06, 0x00, 0x60,
0x06, 0x00, 0x60, 0x07, 0xF0, 0x7F, 0xC0, 0x06, 0x00, 0x60, 0x03, 0x00,
0x30, 0x02, 0xC0, 0x6F, 0xBC, 0x3F, 0x80, 0x07, 0xE0, 0xFF, 0x8E, 0x00,
0xC0, 0x06, 0x00, 0x20, 0x03, 0x00, 0x19, 0xF8, 0xDE, 0xE7, 0x81, 0xB8,
0x07, 0xC0, 0x36, 0x01, 0xB0, 0x0C, 0xC0, 0xC3, 0x9E, 0x0F, 0xC0, 0xFF,
0xFF, 0xFF, 0x80, 0x38, 0x06, 0x80, 0x60, 0x0C, 0x00, 0xC0, 0x18, 0x01,
0x80, 0x10, 0x03, 0x00, 0x30, 0x06, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x18,
0x00, 0x0F, 0x81, 0xFF, 0x18, 0x0C, 0xC0, 0x26, 0x01, 0xB0, 0x09, 0x80,
0xC7, 0xBC, 0x1F, 0xE3, 0x83, 0x98, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0D,
0x80, 0xEF, 0x1E, 0x1F, 0xC0, 0x1F, 0x07, 0xFC, 0xE0, 0x6C, 0x02, 0xC0,
0x38, 0x03, 0xC0, 0x3C, 0x07, 0x71, 0xD3, 0xF9, 0x00, 0x30, 0x03, 0x00,
0x30, 0x06, 0x00, 0xE6, 0x7C, 0x7F, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x7E,
0x1F, 0x80, 0x00, 0x00, 0x76, 0x92, 0xC0, 0x00, 0xC1, 0xE1, 0xE3, 0xC0,
0xC0, 0x3C, 0x03, 0xC0, 0x1E, 0x01, 0xC0, 0x00, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x0F, 0xFC, 0xC0, 0x1C, 0x01, 0xE0, 0x0E, 0x00, 0xC0,
0xF0, 0xE1, 0xE0, 0xC0, 0x00, 0x00, 0x1F, 0x87, 0xFE, 0xE0, 0x60, 0x03,
0x00, 0x30, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x03, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x07,
0x07, 0x00, 0x30, 0x01, 0x80, 0xC0, 0x01, 0x83, 0x00, 0x01, 0x84, 0x1F,
0x91, 0x10, 0x61, 0xA3, 0x21, 0x80, 0xC2, 0xC2, 0x01, 0x85, 0x8C, 0x01,
0x0B, 0x18, 0x02, 0x1E, 0x30, 0x04, 0x3C, 0x60, 0x08, 0x58, 0x40, 0x30,
0x90, 0xC0, 0xE1, 0x30, 0xE3, 0x64, 0x20, 0xFC, 0x78, 0x60, 0x00, 0x00,
0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x3C, 0xF0, 0x00, 0x1F, 0x80, 0x00,
0x00, 0xC0, 0x00, 0xE0, 0x00, 0x58, 0x00, 0x6C, 0x00, 0x22, 0x00, 0x31,
0x80, 0x18, 0x40, 0x18, 0x30, 0x0C, 0x18, 0x0C, 0x06, 0x06, 0x03, 0x03,
0xFF, 0xC3, 0xFF, 0xE1, 0x00, 0x19, 0x80, 0x0C, 0xC0, 0x02, 0xC0, 0x01,
0x80, 0xFF, 0xC3, 0xFF, 0xCC, 0x03, 0x30, 0x06, 0xC0, 0x1B, 0x00, 0x6C,
0x01, 0x30, 0x1C, 0xFF, 0xE3, 0x00, 0xEC, 0x01, 0xB0, 0x03, 0xC0, 0x0F,
0x00, 0x3C, 0x01, 0xB0, 0x3E, 0xFF, 0xE0, 0x03, 0xF0, 0x1F, 0xF8, 0x70,
0x19, 0x80, 0x06, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01,
0x80, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x01, 0x87,
0xBE, 0x07, 0xF8, 0xFF, 0x80, 0xFF, 0xF0, 0xC0, 0x38, 0xC0, 0x0C, 0xC0,
0x06, 0xC0, 0x06, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x02, 0xC0, 0x06, 0xC0, 0x06, 0xC0, 0x0C, 0xC0, 0x38, 0xFF, 0xF0, 0xFF,
0xC0, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C,
0x00, 0xFF, 0xCC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F,
0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30,
0x06, 0x00, 0xFF, 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06,
0x00, 0xC0, 0x00, 0x03, 0xF0, 0x1F, 0xF8, 0x70, 0x19, 0x80, 0x06, 0x00,
0x0C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x07, 0x00, 0x0B,
0x00, 0x16, 0x00, 0x26, 0x00, 0x46, 0x01, 0x87, 0xDF, 0x03, 0xF8, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0,
0x03, 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C,
0x00, 0xF0, 0x03, 0xC0, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0x9F,
0xC0, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10,
0x08, 0x0F, 0x07, 0xEE, 0x3E, 0x00, 0xC0, 0x1B, 0x00, 0xCC, 0x06, 0x30,
0x30, 0xC1, 0x83, 0x0C, 0x0C, 0x60, 0x33, 0x00, 0xDE, 0x03, 0xFC, 0x0F,
0x30, 0x38, 0x60, 0xC0, 0xC3, 0x01, 0x8C, 0x03, 0x30, 0x0E, 0xC0, 0x1C,
0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0,
0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x07, 0xFF, 0xFF, 0xE0,
0x80, 0x00, 0xE0, 0x00, 0xF8, 0x00, 0xFC, 0x00, 0x7B, 0x00, 0x7C, 0x80,
0x2E, 0x60, 0x37, 0x10, 0x33, 0x8C, 0x19, 0xC3, 0x18, 0xE1, 0x88, 0x70,
0x6C, 0x38, 0x14, 0x1C, 0x0E, 0x0E, 0x02, 0x07, 0x00, 0x03, 0x80, 0x01,
0x80, 0x80, 0x0F, 0x00, 0x3E, 0x00, 0xFC, 0x03, 0xF8, 0x0F, 0x60, 0x3C,
0xC0, 0xF1, 0x83, 0xC3, 0x0F, 0x0E, 0x3C, 0x18, 0xF0, 0x33, 0xC0, 0x6F,
0x00, 0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x0C, 0x03, 0xF0, 0x03, 0xFF, 0x01,
0xC0, 0x60, 0xC0, 0x0C, 0x60, 0x01, 0x98, 0x00, 0x6C, 0x00, 0x0F, 0x00,
0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0D, 0x80, 0x02, 0x60, 0x01,
0x8C, 0x00, 0xC1, 0x80, 0x70, 0x3C, 0xF0, 0x03, 0xF8, 0x00, 0xFF, 0x87,
0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0,
0x36, 0x03, 0xBF, 0xF9, 0xFE, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00,
0xC0, 0x00, 0x03, 0xF0, 0x01, 0xFF, 0x80, 0x70, 0x18, 0x18, 0x01, 0x86,
0x00, 0x18, 0xC0, 0x03, 0x30, 0x00, 0x36, 0x00, 0x06, 0xC0, 0x00, 0xD8,
0x00, 0x1B, 0x00, 0x03, 0x30, 0x00, 0xC6, 0x00, 0x18, 0x60, 0x06, 0x06,
0x01, 0xC0, 0x79, 0xE0, 0x07, 0xF8, 0x00, 0x0E, 0x00, 0x00, 0xE3, 0x80,
0x07, 0xE0, 0xFF, 0x87, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x01, 0xE0, 0x0F,
0x00, 0x78, 0x03, 0xC0, 0x36, 0x03, 0xBF, 0xF9, 0xFF, 0x0C, 0x0C, 0x60,
0x33, 0x01, 0x98, 0x06, 0xC0, 0x18, 0x0F, 0xC1, 0xFF, 0x98, 0x04, 0xC0,
0x04, 0x00, 0x20, 0x01, 0x80, 0x07, 0x00, 0x1F, 0x80, 0x0F, 0x00, 0x0C,
0x00, 0x30, 0x01, 0x80, 0x0F, 0x00, 0xCF, 0x3C, 0x1F, 0xC0, 0xFF, 0xFF,
0xFF, 0xF0, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0,
0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30,
0x00, 0xC0, 0x03, 0x00, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00,
0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x3C,
0x01, 0xE0, 0x0D, 0x80, 0xC7, 0xBC, 0x1F, 0xC0, 0xC0, 0x01, 0xB0, 0x01,
0x98, 0x00, 0xC4, 0x00, 0xC3, 0x00, 0x61, 0x80, 0x20, 0x60, 0x30, 0x30,
0x10, 0x0C, 0x18, 0x06, 0x0C, 0x01, 0x8C, 0x00, 0xC6, 0x00, 0x26, 0x00,
0x1B, 0x00, 0x0D, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xC0, 0x18, 0x01,
0xE0, 0x0E, 0x00, 0x90, 0x07, 0x00, 0xCC, 0x06, 0x80, 0x66, 0x03, 0x60,
0x21, 0x01, 0x30, 0x30, 0xC1, 0x88, 0x18, 0x60, 0xC6, 0x08, 0x18, 0x43,
0x0C, 0x0C, 0x60, 0x86, 0x06, 0x30, 0x62, 0x01, 0x10, 0x33, 0x00, 0xD8,
0x09, 0x80, 0x6C, 0x06, 0x80, 0x1C, 0x03, 0xC0, 0x0E, 0x00, 0xE0, 0x07,
0x00, 0x60, 0x00, 0x60, 0x06, 0x60, 0x18, 0xE0, 0x60, 0xC0, 0x80, 0xC3,
0x00, 0xCC, 0x01, 0xF0, 0x01, 0xE0, 0x01, 0x80, 0x07, 0x80, 0x1B, 0x80,
0x63, 0x00, 0xC3, 0x03, 0x03, 0x0C, 0x07, 0x18, 0x06, 0x60, 0x06, 0xC0,
0x06, 0xC0, 0x09, 0x80, 0x31, 0x80, 0xC1, 0x81, 0x83, 0x06, 0x03, 0x08,
0x06, 0x30, 0x06, 0xC0, 0x07, 0x80, 0x0E, 0x00, 0x0C, 0x00, 0x18, 0x00,
0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xF0, 0x01,
0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x1C, 0x00, 0x60, 0x03, 0x00, 0x18,
0x00, 0xC0, 0x07, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x3F, 0xFF, 0xFF,
0xFC, 0xFF, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8F,
0xF0, 0xC0, 0x10, 0x06, 0x01, 0x80, 0x20, 0x0C, 0x01, 0x00, 0x40, 0x18,
0x02, 0x00, 0x80, 0x30, 0x04, 0x01, 0x80, 0x60, 0x08, 0x03, 0x00, 0xC0,
0x10, 0x06, 0x01, 0x80, 0x20, 0xFF, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6,
0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xFF, 0xE0, 0x0C, 0x07, 0x01, 0x60,
0x48, 0x33, 0x08, 0x46, 0x19, 0x02, 0xC0, 0xA0, 0x30, 0xFF, 0xF0, 0xE0,
0xC1, 0x80, 0x0E, 0x0F, 0xF9, 0x83, 0x00, 0x30, 0x06, 0x00, 0xCF, 0xFB,
0x03, 0xC0, 0x78, 0x0F, 0x03, 0xB8, 0xF3, 0xF6, 0xC0, 0x06, 0x00, 0x30,
0x01, 0x80, 0x0C, 0x00, 0x63, 0xC3, 0x7F, 0x9E, 0x0E, 0xE0, 0x36, 0x00,
0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0x7E, 0x06, 0xDC, 0xE6,
0x7E, 0x00, 0x07, 0x01, 0xFC, 0x30, 0x66, 0x00, 0xC0, 0x0C, 0x00, 0xC0,
0x0C, 0x00, 0xC0, 0x06, 0x00, 0x60, 0x23, 0xDE, 0x0F, 0x80, 0x00, 0x18,
0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x83, 0x8C, 0x7F, 0x6E, 0x0F, 0x60,
0x3E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0D, 0x80, 0xEC, 0x07,
0x3D, 0xD8, 0xFC, 0xC0, 0x07, 0x01, 0xFC, 0x70, 0x66, 0x03, 0xC0, 0x3C,
0x01, 0xFF, 0xFC, 0x00, 0xC0, 0x06, 0x00, 0x60, 0x23, 0xDE, 0x0F, 0xC0,
0x0F, 0x0F, 0xC6, 0x02, 0x01, 0x07, 0xFB, 0xFC, 0x20, 0x10, 0x08, 0x04,
0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x07, 0x19, 0xFE,
0xDC, 0x1E, 0xC0, 0x7C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B,
0x01, 0xCC, 0x1E, 0x3F, 0xB0, 0x21, 0x80, 0x0C, 0x00, 0x6C, 0x06, 0x3F,
0xE0, 0x7C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x78,
0xDF, 0xCF, 0x06, 0xE0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03,
0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x0C,
0x30, 0x00, 0x00, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x0F, 0xE7, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0,
0x0C, 0x07, 0xC0, 0xEC, 0x1C, 0xC3, 0x0C, 0x60, 0xCC, 0x0D, 0xE0, 0xF3,
0x0E, 0x18, 0xC1, 0x8C, 0x0C, 0xC0, 0x6C, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xC7, 0x01, 0xC6, 0xFE, 0x7F, 0xBC, 0x1E, 0x0D, 0xC0, 0xE0, 0x3C,
0x03, 0x01, 0xE0, 0x18, 0x0F, 0x00, 0xC0, 0x78, 0x06, 0x03, 0xC0, 0x30,
0x1E, 0x01, 0x80, 0xF0, 0x0C, 0x07, 0x80, 0x60, 0x3C, 0x03, 0x01, 0x80,
0xC7, 0x8D, 0xFC, 0xF0, 0x6E, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03,
0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x30, 0x07, 0x00, 0xFE, 0x0C,
0x1C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01,
0x98, 0x0C, 0x7B, 0xC0, 0xF8, 0x00, 0xC7, 0x86, 0xFF, 0x3C, 0x1D, 0xC0,
0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1F, 0x00, 0xFC, 0x0D,
0xB9, 0xCC, 0xFC, 0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x00,
0x07, 0x18, 0xFE, 0xDC, 0x1E, 0xC0, 0x7C, 0x01, 0xE0, 0x0F, 0x00, 0x78,
0x03, 0xC0, 0x1B, 0x01, 0xD8, 0x0E, 0x7B, 0xB1, 0xF9, 0x80, 0x0C, 0x00,
0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0xC7, 0xBF, 0xC7, 0x0C, 0x18, 0x30,
0x60, 0xC1, 0x83, 0x06, 0x0C, 0x00, 0x0E, 0x1F, 0xFC, 0x0B, 0x00, 0xC0,
0x38, 0x07, 0xE0, 0x1E, 0x00, 0xC0, 0x38, 0x0F, 0xCE, 0x7F, 0x00, 0x10,
0x08, 0x3F, 0xDF, 0xE1, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02,
0x01, 0x80, 0xE4, 0x3E, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C,
0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x07, 0x60, 0x77, 0x9F, 0x1F, 0x30,
0xC0, 0x1A, 0x00, 0xD8, 0x0C, 0xC0, 0x63, 0x06, 0x18, 0x30, 0x41, 0x03,
0x18, 0x08, 0x80, 0x6C, 0x03, 0x40, 0x0E, 0x00, 0x70, 0x00, 0xC0, 0x20,
0x1A, 0x03, 0x80, 0xD8, 0x1C, 0x04, 0xC0, 0xA0, 0x62, 0x0D, 0x82, 0x18,
0x44, 0x30, 0xC2, 0x31, 0x82, 0x31, 0x88, 0x19, 0x04, 0xC0, 0x58, 0x34,
0x03, 0xC0, 0xA0, 0x1C, 0x07, 0x00, 0x60, 0x30, 0x00, 0x60, 0x32, 0x06,
0x30, 0x41, 0x8C, 0x0D, 0x80, 0x70, 0x06, 0x00, 0x70, 0x0D, 0x81, 0x8C,
0x30, 0x43, 0x06, 0x60, 0x30, 0x60, 0x0C, 0x80, 0x33, 0x01, 0x8C, 0x06,
0x18, 0x30, 0x60, 0xC0, 0xC2, 0x03, 0x18, 0x04, 0x40, 0x1B, 0x00, 0x28,
0x00, 0xE0, 0x03, 0x80, 0x0C, 0x00, 0x30, 0x01, 0x80, 0xFC, 0x00, 0xE0,
0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x18,
0x0C, 0x06, 0x03, 0x00, 0xFF, 0xC0, 0x0E, 0x3C, 0xC1, 0x83, 0x06, 0x0C,
0x18, 0x30, 0x60, 0xC7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83,
0x03, 0xC3, 0x80, 0xFF, 0xFF, 0xFE, 0xE1, 0xE0, 0x60, 0xC1, 0x83, 0x06,
0x0C, 0x18, 0x30, 0x60, 0x71, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1,
0x9E, 0x38, 0x00, 0x7C, 0x28, 0xC5, 0x0F, 0x00 };
const GFXglyph Montserrat_Regular12pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 2, 17, 6, 2, -16 }, // 0x21 '!'
{ 6, 5, 7, 9, 2, -16 }, // 0x22 '"'
{ 11, 15, 17, 17, 1, -16 }, // 0x23 '#'
{ 43, 13, 23, 15, 1, -19 }, // 0x24 '$'
{ 81, 18, 17, 20, 1, -16 }, // 0x25 '%'
{ 120, 15, 17, 16, 1, -16 }, // 0x26 '&'
{ 152, 1, 7, 5, 2, -16 }, // 0x27 '''
{ 153, 5, 23, 8, 2, -17 }, // 0x28 '('
{ 168, 4, 23, 8, 1, -17 }, // 0x29 ')'
{ 180, 8, 9, 9, 1, -17 }, // 0x2A '*'
{ 189, 10, 10, 14, 2, -12 }, // 0x2B '+'
{ 202, 3, 7, 5, 1, -2 }, // 0x2C ','
{ 205, 7, 1, 9, 1, -6 }, // 0x2D '-'
{ 206, 3, 3, 5, 1, -2 }, // 0x2E '.'
{ 208, 10, 22, 8, -1, -19 }, // 0x2F '/'
{ 236, 14, 17, 16, 1, -16 }, // 0x30 '0'
{ 266, 6, 17, 9, 0, -16 }, // 0x31 '1'
{ 279, 13, 17, 14, 0, -16 }, // 0x32 '2'
{ 307, 12, 17, 14, 0, -16 }, // 0x33 '3'
{ 333, 15, 17, 16, 1, -16 }, // 0x34 '4'
{ 365, 12, 17, 14, 1, -16 }, // 0x35 '5'
{ 391, 13, 17, 15, 1, -16 }, // 0x36 '6'
{ 419, 12, 17, 14, 1, -16 }, // 0x37 '7'
{ 445, 13, 17, 15, 1, -16 }, // 0x38 '8'
{ 473, 12, 17, 15, 1, -16 }, // 0x39 '9'
{ 499, 3, 13, 5, 1, -12 }, // 0x3A ':'
{ 504, 3, 17, 5, 1, -12 }, // 0x3B ';'
{ 511, 10, 10, 14, 2, -12 }, // 0x3C '<'
{ 524, 10, 7, 14, 2, -11 }, // 0x3D '='
{ 533, 10, 10, 14, 2, -12 }, // 0x3E '>'
{ 546, 12, 17, 14, 0, -16 }, // 0x3F '?'
{ 572, 23, 22, 25, 1, -16 }, // 0x40 '@'
{ 636, 17, 17, 17, 0, -16 }, // 0x41 'A'
{ 673, 14, 17, 18, 3, -16 }, // 0x42 'B'
{ 703, 15, 17, 17, 1, -16 }, // 0x43 'C'
{ 735, 16, 17, 20, 3, -16 }, // 0x44 'D'
{ 769, 12, 17, 16, 3, -16 }, // 0x45 'E'
{ 795, 11, 17, 15, 3, -16 }, // 0x46 'F'
{ 819, 15, 17, 19, 1, -16 }, // 0x47 'G'
{ 851, 14, 17, 20, 3, -16 }, // 0x48 'H'
{ 881, 2, 17, 7, 3, -16 }, // 0x49 'I'
{ 886, 9, 17, 12, 0, -16 }, // 0x4A 'J'
{ 906, 14, 17, 17, 3, -16 }, // 0x4B 'K'
{ 936, 11, 17, 14, 3, -16 }, // 0x4C 'L'
{ 960, 17, 17, 23, 3, -16 }, // 0x4D 'M'
{ 997, 14, 17, 20, 3, -16 }, // 0x4E 'N'
{ 1027, 18, 17, 20, 1, -16 }, // 0x4F 'O'
{ 1066, 13, 17, 17, 3, -16 }, // 0x50 'P'
{ 1094, 19, 20, 20, 1, -16 }, // 0x51 'Q'
{ 1142, 13, 17, 17, 3, -16 }, // 0x52 'R'
{ 1170, 13, 17, 15, 1, -16 }, // 0x53 'S'
{ 1198, 14, 17, 14, 0, -16 }, // 0x54 'T'
{ 1228, 13, 17, 19, 3, -16 }, // 0x55 'U'
{ 1256, 17, 17, 17, 0, -16 }, // 0x56 'V'
{ 1293, 25, 17, 27, 1, -16 }, // 0x57 'W'
{ 1347, 15, 17, 16, 0, -16 }, // 0x58 'X'
{ 1379, 15, 17, 15, 0, -16 }, // 0x59 'Y'
{ 1411, 14, 17, 16, 1, -16 }, // 0x5A 'Z'
{ 1441, 4, 23, 8, 3, -17 }, // 0x5B '['
{ 1453, 10, 22, 8, -1, -19 }, // 0x5C '\'
{ 1481, 5, 23, 8, 0, -17 }, // 0x5D ']'
{ 1496, 10, 10, 14, 2, -12 }, // 0x5E '^'
{ 1509, 12, 1, 12, 0, 1 }, // 0x5F '_'
{ 1511, 6, 3, 14, 3, -17 }, // 0x60 '`'
{ 1514, 11, 13, 14, 1, -12 }, // 0x61 'a'
{ 1532, 13, 18, 16, 2, -17 }, // 0x62 'b'
{ 1562, 12, 13, 14, 1, -12 }, // 0x63 'c'
{ 1582, 13, 18, 16, 1, -17 }, // 0x64 'd'
{ 1612, 12, 13, 15, 1, -12 }, // 0x65 'e'
{ 1632, 9, 18, 8, 0, -17 }, // 0x66 'f'
{ 1653, 13, 18, 16, 1, -12 }, // 0x67 'g'
{ 1683, 12, 18, 16, 2, -17 }, // 0x68 'h'
{ 1710, 2, 18, 6, 2, -17 }, // 0x69 'i'
{ 1715, 6, 23, 7, -2, -17 }, // 0x6A 'j'
{ 1733, 12, 18, 14, 2, -17 }, // 0x6B 'k'
{ 1760, 2, 18, 6, 2, -17 }, // 0x6C 'l'
{ 1765, 21, 13, 25, 2, -12 }, // 0x6D 'm'
{ 1800, 12, 13, 16, 2, -12 }, // 0x6E 'n'
{ 1820, 13, 13, 15, 1, -12 }, // 0x6F 'o'
{ 1842, 13, 18, 16, 2, -12 }, // 0x70 'p'
{ 1872, 13, 18, 16, 1, -12 }, // 0x71 'q'
{ 1902, 7, 13, 10, 2, -12 }, // 0x72 'r'
{ 1914, 10, 13, 12, 1, -12 }, // 0x73 's'
{ 1931, 9, 15, 10, 0, -14 }, // 0x74 't'
{ 1948, 12, 13, 16, 2, -12 }, // 0x75 'u'
{ 1968, 13, 13, 13, 0, -12 }, // 0x76 'v'
{ 1990, 21, 13, 21, 0, -12 }, // 0x77 'w'
{ 2025, 12, 13, 13, 0, -12 }, // 0x78 'x'
{ 2045, 14, 18, 13, -1, -12 }, // 0x79 'y'
{ 2077, 10, 13, 12, 1, -12 }, // 0x7A 'z'
{ 2094, 7, 23, 8, 1, -17 }, // 0x7B '{'
{ 2115, 1, 23, 7, 3, -17 }, // 0x7C '|'
{ 2118, 7, 23, 8, 0, -17 }, // 0x7D '}'
{ 2139, 11, 3, 14, 1, -9 } }; // 0x7E '~'
const GFXfont Montserrat_Regular12pt7b PROGMEM = {
(uint8_t *)Montserrat_Regular12pt7bBitmaps,
(GFXglyph *)Montserrat_Regular12pt7bGlyphs,
0x20, 0x7E, 29 };
// Approx. 2816 bytes
#endif // MONTSERRAT12PT7B_H
@@ -0,0 +1,481 @@
#ifndef MONTSERRAT18PT7B_H
#define MONTSERRAT18PT7B_H
const uint8_t Montserrat_Regular18pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x6C, 0x00, 0x3F, 0xE0, 0xE3,
0xF1, 0xF8, 0xFC, 0x76, 0x1B, 0x0D, 0x86, 0x82, 0x41, 0x20, 0x80, 0x01,
0x80, 0xC0, 0x06, 0x03, 0x00, 0x18, 0x0C, 0x00, 0x60, 0x30, 0x01, 0x80,
0xC0, 0x06, 0x03, 0x00, 0x30, 0x08, 0x1F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC,
0x0C, 0x06, 0x00, 0x30, 0x18, 0x00, 0xC0, 0x60, 0x03, 0x01, 0x80, 0x0C,
0x06, 0x00, 0x60, 0x10, 0x01, 0x80, 0xC0, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF,
0xE0, 0x60, 0x30, 0x01, 0x80, 0xC0, 0x06, 0x03, 0x00, 0x18, 0x0C, 0x00,
0xC0, 0x20, 0x03, 0x01, 0x80, 0x0C, 0x06, 0x00, 0x00, 0xC0, 0x00, 0x30,
0x00, 0x0C, 0x00, 0x03, 0x00, 0x01, 0xF0, 0x03, 0xFF, 0x83, 0xFF, 0xF9,
0xE3, 0x0C, 0x70, 0xC0, 0x38, 0x30, 0x0E, 0x0C, 0x03, 0x83, 0x00, 0xE0,
0xC0, 0x1C, 0x30, 0x07, 0x8C, 0x00, 0xFF, 0x00, 0x0F, 0xF8, 0x00, 0x7F,
0x80, 0x0D, 0xF0, 0x03, 0x1E, 0x00, 0xC1, 0xC0, 0x30, 0x70, 0x0C, 0x1C,
0x03, 0x07, 0x80, 0xC1, 0xF8, 0x30, 0xEF, 0x8C, 0xF0, 0xFF, 0xF8, 0x0F,
0xF8, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x00, 0x06,
0x00, 0x06, 0x03, 0xF0, 0x01, 0x80, 0xC3, 0x00, 0x70, 0x30, 0x30, 0x0C,
0x06, 0x06, 0x03, 0x00, 0x80, 0x40, 0xE0, 0x30, 0x0C, 0x18, 0x06, 0x01,
0x86, 0x00, 0x40, 0x21, 0x80, 0x0C, 0x0C, 0x30, 0x01, 0x81, 0x8C, 0x00,
0x18, 0x63, 0x00, 0x01, 0xF8, 0x63, 0xF0, 0x0C, 0x18, 0xFF, 0x00, 0x06,
0x38, 0x70, 0x00, 0xC6, 0x06, 0x00, 0x30, 0x80, 0x40, 0x0C, 0x10, 0x08,
0x01, 0x86, 0x01, 0x80, 0x60, 0x40, 0x30, 0x18, 0x08, 0x04, 0x07, 0x01,
0x81, 0x80, 0xC0, 0x30, 0x30, 0x30, 0x03, 0xFC, 0x0E, 0x00, 0x3F, 0x00,
0x01, 0xE0, 0x00, 0x3F, 0xC0, 0x03, 0x87, 0x00, 0x38, 0x18, 0x01, 0x80,
0xE0, 0x0C, 0x03, 0x00, 0x60, 0x38, 0x03, 0x81, 0x80, 0x0C, 0x18, 0x00,
0x73, 0x80, 0x01, 0xF8, 0x00, 0x07, 0x80, 0x00, 0xFC, 0x00, 0x0E, 0x70,
0x00, 0xE1, 0xC1, 0xCE, 0x07, 0x0C, 0xE0, 0x1C, 0x66, 0x00, 0x77, 0x30,
0x01, 0xF1, 0x80, 0x07, 0x8E, 0x00, 0x1C, 0x70, 0x03, 0xF1, 0xE0, 0x39,
0xC7, 0xFF, 0x87, 0x0F, 0xF0, 0x10, 0xFF, 0xF6, 0xDA, 0x48, 0x1C, 0x63,
0x8C, 0x31, 0xC6, 0x18, 0xE3, 0x8E, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x0E, 0x38, 0xE1, 0x86, 0x1C, 0x30, 0xC3, 0x86, 0x0C, 0x60,
0xE0, 0xC1, 0xC3, 0x83, 0x07, 0x0E, 0x0C, 0x18, 0x30, 0x70, 0xE1, 0xC3,
0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x06, 0x0C, 0x38, 0x70, 0xC3,
0x86, 0x0C, 0x38, 0x60, 0x06, 0x00, 0x60, 0x06, 0x0C, 0x67, 0x77, 0xE1,
0xF8, 0x0F, 0x03, 0xF8, 0xF6, 0xEC, 0x62, 0x06, 0x00, 0x60, 0x06, 0x00,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x4E, 0xFE, 0x66, 0x4C, 0xC0, 0xFF,
0xFF, 0xFF, 0xE0, 0x4E, 0xFE, 0x00, 0x1C, 0x00, 0x60, 0x01, 0x80, 0x0E,
0x00, 0x30, 0x00, 0xC0, 0x07, 0x00, 0x18, 0x00, 0x60, 0x03, 0x00, 0x0C,
0x00, 0x70, 0x01, 0x80, 0x06, 0x00, 0x38, 0x00, 0xC0, 0x03, 0x00, 0x1C,
0x00, 0x60, 0x01, 0x80, 0x0E, 0x00, 0x30, 0x00, 0xC0, 0x07, 0x00, 0x18,
0x00, 0x60, 0x03, 0x80, 0x0C, 0x00, 0x30, 0x01, 0x80, 0x06, 0x00, 0x38,
0x00, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0xFF, 0x80, 0x3F, 0xFC, 0x0E, 0x03,
0xC3, 0x80, 0x38, 0xE0, 0x03, 0x9C, 0x00, 0x33, 0x00, 0x07, 0xE0, 0x00,
0xFC, 0x00, 0x0F, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00,
0xF0, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x1D, 0x80, 0x03,
0x38, 0x00, 0xE3, 0x80, 0x1C, 0x78, 0x07, 0x07, 0x83, 0xC0, 0x7F, 0xF0,
0x03, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07,
0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0,
0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x80, 0x03, 0xE0, 0x07, 0xFE,
0x07, 0xFF, 0xE3, 0xC0, 0x3C, 0xC0, 0x07, 0x00, 0x00, 0xC0, 0x00, 0x30,
0x00, 0x0C, 0x00, 0x03, 0x00, 0x01, 0xC0, 0x00, 0x70, 0x00, 0x38, 0x00,
0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0,
0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0x9F, 0xFF, 0xE7, 0xFF, 0xF8,
0x00, 0x1C, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00,
0x70, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x07, 0xE0, 0x01, 0xFE, 0x00, 0x03,
0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x01, 0xC0, 0x00, 0x70, 0x00, 0x1C,
0x00, 0x07, 0x40, 0x01, 0xD8, 0x00, 0xE7, 0xC0, 0xF0, 0xFF, 0xF8, 0x0F,
0xF8, 0x00, 0x00, 0x07, 0x00, 0x00, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x07,
0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00,
0x01, 0xC0, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x01, 0x80, 0xE0, 0x0E,
0x03, 0x80, 0x70, 0x0E, 0x03, 0x80, 0x38, 0x1C, 0x00, 0xE0, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xE0, 0x00, 0x03, 0x80,
0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x1F,
0xFF, 0x0F, 0xFF, 0x87, 0xFF, 0xC7, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00,
0xE0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x07, 0xFF,
0x03, 0xFF, 0xE0, 0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0x00, 0x01, 0x80,
0x00, 0xC0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x3B, 0xE0, 0x7C,
0x7F, 0xFC, 0x0F, 0xF8, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0xE0, 0xFF, 0xF0,
0x78, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x01, 0x80, 0x00, 0xE0,
0x00, 0x38, 0x00, 0x0C, 0x0F, 0x03, 0x1F, 0xF8, 0xCF, 0xBF, 0x37, 0x00,
0xEF, 0x80, 0x1F, 0xC0, 0x07, 0xE0, 0x00, 0xF8, 0x00, 0x36, 0x00, 0x0D,
0xC0, 0x07, 0x70, 0x01, 0xCE, 0x00, 0xE1, 0xE0, 0x78, 0x3F, 0xF8, 0x03,
0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xE0,
0x03, 0xB8, 0x00, 0xEE, 0x00, 0x70, 0x00, 0x1C, 0x00, 0x06, 0x00, 0x03,
0x80, 0x00, 0xC0, 0x00, 0x70, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x03, 0x80,
0x01, 0xC0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x01,
0xC0, 0x00, 0x60, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x00, 0x01,
0xF0, 0x01, 0xFF, 0xC0, 0xFC, 0xFC, 0x3C, 0x03, 0xC7, 0x00, 0x38, 0xC0,
0x03, 0x98, 0x00, 0x73, 0x00, 0x0E, 0x60, 0x01, 0xCE, 0x00, 0x70, 0xE0,
0x1C, 0x0F, 0xFF, 0x00, 0xFF, 0xE0, 0x7C, 0x3E, 0x1C, 0x00, 0xE7, 0x00,
0x0E, 0xE0, 0x00, 0xD8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7E, 0x00,
0x1C, 0xE0, 0x03, 0x9F, 0x01, 0xE1, 0xFF, 0xF8, 0x0F, 0xFC, 0x00, 0x03,
0xC0, 0x01, 0xFF, 0x80, 0xFD, 0xF8, 0x3C, 0x03, 0x87, 0x00, 0x39, 0xC0,
0x07, 0x38, 0x00, 0x77, 0x00, 0x0E, 0xE0, 0x01, 0xDC, 0x00, 0x39, 0x80,
0x0F, 0x38, 0x03, 0xE3, 0xC0, 0xEC, 0x3F, 0xF9, 0x81, 0xFC, 0x30, 0x00,
0x06, 0x00, 0x00, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x01, 0xC0, 0x00,
0x30, 0x00, 0x1E, 0x0C, 0x0F, 0x81, 0xFF, 0xE0, 0x1F, 0xF0, 0x00, 0x4E,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xEF, 0xE0, 0x4E, 0xFE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0xEF, 0xE6, 0x64, 0xCC, 0x00, 0x00, 0x00,
0x07, 0x00, 0x1F, 0x00, 0xFC, 0x03, 0xE0, 0x1F, 0x80, 0x7C, 0x00, 0xE0,
0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0xC0, 0x01, 0xF0, 0x00, 0x7E, 0x00,
0x0F, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0xE0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00,
0x3E, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x0F, 0x80, 0x7E,
0x00, 0xF0, 0x00, 0xC0, 0x00, 0x01, 0xF0, 0x07, 0xFE, 0x0F, 0xFF, 0xCF,
0x00, 0xE6, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03,
0x80, 0x01, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x01,
0xC0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x00,
0x03, 0xE0, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x01, 0xF0, 0x0F, 0x80, 0x03,
0x80, 0x01, 0xE0, 0x07, 0x00, 0x00, 0x70, 0x0C, 0x00, 0x00, 0x38, 0x18,
0x00, 0x00, 0x1C, 0x30, 0x07, 0xC1, 0x8C, 0x30, 0x1F, 0xF1, 0x86, 0x60,
0x3C, 0x3D, 0x86, 0x60, 0x70, 0x0D, 0x83, 0xC0, 0xE0, 0x07, 0x83, 0xC0,
0xC0, 0x03, 0x83, 0xC1, 0xC0, 0x03, 0x83, 0xC1, 0x80, 0x03, 0x83, 0xC1,
0x80, 0x03, 0x81, 0xC1, 0x80, 0x01, 0x81, 0xC1, 0x80, 0x03, 0x83, 0xC1,
0xC0, 0x03, 0x83, 0xC1, 0xC0, 0x03, 0x83, 0xC0, 0xE0, 0x07, 0x83, 0x60,
0xE0, 0x0F, 0x86, 0x60, 0x78, 0x1D, 0x86, 0x70, 0x3F, 0xF9, 0xFC, 0x30,
0x0F, 0xE0, 0xF8, 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x01, 0xE0, 0x06, 0x00, 0x00,
0x7F, 0xFE, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x0F, 0x80, 0x00, 0x06, 0xC0, 0x00, 0x07, 0x70, 0x00, 0x03,
0x98, 0x00, 0x01, 0x8E, 0x00, 0x01, 0xC7, 0x00, 0x00, 0xC1, 0x80, 0x00,
0xE0, 0xE0, 0x00, 0x60, 0x30, 0x00, 0x70, 0x1C, 0x00, 0x30, 0x06, 0x00,
0x38, 0x03, 0x80, 0x18, 0x00, 0xC0, 0x1C, 0x00, 0x70, 0x0F, 0xFF, 0xF8,
0x0F, 0xFF, 0xFE, 0x07, 0x00, 0x07, 0x03, 0x00, 0x01, 0xC3, 0x80, 0x00,
0xE1, 0x80, 0x00, 0x31, 0xC0, 0x00, 0x1C, 0xC0, 0x00, 0x06, 0xE0, 0x00,
0x03, 0x80, 0xFF, 0xE0, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0x8E, 0x00, 0x3C,
0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x00, 0x6E, 0x00, 0x06, 0xE0, 0x00,
0xEE, 0x00, 0x0E, 0xE0, 0x01, 0xCE, 0x01, 0xF8, 0xFF, 0xFF, 0x0F, 0xFF,
0xFC, 0xE0, 0x00, 0xEE, 0x00, 0x07, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0,
0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x03, 0xEF,
0xFF, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x3E, 0x00, 0x07, 0xFF, 0x00, 0x7F,
0xFF, 0x03, 0xC0, 0x1E, 0x1E, 0x00, 0x18, 0xE0, 0x00, 0x07, 0x00, 0x00,
0x1C, 0x00, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x30,
0x00, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x00,
0x00, 0xE0, 0x00, 0x01, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00,
0x3C, 0x00, 0x18, 0x78, 0x00, 0xF0, 0xFC, 0x0F, 0x80, 0xFF, 0xF8, 0x00,
0xFF, 0x80, 0xFF, 0xC0, 0x01, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x07, 0x00,
0x1F, 0x0E, 0x00, 0x0F, 0x1C, 0x00, 0x07, 0x38, 0x00, 0x0F, 0x70, 0x00,
0x0E, 0xE0, 0x00, 0x0D, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00, 0x00,
0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x07,
0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x3B, 0x80, 0x00, 0x77, 0x00, 0x01, 0xCE,
0x00, 0x07, 0x1C, 0x00, 0x3E, 0x38, 0x03, 0xF0, 0x7F, 0xFF, 0xC0, 0xFF,
0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0E, 0x00,
0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38,
0x00, 0x1F, 0xFF, 0xCF, 0xFF, 0xE7, 0xFF, 0xF3, 0x80, 0x01, 0xC0, 0x00,
0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,
0x03, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0,
0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0F, 0xFF, 0xE7,
0xFF, 0xF3, 0xFF, 0xF9, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00,
0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0,
0x00, 0x00, 0x00, 0x3E, 0x00, 0x07, 0xFF, 0x80, 0x7F, 0xFF, 0x03, 0xC0,
0x1F, 0x1E, 0x00, 0x18, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00,
0xE0, 0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0,
0x00, 0x03, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0x00,
0x1D, 0x80, 0x00, 0x77, 0x00, 0x01, 0xCE, 0x00, 0x07, 0x3C, 0x00, 0x1C,
0x78, 0x00, 0xF0, 0xFC, 0x0F, 0x80, 0xFF, 0xFC, 0x00, 0xFF, 0x80, 0xE0,
0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E,
0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03,
0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00,
0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xE0,
0x00, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
0x3F, 0xFC, 0xFF, 0xF3, 0xFF, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01,
0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00,
0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x40,
0x1B, 0x80, 0xEF, 0x07, 0x9F, 0xFC, 0x1F, 0xC0, 0xE0, 0x00, 0x77, 0x00,
0x07, 0x38, 0x00, 0x71, 0xC0, 0x07, 0x0E, 0x00, 0x70, 0x70, 0x07, 0x03,
0x80, 0x70, 0x1C, 0x07, 0x00, 0xE0, 0x70, 0x07, 0x07, 0x00, 0x38, 0x70,
0x01, 0xC7, 0x00, 0x0E, 0x7C, 0x00, 0x77, 0xF0, 0x03, 0xFB, 0xC0, 0x1F,
0x8F, 0x00, 0xF8, 0x3C, 0x07, 0x80, 0xE0, 0x38, 0x03, 0x81, 0xC0, 0x0E,
0x0E, 0x00, 0x38, 0x70, 0x00, 0xE3, 0x80, 0x07, 0x9C, 0x00, 0x1C, 0xE0,
0x00, 0x70, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xF8, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0x70,
0x00, 0x37, 0x98, 0x00, 0x3B, 0xCE, 0x00, 0x19, 0xE3, 0x00, 0x1C, 0xF1,
0xC0, 0x1C, 0x78, 0x70, 0x0C, 0x3C, 0x18, 0x0E, 0x1E, 0x0E, 0x06, 0x0F,
0x03, 0x07, 0x07, 0x81, 0xC3, 0x03, 0xC0, 0x73, 0x01, 0xE0, 0x1B, 0x80,
0xF0, 0x0F, 0x80, 0x78, 0x03, 0xC0, 0x3C, 0x01, 0xC0, 0x1E, 0x00, 0x60,
0x0F, 0x00, 0x00, 0x07, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x01, 0x80, 0xC0,
0x00, 0x3E, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x80, 0x03, 0xF8, 0x00, 0x3F,
0xC0, 0x03, 0xEE, 0x00, 0x3E, 0xF0, 0x03, 0xE7, 0x00, 0x3E, 0x38, 0x03,
0xE1, 0xC0, 0x3E, 0x0E, 0x03, 0xE0, 0xF0, 0x3E, 0x07, 0x03, 0xE0, 0x38,
0x3E, 0x01, 0xC3, 0xE0, 0x0E, 0x3E, 0x00, 0xF3, 0xE0, 0x07, 0x3E, 0x00,
0x3B, 0xE0, 0x01, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x07, 0xE0,
0x00, 0x30, 0x00, 0x3E, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x7F, 0xFF, 0x00,
0x3C, 0x01, 0xF0, 0x1C, 0x00, 0x1E, 0x0E, 0x00, 0x03, 0x87, 0x00, 0x00,
0x71, 0xC0, 0x00, 0x0C, 0xE0, 0x00, 0x03, 0xB8, 0x00, 0x00, 0xEE, 0x00,
0x00, 0x1B, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x1B, 0x80, 0x00, 0x06, 0xE0, 0x00, 0x03, 0x98, 0x00, 0x00,
0xE7, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x3C, 0x3C, 0x00, 0x1E, 0x07, 0x80,
0x0F, 0x00, 0xFC, 0x0F, 0x80, 0x0F, 0xFF, 0xC0, 0x00, 0xFF, 0x80, 0x00,
0xFF, 0xC0, 0x1F, 0xFF, 0xC3, 0xFF, 0xFC, 0x70, 0x03, 0xCE, 0x00, 0x1D,
0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0x7C, 0x00, 0x0F,
0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0D, 0xC0, 0x03, 0xB8, 0x01, 0xE7,
0xFF, 0xF8, 0xFF, 0xFC, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E,
0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x00,
0x00, 0x3E, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0x80,
0x3E, 0x01, 0xC0, 0x01, 0xE0, 0x70, 0x00, 0x1C, 0x1C, 0x00, 0x01, 0xC3,
0x80, 0x00, 0x18, 0xE0, 0x00, 0x03, 0x9C, 0x00, 0x00, 0x73, 0x80, 0x00,
0x06, 0x60, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x1D, 0x80, 0x00, 0x03, 0xB8,
0x00, 0x00, 0x67, 0x00, 0x00, 0x0C, 0xE0, 0x00, 0x03, 0x8E, 0x00, 0x00,
0x71, 0xC0, 0x00, 0x1C, 0x1C, 0x00, 0x07, 0x83, 0xC0, 0x01, 0xE0, 0x3C,
0x00, 0x78, 0x03, 0xF0, 0x3E, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0x80,
0x00, 0x00, 0xE0, 0x00, 0x00, 0x0E, 0x03, 0x00, 0x00, 0xF0, 0xE0, 0x00,
0x0F, 0xF8, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0xFF,
0xFF, 0x0E, 0x00, 0x78, 0xE0, 0x01, 0xCE, 0x00, 0x0E, 0xE0, 0x00, 0xEE,
0x00, 0x0E, 0xE0, 0x00, 0x6E, 0x00, 0x06, 0xE0, 0x00, 0xEE, 0x00, 0x0E,
0xE0, 0x00, 0xCE, 0x00, 0x1C, 0xE0, 0x07, 0x8F, 0xFF, 0xF0, 0xFF, 0xFC,
0x0E, 0x01, 0xC0, 0xE0, 0x0E, 0x0E, 0x00, 0x70, 0xE0, 0x03, 0x0E, 0x00,
0x38, 0xE0, 0x01, 0xCE, 0x00, 0x0E, 0xE0, 0x00, 0xE0, 0x01, 0xF0, 0x03,
0xFF, 0x83, 0xFF, 0xF9, 0xE0, 0x0C, 0x70, 0x00, 0x38, 0x00, 0x0E, 0x00,
0x03, 0x80, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x07, 0x80, 0x00, 0xFE, 0x00,
0x0F, 0xF8, 0x00, 0x7F, 0x80, 0x01, 0xF0, 0x00, 0x1E, 0x00, 0x01, 0xC0,
0x00, 0x70, 0x00, 0x1C, 0x00, 0x07, 0x80, 0x01, 0xF8, 0x00, 0xEF, 0x80,
0xF0, 0xFF, 0xF8, 0x0F, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00,
0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00,
0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60,
0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06,
0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x7C,
0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x07,
0xC0, 0x00, 0x7C, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x07, 0xC0, 0x00,
0x7C, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00,
0x07, 0xC0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x66, 0x00, 0x0E, 0x70,
0x00, 0xE3, 0x80, 0x1C, 0x3E, 0x07, 0x80, 0xFF, 0xF0, 0x03, 0xFC, 0x00,
0xE0, 0x00, 0x03, 0x60, 0x00, 0x07, 0x70, 0x00, 0x06, 0x70, 0x00, 0x0E,
0x38, 0x00, 0x0E, 0x38, 0x00, 0x0C, 0x1C, 0x00, 0x1C, 0x1C, 0x00, 0x18,
0x0C, 0x00, 0x38, 0x0E, 0x00, 0x30, 0x06, 0x00, 0x70, 0x07, 0x00, 0x70,
0x07, 0x00, 0xE0, 0x03, 0x80, 0xE0, 0x03, 0x80, 0xC0, 0x01, 0xC1, 0xC0,
0x01, 0xC1, 0x80, 0x00, 0xC3, 0x80, 0x00, 0xE3, 0x00, 0x00, 0x67, 0x00,
0x00, 0x77, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3C, 0x00,
0x00, 0x1C, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x3B, 0x00, 0x03, 0x80, 0x01,
0x9C, 0x00, 0x1C, 0x00, 0x1C, 0xE0, 0x01, 0xF0, 0x00, 0xE3, 0x00, 0x0D,
0x80, 0x06, 0x1C, 0x00, 0x6C, 0x00, 0x70, 0xE0, 0x07, 0x70, 0x03, 0x83,
0x00, 0x31, 0x80, 0x18, 0x1C, 0x01, 0x8C, 0x01, 0xC0, 0xE0, 0x1C, 0x70,
0x0E, 0x03, 0x00, 0xC1, 0x80, 0x60, 0x1C, 0x06, 0x0C, 0x07, 0x00, 0xE0,
0x70, 0x70, 0x38, 0x03, 0x03, 0x01, 0x81, 0x80, 0x1C, 0x38, 0x0C, 0x1C,
0x00, 0xE1, 0xC0, 0x70, 0xE0, 0x03, 0x0C, 0x01, 0x86, 0x00, 0x1C, 0xE0,
0x0E, 0x70, 0x00, 0xE7, 0x00, 0x73, 0x80, 0x03, 0x30, 0x01, 0x98, 0x00,
0x1F, 0x80, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x7E, 0x00, 0x03, 0xC0, 0x01,
0xE0, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x78, 0x00, 0xE0,
0x00, 0x3B, 0x80, 0x03, 0x8E, 0x00, 0x38, 0x70, 0x01, 0xC1, 0xC0, 0x1C,
0x07, 0x01, 0xC0, 0x1C, 0x1C, 0x00, 0xE0, 0xE0, 0x03, 0x8E, 0x00, 0x0E,
0xE0, 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x07, 0x00, 0x00, 0x7C, 0x00,
0x07, 0x70, 0x00, 0x3B, 0x80, 0x03, 0x8E, 0x00, 0x38, 0x38, 0x03, 0x80,
0xE0, 0x1C, 0x07, 0x01, 0xC0, 0x1C, 0x1C, 0x00, 0x71, 0xC0, 0x01, 0xCE,
0x00, 0x0E, 0xE0, 0x00, 0x38, 0xE0, 0x00, 0x0D, 0x80, 0x00, 0x77, 0x00,
0x03, 0x8E, 0x00, 0x0C, 0x38, 0x00, 0x70, 0x70, 0x01, 0x80, 0xC0, 0x0E,
0x03, 0x80, 0x70, 0x07, 0x01, 0x80, 0x0C, 0x0E, 0x00, 0x38, 0x70, 0x00,
0x71, 0x80, 0x01, 0xCE, 0x00, 0x03, 0xB0, 0x00, 0x07, 0xC0, 0x00, 0x1E,
0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x00,
0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00,
0x30, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x1C,
0x00, 0x03, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C,
0x00, 0x03, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C,
0x00, 0x03, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C,
0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFC, 0x30, 0xC3, 0x0C, 0x30, 0xC3,
0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3,
0x0C, 0x30, 0xC3, 0x0C, 0x3F, 0xFC, 0xC0, 0x03, 0x80, 0x06, 0x00, 0x18,
0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x06, 0x00, 0x18, 0x00, 0x70, 0x00,
0xC0, 0x03, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x60, 0x01, 0xC0, 0x03, 0x00,
0x0C, 0x00, 0x38, 0x00, 0x60, 0x01, 0x80, 0x07, 0x00, 0x0C, 0x00, 0x30,
0x00, 0x60, 0x01, 0x80, 0x06, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xE0, 0x01,
0x80, 0x06, 0x00, 0x1C, 0xFF, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
0xC3, 0x0C, 0x30, 0xFF, 0xFC, 0x03, 0x00, 0x0E, 0x00, 0x78, 0x01, 0xE0,
0x0C, 0xC0, 0x33, 0x01, 0xC6, 0x06, 0x18, 0x18, 0x30, 0xC0, 0xC3, 0x03,
0x18, 0x06, 0x60, 0x19, 0x80, 0x3C, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xE0, 0x70, 0x38, 0x0C, 0x07, 0x01, 0x00, 0x3F, 0xE1, 0xFF, 0xF3,
0x80, 0xE4, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F,
0xFD, 0xF8, 0x1F, 0x00, 0x3E, 0x00, 0x78, 0x00, 0xF0, 0x03, 0xF0, 0x07,
0x70, 0x3E, 0xFF, 0xEC, 0x7F, 0x18, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80,
0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00,
0x00, 0xE3, 0xFC, 0x1D, 0xFF, 0xE3, 0xF0, 0x1E, 0x7C, 0x00, 0xEF, 0x00,
0x1D, 0xE0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0x7C, 0x00,
0x0F, 0x80, 0x03, 0xF0, 0x00, 0x7F, 0x00, 0x0D, 0xE0, 0x03, 0xBE, 0x00,
0xE7, 0x70, 0x7C, 0xE7, 0xFE, 0x1C, 0x7F, 0x80, 0x00, 0x40, 0x0F, 0xFC,
0x1F, 0xFE, 0x3C, 0x0F, 0x70, 0x03, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x00,
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0x70, 0x02, 0x78, 0x07, 0x3C, 0x0F, 0x1F, 0xFE, 0x07, 0xF8, 0x00, 0x00,
0xC0, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x00, 0x30,
0x00, 0x0C, 0x02, 0x03, 0x0F, 0xF8, 0xC7, 0xFF, 0x33, 0xC0, 0xED, 0xC0,
0x0F, 0xE0, 0x01, 0xF8, 0x00, 0x7C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00,
0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x80, 0x07, 0xE0, 0x01, 0xDC, 0x00, 0xF7,
0x80, 0x7C, 0xF0, 0x3B, 0x1F, 0xFC, 0xC1, 0xFC, 0x30, 0x00, 0xC0, 0x03,
0xFE, 0x01, 0xFF, 0xC0, 0xE0, 0x38, 0x70, 0x07, 0x38, 0x00, 0xEE, 0x00,
0x1B, 0x00, 0x06, 0xC0, 0x01, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x01, 0xE0, 0x0C, 0x3E, 0x0F, 0x07,
0xFF, 0x80, 0x7F, 0x80, 0x07, 0xE0, 0xFF, 0x1E, 0x01, 0xC0, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0xFF, 0xEF, 0xFE, 0x18, 0x01, 0x80, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01,
0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x00, 0x80, 0x01, 0xFF, 0x1C,
0x7F, 0xFB, 0x9C, 0x03, 0xF7, 0x00, 0x3F, 0xC0, 0x03, 0xF8, 0x00, 0x3E,
0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7E,
0x00, 0x1E, 0xC0, 0x03, 0xDC, 0x00, 0xF9, 0xE0, 0x77, 0x1F, 0xFC, 0xE0,
0xFF, 0x1C, 0x00, 0x03, 0x00, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x03, 0x9C,
0x00, 0xE3, 0xF0, 0xF8, 0x1F, 0xFE, 0x00, 0xFF, 0x00, 0xE0, 0x00, 0x70,
0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01,
0xC0, 0x80, 0xE7, 0xFC, 0x77, 0xFF, 0x3F, 0x01, 0xDF, 0x00, 0x7F, 0x00,
0x3F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8,
0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03,
0xE0, 0x01, 0xF0, 0x00, 0xC0, 0xFF, 0xA0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x03, 0x81, 0xC0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0x00,
0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18,
0x1F, 0x1D, 0xFE, 0x7C, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03,
0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0,
0x07, 0x38, 0x03, 0x8E, 0x01, 0xC3, 0x80, 0xE0, 0xE0, 0x70, 0x38, 0x78,
0x0E, 0x3C, 0x03, 0x9E, 0x00, 0xEF, 0xC0, 0x3F, 0x38, 0x0F, 0x87, 0x03,
0xC1, 0xE0, 0xE0, 0x38, 0x38, 0x07, 0x0E, 0x00, 0xE3, 0x80, 0x1C, 0xE0,
0x07, 0xB8, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0x00, 0x60, 0x01, 0x01, 0xCF, 0xF8, 0x3F, 0xE3, 0xBF, 0xF8,
0xFF, 0xE7, 0xE0, 0x7B, 0x81, 0xEF, 0x80, 0x7E, 0x01, 0xDE, 0x00, 0x78,
0x01, 0xF8, 0x00, 0xE0, 0x03, 0xF0, 0x01, 0xC0, 0x07, 0xE0, 0x03, 0x80,
0x0F, 0xC0, 0x07, 0x00, 0x1F, 0x80, 0x0E, 0x00, 0x3F, 0x00, 0x1C, 0x00,
0x7E, 0x00, 0x38, 0x00, 0xFC, 0x00, 0x70, 0x01, 0xF8, 0x00, 0xE0, 0x03,
0xF0, 0x01, 0xC0, 0x07, 0xE0, 0x03, 0x80, 0x0F, 0xC0, 0x07, 0x00, 0x1F,
0x80, 0x0E, 0x00, 0x38, 0x00, 0x40, 0x73, 0xFE, 0x3B, 0xFF, 0x9F, 0x80,
0xEF, 0x80, 0x3F, 0x80, 0x1F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0,
0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07,
0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x60, 0x00, 0x00, 0x03,
0xFF, 0x01, 0xFF, 0xE0, 0xF0, 0x3C, 0x70, 0x03, 0x98, 0x00, 0x6E, 0x00,
0x1F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03,
0xE0, 0x01, 0xF8, 0x00, 0x77, 0x00, 0x39, 0xE0, 0x1E, 0x3C, 0x0F, 0x07,
0xFF, 0x80, 0x7F, 0x80, 0x00, 0x00, 0x1C, 0x7F, 0x83, 0xBF, 0xFC, 0x7E,
0x03, 0xCF, 0x80, 0x1D, 0xE0, 0x03, 0xBC, 0x00, 0x3F, 0x00, 0x07, 0xE0,
0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xE0,
0x01, 0xBC, 0x00, 0x77, 0xC0, 0x1C, 0xEE, 0x0F, 0x9C, 0xFF, 0xC3, 0x8F,
0xF0, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00,
0x00, 0xE0, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x80, 0x03, 0xFE, 0x31, 0xFF,
0xCC, 0xF0, 0x3B, 0x70, 0x03, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0x00, 0x07,
0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xE0, 0x01, 0xF8,
0x00, 0x77, 0x00, 0x3D, 0xE0, 0x1F, 0x3C, 0x0E, 0xC7, 0xFF, 0x30, 0x7F,
0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x03,
0x00, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x79, 0xFE, 0xFF, 0xF0, 0xF8, 0x3C,
0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
0x80, 0xE0, 0x38, 0x0E, 0x00, 0x01, 0x00, 0x3F, 0xF0, 0xFF, 0xF3, 0x80,
0x66, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x38, 0x00, 0x7E, 0x00, 0x3F, 0xC0,
0x1F, 0xE0, 0x01, 0xE0, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0xA0, 0x07, 0xF0,
0x1C, 0xFF, 0xF0, 0x7F, 0xC0, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0xFF,
0xEF, 0xFE, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18,
0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x1C, 0x01, 0xE0, 0x0F,
0xF0, 0x7E, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00,
0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8,
0x00, 0xFC, 0x00, 0x7E, 0x00, 0x3B, 0x80, 0x3D, 0xC0, 0x1E, 0x78, 0x3B,
0x1F, 0xF9, 0x87, 0xF8, 0xC0, 0xE0, 0x00, 0xEC, 0x00, 0x19, 0xC0, 0x07,
0x18, 0x00, 0xC3, 0x80, 0x38, 0x30, 0x06, 0x07, 0x01, 0xC0, 0x60, 0x30,
0x0E, 0x06, 0x01, 0xC1, 0xC0, 0x18, 0x30, 0x03, 0x8E, 0x00, 0x31, 0x80,
0x07, 0x70, 0x00, 0x6C, 0x00, 0x0F, 0x80, 0x00, 0xE0, 0x00, 0x1C, 0x00,
0x60, 0x03, 0x80, 0x0D, 0x80, 0x0E, 0x00, 0x77, 0x00, 0x7C, 0x01, 0x8C,
0x01, 0xB0, 0x06, 0x30, 0x0E, 0xC0, 0x38, 0xE0, 0x33, 0x80, 0xC1, 0x80,
0xC6, 0x03, 0x07, 0x07, 0x18, 0x1C, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x60,
0xC3, 0x80, 0xE3, 0x03, 0x8C, 0x01, 0x8C, 0x06, 0x30, 0x06, 0x70, 0x19,
0xC0, 0x1D, 0x80, 0x76, 0x00, 0x36, 0x00, 0xD8, 0x00, 0xF8, 0x03, 0xC0,
0x01, 0xC0, 0x07, 0x00, 0x07, 0x00, 0x1C, 0x00, 0x60, 0x07, 0x38, 0x07,
0x0E, 0x03, 0x03, 0x83, 0x80, 0xE3, 0x80, 0x33, 0x80, 0x1D, 0x80, 0x07,
0xC0, 0x01, 0xC0, 0x01, 0xE0, 0x01, 0xF8, 0x00, 0xCE, 0x00, 0xE3, 0x80,
0xE0, 0xE0, 0xE0, 0x30, 0x60, 0x1C, 0x70, 0x07, 0x70, 0x01, 0xC0, 0x70,
0x00, 0x73, 0x00, 0x06, 0x38, 0x00, 0xE1, 0x80, 0x0C, 0x1C, 0x01, 0xC0,
0xC0, 0x18, 0x0E, 0x03, 0x80, 0x60, 0x30, 0x07, 0x03, 0x00, 0x70, 0x70,
0x03, 0x06, 0x00, 0x38, 0xE0, 0x01, 0x8C, 0x00, 0x1D, 0xC0, 0x00, 0xD8,
0x00, 0x0F, 0x80, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x06,
0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x63, 0x80, 0x0F, 0xF8, 0x00, 0x3E,
0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFC, 0x00, 0x70, 0x00, 0xC0, 0x03, 0x80,
0x0E, 0x00, 0x38, 0x00, 0xE0, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70,
0x01, 0xC0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
0x07, 0x87, 0xC7, 0x03, 0x81, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06,
0x03, 0x01, 0x80, 0xC0, 0x61, 0xF0, 0xF0, 0x3C, 0x06, 0x03, 0x01, 0x80,
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xE0, 0x78, 0x1F,
0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0,
0x7C, 0x0E, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03,
0x81, 0xC0, 0xE0, 0x70, 0x1F, 0x07, 0x87, 0x07, 0x03, 0x81, 0xC0, 0xE0,
0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0xE1, 0xF0, 0xE0,
0x00, 0x3E, 0x03, 0x7F, 0x03, 0x63, 0x83, 0xC1, 0xEE, 0xC0, 0x7C };
const GFXglyph Montserrat_Regular18pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 9, 0, 0 }, // 0x20 ' '
{ 1, 3, 25, 9, 3, -24 }, // 0x21 '!'
{ 11, 9, 10, 13, 2, -24 }, // 0x22 '"'
{ 23, 22, 25, 24, 1, -24 }, // 0x23 '#'
{ 92, 18, 33, 22, 2, -28 }, // 0x24 '$'
{ 167, 27, 25, 29, 1, -24 }, // 0x25 '%'
{ 252, 21, 25, 23, 2, -24 }, // 0x26 '&'
{ 318, 3, 10, 7, 2, -24 }, // 0x27 '''
{ 322, 6, 33, 12, 4, -25 }, // 0x28 '('
{ 347, 7, 33, 12, 1, -25 }, // 0x29 ')'
{ 376, 12, 13, 14, 1, -25 }, // 0x2A '*'
{ 396, 16, 15, 20, 2, -19 }, // 0x2B '+'
{ 426, 4, 9, 7, 2, -3 }, // 0x2C ','
{ 431, 9, 3, 13, 2, -10 }, // 0x2D '-'
{ 435, 4, 4, 7, 2, -3 }, // 0x2E '.'
{ 437, 14, 33, 12, -1, -28 }, // 0x2F '/'
{ 495, 19, 25, 23, 2, -24 }, // 0x30 '0'
{ 555, 9, 25, 13, 0, -24 }, // 0x31 '1'
{ 584, 18, 25, 20, 1, -24 }, // 0x32 '2'
{ 641, 18, 25, 20, 0, -24 }, // 0x33 '3'
{ 698, 22, 25, 23, 1, -24 }, // 0x34 '4'
{ 767, 17, 25, 20, 1, -24 }, // 0x35 '5'
{ 821, 18, 25, 21, 2, -24 }, // 0x36 '6'
{ 878, 18, 25, 21, 1, -24 }, // 0x37 '7'
{ 935, 19, 25, 22, 2, -24 }, // 0x38 '8'
{ 995, 19, 25, 21, 1, -24 }, // 0x39 '9'
{ 1055, 4, 19, 7, 2, -18 }, // 0x3A ':'
{ 1065, 4, 24, 7, 2, -18 }, // 0x3B ';'
{ 1077, 16, 15, 20, 2, -19 }, // 0x3C '<'
{ 1107, 16, 10, 20, 2, -16 }, // 0x3D '='
{ 1127, 16, 15, 20, 2, -19 }, // 0x3E '>'
{ 1157, 17, 25, 20, 0, -24 }, // 0x3F '?'
{ 1211, 32, 32, 36, 2, -24 }, // 0x40 '@'
{ 1339, 25, 25, 25, 0, -24 }, // 0x41 'A'
{ 1418, 20, 25, 26, 4, -24 }, // 0x42 'B'
{ 1481, 22, 25, 25, 2, -24 }, // 0x43 'C'
{ 1550, 23, 25, 29, 4, -24 }, // 0x44 'D'
{ 1622, 17, 25, 23, 4, -24 }, // 0x45 'E'
{ 1676, 17, 25, 22, 4, -24 }, // 0x46 'F'
{ 1730, 22, 25, 27, 2, -24 }, // 0x47 'G'
{ 1799, 20, 25, 28, 4, -24 }, // 0x48 'H'
{ 1862, 3, 25, 11, 4, -24 }, // 0x49 'I'
{ 1872, 14, 25, 18, 0, -24 }, // 0x4A 'J'
{ 1916, 21, 25, 25, 4, -24 }, // 0x4B 'K'
{ 1982, 16, 25, 21, 4, -24 }, // 0x4C 'L'
{ 2032, 25, 25, 33, 4, -24 }, // 0x4D 'M'
{ 2111, 20, 25, 28, 4, -24 }, // 0x4E 'N'
{ 2174, 26, 25, 29, 2, -24 }, // 0x4F 'O'
{ 2256, 19, 25, 25, 4, -24 }, // 0x50 'P'
{ 2316, 27, 30, 29, 2, -24 }, // 0x51 'Q'
{ 2418, 20, 25, 25, 4, -24 }, // 0x52 'R'
{ 2481, 18, 25, 22, 2, -24 }, // 0x53 'S'
{ 2538, 20, 25, 20, 0, -24 }, // 0x54 'T'
{ 2601, 20, 25, 28, 4, -24 }, // 0x55 'U'
{ 2664, 24, 25, 24, 0, -24 }, // 0x56 'V'
{ 2739, 37, 25, 39, 1, -24 }, // 0x57 'W'
{ 2855, 21, 25, 23, 1, -24 }, // 0x58 'X'
{ 2921, 22, 25, 22, 0, -24 }, // 0x59 'Y'
{ 2990, 20, 25, 23, 2, -24 }, // 0x5A 'Z'
{ 3053, 6, 33, 11, 4, -25 }, // 0x5B '['
{ 3078, 14, 33, 12, -1, -28 }, // 0x5C '\'
{ 3136, 6, 33, 11, 1, -25 }, // 0x5D ']'
{ 3161, 14, 15, 20, 3, -19 }, // 0x5E '^'
{ 3188, 18, 2, 18, 0, 1 }, // 0x5F '_'
{ 3193, 8, 5, 21, 5, -25 }, // 0x60 '`'
{ 3198, 15, 19, 21, 2, -18 }, // 0x61 'a'
{ 3234, 19, 26, 24, 3, -25 }, // 0x62 'b'
{ 3296, 16, 19, 20, 2, -18 }, // 0x63 'c'
{ 3334, 18, 26, 24, 2, -25 }, // 0x64 'd'
{ 3393, 18, 19, 21, 2, -18 }, // 0x65 'e'
{ 3436, 12, 26, 12, 1, -25 }, // 0x66 'f'
{ 3475, 19, 26, 24, 2, -18 }, // 0x67 'g'
{ 3537, 17, 26, 24, 3, -25 }, // 0x68 'h'
{ 3593, 3, 26, 9, 3, -25 }, // 0x69 'i'
{ 3603, 9, 33, 10, -3, -25 }, // 0x6A 'j'
{ 3641, 18, 26, 21, 3, -25 }, // 0x6B 'k'
{ 3700, 3, 26, 9, 3, -25 }, // 0x6C 'l'
{ 3710, 31, 19, 37, 3, -18 }, // 0x6D 'm'
{ 3784, 17, 19, 24, 3, -18 }, // 0x6E 'n'
{ 3825, 18, 19, 22, 2, -18 }, // 0x6F 'o'
{ 3868, 19, 26, 24, 3, -18 }, // 0x70 'p'
{ 3930, 18, 26, 24, 2, -18 }, // 0x71 'q'
{ 3989, 10, 19, 14, 3, -18 }, // 0x72 'r'
{ 4013, 15, 19, 17, 1, -18 }, // 0x73 's'
{ 4049, 12, 22, 14, 1, -21 }, // 0x74 't'
{ 4082, 17, 18, 24, 3, -17 }, // 0x75 'u'
{ 4121, 19, 18, 19, 0, -17 }, // 0x76 'v'
{ 4164, 30, 18, 31, 0, -17 }, // 0x77 'w'
{ 4232, 17, 18, 19, 1, -17 }, // 0x78 'x'
{ 4271, 20, 25, 19, -1, -17 }, // 0x79 'y'
{ 4334, 15, 18, 18, 1, -17 }, // 0x7A 'z'
{ 4368, 9, 33, 12, 2, -25 }, // 0x7B '{'
{ 4406, 2, 33, 10, 4, -25 }, // 0x7C '|'
{ 4415, 9, 33, 12, 1, -25 }, // 0x7D '}'
{ 4453, 16, 5, 20, 2, -14 } }; // 0x7E '~'
const GFXfont Montserrat_Regular18pt7b PROGMEM = {
(uint8_t *)Montserrat_Regular18pt7bBitmaps,
(GFXglyph *)Montserrat_Regular18pt7bGlyphs,
0x20, 0x7E, 43 };
// Approx. 5135 bytes
#endif // MONTSERRAT18PT7B_H
@@ -0,0 +1,568 @@
#ifndef MONTSERRAT20PT7B_H
#define MONTSERRAT20PT7B_H
const uint8_t Montserrat_Regular20pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0x77, 0x77, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x00,
0x06, 0xFF, 0x70, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xC1, 0xE0, 0xC0, 0x00, 0xC0, 0x30, 0x00, 0x60, 0x18, 0x00, 0x30, 0x0C,
0x00, 0x18, 0x06, 0x00, 0x0C, 0x03, 0x00, 0x0E, 0x01, 0x80, 0x06, 0x01,
0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x80, 0xC0, 0x30, 0x00, 0x60,
0x18, 0x00, 0x30, 0x0C, 0x00, 0x18, 0x06, 0x00, 0x1C, 0x03, 0x00, 0x0C,
0x03, 0x80, 0x06, 0x01, 0x80, 0x03, 0x00, 0xC0, 0x7F, 0xFF, 0xFF, 0xBF,
0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xE0, 0x30, 0x0C, 0x00, 0x38, 0x06, 0x00,
0x18, 0x07, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x01, 0x80, 0x03, 0x00, 0xC0,
0x01, 0x80, 0x60, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00,
0x06, 0x00, 0x00, 0x70, 0x00, 0x7F, 0xF0, 0x1F, 0xFF, 0xC3, 0xE6, 0x3E,
0x78, 0x60, 0x47, 0x06, 0x00, 0x70, 0x60, 0x0E, 0x06, 0x00, 0xE0, 0x60,
0x07, 0x06, 0x00, 0x70, 0x60, 0x07, 0xC6, 0x00, 0x3F, 0x60, 0x00, 0xFF,
0x00, 0x03, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x67, 0xE0, 0x06, 0x1E, 0x00,
0x60, 0xF0, 0x06, 0x07, 0x00, 0x60, 0x70, 0x06, 0x07, 0x00, 0x60, 0x7C,
0x06, 0x0F, 0xF0, 0x61, 0xE7, 0xE6, 0x7C, 0x3F, 0xFF, 0x80, 0x7F, 0xE0,
0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x18, 0x1E, 0x70, 0x01, 0x80,
0xC0, 0xC0, 0x1C, 0x0C, 0x06, 0x00, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0x00,
0xC0, 0xE0, 0x18, 0x06, 0x06, 0x00, 0xC0, 0x30, 0x60, 0x06, 0x01, 0x87,
0x00, 0x30, 0x0C, 0x30, 0x01, 0x80, 0xC3, 0x00, 0x06, 0x0E, 0x38, 0x00,
0x3F, 0xE1, 0x81, 0x80, 0x7E, 0x18, 0x7F, 0x00, 0x01, 0xC7, 0x1C, 0x00,
0x0C, 0x70, 0x70, 0x00, 0xC3, 0x01, 0x80, 0x0E, 0x18, 0x0C, 0x00, 0xE1,
0x80, 0x30, 0x06, 0x0C, 0x01, 0x80, 0x60, 0x60, 0x0C, 0x07, 0x03, 0x00,
0x60, 0x30, 0x0C, 0x06, 0x03, 0x00, 0x60, 0x30, 0x38, 0x01, 0x83, 0x81,
0x80, 0x0F, 0xF8, 0x18, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x03, 0xFC,
0x00, 0x07, 0xFE, 0x00, 0x0E, 0x07, 0x00, 0x0C, 0x03, 0x00, 0x1C, 0x03,
0x80, 0x1C, 0x03, 0x80, 0x1C, 0x03, 0x00, 0x0C, 0x07, 0x00, 0x0E, 0x0E,
0x00, 0x07, 0x1C, 0x00, 0x03, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x03, 0xE0,
0x00, 0x0F, 0xF0, 0x00, 0x1E, 0x78, 0x00, 0x38, 0x3C, 0x0C, 0x70, 0x1E,
0x1C, 0xE0, 0x0F, 0x1C, 0xE0, 0x07, 0x98, 0xE0, 0x03, 0xF8, 0xE0, 0x01,
0xF0, 0xE0, 0x00, 0xF0, 0xE0, 0x00, 0xF8, 0x70, 0x01, 0xFC, 0x3C, 0x0F,
0x9E, 0x1F, 0xFF, 0x0E, 0x07, 0xFC, 0x06, 0xFF, 0xFF, 0xF0, 0x0E, 0x18,
0x70, 0xE3, 0x87, 0x0C, 0x38, 0x70, 0xE1, 0x83, 0x0E, 0x1C, 0x38, 0x70,
0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0xC3, 0x87, 0x06,
0x0E, 0x1C, 0x18, 0x38, 0x70, 0x70, 0x60, 0xC1, 0xC1, 0xC3, 0x83, 0x07,
0x0E, 0x0C, 0x1C, 0x38, 0x70, 0x60, 0xC1, 0xC3, 0x87, 0x0E, 0x1C, 0x38,
0x70, 0xE1, 0xC3, 0x87, 0x0C, 0x38, 0x70, 0xE1, 0xC3, 0x0E, 0x1C, 0x30,
0xE1, 0x87, 0x0C, 0x00, 0x02, 0x00, 0x10, 0x00, 0x81, 0x84, 0x3F, 0x27,
0x9D, 0x70, 0x3E, 0x01, 0xF0, 0x3F, 0xE7, 0x93, 0xF8, 0x86, 0x04, 0x00,
0x20, 0x01, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, 0x00, 0x30, 0x00,
0x18, 0x00, 0x0C, 0x00, 0x06, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xC0, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x03,
0x00, 0x01, 0x80, 0x00, 0x7F, 0xF7, 0x76, 0x66, 0xCC, 0xFF, 0xFF, 0xFF,
0xFF, 0x80, 0x7F, 0xF7, 0x00, 0x06, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x60,
0x01, 0xC0, 0x03, 0x80, 0x06, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x60, 0x01,
0xC0, 0x03, 0x00, 0x06, 0x00, 0x1C, 0x00, 0x30, 0x00, 0x60, 0x01, 0xC0,
0x03, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x30, 0x00, 0xE0, 0x01, 0xC0, 0x03,
0x00, 0x0E, 0x00, 0x1C, 0x00, 0x30, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x00,
0x0E, 0x00, 0x18, 0x00, 0x30, 0x00, 0xE0, 0x01, 0x80, 0x03, 0x00, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x7F, 0xF8, 0x03, 0xC1,
0xF0, 0x1E, 0x01, 0xE0, 0xE0, 0x03, 0xC3, 0x80, 0x07, 0x1C, 0x00, 0x0E,
0x70, 0x00, 0x39, 0x80, 0x00, 0xEE, 0x00, 0x01, 0xB8, 0x00, 0x07, 0xE0,
0x00, 0x1F, 0x80, 0x00, 0x7E, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0x00,
0x1F, 0x80, 0x00, 0x7E, 0x00, 0x01, 0x9C, 0x00, 0x0E, 0x70, 0x00, 0x39,
0xC0, 0x01, 0xE3, 0x80, 0x07, 0x0F, 0x00, 0x3C, 0x1E, 0x01, 0xE0, 0x3F,
0x3F, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0x80, 0xFF, 0xFF, 0xF0, 0x1C, 0x07,
0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0,
0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C,
0x07, 0x01, 0xC0, 0x70, 0x1C, 0x00, 0x40, 0x00, 0xFF, 0xE0, 0x3F, 0xFF,
0x07, 0xC0, 0xF8, 0xF0, 0x03, 0xC4, 0x00, 0x1C, 0x00, 0x01, 0xC0, 0x00,
0x1C, 0x00, 0x01, 0xC0, 0x00, 0x1C, 0x00, 0x01, 0xC0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00,
0x07, 0x80, 0x00, 0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00,
0x0F, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF,
0xF7, 0xFF, 0xFF, 0x7F, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, 0x01, 0xC0, 0x00,
0x3C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00,
0x3C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0F, 0x80, 0x00, 0xFF, 0x00,
0x0F, 0xFC, 0x00, 0x03, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x07,
0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x60, 0x00,
0xEF, 0x80, 0x1E, 0x7F, 0x1F, 0xC1, 0xFF, 0xF8, 0x07, 0xFE, 0x00, 0x00,
0x07, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x03,
0x80, 0x00, 0x0F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x70, 0x00, 0x01, 0xC0,
0x00, 0x07, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x38, 0x0E, 0x00, 0xE0, 0x1C,
0x03, 0x80, 0x38, 0x0E, 0x00, 0x70, 0x3C, 0x00, 0xE0, 0x70, 0x01, 0xC1,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1C, 0x00,
0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00,
0x03, 0x80, 0x00, 0x07, 0x00, 0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x1C, 0x00,
0x01, 0x80, 0x00, 0x18, 0x00, 0x01, 0x80, 0x00, 0x38, 0x00, 0x03, 0x80,
0x00, 0x38, 0x00, 0x03, 0x80, 0x00, 0x38, 0x00, 0x03, 0xFF, 0xC0, 0x3F,
0xFF, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0xE0,
0x00, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x60, 0x00, 0x0E,
0x40, 0x01, 0xEF, 0x00, 0x3C, 0x7F, 0x1F, 0x83, 0xFF, 0xF0, 0x07, 0xFC,
0x00, 0x00, 0x0C, 0x00, 0x0F, 0xFE, 0x01, 0xFF, 0xF8, 0x1F, 0x01, 0x81,
0xE0, 0x00, 0x1E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x70, 0x00,
0x03, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0x1F, 0xF0, 0x73,
0xFF, 0xE3, 0xBC, 0x0F, 0x9F, 0x80, 0x1C, 0xF8, 0x00, 0x77, 0x80, 0x03,
0xBC, 0x00, 0x0C, 0xE0, 0x00, 0x77, 0x00, 0x03, 0xB8, 0x00, 0x18, 0xE0,
0x01, 0xC7, 0x00, 0x0E, 0x1C, 0x00, 0xE0, 0x78, 0x1E, 0x01, 0xFF, 0xE0,
0x03, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7E, 0x00,
0x0F, 0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x01, 0xC0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x0E, 0x00,
0x00, 0xE0, 0x00, 0x1E, 0x00, 0x01, 0xC0, 0x00, 0x1C, 0x00, 0x03, 0x80,
0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x00, 0xE0,
0x00, 0x1C, 0x00, 0x01, 0xC0, 0x00, 0x3C, 0x00, 0x03, 0x80, 0x00, 0x00,
0x20, 0x00, 0x3F, 0xF8, 0x07, 0xFF, 0xF0, 0x7C, 0x07, 0xC3, 0x80, 0x0E,
0x38, 0x00, 0x39, 0xC0, 0x01, 0xCE, 0x00, 0x0E, 0x70, 0x00, 0x73, 0x80,
0x03, 0x9E, 0x00, 0x38, 0x78, 0x03, 0xC1, 0xF8, 0xFC, 0x03, 0xFF, 0x80,
0x7F, 0xFF, 0x07, 0x80, 0x7C, 0x78, 0x00, 0xF7, 0x80, 0x03, 0xB8, 0x00,
0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xEE,
0x00, 0x0E, 0x78, 0x00, 0xF1, 0xF0, 0x1F, 0x07, 0xFF, 0xF0, 0x0F, 0xFE,
0x00, 0x00, 0x60, 0x00, 0x3F, 0xF0, 0x07, 0xFF, 0xC0, 0x78, 0x0F, 0x07,
0x80, 0x1C, 0x38, 0x00, 0x73, 0x80, 0x03, 0x9C, 0x00, 0x0E, 0xE0, 0x00,
0x77, 0x00, 0x03, 0xB8, 0x00, 0x1C, 0xE0, 0x01, 0xF7, 0x00, 0x1F, 0x9C,
0x01, 0xDC, 0xFE, 0x7C, 0xE1, 0xFF, 0xC7, 0x03, 0xF8, 0x38, 0x00, 0x01,
0x80, 0x00, 0x1C, 0x00, 0x00, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00,
0x03, 0x80, 0x00, 0x38, 0x00, 0x07, 0x81, 0xC0, 0xF8, 0x0F, 0xFF, 0x80,
0x3F, 0xF0, 0x00, 0x7F, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0xFF, 0x70, 0x7F, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF,
0x77, 0x66, 0x6C, 0xC0, 0x00, 0x00, 0x80, 0x01, 0xC0, 0x07, 0xE0, 0x0F,
0xC0, 0x3F, 0x00, 0x7E, 0x01, 0xF8, 0x01, 0xE0, 0x00, 0xE0, 0x00, 0x7C,
0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x3E,
0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
0xFF, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x3E, 0x00, 0x07, 0xE0, 0x00, 0xFC,
0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0x80, 0x0F, 0xC0,
0x1F, 0x80, 0x7E, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0xE0, 0x01, 0x80, 0x00,
0x00, 0x60, 0x00, 0xFF, 0xC0, 0x7F, 0xFE, 0x3E, 0x03, 0xEF, 0x00, 0x1E,
0x40, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C,
0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x1E, 0x00, 0x07, 0x80,
0x00, 0xE0, 0x00, 0x38, 0x00, 0x0F, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
0x0F, 0x00, 0x01, 0xE0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
0x00, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xDF, 0xE0, 0x00, 0x1F, 0x00, 0x07,
0x80, 0x03, 0xC0, 0x00, 0x1C, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x0E, 0x00,
0x00, 0x03, 0x01, 0xC0, 0x00, 0x00, 0x18, 0x18, 0x01, 0xF8, 0x71, 0xC3,
0x00, 0xFF, 0xE7, 0x0C, 0x30, 0x1F, 0x1F, 0x70, 0x66, 0x03, 0xC0, 0x3F,
0x06, 0x60, 0x78, 0x01, 0xF0, 0x76, 0x07, 0x00, 0x0F, 0x03, 0xE0, 0xE0,
0x00, 0x70, 0x3C, 0x0E, 0x00, 0x07, 0x03, 0xC0, 0xE0, 0x00, 0x70, 0x3C,
0x0E, 0x00, 0x07, 0x03, 0xC0, 0xE0, 0x00, 0x70, 0x3C, 0x0E, 0x00, 0x07,
0x03, 0xC0, 0xE0, 0x00, 0x70, 0x3C, 0x0E, 0x00, 0x07, 0x03, 0xE0, 0x70,
0x00, 0xF0, 0x36, 0x07, 0x00, 0x0F, 0x06, 0x60, 0x38, 0x03, 0xF0, 0x67,
0x01, 0xE0, 0x73, 0x8E, 0x30, 0x0F, 0xFE, 0x3F, 0xC3, 0x80, 0x3F, 0x81,
0xF8, 0x1C, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x40, 0x00,
0x07, 0xE0, 0x7C, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xC0,
0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x1F, 0x80, 0x00,
0x01, 0xF8, 0x00, 0x00, 0x39, 0xC0, 0x00, 0x03, 0x9C, 0x00, 0x00, 0x70,
0xE0, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x60, 0x60, 0x00, 0x0E, 0x07, 0x00,
0x00, 0xC0, 0x70, 0x00, 0x1C, 0x03, 0x80, 0x01, 0xC0, 0x38, 0x00, 0x38,
0x01, 0xC0, 0x03, 0x80, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x07, 0x00, 0x0E,
0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x1C,
0x00, 0x03, 0x81, 0xC0, 0x00, 0x38, 0x38, 0x00, 0x01, 0xC3, 0x80, 0x00,
0x1C, 0x70, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x0E, 0xE0, 0x00, 0x00, 0x70,
0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xC3, 0x80, 0x07, 0xC7, 0x00, 0x03, 0xCE,
0x00, 0x03, 0x9C, 0x00, 0x03, 0xB8, 0x00, 0x07, 0x70, 0x00, 0x0E, 0xE0,
0x00, 0x1D, 0xC0, 0x00, 0x73, 0x80, 0x01, 0xE7, 0x00, 0x0F, 0x8F, 0xFF,
0xFC, 0x1F, 0xFF, 0xFC, 0x38, 0x00, 0xFE, 0x70, 0x00, 0x1E, 0xE0, 0x00,
0x1F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00, 0x00, 0x7E, 0x00, 0x00,
0xFC, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x1E, 0xE0, 0x03, 0xF9,
0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7F, 0xF0,
0x01, 0xFF, 0xFC, 0x07, 0xE0, 0x3E, 0x0F, 0x80, 0x0F, 0x1E, 0x00, 0x02,
0x3C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00,
0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00,
0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00,
0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00,
0x1C, 0x00, 0x02, 0x1E, 0x00, 0x07, 0x0F, 0x80, 0x0F, 0x07, 0xF8, 0xFE,
0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xE0, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF8,
0x0E, 0x00, 0x3F, 0x83, 0x80, 0x01, 0xF0, 0xE0, 0x00, 0x1E, 0x38, 0x00,
0x03, 0xCE, 0x00, 0x00, 0x73, 0x80, 0x00, 0x0E, 0xE0, 0x00, 0x03, 0xB8,
0x00, 0x00, 0x7E, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x07, 0xE0, 0x00, 0x01,
0xF8, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x07, 0xE0, 0x00,
0x01, 0xF8, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3B, 0x80, 0x00, 0x0E, 0xE0,
0x00, 0x07, 0x38, 0x00, 0x03, 0xCE, 0x00, 0x01, 0xE3, 0x80, 0x01, 0xF0,
0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF,
0xEF, 0xFF, 0xFE, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00,
0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0,
0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, 0xE0, 0x00, 0x0E,
0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00,
0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00,
0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00,
0x01, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00,
0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x7F, 0xFF, 0x00, 0xFC, 0x07, 0xE0,
0xF8, 0x00, 0x78, 0xF0, 0x00, 0x18, 0xF0, 0x00, 0x00, 0x70, 0x00, 0x00,
0x70, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1C, 0x00, 0x00,
0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x80, 0x00, 0x0D, 0xC0, 0x00,
0x06, 0xE0, 0x00, 0x03, 0x70, 0x00, 0x01, 0x9C, 0x00, 0x00, 0xCE, 0x00,
0x00, 0x67, 0x80, 0x00, 0x31, 0xC0, 0x00, 0x18, 0x70, 0x00, 0x0C, 0x3C,
0x00, 0x06, 0x0F, 0x80, 0x0F, 0x01, 0xFC, 0x3F, 0x80, 0x7F, 0xFF, 0x00,
0x07, 0xFC, 0x00, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F,
0x00, 0x00, 0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0,
0x00, 0x07, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00,
0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xF0, 0x00,
0x07, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00, 0x00,
0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x07,
0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x38, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFE, 0x7F, 0xFC,
0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00,
0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03,
0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE8,
0x01, 0xD0, 0x03, 0xF8, 0x0E, 0x7C, 0x7C, 0x7F, 0xF0, 0x3F, 0x80, 0xE0,
0x00, 0x1C, 0xE0, 0x00, 0x38, 0xE0, 0x00, 0x70, 0xE0, 0x00, 0xE0, 0xE0,
0x01, 0xC0, 0xE0, 0x03, 0x80, 0xE0, 0x07, 0x00, 0xE0, 0x0E, 0x00, 0xE0,
0x1C, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x70, 0x00, 0xE0, 0xE0, 0x00, 0xE1,
0xE0, 0x00, 0xE3, 0xF0, 0x00, 0xE7, 0xF8, 0x00, 0xEF, 0x3C, 0x00, 0xFE,
0x1E, 0x00, 0xFC, 0x0E, 0x00, 0xF8, 0x07, 0x00, 0xF0, 0x03, 0x80, 0xE0,
0x03, 0xC0, 0xE0, 0x01, 0xE0, 0xE0, 0x00, 0xF0, 0xE0, 0x00, 0x78, 0xE0,
0x00, 0x38, 0xE0, 0x00, 0x1C, 0xE0, 0x00, 0x0E, 0xE0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00,
0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00,
0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00,
0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00,
0x38, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x80, 0xE0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F,
0xF0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0xFF, 0xB8,
0x00, 0x0E, 0xFC, 0xC0, 0x00, 0x77, 0xE7, 0x00, 0x07, 0x3F, 0x1C, 0x00,
0x39, 0xF8, 0xE0, 0x03, 0x8F, 0xC3, 0x80, 0x18, 0x7E, 0x1C, 0x01, 0xC3,
0xF0, 0x70, 0x1C, 0x1F, 0x81, 0xC0, 0xE0, 0xFC, 0x0E, 0x0E, 0x07, 0xE0,
0x38, 0x60, 0x3F, 0x01, 0xC7, 0x01, 0xF8, 0x07, 0x30, 0x0F, 0xC0, 0x1B,
0x80, 0x7E, 0x00, 0xF8, 0x03, 0xF0, 0x03, 0xC0, 0x1F, 0x80, 0x1C, 0x00,
0xFC, 0x00, 0x40, 0x07, 0xE0, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xF8,
0x00, 0x00, 0x0E, 0xE0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x3F,
0xE0, 0x00, 0x7F, 0xE0, 0x00, 0xFD, 0xC0, 0x01, 0xF9, 0xC0, 0x03, 0xF3,
0xC0, 0x07, 0xE3, 0xC0, 0x0F, 0xC3, 0xC0, 0x1F, 0x83, 0x80, 0x3F, 0x03,
0x80, 0x7E, 0x07, 0x80, 0xFC, 0x07, 0x81, 0xF8, 0x07, 0x83, 0xF0, 0x07,
0x07, 0xE0, 0x07, 0x0F, 0xC0, 0x0F, 0x1F, 0x80, 0x0F, 0x3F, 0x00, 0x0F,
0x7E, 0x00, 0x0E, 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x1F,
0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x38, 0x00, 0x02, 0x00,
0x00, 0x03, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0x00, 0x0F, 0xC0, 0x7E, 0x00,
0xF0, 0x00, 0xF8, 0x0F, 0x00, 0x01, 0xE0, 0xF0, 0x00, 0x07, 0x07, 0x00,
0x00, 0x1C, 0x70, 0x00, 0x00, 0xE3, 0x80, 0x00, 0x03, 0xB8, 0x00, 0x00,
0x1D, 0xC0, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x1F,
0x80, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x3F, 0x00,
0x00, 0x03, 0x9C, 0x00, 0x00, 0x1C, 0xE0, 0x00, 0x00, 0xE7, 0x80, 0x00,
0x0E, 0x1C, 0x00, 0x00, 0xF0, 0x70, 0x00, 0x0F, 0x03, 0xC0, 0x00, 0xF0,
0x0F, 0x80, 0x0F, 0x00, 0x1F, 0xC7, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x00,
0x7F, 0xC0, 0x00, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x0E, 0x00, 0x7E, 0x38,
0x00, 0x3C, 0xE0, 0x00, 0x7B, 0x80, 0x00, 0xEE, 0x00, 0x01, 0xF8, 0x00,
0x07, 0xE0, 0x00, 0x1F, 0x80, 0x00, 0x7E, 0x00, 0x01, 0xF8, 0x00, 0x07,
0xE0, 0x00, 0x3B, 0x80, 0x01, 0xEE, 0x00, 0x0F, 0x38, 0x01, 0xF8, 0xFF,
0xFF, 0xC3, 0xFF, 0xFC, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00,
0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x03,
0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xFF,
0xC0, 0x00, 0x1F, 0xFF, 0xC0, 0x01, 0xF8, 0x0F, 0xC0, 0x0F, 0x00, 0x0F,
0x80, 0x78, 0x00, 0x0F, 0x03, 0xC0, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x38,
0x70, 0x00, 0x00, 0xE1, 0xC0, 0x00, 0x01, 0xCE, 0x00, 0x00, 0x07, 0x38,
0x00, 0x00, 0x1C, 0xE0, 0x00, 0x00, 0x3B, 0x80, 0x00, 0x00, 0xEE, 0x00,
0x00, 0x03, 0xB8, 0x00, 0x00, 0x0E, 0xE0, 0x00, 0x00, 0x3B, 0x80, 0x00,
0x01, 0xC7, 0x00, 0x00, 0x07, 0x1C, 0x00, 0x00, 0x1C, 0x78, 0x00, 0x00,
0xE0, 0xE0, 0x00, 0x07, 0x81, 0xC0, 0x00, 0x3C, 0x07, 0x80, 0x01, 0xE0,
0x0F, 0x80, 0x0F, 0x00, 0x0F, 0xE3, 0xF8, 0x00, 0x1F, 0xFF, 0xC0, 0x00,
0x0F, 0xF8, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0x80, 0x20, 0x00,
0x0F, 0x83, 0xC0, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x1F, 0xE0, 0xFF, 0xFF,
0x03, 0xFF, 0xFF, 0x0E, 0x00, 0x7E, 0x38, 0x00, 0x3C, 0xE0, 0x00, 0x7B,
0x80, 0x00, 0xEE, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1F, 0x80,
0x00, 0x7E, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x3B, 0x80, 0x01,
0xEE, 0x00, 0x0F, 0x38, 0x00, 0xF8, 0xFF, 0xFF, 0xC3, 0xFF, 0xFC, 0x0E,
0x00, 0x70, 0x38, 0x00, 0xE0, 0xE0, 0x03, 0xC3, 0x80, 0x07, 0x0E, 0x00,
0x0E, 0x38, 0x00, 0x1C, 0xE0, 0x00, 0x73, 0x80, 0x00, 0xEE, 0x00, 0x01,
0xC0, 0x00, 0x30, 0x00, 0x7F, 0xF0, 0x1F, 0xFF, 0xC3, 0xE0, 0x3E, 0x78,
0x00, 0x47, 0x00, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x07,
0x00, 0x00, 0x70, 0x00, 0x07, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFF, 0x00,
0x03, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1E, 0x00, 0x00,
0xF0, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x7C, 0x00,
0x0F, 0xF0, 0x01, 0xE7, 0xE0, 0x7C, 0x3F, 0xFF, 0x80, 0x7F, 0xE0, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38,
0x00, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00,
0x00, 0xE0, 0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00,
0xE0, 0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0,
0x00, 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00,
0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x03,
0x80, 0x00, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00,
0x00, 0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0, 0x00,
0x07, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00, 0x00,
0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x07,
0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x33, 0x80, 0x00, 0xE7,
0x00, 0x01, 0xCF, 0x00, 0x07, 0x8E, 0x00, 0x1E, 0x0F, 0x00, 0x78, 0x1F,
0xC7, 0xE0, 0x0F, 0xFF, 0x80, 0x07, 0xFC, 0x00, 0xF0, 0x00, 0x00, 0xEE,
0x00, 0x00, 0x39, 0xC0, 0x00, 0x07, 0x1C, 0x00, 0x00, 0xC3, 0x80, 0x00,
0x38, 0x38, 0x00, 0x07, 0x07, 0x00, 0x01, 0xC0, 0x70, 0x00, 0x38, 0x0E,
0x00, 0x0E, 0x01, 0xE0, 0x01, 0xC0, 0x1C, 0x00, 0x70, 0x03, 0x80, 0x0E,
0x00, 0x38, 0x01, 0x80, 0x07, 0x00, 0x70, 0x00, 0x70, 0x0E, 0x00, 0x0E,
0x03, 0x80, 0x00, 0xE0, 0x70, 0x00, 0x1C, 0x1C, 0x00, 0x03, 0xC3, 0x80,
0x00, 0x38, 0xE0, 0x00, 0x07, 0x1C, 0x00, 0x00, 0x73, 0x00, 0x00, 0x0E,
0xE0, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x01, 0xE0, 0x00,
0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x1C, 0x00, 0x03, 0xB8, 0x00, 0x0F,
0x00, 0x01, 0x9C, 0x00, 0x0F, 0x80, 0x01, 0xC7, 0x00, 0x07, 0xC0, 0x00,
0xE3, 0x80, 0x03, 0x70, 0x00, 0x61, 0xC0, 0x03, 0xB8, 0x00, 0x70, 0x70,
0x01, 0xCC, 0x00, 0x38, 0x38, 0x00, 0xC7, 0x00, 0x18, 0x1C, 0x00, 0xE3,
0x80, 0x1C, 0x07, 0x00, 0x70, 0xC0, 0x0E, 0x03, 0x80, 0x30, 0x70, 0x0E,
0x01, 0xC0, 0x38, 0x38, 0x07, 0x00, 0x70, 0x1C, 0x0C, 0x03, 0x80, 0x38,
0x0C, 0x07, 0x03, 0x80, 0x1C, 0x0E, 0x03, 0x81, 0xC0, 0x07, 0x07, 0x00,
0xC0, 0xE0, 0x03, 0x83, 0x00, 0x70, 0xE0, 0x01, 0xC3, 0x80, 0x38, 0x70,
0x00, 0x71, 0xC0, 0x0C, 0x38, 0x00, 0x38, 0xC0, 0x07, 0x38, 0x00, 0x1C,
0xE0, 0x03, 0x9C, 0x00, 0x07, 0x70, 0x00, 0xEE, 0x00, 0x03, 0xB0, 0x00,
0x7E, 0x00, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x00, 0x7C, 0x00, 0x0F, 0x80,
0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x70,
0x00, 0x1E, 0x38, 0x00, 0x1C, 0x3C, 0x00, 0x38, 0x1C, 0x00, 0x70, 0x0E,
0x00, 0x70, 0x07, 0x00, 0xE0, 0x07, 0x81, 0xC0, 0x03, 0x83, 0x80, 0x01,
0xC3, 0x80, 0x01, 0xE7, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7E, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xEE, 0x00, 0x01,
0xE7, 0x00, 0x01, 0xC3, 0x80, 0x03, 0x83, 0xC0, 0x07, 0x01, 0xC0, 0x0F,
0x00, 0xE0, 0x0E, 0x00, 0xF0, 0x1C, 0x00, 0x78, 0x3C, 0x00, 0x38, 0x78,
0x00, 0x1C, 0x70, 0x00, 0x1E, 0xE0, 0x00, 0x0F, 0x70, 0x00, 0x07, 0x38,
0x00, 0x03, 0x8E, 0x00, 0x03, 0x87, 0x00, 0x01, 0x81, 0xC0, 0x01, 0xC0,
0x70, 0x01, 0xC0, 0x38, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x07, 0x00, 0xE0,
0x01, 0xC0, 0x70, 0x00, 0x70, 0x70, 0x00, 0x38, 0x38, 0x00, 0x0E, 0x38,
0x00, 0x07, 0xB8, 0x00, 0x01, 0xDC, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01,
0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF0, 0x00, 0x03, 0x80, 0x00, 0x1C, 0x00, 0x00, 0xE0, 0x00,
0x07, 0x80, 0x00, 0x3C, 0x00, 0x00, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x3C,
0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00,
0x0F, 0x00, 0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x0E, 0x00, 0x00, 0x70,
0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00,
0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF,
0xFF, 0xC0, 0x01, 0xC0, 0x03, 0x80, 0x03, 0x00, 0x07, 0x00, 0x06, 0x00,
0x0C, 0x00, 0x1C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x70, 0x00, 0x60, 0x00,
0xE0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x07, 0x00, 0x06, 0x00, 0x0E,
0x00, 0x1C, 0x00, 0x18, 0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x00, 0xE0,
0x00, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00,
0x0C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x30, 0x00, 0x70, 0x00, 0xE0, 0xFF,
0xFC, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3,
0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70,
0xE1, 0xC3, 0x87, 0x0E, 0x1F, 0xFF, 0xFF, 0xE0, 0x01, 0xC0, 0x01, 0xC0,
0x03, 0xC0, 0x03, 0x60, 0x06, 0x60, 0x06, 0x70, 0x0E, 0x30, 0x0C, 0x30,
0x0C, 0x18, 0x18, 0x18, 0x18, 0x1C, 0x38, 0x0C, 0x30, 0x0E, 0x70, 0x06,
0x60, 0x06, 0x60, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x07,
0x01, 0xC0, 0x78, 0x01, 0xC0, 0x0F, 0xFE, 0x1F, 0xFF, 0x8F, 0x01, 0xE2,
0x00, 0x78, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x01, 0x80, 0xFF,
0xC7, 0xFF, 0xE7, 0xE0, 0x37, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0,
0x07, 0xE0, 0x03, 0xB8, 0x03, 0xDE, 0x07, 0x67, 0xFF, 0x30, 0xFF, 0x18,
0xE0, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0x00,
0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x1C, 0x00, 0x00, 0xE0, 0x70, 0x07,
0x1F, 0xF0, 0x3B, 0xFF, 0xE1, 0xFC, 0x07, 0x8F, 0x80, 0x1E, 0x78, 0x00,
0x73, 0xC0, 0x01, 0xDC, 0x00, 0x0E, 0xE0, 0x00, 0x37, 0x00, 0x01, 0xF8,
0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x3B, 0x80, 0x01,
0xDE, 0x00, 0x1E, 0xF8, 0x00, 0xE7, 0xE0, 0x0E, 0x3B, 0xC3, 0xF1, 0xCF,
0xFE, 0x0E, 0x1F, 0xC0, 0x00, 0x00, 0xF0, 0x01, 0xFF, 0x80, 0xFF, 0xF8,
0x78, 0x0F, 0x38, 0x01, 0xDC, 0x00, 0x27, 0x00, 0x03, 0x80, 0x00, 0xE0,
0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00,
0x0E, 0x00, 0x01, 0xC0, 0x00, 0x78, 0x00, 0x8F, 0x00, 0x71, 0xF0, 0xF8,
0x3F, 0xFC, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00,
0x0E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x1C, 0x00, 0x00, 0xE0,
0x00, 0x07, 0x00, 0x60, 0x38, 0x3F, 0xF1, 0xC7, 0xFF, 0xCE, 0x7C, 0x07,
0x73, 0x80, 0x1F, 0xB8, 0x00, 0x7D, 0xC0, 0x01, 0xFC, 0x00, 0x0F, 0xE0,
0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03,
0xF0, 0x00, 0x3F, 0x80, 0x01, 0xEE, 0x00, 0x1F, 0x78, 0x00, 0xF9, 0xE0,
0x0F, 0xC7, 0xC3, 0xEE, 0x1F, 0xFE, 0x70, 0x3F, 0xC3, 0x80, 0x00, 0xE0,
0x00, 0x7F, 0xE0, 0x1F, 0xFF, 0x03, 0xC0, 0x78, 0x38, 0x01, 0xC7, 0x00,
0x0E, 0x60, 0x00, 0xEE, 0x00, 0x06, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x07,
0x00, 0x00, 0x78, 0x00, 0x83, 0xC0, 0x1C, 0x1F, 0x87, 0xC0, 0xFF, 0xF8,
0x03, 0xFE, 0x00, 0x03, 0xF8, 0x1F, 0xE0, 0xF1, 0x83, 0x80, 0x1C, 0x00,
0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x03, 0xFF, 0xCF, 0xFF, 0x07, 0x00,
0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0,
0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70,
0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x00, 0x70, 0x00, 0x3F, 0xF1, 0xC7,
0xFF, 0xEE, 0x7C, 0x07, 0xF7, 0x80, 0x0F, 0xB8, 0x00, 0x3F, 0xC0, 0x01,
0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0,
0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x3D, 0xC0, 0x01, 0xEF, 0x00, 0x1F,
0x3C, 0x01, 0xF8, 0xF8, 0x3D, 0xC3, 0xFF, 0xCE, 0x07, 0xF8, 0x70, 0x00,
0x03, 0x80, 0x00, 0x1C, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0x30, 0x00, 0xF3,
0xE0, 0x0F, 0x0F, 0xFF, 0xF0, 0x1F, 0xFF, 0x00, 0x1F, 0x80, 0x00, 0xE0,
0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0,
0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0xF0, 0x1C, 0xFF, 0xC3, 0xBF,
0xFC, 0x7E, 0x03, 0xCF, 0x80, 0x3D, 0xE0, 0x03, 0xB8, 0x00, 0x37, 0x00,
0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00,
0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00,
0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0E, 0xEF, 0xFE, 0x00, 0x00,
0x0E, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xE0, 0x00,
0xE0, 0x0F, 0x00, 0xF0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE4, 0x1C, 0x7F, 0xC7, 0xF8, 0x1C, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03,
0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07,
0x00, 0x00, 0xE0, 0x00, 0x5C, 0x00, 0x73, 0x80, 0x1C, 0x70, 0x07, 0x0E,
0x01, 0xC1, 0xC0, 0xF0, 0x38, 0x3C, 0x07, 0x0F, 0x00, 0xE3, 0xC0, 0x1C,
0xF8, 0x03, 0xBF, 0x80, 0x7F, 0x78, 0x0F, 0xC7, 0x01, 0xE0, 0x70, 0x38,
0x07, 0x07, 0x00, 0xF0, 0xE0, 0x0F, 0x1C, 0x00, 0xE3, 0x80, 0x0E, 0x70,
0x00, 0xEE, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0x00, 0x60, 0x00, 0xE0, 0x39, 0xFF, 0x81, 0xFF, 0x0E,
0xFF, 0xF1, 0xFF, 0xE3, 0xF0, 0x1E, 0xF0, 0x3C, 0xF8, 0x03, 0xF0, 0x07,
0xBC, 0x00, 0x78, 0x00, 0xEE, 0x00, 0x1E, 0x00, 0x1B, 0x80, 0x07, 0x80,
0x07, 0xE0, 0x01, 0xC0, 0x01, 0xF8, 0x00, 0x70, 0x00, 0x7E, 0x00, 0x1C,
0x00, 0x1F, 0x80, 0x07, 0x00, 0x07, 0xE0, 0x01, 0xC0, 0x01, 0xF8, 0x00,
0x70, 0x00, 0x7E, 0x00, 0x1C, 0x00, 0x1F, 0x80, 0x07, 0x00, 0x07, 0xE0,
0x01, 0xC0, 0x01, 0xF8, 0x00, 0x70, 0x00, 0x7E, 0x00, 0x1C, 0x00, 0x1F,
0x80, 0x07, 0x00, 0x07, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x00, 0xF0, 0x1C,
0xFF, 0xC3, 0xBF, 0xFC, 0x7E, 0x03, 0xCF, 0x80, 0x3D, 0xE0, 0x03, 0xB8,
0x00, 0x37, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0,
0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0,
0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0E, 0x00,
0x70, 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0xE0, 0x3C, 0x07, 0x83, 0x80, 0x1E,
0x38, 0x00, 0x71, 0xC0, 0x01, 0xDC, 0x00, 0x0E, 0xE0, 0x00, 0x37, 0x00,
0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x3B,
0x80, 0x01, 0xCE, 0x00, 0x1E, 0x78, 0x00, 0xE1, 0xE0, 0x0E, 0x07, 0xC3,
0xE0, 0x1F, 0xFE, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x70, 0x07, 0x1F, 0xF0,
0x3B, 0xFF, 0xE1, 0xFC, 0x07, 0x8F, 0x80, 0x1E, 0x78, 0x00, 0x73, 0xC0,
0x01, 0xDC, 0x00, 0x0E, 0xE0, 0x00, 0x37, 0x00, 0x01, 0xF8, 0x00, 0x0F,
0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x3B, 0x80, 0x01, 0xDE, 0x00,
0x1E, 0xF8, 0x00, 0xE7, 0xE0, 0x0E, 0x3B, 0xC3, 0xF1, 0xCF, 0xFE, 0x0E,
0x1F, 0xC0, 0x70, 0x00, 0x03, 0x80, 0x00, 0x1C, 0x00, 0x00, 0xE0, 0x00,
0x07, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x00, 0x60, 0x00, 0x3F, 0xF1, 0xC7, 0xFF, 0xCE, 0x7C, 0x07, 0x73, 0x80,
0x1F, 0xB8, 0x00, 0x7D, 0xC0, 0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x3F,
0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00,
0x3F, 0x80, 0x01, 0xEE, 0x00, 0x1F, 0x78, 0x00, 0xF9, 0xE0, 0x0F, 0xC7,
0xC3, 0xEE, 0x1F, 0xFE, 0x70, 0x3F, 0xC3, 0x80, 0x00, 0x1C, 0x00, 0x00,
0xE0, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0x00,
0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x79, 0xFE, 0xFF, 0xF8, 0xF8, 0x3C,
0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x00, 0x01, 0xE0, 0x07, 0xFF,
0x0F, 0xFF, 0xCF, 0x00, 0xC7, 0x00, 0x03, 0x80, 0x01, 0x80, 0x00, 0xE0,
0x00, 0x78, 0x00, 0x1F, 0x80, 0x07, 0xFE, 0x00, 0x7F, 0xC0, 0x01, 0xF0,
0x00, 0x3C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xB0, 0x03, 0xBF, 0x07,
0xCF, 0xFF, 0xC0, 0xFF, 0x80, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00,
0x1C, 0x03, 0xFF, 0xCF, 0xFF, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0,
0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70,
0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x38, 0x00, 0xF1, 0x81, 0xFF, 0x03,
0xF8, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00,
0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C,
0x00, 0x0F, 0x00, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xC0,
0x0F, 0x78, 0x07, 0xCF, 0x8F, 0xB1, 0xFF, 0xCC, 0x3F, 0xC3, 0xE0, 0x00,
0x3B, 0x80, 0x03, 0x9C, 0x00, 0x1C, 0x70, 0x00, 0xC3, 0x80, 0x0E, 0x0E,
0x00, 0x60, 0x70, 0x07, 0x01, 0x80, 0x38, 0x0E, 0x03, 0x80, 0x70, 0x1C,
0x01, 0xC1, 0xC0, 0x0E, 0x0E, 0x00, 0x38, 0x60, 0x01, 0xC7, 0x00, 0x06,
0x30, 0x00, 0x3B, 0x80, 0x00, 0xDC, 0x00, 0x07, 0xC0, 0x00, 0x3E, 0x00,
0x00, 0xE0, 0x00, 0x60, 0x00, 0xE0, 0x01, 0xDC, 0x00, 0x78, 0x00, 0x67,
0x00, 0x1E, 0x00, 0x38, 0xC0, 0x0F, 0xC0, 0x0C, 0x38, 0x03, 0xB0, 0x03,
0x06, 0x00, 0xCE, 0x01, 0xC1, 0xC0, 0x73, 0x80, 0x60, 0x70, 0x18, 0x60,
0x38, 0x0C, 0x06, 0x1C, 0x0E, 0x03, 0x83, 0x83, 0x03, 0x00, 0xE0, 0xC0,
0xC1, 0xC0, 0x18, 0x70, 0x38, 0x60, 0x07, 0x1C, 0x06, 0x18, 0x00, 0xC6,
0x01, 0xCE, 0x00, 0x3B, 0x80, 0x73, 0x00, 0x0E, 0xC0, 0x0D, 0xC0, 0x01,
0xB0, 0x03, 0xF0, 0x00, 0x7C, 0x00, 0x78, 0x00, 0x1E, 0x00, 0x1E, 0x00,
0x03, 0x80, 0x07, 0x00, 0x70, 0x01, 0xC7, 0x00, 0x70, 0xF0, 0x1C, 0x0E,
0x07, 0x80, 0xE0, 0xE0, 0x0E, 0x38, 0x00, 0xEE, 0x00, 0x1F, 0x80, 0x01,
0xF0, 0x00, 0x1C, 0x00, 0x07, 0xC0, 0x01, 0xF8, 0x00, 0x3B, 0x80, 0x0E,
0x38, 0x03, 0x83, 0x80, 0xE0, 0x78, 0x3C, 0x07, 0x07, 0x00, 0x71, 0xC0,
0x07, 0x70, 0x00, 0x70, 0x70, 0x00, 0x1C, 0xE0, 0x00, 0xE3, 0x80, 0x03,
0x87, 0x00, 0x0C, 0x1C, 0x00, 0x70, 0x38, 0x01, 0x80, 0xE0, 0x0E, 0x01,
0x80, 0x38, 0x07, 0x01, 0xC0, 0x1C, 0x07, 0x00, 0x38, 0x38, 0x00, 0xE0,
0xE0, 0x01, 0xC3, 0x00, 0x07, 0x1C, 0x00, 0x0E, 0x60, 0x00, 0x3B, 0x80,
0x00, 0x6E, 0x00, 0x01, 0xF0, 0x00, 0x03, 0xC0, 0x00, 0x0E, 0x00, 0x00,
0x38, 0x00, 0x00, 0xC0, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x40, 0xE0,
0x03, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x07, 0x80, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x38, 0x00, 0x70, 0x00,
0xE0, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E,
0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0x03, 0xC1, 0xF0, 0xF0, 0x38, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C,
0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x3F, 0x0F,
0x80, 0xF0, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70,
0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x03, 0x80, 0xFC, 0x1F, 0x00, 0xC0,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFE, 0xF0, 0x3E, 0x03, 0xC0, 0x70, 0x0E, 0x03, 0x80, 0xE0, 0x38,
0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
0xF0, 0x7C, 0x3C, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0,
0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x07, 0x0F, 0xC3, 0xE0, 0xC0,
0x00, 0x0E, 0x00, 0xCF, 0xE0, 0x37, 0xBC, 0x0D, 0x83, 0x86, 0x60, 0x7F,
0xB0, 0x0F, 0xC0 };
const GFXglyph Montserrat_Regular20pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
{ 1, 4, 27, 10, 3, -26 }, // 0x21 '!'
{ 15, 9, 10, 15, 3, -26 }, // 0x22 '"'
{ 27, 25, 27, 27, 1, -26 }, // 0x23 '#'
{ 112, 20, 37, 24, 2, -31 }, // 0x24 '$'
{ 205, 29, 28, 32, 2, -27 }, // 0x25 '%'
{ 307, 24, 28, 26, 2, -27 }, // 0x26 '&'
{ 391, 2, 10, 8, 3, -26 }, // 0x27 '''
{ 394, 7, 37, 13, 4, -28 }, // 0x28 '('
{ 427, 7, 37, 13, 2, -28 }, // 0x29 ')'
{ 460, 13, 14, 15, 1, -28 }, // 0x2A '*'
{ 483, 17, 17, 22, 3, -21 }, // 0x2B '+'
{ 520, 4, 10, 8, 2, -3 }, // 0x2C ','
{ 525, 11, 3, 15, 2, -11 }, // 0x2D '-'
{ 530, 4, 4, 8, 2, -3 }, // 0x2E '.'
{ 532, 15, 37, 13, -1, -32 }, // 0x2F '/'
{ 602, 22, 28, 26, 2, -27 }, // 0x30 '0'
{ 679, 10, 27, 14, 0, -26 }, // 0x31 '1'
{ 713, 20, 28, 22, 1, -27 }, // 0x32 '2'
{ 783, 20, 27, 22, 0, -26 }, // 0x33 '3'
{ 851, 23, 27, 26, 2, -26 }, // 0x34 '4'
{ 929, 20, 27, 22, 1, -26 }, // 0x35 '5'
{ 997, 21, 28, 24, 2, -27 }, // 0x36 '6'
{ 1071, 20, 27, 23, 1, -26 }, // 0x37 '7'
{ 1139, 21, 28, 25, 2, -27 }, // 0x38 '8'
{ 1213, 21, 28, 24, 1, -27 }, // 0x39 '9'
{ 1287, 4, 21, 8, 2, -20 }, // 0x3A ':'
{ 1298, 4, 27, 8, 2, -20 }, // 0x3B ';'
{ 1312, 17, 16, 22, 3, -21 }, // 0x3C '<'
{ 1346, 17, 11, 22, 3, -18 }, // 0x3D '='
{ 1370, 17, 16, 22, 3, -21 }, // 0x3E '>'
{ 1404, 19, 28, 22, 0, -27 }, // 0x3F '?'
{ 1471, 36, 36, 40, 2, -27 }, // 0x40 '@'
{ 1633, 28, 27, 28, 0, -26 }, // 0x41 'A'
{ 1728, 23, 27, 29, 4, -26 }, // 0x42 'B'
{ 1806, 24, 28, 28, 2, -27 }, // 0x43 'C'
{ 1890, 26, 27, 32, 4, -26 }, // 0x44 'D'
{ 1978, 20, 27, 26, 4, -26 }, // 0x45 'E'
{ 2046, 19, 27, 25, 4, -26 }, // 0x46 'F'
{ 2111, 25, 28, 30, 2, -27 }, // 0x47 'G'
{ 2199, 23, 27, 32, 4, -26 }, // 0x48 'H'
{ 2277, 3, 27, 12, 4, -26 }, // 0x49 'I'
{ 2288, 15, 27, 20, 0, -26 }, // 0x4A 'J'
{ 2339, 24, 27, 28, 4, -26 }, // 0x4B 'K'
{ 2420, 19, 27, 23, 4, -26 }, // 0x4C 'L'
{ 2485, 29, 27, 37, 4, -26 }, // 0x4D 'M'
{ 2583, 23, 27, 32, 4, -26 }, // 0x4E 'N'
{ 2661, 29, 28, 33, 2, -27 }, // 0x4F 'O'
{ 2763, 22, 27, 28, 4, -26 }, // 0x50 'P'
{ 2838, 30, 33, 33, 2, -27 }, // 0x51 'Q'
{ 2962, 22, 27, 28, 4, -26 }, // 0x52 'R'
{ 3037, 20, 28, 24, 2, -27 }, // 0x53 'S'
{ 3107, 22, 27, 22, 0, -26 }, // 0x54 'T'
{ 3182, 23, 27, 31, 4, -26 }, // 0x55 'U'
{ 3260, 27, 27, 27, 0, -26 }, // 0x56 'V'
{ 3352, 41, 27, 43, 1, -26 }, // 0x57 'W'
{ 3491, 24, 27, 26, 1, -26 }, // 0x58 'X'
{ 3572, 25, 27, 25, 0, -26 }, // 0x59 'Y'
{ 3657, 22, 27, 25, 2, -26 }, // 0x5A 'Z'
{ 3732, 8, 37, 12, 4, -28 }, // 0x5B '['
{ 3769, 15, 37, 13, -1, -32 }, // 0x5C '\'
{ 3839, 7, 37, 12, 1, -28 }, // 0x5D ']'
{ 3872, 16, 16, 22, 3, -21 }, // 0x5E '^'
{ 3904, 20, 2, 20, 0, 1 }, // 0x5F '_'
{ 3909, 9, 5, 23, 5, -28 }, // 0x60 '`'
{ 3915, 17, 21, 23, 2, -20 }, // 0x61 'a'
{ 3960, 21, 29, 26, 4, -28 }, // 0x62 'b'
{ 4037, 18, 21, 22, 2, -20 }, // 0x63 'c'
{ 4085, 21, 29, 26, 2, -28 }, // 0x64 'd'
{ 4162, 20, 21, 24, 2, -20 }, // 0x65 'e'
{ 4215, 14, 29, 13, 1, -28 }, // 0x66 'f'
{ 4266, 21, 29, 27, 2, -20 }, // 0x67 'g'
{ 4343, 19, 29, 26, 4, -28 }, // 0x68 'h'
{ 4412, 4, 29, 10, 4, -28 }, // 0x69 'i'
{ 4427, 12, 37, 11, -4, -28 }, // 0x6A 'j'
{ 4483, 19, 29, 23, 4, -28 }, // 0x6B 'k'
{ 4552, 3, 29, 10, 4, -28 }, // 0x6C 'l'
{ 4563, 34, 21, 41, 4, -20 }, // 0x6D 'm'
{ 4653, 19, 21, 26, 4, -20 }, // 0x6E 'n'
{ 4703, 21, 21, 24, 2, -20 }, // 0x6F 'o'
{ 4759, 21, 29, 26, 4, -20 }, // 0x70 'p'
{ 4836, 21, 29, 26, 2, -20 }, // 0x71 'q'
{ 4913, 10, 21, 16, 4, -20 }, // 0x72 'r'
{ 4940, 17, 21, 19, 1, -20 }, // 0x73 's'
{ 4985, 14, 25, 16, 1, -24 }, // 0x74 't'
{ 5029, 18, 20, 26, 4, -19 }, // 0x75 'u'
{ 5074, 21, 20, 21, 0, -19 }, // 0x76 'v'
{ 5127, 34, 20, 34, 0, -19 }, // 0x77 'w'
{ 5212, 19, 20, 21, 1, -19 }, // 0x78 'x'
{ 5260, 22, 28, 21, -1, -19 }, // 0x79 'y'
{ 5337, 16, 20, 20, 2, -19 }, // 0x7A 'z'
{ 5377, 10, 37, 13, 2, -28 }, // 0x7B '{'
{ 5424, 3, 37, 11, 4, -28 }, // 0x7C '|'
{ 5438, 10, 37, 13, 1, -28 }, // 0x7D '}'
{ 5485, 18, 6, 22, 2, -16 } }; // 0x7E '~'
const GFXfont Montserrat_Regular20pt7b PROGMEM = {
(uint8_t *)Montserrat_Regular20pt7bBitmaps,
(GFXglyph *)Montserrat_Regular20pt7bGlyphs,
0x20, 0x7E, 48 };
// Approx. 6171 bytes
#endif // MONTSERRAT20PT7B_H
@@ -0,0 +1,170 @@
#ifndef MONTSERRAT7PT7B_H
#define MONTSERRAT7PT7B_H
const uint8_t Montserrat_Regular7pt7bBitmaps[] PROGMEM = {
0x00, 0xAA, 0xA8, 0x30, 0xB6, 0xD0, 0x11, 0x08, 0x84, 0x4F, 0xF1, 0x20,
0x91, 0xFC, 0x44, 0x22, 0x11, 0x00, 0x10, 0xFB, 0x44, 0x89, 0x0E, 0x07,
0x09, 0x13, 0x25, 0xF0, 0x81, 0x00, 0x60, 0x24, 0x49, 0x22, 0x50, 0xB4,
0x12, 0xE1, 0x24, 0x51, 0x22, 0x50, 0xE0, 0x38, 0x44, 0x44, 0x48, 0x30,
0x50, 0x89, 0x86, 0x86, 0x79, 0xF0, 0x29, 0x25, 0x24, 0x49, 0x22, 0xA5,
0x55, 0x56, 0x80, 0x23, 0xDC, 0x52, 0x00, 0x00, 0x41, 0x3F, 0x10, 0x40,
0xE0, 0xF0, 0x80, 0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00,
0x38, 0x44, 0x82, 0x82, 0x83, 0x81, 0x82, 0x82, 0x46, 0x3C, 0xE4, 0x92,
0x49, 0x24, 0x3D, 0x8C, 0x08, 0x10, 0x41, 0x86, 0x18, 0x60, 0xFC, 0x7E,
0x08, 0x30, 0x41, 0x80, 0xC0, 0x81, 0x82, 0xF8, 0x04, 0x08, 0x10, 0x20,
0x44, 0x44, 0xFF, 0x04, 0x04, 0x04, 0x7E, 0x81, 0x02, 0x07, 0x80, 0xC0,
0x81, 0x02, 0xF8, 0x3C, 0x82, 0x04, 0x0B, 0xD8, 0xE0, 0xC1, 0x42, 0x78,
0xFF, 0x82, 0x82, 0x04, 0x04, 0x0C, 0x08, 0x08, 0x10, 0x10, 0x79, 0x8E,
0x0C, 0x17, 0xD8, 0xA0, 0xC1, 0x82, 0xF8, 0x3C, 0x42, 0x82, 0x83, 0x43,
0x3D, 0x01, 0x02, 0x02, 0x7C, 0x82, 0x83, 0x80, 0x04, 0x6E, 0x30, 0x38,
0x10, 0xFC, 0x00, 0x3F, 0x81, 0x81, 0xC3, 0x72, 0x00, 0x3D, 0x8C, 0x08,
0x10, 0x41, 0x04, 0x00, 0x00, 0x30, 0x0F, 0x81, 0x83, 0x10, 0x05, 0x1E,
0xA9, 0x0C, 0xC8, 0x26, 0x41, 0x32, 0x09, 0x90, 0xCC, 0x7B, 0x90, 0x00,
0x60, 0x00, 0xF8, 0x00, 0x0C, 0x03, 0x01, 0x20, 0x48, 0x12, 0x08, 0x43,
0xF1, 0x02, 0x40, 0xA0, 0x10, 0xFC, 0x82, 0x82, 0x82, 0x86, 0xFE, 0x81,
0x81, 0x83, 0xFE, 0x1E, 0x61, 0xC0, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x61,
0x3E, 0xFC, 0x41, 0x20, 0x50, 0x18, 0x0C, 0x06, 0x03, 0x02, 0x83, 0x7E,
0x00, 0xFD, 0x02, 0x04, 0x08, 0x1F, 0x20, 0x40, 0x81, 0xFC, 0xFE, 0x08,
0x20, 0x83, 0xF8, 0x20, 0x82, 0x00, 0x1E, 0x30, 0xF0, 0x10, 0x08, 0x04,
0x0A, 0x05, 0x82, 0x61, 0x1F, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFD,
0x81, 0x81, 0x81, 0x81, 0xFF, 0xC0, 0x7C, 0x30, 0xC3, 0x0C, 0x30, 0xC2,
0x89, 0xE0, 0x82, 0x84, 0x88, 0x90, 0xA0, 0xF0, 0xC8, 0x8C, 0x86, 0x82,
0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x83, 0xF0, 0x80, 0x60, 0x3C, 0x0F,
0x05, 0xA2, 0x64, 0x99, 0x46, 0x31, 0x88, 0x60, 0x10, 0x81, 0x81, 0xC1,
0xA1, 0x91, 0x99, 0x89, 0x85, 0x83, 0x81, 0x1E, 0x18, 0x6C, 0x0A, 0x01,
0x80, 0x60, 0x18, 0x07, 0x02, 0x61, 0x8F, 0x80, 0xF9, 0x0E, 0x0C, 0x18,
0x30, 0xFE, 0x40, 0x81, 0x00, 0x1E, 0x18, 0x6C, 0x0A, 0x01, 0x80, 0x60,
0x18, 0x07, 0x02, 0x61, 0x8F, 0x80, 0x60, 0x0F, 0xF9, 0x0E, 0x0C, 0x18,
0x30, 0xFE, 0x42, 0x85, 0x04, 0x7D, 0x82, 0x04, 0x06, 0x03, 0x80, 0x81,
0x82, 0xF8, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0xC2, 0x7C, 0x80, 0x50,
0x24, 0x08, 0x84, 0x21, 0x08, 0x81, 0x20, 0x58, 0x0C, 0x03, 0x00, 0x82,
0x06, 0x0C, 0x18, 0x30, 0x91, 0x42, 0x44, 0x89, 0x22, 0x42, 0x89, 0x0A,
0x14, 0x30, 0x60, 0x41, 0x80, 0x41, 0x30, 0x88, 0x82, 0x80, 0xC0, 0x60,
0x50, 0x44, 0x61, 0x20, 0xC0, 0x80, 0xA0, 0x98, 0x84, 0x41, 0x40, 0xA0,
0x20, 0x10, 0x08, 0x04, 0x00, 0xFF, 0x02, 0x04, 0x08, 0x18, 0x10, 0x20,
0x40, 0x80, 0xFF, 0xEA, 0xAA, 0xAA, 0xC0, 0x84, 0x20, 0x84, 0x20, 0x84,
0x20, 0x84, 0x20, 0x80, 0x64, 0x92, 0x49, 0x24, 0x9E, 0x30, 0xC2, 0x92,
0x4A, 0x10, 0xFE, 0x44, 0xF8, 0x10, 0x7F, 0x86, 0x37, 0x40, 0x80, 0x80,
0x80, 0xBE, 0xC2, 0x81, 0x81, 0xC1, 0xC2, 0xBC, 0x7E, 0x08, 0x20, 0x83,
0x17, 0x80, 0x02, 0x04, 0x0B, 0xF8, 0x30, 0x60, 0xC1, 0xC6, 0xF4, 0x7D,
0x0A, 0x0F, 0xF8, 0x18, 0x1F, 0x00, 0x39, 0x08, 0xE2, 0x10, 0x84, 0x21,
0x00, 0x7F, 0x06, 0x0C, 0x18, 0x38, 0xCE, 0x81, 0xC6, 0x70, 0x81, 0x02,
0x05, 0xEC, 0x30, 0x60, 0xC1, 0x83, 0x04, 0xC2, 0xAA, 0xA0, 0x30, 0x02,
0x22, 0x22, 0x22, 0x22, 0xC0, 0x81, 0x02, 0x04, 0x28, 0x92, 0x2E, 0x64,
0x85, 0x04, 0xFF, 0xC0, 0xBD, 0xF6, 0x10, 0xA0, 0x83, 0x04, 0x18, 0x20,
0xC1, 0x06, 0x08, 0x20, 0xBD, 0x86, 0x0C, 0x18, 0x30, 0x60, 0x80, 0x7D,
0x06, 0x0C, 0x18, 0x38, 0xDE, 0x00, 0xBE, 0xC2, 0x81, 0x81, 0xC1, 0xC2,
0xBC, 0x80, 0x80, 0x80, 0x7F, 0x06, 0x0C, 0x18, 0x38, 0xDE, 0x81, 0x02,
0x04, 0xBC, 0x88, 0x88, 0x80, 0x7D, 0x04, 0x0F, 0x04, 0x17, 0xC0, 0x21,
0x1C, 0x42, 0x10, 0x84, 0x38, 0x83, 0x06, 0x0C, 0x18, 0x28, 0xDE, 0x80,
0x82, 0x42, 0x44, 0x24, 0x28, 0x18, 0x18, 0x86, 0x14, 0x61, 0x45, 0x22,
0x92, 0x29, 0x43, 0x0C, 0x10, 0xC0, 0x46, 0x48, 0x60, 0x82, 0x8C, 0x90,
0x80, 0x82, 0x42, 0x44, 0x24, 0x28, 0x18, 0x18, 0x10, 0x30, 0xE0, 0xF8,
0x61, 0x08, 0x42, 0x0F, 0xC0, 0x69, 0x24, 0xB2, 0x49, 0x22, 0xFF, 0xF8,
0x62, 0x22, 0x22, 0x32, 0x22, 0x22, 0xC0, 0xE6, 0x70 };
const GFXglyph Montserrat_Regular7pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
{ 1, 2, 10, 4, 1, -9 }, // 0x21 '!'
{ 4, 3, 4, 5, 1, -9 }, // 0x22 '"'
{ 6, 9, 10, 10, 0, -9 }, // 0x23 '#'
{ 18, 7, 13, 9, 1, -10 }, // 0x24 '$'
{ 30, 10, 10, 12, 1, -9 }, // 0x25 '%'
{ 43, 8, 10, 9, 1, -9 }, // 0x26 '&'
{ 53, 1, 4, 3, 1, -9 }, // 0x27 '''
{ 54, 3, 13, 5, 1, -9 }, // 0x28 '('
{ 59, 2, 13, 5, 1, -9 }, // 0x29 ')'
{ 63, 5, 5, 5, 0, -9 }, // 0x2A '*'
{ 67, 6, 6, 8, 1, -7 }, // 0x2B '+'
{ 72, 1, 3, 3, 1, 0 }, // 0x2C ','
{ 73, 4, 1, 5, 1, -3 }, // 0x2D '-'
{ 74, 1, 1, 3, 1, 0 }, // 0x2E '.'
{ 75, 5, 13, 5, 0, -11 }, // 0x2F '/'
{ 84, 8, 10, 9, 1, -9 }, // 0x30 '0'
{ 94, 3, 10, 5, 0, -9 }, // 0x31 '1'
{ 98, 7, 10, 8, 0, -9 }, // 0x32 '2'
{ 107, 7, 10, 8, 0, -9 }, // 0x33 '3'
{ 116, 8, 10, 9, 1, -9 }, // 0x34 '4'
{ 126, 7, 10, 8, 0, -9 }, // 0x35 '5'
{ 135, 7, 10, 9, 1, -9 }, // 0x36 '6'
{ 144, 8, 10, 8, 0, -9 }, // 0x37 '7'
{ 154, 7, 10, 9, 1, -9 }, // 0x38 '8'
{ 163, 8, 10, 9, 0, -9 }, // 0x39 '9'
{ 173, 1, 7, 3, 1, -6 }, // 0x3A ':'
{ 174, 1, 9, 3, 1, -6 }, // 0x3B ';'
{ 176, 6, 6, 8, 1, -7 }, // 0x3C '<'
{ 181, 6, 4, 8, 1, -6 }, // 0x3D '='
{ 184, 6, 6, 8, 1, -7 }, // 0x3E '>'
{ 189, 7, 10, 8, 0, -9 }, // 0x3F '?'
{ 198, 13, 13, 14, 1, -9 }, // 0x40 '@'
{ 220, 10, 10, 10, 0, -9 }, // 0x41 'A'
{ 233, 8, 10, 11, 2, -9 }, // 0x42 'B'
{ 243, 8, 10, 10, 1, -9 }, // 0x43 'C'
{ 253, 9, 10, 12, 2, -9 }, // 0x44 'D'
{ 265, 7, 10, 9, 2, -9 }, // 0x45 'E'
{ 274, 6, 10, 9, 2, -9 }, // 0x46 'F'
{ 282, 9, 10, 11, 1, -9 }, // 0x47 'G'
{ 294, 8, 10, 11, 2, -9 }, // 0x48 'H'
{ 304, 1, 10, 4, 2, -9 }, // 0x49 'I'
{ 306, 6, 10, 7, 0, -9 }, // 0x4A 'J'
{ 314, 8, 10, 10, 2, -9 }, // 0x4B 'K'
{ 324, 6, 10, 8, 2, -9 }, // 0x4C 'L'
{ 332, 10, 10, 13, 2, -9 }, // 0x4D 'M'
{ 345, 8, 10, 11, 2, -9 }, // 0x4E 'N'
{ 355, 10, 10, 12, 1, -9 }, // 0x4F 'O'
{ 368, 7, 10, 10, 2, -9 }, // 0x50 'P'
{ 377, 10, 12, 12, 1, -9 }, // 0x51 'Q'
{ 392, 7, 10, 10, 2, -9 }, // 0x52 'R'
{ 401, 7, 10, 9, 1, -9 }, // 0x53 'S'
{ 410, 8, 10, 8, 0, -9 }, // 0x54 'T'
{ 420, 8, 10, 11, 2, -9 }, // 0x55 'U'
{ 430, 10, 10, 10, 0, -9 }, // 0x56 'V'
{ 443, 14, 10, 16, 1, -9 }, // 0x57 'W'
{ 461, 9, 10, 9, 0, -9 }, // 0x58 'X'
{ 473, 9, 10, 9, 0, -9 }, // 0x59 'Y'
{ 485, 8, 10, 9, 1, -9 }, // 0x5A 'Z'
{ 495, 2, 13, 4, 2, -9 }, // 0x5B '['
{ 499, 5, 13, 5, 0, -11 }, // 0x5C '\'
{ 508, 3, 13, 4, 0, -9 }, // 0x5D ']'
{ 513, 6, 6, 8, 1, -7 }, // 0x5E '^'
{ 518, 7, 1, 7, 0, 1 }, // 0x5F '_'
{ 519, 3, 2, 8, 2, -9 }, // 0x60 '`'
{ 520, 6, 7, 8, 1, -6 }, // 0x61 'a'
{ 526, 8, 10, 9, 1, -9 }, // 0x62 'b'
{ 536, 6, 7, 8, 1, -6 }, // 0x63 'c'
{ 542, 7, 10, 9, 1, -9 }, // 0x64 'd'
{ 551, 7, 7, 8, 1, -6 }, // 0x65 'e'
{ 558, 5, 10, 5, 0, -9 }, // 0x66 'f'
{ 565, 7, 10, 10, 1, -6 }, // 0x67 'g'
{ 574, 7, 10, 9, 1, -9 }, // 0x68 'h'
{ 583, 2, 10, 4, 1, -9 }, // 0x69 'i'
{ 586, 4, 13, 4, -1, -9 }, // 0x6A 'j'
{ 593, 7, 10, 8, 1, -9 }, // 0x6B 'k'
{ 602, 1, 10, 4, 1, -9 }, // 0x6C 'l'
{ 604, 13, 7, 15, 1, -6 }, // 0x6D 'm'
{ 616, 7, 7, 9, 1, -6 }, // 0x6E 'n'
{ 623, 7, 7, 9, 1, -6 }, // 0x6F 'o'
{ 630, 8, 10, 9, 1, -6 }, // 0x70 'p'
{ 640, 7, 10, 9, 1, -6 }, // 0x71 'q'
{ 649, 4, 7, 6, 1, -6 }, // 0x72 'r'
{ 653, 6, 7, 7, 0, -6 }, // 0x73 's'
{ 659, 5, 9, 6, 0, -8 }, // 0x74 't'
{ 665, 7, 7, 9, 1, -6 }, // 0x75 'u'
{ 672, 8, 7, 8, 0, -6 }, // 0x76 'v'
{ 679, 12, 7, 12, 0, -6 }, // 0x77 'w'
{ 690, 7, 7, 7, 0, -6 }, // 0x78 'x'
{ 697, 8, 10, 8, 0, -6 }, // 0x79 'y'
{ 707, 6, 7, 7, 1, -6 }, // 0x7A 'z'
{ 713, 3, 13, 5, 1, -9 }, // 0x7B '{'
{ 718, 1, 13, 4, 2, -9 }, // 0x7C '|'
{ 720, 4, 13, 5, 0, -9 }, // 0x7D '}'
{ 727, 6, 2, 8, 1, -5 } }; // 0x7E '~'
const GFXfont Montserrat_Regular7pt7b PROGMEM = {
(uint8_t *)Montserrat_Regular7pt7bBitmaps,
(GFXglyph *)Montserrat_Regular7pt7bGlyphs,
0x20, 0x7E, 17 };
// Approx. 1401 bytes
#endif // MONTSERRAT7PT7B_H
@@ -0,0 +1,210 @@
#ifndef MONTSERRAT9PT7B_H
#define MONTSERRAT9PT7B_H
const uint8_t Montserrat_Regular9pt7bBitmaps[] PROGMEM = {
0x00, 0x55, 0x55, 0x41, 0xC0, 0x99, 0x99, 0x90, 0x10, 0x82, 0x10, 0x42,
0x08, 0x8F, 0xFE, 0x22, 0x08, 0x41, 0x08, 0x21, 0x1F, 0xF8, 0x84, 0x10,
0x82, 0x20, 0x08, 0x04, 0x07, 0x8F, 0x7C, 0x84, 0x43, 0x20, 0xD0, 0x3C,
0x07, 0x82, 0x61, 0x10, 0x8E, 0x4D, 0xF8, 0x10, 0x08, 0x00, 0x30, 0x26,
0x43, 0x22, 0x11, 0x11, 0x08, 0x90, 0x44, 0x81, 0xC9, 0xC0, 0x93, 0x04,
0x88, 0x48, 0x44, 0x42, 0x21, 0x12, 0x07, 0x00, 0x1C, 0x06, 0x40, 0x8C,
0x11, 0x82, 0x60, 0x38, 0x0E, 0x03, 0x22, 0xC2, 0x50, 0x7A, 0x06, 0x61,
0xE3, 0xE6, 0xF8, 0x69, 0x69, 0x24, 0x92, 0x4C, 0x93, 0x89, 0x36, 0x49,
0x24, 0x96, 0x94, 0x11, 0xA8, 0xE1, 0xC5, 0x42, 0x00, 0x08, 0x08, 0x08,
0xFF, 0x08, 0x08, 0x08, 0x08, 0xF6, 0x80, 0xF8, 0xF0, 0x04, 0x08, 0x10,
0x40, 0x81, 0x04, 0x08, 0x30, 0x40, 0x83, 0x04, 0x08, 0x30, 0x40, 0x80,
0x0C, 0x0F, 0xC6, 0x1B, 0x02, 0xC0, 0xE0, 0x18, 0x06, 0x01, 0x80, 0x70,
0x34, 0x09, 0x84, 0x1E, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10,
0x1C, 0x1D, 0xC4, 0x18, 0x02, 0x00, 0x80, 0x60, 0x30, 0x18, 0x0C, 0x06,
0x03, 0x01, 0x80, 0x7F, 0xC0, 0x7F, 0xBF, 0xC0, 0xC0, 0x40, 0x40, 0x40,
0x3C, 0x03, 0x00, 0x80, 0x40, 0x38, 0x33, 0xE0, 0x03, 0x00, 0x40, 0x10,
0x04, 0x01, 0x80, 0x60, 0x08, 0x42, 0x08, 0x81, 0x1F, 0xFC, 0x04, 0x00,
0x80, 0x10, 0x3F, 0x9F, 0xC8, 0x04, 0x02, 0x03, 0x01, 0xFC, 0x03, 0x00,
0x80, 0x40, 0x3C, 0x33, 0xF0, 0x0F, 0x1C, 0x98, 0x08, 0x0C, 0x04, 0x62,
0xFD, 0x83, 0xC0, 0xE0, 0x50, 0x2C, 0x31, 0xF0, 0xFF, 0xFF, 0xE0, 0x50,
0x60, 0x20, 0x10, 0x10, 0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x00, 0x1C,
0x1C, 0xC4, 0x0B, 0x02, 0xC0, 0x98, 0x63, 0xE1, 0x06, 0x80, 0xA0, 0x38,
0x0B, 0x06, 0x3F, 0x00, 0x38, 0x33, 0x20, 0x50, 0x38, 0x1C, 0x0F, 0x0A,
0x79, 0x00, 0x80, 0xC0, 0x40, 0xCF, 0xC0, 0xF0, 0x00, 0xF0, 0xF0, 0x00,
0xF6, 0x80, 0x01, 0x0E, 0x38, 0xC0, 0x70, 0x1C, 0x03, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xC0, 0x70, 0x0E, 0x03, 0x07, 0x38, 0xE0, 0x1C, 0x39, 0x90,
0x60, 0x10, 0x18, 0x08, 0x08, 0x08, 0x0C, 0x00, 0x00, 0x01, 0x80, 0xC0,
0x03, 0xE0, 0x06, 0x0C, 0x0C, 0x01, 0x0C, 0x00, 0x44, 0x3C, 0x94, 0x21,
0x4A, 0x20, 0x63, 0x10, 0x11, 0x88, 0x08, 0xC4, 0x04, 0x62, 0x06, 0x58,
0x85, 0x24, 0x3C, 0xE1, 0x00, 0x00, 0xC0, 0x00, 0x1C, 0x60, 0x01, 0xC0,
0x00, 0x02, 0x00, 0x38, 0x01, 0x40, 0x1B, 0x00, 0x88, 0x0C, 0x40, 0x41,
0x02, 0x08, 0x20, 0x61, 0xFF, 0x18, 0x0C, 0x80, 0x2C, 0x01, 0x80, 0xFE,
0x1F, 0xF2, 0x03, 0x40, 0x28, 0x0D, 0x01, 0x3F, 0xC4, 0x06, 0x80, 0x50,
0x0E, 0x01, 0x40, 0x6F, 0xF8, 0x07, 0x03, 0xB9, 0x80, 0xA0, 0x0C, 0x01,
0x00, 0x20, 0x04, 0x00, 0xC0, 0x08, 0x01, 0x80, 0x18, 0x30, 0xF8, 0xFC,
0x0F, 0xF8, 0x80, 0x48, 0x02, 0x80, 0x38, 0x01, 0x80, 0x18, 0x01, 0x80,
0x38, 0x02, 0x80, 0x68, 0x1C, 0xFF, 0x00, 0xFF, 0xFF, 0xE0, 0x10, 0x08,
0x04, 0x03, 0xFD, 0x00, 0x80, 0x40, 0x20, 0x10, 0x0F, 0xF8, 0xFF, 0xFF,
0xE0, 0x10, 0x08, 0x04, 0x03, 0xFD, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x08,
0x00, 0x07, 0x03, 0xBD, 0x80, 0xA0, 0x0C, 0x01, 0x00, 0x20, 0x04, 0x01,
0xC0, 0x28, 0x05, 0x80, 0x98, 0x30, 0xFC, 0x80, 0x70, 0x0E, 0x01, 0xC0,
0x38, 0x07, 0x00, 0xFF, 0xFC, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38,
0x06, 0xFF, 0xF8, 0x7E, 0xFC, 0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x04,
0x0E, 0x37, 0xC0, 0x80, 0x50, 0x12, 0x04, 0x41, 0x08, 0x41, 0x10, 0x26,
0x05, 0xE0, 0xE6, 0x18, 0x62, 0x06, 0x40, 0x48, 0x04, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x0E,
0x00, 0xF0, 0x07, 0x40, 0x7B, 0x02, 0xC8, 0x26, 0x61, 0x31, 0x11, 0x85,
0x8C, 0x28, 0x60, 0x83, 0x00, 0x18, 0x00, 0x80, 0x80, 0x78, 0x0F, 0x81,
0xD8, 0x39, 0x07, 0x10, 0xE3, 0x1C, 0x33, 0x83, 0x70, 0x2E, 0x03, 0xC0,
0x78, 0x06, 0x07, 0x00, 0xEF, 0x18, 0x0C, 0x80, 0x2C, 0x01, 0xC0, 0x06,
0x00, 0x30, 0x01, 0xC0, 0x0A, 0x00, 0xD8, 0x0C, 0x60, 0xC0, 0xFC, 0x00,
0xFC, 0x3F, 0xC8, 0x0A, 0x03, 0x80, 0x60, 0x18, 0x0E, 0x06, 0xFF, 0x20,
0x08, 0x02, 0x00, 0x80, 0x00, 0x07, 0x00, 0x77, 0x86, 0x03, 0x10, 0x04,
0xC0, 0x1A, 0x00, 0x28, 0x00, 0xA0, 0x02, 0xC0, 0x09, 0x00, 0x66, 0x03,
0x0C, 0x18, 0x0F, 0xC0, 0x06, 0x00, 0x0F, 0x80, 0x00, 0xFC, 0x3F, 0xC8,
0x0A, 0x03, 0x80, 0x60, 0x18, 0x0E, 0x06, 0xFF, 0x20, 0xC8, 0x12, 0x02,
0x80, 0xC0, 0x1E, 0x39, 0xF0, 0x10, 0x0C, 0x03, 0x00, 0xF0, 0x0E, 0x01,
0x80, 0x40, 0x38, 0x37, 0xE0, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00, 0x80, 0x60,
0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x06, 0x01, 0x80, 0x70, 0x1C, 0x0D,
0x86, 0x3F, 0x00, 0xC0, 0x12, 0x00, 0x90, 0x0C, 0xC0, 0x42, 0x06, 0x18,
0x20, 0x43, 0x03, 0x10, 0x08, 0x80, 0x6C, 0x01, 0x40, 0x0E, 0x00, 0x60,
0x00, 0x80, 0xC0, 0x60, 0x30, 0x1C, 0x0C, 0x0D, 0x07, 0x82, 0x41, 0x20,
0x98, 0x48, 0x62, 0x33, 0x10, 0x88, 0x44, 0x32, 0x13, 0x05, 0x86, 0x81,
0x40, 0xA0, 0x70, 0x38, 0x08, 0x04, 0x00, 0x40, 0x26, 0x04, 0x30, 0xC1,
0x18, 0x09, 0x00, 0xE0, 0x06, 0x00, 0xE0, 0x09, 0x01, 0x18, 0x30, 0xC6,
0x04, 0x40, 0x20, 0x80, 0x28, 0x0D, 0x81, 0x10, 0x61, 0x08, 0x32, 0x02,
0xC0, 0x70, 0x04, 0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0xFF, 0xFF, 0xF0,
0x18, 0x04, 0x02, 0x01, 0x80, 0xC0, 0x60, 0x10, 0x08, 0x06, 0x03, 0x00,
0xFF, 0xC0, 0xF2, 0x49, 0x24, 0x92, 0x49, 0x27, 0x40, 0x81, 0x01, 0x02,
0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40, 0x80, 0x81, 0x02, 0xF3,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x18, 0x18, 0x14, 0x24, 0x22,
0x42, 0x42, 0xFF, 0x80, 0x60, 0x80, 0x18, 0x7E, 0x03, 0x01, 0x01, 0x7F,
0x81, 0x81, 0xC3, 0x7D, 0x80, 0x40, 0x20, 0x11, 0x0B, 0xF6, 0x0E, 0x03,
0x01, 0x80, 0xC0, 0x70, 0x7C, 0x6B, 0xE0, 0x08, 0x3F, 0x41, 0xC0, 0x80,
0x80, 0x80, 0xC0, 0x63, 0x3E, 0x00, 0x80, 0x40, 0x21, 0x17, 0xEA, 0x0F,
0x03, 0x01, 0x80, 0xC0, 0x70, 0x2C, 0x73, 0xE8, 0x08, 0x3F, 0x10, 0x50,
0x18, 0x0F, 0xFE, 0x01, 0x80, 0x61, 0x1F, 0x00, 0x1E, 0x40, 0x81, 0x0F,
0xC4, 0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x00, 0x08, 0x1F, 0xF4, 0x1E,
0x03, 0x80, 0xE0, 0x38, 0x0F, 0x07, 0x7F, 0xC7, 0x30, 0x08, 0x02, 0x7F,
0x03, 0x00, 0x80, 0x40, 0x20, 0x11, 0x0B, 0xE6, 0x0A, 0x05, 0x02, 0x81,
0xC0, 0xE0, 0x70, 0x38, 0x18, 0xC0, 0x55, 0x55, 0x40, 0x18, 0x00, 0x00,
0x84, 0x21, 0x08, 0x42, 0x10, 0x84, 0x2F, 0x20, 0x80, 0x40, 0x20, 0x10,
0x28, 0x24, 0x22, 0x61, 0x60, 0xF8, 0x66, 0x21, 0x90, 0x48, 0x10, 0xFF,
0xF8, 0x08, 0x11, 0x7C, 0xFB, 0x0E, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x20,
0x60, 0x40, 0xC0, 0x81, 0x81, 0x03, 0x02, 0x04, 0x08, 0x5F, 0x30, 0x50,
0x28, 0x14, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xC0, 0x08, 0x1F, 0x90, 0x78,
0x18, 0x0C, 0x06, 0x03, 0x81, 0x63, 0x1F, 0x00, 0x08, 0x5F, 0xB0, 0x70,
0x18, 0x0C, 0x06, 0x03, 0x83, 0xE3, 0x5F, 0x20, 0x10, 0x08, 0x00, 0x08,
0x3F, 0x50, 0x78, 0x18, 0x0C, 0x06, 0x03, 0x81, 0x63, 0x9F, 0x40, 0x20,
0x10, 0x08, 0x0D, 0xF1, 0x08, 0x42, 0x10, 0x84, 0x00, 0x08, 0x7F, 0x40,
0x40, 0x60, 0x1E, 0x03, 0x01, 0x43, 0x7E, 0x20, 0x40, 0x87, 0xE2, 0x04,
0x08, 0x10, 0x20, 0x40, 0xC0, 0xF0, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0xC3, 0x7D, 0xC0, 0x90, 0x26, 0x10, 0x84, 0x33, 0x04, 0x81, 0x60,
0x30, 0x0C, 0x00, 0xC1, 0x82, 0x41, 0x82, 0x42, 0xC6, 0x22, 0x44, 0x26,
0x44, 0x34, 0x28, 0x14, 0x28, 0x18, 0x28, 0x08, 0x10, 0x61, 0x91, 0x85,
0x81, 0x80, 0xC0, 0xB0, 0xC8, 0x42, 0x41, 0x80, 0xC0, 0x90, 0x26, 0x10,
0x84, 0x33, 0x04, 0x81, 0x60, 0x30, 0x0C, 0x02, 0x00, 0x83, 0xC0, 0x60,
0x00, 0xFE, 0x08, 0x30, 0xC1, 0x04, 0x18, 0x60, 0xFE, 0x39, 0x18, 0xC6,
0x31, 0x8C, 0xE3, 0x18, 0xC6, 0x30, 0x87, 0xFF, 0xFF, 0xE1, 0x0C, 0x63,
0x18, 0xC6, 0x39, 0x8C, 0x63, 0x18, 0x9C, 0x61, 0xD9, 0x8F };
const GFXglyph Montserrat_Regular9pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 5, 0, 0 }, // 0x20 ' '
{ 1, 2, 13, 5, 1, -12 }, // 0x21 '!'
{ 5, 4, 5, 7, 1, -12 }, // 0x22 '"'
{ 8, 11, 13, 13, 1, -12 }, // 0x23 '#'
{ 26, 9, 17, 11, 1, -14 }, // 0x24 '$'
{ 46, 13, 13, 15, 1, -12 }, // 0x25 '%'
{ 68, 11, 13, 12, 1, -12 }, // 0x26 '&'
{ 86, 1, 5, 4, 1, -12 }, // 0x27 '''
{ 87, 3, 16, 6, 2, -12 }, // 0x28 '('
{ 93, 3, 16, 6, 1, -12 }, // 0x29 ')'
{ 99, 7, 6, 7, 0, -12 }, // 0x2A '*'
{ 105, 8, 8, 10, 1, -9 }, // 0x2B '+'
{ 113, 2, 5, 4, 1, -1 }, // 0x2C ','
{ 115, 5, 1, 7, 1, -4 }, // 0x2D '-'
{ 116, 2, 2, 4, 1, -1 }, // 0x2E '.'
{ 117, 7, 17, 6, 0, -14 }, // 0x2F '/'
{ 132, 10, 13, 12, 1, -12 }, // 0x30 '0'
{ 149, 4, 13, 7, 0, -12 }, // 0x31 '1'
{ 156, 10, 13, 10, 0, -12 }, // 0x32 '2'
{ 173, 9, 13, 10, 0, -12 }, // 0x33 '3'
{ 188, 11, 13, 12, 1, -12 }, // 0x34 '4'
{ 206, 9, 13, 10, 0, -12 }, // 0x35 '5'
{ 221, 9, 13, 11, 1, -12 }, // 0x36 '6'
{ 236, 9, 13, 11, 1, -12 }, // 0x37 '7'
{ 251, 10, 13, 11, 1, -12 }, // 0x38 '8'
{ 268, 9, 13, 11, 1, -12 }, // 0x39 '9'
{ 283, 2, 10, 4, 1, -9 }, // 0x3A ':'
{ 286, 2, 13, 4, 1, -9 }, // 0x3B ';'
{ 290, 8, 7, 10, 1, -9 }, // 0x3C '<'
{ 297, 8, 5, 10, 1, -8 }, // 0x3D '='
{ 302, 8, 7, 10, 1, -9 }, // 0x3E '>'
{ 309, 9, 13, 10, 0, -12 }, // 0x3F '?'
{ 324, 17, 17, 19, 1, -12 }, // 0x40 '@'
{ 361, 13, 13, 13, 0, -12 }, // 0x41 'A'
{ 383, 11, 13, 14, 2, -12 }, // 0x42 'B'
{ 401, 11, 13, 13, 1, -12 }, // 0x43 'C'
{ 419, 12, 13, 15, 2, -12 }, // 0x44 'D'
{ 439, 9, 13, 12, 2, -12 }, // 0x45 'E'
{ 454, 9, 13, 11, 2, -12 }, // 0x46 'F'
{ 469, 11, 13, 14, 1, -12 }, // 0x47 'G'
{ 487, 11, 13, 15, 2, -12 }, // 0x48 'H'
{ 505, 1, 13, 5, 2, -12 }, // 0x49 'I'
{ 507, 7, 13, 9, 0, -12 }, // 0x4A 'J'
{ 519, 11, 13, 13, 2, -12 }, // 0x4B 'K'
{ 537, 8, 13, 11, 2, -12 }, // 0x4C 'L'
{ 550, 13, 13, 17, 2, -12 }, // 0x4D 'M'
{ 572, 11, 13, 15, 2, -12 }, // 0x4E 'N'
{ 590, 13, 13, 15, 1, -12 }, // 0x4F 'O'
{ 612, 10, 13, 13, 2, -12 }, // 0x50 'P'
{ 629, 14, 16, 15, 1, -12 }, // 0x51 'Q'
{ 657, 10, 13, 13, 2, -12 }, // 0x52 'R'
{ 674, 9, 13, 11, 1, -12 }, // 0x53 'S'
{ 689, 10, 13, 10, 0, -12 }, // 0x54 'T'
{ 706, 10, 13, 14, 2, -12 }, // 0x55 'U'
{ 723, 13, 13, 13, 0, -12 }, // 0x56 'V'
{ 745, 18, 13, 20, 1, -12 }, // 0x57 'W'
{ 775, 12, 13, 12, 0, -12 }, // 0x58 'X'
{ 795, 11, 13, 11, 0, -12 }, // 0x59 'Y'
{ 813, 10, 13, 12, 1, -12 }, // 0x5A 'Z'
{ 830, 3, 16, 6, 2, -12 }, // 0x5B '['
{ 836, 7, 17, 6, -1, -14 }, // 0x5C '\'
{ 851, 4, 16, 6, 0, -12 }, // 0x5D ']'
{ 859, 8, 7, 10, 1, -9 }, // 0x5E '^'
{ 866, 9, 1, 9, 0, 1 }, // 0x5F '_'
{ 868, 5, 2, 11, 2, -12 }, // 0x60 '`'
{ 870, 8, 10, 11, 1, -9 }, // 0x61 'a'
{ 880, 9, 13, 12, 2, -12 }, // 0x62 'b'
{ 895, 8, 10, 10, 1, -9 }, // 0x63 'c'
{ 905, 9, 13, 12, 1, -12 }, // 0x64 'd'
{ 920, 9, 10, 11, 1, -9 }, // 0x65 'e'
{ 932, 7, 13, 6, 0, -12 }, // 0x66 'f'
{ 944, 10, 14, 12, 1, -9 }, // 0x67 'g'
{ 962, 9, 13, 12, 2, -12 }, // 0x68 'h'
{ 977, 2, 13, 5, 1, -12 }, // 0x69 'i'
{ 981, 5, 17, 5, -2, -12 }, // 0x6A 'j'
{ 992, 9, 13, 11, 2, -12 }, // 0x6B 'k'
{ 1007, 1, 13, 5, 2, -12 }, // 0x6C 'l'
{ 1009, 15, 10, 19, 2, -9 }, // 0x6D 'm'
{ 1028, 9, 10, 12, 2, -9 }, // 0x6E 'n'
{ 1040, 9, 10, 11, 1, -9 }, // 0x6F 'o'
{ 1052, 9, 13, 12, 2, -9 }, // 0x70 'p'
{ 1067, 9, 13, 12, 1, -9 }, // 0x71 'q'
{ 1082, 5, 10, 7, 2, -9 }, // 0x72 'r'
{ 1089, 8, 10, 9, 0, -9 }, // 0x73 's'
{ 1099, 7, 12, 7, 0, -11 }, // 0x74 't'
{ 1110, 8, 9, 12, 2, -8 }, // 0x75 'u'
{ 1119, 10, 9, 10, 0, -8 }, // 0x76 'v'
{ 1131, 16, 9, 16, 0, -8 }, // 0x77 'w'
{ 1149, 9, 9, 10, 0, -8 }, // 0x78 'x'
{ 1160, 10, 13, 10, 0, -8 }, // 0x79 'y'
{ 1177, 7, 9, 9, 1, -8 }, // 0x7A 'z'
{ 1185, 5, 16, 6, 1, -12 }, // 0x7B '{'
{ 1195, 1, 16, 5, 2, -12 }, // 0x7C '|'
{ 1197, 5, 16, 6, 0, -12 }, // 0x7D '}'
{ 1207, 8, 3, 10, 1, -7 } }; // 0x7E '~'
const GFXfont Montserrat_Regular9pt7b PROGMEM = {
(uint8_t *)Montserrat_Regular9pt7bBitmaps,
(GFXglyph *)Montserrat_Regular9pt7bGlyphs,
0x20, 0x7E, 21 };
// Approx. 1882 bytes
#endif // MONTSERRAT9PT7B_H
@@ -0,0 +1,310 @@
#ifndef MONTSERRATBOLD12PT7B_H
#define MONTSERRATBOLD12PT7B_H
const uint8_t Montserrat_Bold12pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xF7, 0x39, 0xCE, 0x73, 0x9C, 0x00, 0x3B, 0xFF, 0x70,
0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0x07, 0x1C, 0x03, 0x8E, 0x01,
0xC7, 0x00, 0xE3, 0x87, 0xFF, 0xFB, 0xFF, 0xFD, 0xFF, 0xFE, 0x1C, 0x30,
0x0E, 0x38, 0x07, 0x1C, 0x03, 0x8E, 0x1F, 0xFF, 0xEF, 0xFF, 0xF0, 0x61,
0xC0, 0x70, 0xC0, 0x38, 0x60, 0x1C, 0x70, 0x00, 0x03, 0x00, 0x0C, 0x00,
0x30, 0x07, 0xF8, 0x3F, 0xF9, 0xFF, 0xCF, 0xB3, 0x3C, 0xC0, 0xF3, 0x03,
0xEC, 0x07, 0xF8, 0x0F, 0xFC, 0x1F, 0xF8, 0x0F, 0xE0, 0x37, 0xC0, 0xCF,
0xE3, 0x7B, 0xFF, 0xEF, 0xFF, 0x0F, 0xF8, 0x03, 0x00, 0x0C, 0x00, 0x30,
0x00, 0x3C, 0x03, 0x0F, 0xC0, 0xE3, 0x9C, 0x38, 0x63, 0x86, 0x0C, 0x31,
0xC1, 0x8E, 0x70, 0x31, 0xCC, 0x07, 0xF3, 0x80, 0x7C, 0xE7, 0x80, 0x39,
0xF8, 0x07, 0x73, 0x81, 0xCE, 0x30, 0x71, 0x86, 0x0E, 0x38, 0xC3, 0x87,
0x38, 0xE0, 0x7F, 0x1C, 0x07, 0xC0, 0x0F, 0xC0, 0x1F, 0xE0, 0x3F, 0xF0,
0x38, 0x70, 0x38, 0x70, 0x3C, 0xF0, 0x1F, 0xE0, 0x1F, 0xC0, 0x3F, 0x88,
0x7F, 0xCE, 0xF1, 0xEE, 0xF0, 0xFE, 0xF0, 0x7C, 0xF0, 0x7C, 0xFF, 0xFE,
0x7F, 0xFE, 0x1F, 0xC6, 0xFF, 0xFF, 0xF8, 0x1C, 0xF7, 0x9E, 0x73, 0xCF,
0x3C, 0xF3, 0x8E, 0x38, 0xE3, 0x8F, 0x3C, 0xF3, 0xC7, 0x1E, 0x38, 0xF1,
0xC0, 0xF0, 0xF1, 0xE1, 0xE3, 0xC7, 0x87, 0x0F, 0x1E, 0x3C, 0x78, 0xF1,
0xE3, 0xC7, 0x8F, 0x1C, 0x78, 0xF1, 0xC7, 0x8F, 0x3C, 0x00, 0x0C, 0x03,
0x06, 0xDF, 0xFF, 0x3F, 0x0F, 0xEF, 0xFD, 0xB2, 0x0C, 0x03, 0x00, 0x07,
0x00, 0x70, 0x07, 0x00, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x70, 0x07,
0x00, 0x70, 0x07, 0x00, 0xFF, 0xFF, 0x76, 0xEE, 0xFF, 0xFF, 0xF8, 0xFF,
0xFF, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xE0, 0x3C, 0x07, 0x00, 0xE0, 0x3C,
0x07, 0x00, 0xE0, 0x3C, 0x07, 0x00, 0xE0, 0x3C, 0x07, 0x00, 0xE0, 0x3C,
0x07, 0x00, 0xE0, 0x3C, 0x07, 0x00, 0xE0, 0x00, 0x0F, 0xC0, 0x7F, 0xC3,
0xFF, 0x9F, 0x3E, 0x78, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F,
0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0x78, 0x3D, 0xF1, 0xE3, 0xFF, 0x8F, 0xFC,
0x0F, 0xC0, 0xFF, 0xFF, 0xF8, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38,
0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1F, 0xC3, 0xFF, 0x3F, 0xFC, 0xF1, 0xF2,
0x07, 0x80, 0x3C, 0x01, 0xE0, 0x1E, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F,
0x01, 0xF0, 0x1F, 0x01, 0xFF, 0xEF, 0xFF, 0x7F, 0xF8, 0x7F, 0xFB, 0xFF,
0xDF, 0xFE, 0x01, 0xE0, 0x1E, 0x01, 0xE0, 0x1E, 0x00, 0xF8, 0x07, 0xF0,
0x3F, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0xB0, 0x7F, 0xFF, 0xFF, 0xFE, 0x3F,
0xC0, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF8, 0x01, 0xE0,
0x07, 0x80, 0x1E, 0x3C, 0x7C, 0x78, 0xF0, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xE0, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x3F, 0xF8, 0xFF,
0xE3, 0xFF, 0x8F, 0x00, 0x3C, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0xF8, 0x3F,
0xF9, 0xFF, 0xE0, 0x07, 0x80, 0x0F, 0x00, 0x3D, 0xC1, 0xE7, 0xFF, 0xBF,
0xFC, 0x3F, 0xE0, 0x07, 0xF0, 0x7F, 0xE3, 0xFF, 0x1F, 0x04, 0x78, 0x03,
0xC0, 0x0F, 0x10, 0x3F, 0xFC, 0xFF, 0xFB, 0xFB, 0xEF, 0x83, 0xFC, 0x0F,
0xF0, 0x3D, 0xE1, 0xF7, 0xFF, 0x8F, 0xFC, 0x0F, 0xE0, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0xFE, 0x0F, 0x70, 0x78, 0x07, 0x80, 0x3C, 0x03, 0xE0,
0x1E, 0x01, 0xF0, 0x0F, 0x00, 0x78, 0x07, 0x80, 0x3C, 0x03, 0xE0, 0x1E,
0x00, 0x0F, 0xC0, 0xFF, 0xC7, 0xFF, 0x9E, 0x1E, 0xF0, 0x7B, 0xC1, 0xE7,
0x87, 0x8F, 0xFC, 0x3F, 0xF1, 0xFF, 0xEF, 0x07, 0xFC, 0x0F, 0xF0, 0x3F,
0xC1, 0xFF, 0xFF, 0x9F, 0xFC, 0x1F, 0xE0, 0x0F, 0xC0, 0xFF, 0xC7, 0xFF,
0x9E, 0x1E, 0x70, 0x3F, 0xC0, 0xF7, 0x83, 0xDF, 0x1F, 0x7F, 0xFC, 0xFF,
0xF0, 0xF3, 0xC0, 0x0F, 0x00, 0x7C, 0x83, 0xE3, 0xFF, 0x1F, 0xF8, 0x3F,
0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0x00, 0x00,
0x0F, 0xFF, 0xF7, 0x6E, 0xE0, 0x00, 0x30, 0x1F, 0x07, 0xF3, 0xFC, 0xFE,
0x0F, 0x00, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0x00, 0x70, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xE0, 0x0F, 0x80, 0xFF, 0x01, 0xFE, 0x07, 0xF0, 0x0F, 0x03, 0xF1,
0xFE, 0xFF, 0x0F, 0xC0, 0xE0, 0x00, 0x00, 0x1F, 0xC3, 0xFF, 0xBF, 0xFC,
0xE1, 0xF2, 0x07, 0x80, 0x3C, 0x03, 0xC0, 0x3E, 0x03, 0xE0, 0x1E, 0x01,
0xE0, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x00,
0xFE, 0x00, 0x0F, 0xFF, 0x80, 0x3E, 0x0F, 0x80, 0xF0, 0x03, 0x83, 0x80,
0x03, 0x8E, 0x1F, 0x7B, 0x9C, 0x7F, 0xF3, 0x71, 0xFF, 0xE6, 0xE7, 0x87,
0xCF, 0xCF, 0x07, 0x9F, 0x9C, 0x0F, 0x3F, 0x38, 0x1E, 0x7E, 0x78, 0x3C,
0xFC, 0xF0, 0xF9, 0xB8, 0xFF, 0xFF, 0x38, 0xFE, 0xFC, 0x70, 0xF8, 0xF0,
0x70, 0x00, 0x00, 0x78, 0x00, 0x00, 0x7E, 0x3C, 0x00, 0x7F, 0xF8, 0x00,
0x1F, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x3E, 0x00, 0x0F, 0xC0, 0x01, 0xFC,
0x00, 0x7F, 0x80, 0x0F, 0x70, 0x03, 0xCF, 0x00, 0x78, 0xE0, 0x0E, 0x1E,
0x03, 0xC3, 0xC0, 0x7F, 0xFC, 0x1F, 0xFF, 0x83, 0xFF, 0xF8, 0xF0, 0x0F,
0x1E, 0x00, 0xF7, 0x80, 0x1E, 0xF0, 0x03, 0xC0, 0xFF, 0xE1, 0xFF, 0xF3,
0xFF, 0xF7, 0x81, 0xEF, 0x01, 0xFE, 0x03, 0xBC, 0x0F, 0x7F, 0xFC, 0xFF,
0xF9, 0xFF, 0xFB, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFF, 0xFF,
0xFF, 0xFE, 0xFF, 0xF0, 0x03, 0xF8, 0x0F, 0xFC, 0x3F, 0xFF, 0x3F, 0x1E,
0x7C, 0x04, 0xF8, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00,
0xF0, 0x00, 0xF8, 0x00, 0x78, 0x04, 0x7E, 0x1E, 0x3F, 0xFF, 0x1F, 0xFE,
0x07, 0xF8, 0xFF, 0xC0, 0x7F, 0xFC, 0x3F, 0xFF, 0x1E, 0x1F, 0xCF, 0x01,
0xF7, 0x80, 0x7B, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC,
0x01, 0xFE, 0x01, 0xEF, 0x01, 0xF7, 0x83, 0xF3, 0xFF, 0xF9, 0xFF, 0xF0,
0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, 0x00, 0x78,
0x03, 0xC0, 0x1F, 0xFE, 0xFF, 0xF7, 0xFF, 0xBC, 0x01, 0xE0, 0x0F, 0x00,
0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xFF, 0xF7, 0xFF, 0xBF,
0xFD, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x00, 0x03,
0xF8, 0x0F, 0xFE, 0x3F, 0xFF, 0x3F, 0x1E, 0x7C, 0x04, 0xF8, 0x00, 0xF0,
0x00, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF8, 0x0F, 0x78,
0x0F, 0x7E, 0x0F, 0x3F, 0xFF, 0x1F, 0xFE, 0x07, 0xF8, 0xF0, 0x0F, 0xE0,
0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC, 0x03, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC,
0x03, 0xF8, 0x07, 0xF0, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x7F, 0xEF, 0xFD, 0xFF, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78,
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0xC3, 0xFF, 0xF7, 0xFE,
0x3F, 0x80, 0xF0, 0x1E, 0xF0, 0x3C, 0xF0, 0x78, 0xF0, 0xF8, 0xF1, 0xF0,
0xF3, 0xE0, 0xF7, 0xC0, 0xFF, 0x80, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0,
0xF9, 0xF0, 0xF0, 0xF0, 0xF0, 0x78, 0xF0, 0x7C, 0xF0, 0x3E, 0xF0, 0x1F,
0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00,
0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0xE0, 0x01, 0xFE, 0x00, 0x3F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF,
0xC0, 0x7F, 0xF8, 0x0F, 0xFF, 0x83, 0xFF, 0xF8, 0xFF, 0xFF, 0x1D, 0xFE,
0xF7, 0xBF, 0xCE, 0xE7, 0xF9, 0xFC, 0xFF, 0x1F, 0x1F, 0xE1, 0xC3, 0xFC,
0x38, 0x7F, 0x80, 0x0F, 0xF0, 0x01, 0xE0, 0xE0, 0x0F, 0xE0, 0x1F, 0xE0,
0x3F, 0xE0, 0x7F, 0xE0, 0xFF, 0xE1, 0xFF, 0xC3, 0xFF, 0xC7, 0xF7, 0xCF,
0xE7, 0xDF, 0xC7, 0xFF, 0x87, 0xFF, 0x0F, 0xFE, 0x0F, 0xFC, 0x0F, 0xF8,
0x0F, 0xF0, 0x0E, 0x03, 0xF8, 0x03, 0xFF, 0x83, 0xFF, 0xF0, 0xFC, 0x7E,
0x7C, 0x07, 0xBE, 0x01, 0xFF, 0x00, 0x3F, 0xC0, 0x0F, 0xF0, 0x03, 0xFC,
0x00, 0xFF, 0x00, 0x3F, 0xE0, 0x0F, 0x78, 0x07, 0x9F, 0x87, 0xE3, 0xFF,
0xF0, 0x7F, 0xF8, 0x07, 0xF8, 0x00, 0xFF, 0xC1, 0xFF, 0xE3, 0xFF, 0xE7,
0x87, 0xEF, 0x03, 0xDE, 0x03, 0xFC, 0x07, 0xF8, 0x1E, 0xF0, 0x3D, 0xFF,
0xFB, 0xFF, 0xE7, 0xFF, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00,
0xF0, 0x00, 0x03, 0xF8, 0x01, 0xFF, 0xC0, 0xFF, 0xFC, 0x1F, 0x8F, 0xC7,
0xC0, 0x79, 0xF0, 0x0F, 0xBC, 0x00, 0xF7, 0x80, 0x1E, 0xF0, 0x03, 0xDE,
0x00, 0x7B, 0xC0, 0x0F, 0x7C, 0x01, 0xE7, 0x80, 0x78, 0xFC, 0x3F, 0x0F,
0xFF, 0xC0, 0xFF, 0xF0, 0x07, 0xF8, 0x00, 0x1F, 0x18, 0x01, 0xFF, 0x80,
0x1F, 0xE0, 0x00, 0xF8, 0xFF, 0x81, 0xFF, 0xE3, 0xFF, 0xE7, 0x87, 0xEF,
0x03, 0xDE, 0x03, 0xFC, 0x07, 0xF8, 0x1E, 0xF0, 0x3D, 0xFF, 0xFB, 0xFF,
0xE7, 0xFF, 0x0F, 0x0F, 0x1E, 0x1E, 0x3C, 0x1E, 0x78, 0x1E, 0xF0, 0x3E,
0x1F, 0xE0, 0xFF, 0xE7, 0xFF, 0x3E, 0x0C, 0xF0, 0x03, 0xC0, 0x0F, 0x80,
0x1F, 0xE0, 0x3F, 0xF0, 0x7F, 0xE0, 0x1F, 0x80, 0x1F, 0x00, 0x3F, 0x81,
0xEF, 0xFF, 0xBF, 0xFC, 0x3F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F,
0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0,
0x07, 0x80, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE,
0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80,
0xFF, 0x01, 0xEF, 0x0F, 0x9F, 0xFF, 0x1F, 0xFC, 0x0F, 0xE0, 0xF0, 0x03,
0xFE, 0x00, 0xF7, 0x80, 0x79, 0xE0, 0x1E, 0x3C, 0x0F, 0x0F, 0x03, 0xC3,
0xE0, 0xE0, 0x78, 0x78, 0x1F, 0x1E, 0x03, 0xCF, 0x00, 0xF3, 0xC0, 0x1F,
0xE0, 0x07, 0xF8, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x01, 0xE0,
0x00, 0xF0, 0x1E, 0x01, 0xFC, 0x07, 0x80, 0xFF, 0x01, 0xF0, 0x3D, 0xE0,
0xFC, 0x0E, 0x78, 0x3F, 0x07, 0x9E, 0x0F, 0xE1, 0xE3, 0xC7, 0xF8, 0x70,
0xF1, 0xCE, 0x3C, 0x3C, 0x73, 0xCF, 0x07, 0xBC, 0xF3, 0x81, 0xEE, 0x1D,
0xE0, 0x7F, 0x87, 0xF8, 0x0F, 0xE1, 0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xFC,
0x0F, 0xC0, 0x1F, 0x03, 0xE0, 0x07, 0x80, 0x78, 0x00, 0x78, 0x0F, 0x3E,
0x07, 0x8F, 0x07, 0x83, 0xC7, 0x81, 0xF7, 0xC0, 0x7F, 0xC0, 0x1F, 0xC0,
0x07, 0xC0, 0x03, 0xE0, 0x03, 0xF8, 0x01, 0xFC, 0x01, 0xEF, 0x01, 0xF7,
0xC0, 0xF1, 0xF0, 0xF0, 0x78, 0xF8, 0x1E, 0xF8, 0x0F, 0x80, 0xF0, 0x07,
0x7C, 0x07, 0x9E, 0x07, 0x87, 0x83, 0xC3, 0xC3, 0xC0, 0xF1, 0xC0, 0x7D,
0xE0, 0x1F, 0xE0, 0x07, 0xF0, 0x03, 0xF0, 0x00, 0xF0, 0x00, 0x78, 0x00,
0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x00, 0xFF,
0xFD, 0xFF, 0xFB, 0xFF, 0xF0, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0x78,
0x01, 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x03, 0xC0, 0x0F,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x8F, 0x1E,
0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7,
0x8F, 0xFF, 0xFF, 0x80, 0xF0, 0x0E, 0x01, 0xC0, 0x3C, 0x03, 0x80, 0x70,
0x0F, 0x00, 0xE0, 0x1C, 0x03, 0xC0, 0x38, 0x07, 0x00, 0xF0, 0x0E, 0x01,
0xC0, 0x3C, 0x03, 0x80, 0x78, 0x07, 0x00, 0xE0, 0x1E, 0x01, 0xC0, 0xFF,
0xFF, 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7,
0x8F, 0x1E, 0x3C, 0x78, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0x00, 0xF8, 0x1F,
0x81, 0xD8, 0x19, 0xC3, 0x9C, 0x38, 0xE7, 0x0E, 0x70, 0x7E, 0x07, 0xFF,
0xFF, 0xFF, 0x78, 0x78, 0x78, 0x3F, 0x8F, 0xFE, 0x7F, 0xE6, 0x0F, 0x00,
0xF0, 0xFF, 0x7F, 0xFF, 0xFF, 0xF0, 0xFF, 0x0F, 0xFB, 0xF7, 0xFF, 0x3F,
0x70, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x9F, 0x0F,
0xFF, 0x3F, 0xFE, 0xF8, 0xFB, 0xC1, 0xFF, 0x03, 0xF8, 0x0F, 0xF0, 0x3F,
0xC0, 0xFF, 0x87, 0xBF, 0xFE, 0xFF, 0xF3, 0xBF, 0x00, 0x0F, 0xC1, 0xFF,
0x9F, 0xFD, 0xF0, 0xEF, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07,
0xC3, 0x9F, 0xFC, 0x7F, 0xE0, 0xFC, 0x00, 0x00, 0x3C, 0x00, 0xF0, 0x03,
0xC0, 0x0F, 0x00, 0x3C, 0x7E, 0xF3, 0xFF, 0xDF, 0xFF, 0xF8, 0x7F, 0xC0,
0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x87, 0xDF, 0xFF, 0x3F,
0xFC, 0x7E, 0xF0, 0x0F, 0xC1, 0xFF, 0x1F, 0xFD, 0xF0, 0xFF, 0x03, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xC1, 0x1F, 0xFC, 0x7F, 0xE0, 0xFE,
0x00, 0x07, 0xC7, 0xF1, 0xF8, 0xF0, 0x3C, 0x3F, 0xEF, 0xFB, 0xFE, 0x3C,
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x00,
0x1F, 0xBC, 0xFF, 0xF7, 0xFF, 0xFE, 0x1F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03,
0xFC, 0x0F, 0xF8, 0x7D, 0xFF, 0xF7, 0xFF, 0xC7, 0xEF, 0x00, 0x3C, 0x00,
0xF7, 0x07, 0x9F, 0xFE, 0x7F, 0xF0, 0x3E, 0x00, 0xE0, 0x07, 0x00, 0x38,
0x01, 0xC0, 0x0E, 0x00, 0x73, 0xE3, 0xFF, 0xDF, 0xFE, 0xF8, 0xFF, 0x83,
0xFC, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F,
0x03, 0xC0, 0x77, 0xBF, 0xE0, 0x01, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE,
0x73, 0x9C, 0x07, 0x07, 0x83, 0xE1, 0xE0, 0x00, 0x00, 0x3C, 0x1E, 0x0F,
0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1,
0xE1, 0xE7, 0xF3, 0xF0, 0xF0, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00,
0xE0, 0x03, 0x83, 0xEE, 0x1F, 0x38, 0xF8, 0xE7, 0xC3, 0xBE, 0x0F, 0xF0,
0x3F, 0xE0, 0xFF, 0xC3, 0xEF, 0x0F, 0x1E, 0x38, 0x7C, 0xE0, 0xFB, 0x81,
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xE7, 0xC3, 0xE3, 0xFF,
0xBF, 0xCF, 0xFF, 0xFF, 0xBE, 0x3F, 0x1E, 0xF0, 0xF8, 0x7B, 0xC1, 0xE0,
0xFE, 0x07, 0x83, 0xF8, 0x1E, 0x0F, 0xE0, 0x78, 0x3F, 0x81, 0xE0, 0xFE,
0x07, 0x83, 0xF8, 0x1E, 0x0F, 0xE0, 0x78, 0x3C, 0xE7, 0xC7, 0xFF, 0xBF,
0xFD, 0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03,
0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0x80, 0x0F, 0xC0, 0xFF, 0xC7, 0xFF, 0xBE,
0x1E, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xE1, 0xE7,
0xFF, 0x8F, 0xFC, 0x0F, 0xC0, 0xE7, 0xC3, 0xFF, 0xCF, 0xFF, 0xBE, 0x3E,
0xF0, 0x7F, 0xC0, 0xFE, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xE1, 0xEF, 0xFF,
0xBF, 0xFC, 0xE7, 0xC3, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80,
0x00, 0x1F, 0xBC, 0xFF, 0xF7, 0xFF, 0xFE, 0x1F, 0xF0, 0x3F, 0xC0, 0xFF,
0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xE1, 0xF7, 0xFF, 0xCF, 0xFF, 0x1F, 0xBC,
0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0xE7, 0xEF, 0xFF,
0xFC, 0xF0, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x1F, 0xE3,
0xFF, 0x7F, 0xE7, 0x82, 0x78, 0x07, 0xF8, 0x3F, 0xE1, 0xFF, 0x00, 0xF0,
0x07, 0x7F, 0xF7, 0xFE, 0x3F, 0xC0, 0x3C, 0x0F, 0x03, 0xC3, 0xFE, 0xFF,
0xBF, 0xE3, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xE1,
0xFC, 0x3F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F,
0x81, 0xFC, 0x0F, 0xF0, 0x7F, 0x87, 0xFF, 0xFE, 0xFF, 0xF3, 0xF7, 0x80,
0xF0, 0x1D, 0xE0, 0x79, 0xE0, 0xF3, 0xC3, 0xC3, 0x87, 0x87, 0x8E, 0x0F,
0x3C, 0x0F, 0x70, 0x1F, 0xE0, 0x1F, 0xC0, 0x3F, 0x00, 0x3E, 0x00, 0x78,
0x00, 0xF0, 0x38, 0x1D, 0xC1, 0xE0, 0x77, 0x07, 0xC3, 0xDE, 0x1F, 0x0E,
0x38, 0xFC, 0x38, 0xE3, 0xF9, 0xE3, 0xDE, 0xE7, 0x07, 0x73, 0xFC, 0x1D,
0xC7, 0xE0, 0x7F, 0x1F, 0x80, 0xF8, 0x7E, 0x03, 0xE0, 0xF0, 0x0F, 0x03,
0xC0, 0x78, 0x3D, 0xE1, 0xE3, 0xCF, 0x07, 0xF8, 0x0F, 0xE0, 0x3F, 0x00,
0x78, 0x03, 0xF0, 0x0F, 0xE0, 0x7F, 0xC3, 0xCF, 0x1E, 0x1E, 0xF8, 0x3C,
0xF0, 0x1D, 0xE0, 0x79, 0xE0, 0xF3, 0xC1, 0xC3, 0xC7, 0x87, 0x8E, 0x07,
0x3C, 0x0F, 0x70, 0x1F, 0xE0, 0x1F, 0xC0, 0x3F, 0x00, 0x3E, 0x00, 0x78,
0x00, 0xF0, 0x13, 0xC0, 0x7F, 0x80, 0xFE, 0x00, 0xF0, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0x1F, 0x3F, 0x3E, 0x3C, 0x3C, 0x3C, 0x3C,
0x3C, 0x3C, 0xF8, 0xF0, 0xFC, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3E,
0x3F, 0x1F, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0xF0, 0xF8, 0xFC, 0x3C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x0F,
0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C, 0x7C, 0xFC, 0xF8, 0xE0, 0x38,
0x37, 0xE3, 0x7F, 0xFE, 0x7E, 0xE1, 0xC0 };
const GFXglyph Montserrat_Bold12pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 7, 0, 0 }, // 0x20 ' '
{ 1, 5, 17, 7, 1, -16 }, // 0x21 '!'
{ 12, 8, 7, 10, 1, -16 }, // 0x22 '"'
{ 19, 17, 17, 17, 0, -16 }, // 0x23 '#'
{ 56, 14, 23, 15, 1, -19 }, // 0x24 '$'
{ 97, 19, 17, 21, 1, -16 }, // 0x25 '%'
{ 138, 16, 17, 17, 1, -16 }, // 0x26 '&'
{ 172, 3, 7, 6, 1, -16 }, // 0x27 '''
{ 175, 6, 23, 9, 2, -17 }, // 0x28 '('
{ 193, 7, 23, 9, 0, -17 }, // 0x29 ')'
{ 214, 10, 10, 10, 0, -17 }, // 0x2A '*'
{ 227, 12, 11, 14, 1, -13 }, // 0x2B '+'
{ 244, 4, 8, 6, 1, -3 }, // 0x2C ','
{ 248, 7, 3, 9, 1, -7 }, // 0x2D '-'
{ 251, 4, 4, 6, 1, -3 }, // 0x2E '.'
{ 253, 11, 22, 9, -1, -19 }, // 0x2F '/'
{ 284, 14, 17, 16, 1, -16 }, // 0x30 '0'
{ 314, 7, 17, 9, 0, -16 }, // 0x31 '1'
{ 329, 13, 17, 14, 0, -16 }, // 0x32 '2'
{ 357, 13, 17, 14, 0, -16 }, // 0x33 '3'
{ 385, 15, 17, 17, 1, -16 }, // 0x34 '4'
{ 417, 14, 17, 14, 0, -16 }, // 0x35 '5'
{ 447, 14, 17, 15, 1, -16 }, // 0x36 '6'
{ 477, 13, 17, 15, 1, -16 }, // 0x37 '7'
{ 505, 14, 17, 16, 1, -16 }, // 0x38 '8'
{ 535, 14, 17, 15, 0, -16 }, // 0x39 '9'
{ 565, 4, 13, 6, 1, -12 }, // 0x3A ':'
{ 572, 4, 17, 6, 1, -12 }, // 0x3B ';'
{ 581, 12, 12, 14, 1, -13 }, // 0x3C '<'
{ 599, 12, 9, 14, 1, -12 }, // 0x3D '='
{ 613, 12, 12, 14, 1, -13 }, // 0x3E '>'
{ 631, 13, 17, 14, 0, -16 }, // 0x3F '?'
{ 659, 23, 22, 25, 1, -16 }, // 0x40 '@'
{ 723, 19, 17, 18, 0, -16 }, // 0x41 'A'
{ 764, 15, 17, 18, 2, -16 }, // 0x42 'B'
{ 796, 16, 17, 17, 1, -16 }, // 0x43 'C'
{ 830, 17, 17, 20, 2, -16 }, // 0x44 'D'
{ 867, 13, 17, 16, 2, -16 }, // 0x45 'E'
{ 895, 13, 17, 15, 2, -16 }, // 0x46 'F'
{ 923, 16, 17, 19, 1, -16 }, // 0x47 'G'
{ 957, 15, 17, 19, 2, -16 }, // 0x48 'H'
{ 989, 4, 17, 8, 2, -16 }, // 0x49 'I'
{ 998, 11, 17, 13, 0, -16 }, // 0x4A 'J'
{ 1022, 16, 17, 18, 2, -16 }, // 0x4B 'K'
{ 1056, 12, 17, 15, 2, -16 }, // 0x4C 'L'
{ 1082, 19, 17, 23, 2, -16 }, // 0x4D 'M'
{ 1123, 15, 17, 19, 2, -16 }, // 0x4E 'N'
{ 1155, 18, 17, 20, 1, -16 }, // 0x4F 'O'
{ 1194, 15, 17, 18, 2, -16 }, // 0x50 'P'
{ 1226, 19, 21, 20, 1, -16 }, // 0x51 'Q'
{ 1276, 15, 17, 18, 2, -16 }, // 0x52 'R'
{ 1308, 14, 17, 15, 1, -16 }, // 0x53 'S'
{ 1338, 15, 17, 15, 0, -16 }, // 0x54 'T'
{ 1370, 15, 17, 19, 2, -16 }, // 0x55 'U'
{ 1402, 18, 17, 18, 0, -16 }, // 0x56 'V'
{ 1441, 26, 17, 28, 1, -16 }, // 0x57 'W'
{ 1497, 17, 17, 17, 0, -16 }, // 0x58 'X'
{ 1534, 17, 17, 16, 0, -16 }, // 0x59 'Y'
{ 1571, 15, 17, 16, 1, -16 }, // 0x5A 'Z'
{ 1603, 7, 23, 9, 2, -17 }, // 0x5B '['
{ 1624, 11, 22, 9, -1, -19 }, // 0x5C '\'
{ 1655, 7, 23, 9, 0, -17 }, // 0x5D ']'
{ 1676, 12, 10, 14, 1, -12 }, // 0x5E '^'
{ 1691, 12, 2, 12, 0, 1 }, // 0x5F '_'
{ 1694, 7, 3, 14, 2, -17 }, // 0x60 '`'
{ 1697, 12, 13, 15, 1, -12 }, // 0x61 'a'
{ 1717, 14, 18, 17, 2, -17 }, // 0x62 'b'
{ 1749, 13, 13, 14, 1, -12 }, // 0x63 'c'
{ 1771, 14, 18, 17, 1, -17 }, // 0x64 'd'
{ 1803, 13, 13, 15, 1, -12 }, // 0x65 'e'
{ 1825, 10, 18, 9, 0, -17 }, // 0x66 'f'
{ 1848, 14, 18, 17, 1, -12 }, // 0x67 'g'
{ 1880, 13, 18, 17, 2, -17 }, // 0x68 'h'
{ 1910, 5, 19, 7, 1, -18 }, // 0x69 'i'
{ 1922, 9, 24, 7, -2, -18 }, // 0x6A 'j'
{ 1949, 14, 18, 16, 2, -17 }, // 0x6B 'k'
{ 1981, 3, 18, 7, 2, -17 }, // 0x6C 'l'
{ 1988, 22, 13, 25, 2, -12 }, // 0x6D 'm'
{ 2024, 13, 13, 17, 2, -12 }, // 0x6E 'n'
{ 2046, 14, 13, 16, 1, -12 }, // 0x6F 'o'
{ 2069, 14, 18, 17, 2, -12 }, // 0x70 'p'
{ 2101, 14, 18, 17, 1, -12 }, // 0x71 'q'
{ 2133, 8, 13, 10, 2, -12 }, // 0x72 'r'
{ 2146, 12, 13, 13, 0, -12 }, // 0x73 's'
{ 2166, 10, 16, 10, 0, -15 }, // 0x74 't'
{ 2186, 13, 13, 16, 2, -12 }, // 0x75 'u'
{ 2208, 15, 13, 14, 0, -12 }, // 0x76 'v'
{ 2233, 22, 13, 22, 0, -12 }, // 0x77 'w'
{ 2269, 14, 13, 14, 0, -12 }, // 0x78 'x'
{ 2292, 15, 18, 14, 0, -12 }, // 0x79 'y'
{ 2326, 11, 13, 13, 1, -12 }, // 0x7A 'z'
{ 2344, 8, 23, 9, 1, -17 }, // 0x7B '{'
{ 2367, 3, 23, 7, 2, -17 }, // 0x7C '|'
{ 2376, 8, 23, 9, 0, -17 }, // 0x7D '}'
{ 2399, 12, 5, 14, 1, -10 } }; // 0x7E '~'
const GFXfont Montserrat_Bold12pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold12pt7bBitmaps,
(GFXglyph *)Montserrat_Bold12pt7bGlyphs,
0x20, 0x7E, 29 };
// Approx. 3079 bytes
#endif // MONTSERRATBOLD12PT7B_H
@@ -0,0 +1,536 @@
#ifndef MONTSERRATBOLD18PT7B_H
#define MONTSERRATBOLD18PT7B_H
const uint8_t Montserrat_Bold18pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xE7,
0x9E, 0x78, 0x00, 0x1E, 0xFF, 0xFF, 0xFF, 0x78, 0xF1, 0xFE, 0x3F, 0xC7,
0xF8, 0xFF, 0x1F, 0xE3, 0xFC, 0x7F, 0x8F, 0xF1, 0xFE, 0x3C, 0x01, 0xE0,
0xF0, 0x03, 0xC0, 0xF0, 0x03, 0xC1, 0xE0, 0x03, 0xC1, 0xE0, 0x03, 0xC1,
0xE0, 0x03, 0xC1, 0xE0, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF,
0xFE, 0x7F, 0xFF, 0xFE, 0x07, 0x83, 0xC0, 0x07, 0x83, 0xC0, 0x07, 0x83,
0xC0, 0x07, 0x83, 0xC0, 0x07, 0x83, 0xC0, 0x07, 0x83, 0xC0, 0xFF, 0xFF,
0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0x0F, 0x07, 0x80, 0x0F, 0x07,
0x80, 0x0F, 0x07, 0x80, 0x0F, 0x07, 0x80, 0x0F, 0x07, 0x80, 0x0F, 0x07,
0x80, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x01,
0xFE, 0x00, 0xFF, 0xFC, 0x1F, 0xFF, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7,
0xE7, 0x1C, 0x7C, 0x70, 0x4F, 0xC7, 0x00, 0xFC, 0x70, 0x07, 0xF7, 0x00,
0x7F, 0xF0, 0x03, 0xFF, 0xE0, 0x1F, 0xFF, 0x80, 0xFF, 0xFE, 0x01, 0xFF,
0xE0, 0x07, 0xFF, 0x00, 0x73, 0xF0, 0x07, 0x1F, 0x00, 0x71, 0xF7, 0x07,
0x3F, 0x7E, 0x77, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE7, 0xFF, 0xF8, 0x0F,
0xFF, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00,
0x0F, 0x00, 0x07, 0x81, 0xFE, 0x00, 0x78, 0x1F, 0xF8, 0x07, 0x80, 0xF3,
0xC0, 0x3C, 0x0F, 0x0F, 0x03, 0xC0, 0x78, 0x78, 0x3C, 0x03, 0x81, 0xC1,
0xE0, 0x1C, 0x0E, 0x1E, 0x00, 0xF0, 0xF1, 0xE0, 0x07, 0x87, 0x9F, 0x00,
0x1E, 0x78, 0xF0, 0x00, 0xFF, 0xCF, 0x00, 0x03, 0xFC, 0xF8, 0xFC, 0x07,
0x87, 0x9F, 0xF0, 0x00, 0x78, 0xFF, 0xC0, 0x07, 0xCF, 0x1E, 0x00, 0x3C,
0x70, 0x78, 0x03, 0xC3, 0x83, 0xC0, 0x3E, 0x1C, 0x1E, 0x01, 0xE0, 0xE0,
0xF0, 0x1E, 0x07, 0x07, 0x81, 0xE0, 0x3C, 0x78, 0x0F, 0x00, 0xFF, 0xC0,
0xF0, 0x07, 0xFC, 0x0F, 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x03, 0xFF,
0x00, 0x0F, 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x1F, 0x87, 0xC0, 0x1F, 0x07,
0xC0, 0x1F, 0x07, 0xC0, 0x1F, 0x0F, 0xC0, 0x0F, 0x9F, 0x80, 0x0F, 0xFF,
0x00, 0x07, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xFC, 0x00, 0x1F, 0xFE,
0x3C, 0x3F, 0x7F, 0x3E, 0x7E, 0x3F, 0xBE, 0x7C, 0x1F, 0xFC, 0xFC, 0x0F,
0xFC, 0xFC, 0x07, 0xF8, 0xFC, 0x03, 0xF8, 0x7E, 0x07, 0xFC, 0x7F, 0xFF,
0xFE, 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0x9C, 0x07, 0xFE, 0x0C, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x0F, 0x8F, 0x8F, 0xC7, 0xC3, 0xE3, 0xF1, 0xF0, 0xF8,
0xFC, 0x7E, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E,
0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF8, 0xFC, 0x3E, 0x1F, 0x0F, 0xC3, 0xE1,
0xF8, 0x7C, 0x3E, 0x0F, 0x80, 0x7C, 0x1F, 0x03, 0xE0, 0xFC, 0x3F, 0x07,
0xC1, 0xF8, 0x7E, 0x0F, 0x83, 0xE0, 0xFC, 0x3F, 0x0F, 0xC1, 0xF0, 0x7C,
0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x3F, 0x0F, 0xC3, 0xF0, 0xF8, 0x3E, 0x0F,
0x87, 0xE1, 0xF8, 0x7C, 0x3F, 0x0F, 0x83, 0xE1, 0xF0, 0xFC, 0x00, 0x03,
0x80, 0x07, 0x00, 0x8E, 0x23, 0xDC, 0xE7, 0xFF, 0xE7, 0xFF, 0x87, 0xFC,
0x0F, 0xF8, 0x7F, 0xFC, 0xFF, 0xF9, 0xCE, 0x71, 0x1C, 0x40, 0x38, 0x00,
0x70, 0x00, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E,
0x00, 0x1F, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0,
0x10, 0xFB, 0xFF, 0xFF, 0xEF, 0xDF, 0x1E, 0x3C, 0xF1, 0xE3, 0x80, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0xFB, 0xFF, 0xFF, 0xEF, 0xDF, 0x00, 0x00,
0x1F, 0x00, 0x1F, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x7C, 0x00,
0x7C, 0x00, 0x78, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF0, 0x01, 0xF0, 0x01,
0xF0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x07, 0xC0, 0x07, 0xC0, 0x07,
0xC0, 0x0F, 0x80, 0x0F, 0x80, 0x0F, 0x80, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
0x00, 0x3E, 0x00, 0x3E, 0x00, 0x3C, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0x78,
0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 0xFC, 0x00, 0x1F, 0xF8, 0x03, 0xFF,
0xE0, 0x3F, 0xFF, 0x81, 0xFF, 0xFE, 0x1F, 0xC3, 0xF9, 0xFC, 0x0F, 0xCF,
0xC0, 0x3F, 0x7E, 0x01, 0xFB, 0xE0, 0x0F, 0xFF, 0x00, 0x3F, 0xF8, 0x01,
0xFF, 0xC0, 0x0F, 0xFE, 0x00, 0x7F, 0xF0, 0x03, 0xEF, 0x80, 0x3F, 0x7C,
0x01, 0xFB, 0xF0, 0x0F, 0xDF, 0x80, 0xFC, 0x7E, 0x07, 0xE3, 0xFC, 0xFF,
0x0F, 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0xFF, 0xF0, 0x03, 0xFE, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0,
0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC,
0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0x03, 0xF8,
0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0x87, 0xFF, 0xFC, 0xFF, 0xFF, 0xC7, 0xC0,
0xFE, 0x18, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00,
0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00,
0x1F, 0xC0, 0x03, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00,
0x3F, 0xFF, 0xF7, 0xFF, 0xFF, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x7F, 0xFF,
0xF0, 0x7F, 0xFF, 0xCF, 0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xFF,
0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x1F,
0x80, 0x07, 0xE0, 0x00, 0xFF, 0x80, 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F,
0xF8, 0x00, 0x3F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x98, 0x03,
0xF7, 0xE1, 0xFE, 0xFF, 0xFF, 0xBF, 0xFF, 0xF3, 0xFF, 0xF8, 0x1F, 0xFE,
0x00, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0,
0x00, 0x07, 0xE0, 0x00, 0x1F, 0x80, 0x00, 0x7E, 0x00, 0x01, 0xFC, 0x00,
0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x01,
0xF8, 0x7E, 0x07, 0xE0, 0xFC, 0x1F, 0x81, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x07,
0xE0, 0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x1F,
0xFF, 0xC1, 0xF0, 0x00, 0x1F, 0x00, 0x01, 0xF0, 0x00, 0x1F, 0x00, 0x01,
0xF0, 0x00, 0x1F, 0xFE, 0x03, 0xFF, 0xF8, 0x3F, 0xFF, 0xC3, 0xFF, 0xFE,
0x00, 0x3F, 0xE0, 0x00, 0x7F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x03,
0xF3, 0x00, 0x7F, 0x3F, 0x1F, 0xE7, 0xFF, 0xFE, 0xFF, 0xFF, 0xC7, 0xFF,
0xF8, 0x0F, 0xFE, 0x00, 0x00, 0x7F, 0x80, 0x0F, 0xFF, 0x01, 0xFF, 0xF8,
0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x1F, 0xE0, 0x20, 0xFC, 0x00, 0x0F, 0xC0,
0x00, 0x7E, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0x3F, 0xC1, 0xFF, 0xFF, 0x8F,
0xFF, 0xFE, 0x7F, 0xFF, 0xFB, 0xFC, 0x1F, 0xDF, 0xC0, 0x7E, 0x7E, 0x01,
0xFB, 0xF0, 0x0F, 0xDF, 0x80, 0x7E, 0xFC, 0x03, 0xE3, 0xF0, 0x3F, 0x0F,
0xFF, 0xF0, 0x7F, 0xFF, 0x80, 0xFF, 0xF8, 0x03, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x80,
0x7E, 0xF8, 0x0F, 0xEF, 0x80, 0xFC, 0xF8, 0x0F, 0xC0, 0x01, 0xF8, 0x00,
0x1F, 0x80, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00,
0x0F, 0xE0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x1F, 0x80,
0x03, 0xF0, 0x00, 0x3F, 0x00, 0x07, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xE0,
0x00, 0x01, 0xFC, 0x00, 0x7F, 0xFC, 0x07, 0xFF, 0xF0, 0x7F, 0xFF, 0xC3,
0xF8, 0xFE, 0x3F, 0x01, 0xF9, 0xF8, 0x0F, 0xCF, 0xC0, 0x7E, 0x7E, 0x03,
0xF1, 0xF8, 0x3F, 0x8F, 0xFF, 0xF8, 0x3F, 0xFF, 0x81, 0xFF, 0xFC, 0x1F,
0xFF, 0xF1, 0xFE, 0x1F, 0xCF, 0xC0, 0x7E, 0xFC, 0x01, 0xFF, 0xE0, 0x0F,
0xFF, 0x00, 0x7F, 0xF8, 0x03, 0xF7, 0xE0, 0x3F, 0x3F, 0xFF, 0xF8, 0xFF,
0xFF, 0x83, 0xFF, 0xF8, 0x07, 0xFF, 0x00, 0x03, 0xF0, 0x01, 0xFF, 0xE0,
0x3F, 0xFF, 0x07, 0xFF, 0xF8, 0x7F, 0x3F, 0xCF, 0xC0, 0x7E, 0xFC, 0x07,
0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xFF, 0xC0, 0x7F, 0xFC, 0x07, 0xFF, 0xFB,
0xFF, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, 0x1F, 0xFB, 0xF0, 0x7E, 0x3F, 0x00,
0x03, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x38, 0x7F, 0xC3,
0xFF, 0xF8, 0x7F, 0xFF, 0x07, 0xFF, 0xE0, 0x3F, 0xF8, 0x00, 0x10, 0xFB,
0xFF, 0xFF, 0xEF, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1F, 0x7F,
0xFF, 0xFD, 0xFB, 0xE0, 0x10, 0xFB, 0xFF, 0xFF, 0xEF, 0xDF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x1F, 0x7F, 0xFF, 0xFD, 0xFB, 0xE3, 0xC7, 0x9E,
0x3C, 0x70, 0x00, 0x00, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x1F, 0xF0, 0x7F,
0xF8, 0xFF, 0xE3, 0xFF, 0x81, 0xFF, 0x00, 0xFC, 0x00, 0x7F, 0x00, 0x3F,
0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x0F, 0xFC, 0x01, 0xFE, 0x00, 0x1F,
0x00, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x80, 0x00, 0x78, 0x00, 0x3F,
0x00, 0x1F, 0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xE0, 0x0F, 0xFE, 0x01, 0xFF,
0x00, 0x1F, 0x80, 0x1F, 0xC0, 0x7F, 0xE1, 0xFF, 0xE7, 0xFF, 0x87, 0xFE,
0x03, 0xFC, 0x01, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x03, 0xF8, 0x01, 0xFF,
0xE0, 0xFF, 0xFE, 0x3F, 0xFF, 0xEF, 0xFF, 0xFC, 0xF8, 0x1F, 0xC6, 0x01,
0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x7E, 0x00, 0x1F,
0xC0, 0x07, 0xF0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xC0, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1F, 0x80, 0x03, 0xF8,
0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x00, 0x07, 0xF8, 0x00,
0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x0F, 0xFE, 0xFF,
0xC0, 0x07, 0xF0, 0x01, 0xF8, 0x03, 0xF0, 0x00, 0x1F, 0x01, 0xF0, 0x00,
0x03, 0xE0, 0x78, 0x00, 0x00, 0x7C, 0x3E, 0x0F, 0xF7, 0xCF, 0x0F, 0x07,
0xFF, 0xF1, 0xE7, 0x83, 0xFF, 0xFC, 0x79, 0xE1, 0xFF, 0xFF, 0x0E, 0x78,
0x7C, 0x0F, 0xC3, 0xDE, 0x3E, 0x01, 0xF0, 0xFF, 0x0F, 0x80, 0x7C, 0x3F,
0xC3, 0xE0, 0x1F, 0x0F, 0xF0, 0xF8, 0x07, 0xC3, 0xFC, 0x3E, 0x01, 0xF0,
0xFF, 0x0F, 0x80, 0x7C, 0x3D, 0xE3, 0xF0, 0x3F, 0x0E, 0x78, 0x7E, 0x1F,
0xC7, 0x9E, 0x1F, 0xFF, 0xFF, 0xE3, 0xC3, 0xFF, 0xFF, 0xF0, 0xF0, 0x7F,
0xE7, 0xF8, 0x1E, 0x0F, 0xE0, 0xFC, 0x07, 0xC0, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x03, 0xFC, 0x0F, 0x00, 0x00,
0x7F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xF8, 0x00,
0x00, 0x1F, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F,
0xE0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x3E, 0xF8, 0x00,
0x0F, 0xDF, 0x00, 0x01, 0xF3, 0xF0, 0x00, 0x3E, 0x3E, 0x00, 0x0F, 0xC7,
0xE0, 0x01, 0xF0, 0x7C, 0x00, 0x7E, 0x0F, 0xC0, 0x0F, 0x81, 0xF8, 0x03,
0xF0, 0x1F, 0x00, 0x7F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFE, 0x03, 0xFF, 0xFF,
0xE0, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xC3, 0xE0, 0x01, 0xF8, 0xFC,
0x00, 0x1F, 0x9F, 0x80, 0x03, 0xF7, 0xE0, 0x00, 0x3E, 0xFC, 0x00, 0x07,
0xE0, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC,
0xFF, 0xFF, 0xFB, 0xF0, 0x0F, 0xEF, 0xC0, 0x1F, 0xBF, 0x00, 0x7E, 0xFC,
0x01, 0xFB, 0xF0, 0x07, 0xEF, 0xC0, 0xFF, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF,
0xE3, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xBF, 0x00, 0x3F, 0xFC, 0x00, 0xFF,
0xF0, 0x01, 0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x3F, 0xFC, 0x03, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xF8, 0xFF, 0xFF, 0x80, 0x00, 0x3F,
0x80, 0x01, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF,
0xFF, 0x1F, 0xE0, 0x7E, 0x3F, 0x80, 0x1C, 0x7F, 0x00, 0x00, 0x7E, 0x00,
0x00, 0x7E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00,
0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x3F, 0x00, 0x18, 0x3F, 0xC0, 0x3C, 0x1F, 0xF9,
0xFE, 0x0F, 0xFF, 0xFE, 0x07, 0xFF, 0xFC, 0x03, 0xFF, 0xF8, 0x00, 0xFF,
0xE0, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xC0, 0x3F, 0xFF, 0xF8, 0x1F, 0xFF,
0xFE, 0x0F, 0xFF, 0xFF, 0x87, 0xE0, 0x3F, 0xE3, 0xF0, 0x03, 0xF9, 0xF8,
0x00, 0xFC, 0xFC, 0x00, 0x3F, 0x7E, 0x00, 0x1F, 0xBF, 0x00, 0x07, 0xDF,
0x80, 0x03, 0xEF, 0xC0, 0x01, 0xFF, 0xE0, 0x00, 0xFF, 0xF0, 0x00, 0x7D,
0xF8, 0x00, 0x7E, 0xFC, 0x00, 0x3F, 0x7E, 0x00, 0x3F, 0xBF, 0x00, 0x3F,
0x9F, 0x80, 0x3F, 0xCF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF,
0xC1, 0xFF, 0xFF, 0x80, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xDF, 0xFF,
0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0xFD, 0xF8, 0x00, 0x3F, 0x00,
0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xFF, 0xFE, 0x7F, 0xFF,
0xCF, 0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xE0, 0x00, 0xFC, 0x00,
0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xC0, 0x03,
0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFF,
0xFF, 0xBF, 0xFF, 0xEF, 0xFF, 0xFB, 0xFF, 0xFE, 0xFC, 0x00, 0x3F, 0x00,
0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03,
0xF0, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x01, 0xFF, 0xF0, 0x03,
0xFF, 0xFC, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x1F, 0xE0, 0x7E, 0x3F,
0x80, 0x1C, 0x7F, 0x00, 0x08, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
0x00, 0x3F, 0x7E, 0x00, 0x3F, 0x7E, 0x00, 0x3F, 0x7F, 0x00, 0x3F, 0x3F,
0x00, 0x3F, 0x3F, 0xC0, 0x3F, 0x1F, 0xF9, 0xFF, 0x0F, 0xFF, 0xFF, 0x07,
0xFF, 0xFE, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xE0, 0xFC, 0x00, 0x7F, 0xF0,
0x01, 0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF0, 0x01,
0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF0, 0x01, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF0, 0x01, 0xFF, 0xC0, 0x07,
0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF0, 0x01, 0xFF, 0xC0, 0x07, 0xFF,
0x00, 0x1F, 0xFC, 0x00, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x1F, 0xFF, 0x8F, 0xFF, 0xC7, 0xFF, 0xE3, 0xFF, 0xF1, 0xFF, 0xF8, 0x00,
0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0,
0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F,
0x80, 0x07, 0xC4, 0x07, 0xE7, 0x03, 0xF3, 0xE3, 0xFB, 0xFF, 0xF9, 0xFF,
0xFC, 0x7F, 0xFC, 0x0F, 0xF8, 0x00, 0xFC, 0x00, 0xFF, 0xF8, 0x03, 0xFB,
0xF0, 0x0F, 0xE7, 0xE0, 0x1F, 0x8F, 0xC0, 0x7E, 0x1F, 0x81, 0xF8, 0x3F,
0x07, 0xE0, 0x7E, 0x1F, 0x80, 0xFC, 0x7E, 0x01, 0xF9, 0xF8, 0x03, 0xF7,
0xE0, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x1F, 0xFF, 0x80, 0x3F, 0xFF,
0x80, 0x7F, 0xFF, 0x80, 0xFF, 0x3F, 0x81, 0xFC, 0x3F, 0x03, 0xF0, 0x7F,
0x07, 0xE0, 0x7F, 0x0F, 0xC0, 0x7F, 0x1F, 0x80, 0x7F, 0x3F, 0x00, 0x7E,
0x7E, 0x00, 0xFE, 0xFC, 0x00, 0xFE, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0,
0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00,
0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F,
0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0,
0x03, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0xF8, 0x00, 0x01, 0xEF, 0x80, 0x00, 0x3E, 0xFC, 0x00,
0x03, 0xEF, 0xC0, 0x00, 0x7E, 0xFE, 0x00, 0x0F, 0xEF, 0xF0, 0x00, 0xFE,
0xFF, 0x00, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xFC,
0x07, 0xFE, 0xFF, 0xE0, 0x7F, 0xEF, 0xBE, 0x0F, 0xBE, 0xFB, 0xF0, 0xFB,
0xEF, 0x9F, 0x1F, 0x3E, 0xF8, 0xFB, 0xF3, 0xEF, 0x8F, 0xFE, 0x3E, 0xF8,
0x7F, 0xC3, 0xEF, 0x87, 0xFC, 0x3E, 0xF8, 0x3F, 0x83, 0xEF, 0x81, 0xF8,
0x3F, 0xF8, 0x1F, 0x03, 0xFF, 0x80, 0xF0, 0x3F, 0xF8, 0x00, 0x03, 0xFF,
0x80, 0x00, 0x3F, 0xF8, 0x00, 0x03, 0xF0, 0xF8, 0x00, 0x7F, 0xE0, 0x01,
0xFF, 0xC0, 0x07, 0xFF, 0x80, 0x1F, 0xFF, 0x00, 0x7F, 0xFE, 0x01, 0xFF,
0xFC, 0x07, 0xFF, 0xF0, 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF,
0x87, 0xFF, 0x7F, 0x1F, 0xFD, 0xFC, 0x7F, 0xF3, 0xF9, 0xFF, 0xC7, 0xF7,
0xFF, 0x0F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF,
0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0x00,
0x3F, 0xFC, 0x00, 0x7C, 0x00, 0x3F, 0x80, 0x00, 0x3F, 0xFE, 0x00, 0x0F,
0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x3F, 0xC0, 0xFF,
0x0F, 0xE0, 0x07, 0xF3, 0xF8, 0x00, 0x7E, 0x7E, 0x00, 0x0F, 0xCF, 0xC0,
0x00, 0xFD, 0xF0, 0x00, 0x1F, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x7F,
0xF8, 0x00, 0x0F, 0xFF, 0x00, 0x01, 0xFB, 0xF0, 0x00, 0x3F, 0x7E, 0x00,
0x07, 0xEF, 0xE0, 0x01, 0xF8, 0xFC, 0x00, 0x7F, 0x1F, 0xE0, 0x1F, 0xC1,
0xFF, 0x9F, 0xF8, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF,
0xC0, 0x00, 0xFF, 0xE0, 0x00, 0xFF, 0xE0, 0x07, 0xFF, 0xF8, 0x3F, 0xFF,
0xF1, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x7E, 0x03, 0xFB, 0xF0, 0x0F, 0xFF,
0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xFF, 0x00, 0x7F, 0xF8, 0x03,
0xFF, 0xC0, 0x3F, 0xFE, 0x0F, 0xFB, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0xFF,
0xFF, 0x87, 0xFF, 0xF0, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00,
0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0x00, 0x00,
0x3F, 0x80, 0x00, 0x1F, 0xFF, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF,
0xE0, 0x1F, 0xFF, 0xFF, 0x01, 0xFE, 0x07, 0xF8, 0x3F, 0x80, 0x1F, 0xC7,
0xF0, 0x00, 0xFC, 0x7E, 0x00, 0x0F, 0xC7, 0xE0, 0x00, 0x7E, 0x7C, 0x00,
0x07, 0xEF, 0xC0, 0x00, 0x7E, 0xFC, 0x00, 0x07, 0xEF, 0xC0, 0x00, 0x7E,
0xFC, 0x00, 0x07, 0xE7, 0xE0, 0x00, 0x7E, 0x7E, 0x00, 0x07, 0xE7, 0xF0,
0x00, 0xFC, 0x3F, 0x00, 0x1F, 0xC3, 0xFC, 0x03, 0xF8, 0x1F, 0xF9, 0xFF,
0x80, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x00,
0xFF, 0xE0, 0x00, 0x00, 0xFE, 0x06, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x3F,
0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x07, 0x00,
0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF8, 0xFF,
0xFF, 0xF3, 0xF0, 0x1F, 0xCF, 0xC0, 0x3F, 0xBF, 0x00, 0x7E, 0xFC, 0x01,
0xFB, 0xF0, 0x07, 0xEF, 0xC0, 0x1F, 0xBF, 0x00, 0x7E, 0xFC, 0x03, 0xFB,
0xF0, 0x7F, 0xCF, 0xFF, 0xFF, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0x83, 0xFF,
0xFC, 0x0F, 0xC1, 0xF8, 0x3F, 0x03, 0xF0, 0xFC, 0x0F, 0xC3, 0xF0, 0x1F,
0x8F, 0xC0, 0x3F, 0x3F, 0x00, 0xFE, 0xFC, 0x01, 0xF8, 0x01, 0xFE, 0x00,
0xFF, 0xFC, 0x1F, 0xFF, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xE0, 0x1C,
0x7C, 0x00, 0x4F, 0xC0, 0x00, 0xFC, 0x00, 0x07, 0xF0, 0x00, 0x7F, 0xE0,
0x03, 0xFF, 0xE0, 0x1F, 0xFF, 0x80, 0xFF, 0xFE, 0x01, 0xFF, 0xE0, 0x01,
0xFF, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x00, 0x01, 0xF7, 0x00, 0x3F, 0x7E,
0x07, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE7, 0xFF, 0xF8, 0x0F, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x80, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00,
0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E,
0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0x07, 0xE0, 0x00,
0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0,
0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF,
0x80, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0x80,
0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x0F,
0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x0F, 0xFE,
0x00, 0x3F, 0xFC, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0xC0, 0x1F, 0x9F, 0x80,
0xFE, 0x7F, 0xDF, 0xF8, 0xFF, 0xFF, 0xC1, 0xFF, 0xFE, 0x03, 0xFF, 0xF0,
0x03, 0xFF, 0x00, 0xFC, 0x00, 0x07, 0xFF, 0x00, 0x03, 0xF7, 0xE0, 0x00,
0xFD, 0xF8, 0x00, 0x3E, 0x7F, 0x00, 0x1F, 0x8F, 0xC0, 0x07, 0xC3, 0xF0,
0x03, 0xF0, 0x7E, 0x00, 0xF8, 0x1F, 0x80, 0x7E, 0x03, 0xF0, 0x1F, 0x80,
0xFC, 0x0F, 0xC0, 0x3F, 0x83, 0xF0, 0x07, 0xE0, 0xF8, 0x01, 0xF8, 0x7E,
0x00, 0x3F, 0x1F, 0x00, 0x0F, 0xCF, 0xC0, 0x01, 0xFB, 0xF0, 0x00, 0x7F,
0xF8, 0x00, 0x1F, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0xC0, 0x00,
0x1F, 0xE0, 0x00, 0x07, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x00,
0x00, 0xFC, 0x00, 0x7C, 0x00, 0x3F, 0xF8, 0x00, 0xFC, 0x00, 0xFF, 0xF0,
0x03, 0xF8, 0x01, 0xF3, 0xF0, 0x07, 0xF0, 0x03, 0xE7, 0xE0, 0x0F, 0xE0,
0x0F, 0xCF, 0xC0, 0x3F, 0xE0, 0x1F, 0x0F, 0xC0, 0x7F, 0xC0, 0x3E, 0x1F,
0x80, 0xFF, 0x80, 0xFC, 0x3F, 0x03, 0xFF, 0x81, 0xF0, 0x3F, 0x07, 0xDF,
0x03, 0xE0, 0x7E, 0x0F, 0xBE, 0x0F, 0xC0, 0xFC, 0x3E, 0x7E, 0x1F, 0x00,
0xFC, 0x7C, 0x7C, 0x3E, 0x01, 0xF8, 0xF8, 0xF8, 0xFC, 0x03, 0xF3, 0xE1,
0xF9, 0xF0, 0x03, 0xE7, 0xC1, 0xF3, 0xE0, 0x07, 0xEF, 0x83, 0xEF, 0xC0,
0x0F, 0xFE, 0x07, 0xFF, 0x00, 0x0F, 0xFC, 0x07, 0xFE, 0x00, 0x1F, 0xF8,
0x0F, 0xFC, 0x00, 0x3F, 0xE0, 0x1F, 0xF0, 0x00, 0x3F, 0xC0, 0x1F, 0xE0,
0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x00, 0xFC,
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x3F, 0x3F, 0x80, 0x3F, 0x8F, 0xC0, 0x1F,
0x83, 0xF0, 0x1F, 0x81, 0xFC, 0x1F, 0x80, 0x7F, 0x0F, 0xC0, 0x1F, 0x8F,
0xC0, 0x07, 0xEF, 0xC0, 0x03, 0xFF, 0xE0, 0x00, 0xFF, 0xE0, 0x00, 0x3F,
0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x03,
0xFE, 0x00, 0x03, 0xFF, 0x80, 0x03, 0xFF, 0xE0, 0x01, 0xFB, 0xF0, 0x01,
0xF8, 0xFC, 0x01, 0xF8, 0x3F, 0x01, 0xFC, 0x1F, 0xC0, 0xFC, 0x07, 0xE0,
0xFC, 0x01, 0xF8, 0xFE, 0x00, 0xFE, 0xFE, 0x00, 0x3F, 0x80, 0xFC, 0x00,
0x1F, 0xFC, 0x00, 0x3F, 0x7E, 0x00, 0x7E, 0x7E, 0x00, 0x7C, 0x3F, 0x00,
0xFC, 0x1F, 0x80, 0xF8, 0x1F, 0x81, 0xF8, 0x0F, 0xC3, 0xF0, 0x0F, 0xC3,
0xE0, 0x07, 0xE7, 0xE0, 0x03, 0xF7, 0xC0, 0x03, 0xFF, 0xC0, 0x01, 0xFF,
0x80, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E,
0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE,
0x7F, 0xFF, 0xF8, 0x00, 0x1F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00,
0x1F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80, 0x00, 0xFC,
0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00,
0x7F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F,
0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1,
0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0x7C, 0x00, 0x3E, 0x00, 0x0F, 0x00, 0x07, 0xC0, 0x03, 0xE0, 0x00, 0xF0,
0x00, 0x7C, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x00,
0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0,
0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x01,
0xE0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x1E, 0x00, 0x0F, 0x80, 0x07, 0xC0,
0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0xFF,
0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1,
0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C,
0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x80, 0x03, 0xE0, 0x01, 0xF0, 0x01, 0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x00,
0x7B, 0xC0, 0x3D, 0xE0, 0x3C, 0x78, 0x1E, 0x3C, 0x1F, 0x1F, 0x0F, 0x07,
0x87, 0x83, 0xC7, 0x80, 0xF3, 0xC0, 0x7B, 0xC0, 0x1E, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x7E, 0x07, 0xE0, 0x3E, 0x03, 0xE0, 0x3C, 0x07,
0xF8, 0x0F, 0xFF, 0x87, 0xFF, 0xF0, 0xFF, 0xFE, 0x3E, 0x3F, 0xC4, 0x03,
0xF0, 0x00, 0xFC, 0x00, 0x1F, 0x0F, 0xFF, 0xCF, 0xFF, 0xF7, 0xFF, 0xFD,
0xF8, 0x1F, 0xFC, 0x07, 0xFF, 0x03, 0xFF, 0xC0, 0xFD, 0xFC, 0xFF, 0x7F,
0xFF, 0xCF, 0xFD, 0xF1, 0xFE, 0x7C, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8,
0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F,
0x9F, 0xC0, 0xFB, 0xFF, 0x0F, 0xFF, 0xF8, 0xFF, 0xFF, 0xCF, 0xF9, 0xFE,
0xFE, 0x07, 0xEF, 0xC0, 0x3F, 0xF8, 0x03, 0xFF, 0x80, 0x3F, 0xF8, 0x03,
0xFF, 0x80, 0x3F, 0xF8, 0x03, 0xFF, 0xC0, 0x3F, 0xFC, 0x07, 0xEF, 0xF1,
0xFE, 0xFF, 0xFF, 0xCF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0x9F, 0xE0, 0x01,
0xFC, 0x00, 0xFF, 0xE0, 0x7F, 0xFF, 0x1F, 0xFF, 0xE7, 0xFC, 0xFE, 0xFC,
0x07, 0x9F, 0x00, 0x47, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0,
0x00, 0x7E, 0x00, 0x07, 0xC0, 0x00, 0xFC, 0x07, 0x1F, 0xE3, 0xF9, 0xFF,
0xFF, 0x1F, 0xFF, 0xC1, 0xFF, 0xF0, 0x0F, 0xF8, 0x00, 0x00, 0x01, 0xF8,
0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00,
0xFC, 0x00, 0x07, 0xE0, 0x7F, 0x3F, 0x0F, 0xFF, 0xF8, 0xFF, 0xFF, 0xCF,
0xFF, 0xFE, 0xFF, 0x9F, 0xF7, 0xE0, 0x3F, 0xBF, 0x01, 0xFF, 0xF0, 0x07,
0xFF, 0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xFF, 0x00, 0x7E, 0xF8,
0x03, 0xF7, 0xE0, 0x3F, 0xBF, 0xC7, 0xFC, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF,
0x0F, 0xFF, 0xF8, 0x1F, 0xCF, 0xC0, 0x03, 0xFC, 0x00, 0xFF, 0xF0, 0x1F,
0xFF, 0x83, 0xFF, 0xFC, 0x7F, 0x0F, 0xE7, 0xE0, 0x3E, 0x7C, 0x03, 0xFF,
0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
0x7C, 0x00, 0x07, 0xE0, 0x10, 0x7F, 0x87, 0x83, 0xFF, 0xFC, 0x1F, 0xFF,
0xC0, 0xFF, 0xF8, 0x03, 0xFE, 0x00, 0x01, 0xFC, 0x0F, 0xF8, 0x3F, 0xF0,
0x7F, 0xE1, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0xFF, 0xF9, 0xFF,
0xF3, 0xFF, 0xE7, 0xFF, 0xC1, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0,
0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07,
0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x03, 0xF8, 0xF8, 0x7F, 0xF7,
0xC7, 0xFF, 0xFE, 0x7F, 0xFF, 0xF7, 0xF8, 0xFF, 0xBF, 0x01, 0xFF, 0xF0,
0x07, 0xFF, 0x80, 0x3F, 0xFC, 0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x7F,
0xF8, 0x03, 0xF7, 0xE0, 0x3F, 0xBF, 0xE7, 0xFC, 0xFF, 0xFF, 0xE3, 0xFF,
0xFF, 0x0F, 0xFF, 0xF8, 0x1F, 0xCF, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF1,
0x80, 0x3F, 0x1F, 0x8F, 0xF8, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, 0x1F, 0xFF,
0x80, 0x3F, 0xF0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C,
0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC7, 0xE0, 0xFB,
0xFF, 0x1F, 0xFF, 0xF3, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xE0, 0xFD, 0xF8,
0x0F, 0xFE, 0x01, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFF, 0xE0,
0x1F, 0xFC, 0x03, 0xFF, 0x80, 0x7F, 0xF0, 0x0F, 0xFE, 0x01, 0xFF, 0xC0,
0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFC, 0x10, 0xFB, 0xFF, 0xFF, 0xEF, 0x84,
0x00, 0x00, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7,
0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE0, 0x00, 0x80, 0x3E, 0x07, 0xF0,
0x7F, 0x07, 0xF0, 0x3E, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3E, 0x03, 0xE0,
0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0,
0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x3E, 0x03, 0xE0,
0x3E, 0x03, 0xE0, 0x7E, 0x47, 0xE7, 0xFC, 0xFF, 0xCF, 0xF8, 0x7E, 0x00,
0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00,
0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x7E, 0xF8, 0x0F, 0xCF, 0x83,
0xF8, 0xF8, 0x7F, 0x0F, 0x8F, 0xE0, 0xF9, 0xFC, 0x0F, 0xBF, 0x80, 0xFF,
0xF0, 0x0F, 0xFF, 0x00, 0xFF, 0xF8, 0x0F, 0xFF, 0x80, 0xFF, 0xFC, 0x0F,
0xEF, 0xE0, 0xFC, 0x7F, 0x0F, 0x83, 0xF8, 0xF8, 0x1F, 0x8F, 0x80, 0xFC,
0xF8, 0x0F, 0xEF, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF9, 0xFC,
0x0F, 0xE1, 0xF7, 0xFE, 0x7F, 0xF3, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF,
0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFE, 0x0F, 0xFF, 0x03, 0xF8,
0x1F, 0xFC, 0x07, 0xE0, 0x1F, 0xF8, 0x07, 0xC0, 0x3F, 0xF0, 0x0F, 0x80,
0x7F, 0xE0, 0x1F, 0x00, 0xFF, 0xC0, 0x3E, 0x01, 0xFF, 0x80, 0x7C, 0x03,
0xFF, 0x00, 0xF8, 0x07, 0xFE, 0x01, 0xF0, 0x0F, 0xFC, 0x03, 0xE0, 0x1F,
0xF8, 0x07, 0xC0, 0x3F, 0xF0, 0x0F, 0x80, 0x7F, 0xE0, 0x1F, 0x00, 0xF8,
0xF8, 0xFC, 0x1F, 0x7F, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF, 0xEF, 0xFF, 0xFD,
0xFC, 0x1F, 0xBF, 0x01, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFF,
0xE0, 0x1F, 0xFC, 0x03, 0xFF, 0x80, 0x7F, 0xF0, 0x0F, 0xFE, 0x01, 0xFF,
0xC0, 0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFF, 0xE0, 0x1F, 0x80, 0x01, 0xFC,
0x00, 0x3F, 0xF8, 0x07, 0xFF, 0xF0, 0x7F, 0xFF, 0xC7, 0xF8, 0xFE, 0x3F,
0x01, 0xF9, 0xF0, 0x0F, 0xDF, 0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F,
0xFF, 0x00, 0x7F, 0xF8, 0x03, 0xF7, 0xC0, 0x1F, 0x3F, 0x01, 0xF9, 0xFE,
0x3F, 0xC7, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0x7F, 0xFC, 0x00, 0xFF, 0x80,
0xF9, 0xFC, 0x0F, 0xBF, 0xF0, 0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0xFF, 0x9F,
0xEF, 0xE0, 0x7E, 0xFC, 0x03, 0xFF, 0x80, 0x3F, 0xF8, 0x03, 0xFF, 0x80,
0x3F, 0xF8, 0x03, 0xFF, 0x80, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, 0x7E, 0xFF,
0x1F, 0xEF, 0xFF, 0xFC, 0xFF, 0xFF, 0x8F, 0xFF, 0xF0, 0xF9, 0xFE, 0x0F,
0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00,
0xF8, 0x00, 0x0F, 0x80, 0x00, 0x03, 0xF9, 0xF8, 0x7F, 0xFF, 0xC7, 0xFF,
0xFE, 0x7F, 0xFF, 0xF7, 0xF9, 0xFF, 0xBF, 0x01, 0xFF, 0xF0, 0x0F, 0xFF,
0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xFF, 0x00, 0x7F, 0xF8, 0x03,
0xFF, 0xC0, 0x1F, 0xBF, 0x01, 0xFD, 0xFE, 0x3F, 0xE7, 0xFF, 0xFF, 0x1F,
0xFF, 0xF8, 0x7F, 0xFF, 0xC0, 0xFE, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F,
0x80, 0x00, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00,
0x0F, 0xC0, 0xF8, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0x07,
0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xC0,
0xF8, 0x1F, 0x03, 0xE0, 0x00, 0x07, 0xFC, 0x0F, 0xFF, 0x9F, 0xFF, 0xCF,
0xFF, 0xCF, 0xC0, 0xE7, 0xC0, 0x03, 0xF0, 0x01, 0xFE, 0x00, 0x7F, 0xF8,
0x3F, 0xFF, 0x07, 0xFF, 0xC0, 0x3F, 0xE0, 0x01, 0xFA, 0x00, 0x7D, 0xC0,
0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0x0F, 0xFE, 0x00, 0x1F, 0x80,
0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x0F, 0xFF, 0x9F, 0xFF, 0x3F, 0xFE, 0x7F,
0xFC, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0,
0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7F, 0x00, 0x7F, 0xE0,
0xFF, 0xC0, 0xFF, 0x80, 0xFF, 0x00, 0xFC, 0x03, 0xFF, 0x80, 0x7F, 0xF0,
0x0F, 0xFE, 0x01, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFF, 0xE0,
0x1F, 0xFC, 0x03, 0xFF, 0x80, 0x7F, 0xF0, 0x0F, 0xFE, 0x01, 0xF7, 0xC0,
0x7E, 0xFC, 0x0F, 0xDF, 0xEF, 0xFB, 0xFF, 0xFF, 0x3F, 0xFF, 0xE3, 0xFF,
0xFC, 0x1F, 0xCF, 0x80, 0xFC, 0x00, 0xFF, 0xE0, 0x0F, 0xDF, 0x00, 0x7C,
0xFC, 0x03, 0xE3, 0xE0, 0x3E, 0x1F, 0x81, 0xF0, 0xFC, 0x1F, 0x83, 0xE0,
0xF8, 0x1F, 0x8F, 0xC0, 0x7C, 0x7C, 0x03, 0xF3, 0xE0, 0x1F, 0xBE, 0x00,
0x7D, 0xF0, 0x03, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0x7F, 0xC0, 0x01, 0xFC,
0x00, 0x0F, 0xE0, 0x00, 0x7E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0xBE, 0x01,
0xF0, 0x0F, 0x9F, 0x01, 0xFC, 0x07, 0xCF, 0x80, 0xFE, 0x03, 0xE3, 0xE0,
0x7F, 0x03, 0xE1, 0xF0, 0x7F, 0xC1, 0xF0, 0xF8, 0x3F, 0xE0, 0xF0, 0x3E,
0x1F, 0xF0, 0xF8, 0x1F, 0x1F, 0x7C, 0x7C, 0x0F, 0x8F, 0xBE, 0x3C, 0x03,
0xEF, 0x8F, 0xBE, 0x01, 0xF7, 0xC7, 0xDF, 0x00, 0xFB, 0xE3, 0xFF, 0x00,
0x3F, 0xE0, 0xFF, 0x80, 0x1F, 0xF0, 0x7F, 0xC0, 0x07, 0xF0, 0x3F, 0xC0,
0x03, 0xF8, 0x0F, 0xE0, 0x01, 0xFC, 0x07, 0xE0, 0x00, 0x7C, 0x03, 0xF0,
0x00, 0x7E, 0x03, 0xF3, 0xF0, 0x1F, 0x0F, 0xC1, 0xF8, 0x3F, 0x1F, 0x80,
0xFD, 0xF8, 0x07, 0xEF, 0x80, 0x1F, 0xFC, 0x00, 0x7F, 0xC0, 0x01, 0xFC,
0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x07, 0xFC, 0x00, 0x7F, 0xF0, 0x07,
0xEF, 0xC0, 0x3E, 0x7E, 0x03, 0xF1, 0xF8, 0x3F, 0x07, 0xE3, 0xF0, 0x3F,
0x9F, 0x00, 0xFC, 0xFC, 0x00, 0xFF, 0xE0, 0x0F, 0xDF, 0x00, 0x7C, 0xFC,
0x03, 0xE3, 0xE0, 0x3E, 0x1F, 0x81, 0xF0, 0xFC, 0x1F, 0x83, 0xE0, 0xF8,
0x1F, 0x8F, 0xC0, 0x7C, 0x7C, 0x03, 0xF3, 0xE0, 0x0F, 0xBE, 0x00, 0x7D,
0xF0, 0x03, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0x7F, 0xC0, 0x01, 0xFC, 0x00,
0x0F, 0xE0, 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x1F, 0x80, 0x39, 0xF8,
0x01, 0xFF, 0xC0, 0x1F, 0xFC, 0x00, 0xFF, 0xC0, 0x01, 0xF8, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xF0, 0x03,
0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF8, 0x01, 0xF8, 0x01,
0xF8, 0x01, 0xF8, 0x01, 0xF8, 0x01, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xE1, 0xFC, 0x7F, 0x8F, 0xF1, 0xF8,
0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x7E,
0x3F, 0xC7, 0xF0, 0xFC, 0x1F, 0xC3, 0xFC, 0x1F, 0x81, 0xF0, 0x3E, 0x07,
0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xFC, 0x3F, 0xC3, 0xF8,
0x3F, 0x01, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0xF8, 0x1F, 0x83, 0xF8, 0x7F, 0x87, 0xF0, 0x7E, 0x07, 0xC0, 0xF8, 0x1F,
0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xF8, 0x7F, 0x07, 0xE3,
0xFC, 0x7F, 0x8F, 0x81, 0xF0, 0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0,
0x7C, 0x1F, 0x8F, 0xF1, 0xFE, 0x3F, 0x87, 0xE0, 0xF0, 0x00, 0x0C, 0x00,
0x1F, 0xC1, 0xDF, 0xF1, 0xFF, 0xFF, 0xFF, 0x3F, 0xF7, 0x07, 0xFB, 0x81,
0xF8 };
const GFXglyph Montserrat_Bold18pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
{ 1, 6, 25, 10, 2, -24 }, // 0x21 '!'
{ 20, 11, 10, 15, 2, -24 }, // 0x22 '"'
{ 34, 24, 25, 25, 1, -24 }, // 0x23 '#'
{ 109, 20, 33, 22, 1, -28 }, // 0x24 '$'
{ 192, 29, 25, 31, 1, -24 }, // 0x25 '%'
{ 283, 24, 25, 25, 1, -24 }, // 0x26 '&'
{ 358, 4, 10, 8, 2, -24 }, // 0x27 '''
{ 363, 9, 33, 13, 3, -25 }, // 0x28 '('
{ 401, 10, 33, 13, 0, -25 }, // 0x29 ')'
{ 443, 15, 14, 15, 0, -25 }, // 0x2A '*'
{ 470, 17, 16, 21, 2, -19 }, // 0x2B '+'
{ 504, 7, 12, 9, 1, -6 }, // 0x2C ','
{ 515, 10, 4, 14, 2, -11 }, // 0x2D '-'
{ 520, 7, 7, 9, 1, -6 }, // 0x2E '.'
{ 527, 16, 33, 14, -1, -28 }, // 0x2F '/'
{ 593, 21, 25, 24, 1, -24 }, // 0x30 '0'
{ 659, 11, 25, 14, 0, -24 }, // 0x31 '1'
{ 694, 20, 25, 21, 0, -24 }, // 0x32 '2'
{ 757, 19, 25, 21, 0, -24 }, // 0x33 '3'
{ 817, 23, 25, 24, 1, -24 }, // 0x34 '4'
{ 889, 20, 25, 21, 0, -24 }, // 0x35 '5'
{ 952, 21, 25, 22, 1, -24 }, // 0x36 '6'
{ 1018, 20, 25, 22, 1, -24 }, // 0x37 '7'
{ 1081, 21, 25, 23, 1, -24 }, // 0x38 '8'
{ 1147, 20, 25, 22, 1, -24 }, // 0x39 '9'
{ 1210, 7, 20, 9, 1, -19 }, // 0x3A ':'
{ 1228, 7, 25, 9, 1, -19 }, // 0x3B ';'
{ 1250, 17, 17, 21, 2, -20 }, // 0x3C '<'
{ 1287, 17, 13, 21, 2, -18 }, // 0x3D '='
{ 1315, 17, 17, 21, 2, -20 }, // 0x3E '>'
{ 1352, 19, 25, 21, 0, -24 }, // 0x3F '?'
{ 1412, 34, 32, 36, 1, -24 }, // 0x40 '@'
{ 1548, 27, 25, 27, 0, -24 }, // 0x41 'A'
{ 1633, 22, 25, 27, 3, -24 }, // 0x42 'B'
{ 1702, 24, 25, 25, 1, -24 }, // 0x43 'C'
{ 1777, 25, 25, 29, 3, -24 }, // 0x44 'D'
{ 1856, 19, 25, 23, 3, -24 }, // 0x45 'E'
{ 1916, 18, 25, 22, 3, -24 }, // 0x46 'F'
{ 1973, 24, 25, 27, 1, -24 }, // 0x47 'G'
{ 2048, 22, 25, 28, 3, -24 }, // 0x48 'H'
{ 2117, 6, 25, 11, 3, -24 }, // 0x49 'I'
{ 2136, 17, 25, 19, -1, -24 }, // 0x4A 'J'
{ 2190, 23, 25, 26, 3, -24 }, // 0x4B 'K'
{ 2262, 18, 25, 21, 3, -24 }, // 0x4C 'L'
{ 2319, 28, 25, 33, 3, -24 }, // 0x4D 'M'
{ 2407, 22, 25, 28, 3, -24 }, // 0x4E 'N'
{ 2476, 27, 25, 30, 1, -24 }, // 0x4F 'O'
{ 2561, 21, 25, 26, 3, -24 }, // 0x50 'P'
{ 2627, 28, 31, 30, 1, -24 }, // 0x51 'Q'
{ 2736, 22, 25, 26, 3, -24 }, // 0x52 'R'
{ 2805, 20, 25, 22, 1, -24 }, // 0x53 'S'
{ 2868, 21, 25, 22, 0, -24 }, // 0x54 'T'
{ 2934, 22, 25, 28, 3, -24 }, // 0x55 'U'
{ 3003, 26, 25, 26, 0, -24 }, // 0x56 'V'
{ 3085, 39, 25, 41, 1, -24 }, // 0x57 'W'
{ 3207, 25, 25, 25, 0, -24 }, // 0x58 'X'
{ 3286, 24, 25, 24, 0, -24 }, // 0x59 'Y'
{ 3361, 22, 25, 23, 1, -24 }, // 0x5A 'Z'
{ 3430, 9, 33, 13, 3, -25 }, // 0x5B '['
{ 3468, 17, 33, 14, -2, -28 }, // 0x5C '\'
{ 3539, 9, 33, 13, 1, -25 }, // 0x5D ']'
{ 3577, 17, 15, 21, 2, -19 }, // 0x5E '^'
{ 3609, 18, 3, 18, 0, 1 }, // 0x5F '_'
{ 3616, 11, 5, 21, 3, -25 }, // 0x60 '`'
{ 3623, 18, 19, 22, 1, -18 }, // 0x61 'a'
{ 3666, 20, 26, 24, 3, -25 }, // 0x62 'b'
{ 3731, 19, 19, 21, 1, -18 }, // 0x63 'c'
{ 3777, 21, 26, 24, 1, -25 }, // 0x64 'd'
{ 3846, 20, 19, 22, 1, -18 }, // 0x65 'e'
{ 3894, 15, 26, 14, 0, -25 }, // 0x66 'f'
{ 3943, 21, 26, 25, 1, -18 }, // 0x67 'g'
{ 4012, 19, 26, 24, 3, -25 }, // 0x68 'h'
{ 4074, 7, 28, 11, 2, -27 }, // 0x69 'i'
{ 4099, 12, 35, 11, -3, -27 }, // 0x6A 'j'
{ 4152, 20, 26, 23, 3, -25 }, // 0x6B 'k'
{ 4217, 5, 26, 11, 3, -25 }, // 0x6C 'l'
{ 4234, 31, 19, 37, 3, -18 }, // 0x6D 'm'
{ 4308, 19, 19, 24, 3, -18 }, // 0x6E 'n'
{ 4354, 21, 19, 23, 1, -18 }, // 0x6F 'o'
{ 4404, 20, 26, 24, 3, -18 }, // 0x70 'p'
{ 4469, 21, 26, 24, 1, -18 }, // 0x71 'q'
{ 4538, 11, 19, 15, 3, -18 }, // 0x72 'r'
{ 4565, 17, 19, 19, 1, -18 }, // 0x73 's'
{ 4606, 15, 23, 15, 0, -22 }, // 0x74 't'
{ 4650, 19, 19, 24, 2, -18 }, // 0x75 'u'
{ 4696, 21, 19, 21, 0, -18 }, // 0x76 'v'
{ 4746, 33, 19, 33, 0, -18 }, // 0x77 'w'
{ 4825, 21, 19, 21, 0, -18 }, // 0x78 'x'
{ 4875, 21, 26, 21, 0, -18 }, // 0x79 'y'
{ 4944, 17, 19, 19, 1, -18 }, // 0x7A 'z'
{ 4985, 11, 33, 14, 2, -25 }, // 0x7B '{'
{ 5031, 5, 33, 11, 3, -25 }, // 0x7C '|'
{ 5052, 11, 33, 14, 1, -25 }, // 0x7D '}'
{ 5098, 17, 7, 21, 2, -15 } }; // 0x7E '~'
const GFXfont Montserrat_Bold18pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold18pt7bBitmaps,
(GFXglyph *)Montserrat_Bold18pt7bGlyphs,
0x20, 0x7E, 43 };
// Approx. 5785 bytes
#endif // MONTSERRATBOLD18PT7B_H
@@ -0,0 +1,745 @@
#ifndef MONTSERRATBOLD22PT7B_H
#define MONTSERRATBOLD22PT7B_H
const uint8_t Montserrat_Bold22pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x3E, 0x00, 0x00, 0x00,
0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x3E, 0xFC, 0x7F, 0xF8, 0xFF, 0xF1,
0xFF, 0xE3, 0xFF, 0xC7, 0xFF, 0x8F, 0xFF, 0x1F, 0xFE, 0x3F, 0xFC, 0x7F,
0xF0, 0xFB, 0xE1, 0xF3, 0xC1, 0xE0, 0x00, 0xF8, 0x1F, 0x00, 0x07, 0xC0,
0xF8, 0x00, 0x3E, 0x07, 0xC0, 0x01, 0xF0, 0x3E, 0x00, 0x0F, 0x81, 0xF0,
0x00, 0x7C, 0x0F, 0x80, 0x03, 0xC0, 0x7C, 0x0F, 0xFF, 0xFF, 0xFF, 0x7F,
0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFE, 0x03, 0xE0,
0x7C, 0x00, 0x1F, 0x03, 0xE0, 0x00, 0xF8, 0x1F, 0x00, 0x07, 0x80, 0xF8,
0x00, 0x7C, 0x07, 0x80, 0x03, 0xE0, 0x7C, 0x00, 0x1F, 0x03, 0xE0, 0x3F,
0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xC0, 0xF8, 0x0F, 0x00, 0x07, 0xC0, 0xF8,
0x00, 0x3E, 0x07, 0xC0, 0x01, 0xF0, 0x3E, 0x00, 0x0F, 0x81, 0xF0, 0x00,
0x7C, 0x0F, 0x80, 0x03, 0xE0, 0x7C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0F,
0x00, 0x00, 0x07, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x0F,
0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x1F,
0xFF, 0xFF, 0x1F, 0xF7, 0x9F, 0x8F, 0xE3, 0xC1, 0x87, 0xF1, 0xE0, 0x03,
0xF8, 0xF0, 0x01, 0xFC, 0x78, 0x00, 0xFF, 0x3C, 0x00, 0x7F, 0xFE, 0x00,
0x1F, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,
0xE0, 0x0F, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0x00, 0x1E,
0x7F, 0x80, 0x0F, 0x1F, 0xC0, 0x07, 0x8F, 0xE6, 0x03, 0xC7, 0xF3, 0xC1,
0xE3, 0xFB, 0xFC, 0xF7, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFC, 0x7F,
0xFF, 0xFC, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x00, 0x03, 0xC0, 0x00,
0x01, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3C, 0x00,
0x0F, 0xE0, 0x00, 0x7C, 0x01, 0xFF, 0x80, 0x0F, 0xC0, 0x3F, 0xFC, 0x00,
0xF8, 0x07, 0xC7, 0xC0, 0x1F, 0x00, 0x78, 0x3E, 0x03, 0xF0, 0x0F, 0x83,
0xE0, 0x3E, 0x00, 0xF8, 0x1E, 0x07, 0xC0, 0x0F, 0x81, 0xE0, 0xFC, 0x00,
0xF8, 0x1E, 0x0F, 0x80, 0x0F, 0x81, 0xE1, 0xF0, 0x00, 0xF8, 0x3E, 0x3E,
0x00, 0x07, 0x83, 0xC3, 0xE0, 0x00, 0x7E, 0xFC, 0x7C, 0x00, 0x03, 0xFF,
0x8F, 0x80, 0x00, 0x1F, 0xF0, 0xF8, 0x7E, 0x00, 0xFE, 0x1F, 0x1F, 0xF8,
0x00, 0x03, 0xE3, 0xFF, 0xC0, 0x00, 0x3E, 0x3E, 0x7E, 0x00, 0x07, 0xC7,
0xC3, 0xE0, 0x00, 0xF8, 0x78, 0x1E, 0x00, 0x1F, 0x87, 0x81, 0xE0, 0x01,
0xF0, 0x78, 0x1F, 0x00, 0x3E, 0x07, 0x81, 0xF0, 0x07, 0xE0, 0x78, 0x1E,
0x00, 0x7C, 0x07, 0x81, 0xE0, 0x0F, 0x80, 0x7C, 0x3E, 0x01, 0xF8, 0x03,
0xE7, 0xE0, 0x1F, 0x00, 0x3F, 0xFC, 0x03, 0xE0, 0x01, 0xFF, 0x80, 0x7C,
0x00, 0x0F, 0xF0, 0x01, 0xFF, 0x80, 0x00, 0x3F, 0xFE, 0x00, 0x07, 0xFF,
0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xE3, 0xF8, 0x01, 0xFC, 0x1F, 0x80,
0x1F, 0x81, 0xF8, 0x01, 0xF8, 0x1F, 0x80, 0x1F, 0xC1, 0xF8, 0x00, 0xFC,
0x7F, 0x00, 0x0F, 0xEF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xC0,
0x00, 0x3F, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x3C, 0x3F,
0xFF, 0xC3, 0xE7, 0xF9, 0xFE, 0x7E, 0xFE, 0x0F, 0xF7, 0xEF, 0xE0, 0x7F,
0xFE, 0xFC, 0x03, 0xFF, 0xCF, 0xC0, 0x1F, 0xFC, 0xFC, 0x00, 0xFF, 0x8F,
0xE0, 0x07, 0xF8, 0xFF, 0x01, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0xFF, 0xF3, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xE1, 0xC0, 0x7F, 0xF8, 0x0C,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
0x9E, 0x07, 0xF0, 0x7E, 0x0F, 0xE0, 0xFC, 0x1F, 0xC1, 0xF8, 0x3F, 0x83,
0xF8, 0x3F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7E, 0x07, 0xE0, 0xFE, 0x0F,
0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F,
0xE0, 0xFE, 0x0F, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xF0, 0x7F, 0x03,
0xF0, 0x3F, 0x83, 0xF8, 0x1F, 0x81, 0xFC, 0x1F, 0xC0, 0xFC, 0x0F, 0xE0,
0x7E, 0x7E, 0x07, 0xF0, 0x3F, 0x03, 0xF8, 0x1F, 0x81, 0xFC, 0x1F, 0xC0,
0xFC, 0x0F, 0xE0, 0xFE, 0x07, 0xE0, 0x7E, 0x07, 0xF0, 0x7F, 0x07, 0xF0,
0x7F, 0x07, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0,
0x3F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7E, 0x0F, 0xE0,
0xFE, 0x0F, 0xE0, 0xFC, 0x1F, 0xC1, 0xF8, 0x3F, 0x83, 0xF8, 0x7F, 0x07,
0xE0, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x0C, 0x78, 0xEF, 0xBC, 0xF7,
0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFE, 0x1F, 0xFF,
0xDF, 0xFF, 0xFF, 0xBD, 0xF3, 0x9E, 0x38, 0x0F, 0x00, 0x07, 0x80, 0x03,
0xC0, 0x00, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80,
0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F,
0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01,
0xF8, 0x00, 0x1F, 0x80, 0x1E, 0x3F, 0x9F, 0xEF, 0xF7, 0xFB, 0xFD, 0xFC,
0x7E, 0x1F, 0x1F, 0x0F, 0x87, 0x83, 0xC3, 0xE1, 0xE0, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x3F, 0x9F, 0xFF, 0xFF, 0xFB,
0xFD, 0xFC, 0x7C, 0x00, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00,
0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00,
0x1F, 0x80, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0x7E, 0x00,
0x07, 0xE0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xC0,
0x01, 0xF8, 0x00, 0x1F, 0x80, 0x03, 0xF8, 0x00, 0x3F, 0x00, 0x03, 0xF0,
0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x00, 0xFC,
0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x3F,
0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x07,
0xE0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x08, 0x00, 0x00, 0xFF,
0xE0, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0xFF,
0xFF, 0xF0, 0xFF, 0x8F, 0xF8, 0xFF, 0x01, 0xFE, 0x7F, 0x00, 0x7F, 0x3F,
0x80, 0x3F, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x07, 0xFF, 0xE0, 0x03, 0xFF,
0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x7F, 0xFE, 0x00, 0x3F,
0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x07, 0xFF, 0xE0, 0x03,
0xFF, 0xF0, 0x01, 0xFD, 0xFC, 0x01, 0xFE, 0xFE, 0x00, 0xFE, 0x7F, 0x80,
0xFF, 0x1F, 0xFB, 0xFF, 0x07, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0x80, 0xFF,
0xFF, 0x80, 0x1F, 0xFF, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x38, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFC, 0x0F, 0xE0, 0x7F,
0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xE0,
0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F,
0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC,
0x00, 0x18, 0x00, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8,
0x7F, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0x7F, 0x87, 0xFE, 0x3E, 0x01, 0xFE,
0x0C, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
0x00, 0x01, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8,
0x00, 0x0F, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80,
0x00, 0xFF, 0x00, 0x01, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00,
0x0F, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE,
0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFC,
0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xE0,
0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0xC0,
0x00, 0xFF, 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFE,
0x00, 0x03, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x7F, 0x30, 0x00, 0xFF, 0x38, 0x00, 0xFE, 0x7F, 0x87, 0xFE,
0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xF0,
0x0F, 0xFF, 0xC0, 0x00, 0x18, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x7F,
0x80, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0xC0, 0x00,
0x03, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0xE0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00,
0x07, 0xF8, 0x7E, 0x00, 0xFF, 0x07, 0xE0, 0x0F, 0xE0, 0x7E, 0x01, 0xFC,
0x07, 0xE0, 0x3F, 0xC0, 0x7E, 0x07, 0xF8, 0x07, 0xE0, 0x7F, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x07,
0xE0, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x7E, 0x00,
0x00, 0x07, 0xE0, 0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE,
0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x0F, 0xC0, 0x00, 0x0F, 0xC0, 0x00,
0x0F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xC0, 0x00,
0x1F, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC,
0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x10, 0x00, 0x7F,
0x3C, 0x00, 0xFF, 0x3F, 0xC7, 0xFF, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFC,
0x7F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x03, 0x80, 0x00, 0x3F, 0xFE, 0x00, 0x7F, 0xFF, 0x80, 0xFF, 0xFF,
0xC0, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xE0, 0xFF, 0xC0, 0x60, 0x7F, 0x80,
0x00, 0x7F, 0x80, 0x00, 0x3F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xC0,
0x00, 0x0F, 0xE1, 0xF8, 0x07, 0xF7, 0xFF, 0x83, 0xFF, 0xFF, 0xE1, 0xFF,
0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x7F, 0xF1, 0xFF, 0xBF, 0xE0, 0x3F, 0xDF,
0xE0, 0x0F, 0xEF, 0xF0, 0x03, 0xF7, 0xF8, 0x01, 0xFF, 0xF8, 0x00, 0xFC,
0xFE, 0x00, 0xFE, 0x7F, 0x00, 0x7F, 0x1F, 0xE0, 0x7F, 0x8F, 0xFF, 0xFF,
0x83, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0x80, 0x07, 0xFF,
0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
0xFE, 0xFC, 0x01, 0xFE, 0xFC, 0x01, 0xFC, 0xFC, 0x01, 0xFC, 0x00, 0x03,
0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x1F,
0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x7F,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE,
0x00, 0x01, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x0E,
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x1F,
0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC3, 0xFC, 0x07, 0xF0, 0xFE, 0x01, 0xFE,
0x3F, 0x80, 0x3F, 0x8F, 0xE0, 0x0F, 0xE3, 0xF8, 0x03, 0xF8, 0xFE, 0x01,
0xFC, 0x3F, 0xE0, 0xFF, 0x07, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xC0, 0x3F,
0xFF, 0xF0, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC7, 0xFC, 0x07, 0xF9,
0xFC, 0x00, 0xFE, 0x7F, 0x00, 0x3F, 0xDF, 0xC0, 0x07, 0xFF, 0xF0, 0x01,
0xFD, 0xFC, 0x00, 0x7F, 0x7F, 0x00, 0x3F, 0xDF, 0xE0, 0x1F, 0xE3, 0xFF,
0xFF, 0xF8, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x00,
0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x01, 0xFF, 0xC0,
0x03, 0xFF, 0xF8, 0x03, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x83, 0xFF, 0xFF,
0xE1, 0xFC, 0x07, 0xF9, 0xFC, 0x01, 0xFC, 0xFE, 0x00, 0x7F, 0x7F, 0x00,
0x3F, 0xBF, 0x80, 0x1F, 0xDF, 0xC0, 0x0F, 0xEF, 0xE0, 0x0F, 0xFF, 0xF8,
0x0F, 0xFD, 0xFF, 0x9F, 0xFE, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x8F,
0xFF, 0xDF, 0xC1, 0xFF, 0xCF, 0xE0, 0x3F, 0x0F, 0xE0, 0x00, 0x07, 0xF0,
0x00, 0x03, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x10, 0x03, 0xFE,
0x0E, 0x07, 0xFE, 0x0F, 0xFF, 0xFE, 0x07, 0xFF, 0xFE, 0x07, 0xFF, 0xFE,
0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xF8, 0x00, 0x01, 0x80, 0x00, 0x1E, 0x3F,
0x9F, 0xFF, 0xFF, 0xFB, 0xFD, 0xFC, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x7F, 0x3F, 0xFF, 0xFF, 0xF7, 0xFB, 0xF8, 0xF8,
0x1E, 0x3F, 0x9F, 0xFF, 0xFF, 0xFB, 0xFD, 0xFC, 0x7C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x7F, 0x3F, 0xDF, 0xEF, 0xF7, 0xFB,
0xF8, 0xFC, 0x3E, 0x3E, 0x1F, 0x0F, 0x07, 0x87, 0xC3, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x07, 0x00, 0x01, 0xF0, 0x00, 0xFF, 0x00, 0x7F, 0xF0, 0x1F,
0xFF, 0x0F, 0xFF, 0xC7, 0xFF, 0xE0, 0xFF, 0xF8, 0x0F, 0xFC, 0x00, 0xFE,
0x00, 0x0F, 0xE0, 0x00, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x3F, 0xFF, 0x00,
0xFF, 0xFC, 0x01, 0xFF, 0xF0, 0x03, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x1F,
0x00, 0x00, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0E,
0x00, 0x00, 0xF8, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0xE0, 0x0F, 0xFF, 0x80,
0x3F, 0xFF, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF0, 0x03, 0xFF, 0x00, 0x07,
0xF0, 0x00, 0xFF, 0x00, 0x3F, 0xF0, 0x1F, 0xFF, 0x0F, 0xFF, 0xC7, 0xFF,
0xF0, 0xFF, 0xF8, 0x0F, 0xFC, 0x00, 0xFF, 0x00, 0x0F, 0x80, 0x00, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x07, 0xFF, 0x80, 0x3F, 0xFF,
0xC1, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xDF, 0xE0, 0xFF,
0x9F, 0x00, 0xFF, 0x0C, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0xFF, 0x00, 0x03, 0xFC, 0x00,
0x0F, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03,
0xF8, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x07, 0xFC,
0x00, 0x07, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF,
0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00,
0x1F, 0xF0, 0x00, 0xFF, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xC0, 0x1F, 0xC0,
0x00, 0x03, 0xF0, 0x1F, 0x80, 0x00, 0x00, 0xFC, 0x0F, 0x80, 0x00, 0x00,
0x3E, 0x0F, 0xC0, 0x7F, 0x9F, 0x8F, 0x8F, 0xC0, 0xFF, 0xEF, 0xC7, 0xC7,
0xC0, 0xFF, 0xFF, 0xE1, 0xF3, 0xE0, 0xFF, 0xFF, 0xF0, 0xFB, 0xE0, 0xFF,
0xFF, 0xF8, 0x3D, 0xF0, 0x7F, 0x03, 0xFC, 0x1E, 0xF8, 0x7F, 0x00, 0xFE,
0x0F, 0xFC, 0x3F, 0x00, 0x3F, 0x07, 0xFE, 0x1F, 0x80, 0x1F, 0x83, 0xFF,
0x0F, 0xC0, 0x0F, 0xC1, 0xFF, 0x87, 0xE0, 0x07, 0xE0, 0xFF, 0xC3, 0xF0,
0x03, 0xF0, 0x7F, 0xE1, 0xF8, 0x01, 0xF8, 0x3F, 0xF0, 0xFC, 0x00, 0xFC,
0x1E, 0xF8, 0x7F, 0x00, 0xFE, 0x0F, 0x7C, 0x1F, 0xC0, 0xFF, 0x8F, 0x9F,
0x0F, 0xFF, 0xFF, 0xEF, 0x8F, 0x83, 0xFF, 0xFF, 0xFF, 0xC7, 0xE0, 0xFF,
0xF9, 0xFF, 0xC1, 0xF0, 0x3F, 0xF8, 0xFF, 0xC0, 0xFC, 0x07, 0xF8, 0x1F,
0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x03,
0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x06, 0x00, 0x00, 0x3F, 0xF8,
0x7F, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0,
0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00,
0x03, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xE0, 0x00,
0x00, 0xFF, 0xF8, 0x00, 0x00, 0x7E, 0xFC, 0x00, 0x00, 0x7F, 0x7F, 0x00,
0x00, 0x3F, 0x1F, 0x80, 0x00, 0x3F, 0x8F, 0xE0, 0x00, 0x1F, 0x87, 0xF0,
0x00, 0x1F, 0xC1, 0xFC, 0x00, 0x0F, 0xE0, 0xFE, 0x00, 0x07, 0xE0, 0x3F,
0x00, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0xF0, 0x0F, 0xE0, 0x03, 0xF8, 0x03,
0xF8, 0x01, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF,
0xFF, 0xF8, 0x3F, 0x80, 0x00, 0xFE, 0x1F, 0xC0, 0x00, 0x7F, 0x1F, 0xC0,
0x00, 0x1F, 0xCF, 0xE0, 0x00, 0x0F, 0xEF, 0xE0, 0x00, 0x07, 0xFF, 0xF0,
0x00, 0x01, 0xFC, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF,
0xF8, 0x7F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF9, 0xF8, 0x01, 0xFF, 0x3F,
0x00, 0x0F, 0xF7, 0xE0, 0x01, 0xFE, 0xFC, 0x00, 0x1F, 0xDF, 0x80, 0x03,
0xF3, 0xF0, 0x00, 0xFE, 0x7E, 0x00, 0x3F, 0xCF, 0xFF, 0xFF, 0xF1, 0xFF,
0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF,
0x9F, 0x80, 0x0F, 0xFB, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xC0,
0x00, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0xFF,
0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0xFF, 0xCF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0x80,
0x00, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFC, 0x07,
0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0x3F, 0xF3, 0xFE, 0x00,
0x7C, 0x7F, 0xC0, 0x01, 0x87, 0xF8, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F,
0xF0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x0F, 0xE0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00,
0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x07, 0xF0,
0x00, 0x00, 0x7F, 0x80, 0x01, 0x03, 0xFC, 0x00, 0x3C, 0x3F, 0xF0, 0x07,
0xE1, 0xFF, 0xE7, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFE, 0x03,
0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x08,
0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0,
0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0x8F,
0xE0, 0x07, 0xFE, 0x3F, 0x80, 0x07, 0xFC, 0xFE, 0x00, 0x0F, 0xFB, 0xF8,
0x00, 0x1F, 0xEF, 0xE0, 0x00, 0x3F, 0xBF, 0x80, 0x00, 0xFE, 0xFE, 0x00,
0x01, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0x80, 0x00,
0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F,
0xBF, 0x80, 0x00, 0xFE, 0xFE, 0x00, 0x07, 0xFB, 0xF8, 0x00, 0x3F, 0xCF,
0xE0, 0x01, 0xFF, 0x3F, 0x80, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF,
0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF,
0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB,
0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xDF, 0x80, 0x00, 0x3F,
0x00, 0x00, 0x7E, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xF0,
0x00, 0x07, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x3F, 0xFF,
0xFC, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF1, 0xF8, 0x00, 0x03, 0xF0, 0x00,
0x07, 0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x80, 0x00, 0x3F, 0x00, 0x00,
0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00,
0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xCF,
0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xCF, 0xFF,
0xFF, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00,
0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F,
0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00,
0x01, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x7F,
0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFC, 0x7F, 0xF0, 0xFF, 0xC7, 0xFE, 0x00,
0xFC, 0x7F, 0xC0, 0x01, 0xC3, 0xFC, 0x00, 0x04, 0x1F, 0xC0, 0x00, 0x01,
0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8,
0x00, 0x00, 0x1F, 0xC0, 0x00, 0x7E, 0xFE, 0x00, 0x03, 0xF7, 0xF0, 0x00,
0x1F, 0xBF, 0x80, 0x00, 0xFD, 0xFC, 0x00, 0x07, 0xEF, 0xF0, 0x00, 0x3F,
0x3F, 0x80, 0x01, 0xF9, 0xFE, 0x00, 0x0F, 0xC7, 0xF8, 0x00, 0x7E, 0x3F,
0xF0, 0x03, 0xF0, 0xFF, 0xFB, 0xFF, 0x83, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF,
0xFF, 0xE0, 0x3F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8,
0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F,
0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0,
0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF,
0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00,
0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xC0, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xC0, 0x1F, 0xFF, 0xF8, 0xFF, 0xFF, 0xC7, 0xFF, 0xFE, 0x3F, 0xFF, 0xF1,
0xFF, 0xFF, 0x80, 0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x03,
0xF8, 0x00, 0x1F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80,
0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x1F,
0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xFC, 0x60,
0x0F, 0xE7, 0x80, 0xFF, 0x3F, 0x0F, 0xF3, 0xFF, 0xFF, 0x9F, 0xFF, 0xF8,
0x7F, 0xFF, 0x81, 0xFF, 0xF8, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x1F, 0xEF, 0xC0, 0x03, 0xFC, 0xFC, 0x00, 0x7F, 0x8F, 0xC0, 0x0F,
0xF0, 0xFC, 0x01, 0xFE, 0x0F, 0xC0, 0x3F, 0xC0, 0xFC, 0x03, 0xF8, 0x0F,
0xC0, 0x7F, 0x80, 0xFC, 0x0F, 0xF0, 0x0F, 0xC1, 0xFE, 0x00, 0xFC, 0x3F,
0xC0, 0x0F, 0xC7, 0xF8, 0x00, 0xFC, 0xFF, 0x00, 0x0F, 0xDF, 0xE0, 0x00,
0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF,
0xFC, 0x00, 0xFF, 0xDF, 0xE0, 0x0F, 0xF8, 0xFF, 0x00, 0xFF, 0x0F, 0xF8,
0x0F, 0xE0, 0x7F, 0xC0, 0xFC, 0x03, 0xFC, 0x0F, 0xC0, 0x1F, 0xE0, 0xFC,
0x00, 0xFF, 0x0F, 0xC0, 0x0F, 0xF8, 0xFC, 0x00, 0x7F, 0xCF, 0xC0, 0x03,
0xFC, 0xFC, 0x00, 0x1F, 0xEF, 0xC0, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00,
0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F,
0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0,
0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00,
0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F,
0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x00, 0x00, 0x1F, 0xBF,
0x00, 0x00, 0x07, 0xEF, 0xE0, 0x00, 0x03, 0xFB, 0xFC, 0x00, 0x00, 0xFE,
0xFF, 0x00, 0x00, 0x7F, 0xBF, 0xE0, 0x00, 0x3F, 0xEF, 0xF8, 0x00, 0x0F,
0xFB, 0xFF, 0x00, 0x07, 0xFE, 0xFF, 0xE0, 0x01, 0xFF, 0xBF, 0xF8, 0x00,
0xFF, 0xEF, 0xFF, 0x00, 0x7F, 0xFB, 0xFF, 0xC0, 0x1F, 0xFE, 0xFF, 0xF8,
0x0F, 0xFF, 0xBF, 0x7F, 0x03, 0xF7, 0xEF, 0xDF, 0xC1, 0xF9, 0xFB, 0xF3,
0xF8, 0xFE, 0x7E, 0xFC, 0x7E, 0x3F, 0x1F, 0xBF, 0x1F, 0xDF, 0xC7, 0xEF,
0xC3, 0xFF, 0xE1, 0xFB, 0xF0, 0xFF, 0xF0, 0x7E, 0xFC, 0x1F, 0xFC, 0x1F,
0xBF, 0x03, 0xFE, 0x07, 0xEF, 0xC0, 0xFF, 0x81, 0xFB, 0xF0, 0x1F, 0xC0,
0x7E, 0xFC, 0x03, 0xE0, 0x1F, 0xBF, 0x00, 0xF8, 0x07, 0xEF, 0xC0, 0x1C,
0x01, 0xFB, 0xF0, 0x00, 0x00, 0x7E, 0xFC, 0x00, 0x00, 0x1F, 0xBF, 0x00,
0x00, 0x07, 0xE0, 0xFC, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00,
0x3F, 0xFF, 0x80, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF,
0xF8, 0x03, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x01,
0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0x07, 0xFF, 0xDF, 0xF0, 0xFF, 0xF9,
0xFE, 0x1F, 0xFF, 0x1F, 0xE3, 0xFF, 0xE1, 0xFE, 0x7F, 0xFC, 0x3F, 0xEF,
0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xC0,
0x3F, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF,
0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x07, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00,
0x0F, 0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x01, 0x80,
0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF,
0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xF0,
0xFF, 0xE0, 0x7F, 0xC0, 0x0F, 0xF8, 0x7F, 0xC0, 0x03, 0xFE, 0x3F, 0xC0,
0x00, 0xFF, 0x1F, 0xC0, 0x00, 0x3F, 0xDF, 0xE0, 0x00, 0x0F, 0xEF, 0xE0,
0x00, 0x07, 0xF7, 0xF0, 0x00, 0x03, 0xFB, 0xF8, 0x00, 0x01, 0xFF, 0xFC,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x3F, 0xFF,
0x80, 0x00, 0x1F, 0xDF, 0xC0, 0x00, 0x0F, 0xEF, 0xF0, 0x00, 0x07, 0xF3,
0xF8, 0x00, 0x07, 0xF9, 0xFE, 0x00, 0x07, 0xF8, 0x7F, 0x80, 0x07, 0xFC,
0x3F, 0xF0, 0x07, 0xFC, 0x0F, 0xFF, 0x3F, 0xFC, 0x03, 0xFF, 0xFF, 0xFE,
0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFC,
0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80,
0x3F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF,
0xFF, 0x3F, 0xFF, 0xFF, 0xCF, 0xE0, 0x0F, 0xFB, 0xF8, 0x00, 0xFE, 0xFE,
0x00, 0x3F, 0xBF, 0x80, 0x0F, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00, 0x7F,
0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x0F, 0xEF, 0xE0, 0x07, 0xFB, 0xF8, 0x03,
0xFE, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE3, 0xFF,
0xFF, 0xE0, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0x80, 0x0F, 0xE0, 0x00, 0x03,
0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00,
0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00,
0x01, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xF8, 0x00,
0x0F, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFE,
0x01, 0xFF, 0xC3, 0xFF, 0x80, 0xFF, 0x80, 0x1F, 0xF0, 0x7F, 0xC0, 0x03,
0xFE, 0x1F, 0xE0, 0x00, 0x7F, 0x87, 0xF0, 0x00, 0x0F, 0xF3, 0xFC, 0x00,
0x01, 0xFC, 0xFE, 0x00, 0x00, 0x7F, 0x3F, 0x80, 0x00, 0x1F, 0xCF, 0xE0,
0x00, 0x07, 0xFB, 0xF8, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x3F, 0xBF,
0x80, 0x00, 0x1F, 0xEF, 0xE0, 0x00, 0x07, 0xF3, 0xF8, 0x00, 0x01, 0xFC,
0xFF, 0x00, 0x00, 0x7F, 0x1F, 0xC0, 0x00, 0x3F, 0xC7, 0xF8, 0x00, 0x1F,
0xE0, 0xFF, 0x00, 0x0F, 0xF8, 0x3F, 0xF0, 0x07, 0xFC, 0x07, 0xFF, 0x9F,
0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x00,
0x0F, 0xF8, 0x0C, 0x00, 0x01, 0xFF, 0x8F, 0x80, 0x00, 0x3F, 0xFF, 0xF0,
0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF,
0x00, 0x00, 0x00, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x0F,
0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
0xCF, 0xE0, 0x0F, 0xFB, 0xF8, 0x00, 0xFE, 0xFE, 0x00, 0x3F, 0xBF, 0x80,
0x0F, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xFE, 0x00, 0x3F, 0xFF,
0x80, 0x0F, 0xEF, 0xE0, 0x07, 0xFB, 0xF8, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF,
0xF0, 0x3F, 0xFF, 0xFC, 0x0F, 0xE0, 0x3F, 0x83, 0xF8, 0x0F, 0xF0, 0xFE,
0x01, 0xFC, 0x3F, 0x80, 0x3F, 0x8F, 0xE0, 0x0F, 0xF3, 0xF8, 0x01, 0xFE,
0xFE, 0x00, 0x3F, 0xBF, 0x80, 0x0F, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0xFF,
0xFC, 0x01, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE1, 0xFF,
0xFF, 0xF1, 0xFF, 0x01, 0xF8, 0xFE, 0x00, 0x18, 0x7F, 0x00, 0x00, 0x3F,
0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xFE, 0x00, 0x01,
0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE,
0x00, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x00, 0x7F, 0xF0, 0x00, 0x07,
0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x60, 0x00, 0x7F, 0x3C, 0x00,
0x3F, 0xBF, 0xC0, 0x7F, 0xDF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xC7, 0xFF,
0xFF, 0xC0, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x00, 0x18, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xF8, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8, 0x00, 0x00,
0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03,
0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00,
0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0,
0x00, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF,
0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F,
0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07,
0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0xFE, 0x7F,
0x00, 0x0F, 0xE7, 0xF0, 0x00, 0xFE, 0x7F, 0x80, 0x1F, 0xE3, 0xFC, 0x03,
0xFC, 0x3F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x00,
0x7F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x7F, 0x80, 0x00, 0x3F, 0x9F, 0xC0,
0x00, 0x3F, 0x8F, 0xF0, 0x00, 0x1F, 0xC3, 0xF8, 0x00, 0x0F, 0xE1, 0xFE,
0x00, 0x0F, 0xE0, 0xFF, 0x00, 0x07, 0xF0, 0x3F, 0x80, 0x07, 0xF0, 0x1F,
0xE0, 0x03, 0xF8, 0x07, 0xF0, 0x03, 0xF8, 0x03, 0xFC, 0x01, 0xFC, 0x00,
0xFE, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0xFE, 0x00, 0x3F, 0xC0, 0x7F, 0x00,
0x0F, 0xE0, 0x7F, 0x00, 0x07, 0xF8, 0x3F, 0x80, 0x01, 0xFC, 0x3F, 0x80,
0x00, 0xFF, 0x1F, 0xC0, 0x00, 0x3F, 0x8F, 0xC0, 0x00, 0x1F, 0xCF, 0xE0,
0x00, 0x0F, 0xF7, 0xF0, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xF8,
0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x0F, 0xFC,
0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x7F,
0xFF, 0x00, 0x07, 0xF0, 0x00, 0x7F, 0x7F, 0x00, 0x0F, 0xF0, 0x00, 0x7E,
0x7F, 0x00, 0x0F, 0xF8, 0x00, 0xFE, 0x7F, 0x80, 0x1F, 0xF8, 0x00, 0xFE,
0x3F, 0x80, 0x1F, 0xF8, 0x00, 0xFC, 0x3F, 0x80, 0x1F, 0xFC, 0x01, 0xFC,
0x3F, 0xC0, 0x3F, 0xFC, 0x01, 0xFC, 0x1F, 0xC0, 0x3F, 0xFC, 0x01, 0xF8,
0x1F, 0xC0, 0x3F, 0xFE, 0x03, 0xF8, 0x1F, 0xE0, 0x7F, 0xFE, 0x03, 0xF8,
0x0F, 0xE0, 0x7E, 0x7E, 0x03, 0xF0, 0x0F, 0xE0, 0x7E, 0x7F, 0x07, 0xF0,
0x0F, 0xF0, 0xFE, 0x7F, 0x07, 0xF0, 0x07, 0xF0, 0xFC, 0x3F, 0x07, 0xE0,
0x07, 0xF0, 0xFC, 0x3F, 0x8F, 0xE0, 0x07, 0xF1, 0xFC, 0x3F, 0x8F, 0xE0,
0x03, 0xF9, 0xF8, 0x1F, 0x8F, 0xC0, 0x03, 0xF9, 0xF8, 0x1F, 0xDF, 0xC0,
0x03, 0xFB, 0xF8, 0x1F, 0xDF, 0xC0, 0x01, 0xFF, 0xF0, 0x0F, 0xDF, 0x80,
0x01, 0xFF, 0xF0, 0x0F, 0xFF, 0x80, 0x01, 0xFF, 0xF0, 0x0F, 0xFF, 0x80,
0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00,
0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x03, 0xFE, 0x00,
0x00, 0x7F, 0xC0, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x03, 0xFE, 0x00,
0x00, 0x3F, 0x80, 0x01, 0xFC, 0x00, 0x7F, 0x80, 0x03, 0xF8, 0x7F, 0x80,
0x0F, 0xF0, 0x7F, 0x00, 0x3F, 0xC0, 0xFF, 0x00, 0x7F, 0x00, 0xFF, 0x01,
0xFE, 0x00, 0xFF, 0x07, 0xF8, 0x01, 0xFE, 0x0F, 0xE0, 0x01, 0xFE, 0x3F,
0x80, 0x01, 0xFE, 0xFF, 0x00, 0x01, 0xFD, 0xFC, 0x00, 0x03, 0xFF, 0xF0,
0x00, 0x03, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x07, 0xFE, 0x00,
0x00, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F, 0xF8, 0x00,
0x00, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xF0, 0x00,
0x1F, 0xEF, 0xF0, 0x00, 0x7F, 0x8F, 0xE0, 0x00, 0xFE, 0x1F, 0xE0, 0x03,
0xFC, 0x1F, 0xE0, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x3F, 0xC0, 0x7F,
0x80, 0x3F, 0xC1, 0xFE, 0x00, 0x3F, 0xC7, 0xF8, 0x00, 0x7F, 0xDF, 0xE0,
0x00, 0x7F, 0x80, 0x7F, 0x00, 0x01, 0xFC, 0xFF, 0x00, 0x03, 0xF8, 0xFE,
0x00, 0x0F, 0xE0, 0xFE, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x7F, 0x01, 0xFC,
0x01, 0xFC, 0x03, 0xFC, 0x03, 0xF8, 0x03, 0xF8, 0x0F, 0xE0, 0x03, 0xF8,
0x1F, 0xC0, 0x07, 0xF8, 0x7F, 0x00, 0x07, 0xF1, 0xFC, 0x00, 0x0F, 0xF3,
0xF8, 0x00, 0x0F, 0xEF, 0xE0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF,
0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x3F, 0xE0,
0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x01, 0xFC, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x07, 0xF0, 0x00,
0x00, 0x0F, 0xE0, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x3F, 0x80, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF,
0xFE, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xF0, 0x00,
0x07, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x7F, 0x80, 0x00, 0x3F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8,
0x00, 0x03, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x7F,
0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03,
0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0x07,
0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0,
0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC,
0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F,
0x83, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07,
0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00, 0x03, 0xF0, 0x00,
0x3F, 0x00, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0x0F, 0xC0,
0x00, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x3F,
0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01,
0xF8, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00,
0x07, 0xE0, 0x00, 0x3E, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x00, 0x01, 0xF8,
0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F,
0xC0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00,
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xC1, 0xF8, 0x3F,
0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07,
0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0,
0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC,
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFC, 0x00, 0x07,
0xE0, 0x00, 0x7F, 0x80, 0x03, 0xFC, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80,
0x1F, 0x7C, 0x00, 0xF9, 0xF0, 0x07, 0xCF, 0x80, 0x7C, 0x3E, 0x03, 0xE1,
0xF0, 0x3E, 0x07, 0xC1, 0xF0, 0x3E, 0x1F, 0x01, 0xF0, 0xF8, 0x07, 0xCF,
0xC0, 0x3E, 0x7C, 0x00, 0xFB, 0xE0, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0x07, 0xF0,
0x0F, 0xC0, 0x3F, 0x00, 0xF8, 0x0F, 0xFF, 0x00, 0xFF, 0xFF, 0x07, 0xFF,
0xFE, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF8, 0xF0, 0x1F, 0xE1, 0x00, 0x3F,
0x80, 0x00, 0x7E, 0x00, 0x01, 0xFC, 0x03, 0xFF, 0xF1, 0xFF, 0xFF, 0xCF,
0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xFF, 0x00,
0x7F, 0xFC, 0x03, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0xFF, 0xFC, 0xFF, 0xF7, 0xF0, 0xFF, 0x9F, 0xC0, 0xFE, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00,
0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x7F, 0x3F, 0xF0, 0x3F, 0xBF, 0xFC, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF,
0xFF, 0xE7, 0xFF, 0xFF, 0xF3, 0xFF, 0x07, 0xFD, 0xFF, 0x01, 0xFE, 0xFF,
0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x07, 0xFF,
0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x7F, 0xBF, 0xF8, 0x7F, 0xDF, 0xFF, 0xFF,
0xCF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xC3, 0xFB, 0xFF, 0xC1, 0xFC, 0xFF,
0x80, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x1F, 0xFF,
0xFC, 0x1F, 0xFF, 0xFE, 0x3F, 0xE1, 0xFE, 0x7F, 0x80, 0x7C, 0x7F, 0x00,
0x30, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00,
0x30, 0x7F, 0x80, 0x7C, 0x3F, 0xE1, 0xFF, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF,
0xFC, 0x07, 0xFF, 0xFC, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0xC0, 0x00, 0x00,
0x1F, 0xC0, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x1F, 0xC0, 0x7F, 0xE7, 0xF0, 0x7F, 0xFD, 0xFC, 0x3F, 0xFF,
0xFF, 0x1F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF3, 0xFE, 0x1F, 0xFD, 0xFE,
0x01, 0xFF, 0x7F, 0x00, 0x3F, 0xDF, 0xC0, 0x07, 0xF7, 0xE0, 0x01, 0xFF,
0xF8, 0x00, 0x7F, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x07, 0xF7, 0xF0, 0x01,
0xFD, 0xFC, 0x00, 0xFF, 0x7F, 0x00, 0x3F, 0xDF, 0xE0, 0x1F, 0xF3, 0xFE,
0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF0,
0x3F, 0xFD, 0xFC, 0x07, 0xFC, 0x7F, 0x00, 0xFF, 0xC0, 0x01, 0xFF, 0xF8,
0x03, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE1, 0xFE, 0x07,
0xF1, 0xFC, 0x01, 0xFC, 0xFE, 0x00, 0x7E, 0x7E, 0x00, 0x3F, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF0,
0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x80, 0x10, 0x1F,
0xF0, 0x3C, 0x07, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xC0,
0x1F, 0xFF, 0xC0, 0x03, 0xFF, 0x80, 0x00, 0x7F, 0x80, 0x7F, 0xF0, 0x3F,
0xF8, 0x1F, 0xFE, 0x07, 0xFF, 0x83, 0xFC, 0x00, 0xFE, 0x00, 0x3F, 0x80,
0x0F, 0xC0, 0x3F, 0xFF, 0xCF, 0xFF, 0xF3, 0xFF, 0xFC, 0xFF, 0xFF, 0x3F,
0xFF, 0xCF, 0xFF, 0xF0, 0x3F, 0x80, 0x0F, 0xE0, 0x03, 0xF8, 0x00, 0xFE,
0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80,
0x0F, 0xE0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x03,
0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x01, 0xFF, 0x8F, 0xC1, 0xFF, 0xF3,
0xF0, 0xFF, 0xFE, 0xFC, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xCF, 0xF8,
0x3F, 0xF7, 0xF8, 0x03, 0xFD, 0xFC, 0x00, 0xFF, 0x7F, 0x00, 0x1F, 0xFF,
0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xFE, 0x00, 0x1F,
0xDF, 0xC0, 0x07, 0xF7, 0xF8, 0x03, 0xFD, 0xFF, 0x01, 0xFF, 0x3F, 0xFF,
0xFF, 0xC7, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x03,
0xFF, 0x9F, 0xC0, 0x1F, 0x87, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x7E,
0x08, 0x00, 0x3F, 0x87, 0xC0, 0x1F, 0xE1, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,
0xFC, 0x3F, 0xFF, 0xFE, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0x00,
0xFC, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x7F, 0xE0, 0xFE, 0xFF, 0xF0, 0xFF,
0xFF, 0xF8, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xE7, 0xFE, 0xFF,
0x80, 0xFE, 0xFF, 0x00, 0xFF, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
0x00, 0x7F, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x18, 0x00, 0x00,
0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0x00, 0x78, 0x01, 0xF8, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0,
0x3F, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1F,
0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0,
0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC, 0x03,
0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE,
0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xCF, 0xFF, 0x9F,
0xFE, 0x3F, 0xF8, 0xFF, 0xF1, 0xFF, 0x80, 0x38, 0x00, 0xFE, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00,
0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x7F, 0x00, 0x7F, 0xBF, 0x80, 0x7F, 0x9F, 0xC0, 0x7F, 0x8F, 0xE0,
0x7F, 0x87, 0xF0, 0x7F, 0x83, 0xF8, 0x7F, 0x81, 0xFC, 0x7F, 0x80, 0xFE,
0x7F, 0x80, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0x80, 0x1F, 0xFF, 0xE0, 0x0F,
0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0x01, 0xFF, 0x7F, 0xC0,
0xFF, 0x1F, 0xF0, 0x7F, 0x07, 0xF8, 0x3F, 0x81, 0xFE, 0x1F, 0xC0, 0x7F,
0x8F, 0xE0, 0x1F, 0xE7, 0xF0, 0x0F, 0xF3, 0xF8, 0x03, 0xFD, 0xFC, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xC0, 0x7F, 0xC1, 0xFD, 0xFF,
0xE3, 0xFF, 0xE3, 0xFF, 0xFF, 0xEF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF,
0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0,
0x7F, 0xE0, 0x7F, 0xFF, 0x80, 0x7F, 0x80, 0x7F, 0xFE, 0x00, 0xFE, 0x00,
0xFF, 0xFC, 0x01, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xF8, 0x03, 0xFF, 0xF0,
0x07, 0xF0, 0x07, 0xFF, 0xE0, 0x0F, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xC0,
0x1F, 0xFF, 0x80, 0x3F, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0x00, 0x7F, 0xFE,
0x00, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xF8,
0x03, 0xFF, 0xF0, 0x07, 0xF0, 0x07, 0xFF, 0xE0, 0x0F, 0xE0, 0x0F, 0xFF,
0xC0, 0x1F, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0x80, 0x3F, 0x80, 0xFE, 0x7F,
0xE0, 0xFE, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
0xFE, 0xFF, 0xE7, 0xFE, 0xFF, 0x80, 0xFE, 0xFF, 0x00, 0xFF, 0xFE, 0x00,
0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00,
0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00,
0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00,
0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x00, 0xFF, 0xC0, 0x00, 0xFF,
0xFC, 0x00, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x0F,
0xF8, 0x7F, 0xC7, 0xF8, 0x07, 0xF9, 0xFC, 0x00, 0xFE, 0x7F, 0x00, 0x3F,
0xBF, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xFE, 0x00,
0x1F, 0xDF, 0x80, 0x07, 0xF7, 0xF0, 0x03, 0xF9, 0xFC, 0x00, 0xFE, 0x7F,
0x80, 0x7F, 0x8F, 0xF8, 0x7F, 0xC1, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8,
0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFC, 0x00, 0x0F, 0xFC, 0x00, 0xFE, 0x7F,
0xE0, 0x7F, 0x7F, 0xF8, 0x3F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xCF, 0xFF,
0xFF, 0xE7, 0xFE, 0x0F, 0xFB, 0xFE, 0x03, 0xFD, 0xFE, 0x00, 0xFF, 0xFE,
0x00, 0x3F, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x07, 0xFF,
0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0xFF,
0xFF, 0x80, 0xFF, 0x7F, 0xF0, 0xFF, 0xBF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
0xCF, 0xFF, 0xFF, 0xC7, 0xF7, 0xFF, 0x83, 0xF9, 0xFF, 0x01, 0xFC, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0,
0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x01,
0xFF, 0x9F, 0xC1, 0xFF, 0xF7, 0xF0, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0xCF, 0xF8, 0x7F, 0xF7, 0xF8, 0x07, 0xFD, 0xFC, 0x00,
0xFF, 0x7F, 0x00, 0x3F, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF8,
0x00, 0x7F, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x07, 0xF7, 0xF0, 0x03, 0xFD,
0xFC, 0x00, 0xFF, 0x7F, 0x80, 0x7F, 0xCF, 0xF8, 0x7F, 0xF3, 0xFF, 0xFF,
0xFC, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xF7, 0xF0, 0x1F,
0xF1, 0xFC, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x07, 0xF0,
0x00, 0x01, 0xFC, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x07,
0xF0, 0x00, 0x01, 0xFC, 0xFE, 0x3F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xC0, 0xFF, 0x03, 0xF8, 0x0F, 0xE0, 0x3F,
0x80, 0xFE, 0x03, 0xF8, 0x0F, 0xE0, 0x3F, 0x80, 0xFE, 0x03, 0xF8, 0x0F,
0xE0, 0x3F, 0x80, 0xFE, 0x03, 0xF8, 0x0F, 0xE0, 0x00, 0x07, 0xFF, 0xC0,
0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0xFF, 0xFF, 0xC7, 0xFF, 0xFE, 0x3F, 0x00,
0x63, 0xF8, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x80, 0x03, 0xFF, 0xE0, 0x1F,
0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0xFF, 0xFF, 0x00, 0xFF, 0xF8, 0x00, 0x3F,
0xE0, 0x00, 0x7F, 0x20, 0x03, 0xFB, 0xC0, 0x1F, 0xDF, 0xFF, 0xFD, 0xFF,
0xFF, 0xEF, 0xFF, 0xFE, 0x3F, 0xFF, 0xE0, 0x3F, 0xFC, 0x00, 0x0F, 0xE0,
0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x3F, 0xFF, 0xCF,
0xFF, 0xF3, 0xFF, 0xFC, 0xFF, 0xFF, 0x3F, 0xFF, 0xC0, 0xFE, 0x00, 0x3F,
0x80, 0x0F, 0xE0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x0F, 0xE0,
0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x03, 0xF8, 0x00,
0xFF, 0x00, 0x3F, 0xFE, 0x07, 0xFF, 0x81, 0xFF, 0xE0, 0x3F, 0xFC, 0x03,
0xFE, 0xFE, 0x00, 0x7F, 0xFC, 0x00, 0xFF, 0xF8, 0x01, 0xFF, 0xF0, 0x03,
0xFF, 0xE0, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x1F, 0xFF, 0x00, 0x3F,
0xFE, 0x00, 0x7F, 0xFC, 0x00, 0xFF, 0xF8, 0x01, 0xFF, 0xF0, 0x03, 0xFF,
0xE0, 0x07, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0xFF,
0x01, 0xFE, 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF3, 0xFF,
0xFF, 0xE3, 0xFF, 0xEF, 0xC1, 0xFF, 0x1F, 0x80, 0xFE, 0x00, 0x1F, 0xFF,
0x80, 0x07, 0xE7, 0xF0, 0x03, 0xF9, 0xFC, 0x00, 0xFE, 0x3F, 0x00, 0x3F,
0x0F, 0xE0, 0x1F, 0xC3, 0xF8, 0x07, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0,
0xFC, 0x03, 0xF0, 0x3F, 0x00, 0xFE, 0x1F, 0xC0, 0x1F, 0x87, 0xE0, 0x07,
0xF3, 0xF8, 0x01, 0xFC, 0xFC, 0x00, 0x3F, 0xFF, 0x00, 0x0F, 0xFF, 0x80,
0x01, 0xFF, 0xE0, 0x00, 0x7F, 0xF8, 0x00, 0x1F, 0xFC, 0x00, 0x03, 0xFF,
0x00, 0x00, 0xFF, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xF8, 0x00, 0xFE,
0x00, 0x7E, 0x00, 0x3F, 0x7E, 0x00, 0x7F, 0x00, 0x3F, 0x7E, 0x00, 0x7F,
0x00, 0x7E, 0x7F, 0x00, 0xFF, 0x00, 0x7E, 0x3F, 0x00, 0xFF, 0x80, 0x7E,
0x3F, 0x01, 0xFF, 0x80, 0xFC, 0x3F, 0x81, 0xFF, 0xC0, 0xFC, 0x1F, 0x81,
0xFF, 0xC0, 0xF8, 0x1F, 0x83, 0xFF, 0xC1, 0xF8, 0x0F, 0xC3, 0xF7, 0xE1,
0xF8, 0x0F, 0xC3, 0xF7, 0xE3, 0xF0, 0x0F, 0xC7, 0xE7, 0xE3, 0xF0, 0x07,
0xE7, 0xE3, 0xF3, 0xF0, 0x07, 0xE7, 0xC3, 0xF7, 0xE0, 0x07, 0xEF, 0xC3,
0xF7, 0xE0, 0x03, 0xFF, 0xC1, 0xFF, 0xE0, 0x03, 0xFF, 0x81, 0xFF, 0xC0,
0x03, 0xFF, 0x81, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x01, 0xFF,
0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x00, 0xFE, 0x00, 0x7F,
0x00, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x9F, 0xC0, 0x3F,
0x8F, 0xF0, 0x3F, 0x83, 0xFC, 0x3F, 0x80, 0xFE, 0x3F, 0xC0, 0x3F, 0x9F,
0xC0, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xC0, 0x01, 0xFF, 0xE0, 0x00, 0x7F,
0xE0, 0x00, 0x3F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF8, 0x00, 0x0F,
0xFE, 0x00, 0x07, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x07, 0xF7, 0xF8, 0x07,
0xF9, 0xFC, 0x03, 0xF8, 0x7F, 0x03, 0xF8, 0x3F, 0xC3, 0xF8, 0x0F, 0xF3,
0xFC, 0x03, 0xF9, 0xFC, 0x01, 0xFE, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x07,
0xE7, 0xF0, 0x03, 0xF9, 0xFC, 0x00, 0xFE, 0x3F, 0x80, 0x3F, 0x0F, 0xE0,
0x1F, 0xC3, 0xF8, 0x07, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFC, 0x03,
0xF8, 0x3F, 0x00, 0xFE, 0x1F, 0xC0, 0x1F, 0x87, 0xE0, 0x07, 0xF3, 0xF8,
0x01, 0xFC, 0xFC, 0x00, 0x3F, 0xBF, 0x00, 0x0F, 0xFF, 0x80, 0x01, 0xFF,
0xE0, 0x00, 0x7F, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x03, 0xFF, 0x00, 0x00,
0x7F, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFC, 0x00,
0x00, 0x7F, 0x00, 0x08, 0x3F, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF0,
0x00, 0xFF, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0xFF, 0xFF,
0xF7, 0xFF, 0xFF, 0x00, 0x07, 0xF0, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00,
0x7F, 0x80, 0x07, 0xF8, 0x00, 0x3F, 0x80, 0x03, 0xF8, 0x00, 0x3F, 0xC0,
0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x1F, 0xC0, 0x01, 0xFC,
0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE0, 0x00, 0xFC, 0x0F, 0xF0, 0x7F, 0xC3, 0xFF, 0x0F, 0xFC,
0x3F, 0xC0, 0xFE, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0,
0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x1F, 0xC0, 0xFF, 0x0F, 0xFC,
0x3F, 0xE0, 0xFF, 0x03, 0xFE, 0x0F, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x3F,
0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
0xC0, 0x3F, 0x80, 0xFE, 0x03, 0xFF, 0x0F, 0xFC, 0x1F, 0xF0, 0x3F, 0xC0,
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFC, 0x0F, 0xF8,
0x3F, 0xE0, 0xFF, 0xC1, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x3F,
0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
0xC0, 0x3F, 0xC0, 0xFF, 0xC1, 0xFF, 0x03, 0xFC, 0x3F, 0xF0, 0xFF, 0xC3,
0xF8, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x7F, 0x03, 0xFC, 0x3F, 0xF0, 0xFF, 0xC3,
0xFE, 0x0F, 0xF0, 0x3F, 0x80, 0x1F, 0xC0, 0x7C, 0xFF, 0x81, 0xF7, 0xFF,
0x87, 0x9F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFB, 0xE1, 0xFF, 0xCF, 0x81, 0xFE,
0x3C, 0x03, 0xF0 };
const GFXglyph Montserrat_Bold22pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 12, 0, 0 }, // 0x20 ' '
{ 1, 8, 30, 12, 2, -29 }, // 0x21 '!'
{ 31, 15, 12, 19, 2, -29 }, // 0x22 '"'
{ 54, 29, 30, 31, 1, -29 }, // 0x23 '#'
{ 163, 25, 40, 27, 1, -34 }, // 0x24 '$'
{ 288, 36, 30, 38, 1, -29 }, // 0x25 '%'
{ 423, 28, 31, 31, 2, -29 }, // 0x26 '&'
{ 532, 6, 12, 10, 2, -29 }, // 0x27 '''
{ 541, 12, 40, 15, 3, -31 }, // 0x28 '('
{ 601, 12, 40, 15, 0, -31 }, // 0x29 ')'
{ 661, 17, 17, 19, 1, -31 }, // 0x2A '*'
{ 698, 20, 20, 26, 3, -24 }, // 0x2B '+'
{ 748, 9, 15, 11, 1, -7 }, // 0x2C ','
{ 765, 12, 6, 17, 2, -14 }, // 0x2D '-'
{ 774, 9, 8, 11, 1, -7 }, // 0x2E '.'
{ 783, 20, 40, 17, -1, -35 }, // 0x2F '/'
{ 883, 25, 32, 29, 2, -30 }, // 0x30 '0'
{ 983, 13, 30, 17, 0, -29 }, // 0x31 '1'
{ 1032, 24, 31, 25, 0, -30 }, // 0x32 '2'
{ 1125, 24, 31, 25, 0, -29 }, // 0x33 '3'
{ 1218, 28, 30, 30, 1, -29 }, // 0x34 '4'
{ 1323, 24, 31, 26, 0, -29 }, // 0x35 '5'
{ 1416, 25, 32, 27, 2, -30 }, // 0x36 '6'
{ 1516, 24, 30, 27, 1, -29 }, // 0x37 '7'
{ 1606, 26, 32, 28, 1, -30 }, // 0x38 '8'
{ 1710, 25, 32, 27, 1, -30 }, // 0x39 '9'
{ 1810, 9, 23, 11, 1, -22 }, // 0x3A ':'
{ 1836, 9, 30, 11, 1, -22 }, // 0x3B ';'
{ 1870, 20, 22, 26, 3, -25 }, // 0x3C '<'
{ 1925, 20, 16, 26, 3, -22 }, // 0x3D '='
{ 1965, 20, 22, 26, 3, -25 }, // 0x3E '>'
{ 2020, 23, 31, 25, 0, -30 }, // 0x3F '?'
{ 2110, 41, 40, 45, 2, -30 }, // 0x40 '@'
{ 2315, 33, 30, 33, 0, -29 }, // 0x41 'A'
{ 2439, 27, 30, 33, 4, -29 }, // 0x42 'B'
{ 2541, 28, 32, 31, 2, -30 }, // 0x43 'C'
{ 2653, 30, 30, 36, 4, -29 }, // 0x44 'D'
{ 2766, 23, 30, 29, 4, -29 }, // 0x45 'E'
{ 2853, 22, 30, 27, 4, -29 }, // 0x46 'F'
{ 2936, 29, 32, 33, 2, -30 }, // 0x47 'G'
{ 3052, 27, 30, 35, 4, -29 }, // 0x48 'H'
{ 3154, 7, 30, 14, 4, -29 }, // 0x49 'I'
{ 3181, 21, 31, 23, -1, -29 }, // 0x4A 'J'
{ 3263, 28, 30, 32, 4, -29 }, // 0x4B 'K'
{ 3368, 22, 30, 26, 4, -29 }, // 0x4C 'L'
{ 3451, 34, 30, 41, 4, -29 }, // 0x4D 'M'
{ 3579, 27, 30, 35, 4, -29 }, // 0x4E 'N'
{ 3681, 33, 32, 36, 2, -30 }, // 0x4F 'O'
{ 3813, 26, 30, 31, 4, -29 }, // 0x50 'P'
{ 3911, 34, 38, 36, 2, -30 }, // 0x51 'Q'
{ 4073, 26, 30, 32, 4, -29 }, // 0x52 'R'
{ 4171, 25, 32, 27, 1, -30 }, // 0x53 'S'
{ 4271, 26, 30, 27, 0, -29 }, // 0x54 'T'
{ 4369, 28, 31, 34, 3, -29 }, // 0x55 'U'
{ 4478, 33, 30, 32, 0, -29 }, // 0x56 'V'
{ 4602, 48, 30, 50, 1, -29 }, // 0x57 'W'
{ 4782, 31, 30, 31, 0, -29 }, // 0x58 'X'
{ 4899, 31, 30, 29, -1, -29 }, // 0x59 'Y'
{ 5016, 26, 30, 29, 2, -29 }, // 0x5A 'Z'
{ 5114, 11, 40, 16, 4, -31 }, // 0x5B '['
{ 5169, 20, 40, 17, -2, -35 }, // 0x5C '\'
{ 5269, 11, 40, 16, 1, -31 }, // 0x5D ']'
{ 5324, 21, 18, 26, 2, -23 }, // 0x5E '^'
{ 5372, 22, 4, 22, 0, 1 }, // 0x5F '_'
{ 5383, 13, 6, 26, 4, -31 }, // 0x60 '`'
{ 5393, 22, 23, 27, 2, -22 }, // 0x61 'a'
{ 5457, 25, 32, 30, 3, -31 }, // 0x62 'b'
{ 5557, 24, 23, 25, 1, -22 }, // 0x63 'c'
{ 5626, 26, 32, 30, 1, -31 }, // 0x64 'd'
{ 5730, 25, 23, 27, 1, -22 }, // 0x65 'e'
{ 5802, 18, 32, 17, 0, -31 }, // 0x66 'f'
{ 5874, 26, 32, 30, 1, -22 }, // 0x67 'g'
{ 5978, 24, 32, 30, 3, -31 }, // 0x68 'h'
{ 6074, 8, 34, 13, 3, -33 }, // 0x69 'i'
{ 6108, 15, 43, 13, -4, -33 }, // 0x6A 'j'
{ 6189, 25, 32, 28, 3, -31 }, // 0x6B 'k'
{ 6289, 7, 32, 13, 3, -31 }, // 0x6C 'l'
{ 6317, 39, 23, 45, 3, -22 }, // 0x6D 'm'
{ 6430, 24, 23, 30, 3, -22 }, // 0x6E 'n'
{ 6499, 26, 23, 28, 1, -22 }, // 0x6F 'o'
{ 6574, 25, 31, 30, 3, -22 }, // 0x70 'p'
{ 6671, 26, 31, 30, 1, -22 }, // 0x71 'q'
{ 6772, 14, 23, 19, 3, -22 }, // 0x72 'r'
{ 6813, 21, 23, 23, 1, -22 }, // 0x73 's'
{ 6874, 18, 28, 19, 0, -27 }, // 0x74 't'
{ 6937, 23, 23, 30, 3, -22 }, // 0x75 'u'
{ 7004, 26, 23, 26, 0, -22 }, // 0x76 'v'
{ 7079, 40, 23, 40, 0, -22 }, // 0x77 'w'
{ 7194, 25, 23, 26, 0, -22 }, // 0x78 'x'
{ 7266, 26, 32, 26, 0, -22 }, // 0x79 'y'
{ 7370, 21, 23, 23, 1, -22 }, // 0x7A 'z'
{ 7431, 14, 40, 17, 2, -31 }, // 0x7B '{'
{ 7501, 6, 40, 13, 4, -31 }, // 0x7C '|'
{ 7531, 14, 40, 17, 1, -31 }, // 0x7D '}'
{ 7601, 22, 8, 26, 2, -18 } }; // 0x7E '~'
const GFXfont Montserrat_Bold22pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold22pt7bBitmaps,
(GFXglyph *)Montserrat_Bold22pt7bGlyphs,
0x20, 0x7E, 53 };
// Approx. 8295 bytes
#endif // MONTSERRATBOLD22PT7B_H
@@ -0,0 +1,873 @@
#ifndef MONTSERRATBOLD24PT7B_H
#define MONTSERRATBOLD24PT7B_H
const uint8_t Montserrat_Bold24pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0xBF,
0xDF, 0xCF, 0xE7, 0xF3, 0xF9, 0xFC, 0xFE, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3,
0xF1, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0xCF, 0xFF, 0xFF, 0xFD, 0xFE,
0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0xFF, 0x1F, 0xFF, 0x0F, 0xDF, 0x87, 0xEF,
0xC3, 0xF7, 0xE1, 0xF9, 0xF0, 0x7C, 0xF8, 0x3E, 0x7C, 0x1F, 0x3E, 0x0F,
0x9F, 0x07, 0xCF, 0x83, 0xE7, 0xC1, 0xF0, 0x00, 0x7C, 0x07, 0xE0, 0x00,
0x7C, 0x07, 0xE0, 0x00, 0x7C, 0x07, 0xC0, 0x00, 0x7C, 0x07, 0xC0, 0x00,
0x7C, 0x07, 0xC0, 0x00, 0x7C, 0x07, 0xC0, 0x00, 0xFC, 0x07, 0xC0, 0x00,
0xFC, 0x0F, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F,
0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x00,
0xF8, 0x0F, 0x80, 0x01, 0xF8, 0x0F, 0x80, 0x01, 0xF8, 0x1F, 0x80, 0x01,
0xF0, 0x1F, 0x80, 0x01, 0xF0, 0x1F, 0x80, 0x01, 0xF0, 0x1F, 0x00, 0x01,
0xF0, 0x1F, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF,
0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFC, 0x03,
0xE0, 0x3F, 0x00, 0x03, 0xE0, 0x3E, 0x00, 0x03, 0xE0, 0x3E, 0x00, 0x03,
0xE0, 0x3E, 0x00, 0x03, 0xE0, 0x3E, 0x00, 0x07, 0xE0, 0x3E, 0x00, 0x07,
0xE0, 0x7E, 0x00, 0x07, 0xE0, 0x7E, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00,
0xF8, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x0F, 0x80,
0x00, 0x00, 0xF8, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xF8, 0x0F,
0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF,
0xF8, 0x3F, 0xCF, 0x8F, 0x87, 0xF8, 0xF8, 0x30, 0x7F, 0x8F, 0x80, 0x07,
0xF8, 0xF8, 0x00, 0x7F, 0x8F, 0x80, 0x07, 0xFC, 0xF8, 0x00, 0x7F, 0xFF,
0x80, 0x03, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xC0,
0x0F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xC0, 0x00,
0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xF9, 0xFF, 0x00, 0x0F, 0x8F,
0xF0, 0x00, 0xF8, 0xFF, 0x10, 0x0F, 0x8F, 0xF3, 0x80, 0xF8, 0xFE, 0x3F,
0x0F, 0x9F, 0xE7, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF,
0xF8, 0x7F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xF8, 0x00,
0x00, 0xF8, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x0F,
0x80, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x07, 0xF0, 0x00,
0x0F, 0x80, 0x3F, 0xF8, 0x00, 0x3F, 0x00, 0xFF, 0xF8, 0x00, 0xFC, 0x01,
0xFF, 0xF0, 0x01, 0xF0, 0x07, 0xC1, 0xF0, 0x07, 0xE0, 0x0F, 0x83, 0xE0,
0x1F, 0x80, 0x3E, 0x03, 0xC0, 0x3E, 0x00, 0x7C, 0x07, 0xC0, 0xFC, 0x00,
0xF8, 0x0F, 0x83, 0xF0, 0x01, 0xF0, 0x1F, 0x07, 0xC0, 0x03, 0xE0, 0x3C,
0x1F, 0x80, 0x03, 0xC0, 0x78, 0x7E, 0x00, 0x07, 0xC1, 0xF0, 0xF8, 0x00,
0x0F, 0xC7, 0xE3, 0xE0, 0x00, 0x0F, 0xFF, 0x8F, 0xC0, 0x00, 0x0F, 0xFE,
0x1F, 0x03, 0xC0, 0x0F, 0xF8, 0x7C, 0x3F, 0xE0, 0x07, 0xC1, 0xF8, 0xFF,
0xE0, 0x00, 0x07, 0xE3, 0xFF, 0xE0, 0x00, 0x0F, 0x87, 0xC7, 0xE0, 0x00,
0x3F, 0x1F, 0x07, 0xC0, 0x00, 0xFC, 0x3E, 0x07, 0xC0, 0x01, 0xF0, 0x78,
0x0F, 0x80, 0x07, 0xE0, 0xF0, 0x1F, 0x00, 0x1F, 0x81, 0xE0, 0x3E, 0x00,
0x3E, 0x03, 0xC0, 0x7C, 0x00, 0xFC, 0x07, 0xC0, 0xF8, 0x03, 0xF0, 0x0F,
0x81, 0xF0, 0x07, 0xC0, 0x1F, 0x87, 0xC0, 0x1F, 0x80, 0x1F, 0xFF, 0x80,
0x7E, 0x00, 0x1F, 0xFE, 0x00, 0xF8, 0x00, 0x3F, 0xF8, 0x03, 0xF0, 0x00,
0x1F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x0F, 0xFF,
0xE0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xE0, 0x01, 0xFC, 0x1F,
0xC0, 0x03, 0xF0, 0x1F, 0x80, 0x07, 0xE0, 0x3F, 0x00, 0x0F, 0xC0, 0x7E,
0x00, 0x1F, 0xC1, 0xFC, 0x00, 0x3F, 0x87, 0xF0, 0x00, 0x7F, 0xBF, 0xE0,
0x00, 0x7F, 0xFF, 0x80, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x7F, 0xF8, 0x00,
0x01, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xC0, 0xC0, 0x3F, 0xFF, 0xC1, 0xF0,
0xFF, 0xFF, 0xC3, 0xF3, 0xFC, 0x7F, 0xC7, 0xE7, 0xF0, 0x7F, 0xDF, 0xDF,
0xC0, 0x7F, 0xFF, 0x3F, 0x80, 0x7F, 0xFE, 0x7F, 0x00, 0x7F, 0xF8, 0xFE,
0x00, 0x7F, 0xF1, 0xFC, 0x00, 0x7F, 0xE3, 0xFC, 0x00, 0xFF, 0xE7, 0xFE,
0x0F, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF,
0xFF, 0x3F, 0x07, 0xFF, 0xFC, 0x3C, 0x03, 0xFF, 0xE0, 0x30, 0x00, 0x30,
0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xEF, 0xDF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3,
0xE7, 0xC0, 0x03, 0xF8, 0x3F, 0xC1, 0xFC, 0x1F, 0xE0, 0xFE, 0x0F, 0xF0,
0x7F, 0x03, 0xF8, 0x3F, 0xC1, 0xFC, 0x0F, 0xE0, 0x7F, 0x07, 0xF8, 0x3F,
0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC1, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07,
0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xF0, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F,
0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x81, 0xFC, 0x0F, 0xE0, 0x3F, 0x81, 0xFC,
0x07, 0xF0, 0x7F, 0x03, 0xF8, 0x0F, 0xE0, 0x7F, 0x01, 0xFC, 0x0F, 0xE0,
0x7F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03,
0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F,
0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0,
0x3F, 0x81, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x1F,
0xE0, 0xFE, 0x07, 0xF0, 0x7F, 0x03, 0xF8, 0x3F, 0xC1, 0xFC, 0x1F, 0xC0,
0xFE, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x30, 0xF0, 0xC7,
0x9E, 0x3D, 0xFB, 0xDF, 0xBF, 0xFF, 0xFB, 0xFF, 0xFC, 0x1F, 0xFE, 0x00,
0xFF, 0x80, 0x7F, 0xFC, 0x3F, 0xFF, 0xEF, 0xFF, 0xFF, 0xFB, 0xDF, 0x9C,
0x78, 0xE1, 0x0F, 0x04, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00,
0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00,
0xFC, 0x00, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x03,
0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x1C, 0x3F,
0x3F, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0x1F, 0x0F, 0x8F, 0xC7,
0xC3, 0xE1, 0xE1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF0, 0x18, 0x3F, 0x3F, 0xDF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFE,
0x7E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xC0, 0x00,
0x7E, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xFC,
0x00, 0x07, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00,
0x0F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F,
0x80, 0x00, 0xFE, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7E, 0x00,
0x01, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x07,
0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xC0,
0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x80, 0x00,
0xFE, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xF8,
0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x07, 0xF0, 0x00,
0x1F, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x1F, 0xFF,
0x80, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x01,
0xFF, 0xFF, 0xF8, 0x3F, 0xF0, 0xFF, 0xC3, 0xFC, 0x03, 0xFC, 0x7F, 0x80,
0x1F, 0xE7, 0xF8, 0x01, 0xFE, 0xFF, 0x00, 0x0F, 0xEF, 0xF0, 0x00, 0xFF,
0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0,
0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F,
0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF,
0x00, 0x0F, 0xE7, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xE3, 0xFC, 0x03,
0xFC, 0x3F, 0xE0, 0x7F, 0xC1, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x80,
0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF,
0xE0, 0x00, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC,
0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01,
0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F,
0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0,
0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x01, 0xFF, 0xE0, 0x01, 0xFF,
0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0x3F,
0xFF, 0xFF, 0xE7, 0xF8, 0x1F, 0xF8, 0x78, 0x01, 0xFE, 0x0C, 0x00, 0x7F,
0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFE, 0x00, 0x00,
0x7F, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xFE, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x7F, 0xC0,
0x00, 0x3F, 0xE0, 0x00, 0x3F, 0xF0, 0x00, 0x1F, 0xF8, 0x00, 0x0F, 0xFC,
0x00, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x00, 0xFF,
0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFC,
0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0x8F, 0xFF,
0xFF, 0xE3, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0x8F,
0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC,
0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F,
0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xFF, 0x80, 0x01, 0xFF, 0xF0, 0x00,
0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0x03, 0xFF,
0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x3F, 0xCE, 0x00, 0x1F, 0xF3, 0xF0, 0x0F, 0xF9, 0xFF,
0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xE0,
0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xE0, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x3F,
0xC0, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x07, 0xF8,
0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x03, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xE0, 0x00,
0x00, 0x7F, 0x80, 0x00, 0x01, 0xFE, 0x0F, 0xF0, 0x07, 0xFC, 0x1F, 0xE0,
0x0F, 0xF0, 0x3F, 0xC0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x80, 0xFF, 0x01,
0xFE, 0x01, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00,
0x03, 0xFC, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00,
0x1F, 0xE0, 0x00, 0x00, 0x3F, 0xC0, 0x07, 0xFF, 0xFF, 0x81, 0xFF, 0xFF,
0xF0, 0x3F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF8, 0x1F,
0xFF, 0xFF, 0x03, 0xF8, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xE0, 0x00,
0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFF,
0xE0, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF8,
0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x00, 0x00,
0x3F, 0xE0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x07, 0xF8,
0x00, 0x00, 0xFF, 0x10, 0x00, 0x1F, 0xE3, 0x80, 0x07, 0xF8, 0xFC, 0x01,
0xFF, 0x1F, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x1F,
0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x00, 0x01, 0x80,
0x00, 0x00, 0x3F, 0xFE, 0x00, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFE, 0x03,
0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x07, 0xFE, 0x01,
0x81, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFE,
0x00, 0x00, 0x7F, 0x80, 0x00, 0x0F, 0xF0, 0x3C, 0x01, 0xFE, 0x7F, 0xF0,
0x3F, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF,
0xFF, 0xFB, 0xFF, 0xC1, 0xFF, 0x7F, 0xE0, 0x1F, 0xFF, 0xF8, 0x01, 0xFF,
0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x03, 0xFB, 0xF8, 0x00, 0x7F, 0x7F, 0x80,
0x1F, 0xEF, 0xF0, 0x03, 0xFC, 0xFF, 0x00, 0xFF, 0x1F, 0xF8, 0x7F, 0xE1,
0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF,
0xE0, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x80, 0x0F, 0xF7, 0xF0, 0x03, 0xFE, 0xFE,
0x00, 0x7F, 0x9F, 0xC0, 0x1F, 0xF3, 0xF8, 0x03, 0xFC, 0x7F, 0x00, 0x7F,
0x80, 0x00, 0x1F, 0xE0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x1F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xE0,
0x00, 0x07, 0xF8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x07,
0xF8, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF8, 0x00,
0x01, 0xFE, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFE,
0x00, 0x00, 0x7F, 0x80, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00,
0x01, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF8, 0x0F, 0xFF,
0xFF, 0x83, 0xFF, 0xFF, 0xF8, 0xFF, 0xC1, 0xFF, 0x9F, 0xF0, 0x0F, 0xF3,
0xFC, 0x01, 0xFE, 0x7F, 0x00, 0x1F, 0xCF, 0xE0, 0x03, 0xF9, 0xFE, 0x00,
0xFF, 0x3F, 0xC0, 0x1F, 0xE3, 0xFC, 0x07, 0xF8, 0x7F, 0xFF, 0xFF, 0x07,
0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF,
0xF1, 0xFF, 0xFF, 0xFF, 0x3F, 0xC0, 0x1F, 0xEF, 0xF0, 0x01, 0xFF, 0xFE,
0x00, 0x3F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x1F,
0xFF, 0xE0, 0x03, 0xFF, 0xFE, 0x00, 0xFF, 0xBF, 0xF0, 0x7F, 0xE7, 0xFF,
0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xF0,
0x01, 0xFF, 0xF0, 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0xFF,
0xFE, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xF0,
0xFF, 0xC3, 0xFF, 0x1F, 0xE0, 0x1F, 0xE7, 0xF8, 0x01, 0xFE, 0xFF, 0x00,
0x3F, 0xDF, 0xC0, 0x03, 0xFB, 0xF8, 0x00, 0x7F, 0xFF, 0x80, 0x1F, 0xFF,
0xF0, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0xDF, 0xF0, 0x3F, 0xFB, 0xFF, 0xFF,
0xFF, 0x3F, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x81,
0xFF, 0xCF, 0xF0, 0x07, 0xC1, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F,
0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x1F, 0xF0, 0x20,
0x0F, 0xFC, 0x0F, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8,
0x0F, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x0C,
0x00, 0x00, 0x18, 0x3F, 0x3F, 0xDF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFE, 0x7E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1F, 0x9F,
0xEF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x3F, 0x00, 0x18, 0x3F, 0x3F, 0xDF,
0xFF, 0xFF, 0xFF, 0xFD, 0xFE, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x1F, 0x9F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x1F, 0x8F, 0x87, 0xC7, 0xE3, 0xE1, 0xF0, 0xF0, 0xF8, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0xC0, 0x01, 0xFF, 0x00, 0x3F, 0xFC,
0x03, 0xFF, 0xF0, 0x7F, 0xFF, 0x87, 0xFF, 0xF0, 0xFF, 0xFE, 0x03, 0xFF,
0xC0, 0x0F, 0xFC, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0x80, 0x03, 0xFF, 0xC0,
0x0F, 0xFF, 0xE0, 0x0F, 0xFF, 0xF0, 0x07, 0xFF, 0xF0, 0x07, 0xFF, 0xF0,
0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xF0, 0x00,
0x00, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFC, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0xE0, 0x00,
0xFF, 0xF0, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xF8, 0x03, 0xFF, 0xFC, 0x01,
0xFF, 0xFC, 0x00, 0xFF, 0xF0, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0x00, 0x07,
0xFC, 0x00, 0xFF, 0xF0, 0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x3F, 0xFF, 0x83,
0xFF, 0xF8, 0x0F, 0xFF, 0x00, 0x3F, 0xE0, 0x00, 0xFE, 0x00, 0x03, 0xC0,
0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x07,
0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFD,
0xFE, 0x03, 0xFE, 0x3C, 0x00, 0xFF, 0x0C, 0x00, 0x7F, 0x80, 0x00, 0x1F,
0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF8, 0x00, 0x0F, 0xF8, 0x00, 0x0F, 0xF8, 0x00, 0x0F,
0xF0, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xFE, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x1F, 0x80,
0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00,
0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
0x1F, 0xFC, 0x01, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x1F,
0xE0, 0x00, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0x00, 0x07, 0xF0, 0x0F, 0xC0,
0x00, 0x00, 0x1F, 0x80, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0x0F, 0xC0, 0x3F,
0xE3, 0xF1, 0xF0, 0x7E, 0x03, 0xFF, 0xDF, 0x87, 0xC7, 0xE0, 0x7F, 0xFF,
0xFC, 0x3E, 0x3F, 0x07, 0xFF, 0xFF, 0xE0, 0xF9, 0xF0, 0x3F, 0xFF, 0xFF,
0x07, 0xDF, 0x83, 0xFE, 0x0F, 0xF8, 0x3E, 0xFC, 0x1F, 0xC0, 0x3F, 0xC0,
0xFF, 0xC1, 0xFC, 0x00, 0xFE, 0x07, 0xFE, 0x0F, 0xE0, 0x03, 0xF0, 0x3F,
0xF0, 0x7F, 0x00, 0x1F, 0x81, 0xFF, 0x83, 0xF0, 0x00, 0xFC, 0x0F, 0xFC,
0x1F, 0x80, 0x07, 0xE0, 0x7F, 0xE0, 0xFC, 0x00, 0x3F, 0x03, 0xFF, 0x07,
0xF0, 0x01, 0xF8, 0x1F, 0xF8, 0x3F, 0x80, 0x1F, 0xC0, 0xF7, 0xE1, 0xFC,
0x00, 0xFE, 0x0F, 0xBF, 0x07, 0xF0, 0x0F, 0xF0, 0x7C, 0xF8, 0x3F, 0xE1,
0xFF, 0xC7, 0xE7, 0xE0, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0x07, 0xFF, 0xFF,
0xFF, 0xE0, 0xFC, 0x1F, 0xFF, 0xDF, 0xFF, 0x07, 0xE0, 0x3F, 0xFC, 0x7F,
0xF0, 0x1F, 0x80, 0xFF, 0x81, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x3F, 0xC0, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xC0, 0x07, 0x80, 0x00, 0x03,
0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F,
0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03,
0xE0, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00,
0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x0F, 0xFF,
0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x01,
0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x03, 0xF9, 0xFC, 0x00,
0x00, 0x3F, 0x9F, 0xC0, 0x00, 0x07, 0xF0, 0xFE, 0x00, 0x00, 0x7F, 0x0F,
0xE0, 0x00, 0x0F, 0xE0, 0xFF, 0x00, 0x00, 0xFE, 0x07, 0xF0, 0x00, 0x1F,
0xE0, 0x7F, 0x80, 0x01, 0xFC, 0x03, 0xF8, 0x00, 0x3F, 0xC0, 0x3F, 0xC0,
0x03, 0xF8, 0x03, 0xFC, 0x00, 0x3F, 0x80, 0x1F, 0xC0, 0x07, 0xFF, 0xFF,
0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xF8,
0x3F, 0xC0, 0x00, 0x3F, 0xC3, 0xFC, 0x00, 0x03, 0xFC, 0x3F, 0x80, 0x00,
0x1F, 0xC7, 0xF8, 0x00, 0x01, 0xFE, 0x7F, 0x00, 0x00, 0x1F, 0xEF, 0xF0,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0xFF, 0xF8, 0x03,
0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0xFF,
0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xCF, 0xE0, 0x01, 0xFF, 0x3F, 0x80,
0x03, 0xFC, 0xFE, 0x00, 0x07, 0xF3, 0xF8, 0x00, 0x1F, 0xCF, 0xE0, 0x00,
0x7F, 0x3F, 0x80, 0x03, 0xFC, 0xFE, 0x00, 0x1F, 0xF3, 0xF8, 0x03, 0xFF,
0x8F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xC3,
0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0x3F, 0x80, 0x07, 0xFE, 0xFE,
0x00, 0x07, 0xFB, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80,
0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF,
0xCF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFC, 0x00,
0x00, 0x1F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xC0,
0x1F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xC7,
0xFF, 0x81, 0xFF, 0x1F, 0xF8, 0x00, 0x7C, 0x3F, 0xE0, 0x00, 0x70, 0xFF,
0x80, 0x00, 0x41, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x7F, 0x80,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00,
0x00, 0x07, 0xF8, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xF0, 0x00,
0x00, 0x1F, 0xE0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x10, 0x3F, 0xE0, 0x00,
0x70, 0x7F, 0xE0, 0x01, 0xF0, 0x7F, 0xF0, 0x0F, 0xF0, 0x7F, 0xFF, 0xFF,
0xF0, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFC,
0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00, 0xA0, 0x00,
0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xE0,
0x1F, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF,
0xC3, 0xFC, 0x03, 0xFF, 0xF1, 0xFE, 0x00, 0x1F, 0xF8, 0xFF, 0x00, 0x03,
0xFE, 0x7F, 0x80, 0x00, 0xFF, 0xBF, 0xC0, 0x00, 0x3F, 0xDF, 0xE0, 0x00,
0x1F, 0xEF, 0xF0, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFC, 0x00,
0x01, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x80,
0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xF0,
0x00, 0x07, 0xFF, 0xF8, 0x00, 0x07, 0xFB, 0xFC, 0x00, 0x03, 0xFD, 0xFE,
0x00, 0x03, 0xFE, 0xFF, 0x00, 0x03, 0xFE, 0x7F, 0x80, 0x07, 0xFF, 0x3F,
0xC0, 0x1F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x07,
0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFC, 0x00,
0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xFF, 0xFF,
0xF3, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF,
0xFF, 0x3F, 0xFF, 0xFF, 0x9F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0,
0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFE,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F,
0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x01,
0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
0x9F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xE7, 0xF8, 0x00, 0x03, 0xFC, 0x00,
0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0xC0,
0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xFC,
0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF,
0xFC, 0x07, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFE, 0x1F, 0xFE, 0x03,
0xFC, 0x3F, 0xF0, 0x00, 0xF8, 0x3F, 0xE0, 0x00, 0x70, 0x7F, 0xC0, 0x00,
0x00, 0x7F, 0x80, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00,
0xFE, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x80, 0x00,
0xFE, 0x7F, 0x80, 0x00, 0xFE, 0x7F, 0xC0, 0x00, 0xFE, 0x3F, 0xE0, 0x00,
0xFE, 0x3F, 0xF0, 0x00, 0xFE, 0x1F, 0xFC, 0x03, 0xFE, 0x0F, 0xFF, 0xFF,
0xFE, 0x07, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF,
0xF8, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x70,
0x00, 0xFF, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x3F,
0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF,
0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFC,
0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00,
0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF,
0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFC,
0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00,
0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xC0, 0x00,
0xFF, 0xFF, 0x00, 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF8, 0x7F,
0xFF, 0xF0, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0x80, 0x00,
0xFF, 0x00, 0x01, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x0F,
0xF0, 0x00, 0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0xFF,
0x00, 0x01, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x0F, 0xF0,
0x00, 0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0xFF, 0x08,
0x01, 0xFE, 0x38, 0x07, 0xF8, 0xFC, 0x1F, 0xF3, 0xFF, 0xFF, 0xEF, 0xFF,
0xFF, 0x8F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFC, 0x0F, 0xFF, 0xF0, 0x07, 0xFF,
0x80, 0x00, 0x70, 0x00, 0xFE, 0x00, 0x03, 0xFD, 0xFC, 0x00, 0x0F, 0xF3,
0xF8, 0x00, 0x3F, 0xC7, 0xF0, 0x00, 0xFF, 0x0F, 0xE0, 0x03, 0xFC, 0x1F,
0xC0, 0x0F, 0xF0, 0x3F, 0x80, 0x3F, 0xE0, 0x7F, 0x00, 0xFF, 0x80, 0xFE,
0x03, 0xFE, 0x01, 0xFC, 0x0F, 0xF8, 0x03, 0xF8, 0x3F, 0xE0, 0x07, 0xF0,
0xFF, 0x80, 0x0F, 0xE3, 0xFE, 0x00, 0x1F, 0xCF, 0xF8, 0x00, 0x3F, 0xBF,
0xE0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF,
0xC0, 0x03, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF,
0x80, 0x1F, 0xFC, 0xFF, 0x80, 0x3F, 0xF0, 0xFF, 0x80, 0x7F, 0xC0, 0xFF,
0x80, 0xFF, 0x01, 0xFF, 0x81, 0xFC, 0x01, 0xFF, 0x03, 0xF8, 0x01, 0xFF,
0x07, 0xF0, 0x01, 0xFF, 0x0F, 0xE0, 0x01, 0xFF, 0x1F, 0xC0, 0x01, 0xFF,
0x3F, 0x80, 0x03, 0xFE, 0x7F, 0x00, 0x03, 0xFE, 0xFE, 0x00, 0x03, 0xFE,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x1F,
0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00,
0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF,
0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x03,
0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF,
0xC0, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFB, 0xF8, 0x0F, 0xEF,
0xFF, 0xDF, 0xC0, 0xFE, 0x7F, 0xFE, 0x7F, 0x07, 0xF3, 0xFF, 0xF3, 0xFC,
0x7F, 0x1F, 0xFF, 0x8F, 0xE3, 0xF8, 0xFF, 0xFC, 0x3F, 0xBF, 0x87, 0xFF,
0xE1, 0xFF, 0xF8, 0x3F, 0xFF, 0x07, 0xFF, 0xC1, 0xFF, 0xF8, 0x3F, 0xFC,
0x0F, 0xFF, 0xC0, 0xFF, 0xE0, 0x7F, 0xFE, 0x03, 0xFE, 0x03, 0xFF, 0xF0,
0x1F, 0xF0, 0x1F, 0xFF, 0x80, 0x7F, 0x00, 0xFF, 0xFC, 0x03, 0xF0, 0x07,
0xFF, 0xE0, 0x0F, 0x80, 0x3F, 0xFF, 0x00, 0x38, 0x01, 0xFF, 0xF8, 0x00,
0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x03, 0xF8,
0xFE, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF,
0xE0, 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFE,
0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xF0,
0x07, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x01,
0xFF, 0xFB, 0xFE, 0x07, 0xFF, 0xE7, 0xFC, 0x1F, 0xFF, 0x9F, 0xF8, 0x7F,
0xFE, 0x3F, 0xF1, 0xFF, 0xF8, 0x7F, 0xC7, 0xFF, 0xE0, 0xFF, 0x9F, 0xFF,
0x81, 0xFF, 0x7F, 0xFE, 0x03, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xE0,
0x1F, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF8, 0x00,
0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFE, 0x00, 0x0F,
0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x7F,
0xFE, 0x00, 0x01, 0xFC, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFE,
0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFE, 0x07, 0xFF, 0x83,
0xFF, 0x00, 0x1F, 0xF8, 0x3F, 0xE0, 0x00, 0x7F, 0xC7, 0xFC, 0x00, 0x03,
0xFC, 0x7F, 0x80, 0x00, 0x3F, 0xE7, 0xF8, 0x00, 0x01, 0xFE, 0xFF, 0x00,
0x00, 0x1F, 0xEF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF,
0xF0, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0x00,
0x00, 0x1F, 0xE7, 0xF8, 0x00, 0x01, 0xFE, 0x7F, 0x80, 0x00, 0x3F, 0xE7,
0xFC, 0x00, 0x03, 0xFC, 0x3F, 0xE0, 0x00, 0x7F, 0xC3, 0xFF, 0x00, 0x1F,
0xF8, 0x1F, 0xFC, 0x07, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFF,
0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xF8, 0x00,
0x07, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x07, 0x00,
0x00, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0x0F,
0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFE, 0xFF, 0x01,
0xFF, 0xEF, 0xF0, 0x01, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF,
0xFF, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x07, 0xFF, 0xF0,
0x00, 0x7F, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x1F,
0xFF, 0xF0, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFC, 0xFF,
0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFE,
0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F,
0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x07,
0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF,
0x80, 0x7F, 0xF8, 0x1F, 0xFE, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x3F, 0xE0,
0x00, 0x7F, 0xC3, 0xFE, 0x00, 0x01, 0xFE, 0x1F, 0xE0, 0x00, 0x0F, 0xF8,
0xFF, 0x00, 0x00, 0x3F, 0xCF, 0xF0, 0x00, 0x01, 0xFE, 0x7F, 0x80, 0x00,
0x07, 0xFB, 0xFC, 0x00, 0x00, 0x3F, 0xDF, 0xE0, 0x00, 0x01, 0xFE, 0xFF,
0x00, 0x00, 0x0F, 0xF7, 0xF8, 0x00, 0x00, 0x7F, 0xBF, 0xC0, 0x00, 0x03,
0xFD, 0xFE, 0x00, 0x00, 0x1F, 0xEF, 0xF0, 0x00, 0x01, 0xFE, 0x3F, 0xC0,
0x00, 0x0F, 0xF1, 0xFE, 0x00, 0x00, 0xFF, 0x8F, 0xF8, 0x00, 0x07, 0xF8,
0x3F, 0xE0, 0x00, 0x7F, 0xC1, 0xFF, 0x80, 0x0F, 0xFC, 0x07, 0xFF, 0x01,
0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x01,
0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC,
0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFC, 0x03, 0x00, 0x00,
0x3F, 0xF8, 0x7C, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF,
0x80, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00,
0x3F, 0xF8, 0x00, 0x00, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF,
0xFC, 0x7F, 0xFF, 0xFF, 0xF3, 0xFC, 0x07, 0xFF, 0x9F, 0xE0, 0x03, 0xFE,
0xFF, 0x00, 0x0F, 0xF7, 0xF8, 0x00, 0x7F, 0xBF, 0xC0, 0x01, 0xFD, 0xFE,
0x00, 0x0F, 0xEF, 0xF0, 0x00, 0x7F, 0x7F, 0x80, 0x03, 0xFB, 0xFC, 0x00,
0x3F, 0xDF, 0xE0, 0x01, 0xFE, 0xFF, 0x00, 0x1F, 0xF7, 0xF8, 0x07, 0xFF,
0x3F, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8, 0x7F,
0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x80, 0xFF, 0x01,
0xFE, 0x07, 0xF8, 0x07, 0xF8, 0x3F, 0xC0, 0x3F, 0xE1, 0xFE, 0x00, 0xFF,
0x0F, 0xF0, 0x03, 0xFC, 0x7F, 0x80, 0x1F, 0xF3, 0xFC, 0x00, 0x7F, 0x9F,
0xE0, 0x01, 0xFE, 0xFF, 0x00, 0x0F, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x3F,
0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF,
0x83, 0xFF, 0xFF, 0xF8, 0x3F, 0xC0, 0x0F, 0x87, 0xF8, 0x00, 0x30, 0x7F,
0x80, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x07, 0xFC, 0x00,
0x00, 0x7F, 0xF0, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xE0, 0x01,
0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0xFF,
0xFF, 0xC0, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x01, 0xFF,
0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x10, 0x00, 0x0F, 0xF3, 0x80,
0x00, 0xFE, 0x3F, 0x00, 0x1F, 0xE7, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF,
0xCF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xE0, 0x03,
0xFF, 0xF8, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00,
0x1F, 0xC0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x3F,
0x80, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x07, 0xF0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x0F,
0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x3F, 0x80, 0x00,
0x01, 0xFC, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03,
0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0xFE, 0x00, 0x03, 0xFF, 0xF0, 0x00,
0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x3F,
0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x7F, 0xFE,
0x00, 0x03, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xFC, 0x00,
0x07, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x0F,
0xFF, 0xC0, 0x00, 0x7F, 0xFE, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x1F, 0xFF,
0x80, 0x00, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80,
0x03, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0x80, 0x0F,
0xFB, 0xFE, 0x00, 0xFF, 0x9F, 0xF8, 0x0F, 0xFC, 0x7F, 0xFF, 0xFF, 0xC3,
0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFE, 0x00, 0x7F,
0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x50, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x0F, 0xEF, 0xF0, 0x00, 0x01, 0xFE, 0x7F, 0x80, 0x00, 0x1F, 0xE7,
0xF8, 0x00, 0x03, 0xFC, 0x7F, 0xC0, 0x00, 0x3F, 0xC3, 0xFC, 0x00, 0x03,
0xF8, 0x3F, 0xE0, 0x00, 0x7F, 0x81, 0xFE, 0x00, 0x07, 0xF0, 0x1F, 0xE0,
0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0F, 0xE0, 0x0F, 0xF0, 0x01, 0xFE, 0x00,
0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xF8, 0x01, 0xFC, 0x00, 0x7F, 0xC0, 0x3F,
0xC0, 0x03, 0xFC, 0x03, 0xF8, 0x00, 0x3F, 0xC0, 0x7F, 0x80, 0x01, 0xFE,
0x07, 0xF0, 0x00, 0x1F, 0xE0, 0xFF, 0x00, 0x00, 0xFF, 0x0F, 0xF0, 0x00,
0x0F, 0xF0, 0xFE, 0x00, 0x00, 0xFF, 0x1F, 0xE0, 0x00, 0x07, 0xF9, 0xFC,
0x00, 0x00, 0x7F, 0xBF, 0xC0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x3F,
0xFF, 0x80, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00,
0x01, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xE0,
0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x03,
0xFC, 0x00, 0x00, 0xFF, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xF7, 0xF8, 0x00,
0x0F, 0xF0, 0x00, 0x3F, 0x9F, 0xE0, 0x00, 0xFF, 0x80, 0x01, 0xFC, 0xFF,
0x00, 0x07, 0xFC, 0x00, 0x1F, 0xE7, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0xFE,
0x1F, 0xE0, 0x03, 0xFF, 0x80, 0x07, 0xF0, 0xFF, 0x00, 0x1F, 0xFC, 0x00,
0x7F, 0x87, 0xF8, 0x00, 0xFF, 0xF0, 0x03, 0xF8, 0x1F, 0xE0, 0x0F, 0xFF,
0x80, 0x1F, 0xC0, 0xFF, 0x00, 0x7F, 0xFC, 0x01, 0xFE, 0x07, 0xF8, 0x03,
0xFF, 0xF0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F, 0xBF, 0x80, 0x7F, 0x00, 0xFF,
0x01, 0xFD, 0xFC, 0x07, 0xF8, 0x07, 0xF8, 0x0F, 0xEF, 0xE0, 0x3F, 0x80,
0x1F, 0xE0, 0xFE, 0x3F, 0x81, 0xFC, 0x00, 0xFF, 0x07, 0xF1, 0xFC, 0x1F,
0xE0, 0x07, 0xF8, 0x3F, 0x8F, 0xE0, 0xFE, 0x00, 0x1F, 0xE3, 0xF8, 0x3F,
0x87, 0xF0, 0x00, 0xFF, 0x1F, 0xC1, 0xFC, 0x7F, 0x80, 0x07, 0xF8, 0xFE,
0x0F, 0xE3, 0xF8, 0x00, 0x1F, 0xCF, 0xE0, 0x3F, 0x9F, 0xC0, 0x00, 0xFF,
0x7F, 0x01, 0xFD, 0xFE, 0x00, 0x07, 0xFB, 0xF8, 0x0F, 0xEF, 0xE0, 0x00,
0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8,
0x00, 0x07, 0xFF, 0xE0, 0x0F, 0xFF, 0x80, 0x00, 0x1F, 0xFE, 0x00, 0x3F,
0xFC, 0x00, 0x00, 0xFF, 0xF0, 0x01, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0x00,
0x0F, 0xFE, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0xFF,
0xC0, 0x01, 0xFF, 0x80, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x00,
0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x1F, 0xE0,
0x00, 0xFF, 0x8F, 0xF8, 0x00, 0x7F, 0x83, 0xFE, 0x00, 0x7F, 0x80, 0xFF,
0x80, 0x7F, 0x80, 0x3F, 0xC0, 0x3F, 0xC0, 0x1F, 0xF0, 0x3F, 0xC0, 0x07,
0xFC, 0x3F, 0xC0, 0x01, 0xFE, 0x3F, 0xE0, 0x00, 0xFF, 0x9F, 0xE0, 0x00,
0x3F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xF0, 0x00,
0x01, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x1F, 0xF8, 0x00,
0x00, 0x0F, 0xFC, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0x80,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFC,
0x00, 0x03, 0xFD, 0xFF, 0x00, 0x03, 0xFC, 0x7F, 0xC0, 0x03, 0xFE, 0x1F,
0xE0, 0x01, 0xFE, 0x0F, 0xF8, 0x01, 0xFE, 0x03, 0xFE, 0x01, 0xFF, 0x00,
0xFF, 0x01, 0xFF, 0x00, 0x7F, 0xC0, 0xFF, 0x00, 0x1F, 0xF0, 0xFF, 0x80,
0x07, 0xFC, 0xFF, 0x80, 0x01, 0xFE, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x7F,
0x80, 0x00, 0x3F, 0xBF, 0xC0, 0x00, 0x3F, 0xCF, 0xF0, 0x00, 0x1F, 0xC7,
0xF8, 0x00, 0x1F, 0xC1, 0xFE, 0x00, 0x1F, 0xE0, 0x7F, 0x80, 0x0F, 0xE0,
0x3F, 0xC0, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0, 0x07, 0xF8, 0x07, 0xF0,
0x01, 0xFE, 0x07, 0xF8, 0x00, 0x7F, 0x83, 0xF8, 0x00, 0x3F, 0xC3, 0xFC,
0x00, 0x0F, 0xF1, 0xFC, 0x00, 0x07, 0xF9, 0xFC, 0x00, 0x01, 0xFF, 0xFE,
0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x0F, 0xFF,
0x00, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x7F,
0x80, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x0F,
0xF0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x01,
0xFE, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00,
0x3F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00,
0x07, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xBF,
0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
0xFF, 0xF0, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF,
0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x07, 0xFC, 0x00,
0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07,
0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x3F, 0xE0,
0x00, 0x03, 0xFE, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00,
0x3F, 0xE0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x01, 0xFF,
0x00, 0x00, 0x1F, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC, 0x0F,
0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81, 0xFC,
0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F, 0x81,
0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x07, 0xF0, 0x3F,
0x81, 0xFC, 0x0F, 0xE0, 0x7F, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xF0, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xE0, 0x00,
0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x0F,
0xE0, 0x00, 0x1F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0,
0x00, 0x0F, 0xE0, 0x00, 0x1F, 0x80, 0x00, 0x7E, 0x00, 0x01, 0xFC, 0x00,
0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7E, 0x00, 0x01,
0xFC, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0xFE,
0x00, 0x01, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x00,
0x00, 0xFE, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
0x3F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1F,
0x80, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0,
0x00, 0x1F, 0x80, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07,
0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07,
0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07,
0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07,
0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x0F,
0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x7F, 0xF0, 0x01, 0xFB, 0xE0, 0x03, 0xE7,
0xC0, 0x0F, 0xCF, 0xC0, 0x1F, 0x0F, 0x80, 0x7E, 0x1F, 0x80, 0xFC, 0x1F,
0x01, 0xF0, 0x3F, 0x07, 0xE0, 0x7E, 0x0F, 0x80, 0x7C, 0x3F, 0x00, 0xFC,
0x7E, 0x00, 0xF9, 0xF8, 0x01, 0xFB, 0xF0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xFF,
0x00, 0xFE, 0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0, 0x00, 0x7C, 0x00, 0x07,
0xFF, 0xC0, 0x3F, 0xFF, 0xF0, 0x7F, 0xFF, 0xF8, 0x7F, 0xFF, 0xFC, 0x3F,
0xFF, 0xFC, 0x3F, 0x07, 0xFE, 0x18, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x3F,
0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x00, 0xFF, 0xFE,
0x00, 0xFF, 0xFE, 0x00, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0x03, 0xFF, 0xFF,
0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0x7F, 0x1F, 0xFE, 0x7F, 0x0F,
0xFC, 0x7F, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x38,
0x00, 0xFF, 0x3F, 0xF8, 0x0F, 0xF7, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x0F,
0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x9F, 0xFC, 0xFF, 0xC0,
0x3F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x0F, 0xEF, 0xF0, 0x00, 0xFF,
0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0,
0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x80, 0x1F,
0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0xE0, 0x7F, 0xEF, 0xFF, 0xFF, 0xFC, 0xFF,
0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8, 0xFE, 0xFF, 0xFF, 0x0F, 0xE7, 0xFF,
0xC0, 0xFE, 0x1F, 0xF0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x3F, 0xFE, 0x00,
0x3F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x87, 0xFF, 0xFF,
0xE3, 0xFF, 0x8F, 0xFC, 0xFF, 0x80, 0xFE, 0x7F, 0xC0, 0x1E, 0x1F, 0xE0,
0x02, 0x07, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F,
0xC0, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x7F, 0x80, 0x00,
0x1F, 0xE0, 0x02, 0x07, 0xFC, 0x01, 0xE0, 0xFF, 0x80, 0xFE, 0x1F, 0xFF,
0xFF, 0xC7, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x01,
0xFF, 0xFC, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x1F, 0xC0, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F,
0xE0, 0x03, 0x81, 0xFC, 0x07, 0xFE, 0x3F, 0x83, 0xFF, 0xF7, 0xF0, 0xFF,
0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFB, 0xFF, 0x8F, 0xFF,
0x7F, 0xC0, 0x7F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00,
0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF,
0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00,
0x7F, 0xFF, 0xC0, 0x1F, 0xF7, 0xFC, 0x07, 0xFE, 0xFF, 0xFF, 0xFF, 0xCF,
0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFD,
0xFC, 0x07, 0xFE, 0x3F, 0x80, 0x00, 0x06, 0x00, 0x00, 0x1F, 0xFE, 0x00,
0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF,
0xFF, 0x0F, 0xF8, 0x1F, 0xE1, 0xFE, 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xCF,
0xE0, 0x01, 0xFD, 0xFC, 0x00, 0x3F, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFB, 0xF8, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFF, 0x00, 0x10, 0x1F, 0xF0, 0x0F,
0x01, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xE0, 0x3F,
0xFF, 0xF8, 0x01, 0xFF, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x3F, 0xE0,
0x0F, 0xFF, 0x01, 0xFF, 0xE0, 0x3F, 0xFE, 0x07, 0xFF, 0xC0, 0x7F, 0xFC,
0x07, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0xFF, 0xFF,
0xCF, 0xFF, 0xFC, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, 0xFF, 0xCF, 0xFF,
0xFC, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00,
0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00,
0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0xFE, 0x3F, 0x03, 0xFF, 0xF3, 0xF0,
0xFF, 0xFF, 0xBF, 0x1F, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x3F, 0xF8,
0xFF, 0xF7, 0xFE, 0x01, 0xFF, 0x7F, 0x80, 0x0F, 0xF7, 0xF8, 0x00, 0xFF,
0x7F, 0x00, 0x07, 0xF7, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x07, 0xF7, 0xF0,
0x00, 0x7F, 0x7F, 0x00, 0x07, 0xF7, 0xF8, 0x00, 0x7F, 0x7F, 0x80, 0x0F,
0xF7, 0xFC, 0x01, 0xFF, 0x3F, 0xF8, 0x7F, 0xF1, 0xFF, 0xFF, 0xFF, 0x1F,
0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xF7, 0xF0, 0x1F, 0xFE,
0x7F, 0x00, 0x1F, 0x07, 0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xF0,
0xC0, 0x00, 0xFF, 0x0F, 0x00, 0x1F, 0xE1, 0xFF, 0x1F, 0xFE, 0x1F, 0xFF,
0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xE0,
0x01, 0xFF, 0xF8, 0x00, 0x00, 0x60, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0,
0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F,
0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x3F, 0xC0, 0xE0, 0x0F, 0xF3, 0xFF, 0x83, 0xFD, 0xFF, 0xF8, 0xFF, 0xFF,
0xFF, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFE, 0xFF,
0xE0, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xF8, 0x03, 0xFF, 0xFC, 0x00, 0x7F,
0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00,
0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC,
0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x01, 0xFF,
0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x01,
0xFC, 0x3C, 0x7F, 0xBF, 0xDF, 0xFF, 0xFF, 0xFB, 0xFC, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x0F, 0xF7, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0xBF, 0xDF, 0xEF,
0xF7, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
0xFE, 0xFF, 0x7F, 0xBF, 0xDF, 0xEF, 0xF0, 0x00, 0x78, 0x01, 0xFE, 0x01,
0xFE, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFE, 0x01, 0xFE, 0x00, 0xFC, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0xFE, 0x01, 0xFE, 0x63, 0xFE, 0x7F, 0xFC, 0x7F, 0xFC, 0xFF, 0xF8, 0xFF,
0xF0, 0xFF, 0xC0, 0x04, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x3F, 0xEF, 0xF0, 0x07, 0xF8, 0xFF,
0x01, 0xFF, 0x0F, 0xF0, 0x3F, 0xE0, 0xFF, 0x07, 0xFC, 0x0F, 0xF0, 0xFF,
0xC0, 0xFF, 0x1F, 0xF8, 0x0F, 0xF3, 0xFF, 0x00, 0xFF, 0x7F, 0xE0, 0x0F,
0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF,
0xC0, 0x0F, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFE, 0xFF, 0x80,
0xFF, 0xCF, 0xF8, 0x0F, 0xF8, 0x7F, 0xC0, 0xFF, 0x03, 0xFE, 0x0F, 0xF0,
0x1F, 0xF0, 0xFF, 0x00, 0xFF, 0x8F, 0xF0, 0x0F, 0xF8, 0xFF, 0x00, 0x7F,
0xCF, 0xF0, 0x03, 0xFE, 0xFF, 0x00, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0x00, 0x00, 0xC0,
0x1F, 0xC7, 0xFE, 0x03, 0xFF, 0x83, 0xF9, 0xFF, 0xF0, 0xFF, 0xFC, 0x7F,
0x7F, 0xFF, 0x3F, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFE, 0x07, 0xFF,
0x81, 0xFF, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xFF, 0xE0, 0x07, 0xF8, 0x03,
0xFF, 0xFC, 0x00, 0xFF, 0x00, 0x3F, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF,
0xF0, 0x03, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0x7F, 0x00, 0x1F, 0xFF, 0xC0,
0x0F, 0xE0, 0x03, 0xFF, 0xF8, 0x01, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x3F,
0x80, 0x0F, 0xFF, 0xE0, 0x07, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0xFE, 0x00,
0x3F, 0xFF, 0x80, 0x1F, 0xC0, 0x07, 0xFF, 0xF0, 0x03, 0xF8, 0x00, 0xFF,
0xFE, 0x00, 0x7F, 0x00, 0x1F, 0xFF, 0xC0, 0x0F, 0xE0, 0x03, 0xFF, 0xF8,
0x01, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0x80, 0x0F, 0xFF, 0xE0, 0x07,
0xF0, 0x01, 0xFC, 0x00, 0x03, 0x80, 0x3F, 0x8F, 0xFE, 0x0F, 0xE7, 0xFF,
0xE3, 0xFB, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xEF, 0xFF,
0xFF, 0xFB, 0xFF, 0x81, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xE0, 0x0F, 0xFF,
0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07,
0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0,
0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF,
0xC0, 0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F,
0xFF, 0xC0, 0x07, 0xF0, 0x00, 0x07, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x03,
0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x81, 0xFF, 0xFF,
0xFC, 0x3F, 0xF8, 0xFF, 0xC3, 0xFE, 0x03, 0xFE, 0x7F, 0xC0, 0x1F, 0xE7,
0xF8, 0x00, 0xFF, 0x7F, 0x00, 0x0F, 0xF7, 0xF0, 0x00, 0x7F, 0xFF, 0x00,
0x07, 0xFF, 0xF0, 0x00, 0x7F, 0x7F, 0x00, 0x07, 0xF7, 0xF0, 0x00, 0x7F,
0x7F, 0x80, 0x0F, 0xF7, 0xF8, 0x00, 0xFF, 0x3F, 0xC0, 0x1F, 0xE3, 0xFE,
0x03, 0xFE, 0x1F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF,
0x80, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0x00, 0x00,
0x03, 0x80, 0x0F, 0xE3, 0xFF, 0x80, 0xFE, 0x7F, 0xFE, 0x0F, 0xFF, 0xFF,
0xF0, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFC, 0xFF, 0xF9, 0xFF, 0xCF,
0xFC, 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x00, 0xFE, 0xFF, 0x00,
0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF,
0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8,
0x01, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xFE, 0x07, 0xFE, 0xFF, 0xFF, 0xFF,
0xCF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF0, 0xFF,
0x7F, 0xFC, 0x0F, 0xF1, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F,
0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xFC, 0x7F, 0x03, 0xFF, 0xF7,
0xF0, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x3F,
0xF8, 0xFF, 0xF3, 0xFE, 0x03, 0xFF, 0x7F, 0xC0, 0x1F, 0xF7, 0xF8, 0x00,
0xFF, 0x7F, 0x00, 0x0F, 0xF7, 0xF0, 0x00, 0x7F, 0xFF, 0x00, 0x07, 0xFF,
0xF0, 0x00, 0x7F, 0x7F, 0x00, 0x07, 0xF7, 0xF0, 0x00, 0x7F, 0x7F, 0x80,
0x0F, 0xF7, 0xF8, 0x00, 0xFF, 0x7F, 0xC0, 0x1F, 0xF3, 0xFE, 0x03, 0xFF,
0x3F, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F,
0xFF, 0xFF, 0x03, 0xFF, 0xE7, 0xF0, 0x0F, 0xFC, 0x7F, 0x00, 0x00, 0x07,
0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x07, 0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFE, 0x3F, 0xFE, 0x7F, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xC0, 0xFF,
0x80, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x3E, 0x00,
0x07, 0xFF, 0xE0, 0x3F, 0xFF, 0xF0, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x8F,
0xFF, 0xFF, 0x1F, 0xE0, 0x1C, 0x3F, 0x80, 0x08, 0x7F, 0x00, 0x00, 0xFE,
0x00, 0x01, 0xFF, 0x80, 0x03, 0xFF, 0xFC, 0x03, 0xFF, 0xFE, 0x03, 0xFF,
0xFF, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0xFE, 0x00, 0x07, 0xFE, 0x00, 0x03,
0xFC, 0x80, 0x03, 0xF9, 0xC0, 0x07, 0xF7, 0xF0, 0x3F, 0xCF, 0xFF, 0xFF,
0xBF, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0x00,
0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0,
0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF, 0xFF, 0xCF, 0xFF,
0xFC, 0xFF, 0xFF, 0xC0, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00,
0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00,
0x0F, 0xF0, 0x00, 0x7F, 0xDC, 0x07, 0xFF, 0xC0, 0x7F, 0xFE, 0x03, 0xFF,
0xE0, 0x1F, 0xFF, 0x00, 0x7F, 0xC0, 0xFF, 0x00, 0x1F, 0xFF, 0xC0, 0x07,
0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xC0,
0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF,
0xC0, 0x07, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x1F,
0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00,
0x7F, 0xDF, 0xE0, 0x1F, 0xF7, 0xFC, 0x1F, 0xFD, 0xFF, 0xFF, 0xFF, 0x3F,
0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFC, 0x3F, 0xFE, 0x7F,
0x03, 0xFE, 0x1F, 0xC0, 0xFF, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x7F, 0x7F,
0x00, 0x0F, 0xE7, 0xF8, 0x00, 0xFE, 0x3F, 0x80, 0x1F, 0xC3, 0xFC, 0x01,
0xFC, 0x3F, 0xC0, 0x1F, 0xC1, 0xFC, 0x03, 0xF8, 0x1F, 0xE0, 0x3F, 0x80,
0xFE, 0x07, 0xF0, 0x0F, 0xF0, 0x7F, 0x00, 0x7F, 0x0F, 0xF0, 0x07, 0xF0,
0xFE, 0x00, 0x7F, 0x8F, 0xE0, 0x03, 0xF9, 0xFC, 0x00, 0x3F, 0xDF, 0xC0,
0x01, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xF8, 0x00, 0x0F,
0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x7F, 0xE0,
0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0xFE, 0x00, 0x1F, 0xC0,
0x07, 0xF7, 0xF0, 0x03, 0xFC, 0x00, 0x7E, 0x7F, 0x00, 0x3F, 0xC0, 0x0F,
0xE7, 0xF0, 0x03, 0xFE, 0x00, 0xFE, 0x3F, 0x80, 0x7F, 0xE0, 0x0F, 0xC3,
0xF8, 0x07, 0xFE, 0x01, 0xFC, 0x3F, 0x80, 0x7F, 0xF0, 0x1F, 0xC1, 0xFC,
0x0F, 0xFF, 0x01, 0xF8, 0x1F, 0xC0, 0xFF, 0xF0, 0x3F, 0x80, 0xFC, 0x0F,
0xFF, 0x83, 0xF0, 0x0F, 0xE1, 0xFD, 0xF8, 0x3F, 0x00, 0xFE, 0x1F, 0x9F,
0x87, 0xF0, 0x07, 0xE3, 0xF9, 0xFC, 0x7E, 0x00, 0x7F, 0x3F, 0x8F, 0xC7,
0xE0, 0x07, 0xF3, 0xF0, 0xFE, 0xFE, 0x00, 0x3F, 0x7F, 0x0F, 0xEF, 0xC0,
0x03, 0xFF, 0xE0, 0x7F, 0xFC, 0x00, 0x3F, 0xFE, 0x07, 0xFF, 0xC0, 0x01,
0xFF, 0xE0, 0x7F, 0xF8, 0x00, 0x1F, 0xFC, 0x03, 0xFF, 0x80, 0x00, 0xFF,
0xC0, 0x3F, 0xF0, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x80,
0x1F, 0xF0, 0x00, 0x07, 0xF8, 0x01, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x0F,
0xE0, 0x00, 0x7F, 0x80, 0x1F, 0xE3, 0xFC, 0x03, 0xFC, 0x1F, 0xE0, 0x3F,
0x81, 0xFF, 0x07, 0xF8, 0x0F, 0xF0, 0xFF, 0x00, 0x7F, 0x9F, 0xE0, 0x03,
0xFD, 0xFC, 0x00, 0x3F, 0xFF, 0x80, 0x01, 0xFF, 0xF8, 0x00, 0x0F, 0xFF,
0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00,
0x07, 0xFE, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x80, 0x01, 0xFF,
0xF8, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xF9, 0xFE, 0x00, 0xFF, 0x0F, 0xF0,
0x0F, 0xF0, 0xFF, 0x01, 0xFE, 0x07, 0xF8, 0x3F, 0xC0, 0x3F, 0xC7, 0xF8,
0x03, 0xFE, 0x7F, 0x80, 0x1F, 0xE0, 0xFF, 0x00, 0x07, 0xFF, 0xF0, 0x00,
0x7F, 0x7F, 0x00, 0x0F, 0xE7, 0xF8, 0x00, 0xFE, 0x3F, 0x80, 0x1F, 0xC3,
0xFC, 0x01, 0xFC, 0x1F, 0xC0, 0x1F, 0xC1, 0xFC, 0x03, 0xF8, 0x1F, 0xE0,
0x3F, 0x80, 0xFE, 0x07, 0xF0, 0x0F, 0xF0, 0x7F, 0x00, 0x7F, 0x07, 0xE0,
0x07, 0xF0, 0xFE, 0x00, 0x3F, 0x8F, 0xE0, 0x03, 0xF9, 0xFC, 0x00, 0x3F,
0xDF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xF8,
0x00, 0x0F, 0xFF, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x07, 0xFE, 0x00, 0x00,
0x7F, 0xE0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x03, 0xFC,
0x00, 0x00, 0x3F, 0x80, 0x02, 0x07, 0xF8, 0x00, 0x7D, 0xFF, 0x00, 0x07,
0xFF, 0xF0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0xFF, 0xF8,
0x00, 0x03, 0xFE, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
0x3F, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F, 0xC0, 0x01, 0xFE,
0x00, 0x0F, 0xF0, 0x00, 0x7F, 0xC0, 0x03, 0xFE, 0x00, 0x0F, 0xF0, 0x00,
0x7F, 0x80, 0x03, 0xFC, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xFC,
0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0x01, 0xFF, 0x03, 0xFF,
0x07, 0xFF, 0x07, 0xFF, 0x0F, 0xFF, 0x0F, 0xF8, 0x0F, 0xF0, 0x0F, 0xE0,
0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0,
0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0,
0xFF, 0xC0, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0, 0x1F, 0xE0, 0x0F, 0xE0,
0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0,
0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xFF,
0x07, 0xFF, 0x07, 0xFF, 0x03, 0xFF, 0x01, 0xFF, 0x00, 0x7F, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xFC, 0x01, 0xFE, 0x03, 0xFE, 0x07, 0xFE, 0x0F, 0xFE, 0x1F, 0xFC,
0x07, 0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00,
0xFE, 0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F,
0xC0, 0x7F, 0xF0, 0x7F, 0xE0, 0x7F, 0xC0, 0xFF, 0x83, 0xFF, 0x0F, 0xFE,
0x1F, 0xE0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC, 0x03, 0xF8, 0x07,
0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x03, 0xFC,
0x3F, 0xF8, 0x7F, 0xF0, 0xFF, 0xC1, 0xFF, 0x83, 0xFC, 0x07, 0xF0, 0x00,
0x0F, 0xC0, 0x1F, 0x1F, 0xF0, 0x1F, 0x3F, 0xF8, 0x1F, 0x7F, 0xFE, 0x3E,
0x7F, 0xFF, 0xFE, 0x7C, 0x7F, 0xFE, 0x78, 0x1F, 0xFC, 0xF8, 0x0F, 0xF8,
0xF8, 0x03, 0xF0 };
const GFXglyph Montserrat_Bold24pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 13, 0, 0 }, // 0x20 ' '
{ 1, 9, 33, 14, 2, -32 }, // 0x21 '!'
{ 39, 17, 13, 21, 2, -32 }, // 0x22 '"'
{ 67, 32, 33, 34, 1, -32 }, // 0x23 '#'
{ 199, 28, 45, 30, 1, -38 }, // 0x24 '$'
{ 357, 39, 33, 41, 1, -32 }, // 0x25 '%'
{ 518, 31, 34, 34, 2, -32 }, // 0x26 '&'
{ 650, 7, 13, 11, 2, -32 }, // 0x27 '''
{ 662, 13, 44, 17, 3, -34 }, // 0x28 '('
{ 734, 13, 44, 17, 0, -34 }, // 0x29 ')'
{ 806, 19, 19, 20, 1, -34 }, // 0x2A '*'
{ 852, 22, 21, 28, 3, -26 }, // 0x2B '+'
{ 910, 9, 16, 12, 2, -8 }, // 0x2C ','
{ 928, 14, 6, 18, 2, -15 }, // 0x2D '-'
{ 939, 9, 9, 12, 2, -8 }, // 0x2E '.'
{ 950, 22, 45, 18, -2, -39 }, // 0x2F '/'
{ 1074, 28, 34, 32, 2, -32 }, // 0x30 '0'
{ 1193, 15, 33, 18, 0, -32 }, // 0x31 '1'
{ 1255, 26, 33, 28, 0, -32 }, // 0x32 '2'
{ 1363, 26, 34, 28, 0, -32 }, // 0x33 '3'
{ 1474, 31, 33, 32, 1, -32 }, // 0x34 '4'
{ 1602, 27, 34, 28, 0, -32 }, // 0x35 '5'
{ 1717, 27, 34, 30, 2, -32 }, // 0x36 '6'
{ 1832, 27, 33, 29, 1, -32 }, // 0x37 '7'
{ 1944, 27, 34, 31, 2, -32 }, // 0x38 '8'
{ 2059, 27, 34, 30, 1, -32 }, // 0x39 '9'
{ 2174, 9, 26, 12, 2, -25 }, // 0x3A ':'
{ 2204, 9, 33, 12, 2, -25 }, // 0x3B ';'
{ 2242, 22, 23, 28, 3, -27 }, // 0x3C '<'
{ 2306, 22, 17, 28, 3, -24 }, // 0x3D '='
{ 2353, 22, 23, 28, 3, -27 }, // 0x3E '>'
{ 2417, 25, 33, 28, 0, -32 }, // 0x3F '?'
{ 2521, 45, 43, 49, 2, -32 }, // 0x40 '@'
{ 2763, 36, 33, 36, 0, -32 }, // 0x41 'A'
{ 2912, 30, 33, 36, 4, -32 }, // 0x42 'B'
{ 3036, 31, 34, 34, 2, -32 }, // 0x43 'C'
{ 3168, 33, 33, 39, 4, -32 }, // 0x44 'D'
{ 3305, 25, 33, 32, 4, -32 }, // 0x45 'E'
{ 3409, 25, 33, 30, 4, -32 }, // 0x46 'F'
{ 3513, 32, 34, 36, 2, -32 }, // 0x47 'G'
{ 3649, 30, 33, 38, 4, -32 }, // 0x48 'H'
{ 3773, 8, 33, 15, 4, -32 }, // 0x49 'I'
{ 3806, 23, 34, 25, -1, -32 }, // 0x4A 'J'
{ 3904, 31, 33, 35, 4, -32 }, // 0x4B 'K'
{ 4032, 24, 33, 28, 4, -32 }, // 0x4C 'L'
{ 4131, 37, 33, 45, 4, -32 }, // 0x4D 'M'
{ 4284, 30, 33, 38, 4, -32 }, // 0x4E 'N'
{ 4408, 36, 34, 40, 2, -32 }, // 0x4F 'O'
{ 4561, 28, 33, 34, 4, -32 }, // 0x50 'P'
{ 4677, 37, 41, 40, 2, -32 }, // 0x51 'Q'
{ 4867, 29, 33, 35, 4, -32 }, // 0x52 'R'
{ 4987, 28, 34, 30, 1, -32 }, // 0x53 'S'
{ 5106, 29, 33, 29, 0, -32 }, // 0x54 'T'
{ 5226, 29, 34, 37, 4, -32 }, // 0x55 'U'
{ 5350, 36, 33, 35, 0, -32 }, // 0x56 'V'
{ 5499, 53, 33, 55, 1, -32 }, // 0x57 'W'
{ 5718, 33, 33, 34, 0, -32 }, // 0x58 'X'
{ 5855, 33, 33, 32, -1, -32 }, // 0x59 'Y'
{ 5992, 29, 33, 32, 2, -32 }, // 0x5A 'Z'
{ 6112, 13, 44, 17, 4, -34 }, // 0x5B '['
{ 6184, 22, 45, 18, -2, -39 }, // 0x5C '\'
{ 6308, 12, 44, 17, 1, -34 }, // 0x5D ']'
{ 6374, 23, 19, 28, 3, -25 }, // 0x5E '^'
{ 6429, 24, 4, 24, 0, 1 }, // 0x5F '_'
{ 6441, 14, 6, 28, 4, -34 }, // 0x60 '`'
{ 6452, 24, 26, 29, 2, -25 }, // 0x61 'a'
{ 6530, 28, 35, 32, 3, -34 }, // 0x62 'b'
{ 6653, 26, 26, 28, 1, -25 }, // 0x63 'c'
{ 6738, 27, 35, 33, 2, -34 }, // 0x64 'd'
{ 6857, 27, 26, 30, 1, -25 }, // 0x65 'e'
{ 6945, 20, 35, 18, 0, -34 }, // 0x66 'f'
{ 7033, 28, 36, 33, 1, -25 }, // 0x67 'g'
{ 7159, 26, 35, 32, 3, -34 }, // 0x68 'h'
{ 7273, 9, 37, 14, 3, -36 }, // 0x69 'i'
{ 7315, 16, 47, 14, -4, -36 }, // 0x6A 'j'
{ 7409, 28, 35, 31, 3, -34 }, // 0x6B 'k'
{ 7532, 8, 35, 14, 3, -34 }, // 0x6C 'l'
{ 7567, 43, 26, 49, 3, -25 }, // 0x6D 'm'
{ 7707, 26, 26, 32, 3, -25 }, // 0x6E 'n'
{ 7792, 28, 26, 31, 1, -25 }, // 0x6F 'o'
{ 7883, 28, 35, 32, 3, -25 }, // 0x70 'p'
{ 8006, 28, 35, 32, 1, -25 }, // 0x71 'q'
{ 8129, 16, 26, 20, 3, -25 }, // 0x72 'r'
{ 8181, 23, 26, 25, 1, -25 }, // 0x73 's'
{ 8256, 20, 31, 20, 0, -30 }, // 0x74 't'
{ 8334, 26, 25, 32, 3, -24 }, // 0x75 'u'
{ 8416, 28, 25, 28, 0, -24 }, // 0x76 'v'
{ 8504, 44, 25, 44, 0, -24 }, // 0x77 'w'
{ 8642, 28, 25, 28, 0, -24 }, // 0x78 'x'
{ 8730, 28, 35, 28, 0, -24 }, // 0x79 'y'
{ 8853, 22, 25, 26, 2, -24 }, // 0x7A 'z'
{ 8922, 16, 44, 18, 2, -34 }, // 0x7B '{'
{ 9010, 7, 44, 15, 4, -34 }, // 0x7C '|'
{ 9049, 15, 44, 18, 1, -34 }, // 0x7D '}'
{ 9132, 24, 9, 28, 2, -20 } }; // 0x7E '~'
const GFXfont Montserrat_Bold24pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold24pt7bBitmaps,
(GFXglyph *)Montserrat_Bold24pt7bGlyphs,
0x20, 0x7E, 57 };
// Approx. 9831 bytes
#endif // MONTSERRATBOLD24PT7B_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,182 @@
#ifndef MONTSERRATBOLD7PT7B_H
#define MONTSERRATBOLD7PT7B_H
const uint8_t Montserrat_Bold7pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFC, 0xF0, 0xDC, 0xA5, 0x20, 0x19, 0x04, 0x47, 0xFD, 0xFF,
0x13, 0x0C, 0xCF, 0xFB, 0xFE, 0x32, 0x08, 0x80, 0x08, 0x1F, 0x1F, 0xCD,
0x06, 0x83, 0xE0, 0xFC, 0x16, 0x0B, 0xBF, 0x9F, 0x81, 0x00, 0x80, 0x70,
0xC5, 0x88, 0xC9, 0x8C, 0xB0, 0x7A, 0x00, 0x6E, 0x0D, 0xB0, 0x93, 0x19,
0xB3, 0x0E, 0x1C, 0x0F, 0x83, 0x30, 0xD8, 0x1C, 0x1F, 0x36, 0x79, 0x8E,
0x7F, 0xCF, 0xA0, 0xEA, 0x66, 0xEC, 0xCC, 0xCC, 0xCE, 0x66, 0x30, 0x66,
0x73, 0x33, 0x33, 0x37, 0x66, 0xC0, 0x33, 0xF7, 0xBF, 0x30, 0x30, 0x63,
0xFF, 0xF3, 0x06, 0x00, 0x4D, 0xB4, 0xFF, 0x5D, 0x80, 0x0C, 0x31, 0x86,
0x18, 0xC3, 0x0C, 0x61, 0x86, 0x30, 0xC0, 0x3C, 0x7E, 0xE6, 0xC7, 0xC3,
0xC3, 0xC3, 0xC7, 0xFE, 0x7C, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3C, 0xFE,
0x47, 0x07, 0x06, 0x0C, 0x18, 0x30, 0x7F, 0xFF, 0xFE, 0xFE, 0x0E, 0x1C,
0x1C, 0x1E, 0x07, 0x07, 0xFE, 0x7C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x33,
0x1C, 0xCF, 0xFF, 0xFF, 0x03, 0x00, 0xC0, 0x7E, 0x7E, 0x60, 0x60, 0x7E,
0x7F, 0x03, 0x03, 0xFF, 0x7E, 0x3E, 0x7E, 0xE0, 0xC0, 0xFC, 0xFE, 0xC7,
0xC7, 0xFE, 0x7C, 0xFF, 0xFF, 0xC7, 0xC6, 0x06, 0x0E, 0x0C, 0x1C, 0x18,
0x38, 0x3E, 0x3F, 0x98, 0xCC, 0x63, 0xF3, 0xF9, 0x8E, 0xC7, 0x7F, 0x1F,
0x00, 0x3C, 0x7E, 0xE3, 0xE3, 0x67, 0x7F, 0x03, 0x07, 0x7E, 0x7C, 0x5D,
0x80, 0xBB, 0x5D, 0x80, 0x9B, 0x68, 0x0E, 0x7B, 0xC7, 0x07, 0xC1, 0xC0,
0x80, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0xC1, 0xF0, 0x78, 0xF7, 0x9C, 0x00,
0x00, 0x3C, 0xFE, 0x46, 0x06, 0x0E, 0x1C, 0x18, 0x00, 0x18, 0x18, 0x0F,
0x81, 0xC7, 0x18, 0x0D, 0x9D, 0xA9, 0xFD, 0xCC, 0x6E, 0x43, 0x33, 0x1B,
0x9F, 0xD6, 0x7B, 0x98, 0x00, 0x73, 0x00, 0xF8, 0x00, 0x0E, 0x01, 0xC0,
0x7C, 0x0D, 0x83, 0x30, 0x63, 0x1F, 0xE3, 0xFE, 0x60, 0xD8, 0x1C, 0xFE,
0x7F, 0xB0, 0xF8, 0x7F, 0xF7, 0xFB, 0x07, 0x83, 0xFF, 0xFF, 0x80, 0x1E,
0x3F, 0xF8, 0x58, 0x0C, 0x06, 0x03, 0x01, 0xC2, 0x7F, 0x9F, 0x80, 0xFE,
0x3F, 0xCC, 0x3B, 0x07, 0xC0, 0xF0, 0x3C, 0x1F, 0x06, 0xFF, 0xBF, 0x80,
0xFF, 0xFF, 0xC0, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0x1E, 0x3F, 0xF8, 0x58,
0x0C, 0x06, 0x0F, 0x07, 0xC3, 0x7F, 0x9F, 0x80, 0xC1, 0xE0, 0xF0, 0x78,
0x3F, 0xFF, 0xFF, 0x07, 0x83, 0xC1, 0xE0, 0xC0, 0xFF, 0xFF, 0xF0, 0x7E,
0xFC, 0x38, 0x70, 0xE1, 0xC3, 0x86, 0xFC, 0xF0, 0xC3, 0xB0, 0xCC, 0x63,
0x30, 0xD8, 0x3F, 0x0E, 0xE3, 0x1C, 0xC3, 0x30, 0xE0, 0xC1, 0x83, 0x06,
0x0C, 0x18, 0x30, 0x60, 0xFF, 0xFC, 0xC0, 0x7C, 0x0F, 0x83, 0xF8, 0xFF,
0x9F, 0xB6, 0xF3, 0xDE, 0x73, 0xC4, 0x78, 0x0C, 0xC1, 0xF0, 0xFC, 0x7F,
0x3D, 0xDE, 0x6F, 0x3F, 0x8F, 0xC3, 0xE0, 0xC0, 0x1E, 0x1F, 0xEE, 0x1F,
0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x87, 0x7F, 0x8F, 0xC0, 0xFC, 0x7F, 0xB0,
0xD8, 0x7C, 0x3F, 0xFB, 0xF9, 0x80, 0xC0, 0x60, 0x00, 0x1E, 0x0F, 0xF3,
0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, 0x37, 0x0E, 0x7F, 0x87, 0xE0, 0x3D,
0x01, 0xE0, 0xFC, 0x7F, 0xB0, 0xD8, 0x7C, 0x3F, 0xFB, 0xF9, 0x8C, 0xC7,
0x61, 0x80, 0x3E, 0x3F, 0x98, 0x0C, 0x07, 0xC1, 0xF8, 0x0C, 0x07, 0x7F,
0x3F, 0x00, 0xFF, 0xFF, 0xC6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18,
0x0C, 0x00, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F,
0x1F, 0x00, 0xC0, 0xDC, 0x19, 0x87, 0x38, 0xC3, 0x38, 0x76, 0x06, 0xC0,
0xF0, 0x1E, 0x01, 0xC0, 0xE1, 0x83, 0x61, 0xC7, 0x63, 0xC6, 0x73, 0xC6,
0x33, 0x6E, 0x36, 0x6C, 0x3E, 0x6C, 0x1E, 0x3C, 0x1C, 0x38, 0x1C, 0x38,
0xE1, 0xDC, 0xE3, 0x30, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0xCC, 0x73, 0xB8,
0x70, 0xC1, 0x98, 0x67, 0x30, 0xDC, 0x3E, 0x07, 0x00, 0xC0, 0x30, 0x0C,
0x03, 0x00, 0xFF, 0xFF, 0x06, 0x0C, 0x1C, 0x38, 0x70, 0xE0, 0xFF, 0xFF,
0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0, 0xC0, 0xC1, 0x81, 0x03, 0x06,
0x06, 0x0C, 0x18, 0x18, 0x30, 0x60, 0x60, 0xF3, 0x33, 0x33, 0x33, 0x33,
0x3F, 0xF0, 0x30, 0x71, 0xE3, 0x6C, 0xD8, 0x80, 0xFE, 0xE3, 0x10, 0x31,
0xFA, 0x38, 0x7F, 0xF9, 0xF3, 0xFB, 0xC0, 0xC0, 0xDC, 0xFE, 0xE7, 0xC3,
0xC3, 0xE3, 0xFF, 0xFE, 0x1C, 0x3F, 0x63, 0x60, 0xE0, 0x62, 0x7F, 0x3E,
0x03, 0x81, 0xC6, 0xEF, 0xF6, 0x3B, 0x1F, 0x86, 0xC7, 0x7F, 0x9E, 0xC0,
0x1C, 0x3E, 0x63, 0x63, 0xFF, 0x60, 0x7E, 0x3E, 0x00, 0xF7, 0x18, 0xF9,
0x86, 0x18, 0x61, 0x86, 0x00, 0x19, 0xBF, 0xD8, 0xFC, 0x3E, 0x1B, 0x1D,
0xFE, 0x33, 0x03, 0xBF, 0x8F, 0x80, 0xC0, 0xC0, 0xCC, 0xFE, 0xE7, 0xC7,
0xC3, 0xC3, 0xC3, 0xC3, 0xDC, 0x6D, 0xB6, 0xDB, 0x00, 0x31, 0xC0, 0x63,
0x18, 0xC6, 0x31, 0x8C, 0x6F, 0x70, 0xC0, 0xC0, 0xC7, 0xCE, 0xDC, 0xF8,
0xFC, 0xEC, 0xCE, 0xC7, 0xFF, 0xFF, 0xF0, 0xD8, 0x67, 0xFF, 0xB9, 0xCF,
0x8E, 0x3C, 0x61, 0xE3, 0x0F, 0x18, 0x78, 0xC3, 0xCC, 0xFE, 0xE7, 0xC7,
0xC3, 0xC3, 0xC3, 0xC3, 0x1C, 0x1F, 0x98, 0xCC, 0x7E, 0x1B, 0x1D, 0xFC,
0x7C, 0xDC, 0xFE, 0xE7, 0xC3, 0xC3, 0xE3, 0xFF, 0xDE, 0xC0, 0xC0, 0xC0,
0x19, 0xBF, 0xD8, 0xEC, 0x7E, 0x1B, 0x1D, 0xFE, 0x7F, 0x03, 0x81, 0xC0,
0xE0, 0xCF, 0xF9, 0x8C, 0x63, 0x18, 0x18, 0xFF, 0x83, 0x87, 0xE0, 0xDF,
0xBE, 0x63, 0xEF, 0x98, 0x61, 0x86, 0x1E, 0x3C, 0xC7, 0xC7, 0xC7, 0xC7,
0xC7, 0xC7, 0xFF, 0x7B, 0xC3, 0xE3, 0x63, 0x66, 0x36, 0x3C, 0x3C, 0x1C,
0xC3, 0x1E, 0x38, 0xD9, 0xCC, 0xCF, 0x66, 0xDB, 0x1E, 0xF0, 0xE3, 0x83,
0x1C, 0xE3, 0x66, 0x3E, 0x3C, 0x1C, 0x3C, 0x76, 0xE7, 0xC3, 0xE3, 0x63,
0x66, 0x36, 0x3C, 0x3C, 0x18, 0x18, 0xF8, 0xE0, 0x7E, 0xFC, 0x30, 0xE3,
0x8E, 0x1F, 0xFF, 0x76, 0x66, 0x6E, 0xE6, 0x66, 0x67, 0x30, 0xFF, 0xFF,
0xFF, 0xC0, 0xE3, 0x9C, 0xE7, 0x1C, 0xEE, 0x73, 0x9D, 0xCC, 0x00, 0xF7,
0x38 };
const GFXglyph Montserrat_Bold7pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
{ 1, 2, 10, 4, 1, -9 }, // 0x21 '!'
{ 4, 5, 4, 6, 1, -9 }, // 0x22 '"'
{ 7, 10, 10, 10, 0, -9 }, // 0x23 '#'
{ 20, 9, 13, 9, 0, -10 }, // 0x24 '$'
{ 35, 12, 10, 12, 0, -9 }, // 0x25 '%'
{ 50, 10, 10, 10, 0, -9 }, // 0x26 '&'
{ 63, 2, 4, 3, 1, -9 }, // 0x27 '''
{ 64, 4, 13, 5, 1, -9 }, // 0x28 '('
{ 71, 4, 13, 5, 0, -9 }, // 0x29 ')'
{ 78, 6, 5, 6, 0, -9 }, // 0x2A '*'
{ 82, 7, 6, 8, 1, -7 }, // 0x2B '+'
{ 88, 3, 5, 4, 0, -2 }, // 0x2C ','
{ 90, 4, 2, 5, 1, -4 }, // 0x2D '-'
{ 91, 3, 3, 4, 0, -2 }, // 0x2E '.'
{ 93, 6, 13, 5, 0, -11 }, // 0x2F '/'
{ 103, 8, 10, 10, 1, -9 }, // 0x30 '0'
{ 113, 4, 10, 5, 0, -9 }, // 0x31 '1'
{ 118, 8, 10, 8, 0, -9 }, // 0x32 '2'
{ 128, 8, 10, 8, 0, -9 }, // 0x33 '3'
{ 138, 10, 10, 10, 0, -9 }, // 0x34 '4'
{ 151, 8, 10, 8, 0, -9 }, // 0x35 '5'
{ 161, 8, 10, 9, 1, -9 }, // 0x36 '6'
{ 171, 8, 10, 9, 0, -9 }, // 0x37 '7'
{ 181, 9, 10, 9, 0, -9 }, // 0x38 '8'
{ 193, 8, 10, 9, 0, -9 }, // 0x39 '9'
{ 203, 3, 8, 4, 0, -7 }, // 0x3A ':'
{ 206, 3, 10, 4, 0, -7 }, // 0x3B ';'
{ 210, 7, 7, 8, 1, -7 }, // 0x3C '<'
{ 217, 7, 5, 8, 1, -6 }, // 0x3D '='
{ 222, 7, 7, 8, 1, -7 }, // 0x3E '>'
{ 229, 8, 10, 8, 0, -9 }, // 0x3F '?'
{ 239, 13, 13, 14, 1, -9 }, // 0x40 '@'
{ 261, 11, 10, 11, 0, -9 }, // 0x41 'A'
{ 275, 9, 10, 11, 1, -9 }, // 0x42 'B'
{ 287, 9, 10, 10, 1, -9 }, // 0x43 'C'
{ 299, 10, 10, 12, 1, -9 }, // 0x44 'D'
{ 312, 8, 10, 9, 1, -9 }, // 0x45 'E'
{ 322, 8, 10, 9, 1, -9 }, // 0x46 'F'
{ 332, 9, 10, 11, 1, -9 }, // 0x47 'G'
{ 344, 9, 10, 11, 1, -9 }, // 0x48 'H'
{ 356, 2, 10, 5, 1, -9 }, // 0x49 'I'
{ 359, 7, 10, 8, 0, -9 }, // 0x4A 'J'
{ 368, 10, 10, 10, 1, -9 }, // 0x4B 'K'
{ 381, 7, 10, 8, 1, -9 }, // 0x4C 'L'
{ 390, 11, 10, 13, 1, -9 }, // 0x4D 'M'
{ 404, 9, 10, 11, 1, -9 }, // 0x4E 'N'
{ 416, 10, 10, 12, 1, -9 }, // 0x4F 'O'
{ 429, 9, 10, 10, 1, -9 }, // 0x50 'P'
{ 441, 11, 12, 12, 1, -9 }, // 0x51 'Q'
{ 458, 9, 10, 10, 1, -9 }, // 0x52 'R'
{ 470, 9, 10, 9, 0, -9 }, // 0x53 'S'
{ 482, 9, 10, 9, 0, -9 }, // 0x54 'T'
{ 494, 9, 10, 11, 1, -9 }, // 0x55 'U'
{ 506, 11, 10, 10, 0, -9 }, // 0x56 'V'
{ 520, 16, 10, 16, 0, -9 }, // 0x57 'W'
{ 540, 10, 10, 10, 0, -9 }, // 0x58 'X'
{ 553, 10, 10, 9, 0, -9 }, // 0x59 'Y'
{ 566, 8, 10, 9, 1, -9 }, // 0x5A 'Z'
{ 576, 4, 13, 5, 1, -9 }, // 0x5B '['
{ 583, 7, 13, 5, -1, -11 }, // 0x5C '\'
{ 595, 4, 13, 5, 0, -9 }, // 0x5D ']'
{ 602, 7, 6, 8, 1, -7 }, // 0x5E '^'
{ 608, 7, 1, 7, 0, 1 }, // 0x5F '_'
{ 609, 4, 3, 8, 1, -10 }, // 0x60 '`'
{ 611, 7, 8, 9, 1, -7 }, // 0x61 'a'
{ 618, 8, 10, 10, 1, -9 }, // 0x62 'b'
{ 628, 8, 8, 8, 0, -7 }, // 0x63 'c'
{ 636, 9, 10, 10, 0, -9 }, // 0x64 'd'
{ 648, 8, 8, 9, 0, -7 }, // 0x65 'e'
{ 656, 6, 11, 5, 0, -10 }, // 0x66 'f'
{ 665, 9, 11, 10, 0, -7 }, // 0x67 'g'
{ 678, 8, 10, 10, 1, -9 }, // 0x68 'h'
{ 688, 3, 11, 4, 1, -10 }, // 0x69 'i'
{ 693, 5, 14, 4, -1, -10 }, // 0x6A 'j'
{ 702, 8, 10, 9, 1, -9 }, // 0x6B 'k'
{ 712, 2, 10, 4, 1, -9 }, // 0x6C 'l'
{ 715, 13, 8, 15, 1, -7 }, // 0x6D 'm'
{ 728, 8, 8, 10, 1, -7 }, // 0x6E 'n'
{ 736, 9, 8, 9, 0, -7 }, // 0x6F 'o'
{ 745, 8, 11, 10, 1, -7 }, // 0x70 'p'
{ 756, 9, 11, 10, 0, -7 }, // 0x71 'q'
{ 769, 5, 8, 6, 1, -7 }, // 0x72 'r'
{ 774, 7, 8, 7, 0, -7 }, // 0x73 's'
{ 781, 6, 9, 6, 0, -8 }, // 0x74 't'
{ 788, 8, 8, 10, 1, -7 }, // 0x75 'u'
{ 796, 8, 8, 8, 0, -7 }, // 0x76 'v'
{ 804, 13, 8, 13, 0, -7 }, // 0x77 'w'
{ 817, 8, 8, 8, 0, -7 }, // 0x78 'x'
{ 825, 8, 11, 8, 0, -7 }, // 0x79 'y'
{ 836, 7, 8, 8, 0, -7 }, // 0x7A 'z'
{ 843, 4, 13, 5, 1, -9 }, // 0x7B '{'
{ 850, 2, 13, 4, 1, -9 }, // 0x7C '|'
{ 854, 5, 13, 5, 0, -9 }, // 0x7D '}'
{ 863, 7, 2, 8, 1, -5 } }; // 0x7E '~'
const GFXfont Montserrat_Bold7pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold7pt7bBitmaps,
(GFXglyph *)Montserrat_Bold7pt7bGlyphs,
0x20, 0x7E, 17 };
// Approx. 1537 bytes
#endif // MONTSERRATBOLD7PT7B_H
@@ -0,0 +1,227 @@
#ifndef MONTSERRATBOLD9PT7B_H
#define MONTSERRATBOLD9PT7B_H
const uint8_t Montserrat_Bold9pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xE3, 0xFE, 0xCF, 0x3C, 0xF3, 0xCF, 0x30, 0x0C,
0x60, 0x66, 0x03, 0x30, 0xFF, 0xF7, 0xFF, 0x8C, 0x60, 0x63, 0x03, 0x18,
0xFF, 0xF7, 0xFF, 0x86, 0x60, 0x33, 0x03, 0x18, 0x00, 0x06, 0x00, 0xC0,
0x3E, 0x1F, 0xE7, 0xFC, 0xEC, 0x1D, 0x83, 0xF0, 0x3F, 0x81, 0xF8, 0x1F,
0x83, 0x76, 0x6E, 0xFF, 0x8F, 0xE0, 0x30, 0x06, 0x00, 0x38, 0x18, 0xF8,
0x71, 0x98, 0xC6, 0x33, 0x04, 0x6C, 0x0D, 0x98, 0x0F, 0x67, 0x01, 0x9F,
0x03, 0x66, 0x0C, 0xCC, 0x31, 0x98, 0x63, 0xB1, 0x83, 0xC0, 0x1E, 0x03,
0xF0, 0x73, 0x87, 0x38, 0x77, 0x03, 0xE0, 0x3C, 0x0F, 0xE6, 0xE7, 0xEC,
0x3E, 0xE1, 0xEF, 0xFF, 0x7F, 0x60, 0xFF, 0xF0, 0x39, 0x9C, 0xE6, 0x73,
0x9C, 0xE7, 0x38, 0xC7, 0x38, 0xC7, 0x63, 0x9C, 0x73, 0x9C, 0xE7, 0x39,
0xCE, 0x73, 0x99, 0xCC, 0x18, 0x5E, 0x7E, 0x3C, 0xFE, 0x5A, 0x18, 0x1C,
0x0E, 0x07, 0x1F, 0xFF, 0xF8, 0xE0, 0x70, 0x38, 0xFF, 0xFD, 0x80, 0xFF,
0xC0, 0xFF, 0x80, 0x03, 0x81, 0x81, 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x18,
0x1C, 0x0C, 0x06, 0x07, 0x03, 0x01, 0x81, 0xC0, 0xC0, 0x60, 0x00, 0x1E,
0x07, 0xF1, 0xFE, 0x70, 0xEE, 0x1D, 0xC3, 0xB8, 0x37, 0x06, 0xE1, 0xDC,
0x39, 0xCF, 0x3F, 0xC3, 0xF0, 0xFF, 0xFF, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
0x71, 0xC7, 0x1C, 0x1E, 0x1F, 0xEF, 0xF8, 0x07, 0x01, 0xC0, 0xE0, 0x78,
0x3C, 0x1E, 0x0F, 0x07, 0x81, 0xFF, 0x7F, 0xC0, 0x7F, 0x9F, 0xE7, 0xF8,
0x1C, 0x0E, 0x03, 0x81, 0xF8, 0x7F, 0x01, 0xC0, 0x76, 0x3F, 0xFE, 0x7F,
0x00, 0x07, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0xC0, 0x70, 0x1C, 0xE7, 0x1C,
0xFF, 0xFF, 0xFC, 0x0E, 0x01, 0xC0, 0x38, 0x3F, 0x8F, 0xE3, 0xF9, 0xC0,
0x70, 0x1F, 0xC7, 0xF8, 0x1F, 0x01, 0xC0, 0x76, 0x3F, 0xFE, 0x7F, 0x00,
0x0F, 0x0F, 0xE7, 0xFB, 0xC0, 0xE0, 0x3B, 0xCF, 0xFB, 0xCF, 0xE1, 0xF8,
0x7F, 0x1D, 0xFE, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0xEE, 0x3C,
0x07, 0x00, 0xE0, 0x38, 0x07, 0x01, 0xC0, 0x38, 0x0F, 0x01, 0xC0, 0x1E,
0x1F, 0xEF, 0x3F, 0x87, 0xE1, 0xDF, 0xE7, 0xFB, 0xCF, 0xE1, 0xF8, 0x7E,
0x1F, 0xFE, 0x3F, 0x00, 0x1E, 0x07, 0xF1, 0xCF, 0x70, 0xEE, 0x1E, 0xE3,
0xDF, 0xF9, 0xF7, 0x00, 0xE0, 0x38, 0x0F, 0x3F, 0xC7, 0xF0, 0xFF, 0x80,
0x3F, 0xE0, 0xFF, 0x80, 0x3F, 0xFF, 0x60, 0x00, 0x83, 0xC7, 0xFF, 0x8E,
0x07, 0xC0, 0xFC, 0x1F, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x07,
0xFF, 0xFE, 0x80, 0x70, 0x3F, 0x03, 0xF0, 0x38, 0x7D, 0xF9, 0xE0, 0xC0,
0x00, 0x1E, 0x1F, 0xEF, 0xF8, 0x07, 0x01, 0xC0, 0xE0, 0x70, 0x38, 0x0E,
0x00, 0x00, 0xE0, 0x38, 0x0E, 0x00, 0x03, 0xE0, 0x0F, 0xFC, 0x0E, 0x07,
0x8E, 0x00, 0xC6, 0x3F, 0xB6, 0x3F, 0xCF, 0x38, 0xE7, 0x98, 0x73, 0xCC,
0x39, 0xE6, 0x1C, 0xF3, 0x8E, 0x79, 0xFF, 0xE6, 0x3D, 0xE3, 0x80, 0x00,
0xF0, 0x40, 0x1F, 0xE0, 0x03, 0xC0, 0x00, 0x07, 0x00, 0x1E, 0x00, 0x78,
0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x81, 0xCE, 0x0E, 0x1C, 0x3F, 0xF1, 0xFF,
0xC7, 0x03, 0x98, 0x0E, 0xE0, 0x1C, 0xFF, 0x0F, 0xFC, 0xFF, 0xEE, 0x0E,
0xE0, 0xEE, 0x1E, 0xFF, 0xCF, 0xFE, 0xE0, 0x7E, 0x07, 0xE0, 0xFF, 0xFE,
0xFF, 0xC0, 0x0F, 0x83, 0xFE, 0x7F, 0xF7, 0x06, 0xE0, 0x0E, 0x00, 0xE0,
0x0E, 0x00, 0xE0, 0x0F, 0x00, 0x78, 0xE3, 0xFE, 0x1F, 0xC0, 0xFF, 0x07,
0xFE, 0x3F, 0xFD, 0xC0, 0xEE, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0,
0x3F, 0x03, 0xF8, 0x7D, 0xFF, 0xCF, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0x80, 0xE0, 0x3F, 0xEF, 0xFB, 0xFE, 0xE0, 0x38, 0x0E, 0x03, 0xFF, 0xFF,
0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x38, 0x0F, 0xFB, 0xFE, 0xE0,
0x38, 0x0E, 0x03, 0x80, 0xE0, 0x00, 0x0F, 0x83, 0xFE, 0x7F, 0xF7, 0x06,
0xE0, 0x0E, 0x00, 0xE0, 0x7E, 0x07, 0xE0, 0x7F, 0x07, 0x78, 0xF3, 0xFF,
0x1F, 0xC0, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7F, 0xFF, 0xFF,
0xFF, 0xFF, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x70, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0x7F, 0x7F, 0x7F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0xC7, 0xFF, 0x7E, 0xE0, 0x77, 0x07, 0x38, 0x71, 0xC7, 0x0E, 0x70,
0x77, 0x03, 0xF8, 0x1F, 0xE0, 0xFF, 0x87, 0x9E, 0x38, 0x79, 0xC1, 0xCE,
0x07, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80,
0xE0, 0x38, 0x0E, 0x03, 0xFF, 0xFF, 0xC0, 0xE0, 0x0F, 0xE0, 0x1F, 0xC0,
0x7F, 0xC1, 0xFF, 0x83, 0xFF, 0x8F, 0xFB, 0x9B, 0xF7, 0x77, 0xE7, 0xCF,
0xC7, 0x9F, 0x8E, 0x3F, 0x08, 0x7E, 0x00, 0xE0, 0xE0, 0x7F, 0x07, 0xF8,
0x7F, 0x87, 0xFC, 0x7F, 0xE7, 0xEF, 0x7E, 0x7F, 0xE3, 0xFE, 0x1F, 0xE0,
0xFE, 0x0F, 0xE0, 0x70, 0x0F, 0x81, 0xFF, 0x1F, 0xFC, 0xE0, 0xFE, 0x03,
0xF0, 0x1F, 0x80, 0x7C, 0x07, 0xE0, 0x3F, 0x81, 0xDE, 0x3C, 0x7F, 0xC1,
0xFC, 0x00, 0xFE, 0x1F, 0xFB, 0xFF, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F,
0xFF, 0xFF, 0xDF, 0xC3, 0x80, 0x70, 0x0E, 0x00, 0x0F, 0x80, 0xFF, 0x87,
0xFF, 0x1C, 0x1E, 0xE0, 0x3B, 0x80, 0xEE, 0x01, 0xB8, 0x0E, 0xE0, 0x3B,
0xC0, 0xE7, 0x8F, 0x0F, 0xF8, 0x1F, 0xC0, 0x0F, 0x20, 0x1F, 0xC0, 0x1E,
0xFE, 0x0F, 0xFC, 0xFF, 0xEE, 0x0E, 0xE0, 0xEE, 0x0E, 0xE0, 0xEF, 0xFE,
0xFF, 0xCE, 0x38, 0xE1, 0xCE, 0x1E, 0xE0, 0xE0, 0x0F, 0x87, 0xF9, 0xFF,
0x38, 0x07, 0x00, 0xF8, 0x0F, 0xE0, 0x7E, 0x01, 0xE0, 0x1D, 0x83, 0xBF,
0xE3, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0xE0, 0x1C, 0x03, 0x80,
0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0xE0, 0x7E, 0x07, 0xE0,
0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x77, 0x0F, 0x79,
0xE3, 0xFE, 0x1F, 0x80, 0xE0, 0x1F, 0x80, 0xE7, 0x03, 0x9C, 0x1C, 0x38,
0x70, 0xE1, 0x83, 0xCE, 0x07, 0x38, 0x1D, 0xC0, 0x3F, 0x00, 0xF8, 0x01,
0xE0, 0x07, 0x00, 0xE0, 0x70, 0x3B, 0x83, 0x83, 0x9C, 0x1E, 0x1C, 0xE1,
0xF0, 0xE3, 0x8D, 0x8E, 0x1C, 0x6E, 0x70, 0xE7, 0x73, 0x83, 0xB3, 0xB8,
0x1D, 0x8F, 0xC0, 0xFC, 0x7E, 0x03, 0xC3, 0xE0, 0x1E, 0x0F, 0x00, 0xF0,
0x78, 0x00, 0xF0, 0x73, 0x83, 0x8E, 0x38, 0x7B, 0x81, 0xFC, 0x07, 0xC0,
0x1C, 0x01, 0xF0, 0x1F, 0xC0, 0xEE, 0x0E, 0x38, 0xE1, 0xEF, 0x07, 0x00,
0xE0, 0x3F, 0x07, 0x70, 0xE3, 0x8E, 0x39, 0xC1, 0xD8, 0x1F, 0x80, 0xF0,
0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0xFF, 0xDF, 0xFB, 0xFF,
0x01, 0xC0, 0x78, 0x1E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0xC0, 0x7F,
0xFF, 0xFE, 0xFF, 0xF9, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0xFF,
0xE0, 0x30, 0x1C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03,
0x01, 0xC0, 0x60, 0x38, 0x1C, 0x06, 0x03, 0x80, 0xFF, 0xCE, 0x73, 0x9C,
0xE7, 0x39, 0xCE, 0x73, 0x9F, 0xFF, 0x1C, 0x0E, 0x0D, 0x86, 0xC6, 0x73,
0x1B, 0x8C, 0xFF, 0xFF, 0xC0, 0xE3, 0x8E, 0x3C, 0x7F, 0x99, 0xE0, 0x73,
0xFF, 0xFF, 0x8F, 0x87, 0xFF, 0xBF, 0xC0, 0xE0, 0x1C, 0x03, 0x80, 0x77,
0x8F, 0xF9, 0xF7, 0xBC, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0xC7, 0x7F, 0xEE,
0xF8, 0x1E, 0x3F, 0xFF, 0xFC, 0x2C, 0x06, 0x03, 0x81, 0xE7, 0x7F, 0x9F,
0x80, 0x01, 0xC0, 0x70, 0x1C, 0x77, 0x7F, 0xFF, 0xFE, 0x1F, 0x87, 0xC1,
0xF8, 0x7F, 0x3D, 0xFF, 0x3F, 0xC0, 0x1E, 0x1F, 0xCF, 0x3B, 0x87, 0xFF,
0xFF, 0xFE, 0x03, 0xC4, 0x7F, 0x8F, 0xC0, 0x00, 0x1E, 0x3E, 0x30, 0x30,
0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1C, 0xDF, 0xFF,
0xFF, 0x87, 0xC1, 0xF8, 0x7E, 0x1F, 0xFF, 0x7F, 0xC2, 0x74, 0x1D, 0xFF,
0xFF, 0x87, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0xBC, 0xFF, 0xBF, 0xFF, 0x1F,
0x87, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xC0, 0xFF, 0x8F, 0xFF, 0xFF,
0xFF, 0xC0, 0x1C, 0x71, 0xC0, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
0x71, 0xDF, 0x79, 0xC0, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0xEE, 0x39, 0xCE,
0x3B, 0x87, 0xF0, 0xFE, 0x1E, 0xE3, 0x9E, 0x71, 0xEE, 0x1E, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0xEF, 0x1C, 0x7F, 0xFF, 0xBF, 0xFF, 0xDC, 0x38, 0x7E,
0x1C, 0x3F, 0x0E, 0x1F, 0x87, 0x0F, 0xC3, 0x87, 0xE1, 0xC3, 0xF0, 0xE1,
0xC0, 0xEF, 0x3F, 0xEF, 0xFF, 0xC7, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1,
0xF8, 0x70, 0x1E, 0x1F, 0xEF, 0xFB, 0x87, 0xC1, 0xF0, 0x7E, 0x1F, 0xCF,
0x7F, 0x8F, 0xC0, 0xEF, 0x1F, 0xF3, 0xEF, 0x78, 0x7E, 0x0F, 0xC1, 0xF8,
0x3F, 0x8E, 0xFF, 0xDD, 0xF3, 0x80, 0x70, 0x0E, 0x00, 0x1D, 0xDF, 0xFF,
0xFF, 0x87, 0xC1, 0xF0, 0x7E, 0x1F, 0xCF, 0x7F, 0xCF, 0xF0, 0x1C, 0x07,
0x01, 0xC0, 0xEF, 0xFF, 0xFC, 0xE3, 0x8E, 0x38, 0xE3, 0x80, 0x1F, 0x3F,
0xDC, 0x4C, 0x07, 0xE1, 0xFC, 0x0E, 0x87, 0x7F, 0xBF, 0x80, 0x30, 0x30,
0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x3E, 0x1F, 0xE1, 0xF8,
0x7E, 0x1F, 0x87, 0xE1, 0xF8, 0x7E, 0x1F, 0xCF, 0x7F, 0xCF, 0xF0, 0xE0,
0xFC, 0x19, 0xC7, 0x38, 0xE3, 0x38, 0x77, 0x0E, 0xC0, 0xF8, 0x1E, 0x01,
0xC0, 0xE1, 0xC3, 0xF0, 0xE1, 0x98, 0x70, 0xCE, 0x7C, 0xE3, 0x36, 0x61,
0xBB, 0xB0, 0xFD, 0xF8, 0x3C, 0x78, 0x1E, 0x3C, 0x0E, 0x1E, 0x00, 0xE1,
0xCE, 0x38, 0xEE, 0x0F, 0x81, 0xE0, 0x1C, 0x07, 0xC1, 0xDC, 0x73, 0xDC,
0x38, 0xE0, 0xFC, 0x19, 0xC7, 0x38, 0xE3, 0x38, 0x77, 0x06, 0xC0, 0xF8,
0x1E, 0x01, 0xC0, 0x38, 0x7E, 0x0F, 0x80, 0xE0, 0x00, 0xFF, 0xFF, 0x07,
0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xFF, 0xFF, 0x3C, 0xF7, 0x1C, 0x71, 0xC7,
0x3C, 0xF1, 0xC7, 0x1C, 0x71, 0xC7, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF3, 0xE3, 0x8E, 0x38, 0xE3, 0x8F, 0x3C, 0xE3, 0x8E, 0x38, 0xEF,
0xBC, 0x71, 0xFF, 0xF3, 0xC0 };
const GFXglyph Montserrat_Bold9pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 5, 0, 0 }, // 0x20 ' '
{ 1, 3, 13, 5, 1, -12 }, // 0x21 '!'
{ 6, 6, 6, 8, 1, -12 }, // 0x22 '"'
{ 11, 13, 13, 13, 0, -12 }, // 0x23 '#'
{ 33, 11, 17, 11, 0, -14 }, // 0x24 '$'
{ 57, 15, 13, 16, 0, -12 }, // 0x25 '%'
{ 82, 12, 13, 13, 1, -12 }, // 0x26 '&'
{ 102, 2, 6, 4, 1, -12 }, // 0x27 '''
{ 104, 5, 16, 6, 1, -12 }, // 0x28 '('
{ 114, 5, 16, 6, 0, -12 }, // 0x29 ')'
{ 124, 8, 7, 8, 0, -12 }, // 0x2A '*'
{ 131, 9, 8, 11, 1, -9 }, // 0x2B '+'
{ 140, 3, 6, 5, 1, -2 }, // 0x2C ','
{ 143, 5, 2, 7, 1, -5 }, // 0x2D '-'
{ 145, 3, 3, 5, 1, -2 }, // 0x2E '.'
{ 147, 9, 17, 7, -1, -14 }, // 0x2F '/'
{ 167, 11, 13, 12, 1, -12 }, // 0x30 '0'
{ 185, 6, 13, 7, 0, -12 }, // 0x31 '1'
{ 195, 10, 13, 11, 0, -12 }, // 0x32 '2'
{ 212, 10, 13, 11, 0, -12 }, // 0x33 '3'
{ 229, 11, 13, 12, 1, -12 }, // 0x34 '4'
{ 247, 10, 13, 11, 0, -12 }, // 0x35 '5'
{ 264, 10, 13, 11, 1, -12 }, // 0x36 '6'
{ 281, 11, 13, 11, 0, -12 }, // 0x37 '7'
{ 299, 10, 13, 12, 1, -12 }, // 0x38 '8'
{ 316, 11, 13, 11, 0, -12 }, // 0x39 '9'
{ 334, 3, 9, 5, 1, -8 }, // 0x3A ':'
{ 338, 3, 12, 5, 1, -8 }, // 0x3B ';'
{ 343, 9, 9, 11, 1, -10 }, // 0x3C '<'
{ 354, 9, 7, 11, 1, -9 }, // 0x3D '='
{ 362, 9, 9, 11, 1, -10 }, // 0x3E '>'
{ 373, 10, 13, 11, 0, -12 }, // 0x3F '?'
{ 390, 17, 17, 19, 1, -12 }, // 0x40 '@'
{ 427, 14, 13, 14, 0, -12 }, // 0x41 'A'
{ 450, 12, 13, 14, 1, -12 }, // 0x42 'B'
{ 470, 12, 13, 13, 1, -12 }, // 0x43 'C'
{ 490, 13, 13, 15, 1, -12 }, // 0x44 'D'
{ 512, 10, 13, 12, 1, -12 }, // 0x45 'E'
{ 529, 10, 13, 12, 1, -12 }, // 0x46 'F'
{ 546, 12, 13, 14, 1, -12 }, // 0x47 'G'
{ 566, 12, 13, 15, 1, -12 }, // 0x48 'H'
{ 586, 3, 13, 6, 1, -12 }, // 0x49 'I'
{ 591, 8, 13, 10, 0, -12 }, // 0x4A 'J'
{ 604, 13, 13, 13, 1, -12 }, // 0x4B 'K'
{ 626, 10, 13, 11, 1, -12 }, // 0x4C 'L'
{ 643, 15, 13, 17, 1, -12 }, // 0x4D 'M'
{ 668, 12, 13, 15, 1, -12 }, // 0x4E 'N'
{ 688, 13, 13, 15, 1, -12 }, // 0x4F 'O'
{ 710, 11, 13, 13, 1, -12 }, // 0x50 'P'
{ 728, 14, 16, 15, 1, -12 }, // 0x51 'Q'
{ 756, 12, 13, 13, 1, -12 }, // 0x52 'R'
{ 776, 11, 13, 11, 0, -12 }, // 0x53 'S'
{ 794, 11, 13, 11, 0, -12 }, // 0x54 'T'
{ 812, 12, 13, 14, 1, -12 }, // 0x55 'U'
{ 832, 14, 13, 13, 0, -12 }, // 0x56 'V'
{ 855, 21, 13, 21, 0, -12 }, // 0x57 'W'
{ 890, 13, 13, 13, 0, -12 }, // 0x58 'X'
{ 912, 12, 13, 12, 0, -12 }, // 0x59 'Y'
{ 932, 11, 13, 12, 1, -12 }, // 0x5A 'Z'
{ 950, 5, 16, 7, 1, -12 }, // 0x5B '['
{ 960, 9, 17, 7, -1, -14 }, // 0x5C '\'
{ 980, 5, 16, 7, 0, -12 }, // 0x5D ']'
{ 990, 9, 7, 11, 1, -9 }, // 0x5E '^'
{ 998, 9, 2, 9, 0, 1 }, // 0x5F '_'
{ 1001, 5, 3, 11, 2, -13 }, // 0x60 '`'
{ 1003, 9, 10, 11, 1, -9 }, // 0x61 'a'
{ 1015, 11, 13, 12, 1, -12 }, // 0x62 'b'
{ 1033, 9, 10, 11, 1, -9 }, // 0x63 'c'
{ 1045, 10, 13, 12, 1, -12 }, // 0x64 'd'
{ 1062, 10, 10, 11, 1, -9 }, // 0x65 'e'
{ 1075, 8, 14, 7, 0, -13 }, // 0x66 'f'
{ 1089, 10, 14, 13, 1, -9 }, // 0x67 'g'
{ 1107, 10, 13, 12, 1, -12 }, // 0x68 'h'
{ 1124, 3, 14, 5, 1, -13 }, // 0x69 'i'
{ 1130, 6, 18, 6, -2, -13 }, // 0x6A 'j'
{ 1144, 11, 13, 12, 1, -12 }, // 0x6B 'k'
{ 1162, 3, 13, 5, 1, -12 }, // 0x6C 'l'
{ 1167, 17, 10, 19, 1, -9 }, // 0x6D 'm'
{ 1189, 10, 10, 12, 1, -9 }, // 0x6E 'n'
{ 1202, 10, 10, 12, 1, -9 }, // 0x6F 'o'
{ 1215, 11, 13, 12, 1, -9 }, // 0x70 'p'
{ 1233, 10, 13, 12, 1, -9 }, // 0x71 'q'
{ 1250, 6, 10, 8, 1, -9 }, // 0x72 'r'
{ 1258, 9, 10, 10, 0, -9 }, // 0x73 's'
{ 1270, 8, 12, 8, 0, -11 }, // 0x74 't'
{ 1282, 10, 10, 12, 1, -9 }, // 0x75 'u'
{ 1295, 11, 10, 11, 0, -9 }, // 0x76 'v'
{ 1309, 17, 10, 17, 0, -9 }, // 0x77 'w'
{ 1331, 11, 10, 11, 0, -9 }, // 0x78 'x'
{ 1345, 11, 14, 11, 0, -9 }, // 0x79 'y'
{ 1365, 8, 10, 10, 1, -9 }, // 0x7A 'z'
{ 1375, 6, 16, 7, 1, -12 }, // 0x7B '{'
{ 1387, 3, 16, 6, 1, -12 }, // 0x7C '|'
{ 1393, 6, 16, 7, 0, -12 }, // 0x7D '}'
{ 1405, 9, 3, 11, 1, -7 } }; // 0x7E '~'
const GFXfont Montserrat_Bold9pt7b PROGMEM = {
(uint8_t *)Montserrat_Bold9pt7bBitmaps,
(GFXglyph *)Montserrat_Bold9pt7bGlyphs,
0x20, 0x7E, 21 };
// Approx. 2081 bytes
#endif // MONTSERRATBOLD9PT7B_H
@@ -0,0 +1,272 @@
#ifndef NOTOSANS12PT7B_H
#define NOTOSANS12PT7B_H
const uint8_t NotoSans_Regular12pt7bBitmaps[] PROGMEM = {
0x00, 0xDB, 0x6D, 0xB6, 0xDB, 0x60, 0x37, 0xC0, 0xCF, 0x3C, 0xF3, 0x8E,
0x30, 0x06, 0x30, 0x10, 0x80, 0xC6, 0x03, 0x18, 0x0C, 0x63, 0xFF, 0xFF,
0xFF, 0xC6, 0x30, 0x18, 0xC0, 0x63, 0x01, 0x8C, 0x3F, 0xFE, 0x31, 0x80,
0xC6, 0x03, 0x18, 0x0C, 0x60, 0x21, 0x00, 0x04, 0x00, 0x80, 0x7E, 0x1F,
0xF6, 0x45, 0xC8, 0x39, 0x03, 0x20, 0x7C, 0x03, 0xF0, 0x1F, 0x02, 0x70,
0x46, 0x08, 0xF1, 0x3F, 0xFE, 0x3F, 0x00, 0x80, 0x10, 0x00, 0x38, 0x0C,
0x36, 0x06, 0x31, 0x86, 0x18, 0xC3, 0x0C, 0x63, 0x06, 0x31, 0x03, 0x19,
0x81, 0x8D, 0x9E, 0x66, 0xD9, 0xBE, 0xC8, 0xC4, 0x6C, 0x20, 0x66, 0x10,
0x33, 0x08, 0x30, 0x84, 0x10, 0x46, 0x18, 0x33, 0x18, 0x0F, 0x00, 0x0F,
0x00, 0x3F, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x31, 0xC0, 0x1B,
0x80, 0x0F, 0x00, 0x1E, 0x00, 0x73, 0x06, 0x61, 0x8E, 0xE0, 0xEC, 0xC0,
0x7C, 0xE0, 0x38, 0x60, 0x7C, 0x7F, 0xEE, 0x3F, 0x87, 0xFF, 0xA0, 0x19,
0x8C, 0xC6, 0x33, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x8C, 0x63, 0x0C, 0x71,
0x80, 0xC3, 0x18, 0x63, 0x18, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x66, 0x31,
0x98, 0xCC, 0x00, 0x0E, 0x01, 0x80, 0x10, 0x42, 0x1F, 0x5F, 0xFF, 0xC3,
0x80, 0xD8, 0x3B, 0x8E, 0x30, 0x44, 0x00, 0x06, 0x00, 0xC0, 0x18, 0x03,
0x00, 0x61, 0xFF, 0xFF, 0xF8, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00, 0x76,
0x66, 0xCC, 0xFF, 0xF0, 0xDF, 0x00, 0x03, 0x81, 0x80, 0xC0, 0xC0, 0x60,
0x30, 0x30, 0x18, 0x18, 0x0C, 0x06, 0x06, 0x03, 0x01, 0x81, 0x80, 0xC0,
0xC0, 0x00, 0x1F, 0x07, 0xF1, 0xC3, 0x30, 0x76, 0x07, 0x80, 0xF0, 0x1E,
0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x06, 0xC1, 0xD8, 0x31, 0xFE,
0x1F, 0x00, 0x0C, 0x73, 0xFB, 0x4C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x0C, 0x1F, 0x0F, 0xF3, 0x83, 0x00, 0x60, 0x0E, 0x01, 0x80,
0x30, 0x0E, 0x01, 0x80, 0x60, 0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x07,
0xFF, 0xFF, 0xE0, 0x3F, 0x1F, 0xF9, 0x03, 0x00, 0x70, 0x0E, 0x01, 0x80,
0x70, 0xFC, 0x1F, 0x00, 0x38, 0x03, 0x80, 0x30, 0x06, 0x00, 0xE0, 0x3F,
0xFE, 0x7F, 0x80, 0x00, 0xE0, 0x0F, 0x00, 0x58, 0x06, 0xC0, 0x66, 0x03,
0x30, 0x31, 0x83, 0x0C, 0x18, 0x61, 0x83, 0x18, 0x19, 0xFF, 0xFF, 0xFF,
0x80, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x7F, 0xCF, 0xF9, 0x80, 0x30,
0x06, 0x00, 0xC0, 0x18, 0x03, 0xFC, 0x77, 0xC0, 0x1C, 0x01, 0x80, 0x30,
0x06, 0x00, 0xE0, 0x37, 0xFE, 0x7F, 0x00, 0x07, 0xC3, 0xF8, 0xE0, 0x18,
0x06, 0x00, 0xC0, 0x18, 0x86, 0xFE, 0xF0, 0xFC, 0x0F, 0x81, 0xE0, 0x36,
0x06, 0xC0, 0xDC, 0x39, 0xFE, 0x1F, 0x80, 0xFF, 0xFF, 0xFC, 0x01, 0x80,
0x70, 0x0C, 0x03, 0x80, 0x60, 0x0C, 0x03, 0x00, 0x60, 0x18, 0x03, 0x00,
0xE0, 0x18, 0x07, 0x00, 0xC0, 0x38, 0x00, 0x1F, 0x07, 0xF9, 0x83, 0x30,
0x36, 0x06, 0xC1, 0x8C, 0x70, 0xFC, 0x1F, 0x07, 0x79, 0x83, 0xE0, 0x3C,
0x07, 0x80, 0xF8, 0x1B, 0xDE, 0x3F, 0x80, 0x1F, 0x07, 0xF1, 0x83, 0x70,
0x7C, 0x07, 0x80, 0xF0, 0x1F, 0x03, 0x60, 0xE7, 0xEC, 0x79, 0x80, 0x30,
0x0C, 0x01, 0x80, 0x63, 0x7C, 0x7E, 0x00, 0xDF, 0x00, 0x00, 0x03, 0x7C,
0x67, 0x60, 0x00, 0x00, 0x00, 0x66, 0x6C, 0xCC, 0x00, 0x20, 0x1C, 0x0E,
0x07, 0x03, 0x81, 0xC0, 0x3C, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0x80,
0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0xC0, 0x1E, 0x00,
0xF0, 0x07, 0x80, 0x3C, 0x01, 0xC0, 0x78, 0x3C, 0x3E, 0x1E, 0x03, 0x00,
0x00, 0x3E, 0x3F, 0xE4, 0x18, 0x03, 0x00, 0xC0, 0x60, 0x18, 0x1C, 0x0E,
0x03, 0x01, 0x80, 0x60, 0x00, 0x00, 0x01, 0x80, 0x70, 0x1C, 0x00, 0x00,
0xF8, 0x00, 0xFF, 0xC0, 0x38, 0x0C, 0x0C, 0x00, 0xC3, 0x00, 0x0C, 0xC3,
0xF8, 0x98, 0xE3, 0x1A, 0x18, 0x63, 0xC6, 0x0C, 0x78, 0xC1, 0x0F, 0x18,
0x21, 0xE3, 0x0C, 0x24, 0x31, 0xCC, 0xC7, 0xCF, 0x18, 0x00, 0x01, 0x80,
0x00, 0x38, 0x00, 0x03, 0xF7, 0x80, 0x1F, 0xE0, 0x00, 0x03, 0x80, 0x07,
0x00, 0x0A, 0x00, 0x36, 0x00, 0x6C, 0x01, 0xCC, 0x03, 0x18, 0x06, 0x30,
0x18, 0x30, 0x30, 0x60, 0x7F, 0xC1, 0xFF, 0xC3, 0x01, 0x8E, 0x03, 0x98,
0x03, 0x30, 0x06, 0xC0, 0x06, 0xFF, 0x0F, 0xFC, 0xC0, 0xEC, 0x06, 0xC0,
0x6C, 0x06, 0xC0, 0x6F, 0xFC, 0xFF, 0x8C, 0x0E, 0xC0, 0x7C, 0x03, 0xC0,
0x3C, 0x07, 0xC0, 0x6F, 0xFE, 0xFF, 0x80, 0x07, 0xF0, 0xFF, 0xCF, 0x02,
0x60, 0x07, 0x00, 0x30, 0x01, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x18,
0x00, 0xC0, 0x06, 0x00, 0x38, 0x00, 0xE0, 0x03, 0xFE, 0x0F, 0xF0, 0xFF,
0x03, 0xFF, 0x0C, 0x0F, 0x30, 0x0C, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xF0,
0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x06, 0xC0, 0x1B, 0x00, 0xCC,
0x0F, 0x3F, 0xF8, 0xFF, 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x30,
0x0C, 0x03, 0xFE, 0xFF, 0xB0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03,
0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xFF, 0xBF, 0xEC, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
0x00, 0x03, 0xF8, 0x3F, 0xF1, 0xC0, 0x4C, 0x00, 0x70, 0x01, 0x80, 0x06,
0x00, 0x38, 0x00, 0xE0, 0x7F, 0x81, 0xF6, 0x00, 0xD8, 0x03, 0x60, 0x0C,
0xC0, 0x33, 0x80, 0xC7, 0xFF, 0x07, 0xFC, 0xC0, 0x1E, 0x00, 0xF0, 0x07,
0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0xF0,
0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x18, 0xFF,
0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x1E, 0xFC,
0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3,
0x0C, 0x30, 0xEF, 0xF8, 0xC0, 0x36, 0x03, 0x30, 0x31, 0x83, 0x0C, 0x30,
0x63, 0x83, 0x38, 0x1B, 0x80, 0xFC, 0x07, 0xF0, 0x31, 0xC1, 0x87, 0x0C,
0x18, 0x60, 0xE3, 0x03, 0x98, 0x0C, 0xC0, 0x38, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
0x30, 0x0C, 0x03, 0xFF, 0xFF, 0xC0, 0xF0, 0x03, 0xF8, 0x03, 0xFC, 0x01,
0xFB, 0x00, 0xFD, 0x80, 0xDE, 0xC0, 0x6F, 0x30, 0x27, 0x98, 0x33, 0xCE,
0x19, 0xE3, 0x18, 0xF1, 0x8C, 0x78, 0x66, 0x3C, 0x36, 0x1E, 0x1B, 0x0F,
0x07, 0x07, 0x83, 0x83, 0xC1, 0xC1, 0x80, 0xE0, 0x0F, 0xC0, 0x3F, 0x00,
0xFE, 0x03, 0xD8, 0x0F, 0x30, 0x3C, 0xE0, 0xF1, 0x83, 0xC3, 0x0F, 0x0E,
0x3C, 0x18, 0xF0, 0x33, 0xC0, 0xEF, 0x01, 0xBC, 0x07, 0xF0, 0x0F, 0xC0,
0x1C, 0x07, 0xE0, 0x1F, 0xF8, 0x38, 0x1C, 0x30, 0x0E, 0x60, 0x06, 0x60,
0x07, 0x60, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x60, 0x03, 0x60,
0x07, 0x60, 0x06, 0x70, 0x0E, 0x38, 0x1C, 0x1F, 0xF8, 0x0F, 0xF0, 0xFE,
0x1F, 0xFB, 0x07, 0x60, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0xC7, 0xDF,
0xF3, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x00, 0x07,
0xE0, 0x1F, 0xF8, 0x38, 0x1C, 0x30, 0x0E, 0x60, 0x06, 0x60, 0x07, 0x60,
0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x60,
0x06, 0x70, 0x0E, 0x38, 0x1C, 0x1F, 0xF8, 0x0F, 0xF0, 0x00, 0x70, 0x00,
0x38, 0x00, 0x1C, 0x00, 0x0E, 0xFF, 0x0F, 0xFC, 0xC1, 0xCC, 0x0E, 0xC0,
0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8F, 0xF0, 0xC3, 0x0C, 0x18, 0xC1,
0xCC, 0x0C, 0xC0, 0xEC, 0x06, 0xC0, 0x70, 0x1F, 0x8F, 0xF9, 0x81, 0x70,
0x0E, 0x00, 0xC0, 0x1C, 0x01, 0xE0, 0x1F, 0x00, 0xF8, 0x07, 0x00, 0x70,
0x06, 0x00, 0xE0, 0x37, 0xFE, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0,
0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01,
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0xC0,
0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03,
0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xF0, 0x1D, 0xC0, 0xC7,
0xFC, 0x1F, 0xC0, 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x98, 0x06, 0x30, 0x38,
0xC0, 0xC3, 0x03, 0x06, 0x1C, 0x18, 0x60, 0x61, 0x80, 0xCC, 0x03, 0x30,
0x0C, 0xC0, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x03, 0x00, 0xE0, 0x30, 0x1D,
0x81, 0xC0, 0x66, 0x07, 0x81, 0x98, 0x1E, 0x0E, 0x70, 0xD8, 0x30, 0xC3,
0x30, 0xC3, 0x0C, 0xC3, 0x0C, 0x33, 0x1C, 0x39, 0x8C, 0x60, 0x66, 0x19,
0x81, 0x98, 0x66, 0x06, 0xC1, 0xB8, 0x0F, 0x03, 0xC0, 0x3C, 0x0F, 0x00,
0xF0, 0x3C, 0x03, 0x80, 0xE0, 0x06, 0x01, 0x80, 0xE0, 0x19, 0xC0, 0xC3,
0x03, 0x06, 0x18, 0x18, 0xE0, 0x33, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x00,
0x1E, 0x00, 0xDC, 0x03, 0x30, 0x18, 0x60, 0xE1, 0x83, 0x03, 0x18, 0x0E,
0xE0, 0x1C, 0xC0, 0x1B, 0x01, 0xDC, 0x0C, 0x60, 0xE3, 0x86, 0x0C, 0x60,
0x73, 0x01, 0xB0, 0x0F, 0x80, 0x38, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01,
0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0xFF, 0xEF, 0xFE, 0x00, 0xE0, 0x0C,
0x01, 0xC0, 0x38, 0x03, 0x00, 0x70, 0x0E, 0x00, 0xC0, 0x1C, 0x03, 0x80,
0x30, 0x07, 0x00, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xF1, 0x8C, 0x63,
0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xFF, 0x80, 0xC0, 0x30,
0x18, 0x0C, 0x03, 0x01, 0x80, 0x60, 0x30, 0x18, 0x06, 0x03, 0x01, 0x80,
0x60, 0x30, 0x0C, 0x06, 0x03, 0x80, 0xFF, 0xC6, 0x31, 0x8C, 0x63, 0x18,
0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC7, 0xFF, 0x80, 0x04, 0x00, 0xE0, 0x0A,
0x01, 0xB0, 0x19, 0x03, 0x18, 0x30, 0x86, 0x0C, 0x60, 0x4C, 0x06, 0xC0,
0x30, 0xFF, 0xFF, 0xF0, 0xE3, 0x0C, 0x30, 0x1F, 0x1F, 0xE2, 0x0C, 0x03,
0x00, 0xC0, 0xF3, 0xFD, 0x83, 0xC0, 0xF0, 0x3C, 0x1D, 0xDF, 0x7E, 0x40,
0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x9E, 0x37, 0xE7, 0x06, 0xE0,
0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1F, 0x06, 0xFF, 0xDB,
0xF0, 0x0F, 0x4F, 0xE7, 0x09, 0x80, 0x60, 0x38, 0x0C, 0x03, 0x00, 0xE0,
0x18, 0x07, 0x00, 0xFE, 0x1F, 0x80, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30,
0x06, 0x1C, 0xCF, 0xFB, 0x87, 0x60, 0x7C, 0x0F, 0x81, 0xE0, 0x3C, 0x07,
0xC0, 0xD8, 0x1B, 0x03, 0x3F, 0xA3, 0xE4, 0x0F, 0x07, 0xF1, 0xC3, 0x30,
0x36, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x0C, 0x01, 0xC0, 0x1F, 0xE1,
0xFC, 0x0F, 0x8F, 0xC6, 0x03, 0x01, 0x81, 0xFB, 0xFC, 0x30, 0x18, 0x0C,
0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x0E, 0x27,
0xF5, 0xC3, 0xB0, 0x36, 0x07, 0xC0, 0xF0, 0x1E, 0x03, 0xE0, 0x6C, 0x0D,
0x81, 0x9F, 0xF1, 0xF6, 0x00, 0xC0, 0x18, 0x03, 0x60, 0xEF, 0xF8, 0x38,
0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x9E, 0x37, 0xF7, 0x06,
0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0,
0x78, 0x0C, 0xF0, 0xFF, 0xFF, 0xFF, 0xC0, 0x18, 0xC0, 0x01, 0x8C, 0x63,
0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x33, 0xFB, 0x00, 0xC0, 0x30,
0x0C, 0x03, 0x00, 0xC0, 0x30, 0x7C, 0x1B, 0x0C, 0xC6, 0x33, 0x0D, 0x83,
0xE0, 0xEC, 0x33, 0x8C, 0x73, 0x0C, 0xC1, 0xB0, 0x70, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0xCF, 0x0F, 0x37, 0xEF, 0xEE, 0x1E, 0x1F, 0x83, 0x83, 0xC0,
0xC0, 0xF0, 0x30, 0x3C, 0x0C, 0x0F, 0x03, 0x03, 0xC0, 0xC0, 0xF0, 0x30,
0x3C, 0x0C, 0x0F, 0x03, 0x03, 0xC0, 0xC0, 0xC0, 0xCF, 0x1B, 0xFB, 0x83,
0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0,
0x3C, 0x06, 0x0F, 0x03, 0xFC, 0x70, 0xE6, 0x06, 0x60, 0x3E, 0x03, 0xC0,
0x3C, 0x03, 0xE0, 0x36, 0x07, 0x70, 0x63, 0xFC, 0x1F, 0x80, 0xCF, 0x1B,
0xF3, 0x83, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F,
0x83, 0x7F, 0xED, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00,
0x00, 0x0E, 0x27, 0xF5, 0xC3, 0xB0, 0x3E, 0x07, 0xC0, 0xF0, 0x1E, 0x03,
0xE0, 0x6C, 0x0D, 0x81, 0x9F, 0xF1, 0xF6, 0x00, 0xC0, 0x18, 0x03, 0x00,
0x60, 0x0C, 0x01, 0x80, 0xCF, 0xBF, 0xC7, 0x0C, 0x18, 0x30, 0x60, 0xC1,
0x83, 0x06, 0x0C, 0x00, 0x1E, 0x3F, 0xF8, 0x38, 0x0E, 0x03, 0xC0, 0xF8,
0x0E, 0x01, 0x80, 0xC0, 0x7E, 0xFF, 0xE0, 0x10, 0x30, 0x7F, 0xFF, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1D, 0x1F, 0xC0, 0xF8,
0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xC0, 0xF8, 0x1F,
0x03, 0xBF, 0xB7, 0xE6, 0xC0, 0x3E, 0x07, 0x60, 0x66, 0x06, 0x30, 0xC3,
0x0C, 0x30, 0xC1, 0x98, 0x19, 0x81, 0xB0, 0x0F, 0x00, 0xF0, 0x06, 0x00,
0xC0, 0xC0, 0xD8, 0x38, 0x36, 0x1E, 0x0D, 0x87, 0x86, 0x61, 0xB1, 0x8C,
0x4C, 0x63, 0x33, 0x38, 0xCC, 0x6C, 0x33, 0x1B, 0x07, 0x86, 0xC1, 0xE0,
0xA0, 0x78, 0x38, 0x0C, 0x0E, 0x00, 0x60, 0x77, 0x06, 0x30, 0xC1, 0x9C,
0x0D, 0x80, 0xF0, 0x06, 0x00, 0xF0, 0x0D, 0x81, 0x9C, 0x30, 0xC7, 0x06,
0xE0, 0x70, 0xC0, 0x3E, 0x07, 0x60, 0x66, 0x06, 0x30, 0xC3, 0x0C, 0x38,
0xC1, 0x98, 0x19, 0x80, 0xD8, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06,
0x00, 0xC0, 0x1C, 0x0F, 0x80, 0xE0, 0x00, 0xFF, 0xFF, 0xC0, 0xE0, 0x60,
0x60, 0x60, 0x30, 0x30, 0x30, 0x38, 0x18, 0x1F, 0xFF, 0xF8, 0x02, 0x3C,
0x60, 0xC1, 0x83, 0x06, 0x0C, 0x31, 0xE3, 0x03, 0x83, 0x03, 0x06, 0x0C,
0x18, 0x30, 0x60, 0xF0, 0x20, 0xFF, 0xFF, 0xFF, 0x81, 0xE0, 0xC1, 0x83,
0x06, 0x0C, 0x18, 0x38, 0x3C, 0x18, 0xE3, 0x86, 0x0C, 0x18, 0x30, 0x60,
0xC7, 0x08, 0x00, 0x78, 0x3F, 0xEE, 0x1F, 0x80 };
const GFXglyph NotoSans_Regular12pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 3, 17, 6, 2, -16 }, // 0x21 '!'
{ 8, 6, 6, 10, 2, -16 }, // 0x22 '"'
{ 13, 14, 17, 15, 1, -16 }, // 0x23 '#'
{ 43, 11, 19, 13, 1, -17 }, // 0x24 '$'
{ 70, 17, 17, 20, 1, -16 }, // 0x25 '%'
{ 107, 16, 17, 17, 1, -16 }, // 0x26 '&'
{ 141, 2, 6, 5, 2, -16 }, // 0x27 '''
{ 143, 5, 21, 7, 1, -16 }, // 0x28 '('
{ 157, 5, 21, 7, 1, -16 }, // 0x29 ')'
{ 171, 11, 11, 13, 1, -17 }, // 0x2A '*'
{ 187, 11, 11, 13, 1, -13 }, // 0x2B '+'
{ 203, 4, 6, 6, 1, -2 }, // 0x2C ','
{ 206, 6, 2, 8, 1, -6 }, // 0x2D '-'
{ 208, 3, 3, 6, 2, -2 }, // 0x2E '.'
{ 210, 9, 17, 9, 0, -16 }, // 0x2F '/'
{ 230, 11, 17, 13, 1, -16 }, // 0x30 '0'
{ 254, 6, 17, 13, 2, -16 }, // 0x31 '1'
{ 267, 11, 17, 13, 1, -16 }, // 0x32 '2'
{ 291, 11, 17, 13, 1, -16 }, // 0x33 '3'
{ 315, 13, 17, 13, 0, -16 }, // 0x34 '4'
{ 343, 11, 17, 13, 1, -16 }, // 0x35 '5'
{ 367, 11, 17, 13, 1, -16 }, // 0x36 '6'
{ 391, 11, 17, 13, 1, -16 }, // 0x37 '7'
{ 415, 11, 17, 13, 1, -16 }, // 0x38 '8'
{ 439, 11, 17, 13, 1, -16 }, // 0x39 '9'
{ 463, 3, 13, 6, 2, -12 }, // 0x3A ':'
{ 468, 4, 16, 6, 1, -12 }, // 0x3B ';'
{ 476, 11, 11, 13, 1, -13 }, // 0x3C '<'
{ 492, 11, 6, 13, 1, -10 }, // 0x3D '='
{ 501, 11, 11, 13, 1, -13 }, // 0x3E '>'
{ 517, 10, 17, 10, 0, -16 }, // 0x3F '?'
{ 539, 19, 19, 21, 1, -16 }, // 0x40 '@'
{ 585, 15, 17, 15, 0, -16 }, // 0x41 'A'
{ 617, 12, 17, 15, 2, -16 }, // 0x42 'B'
{ 643, 13, 17, 15, 1, -16 }, // 0x43 'C'
{ 671, 14, 17, 17, 2, -16 }, // 0x44 'D'
{ 701, 10, 17, 13, 2, -16 }, // 0x45 'E'
{ 723, 10, 17, 12, 2, -16 }, // 0x46 'F'
{ 745, 14, 17, 17, 1, -16 }, // 0x47 'G'
{ 775, 13, 17, 17, 2, -16 }, // 0x48 'H'
{ 803, 6, 17, 8, 1, -16 }, // 0x49 'I'
{ 816, 6, 21, 6, -2, -16 }, // 0x4A 'J'
{ 832, 13, 17, 15, 2, -16 }, // 0x4B 'K'
{ 860, 10, 17, 12, 2, -16 }, // 0x4C 'L'
{ 882, 17, 17, 21, 2, -16 }, // 0x4D 'M'
{ 919, 14, 17, 18, 2, -16 }, // 0x4E 'N'
{ 949, 16, 17, 18, 1, -16 }, // 0x4F 'O'
{ 983, 11, 17, 14, 2, -16 }, // 0x50 'P'
{ 1007, 16, 21, 18, 1, -16 }, // 0x51 'Q'
{ 1049, 12, 17, 15, 2, -16 }, // 0x52 'R'
{ 1075, 11, 17, 13, 1, -16 }, // 0x53 'S'
{ 1099, 13, 17, 13, 0, -16 }, // 0x54 'T'
{ 1127, 13, 17, 17, 2, -16 }, // 0x55 'U'
{ 1155, 14, 17, 14, 0, -16 }, // 0x56 'V'
{ 1185, 22, 17, 22, 0, -16 }, // 0x57 'W'
{ 1232, 14, 17, 14, 0, -16 }, // 0x58 'X'
{ 1262, 13, 17, 13, 0, -16 }, // 0x59 'Y'
{ 1290, 12, 17, 13, 1, -16 }, // 0x5A 'Z'
{ 1316, 5, 21, 8, 2, -16 }, // 0x5B '['
{ 1330, 9, 17, 9, 0, -16 }, // 0x5C '\'
{ 1350, 5, 21, 8, 1, -16 }, // 0x5D ']'
{ 1364, 12, 11, 13, 1, -16 }, // 0x5E '^'
{ 1381, 10, 2, 10, 0, 3 }, // 0x5F '_'
{ 1384, 5, 4, 7, 1, -17 }, // 0x60 '`'
{ 1387, 10, 13, 13, 1, -12 }, // 0x61 'a'
{ 1404, 11, 18, 14, 2, -17 }, // 0x62 'b'
{ 1429, 10, 13, 11, 1, -12 }, // 0x63 'c'
{ 1446, 11, 18, 14, 1, -17 }, // 0x64 'd'
{ 1471, 11, 13, 13, 1, -12 }, // 0x65 'e'
{ 1489, 9, 18, 8, 0, -17 }, // 0x66 'f'
{ 1510, 11, 19, 14, 1, -12 }, // 0x67 'g'
{ 1537, 11, 18, 15, 2, -17 }, // 0x68 'h'
{ 1562, 2, 17, 6, 2, -16 }, // 0x69 'i'
{ 1567, 5, 23, 6, -1, -16 }, // 0x6A 'j'
{ 1582, 10, 18, 13, 2, -17 }, // 0x6B 'k'
{ 1605, 2, 18, 6, 2, -17 }, // 0x6C 'l'
{ 1610, 18, 13, 22, 2, -12 }, // 0x6D 'm'
{ 1640, 11, 13, 15, 2, -12 }, // 0x6E 'n'
{ 1658, 12, 13, 14, 1, -12 }, // 0x6F 'o'
{ 1678, 11, 19, 14, 2, -12 }, // 0x70 'p'
{ 1705, 11, 19, 14, 1, -12 }, // 0x71 'q'
{ 1732, 7, 13, 10, 2, -12 }, // 0x72 'r'
{ 1744, 9, 13, 11, 1, -12 }, // 0x73 's'
{ 1759, 8, 15, 8, 0, -14 }, // 0x74 't'
{ 1774, 11, 13, 15, 2, -12 }, // 0x75 'u'
{ 1792, 12, 13, 12, 0, -12 }, // 0x76 'v'
{ 1812, 18, 13, 18, 0, -12 }, // 0x77 'w'
{ 1842, 12, 13, 12, 0, -12 }, // 0x78 'x'
{ 1862, 12, 19, 12, 0, -12 }, // 0x79 'y'
{ 1891, 9, 13, 11, 1, -12 }, // 0x7A 'z'
{ 1906, 7, 21, 9, 1, -16 }, // 0x7B '{'
{ 1925, 1, 24, 13, 6, -17 }, // 0x7C '|'
{ 1928, 7, 21, 9, 1, -16 }, // 0x7D '}'
{ 1947, 11, 3, 13, 1, -9 } }; // 0x7E '~'
const GFXfont NotoSans_Regular12pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular12pt7bBitmaps,
(GFXglyph *)NotoSans_Regular12pt7bGlyphs,
0x20, 0x7E, 32 };
// Approx. 2624 bytes
#endif // NOTOSANS12PT7B_H
@@ -0,0 +1,464 @@
#ifndef NOTOSANS18PT7B_H
#define NOTOSANS18PT7B_H
const uint8_t NotoSans_Regular18pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFE, 0xEE, 0xEE, 0xEE, 0xEE, 0xE6, 0x66, 0x66, 0x00, 0x0E,
0xFF, 0xF4, 0xF1, 0xFC, 0x76, 0x1D, 0x87, 0x61, 0xD8, 0x76, 0x1D, 0x87,
0x61, 0x80, 0x00, 0xC1, 0xC0, 0x0E, 0x0C, 0x00, 0x70, 0x60, 0x03, 0x83,
0x00, 0x18, 0x38, 0x00, 0xC1, 0xC0, 0x0E, 0x0E, 0x0F, 0xFF, 0xFF, 0x7F,
0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0xC1, 0xC0, 0x06, 0x0E, 0x00, 0x70, 0x60,
0x03, 0x83, 0x00, 0x18, 0x38, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF7, 0xFF,
0xFF, 0x83, 0x83, 0x00, 0x1C, 0x38, 0x00, 0xC1, 0xC0, 0x06, 0x0E, 0x00,
0x70, 0x60, 0x03, 0x83, 0x00, 0x1C, 0x38, 0x00, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0x03, 0xE0, 0x1F, 0xFE, 0x3F, 0xFE, 0x79, 0x8E, 0xF1, 0x80,
0xE1, 0x80, 0xE1, 0x80, 0xF1, 0x80, 0x79, 0x80, 0x7F, 0x80, 0x3F, 0xE0,
0x0F, 0xF8, 0x01, 0xFE, 0x01, 0xBE, 0x01, 0x8F, 0x01, 0x87, 0x01, 0x87,
0x01, 0x87, 0x81, 0x8F, 0xFD, 0xFE, 0xFF, 0xFC, 0x7F, 0xF0, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x08, 0x00, 0x00, 0x0F, 0xC0, 0x0E,
0x07, 0xF8, 0x07, 0x03, 0x86, 0x01, 0xC0, 0xE1, 0xC0, 0xE0, 0x38, 0x70,
0x30, 0x0C, 0x1C, 0x1C, 0x03, 0x03, 0x06, 0x00, 0xC0, 0xC3, 0x80, 0x30,
0x31, 0xC0, 0x0C, 0x1C, 0x70, 0x03, 0x87, 0x39, 0xF8, 0xE1, 0xCE, 0xFF,
0x1C, 0xE7, 0x38, 0xE7, 0xF9, 0x8C, 0x38, 0xFC, 0xE7, 0x06, 0x00, 0x31,
0xC1, 0x80, 0x1C, 0x70, 0x70, 0x0E, 0x1C, 0x1C, 0x03, 0x87, 0x07, 0x01,
0xC1, 0xC1, 0x80, 0x70, 0x70, 0x60, 0x38, 0x0C, 0x38, 0x0C, 0x03, 0x8E,
0x07, 0x00, 0x7F, 0x03, 0x80, 0x0F, 0x80, 0x00, 0x80, 0x00, 0x0F, 0xF8,
0x00, 0x1F, 0xFC, 0x00, 0x1E, 0x3C, 0x00, 0x3C, 0x1E, 0x00, 0x38, 0x0E,
0x00, 0x38, 0x0E, 0x00, 0x3C, 0x1E, 0x00, 0x1C, 0x1C, 0x00, 0x1E, 0x3C,
0x00, 0x0F, 0xF0, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x1F, 0xE0,
0x1C, 0x3C, 0xF0, 0x1C, 0x78, 0x78, 0x3C, 0xF0, 0x3C, 0x38, 0xE0, 0x1E,
0x38, 0xE0, 0x0F, 0x70, 0xE0, 0x07, 0xF0, 0xE0, 0x03, 0xE0, 0xF0, 0x03,
0xE0, 0xF0, 0x07, 0xF0, 0x7E, 0x7F, 0x78, 0x3F, 0xFE, 0x3C, 0x1F, 0xF8,
0x1F, 0xFF, 0x66, 0x66, 0x66, 0x60, 0x07, 0x87, 0x03, 0x83, 0x81, 0xC1,
0xC0, 0xE0, 0xF0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x07, 0x83, 0xC1, 0xE0,
0xF0, 0x78, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xE0, 0x70, 0x38, 0x1E, 0x07,
0x03, 0xC0, 0xE0, 0x38, 0x0C, 0xF0, 0x70, 0x38, 0x38, 0x1C, 0x1C, 0x0E,
0x0E, 0x0E, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x0F, 0x0E, 0x0E, 0x0E, 0x1E, 0x1C, 0x3C, 0x38, 0x78, 0x70, 0xE0,
0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x02, 0x0E,
0x09, 0xF3, 0x7E, 0xFF, 0xFF, 0x9F, 0xFE, 0x01, 0xF0, 0x00, 0xDC, 0x00,
0xEE, 0x00, 0xE3, 0x80, 0xF1, 0xE0, 0x78, 0x78, 0x08, 0x30, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x3C, 0xE3, 0x8E, 0x71,
0xC7, 0x18, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xEF, 0xFF, 0x40, 0x00, 0x78,
0x03, 0x80, 0x1C, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x07, 0x00, 0x38, 0x03,
0xC0, 0x1C, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x38, 0x01, 0xC0,
0x0E, 0x00, 0xE0, 0x07, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x0E,
0x00, 0xF0, 0x00, 0x00, 0x80, 0x0F, 0xF0, 0x1F, 0xF8, 0x3C, 0x3C, 0x78,
0x1E, 0x70, 0x0E, 0x70, 0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0x70, 0x0F, 0x70, 0x0E, 0x38,
0x1E, 0x3E, 0x7C, 0x1F, 0xF8, 0x0F, 0xF0, 0x03, 0xC1, 0xF1, 0xFC, 0xF7,
0x79, 0xFC, 0xF6, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0x01, 0x00, 0x1F, 0xF0, 0x7F, 0xFC, 0xF8, 0x3C, 0x60,
0x1E, 0x40, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00,
0x1E, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x00, 0xE0, 0x01,
0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0x3F, 0xF0, 0x7F,
0xFC, 0xF8, 0x3C, 0x40, 0x1E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00,
0x0E, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0xF8, 0x1F, 0xE0, 0x1F, 0xF8, 0x01,
0xFC, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00,
0x07, 0x00, 0x0F, 0x80, 0x1E, 0xF8, 0x7E, 0xFF, 0xFC, 0x7F, 0xF0, 0x00,
0x1E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x01, 0xF8, 0x00, 0xEE, 0x00, 0x73,
0x80, 0x1C, 0xE0, 0x0E, 0x38, 0x07, 0x0E, 0x01, 0xC3, 0x80, 0xE0, 0xE0,
0x70, 0x38, 0x1C, 0x0E, 0x0E, 0x03, 0x87, 0x00, 0xE1, 0x80, 0x38, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03,
0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x3F, 0xFC, 0x3F, 0xFC,
0x3F, 0xFC, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00,
0x70, 0x00, 0x70, 0x00, 0x7F, 0xF0, 0x7F, 0xFC, 0x30, 0x7E, 0x00, 0x1E,
0x00, 0x0F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07,
0x00, 0x0E, 0x80, 0x1E, 0xF8, 0x7C, 0xFF, 0xF8, 0x7F, 0xF0, 0x00, 0x10,
0x01, 0xFF, 0x01, 0xFF, 0x83, 0xE0, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xE0,
0x00, 0xE0, 0x00, 0x70, 0x00, 0x78, 0x00, 0x38, 0x78, 0x1C, 0xFF, 0x8E,
0xFF, 0xE7, 0xC0, 0x73, 0xC0, 0x1D, 0xE0, 0x0E, 0xE0, 0x07, 0x70, 0x03,
0xF8, 0x01, 0xDC, 0x00, 0xE7, 0x00, 0x73, 0x80, 0x38, 0xE0, 0x38, 0x7C,
0x7C, 0x1F, 0xFC, 0x03, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x07, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x3C,
0x00, 0x38, 0x00, 0x78, 0x00, 0x70, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xE0,
0x01, 0xC0, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x00,
0x0F, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x01, 0x80, 0x0F, 0xF8,
0x3F, 0xFC, 0x78, 0x1E, 0x70, 0x0E, 0x70, 0x0F, 0x70, 0x07, 0x70, 0x0F,
0x70, 0x0E, 0x78, 0x1E, 0x3C, 0x3C, 0x1F, 0xF8, 0x0F, 0xE0, 0x0F, 0xF0,
0x3E, 0xFC, 0x78, 0x1E, 0xF0, 0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0x7C, 0x1E, 0x3F, 0xFC, 0x1F, 0xF8,
0x01, 0x00, 0x0F, 0xF0, 0x3F, 0xF8, 0x7C, 0x3C, 0x70, 0x1E, 0xF0, 0x0E,
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0xF0, 0x0F, 0x78, 0x3F, 0x3F, 0xF7, 0x1F, 0xE7, 0x07, 0x07, 0x00, 0x07,
0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x3C, 0x41, 0xF8,
0x3F, 0xF0, 0x3F, 0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
0xFF, 0xF4, 0x39, 0xF7, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x39, 0xE7, 0x1C, 0x71, 0x8E, 0x30, 0x00, 0x03, 0x00, 0x0F,
0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xF8, 0x00,
0xE0, 0x00, 0xF8, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x7E,
0x00, 0x1F, 0x00, 0x07, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xC0, 0x00, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0,
0x00, 0x7C, 0x00, 0x1F, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x03, 0xF0,
0x0F, 0xC0, 0x7F, 0x00, 0xF8, 0x00, 0xE0, 0x00, 0x80, 0x00, 0x01, 0x00,
0xFF, 0xCF, 0xFF, 0x9E, 0x1F, 0x40, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07,
0x00, 0x1C, 0x00, 0xF0, 0x03, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x38,
0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0x20, 0x00, 0x00, 0x3F,
0xE0, 0x00, 0x0F, 0xFF, 0xC0, 0x03, 0xF0, 0x3E, 0x00, 0x78, 0x00, 0xF0,
0x0E, 0x00, 0x03, 0x81, 0xC0, 0x00, 0x1C, 0x38, 0x00, 0x00, 0xC3, 0x81,
0xFF, 0x0E, 0x70, 0x3F, 0xF0, 0x67, 0x07, 0x07, 0x06, 0x60, 0xE0, 0x70,
0x7E, 0x0C, 0x07, 0x07, 0xE1, 0xC0, 0x70, 0x7E, 0x1C, 0x07, 0x07, 0xE1,
0xC0, 0x70, 0x6E, 0x1C, 0x07, 0x06, 0xE1, 0xC0, 0xF0, 0xEE, 0x0C, 0x0F,
0x0E, 0xE0, 0xE1, 0xB1, 0xC6, 0x07, 0xFB, 0xF8, 0x70, 0x3F, 0x1F, 0x07,
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x1E, 0x00,
0x08, 0x00, 0xFC, 0x0F, 0x80, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFC, 0x00,
0x00, 0x38, 0x00, 0x01, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x3F, 0x00, 0x00,
0xEE, 0x00, 0x03, 0xB8, 0x00, 0x1C, 0xE0, 0x00, 0x71, 0xC0, 0x03, 0x87,
0x00, 0x0E, 0x1C, 0x00, 0x38, 0x38, 0x01, 0xC0, 0xE0, 0x07, 0x01, 0xC0,
0x3C, 0x07, 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xF8, 0x1F, 0xFF, 0xE0, 0x70,
0x03, 0xC1, 0xC0, 0x07, 0x0E, 0x00, 0x1C, 0x38, 0x00, 0x79, 0xE0, 0x00,
0xE7, 0x00, 0x03, 0xDC, 0x00, 0x07, 0xE0, 0x00, 0x1C, 0xFF, 0xF8, 0x3F,
0xFF, 0x8F, 0xFF, 0xF3, 0xC0, 0x3E, 0xF0, 0x07, 0xBC, 0x00, 0xEF, 0x00,
0x3B, 0xC0, 0x0E, 0xF0, 0x07, 0xBC, 0x01, 0xCF, 0x07, 0xE3, 0xFF, 0xE0,
0xFF, 0xFE, 0x3C, 0x07, 0xCF, 0x00, 0x7B, 0xC0, 0x0F, 0xF0, 0x03, 0xFC,
0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x0F, 0xF0, 0x03, 0xFC, 0x01, 0xEF, 0xFF,
0xF3, 0xFF, 0xF8, 0xFF, 0xF8, 0x00, 0x00, 0x18, 0x00, 0x3F, 0xF8, 0x1F,
0xFF, 0x87, 0xE1, 0xE1, 0xF0, 0x04, 0x78, 0x00, 0x0E, 0x00, 0x03, 0xC0,
0x00, 0x70, 0x00, 0x0E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00,
0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0xF0, 0x00, 0x0E, 0x00,
0x01, 0xC0, 0x00, 0x3C, 0x00, 0x03, 0x80, 0x00, 0x78, 0x00, 0x07, 0xC0,
0x00, 0x7F, 0xBE, 0x07, 0xFF, 0xC0, 0x3F, 0xF8, 0xFF, 0xF8, 0x07, 0xFF,
0xF0, 0x3F, 0xFF, 0xE1, 0xE0, 0x0F, 0x8F, 0x00, 0x3E, 0x78, 0x00, 0xF3,
0xC0, 0x03, 0xDE, 0x00, 0x1E, 0xF0, 0x00, 0x77, 0x80, 0x03, 0xBC, 0x00,
0x1D, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F, 0xC0, 0x01, 0xDE,
0x00, 0x0E, 0xF0, 0x00, 0x77, 0x80, 0x07, 0xBC, 0x00, 0x39, 0xE0, 0x03,
0xCF, 0x00, 0x3C, 0x78, 0x07, 0xC3, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0xFF,
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C,
0x00, 0xF0, 0x03, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00,
0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0x00, 0x04, 0x00, 0x0F, 0xFF, 0x81,
0xFF, 0xFE, 0x1F, 0xC3, 0xE1, 0xF0, 0x01, 0x1E, 0x00, 0x00, 0xF0, 0x00,
0x0F, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x3C, 0x00, 0x01, 0xE0,
0x00, 0x0F, 0x00, 0x00, 0x70, 0x07, 0xFF, 0x80, 0x3F, 0xFE, 0x01, 0xFF,
0xF0, 0x00, 0x3B, 0x80, 0x01, 0xDC, 0x00, 0x0E, 0xF0, 0x00, 0x73, 0x80,
0x03, 0x9E, 0x00, 0x1C, 0x7C, 0x00, 0xE1, 0xFE, 0x3F, 0x07, 0xFF, 0xF8,
0x0F, 0xFF, 0x00, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00,
0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0,
0x00, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00,
0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xF0, 0xFF, 0xFF, 0xF1, 0xE0, 0x78, 0x1E,
0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81,
0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE3, 0xFF,
0xFF, 0xC0, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03,
0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0,
0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x7F, 0xFB,
0xF8, 0xF0, 0xF0, 0x03, 0xDE, 0x00, 0xF3, 0xC0, 0x3C, 0x78, 0x0F, 0x0F,
0x01, 0xC1, 0xE0, 0x70, 0x3C, 0x1C, 0x07, 0x87, 0x00, 0xF1, 0xE0, 0x1E,
0x78, 0x03, 0xDE, 0x00, 0x7F, 0xC0, 0x0F, 0xFC, 0x01, 0xFB, 0x80, 0x3C,
0x78, 0x07, 0x87, 0x80, 0xF0, 0x78, 0x1E, 0x07, 0x03, 0xC0, 0xF0, 0x78,
0x0F, 0x0F, 0x00, 0xF1, 0xE0, 0x1E, 0x3C, 0x01, 0xE7, 0x80, 0x1E, 0xF0,
0x01, 0xE0, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E,
0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80,
0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03,
0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0xF8, 0x00, 0x07, 0xFF, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0xFF, 0xF0,
0x00, 0x77, 0xEE, 0x00, 0x1D, 0xFB, 0x80, 0x07, 0xFE, 0x70, 0x03, 0xBF,
0x9C, 0x00, 0xEF, 0xE7, 0x00, 0x33, 0xF8, 0xE0, 0x1C, 0xFE, 0x38, 0x07,
0x3F, 0x8E, 0x03, 0x8F, 0xE1, 0xC0, 0xE3, 0xF8, 0x70, 0x38, 0xFE, 0x0E,
0x1C, 0x3F, 0x83, 0x87, 0x0F, 0xE0, 0xE3, 0x83, 0xF8, 0x1C, 0xE0, 0xFE,
0x07, 0x38, 0x3F, 0x81, 0xFC, 0x0F, 0xE0, 0x3F, 0x03, 0xF8, 0x0F, 0x80,
0xFE, 0x01, 0xE0, 0x3F, 0x80, 0x78, 0x0F, 0xE0, 0x1C, 0x03, 0xC0, 0xF8,
0x00, 0x7F, 0x80, 0x07, 0xFC, 0x00, 0x7F, 0xC0, 0x07, 0xFE, 0x00, 0x7E,
0xF0, 0x07, 0xE7, 0x00, 0x7E, 0x78, 0x07, 0xE3, 0xC0, 0x7E, 0x1C, 0x07,
0xE1, 0xE0, 0x7E, 0x0F, 0x07, 0xE0, 0x70, 0x7E, 0x07, 0x87, 0xE0, 0x3C,
0x7E, 0x01, 0xC7, 0xE0, 0x1E, 0x7E, 0x00, 0xE7, 0xE0, 0x0F, 0x3E, 0x00,
0x7B, 0xE0, 0x03, 0xBE, 0x00, 0x3F, 0xE0, 0x01, 0xFE, 0x00, 0x0F, 0xE0,
0x00, 0xF0, 0x00, 0x10, 0x00, 0x07, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0xFC,
0x1F, 0x81, 0xE0, 0x07, 0x87, 0x80, 0x07, 0x1E, 0x00, 0x0F, 0x3C, 0x00,
0x0E, 0x70, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x80, 0x00,
0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07,
0xF0, 0x00, 0x0E, 0xE0, 0x00, 0x1D, 0xC0, 0x00, 0x7B, 0xC0, 0x00, 0xE3,
0x80, 0x03, 0xC7, 0x80, 0x0F, 0x07, 0x80, 0x3E, 0x07, 0xF3, 0xF8, 0x07,
0xFF, 0xE0, 0x03, 0xFF, 0x00, 0xFF, 0xF0, 0x7F, 0xFE, 0x3F, 0xFF, 0x9E,
0x03, 0xEF, 0x00, 0xF7, 0x80, 0x3B, 0xC0, 0x1D, 0xE0, 0x0F, 0xF0, 0x07,
0x78, 0x03, 0xBC, 0x03, 0xDE, 0x03, 0xCF, 0xFF, 0xE7, 0xFF, 0xC3, 0xFF,
0x81, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F,
0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x10, 0x00, 0x07, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0xFC, 0x1F, 0x81, 0xE0,
0x07, 0x87, 0x80, 0x07, 0x1E, 0x00, 0x0F, 0x3C, 0x00, 0x0E, 0x70, 0x00,
0x1F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00,
0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0E,
0xE0, 0x00, 0x1D, 0xC0, 0x00, 0x7B, 0xC0, 0x00, 0xE3, 0x80, 0x03, 0xC7,
0x80, 0x0F, 0x07, 0x80, 0x3E, 0x07, 0xF3, 0xF8, 0x07, 0xFF, 0xE0, 0x03,
0xFF, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, 0xFF, 0xF0, 0x3F, 0xFF, 0x0F,
0xFF, 0xE3, 0xC0, 0x3C, 0xF0, 0x07, 0x3C, 0x01, 0xCF, 0x00, 0x7B, 0xC0,
0x1E, 0xF0, 0x07, 0x3C, 0x01, 0xCF, 0x00, 0xF3, 0xC0, 0xF8, 0xFF, 0xFC,
0x3F, 0xFC, 0x0F, 0xFF, 0x03, 0xC1, 0xE0, 0xF0, 0x38, 0x3C, 0x0F, 0x0F,
0x01, 0xC3, 0xC0, 0x78, 0xF0, 0x0F, 0x3C, 0x01, 0xCF, 0x00, 0x7B, 0xC0,
0x0E, 0xF0, 0x03, 0xC0, 0x00, 0x80, 0x1F, 0xFC, 0x3F, 0xFE, 0x7E, 0x3E,
0x70, 0x04, 0xF0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0x70, 0x00,
0x78, 0x00, 0x3F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x7E,
0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x07, 0x00, 0x0F, 0x00, 0x0E,
0x80, 0x1E, 0xFC, 0xFC, 0xFF, 0xF8, 0x7F, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x80, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38,
0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70,
0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0,
0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0,
0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xFE, 0x00,
0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0,
0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE,
0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F,
0xE0, 0x00, 0xFE, 0x00, 0x0E, 0xF0, 0x00, 0xE7, 0x00, 0x0E, 0x78, 0x01,
0xE3, 0xC0, 0x3C, 0x3F, 0x9F, 0x81, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xF0,
0x00, 0x3B, 0x80, 0x03, 0xDC, 0x00, 0x1C, 0xF0, 0x01, 0xE3, 0x80, 0x0F,
0x1C, 0x00, 0x70, 0xF0, 0x07, 0x83, 0x80, 0x38, 0x1C, 0x01, 0xC0, 0xF0,
0x1E, 0x03, 0x80, 0xE0, 0x1C, 0x07, 0x00, 0x70, 0x78, 0x03, 0x83, 0x80,
0x1C, 0x1C, 0x00, 0x71, 0xE0, 0x03, 0x8E, 0x00, 0x1E, 0x70, 0x00, 0x77,
0x80, 0x03, 0xB8, 0x00, 0x1D, 0xC0, 0x00, 0x7C, 0x00, 0x03, 0xE0, 0x00,
0x1F, 0x00, 0x00, 0x70, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x70, 0x03, 0xC0,
0x07, 0x70, 0x03, 0xE0, 0x0F, 0x78, 0x03, 0xE0, 0x0E, 0x38, 0x07, 0xE0,
0x0E, 0x38, 0x07, 0x70, 0x0E, 0x38, 0x07, 0x70, 0x1E, 0x3C, 0x0E, 0x70,
0x1C, 0x1C, 0x0E, 0x38, 0x1C, 0x1C, 0x0E, 0x38, 0x1C, 0x1C, 0x1E, 0x38,
0x3C, 0x0E, 0x1C, 0x38, 0x38, 0x0E, 0x1C, 0x1C, 0x38, 0x0E, 0x1C, 0x1C,
0x38, 0x0E, 0x38, 0x1C, 0x70, 0x07, 0x38, 0x0E, 0x70, 0x07, 0x38, 0x0E,
0x70, 0x07, 0x30, 0x0E, 0x70, 0x07, 0x70, 0x0E, 0xE0, 0x03, 0xF0, 0x07,
0xE0, 0x03, 0xF0, 0x07, 0xE0, 0x03, 0xE0, 0x07, 0xE0, 0x03, 0xE0, 0x03,
0xC0, 0x01, 0xE0, 0x03, 0xC0, 0x01, 0xC0, 0x03, 0xC0, 0x78, 0x00, 0xF1,
0xC0, 0x0F, 0x0F, 0x00, 0x70, 0x38, 0x07, 0x80, 0xE0, 0x38, 0x07, 0x83,
0x80, 0x1C, 0x3C, 0x00, 0x71, 0xC0, 0x03, 0xDC, 0x00, 0x0F, 0xE0, 0x00,
0x3E, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0xFC, 0x00, 0x07, 0xF0,
0x00, 0x73, 0x80, 0x03, 0x8E, 0x00, 0x38, 0x78, 0x03, 0xC1, 0xC0, 0x1C,
0x07, 0x01, 0xC0, 0x3C, 0x1E, 0x00, 0xE0, 0xE0, 0x07, 0x8E, 0x00, 0x1E,
0xF0, 0x00, 0x78, 0xF0, 0x00, 0xF7, 0x00, 0x0E, 0x78, 0x01, 0xE3, 0x80,
0x1C, 0x1C, 0x03, 0x81, 0xC0, 0x38, 0x0E, 0x07, 0x00, 0xE0, 0xF0, 0x07,
0x0E, 0x00, 0x79, 0xE0, 0x03, 0x9C, 0x00, 0x3F, 0xC0, 0x01, 0xF8, 0x00,
0x1F, 0x80, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00,
0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0,
0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x7F, 0xFF, 0x9F, 0xFF, 0xE7, 0xFF,
0xF8, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x03, 0x80, 0x01, 0xE0, 0x00, 0xF0,
0x00, 0x38, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x03, 0x80, 0x01, 0xE0, 0x00,
0xF0, 0x00, 0x38, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x03, 0x80, 0x01, 0xE0,
0x00, 0xF0, 0x00, 0x38, 0x00, 0x1E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xF0, 0x03,
0x80, 0x1C, 0x00, 0x70, 0x03, 0x80, 0x1E, 0x00, 0x70, 0x03, 0x80, 0x0E,
0x00, 0x70, 0x03, 0x80, 0x0E, 0x00, 0x70, 0x03, 0xC0, 0x0E, 0x00, 0x70,
0x01, 0xC0, 0x0E, 0x00, 0x70, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x01, 0xC0,
0x0E, 0x00, 0x38, 0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0x01, 0xC0,
0x00, 0x78, 0x00, 0x3E, 0x00, 0x0D, 0xC0, 0x03, 0x30, 0x01, 0xCE, 0x00,
0x61, 0x80, 0x38, 0x70, 0x0C, 0x0C, 0x07, 0x03, 0x81, 0x80, 0x60, 0xE0,
0x1C, 0x30, 0x03, 0x1C, 0x00, 0xE7, 0x00, 0x1B, 0x80, 0x07, 0xFF, 0xFF,
0xFF, 0xFF, 0xF0, 0x78, 0x3C, 0x1C, 0x0E, 0x07, 0x0F, 0xF0, 0x7F, 0xF0,
0xF9, 0xF1, 0x00, 0xF0, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x0F,
0xFE, 0x7F, 0xFD, 0xE0, 0x3F, 0x80, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x07,
0xF0, 0x1F, 0xF8, 0xFE, 0xFF, 0xDC, 0xFF, 0x18, 0xE0, 0x00, 0x70, 0x00,
0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0,
0x00, 0xE7, 0xF0, 0x77, 0xFE, 0x3F, 0x9F, 0x9F, 0x01, 0xCF, 0x00, 0xF7,
0x80, 0x3B, 0x80, 0x1D, 0xC0, 0x0F, 0xE0, 0x07, 0xF0, 0x01, 0xF8, 0x01,
0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x80, 0x3B, 0xC0, 0x1D, 0xF0, 0x1E, 0xFE,
0x3E, 0x77, 0xFE, 0x31, 0xFE, 0x00, 0x07, 0xF8, 0x7F, 0xF3, 0xF7, 0x9E,
0x00, 0x70, 0x03, 0xC0, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E,
0x00, 0x38, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x1E, 0x00, 0x3E, 0x38,
0x7F, 0xE0, 0xFF, 0x80, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00,
0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x0F, 0xE3, 0x8F,
0xFD, 0xCF, 0x9F, 0xEF, 0x01, 0xF7, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F,
0xC0, 0x0F, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00,
0x7F, 0x80, 0x3D, 0xC0, 0x1E, 0xF0, 0x1F, 0x3E, 0x3F, 0x8F, 0xFD, 0xC3,
0xF8, 0xE0, 0x07, 0xF0, 0x1F, 0xF8, 0x3E, 0x3C, 0x78, 0x1E, 0x70, 0x0E,
0x70, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x78, 0x01, 0x3F, 0x1E,
0x1F, 0xFE, 0x07, 0xFC, 0x03, 0xF8, 0x3F, 0x83, 0xFC, 0x3C, 0x01, 0xC0,
0x0E, 0x00, 0x70, 0x03, 0x80, 0x7F, 0xE7, 0xFF, 0x3F, 0xF8, 0x38, 0x01,
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38,
0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00,
0x0F, 0xE3, 0x8F, 0xFD, 0xCF, 0x9F, 0xEF, 0x01, 0xF7, 0x00, 0x7F, 0x80,
0x3F, 0x80, 0x1F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC,
0x00, 0x7E, 0x00, 0x7F, 0x80, 0x3D, 0xC0, 0x1E, 0xF0, 0x1F, 0x3E, 0x3F,
0x8F, 0xFD, 0xC3, 0xF8, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x3C, 0x00,
0x1C, 0x80, 0x1E, 0x78, 0x1E, 0x3F, 0xFF, 0x0F, 0xFE, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE3, 0xF8, 0xEF, 0xFC, 0xFE, 0x3E, 0xF8, 0x0E, 0xF0, 0x0F,
0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0F, 0xFE, 0xFC,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x1E, 0xE0, 0x3C, 0xE0, 0x78, 0xE0, 0xF0,
0xE1, 0xE0, 0xE3, 0xC0, 0xE7, 0x80, 0xEF, 0x00, 0xEF, 0x00, 0xFF, 0x00,
0xFF, 0x80, 0xF3, 0xC0, 0xE1, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xE0, 0x78,
0xE0, 0x3C, 0xE0, 0x1C, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE7, 0xF0, 0x7F, 0x1D, 0xFF, 0x9F, 0xFB,
0xF9, 0xF7, 0x9F, 0x7C, 0x0F, 0xC0, 0xFF, 0x00, 0xF0, 0x0F, 0xE0, 0x1C,
0x01, 0xF8, 0x03, 0x80, 0x3F, 0x00, 0x70, 0x07, 0xE0, 0x0E, 0x00, 0xFC,
0x01, 0xC0, 0x1F, 0x80, 0x38, 0x03, 0xF0, 0x07, 0x00, 0x7E, 0x00, 0xE0,
0x0F, 0xC0, 0x1C, 0x01, 0xF8, 0x03, 0x80, 0x3F, 0x00, 0x70, 0x07, 0xE0,
0x0E, 0x00, 0xFC, 0x01, 0xC0, 0x1F, 0x80, 0x38, 0x03, 0x80, 0xE3, 0xF8,
0xEF, 0xFC, 0xFF, 0x3E, 0xF8, 0x0E, 0xF0, 0x0F, 0xF0, 0x07, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0xCF, 0x8F, 0x01, 0xE7, 0x00, 0x77, 0x80,
0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC,
0x00, 0x7E, 0x00, 0x3B, 0x80, 0x1D, 0xC0, 0x1C, 0xF0, 0x1E, 0x3E, 0x1E,
0x0F, 0xFE, 0x01, 0xFE, 0x00, 0xE3, 0xF0, 0x77, 0xFE, 0x3F, 0x9F, 0x9F,
0x01, 0xCF, 0x00, 0xF7, 0x80, 0x3B, 0x80, 0x1D, 0xC0, 0x0F, 0xE0, 0x07,
0xF0, 0x01, 0xF8, 0x01, 0xFC, 0x00, 0xFE, 0x00, 0x77, 0x80, 0x3B, 0xC0,
0x3D, 0xF0, 0x1C, 0xFC, 0x3E, 0x77, 0xFE, 0x39, 0xFE, 0x1C, 0x00, 0x0E,
0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00,
0x38, 0x00, 0x00, 0x0F, 0xE3, 0x8F, 0xFD, 0xCF, 0x9E, 0xEF, 0x01, 0xF7,
0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xC0, 0x0F, 0xE0, 0x03, 0xF0, 0x01,
0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00, 0x7F, 0x80, 0x3D, 0xC0, 0x1E, 0xF0,
0x1F, 0x3E, 0x3F, 0x8F, 0xFD, 0xC3, 0xF8, 0xE0, 0x00, 0x70, 0x00, 0x38,
0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00,
0xE0, 0xE3, 0xFC, 0xFF, 0xBF, 0xFE, 0x0F, 0x81, 0xE0, 0x38, 0x07, 0x00,
0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0,
0x1C, 0x03, 0x80, 0x00, 0x1F, 0xF3, 0xFF, 0xFE, 0x3D, 0xC0, 0x0E, 0x00,
0x70, 0x03, 0xC0, 0x0F, 0x80, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0,
0x03, 0x80, 0x1C, 0x00, 0xF0, 0x07, 0xE0, 0xFF, 0xFF, 0x9F, 0xF0, 0x18,
0x03, 0x00, 0x60, 0x1C, 0x07, 0xFF, 0xFF, 0xFF, 0xF9, 0xC0, 0x38, 0x07,
0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00,
0xE0, 0x1E, 0x01, 0xE2, 0x3F, 0xC3, 0xF8, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0,
0x0F, 0xF0, 0x1F, 0x78, 0x7F, 0x7F, 0xF7, 0x1F, 0xC7, 0xE0, 0x03, 0xDC,
0x00, 0xE7, 0x00, 0x39, 0xE0, 0x1E, 0x38, 0x07, 0x0E, 0x01, 0xC3, 0xC0,
0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x03, 0x87, 0x00, 0xE1, 0xC0, 0x38, 0xF0,
0x07, 0x38, 0x01, 0xCE, 0x00, 0x77, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00,
0x78, 0x00, 0x1E, 0x00, 0xF0, 0x0F, 0x00, 0xEE, 0x01, 0xE0, 0x1D, 0xC0,
0x7C, 0x07, 0xB8, 0x0F, 0xC0, 0xE3, 0x81, 0xF8, 0x1C, 0x70, 0x77, 0x03,
0x8E, 0x0E, 0x70, 0xF1, 0xE1, 0xCE, 0x1C, 0x1C, 0x31, 0xC3, 0x83, 0x8E,
0x18, 0x70, 0x71, 0xC3, 0x9C, 0x07, 0x30, 0x73, 0x80, 0xEE, 0x0E, 0x70,
0x1D, 0xC0, 0xEE, 0x03, 0xB8, 0x1F, 0x80, 0x36, 0x03, 0xF0, 0x07, 0xC0,
0x3E, 0x00, 0xF8, 0x07, 0x80, 0x1E, 0x00, 0xF0, 0x00, 0xF0, 0x07, 0xB8,
0x07, 0x8E, 0x03, 0x87, 0x83, 0x81, 0xE3, 0xC0, 0x73, 0xC0, 0x3D, 0xC0,
0x0F, 0xC0, 0x03, 0xE0, 0x01, 0xE0, 0x00, 0xF8, 0x00, 0xFE, 0x00, 0xF7,
0x00, 0x71, 0xC0, 0x70, 0xF0, 0x78, 0x3C, 0x78, 0x0E, 0x38, 0x07, 0xB8,
0x01, 0xE0, 0xF0, 0x03, 0xDC, 0x00, 0xE7, 0x00, 0x39, 0xE0, 0x1E, 0x38,
0x07, 0x0E, 0x01, 0xC1, 0xC0, 0xF0, 0x70, 0x38, 0x1E, 0x0E, 0x03, 0x87,
0x00, 0xE1, 0xC0, 0x1C, 0x70, 0x07, 0x38, 0x01, 0xCE, 0x00, 0x3B, 0x80,
0x0F, 0xC0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x01,
0xC0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x3F, 0xC0,
0x0F, 0xC0, 0x00, 0x7F, 0xFD, 0xFF, 0xF7, 0xFF, 0xC0, 0x0E, 0x00, 0x78,
0x03, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0xC0,
0x1E, 0x00, 0x70, 0x03, 0x80, 0x1E, 0x00, 0x70, 0x03, 0xFF, 0xFF, 0xFF,
0xC0, 0x00, 0xE0, 0x7C, 0x1F, 0x83, 0x80, 0xF0, 0x1C, 0x03, 0x80, 0x70,
0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x7C, 0x3E, 0x07, 0x80, 0xFC,
0x03, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01,
0xC0, 0x3C, 0x03, 0xC0, 0x7E, 0x03, 0xC0, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x1F,
0x81, 0xF0, 0x0F, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0,
0x38, 0x07, 0x00, 0xF0, 0x0F, 0x00, 0xF8, 0x0F, 0x07, 0xE1, 0xE0, 0x38,
0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x1F,
0x0F, 0xC1, 0xF0, 0x30, 0x00, 0x1C, 0x01, 0xFF, 0x81, 0xFF, 0xFF, 0xC1,
0xFF, 0x80, 0x3C };
const GFXglyph NotoSans_Regular18pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 9, 0, 0 }, // 0x20 ' '
{ 1, 4, 26, 9, 3, -24 }, // 0x21 '!'
{ 14, 10, 9, 14, 2, -24 }, // 0x22 '"'
{ 26, 21, 25, 23, 1, -24 }, // 0x23 '#'
{ 92, 16, 29, 20, 2, -26 }, // 0x24 '$'
{ 150, 26, 26, 29, 2, -25 }, // 0x25 '%'
{ 235, 24, 26, 26, 2, -25 }, // 0x26 '&'
{ 313, 4, 9, 8, 2, -24 }, // 0x27 '''
{ 318, 9, 31, 11, 1, -24 }, // 0x28 '('
{ 353, 8, 31, 11, 1, -24 }, // 0x29 ')'
{ 384, 17, 16, 19, 1, -26 }, // 0x2A '*'
{ 418, 16, 17, 20, 2, -20 }, // 0x2B '+'
{ 452, 6, 9, 9, 1, -3 }, // 0x2C ','
{ 459, 9, 3, 11, 1, -10 }, // 0x2D '-'
{ 463, 4, 5, 9, 3, -3 }, // 0x2E '.'
{ 466, 13, 25, 13, 0, -24 }, // 0x2F '/'
{ 507, 16, 26, 20, 2, -25 }, // 0x30 '0'
{ 559, 10, 25, 20, 3, -24 }, // 0x31 '1'
{ 591, 16, 26, 20, 2, -25 }, // 0x32 '2'
{ 643, 16, 26, 20, 2, -25 }, // 0x33 '3'
{ 695, 18, 25, 20, 1, -24 }, // 0x34 '4'
{ 752, 16, 25, 20, 2, -24 }, // 0x35 '5'
{ 802, 17, 26, 20, 2, -25 }, // 0x36 '6'
{ 858, 16, 25, 20, 2, -24 }, // 0x37 '7'
{ 908, 16, 26, 20, 2, -25 }, // 0x38 '8'
{ 960, 16, 26, 20, 2, -25 }, // 0x39 '9'
{ 1012, 4, 20, 9, 3, -18 }, // 0x3A ':'
{ 1022, 6, 24, 9, 1, -18 }, // 0x3B ';'
{ 1040, 16, 17, 20, 2, -20 }, // 0x3C '<'
{ 1074, 16, 9, 20, 2, -16 }, // 0x3D '='
{ 1092, 16, 17, 20, 2, -20 }, // 0x3E '>'
{ 1126, 14, 27, 15, 0, -25 }, // 0x3F '?'
{ 1174, 28, 28, 32, 2, -24 }, // 0x40 '@'
{ 1272, 22, 25, 23, 0, -24 }, // 0x41 'A'
{ 1341, 18, 25, 23, 3, -24 }, // 0x42 'B'
{ 1398, 19, 26, 22, 2, -25 }, // 0x43 'C'
{ 1460, 21, 25, 26, 3, -24 }, // 0x44 'D'
{ 1526, 14, 25, 20, 3, -24 }, // 0x45 'E'
{ 1570, 14, 25, 18, 3, -24 }, // 0x46 'F'
{ 1614, 21, 26, 26, 2, -25 }, // 0x47 'G'
{ 1683, 20, 25, 26, 3, -24 }, // 0x48 'H'
{ 1746, 10, 25, 12, 1, -24 }, // 0x49 'I'
{ 1778, 9, 32, 10, -3, -24 }, // 0x4A 'J'
{ 1814, 19, 25, 22, 3, -24 }, // 0x4B 'K'
{ 1874, 15, 25, 18, 3, -24 }, // 0x4C 'L'
{ 1921, 26, 25, 32, 3, -24 }, // 0x4D 'M'
{ 2003, 20, 25, 27, 3, -24 }, // 0x4E 'N'
{ 2066, 23, 26, 28, 2, -25 }, // 0x4F 'O'
{ 2141, 17, 25, 21, 3, -24 }, // 0x50 'P'
{ 2195, 23, 32, 28, 2, -25 }, // 0x51 'Q'
{ 2287, 18, 25, 22, 3, -24 }, // 0x52 'R'
{ 2344, 16, 26, 19, 2, -25 }, // 0x53 'S'
{ 2396, 19, 25, 20, 0, -24 }, // 0x54 'T'
{ 2456, 20, 25, 26, 3, -24 }, // 0x55 'U'
{ 2519, 21, 25, 21, 0, -24 }, // 0x56 'V'
{ 2585, 32, 25, 33, 0, -24 }, // 0x57 'W'
{ 2685, 21, 25, 21, 0, -24 }, // 0x58 'X'
{ 2751, 20, 25, 20, 0, -24 }, // 0x59 'Y'
{ 2814, 18, 25, 20, 1, -24 }, // 0x5A 'Z'
{ 2871, 8, 31, 12, 3, -24 }, // 0x5B '['
{ 2902, 13, 25, 13, 0, -24 }, // 0x5C '\'
{ 2943, 8, 31, 12, 1, -24 }, // 0x5D ']'
{ 2974, 18, 16, 20, 1, -24 }, // 0x5E '^'
{ 3010, 16, 2, 16, 0, 4 }, // 0x5F '_'
{ 3014, 8, 6, 10, 1, -26 }, // 0x60 '`'
{ 3020, 15, 19, 20, 2, -18 }, // 0x61 'a'
{ 3056, 17, 27, 22, 3, -26 }, // 0x62 'b'
{ 3114, 14, 19, 17, 2, -18 }, // 0x63 'c'
{ 3148, 17, 27, 22, 2, -26 }, // 0x64 'd'
{ 3206, 16, 19, 20, 2, -18 }, // 0x65 'e'
{ 3244, 13, 27, 12, 1, -26 }, // 0x66 'f'
{ 3288, 17, 27, 22, 2, -18 }, // 0x67 'g'
{ 3346, 16, 27, 22, 3, -26 }, // 0x68 'h'
{ 3400, 3, 26, 9, 3, -25 }, // 0x69 'i'
{ 3410, 8, 34, 9, -2, -25 }, // 0x6A 'j'
{ 3444, 16, 27, 19, 3, -26 }, // 0x6B 'k'
{ 3498, 3, 27, 9, 3, -26 }, // 0x6C 'l'
{ 3509, 27, 19, 33, 3, -18 }, // 0x6D 'm'
{ 3574, 16, 19, 22, 3, -18 }, // 0x6E 'n'
{ 3612, 17, 19, 21, 2, -18 }, // 0x6F 'o'
{ 3653, 17, 27, 22, 3, -18 }, // 0x70 'p'
{ 3711, 17, 27, 22, 2, -18 }, // 0x71 'q'
{ 3769, 11, 19, 15, 3, -18 }, // 0x72 'r'
{ 3796, 13, 19, 17, 2, -18 }, // 0x73 's'
{ 3827, 11, 23, 13, 1, -22 }, // 0x74 't'
{ 3859, 16, 19, 22, 3, -18 }, // 0x75 'u'
{ 3897, 18, 19, 18, 0, -18 }, // 0x76 'v'
{ 3940, 27, 19, 28, 0, -18 }, // 0x77 'w'
{ 4005, 17, 19, 19, 1, -18 }, // 0x78 'x'
{ 4046, 18, 27, 18, 0, -18 }, // 0x79 'y'
{ 4107, 14, 19, 17, 1, -18 }, // 0x7A 'z'
{ 4141, 11, 31, 13, 1, -24 }, // 0x7B '{'
{ 4184, 3, 36, 19, 8, -26 }, // 0x7C '|'
{ 4198, 11, 31, 13, 1, -24 }, // 0x7D '}'
{ 4241, 16, 5, 20, 2, -14 } }; // 0x7E '~'
const GFXfont NotoSans_Regular18pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular18pt7bBitmaps,
(GFXglyph *)NotoSans_Regular18pt7bGlyphs,
0x20, 0x7E, 48 };
// Approx. 4923 bytes
#endif // NOTOSANS18PT7B_H
@@ -0,0 +1,545 @@
#ifndef NOTOSANS20PT7B_H
#define NOTOSANS20PT7B_H
const uint8_t NotoSans_Regular20pt7bBitmaps[] PROGMEM = {
0x00, 0xF7, 0xBD, 0xEF, 0x7B, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73,
0x98, 0xC0, 0x00, 0x0C, 0xF7, 0xFF, 0xE2, 0x00, 0xE1, 0xF8, 0x7E, 0x1F,
0x87, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xF8, 0x70, 0x00, 0x70, 0x70,
0x01, 0xC0, 0xE0, 0x03, 0x81, 0x80, 0x07, 0x03, 0x00, 0x0E, 0x0E, 0x00,
0x1C, 0x1C, 0x00, 0x70, 0x38, 0x00, 0xE0, 0x60, 0x7F, 0xFF, 0xFE, 0xFF,
0xFF, 0xFD, 0xFF, 0xFF, 0xF8, 0x0C, 0x0E, 0x00, 0x38, 0x1C, 0x00, 0x70,
0x70, 0x00, 0xE0, 0xE0, 0x01, 0xC1, 0xC0, 0x03, 0x03, 0x81, 0xFF, 0xFF,
0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xE0, 0x70, 0x70, 0x00, 0xC0, 0xE0,
0x03, 0x81, 0xC0, 0x07, 0x03, 0x00, 0x0E, 0x0E, 0x00, 0x1C, 0x1C, 0x00,
0x30, 0x38, 0x00, 0xE0, 0x70, 0x00, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x0C,
0x00, 0x03, 0x00, 0x0F, 0xFF, 0x07, 0xFF, 0xE3, 0xFF, 0xF9, 0xE3, 0x04,
0x70, 0xC0, 0x3C, 0x30, 0x0F, 0x0C, 0x01, 0xC3, 0x00, 0x78, 0xC0, 0x1F,
0xB0, 0x03, 0xFC, 0x00, 0x3F, 0xE0, 0x03, 0xFE, 0x00, 0x3F, 0xE0, 0x0C,
0xFC, 0x03, 0x0F, 0x00, 0xC1, 0xC0, 0x30, 0x70, 0x0C, 0x1E, 0x03, 0x0F,
0xF0, 0xCF, 0xBF, 0xFF, 0xEF, 0xFF, 0xE0, 0x7F, 0xE0, 0x00, 0xC0, 0x00,
0x30, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x1F, 0x80, 0x0F, 0x01, 0xFE, 0x00,
0x70, 0x1C, 0x70, 0x07, 0x00, 0xE1, 0xC0, 0x38, 0x0E, 0x0E, 0x03, 0x80,
0x70, 0x70, 0x3C, 0x03, 0x81, 0x81, 0xC0, 0x1C, 0x0C, 0x1C, 0x00, 0xE0,
0x70, 0xE0, 0x07, 0x03, 0x0E, 0x00, 0x38, 0x18, 0x70, 0x01, 0xC1, 0xC7,
0x1F, 0x0E, 0x0E, 0x39, 0xFE, 0x38, 0x73, 0x9E, 0xF1, 0xEF, 0x3C, 0xE1,
0xC7, 0xF9, 0xCE, 0x0E, 0x1F, 0x1C, 0x70, 0x30, 0x00, 0xE3, 0x81, 0xC0,
0x0E, 0x1C, 0x0E, 0x00, 0x70, 0xE0, 0x70, 0x07, 0x07, 0x03, 0x80, 0x38,
0x38, 0x1C, 0x03, 0x81, 0xC0, 0xC0, 0x1C, 0x0E, 0x0E, 0x01, 0xC0, 0x38,
0x70, 0x1C, 0x01, 0xC7, 0x00, 0xE0, 0x07, 0xF8, 0x0E, 0x00, 0x1F, 0x80,
0x03, 0xFC, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x7E, 0xFC, 0x00, 0x0F, 0x07,
0x80, 0x01, 0xC0, 0x78, 0x00, 0x38, 0x0F, 0x00, 0x07, 0x01, 0xE0, 0x00,
0xE0, 0x38, 0x00, 0x1E, 0x0F, 0x00, 0x01, 0xE3, 0xC0, 0x00, 0x3E, 0xF0,
0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x07,
0xFE, 0x01, 0xE1, 0xF3, 0xE0, 0x38, 0x7C, 0x3E, 0x07, 0x0F, 0x03, 0xE1,
0xE3, 0xC0, 0x3E, 0x38, 0x78, 0x03, 0xEF, 0x0F, 0x00, 0x3F, 0xC1, 0xE0,
0x03, 0xF8, 0x3C, 0x00, 0x3E, 0x07, 0xC0, 0x0F, 0xE0, 0x7C, 0x07, 0xFE,
0x07, 0xFF, 0xFB, 0xE0, 0x7F, 0xFC, 0x3E, 0x07, 0xFE, 0x03, 0xF0, 0xFF,
0xFF, 0xFF, 0xFC, 0x07, 0x87, 0x87, 0x83, 0x83, 0xC1, 0xC1, 0xE0, 0xF0,
0x70, 0x78, 0x3C, 0x1E, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38,
0x1C, 0x0E, 0x07, 0x03, 0xC1, 0xE0, 0xF0, 0x38, 0x1E, 0x0F, 0x03, 0x81,
0xE0, 0x70, 0x3C, 0x0E, 0x03, 0xC0, 0xF0, 0x3C, 0x0E, 0x07, 0x81, 0xC0,
0xF0, 0x38, 0x1E, 0x0F, 0x03, 0x81, 0xC0, 0xF0, 0x78, 0x3C, 0x0E, 0x07,
0x03, 0x81, 0xC0, 0xE0, 0x70, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x07, 0x83,
0xC1, 0xC1, 0xE0, 0xF0, 0xF0, 0x70, 0x78, 0x78, 0x00, 0x01, 0xE0, 0x00,
0x70, 0x00, 0x1C, 0x00, 0x07, 0x00, 0x01, 0xC0, 0x00, 0x70, 0x0E, 0x1C,
0x3B, 0xFB, 0x7F, 0xFF, 0xFF, 0xC7, 0xFF, 0x80, 0x3E, 0x00, 0x1D, 0xC0,
0x07, 0x78, 0x03, 0xCE, 0x01, 0xE3, 0xC0, 0xF8, 0x78, 0x1C, 0x1C, 0x01,
0x02, 0x00, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00,
0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x03, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00,
0x03, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x3D, 0xE7, 0x9E,
0x71, 0xCF, 0x38, 0xE3, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x67, 0xBF, 0xFF,
0x10, 0x00, 0x1C, 0x00, 0xF0, 0x03, 0x80, 0x0E, 0x00, 0x78, 0x01, 0xC0,
0x0F, 0x00, 0x38, 0x00, 0xE0, 0x07, 0x80, 0x1C, 0x00, 0x70, 0x03, 0xC0,
0x0E, 0x00, 0x78, 0x01, 0xC0, 0x07, 0x00, 0x3C, 0x00, 0xE0, 0x03, 0x80,
0x1E, 0x00, 0x70, 0x03, 0xC0, 0x0E, 0x00, 0x38, 0x01, 0xE0, 0x07, 0x00,
0x3C, 0x00, 0x07, 0xF8, 0x03, 0xFF, 0x81, 0xFF, 0xF0, 0xF0, 0x3C, 0x78,
0x07, 0x9E, 0x00, 0xE7, 0x00, 0x3D, 0xC0, 0x0F, 0xF0, 0x01, 0xFC, 0x00,
0x7F, 0x00, 0x1F, 0x80, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x7E, 0x00, 0x1F,
0x80, 0x07, 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0x70,
0x03, 0xDC, 0x00, 0xF7, 0x80, 0x38, 0xE0, 0x1E, 0x3C, 0x0F, 0x07, 0xFF,
0xC0, 0xFF, 0xE0, 0x1F, 0xE0, 0x01, 0xE0, 0x7C, 0x1F, 0x87, 0xF3, 0xEF,
0xF9, 0xDC, 0x39, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01,
0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0,
0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0F, 0xF8, 0x0F, 0xFF,
0x87, 0xFF, 0xF3, 0xE0, 0x3C, 0x60, 0x07, 0x80, 0x01, 0xE0, 0x00, 0x38,
0x00, 0x0E, 0x00, 0x03, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x1C, 0x00,
0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78,
0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xC0, 0x01,
0xE0, 0x00, 0x70, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
0xF8, 0x1F, 0xFF, 0x8F, 0xFF, 0xF1, 0xC0, 0x3E, 0x40, 0x07, 0x80, 0x00,
0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00, 0xF0,
0x00, 0xF8, 0x0F, 0xFC, 0x03, 0xFC, 0x00, 0xFF, 0xE0, 0x00, 0x7C, 0x00,
0x07, 0x80, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x07, 0x00, 0x01, 0xC0, 0x00,
0xF0, 0x00, 0x3C, 0x00, 0x1F, 0xC0, 0x0F, 0xBF, 0xFF, 0xCF, 0xFF, 0xE1,
0xFF, 0xE0, 0x00, 0x07, 0x80, 0x00, 0x7C, 0x00, 0x07, 0xE0, 0x00, 0x7F,
0x00, 0x03, 0xF8, 0x00, 0x3B, 0xC0, 0x03, 0xDE, 0x00, 0x1C, 0xF0, 0x01,
0xC7, 0x80, 0x1E, 0x3C, 0x00, 0xE1, 0xE0, 0x0E, 0x0F, 0x00, 0xE0, 0x78,
0x0F, 0x03, 0xC0, 0x70, 0x1E, 0x07, 0x00, 0xF0, 0x78, 0x07, 0x83, 0x80,
0x3C, 0x38, 0x01, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x80, 0x00, 0x3C, 0x00, 0x01,
0xE0, 0x00, 0x0F, 0x00, 0x3F, 0xFF, 0x0F, 0xFF, 0xC3, 0xFF, 0xF0, 0xE0,
0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00,
0x1E, 0x00, 0x07, 0x80, 0x01, 0xFF, 0xE0, 0x7F, 0xFE, 0x0F, 0xFF, 0xC0,
0x00, 0xF8, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x1C, 0x00,
0x07, 0x00, 0x01, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0x0F,
0xBF, 0xFF, 0xCF, 0xFF, 0xE0, 0xFF, 0xE0, 0x00, 0xFF, 0x00, 0x7F, 0xE0,
0x3F, 0xEC, 0x07, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x0E, 0x00, 0x03,
0xC0, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x80, 0x79, 0xFF, 0x0F,
0x7F, 0xF1, 0xFE, 0x1F, 0x3F, 0x00, 0xF7, 0xC0, 0x1E, 0xF0, 0x01, 0xDE,
0x00, 0x3B, 0xC0, 0x07, 0xF8, 0x00, 0xF7, 0x00, 0x1C, 0xE0, 0x03, 0x9E,
0x00, 0x71, 0xC0, 0x1E, 0x3C, 0x07, 0x83, 0xFF, 0xF0, 0x3F, 0xFC, 0x01,
0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07, 0x00,
0x03, 0xC0, 0x00, 0xE0, 0x00, 0x78, 0x00, 0x1C, 0x00, 0x0F, 0x00, 0x03,
0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0x80,
0x01, 0xE0, 0x00, 0x70, 0x00, 0x3C, 0x00, 0x0E, 0x00, 0x07, 0x80, 0x01,
0xE0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x03, 0xC0,
0x00, 0xF0, 0x00, 0x78, 0x00, 0x07, 0xFC, 0x07, 0xFF, 0x83, 0xFB, 0xF1,
0xF0, 0x1E, 0x78, 0x03, 0x9C, 0x00, 0xE7, 0x00, 0x3D, 0xC0, 0x0E, 0x78,
0x03, 0x8E, 0x01, 0xE3, 0xE0, 0xF0, 0x7E, 0xF8, 0x0F, 0xF8, 0x01, 0xFE,
0x00, 0xFF, 0xE0, 0xF8, 0xFC, 0x7C, 0x0F, 0x9E, 0x00, 0xFF, 0x00, 0x3F,
0x80, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x0F, 0x78,
0x07, 0xDF, 0xCF, 0xE3, 0xFF, 0xF0, 0x3F, 0xF0, 0x07, 0xF8, 0x07, 0xFF,
0x03, 0xFF, 0xE1, 0xF0, 0x3C, 0x78, 0x07, 0xBC, 0x00, 0xEF, 0x00, 0x3F,
0x80, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xC0, 0x0F, 0xF0,
0x03, 0xDE, 0x01, 0xF7, 0xE1, 0xFC, 0xFF, 0xF7, 0x0F, 0xF1, 0xC0, 0x40,
0x70, 0x00, 0x3C, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x01, 0xE0, 0x00, 0x70,
0x00, 0x3C, 0x00, 0x3E, 0x0C, 0xFF, 0x03, 0xFF, 0x80, 0xFF, 0x80, 0x27,
0xBF, 0xFF, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3D, 0xFF,
0xF8, 0x80, 0x08, 0x78, 0xF9, 0xF3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xF1, 0xE3, 0x8F, 0x1E, 0x38, 0x70,
0xC3, 0x80, 0x00, 0x00, 0x40, 0x00, 0x30, 0x00, 0x3C, 0x00, 0x3F, 0x00,
0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x3E, 0x00,
0x0F, 0x00, 0x03, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xFC, 0x00, 0x1F, 0xC0,
0x01, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xF0, 0x00, 0x0C, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x00,
0x38, 0x00, 0x0F, 0x80, 0x03, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00,
0x1F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF0, 0x00, 0x3C, 0x00,
0x3F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7E, 0x00, 0xFE, 0x00, 0xFE, 0x00,
0x3C, 0x00, 0x0C, 0x00, 0x00, 0x1F, 0xF0, 0xFF, 0xFC, 0x7F, 0xFE, 0x70,
0x1E, 0x00, 0x0F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0F, 0x00,
0x0E, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03,
0xC0, 0x03, 0x80, 0x03, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x07, 0x80, 0x07, 0x80, 0x07,
0x80, 0x01, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03,
0xFF, 0xFE, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x78, 0x00, 0x0F, 0x01, 0xE0,
0x00, 0x0E, 0x07, 0x80, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x0E, 0x38, 0x07,
0xFC, 0x1C, 0x70, 0x3F, 0xF8, 0x39, 0xC0, 0xF0, 0x70, 0x3B, 0x83, 0xC0,
0xE0, 0x77, 0x07, 0x01, 0xC0, 0xEC, 0x1E, 0x03, 0x81, 0xF8, 0x38, 0x07,
0x03, 0xF0, 0x70, 0x0E, 0x07, 0xE0, 0xE0, 0x1C, 0x0F, 0xC1, 0xC0, 0x38,
0x1F, 0x83, 0x80, 0xF0, 0x77, 0x03, 0x81, 0xE0, 0xE6, 0x07, 0x87, 0xE3,
0x8E, 0x07, 0xFD, 0xFF, 0x1C, 0x0F, 0xF1, 0xFC, 0x38, 0x03, 0x80, 0xE0,
0x38, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
0x78, 0x00, 0x10, 0x00, 0x7E, 0x01, 0xE0, 0x00, 0x3F, 0xFF, 0xC0, 0x00,
0x1F, 0xFF, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x0F,
0x80, 0x00, 0x07, 0xE0, 0x00, 0x07, 0x70, 0x00, 0x03, 0xB8, 0x00, 0x03,
0xDE, 0x00, 0x01, 0xC7, 0x00, 0x00, 0xE3, 0x80, 0x00, 0xF1, 0xE0, 0x00,
0x70, 0x70, 0x00, 0x78, 0x3C, 0x00, 0x38, 0x0E, 0x00, 0x1C, 0x07, 0x00,
0x1E, 0x03, 0xC0, 0x0E, 0x00, 0xE0, 0x0F, 0xFF, 0xF8, 0x07, 0xFF, 0xFC,
0x03, 0xFF, 0xFE, 0x03, 0xC0, 0x07, 0x81, 0xC0, 0x03, 0xC0, 0xE0, 0x00,
0xE0, 0xF0, 0x00, 0x78, 0x70, 0x00, 0x1C, 0x78, 0x00, 0x0F, 0x3C, 0x00,
0x07, 0x9C, 0x00, 0x01, 0xDE, 0x00, 0x00, 0xF0, 0xFF, 0xF8, 0x1F, 0xFF,
0xE3, 0xFF, 0xFE, 0x70, 0x07, 0xEE, 0x00, 0x3D, 0xC0, 0x07, 0xB8, 0x00,
0x77, 0x00, 0x0E, 0xE0, 0x01, 0xDC, 0x00, 0x7B, 0x80, 0x0E, 0x70, 0x07,
0xCF, 0xFF, 0xE1, 0xFF, 0xF8, 0x3F, 0xFF, 0xE7, 0x00, 0x3E, 0xE0, 0x03,
0xFC, 0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x03,
0xF8, 0x00, 0x7F, 0x00, 0x1F, 0xE0, 0x07, 0xDF, 0xFF, 0xF3, 0xFF, 0xFC,
0x7F, 0xFE, 0x00, 0x00, 0x7F, 0xF0, 0x0F, 0xFF, 0xF0, 0x7F, 0xFF, 0x83,
0xF0, 0x0E, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xC0, 0x00, 0x1F, 0x00,
0x00, 0x78, 0x00, 0x01, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00,
0xF0, 0x00, 0x03, 0xC0, 0x00, 0x0F, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF0,
0x00, 0x01, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x1E, 0x00, 0x00, 0x78, 0x00,
0x00, 0xF0, 0x00, 0x03, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x0F, 0x80, 0x10,
0x1F, 0xFF, 0xC0, 0x3F, 0xFF, 0x00, 0x3F, 0xFC, 0xFF, 0xF8, 0x03, 0xFF,
0xFC, 0x0F, 0xFF, 0xF8, 0x38, 0x03, 0xF0, 0xE0, 0x03, 0xE3, 0x80, 0x03,
0xCE, 0x00, 0x0F, 0xB8, 0x00, 0x1E, 0xE0, 0x00, 0x3B, 0x80, 0x00, 0xFE,
0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00,
0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x03,
0xF8, 0x00, 0x1E, 0xE0, 0x00, 0x7B, 0x80, 0x03, 0xEE, 0x00, 0x1F, 0x38,
0x00, 0xF8, 0xE0, 0x1F, 0xC3, 0xFF, 0xFE, 0x0F, 0xFF, 0xE0, 0x3F, 0xFC,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0E, 0x00, 0x1C, 0x00,
0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80,
0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0,
0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38,
0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x00, 0x00,
0x7F, 0xF8, 0x01, 0xFF, 0xFE, 0x07, 0xFF, 0xFE, 0x0F, 0xC0, 0x0C, 0x1F,
0x00, 0x00, 0x1E, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x78,
0x00, 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0,
0x00, 0x00, 0xF0, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0x70,
0x00, 0x0F, 0x70, 0x00, 0x0F, 0x78, 0x00, 0x0F, 0x78, 0x00, 0x0F, 0x78,
0x00, 0x0F, 0x3C, 0x00, 0x0F, 0x3E, 0x00, 0x0F, 0x1F, 0x00, 0x0F, 0x0F,
0xC0, 0x0F, 0x07, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0xFC, 0xE0,
0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03,
0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00,
0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00,
0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC,
0x00, 0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00,
0x70, 0xFF, 0xFF, 0xF7, 0xF0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C,
0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01,
0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x0F, 0xCF, 0xFF, 0xFF,
0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0,
0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C,
0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01,
0xC0, 0xF0, 0x3C, 0x1E, 0xFF, 0xBF, 0xCF, 0xE0, 0xE0, 0x01, 0xFE, 0x00,
0x3C, 0xE0, 0x07, 0xCE, 0x00, 0x78, 0xE0, 0x0F, 0x0E, 0x01, 0xE0, 0xE0,
0x3C, 0x0E, 0x07, 0x80, 0xE0, 0xF0, 0x0E, 0x1E, 0x00, 0xE3, 0xC0, 0x0E,
0x78, 0x00, 0xEF, 0x80, 0x0E, 0xFC, 0x00, 0xFF, 0xC0, 0x0F, 0x9E, 0x00,
0xF0, 0xF0, 0x0E, 0x0F, 0x80, 0xE0, 0x78, 0x0E, 0x03, 0xC0, 0xE0, 0x1E,
0x0E, 0x01, 0xF0, 0xE0, 0x0F, 0x0E, 0x00, 0x78, 0xE0, 0x07, 0xCE, 0x00,
0x3C, 0xE0, 0x01, 0xEE, 0x00, 0x0F, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x3F, 0xFC, 0x00, 0x03,
0xFF, 0xC0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFE, 0xE0, 0x00, 0xFF, 0xEE,
0x00, 0x0E, 0xFE, 0xF0, 0x00, 0xEF, 0xE7, 0x00, 0x1C, 0xFE, 0x78, 0x01,
0xCF, 0xE3, 0x80, 0x1C, 0xFE, 0x38, 0x03, 0x8F, 0xE3, 0xC0, 0x38, 0xFE,
0x1C, 0x07, 0x8F, 0xE1, 0xC0, 0x70, 0xFE, 0x1E, 0x07, 0x0F, 0xE0, 0xE0,
0xE0, 0xFE, 0x0F, 0x0E, 0x0F, 0xE0, 0x71, 0xE0, 0xFE, 0x07, 0x1C, 0x0F,
0xE0, 0x79, 0xC0, 0xFE, 0x03, 0xBC, 0x0F, 0xE0, 0x3B, 0x80, 0xFE, 0x03,
0xF8, 0x0F, 0xE0, 0x1F, 0x00, 0xFE, 0x01, 0xF0, 0x0F, 0xE0, 0x0F, 0x00,
0xFE, 0x00, 0xE0, 0x0F, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0x7F, 0x80, 0x01,
0xFF, 0x00, 0x07, 0xFE, 0x00, 0x1F, 0xF8, 0x00, 0x7E, 0xF0, 0x01, 0xF9,
0xE0, 0x07, 0xE7, 0x80, 0x1F, 0x8F, 0x00, 0x7E, 0x1E, 0x01, 0xF8, 0x78,
0x07, 0xE0, 0xF0, 0x1F, 0x81, 0xE0, 0x7E, 0x07, 0x81, 0xF8, 0x0F, 0x07,
0xE0, 0x3C, 0x1F, 0x80, 0x78, 0x7E, 0x00, 0xF1, 0xF8, 0x03, 0xC7, 0xE0,
0x07, 0x9F, 0x80, 0x0F, 0x7E, 0x00, 0x3D, 0xF8, 0x00, 0x7F, 0xE0, 0x00,
0xFF, 0x80, 0x03, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x0F, 0x00, 0xFF, 0xE0,
0x00, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x3E, 0x00, 0xF8, 0x1F, 0x00,
0x1F, 0x0F, 0x80, 0x03, 0xC3, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x1E, 0x78,
0x00, 0x03, 0x9E, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F,
0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00,
0x0F, 0x70, 0x00, 0x03, 0xDC, 0x00, 0x00, 0xF7, 0x80, 0x00, 0x3D, 0xE0,
0x00, 0x0E, 0x78, 0x00, 0x07, 0x8F, 0x00, 0x01, 0xE3, 0xC0, 0x00, 0xF0,
0x7C, 0x00, 0x7C, 0x0F, 0x80, 0x3E, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF,
0x80, 0x03, 0xFF, 0x80, 0xFF, 0xF0, 0x3F, 0xFF, 0x0F, 0xFF, 0xF3, 0x80,
0xFC, 0xE0, 0x0F, 0xB8, 0x01, 0xEE, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x03,
0xF8, 0x00, 0xFE, 0x00, 0x3B, 0x80, 0x1E, 0xE0, 0x0F, 0xB8, 0x07, 0xCF,
0xFF, 0xE3, 0xFF, 0xF0, 0xFF, 0xF0, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80,
0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0, 0x00,
0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0xFF,
0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x3E, 0x00, 0xF8, 0x1F, 0x00, 0x1F, 0x0F,
0x80, 0x03, 0xC3, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x1E, 0x78, 0x00, 0x03,
0x9E, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00,
0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0x70,
0x00, 0x03, 0xDC, 0x00, 0x00, 0xF7, 0x80, 0x00, 0x3D, 0xE0, 0x00, 0x0E,
0x78, 0x00, 0x07, 0x8F, 0x00, 0x01, 0xE3, 0xC0, 0x00, 0xF0, 0x7C, 0x00,
0x7C, 0x0F, 0x80, 0x3E, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0x80, 0x03,
0xFF, 0x80, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x80,
0x00, 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00,
0xF8, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0xFF, 0xFF, 0x0E, 0x01, 0xF8, 0xE0,
0x07, 0x8E, 0x00, 0x78, 0xE0, 0x03, 0xCE, 0x00, 0x3C, 0xE0, 0x03, 0xCE,
0x00, 0x3C, 0xE0, 0x03, 0x8E, 0x00, 0x78, 0xE0, 0x0F, 0x0F, 0xFF, 0xE0,
0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0xE0, 0x78, 0x0E, 0x03, 0x80, 0xE0, 0x3C,
0x0E, 0x01, 0xE0, 0xE0, 0x1E, 0x0E, 0x00, 0xF0, 0xE0, 0x0F, 0x0E, 0x00,
0x78, 0xE0, 0x03, 0xCE, 0x00, 0x3C, 0xE0, 0x01, 0xEE, 0x00, 0x1F, 0x07,
0xFE, 0x07, 0xFF, 0xE3, 0xFF, 0xF9, 0xF0, 0x0C, 0x78, 0x00, 0x3C, 0x00,
0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x1E, 0x00, 0x07, 0xC0, 0x00,
0xFC, 0x00, 0x1F, 0xC0, 0x03, 0xFE, 0x00, 0x3F, 0xC0, 0x01, 0xFC, 0x00,
0x1F, 0x80, 0x01, 0xE0, 0x00, 0x38, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00,
0xF0, 0x00, 0x38, 0x00, 0x1E, 0xC0, 0x0F, 0xBF, 0xFF, 0xCF, 0xFF, 0xE1,
0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xF0,
0x00, 0x07, 0x80, 0x00, 0x3C, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00,
0x78, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x80,
0x00, 0x3C, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x03,
0xC0, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x80, 0x00, 0x3C, 0x00,
0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x1E,
0x00, 0x00, 0xF0, 0x00, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F,
0xC0, 0x00, 0x7E, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00,
0x07, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x7E,
0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xFC, 0x00, 0x07, 0xE0, 0x00,
0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF8,
0x00, 0x3F, 0xC0, 0x03, 0xCF, 0x00, 0x1E, 0x7C, 0x03, 0xE1, 0xFF, 0xFE,
0x07, 0xFF, 0xE0, 0x0F, 0xFC, 0x00, 0xF0, 0x00, 0x0F, 0x70, 0x00, 0x1E,
0x78, 0x00, 0x1E, 0x78, 0x00, 0x1C, 0x38, 0x00, 0x3C, 0x3C, 0x00, 0x3C,
0x3C, 0x00, 0x78, 0x1C, 0x00, 0x78, 0x1E, 0x00, 0x70, 0x1E, 0x00, 0xF0,
0x0E, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x0F, 0x01, 0xE0, 0x07, 0x01, 0xE0,
0x07, 0x81, 0xC0, 0x03, 0x83, 0xC0, 0x03, 0x83, 0xC0, 0x03, 0xC3, 0x80,
0x01, 0xC7, 0x80, 0x01, 0xE7, 0x80, 0x01, 0xE7, 0x00, 0x00, 0xEF, 0x00,
0x00, 0xEE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C, 0x00,
0x00, 0x7C, 0x00, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF7, 0x80,
0x0F, 0x00, 0x0F, 0x78, 0x00, 0xF8, 0x00, 0xE7, 0x80, 0x1F, 0x80, 0x1E,
0x38, 0x01, 0xF8, 0x01, 0xE3, 0xC0, 0x1F, 0xC0, 0x1C, 0x3C, 0x03, 0xDC,
0x01, 0xC3, 0xC0, 0x39, 0xC0, 0x3C, 0x1C, 0x03, 0x9C, 0x03, 0xC1, 0xE0,
0x79, 0xE0, 0x38, 0x1E, 0x07, 0x8E, 0x03, 0x80, 0xE0, 0x70, 0xE0, 0x78,
0x0E, 0x07, 0x0F, 0x07, 0x80, 0xF0, 0xF0, 0x70, 0x70, 0x0F, 0x0E, 0x07,
0x07, 0x00, 0x70, 0xE0, 0x78, 0xF0, 0x07, 0x1E, 0x03, 0x8F, 0x00, 0x79,
0xE0, 0x38, 0xE0, 0x07, 0x9C, 0x03, 0x8E, 0x00, 0x39, 0xC0, 0x3D, 0xE0,
0x03, 0xBC, 0x01, 0xDC, 0x00, 0x3B, 0x80, 0x1D, 0xC0, 0x03, 0xF8, 0x01,
0xDC, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x1F,
0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x0F, 0x00, 0x07, 0x80,
0x78, 0x00, 0x3C, 0x78, 0x00, 0xF0, 0xF0, 0x01, 0xE0, 0xF0, 0x07, 0x80,
0xE0, 0x0E, 0x01, 0xE0, 0x3C, 0x01, 0xE0, 0xF0, 0x01, 0xC1, 0xC0, 0x03,
0xC7, 0x80, 0x03, 0xDE, 0x00, 0x03, 0xB8, 0x00, 0x07, 0xF0, 0x00, 0x07,
0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x7F, 0x00, 0x01, 0xEE,
0x00, 0x03, 0x9E, 0x00, 0x0F, 0x1E, 0x00, 0x1C, 0x1C, 0x00, 0x78, 0x3C,
0x01, 0xE0, 0x3C, 0x03, 0x80, 0x78, 0x0F, 0x00, 0x78, 0x3C, 0x00, 0x78,
0x70, 0x00, 0xF1, 0xE0, 0x00, 0xF7, 0x80, 0x01, 0xF0, 0xF0, 0x00, 0x3D,
0xE0, 0x00, 0xE7, 0x80, 0x07, 0x8F, 0x00, 0x1C, 0x3C, 0x00, 0xF0, 0x78,
0x07, 0x81, 0xE0, 0x1E, 0x03, 0xC0, 0xF0, 0x07, 0x03, 0xC0, 0x1E, 0x1E,
0x00, 0x38, 0x70, 0x00, 0xF3, 0xC0, 0x01, 0xCE, 0x00, 0x07, 0xF8, 0x00,
0x0F, 0xC0, 0x00, 0x3F, 0x00, 0x00, 0x78, 0x00, 0x01, 0xE0, 0x00, 0x07,
0x80, 0x00, 0x1E, 0x00, 0x00, 0x78, 0x00, 0x01, 0xE0, 0x00, 0x07, 0x80,
0x00, 0x1E, 0x00, 0x00, 0x78, 0x00, 0x01, 0xE0, 0x00, 0x07, 0x80, 0x00,
0x1E, 0x00, 0x7F, 0xFF, 0xE7, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x1E,
0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0xF0, 0x00, 0x0F,
0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F,
0x00, 0x00, 0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x07,
0x80, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x03,
0xC0, 0x00, 0x78, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C,
0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07,
0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xFF,
0xFF, 0xFF, 0xC0, 0xF0, 0x01, 0xC0, 0x07, 0x80, 0x0E, 0x00, 0x38, 0x00,
0xF0, 0x01, 0xC0, 0x07, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xF0, 0x01, 0xC0,
0x07, 0x00, 0x1E, 0x00, 0x38, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1E,
0x00, 0x38, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x1E, 0x00, 0x38, 0x00,
0xE0, 0x03, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
0x78, 0x3C, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xE0, 0x00, 0x0F, 0x00,
0x00, 0xF0, 0x00, 0x1F, 0x80, 0x01, 0xB8, 0x00, 0x39, 0xC0, 0x03, 0x1C,
0x00, 0x70, 0xE0, 0x07, 0x0E, 0x00, 0xE0, 0x70, 0x0E, 0x07, 0x01, 0xC0,
0x38, 0x1C, 0x03, 0x83, 0x80, 0x1C, 0x38, 0x01, 0xC7, 0x00, 0x0E, 0x70,
0x00, 0xEF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF1, 0xE1, 0xE1,
0xE1, 0xC1, 0xC0, 0x0F, 0xFC, 0x1F, 0xFF, 0x07, 0xEF, 0xC2, 0x01, 0xE0,
0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x7F, 0x87, 0xFF,
0xCF, 0xFF, 0xEF, 0x80, 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0x80, 0x1F, 0xC0,
0x0F, 0xF0, 0x0F, 0xF8, 0x0F, 0xDF, 0x3E, 0xEF, 0xFE, 0x71, 0xFE, 0x38,
0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01,
0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0xF0, 0x00, 0x1E, 0x7F, 0x83,
0xDF, 0xFC, 0x7F, 0xFF, 0xCF, 0xC0, 0x79, 0xF0, 0x07, 0xBE, 0x00, 0x77,
0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFF,
0x00, 0x1F, 0xE0, 0x03, 0xFC, 0x00, 0x7F, 0x80, 0x0F, 0xF8, 0x03, 0xDF,
0x00, 0x7B, 0xF0, 0x1E, 0x77, 0xDF, 0xCE, 0x7F, 0xF1, 0xC7, 0xF8, 0x00,
0x07, 0xFF, 0x0F, 0xFE, 0x1F, 0xFE, 0x3C, 0x02, 0x78, 0x00, 0x78, 0x00,
0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00,
0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x78, 0x00, 0x78, 0x00, 0x3C, 0x02,
0x1F, 0xFE, 0x0F, 0xFE, 0x07, 0xFE, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00,
0x07, 0x80, 0x00, 0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00,
0x0F, 0x00, 0x01, 0xE0, 0xFF, 0x3C, 0x7F, 0xF7, 0x9F, 0xDF, 0x73, 0xC0,
0x7E, 0xF0, 0x07, 0xDE, 0x00, 0x7B, 0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00,
0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xE0, 0x03, 0xFC, 0x00,
0x7B, 0x80, 0x0F, 0x78, 0x01, 0xEF, 0x00, 0x7C, 0xF0, 0x1F, 0x9F, 0xDF,
0x71, 0xFF, 0xCE, 0x0F, 0xF1, 0xC0, 0x07, 0xFC, 0x03, 0xFF, 0x81, 0xFB,
0xF0, 0xF0, 0x1E, 0x78, 0x07, 0x9E, 0x00, 0xF7, 0x00, 0x3F, 0xC0, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xF0, 0x00, 0x3C,
0x00, 0x07, 0x00, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x0F, 0x80, 0x21, 0xFF,
0xF8, 0x3F, 0xFE, 0x03, 0xFF, 0x00, 0x01, 0xF8, 0x1F, 0xF0, 0xFF, 0xC3,
0xC0, 0x0E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x01, 0xFF, 0xCF,
0xFF, 0x3F, 0xFC, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00,
0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80,
0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x00, 0x07,
0xF8, 0xE3, 0xFF, 0x9C, 0xFF, 0xFB, 0x9E, 0x03, 0xF7, 0x80, 0x3E, 0xF0,
0x03, 0xDC, 0x00, 0x7F, 0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F, 0xC0,
0x07, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xE0, 0x03, 0xDC, 0x00, 0x7B, 0xC0,
0x0F, 0x78, 0x03, 0xE7, 0x80, 0xFC, 0xFE, 0xFF, 0x8F, 0xFE, 0xF0, 0x7F,
0x9E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01, 0xC0, 0x00,
0x78, 0x80, 0x1F, 0x1F, 0xDF, 0xC3, 0xFF, 0xF0, 0x3F, 0xF8, 0x00, 0xF0,
0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00,
0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x7F, 0x8F, 0x7F, 0xF3,
0xFF, 0xFE, 0xFC, 0x07, 0xBE, 0x00, 0xFF, 0x80, 0x3F, 0xC0, 0x07, 0xF0,
0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00,
0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F,
0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x70, 0x6F, 0xFF, 0x20, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0x03,
0xC1, 0xE0, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xC1, 0xDB, 0xEF, 0xF7, 0xE0, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03,
0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0,
0x00, 0x3C, 0x03, 0xEF, 0x00, 0xF3, 0xC0, 0x78, 0xF0, 0x3C, 0x3C, 0x1E,
0x0F, 0x0F, 0x03, 0xC7, 0x80, 0xF3, 0xC0, 0x3D, 0xE0, 0x0F, 0xF8, 0x03,
0xFF, 0x00, 0xFF, 0xC0, 0x3E, 0x78, 0x0F, 0x0F, 0x03, 0xC1, 0xE0, 0xF0,
0x78, 0x3C, 0x0F, 0x0F, 0x01, 0xE3, 0xC0, 0x3C, 0xF0, 0x0F, 0x3C, 0x01,
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFC, 0x1F, 0xE3, 0x9F, 0xF8, 0xFF, 0xEF,
0xFF, 0xF7, 0xFF, 0xBF, 0x03, 0xF8, 0x0F, 0xF8, 0x07, 0xC0, 0x3F, 0xC0,
0x1F, 0x00, 0x7F, 0x00, 0x38, 0x01, 0xFC, 0x00, 0xE0, 0x07, 0xF0, 0x03,
0x80, 0x1F, 0xC0, 0x0E, 0x00, 0x7F, 0x00, 0x38, 0x01, 0xFC, 0x00, 0xE0,
0x07, 0xF0, 0x03, 0x80, 0x1F, 0xC0, 0x0E, 0x00, 0x7F, 0x00, 0x38, 0x01,
0xFC, 0x00, 0xE0, 0x07, 0xF0, 0x03, 0x80, 0x1F, 0xC0, 0x0E, 0x00, 0x7F,
0x00, 0x38, 0x01, 0xFC, 0x00, 0xE0, 0x07, 0xF0, 0x03, 0x80, 0x1C, 0xE3,
0xFE, 0x39, 0xFF, 0xCF, 0xFF, 0xFB, 0xF0, 0x1E, 0xF8, 0x03, 0xFE, 0x00,
0xFF, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F,
0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0,
0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xC0, 0x07,
0xFC, 0x00, 0xFF, 0xF0, 0x1F, 0xFF, 0x83, 0xC0, 0x7C, 0x78, 0x03, 0xC7,
0x80, 0x1E, 0x70, 0x01, 0xEF, 0x00, 0x0E, 0xF0, 0x00, 0xEF, 0x00, 0x0F,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xEF, 0x00, 0x0E, 0x70, 0x01,
0xE7, 0x80, 0x1E, 0x78, 0x03, 0xC3, 0xC0, 0x7C, 0x1F, 0xFF, 0x80, 0xFF,
0xF0, 0x03, 0xFC, 0x00, 0xE3, 0xFC, 0x1C, 0xFF, 0xE3, 0xFF, 0xFE, 0x7E,
0x03, 0xCF, 0x80, 0x3D, 0xE0, 0x07, 0xBC, 0x00, 0x7F, 0x80, 0x0F, 0xF0,
0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xE0,
0x03, 0xFC, 0x00, 0x7F, 0xC0, 0x1E, 0xF8, 0x03, 0xDF, 0x80, 0xF3, 0xFE,
0xFE, 0x7B, 0xFF, 0x8F, 0x3F, 0xC1, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80,
0x00, 0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00,
0x01, 0xE0, 0x00, 0x00, 0x07, 0xF8, 0xE3, 0xFF, 0x9C, 0xFE, 0xFB, 0x9E,
0x03, 0xF7, 0x80, 0x3E, 0xF0, 0x03, 0xDC, 0x00, 0x7F, 0x80, 0x0F, 0xF0,
0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xE0,
0x03, 0xDC, 0x00, 0x7B, 0xC0, 0x0F, 0x78, 0x03, 0xE7, 0x80, 0xFC, 0xFE,
0xFF, 0x8F, 0xFE, 0xF0, 0x7F, 0x9E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00,
0x0F, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0xF0, 0x00,
0x1E, 0x00, 0x03, 0xC0, 0xE1, 0xFF, 0x1F, 0xB9, 0xFD, 0xFC, 0x0F, 0xC0,
0x7C, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F,
0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0,
0x0F, 0x00, 0x00, 0x1F, 0xF8, 0x7F, 0xFD, 0xFB, 0xF7, 0x80, 0x2E, 0x00,
0x1C, 0x00, 0x3C, 0x00, 0x7C, 0x00, 0x7F, 0x00, 0x7F, 0x80, 0x3F, 0xC0,
0x0F, 0xC0, 0x07, 0xC0, 0x03, 0xC0, 0x07, 0x80, 0x07, 0x00, 0x1F, 0x00,
0x3F, 0xE3, 0xF7, 0xFF, 0xC7, 0xFE, 0x00, 0x0C, 0x00, 0xC0, 0x1C, 0x01,
0xC0, 0x1C, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0x01, 0xC0, 0x1C, 0x01,
0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01,
0xC0, 0x1C, 0x01, 0xC0, 0x1E, 0x01, 0xFB, 0x0F, 0xF0, 0x7F, 0xF0, 0x03,
0xFC, 0x00, 0xFF, 0x00, 0x3F, 0xC0, 0x0F, 0xF0, 0x03, 0xFC, 0x00, 0xFF,
0x00, 0x3F, 0xC0, 0x0F, 0xF0, 0x03, 0xFC, 0x00, 0xFF, 0x00, 0x3F, 0xC0,
0x0F, 0xF0, 0x03, 0xFC, 0x00, 0xFF, 0x00, 0x3F, 0xC0, 0x0F, 0xF0, 0x07,
0xDE, 0x03, 0xF7, 0xF7, 0xDC, 0xFF, 0xE7, 0x1F, 0xF1, 0xC0, 0xF0, 0x00,
0xF7, 0x00, 0x0E, 0x78, 0x01, 0xE7, 0x80, 0x1E, 0x38, 0x01, 0xC3, 0xC0,
0x3C, 0x3C, 0x03, 0x81, 0xC0, 0x78, 0x1E, 0x07, 0x80, 0xE0, 0x70, 0x0E,
0x0F, 0x00, 0xF0, 0xF0, 0x07, 0x0E, 0x00, 0x79, 0xE0, 0x07, 0x9C, 0x00,
0x39, 0xC0, 0x03, 0xBC, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x00,
0x00, 0xF0, 0x00, 0xF0, 0x07, 0x80, 0x1D, 0xC0, 0x1F, 0x00, 0xF7, 0x80,
0x7C, 0x03, 0xDE, 0x03, 0xF0, 0x0E, 0x38, 0x0E, 0xE0, 0x38, 0xE0, 0x3B,
0x81, 0xE3, 0xC1, 0xEE, 0x07, 0x8F, 0x07, 0x3C, 0x1C, 0x1C, 0x1C, 0x70,
0x70, 0x70, 0x71, 0xC3, 0xC1, 0xE3, 0x87, 0x8E, 0x03, 0x8E, 0x0E, 0x38,
0x0E, 0x38, 0x38, 0xE0, 0x39, 0xC0, 0xE7, 0x80, 0xF7, 0x01, 0xDC, 0x01,
0xDC, 0x07, 0x70, 0x07, 0x70, 0x1D, 0xC0, 0x1F, 0x80, 0x7F, 0x00, 0x3E,
0x00, 0xF8, 0x00, 0xF8, 0x03, 0xE0, 0x03, 0xC0, 0x0F, 0x80, 0xF0, 0x03,
0xEF, 0x00, 0x78, 0xF0, 0x1E, 0x0E, 0x07, 0x81, 0xE0, 0xE0, 0x1E, 0x3C,
0x01, 0xCF, 0x00, 0x3D, 0xC0, 0x03, 0xF8, 0x00, 0x3E, 0x00, 0x07, 0xC0,
0x01, 0xF8, 0x00, 0x3F, 0x80, 0x0F, 0x78, 0x03, 0xC7, 0x00, 0x70, 0xF0,
0x1E, 0x0F, 0x07, 0x80, 0xF1, 0xE0, 0x1E, 0x3C, 0x01, 0xEF, 0x00, 0x1E,
0xF0, 0x00, 0xF7, 0x00, 0x0E, 0x78, 0x01, 0xE7, 0x80, 0x1E, 0x38, 0x01,
0xC3, 0xC0, 0x3C, 0x1C, 0x03, 0xC1, 0xE0, 0x38, 0x1E, 0x07, 0x80, 0xE0,
0x70, 0x0F, 0x0F, 0x00, 0x70, 0xF0, 0x07, 0x0E, 0x00, 0x79, 0xE0, 0x03,
0x9E, 0x00, 0x39, 0xC0, 0x01, 0xFC, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00,
0x0F, 0x80, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00,
0x01, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0xC0, 0x0D, 0xF8, 0x00, 0xFF, 0x00,
0x0F, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xE0, 0x03,
0x80, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x80, 0x1E, 0x00,
0x38, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x01, 0xE0,
0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x78, 0x0F, 0xC0, 0xFE,
0x0F, 0x80, 0x78, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01,
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x3C, 0x0F, 0xC0, 0xFC, 0x07, 0xC0,
0x3F, 0x80, 0x1E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00,
0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0xC0, 0x1E, 0x00, 0x7F, 0x01,
0xF8, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0x07, 0xE0, 0x3F, 0x80, 0x3C,
0x00, 0xF0, 0x07, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0,
0x0E, 0x00, 0x70, 0x03, 0x80, 0x1E, 0x00, 0x7E, 0x01, 0xF8, 0x07, 0xC0,
0xFE, 0x0F, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38,
0x01, 0xC0, 0x0E, 0x00, 0x70, 0x07, 0x80, 0x7C, 0x1F, 0xC0, 0xFC, 0x07,
0x80, 0x00, 0x7F, 0x80, 0x7F, 0xF8, 0x3F, 0x7F, 0xFF, 0x03, 0xFE, 0x80,
0x1E, 0x00 };
const GFXglyph NotoSans_Regular20pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
{ 1, 5, 29, 11, 3, -27 }, // 0x21 '!'
{ 20, 10, 10, 16, 3, -27 }, // 0x22 '"'
{ 33, 23, 28, 25, 1, -27 }, // 0x23 '#'
{ 114, 18, 32, 22, 2, -29 }, // 0x24 '$'
{ 186, 29, 28, 33, 2, -27 }, // 0x25 '%'
{ 288, 27, 28, 29, 2, -27 }, // 0x26 '&'
{ 383, 3, 10, 9, 3, -27 }, // 0x27 '''
{ 387, 9, 34, 12, 2, -27 }, // 0x28 '('
{ 426, 9, 34, 12, 1, -27 }, // 0x29 ')'
{ 465, 18, 18, 22, 2, -29 }, // 0x2A '*'
{ 506, 18, 19, 22, 2, -22 }, // 0x2B '+'
{ 549, 6, 10, 11, 2, -4 }, // 0x2C ','
{ 557, 9, 3, 13, 2, -11 }, // 0x2D '-'
{ 561, 5, 6, 11, 3, -4 }, // 0x2E '.'
{ 565, 14, 28, 15, 0, -27 }, // 0x2F '/'
{ 614, 18, 28, 22, 2, -27 }, // 0x30 '0'
{ 677, 11, 28, 22, 3, -27 }, // 0x31 '1'
{ 716, 18, 28, 22, 2, -27 }, // 0x32 '2'
{ 779, 18, 28, 22, 2, -27 }, // 0x33 '3'
{ 842, 21, 28, 22, 1, -27 }, // 0x34 '4'
{ 916, 18, 28, 22, 2, -27 }, // 0x35 '5'
{ 979, 19, 28, 22, 2, -27 }, // 0x36 '6'
{ 1046, 18, 28, 22, 2, -27 }, // 0x37 '7'
{ 1109, 18, 28, 22, 2, -27 }, // 0x38 '8'
{ 1172, 18, 28, 22, 2, -27 }, // 0x39 '9'
{ 1235, 5, 23, 11, 3, -21 }, // 0x3A ':'
{ 1250, 7, 27, 11, 1, -21 }, // 0x3B ';'
{ 1274, 18, 19, 22, 2, -23 }, // 0x3C '<'
{ 1317, 18, 11, 22, 2, -18 }, // 0x3D '='
{ 1342, 18, 19, 22, 2, -23 }, // 0x3E '>'
{ 1385, 16, 29, 17, 0, -27 }, // 0x3F '?'
{ 1443, 31, 31, 35, 2, -27 }, // 0x40 '@'
{ 1564, 25, 28, 25, 0, -27 }, // 0x41 'A'
{ 1652, 19, 28, 25, 4, -27 }, // 0x42 'B'
{ 1719, 22, 28, 25, 2, -27 }, // 0x43 'C'
{ 1796, 22, 28, 29, 4, -27 }, // 0x44 'D'
{ 1873, 15, 28, 22, 4, -27 }, // 0x45 'E'
{ 1926, 15, 28, 20, 4, -27 }, // 0x46 'F'
{ 1979, 24, 28, 29, 2, -27 }, // 0x47 'G'
{ 2063, 21, 28, 29, 4, -27 }, // 0x48 'H'
{ 2137, 10, 28, 13, 2, -27 }, // 0x49 'I'
{ 2172, 10, 35, 11, -3, -27 }, // 0x4A 'J'
{ 2216, 20, 28, 24, 4, -27 }, // 0x4B 'K'
{ 2286, 16, 28, 21, 4, -27 }, // 0x4C 'L'
{ 2342, 28, 28, 36, 4, -27 }, // 0x4D 'M'
{ 2440, 22, 28, 30, 4, -27 }, // 0x4E 'N'
{ 2517, 26, 28, 31, 2, -27 }, // 0x4F 'O'
{ 2608, 18, 28, 24, 4, -27 }, // 0x50 'P'
{ 2671, 26, 35, 31, 2, -27 }, // 0x51 'Q'
{ 2785, 20, 28, 24, 4, -27 }, // 0x52 'R'
{ 2855, 18, 28, 22, 2, -27 }, // 0x53 'S'
{ 2918, 21, 28, 22, 0, -27 }, // 0x54 'T'
{ 2992, 21, 28, 29, 4, -27 }, // 0x55 'U'
{ 3066, 24, 28, 24, 0, -27 }, // 0x56 'V'
{ 3150, 36, 28, 36, 0, -27 }, // 0x57 'W'
{ 3276, 23, 28, 23, 0, -27 }, // 0x58 'X'
{ 3357, 22, 28, 22, 0, -27 }, // 0x59 'Y'
{ 3434, 20, 28, 22, 1, -27 }, // 0x5A 'Z'
{ 3504, 9, 34, 13, 3, -27 }, // 0x5B '['
{ 3543, 14, 28, 15, 0, -27 }, // 0x5C '\'
{ 3592, 9, 34, 13, 1, -27 }, // 0x5D ']'
{ 3631, 20, 18, 22, 1, -27 }, // 0x5E '^'
{ 3676, 17, 2, 17, 0, 5 }, // 0x5F '_'
{ 3681, 7, 6, 11, 2, -29 }, // 0x60 '`'
{ 3687, 17, 21, 22, 2, -20 }, // 0x61 'a'
{ 3732, 19, 30, 24, 3, -29 }, // 0x62 'b'
{ 3804, 16, 21, 19, 2, -20 }, // 0x63 'c'
{ 3846, 19, 30, 24, 2, -29 }, // 0x64 'd'
{ 3918, 18, 21, 22, 2, -20 }, // 0x65 'e'
{ 3966, 14, 30, 13, 1, -29 }, // 0x66 'f'
{ 4019, 19, 30, 24, 2, -20 }, // 0x67 'g'
{ 4091, 18, 30, 24, 3, -29 }, // 0x68 'h'
{ 4159, 4, 29, 10, 3, -28 }, // 0x69 'i'
{ 4174, 9, 38, 10, -2, -28 }, // 0x6A 'j'
{ 4217, 18, 30, 21, 3, -29 }, // 0x6B 'k'
{ 4285, 4, 30, 10, 3, -29 }, // 0x6C 'l'
{ 4300, 30, 21, 37, 3, -20 }, // 0x6D 'm'
{ 4379, 18, 21, 24, 3, -20 }, // 0x6E 'n'
{ 4427, 20, 21, 24, 2, -20 }, // 0x6F 'o'
{ 4480, 19, 30, 24, 3, -20 }, // 0x70 'p'
{ 4552, 19, 30, 24, 2, -20 }, // 0x71 'q'
{ 4624, 13, 21, 16, 3, -20 }, // 0x72 'r'
{ 4659, 15, 21, 19, 2, -20 }, // 0x73 's'
{ 4699, 12, 26, 14, 1, -25 }, // 0x74 't'
{ 4738, 18, 21, 24, 3, -20 }, // 0x75 'u'
{ 4786, 20, 21, 20, 0, -20 }, // 0x76 'v'
{ 4839, 30, 21, 31, 0, -20 }, // 0x77 'w'
{ 4918, 19, 21, 21, 1, -20 }, // 0x78 'x'
{ 4968, 20, 30, 20, 0, -20 }, // 0x79 'y'
{ 5043, 15, 21, 18, 2, -20 }, // 0x7A 'z'
{ 5083, 13, 34, 15, 1, -27 }, // 0x7B '{'
{ 5139, 3, 39, 22, 9, -29 }, // 0x7C '|'
{ 5154, 13, 34, 15, 1, -27 }, // 0x7D '}'
{ 5210, 18, 5, 22, 2, -15 } }; // 0x7E '~'
const GFXfont NotoSans_Regular20pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular20pt7bBitmaps,
(GFXglyph *)NotoSans_Regular20pt7bGlyphs,
0x20, 0x7E, 53 };
// Approx. 5894 bytes
#endif // NOTOSANS20PT7B_H
@@ -0,0 +1,639 @@
#ifndef NOTOSANS22PT7B_H
#define NOTOSANS22PT7B_H
const uint8_t NotoSans_Regular22pt7bBitmaps[] PROGMEM = {
0x00, 0xFB, 0xDE, 0xF7, 0xBD, 0xEF, 0x7B, 0xDE, 0xF7, 0xB9, 0xCE, 0x73,
0x9C, 0xE7, 0x18, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xE4, 0xF0, 0xFF, 0x0F,
0xF0, 0xFF, 0x0F, 0xF0, 0xEF, 0x0E, 0xE0, 0xEE, 0x0E, 0xE0, 0xE6, 0x0E,
0x60, 0xE0, 0x00, 0x38, 0x1C, 0x00, 0x1E, 0x07, 0x00, 0x07, 0x01, 0xC0,
0x01, 0xC0, 0xE0, 0x00, 0x70, 0x38, 0x00, 0x1C, 0x0E, 0x00, 0x0F, 0x03,
0x80, 0x03, 0x80, 0xE0, 0x00, 0xE0, 0x70, 0x0F, 0xFF, 0xFF, 0xF3, 0xFF,
0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x70, 0x00, 0x70, 0x38, 0x00,
0x1C, 0x0E, 0x00, 0x07, 0x03, 0x80, 0x01, 0xC0, 0xE0, 0x00, 0xE0, 0x38,
0x00, 0x38, 0x1C, 0x03, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF,
0xFF, 0xC0, 0x70, 0x1C, 0x00, 0x1C, 0x0F, 0x00, 0x07, 0x03, 0x80, 0x01,
0xC0, 0xE0, 0x00, 0x70, 0x38, 0x00, 0x3C, 0x0E, 0x00, 0x0E, 0x07, 0x80,
0x03, 0x81, 0xC0, 0x00, 0xE0, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x70, 0x00, 0x7F, 0xE0, 0x3F, 0xFF, 0x8F, 0xFF, 0xF3,
0xF7, 0x7E, 0xF0, 0xE0, 0x9E, 0x1C, 0x03, 0x83, 0x80, 0x70, 0x70, 0x0F,
0x0E, 0x01, 0xE1, 0xC0, 0x3F, 0x38, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x01,
0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x7F, 0xE0, 0x0E, 0x7E, 0x01, 0xC3, 0xC0,
0x38, 0x78, 0x07, 0x07, 0x00, 0xE1, 0xE0, 0x1C, 0x3F, 0x03, 0x8F, 0xFF,
0x7F, 0xEF, 0xFF, 0xF9, 0xFF, 0xFC, 0x07, 0xFC, 0x00, 0x07, 0x00, 0x00,
0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x1F, 0x80, 0x01,
0xC0, 0x3F, 0xE0, 0x03, 0x80, 0x3F, 0xE0, 0x07, 0x80, 0x70, 0xF0, 0x07,
0x00, 0x70, 0x70, 0x0F, 0x00, 0xF0, 0x70, 0x0E, 0x00, 0xE0, 0x38, 0x1E,
0x00, 0xE0, 0x38, 0x1C, 0x00, 0xE0, 0x38, 0x3C, 0x00, 0xE0, 0x38, 0x38,
0x00, 0xE0, 0x38, 0x70, 0x00, 0xE0, 0x38, 0x70, 0x00, 0xE0, 0x78, 0xE1,
0xE0, 0x70, 0x71, 0xE7, 0xF8, 0x70, 0x71, 0xC7, 0xFC, 0x78, 0xF3, 0xCF,
0x1E, 0x3F, 0xE3, 0x8E, 0x0E, 0x3F, 0xE7, 0x9E, 0x0E, 0x0F, 0x87, 0x1C,
0x0E, 0x00, 0x0E, 0x1C, 0x0F, 0x00, 0x0E, 0x1C, 0x0F, 0x00, 0x1C, 0x1C,
0x07, 0x00, 0x3C, 0x1C, 0x07, 0x00, 0x38, 0x1C, 0x0F, 0x00, 0x78, 0x1C,
0x0F, 0x00, 0x70, 0x1C, 0x0E, 0x00, 0xF0, 0x1E, 0x0E, 0x00, 0xE0, 0x0E,
0x1E, 0x01, 0xC0, 0x0F, 0xBC, 0x01, 0xC0, 0x07, 0xFC, 0x03, 0x80, 0x03,
0xF8, 0x01, 0xFE, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x03, 0xFF, 0xE0, 0x00,
0x1F, 0x0F, 0x80, 0x01, 0xE0, 0x3C, 0x00, 0x0F, 0x00, 0xE0, 0x00, 0x78,
0x07, 0x80, 0x03, 0xC0, 0x38, 0x00, 0x1E, 0x03, 0xC0, 0x00, 0x78, 0x1E,
0x00, 0x03, 0xE1, 0xE0, 0x00, 0x0F, 0x3E, 0x00, 0x00, 0x3F, 0xE0, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x01, 0xFF, 0x00, 0x02, 0x1F,
0xFE, 0x01, 0xE1, 0xF1, 0xF8, 0x0F, 0x1F, 0x07, 0xE0, 0x78, 0xF0, 0x1F,
0x87, 0x87, 0x80, 0x7E, 0x3C, 0x78, 0x00, 0xFB, 0xC3, 0xC0, 0x03, 0xFE,
0x1E, 0x00, 0x0F, 0xE0, 0xF0, 0x00, 0x3E, 0x03, 0xC0, 0x01, 0xF8, 0x1F,
0x00, 0x3F, 0xE0, 0xFC, 0x07, 0xEF, 0x83, 0xFF, 0xFE, 0x3E, 0x0F, 0xFF,
0xE0, 0xF8, 0x1F, 0xF8, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0xEE, 0xE6, 0x60,
0x03, 0xC1, 0xE0, 0xF0, 0x38, 0x1E, 0x07, 0x03, 0xC0, 0xF0, 0x78, 0x1E,
0x07, 0x81, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x01, 0xE0, 0x78,
0x1E, 0x03, 0xC0, 0xF0, 0x1C, 0x07, 0x80, 0xE0, 0x3C, 0x07, 0x80, 0xF0,
0xF0, 0x1E, 0x03, 0xC0, 0xF0, 0x1E, 0x07, 0x80, 0xF0, 0x3C, 0x07, 0x01,
0xE0, 0x78, 0x1E, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x78, 0x1E, 0x07,
0x81, 0xE0, 0xF0, 0x3C, 0x1E, 0x07, 0x83, 0xC0, 0xF0, 0x78, 0x3C, 0x00,
0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xE0,
0x00, 0x0E, 0x00, 0x80, 0xE0, 0x2F, 0x8E, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x0F, 0xFF, 0x00, 0x1F, 0x00, 0x03, 0xF8, 0x00, 0x3B, 0xC0, 0x07,
0x9E, 0x00, 0xF1, 0xE0, 0x1F, 0x0F, 0x01, 0xE0, 0xF8, 0x0E, 0x06, 0x00,
0x20, 0x40, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00,
0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70,
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x70, 0x00, 0x07,
0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x07, 0x00, 0x00,
0x70, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x3C, 0xF7, 0xDE, 0x79, 0xE7,
0x3C, 0xE3, 0x8E, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xF7, 0x98,
0x00, 0x0F, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x3C,
0x00, 0x38, 0x00, 0x78, 0x00, 0x78, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xE0,
0x01, 0xE0, 0x01, 0xE0, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x07, 0x80,
0x07, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x1E, 0x00,
0x1E, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x38, 0x00, 0x78, 0x00, 0x78, 0x00,
0xF0, 0x00, 0x03, 0xFC, 0x00, 0x3F, 0xF8, 0x07, 0xFF, 0xE0, 0x3E, 0x0F,
0x83, 0xC0, 0x3C, 0x1E, 0x00, 0xF1, 0xE0, 0x07, 0x8F, 0x00, 0x1E, 0x78,
0x00, 0xF3, 0x80, 0x07, 0xBC, 0x00, 0x3D, 0xE0, 0x00, 0xEF, 0x00, 0x07,
0x78, 0x00, 0x3B, 0xC0, 0x01, 0xFE, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0x80,
0x03, 0xBC, 0x00, 0x1D, 0xE0, 0x00, 0xEF, 0x00, 0x0F, 0x38, 0x00, 0x79,
0xE0, 0x03, 0xCF, 0x00, 0x1E, 0x78, 0x01, 0xE1, 0xE0, 0x0F, 0x0F, 0x00,
0xF8, 0x3C, 0x0F, 0x81, 0xFF, 0xF8, 0x07, 0xFF, 0x80, 0x0F, 0xF8, 0x00,
0x00, 0xE0, 0x3C, 0x1F, 0x87, 0xF1, 0xEE, 0xF9, 0xFE, 0x3F, 0x87, 0x60,
0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0,
0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C,
0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x03, 0xFC, 0x01, 0xFF, 0xF0,
0x3F, 0xFF, 0x8F, 0xE0, 0xFC, 0x78, 0x03, 0xC2, 0x00, 0x1E, 0x00, 0x01,
0xE0, 0x00, 0x1E, 0x00, 0x01, 0xE0, 0x00, 0x1E, 0x00, 0x01, 0xE0, 0x00,
0x1E, 0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x07, 0x80, 0x00, 0xF0, 0x00,
0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00,
0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00,
0x7C, 0x00, 0x0F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0x07, 0xFC, 0x01, 0xFF, 0xF0, 0x7F, 0xFF, 0x8F, 0xC0, 0x7C, 0x70,
0x03, 0xE2, 0x00, 0x1E, 0x00, 0x01, 0xE0, 0x00, 0x1E, 0x00, 0x01, 0xE0,
0x00, 0x1E, 0x00, 0x01, 0xE0, 0x00, 0x3C, 0x00, 0x0F, 0x80, 0x0F, 0xF0,
0x07, 0xFC, 0x00, 0x7F, 0xE0, 0x07, 0xFF, 0x80, 0x00, 0x7E, 0x00, 0x01,
0xE0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00,
0x0F, 0x00, 0x00, 0xF0, 0x00, 0x1F, 0x80, 0x01, 0xEE, 0x00, 0x7E, 0xFF,
0xFF, 0xCF, 0xFF, 0xF0, 0x3F, 0xFE, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x0F,
0x80, 0x00, 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xB8,
0x00, 0x0E, 0x70, 0x00, 0x3C, 0xE0, 0x00, 0xF1, 0xC0, 0x01, 0xC3, 0x80,
0x07, 0x87, 0x00, 0x1E, 0x0E, 0x00, 0x38, 0x1C, 0x00, 0xF0, 0x38, 0x03,
0xC0, 0x70, 0x07, 0x00, 0xE0, 0x1E, 0x01, 0xC0, 0x78, 0x03, 0x81, 0xE0,
0x07, 0x03, 0x80, 0x0E, 0x0F, 0x00, 0x1C, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07,
0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70,
0x00, 0x3F, 0xFF, 0x8F, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0x80,
0x00, 0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x70, 0x00, 0x0E, 0x00,
0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x7F, 0x00, 0xFF, 0xFC, 0x3F, 0xFF,
0xC1, 0xC3, 0xFC, 0x00, 0x07, 0xC0, 0x00, 0x7C, 0x00, 0x07, 0x80, 0x00,
0xF0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01,
0xE0, 0x00, 0x7A, 0x00, 0x1F, 0x70, 0x07, 0xCF, 0xFF, 0xF1, 0xFF, 0xFC,
0x1F, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x0F, 0xFE, 0x00, 0xFF, 0xF0, 0x0F,
0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00,
0x38, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x0F,
0xF0, 0x39, 0xFF, 0xC3, 0xDF, 0xFF, 0x1F, 0xE0, 0x7C, 0xFC, 0x01, 0xF7,
0xC0, 0x07, 0xBE, 0x00, 0x1D, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xB8, 0x00,
0x3D, 0xC0, 0x01, 0xEF, 0x00, 0x0E, 0x78, 0x00, 0xF1, 0xE0, 0x07, 0x8F,
0x80, 0x78, 0x3E, 0x07, 0xC0, 0xFF, 0xFC, 0x03, 0xFF, 0xC0, 0x07, 0xF8,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x3C, 0x00, 0x03,
0xC0, 0x00, 0x1E, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00,
0x07, 0x80, 0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x01, 0xE0,
0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x03,
0xC0, 0x00, 0x3C, 0x00, 0x01, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF0, 0x00,
0x0F, 0x80, 0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x00, 0x03,
0xFE, 0x00, 0xFF, 0xF8, 0x1F, 0xFF, 0xC3, 0xE0, 0x7E, 0x3C, 0x01, 0xE7,
0x80, 0x1E, 0x78, 0x00, 0xE7, 0x80, 0x0F, 0x78, 0x00, 0xE7, 0x80, 0x1E,
0x3C, 0x01, 0xE3, 0xE0, 0x3C, 0x1F, 0x8F, 0x80, 0xFF, 0xF0, 0x03, 0xFC,
0x00, 0x7F, 0xE0, 0x0F, 0xFF, 0x81, 0xF0, 0xFC, 0x3C, 0x03, 0xE7, 0x80,
0x1F, 0x70, 0x00, 0xFF, 0x00, 0x07, 0xF0, 0x00, 0x7F, 0x00, 0x07, 0xF0,
0x00, 0x7F, 0x00, 0x0F, 0x78, 0x00, 0xF7, 0xC0, 0x3E, 0x3F, 0xFF, 0xC1,
0xFF, 0xF8, 0x07, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0xFF, 0xF0, 0x1F, 0xFF,
0x83, 0xE0, 0xFC, 0x7C, 0x03, 0xC7, 0x80, 0x1E, 0x78, 0x01, 0xEF, 0x00,
0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0x00, 0x0F, 0xF0,
0x00, 0xF7, 0x80, 0x0F, 0x78, 0x01, 0xF7, 0xC0, 0x3F, 0x3F, 0xFF, 0x71,
0xFF, 0xEF, 0x0F, 0xF8, 0xF0, 0x08, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0E,
0x00, 0x01, 0xE0, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x07,
0x80, 0x01, 0xF0, 0x3F, 0xFE, 0x03, 0xFF, 0xC0, 0x3F, 0xF0, 0x00, 0x37,
0xFF, 0xFF, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0xEF, 0x30, 0x0C, 0x7C, 0xF9, 0xF3, 0xE3, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF3, 0xE7, 0x8F, 0x1E,
0x78, 0xF1, 0xC3, 0x87, 0x1C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
0x01, 0xF0, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xF8, 0x00,
0x7E, 0x00, 0x1F, 0x80, 0x07, 0xE0, 0x00, 0xF8, 0x00, 0x0F, 0xC0, 0x00,
0x7F, 0x00, 0x01, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F,
0xC0, 0x00, 0xFF, 0x00, 0x01, 0xF0, 0x00, 0x07, 0x00, 0x00, 0x10, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0x00, 0x00, 0xFC, 0x00,
0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07,
0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0xF0, 0x00, 0x1F, 0x00,
0x0F, 0xE0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xC0, 0x0F,
0xF0, 0x00, 0xFC, 0x00, 0x0F, 0x00, 0x00, 0x80, 0x00, 0x00, 0x1F, 0xF0,
0x7F, 0xFE, 0x3F, 0xFF, 0x9F, 0x07, 0xE4, 0x00, 0xF0, 0x00, 0x38, 0x00,
0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x80, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xC0, 0x01, 0xC0,
0x01, 0xE0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00,
0x7C, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x07,
0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x03, 0xF8, 0x0F, 0xE0, 0x03,
0xF0, 0x00, 0x7C, 0x01, 0xF0, 0x00, 0x07, 0x80, 0x78, 0x00, 0x00, 0xF0,
0x3C, 0x00, 0x00, 0x1C, 0x1E, 0x00, 0x00, 0x07, 0x87, 0x00, 0xFF, 0xC0,
0xE3, 0x80, 0xFF, 0xF8, 0x3C, 0xE0, 0x7E, 0x3E, 0x07, 0x78, 0x1E, 0x07,
0x81, 0xDC, 0x0F, 0x01, 0xE0, 0x77, 0x03, 0x80, 0x78, 0x1D, 0xC1, 0xE0,
0x1E, 0x07, 0x70, 0x78, 0x07, 0x81, 0xDC, 0x1E, 0x01, 0xC0, 0x7F, 0x07,
0x00, 0x70, 0x1F, 0xC1, 0xE0, 0x1C, 0x07, 0x70, 0x78, 0x07, 0x03, 0x9C,
0x0E, 0x03, 0xC0, 0xE7, 0x03, 0xC1, 0xF8, 0x79, 0xC0, 0xFD, 0xE7, 0x3C,
0x70, 0x1F, 0xF9, 0xFE, 0x0E, 0x01, 0xF8, 0x3F, 0x03, 0x80, 0x00, 0x00,
0x00, 0xF0, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00,
0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x0F, 0xC0, 0x1F, 0x00, 0x01, 0xFF,
0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0xC0,
0x00, 0x03, 0xF8, 0x00, 0x00, 0x77, 0x80, 0x00, 0x0E, 0xF0, 0x00, 0x03,
0xCE, 0x00, 0x00, 0x71, 0xE0, 0x00, 0x1E, 0x3C, 0x00, 0x03, 0xC3, 0xC0,
0x00, 0x70, 0x78, 0x00, 0x1E, 0x07, 0x00, 0x03, 0xC0, 0xF0, 0x00, 0xF0,
0x1E, 0x00, 0x1E, 0x01, 0xC0, 0x03, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0x80,
0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xE0, 0x1E, 0x00,
0x1E, 0x07, 0x80, 0x03, 0xC0, 0xF0, 0x00, 0x3C, 0x1C, 0x00, 0x07, 0x87,
0x80, 0x00, 0xF0, 0xF0, 0x00, 0x0F, 0x3C, 0x00, 0x01, 0xE7, 0x80, 0x00,
0x3E, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x78, 0xFF, 0xF0, 0x03, 0xFF,
0xFE, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0xF0, 0x03, 0xF3, 0xC0, 0x03,
0xCF, 0x00, 0x0F, 0xBC, 0x00, 0x1E, 0xF0, 0x00, 0x7B, 0xC0, 0x01, 0xCF,
0x00, 0x0F, 0x3C, 0x00, 0x3C, 0xF0, 0x01, 0xE3, 0xFF, 0xFF, 0x0F, 0xFF,
0xE0, 0x3F, 0xFF, 0xE0, 0xFF, 0xFF, 0xE3, 0xC0, 0x07, 0xCF, 0x00, 0x0F,
0xBC, 0x00, 0x1E, 0xF0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x00, 0x03, 0xFC,
0x00, 0x1F, 0xF0, 0x00, 0x7B, 0xC0, 0x03, 0xEF, 0x00, 0x1F, 0xBC, 0x03,
0xFC, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x7F,
0xF0, 0x03, 0xFF, 0xFC, 0x1F, 0xFF, 0xF0, 0x7F, 0x83, 0xE1, 0xF8, 0x00,
0xC7, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00, 0x00, 0x78, 0x00, 0x01,
0xF0, 0x00, 0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x1E,
0x00, 0x00, 0x3C, 0x00, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x00, 0x01, 0xE0,
0x00, 0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x1F, 0x00,
0x00, 0x1E, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00,
0x00, 0x7C, 0x00, 0x00, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF,
0x80, 0x3F, 0xFE, 0x00, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xC0, 0x3F, 0xFF,
0xF8, 0x1F, 0xFF, 0xFE, 0x0F, 0x00, 0x1F, 0x87, 0x80, 0x03, 0xE3, 0xC0,
0x00, 0xF9, 0xE0, 0x00, 0x3C, 0xF0, 0x00, 0x1F, 0x78, 0x00, 0x07, 0xBC,
0x00, 0x03, 0xDE, 0x00, 0x01, 0xEF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F,
0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03,
0xFC, 0x00, 0x03, 0xFE, 0x00, 0x01, 0xEF, 0x00, 0x00, 0xF7, 0x80, 0x00,
0x7B, 0xC0, 0x00, 0x7D, 0xE0, 0x00, 0x3C, 0xF0, 0x00, 0x3E, 0x78, 0x00,
0x3E, 0x3C, 0x00, 0x7E, 0x1E, 0x03, 0xFE, 0x0F, 0xFF, 0xFE, 0x07, 0xFF,
0xFC, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00,
0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F,
0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00,
0x3C, 0x00, 0x1E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0x80, 0x03,
0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00,
0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01,
0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00,
0x07, 0x80, 0x03, 0xC0, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x7F, 0xFF, 0xC0,
0xFF, 0xFF, 0xC1, 0xFF, 0x07, 0xE1, 0xF8, 0x00, 0x30, 0xF8, 0x00, 0x00,
0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3C, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x07, 0x80, 0x00,
0x03, 0xC0, 0x00, 0x01, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00,
0xFF, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0xC0,
0x00, 0x3D, 0xE0, 0x00, 0x1E, 0xF8, 0x00, 0x0F, 0x3C, 0x00, 0x07, 0x9F,
0x00, 0x03, 0xC7, 0xE0, 0x01, 0xE1, 0xFC, 0x00, 0xF0, 0x7F, 0xFF, 0xF8,
0x1F, 0xFF, 0xFC, 0x03, 0xFF, 0xF8, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F,
0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x01, 0xE0, 0x3C, 0x07,
0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80,
0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0,
0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x07, 0xFD, 0xFF, 0xFF, 0xF8, 0x01, 0xE0,
0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C,
0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07,
0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80,
0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x0F, 0x47, 0xEF,
0xF9, 0xFE, 0x3F, 0x00, 0xF0, 0x00, 0x7D, 0xE0, 0x00, 0xF3, 0xC0, 0x03,
0xC7, 0x80, 0x0F, 0x0F, 0x00, 0x3C, 0x1E, 0x00, 0xF0, 0x3C, 0x03, 0xE0,
0x78, 0x0F, 0x80, 0xF0, 0x3E, 0x01, 0xE0, 0xF8, 0x03, 0xC3, 0xE0, 0x07,
0x87, 0x80, 0x0F, 0x1E, 0x00, 0x1E, 0x78, 0x00, 0x3D, 0xF8, 0x00, 0x7F,
0xF0, 0x00, 0xFF, 0xF0, 0x01, 0xF9, 0xF0, 0x03, 0xE1, 0xF0, 0x07, 0x81,
0xE0, 0x0F, 0x03, 0xE0, 0x1E, 0x03, 0xE0, 0x3C, 0x03, 0xC0, 0x78, 0x03,
0xC0, 0xF0, 0x07, 0xC1, 0xE0, 0x07, 0xC3, 0xC0, 0x07, 0x87, 0x80, 0x0F,
0x8F, 0x00, 0x0F, 0x9E, 0x00, 0x0F, 0xBC, 0x00, 0x0F, 0x80, 0xF0, 0x00,
0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F,
0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0,
0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00,
0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F,
0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0x00, 0x00, 0x7F,
0xF8, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x07, 0xFE,
0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFD, 0xC0, 0x00, 0x77, 0xFB,
0xC0, 0x01, 0xEF, 0xF7, 0x80, 0x03, 0xDF, 0xE7, 0x00, 0x07, 0x3F, 0xCF,
0x00, 0x1E, 0x7F, 0x9E, 0x00, 0x38, 0xFF, 0x1E, 0x00, 0xF1, 0xFE, 0x3C,
0x01, 0xE3, 0xFC, 0x38, 0x03, 0x87, 0xF8, 0x78, 0x0F, 0x0F, 0xF0, 0xF0,
0x1C, 0x1F, 0xE0, 0xE0, 0x38, 0x3F, 0xC1, 0xE0, 0xF0, 0x7F, 0x83, 0xC1,
0xC0, 0xFF, 0x03, 0xC7, 0x81, 0xFE, 0x07, 0x8F, 0x03, 0xFC, 0x07, 0x1C,
0x07, 0xF8, 0x0F, 0x78, 0x0F, 0xF0, 0x1E, 0xE0, 0x1F, 0xE0, 0x1F, 0xC0,
0x3F, 0xC0, 0x3F, 0x80, 0x7F, 0x80, 0x7E, 0x00, 0xFF, 0x00, 0x7C, 0x01,
0xFE, 0x00, 0xF8, 0x03, 0xFC, 0x00, 0xE0, 0x07, 0x80, 0xF8, 0x00, 0x07,
0xFC, 0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0xFF, 0xE0, 0x00,
0x7F, 0x78, 0x00, 0x3F, 0xBE, 0x00, 0x1F, 0xEF, 0x00, 0x0F, 0xF3, 0xC0,
0x07, 0xF9, 0xF0, 0x03, 0xFC, 0x78, 0x01, 0xFE, 0x3E, 0x00, 0xFF, 0x0F,
0x80, 0x7F, 0x83, 0xC0, 0x3F, 0xC1, 0xF0, 0x1F, 0xE0, 0x7C, 0x0F, 0xF0,
0x1E, 0x07, 0xF8, 0x0F, 0x83, 0xFC, 0x03, 0xC1, 0xFE, 0x00, 0xF0, 0xFF,
0x00, 0x7C, 0x7F, 0x80, 0x1E, 0x3F, 0xC0, 0x07, 0x9F, 0xE0, 0x03, 0xEF,
0xF0, 0x00, 0xF7, 0xF8, 0x00, 0x7F, 0xFC, 0x00, 0x1F, 0xFE, 0x00, 0x07,
0xFF, 0x00, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x00, 0x3E, 0x00, 0x7F,
0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x07, 0xFF, 0xFE, 0x00, 0xFE, 0x07, 0xF0,
0x1F, 0x00, 0x1F, 0x83, 0xE0, 0x00, 0x78, 0x3C, 0x00, 0x03, 0xC7, 0x80,
0x00, 0x3C, 0x78, 0x00, 0x01, 0xEF, 0x80, 0x00, 0x1E, 0xF0, 0x00, 0x01,
0xEF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFF,
0x80, 0x00, 0x1E, 0x78, 0x00, 0x01, 0xE7, 0x80, 0x00, 0x3E, 0x7C, 0x00,
0x03, 0xC3, 0xE0, 0x00, 0x7C, 0x1F, 0x00, 0x0F, 0x81, 0xFC, 0x03, 0xF0,
0x07, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xF0, 0x00, 0xFF,
0xF0, 0x0F, 0xFF, 0xE0, 0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0xF0, 0x07, 0xEF,
0x00, 0x3E, 0xF0, 0x01, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x01, 0xEF, 0x00, 0x1E, 0xF0, 0x07,
0xCF, 0x03, 0xFC, 0xFF, 0xFF, 0x8F, 0xFF, 0xE0, 0xFF, 0xF8, 0x0F, 0x00,
0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0,
0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F,
0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xFF, 0x80,
0x07, 0xFF, 0xFE, 0x00, 0xFE, 0x07, 0xF0, 0x1F, 0x00, 0x1F, 0x83, 0xE0,
0x00, 0x78, 0x3C, 0x00, 0x03, 0xC7, 0x80, 0x00, 0x3C, 0x78, 0x00, 0x01,
0xEF, 0x80, 0x00, 0x1E, 0xF0, 0x00, 0x01, 0xEF, 0x00, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x1E, 0x78, 0x00,
0x01, 0xE7, 0x80, 0x00, 0x3E, 0x7C, 0x00, 0x03, 0xC3, 0xE0, 0x00, 0x7C,
0x1F, 0x00, 0x0F, 0x81, 0xFC, 0x03, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x3F,
0xFF, 0xC0, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x03, 0xF0, 0x00,
0x00, 0x1F, 0x80, 0x00, 0x00, 0xFC, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x0F,
0xFF, 0xF8, 0x3F, 0xFF, 0xF0, 0xF0, 0x07, 0xE3, 0xC0, 0x07, 0x8F, 0x00,
0x1F, 0x3C, 0x00, 0x3C, 0xF0, 0x00, 0xF3, 0xC0, 0x03, 0xCF, 0x00, 0x0F,
0x3C, 0x00, 0x7C, 0xF0, 0x01, 0xE3, 0xC0, 0x0F, 0x8F, 0x00, 0xFC, 0x3F,
0xFF, 0xE0, 0xFF, 0xFE, 0x03, 0xFF, 0xF0, 0x0F, 0x03, 0xC0, 0x3C, 0x07,
0x80, 0xF0, 0x1F, 0x03, 0xC0, 0x3C, 0x0F, 0x00, 0x78, 0x3C, 0x01, 0xF0,
0xF0, 0x03, 0xC3, 0xC0, 0x0F, 0x8F, 0x00, 0x1E, 0x3C, 0x00, 0x3C, 0xF0,
0x00, 0xFB, 0xC0, 0x01, 0xEF, 0x00, 0x07, 0xC0, 0x03, 0xFF, 0x00, 0xFF,
0xFE, 0x1F, 0xFF, 0xE3, 0xF0, 0x7C, 0x7C, 0x00, 0x47, 0x80, 0x00, 0x78,
0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x07,
0xC0, 0x00, 0x3F, 0x00, 0x01, 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0,
0x00, 0xFF, 0x80, 0x03, 0xFC, 0x00, 0x07, 0xC0, 0x00, 0x3E, 0x00, 0x01,
0xE0, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00, 0xE0, 0x00,
0x1E, 0x80, 0x03, 0xEF, 0x00, 0x7C, 0xFF, 0xFF, 0x8F, 0xFF, 0xF0, 0x7F,
0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x1E,
0x00, 0x00, 0x3C, 0x00, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x00, 0x01, 0xE0,
0x00, 0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x1E, 0x00,
0x00, 0x3C, 0x00, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x00, 0x01, 0xE0, 0x00,
0x03, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x1E, 0x00, 0x00,
0x3C, 0x00, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x00, 0x01, 0xE0, 0x00, 0x03,
0xC0, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0,
0x00, 0x0E, 0xF0, 0x00, 0x1E, 0xF0, 0x00, 0x1E, 0x78, 0x00, 0x1E, 0x78,
0x00, 0x3C, 0x7C, 0x00, 0x7C, 0x3F, 0x01, 0xF8, 0x1F, 0xFF, 0xF0, 0x0F,
0xFF, 0xE0, 0x03, 0xFF, 0x80, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xE7,
0x80, 0x00, 0x79, 0xE0, 0x00, 0x1E, 0x3C, 0x00, 0x0F, 0x0F, 0x00, 0x03,
0xC3, 0xC0, 0x00, 0xF0, 0x78, 0x00, 0x78, 0x1E, 0x00, 0x1E, 0x07, 0x80,
0x0F, 0x80, 0xF0, 0x03, 0xC0, 0x3C, 0x00, 0xF0, 0x0F, 0x00, 0x78, 0x01,
0xE0, 0x1E, 0x00, 0x78, 0x07, 0x80, 0x1E, 0x03, 0xC0, 0x03, 0xC0, 0xF0,
0x00, 0xF0, 0x3C, 0x00, 0x1C, 0x1E, 0x00, 0x07, 0x87, 0x80, 0x01, 0xE1,
0xE0, 0x00, 0x3C, 0xF0, 0x00, 0x0F, 0x3C, 0x00, 0x03, 0xCF, 0x00, 0x00,
0x77, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFC, 0x00,
0x00, 0x3F, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x01, 0xE0, 0x00, 0xF0, 0x00,
0x78, 0x00, 0x3F, 0xE0, 0x01, 0xF0, 0x00, 0x7B, 0xC0, 0x03, 0xF0, 0x00,
0xF7, 0x80, 0x07, 0xE0, 0x01, 0xE7, 0x80, 0x0F, 0xC0, 0x07, 0x8F, 0x00,
0x3F, 0x80, 0x0F, 0x1E, 0x00, 0x7F, 0x80, 0x1E, 0x3C, 0x00, 0xEF, 0x00,
0x3C, 0x3C, 0x03, 0xCE, 0x00, 0xF0, 0x78, 0x07, 0x9E, 0x01, 0xE0, 0xF0,
0x0F, 0x3C, 0x03, 0xC0, 0xE0, 0x1C, 0x38, 0x07, 0x81, 0xE0, 0x78, 0x78,
0x1E, 0x03, 0xC0, 0xF0, 0xF0, 0x3C, 0x07, 0x81, 0xC1, 0xE0, 0x78, 0x07,
0x07, 0x81, 0xE0, 0xE0, 0x0F, 0x0F, 0x03, 0xC3, 0xC0, 0x1E, 0x1E, 0x07,
0x87, 0x80, 0x3C, 0x38, 0x07, 0x0F, 0x00, 0x38, 0xF0, 0x0F, 0x1C, 0x00,
0x79, 0xE0, 0x1E, 0x78, 0x00, 0xF3, 0x80, 0x1C, 0xF0, 0x01, 0xEF, 0x00,
0x39, 0xE0, 0x01, 0xDE, 0x00, 0x7B, 0x80, 0x03, 0xF8, 0x00, 0xFF, 0x00,
0x07, 0xF0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x0F, 0xC0,
0x03, 0xF0, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x3E, 0x00, 0x07, 0xC0,
0x00, 0x3C, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x0F, 0x1E, 0x00, 0x0F,
0x8F, 0x80, 0x07, 0x83, 0xC0, 0x07, 0x80, 0xF0, 0x03, 0xC0, 0x78, 0x03,
0xC0, 0x1E, 0x03, 0xC0, 0x07, 0x81, 0xE0, 0x03, 0xC1, 0xE0, 0x00, 0xF1,
0xE0, 0x00, 0x7C, 0xF0, 0x00, 0x1E, 0xF0, 0x00, 0x07, 0xF0, 0x00, 0x03,
0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x3F, 0x80, 0x00, 0x3D, 0xE0, 0x00, 0x3C, 0x78, 0x00, 0x1E, 0x3C, 0x00,
0x1E, 0x0F, 0x00, 0x0F, 0x03, 0xC0, 0x0F, 0x01, 0xE0, 0x0F, 0x00, 0x78,
0x07, 0x80, 0x3E, 0x07, 0x80, 0x0F, 0x07, 0x80, 0x03, 0xC3, 0xC0, 0x01,
0xE3, 0xC0, 0x00, 0x7B, 0xE0, 0x00, 0x3E, 0xF0, 0x00, 0x0F, 0x78, 0x00,
0x0F, 0x78, 0x00, 0x1E, 0x3C, 0x00, 0x3E, 0x3C, 0x00, 0x3C, 0x1E, 0x00,
0x7C, 0x1F, 0x00, 0x78, 0x0F, 0x00, 0xF0, 0x0F, 0x80, 0xF0, 0x07, 0x81,
0xE0, 0x03, 0xC1, 0xE0, 0x03, 0xC3, 0xC0, 0x01, 0xE3, 0xC0, 0x01, 0xE7,
0x80, 0x00, 0xF7, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C,
0x00, 0x00, 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x00, 0x00,
0xF8, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x07, 0xC0, 0x00, 0x3C, 0x00,
0x03, 0xC0, 0x00, 0x3E, 0x00, 0x01, 0xE0, 0x00, 0x1E, 0x00, 0x01, 0xF0,
0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x80, 0x00, 0x78, 0x00, 0x07,
0x80, 0x00, 0x7C, 0x00, 0x03, 0xC0, 0x00, 0x3C, 0x00, 0x03, 0xE0, 0x00,
0x1E, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFF, 0xFF,
0xFF, 0xF0, 0xF0, 0x00, 0x78, 0x00, 0x78, 0x00, 0x38, 0x00, 0x3C, 0x00,
0x3C, 0x00, 0x1C, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x0F, 0x00,
0x07, 0x00, 0x07, 0x80, 0x07, 0x80, 0x03, 0x80, 0x03, 0xC0, 0x03, 0xC0,
0x01, 0xE0, 0x01, 0xE0, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70,
0x00, 0x78, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x1C, 0x00, 0x1E,
0x00, 0x1E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3F,
0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x60, 0x00, 0x07, 0x80, 0x00, 0x3C, 0x00,
0x03, 0xF0, 0x00, 0x1F, 0x80, 0x01, 0xCE, 0x00, 0x0E, 0x70, 0x00, 0xE1,
0xC0, 0x07, 0x0E, 0x00, 0x70, 0x38, 0x03, 0x81, 0xC0, 0x3C, 0x07, 0x01,
0xC0, 0x38, 0x1E, 0x00, 0xE0, 0xE0, 0x07, 0x0F, 0x00, 0x1C, 0x70, 0x00,
0xE3, 0x80, 0x03, 0xB8, 0x00, 0x1D, 0xC0, 0x00, 0x70, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xF0, 0xF8, 0x7C, 0x3C, 0x1E, 0x0F, 0x07,
0x07, 0xFE, 0x03, 0xFF, 0xF0, 0x7F, 0xFF, 0x0E, 0x03, 0xE0, 0x00, 0x3C,
0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01, 0xE0, 0x1F, 0xFC,
0x3F, 0xFF, 0x9F, 0xFF, 0xF7, 0xE0, 0x1E, 0xF0, 0x03, 0xFC, 0x00, 0x7F,
0x80, 0x0F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x1F, 0xFC, 0x07, 0xF7,
0xFF, 0xDE, 0x7F, 0xF1, 0xC7, 0xFC, 0x38, 0xE0, 0x00, 0x0E, 0x00, 0x00,
0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00,
0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE3, 0xFE, 0x0E, 0x7F,
0xF0, 0xEF, 0xFF, 0xCF, 0xC0, 0x7C, 0xF8, 0x03, 0xEF, 0x00, 0x1E, 0xF0,
0x01, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xE0, 0x00, 0xFE,
0x00, 0x0F, 0xE0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F,
0xF0, 0x01, 0xFF, 0x80, 0x1E, 0xF8, 0x03, 0xEF, 0xC0, 0x7C, 0xEF, 0xFF,
0x8E, 0x7F, 0xF0, 0xE3, 0xFE, 0x00, 0x00, 0x10, 0x01, 0xFF, 0xC3, 0xFF,
0xE3, 0xFF, 0xF3, 0xF0, 0x11, 0xE0, 0x01, 0xF0, 0x00, 0xF0, 0x00, 0x78,
0x00, 0x3C, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03,
0xC0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1F, 0x00, 0x07, 0x80,
0x03, 0xF0, 0x18, 0xFF, 0xFC, 0x3F, 0xFE, 0x07, 0xFE, 0x00, 0x00, 0x78,
0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0x80, 0x00,
0x3C, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x03, 0x03, 0xC1,
0xFF, 0x1E, 0x1F, 0xFE, 0xF1, 0xFF, 0xFF, 0x9F, 0x01, 0xFC, 0xF0, 0x07,
0xEF, 0x80, 0x1F, 0x78, 0x00, 0xFB, 0xC0, 0x03, 0xDE, 0x00, 0x1F, 0xE0,
0x00, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F, 0xC0, 0x01, 0xFE, 0x00, 0x0F,
0x78, 0x00, 0x7B, 0xC0, 0x03, 0xDE, 0x00, 0x3E, 0xF8, 0x01, 0xF3, 0xC0,
0x1F, 0x9F, 0x01, 0xFC, 0x7F, 0xFF, 0xE1, 0xFF, 0xEF, 0x03, 0xFC, 0x38,
0x00, 0x20, 0x00, 0x3F, 0xE0, 0x0F, 0xFF, 0x81, 0xFF, 0xFC, 0x1E, 0x03,
0xC3, 0xC0, 0x1E, 0x78, 0x01, 0xE7, 0x80, 0x0F, 0x78, 0x00, 0xF7, 0x00,
0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xF0,
0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x7C, 0x00, 0x03,
0xE0, 0x00, 0x1F, 0x00, 0x61, 0xFF, 0xFE, 0x07, 0xFF, 0xE0, 0x3F, 0xFC,
0x00, 0xFE, 0x03, 0xFF, 0x07, 0xFE, 0x07, 0xC2, 0x0F, 0x00, 0x0F, 0x00,
0x0F, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x7F, 0xF8, 0xFF, 0xF8,
0xFF, 0xF8, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00,
0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00,
0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00,
0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x60, 0x00, 0x3F, 0xE1, 0xC3,
0xFF, 0xCE, 0x3F, 0xFF, 0xF3, 0xE0, 0x3F, 0x9E, 0x00, 0xFD, 0xF0, 0x03,
0xEF, 0x00, 0x1F, 0x78, 0x00, 0x7B, 0xC0, 0x03, 0xFC, 0x00, 0x1F, 0xE0,
0x00, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F, 0xE0, 0x01, 0xEF, 0x00, 0x0F,
0x78, 0x00, 0x7B, 0xC0, 0x03, 0xDF, 0x00, 0x3E, 0x78, 0x03, 0xF3, 0xE0,
0x3F, 0x8F, 0xFF, 0xFC, 0x3F, 0xFD, 0xE0, 0x7F, 0x8F, 0x00, 0x00, 0x78,
0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00, 0xF0, 0x00, 0x0F, 0x10, 0x00,
0xF8, 0xE0, 0x0F, 0x87, 0xFF, 0xFC, 0x3F, 0xFF, 0xC0, 0x7F, 0xF8, 0x00,
0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01,
0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03,
0x8F, 0xFC, 0x73, 0xFF, 0xCE, 0xFF, 0xFD, 0xF8, 0x0F, 0xBE, 0x00, 0xFF,
0xC0, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFE,
0x00, 0x1F, 0xC0, 0x03, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC,
0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03, 0xF8,
0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xE0, 0x33, 0xFF, 0xF7, 0x00, 0x00,
0x03, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C,
0xE7, 0x39, 0xCE, 0x01, 0x80, 0xF0, 0x7C, 0x1F, 0x03, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0,
0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E,
0x03, 0x81, 0xE0, 0x7B, 0xFE, 0xFF, 0x3F, 0x80, 0xE0, 0x00, 0x1C, 0x00,
0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00,
0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x1F, 0x70, 0x07,
0x8E, 0x01, 0xF1, 0xC0, 0x7C, 0x38, 0x1F, 0x07, 0x07, 0xC0, 0xE1, 0xF0,
0x1C, 0x7C, 0x03, 0x9F, 0x00, 0x73, 0xC0, 0x0E, 0xF8, 0x01, 0xFF, 0x80,
0x3F, 0xF8, 0x07, 0xCF, 0x00, 0xE0, 0xF0, 0x1C, 0x1F, 0x03, 0x81, 0xF0,
0x70, 0x1E, 0x0E, 0x01, 0xE1, 0xC0, 0x3E, 0x38, 0x03, 0xE7, 0x00, 0x3C,
0xE0, 0x03, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x71, 0xFF, 0x03, 0xFE,
0x39, 0xFF, 0xC7, 0xFF, 0x9D, 0xFF, 0xF7, 0xFF, 0xEF, 0xC0, 0x7F, 0x81,
0xF7, 0xC0, 0x3F, 0x80, 0x7B, 0xC0, 0x0F, 0x80, 0x1F, 0xE0, 0x07, 0xC0,
0x0F, 0xF0, 0x03, 0xC0, 0x07, 0xF8, 0x01, 0xE0, 0x03, 0xFC, 0x00, 0xF0,
0x01, 0xFC, 0x00, 0x78, 0x00, 0xFE, 0x00, 0x3C, 0x00, 0x7F, 0x00, 0x1E,
0x00, 0x3F, 0x80, 0x0F, 0x00, 0x1F, 0xC0, 0x07, 0x80, 0x0F, 0xE0, 0x03,
0xC0, 0x07, 0xF0, 0x01, 0xE0, 0x03, 0xF8, 0x00, 0xF0, 0x01, 0xFC, 0x00,
0x78, 0x00, 0xFE, 0x00, 0x3C, 0x00, 0x7F, 0x00, 0x1E, 0x00, 0x3F, 0x80,
0x0F, 0x00, 0x1F, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x30, 0x1C, 0x7F, 0xE3,
0x9F, 0xFE, 0x77, 0xFF, 0xEF, 0xC0, 0x7D, 0xF0, 0x07, 0xFC, 0x00, 0x7F,
0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF0, 0x00, 0xFE,
0x00, 0x1F, 0xC0, 0x03, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC,
0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03, 0xF8,
0x00, 0x7F, 0x00, 0x0F, 0x00, 0x10, 0x00, 0x0F, 0xFC, 0x00, 0xFF, 0xFC,
0x07, 0xFF, 0xF8, 0x3E, 0x03, 0xE0, 0xF0, 0x03, 0xC7, 0xC0, 0x0F, 0x9E,
0x00, 0x1E, 0x78, 0x00, 0x79, 0xE0, 0x00, 0xEF, 0x00, 0x03, 0xFC, 0x00,
0x0F, 0xF0, 0x00, 0x3F, 0xC0, 0x00, 0xFF, 0x00, 0x03, 0xDE, 0x00, 0x0E,
0x78, 0x00, 0x79, 0xE0, 0x01, 0xE3, 0xC0, 0x0F, 0x8F, 0x00, 0x3C, 0x1F,
0x03, 0xE0, 0x3F, 0xFF, 0x80, 0x7F, 0xFC, 0x00, 0xFF, 0xC0, 0x00, 0x20,
0x0E, 0x3F, 0xE0, 0xE7, 0xFF, 0x8E, 0xFF, 0xFC, 0xFC, 0x07, 0xCF, 0x80,
0x3E, 0xF0, 0x01, 0xEF, 0x00, 0x1F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0,
0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xF0, 0x00, 0xFF,
0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x1E, 0xF8, 0x01, 0xEF, 0x80, 0x3E,
0xFE, 0x07, 0xCE, 0xFF, 0xF8, 0xE7, 0xFF, 0x0E, 0x3F, 0xE0, 0xE0, 0x00,
0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00,
0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x60, 0x00, 0x1F, 0xE1, 0xC3, 0xFF, 0xCE, 0x3F, 0xFF, 0xF3, 0xE0, 0x3F,
0x9E, 0x00, 0xFD, 0xF0, 0x03, 0xEF, 0x00, 0x1F, 0x78, 0x00, 0x7B, 0xC0,
0x03, 0xFC, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F,
0xC0, 0x01, 0xEF, 0x00, 0x0F, 0x78, 0x00, 0x7B, 0xC0, 0x07, 0xDF, 0x00,
0x3E, 0x78, 0x03, 0xF3, 0xE0, 0x3F, 0x8F, 0xFF, 0xFC, 0x3F, 0xFD, 0xE0,
0x7F, 0x8F, 0x00, 0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x1E, 0x00, 0x00,
0xF0, 0x00, 0x07, 0x80, 0x00, 0x3C, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00,
0x00, 0x78, 0x00, 0x03, 0xC0, 0x00, 0x27, 0x0F, 0xF9, 0xFF, 0xDF, 0xFE,
0xF0, 0x7E, 0x03, 0xE0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xC0,
0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01,
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0x00, 0xC0, 0x07, 0xFF,
0x0F, 0xFF, 0xCF, 0xFF, 0xE7, 0x80, 0x67, 0x80, 0x03, 0xC0, 0x01, 0xE0,
0x00, 0xF8, 0x00, 0x3F, 0x00, 0x0F, 0xE0, 0x03, 0xFE, 0x00, 0x7F, 0xC0,
0x0F, 0xF0, 0x00, 0xFC, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01,
0xE0, 0x00, 0xEE, 0x00, 0xF7, 0xFF, 0xF3, 0xFF, 0xF8, 0xFF, 0xF0, 0x0E,
0x00, 0x38, 0x00, 0xE0, 0x07, 0x80, 0x1E, 0x01, 0xFF, 0xEF, 0xFF, 0xBF,
0xFE, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01,
0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00,
0x78, 0x01, 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x3F, 0xF0, 0x7F, 0xC0, 0xFF,
0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00,
0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00,
0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x00, 0x0F, 0xF0,
0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xF7, 0x80, 0x1F, 0x78, 0x03, 0xF7,
0xC0, 0x7F, 0x3F, 0xFF, 0xF1, 0xFF, 0xE7, 0x0F, 0xF8, 0x70, 0xF0, 0x00,
0x3D, 0xE0, 0x01, 0xE7, 0x80, 0x07, 0x9E, 0x00, 0x1E, 0x3C, 0x00, 0xF0,
0xF0, 0x03, 0xC1, 0xC0, 0x1E, 0x07, 0x80, 0x78, 0x1E, 0x01, 0xE0, 0x3C,
0x0F, 0x00, 0xF0, 0x3C, 0x03, 0xC0, 0xE0, 0x07, 0x87, 0x80, 0x1E, 0x1E,
0x00, 0x38, 0x70, 0x00, 0xF3, 0xC0, 0x03, 0xCF, 0x00, 0x07, 0x38, 0x00,
0x1F, 0xE0, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x07,
0x80, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0xBC, 0x01, 0xF8, 0x03, 0xDE, 0x00,
0xFC, 0x01, 0xEF, 0x00, 0x7E, 0x00, 0xE3, 0xC0, 0x7F, 0x00, 0xF1, 0xE0,
0x3B, 0xC0, 0x78, 0xF0, 0x1C, 0xE0, 0x3C, 0x38, 0x1E, 0x70, 0x1C, 0x1E,
0x0F, 0x3C, 0x1E, 0x0F, 0x07, 0x1E, 0x0F, 0x07, 0x83, 0x87, 0x07, 0x01,
0xC3, 0xC3, 0xC7, 0x80, 0xF1, 0xC1, 0xE3, 0xC0, 0x78, 0xE0, 0x71, 0xE0,
0x3C, 0xF0, 0x38, 0xE0, 0x0E, 0x70, 0x1E, 0xF0, 0x07, 0xB8, 0x07, 0x78,
0x03, 0xDC, 0x03, 0xBC, 0x00, 0xFE, 0x01, 0xDC, 0x00, 0x7E, 0x00, 0xFE,
0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x1F, 0x00, 0x07, 0x80, 0x0F,
0x80, 0xF8, 0x00, 0xFB, 0xE0, 0x0F, 0x0F, 0x00, 0x78, 0x3C, 0x07, 0x81,
0xF0, 0x78, 0x07, 0x83, 0xC0, 0x1E, 0x3C, 0x00, 0x7B, 0xC0, 0x03, 0xFE,
0x00, 0x0F, 0xE0, 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x1F, 0xC0, 0x01,
0xFE, 0x00, 0x0F, 0x78, 0x00, 0xF1, 0xE0, 0x0F, 0x8F, 0x00, 0x78, 0x3C,
0x07, 0x80, 0xF0, 0x78, 0x07, 0xC3, 0xC0, 0x1E, 0x3C, 0x00, 0x7B, 0xC0,
0x03, 0xE0, 0xF0, 0x00, 0x3D, 0xE0, 0x01, 0xE7, 0x80, 0x07, 0x9E, 0x00,
0x1E, 0x3C, 0x00, 0xF0, 0xF0, 0x03, 0xC1, 0xE0, 0x1E, 0x07, 0x80, 0x78,
0x1E, 0x01, 0xE0, 0x3C, 0x0F, 0x00, 0xF0, 0x3C, 0x01, 0xC0, 0xF0, 0x07,
0x87, 0x80, 0x0E, 0x1E, 0x00, 0x3C, 0x70, 0x00, 0xF3, 0xC0, 0x01, 0xCF,
0x00, 0x07, 0xB8, 0x00, 0x1F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFC, 0x00,
0x01, 0xF0, 0x00, 0x07, 0x80, 0x00, 0x1E, 0x00, 0x00, 0x78, 0x00, 0x03,
0xC0, 0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0x00,
0x0F, 0xFC, 0x00, 0x3F, 0xE0, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x7F,
0xFF, 0xBF, 0xFF, 0xC0, 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xE0, 0x00, 0xF0,
0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78,
0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3E, 0x00, 0x1E, 0x00, 0x1E,
0x00, 0x1E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x1C,
0x01, 0xF0, 0x1F, 0xC0, 0xFE, 0x03, 0xC0, 0x0F, 0x00, 0x78, 0x01, 0xE0,
0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78,
0x01, 0xE0, 0x0F, 0x83, 0xFC, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0x3E,
0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07,
0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80,
0x7F, 0x00, 0xFC, 0x00, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x03,
0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x01, 0xE0,
0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78,
0x01, 0xE0, 0x03, 0xC0, 0x07, 0xF0, 0x0F, 0xC0, 0x1F, 0x01, 0xFC, 0x0F,
0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07,
0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x3C, 0x07, 0xF0, 0x3F,
0x80, 0xFC, 0x03, 0x80, 0x00, 0x1F, 0x80, 0x17, 0xFE, 0x01, 0xFF, 0xFE,
0xFE, 0x0F, 0xFF, 0xC0, 0x3F, 0xE8, 0x00, 0x78 };
const GFXglyph NotoSans_Regular22pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 11, 0, 0 }, // 0x20 ' '
{ 1, 5, 32, 12, 3, -30 }, // 0x21 '!'
{ 21, 12, 11, 18, 3, -30 }, // 0x22 '"'
{ 38, 26, 31, 28, 1, -30 }, // 0x23 '#'
{ 139, 19, 36, 25, 3, -32 }, // 0x24 '$'
{ 225, 32, 31, 36, 2, -30 }, // 0x25 '%'
{ 349, 29, 31, 32, 2, -30 }, // 0x26 '&'
{ 462, 4, 11, 10, 3, -30 }, // 0x27 '''
{ 468, 10, 38, 13, 2, -30 }, // 0x28 '('
{ 516, 10, 38, 13, 1, -30 }, // 0x29 ')'
{ 564, 20, 20, 24, 2, -32 }, // 0x2A '*'
{ 614, 20, 21, 25, 2, -25 }, // 0x2B '+'
{ 667, 6, 11, 12, 2, -4 }, // 0x2C ','
{ 676, 10, 3, 14, 2, -12 }, // 0x2D '-'
{ 680, 5, 6, 12, 3, -4 }, // 0x2E '.'
{ 684, 16, 31, 16, 0, -30 }, // 0x2F '/'
{ 746, 21, 31, 25, 2, -30 }, // 0x30 '0'
{ 828, 11, 31, 25, 4, -30 }, // 0x31 '1'
{ 871, 20, 31, 25, 2, -30 }, // 0x32 '2'
{ 949, 20, 31, 25, 2, -30 }, // 0x33 '3'
{ 1027, 23, 31, 25, 1, -30 }, // 0x34 '4'
{ 1117, 19, 31, 25, 3, -30 }, // 0x35 '5'
{ 1191, 21, 31, 25, 2, -30 }, // 0x36 '6'
{ 1273, 21, 31, 25, 2, -30 }, // 0x37 '7'
{ 1355, 20, 31, 25, 2, -30 }, // 0x38 '8'
{ 1433, 20, 31, 25, 2, -30 }, // 0x39 '9'
{ 1511, 5, 25, 12, 3, -23 }, // 0x3A ':'
{ 1527, 7, 30, 12, 1, -23 }, // 0x3B ';'
{ 1554, 20, 21, 25, 2, -25 }, // 0x3C '<'
{ 1607, 20, 12, 25, 2, -20 }, // 0x3D '='
{ 1637, 20, 21, 25, 2, -25 }, // 0x3E '>'
{ 1690, 17, 32, 19, 1, -30 }, // 0x3F '?'
{ 1758, 34, 35, 39, 2, -30 }, // 0x40 '@'
{ 1907, 27, 31, 28, 0, -30 }, // 0x41 'A'
{ 2012, 22, 31, 28, 4, -30 }, // 0x42 'B'
{ 2098, 23, 31, 27, 3, -30 }, // 0x43 'C'
{ 2188, 25, 31, 31, 4, -30 }, // 0x44 'D'
{ 2285, 17, 31, 24, 4, -30 }, // 0x45 'E'
{ 2351, 17, 31, 22, 4, -30 }, // 0x46 'F'
{ 2417, 25, 31, 31, 3, -30 }, // 0x47 'G'
{ 2514, 24, 31, 32, 4, -30 }, // 0x48 'H'
{ 2607, 11, 31, 15, 2, -30 }, // 0x49 'I'
{ 2650, 11, 39, 12, -3, -30 }, // 0x4A 'J'
{ 2704, 23, 31, 27, 4, -30 }, // 0x4B 'K'
{ 2794, 18, 31, 23, 4, -30 }, // 0x4C 'L'
{ 2864, 31, 31, 39, 4, -30 }, // 0x4D 'M'
{ 2985, 25, 31, 33, 4, -30 }, // 0x4E 'N'
{ 3082, 28, 31, 34, 3, -30 }, // 0x4F 'O'
{ 3191, 20, 31, 26, 4, -30 }, // 0x50 'P'
{ 3269, 28, 38, 34, 3, -30 }, // 0x51 'Q'
{ 3402, 22, 31, 27, 4, -30 }, // 0x52 'R'
{ 3488, 20, 31, 24, 2, -30 }, // 0x53 'S'
{ 3566, 23, 31, 24, 0, -30 }, // 0x54 'T'
{ 3656, 24, 31, 31, 4, -30 }, // 0x55 'U'
{ 3749, 26, 31, 26, 0, -30 }, // 0x56 'V'
{ 3850, 39, 31, 40, 1, -30 }, // 0x57 'W'
{ 4002, 25, 31, 25, 0, -30 }, // 0x58 'X'
{ 4099, 24, 31, 24, 0, -30 }, // 0x59 'Y'
{ 4192, 21, 31, 25, 2, -30 }, // 0x5A 'Z'
{ 4274, 10, 38, 14, 3, -30 }, // 0x5B '['
{ 4322, 16, 31, 16, 0, -30 }, // 0x5C '\'
{ 4384, 10, 38, 14, 1, -30 }, // 0x5D ']'
{ 4432, 21, 20, 25, 2, -30 }, // 0x5E '^'
{ 4485, 19, 3, 19, 0, 5 }, // 0x5F '_'
{ 4493, 8, 7, 12, 2, -32 }, // 0x60 '`'
{ 4500, 19, 23, 24, 2, -22 }, // 0x61 'a'
{ 4555, 20, 33, 27, 4, -32 }, // 0x62 'b'
{ 4638, 17, 24, 21, 2, -23 }, // 0x63 'c'
{ 4689, 21, 33, 27, 2, -32 }, // 0x64 'd'
{ 4776, 20, 24, 24, 2, -23 }, // 0x65 'e'
{ 4836, 16, 33, 15, 1, -32 }, // 0x66 'f'
{ 4902, 21, 34, 27, 2, -23 }, // 0x67 'g'
{ 4992, 19, 33, 27, 4, -32 }, // 0x68 'h'
{ 5071, 5, 32, 11, 3, -31 }, // 0x69 'i'
{ 5091, 10, 42, 11, -2, -31 }, // 0x6A 'j'
{ 5144, 19, 33, 23, 4, -32 }, // 0x6B 'k'
{ 5223, 3, 33, 11, 4, -32 }, // 0x6C 'l'
{ 5236, 33, 24, 40, 4, -23 }, // 0x6D 'm'
{ 5335, 19, 24, 27, 4, -23 }, // 0x6E 'n'
{ 5392, 22, 24, 26, 2, -23 }, // 0x6F 'o'
{ 5458, 20, 34, 27, 4, -23 }, // 0x70 'p'
{ 5543, 21, 34, 27, 2, -23 }, // 0x71 'q'
{ 5633, 13, 24, 18, 4, -23 }, // 0x72 'r'
{ 5672, 17, 24, 21, 2, -23 }, // 0x73 's'
{ 5723, 14, 28, 16, 1, -27 }, // 0x74 't'
{ 5772, 20, 23, 27, 3, -22 }, // 0x75 'u'
{ 5830, 22, 23, 22, 0, -22 }, // 0x76 'v'
{ 5894, 33, 23, 34, 0, -22 }, // 0x77 'w'
{ 5989, 21, 23, 23, 1, -22 }, // 0x78 'x'
{ 6050, 22, 33, 22, 0, -22 }, // 0x79 'y'
{ 6141, 17, 23, 20, 2, -22 }, // 0x7A 'z'
{ 6190, 14, 38, 16, 1, -30 }, // 0x7B '{'
{ 6257, 3, 43, 24, 10, -32 }, // 0x7C '|'
{ 6274, 14, 38, 16, 1, -30 }, // 0x7D '}'
{ 6341, 20, 6, 25, 2, -17 } }; // 0x7E '~'
const GFXfont NotoSans_Regular22pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular22pt7bBitmaps,
(GFXglyph *)NotoSans_Regular22pt7bGlyphs,
0x20, 0x7E, 59 };
// Approx. 7028 bytes
#endif // NOTOSANS22PT7B_H
@@ -0,0 +1,166 @@
#ifndef NOTOSANS7PT7B_H
#define NOTOSANS7PT7B_H
const uint8_t NotoSans_Regular7pt7bBitmaps[] PROGMEM = {
0x00, 0xFA, 0xA8, 0xB0, 0xBB, 0x99, 0x12, 0x09, 0x04, 0x8F, 0xF1, 0x41,
0x23, 0xFC, 0x48, 0x24, 0x16, 0x00, 0x21, 0xFA, 0x28, 0xE0, 0xE2, 0x49,
0xF8, 0x82, 0x00, 0xE1, 0x2C, 0x89, 0x22, 0x50, 0x97, 0xBA, 0xB1, 0x24,
0x49, 0x22, 0x58, 0xE0, 0x78, 0x24, 0x13, 0x09, 0x03, 0x02, 0x8A, 0x25,
0x0C, 0x86, 0x3C, 0xC0, 0xF0, 0x6A, 0x49, 0x24, 0x93, 0x30, 0xC4, 0x22,
0x23, 0x32, 0x22, 0x6C, 0x22, 0x9F, 0xCC, 0x5B, 0x20, 0x20, 0x82, 0x3F,
0x20, 0x80, 0xEA, 0xE0, 0xB0, 0x08, 0x84, 0x22, 0x11, 0x88, 0x44, 0x00,
0x7B, 0x28, 0x61, 0x86, 0x18, 0x61, 0xCD, 0xE0, 0x37, 0xD1, 0x11, 0x11,
0x11, 0x7A, 0x20, 0xC3, 0x08, 0x43, 0x18, 0xC3, 0xF0, 0x7A, 0x30, 0x43,
0x78, 0x60, 0x41, 0x8F, 0xE0, 0x04, 0x0C, 0x14, 0x14, 0x24, 0x44, 0xC4,
0xFF, 0x04, 0x04, 0xFA, 0x08, 0x20, 0xF8, 0x30, 0x41, 0x8F, 0xE0, 0x39,
0x0C, 0x20, 0xFA, 0x18, 0x61, 0xC5, 0xE0, 0xFC, 0x10, 0xC2, 0x18, 0x43,
0x08, 0x21, 0x00, 0x7B, 0x38, 0x73, 0x79, 0x68, 0x61, 0x85, 0xE0, 0x73,
0x28, 0x61, 0x87, 0xF0, 0x43, 0x0B, 0xC0, 0xB0, 0x0B, 0x4C, 0x00, 0x1A,
0x50, 0x0C, 0xEC, 0x30, 0x30, 0x30, 0xFC, 0x00, 0x3F, 0x81, 0x81, 0x83,
0x33, 0x00, 0x7A, 0x20, 0xC2, 0x18, 0xC2, 0x00, 0x20, 0x80, 0x0E, 0x06,
0x31, 0x01, 0x47, 0xA9, 0x23, 0x24, 0x64, 0x94, 0xBA, 0x88, 0x88, 0x00,
0xFC, 0x00, 0x08, 0x0C, 0x05, 0x02, 0x82, 0x61, 0x11, 0xF8, 0x82, 0x41,
0x40, 0xC0, 0xF9, 0x8F, 0x0E, 0x3F, 0xD9, 0xB0, 0xE1, 0xC7, 0xF8, 0x3E,
0xC7, 0x04, 0x08, 0x10, 0x20, 0x60, 0x60, 0x7C, 0xF8, 0xC6, 0xC3, 0xC1,
0xC1, 0xC1, 0xC1, 0xC3, 0xC6, 0xFC, 0xFF, 0x0C, 0x30, 0xFF, 0x0C, 0x30,
0xC3, 0xF0, 0xFF, 0x0C, 0x30, 0xC3, 0xFC, 0x30, 0xC3, 0x00, 0x1E, 0x61,
0xC0, 0x80, 0x80, 0x87, 0x81, 0xC1, 0x61, 0x3F, 0xC1, 0xC1, 0xC1, 0xC1,
0xFF, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xE9, 0x24, 0x92, 0x5C, 0x33, 0x33,
0x33, 0x33, 0x33, 0x2E, 0xC0, 0xC3, 0x8B, 0x26, 0x8E, 0x1A, 0x36, 0x66,
0xC5, 0x84, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0xF0, 0xC0, 0xF8,
0x3A, 0x1E, 0x85, 0x91, 0x64, 0x99, 0xA6, 0x29, 0x8C, 0x63, 0x10, 0xC1,
0xE1, 0xA1, 0xB1, 0x99, 0x89, 0x8D, 0x85, 0x83, 0x83, 0x3E, 0x31, 0xB0,
0x50, 0x38, 0x0C, 0x06, 0x07, 0x82, 0x43, 0x1F, 0x00, 0xF9, 0x9B, 0x1E,
0x3C, 0x5F, 0x30, 0x60, 0xC1, 0x80, 0x3E, 0x31, 0xB0, 0x50, 0x38, 0x0C,
0x06, 0x07, 0x82, 0x43, 0x1F, 0x01, 0x80, 0x60, 0xF9, 0x9B, 0x1E, 0x3C,
0x5F, 0x32, 0x66, 0xC5, 0x84, 0x7B, 0x18, 0x20, 0x60, 0xE0, 0xC1, 0x8F,
0xE0, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x20, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0xC3, 0x42, 0x3C, 0x81, 0xC3, 0x42, 0x42,
0x26, 0x24, 0x34, 0x1C, 0x18, 0x18, 0xC2, 0x1A, 0x30, 0x91, 0x44, 0x8A,
0x66, 0xD2, 0x14, 0xD0, 0xA2, 0x85, 0x1C, 0x30, 0xC0, 0x82, 0x00, 0xC3,
0x42, 0x24, 0x3C, 0x18, 0x18, 0x3C, 0x24, 0x42, 0xC3, 0x83, 0x42, 0x66,
0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFC, 0x10, 0x86, 0x10, 0x86,
0x10, 0x83, 0xF0, 0xF2, 0x49, 0x24, 0x92, 0x70, 0x82, 0x10, 0xC2, 0x10,
0xC2, 0x10, 0x40, 0xE4, 0x92, 0x49, 0x24, 0xF0, 0x20, 0xC5, 0x12, 0x8A,
0x10, 0xFC, 0xB4, 0xF8, 0x30, 0xFF, 0x8E, 0x3F, 0x40, 0x81, 0x02, 0x07,
0xEC, 0x50, 0xE1, 0xC3, 0xC5, 0x78, 0x7C, 0x21, 0x08, 0x61, 0xE0, 0x04,
0x10, 0x5F, 0x86, 0x18, 0x61, 0xC5, 0xF0, 0x7A, 0x18, 0x7F, 0x83, 0x07,
0xC0, 0x39, 0x19, 0xF6, 0x31, 0x8C, 0x63, 0x00, 0x7E, 0x18, 0x61, 0x87,
0x17, 0xC1, 0x07, 0xE0, 0x82, 0x08, 0x2F, 0xC6, 0x18, 0x61, 0x86, 0x10,
0x9F, 0xC0, 0x20, 0x12, 0x49, 0x24, 0x9E, 0x82, 0x08, 0x62, 0x92, 0x8F,
0x24, 0x8A, 0x30, 0xFF, 0xC0, 0xFF, 0xD8, 0x8E, 0x10, 0xC2, 0x18, 0x43,
0x08, 0x61, 0x08, 0xFF, 0x18, 0x61, 0x86, 0x18, 0x40, 0x7D, 0x0A, 0x14,
0x38, 0x58, 0x9E, 0x00, 0xFD, 0x8A, 0x1C, 0x38, 0x78, 0xAF, 0x40, 0x81,
0x00, 0x7E, 0x18, 0x61, 0x87, 0x17, 0xC1, 0x04, 0x10, 0xBC, 0x88, 0x88,
0x80, 0xFC, 0x30, 0x60, 0x87, 0xC0, 0x22, 0x3E, 0x84, 0x21, 0x0C, 0x38,
0x86, 0x18, 0x61, 0x87, 0x17, 0xC0, 0xC6, 0x89, 0x13, 0x62, 0x85, 0x04,
0x00, 0xCC, 0x69, 0x49, 0x29, 0x25, 0x67, 0x38, 0x63, 0x0C, 0x60, 0xC6,
0x58, 0xE0, 0xC2, 0x8C, 0xB1, 0x80, 0xC6, 0x89, 0x11, 0x62, 0x85, 0x04,
0x08, 0x31, 0xC0, 0xF8, 0x88, 0xC4, 0x43, 0xE0, 0x19, 0x88, 0x42, 0x33,
0x84, 0x21, 0x08, 0x30, 0xFF, 0xF8, 0xC1, 0x08, 0x42, 0x18, 0x64, 0x21,
0x09, 0xC0, 0xE6, 0xF0 };
const GFXglyph NotoSans_Regular7pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
{ 1, 2, 10, 4, 1, -9 }, // 0x21 '!'
{ 4, 4, 4, 6, 1, -9 }, // 0x22 '"'
{ 6, 9, 10, 9, 0, -9 }, // 0x23 '#'
{ 18, 6, 11, 8, 1, -9 }, // 0x24 '$'
{ 27, 10, 10, 11, 1, -9 }, // 0x25 '%'
{ 40, 9, 10, 10, 1, -9 }, // 0x26 '&'
{ 52, 1, 4, 3, 1, -9 }, // 0x27 '''
{ 53, 3, 12, 4, 1, -9 }, // 0x28 '('
{ 58, 4, 12, 4, 0, -9 }, // 0x29 ')'
{ 64, 6, 6, 8, 1, -9 }, // 0x2A '*'
{ 69, 6, 6, 8, 1, -7 }, // 0x2B '+'
{ 74, 2, 4, 4, 1, -1 }, // 0x2C ','
{ 75, 3, 1, 4, 1, -3 }, // 0x2D '-'
{ 76, 2, 2, 4, 1, -1 }, // 0x2E '.'
{ 77, 5, 10, 5, 0, -9 }, // 0x2F '/'
{ 84, 6, 10, 8, 1, -9 }, // 0x30 '0'
{ 92, 4, 10, 8, 1, -9 }, // 0x31 '1'
{ 97, 6, 10, 8, 1, -9 }, // 0x32 '2'
{ 105, 6, 10, 8, 1, -9 }, // 0x33 '3'
{ 113, 8, 10, 8, 0, -9 }, // 0x34 '4'
{ 123, 6, 10, 8, 1, -9 }, // 0x35 '5'
{ 131, 6, 10, 8, 1, -9 }, // 0x36 '6'
{ 139, 6, 10, 8, 1, -9 }, // 0x37 '7'
{ 147, 6, 10, 8, 1, -9 }, // 0x38 '8'
{ 155, 6, 10, 8, 1, -9 }, // 0x39 '9'
{ 163, 2, 8, 4, 1, -7 }, // 0x3A ':'
{ 165, 3, 10, 4, 0, -7 }, // 0x3B ';'
{ 169, 6, 6, 8, 1, -7 }, // 0x3C '<'
{ 174, 6, 4, 8, 1, -6 }, // 0x3D '='
{ 177, 6, 6, 8, 1, -7 }, // 0x3E '>'
{ 182, 6, 10, 6, 0, -9 }, // 0x3F '?'
{ 190, 11, 11, 12, 1, -9 }, // 0x40 '@'
{ 206, 9, 10, 9, 0, -9 }, // 0x41 'A'
{ 218, 7, 10, 9, 1, -9 }, // 0x42 'B'
{ 227, 7, 10, 9, 1, -9 }, // 0x43 'C'
{ 236, 8, 10, 10, 1, -9 }, // 0x44 'D'
{ 246, 6, 10, 8, 1, -9 }, // 0x45 'E'
{ 254, 6, 10, 7, 1, -9 }, // 0x46 'F'
{ 262, 8, 10, 10, 1, -9 }, // 0x47 'G'
{ 272, 8, 10, 10, 1, -9 }, // 0x48 'H'
{ 282, 3, 10, 5, 1, -9 }, // 0x49 'I'
{ 286, 4, 13, 4, -1, -9 }, // 0x4A 'J'
{ 293, 7, 10, 8, 1, -9 }, // 0x4B 'K'
{ 302, 6, 10, 7, 1, -9 }, // 0x4C 'L'
{ 310, 10, 10, 12, 1, -9 }, // 0x4D 'M'
{ 323, 8, 10, 10, 1, -9 }, // 0x4E 'N'
{ 333, 9, 10, 11, 1, -9 }, // 0x4F 'O'
{ 345, 7, 10, 8, 1, -9 }, // 0x50 'P'
{ 354, 9, 12, 11, 1, -9 }, // 0x51 'Q'
{ 368, 7, 10, 9, 1, -9 }, // 0x52 'R'
{ 377, 6, 10, 8, 1, -9 }, // 0x53 'S'
{ 385, 7, 10, 8, 0, -9 }, // 0x54 'T'
{ 394, 8, 10, 10, 1, -9 }, // 0x55 'U'
{ 404, 8, 10, 8, 0, -9 }, // 0x56 'V'
{ 414, 13, 10, 13, 0, -9 }, // 0x57 'W'
{ 431, 8, 10, 8, 0, -9 }, // 0x58 'X'
{ 441, 8, 10, 8, 0, -9 }, // 0x59 'Y'
{ 451, 6, 10, 8, 1, -9 }, // 0x5A 'Z'
{ 459, 3, 12, 5, 1, -9 }, // 0x5B '['
{ 464, 5, 10, 5, 0, -9 }, // 0x5C '\'
{ 471, 3, 12, 5, 0, -9 }, // 0x5D ']'
{ 476, 6, 6, 8, 1, -9 }, // 0x5E '^'
{ 481, 6, 1, 6, 0, 2 }, // 0x5F '_'
{ 482, 2, 3, 4, 1, -10 }, // 0x60 '`'
{ 483, 6, 7, 8, 1, -6 }, // 0x61 'a'
{ 489, 7, 10, 8, 1, -9 }, // 0x62 'b'
{ 498, 5, 7, 7, 1, -6 }, // 0x63 'c'
{ 503, 6, 10, 8, 1, -9 }, // 0x64 'd'
{ 511, 6, 7, 8, 1, -6 }, // 0x65 'e'
{ 517, 5, 10, 5, 0, -9 }, // 0x66 'f'
{ 524, 6, 10, 8, 1, -6 }, // 0x67 'g'
{ 532, 6, 10, 8, 1, -9 }, // 0x68 'h'
{ 540, 1, 10, 4, 1, -9 }, // 0x69 'i'
{ 542, 3, 13, 4, -1, -9 }, // 0x6A 'j'
{ 547, 6, 10, 7, 1, -9 }, // 0x6B 'k'
{ 555, 1, 10, 4, 1, -9 }, // 0x6C 'l'
{ 557, 11, 7, 13, 1, -6 }, // 0x6D 'm'
{ 567, 6, 7, 8, 1, -6 }, // 0x6E 'n'
{ 573, 7, 7, 8, 1, -6 }, // 0x6F 'o'
{ 580, 7, 10, 8, 1, -6 }, // 0x70 'p'
{ 589, 6, 10, 8, 1, -6 }, // 0x71 'q'
{ 597, 4, 7, 6, 1, -6 }, // 0x72 'r'
{ 601, 5, 7, 7, 1, -6 }, // 0x73 's'
{ 606, 5, 9, 5, 0, -8 }, // 0x74 't'
{ 612, 6, 7, 8, 1, -6 }, // 0x75 'u'
{ 618, 7, 7, 7, 0, -6 }, // 0x76 'v'
{ 625, 11, 7, 11, 0, -6 }, // 0x77 'w'
{ 635, 7, 7, 7, 0, -6 }, // 0x78 'x'
{ 642, 7, 10, 7, 0, -6 }, // 0x79 'y'
{ 651, 5, 7, 6, 1, -6 }, // 0x7A 'z'
{ 656, 5, 12, 5, 0, -9 }, // 0x7B '{'
{ 664, 1, 13, 8, 3, -9 }, // 0x7C '|'
{ 666, 5, 12, 5, 0, -9 }, // 0x7D '}'
{ 674, 6, 2, 8, 1, -5 } }; // 0x7E '~'
const GFXfont NotoSans_Regular7pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular7pt7bBitmaps,
(GFXglyph *)NotoSans_Regular7pt7bGlyphs,
0x20, 0x7E, 19 };
// Approx. 1348 bytes
#endif // NOTOSANS7PT7B_H
@@ -0,0 +1,201 @@
#ifndef NOTOSANS9PT7B_H
#define NOTOSANS9PT7B_H
const uint8_t NotoSans_Regular9pt7bBitmaps[] PROGMEM = {
0x00, 0xF5, 0x55, 0x43, 0xC0, 0xDE, 0xF3, 0x9C, 0x80, 0x0C, 0x81, 0x10,
0x22, 0x04, 0x47, 0xFE, 0x32, 0x04, 0x40, 0x88, 0xFF, 0xC2, 0x60, 0xC8,
0x11, 0x02, 0x20, 0x18, 0x3E, 0x7F, 0xD8, 0xD8, 0xF8, 0x3C, 0x1F, 0x1B,
0x19, 0x9B, 0xFE, 0x18, 0x18, 0x70, 0x46, 0xC2, 0x22, 0x21, 0x13, 0x08,
0x90, 0x45, 0xB3, 0x6B, 0x4E, 0xD3, 0x04, 0x98, 0x44, 0xC2, 0x26, 0x21,
0x23, 0x07, 0x00, 0x1C, 0x07, 0x60, 0x62, 0x06, 0x20, 0x26, 0x03, 0xC0,
0x38, 0x06, 0xC6, 0xC6, 0x6C, 0x3C, 0xC1, 0x8E, 0x3C, 0x7E, 0x70, 0xFF,
0xC0, 0x32, 0x64, 0xCC, 0x88, 0x88, 0x8C, 0xC4, 0x63, 0x8C, 0x46, 0x22,
0x23, 0x33, 0x22, 0x64, 0xC8, 0x18, 0x10, 0xD3, 0xFF, 0x18, 0x2C, 0x66,
0x24, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x7E, 0xF0, 0xF0,
0x04, 0x30, 0xC2, 0x18, 0x41, 0x0C, 0x21, 0x86, 0x10, 0xC0, 0x3C, 0x7E,
0x42, 0xC3, 0xC1, 0x81, 0x81, 0x81, 0xC1, 0xC3, 0xC3, 0x66, 0x3C, 0x13,
0xD9, 0x11, 0x11, 0x11, 0x11, 0x10, 0x3C, 0xFE, 0x83, 0x03, 0x03, 0x02,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFF, 0x3C, 0xFE, 0x83, 0x03, 0x03,
0x06, 0x38, 0x06, 0x03, 0x03, 0x03, 0x86, 0xFC, 0x03, 0x01, 0xC0, 0x70,
0x3C, 0x1B, 0x04, 0xC2, 0x31, 0x8C, 0x43, 0x3F, 0xF0, 0x30, 0x0C, 0x03,
0x00, 0x7E, 0x7E, 0x40, 0x40, 0x40, 0xFC, 0x7E, 0x03, 0x03, 0x03, 0x03,
0x86, 0xFC, 0x0E, 0x3E, 0x60, 0x40, 0xC0, 0xDC, 0xE7, 0xC3, 0xC1, 0xC1,
0xC3, 0x63, 0x3E, 0xFF, 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x0C, 0x18,
0x18, 0x10, 0x30, 0x60, 0x3C, 0x7E, 0xC3, 0xC3, 0x43, 0x76, 0x3C, 0x66,
0xC3, 0x81, 0x81, 0xC3, 0x7E, 0x38, 0x7E, 0xC3, 0xC3, 0x81, 0xC3, 0xC3,
0x7D, 0x03, 0x03, 0x02, 0x0E, 0x78, 0x74, 0x00, 0xF0, 0x74, 0x00, 0xFA,
0x01, 0x03, 0x0C, 0x30, 0xC0, 0xE0, 0x1C, 0x07, 0x01, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x07, 0x38, 0xE0, 0x80, 0x39,
0xFC, 0x08, 0x10, 0x60, 0x86, 0x08, 0x30, 0x00, 0x01, 0x83, 0x00, 0x03,
0x80, 0x7F, 0x83, 0x01, 0x18, 0x02, 0x47, 0xCF, 0x31, 0x38, 0x84, 0x62,
0x31, 0x88, 0xCE, 0x23, 0x2C, 0x77, 0x10, 0x00, 0x60, 0x00, 0x7F, 0x00,
0x30, 0x00, 0x04, 0x01, 0xC0, 0x28, 0x05, 0x81, 0xB0, 0x22, 0x04, 0x61,
0x84, 0x3F, 0xCC, 0x19, 0x81, 0x20, 0x3C, 0x06, 0xF8, 0x7F, 0x20, 0xD0,
0x68, 0x34, 0x33, 0xF1, 0x06, 0x81, 0x40, 0xE0, 0x50, 0xEF, 0xE0, 0x0F,
0x0F, 0xF6, 0x01, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x06,
0x00, 0xC2, 0x1F, 0x80, 0xF8, 0x3F, 0xC8, 0x3A, 0x06, 0x80, 0xE0, 0x38,
0x0E, 0x03, 0x80, 0xE0, 0x68, 0x1A, 0x1C, 0xFC, 0x00, 0xFF, 0xFE, 0x04,
0x08, 0x10, 0x3F, 0x40, 0x81, 0x02, 0x04, 0x0F, 0xE0, 0xFF, 0xFE, 0x04,
0x08, 0x10, 0x3F, 0x7E, 0x81, 0x02, 0x04, 0x08, 0x00, 0x0F, 0x87, 0xF9,
0xC0, 0x30, 0x0C, 0x01, 0x80, 0x30, 0xFE, 0x1F, 0xC0, 0x68, 0x0D, 0x81,
0x98, 0x31, 0xFE, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0x01,
0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0xFF, 0x66, 0x66, 0x66, 0x66, 0x66,
0xF0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3E, 0x81, 0xC1, 0xA1,
0x91, 0x89, 0x85, 0x83, 0xC1, 0xB0, 0x8C, 0x46, 0x21, 0x90, 0x68, 0x18,
0x81, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x04, 0x0F, 0xE0,
0xC0, 0x3C, 0x03, 0xE0, 0x7A, 0x05, 0xB0, 0xDB, 0x09, 0x90, 0x99, 0x99,
0x89, 0x18, 0xB1, 0x8F, 0x18, 0x61, 0x86, 0x10, 0xC0, 0xF0, 0x3E, 0x0E,
0xC3, 0xB0, 0xE6, 0x38, 0x8E, 0x33, 0x86, 0xE0, 0xB8, 0x3E, 0x07, 0x80,
0xC0, 0x0F, 0x03, 0xFC, 0x60, 0x64, 0x06, 0xC0, 0x2C, 0x03, 0xC0, 0x3C,
0x03, 0xC0, 0x3C, 0x02, 0x60, 0x63, 0x0C, 0x1F, 0x80, 0xF0, 0xFE, 0x82,
0x83, 0x83, 0x83, 0x86, 0xFC, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0F, 0x03,
0xFC, 0x60, 0x64, 0x06, 0xC0, 0x2C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C,
0x02, 0x60, 0x63, 0x0C, 0x1F, 0x80, 0x18, 0x01, 0xC0, 0x0E, 0xF0, 0x7F,
0x20, 0xD0, 0x68, 0x34, 0x13, 0xF9, 0xF0, 0x8C, 0x43, 0x21, 0x90, 0x68,
0x18, 0x3D, 0x7E, 0xC0, 0xC0, 0xC0, 0x60, 0x3C, 0x0E, 0x03, 0x03, 0x03,
0x86, 0xFC, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18,
0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x70, 0x7C, 0x63, 0xE0, 0xC0, 0x78,
0x09, 0x03, 0x30, 0x46, 0x18, 0x43, 0x0C, 0x40, 0x98, 0x1B, 0x03, 0x40,
0x38, 0x07, 0x00, 0xC0, 0xC1, 0x83, 0x41, 0x83, 0x41, 0xC3, 0x63, 0xC2,
0x63, 0x46, 0x22, 0x46, 0x22, 0x66, 0x36, 0x24, 0x34, 0x2C, 0x14, 0x3C,
0x14, 0x38, 0x1C, 0x18, 0x18, 0x18, 0xC0, 0xD8, 0x22, 0x18, 0xCC, 0x1A,
0x03, 0x80, 0xC0, 0x38, 0x1A, 0x0C, 0xC2, 0x19, 0x82, 0xC0, 0xC0, 0xC0,
0xD0, 0x26, 0x18, 0x84, 0x33, 0x04, 0x81, 0xE0, 0x30, 0x0C, 0x03, 0x00,
0xC0, 0x30, 0x0C, 0x00, 0xFF, 0xFF, 0x03, 0x06, 0x04, 0x0C, 0x18, 0x10,
0x30, 0x60, 0x40, 0xC0, 0xFF, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCF, 0xC1, 0x04, 0x18, 0x20, 0xC3, 0x04, 0x18, 0x20, 0x83, 0x04, 0xFF,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x10, 0x18, 0x38, 0x24, 0x64,
0x42, 0x42, 0x81, 0xFF, 0xD9, 0x80, 0x18, 0xFC, 0x08, 0x11, 0xEE, 0x70,
0xC1, 0xC6, 0xF4, 0xC0, 0x60, 0x30, 0x19, 0x8F, 0xF7, 0x0B, 0x07, 0x83,
0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, 0x1C, 0xFD, 0x06, 0x0C, 0x18, 0x30,
0x60, 0x62, 0x7C, 0x01, 0x01, 0x01, 0x19, 0x7F, 0xC3, 0xC1, 0xC1, 0xC1,
0xC1, 0xC1, 0x63, 0x3D, 0x18, 0x7E, 0x43, 0xC3, 0xFF, 0xFF, 0xC0, 0xC0,
0x61, 0x3F, 0x1E, 0x60, 0x81, 0x0F, 0xC4, 0x08, 0x10, 0x20, 0x40, 0x81,
0x02, 0x00, 0x18, 0x7F, 0x43, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x63, 0x3D,
0x01, 0x01, 0x43, 0x7E, 0xC0, 0xC0, 0xC0, 0xCC, 0xFF, 0xE1, 0xC1, 0xC1,
0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xF0, 0xFF, 0xFF, 0xC0, 0x33, 0x00, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC0, 0xC0, 0xC0, 0xC1, 0xC6, 0xCC,
0xD8, 0xD0, 0xF8, 0xCC, 0xC4, 0xC6, 0xC3, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C,
0x33, 0xFB, 0xFE, 0x38, 0xF0, 0xC3, 0xC1, 0x07, 0x04, 0x1C, 0x10, 0x70,
0x41, 0xC1, 0x07, 0x04, 0x10, 0x0C, 0xFF, 0xE1, 0xC1, 0xC1, 0xC1, 0xC1,
0xC1, 0xC1, 0xC1, 0x18, 0x3F, 0x10, 0xD8, 0x3C, 0x1E, 0x0F, 0x07, 0x82,
0x63, 0x1F, 0x00, 0x0C, 0x7F, 0xB8, 0x58, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x18, 0x7F, 0xC3, 0xC1, 0xC1,
0xC1, 0xC1, 0xC1, 0x63, 0x3D, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x7E, 0x30,
0xC3, 0x0C, 0x30, 0xC3, 0x00, 0x39, 0xFA, 0x06, 0x07, 0x07, 0x81, 0x83,
0x85, 0xF8, 0x20, 0x86, 0x3F, 0x20, 0x82, 0x08, 0x20, 0x83, 0x0F, 0xC1,
0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x63, 0x7D, 0xC1, 0xA0, 0x98, 0xCC,
0x42, 0x21, 0xB0, 0x50, 0x28, 0x1C, 0x00, 0xC3, 0x0D, 0x1C, 0x26, 0x79,
0x99, 0x26, 0x24, 0x90, 0xB3, 0x43, 0x8F, 0x0E, 0x18, 0x18, 0x60, 0xE3,
0x99, 0x05, 0x83, 0x80, 0xC0, 0xB0, 0xC8, 0xC6, 0xC1, 0x80, 0xC1, 0xA0,
0x98, 0xC4, 0x43, 0x21, 0xB0, 0x50, 0x38, 0x0C, 0x04, 0x06, 0x02, 0x0F,
0x00, 0xFC, 0x18, 0x20, 0xC3, 0x0C, 0x10, 0x60, 0xFE, 0x04, 0x71, 0x04,
0x10, 0x41, 0x3C, 0xE0, 0xC1, 0x04, 0x10, 0x41, 0xC3, 0xFF, 0xFF, 0xFF,
0xFF, 0xC0, 0x87, 0x18, 0x42, 0x10, 0x87, 0x39, 0x08, 0x42, 0x33, 0x90,
0xF9, 0x8F };
const GFXglyph NotoSans_Regular9pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 5, 0, 0 }, // 0x20 ' '
{ 1, 2, 13, 5, 1, -12 }, // 0x21 '!'
{ 5, 5, 5, 7, 1, -12 }, // 0x22 '"'
{ 9, 11, 13, 11, 0, -12 }, // 0x23 '#'
{ 27, 8, 14, 10, 1, -12 }, // 0x24 '$'
{ 41, 13, 13, 15, 1, -12 }, // 0x25 '%'
{ 63, 12, 13, 13, 1, -12 }, // 0x26 '&'
{ 83, 2, 5, 4, 1, -12 }, // 0x27 '''
{ 85, 4, 16, 5, 1, -12 }, // 0x28 '('
{ 93, 4, 16, 5, 1, -12 }, // 0x29 ')'
{ 101, 8, 8, 10, 1, -12 }, // 0x2A '*'
{ 109, 8, 8, 10, 1, -9 }, // 0x2B '+'
{ 117, 2, 4, 5, 1, -1 }, // 0x2C ','
{ 118, 4, 1, 6, 1, -4 }, // 0x2D '-'
{ 119, 2, 2, 5, 1, -1 }, // 0x2E '.'
{ 120, 6, 13, 7, 0, -12 }, // 0x2F '/'
{ 130, 8, 13, 10, 1, -12 }, // 0x30 '0'
{ 143, 4, 13, 10, 2, -12 }, // 0x31 '1'
{ 150, 8, 13, 10, 1, -12 }, // 0x32 '2'
{ 163, 8, 13, 10, 1, -12 }, // 0x33 '3'
{ 176, 10, 13, 10, 0, -12 }, // 0x34 '4'
{ 193, 8, 13, 10, 1, -12 }, // 0x35 '5'
{ 206, 8, 13, 10, 1, -12 }, // 0x36 '6'
{ 219, 8, 13, 10, 1, -12 }, // 0x37 '7'
{ 232, 8, 13, 10, 1, -12 }, // 0x38 '8'
{ 245, 8, 13, 10, 1, -12 }, // 0x39 '9'
{ 258, 2, 10, 5, 1, -9 }, // 0x3A ':'
{ 261, 2, 12, 5, 1, -9 }, // 0x3B ';'
{ 264, 8, 9, 10, 1, -10 }, // 0x3C '<'
{ 273, 8, 5, 10, 1, -8 }, // 0x3D '='
{ 278, 8, 9, 10, 1, -10 }, // 0x3E '>'
{ 287, 7, 13, 8, 0, -12 }, // 0x3F '?'
{ 299, 14, 15, 16, 1, -12 }, // 0x40 '@'
{ 326, 11, 13, 11, 0, -12 }, // 0x41 'A'
{ 344, 9, 13, 11, 2, -12 }, // 0x42 'B'
{ 359, 10, 13, 11, 1, -12 }, // 0x43 'C'
{ 376, 10, 13, 13, 2, -12 }, // 0x44 'D'
{ 393, 7, 13, 10, 2, -12 }, // 0x45 'E'
{ 405, 7, 13, 9, 2, -12 }, // 0x46 'F'
{ 417, 11, 13, 13, 1, -12 }, // 0x47 'G'
{ 435, 9, 13, 13, 2, -12 }, // 0x48 'H'
{ 450, 4, 13, 6, 1, -12 }, // 0x49 'I'
{ 457, 4, 16, 5, -1, -12 }, // 0x4A 'J'
{ 465, 9, 13, 11, 2, -12 }, // 0x4B 'K'
{ 480, 7, 13, 9, 2, -12 }, // 0x4C 'L'
{ 492, 12, 13, 16, 2, -12 }, // 0x4D 'M'
{ 512, 10, 13, 13, 2, -12 }, // 0x4E 'N'
{ 529, 12, 13, 14, 1, -12 }, // 0x4F 'O'
{ 549, 8, 13, 11, 2, -12 }, // 0x50 'P'
{ 562, 12, 16, 14, 1, -12 }, // 0x51 'Q'
{ 586, 9, 13, 11, 2, -12 }, // 0x52 'R'
{ 601, 8, 13, 10, 1, -12 }, // 0x53 'S'
{ 614, 10, 13, 10, 0, -12 }, // 0x54 'T'
{ 631, 9, 13, 13, 2, -12 }, // 0x55 'U'
{ 646, 11, 13, 11, 0, -12 }, // 0x56 'V'
{ 664, 16, 13, 16, 0, -12 }, // 0x57 'W'
{ 690, 10, 13, 10, 0, -12 }, // 0x58 'X'
{ 707, 10, 13, 10, 0, -12 }, // 0x59 'Y'
{ 724, 8, 13, 10, 1, -12 }, // 0x5A 'Z'
{ 737, 4, 16, 6, 1, -12 }, // 0x5B '['
{ 745, 6, 13, 7, 0, -12 }, // 0x5C '\'
{ 755, 4, 16, 6, 0, -12 }, // 0x5D ']'
{ 763, 8, 8, 10, 1, -12 }, // 0x5E '^'
{ 771, 8, 1, 8, 0, 3 }, // 0x5F '_'
{ 772, 3, 3, 5, 1, -13 }, // 0x60 '`'
{ 774, 7, 10, 10, 1, -9 }, // 0x61 'a'
{ 783, 9, 13, 11, 1, -12 }, // 0x62 'b'
{ 798, 7, 10, 8, 1, -9 }, // 0x63 'c'
{ 807, 8, 13, 11, 1, -12 }, // 0x64 'd'
{ 820, 8, 10, 10, 1, -9 }, // 0x65 'e'
{ 830, 7, 13, 6, 0, -12 }, // 0x66 'f'
{ 842, 8, 14, 11, 1, -9 }, // 0x67 'g'
{ 856, 8, 13, 11, 1, -12 }, // 0x68 'h'
{ 869, 2, 13, 5, 1, -12 }, // 0x69 'i'
{ 873, 4, 17, 5, -1, -12 }, // 0x6A 'j'
{ 882, 8, 13, 9, 1, -12 }, // 0x6B 'k'
{ 895, 2, 13, 5, 1, -12 }, // 0x6C 'l'
{ 899, 14, 10, 16, 1, -9 }, // 0x6D 'm'
{ 917, 8, 10, 11, 1, -9 }, // 0x6E 'n'
{ 927, 9, 10, 11, 1, -9 }, // 0x6F 'o'
{ 939, 9, 14, 11, 1, -9 }, // 0x70 'p'
{ 955, 8, 14, 11, 1, -9 }, // 0x71 'q'
{ 969, 6, 10, 7, 1, -9 }, // 0x72 'r'
{ 977, 7, 10, 8, 1, -9 }, // 0x73 's'
{ 986, 6, 12, 6, 0, -11 }, // 0x74 't'
{ 995, 8, 9, 11, 1, -8 }, // 0x75 'u'
{ 1004, 9, 9, 9, 0, -8 }, // 0x76 'v'
{ 1015, 14, 9, 14, 0, -8 }, // 0x77 'w'
{ 1031, 9, 9, 9, 0, -8 }, // 0x78 'x'
{ 1042, 9, 13, 9, 0, -8 }, // 0x79 'y'
{ 1057, 7, 9, 8, 1, -8 }, // 0x7A 'z'
{ 1065, 6, 16, 7, 0, -12 }, // 0x7B '{'
{ 1077, 2, 17, 10, 4, -12 }, // 0x7C '|'
{ 1082, 5, 16, 7, 1, -12 }, // 0x7D '}'
{ 1092, 8, 2, 10, 1, -6 } }; // 0x7E '~'
const GFXfont NotoSans_Regular9pt7b PROGMEM = {
(uint8_t *)NotoSans_Regular9pt7bBitmaps,
(GFXglyph *)NotoSans_Regular9pt7bGlyphs,
0x20, 0x7E, 24 };
// Approx. 1766 bytes
#endif // NOTOSANS9PT7B_H
@@ -0,0 +1,285 @@
#ifndef NOTOSANSBOLD12PT7B_H
#define NOTOSANSBOLD12PT7B_H
const uint8_t NotoSans_Bold12pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0x06, 0xFF, 0x70, 0xF7, 0xB9,
0xDC, 0xEE, 0x77, 0x33, 0x18, 0x0E, 0x70, 0x39, 0xC0, 0xE6, 0x03, 0x18,
0x0C, 0x63, 0xFF, 0xFF, 0xFF, 0xC7, 0x30, 0x1C, 0xC0, 0x63, 0x0F, 0xFF,
0xBF, 0xFE, 0x39, 0x80, 0xE6, 0x03, 0x18, 0x0C, 0xE0, 0x73, 0x80, 0x06,
0x00, 0x60, 0x1F, 0xC7, 0xFE, 0xFF, 0xEF, 0x62, 0xF6, 0x0F, 0xE0, 0x7F,
0x03, 0xFC, 0x0F, 0xE0, 0x7E, 0x06, 0xF8, 0x6E, 0xFF, 0xEF, 0xFC, 0x7F,
0x80, 0x60, 0x06, 0x00, 0x3C, 0x07, 0x0F, 0xC1, 0xC3, 0xB8, 0x30, 0x73,
0x8E, 0x0E, 0x73, 0x81, 0x8E, 0x70, 0x39, 0xDC, 0x07, 0x33, 0xBE, 0xFE,
0xEF, 0xEF, 0x99, 0xDC, 0x47, 0x31, 0x80, 0xCE, 0x30, 0x38, 0xC6, 0x0E,
0x18, 0xC1, 0xC3, 0xB8, 0x70, 0x7F, 0x0E, 0x07, 0xC0, 0x0F, 0x80, 0x1F,
0xE0, 0x0F, 0xF8, 0x0F, 0x3C, 0x07, 0x8E, 0x01, 0xCF, 0x00, 0xFF, 0x00,
0x3F, 0x00, 0x3F, 0x0F, 0x3F, 0xC7, 0x3C, 0xF7, 0x9E, 0x3F, 0xCF, 0x0F,
0xC7, 0x83, 0xC3, 0xFF, 0xF0, 0xFF, 0xFC, 0x3F, 0xCF, 0x80, 0xF7, 0x77,
0x76, 0x1C, 0xE3, 0x9C, 0x71, 0xCE, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E,
0x1C, 0x71, 0xC3, 0x8E, 0x1C, 0xE1, 0xC7, 0x0E, 0x38, 0xE3, 0xC7, 0x1C,
0x71, 0xC7, 0x1C, 0x73, 0xCE, 0x38, 0xE7, 0x38, 0xE0, 0x0E, 0x01, 0xC0,
0x38, 0x47, 0x3F, 0xFF, 0xFF, 0xC7, 0x80, 0xF8, 0x3B, 0x8E, 0x78, 0xC4,
0x00, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x70,
0x0E, 0x01, 0xC0, 0x38, 0x00, 0x77, 0xFE, 0xEC, 0xFF, 0xFF, 0xC0, 0x6F,
0xF7, 0x03, 0xC0, 0xE0, 0x38, 0x1C, 0x07, 0x03, 0xC0, 0xE0, 0x38, 0x1E,
0x07, 0x01, 0xC0, 0xE0, 0x38, 0x1E, 0x07, 0x01, 0xC0, 0xF0, 0x00, 0x1F,
0x03, 0xFC, 0x7F, 0xC7, 0x1E, 0xF0, 0xEF, 0x0E, 0xE0, 0xEE, 0x0F, 0xE0,
0xFE, 0x0F, 0xE0, 0xFF, 0x0E, 0xF0, 0xE7, 0x1E, 0x7F, 0xE3, 0xFC, 0x1F,
0x80, 0x07, 0x87, 0xC7, 0xE7, 0xFF, 0xFB, 0xBC, 0x9E, 0x0F, 0x07, 0x83,
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x80, 0x1F, 0x87, 0xFC,
0xFF, 0xE7, 0x1E, 0x40, 0xE0, 0x0E, 0x01, 0xE0, 0x1C, 0x03, 0xC0, 0x78,
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F,
0x0F, 0xFC, 0xFF, 0xE6, 0x1E, 0x00, 0xE0, 0x1E, 0x01, 0xC3, 0xF8, 0x3F,
0x83, 0xFE, 0x01, 0xE0, 0x0E, 0x00, 0xF8, 0x1E, 0xFF, 0xEF, 0xFC, 0xFF,
0x80, 0x00, 0xE0, 0x0F, 0x00, 0xF8, 0x07, 0xC0, 0x7E, 0x07, 0x70, 0x73,
0x83, 0x9C, 0x38, 0xE3, 0x87, 0x1C, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x03, 0x80, 0x1C, 0x00, 0xE0, 0x7F, 0xCF, 0xF9, 0xFF, 0x38, 0x07, 0x00,
0xE0, 0x1F, 0xC3, 0xFE, 0xFF, 0xE8, 0x7C, 0x03, 0x80, 0x70, 0x0F, 0x03,
0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x07, 0xC1, 0xFC, 0x3F, 0xC7, 0x80, 0x70,
0x0F, 0x00, 0xE7, 0x8E, 0xFC, 0xFF, 0xEF, 0x0E, 0xE0, 0xFE, 0x0F, 0xF0,
0xFF, 0x0E, 0x7F, 0xE3, 0xFC, 0x1F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
0x0E, 0x01, 0xE0, 0x1C, 0x03, 0xC0, 0x38, 0x07, 0x80, 0x78, 0x07, 0x00,
0xF0, 0x0E, 0x01, 0xE0, 0x1C, 0x03, 0xC0, 0x3C, 0x00, 0x1F, 0x07, 0xFC,
0x7F, 0xEF, 0x0E, 0xF0, 0xE7, 0x1E, 0x7B, 0xC3, 0xF8, 0x1F, 0x87, 0xFC,
0xF1, 0xEE, 0x0E, 0xE0, 0xFE, 0x0F, 0xF9, 0xE7, 0xFC, 0x3F, 0x80, 0x1F,
0x07, 0xF8, 0x7F, 0xCF, 0x1E, 0xE0, 0xEE, 0x0E, 0xE0, 0xFF, 0x1F, 0xFF,
0xF7, 0xFE, 0x3E, 0xE0, 0x0E, 0x01, 0xE0, 0x1C, 0x7F, 0xC7, 0xF8, 0x7E,
0x00, 0x7F, 0xF6, 0x00, 0x00, 0x06, 0xFF, 0x70, 0x7F, 0xF6, 0x00, 0x00,
0x00, 0x77, 0xFE, 0xEC, 0x00, 0x20, 0x0C, 0x07, 0x83, 0xE1, 0xF0, 0xF8,
0x3C, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0x80, 0x30, 0x02, 0xFF, 0xFF,
0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x80, 0x18, 0x03, 0xC0,
0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x78, 0x1F, 0x1F, 0x8F, 0xC3, 0xE0, 0x70,
0x08, 0x00, 0x3F, 0x1F, 0xF9, 0xFF, 0x20, 0xF0, 0x1E, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0x70, 0x0E, 0x00, 0x00, 0x10, 0x07, 0x80, 0xF0,
0x1E, 0x00, 0x01, 0xF8, 0x00, 0xFF, 0xC0, 0x7C, 0x3E, 0x1E, 0x01, 0xE3,
0x83, 0x1C, 0xE3, 0xF9, 0xD8, 0xFF, 0x3F, 0x38, 0xE7, 0xE7, 0x1C, 0xFC,
0xC3, 0x9F, 0x98, 0x73, 0xF3, 0x8E, 0x6E, 0x7F, 0xFC, 0xC7, 0xCF, 0x1C,
0x00, 0x01, 0xC0, 0x00, 0x3E, 0x1E, 0x01, 0xFF, 0xC0, 0x0F, 0xE0, 0x00,
0x03, 0xC0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0x70, 0x0E, 0x70,
0x0E, 0x78, 0x1E, 0x78, 0x1E, 0x38, 0x1C, 0x3C, 0x3F, 0xFC, 0x3F, 0xFC,
0x3F, 0xFE, 0x78, 0x1E, 0x78, 0x0E, 0x70, 0x0F, 0xF0, 0x0F, 0xFF, 0x8F,
0xFE, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF1, 0xEF, 0xFE, 0xFF, 0xCF,
0xFF, 0xF0, 0xFF, 0x07, 0xF0, 0x7F, 0x0F, 0xFF, 0xFF, 0xFE, 0xFF, 0x80,
0x07, 0xF0, 0xFF, 0xCF, 0xFE, 0x78, 0x27, 0x80, 0x3C, 0x03, 0xC0, 0x1E,
0x00, 0xF0, 0x07, 0x80, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x3E, 0x04, 0xFF,
0xE3, 0xFF, 0x0F, 0xF0, 0xFF, 0x03, 0xFF, 0x8F, 0xFF, 0x3C, 0x7E, 0xF0,
0x7B, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC,
0x0F, 0xF0, 0x7B, 0xC3, 0xEF, 0xFF, 0x3F, 0xF8, 0xFF, 0x80, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFE, 0xFF, 0xBF, 0xEF, 0x03,
0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFE, 0xFF, 0xBF, 0xEF, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x00, 0x03, 0xF8, 0x3F, 0xF3, 0xFF, 0xCF,
0x82, 0x78, 0x01, 0xE0, 0x07, 0x00, 0x3C, 0x00, 0xF1, 0xFF, 0xC7, 0xFF,
0x1F, 0xDC, 0x07, 0x78, 0x1D, 0xF0, 0x73, 0xFF, 0xC7, 0xFF, 0x0F, 0xF8,
0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0,
0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3C, 0xFF, 0xFF, 0xF9, 0xC3, 0x87, 0x0E,
0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x1F, 0x7F, 0xFE, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x1E, 0xFE, 0xFC, 0xF8, 0xF0, 0x7F, 0xC1, 0xEF, 0x0F,
0x3C, 0x78, 0xF3, 0xC3, 0xDE, 0x0F, 0x78, 0x3F, 0xC0, 0xFF, 0x03, 0xFE,
0x0F, 0x3C, 0x3C, 0xF0, 0xF1, 0xE3, 0xC7, 0x8F, 0x0F, 0x3C, 0x1E, 0xF0,
0x7C, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0xF8,
0x07, 0xFE, 0x01, 0xFF, 0xC0, 0xFF, 0xF0, 0x3F, 0xFC, 0x0F, 0xFB, 0x87,
0x7E, 0xE1, 0xDF, 0xB8, 0x77, 0xE7, 0x39, 0xF9, 0xCE, 0x7E, 0x73, 0x9F,
0x8D, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3E, 0x1F, 0x87, 0x87, 0xE1,
0xE1, 0xC0, 0xF8, 0x0F, 0xF0, 0x1F, 0xF0, 0x3F, 0xF0, 0x7F, 0xE0, 0xFD,
0xE1, 0xFB, 0xC3, 0xF3, 0xC7, 0xE3, 0x8F, 0xC7, 0x9F, 0x87, 0xBF, 0x0F,
0x7E, 0x0F, 0xFC, 0x1F, 0xF8, 0x1F, 0xF0, 0x1F, 0xE0, 0x3E, 0x07, 0xF0,
0x1F, 0xF8, 0x3F, 0xFE, 0x7C, 0x3E, 0x78, 0x0F, 0x78, 0x0F, 0xF0, 0x0F,
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0x70, 0x0F, 0x78, 0x0F,
0x7C, 0x1E, 0x3F, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0xFF, 0x0F, 0xFC, 0xFF,
0xEF, 0x1E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1E, 0xFF, 0xEF, 0xFC, 0xFF,
0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0x07, 0xF0,
0x1F, 0xF8, 0x3F, 0xFE, 0x7C, 0x3E, 0x78, 0x0F, 0x78, 0x0F, 0xF0, 0x0F,
0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0x70, 0x0F, 0x78, 0x0F,
0x7C, 0x1E, 0x3F, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0x00, 0x78, 0x00, 0x3C,
0x00, 0x3E, 0x00, 0x1F, 0xFF, 0x07, 0xFE, 0x3F, 0xF9, 0xE3, 0xCF, 0x0F,
0x78, 0x7B, 0xC3, 0xDE, 0x3C, 0xFF, 0xC7, 0xFC, 0x3F, 0xE1, 0xE7, 0x8F,
0x1E, 0x78, 0xF3, 0xC3, 0xDE, 0x1E, 0xF0, 0x78, 0x1F, 0x87, 0xFD, 0xFF,
0x78, 0x2F, 0x01, 0xE0, 0x1E, 0x03, 0xF0, 0x3F, 0x81, 0xF8, 0x0F, 0x80,
0xF0, 0x0F, 0x83, 0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C,
0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80,
0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03,
0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xE1,
0xE7, 0xFF, 0x8F, 0xFC, 0x1F, 0xE0, 0xF0, 0x0F, 0xE0, 0x3D, 0xC0, 0x7B,
0xC0, 0xE7, 0x83, 0xC7, 0x07, 0x0F, 0x0E, 0x1E, 0x3C, 0x1C, 0x70, 0x3C,
0xE0, 0x7B, 0xC0, 0x77, 0x00, 0xEE, 0x01, 0xFC, 0x01, 0xF0, 0x03, 0xE0,
0x03, 0xC0, 0xF0, 0x38, 0x1F, 0xE0, 0xF0, 0x39, 0xC1, 0xF0, 0x73, 0x83,
0xE1, 0xE7, 0x87, 0xC3, 0xCF, 0x1D, 0x87, 0x0E, 0x3B, 0x8E, 0x1C, 0x77,
0x3C, 0x38, 0xEE, 0x78, 0x7B, 0x9C, 0xE0, 0x77, 0x1D, 0xC0, 0xEE, 0x3B,
0x81, 0xD8, 0x7F, 0x03, 0xF0, 0xFC, 0x03, 0xE0, 0xF8, 0x07, 0xC1, 0xF0,
0x0F, 0x03, 0xE0, 0xF8, 0x1E, 0x78, 0x3C, 0x3C, 0x3C, 0x1C, 0x78, 0x1E,
0x78, 0x0F, 0xF0, 0x0F, 0xE0, 0x07, 0xE0, 0x03, 0xC0, 0x07, 0xE0, 0x0F,
0xE0, 0x0E, 0xF0, 0x1E, 0x78, 0x3C, 0x78, 0x3C, 0x3C, 0x78, 0x1E, 0xF0,
0x1F, 0xF0, 0x1E, 0xF0, 0x79, 0xE0, 0xE1, 0xE3, 0xC3, 0xC7, 0x03, 0xDE,
0x07, 0xB8, 0x07, 0xF0, 0x0F, 0xC0, 0x0F, 0x80, 0x1E, 0x00, 0x1C, 0x00,
0x38, 0x00, 0x70, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x1E, 0x01, 0xC0, 0x3C, 0x07, 0x80, 0x70, 0x0F, 0x01, 0xE0,
0x3C, 0x03, 0xC0, 0x78, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF,
0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x3F, 0xFF,
0x80, 0xF0, 0x1C, 0x07, 0x01, 0xE0, 0x38, 0x0E, 0x03, 0xC0, 0x70, 0x1C,
0x03, 0x80, 0xE0, 0x3C, 0x07, 0x01, 0xC0, 0x78, 0x0E, 0x03, 0xC0, 0xFF,
0xFE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xFF, 0xFF,
0x80, 0x0C, 0x00, 0xE0, 0x1E, 0x01, 0xF0, 0x1B, 0x83, 0xB8, 0x31, 0xC7,
0x1C, 0x60, 0xEE, 0x0E, 0xC0, 0x70, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x70,
0x70, 0x1F, 0x8F, 0xFC, 0xFF, 0x80, 0x70, 0x0E, 0x3F, 0xDF, 0xFF, 0xC7,
0xF0, 0xFE, 0x1F, 0xEF, 0xFF, 0xF7, 0xE6, 0xE0, 0x0E, 0x00, 0xE0, 0x0E,
0x00, 0xE0, 0x0E, 0x78, 0xFF, 0xCF, 0xFE, 0xF1, 0xEE, 0x0F, 0xE0, 0xFE,
0x0F, 0xE0, 0xFE, 0x0F, 0xF1, 0xEF, 0xFE, 0xFF, 0xCE, 0xF8, 0x0F, 0xCF,
0xF7, 0xFD, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3E, 0x17, 0xFC,
0xFF, 0x1F, 0xC0, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x71, 0xE7,
0x3F, 0x77, 0xFF, 0xF8, 0xFF, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x07,
0xF0, 0xF7, 0xFF, 0x7F, 0x73, 0xF7, 0x1F, 0x83, 0xFC, 0x7F, 0xE7, 0x0F,
0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x07, 0x00, 0x7C, 0xE3, 0xFE,
0x1F, 0xE0, 0x0F, 0xC7, 0xF1, 0xF8, 0xF0, 0x3C, 0x0F, 0xEF, 0xFB, 0xFE,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
0x00, 0x1E, 0x73, 0xF7, 0x7F, 0xF7, 0x8F, 0xF0, 0x7F, 0x07, 0xF0, 0x7F,
0x07, 0xF0, 0x7F, 0x0F, 0x7F, 0xF7, 0xF7, 0x3F, 0x70, 0x07, 0x00, 0xF6,
0x1F, 0x7F, 0xE7, 0xFC, 0x0F, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x7C, 0xFF, 0xEF, 0xFE, 0xF0, 0xFF, 0x0F, 0xE0, 0xFE, 0x0F,
0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xFF, 0xA1, 0xFF,
0xFF, 0xFF, 0xFF, 0xFC, 0x1C, 0x71, 0xC2, 0x00, 0x71, 0xC7, 0x1C, 0x71,
0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x3F, 0xFF, 0x98, 0xE0, 0x07,
0x00, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0x70, 0x7B, 0x87, 0x9C, 0x78, 0xE7,
0x87, 0x78, 0x3B, 0x81, 0xFE, 0x0F, 0xF0, 0x7B, 0xC3, 0x8F, 0x1C, 0x3C,
0xE1, 0xE7, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xEF,
0x8F, 0x9F, 0xFF, 0xFB, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0x0F, 0x0F, 0xC1,
0xC1, 0xF8, 0x38, 0x3F, 0x07, 0x07, 0xE0, 0xE0, 0xFC, 0x1C, 0x1F, 0x83,
0x83, 0xF0, 0x70, 0x7E, 0x0E, 0x0E, 0xE7, 0xCF, 0xFE, 0xFF, 0xEF, 0x0F,
0xF0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F,
0xE0, 0xF0, 0x1F, 0x81, 0xFF, 0x1F, 0xF8, 0xE1, 0xEF, 0x07, 0x78, 0x3B,
0xC1, 0xFE, 0x0F, 0xF0, 0x73, 0x87, 0x9F, 0xFC, 0x7F, 0xC1, 0xFC, 0x00,
0xE7, 0x8F, 0xFC, 0xFF, 0xEF, 0x1E, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F,
0xE0, 0xFF, 0x1E, 0xFF, 0xEF, 0xFC, 0xEF, 0x8E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x00, 0xE0, 0x00, 0x1E, 0x73, 0xF7, 0x7F, 0xFF, 0x8F, 0xF0,
0x7F, 0x07, 0xF0, 0x7F, 0x07, 0xF0, 0x7F, 0x0F, 0x7F, 0xF7, 0xF7, 0x3F,
0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0xE7, 0xEF,
0xFF, 0xF8, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x3F,
0x9F, 0xFF, 0xBB, 0xC0, 0xF8, 0x1F, 0x83, 0xF8, 0x3E, 0x03, 0xC0, 0xFF,
0x7F, 0xFE, 0xFF, 0x00, 0x38, 0x38, 0x38, 0x7F, 0xFF, 0xFF, 0x78, 0x78,
0x78, 0x78, 0x78, 0x78, 0x78, 0x7F, 0x3F, 0x1F, 0xE0, 0xFE, 0x0F, 0xE0,
0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFE, 0x0F, 0xE0, 0xFF, 0x1F, 0xFF,
0xFF, 0xFF, 0x7E, 0x70, 0xF0, 0x3B, 0x83, 0xDC, 0x1E, 0xF0, 0xE3, 0x8F,
0x1C, 0x70, 0xF3, 0x83, 0xBC, 0x1D, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x00,
0x78, 0x00, 0xF0, 0xF0, 0xF7, 0x0F, 0x0F, 0x70, 0xF8, 0xE7, 0x9F, 0x8E,
0x79, 0xF9, 0xE3, 0x99, 0x9C, 0x39, 0x9D, 0xC3, 0xF9, 0xDC, 0x1F, 0x9F,
0x81, 0xF0, 0xF8, 0x1F, 0x0F, 0x81, 0xF0, 0xF8, 0x0F, 0x0F, 0x00, 0xF8,
0x7B, 0xC7, 0x8F, 0x3C, 0x3B, 0xC1, 0xFC, 0x07, 0xE0, 0x3E, 0x01, 0xF8,
0x1F, 0xC1, 0xEF, 0x0F, 0x3C, 0xF0, 0xEF, 0x07, 0x80, 0xF0, 0x3B, 0x83,
0xDE, 0x1E, 0xF0, 0xE3, 0x8F, 0x1E, 0x70, 0x73, 0x83, 0xBC, 0x1D, 0xC0,
0x7E, 0x03, 0xF0, 0x0F, 0x00, 0x78, 0x03, 0x80, 0x3C, 0x03, 0xE0, 0x7E,
0x03, 0xE0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x1E, 0x0F, 0x03, 0x81,
0xE0, 0xF0, 0x78, 0x1C, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0x0F, 0x1F,
0x1E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0xFC, 0xF0, 0xFC, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1E, 0x1F, 0x0F, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF8, 0xE0, 0xF0, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3C,
0x1F, 0x07, 0x3F, 0x3C, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0xF0, 0xC0,
0x7C, 0x3F, 0xFF, 0x3F, 0xC0, 0xC0 };
const GFXglyph NotoSans_Bold12pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 4, 17, 7, 1, -16 }, // 0x21 '!'
{ 10, 9, 6, 11, 1, -16 }, // 0x22 '"'
{ 17, 14, 17, 15, 1, -16 }, // 0x23 '#'
{ 47, 12, 19, 13, 1, -17 }, // 0x24 '$'
{ 76, 19, 17, 21, 1, -16 }, // 0x25 '%'
{ 117, 17, 17, 18, 1, -16 }, // 0x26 '&'
{ 154, 4, 6, 6, 1, -16 }, // 0x27 '''
{ 157, 6, 21, 8, 1, -16 }, // 0x28 '('
{ 173, 6, 21, 8, 1, -16 }, // 0x29 ')'
{ 189, 11, 11, 13, 1, -17 }, // 0x2A '*'
{ 205, 11, 11, 13, 1, -13 }, // 0x2B '+'
{ 221, 4, 6, 7, 1, -2 }, // 0x2C ','
{ 224, 6, 3, 8, 1, -7 }, // 0x2D '-'
{ 227, 4, 4, 7, 1, -3 }, // 0x2E '.'
{ 229, 10, 17, 10, 0, -16 }, // 0x2F '/'
{ 251, 12, 17, 13, 1, -16 }, // 0x30 '0'
{ 277, 9, 17, 13, 1, -16 }, // 0x31 '1'
{ 297, 12, 17, 13, 1, -16 }, // 0x32 '2'
{ 323, 12, 17, 13, 1, -16 }, // 0x33 '3'
{ 349, 13, 17, 13, 0, -16 }, // 0x34 '4'
{ 377, 11, 17, 13, 1, -16 }, // 0x35 '5'
{ 401, 12, 17, 13, 1, -16 }, // 0x36 '6'
{ 427, 12, 17, 13, 1, -16 }, // 0x37 '7'
{ 453, 12, 17, 13, 1, -16 }, // 0x38 '8'
{ 479, 12, 17, 13, 1, -16 }, // 0x39 '9'
{ 505, 4, 13, 7, 1, -12 }, // 0x3A ':'
{ 512, 4, 16, 7, 1, -12 }, // 0x3B ';'
{ 520, 11, 13, 13, 1, -14 }, // 0x3C '<'
{ 538, 11, 7, 13, 1, -11 }, // 0x3D '='
{ 548, 11, 13, 13, 1, -14 }, // 0x3E '>'
{ 566, 11, 17, 11, 0, -16 }, // 0x3F '?'
{ 590, 19, 19, 21, 1, -16 }, // 0x40 '@'
{ 636, 16, 17, 16, 0, -16 }, // 0x41 'A'
{ 670, 12, 17, 16, 2, -16 }, // 0x42 'B'
{ 696, 13, 17, 15, 1, -16 }, // 0x43 'C'
{ 724, 14, 17, 17, 2, -16 }, // 0x44 'D'
{ 754, 10, 17, 13, 2, -16 }, // 0x45 'E'
{ 776, 10, 17, 13, 2, -16 }, // 0x46 'F'
{ 798, 14, 17, 17, 1, -16 }, // 0x47 'G'
{ 828, 14, 17, 18, 2, -16 }, // 0x48 'H'
{ 858, 7, 17, 9, 1, -16 }, // 0x49 'I'
{ 873, 8, 22, 8, -2, -16 }, // 0x4A 'J'
{ 895, 14, 17, 16, 2, -16 }, // 0x4B 'K'
{ 925, 10, 17, 13, 2, -16 }, // 0x4C 'L'
{ 947, 18, 17, 22, 2, -16 }, // 0x4D 'M'
{ 986, 15, 17, 19, 2, -16 }, // 0x4E 'N'
{ 1018, 16, 17, 19, 1, -16 }, // 0x4F 'O'
{ 1052, 12, 17, 15, 2, -16 }, // 0x50 'P'
{ 1078, 16, 21, 19, 1, -16 }, // 0x51 'Q'
{ 1120, 13, 17, 15, 2, -16 }, // 0x52 'R'
{ 1148, 11, 17, 13, 1, -16 }, // 0x53 'S'
{ 1172, 13, 17, 14, 0, -16 }, // 0x54 'T'
{ 1200, 14, 17, 18, 2, -16 }, // 0x55 'U'
{ 1230, 15, 17, 15, 0, -16 }, // 0x56 'V'
{ 1262, 23, 17, 23, 0, -16 }, // 0x57 'W'
{ 1311, 16, 17, 16, 0, -16 }, // 0x58 'X'
{ 1345, 15, 17, 15, 0, -16 }, // 0x59 'Y'
{ 1377, 12, 17, 14, 1, -16 }, // 0x5A 'Z'
{ 1403, 5, 21, 8, 2, -16 }, // 0x5B '['
{ 1417, 10, 17, 10, 0, -16 }, // 0x5C '\'
{ 1439, 5, 21, 8, 1, -16 }, // 0x5D ']'
{ 1453, 12, 11, 13, 1, -16 }, // 0x5E '^'
{ 1470, 10, 2, 10, 0, 3 }, // 0x5F '_'
{ 1473, 7, 4, 9, 1, -17 }, // 0x60 '`'
{ 1477, 11, 13, 14, 1, -12 }, // 0x61 'a'
{ 1495, 12, 18, 15, 2, -17 }, // 0x62 'b'
{ 1522, 10, 13, 12, 1, -12 }, // 0x63 'c'
{ 1539, 12, 18, 15, 1, -17 }, // 0x64 'd'
{ 1566, 12, 13, 14, 1, -12 }, // 0x65 'e'
{ 1586, 10, 18, 9, 0, -17 }, // 0x66 'f'
{ 1609, 12, 19, 15, 1, -12 }, // 0x67 'g'
{ 1638, 12, 18, 15, 2, -17 }, // 0x68 'h'
{ 1665, 3, 18, 7, 2, -17 }, // 0x69 'i'
{ 1672, 6, 24, 7, -1, -17 }, // 0x6A 'j'
{ 1690, 13, 18, 15, 2, -17 }, // 0x6B 'k'
{ 1720, 3, 18, 7, 2, -17 }, // 0x6C 'l'
{ 1727, 19, 13, 23, 2, -12 }, // 0x6D 'm'
{ 1758, 12, 13, 15, 2, -12 }, // 0x6E 'n'
{ 1778, 13, 13, 15, 1, -12 }, // 0x6F 'o'
{ 1800, 12, 19, 15, 2, -12 }, // 0x70 'p'
{ 1829, 12, 19, 15, 1, -12 }, // 0x71 'q'
{ 1858, 8, 13, 11, 2, -12 }, // 0x72 'r'
{ 1871, 10, 13, 12, 1, -12 }, // 0x73 's'
{ 1888, 8, 16, 10, 1, -15 }, // 0x74 't'
{ 1904, 12, 13, 15, 2, -12 }, // 0x75 'u'
{ 1924, 13, 13, 13, 0, -12 }, // 0x76 'v'
{ 1946, 20, 13, 20, 0, -12 }, // 0x77 'w'
{ 1979, 13, 13, 14, 0, -12 }, // 0x78 'x'
{ 2001, 13, 19, 13, 0, -12 }, // 0x79 'y'
{ 2032, 10, 13, 12, 1, -12 }, // 0x7A 'z'
{ 2049, 8, 21, 9, 0, -16 }, // 0x7B '{'
{ 2070, 3, 23, 13, 5, -17 }, // 0x7C '|'
{ 2079, 8, 21, 9, 1, -16 }, // 0x7D '}'
{ 2100, 11, 4, 13, 1, -9 } }; // 0x7E '~'
const GFXfont NotoSans_Bold12pt7b PROGMEM = {
(uint8_t *)NotoSans_Bold12pt7bBitmaps,
(GFXglyph *)NotoSans_Bold12pt7bGlyphs,
0x20, 0x7E, 32 };
// Approx. 2778 bytes
#endif // NOTOSANSBOLD12PT7B_H
@@ -0,0 +1,498 @@
#ifndef NOTOSANSBOLD18PT7B_H
#define NOTOSANSBOLD18PT7B_H
const uint8_t NotoSans_Bold18pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x9E, 0x79, 0xE7,
0x9E, 0x78, 0x00, 0x00, 0x7B, 0xFF, 0xFF, 0x78, 0xF8, 0xFF, 0xC7, 0xFE,
0x3F, 0xF1, 0xE7, 0x8F, 0x3C, 0x79, 0xE3, 0xCF, 0x1E, 0x78, 0xF0, 0x01,
0xE3, 0xC0, 0x0F, 0x1E, 0x00, 0x78, 0xF0, 0x03, 0x87, 0x80, 0x3C, 0x38,
0x01, 0xE3, 0xC0, 0x0F, 0x1E, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFB, 0xFF,
0xFF, 0xC1, 0xE3, 0xC0, 0x0F, 0x1E, 0x00, 0x78, 0xF0, 0x03, 0x87, 0x83,
0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x83, 0xC7,
0x80, 0x1C, 0x38, 0x01, 0xE3, 0xC0, 0x0F, 0x1E, 0x00, 0x78, 0xF0, 0x03,
0xC7, 0x80, 0x1C, 0x38, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, 0x01,
0xFF, 0x83, 0xFF, 0xF3, 0xFF, 0xFB, 0xFF, 0xFD, 0xFB, 0x1C, 0xF9, 0x80,
0x7C, 0xC0, 0x3F, 0x60, 0x1F, 0xF0, 0x07, 0xFC, 0x01, 0xFF, 0xC0, 0x7F,
0xF0, 0x0F, 0xFC, 0x01, 0xFF, 0x00, 0xDF, 0xC0, 0x67, 0xE0, 0x31, 0xFC,
0x19, 0xFF, 0xFF, 0xFB, 0xFF, 0xFD, 0xFF, 0xFC, 0xFF, 0xF8, 0x01, 0xE0,
0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x7C, 0x03, 0xFC, 0x01, 0xE0, 0x1F, 0xF8, 0x0F, 0x00, 0x79, 0xE0,
0x3C, 0x03, 0xE3, 0xC1, 0xE0, 0x0F, 0x0F, 0x07, 0x80, 0x3C, 0x3C, 0x3C,
0x00, 0xF0, 0xF1, 0xF0, 0x03, 0xC3, 0xC7, 0x80, 0x0F, 0x0F, 0x3E, 0x00,
0x3E, 0x7C, 0xF3, 0xF8, 0x79, 0xE7, 0x9F, 0xF1, 0xFF, 0x9E, 0x7F, 0xE3,
0xFC, 0xF3, 0xE7, 0x87, 0xE3, 0xCF, 0x1E, 0x00, 0x1E, 0x3C, 0x7C, 0x00,
0xF8, 0xF0, 0xF0, 0x03, 0xC3, 0xC3, 0xC0, 0x1F, 0x0F, 0x0F, 0x00, 0x78,
0x3C, 0x7C, 0x03, 0xC0, 0xF1, 0xE0, 0x0F, 0x03, 0xE7, 0x80, 0x78, 0x07,
0xFE, 0x01, 0xE0, 0x0F, 0xF0, 0x0F, 0x00, 0x1F, 0x80, 0x00, 0x60, 0x00,
0x03, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xE0, 0x01, 0xFF, 0xF8,
0x00, 0xF8, 0x7C, 0x00, 0x78, 0x3E, 0x00, 0x3E, 0x1F, 0x00, 0x1F, 0x1F,
0x00, 0x0F, 0xDF, 0x80, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0xFF,
0x81, 0xF0, 0xFF, 0xC0, 0xF8, 0xFF, 0xF0, 0xFC, 0xFF, 0xFC, 0x7C, 0x7E,
0x7F, 0x7E, 0x3E, 0x1F, 0xFF, 0x3F, 0x07, 0xFF, 0x1F, 0x81, 0xFF, 0x07,
0xC0, 0x7F, 0x83, 0xF8, 0x7F, 0xC1, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFC,
0x1F, 0xFF, 0x7F, 0x03, 0xFE, 0x1F, 0xC0, 0xFF, 0xFF, 0xF7, 0xBD, 0xEF,
0x78, 0x07, 0xC3, 0xE0, 0xF0, 0x7C, 0x1E, 0x0F, 0x83, 0xC1, 0xF0, 0x7C,
0x1F, 0x07, 0x81, 0xE0, 0x78, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x07,
0x81, 0xE0, 0x7C, 0x1F, 0x07, 0xC0, 0xF0, 0x3E, 0x0F, 0x81, 0xE0, 0x7C,
0x0F, 0x81, 0xE0, 0x3C, 0xF8, 0x1F, 0x03, 0xC0, 0xF8, 0x1E, 0x07, 0xC1,
0xF0, 0x3C, 0x0F, 0x83, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x7C, 0x1F,
0x07, 0xC1, 0xE0, 0x78, 0x1E, 0x0F, 0x83, 0xE0, 0xF8, 0x3C, 0x1F, 0x07,
0xC3, 0xE0, 0xF8, 0x7C, 0x1E, 0x0F, 0x00, 0x03, 0xE0, 0x01, 0xF0, 0x00,
0x78, 0x00, 0x38, 0x00, 0x1C, 0x03, 0x0E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x83, 0xF8, 0x01, 0xFC, 0x01, 0xEF, 0x00, 0xF7, 0x80, 0xF9,
0xE0, 0xF8, 0xF8, 0x1C, 0x30, 0x04, 0x10, 0x00, 0x03, 0xC0, 0x01, 0xE0,
0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x01, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00,
0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x00, 0x3E, 0x7D, 0xF3,
0xE7, 0xCF, 0x1E, 0x78, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7B,
0xFF, 0xFF, 0x78, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0x80, 0x3E, 0x00, 0xF8,
0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x01, 0xF0,
0x07, 0xC0, 0x1E, 0x00, 0xF8, 0x03, 0xE0, 0x1F, 0x00, 0x7C, 0x01, 0xF0,
0x0F, 0x80, 0x3E, 0x00, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0xF8, 0x00, 0x00,
0x40, 0x01, 0xFE, 0x01, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0x1F, 0x87,
0xE7, 0xC0, 0xF9, 0xF0, 0x3E, 0x7C, 0x0F, 0xBF, 0x03, 0xFF, 0xC0, 0xFF,
0xF0, 0x1F, 0xFC, 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0x7F, 0xF0, 0x3F, 0xFC,
0x0F, 0xDF, 0x03, 0xF7, 0xC0, 0xF9, 0xF0, 0x3E, 0x7E, 0x0F, 0x8F, 0x87,
0xE3, 0xFF, 0xF0, 0x7F, 0xF8, 0x0F, 0xFE, 0x01, 0xFE, 0x00, 0x01, 0xF8,
0x1F, 0xC1, 0xFE, 0x1F, 0xF3, 0xFF, 0xBF, 0xFF, 0xF7, 0xEF, 0x3F, 0x31,
0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F,
0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0,
0x3F, 0x01, 0xF8, 0x00, 0x40, 0x03, 0xFF, 0x03, 0xFF, 0xE1, 0xFF, 0xFC,
0xFF, 0xFF, 0x8F, 0x07, 0xE3, 0x80, 0xF8, 0x40, 0x3E, 0x00, 0x0F, 0x80,
0x03, 0xE0, 0x01, 0xF8, 0x00, 0x7C, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F,
0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00,
0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF0, 0x00, 0xC0, 0x07, 0xFF, 0x07, 0xFF, 0xE3, 0xFF, 0xFC, 0x7F,
0xFF, 0x8E, 0x07, 0xE2, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x07,
0xC0, 0x03, 0xF0, 0x3F, 0xF0, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0xFF, 0xF0,
0x00, 0xFE, 0x00, 0x0F, 0x80, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x80,
0x0F, 0xF8, 0x0F, 0xEF, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFE, 0x0F, 0xFE,
0x00, 0x00, 0x3F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x80, 0x1F,
0xF0, 0x03, 0xFE, 0x00, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xBF, 0x01, 0xE7,
0xE0, 0x7C, 0xFC, 0x0F, 0x1F, 0x83, 0xC3, 0xF0, 0xF8, 0x7E, 0x1E, 0x0F,
0xC7, 0x81, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F,
0x00, 0x7F, 0xFE, 0x3F, 0xFF, 0x1F, 0xFF, 0x8F, 0xFF, 0xC7, 0xC0, 0x03,
0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x7F, 0xF8, 0x3F, 0xFF,
0x1F, 0xFF, 0xCF, 0xFF, 0xF1, 0x87, 0xF8, 0x00, 0xFC, 0x00, 0x3E, 0x00,
0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xD0, 0x07, 0xEE, 0x07, 0xF7, 0xFF, 0xF3,
0xFF, 0xF9, 0xFF, 0xF0, 0x7F, 0xF0, 0x00, 0x01, 0xFF, 0x01, 0xFF, 0xC0,
0xFF, 0xF0, 0x7F, 0xFC, 0x3F, 0x80, 0x0F, 0x80, 0x07, 0xC0, 0x01, 0xF0,
0x00, 0x7C, 0x00, 0x1E, 0x7F, 0x8F, 0xBF, 0xF3, 0xFF, 0xFE, 0xFF, 0xFF,
0xBF, 0x83, 0xFF, 0xC0, 0xFF, 0xF0, 0x1F, 0xFC, 0x07, 0xFF, 0x01, 0xF7,
0xC0, 0x7D, 0xF0, 0x3F, 0x7E, 0x1F, 0x8F, 0xFF, 0xE1, 0xFF, 0xF0, 0x3F,
0xF8, 0x07, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x01, 0xF8, 0x00, 0x7C, 0x00, 0x3F,
0x00, 0x0F, 0x80, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0x7C, 0x00, 0x3F, 0x00,
0x0F, 0x80, 0x07, 0xE0, 0x01, 0xF0, 0x00, 0xFC, 0x00, 0x3E, 0x00, 0x1F,
0x80, 0x07, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3E, 0x00, 0x1F, 0x80,
0x00, 0x0F, 0xFC, 0x07, 0xFF, 0x83, 0xFF, 0xF1, 0xFC, 0xFE, 0x7C, 0x0F,
0x9F, 0x03, 0xE7, 0xC0, 0xF9, 0xF0, 0x3E, 0x3E, 0x1F, 0x0F, 0xFF, 0xC1,
0xFF, 0xE0, 0x3F, 0xE0, 0x0F, 0xFC, 0x07, 0xFF, 0x83, 0xF3, 0xF1, 0xF8,
0x7E, 0x7C, 0x0F, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xFC, 0x0F,
0xDF, 0xFF, 0xE7, 0xFF, 0xF8, 0xFF, 0xF8, 0x0F, 0xFC, 0x00, 0x0F, 0xF8,
0x07, 0xFF, 0x03, 0xFF, 0xE1, 0xFF, 0xFC, 0x7E, 0x1F, 0xBF, 0x03, 0xEF,
0x80, 0xFB, 0xE0, 0x3F, 0xF8, 0x07, 0xFE, 0x03, 0xFF, 0xC0, 0xFD, 0xF8,
0x7F, 0x7F, 0xFF, 0xCF, 0xFF, 0xF3, 0xFF, 0x7C, 0x3F, 0x9E, 0x00, 0x07,
0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x7F, 0x0F, 0xFF, 0x83,
0xFF, 0xC0, 0xFF, 0xE0, 0x3F, 0xE0, 0x00, 0x33, 0xFF, 0xFF, 0xFD, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xFF, 0xFF, 0xDE, 0x18, 0xFD,
0xFB, 0xF7, 0xE7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x7D, 0xF3, 0xE7, 0xCF, 0x1E, 0x78, 0xF0, 0x00, 0x00, 0x80, 0x01,
0xC0, 0x03, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0x80, 0x7F,
0x00, 0xFE, 0x00, 0x7C, 0x00, 0x3F, 0x80, 0x0F, 0xF8, 0x01, 0xFF, 0x00,
0x3F, 0xE0, 0x07, 0xFE, 0x00, 0x7F, 0x00, 0x0F, 0x80, 0x01, 0xC0, 0x00,
0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE0, 0x80, 0x00, 0x70, 0x00, 0x3E, 0x00, 0x1F, 0xC0, 0x0F, 0xF8, 0x00,
0xFF, 0x00, 0x1F, 0xE0, 0x03, 0xFC, 0x00, 0x7F, 0x80, 0x0F, 0xC0, 0x1F,
0xE0, 0x3F, 0xC0, 0xFF, 0x81, 0xFF, 0x03, 0xFE, 0x01, 0xF8, 0x00, 0xF0,
0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x1F, 0xF8, 0xFF, 0xFC,
0x7F, 0xFE, 0x7F, 0xFF, 0x30, 0x3F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
0x00, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x03, 0xF8, 0x03, 0xF0, 0x07, 0xC0,
0x07, 0xC0, 0x07, 0x80, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x07, 0xC0, 0x00, 0x7F,
0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x00, 0xFE, 0x01, 0xF8,
0x1F, 0x80, 0x07, 0xC3, 0xE0, 0x00, 0x3C, 0x3C, 0x0F, 0xC1, 0xE7, 0x83,
0xFF, 0x9E, 0x78, 0x7F, 0xF8, 0xFF, 0x0F, 0xCF, 0x8F, 0xF1, 0xF0, 0x78,
0xFF, 0x1E, 0x07, 0x8F, 0xF1, 0xE0, 0xF0, 0xFF, 0x1E, 0x0F, 0x0F, 0xF1,
0xE0, 0xF0, 0xFF, 0x1E, 0x0F, 0x0F, 0xF1, 0xE0, 0xF1, 0xEF, 0x1F, 0x1F,
0x9E, 0xF0, 0xFF, 0xFF, 0xCF, 0x0F, 0xFB, 0xF8, 0x78, 0x3E, 0x1F, 0x07,
0xC0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x03, 0xF0, 0x00, 0xC0, 0x1F, 0xFB,
0xFC, 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x03, 0xF8, 0x00,
0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x80,
0x01, 0xFF, 0x80, 0x01, 0xF7, 0xC0, 0x03, 0xE7, 0xC0, 0x03, 0xE7, 0xC0,
0x03, 0xE7, 0xE0, 0x07, 0xE3, 0xE0, 0x07, 0xC3, 0xE0, 0x07, 0xC3, 0xF0,
0x0F, 0xC1, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF8, 0x1F, 0xFF, 0xF8,
0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0x00, 0x7C,
0x3E, 0x00, 0x7E, 0x7E, 0x00, 0x7E, 0x7E, 0x00, 0x3F, 0x7C, 0x00, 0x3F,
0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF,
0xEF, 0x81, 0xFD, 0xF0, 0x1F, 0xBE, 0x03, 0xF7, 0xC0, 0x7E, 0xF8, 0x0F,
0xDF, 0x03, 0xF3, 0xFF, 0xFC, 0x7F, 0xFE, 0x0F, 0xFF, 0xF1, 0xFF, 0xFF,
0x3E, 0x07, 0xF7, 0xC0, 0x3E, 0xF8, 0x07, 0xFF, 0x00, 0xFF, 0xE0, 0x1F,
0xFC, 0x07, 0xEF, 0x81, 0xFD, 0xFF, 0xFF, 0xBF, 0xFF, 0xE7, 0xFF, 0xF8,
0xFF, 0xF8, 0x00, 0x00, 0x18, 0x00, 0x1F, 0xFC, 0x07, 0xFF, 0xF0, 0xFF,
0xFE, 0x1F, 0xFF, 0xE3, 0xF8, 0x1C, 0x7F, 0x00, 0x07, 0xE0, 0x00, 0x7C,
0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F,
0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0xFC, 0x00, 0x0F, 0xC0, 0x00,
0x7C, 0x00, 0x07, 0xE0, 0x00, 0x7F, 0x00, 0x23, 0xFC, 0x1E, 0x3F, 0xFF,
0xE1, 0xFF, 0xFE, 0x07, 0xFF, 0xE0, 0x3F, 0xF8, 0xFF, 0xF8, 0x07, 0xFF,
0xF8, 0x3F, 0xFF, 0xE1, 0xFF, 0xFF, 0x8F, 0x83, 0xFE, 0x7C, 0x03, 0xF3,
0xE0, 0x0F, 0xDF, 0x00, 0x7E, 0xF8, 0x01, 0xFF, 0xC0, 0x0F, 0xFE, 0x00,
0x7F, 0xF0, 0x03, 0xFF, 0x80, 0x1F, 0xFC, 0x00, 0xFF, 0xE0, 0x07, 0xFF,
0x00, 0x3F, 0xF8, 0x01, 0xF7, 0xC0, 0x1F, 0xBE, 0x01, 0xFD, 0xF0, 0x1F,
0xCF, 0x87, 0xFC, 0x7F, 0xFF, 0xE3, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0xFF,
0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F,
0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xFF, 0xF7, 0xFF,
0xEF, 0xFF, 0xDF, 0xFF, 0xBF, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03,
0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0x00,
0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0xFF, 0xEF,
0xFF, 0xDF, 0xFF, 0xBF, 0xFF, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xE0,
0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x00,
0x00, 0x04, 0x00, 0x0F, 0xFF, 0x01, 0xFF, 0xFE, 0x1F, 0xFF, 0xE1, 0xFF,
0xFF, 0x1F, 0xE0, 0x30, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0x7E, 0x00, 0x07,
0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x0F, 0xC1, 0xFF, 0xFE, 0x0F,
0xFF, 0xF0, 0x7F, 0xFF, 0x83, 0xFF, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xDF,
0x00, 0x7E, 0xFC, 0x03, 0xF7, 0xF0, 0x1F, 0x9F, 0xE0, 0xFC, 0x7F, 0xFF,
0xE1, 0xFF, 0xFF, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0x00, 0xFC, 0x01, 0xFF,
0xE0, 0x0F, 0xFF, 0x00, 0x7F, 0xF8, 0x03, 0xFF, 0xC0, 0x1F, 0xFE, 0x00,
0xFF, 0xF0, 0x07, 0xFF, 0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07,
0xFF, 0x80, 0x3F, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xFF, 0x00, 0x7F, 0xF8,
0x03, 0xFF, 0xC0, 0x1F, 0xFE, 0x00, 0xFF, 0xF0, 0x07, 0xFF, 0x80, 0x3F,
0xFC, 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFC, 0x1F, 0x81, 0xF8,
0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8,
0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0x81, 0xF8, 0x1F, 0x87, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03,
0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03,
0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03,
0xF0, 0x3F, 0x03, 0xF0, 0x3F, 0x03, 0xE0, 0x3E, 0x03, 0xE0, 0x7E, 0xFF,
0xEF, 0xFC, 0xFF, 0x8F, 0xF0, 0xFC, 0x03, 0xFF, 0xC0, 0x7E, 0xFC, 0x0F,
0xCF, 0xC1, 0xF8, 0xFC, 0x1F, 0x8F, 0xC3, 0xF0, 0xFC, 0x7E, 0x0F, 0xCF,
0xC0, 0xFC, 0xFC, 0x0F, 0xDF, 0x80, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0xFF,
0xF8, 0x0F, 0xFF, 0x80, 0xFF, 0xFC, 0x0F, 0xCF, 0xC0, 0xFC, 0x7E, 0x0F,
0xC3, 0xF0, 0xFC, 0x3F, 0x0F, 0xC1, 0xF8, 0xFC, 0x0F, 0xCF, 0xC0, 0xFC,
0xFC, 0x07, 0xEF, 0xC0, 0x7E, 0xFC, 0x03, 0xF0, 0xF8, 0x00, 0xF8, 0x00,
0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x0F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF,
0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFE, 0x03,
0xDF, 0xFB, 0xC0, 0x7B, 0xFF, 0x78, 0x0F, 0x7F, 0xEF, 0x83, 0xEF, 0xFC,
0xF0, 0x79, 0xFF, 0x9E, 0x0F, 0x3F, 0xF3, 0xE3, 0xE7, 0xFE, 0x3C, 0x78,
0xFF, 0xC7, 0x8F, 0x1F, 0xF8, 0xFB, 0xE3, 0xFF, 0x0F, 0x78, 0x7F, 0xE1,
0xEF, 0x0F, 0xFC, 0x3F, 0xE1, 0xFF, 0x87, 0xF8, 0x3F, 0xF0, 0x7F, 0x07,
0xFE, 0x0F, 0xE0, 0xFF, 0xC1, 0xF8, 0x1F, 0xF8, 0x1F, 0x03, 0xE0, 0xFE,
0x00, 0x3F, 0xFC, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0,
0x3F, 0xFF, 0x00, 0xFF, 0xFE, 0x03, 0xFE, 0xF8, 0x0F, 0xFB, 0xF0, 0x3F,
0xE7, 0xE0, 0xFF, 0x9F, 0x83, 0xFE, 0x3F, 0x0F, 0xF8, 0x7C, 0x3F, 0xE1,
0xF8, 0xFF, 0x83, 0xE3, 0xFE, 0x0F, 0xCF, 0xF8, 0x1F, 0xBF, 0xE0, 0x7E,
0xFF, 0x80, 0xFF, 0xFE, 0x01, 0xFF, 0xF8, 0x07, 0xFF, 0xE0, 0x0F, 0xFF,
0x80, 0x3F, 0xFE, 0x00, 0x7F, 0xF8, 0x01, 0xFC, 0x00, 0x18, 0x00, 0x03,
0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x3F,
0x81, 0xFC, 0x7F, 0x00, 0xFE, 0x7E, 0x00, 0x7E, 0x7C, 0x00, 0x7E, 0xFC,
0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
0x00, 0x3F, 0x7E, 0x00, 0x7E, 0x7E, 0x00, 0x7E, 0x7F, 0x00, 0xFC, 0x3F,
0xC3, 0xFC, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x07, 0xFF, 0xE0, 0x01,
0xFF, 0x80, 0xFF, 0xF8, 0x7F, 0xFF, 0x3F, 0xFF, 0xDF, 0xFF, 0xEF, 0x83,
0xFF, 0xC0, 0xFF, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE,
0x07, 0xFF, 0x1F, 0xFF, 0xFF, 0xF7, 0xFF, 0xF3, 0xFF, 0xF1, 0xFF, 0xE0,
0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0,
0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03,
0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x3F,
0x81, 0xFC, 0x7F, 0x00, 0xFE, 0x7E, 0x00, 0x7E, 0x7C, 0x00, 0x7E, 0xFC,
0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
0x00, 0x3F, 0x7E, 0x00, 0x7E, 0x7E, 0x00, 0x7E, 0x7F, 0x00, 0xFC, 0x3F,
0xC3, 0xFC, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x07, 0xFF, 0xE0, 0x01,
0xFF, 0xC0, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00,
0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF,
0xE0, 0xFF, 0xFF, 0x0F, 0xFF, 0xF8, 0xF8, 0x3F, 0x8F, 0x80, 0xF8, 0xF8,
0x0F, 0xCF, 0x80, 0xFC, 0xF8, 0x0F, 0x8F, 0x80, 0xF8, 0xF8, 0x1F, 0x8F,
0xFF, 0xF0, 0xFF, 0xFE, 0x0F, 0xFF, 0xC0, 0xFF, 0xF8, 0x0F, 0x8F, 0xC0,
0xF8, 0x7E, 0x0F, 0x83, 0xE0, 0xF8, 0x3F, 0x0F, 0x81, 0xF8, 0xF8, 0x1F,
0x8F, 0x80, 0xFC, 0xF8, 0x07, 0xEF, 0x80, 0x7E, 0xF8, 0x03, 0xF0, 0x00,
0x80, 0x0F, 0xFC, 0x3F, 0xFF, 0x7F, 0xFE, 0x7F, 0xFE, 0xFC, 0x0E, 0xF8,
0x00, 0xF8, 0x00, 0xF8, 0x00, 0xFC, 0x00, 0xFF, 0x00, 0x7F, 0xC0, 0x3F,
0xF0, 0x1F, 0xF8, 0x07, 0xFC, 0x01, 0xFE, 0x00, 0x7F, 0x00, 0x3F, 0x00,
0x1F, 0x00, 0x1F, 0x80, 0x3F, 0xF0, 0x7F, 0xFF, 0xFE, 0xFF, 0xFC, 0xFF,
0xF8, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0,
0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0,
0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0,
0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80,
0x03, 0xF0, 0x00, 0xF8, 0x01, 0xFF, 0xC0, 0x0F, 0xFE, 0x00, 0x7F, 0xF0,
0x03, 0xFF, 0x80, 0x1F, 0xFC, 0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x3F,
0xF8, 0x01, 0xFF, 0xC0, 0x0F, 0xFE, 0x00, 0x7F, 0xF0, 0x03, 0xFF, 0x80,
0x1F, 0xFC, 0x00, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x3F, 0xF8, 0x01, 0xFF,
0xE0, 0x0F, 0xFF, 0x00, 0x7C, 0xF8, 0x07, 0xE7, 0xF0, 0x7F, 0x1F, 0xFF,
0xF0, 0xFF, 0xFF, 0x03, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xFC, 0x00, 0x7E,
0xF8, 0x00, 0xF9, 0xF0, 0x01, 0xF3, 0xF0, 0x07, 0xE3, 0xE0, 0x0F, 0x87,
0xC0, 0x1F, 0x0F, 0x80, 0x7E, 0x0F, 0x80, 0xF8, 0x1F, 0x01, 0xF0, 0x3E,
0x07, 0xE0, 0x3E, 0x0F, 0x80, 0x7C, 0x1F, 0x00, 0xF8, 0x7E, 0x00, 0xF8,
0xF8, 0x01, 0xF1, 0xF0, 0x03, 0xE3, 0xE0, 0x03, 0xEF, 0x80, 0x07, 0xDF,
0x00, 0x0F, 0xBE, 0x00, 0x0F, 0x78, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0,
0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0xF8, 0x03, 0xF0,
0x07, 0xFF, 0x00, 0xFC, 0x03, 0xF7, 0xC0, 0x3F, 0x00, 0xF9, 0xF0, 0x0F,
0xE0, 0x3E, 0x7C, 0x07, 0xF8, 0x0F, 0x9F, 0x81, 0xFE, 0x07, 0xE3, 0xE0,
0x7F, 0x81, 0xF0, 0xF8, 0x1F, 0xF0, 0x7C, 0x3E, 0x0F, 0xFC, 0x1F, 0x0F,
0xC3, 0xCF, 0x07, 0xC1, 0xF0, 0xF3, 0xC3, 0xE0, 0x7C, 0x7C, 0xF8, 0xF8,
0x1F, 0x1F, 0x3E, 0x3E, 0x07, 0xC7, 0x87, 0x8F, 0x80, 0xF9, 0xE1, 0xE7,
0xC0, 0x3E, 0xF8, 0x7D, 0xF0, 0x0F, 0xBE, 0x1F, 0x7C, 0x01, 0xEF, 0x03,
0xDF, 0x00, 0x7B, 0xC0, 0xF7, 0x80, 0x1F, 0xF0, 0x3F, 0xE0, 0x07, 0xFC,
0x0F, 0xF8, 0x00, 0xFE, 0x01, 0xFE, 0x00, 0x3F, 0x80, 0x7F, 0x00, 0x0F,
0xE0, 0x1F, 0xC0, 0x03, 0xF8, 0x07, 0xF0, 0x00, 0x7E, 0x00, 0xFE, 0x7E,
0x01, 0xF8, 0xFC, 0x07, 0xE0, 0xFC, 0x0F, 0xC0, 0xF8, 0x3F, 0x01, 0xF8,
0xFC, 0x01, 0xF9, 0xF8, 0x01, 0xF7, 0xE0, 0x03, 0xFF, 0x80, 0x03, 0xFF,
0x00, 0x07, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0xE0,
0x00, 0x7F, 0xC0, 0x01, 0xFF, 0xC0, 0x03, 0xEF, 0xC0, 0x0F, 0xCF, 0x80,
0x3F, 0x1F, 0x80, 0x7E, 0x1F, 0x81, 0xF8, 0x3F, 0x07, 0xE0, 0x3F, 0x0F,
0xC0, 0x3F, 0x3F, 0x00, 0x7E, 0xFC, 0x00, 0x7E, 0xFC, 0x00, 0xFD, 0xF8,
0x07, 0xE7, 0xE0, 0x1F, 0x8F, 0xC0, 0xFC, 0x3F, 0x03, 0xF0, 0x7E, 0x1F,
0x80, 0xF8, 0x7C, 0x03, 0xF3, 0xF0, 0x07, 0xCF, 0x80, 0x1F, 0xFE, 0x00,
0x3F, 0xF0, 0x00, 0xFF, 0xC0, 0x01, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x0F,
0xC0, 0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x0F, 0xC0,
0x00, 0x3F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00,
0x3F, 0x00, 0x00, 0xFC, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFB, 0xFF, 0xFF,
0x7F, 0xFF, 0xE0, 0x00, 0xF8, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x01, 0xF0,
0x00, 0x7E, 0x00, 0x1F, 0x80, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x3F, 0x00,
0x0F, 0xC0, 0x01, 0xF0, 0x00, 0x7E, 0x00, 0x1F, 0x80, 0x03, 0xE0, 0x00,
0xFC, 0x00, 0x3F, 0x00, 0x07, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x87, 0xC3,
0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8,
0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F,
0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0x01, 0xF0, 0x07, 0xC0, 0x0F, 0x00, 0x3E,
0x00, 0xF8, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x3E, 0x00, 0xF8, 0x01,
0xE0, 0x07, 0xC0, 0x1F, 0x00, 0x3C, 0x00, 0xF8, 0x03, 0xE0, 0x07, 0xC0,
0x1F, 0x00, 0x7C, 0x00, 0xF8, 0x03, 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C,
0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0x78, 0x00,
0x3E, 0x00, 0x0F, 0xC0, 0x07, 0xF0, 0x01, 0xDE, 0x00, 0xF7, 0x80, 0x3C,
0xF0, 0x1E, 0x3C, 0x07, 0x87, 0x83, 0xC1, 0xE0, 0xF0, 0x3C, 0x78, 0x0F,
0x9E, 0x01, 0xE7, 0x80, 0x7F, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF8, 0xFE, 0x0F, 0x81, 0xF0, 0x3E, 0x07, 0xC0, 0x70, 0x00, 0x60, 0x03,
0xFF, 0x83, 0xFF, 0xF0, 0x7F, 0xFE, 0x1F, 0x1F, 0x82, 0x03, 0xE0, 0x00,
0xFC, 0x00, 0x3F, 0x03, 0xFF, 0xC7, 0xFF, 0xF3, 0xFF, 0xFD, 0xFC, 0x3F,
0x7C, 0x0F, 0xFF, 0x03, 0xFF, 0xC0, 0xFF, 0xF0, 0x7F, 0x7F, 0xFF, 0xDF,
0xFF, 0xF3, 0xFF, 0x7C, 0x7F, 0x0F, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80,
0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x80,
0xF9, 0xFC, 0x3F, 0xFF, 0x8F, 0xFF, 0xF3, 0xFF, 0xFE, 0xFC, 0x1F, 0xBE,
0x03, 0xEF, 0x80, 0xFB, 0xE0, 0x3E, 0xF8, 0x0F, 0xFE, 0x03, 0xFF, 0x80,
0xFF, 0xE0, 0x3E, 0xF8, 0x0F, 0xBF, 0x07, 0xEF, 0xE3, 0xFB, 0xFF, 0xFC,
0xFF, 0xFF, 0x3D, 0xFF, 0x8F, 0x1F, 0xC0, 0x00, 0xC0, 0x1F, 0xFC, 0x7F,
0xF9, 0xFF, 0xF7, 0xFF, 0xCF, 0xC0, 0xBF, 0x00, 0x7C, 0x00, 0xF8, 0x01,
0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x80, 0x3F, 0x00, 0x3F,
0x07, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF8, 0x3F, 0xE0, 0x00, 0x0F, 0xC0,
0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00,
0xFC, 0x0C, 0x3F, 0x1F, 0xEF, 0xCF, 0xFD, 0xF7, 0xFF, 0xFD, 0xFF, 0xFF,
0xFE, 0x1F, 0xFF, 0x03, 0xFF, 0x80, 0xFF, 0xE0, 0x1F, 0xF8, 0x07, 0xFE,
0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x0F, 0xFF, 0x03, 0xFF, 0xE1,
0xFD, 0xFF, 0xFF, 0x7F, 0xFF, 0xCF, 0xFD, 0xF0, 0xFC, 0x7C, 0x00, 0xC0,
0x07, 0xFE, 0x07, 0xFF, 0x87, 0xFF, 0xE7, 0xE3, 0xF3, 0xE0, 0x7F, 0xF0,
0x3F, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x80, 0x07, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x02, 0x7F, 0xFF, 0x1F, 0xFF,
0x87, 0xFF, 0xC0, 0xFF, 0xC0, 0x03, 0xF8, 0x3F, 0xF1, 0xFF, 0xC7, 0xFE,
0x1F, 0x88, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x7F, 0xF3, 0xFF, 0xCF, 0xFF,
0x3F, 0xFC, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C,
0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F,
0x00, 0x7C, 0x01, 0xF0, 0x00, 0x03, 0x00, 0x07, 0xF9, 0xF3, 0xFF, 0x7D,
0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x07, 0xFF, 0xC0, 0xFF, 0xE0, 0x3F, 0xF8,
0x07, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x03,
0xFF, 0xC0, 0xFF, 0xF8, 0x7F, 0x7F, 0xFF, 0xDF, 0xFF, 0xF3, 0xFF, 0xFC,
0x3F, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xF9, 0x80, 0x7E, 0x7F,
0xFF, 0x9F, 0xFF, 0xC7, 0xFF, 0xE1, 0xFF, 0xE0, 0xF8, 0x00, 0x7C, 0x00,
0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0,
0x60, 0xF9, 0xFE, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF,
0xE0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03,
0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8,
0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xE0, 0x39, 0xFF, 0xFF, 0x7C, 0x00, 0x00,
0x7D, 0xF7, 0xDF, 0x7D, 0xF7, 0xDF, 0x7D, 0xF7, 0xDF, 0x7D, 0xF7, 0xDF,
0x7D, 0xF7, 0xC0, 0x03, 0x81, 0xF0, 0xFC, 0x3F, 0x07, 0xC0, 0x00, 0x00,
0x00, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07,
0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0,
0x7C, 0x1F, 0x07, 0xC3, 0xF0, 0xFF, 0xFF, 0xFF, 0xBF, 0xCF, 0xE0, 0xF8,
0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0,
0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x0F, 0xDF, 0x03, 0xF3, 0xE0,
0xFC, 0x7C, 0x3F, 0x0F, 0x8F, 0xC1, 0xF3, 0xF0, 0x3E, 0xFC, 0x07, 0xDF,
0x00, 0xFF, 0xE0, 0x1F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F, 0xFC, 0x0F, 0xCF,
0xC1, 0xF0, 0xFC, 0x3E, 0x0F, 0xC7, 0xC1, 0xF8, 0xF8, 0x1F, 0x9F, 0x01,
0xFB, 0xE0, 0x3F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x20, 0x06,
0x07, 0x9F, 0xF1, 0xFE, 0x3D, 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xEF,
0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xE0, 0xFF, 0xF0, 0x7F, 0x07, 0xFF, 0x03,
0xF0, 0x3F, 0xF8, 0x0F, 0x80, 0xFF, 0xC0, 0x7C, 0x07, 0xFE, 0x03, 0xE0,
0x3F, 0xF0, 0x1F, 0x01, 0xFF, 0x80, 0xF8, 0x0F, 0xFC, 0x07, 0xC0, 0x7F,
0xE0, 0x3E, 0x03, 0xFF, 0x01, 0xF0, 0x1F, 0xF8, 0x0F, 0x80, 0xFF, 0xC0,
0x7C, 0x07, 0xFE, 0x03, 0xE0, 0x3F, 0xF0, 0x1F, 0x01, 0xF0, 0x00, 0x20,
0x79, 0xFF, 0x3D, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xF0,
0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF,
0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07,
0xFE, 0x03, 0xFF, 0x01, 0xF0, 0x00, 0xE0, 0x03, 0xFF, 0x01, 0xFF, 0xE0,
0xFF, 0xFC, 0x7F, 0xFF, 0x9F, 0x03, 0xEF, 0xC0, 0xFF, 0xE0, 0x1F, 0xF8,
0x07, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x01,
0xFF, 0xC0, 0xFD, 0xF8, 0x7E, 0x7F, 0xFF, 0x8F, 0xFF, 0xC1, 0xFF, 0xE0,
0x1F, 0xE0, 0x00, 0x30, 0x3C, 0x7F, 0x0F, 0x7F, 0xE3, 0xFF, 0xFC, 0xFF,
0xFF, 0xBF, 0x07, 0xEF, 0x80, 0xFB, 0xE0, 0x3E, 0xF8, 0x0F, 0xFE, 0x03,
0xFF, 0x80, 0xFF, 0xE0, 0x3F, 0xF8, 0x0F, 0xBE, 0x03, 0xEF, 0xC1, 0xFB,
0xF8, 0xFE, 0xFF, 0xFF, 0x3F, 0xFF, 0xCF, 0xFF, 0xE3, 0xE7, 0xF0, 0xF8,
0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00,
0x0F, 0x80, 0x03, 0xE0, 0x00, 0x03, 0x00, 0x07, 0xF9, 0xF3, 0xFF, 0x7D,
0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x07, 0xFF, 0xC0, 0xFF, 0xE0, 0x3F, 0xF8,
0x07, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x03,
0xFF, 0xC0, 0xFF, 0xF8, 0x7F, 0x7F, 0xFF, 0xDF, 0xFF, 0xF3, 0xFF, 0xFC,
0x3F, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00,
0x0F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x3F, 0x1F, 0xF3,
0xFF, 0x7F, 0xFF, 0xFF, 0xF9, 0xFC, 0x0F, 0xC0, 0xF8, 0x0F, 0x80, 0xF8,
0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8,
0x0F, 0x80, 0x03, 0x00, 0xFF, 0xE7, 0xFF, 0xFF, 0xFE, 0xF8, 0x3B, 0xE0,
0x2F, 0x80, 0x3F, 0x80, 0xFF, 0x81, 0xFF, 0x83, 0xFF, 0x83, 0xFF, 0x01,
0xFC, 0x03, 0xF0, 0x07, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xBF,
0xF8, 0x0F, 0x00, 0x78, 0x07, 0xC0, 0x3E, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80,
0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x3F, 0xF1, 0xFF, 0x87,
0xFC, 0x1F, 0xE0, 0xFC, 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0x7F, 0xF0, 0x1F,
0xFC, 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0x7F, 0xF0, 0x1F, 0xFC, 0x07, 0xFF,
0x01, 0xFF, 0xC0, 0x7F, 0xF0, 0x1F, 0xFC, 0x07, 0xDF, 0x03, 0xF7, 0xE1,
0xFD, 0xFF, 0xFF, 0x7F, 0xFF, 0xCF, 0xFC, 0xF1, 0xFE, 0x3C, 0xFC, 0x03,
0xF7, 0xC0, 0x3E, 0x7C, 0x03, 0xE7, 0xE0, 0x7E, 0x3E, 0x07, 0xC3, 0xE0,
0x7C, 0x1F, 0x0F, 0xC1, 0xF0, 0xF8, 0x1F, 0x0F, 0x80, 0xF9, 0xF0, 0x0F,
0x9F, 0x00, 0xF9, 0xF0, 0x07, 0xFE, 0x00, 0x7F, 0xE0, 0x03, 0xFE, 0x00,
0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0xFC, 0x0F,
0xC0, 0xFD, 0xF0, 0x3F, 0x03, 0xE7, 0xC0, 0xFE, 0x0F, 0x9F, 0x87, 0xF8,
0x3E, 0x3E, 0x1F, 0xE1, 0xF0, 0xF8, 0x7B, 0x87, 0xC3, 0xE3, 0xCF, 0x1F,
0x07, 0xCF, 0x3C, 0x7C, 0x1F, 0x3C, 0xF3, 0xE0, 0x7C, 0xF3, 0xCF, 0x81,
0xF3, 0x87, 0xBE, 0x03, 0xDE, 0x1E, 0xF0, 0x0F, 0xF8, 0x7B, 0xC0, 0x3F,
0xE1, 0xFF, 0x00, 0x7F, 0x83, 0xFC, 0x01, 0xFC, 0x0F, 0xE0, 0x07, 0xF0,
0x3F, 0x80, 0x1F, 0xC0, 0xFE, 0x00, 0x3F, 0x03, 0xF0, 0x00, 0xFE, 0x07,
0xF3, 0xF0, 0x7E, 0x3F, 0x0F, 0xC1, 0xF8, 0xF8, 0x0F, 0x9F, 0x80, 0xFF,
0xF0, 0x07, 0xFE, 0x00, 0x3F, 0xE0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03,
0xFE, 0x00, 0x7F, 0xE0, 0x0F, 0xFF, 0x00, 0xFD, 0xF8, 0x1F, 0x9F, 0x83,
0xF0, 0xFC, 0x3F, 0x07, 0xE7, 0xE0, 0x7E, 0xFC, 0x03, 0xF0, 0xFC, 0x03,
0xF7, 0xC0, 0x3E, 0x7E, 0x03, 0xE7, 0xE0, 0x7E, 0x3E, 0x07, 0xC3, 0xF0,
0x7C, 0x1F, 0x0F, 0xC1, 0xF0, 0xF8, 0x1F, 0x0F, 0x80, 0xF9, 0xF0, 0x0F,
0x9F, 0x00, 0x79, 0xF0, 0x07, 0xDE, 0x00, 0x3F, 0xE0, 0x03, 0xFE, 0x00,
0x3F, 0xC0, 0x01, 0xFC, 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00, 0x1F, 0x80,
0x01, 0xF0, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x07, 0xFE, 0x00, 0x7F, 0xC0,
0x07, 0xF8, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFD, 0xFF, 0xFB,
0xFF, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x0F,
0x80, 0x3F, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x80, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xE0, 0xFC, 0x3F, 0x87, 0xF0,
0xF8, 0x1F, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x81, 0xF1,
0xFE, 0x3F, 0x07, 0xC0, 0xFE, 0x0F, 0xE0, 0x7C, 0x07, 0x80, 0xF0, 0x1E,
0x03, 0xC0, 0x78, 0x0F, 0x01, 0xF0, 0x3F, 0x07, 0xF0, 0x7E, 0x07, 0xC0,
0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x0F, 0xE0, 0xFF, 0x0F,
0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01,
0xF0, 0x0F, 0x80, 0xFF, 0x07, 0xF0, 0x3F, 0x0F, 0xF0, 0xFE, 0x1F, 0x81,
0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x1F, 0x01, 0xF0, 0x3F, 0x0F,
0xF0, 0xFE, 0x0F, 0xC0, 0x80, 0x00, 0x7F, 0x00, 0xFF, 0xF1, 0xFF, 0xFF,
0xFD, 0xFF, 0xF8, 0x0F, 0xF4, 0x00, 0x00 };
const GFXglyph NotoSans_Bold18pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 9, 0, 0 }, // 0x20 ' '
{ 1, 6, 25, 10, 2, -24 }, // 0x21 '!'
{ 20, 13, 9, 17, 2, -24 }, // 0x22 '"'
{ 35, 21, 25, 23, 1, -24 }, // 0x23 '#'
{ 101, 17, 29, 20, 2, -26 }, // 0x24 '$'
{ 163, 30, 26, 32, 1, -25 }, // 0x25 '%'
{ 261, 25, 26, 26, 1, -25 }, // 0x26 '&'
{ 343, 5, 9, 9, 2, -24 }, // 0x27 '''
{ 349, 10, 31, 12, 1, -24 }, // 0x28 '('
{ 388, 10, 31, 12, 1, -24 }, // 0x29 ')'
{ 427, 17, 17, 19, 1, -26 }, // 0x2A '*'
{ 464, 17, 17, 20, 2, -20 }, // 0x2B '+'
{ 501, 7, 9, 10, 1, -3 }, // 0x2C ','
{ 509, 9, 5, 11, 1, -11 }, // 0x2D '-'
{ 515, 6, 5, 10, 2, -4 }, // 0x2E '.'
{ 519, 14, 25, 15, 0, -24 }, // 0x2F '/'
{ 563, 18, 26, 20, 1, -25 }, // 0x30 '0'
{ 622, 13, 25, 20, 2, -24 }, // 0x31 '1'
{ 663, 18, 26, 20, 1, -25 }, // 0x32 '2'
{ 722, 18, 26, 20, 1, -25 }, // 0x33 '3'
{ 781, 19, 25, 20, 1, -24 }, // 0x34 '4'
{ 841, 17, 25, 20, 2, -24 }, // 0x35 '5'
{ 895, 18, 25, 20, 1, -24 }, // 0x36 '6'
{ 952, 18, 25, 20, 1, -24 }, // 0x37 '7'
{ 1009, 18, 25, 20, 1, -24 }, // 0x38 '8'
{ 1066, 18, 25, 20, 1, -24 }, // 0x39 '9'
{ 1123, 6, 20, 10, 2, -19 }, // 0x3A ':'
{ 1138, 7, 25, 10, 1, -19 }, // 0x3B ';'
{ 1160, 17, 19, 20, 2, -21 }, // 0x3C '<'
{ 1201, 17, 11, 20, 2, -17 }, // 0x3D '='
{ 1225, 17, 19, 20, 2, -21 }, // 0x3E '>'
{ 1266, 16, 26, 17, 0, -25 }, // 0x3F '?'
{ 1318, 28, 28, 32, 2, -24 }, // 0x40 '@'
{ 1416, 24, 25, 24, 0, -24 }, // 0x41 'A'
{ 1491, 19, 25, 23, 3, -24 }, // 0x42 'B'
{ 1551, 20, 26, 23, 2, -25 }, // 0x43 'C'
{ 1616, 21, 25, 26, 3, -24 }, // 0x44 'D'
{ 1682, 15, 25, 20, 3, -24 }, // 0x45 'E'
{ 1729, 15, 25, 19, 3, -24 }, // 0x46 'F'
{ 1776, 21, 26, 26, 2, -25 }, // 0x47 'G'
{ 1845, 21, 25, 27, 3, -24 }, // 0x48 'H'
{ 1911, 12, 25, 14, 1, -24 }, // 0x49 'I'
{ 1949, 12, 32, 12, -3, -24 }, // 0x4A 'J'
{ 1997, 20, 25, 23, 3, -24 }, // 0x4B 'K'
{ 2060, 16, 25, 20, 3, -24 }, // 0x4C 'L'
{ 2110, 27, 25, 33, 3, -24 }, // 0x4D 'M'
{ 2195, 22, 25, 29, 3, -24 }, // 0x4E 'N'
{ 2264, 24, 26, 28, 2, -25 }, // 0x4F 'O'
{ 2342, 17, 25, 22, 3, -24 }, // 0x50 'P'
{ 2396, 24, 32, 28, 2, -25 }, // 0x51 'Q'
{ 2492, 20, 25, 23, 3, -24 }, // 0x52 'R'
{ 2555, 16, 26, 19, 2, -25 }, // 0x53 'S'
{ 2607, 19, 25, 20, 1, -24 }, // 0x54 'T'
{ 2667, 21, 25, 27, 3, -24 }, // 0x55 'U'
{ 2733, 23, 25, 23, 0, -24 }, // 0x56 'V'
{ 2805, 34, 25, 34, 0, -24 }, // 0x57 'W'
{ 2912, 23, 25, 24, 0, -24 }, // 0x58 'X'
{ 2984, 22, 25, 22, 0, -24 }, // 0x59 'Y'
{ 3053, 19, 25, 20, 1, -24 }, // 0x5A 'Z'
{ 3113, 9, 31, 12, 2, -24 }, // 0x5B '['
{ 3148, 14, 25, 15, 0, -24 }, // 0x5C '\'
{ 3192, 8, 31, 12, 1, -24 }, // 0x5D ']'
{ 3223, 18, 16, 20, 1, -24 }, // 0x5E '^'
{ 3259, 15, 3, 14, 0, 4 }, // 0x5F '_'
{ 3265, 10, 6, 13, 1, -26 }, // 0x60 '`'
{ 3273, 18, 20, 21, 1, -19 }, // 0x61 'a'
{ 3318, 18, 27, 22, 3, -26 }, // 0x62 'b'
{ 3379, 15, 20, 18, 2, -19 }, // 0x63 'c'
{ 3417, 18, 27, 22, 2, -26 }, // 0x64 'd'
{ 3478, 17, 20, 21, 2, -19 }, // 0x65 'e'
{ 3521, 14, 27, 14, 1, -26 }, // 0x66 'f'
{ 3569, 18, 28, 22, 2, -19 }, // 0x67 'g'
{ 3632, 17, 27, 23, 3, -26 }, // 0x68 'h'
{ 3690, 6, 27, 11, 2, -26 }, // 0x69 'i'
{ 3711, 10, 35, 11, -2, -26 }, // 0x6A 'j'
{ 3755, 19, 27, 22, 3, -26 }, // 0x6B 'k'
{ 3820, 5, 27, 11, 3, -26 }, // 0x6C 'l'
{ 3837, 29, 20, 34, 3, -19 }, // 0x6D 'm'
{ 3910, 17, 20, 23, 3, -19 }, // 0x6E 'n'
{ 3953, 18, 20, 22, 2, -19 }, // 0x6F 'o'
{ 3998, 18, 28, 22, 3, -19 }, // 0x70 'p'
{ 4061, 18, 28, 22, 2, -19 }, // 0x71 'q'
{ 4124, 12, 20, 16, 3, -19 }, // 0x72 'r'
{ 4154, 14, 20, 18, 2, -19 }, // 0x73 's'
{ 4189, 13, 23, 15, 1, -22 }, // 0x74 't'
{ 4227, 18, 19, 23, 2, -18 }, // 0x75 'u'
{ 4270, 20, 19, 20, 0, -18 }, // 0x76 'v'
{ 4318, 30, 19, 30, 0, -18 }, // 0x77 'w'
{ 4390, 20, 19, 20, 0, -18 }, // 0x78 'x'
{ 4438, 20, 27, 20, 0, -18 }, // 0x79 'y'
{ 4506, 15, 19, 17, 1, -18 }, // 0x7A 'z'
{ 4542, 11, 31, 14, 1, -24 }, // 0x7B '{'
{ 4585, 4, 35, 19, 8, -26 }, // 0x7C '|'
{ 4603, 12, 31, 14, 1, -24 }, // 0x7D '}'
{ 4650, 17, 6, 20, 2, -14 } }; // 0x7E '~'
const GFXfont NotoSans_Bold18pt7b PROGMEM = {
(uint8_t *)NotoSans_Bold18pt7bBitmaps,
(GFXglyph *)NotoSans_Bold18pt7bGlyphs,
0x20, 0x7E, 48 };
// Approx. 5335 bytes
#endif // NOTOSANSBOLD18PT7B_H
@@ -0,0 +1,801 @@
#ifndef NOTOSANSBOLD24PT7B_H
#define NOTOSANSBOLD24PT7B_H
const uint8_t NotoSans_Bold24pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x10,
0xFE, 0x3F, 0xFF, 0x1F, 0xFF, 0x0F, 0xDF, 0x87, 0xEF, 0xC3, 0xF7, 0xE1,
0xFB, 0xF0, 0xFD, 0xF8, 0x7E, 0xFC, 0x1F, 0x3E, 0x0F, 0x9F, 0x07, 0xCF,
0x83, 0xE7, 0xC1, 0xF0, 0x00, 0x3E, 0x0F, 0x80, 0x03, 0xE1, 0xF0, 0x00,
0x3E, 0x1F, 0x00, 0x03, 0xE1, 0xF0, 0x00, 0x7C, 0x1F, 0x00, 0x07, 0xC1,
0xF0, 0x00, 0x7C, 0x1E, 0x00, 0x07, 0xC3, 0xE0, 0x00, 0x7C, 0x3E, 0x00,
0x0F, 0x83, 0xE0, 0x3F, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF,
0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0x07, 0xC0,
0x01, 0xF0, 0x7C, 0x00, 0x1F, 0x0F, 0x80, 0x01, 0xF0, 0xF8, 0x00, 0x3E,
0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
0xEF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xE0, 0x7C, 0x1F, 0x00, 0x07,
0xC1, 0xF0, 0x00, 0x7C, 0x3E, 0x00, 0x07, 0xC3, 0xE0, 0x00, 0x7C, 0x3E,
0x00, 0x0F, 0x83, 0xE0, 0x00, 0xF8, 0x3E, 0x00, 0x0F, 0x87, 0xC0, 0x00,
0xF8, 0x7C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00,
0x01, 0xC0, 0x00, 0x3F, 0xFE, 0x01, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x1F,
0xFF, 0xFE, 0x7F, 0xFF, 0xF9, 0xFF, 0xF7, 0xF3, 0xFC, 0xE0, 0xE7, 0xF1,
0xC0, 0x0F, 0xE3, 0x80, 0x1F, 0xE7, 0x00, 0x3F, 0xEE, 0x00, 0x3F, 0xFC,
0x00, 0x7F, 0xFC, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xFF,
0x80, 0x1F, 0xFF, 0x80, 0x07, 0xFF, 0x80, 0x0F, 0xFF, 0x00, 0x1D, 0xFF,
0x00, 0x38, 0xFE, 0x00, 0x71, 0xFE, 0x00, 0xE3, 0xFF, 0x81, 0xCF, 0xFF,
0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x7F,
0xFF, 0xE0, 0x1F, 0xFE, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03,
0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x1F,
0x00, 0x0F, 0xF8, 0x00, 0x3F, 0x00, 0x1F, 0xFC, 0x00, 0x7E, 0x00, 0x3F,
0xFE, 0x00, 0x7E, 0x00, 0x7F, 0xFE, 0x00, 0xFC, 0x00, 0x7E, 0x3F, 0x00,
0xF8, 0x00, 0x7C, 0x3F, 0x01, 0xF8, 0x00, 0x7C, 0x1F, 0x01, 0xF0, 0x00,
0xFC, 0x1F, 0x03, 0xF0, 0x00, 0xFC, 0x1F, 0x03, 0xE0, 0x00, 0xFC, 0x1F,
0x07, 0xE0, 0x00, 0xFC, 0x1F, 0x0F, 0xC0, 0x00, 0xFC, 0x1F, 0x0F, 0xC0,
0x00, 0x7C, 0x1F, 0x1F, 0x83, 0xC0, 0x7C, 0x3F, 0x1F, 0x0F, 0xF0, 0x7E,
0x3F, 0x3F, 0x3F, 0xF8, 0x7F, 0xFE, 0x3E, 0x3F, 0xFC, 0x3F, 0xFE, 0x7E,
0x7F, 0xFE, 0x1F, 0xFC, 0x7C, 0x7E, 0x7E, 0x0F, 0xF8, 0xFC, 0xFC, 0x3E,
0x07, 0xF0, 0xF8, 0xFC, 0x3F, 0x00, 0x01, 0xF8, 0xFC, 0x3F, 0x00, 0x03,
0xF0, 0xFC, 0x3F, 0x00, 0x03, 0xE0, 0xFC, 0x3F, 0x00, 0x07, 0xE0, 0xFC,
0x3F, 0x00, 0x07, 0xC0, 0xFC, 0x3F, 0x00, 0x0F, 0xC0, 0xFC, 0x3F, 0x00,
0x0F, 0x80, 0xFC, 0x3F, 0x00, 0x1F, 0x80, 0x7C, 0x3E, 0x00, 0x1F, 0x00,
0x7E, 0x7E, 0x00, 0x3F, 0x00, 0x7F, 0xFE, 0x00, 0x7E, 0x00, 0x3F, 0xFC,
0x00, 0x7C, 0x00, 0x1F, 0xF8, 0x00, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x7F,
0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x01, 0xFF,
0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xBF, 0xE0, 0x00, 0x7F,
0x07, 0xF0, 0x00, 0x3F, 0x03, 0xF8, 0x00, 0x1F, 0x81, 0xFC, 0x00, 0x0F,
0xC0, 0xFE, 0x00, 0x07, 0xF0, 0xFE, 0x00, 0x03, 0xF8, 0xFF, 0x00, 0x00,
0xFE, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00,
0x07, 0xFF, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0xFF, 0x0F, 0xFF, 0x80, 0x7F,
0x0F, 0xFF, 0xE0, 0x3F, 0x8F, 0xFF, 0xF8, 0x3F, 0xC7, 0xF9, 0xFE, 0x1F,
0xC7, 0xF8, 0x7F, 0x8F, 0xE3, 0xFC, 0x1F, 0xEF, 0xE1, 0xFC, 0x07, 0xFF,
0xF0, 0xFE, 0x01, 0xFF, 0xF0, 0x7F, 0x00, 0x7F, 0xF8, 0x3F, 0xC0, 0x1F,
0xF8, 0x1F, 0xF0, 0x0F, 0xFC, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF,
0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF,
0xF1, 0xFF, 0x01, 0xFF, 0xE0, 0x7F, 0xC0, 0xFF, 0xFF, 0xF7, 0xEF, 0xDF,
0xBF, 0x7E, 0xFC, 0xF9, 0xF3, 0xE7, 0xC0, 0x01, 0xF8, 0x1F, 0x81, 0xF8,
0x0F, 0xC0, 0xFC, 0x0F, 0xC0, 0x7E, 0x07, 0xF0, 0x3F, 0x01, 0xF8, 0x1F,
0xC0, 0xFC, 0x07, 0xE0, 0x3F, 0x03, 0xF8, 0x1F, 0x80, 0xFC, 0x07, 0xE0,
0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07,
0xE0, 0x3F, 0x01, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xE0, 0x3F,
0x01, 0xF8, 0x0F, 0xE0, 0x3F, 0x01, 0xFC, 0x07, 0xE0, 0x1F, 0x80, 0xFC,
0x03, 0xF0, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x7E, 0x01, 0xF8, 0x0F, 0xE0,
0x3F, 0x01, 0xF8, 0x07, 0xE0, 0x3F, 0x01, 0xFC, 0x07, 0xE0, 0x3F, 0x01,
0xF8, 0x0F, 0xC0, 0x7F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F,
0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x07, 0xE0,
0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0xFE, 0x07, 0xE0, 0x3F, 0x03, 0xF0, 0x1F,
0x81, 0xF8, 0x0F, 0xC0, 0xFC, 0x07, 0xE0, 0xFE, 0x00, 0x00, 0x7E, 0x00,
0x00, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x07, 0xC0, 0x00,
0x0F, 0x80, 0x10, 0x1F, 0x00, 0xBC, 0x3E, 0x1E, 0x7F, 0xBD, 0xFE, 0xFF,
0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFE, 0x00, 0x1F,
0xE0, 0x00, 0x7F, 0xE0, 0x01, 0xF7, 0xC0, 0x07, 0xEF, 0xC0, 0x0F, 0xCF,
0xC0, 0x3F, 0x1F, 0xC0, 0xFE, 0x1F, 0x80, 0x78, 0x3E, 0x00, 0x30, 0x30,
0x00, 0x00, 0x7C, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x03, 0xE0,
0x00, 0x07, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x3E, 0x00,
0x00, 0x7C, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0x00, 0x00, 0x3E, 0x00, 0x00,
0x7C, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x03, 0xE0, 0x00, 0x07,
0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0xCF, 0xE3, 0xF8,
0xFC, 0x3F, 0x0F, 0xC7, 0xE1, 0xF8, 0x7E, 0x1F, 0x0F, 0xC0, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7C, 0xFE, 0xFF, 0xFF,
0xFF, 0xFE, 0xFE, 0x10, 0x00, 0x07, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x00,
0x07, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00,
0x3F, 0x00, 0x0F, 0xE0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x0F, 0xE0, 0x01,
0xF8, 0x00, 0x3F, 0x00, 0x0F, 0xE0, 0x01, 0xF8, 0x00, 0x7F, 0x00, 0x0F,
0xE0, 0x01, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x7F,
0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8,
0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xC0,
0x00, 0x01, 0xFE, 0x00, 0x0F, 0xFF, 0x00, 0x3F, 0xFF, 0x80, 0xFF, 0xFF,
0x83, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x1F, 0xE0, 0xFE, 0x3F, 0x80, 0xFE,
0x7F, 0x01, 0xFD, 0xFC, 0x03, 0xFB, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF,
0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0xFE,
0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xE0,
0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0xFE, 0x01,
0xFE, 0xFE, 0x03, 0xF9, 0xFC, 0x07, 0xF3, 0xFC, 0x1F, 0xE3, 0xFC, 0x7F,
0x87, 0xFF, 0xFF, 0x07, 0xFF, 0xFC, 0x07, 0xFF, 0xF0, 0x07, 0xFF, 0xC0,
0x07, 0xFE, 0x00, 0x00, 0x3F, 0x00, 0x7F, 0x00, 0xFF, 0x01, 0xFF, 0x07,
0xFF, 0x0F, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E,
0x7F, 0x38, 0x7F, 0x10, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00,
0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00,
0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00,
0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x01,
0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x7F, 0xFF, 0x83, 0xFF, 0xFF, 0x8F, 0xFF,
0xFF, 0x9F, 0xFF, 0xFF, 0x9F, 0xC0, 0xFF, 0x1E, 0x00, 0xFE, 0x18, 0x01,
0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F,
0xC0, 0x00, 0x7F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xF0,
0x00, 0x3F, 0xC0, 0x00, 0xFF, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xF0, 0x00,
0x3F, 0xC0, 0x00, 0xFF, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x3F,
0xC0, 0x00, 0xFF, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFC, 0x03, 0xFE, 0x00, 0x3F, 0xFF, 0x81, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF,
0xC7, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x8F, 0x00, 0xFF, 0x08, 0x00, 0xFE,
0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xC0,
0x00, 0x3F, 0x80, 0x01, 0xFE, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xC0, 0x07,
0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xC0, 0x00,
0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00,
0xFE, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xFE, 0x00, 0x1F, 0xEF, 0xC0, 0xFF,
0xDF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xC0,
0x7F, 0xFE, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x01, 0xFE,
0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x00, 0xFF,
0xE0, 0x00, 0x7F, 0xF0, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0xFC, 0x00, 0x3E,
0xFE, 0x00, 0x3F, 0x7F, 0x00, 0x3F, 0x3F, 0x80, 0x1F, 0x1F, 0xC0, 0x1F,
0x8F, 0xE0, 0x1F, 0x87, 0xF0, 0x0F, 0x83, 0xF8, 0x0F, 0xC1, 0xFC, 0x0F,
0xC0, 0xFE, 0x07, 0xC0, 0x7F, 0x07, 0xE0, 0x3F, 0x87, 0xE0, 0x1F, 0xC3,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F,
0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01,
0xFC, 0x00, 0x3F, 0xFF, 0xF0, 0x7F, 0xFF, 0xE0, 0xFF, 0xFF, 0xC1, 0xFF,
0xFF, 0x83, 0xFF, 0xFF, 0x07, 0xFF, 0xFE, 0x0F, 0xC0, 0x00, 0x1F, 0x80,
0x00, 0x3F, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00,
0x07, 0xF0, 0x00, 0x0F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8,
0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0x78, 0x7F, 0xF0, 0x00, 0x1F, 0xE0,
0x00, 0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00,
0x01, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF7, 0x00, 0x1F, 0xEF, 0xE1,
0xFF, 0xDF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0xFF, 0xFF,
0xC0, 0x7F, 0xFE, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0xFF, 0xF0, 0x07, 0xFF,
0xE0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0x07, 0xF8, 0x00,
0x1F, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x01, 0xF8, 0x00, 0x03,
0xF0, 0x00, 0x0F, 0xE1, 0xF8, 0x1F, 0x8F, 0xFC, 0x3F, 0x3F, 0xFC, 0x7E,
0xFF, 0xFC, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB, 0xFE, 0x07, 0xFF, 0xF8,
0x07, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00,
0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFD, 0xFC, 0x03, 0xFB, 0xFC, 0x0F,
0xF3, 0xFC, 0x7F, 0xC7, 0xFF, 0xFF, 0x87, 0xFF, 0xFE, 0x07, 0xFF, 0xF8,
0x07, 0xFF, 0xE0, 0x03, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC,
0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0x03, 0xF8,
0x00, 0x07, 0xF0, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0xE0,
0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0x80,
0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00,
0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xFC, 0x00,
0x03, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xF0, 0x00,
0x00, 0xFE, 0x00, 0x0F, 0xFF, 0x80, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0xC3,
0xFF, 0xFF, 0x8F, 0xF8, 0xFF, 0x9F, 0xC0, 0x7F, 0x3F, 0x80, 0xFE, 0x7E,
0x01, 0xFC, 0xFC, 0x03, 0xF9, 0xFC, 0x07, 0xF3, 0xFC, 0x1F, 0xC3, 0xFC,
0x7F, 0x83, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, 0x03, 0xFF, 0xE0, 0x03, 0xFF,
0x80, 0x1F, 0xFF, 0x80, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0xC7, 0xF8, 0x7F,
0xCF, 0xE0, 0x7F, 0xBF, 0x80, 0x3F, 0xFE, 0x00, 0x7F, 0xFC, 0x00, 0x7F,
0xF8, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xF0, 0x1F, 0xEF,
0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xE0, 0x0F,
0xFF, 0x00, 0x00, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F,
0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x7F, 0x81, 0xFE, 0x7F,
0x00, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0xFE,
0x00, 0x7F, 0x7E, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x00, 0xFF, 0x7F,
0x80, 0xFF, 0x7F, 0xC3, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF, 0xBF, 0x1F,
0xFF, 0xBF, 0x0F, 0xFF, 0x7F, 0x03, 0xFC, 0x7F, 0x00, 0x00, 0x7E, 0x00,
0x00, 0x7E, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xFC, 0x00,
0x03, 0xF8, 0x20, 0x1F, 0xF8, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0xE0, 0x1F,
0xFF, 0xC0, 0x1F, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7C, 0xFE, 0xFF, 0xFF,
0xFF, 0xFE, 0xFE, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x10, 0x1F,
0x0F, 0xE3, 0xFC, 0xFF, 0x3F, 0xCF, 0xE1, 0xF8, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xF3, 0xF8, 0xFE, 0x3F, 0x0F, 0xC3, 0xF1, 0xF8, 0x7E, 0x1F,
0x87, 0xC3, 0xF0, 0x00, 0x00, 0x06, 0x00, 0x00, 0x3C, 0x00, 0x01, 0xF8,
0x00, 0x0F, 0xF0, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x80, 0x1F, 0xFC, 0x00,
0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x07, 0xFC,
0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x0F, 0xFF,
0x00, 0x07, 0xFF, 0x80, 0x03, 0xFF, 0xE0, 0x00, 0xFF, 0xF0, 0x00, 0x7F,
0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x07, 0x80, 0x00, 0x03,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x03, 0xF0,
0x00, 0x07, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x0F, 0xFE, 0x00, 0x07, 0xFF,
0x00, 0x03, 0xFF, 0x80, 0x01, 0xFF, 0xC0, 0x00, 0xFF, 0xE0, 0x00, 0x3F,
0xF0, 0x00, 0x1F, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0xC0, 0x07, 0xFF,
0x00, 0x7F, 0xF8, 0x03, 0xFF, 0xC0, 0x3F, 0xFE, 0x01, 0xFF, 0xE0, 0x07,
0xFF, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0x80, 0x00, 0x3C, 0x00, 0x00, 0x60,
0x00, 0x00, 0x03, 0xFE, 0x00, 0xFF, 0xFE, 0x1F, 0xFF, 0xF9, 0xFF, 0xFF,
0xE7, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0xF0, 0x0F, 0xE6, 0x00, 0x7F, 0x00,
0x01, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x7F,
0x00, 0x07, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F,
0xF0, 0x00, 0x7F, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00,
0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xE0, 0x00, 0x3F, 0x80, 0x01, 0xFE, 0x00, 0x0F, 0xF0, 0x00,
0x7F, 0x80, 0x03, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0x10, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xC0,
0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xF0,
0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x03, 0xF8, 0x00, 0x01, 0xF8,
0x0F, 0xC0, 0x00, 0x03, 0xF0, 0x7E, 0x03, 0xFF, 0x07, 0xE3, 0xF0, 0x3F,
0xFF, 0x0F, 0x8F, 0x81, 0xFF, 0xFC, 0x3E, 0x3E, 0x0F, 0xFF, 0xF0, 0xFD,
0xF8, 0x7F, 0x07, 0xC1, 0xF7, 0xC3, 0xF8, 0x1F, 0x07, 0xDF, 0x0F, 0xC0,
0x7C, 0x1F, 0xFC, 0x3E, 0x01, 0xF0, 0x7F, 0xF0, 0xF8, 0x07, 0xC1, 0xFF,
0x87, 0xE0, 0x1F, 0x07, 0xFE, 0x1F, 0x80, 0xFC, 0x1F, 0xF8, 0x7E, 0x03,
0xF0, 0x7F, 0xE0, 0xF8, 0x0F, 0xC3, 0xEF, 0x83, 0xE0, 0x3F, 0x0F, 0xBF,
0x0F, 0xC1, 0xFC, 0x7E, 0x7C, 0x3F, 0xDF, 0xFB, 0xF1, 0xF0, 0x7F, 0xFF,
0xFF, 0x87, 0xC0, 0xFF, 0xE7, 0xFE, 0x1F, 0x81, 0xFF, 0x0F, 0xF0, 0x3F,
0x01, 0xF0, 0x0E, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00,
0x00, 0x03, 0xF8, 0x00, 0x01, 0x00, 0x0F, 0xF8, 0x00, 0x7C, 0x00, 0x1F,
0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF,
0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00,
0x0F, 0xF8, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00,
0x03, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xE0, 0x00,
0x00, 0xFF, 0xF8, 0x00, 0x00, 0xFE, 0xFC, 0x00, 0x00, 0x7F, 0x7F, 0x00,
0x00, 0x3F, 0x3F, 0x80, 0x00, 0x3F, 0x8F, 0xC0, 0x00, 0x1F, 0xC7, 0xF0,
0x00, 0x0F, 0xE3, 0xF8, 0x00, 0x0F, 0xE1, 0xFC, 0x00, 0x07, 0xF0, 0x7F,
0x00, 0x07, 0xF8, 0x3F, 0x80, 0x03, 0xF8, 0x1F, 0xC0, 0x01, 0xFC, 0x07,
0xF0, 0x01, 0xFE, 0x03, 0xF8, 0x00, 0xFE, 0x01, 0xFC, 0x00, 0x7F, 0xFF,
0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF,
0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFE, 0x07, 0xF0,
0x00, 0xFF, 0x07, 0xF8, 0x00, 0x3F, 0x83, 0xFC, 0x00, 0x1F, 0xE1, 0xFC,
0x00, 0x0F, 0xF1, 0xFE, 0x00, 0x03, 0xF8, 0xFF, 0x00, 0x01, 0xFE, 0x7F,
0x00, 0x00, 0xFF, 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0xFF, 0xF0, 0x00, 0x7F,
0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE7,
0xFF, 0xFF, 0xF3, 0xF8, 0x0F, 0xFD, 0xFC, 0x01, 0xFE, 0xFE, 0x00, 0xFF,
0x7F, 0x00, 0x3F, 0xBF, 0x80, 0x1F, 0xDF, 0xC0, 0x1F, 0xEF, 0xE0, 0x0F,
0xE7, 0xF0, 0x1F, 0xF3, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF,
0xE0, 0x7F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x9F, 0xC0, 0x7F, 0xEF, 0xE0,
0x0F, 0xF7, 0xF0, 0x03, 0xFF, 0xF8, 0x01, 0xFF, 0xFC, 0x00, 0xFF, 0xFE,
0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x1F, 0xEF,
0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xF8,
0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x3F,
0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0x87,
0xFF, 0xFF, 0xC3, 0xFF, 0x80, 0xF0, 0xFF, 0x80, 0x0C, 0x7F, 0xC0, 0x00,
0x1F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xF8, 0x00, 0x00,
0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00,
0x00, 0x7F, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0xFF,
0xC0, 0x0C, 0x3F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0,
0x1F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0x00, 0xFF, 0xF0,
0x00, 0x0F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xC0,
0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFE, 0x07, 0xFF, 0x8F, 0xE0,
0x0F, 0xFC, 0xFE, 0x00, 0x3F, 0xCF, 0xE0, 0x03, 0xFE, 0xFE, 0x00, 0x1F,
0xEF, 0xE0, 0x01, 0xFE, 0xFE, 0x00, 0x0F, 0xEF, 0xE0, 0x00, 0xFF, 0xFE,
0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00,
0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF,
0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x1F, 0xEF, 0xE0, 0x01, 0xFE, 0xFE, 0x00,
0x3F, 0xEF, 0xE0, 0x03, 0xFC, 0xFE, 0x00, 0xFF, 0xCF, 0xE0, 0x3F, 0xF8,
0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF,
0xFF, 0x80, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00,
0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFF, 0xFF, 0xEF, 0xFF,
0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xE0, 0x00, 0xFE,
0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x00, 0x0F,
0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03, 0xF8, 0x00,
0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x80, 0x07, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFC, 0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03,
0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x80, 0x07,
0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x0F,
0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC,
0x3F, 0xFF, 0xFF, 0x87, 0xFF, 0x00, 0xE1, 0xFF, 0x80, 0x04, 0x3F, 0xC0,
0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x0F,
0xF0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x1F,
0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF,
0x01, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xC0, 0x03,
0xFF, 0xF8, 0x00, 0x7F, 0x7F, 0x80, 0x0F, 0xEF, 0xF0, 0x01, 0xFD, 0xFF,
0x00, 0x3F, 0x9F, 0xF0, 0x07, 0xF1, 0xFF, 0xE7, 0xFE, 0x3F, 0xFF, 0xFF,
0xC3, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xE0, 0x0F,
0xFF, 0xE0, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07,
0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00,
0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF,
0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0,
0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07,
0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00,
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x1F,
0xFC, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07,
0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07,
0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07,
0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x0F, 0xF8, 0x7F,
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFC, 0x07,
0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01,
0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0,
0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0,
0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC,
0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F,
0x03, 0xFE, 0x1F, 0xFF, 0xFF, 0xBF, 0xFE, 0xFF, 0xF3, 0xFF, 0x8F, 0xFC,
0x3F, 0x80, 0xFE, 0x00, 0x1F, 0xFF, 0xC0, 0x07, 0xFB, 0xF8, 0x00, 0xFF,
0x7F, 0x00, 0x3F, 0xCF, 0xE0, 0x0F, 0xF1, 0xFC, 0x03, 0xFC, 0x3F, 0x80,
0xFF, 0x07, 0xF0, 0x1F, 0xE0, 0xFE, 0x07, 0xF8, 0x1F, 0xC1, 0xFE, 0x03,
0xF8, 0x7F, 0x80, 0x7F, 0x1F, 0xE0, 0x0F, 0xE3, 0xFC, 0x01, 0xFC, 0xFF,
0x00, 0x3F, 0xBF, 0xC0, 0x07, 0xF7, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F,
0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xF9, 0xFE,
0x01, 0xFE, 0x3F, 0xC0, 0x3F, 0x83, 0xFC, 0x07, 0xF0, 0x3F, 0xC0, 0xFE,
0x07, 0xF8, 0x1F, 0xC0, 0x7F, 0x83, 0xF8, 0x0F, 0xF0, 0x7F, 0x00, 0xFF,
0x0F, 0xE0, 0x0F, 0xF1, 0xFC, 0x01, 0xFE, 0x3F, 0x80, 0x1F, 0xE7, 0xF0,
0x01, 0xFE, 0xFE, 0x00, 0x3F, 0xDF, 0xC0, 0x03, 0xFC, 0xFE, 0x00, 0x07,
0xF0, 0x00, 0x3F, 0x80, 0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00,
0x03, 0xF8, 0x00, 0x1F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F,
0x80, 0x01, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00,
0x1F, 0xC0, 0x00, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xFC,
0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x1F, 0xC0, 0x00,
0xFE, 0x00, 0x07, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xFC, 0x00, 0x0F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xC0, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x03, 0xFF,
0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00,
0x7F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF,
0x00, 0x0F, 0xFF, 0xFD, 0xF0, 0x00, 0xFB, 0xFF, 0xDF, 0x80, 0x1F, 0xBF,
0xFD, 0xF8, 0x01, 0xFB, 0xFF, 0xCF, 0x80, 0x1F, 0x3F, 0xFC, 0xFC, 0x03,
0xF3, 0xFF, 0xCF, 0xC0, 0x3F, 0x3F, 0xFC, 0xFC, 0x03, 0xE3, 0xFF, 0xE7,
0xE0, 0x7E, 0x7F, 0xFE, 0x7E, 0x07, 0xE7, 0xFF, 0xE7, 0xE0, 0x7C, 0x7F,
0xFE, 0x3E, 0x0F, 0xC7, 0xFF, 0xE3, 0xF0, 0xFC, 0x7F, 0xFE, 0x3F, 0x0F,
0x87, 0xFF, 0xE1, 0xF1, 0xF8, 0x7F, 0xFE, 0x1F, 0x9F, 0x87, 0xFF, 0xE1,
0xF9, 0xF0, 0x7F, 0xFE, 0x1F, 0x9F, 0x07, 0xFF, 0xE0, 0xFF, 0xF0, 0x7F,
0xFE, 0x0F, 0xFE, 0x07, 0xFF, 0xE0, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, 0xFE,
0x07, 0xFF, 0xE0, 0x7F, 0xC0, 0x7F, 0xFE, 0x07, 0xFC, 0x07, 0xFF, 0xE0,
0x3F, 0xC0, 0x7F, 0xFE, 0x03, 0xF8, 0x07, 0xFF, 0xE0, 0x3F, 0x80, 0x7F,
0xFF, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0xFF,
0xF8, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF,
0x80, 0x0F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0xFF, 0xF7, 0xF0,
0x03, 0xFF, 0xDF, 0xE0, 0x0F, 0xFF, 0x3F, 0xC0, 0x3F, 0xFC, 0x7F, 0x00,
0xFF, 0xF1, 0xFE, 0x03, 0xFF, 0xC3, 0xF8, 0x0F, 0xFF, 0x0F, 0xF0, 0x3F,
0xFE, 0x1F, 0xE0, 0xFF, 0xF8, 0x7F, 0x83, 0xFF, 0xE0, 0xFF, 0x0F, 0xFF,
0x81, 0xFC, 0x3F, 0xFE, 0x07, 0xF8, 0xFF, 0xF8, 0x0F, 0xE3, 0xFF, 0xE0,
0x3F, 0xCF, 0xFF, 0x80, 0x7F, 0xBF, 0xFE, 0x01, 0xFE, 0xFF, 0xF8, 0x03,
0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFE, 0x00, 0x3F,
0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
0xFE, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xF8, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xE0,
0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, 0x3F, 0xF0, 0x1F, 0xF8,
0x3F, 0xC0, 0x07, 0xFC, 0x7F, 0x80, 0x03, 0xFC, 0x7F, 0x80, 0x03, 0xFC,
0xFF, 0x00, 0x01, 0xFE, 0xFF, 0x00, 0x01, 0xFE, 0xFF, 0x00, 0x00, 0xFE,
0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFE,
0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF,
0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFE,
0xFF, 0x00, 0x01, 0xFE, 0xFF, 0x00, 0x01, 0xFE, 0x7F, 0x80, 0x01, 0xFC,
0x7F, 0x80, 0x03, 0xFC, 0x7F, 0xC0, 0x07, 0xFC, 0x3F, 0xE0, 0x0F, 0xF8,
0x1F, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xE0,
0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFC, 0x00,
0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x8F,
0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xBF, 0x83, 0xFF, 0x7F, 0x01, 0xFF, 0xFE,
0x01, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xE0,
0x0F, 0xFF, 0xC0, 0x3F, 0xFF, 0x80, 0x7F, 0xFF, 0x03, 0xFE, 0xFF, 0xFF,
0xFD, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x0F, 0xFF, 0xFC,
0x1F, 0xFF, 0xC0, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01,
0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F,
0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC,
0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x03, 0xFF,
0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF,
0xFF, 0xF0, 0x3F, 0xF0, 0x1F, 0xF8, 0x3F, 0xC0, 0x07, 0xFC, 0x7F, 0x80,
0x03, 0xFC, 0x7F, 0x80, 0x03, 0xFC, 0xFF, 0x00, 0x01, 0xFE, 0xFF, 0x00,
0x01, 0xFE, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00,
0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00,
0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x00,
0x00, 0xFE, 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x01, 0xFE, 0xFF, 0x00,
0x01, 0xFE, 0x7F, 0x80, 0x01, 0xFE, 0x7F, 0x80, 0x03, 0xFC, 0x7F, 0xC0,
0x07, 0xFC, 0x3F, 0xE0, 0x0F, 0xF8, 0x1F, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF,
0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xFF,
0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00,
0x7F, 0xC0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00,
0x1F, 0xF0, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00,
0x03, 0xFE, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xC0,
0x7F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF8, 0x3F, 0x81,
0xFF, 0x87, 0xF0, 0x0F, 0xF0, 0xFE, 0x00, 0xFE, 0x1F, 0xC0, 0x1F, 0xC3,
0xF8, 0x03, 0xF8, 0x7F, 0x00, 0x7F, 0x0F, 0xE0, 0x0F, 0xE1, 0xFC, 0x03,
0xFC, 0x3F, 0x80, 0xFF, 0x07, 0xF0, 0xFF, 0xE0, 0xFF, 0xFF, 0xF8, 0x1F,
0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC,
0x01, 0xFC, 0x3F, 0xC0, 0x3F, 0x83, 0xF8, 0x07, 0xF0, 0x3F, 0x80, 0xFE,
0x07, 0xF8, 0x1F, 0xC0, 0x7F, 0x03, 0xF8, 0x0F, 0xF0, 0x7F, 0x00, 0xFF,
0x0F, 0xE0, 0x1F, 0xE1, 0xFC, 0x01, 0xFE, 0x3F, 0x80, 0x1F, 0xE7, 0xF0,
0x03, 0xFC, 0xFE, 0x00, 0x3F, 0xDF, 0xC0, 0x07, 0xFC, 0x00, 0xFF, 0x80,
0x1F, 0xFF, 0xC0, 0xFF, 0xFF, 0xC7, 0xFF, 0xFE, 0x3F, 0xFF, 0xF9, 0xFF,
0xFF, 0xE7, 0xF8, 0x0F, 0x1F, 0xC0, 0x04, 0x7F, 0x00, 0x01, 0xFC, 0x00,
0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0xC0, 0x01, 0xFF, 0xC0, 0x03,
0xFF, 0xC0, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x1F, 0xFF, 0x80, 0x1F,
0xFF, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x3F,
0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xFC, 0x00, 0x1F, 0xFC,
0x00, 0xFF, 0xFF, 0x9F, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x3F, 0xFF,
0xF8, 0xFF, 0xFF, 0xC0, 0x7F, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFC, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00,
0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0,
0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07,
0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00,
0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF,
0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00,
0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF,
0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0,
0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F,
0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE,
0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFE, 0xFF, 0x00, 0x0F, 0xEF, 0xF0, 0x00,
0xFE, 0x7F, 0x80, 0x1F, 0xE7, 0xFC, 0x03, 0xFC, 0x7F, 0xFF, 0xFF, 0xC3,
0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xE0, 0x07, 0xFF,
0xFC, 0x00, 0x1F, 0xFF, 0x00, 0xFE, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x03,
0xF9, 0xFC, 0x00, 0x07, 0xF3, 0xF8, 0x00, 0x1F, 0xE7, 0xF0, 0x00, 0x3F,
0x87, 0xF0, 0x00, 0x7F, 0x0F, 0xE0, 0x01, 0xFE, 0x1F, 0xC0, 0x03, 0xF8,
0x1F, 0xC0, 0x07, 0xF0, 0x3F, 0x80, 0x1F, 0xC0, 0x7F, 0x00, 0x3F, 0x80,
0x7F, 0x00, 0x7F, 0x00, 0xFE, 0x00, 0xFC, 0x01, 0xFC, 0x03, 0xF8, 0x01,
0xFC, 0x07, 0xF0, 0x03, 0xF8, 0x0F, 0xC0, 0x07, 0xF0, 0x3F, 0x80, 0x07,
0xF0, 0x7F, 0x00, 0x0F, 0xE0, 0xFC, 0x00, 0x1F, 0xC3, 0xF8, 0x00, 0x1F,
0xC7, 0xF0, 0x00, 0x3F, 0x8F, 0xC0, 0x00, 0x7F, 0x3F, 0x80, 0x00, 0x7E,
0x7F, 0x00, 0x00, 0xFE, 0xFC, 0x00, 0x01, 0xFD, 0xF8, 0x00, 0x01, 0xFF,
0xF0, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x07, 0xFF,
0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0,
0x00, 0x00, 0x3F, 0xC0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03, 0xFF, 0xF0,
0x00, 0xFE, 0x00, 0x1F, 0xDF, 0x80, 0x07, 0xF8, 0x00, 0xFE, 0xFE, 0x00,
0x3F, 0xC0, 0x07, 0xF7, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0x3F, 0x80, 0x1F,
0xF0, 0x03, 0xF8, 0xFC, 0x00, 0xFF, 0xC0, 0x1F, 0xC7, 0xF0, 0x07, 0xFE,
0x00, 0xFE, 0x3F, 0x80, 0x7F, 0xF0, 0x07, 0xE1, 0xFC, 0x03, 0xFF, 0x80,
0x7F, 0x07, 0xE0, 0x1F, 0x7E, 0x03, 0xF8, 0x3F, 0x81, 0xFB, 0xF0, 0x1F,
0xC1, 0xFC, 0x0F, 0xDF, 0x80, 0xFC, 0x0F, 0xE0, 0x7E, 0x7C, 0x0F, 0xE0,
0x3F, 0x03, 0xF3, 0xF0, 0x7F, 0x01, 0xFC, 0x3F, 0x1F, 0x83, 0xF8, 0x0F,
0xE1, 0xF8, 0xFC, 0x1F, 0x80, 0x7F, 0x0F, 0xC3, 0xF1, 0xFC, 0x01, 0xF8,
0x7E, 0x1F, 0x8F, 0xE0, 0x0F, 0xC7, 0xE0, 0xFC, 0x7F, 0x00, 0x7F, 0x3F,
0x07, 0xE3, 0xF0, 0x03, 0xF9, 0xF8, 0x1F, 0x1F, 0x80, 0x0F, 0xCF, 0xC0,
0xFD, 0xFC, 0x00, 0x7E, 0x7C, 0x07, 0xEF, 0xE0, 0x03, 0xF7, 0xE0, 0x3F,
0x7E, 0x00, 0x1F, 0xFF, 0x00, 0xFB, 0xF0, 0x00, 0x7F, 0xF8, 0x07, 0xDF,
0x80, 0x03, 0xFF, 0x80, 0x3F, 0xFC, 0x00, 0x1F, 0xFC, 0x01, 0xFF, 0xC0,
0x00, 0xFF, 0xE0, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00,
0x1F, 0xF0, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0x07,
0xFC, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x03, 0xFE, 0xFF, 0x00, 0x07,
0xF8, 0xFF, 0x00, 0x1F, 0xE0, 0xFF, 0x00, 0x3F, 0xC1, 0xFE, 0x00, 0xFF,
0x01, 0xFE, 0x03, 0xFC, 0x01, 0xFC, 0x07, 0xF8, 0x03, 0xFC, 0x1F, 0xE0,
0x03, 0xFC, 0x3F, 0x80, 0x03, 0xF8, 0xFF, 0x00, 0x07, 0xF9, 0xFC, 0x00,
0x07, 0xF7, 0xF8, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0x80, 0x00,
0x0F, 0xFF, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00,
0x3F, 0xE0, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x07,
0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x3F, 0xBF, 0xC0, 0x00, 0xFF,
0x3F, 0x80, 0x03, 0xFC, 0x7F, 0x80, 0x07, 0xF0, 0x7F, 0x80, 0x1F, 0xE0,
0xFF, 0x00, 0x7F, 0x80, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x03, 0xFC, 0x01,
0xFE, 0x0F, 0xF0, 0x01, 0xFE, 0x1F, 0xE0, 0x03, 0xFE, 0x7F, 0x80, 0x03,
0xFD, 0xFE, 0x00, 0x03, 0xFC, 0xFF, 0x00, 0x03, 0xFB, 0xF8, 0x00, 0x3F,
0xDF, 0xE0, 0x01, 0xFC, 0x7F, 0x00, 0x1F, 0xE3, 0xFC, 0x00, 0xFE, 0x0F,
0xE0, 0x0F, 0xF0, 0x7F, 0x80, 0x7F, 0x01, 0xFC, 0x07, 0xF8, 0x0F, 0xF0,
0x3F, 0x80, 0x3F, 0x83, 0xFC, 0x01, 0xFE, 0x1F, 0xC0, 0x07, 0xF1, 0xFC,
0x00, 0x3F, 0xCF, 0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x03, 0xFF, 0xF0, 0x00,
0x1F, 0xFF, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x0F,
0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x0F, 0xE0,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x01,
0xFC, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8,
0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
0xBF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF,
0xFB, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x01,
0xFC, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00,
0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x7F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0x80, 0x00, 0x3F, 0xC0, 0x00,
0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, 0x00,
0x0F, 0xE0, 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00,
0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E,
0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F,
0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1,
0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFE, 0x00, 0x0F, 0xC0, 0x01, 0xFC, 0x00,
0x3F, 0x80, 0x03, 0xF0, 0x00, 0x7F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00,
0x1F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xF0, 0x00, 0x7E, 0x00,
0x0F, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF8, 0x00, 0x3F, 0x00,
0x07, 0xE0, 0x00, 0xFE, 0x00, 0x0F, 0xC0, 0x01, 0xFC, 0x00, 0x3F, 0x80,
0x03, 0xF0, 0x00, 0x7F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0xC0,
0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xE0,
0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xC1, 0xF8,
0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F,
0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07,
0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0,
0xFC, 0x1F, 0x83, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
0x3C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0xC0, 0x00,
0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00,
0x03, 0xE7, 0xC0, 0x01, 0xF3, 0xE0, 0x01, 0xF8, 0xF8, 0x00, 0xF8, 0x7C,
0x00, 0xFC, 0x1F, 0x00, 0x7C, 0x0F, 0x80, 0x3E, 0x03, 0xE0, 0x3E, 0x01,
0xF0, 0x1F, 0x00, 0x7C, 0x1F, 0x00, 0x3E, 0x0F, 0x80, 0x0F, 0x8F, 0xC0,
0x07, 0xC7, 0xC0, 0x01, 0xF7, 0xE0, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0x80, 0xFE,
0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x01, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x7F,
0xFF, 0xE0, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xC1, 0xF0, 0x7F, 0x83, 0x00,
0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x03, 0xFF,
0xF8, 0x7F, 0xFF, 0xF1, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xDF, 0xF8, 0x3F,
0xFF, 0x80, 0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x07, 0xFF,
0xF0, 0x0F, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBF,
0xFF, 0x3F, 0x3F, 0xFC, 0x7E, 0x1F, 0xF0, 0x7C, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFE, 0x1F, 0xC0, 0xFE, 0x3F, 0xF0, 0xFE, 0xFF, 0xF8, 0xFE,
0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0x81, 0xFE, 0xFF,
0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF,
0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF,
0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF,
0x80, 0xFF, 0xFF, 0xE3, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0xFE,
0xFF, 0xF8, 0xFE, 0x7F, 0xF0, 0xFC, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x1F,
0xFF, 0xC1, 0xFF, 0xFE, 0x3F, 0xFF, 0xE1, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1,
0xFF, 0x00, 0x8F, 0xF0, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x3F, 0xC0,
0x01, 0xFE, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x1F,
0xE0, 0x00, 0xFF, 0x00, 0x03, 0xF8, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0x00,
0x23, 0xFE, 0x1F, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xC1, 0xFF, 0xFE, 0x07,
0xFF, 0xF0, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x01,
0xFC, 0x7F, 0x07, 0xFE, 0x7F, 0x0F, 0xFF, 0x7F, 0x1F, 0xFF, 0xFF, 0x3F,
0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0xC1, 0xFF, 0x7F, 0x80, 0xFF, 0x7F,
0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xFE,
0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFF, 0x00, 0x3F, 0xFF,
0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x80, 0xFF, 0x7F,
0xE3, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x1F, 0xFF, 0xBF, 0x0F,
0xFF, 0x3F, 0x03, 0xFC, 0x1F, 0x00, 0xFF, 0x80, 0x03, 0xFF, 0xE0, 0x0F,
0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x3F, 0xC1, 0xFE, 0x7F,
0x80, 0xFE, 0x7F, 0x00, 0x7E, 0x7F, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F,
0x00, 0x00, 0x7F, 0x80, 0x02, 0x3F, 0xE0, 0x1C, 0x3F, 0xFF, 0xFC, 0x1F,
0xFF, 0xFC, 0x0F, 0xFF, 0xFC, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xF0, 0x00,
0x7F, 0x80, 0x3F, 0xFC, 0x0F, 0xFF, 0x83, 0xFF, 0xE0, 0xFF, 0xFC, 0x1F,
0xFF, 0x83, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x7F,
0xFE, 0x3F, 0xFF, 0xCF, 0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xFF,
0xFC, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE,
0x00, 0x1F, 0xC0, 0x03, 0xF8, 0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC,
0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0x1F, 0xC0, 0x03, 0xF8,
0x00, 0x7F, 0x00, 0x0F, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x80, 0x07, 0xF0,
0x00, 0x01, 0xFC, 0x3F, 0x07, 0xFE, 0x3F, 0x0F, 0xFF, 0xBF, 0x1F, 0xFF,
0xBF, 0x3F, 0xFF, 0xFF, 0x3F, 0xF7, 0xFF, 0x7F, 0x80, 0xFF, 0x7F, 0x80,
0x7F, 0x7F, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFF, 0x00,
0x3F, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x80,
0xFF, 0x7F, 0xC1, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x1F, 0xFF,
0xFF, 0x0F, 0xFF, 0x7F, 0x03, 0xFC, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x30, 0x01, 0xFF, 0x3F, 0x07,
0xFE, 0x3F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF,
0xF0, 0x0F, 0xFF, 0x80, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFE, 0x1F,
0xE0, 0xFE, 0x7F, 0xF8, 0xFE, 0xFF, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF,
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xE0, 0x1F, 0x81, 0xFE, 0x0F, 0xF0, 0x7F,
0x81, 0xFC, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x0F, 0xF0,
0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F,
0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE,
0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1,
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF4, 0xFF,
0xBF, 0xFD, 0xFF, 0xCF, 0xFE, 0x7F, 0xE3, 0xFC, 0x00, 0xFE, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00,
0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x3F, 0xFF, 0xC0, 0x1F, 0xCF, 0xE0,
0x1F, 0xE7, 0xF0, 0x1F, 0xE3, 0xF8, 0x1F, 0xE1, 0xFC, 0x1F, 0xE0, 0xFE,
0x1F, 0xE0, 0x7F, 0x1F, 0xE0, 0x3F, 0x9F, 0xE0, 0x1F, 0xDF, 0xE0, 0x0F,
0xCF, 0xE0, 0x07, 0xEF, 0xE0, 0x03, 0xFF, 0xF8, 0x01, 0xFF, 0xFE, 0x00,
0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xC0, 0x3F, 0xEF, 0xF0, 0x1F, 0xC3, 0xFC,
0x0F, 0xE0, 0xFF, 0x07, 0xF0, 0x7F, 0x83, 0xF8, 0x1F, 0xE1, 0xFC, 0x07,
0xF8, 0xFE, 0x01, 0xFE, 0x7F, 0x00, 0xFF, 0x3F, 0x80, 0x3F, 0xDF, 0xC0,
0x0F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFC, 0x1F, 0xE0, 0x1F, 0xE1, 0xF8, 0xFF, 0xF0, 0xFF, 0xF3,
0xFB, 0xFF, 0xF3, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xEF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xE0, 0x7F,
0xFF, 0xC0, 0x7F, 0xC0, 0x7F, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFE, 0x01,
0xFE, 0x01, 0xFF, 0xFC, 0x03, 0xFC, 0x03, 0xFF, 0xF8, 0x07, 0xF8, 0x07,
0xFF, 0xF0, 0x0F, 0xF0, 0x0F, 0xFF, 0xE0, 0x1F, 0xE0, 0x1F, 0xFF, 0xC0,
0x3F, 0xC0, 0x3F, 0xFF, 0x80, 0x7F, 0x80, 0x7F, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0xFE, 0x01, 0xFE, 0x01, 0xFF, 0xFC, 0x03, 0xFC, 0x03, 0xFF, 0xF8,
0x07, 0xF8, 0x07, 0xFF, 0xF0, 0x0F, 0xF0, 0x0F, 0xFF, 0xE0, 0x1F, 0xE0,
0x1F, 0xFF, 0xC0, 0x3F, 0xC0, 0x3F, 0xFF, 0x80, 0x7F, 0x80, 0x7F, 0xFF,
0x00, 0xFF, 0x00, 0xFF, 0xFE, 0x01, 0xFE, 0x01, 0xFC, 0xFC, 0x1F, 0xE0,
0xFC, 0x7F, 0xF8, 0xFE, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F,
0xFF, 0x00, 0x7F, 0x00, 0xFF, 0x80, 0x01, 0xFF, 0xF0, 0x03, 0xFF, 0xFE,
0x03, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xE1, 0xFF, 0x1F, 0xF1, 0xFE, 0x03,
0xFC, 0xFF, 0x00, 0xFE, 0x7F, 0x00, 0x7F, 0xBF, 0x80, 0x3F, 0xFF, 0xC0,
0x0F, 0xFF, 0xE0, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8,
0x00, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xBF, 0x80, 0x3F, 0xDF,
0xC0, 0x1F, 0xCF, 0xF0, 0x1F, 0xE3, 0xFC, 0x1F, 0xF0, 0xFF, 0xFF, 0xF0,
0x7F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0xE0,
0x00, 0xFC, 0x1F, 0xC0, 0xFE, 0x7F, 0xF0, 0xFE, 0xFF, 0xF8, 0xFE, 0xFF,
0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0x81, 0xFF, 0xFF, 0x80,
0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0x81,
0xFF, 0xFF, 0xE3, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0xFE, 0xFF,
0xF8, 0xFE, 0x7F, 0xF0, 0xFE, 0x3F, 0xE0, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x01, 0xFC, 0x3F, 0x07, 0xFE, 0x3F, 0x0F, 0xFF,
0x3F, 0x1F, 0xFF, 0xBF, 0x3F, 0xFF, 0xFF, 0x3F, 0xE7, 0xFF, 0x7F, 0x80,
0xFF, 0x7F, 0x80, 0x7F, 0x7F, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x00,
0x7F, 0xFF, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00,
0x3F, 0xFF, 0x00, 0x3F, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x00,
0x7F, 0x7F, 0x80, 0xFF, 0x7F, 0xE1, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF,
0xFF, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0x7F, 0x03, 0xFC, 0x7F, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xFC, 0x0F, 0xFE, 0x1F, 0xFF,
0x1F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
0xFF, 0x80, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8,
0x03, 0xFC, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F,
0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0xFF, 0x00,
0x7F, 0x80, 0x00, 0x03, 0xFE, 0x01, 0xFF, 0xFE, 0x3F, 0xFF, 0xE7, 0xFF,
0xFE, 0x7F, 0xFF, 0xCF, 0xF0, 0x3C, 0xFE, 0x00, 0x4F, 0xE0, 0x00, 0xFF,
0x00, 0x0F, 0xFC, 0x00, 0x7F, 0xF8, 0x03, 0xFF, 0xE0, 0x3F, 0xFF, 0x80,
0xFF, 0xFC, 0x03, 0xFF, 0xE0, 0x0F, 0xFE, 0x00, 0x1F, 0xE0, 0x00, 0xFF,
0x00, 0x07, 0xF8, 0x00, 0x7F, 0xF0, 0x0F, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF,
0xEF, 0xFF, 0xFC, 0xFF, 0xFF, 0x83, 0xFF, 0xE0, 0x03, 0xC0, 0x01, 0xF0,
0x00, 0x7C, 0x00, 0x1F, 0x00, 0x0F, 0xC0, 0x03, 0xFF, 0xF3, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0x00, 0x1F,
0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0,
0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x07, 0xF0, 0x01, 0xFC, 0x00,
0x7F, 0x00, 0x1F, 0xE0, 0x03, 0xFC, 0x30, 0xFF, 0xFC, 0x3F, 0xFF, 0x07,
0xFF, 0xC0, 0xFF, 0xF0, 0x1F, 0xF8, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F,
0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F,
0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F,
0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F,
0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x01, 0xFF, 0x7F, 0xC7, 0xFF, 0x7F, 0xFF, 0xFF,
0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xBF, 0x1F, 0xFF, 0x3F, 0x07, 0xFC, 0x3F,
0xFE, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xF9, 0xFC, 0x00, 0x7F, 0x3F, 0x80,
0x1F, 0xE3, 0xF8, 0x03, 0xF8, 0x7F, 0x00, 0x7F, 0x0F, 0xE0, 0x1F, 0xE0,
0xFE, 0x03, 0xF8, 0x1F, 0xC0, 0x7F, 0x03, 0xF8, 0x1F, 0xC0, 0x3F, 0x83,
0xF8, 0x07, 0xF0, 0x7F, 0x00, 0x7E, 0x1F, 0xC0, 0x0F, 0xE3, 0xF8, 0x01,
0xFC, 0x7E, 0x00, 0x1F, 0x8F, 0xC0, 0x03, 0xFB, 0xF8, 0x00, 0x3F, 0x7E,
0x00, 0x07, 0xEF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFE, 0x00, 0x01,
0xFF, 0xC0, 0x00, 0x3F, 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0,
0x00, 0x07, 0xF0, 0x00, 0xFE, 0x00, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0xFF,
0x00, 0x7E, 0x7F, 0x00, 0xFF, 0x80, 0xFE, 0x7F, 0x01, 0xFF, 0x80, 0xFE,
0x3F, 0x81, 0xFF, 0x80, 0xFE, 0x3F, 0x81, 0xFF, 0x80, 0xFC, 0x3F, 0x81,
0xFF, 0xC1, 0xFC, 0x1F, 0x83, 0xF7, 0xC1, 0xFC, 0x1F, 0xC3, 0xE7, 0xC1,
0xF8, 0x1F, 0xC3, 0xE7, 0xC3, 0xF8, 0x1F, 0xC3, 0xE7, 0xC3, 0xF8, 0x0F,
0xC7, 0xE3, 0xE3, 0xF8, 0x0F, 0xE7, 0xC3, 0xE3, 0xF0, 0x0F, 0xE7, 0xC3,
0xE7, 0xF0, 0x0F, 0xE7, 0xC3, 0xE7, 0xF0, 0x07, 0xE7, 0xC3, 0xF7, 0xE0,
0x07, 0xEF, 0x81, 0xF7, 0xE0, 0x07, 0xEF, 0x81, 0xF7, 0xE0, 0x03, 0xFF,
0x81, 0xF7, 0xE0, 0x03, 0xFF, 0x81, 0xFF, 0xC0, 0x03, 0xFF, 0x80, 0xFF,
0xC0, 0x03, 0xFF, 0x00, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x01,
0xFF, 0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x00, 0xFE, 0x00,
0x7F, 0x80, 0x7F, 0x80, 0x1F, 0xEF, 0xF0, 0x07, 0xF8, 0xFF, 0x01, 0xFE,
0x0F, 0xF0, 0x3F, 0x81, 0xFE, 0x0F, 0xF0, 0x1F, 0xE3, 0xFC, 0x01, 0xFC,
0x7F, 0x00, 0x3F, 0xDF, 0xE0, 0x03, 0xFF, 0xF8, 0x00, 0x3F, 0xFE, 0x00,
0x07, 0xFF, 0xC0, 0x00, 0x7F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0xFF,
0xC0, 0x00, 0x3F, 0xF8, 0x00, 0x0F, 0xFF, 0x80, 0x01, 0xFF, 0xF8, 0x00,
0x7F, 0x7F, 0x00, 0x1F, 0xEF, 0xF0, 0x03, 0xF8, 0xFF, 0x00, 0xFF, 0x0F,
0xE0, 0x3F, 0xC1, 0xFE, 0x07, 0xF0, 0x1F, 0xE1, 0xFE, 0x03, 0xFC, 0x7F,
0x80, 0x3F, 0xDF, 0xE0, 0x03, 0xFC, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03,
0xF9, 0xFC, 0x00, 0x7F, 0x3F, 0xC0, 0x1F, 0xE3, 0xF8, 0x03, 0xF8, 0x7F,
0x00, 0x7F, 0x0F, 0xE0, 0x1F, 0xE0, 0xFE, 0x03, 0xF8, 0x1F, 0xC0, 0x7F,
0x01, 0xFC, 0x0F, 0xC0, 0x3F, 0x83, 0xF8, 0x07, 0xF0, 0x7F, 0x00, 0x7E,
0x0F, 0xC0, 0x0F, 0xE3, 0xF8, 0x00, 0xFC, 0x7F, 0x00, 0x1F, 0x8F, 0xC0,
0x03, 0xFB, 0xF8, 0x00, 0x3F, 0x7E, 0x00, 0x07, 0xEF, 0xC0, 0x00, 0x7F,
0xF8, 0x00, 0x0F, 0xFE, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x1F, 0xF8, 0x00,
0x03, 0xFE, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x1F, 0xC0, 0x00, 0x07, 0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00,
0x3F, 0x80, 0x01, 0x3F, 0xF0, 0x00, 0x3F, 0xFC, 0x00, 0x07, 0xFF, 0x80,
0x00, 0xFF, 0xE0, 0x00, 0x1F, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x7F,
0xFF, 0xF3, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF,
0x3F, 0xFF, 0xF8, 0x00, 0x3F, 0x80, 0x03, 0xF8, 0x00, 0x3F, 0xC0, 0x03,
0xFC, 0x00, 0x1F, 0xC0, 0x01, 0xFC, 0x00, 0x1F, 0xE0, 0x00, 0xFE, 0x00,
0x0F, 0xE0, 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0x00, 0x07, 0xF0,
0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0x00, 0xFF,
0x01, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xF0, 0x03, 0xF0,
0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0,
0x03, 0xF0, 0x07, 0xF0, 0x07, 0xF0, 0x0F, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0,
0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xC0, 0xFF, 0xE0, 0x0F, 0xE0, 0x07, 0xF0,
0x07, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0,
0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF0, 0x03, 0xF8, 0x03, 0xFF, 0x03, 0xFF,
0x03, 0xFF, 0x01, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
0x80, 0x00, 0xFE, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xC0,
0x1F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0,
0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xE0, 0x0F, 0xF0,
0x07, 0xFF, 0x03, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0x07, 0xFF,
0x0F, 0xF0, 0x0F, 0xE0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0,
0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x0F, 0xC0, 0x1F, 0xC0,
0xFF, 0xC0, 0xFF, 0xC0, 0xFF, 0x80, 0xFF, 0x00, 0xFE, 0x00, 0x3F, 0xE0,
0x02, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF8, 0x07, 0xFF, 0xA0, 0x03, 0xFE, 0x00 };
const GFXglyph NotoSans_Bold24pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 12, 0, 0 }, // 0x20 ' '
{ 1, 8, 35, 13, 3, -33 }, // 0x21 '!'
{ 36, 17, 13, 23, 3, -33 }, // 0x22 '"'
{ 64, 28, 34, 30, 1, -33 }, // 0x23 '#'
{ 183, 23, 39, 27, 2, -35 }, // 0x24 '$'
{ 296, 40, 34, 42, 1, -33 }, // 0x25 '%'
{ 466, 33, 34, 35, 2, -33 }, // 0x26 '&'
{ 607, 7, 13, 13, 3, -33 }, // 0x27 '''
{ 619, 13, 41, 16, 2, -33 }, // 0x28 '('
{ 686, 13, 41, 16, 1, -33 }, // 0x29 ')'
{ 753, 23, 22, 25, 1, -35 }, // 0x2A '*'
{ 817, 23, 23, 27, 2, -27 }, // 0x2B '+'
{ 884, 10, 11, 13, 1, -4 }, // 0x2C ','
{ 898, 13, 6, 15, 1, -15 }, // 0x2D '-'
{ 908, 8, 8, 13, 3, -6 }, // 0x2E '.'
{ 916, 19, 34, 20, 0, -33 }, // 0x2F '/'
{ 997, 23, 34, 27, 2, -33 }, // 0x30 '0'
{ 1095, 16, 34, 27, 3, -33 }, // 0x31 '1'
{ 1163, 23, 34, 27, 2, -33 }, // 0x32 '2'
{ 1261, 23, 34, 27, 2, -33 }, // 0x33 '3'
{ 1359, 25, 34, 27, 1, -33 }, // 0x34 '4'
{ 1466, 23, 34, 27, 2, -33 }, // 0x35 '5'
{ 1564, 23, 34, 27, 2, -33 }, // 0x36 '6'
{ 1662, 24, 34, 27, 1, -33 }, // 0x37 '7'
{ 1764, 23, 34, 27, 2, -33 }, // 0x38 '8'
{ 1862, 24, 34, 27, 1, -33 }, // 0x39 '9'
{ 1964, 8, 27, 13, 3, -25 }, // 0x3A ':'
{ 1991, 10, 32, 13, 1, -25 }, // 0x3B ';'
{ 2031, 23, 24, 27, 2, -28 }, // 0x3C '<'
{ 2100, 23, 14, 27, 2, -23 }, // 0x3D '='
{ 2141, 23, 24, 27, 2, -28 }, // 0x3E '>'
{ 2210, 21, 35, 22, 0, -33 }, // 0x3F '?'
{ 2302, 38, 38, 42, 2, -33 }, // 0x40 '@'
{ 2483, 33, 34, 33, 0, -33 }, // 0x41 'A'
{ 2624, 25, 34, 31, 4, -33 }, // 0x42 'B'
{ 2731, 26, 34, 30, 3, -33 }, // 0x43 'C'
{ 2842, 28, 34, 34, 4, -33 }, // 0x44 'D'
{ 2961, 20, 34, 26, 4, -33 }, // 0x45 'E'
{ 3046, 19, 34, 26, 4, -33 }, // 0x46 'F'
{ 3127, 27, 34, 34, 3, -33 }, // 0x47 'G'
{ 3242, 28, 34, 36, 4, -33 }, // 0x48 'H'
{ 3361, 16, 34, 18, 1, -33 }, // 0x49 'I'
{ 3429, 14, 44, 16, -3, -33 }, // 0x4A 'J'
{ 3506, 27, 34, 31, 4, -33 }, // 0x4B 'K'
{ 3621, 21, 34, 26, 4, -33 }, // 0x4C 'L'
{ 3711, 36, 34, 44, 4, -33 }, // 0x4D 'M'
{ 3864, 30, 34, 38, 4, -33 }, // 0x4E 'N'
{ 3992, 32, 34, 37, 3, -33 }, // 0x4F 'O'
{ 4128, 23, 34, 29, 4, -33 }, // 0x50 'P'
{ 4226, 32, 42, 37, 3, -33 }, // 0x51 'Q'
{ 4394, 27, 34, 31, 4, -33 }, // 0x52 'R'
{ 4509, 22, 34, 26, 2, -33 }, // 0x53 'S'
{ 4603, 25, 34, 27, 1, -33 }, // 0x54 'T'
{ 4710, 28, 34, 36, 4, -33 }, // 0x55 'U'
{ 4829, 31, 34, 31, 0, -33 }, // 0x56 'V'
{ 4961, 45, 34, 45, 0, -33 }, // 0x57 'W'
{ 5153, 31, 34, 31, 0, -33 }, // 0x58 'X'
{ 5285, 29, 34, 29, 0, -33 }, // 0x59 'Y'
{ 5409, 25, 34, 27, 1, -33 }, // 0x5A 'Z'
{ 5516, 11, 41, 16, 3, -33 }, // 0x5B '['
{ 5573, 19, 34, 20, 0, -33 }, // 0x5C '\'
{ 5654, 11, 41, 16, 1, -33 }, // 0x5D ']'
{ 5711, 25, 22, 27, 1, -33 }, // 0x5E '^'
{ 5780, 19, 3, 19, 0, 5 }, // 0x5F '_'
{ 5788, 13, 8, 17, 2, -35 }, // 0x60 '`'
{ 5801, 23, 26, 28, 2, -25 }, // 0x61 'a'
{ 5876, 24, 36, 30, 3, -35 }, // 0x62 'b'
{ 5984, 21, 26, 24, 2, -25 }, // 0x63 'c'
{ 6053, 24, 36, 30, 2, -35 }, // 0x64 'd'
{ 6161, 24, 26, 28, 2, -25 }, // 0x65 'e'
{ 6239, 19, 36, 18, 1, -35 }, // 0x66 'f'
{ 6325, 24, 37, 30, 2, -25 }, // 0x67 'g'
{ 6436, 24, 36, 31, 3, -35 }, // 0x68 'h'
{ 6544, 8, 36, 14, 3, -35 }, // 0x69 'i'
{ 6580, 13, 47, 14, -2, -35 }, // 0x6A 'j'
{ 6657, 25, 36, 29, 4, -35 }, // 0x6B 'k'
{ 6770, 8, 36, 14, 3, -35 }, // 0x6C 'l'
{ 6806, 39, 26, 46, 3, -25 }, // 0x6D 'm'
{ 6933, 24, 26, 31, 3, -25 }, // 0x6E 'n'
{ 7011, 25, 26, 29, 2, -25 }, // 0x6F 'o'
{ 7093, 24, 37, 30, 3, -25 }, // 0x70 'p'
{ 7204, 24, 37, 30, 2, -25 }, // 0x71 'q'
{ 7315, 17, 26, 21, 3, -25 }, // 0x72 'r'
{ 7371, 20, 26, 24, 2, -25 }, // 0x73 's'
{ 7436, 18, 31, 20, 1, -30 }, // 0x74 't'
{ 7506, 24, 26, 31, 3, -25 }, // 0x75 'u'
{ 7584, 27, 26, 27, 0, -25 }, // 0x76 'v'
{ 7672, 40, 26, 40, 0, -25 }, // 0x77 'w'
{ 7802, 27, 26, 27, 0, -25 }, // 0x78 'x'
{ 7890, 27, 37, 27, 0, -25 }, // 0x79 'y'
{ 8015, 21, 26, 23, 1, -25 }, // 0x7A 'z'
{ 8084, 16, 41, 19, 1, -33 }, // 0x7B '{'
{ 8166, 5, 47, 26, 10, -35 }, // 0x7C '|'
{ 8196, 16, 41, 19, 2, -33 }, // 0x7D '}'
{ 8278, 23, 7, 27, 2, -19 } }; // 0x7E '~'
const GFXfont NotoSans_Bold24pt7b PROGMEM = {
(uint8_t *)NotoSans_Bold24pt7bBitmaps,
(GFXglyph *)NotoSans_Bold24pt7bGlyphs,
0x20, 0x7E, 64 };
// Approx. 8971 bytes
#endif // NOTOSANSBOLD24PT7B_H
@@ -0,0 +1,171 @@
#ifndef NOTOSANSBOLD7PT7B_H
#define NOTOSANSBOLD7PT7B_H
const uint8_t NotoSans_Bold7pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFC, 0xF0, 0xDE, 0xF7, 0xA0, 0x1A, 0x09, 0x04, 0x8F, 0xF3,
0x61, 0xA3, 0xFC, 0x48, 0x2C, 0x36, 0x00, 0x23, 0xFE, 0x78, 0xF0, 0xF2,
0xEB, 0xFC, 0x82, 0x00, 0x70, 0xC5, 0x98, 0xD9, 0x0D, 0xB0, 0x5A, 0xE7,
0x6B, 0x05, 0xB0, 0xDB, 0x19, 0xB1, 0x8E, 0x78, 0x3E, 0x33, 0x0F, 0x87,
0x87, 0xCF, 0x7D, 0x9E, 0xFF, 0x3F, 0xC0, 0xFF, 0x6B, 0x69, 0x24, 0xDB,
0x30, 0xC6, 0x23, 0x33, 0x33, 0x33, 0x6E, 0x19, 0x27, 0xF9, 0xC2, 0xCD,
0x80, 0x30, 0xCF, 0xFF, 0x30, 0xC0, 0x6D, 0x60, 0xFF, 0xF0, 0x0C, 0x61,
0x84, 0x30, 0xC6, 0x18, 0x63, 0x00, 0x3C, 0xFD, 0x9B, 0x36, 0x7C, 0xD9,
0xB3, 0x7E, 0x78, 0x1B, 0xFF, 0x31, 0x8C, 0x63, 0x18, 0xC0, 0x7B, 0xF8,
0xC3, 0x1C, 0x63, 0x18, 0xFF, 0xF0, 0x7B, 0xF0, 0xC3, 0x79, 0xF0, 0xC3,
0xFF, 0xE0, 0x0C, 0x0C, 0x1C, 0x3C, 0x2C, 0x6C, 0xFF, 0xFF, 0x0C, 0x0C,
0xFF, 0xFC, 0x30, 0xFA, 0x70, 0xC3, 0xFF, 0xE0, 0x1E, 0x7D, 0x83, 0x05,
0xFC, 0xD9, 0xB3, 0x7E, 0x78, 0xFF, 0xFC, 0x18, 0x70, 0xC1, 0x86, 0x0C,
0x30, 0x60, 0x3C, 0xFD, 0x9B, 0x33, 0xCF, 0x99, 0xE3, 0x66, 0xF8, 0x38,
0xFD, 0x9E, 0x36, 0x6F, 0xCD, 0x83, 0x5C, 0xF0, 0xFC, 0x0F, 0x6D, 0x80,
0x1B, 0x58, 0x04, 0x33, 0xB8, 0xC1, 0xE0, 0xC1, 0xFF, 0xF0, 0x3F, 0x83,
0x07, 0x07, 0x1D, 0xCC, 0x20, 0x7B, 0xF0, 0xC3, 0x18, 0xC3, 0x00, 0x30,
0xC0, 0x1F, 0x06, 0x31, 0x03, 0x6F, 0xA9, 0x37, 0x66, 0xEC, 0xD4, 0xFE,
0xC0, 0x0C, 0x20, 0xFC, 0x00, 0x1C, 0x0E, 0x07, 0x86, 0xC3, 0x31, 0x99,
0xFC, 0xFF, 0x61, 0xE0, 0xC0, 0xFD, 0xFF, 0x1E, 0x3F, 0xDF, 0xF1, 0xE3,
0xFF, 0xF8, 0x3E, 0xFF, 0x86, 0x0C, 0x18, 0x30, 0x70, 0x7E, 0x7C, 0xF8,
0xFE, 0xC7, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0xFE, 0xFC, 0xFF, 0xFC, 0x30,
0xFF, 0xFC, 0x30, 0xFF, 0xF0, 0xFF, 0xFC, 0x30, 0xFF, 0xFC, 0x30, 0xC3,
0x00, 0x1E, 0x7F, 0xE0, 0xC0, 0xCF, 0xCF, 0xC3, 0xE3, 0x7F, 0x3F, 0xC3,
0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFB, 0xCC, 0x63,
0x18, 0xC6, 0x77, 0xC0, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0, 0xC3,
0xC6, 0xCC, 0xD8, 0xF8, 0xF8, 0xCC, 0xCE, 0xC6, 0xC7, 0xC3, 0x0C, 0x30,
0xC3, 0x0C, 0x30, 0xFF, 0xF0, 0xE0, 0xFC, 0x3F, 0xC7, 0xF8, 0xBD, 0x37,
0xB6, 0xF6, 0x9E, 0x73, 0xCE, 0x79, 0x8C, 0xE1, 0xF8, 0xFC, 0x7B, 0x3D,
0x9E, 0x6F, 0x37, 0x8F, 0xC7, 0xE1, 0xC0, 0x3E, 0x3F, 0xB8, 0xF8, 0x3C,
0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00, 0xF9, 0xFB, 0x1E, 0x3C, 0xFF,
0xBC, 0x60, 0xC1, 0x80, 0x3E, 0x3F, 0xB8, 0xF8, 0x3C, 0x1E, 0x0F, 0x07,
0xC7, 0x7F, 0x1F, 0x01, 0x80, 0x70, 0xF8, 0xFE, 0xC6, 0xC6, 0xCE, 0xFC,
0xCC, 0xCC, 0xC6, 0xC7, 0x7B, 0xFC, 0x30, 0xF0, 0xE1, 0xC3, 0xFF, 0xE0,
0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xC3, 0xC3,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x7F, 0x3E, 0xC1, 0xE1, 0x98, 0xCC,
0x66, 0x61, 0xB0, 0xD8, 0x68, 0x1C, 0x0E, 0x00, 0xC3, 0x1E, 0x38, 0xD9,
0xC6, 0xCA, 0x66, 0x5B, 0x36, 0xD8, 0xB2, 0xC7, 0x14, 0x38, 0xE1, 0xC7,
0x00, 0xE3, 0xB1, 0x8D, 0x87, 0xC1, 0xC0, 0xE0, 0xF8, 0x6C, 0x63, 0x71,
0xC0, 0xC3, 0xB1, 0x99, 0x86, 0xC3, 0xC0, 0xE0, 0x60, 0x30, 0x18, 0x0C,
0x00, 0xFE, 0xFE, 0x06, 0x0C, 0x18, 0x18, 0x30, 0x60, 0xFF, 0xFF, 0xFF,
0x6D, 0xB6, 0xDB, 0x70, 0xC1, 0x06, 0x18, 0x30, 0xC3, 0x06, 0x18, 0x30,
0xFF, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x10, 0x18, 0x38, 0x2C, 0x64, 0x46,
0xC3, 0xFC, 0xCC, 0x80, 0x33, 0xF0, 0xCF, 0xFF, 0x3D, 0xFD, 0xC1, 0x83,
0x67, 0xEC, 0x78, 0xF1, 0xE3, 0xFF, 0xF8, 0x39, 0xFC, 0x30, 0xC3, 0x0F,
0x9E, 0x06, 0x0C, 0x9F, 0xFC, 0xF8, 0xF1, 0xE3, 0xFE, 0xEC, 0x30, 0xFB,
0x37, 0xFF, 0xF8, 0x39, 0x3E, 0x3D, 0xC6, 0x3E, 0x61, 0x86, 0x18, 0x61,
0x80, 0x21, 0xFF, 0x3E, 0x3C, 0x78, 0xFF, 0xBB, 0x07, 0x1B, 0xF0, 0xC1,
0x83, 0x67, 0xFE, 0x78, 0xF1, 0xE3, 0xC7, 0x8C, 0xD3, 0xFF, 0xF0, 0x31,
0x03, 0x33, 0x33, 0x33, 0x3B, 0xF0, 0xC0, 0xC0, 0xC2, 0xCC, 0xDC, 0xF8,
0xF8, 0xDC, 0xCC, 0xC7, 0xFF, 0xFF, 0xF0, 0x18, 0xDF, 0xFF, 0x39, 0xE3,
0x3C, 0x67, 0x8C, 0xF1, 0x9E, 0x33, 0x19, 0xFF, 0x9E, 0x3C, 0x78, 0xF1,
0xE3, 0x31, 0xFB, 0x3E, 0x3C, 0x78, 0xFB, 0x3C, 0x19, 0xFB, 0x1E, 0x3C,
0x78, 0xFF, 0xFE, 0xC1, 0x83, 0x00, 0x21, 0xFF, 0x3E, 0x3C, 0x78, 0xFF,
0xBB, 0x06, 0x0C, 0x18, 0x1F, 0xF9, 0x8C, 0x63, 0x18, 0x77, 0xF1, 0xC7,
0x8E, 0x7F, 0x21, 0x8F, 0x98, 0x61, 0x86, 0x1F, 0x3C, 0xC7, 0x8F, 0x1E,
0x3C, 0x7F, 0xDF, 0x80, 0xC7, 0x66, 0x66, 0x2C, 0x3C, 0x3C, 0x18, 0xC6,
0x76, 0xE6, 0x6F, 0x66, 0xB4, 0x29, 0xC3, 0x9C, 0x39, 0xC0, 0xE7, 0x3C,
0x3C, 0x3C, 0x3C, 0x66, 0xE7, 0xC7, 0x66, 0x66, 0x2C, 0x3C, 0x3C, 0x18,
0x18, 0x30, 0xF0, 0x7C, 0x31, 0x8C, 0x71, 0xFF, 0xC0, 0x19, 0xCC, 0x63,
0x73, 0x86, 0x31, 0x8C, 0x70, 0xFF, 0xFF, 0xFF, 0xC0, 0xCC, 0x44, 0x67,
0x76, 0x44, 0xCC, 0xE7, 0xF0 };
const GFXglyph NotoSans_Bold7pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
{ 1, 2, 10, 4, 1, -9 }, // 0x21 '!'
{ 4, 5, 4, 7, 1, -9 }, // 0x22 '"'
{ 7, 9, 10, 9, 0, -9 }, // 0x23 '#'
{ 19, 6, 11, 8, 1, -9 }, // 0x24 '$'
{ 28, 12, 10, 12, 0, -9 }, // 0x25 '%'
{ 43, 9, 10, 10, 1, -9 }, // 0x26 '&'
{ 55, 2, 4, 4, 1, -9 }, // 0x27 '''
{ 56, 3, 12, 5, 1, -9 }, // 0x28 '('
{ 61, 4, 12, 5, 0, -9 }, // 0x29 ')'
{ 67, 7, 6, 7, 0, -9 }, // 0x2A '*'
{ 73, 6, 6, 8, 1, -7 }, // 0x2B '+'
{ 78, 3, 4, 4, 0, -1 }, // 0x2C ','
{ 80, 4, 2, 4, 0, -4 }, // 0x2D '-'
{ 81, 2, 2, 4, 1, -1 }, // 0x2E '.'
{ 82, 6, 10, 6, 0, -9 }, // 0x2F '/'
{ 90, 7, 10, 8, 0, -9 }, // 0x30 '0'
{ 99, 5, 10, 8, 1, -9 }, // 0x31 '1'
{ 106, 6, 10, 8, 1, -9 }, // 0x32 '2'
{ 114, 6, 10, 8, 1, -9 }, // 0x33 '3'
{ 122, 8, 10, 8, 0, -9 }, // 0x34 '4'
{ 132, 6, 10, 8, 1, -9 }, // 0x35 '5'
{ 140, 7, 10, 8, 0, -9 }, // 0x36 '6'
{ 149, 7, 10, 8, 0, -9 }, // 0x37 '7'
{ 158, 7, 10, 8, 0, -9 }, // 0x38 '8'
{ 167, 7, 10, 8, 0, -9 }, // 0x39 '9'
{ 176, 2, 8, 4, 1, -7 }, // 0x3A ':'
{ 178, 3, 10, 4, 0, -7 }, // 0x3B ';'
{ 182, 6, 8, 8, 1, -8 }, // 0x3C '<'
{ 188, 6, 4, 8, 1, -6 }, // 0x3D '='
{ 191, 6, 8, 8, 1, -8 }, // 0x3E '>'
{ 197, 6, 10, 7, 0, -9 }, // 0x3F '?'
{ 205, 11, 11, 12, 1, -9 }, // 0x40 '@'
{ 221, 9, 10, 9, 0, -9 }, // 0x41 'A'
{ 233, 7, 10, 9, 1, -9 }, // 0x42 'B'
{ 242, 7, 10, 9, 1, -9 }, // 0x43 'C'
{ 251, 8, 10, 10, 1, -9 }, // 0x44 'D'
{ 261, 6, 10, 8, 1, -9 }, // 0x45 'E'
{ 269, 6, 10, 8, 1, -9 }, // 0x46 'F'
{ 277, 8, 10, 10, 1, -9 }, // 0x47 'G'
{ 287, 8, 10, 10, 1, -9 }, // 0x48 'H'
{ 297, 5, 10, 5, 0, -9 }, // 0x49 'I'
{ 304, 4, 13, 5, -1, -9 }, // 0x4A 'J'
{ 311, 8, 10, 9, 1, -9 }, // 0x4B 'K'
{ 321, 6, 10, 8, 1, -9 }, // 0x4C 'L'
{ 329, 11, 10, 13, 1, -9 }, // 0x4D 'M'
{ 343, 9, 10, 11, 1, -9 }, // 0x4E 'N'
{ 355, 9, 10, 11, 1, -9 }, // 0x4F 'O'
{ 367, 7, 10, 9, 1, -9 }, // 0x50 'P'
{ 376, 9, 12, 11, 1, -9 }, // 0x51 'Q'
{ 390, 8, 10, 9, 1, -9 }, // 0x52 'R'
{ 400, 6, 10, 8, 1, -9 }, // 0x53 'S'
{ 408, 8, 10, 8, 0, -9 }, // 0x54 'T'
{ 418, 8, 10, 10, 1, -9 }, // 0x55 'U'
{ 428, 9, 10, 9, 0, -9 }, // 0x56 'V'
{ 440, 13, 10, 13, 0, -9 }, // 0x57 'W'
{ 457, 9, 10, 9, 0, -9 }, // 0x58 'X'
{ 469, 9, 10, 9, 0, -9 }, // 0x59 'Y'
{ 481, 8, 10, 8, 0, -9 }, // 0x5A 'Z'
{ 491, 3, 12, 5, 1, -9 }, // 0x5B '['
{ 496, 6, 10, 6, 0, -9 }, // 0x5C '\'
{ 504, 4, 12, 5, 0, -9 }, // 0x5D ']'
{ 510, 8, 7, 8, 0, -9 }, // 0x5E '^'
{ 517, 6, 1, 6, 0, 2 }, // 0x5F '_'
{ 518, 3, 3, 5, 1, -10 }, // 0x60 '`'
{ 520, 6, 8, 8, 1, -7 }, // 0x61 'a'
{ 526, 7, 10, 9, 1, -9 }, // 0x62 'b'
{ 535, 6, 8, 7, 1, -7 }, // 0x63 'c'
{ 541, 7, 10, 9, 1, -9 }, // 0x64 'd'
{ 550, 7, 8, 8, 1, -7 }, // 0x65 'e'
{ 557, 6, 10, 5, 0, -9 }, // 0x66 'f'
{ 565, 7, 11, 9, 1, -7 }, // 0x67 'g'
{ 575, 7, 10, 9, 1, -9 }, // 0x68 'h'
{ 584, 2, 10, 4, 1, -9 }, // 0x69 'i'
{ 587, 4, 13, 4, -1, -9 }, // 0x6A 'j'
{ 594, 8, 10, 9, 1, -9 }, // 0x6B 'k'
{ 604, 2, 10, 4, 1, -9 }, // 0x6C 'l'
{ 607, 11, 8, 13, 1, -7 }, // 0x6D 'm'
{ 618, 7, 8, 9, 1, -7 }, // 0x6E 'n'
{ 625, 7, 8, 9, 1, -7 }, // 0x6F 'o'
{ 632, 7, 11, 9, 1, -7 }, // 0x70 'p'
{ 642, 7, 11, 9, 1, -7 }, // 0x71 'q'
{ 652, 5, 8, 6, 1, -7 }, // 0x72 'r'
{ 657, 5, 8, 7, 1, -7 }, // 0x73 's'
{ 662, 6, 9, 6, 0, -8 }, // 0x74 't'
{ 669, 7, 7, 9, 1, -6 }, // 0x75 'u'
{ 676, 8, 7, 8, 0, -6 }, // 0x76 'v'
{ 683, 12, 7, 12, 0, -6 }, // 0x77 'w'
{ 694, 8, 7, 8, 0, -6 }, // 0x78 'x'
{ 701, 8, 10, 8, 0, -6 }, // 0x79 'y'
{ 711, 6, 7, 7, 0, -6 }, // 0x7A 'z'
{ 717, 5, 12, 5, 0, -9 }, // 0x7B '{'
{ 725, 2, 13, 8, 3, -9 }, // 0x7C '|'
{ 729, 4, 12, 5, 1, -9 }, // 0x7D '}'
{ 735, 6, 2, 8, 1, -5 } }; // 0x7E '~'
const GFXfont NotoSans_Bold7pt7b PROGMEM = {
(uint8_t *)NotoSans_Bold7pt7bBitmaps,
(GFXglyph *)NotoSans_Bold7pt7bGlyphs,
0x20, 0x7E, 19 };
// Approx. 1409 bytes
#endif // NOTOSANSBOLD7PT7B_H
@@ -0,0 +1,210 @@
#ifndef NOTOSANSBOLD9PT7B_H
#define NOTOSANSBOLD9PT7B_H
const uint8_t NotoSans_Bold9pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xE1, 0x7E, 0xEF, 0xBC, 0xF3, 0xCC, 0x0C, 0xC1,
0x90, 0x36, 0x04, 0xC7, 0xFE, 0xFF, 0xC6, 0x40, 0xD8, 0xFF, 0xDF, 0xF8,
0xCC, 0x19, 0x03, 0x60, 0x18, 0x7F, 0xFF, 0xF9, 0xF8, 0xF8, 0x7E, 0x1F,
0x1F, 0x9B, 0xFF, 0xFE, 0x18, 0x18, 0x70, 0x63, 0xE1, 0x8D, 0x8C, 0x36,
0x30, 0xDD, 0x83, 0x66, 0xEF, 0xB7, 0xDD, 0xDB, 0x06, 0xCC, 0x33, 0x30,
0xCE, 0xC6, 0x1F, 0x38, 0x38, 0x1C, 0x07, 0xF0, 0x77, 0x06, 0x30, 0x77,
0x03, 0xE0, 0x7C, 0x7F, 0xE6, 0xEF, 0xEC, 0x7C, 0xE3, 0xCF, 0xFE, 0x7E,
0xF0, 0xFF, 0x6C, 0x33, 0x66, 0xCC, 0xCC, 0xCC, 0xCC, 0xE6, 0x73, 0xCC,
0x66, 0x73, 0x33, 0x33, 0x33, 0x76, 0xEC, 0x18, 0x18, 0xDB, 0xFF, 0x38,
0x3C, 0x6E, 0x24, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18,
0xFF, 0x60, 0xFF, 0xC0, 0x5F, 0x80, 0x06, 0x1C, 0x30, 0x61, 0xC3, 0x06,
0x1C, 0x30, 0xE1, 0x83, 0x0E, 0x00, 0x3C, 0x7E, 0xE7, 0xE7, 0xC3, 0xC3,
0xC3, 0xC3, 0xC3, 0xE3, 0xE7, 0x7E, 0x3C, 0x0C, 0x77, 0xFB, 0x4C, 0x30,
0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x3C, 0x7F, 0x3B, 0xC8, 0xE0, 0x70, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x1F, 0xFF, 0xF8, 0x3C, 0xFE, 0xEF, 0x07,
0x07, 0x1E, 0x3C, 0x3F, 0x07, 0x03, 0x87, 0xFF, 0xFE, 0x03, 0x01, 0xC0,
0xF0, 0x3C, 0x1B, 0x0E, 0xC3, 0x31, 0x8C, 0xFF, 0xFF, 0xF0, 0x30, 0x0C,
0x03, 0x00, 0x7E, 0x7E, 0xFE, 0xE0, 0xE0, 0xFE, 0xFF, 0x07, 0x03, 0x03,
0x87, 0xFE, 0xFC, 0x0F, 0x1F, 0x9E, 0x5C, 0x0C, 0x06, 0xF3, 0xFD, 0xC6,
0xC3, 0xE1, 0xB9, 0xCF, 0xE3, 0xE0, 0xFF, 0xFF, 0xFF, 0xF8, 0x0E, 0x03,
0x01, 0xC0, 0x70, 0x38, 0x0E, 0x03, 0x01, 0xC0, 0x60, 0x38, 0x00, 0x3C,
0x7E, 0xE7, 0xE3, 0xE7, 0x7E, 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xFF, 0x7E,
0x38, 0x7E, 0xEF, 0xC3, 0xC3, 0xC3, 0xEF, 0xFF, 0x33, 0x07, 0x06, 0xFE,
0xF8, 0xFF, 0x80, 0x02, 0xFC, 0xFF, 0x80, 0x00, 0xFF, 0x60, 0x01, 0x07,
0x1E, 0x78, 0xE0, 0xF0, 0x3E, 0x0F, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
0x80, 0xE0, 0x78, 0x1E, 0x07, 0x0F, 0x7C, 0xF0, 0x80, 0x3C, 0xFE, 0x67,
0x03, 0x07, 0x0E, 0x1C, 0x18, 0x38, 0x00, 0x18, 0x38, 0x38, 0x03, 0x80,
0x7F, 0xC3, 0x83, 0x98, 0x06, 0x67, 0xCF, 0x33, 0x3D, 0x8C, 0xF6, 0x33,
0xD8, 0xCF, 0x3F, 0xEC, 0xF7, 0x18, 0x00, 0x78, 0x60, 0x7F, 0x80, 0x0F,
0x00, 0xF0, 0x0F, 0x01, 0xF8, 0x1D, 0x81, 0x9C, 0x39, 0xC3, 0x8C, 0x3F,
0xE7, 0xFE, 0x70, 0xE6, 0x07, 0xE0, 0x70, 0xFC, 0x3F, 0xEF, 0xFB, 0x87,
0xE1, 0xBF, 0xEF, 0xF3, 0x9E, 0xE1, 0xF8, 0x7E, 0x3F, 0xFE, 0xFF, 0x00,
0x0F, 0x0F, 0xF7, 0xF9, 0xC0, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38,
0x07, 0x09, 0xFE, 0x1F, 0x80, 0xFC, 0x1F, 0xF3, 0xFF, 0x70, 0xEE, 0x0F,
0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x3B, 0x8F, 0x7F, 0xCF, 0xE0, 0xFF,
0xFF, 0xFE, 0x0C, 0x1F, 0xFF, 0xFF, 0xC1, 0x83, 0x07, 0xFF, 0xE0, 0xFF,
0xFF, 0xFE, 0x0C, 0x18, 0x3F, 0x7E, 0xC1, 0x83, 0x06, 0x0C, 0x00, 0x0F,
0x8F, 0xF7, 0xDD, 0xC0, 0xE0, 0x38, 0x0E, 0x7F, 0x9F, 0xE0, 0xF8, 0x37,
0x0C, 0xFF, 0x1F, 0xC0, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xFF, 0xFF,
0xFF, 0xFF, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xC0, 0xFF, 0xDC, 0xE7,
0x39, 0xCE, 0x73, 0x9D, 0xFF, 0x80, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
0xC6, 0x31, 0x9F, 0xFE, 0xE0, 0xC1, 0xF0, 0xEC, 0x73, 0x38, 0xDC, 0x37,
0x0F, 0xC3, 0xF0, 0xCE, 0x33, 0x8C, 0x73, 0x0E, 0xC3, 0xC0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xE0,
0x7F, 0x83, 0xFC, 0x1F, 0xE1, 0xBF, 0x0D, 0xEC, 0x6F, 0x67, 0x7B, 0x33,
0xCD, 0x9E, 0x7C, 0xF3, 0xC7, 0x9E, 0x3C, 0x71, 0x80, 0xE0, 0xFE, 0x1F,
0xC3, 0xFC, 0x7F, 0x8F, 0xB9, 0xF3, 0x3E, 0x77, 0xC7, 0xF8, 0xFF, 0x0F,
0xE1, 0xFC, 0x1E, 0x0F, 0x03, 0xFC, 0x79, 0xE7, 0x0E, 0xE0, 0x7E, 0x07,
0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0x70, 0xE3, 0xFC, 0x1F, 0x80, 0xFC,
0x7F, 0xBF, 0xFC, 0x7E, 0x3F, 0x1F, 0xFF, 0xFE, 0xF8, 0x70, 0x38, 0x1C,
0x0E, 0x00, 0x0F, 0x03, 0xFC, 0x79, 0xE7, 0x0E, 0xE0, 0x7E, 0x07, 0xE0,
0x7E, 0x07, 0xE0, 0x7E, 0x07, 0x70, 0xE3, 0xFC, 0x1F, 0x80, 0x3C, 0x01,
0xE0, 0x0F, 0xFC, 0x1F, 0xE3, 0xFE, 0x71, 0xCE, 0x19, 0xC7, 0x3F, 0xC7,
0xF0, 0xE7, 0x1C, 0xE3, 0x8E, 0x70, 0xEE, 0x1E, 0x3C, 0x7F, 0xF6, 0xE0,
0xE0, 0xF0, 0x7C, 0x1E, 0x07, 0x07, 0x87, 0xFE, 0xFC, 0xFF, 0xFF, 0xFF,
0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
0x0C, 0x00, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F,
0x07, 0xE0, 0xEC, 0x1D, 0xC7, 0x3F, 0xE1, 0xF8, 0xE0, 0x7C, 0x1D, 0x83,
0xB8, 0x67, 0x1C, 0x63, 0x8E, 0x61, 0xCC, 0x1B, 0x83, 0x60, 0x7C, 0x07,
0x80, 0xE0, 0xE1, 0xC3, 0xF0, 0xE1, 0xD8, 0x70, 0xEC, 0x7C, 0x67, 0x36,
0x73, 0x9B, 0x38, 0xCD, 0x98, 0x6E, 0xEC, 0x36, 0x36, 0x1F, 0x1F, 0x07,
0x8F, 0x03, 0xC7, 0x81, 0xC1, 0xC0, 0xE0, 0xE7, 0x0E, 0x39, 0xC3, 0x98,
0x1F, 0x80, 0xF0, 0x0F, 0x00, 0xF0, 0x1F, 0x83, 0xB8, 0x39, 0xC7, 0x0E,
0xE0, 0xF0, 0xE0, 0xEC, 0x19, 0xC7, 0x18, 0xC3, 0xB8, 0x36, 0x07, 0xC0,
0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x7F, 0xDF, 0xF7, 0xF8,
0x0E, 0x07, 0x03, 0x80, 0xE0, 0x70, 0x38, 0x0C, 0x07, 0x03, 0xFF, 0xFF,
0xC0, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFF, 0xE0, 0xC1, 0x83,
0x83, 0x06, 0x0E, 0x0C, 0x1C, 0x38, 0x30, 0x70, 0x60, 0xFF, 0xCE, 0x73,
0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9F, 0xFF, 0x08, 0x03, 0x01, 0xE0, 0x78,
0x33, 0x0C, 0xC6, 0x19, 0x86, 0xC0, 0xC0, 0xFE, 0xE3, 0x0E, 0x3C, 0x7F,
0x47, 0x03, 0x3F, 0xFF, 0xE3, 0xC7, 0xFF, 0x7B, 0xE0, 0x70, 0x38, 0x1D,
0xCF, 0xF7, 0x9F, 0x8F, 0xC3, 0xE1, 0xF1, 0xF8, 0xFF, 0xFE, 0xF0, 0x1F,
0x7E, 0xF2, 0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0x7E, 0x3E, 0x03, 0x81, 0xC0,
0xE7, 0x77, 0xFF, 0xBF, 0x8F, 0xC7, 0xE3, 0xF1, 0xF8, 0xEF, 0xF7, 0xD8,
0x1C, 0x3F, 0xB8, 0xDC, 0x7F, 0xFF, 0xFF, 0x81, 0xC1, 0x7F, 0x1F, 0x80,
0x3F, 0x3E, 0x30, 0x3E, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x39, 0xBF, 0xFD, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0x7F, 0xBF,
0xC0, 0xF0, 0x7F, 0xF7, 0xF0, 0xE0, 0x70, 0x38, 0x1D, 0xCF, 0xFF, 0x9F,
0x8F, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x18, 0xFC, 0x7F, 0xFF, 0xFF,
0xFE, 0x39, 0xC0, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xFF, 0xF0,
0xE0, 0x38, 0x0E, 0x03, 0x87, 0xE3, 0xB9, 0xCE, 0xE3, 0xF0, 0xFE, 0x3F,
0x8E, 0x73, 0x8E, 0xE1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xCE, 0x39,
0xFF, 0xFB, 0xCF, 0x3F, 0x1C, 0x7E, 0x38, 0xFC, 0x71, 0xF8, 0xE3, 0xF1,
0xC7, 0xE3, 0x8F, 0xC7, 0x1C, 0xCE, 0x7F, 0xFC, 0xFC, 0x7E, 0x1F, 0x0F,
0x87, 0xC3, 0xE1, 0xF0, 0xC0, 0x1C, 0x3F, 0xB8, 0xFC, 0x7E, 0x3F, 0x1F,
0x8F, 0xC7, 0x7F, 0x1F, 0x00, 0xCE, 0x7F, 0xBC, 0xFC, 0x7E, 0x1F, 0x0F,
0x8F, 0xC7, 0xFF, 0xFF, 0xB8, 0x1C, 0x0E, 0x07, 0x00, 0x39, 0xBF, 0xFD,
0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0x7F, 0xBF, 0xC0, 0xE0, 0x70, 0x38,
0x1C, 0xCF, 0xFF, 0xF7, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x3D, 0xFF,
0x17, 0x0F, 0x87, 0xC3, 0xC3, 0xFF, 0xF8, 0x10, 0x60, 0xFF, 0xF3, 0x06,
0x0C, 0x18, 0x30, 0x60, 0xF8, 0xF0, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F,
0x1F, 0x8F, 0xC7, 0x7F, 0xBE, 0xC0, 0xE1, 0xF8, 0x76, 0x19, 0xCE, 0x33,
0x0C, 0xC3, 0xF0, 0x78, 0x1E, 0x07, 0x80, 0xE3, 0x8F, 0xC7, 0x1D, 0x8B,
0x33, 0xB6, 0xE7, 0x6D, 0xC6, 0xDB, 0x0D, 0x96, 0x1A, 0x3C, 0x3C, 0x78,
0x38, 0xE0, 0xE1, 0xDC, 0xE3, 0xB8, 0xFC, 0x1E, 0x07, 0x83, 0xF0, 0xEC,
0x73, 0xB8, 0x70, 0xE1, 0xF8, 0x77, 0x19, 0xCE, 0x33, 0x8E, 0xC3, 0xF0,
0x78, 0x1E, 0x03, 0x80, 0xC0, 0x70, 0x78, 0x1C, 0x00, 0xFF, 0xFC, 0x38,
0xE3, 0x86, 0x1C, 0x70, 0xFF, 0xFC, 0x04, 0x73, 0x8E, 0x38, 0xE3, 0xBC,
0xF0, 0xE3, 0x8E, 0x38, 0xE1, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x83,
0x86, 0x18, 0x61, 0x87, 0x0F, 0x3D, 0xC6, 0x18, 0x61, 0x8E, 0x30, 0x61,
0xFF, 0x9F };
const GFXglyph NotoSans_Bold9pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 5, 0, 0 }, // 0x20 ' '
{ 1, 3, 13, 5, 1, -12 }, // 0x21 '!'
{ 6, 6, 5, 8, 1, -12 }, // 0x22 '"'
{ 10, 11, 13, 11, 0, -12 }, // 0x23 '#'
{ 28, 8, 14, 10, 1, -12 }, // 0x24 '$'
{ 42, 14, 13, 16, 1, -12 }, // 0x25 '%'
{ 65, 12, 13, 13, 1, -12 }, // 0x26 '&'
{ 85, 3, 5, 5, 1, -12 }, // 0x27 '''
{ 87, 4, 16, 6, 1, -12 }, // 0x28 '('
{ 95, 4, 16, 6, 1, -12 }, // 0x29 ')'
{ 103, 8, 8, 10, 1, -12 }, // 0x2A '*'
{ 111, 8, 9, 10, 1, -10 }, // 0x2B '+'
{ 120, 3, 4, 5, 1, -1 }, // 0x2C ','
{ 122, 5, 2, 6, 0, -5 }, // 0x2D '-'
{ 124, 3, 3, 5, 1, -2 }, // 0x2E '.'
{ 126, 7, 13, 7, 0, -12 }, // 0x2F '/'
{ 138, 8, 13, 10, 1, -12 }, // 0x30 '0'
{ 151, 6, 13, 10, 1, -12 }, // 0x31 '1'
{ 161, 9, 13, 10, 1, -12 }, // 0x32 '2'
{ 176, 8, 13, 10, 1, -12 }, // 0x33 '3'
{ 189, 10, 13, 10, 0, -12 }, // 0x34 '4'
{ 206, 8, 13, 10, 1, -12 }, // 0x35 '5'
{ 219, 9, 13, 10, 1, -12 }, // 0x36 '6'
{ 234, 10, 13, 10, 0, -12 }, // 0x37 '7'
{ 251, 8, 13, 10, 1, -12 }, // 0x38 '8'
{ 264, 8, 13, 10, 1, -12 }, // 0x39 '9'
{ 277, 3, 10, 5, 1, -9 }, // 0x3A ':'
{ 281, 3, 12, 5, 1, -9 }, // 0x3B ';'
{ 286, 8, 9, 10, 1, -10 }, // 0x3C '<'
{ 295, 8, 5, 10, 1, -8 }, // 0x3D '='
{ 300, 8, 9, 10, 1, -10 }, // 0x3E '>'
{ 309, 8, 13, 8, 0, -12 }, // 0x3F '?'
{ 322, 14, 14, 16, 1, -12 }, // 0x40 '@'
{ 347, 12, 13, 12, 0, -12 }, // 0x41 'A'
{ 367, 10, 13, 12, 1, -12 }, // 0x42 'B'
{ 384, 10, 13, 11, 1, -12 }, // 0x43 'C'
{ 401, 11, 13, 13, 1, -12 }, // 0x44 'D'
{ 419, 7, 13, 10, 2, -12 }, // 0x45 'E'
{ 431, 7, 13, 10, 2, -12 }, // 0x46 'F'
{ 443, 10, 13, 13, 1, -12 }, // 0x47 'G'
{ 460, 10, 13, 13, 2, -12 }, // 0x48 'H'
{ 477, 5, 13, 7, 1, -12 }, // 0x49 'I'
{ 486, 5, 17, 6, -1, -12 }, // 0x4A 'J'
{ 497, 10, 13, 12, 2, -12 }, // 0x4B 'K'
{ 514, 8, 13, 10, 1, -12 }, // 0x4C 'L'
{ 527, 13, 13, 17, 2, -12 }, // 0x4D 'M'
{ 549, 11, 13, 14, 2, -12 }, // 0x4E 'N'
{ 567, 12, 13, 14, 1, -12 }, // 0x4F 'O'
{ 587, 9, 13, 11, 1, -12 }, // 0x50 'P'
{ 602, 12, 16, 14, 1, -12 }, // 0x51 'Q'
{ 626, 11, 13, 12, 1, -12 }, // 0x52 'R'
{ 644, 8, 13, 10, 1, -12 }, // 0x53 'S'
{ 657, 10, 13, 10, 0, -12 }, // 0x54 'T'
{ 674, 11, 13, 13, 1, -12 }, // 0x55 'U'
{ 692, 11, 13, 11, 0, -12 }, // 0x56 'V'
{ 710, 17, 13, 17, 0, -12 }, // 0x57 'W'
{ 738, 12, 13, 12, 0, -12 }, // 0x58 'X'
{ 758, 11, 13, 11, 0, -12 }, // 0x59 'Y'
{ 776, 10, 13, 10, 0, -12 }, // 0x5A 'Z'
{ 793, 4, 16, 6, 1, -12 }, // 0x5B '['
{ 801, 7, 13, 7, 0, -12 }, // 0x5C '\'
{ 813, 5, 16, 6, 0, -12 }, // 0x5D ']'
{ 823, 10, 9, 10, 0, -12 }, // 0x5E '^'
{ 835, 7, 1, 7, 0, 3 }, // 0x5F '_'
{ 836, 5, 3, 6, 1, -13 }, // 0x60 '`'
{ 838, 8, 10, 11, 1, -9 }, // 0x61 'a'
{ 848, 9, 13, 11, 1, -12 }, // 0x62 'b'
{ 863, 8, 10, 9, 1, -9 }, // 0x63 'c'
{ 873, 9, 13, 11, 1, -12 }, // 0x64 'd'
{ 888, 9, 10, 11, 1, -9 }, // 0x65 'e'
{ 900, 8, 13, 7, 0, -12 }, // 0x66 'f'
{ 913, 9, 14, 11, 1, -9 }, // 0x67 'g'
{ 929, 9, 13, 11, 1, -12 }, // 0x68 'h'
{ 944, 3, 13, 5, 1, -12 }, // 0x69 'i'
{ 949, 5, 17, 5, -1, -12 }, // 0x6A 'j'
{ 960, 10, 13, 11, 1, -12 }, // 0x6B 'k'
{ 977, 3, 13, 5, 1, -12 }, // 0x6C 'l'
{ 982, 15, 10, 17, 1, -9 }, // 0x6D 'm'
{ 1001, 9, 10, 11, 1, -9 }, // 0x6E 'n'
{ 1013, 9, 10, 11, 1, -9 }, // 0x6F 'o'
{ 1025, 9, 14, 11, 1, -9 }, // 0x70 'p'
{ 1041, 9, 14, 11, 1, -9 }, // 0x71 'q'
{ 1057, 7, 10, 8, 1, -9 }, // 0x72 'r'
{ 1066, 7, 10, 9, 1, -9 }, // 0x73 's'
{ 1075, 7, 12, 8, 0, -11 }, // 0x74 't'
{ 1086, 9, 10, 11, 1, -9 }, // 0x75 'u'
{ 1098, 10, 10, 10, 0, -9 }, // 0x76 'v'
{ 1111, 15, 10, 15, 0, -9 }, // 0x77 'w'
{ 1130, 10, 10, 10, 0, -9 }, // 0x78 'x'
{ 1143, 10, 14, 10, 0, -9 }, // 0x79 'y'
{ 1161, 7, 10, 9, 1, -9 }, // 0x7A 'z'
{ 1170, 6, 16, 7, 0, -12 }, // 0x7B '{'
{ 1182, 2, 17, 10, 4, -12 }, // 0x7C '|'
{ 1187, 6, 16, 7, 1, -12 }, // 0x7D '}'
{ 1199, 8, 3, 10, 1, -7 } }; // 0x7E '~'
const GFXfont NotoSans_Bold9pt7b PROGMEM = {
(uint8_t *)NotoSans_Bold9pt7bBitmaps,
(GFXglyph *)NotoSans_Bold9pt7bGlyphs,
0x20, 0x7E, 24 };
// Approx. 1874 bytes
#endif // NOTOSANSBOLD9PT7B_H
@@ -0,0 +1,63 @@
#pragma once
// =============================================================================
// HomeIcons — 12x12 icon sprites for T5S3 home screen tiles
// MSB-first, 2 bytes per row (same format as emoji sprites)
// =============================================================================
#include <stdint.h>
#ifdef ESP32
#include <pgmspace.h>
#endif
#define HOME_ICON_W 12
#define HOME_ICON_H 12
// ✉️ Envelope (Messages)
static const uint8_t icon_envelope[] PROGMEM = {
0xFF,0xF0, 0x80,0x10, 0xC0,0x30, 0xA0,0x50, 0x90,0x90, 0x89,0x10,
0x86,0x10, 0x80,0x10, 0x80,0x10, 0x80,0x10, 0x80,0x10, 0xFF,0xF0,
};
// 👥 People (Contacts)
static const uint8_t icon_people[] PROGMEM = {
0x31,0x80, 0x7B,0xC0, 0x7B,0xC0, 0x31,0x80, 0x00,0x00, 0x7B,0xC0,
0xFD,0xE0, 0xFD,0xE0, 0x7B,0xC0, 0x00,0x00, 0x00,0x00, 0x00,0x00,
};
// 🎚 Sliders (Settings)
static const uint8_t icon_gear[] PROGMEM = {
0x22,0x20, 0x22,0x20, 0x72,0x70, 0x72,0x70, 0x27,0x20, 0x27,0x20,
0x22,0x20, 0x72,0x20, 0x72,0x70, 0x22,0x70, 0x22,0x20, 0x22,0x20,
};
// 📖 Book (Reader)
static const uint8_t icon_book[] PROGMEM = {
0x7F,0xC0, 0x41,0x40, 0x5D,0x40, 0x5D,0x40, 0x41,0x40, 0x5D,0x40,
0x5D,0x40, 0x41,0x40, 0x5D,0x40, 0x41,0x40, 0x7F,0xC0, 0x00,0x00,
};
// 🗒 Notepad (Notes)
static const uint8_t icon_notepad[] PROGMEM = {
0x3F,0xC0, 0x20,0x40, 0x2F,0x40, 0x20,0x40, 0x2F,0x40, 0x20,0x40,
0x2F,0x40, 0x20,0x40, 0x2F,0x40, 0x20,0x40, 0x3F,0xC0, 0x00,0x00,
};
// 🔍 Magnifying glass (Discover)
static const uint8_t icon_search[] PROGMEM = {
0x3C,0x00, 0x42,0x00, 0x81,0x00, 0x81,0x00, 0x81,0x00, 0x42,0x00,
0x3C,0x00, 0x03,0x00, 0x01,0x80, 0x00,0xC0, 0x00,0x40, 0x00,0x00,
};
// ⏰ Alarm Clock (AlarmScreen) — 12x12 home tile icon
static const uint8_t icon_alarm[] PROGMEM = {
0x40,0x40, 0x9E,0x20, 0x20,0x80, 0x44,0x40, 0x44,0x40, 0x46,0x40,
0x40,0x40, 0x20,0x80, 0x1F,0x00, 0x00,0x00, 0x20,0x40, 0x40,0x20,
};
// 🔔 Bell — 7x8 status bar indicator (alarm enabled)
// MSB-first, 1 byte per row
#define BELL_ICON_W 7
#define BELL_ICON_H 8
static const uint8_t icon_bell_small[] PROGMEM = {
0x10, 0x38, 0x7C, 0x7C, 0x7C, 0xFE, 0x00, 0x10,
};
@@ -0,0 +1,538 @@
#pragma once
// =============================================================================
// VirtualKeyboard — On-screen QWERTY keyboard for T5S3 (touch-only devices)
//
// Renders in virtual coordinate space (128×128). Touch hit testing converts
// physical GT911 coords (960×540) to virtual coords.
//
// Usage:
// keyboard.open("To: General", "", 137); // label, initial text, max len
// keyboard.render(display); // in render loop
// keyboard.handleTap(vx, vy); // on touch tap (virtual coords)
// if (keyboard.status() == VKB_SUBMITTED) { ... keyboard.getText() ... }
// =============================================================================
#if defined(LilyGo_T5S3_EPaper_Pro)
#ifndef VIRTUAL_KEYBOARD_H
#define VIRTUAL_KEYBOARD_H
#include <Arduino.h>
#include <helpers/ui/DisplayDriver.h>
#include "EmojiSprites.h"
enum VKBStatus { VKB_EDITING, VKB_SUBMITTED, VKB_CANCELLED };
// What the keyboard is being used for (dispatch on submit)
enum VKBPurpose {
VKB_CHANNEL_MSG, // Send to channel
VKB_DM, // Direct message to contact
VKB_ADMIN_PASSWORD, // Repeater admin login
VKB_ADMIN_CLI, // Repeater admin CLI command
VKB_NOTES, // Insert text into notes
VKB_SETTINGS_NAME, // Edit node name
VKB_SETTINGS_TEXT, // Generic settings text edit (channel name, freq, APN)
VKB_WIFI_PASSWORD, // WiFi password entry (settings screen)
#ifdef MECK_WEB_READER
VKB_WEB_URL, // Web reader URL entry
VKB_WEB_SEARCH, // Web reader DuckDuckGo search query
VKB_WEB_WIFI_PASS, // Web reader WiFi password
VKB_WEB_LINK, // Web reader link number entry
#endif
VKB_TEXT_PAGE, // Text reader: go to page number
};
class VirtualKeyboard {
public:
static const int MAX_TEXT = 140;
VirtualKeyboard() : _status(VKB_CANCELLED), _purpose(VKB_CHANNEL_MSG),
_contextIdx(0), _textLen(0), _shifted(false), _symbols(false),
_emojiMode(false), _emojiScroll(0) {
_text[0] = '\0';
_label[0] = '\0';
}
void open(VKBPurpose purpose, const char* label, const char* initial, int maxLen, int contextIdx = 0) {
_purpose = purpose;
_contextIdx = contextIdx;
_status = VKB_EDITING;
_shifted = false;
_symbols = false;
_emojiMode = false;
_emojiScroll = 0;
_maxLen = (maxLen > 0 && maxLen < MAX_TEXT) ? maxLen : MAX_TEXT;
strncpy(_label, label, sizeof(_label) - 1);
_label[sizeof(_label) - 1] = '\0';
if (initial && initial[0]) {
strncpy(_text, initial, _maxLen);
_text[_maxLen] = '\0';
_textLen = strlen(_text);
} else {
_text[0] = '\0';
_textLen = 0;
}
}
VKBStatus status() const { return _status; }
VKBPurpose purpose() const { return _purpose; }
int contextIdx() const { return _contextIdx; }
const char* getText() const { return _text; }
int getTextLen() const { return _textLen; }
bool isActive() const { return _status == VKB_EDITING; }
// --- Render keyboard + input field ---
void render(DisplayDriver& display) {
// Header label (To: channel, DM: name, etc.)
display.setTextSize(0);
display.setColor(DisplayDriver::GREEN);
display.setCursor(2, 0);
display.print(_label);
// Input text field
display.setColor(DisplayDriver::LIGHT);
display.drawRect(0, 10, 128, 18); // Border
// Render text with inline emoji sprites
renderTextField(display);
// Character count
{
char countBuf[12];
snprintf(countBuf, sizeof(countBuf), "%d/%d", _textLen, _maxLen);
int cw = display.getTextWidth(countBuf);
display.setCursor(128 - cw - 2, 0);
display.setColor(DisplayDriver::LIGHT);
display.print(countBuf);
}
// Separator
display.drawRect(0, 30, 128, 1);
if (_emojiMode) {
renderEmojiGrid(display);
return;
}
// --- Draw keyboard rows ---
const char* const* layout = getLayout();
for (int row = 0; row < 3; row++) {
int numKeys = strlen(layout[row]);
int rowY = KEY_START_Y + row * (KEY_H + KEY_GAP);
// Calculate key width and starting X for this row
int totalW = numKeys * KEY_W + (numKeys - 1) * KEY_GAP;
int startX = (128 - totalW) / 2;
for (int k = 0; k < numKeys; k++) {
int kx = startX + k * (KEY_W + KEY_GAP);
char ch = layout[row][k];
// Draw key background (inverted for special keys)
bool special = (ch == '<' || ch == '^' || ch == '~' || ch == '>' || ch == '\x01');
if (special) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(kx, rowY + 1, KEY_W, KEY_H - 1);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
display.drawRect(kx, rowY + 1, KEY_W, KEY_H - 1);
}
// Draw key label
char keyLabel[2] = { ch, '\0' };
// Remap special chars to display labels
if (ch == '<') keyLabel[0] = '<'; // Backspace
if (ch == '^') keyLabel[0] = '^'; // Shift
if (ch == '>') keyLabel[0] = '>'; // Enter
if (ch == '~') {
// Space key — don't draw individual label
} else if (ch == '\x01') {
// Symbol toggle in row — show "ab" hint
int lx = kx + KEY_W / 2 - display.getTextWidth("ab") / 2;
display.setCursor(lx, rowY + 2);
display.print("ab");
} else {
int lx = kx + KEY_W / 2 - display.getTextWidth(keyLabel) / 2;
display.setCursor(lx, rowY + 2);
display.print(keyLabel);
}
// Restore color
display.setColor(DisplayDriver::LIGHT);
}
}
// Draw row 4 with variable-width keys
int r4y = KEY_START_Y + 3 * (KEY_H + KEY_GAP);
drawRow4(display, r4y);
// Shift/symbol indicator
display.setTextSize(0);
display.setColor(DisplayDriver::GREEN);
if (_shifted) {
display.setCursor(2, 126);
display.print("SHIFT");
} else if (_symbols) {
display.setCursor(2, 126);
display.print("123");
}
}
// --- Handle touch tap (virtual coordinates) ---
// Returns true if the tap was consumed
bool handleTap(int vx, int vy) {
if (_status != VKB_EDITING) return false;
if (_emojiMode) return handleEmojiTap(vx, vy);
// Check keyboard rows 0-2
const char* const* layout = getLayout();
for (int row = 0; row < 3; row++) {
int numKeys = strlen(layout[row]);
int rowY = KEY_START_Y + row * (KEY_H + KEY_GAP);
if (vy < rowY || vy >= rowY + KEY_H) continue;
int totalW = numKeys * KEY_W + (numKeys - 1) * KEY_GAP;
int startX = (128 - totalW) / 2;
for (int k = 0; k < numKeys; k++) {
int kx = startX + k * (KEY_W + KEY_GAP);
if (vx >= kx && vx < kx + KEY_W) {
char ch = layout[row][k];
processKey(ch);
return true;
}
}
return true; // Tap was in row area but between keys — consume
}
// Check row 4 (variable width keys)
int r4y = KEY_START_Y + 3 * (KEY_H + KEY_GAP);
if (vy >= r4y && vy < r4y + KEY_H) {
return handleRow4Tap(vx);
}
return false;
}
// Swipe up on keyboard = cancel
void cancel() { _status = VKB_CANCELLED; }
// --- Feed a raw ASCII character from an external physical keyboard ---
// Maps standard ASCII control chars to internal VKB actions.
// Returns true if the character was consumed.
#ifdef MECK_CARDKB
bool feedChar(char c) {
if (_status != VKB_EDITING) return false;
switch (c) {
case '\r': processKey('>'); return true; // Enter → submit
case '\b': processKey('<'); return true; // Backspace
case 0x7F: processKey('<'); return true; // Delete → backspace
case 0x1B: _status = VKB_CANCELLED; return true; // ESC → cancel
case ' ': processKey('~'); return true; // Space
default:
// Printable ASCII → insert directly
if (c >= 0x20 && c <= 0x7E) {
if (_textLen < _maxLen) {
_text[_textLen++] = c;
_text[_textLen] = '\0';
}
return true;
}
return false; // Non-printable / nav keys — not consumed
}
}
#endif
private:
VKBStatus _status;
VKBPurpose _purpose;
int _contextIdx;
char _text[MAX_TEXT + 1];
int _textLen;
int _maxLen;
char _label[40];
bool _shifted;
bool _symbols;
bool _emojiMode;
int _emojiScroll;
// Emoji grid constants (virtual coords)
static const int EMJ_COLS = 8;
static const int EMJ_CELL = 15; // 12px sprite + 3px gap
static const int EMJ_GRID_X = 4;
static const int EMJ_GRID_Y = 34;
static const int EMJ_VIS_ROWS = 5;
int emojiTotalRows() const { return (EMOJI_COUNT + EMJ_COLS - 1) / EMJ_COLS; }
int emojiMaxScroll() const { int m = emojiTotalRows() - EMJ_VIS_ROWS; return m < 0 ? 0 : m; }
void renderEmojiGrid(DisplayDriver& display) {
display.setTextSize(0);
for (int vr = 0; vr < EMJ_VIS_ROWS; vr++) {
int absRow = _emojiScroll + vr;
if (absRow >= emojiTotalRows()) break;
for (int col = 0; col < EMJ_COLS; col++) {
int idx = absRow * EMJ_COLS + col;
if (idx >= EMOJI_COUNT) break;
int cx = EMJ_GRID_X + col * EMJ_CELL;
int cy = EMJ_GRID_Y + vr * EMJ_CELL;
display.setColor(DisplayDriver::LIGHT);
const uint8_t* sprite = (const uint8_t*)pgm_read_ptr(&EMOJI_SPRITES_LG[idx]);
if (sprite) {
display.drawXbm(cx + 1, cy + 1, sprite, EMOJI_LG_W, EMOJI_LG_H);
}
}
}
// Footer: [Back] [▲] page/total [▼]
int fy = EMJ_GRID_Y + EMJ_VIS_ROWS * EMJ_CELL + 2;
display.setColor(DisplayDriver::LIGHT);
display.drawRect(0, fy - 1, 128, 1);
// Back button (inverted)
display.fillRect(4, fy + 1, 30, 12);
display.setColor(DisplayDriver::DARK);
int bw = display.getTextWidth("Back");
display.setCursor(4 + (30 - bw) / 2, fy + 2);
display.print("Back");
display.setColor(DisplayDriver::LIGHT);
// Scroll arrows (only if scrollable)
if (emojiTotalRows() > EMJ_VIS_ROWS) {
// Up arrow
if (_emojiScroll > 0) {
display.fillRect(50, fy + 1, 12, 12);
display.setColor(DisplayDriver::DARK);
display.setCursor(53, fy + 2);
display.print("^");
display.setColor(DisplayDriver::LIGHT);
}
// Page info
char pg[8];
snprintf(pg, sizeof(pg), "%d/%d", _emojiScroll + 1, emojiMaxScroll() + 1);
int pw = display.getTextWidth(pg);
display.setCursor(75 - pw / 2, fy + 2);
display.print(pg);
// Down arrow
if (_emojiScroll < emojiMaxScroll()) {
display.fillRect(90, fy + 1, 12, 12);
display.setColor(DisplayDriver::DARK);
display.setCursor(93, fy + 2);
display.print("v");
display.setColor(DisplayDriver::LIGHT);
}
}
}
bool handleEmojiTap(int vx, int vy) {
int fy = EMJ_GRID_Y + EMJ_VIS_ROWS * EMJ_CELL + 2;
// Footer area
if (vy >= fy) {
if (vx >= 4 && vx < 34) {
// Back button
_emojiMode = false;
return true;
}
if (vx >= 50 && vx < 62 && _emojiScroll > 0) {
_emojiScroll--;
return true;
}
if (vx >= 90 && vx < 102 && _emojiScroll < emojiMaxScroll()) {
_emojiScroll++;
return true;
}
return true; // Consume tap in footer
}
// Grid area
if (vy >= EMJ_GRID_Y && vy < EMJ_GRID_Y + EMJ_VIS_ROWS * EMJ_CELL) {
int col = (vx - EMJ_GRID_X) / EMJ_CELL;
int vr = (vy - EMJ_GRID_Y) / EMJ_CELL;
if (col < 0 || col >= EMJ_COLS || vr < 0 || vr >= EMJ_VIS_ROWS) return true;
int idx = (_emojiScroll + vr) * EMJ_COLS + col;
if (idx >= 0 && idx < EMOJI_COUNT) {
insertEmoji(idx);
_emojiMode = false;
}
return true;
}
return true; // Consume any tap while in emoji mode
}
void insertEmoji(int idx) {
// Insert as UTF-8 directly (not escape bytes) so sent messages are valid
uint8_t utf8[8];
int len = emojiEncodeUtf8(EMOJI_CODEPOINTS[idx].cp, utf8);
if (EMOJI_CODEPOINTS[idx].cp2 != 0)
len += emojiEncodeUtf8(EMOJI_CODEPOINTS[idx].cp2, utf8 + len);
if (_textLen + len > _maxLen) return;
memcpy(_text + _textLen, utf8, len);
_textLen += len;
_text[_textLen] = '\0';
}
// Render text field with inline emoji sprites (10×10)
void renderTextField(DisplayDriver& display) {
// Convert UTF-8 emoji to escape bytes for sprite lookup
char sanitized[MAX_TEXT + 1];
emojiSanitize(_text, sanitized, sizeof(sanitized));
int x = 2;
int maxX = 124;
display.setColor(DisplayDriver::LIGHT);
display.setTextSize(0);
for (int i = 0; sanitized[i] && x < maxX; i++) {
uint8_t b = (uint8_t)sanitized[i];
if (b == EMOJI_PAD_BYTE) continue;
if (isEmojiEscape(b)) {
const uint8_t* sprite = getEmojiSpriteSm(b);
if (sprite && x + EMOJI_SM_W < maxX) {
display.drawXbm(x, 14, sprite, EMOJI_SM_W, EMOJI_SM_H);
x += EMOJI_SM_W + 1;
}
} else {
char ch[2] = { (char)b, '\0' };
display.setCursor(x, 12);
display.print(ch);
x += display.getTextWidth(ch);
}
}
// Blinking cursor
if (x < maxX) {
display.setCursor(x, 12);
display.print("_");
}
}
// Layout constants (virtual coords)
static const int KEY_W = 11;
static const int KEY_H = 19;
static const int KEY_GAP = 1;
static const int KEY_START_Y = 34;
// Key layouts — rows 0-2 as char arrays
// Special: ^ = shift, < = backspace, \x01 = sym toggle, \x02 = emoji, > = enter, ~ = space
const char* const* getLayout() const {
static const char* const lower[3] = { "qwertyuiop", "asdfghjkl", "^zxcvbnm<" };
static const char* const upper[3] = { "QWERTYUIOP", "ASDFGHJKL", "^ZXCVBNM<" };
static const char* const syms[3] = { "1234567890", "-/:;()@$&#", "\x01.,?!'\"_<" };
return _symbols ? syms : (_shifted ? upper : lower);
}
// Row 4: variable-width keys [#/ABC] [,] [$] [SPACE] [.] [Enter]
// Defined by physical zones, not the char-array approach
struct R4Key { int x; int w; char ch; const char* label; };
void drawRow4(DisplayDriver& display, int y) {
const R4Key keys[] = {
{ 4, 20, '\x01', _symbols ? "ABC" : "123" },
{ 26, 11, ',', "," },
{ 39, 11, '\x02', "$" },
{ 52, 37, '~', "space" },
{ 91, 11, '.', "." },
{ 104, 20, '>', "Send" }
};
for (int i = 0; i < 6; i++) {
bool special = (keys[i].ch == '\x01' || keys[i].ch == '>' || keys[i].ch == '\x02');
if (special) {
display.setColor(DisplayDriver::LIGHT);
display.fillRect(keys[i].x, y + 1, keys[i].w, KEY_H - 1);
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
display.drawRect(keys[i].x, y + 1, keys[i].w, KEY_H - 1);
}
// Center label in key
display.setTextSize(0);
int lw = display.getTextWidth(keys[i].label);
int lx = keys[i].x + (keys[i].w - lw) / 2;
display.setCursor(lx, y + 2);
display.print(keys[i].label);
display.setColor(DisplayDriver::LIGHT);
}
}
bool handleRow4Tap(int vx) {
const R4Key keys[] = {
{ 4, 20, '\x01', nullptr },
{ 26, 11, ',', nullptr },
{ 39, 11, '\x02', nullptr },
{ 52, 37, '~', nullptr },
{ 91, 11, '.', nullptr },
{ 104, 20, '>', nullptr }
};
for (int i = 0; i < 6; i++) {
if (vx >= keys[i].x && vx < keys[i].x + keys[i].w) {
processKey(keys[i].ch);
return true;
}
}
return true; // Consume tap in row area
}
void processKey(char ch) {
if (ch == '^') {
// Shift toggle
_shifted = !_shifted;
_symbols = false;
} else if (ch == '\x01') {
// Symbol/letter toggle
_symbols = !_symbols;
_shifted = false;
} else if (ch == '\x02') {
// Emoji picker toggle
_emojiMode = !_emojiMode;
_emojiScroll = 0;
} else if (ch == '<') {
// Backspace — UTF-8 aware (walk back past continuation bytes 10xxxxxx)
if (_textLen > 0) {
_textLen--;
while (_textLen > 0 && ((uint8_t)_text[_textLen] & 0xC0) == 0x80) {
_textLen--;
}
_text[_textLen] = '\0';
}
} else if (ch == '>') {
// Enter/Send
_status = VKB_SUBMITTED;
} else if (ch == '~') {
// Space
if (_textLen < _maxLen) {
_text[_textLen++] = ' ';
_text[_textLen] = '\0';
}
} else {
// Regular character
if (_textLen < _maxLen) {
_text[_textLen++] = ch;
_text[_textLen] = '\0';
// Auto-unshift after typing one character
if (_shifted) _shifted = false;
}
}
}
};
#endif // VIRTUAL_KEYBOARD_H
#endif // LilyGo_T5S3_EPaper_Pro
+372
View File
@@ -0,0 +1,372 @@
#pragma once
// =============================================================================
// ApnDatabase.h - Embedded APN Lookup Table
//
// Maps MCC/MNC (Mobile Country Code / Mobile Network Code) to default APN
// settings for common carriers worldwide. Compiled directly into flash (~3KB)
// so users never need to manually install a lookup file.
//
// The modem queries IMSI via AT+CIMI to extract MCC (3 digits) + MNC (2-3
// digits), then looks up the APN here. If not found, falls back to the
// modem's existing PDP context (AT+CGDCONT?) or user-configured APN.
//
// To add a carrier: append to APN_DATABASE[] with the MCC+MNC as a single
// integer. MNC can be 2 or 3 digits:
// MCC=310, MNC=260 → mccmnc = 310260
// MCC=505, MNC=01 → mccmnc = 50501
//
// Guard: HAS_4G_MODEM
// =============================================================================
#ifdef HAS_4G_MODEM
#ifndef APN_DATABASE_H
#define APN_DATABASE_H
struct ApnEntry {
uint32_t mccmnc; // MCC+MNC as integer (e.g. 310260 for T-Mobile US)
const char* apn; // APN string
const char* carrier; // Human-readable carrier name (for debug/display)
};
// ---------------------------------------------------------------------------
// APN Database — sorted by MCC for binary search potential (not required)
//
// Sources: carrier documentation, GSMA databases, community wikis.
// This covers ~120 major carriers across key regions. Users with less
// common carriers can set APN manually in Settings.
// ---------------------------------------------------------------------------
static const ApnEntry APN_DATABASE[] = {
// =========================================================================
// Australia (MCC 505)
// =========================================================================
{ 50501, "telstra.internet", "Telstra" },
{ 50502, "yesinternet", "Optus" },
{ 50503, "vfinternet.au", "Vodafone AU" },
{ 50506, "3netaccess", "Three AU" },
{ 50507, "telstra.internet", "Vodafone AU (MVNO)" }, // Many MVNOs on Telstra
{ 50510, "telstra.internet", "Norfolk Tel" },
{ 50512, "3netaccess", "Amaysim" }, // Optus MVNO
{ 50514, "yesinternet", "Aussie Broadband" }, // Optus MVNO
{ 50590, "yesinternet", "Optus MVNO" },
// =========================================================================
// New Zealand (MCC 530)
// =========================================================================
{ 53001, "internet", "Vodafone NZ" },
{ 53005, "internet", "Spark NZ" },
{ 53024, "internet", "2degrees" },
// =========================================================================
// United States (MCC 310, 311, 312, 313, 316)
// =========================================================================
{ 310012, "fast.t-mobile.com", "Verizon (old)" },
{ 310026, "fast.t-mobile.com", "T-Mobile US" },
{ 310030, "fast.t-mobile.com", "T-Mobile US" },
{ 310032, "fast.t-mobile.com", "T-Mobile US" },
{ 310060, "fast.t-mobile.com", "T-Mobile US" },
{ 310160, "fast.t-mobile.com", "T-Mobile US" },
{ 310200, "fast.t-mobile.com", "T-Mobile US" },
{ 310210, "fast.t-mobile.com", "T-Mobile US" },
{ 310220, "fast.t-mobile.com", "T-Mobile US" },
{ 310230, "fast.t-mobile.com", "T-Mobile US" },
{ 310240, "fast.t-mobile.com", "T-Mobile US" },
{ 310250, "fast.t-mobile.com", "T-Mobile US" },
{ 310260, "fast.t-mobile.com", "T-Mobile US" },
{ 310270, "fast.t-mobile.com", "T-Mobile US" },
{ 310310, "fast.t-mobile.com", "T-Mobile US" },
{ 310490, "fast.t-mobile.com", "T-Mobile US" },
{ 310530, "fast.t-mobile.com", "T-Mobile US" },
{ 310580, "fast.t-mobile.com", "T-Mobile US" },
{ 310660, "fast.t-mobile.com", "T-Mobile US" },
{ 310800, "fast.t-mobile.com", "T-Mobile US" },
{ 311480, "vzwinternet", "Verizon" },
{ 311481, "vzwinternet", "Verizon" },
{ 311482, "vzwinternet", "Verizon" },
{ 311483, "vzwinternet", "Verizon" },
{ 311484, "vzwinternet", "Verizon" },
{ 311489, "vzwinternet", "Verizon" },
{ 310410, "fast.t-mobile.com", "AT&T (migrated)" },
{ 310120, "att.mvno", "AT&T (Sprint)" },
{ 312530, "iot.1nce.net", "1NCE IoT" },
{ 310120, "tfdata", "Tracfone" },
// =========================================================================
// Canada (MCC 302)
// =========================================================================
{ 30220, "internet.com", "Rogers" },
{ 30221, "internet.com", "Rogers" },
{ 30237, "internet.com", "Rogers" },
{ 30272, "internet.com", "Rogers" },
{ 30234, "sp.telus.com", "Telus" },
{ 30286, "sp.telus.com", "Telus" },
{ 30236, "sp.telus.com", "Telus" },
{ 30261, "sp.bell.ca", "Bell" },
{ 30263, "sp.bell.ca", "Bell" },
{ 30267, "sp.bell.ca", "Bell" },
{ 30268, "fido-core-appl1.apn", "Fido" },
{ 30278, "internet.com", "SaskTel" },
{ 30266, "sp.mb.com", "MTS" },
// =========================================================================
// United Kingdom (MCC 234, 235)
// =========================================================================
{ 23410, "o2-internet", "O2 UK" },
{ 23415, "three.co.uk", "Vodafone UK" },
{ 23420, "three.co.uk", "Three UK" },
{ 23430, "everywhere", "EE" },
{ 23431, "everywhere", "EE" },
{ 23432, "everywhere", "EE" },
{ 23433, "everywhere", "EE" },
{ 23450, "data.lycamobile.co.uk","Lycamobile UK" },
{ 23486, "three.co.uk", "Three UK" },
// =========================================================================
// Germany (MCC 262)
// =========================================================================
{ 26201, "internet.t-mobile", "Telekom DE" },
{ 26202, "web.vodafone.de", "Vodafone DE" },
{ 26203, "internet", "O2 DE" },
{ 26207, "internet", "O2 DE" },
// =========================================================================
// France (MCC 208)
// =========================================================================
{ 20801, "orange", "Orange FR" },
{ 20810, "sl2sfr", "SFR" },
{ 20815, "free", "Free Mobile" },
{ 20820, "ofnew.fr", "Bouygues" },
// =========================================================================
// Italy (MCC 222)
// =========================================================================
{ 22201, "mobile.vodafone.it", "TIM" },
{ 22210, "mobile.vodafone.it", "Vodafone IT" },
{ 22250, "internet.it", "Iliad IT" },
{ 22288, "internet.wind", "WindTre" },
{ 22299, "internet.wind", "WindTre" },
// =========================================================================
// Spain (MCC 214)
// =========================================================================
{ 21401, "internet", "Vodafone ES" },
{ 21403, "internet", "Orange ES" },
{ 21404, "internet", "Yoigo" },
{ 21407, "internet", "Movistar" },
// =========================================================================
// Netherlands (MCC 204)
// =========================================================================
{ 20404, "internet", "Vodafone NL" },
{ 20408, "internet", "KPN" },
{ 20412, "internet", "Telfort" },
{ 20416, "internet", "T-Mobile NL" },
{ 20420, "internet", "T-Mobile NL" },
// =========================================================================
// Sweden (MCC 240)
// =========================================================================
{ 24001, "internet.telia.se", "Telia SE" },
{ 24002, "tre.se", "Three SE" },
{ 24007, "internet.telenor.se", "Telenor SE" },
// =========================================================================
// Norway (MCC 242)
// =========================================================================
{ 24201, "internet.telenor.no", "Telenor NO" },
{ 24202, "internet.netcom.no", "Telia NO" },
// =========================================================================
// Denmark (MCC 238)
// =========================================================================
{ 23801, "internet", "TDC" },
{ 23802, "internet", "Telenor DK" },
{ 23806, "internet", "Three DK" },
{ 23820, "internet", "Telia DK" },
// =========================================================================
// Switzerland (MCC 228)
// =========================================================================
{ 22801, "gprs.swisscom.ch", "Swisscom" },
{ 22802, "internet", "Sunrise" },
{ 22803, "internet", "Salt" },
// =========================================================================
// Austria (MCC 232)
// =========================================================================
{ 23201, "a1.net", "A1" },
{ 23203, "web.one.at", "Three AT" },
{ 23205, "web", "T-Mobile AT" },
// =========================================================================
// Japan (MCC 440, 441)
// =========================================================================
{ 44010, "spmode.ne.jp", "NTT Docomo" },
{ 44020, "plus.4g", "SoftBank" },
{ 44051, "au.au-net.ne.jp", "KDDI au" },
// =========================================================================
// South Korea (MCC 450)
// =========================================================================
{ 45005, "lte.sktelecom.com", "SK Telecom" },
{ 45006, "lte.ktfwing.com", "KT" },
{ 45008, "lte.lguplus.co.kr", "LG U+" },
// =========================================================================
// India (MCC 404, 405)
// =========================================================================
{ 40445, "airtelgprs.com", "Airtel" },
{ 40410, "airtelgprs.com", "Airtel" },
{ 40411, "www", "Vodafone IN (Vi)" },
{ 40413, "www", "Vodafone IN (Vi)" },
{ 40486, "www", "Vodafone IN (Vi)" },
{ 40553, "jionet", "Jio" },
{ 40554, "jionet", "Jio" },
{ 40512, "bsnlnet", "BSNL" },
// =========================================================================
// Singapore (MCC 525)
// =========================================================================
{ 52501, "internet", "Singtel" },
{ 52503, "internet", "M1" },
{ 52505, "internet", "StarHub" },
// =========================================================================
// Hong Kong (MCC 454)
// =========================================================================
{ 45400, "internet", "CSL" },
{ 45406, "internet", "SmarTone" },
{ 45412, "internet", "CMHK" },
// =========================================================================
// Brazil (MCC 724)
// =========================================================================
{ 72405, "claro.com.br", "Claro BR" },
{ 72406, "wap.oi.com.br", "Vivo" },
{ 72410, "wap.oi.com.br", "Vivo" },
{ 72411, "wap.oi.com.br", "Vivo" },
{ 72415, "internet.tim.br", "TIM BR" },
{ 72431, "gprs.oi.com.br", "Oi" },
// =========================================================================
// Mexico (MCC 334)
// =========================================================================
{ 33402, "internet.itelcel.com","Telcel" },
{ 33403, "internet.movistar.mx","Movistar MX" },
{ 33404, "internet.att.net.mx", "AT&T MX" },
// =========================================================================
// South Africa (MCC 655)
// =========================================================================
{ 65501, "internet", "Vodacom" },
{ 65502, "internet", "Telkom ZA" },
{ 65507, "internet", "Cell C" },
{ 65510, "internet", "MTN ZA" },
// =========================================================================
// Philippines (MCC 515)
// =========================================================================
{ 51502, "internet.globe.com.ph","Globe" },
{ 51503, "internet", "Smart" },
{ 51505, "internet", "Sun Cellular" },
// =========================================================================
// Thailand (MCC 520)
// =========================================================================
{ 52001, "internet", "AIS" },
{ 52004, "internet", "TrueMove" },
{ 52005, "internet", "dtac" },
// =========================================================================
// Indonesia (MCC 510)
// =========================================================================
{ 51001, "internet", "Telkomsel" },
{ 51010, "internet", "Telkomsel" },
{ 51011, "3gprs", "XL Axiata" },
{ 51028, "3gprs", "XL Axiata (Axis)" },
// =========================================================================
// Malaysia (MCC 502)
// =========================================================================
{ 50212, "celcom3g", "Celcom" },
{ 50213, "celcom3g", "Celcom" },
{ 50216, "internet", "Digi" },
{ 50219, "celcom3g", "Celcom" },
// =========================================================================
// Czech Republic (MCC 230)
// =========================================================================
{ 23001, "internet.t-mobile.cz","T-Mobile CZ" },
{ 23002, "internet", "O2 CZ" },
{ 23003, "internet.vodafone.cz","Vodafone CZ" },
// =========================================================================
// Poland (MCC 260)
// =========================================================================
{ 26001, "internet", "Plus PL" },
{ 26002, "internet", "T-Mobile PL" },
{ 26003, "internet", "Orange PL" },
{ 26006, "internet", "Play" },
// =========================================================================
// Portugal (MCC 268)
// =========================================================================
{ 26801, "internet", "Vodafone PT" },
{ 26803, "internet", "NOS" },
{ 26806, "internet", "MEO" },
// =========================================================================
// Ireland (MCC 272)
// =========================================================================
{ 27201, "internet", "Vodafone IE" },
{ 27202, "open.internet", "Three IE" },
{ 27205, "three.ie", "Three IE" },
// =========================================================================
// IoT / Global SIMs
// =========================================================================
{ 901028, "iot.1nce.net", "1NCE (IoT)" },
{ 90143, "hologram", "Hologram" },
};
#define APN_DATABASE_SIZE (sizeof(APN_DATABASE) / sizeof(APN_DATABASE[0]))
// ---------------------------------------------------------------------------
// Lookup function — returns nullptr if not found
// ---------------------------------------------------------------------------
inline const ApnEntry* apnLookup(uint32_t mccmnc) {
for (int i = 0; i < (int)APN_DATABASE_SIZE; i++) {
if (APN_DATABASE[i].mccmnc == mccmnc) {
return &APN_DATABASE[i];
}
}
return nullptr;
}
// Parse IMSI string into MCC+MNC. Tries 3-digit MNC first (6-digit mccmnc),
// falls back to 2-digit MNC (5-digit mccmnc) if not found.
inline const ApnEntry* apnLookupFromIMSI(const char* imsi) {
if (!imsi || strlen(imsi) < 5) return nullptr;
// Extract MCC (always 3 digits)
uint32_t mcc = (imsi[0] - '0') * 100 + (imsi[1] - '0') * 10 + (imsi[2] - '0');
// Try 3-digit MNC first (more specific)
if (strlen(imsi) >= 6) {
uint32_t mnc3 = (imsi[3] - '0') * 100 + (imsi[4] - '0') * 10 + (imsi[5] - '0');
uint32_t mccmnc6 = mcc * 1000 + mnc3;
const ApnEntry* entry = apnLookup(mccmnc6);
if (entry) return entry;
}
// Fall back to 2-digit MNC
uint32_t mnc2 = (imsi[3] - '0') * 10 + (imsi[4] - '0');
uint32_t mccmnc5 = mcc * 100 + mnc2;
return apnLookup(mccmnc5);
}
#endif // APN_DATABASE_H
#endif // HAS_4G_MODEM
+227
View File
@@ -0,0 +1,227 @@
#pragma once
// =============================================================================
// CellularMQTT — A7682E Modem + MQTT via native AT commands
// =============================================================================
#ifdef HAS_4G_MODEM
#ifndef CELLULAR_MQTT_H
#define CELLULAR_MQTT_H
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include "variant.h"
#include "ApnDatabase.h"
// ---------------------------------------------------------------------------
// Configuration
// ---------------------------------------------------------------------------
#define MQTT_TOPIC_MAX 80
#define MQTT_PAYLOAD_MAX 512
#define MQTT_CLIENT_ID_MAX 32
#define CMD_QUEUE_SIZE 4
#define RSP_QUEUE_SIZE 4
#define TELEMETRY_INTERVAL 60000
#define CELL_TASK_PRIORITY 1
#define CELL_TASK_STACK_SIZE 8192
#define CELL_TASK_CORE 0
#define MQTT_RECONNECT_MIN 5000
#define MQTT_RECONNECT_MAX 300000
#define MQTT_PUB_FAIL_MAX 5
#define OTA_CHUNK_SIZE 1024
// ---------------------------------------------------------------------------
// State machine
// ---------------------------------------------------------------------------
enum class CellState : uint8_t {
OFF,
POWERING_ON,
INITIALIZING,
REGISTERING,
DATA_ACTIVATING,
MQTT_STARTING,
MQTT_CONNECTING,
CONNECTED,
RECONNECTING,
OTA_IN_PROGRESS,
ERROR
};
// ---------------------------------------------------------------------------
// Queue message types
// ---------------------------------------------------------------------------
struct MQTTCommand {
char cmd[MQTT_PAYLOAD_MAX];
};
struct MQTTResponse {
char topic[MQTT_TOPIC_MAX];
char payload[MQTT_PAYLOAD_MAX];
};
// ---------------------------------------------------------------------------
// MQTT config (loaded from SD: /remote/mqtt.cfg)
// ---------------------------------------------------------------------------
struct MQTTConfig {
char broker[80];
uint16_t port;
char username[40];
char password[40];
char deviceId[MQTT_CLIENT_ID_MAX];
};
// ---------------------------------------------------------------------------
// Telemetry snapshot
// ---------------------------------------------------------------------------
struct TelemetryData {
uint32_t uptime_secs;
uint16_t battery_mv;
uint8_t battery_pct;
int16_t temperature;
int csq;
uint8_t neighbor_count;
float freq;
float bw;
uint8_t sf;
uint8_t cr;
uint8_t tx_power;
char node_name[32];
char apn[40];
char oper[24];
bool mqtt_connected;
};
// ---------------------------------------------------------------------------
// CellularMQTT class
// ---------------------------------------------------------------------------
class CellularMQTT {
public:
void begin();
void stop();
// --- Queue API (called from main loop) ---
bool recvCommand(MQTTCommand& out);
bool sendResponse(const char* topic, const char* payload);
// --- Telemetry ---
void updateTelemetry(const TelemetryData& data);
// --- OTA ---
void requestOTA(const char* url);
bool isOTAInProgress() const { return _state == CellState::OTA_IN_PROGRESS; }
// --- State queries ---
CellState getState() const { return _state; }
bool isConnected() const { return _state == CellState::CONNECTED; }
int getCSQ() const { return _csq; }
int getSignalBars() const;
const char* getOperator() const { return _operator; }
const char* getIPAddress() const { return _ipAddr; }
const char* getBroker() const { return _config.broker; }
const char* getAPN() const { return _apn; }
const char* getRspTopic() const { return _topicRsp; }
const char* stateString() const;
uint32_t getLastCmdTime() const { return _lastCmdTime; }
static bool loadConfig(MQTTConfig& cfg);
private:
volatile CellState _state = CellState::OFF;
volatile int _csq = 99;
volatile uint32_t _lastCmdTime = 0;
char _operator[24] = {0};
char _ipAddr[20] = {0};
char _imei[20] = {0};
char _imsi[20] = {0};
char _apn[64] = {0};
MQTTConfig _config = {};
TelemetryData _telemetry = {};
SemaphoreHandle_t _telemetryMutex = nullptr;
char _topicCmd[MQTT_TOPIC_MAX] = {0};
char _topicRsp[MQTT_TOPIC_MAX] = {0};
char _topicTelem[MQTT_TOPIC_MAX] = {0};
char _topicOta[MQTT_TOPIC_MAX] = {0};
TaskHandle_t _taskHandle = nullptr;
QueueHandle_t _cmdQueue = nullptr;
QueueHandle_t _rspQueue = nullptr;
SemaphoreHandle_t _uartMutex = nullptr;
uint8_t _pubFailCount = 0;
static const int AT_BUF_SIZE = 512;
char _atBuf[AT_BUF_SIZE];
static const int URC_BUF_SIZE = 600;
char _urcBuf[URC_BUF_SIZE];
int _urcPos = 0;
enum MqttRxState { RX_IDLE, RX_WAIT_TOPIC, RX_WAIT_PAYLOAD };
MqttRxState _rxState = RX_IDLE;
int _rxTopicLen = 0;
int _rxPayloadLen = 0;
char _rxTopic[MQTT_TOPIC_MAX];
char _rxPayload[MQTT_PAYLOAD_MAX];
uint32_t _reconnectDelay = MQTT_RECONNECT_MIN;
// OTA state
volatile bool _otaPending = false;
char _otaUrl[256] = {0};
// --- Modem UART helpers ---
bool modemPowerOn();
bool sendAT(const char* cmd, const char* expect, uint32_t timeout_ms = 2000);
bool waitResponse(const char* expect, uint32_t timeout_ms, char* buf = nullptr, size_t bufLen = 0);
bool waitPrompt(uint32_t timeout_ms = 5000);
void drainURCs();
void processURCLine(const char* line);
// --- Data connection ---
void resolveAPN();
bool activateData();
// --- MQTT operations ---
bool mqttStart();
bool mqttConnect();
bool mqttSubscribe(const char* topic);
bool mqttPublish(const char* topic, const char* payload);
void mqttDisconnect();
// --- URC handlers ---
void handleMqttRxStart(const char* line);
void handleMqttRxTopic(const char* data, int len);
void handleMqttRxPayload(const char* data, int len);
void handleMqttRxEnd();
void handleMqttConnLost(const char* line);
// --- OTA operations (modem task only) ---
void performOTA();
int httpGet(const char* url);
bool httpReadChunk(int offset, int len, uint8_t* dest, int* bytesRead);
void httpTerm();
int readRawBytes(uint8_t* dest, int count, uint32_t timeout_ms);
// --- Task ---
static void taskEntry(void* param);
void taskLoop();
};
extern CellularMQTT cellularMQTT;
#endif // CELLULAR_MQTT_H
#endif // HAS_4G_MODEM
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -68,11 +68,11 @@ struct NeighbourInfo {
};
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "30 Nov 2025"
#define FIRMWARE_BUILD_DATE "3 April 2026"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "v1.11.0"
#define FIRMWARE_VERSION "v0.2"
#endif
#define FIRMWARE_ROLE "repeater"
+126 -25
View File
@@ -2,7 +2,21 @@
#include <Arduino.h>
#include <helpers/CommonCLI.h>
#define AUTO_OFF_MILLIS 20000 // 20 seconds
#ifdef HAS_4G_MODEM
#include "CellularMQTT.h"
#endif
#ifdef MECK_WIFI_REMOTE
#include "WiFiMQTT.h"
#endif
#if defined(HAS_4G_MODEM) || defined(MECK_WIFI_REMOTE)
#define AUTO_OFF_DISABLED true
#else
#define AUTO_OFF_DISABLED false
#endif
#define AUTO_OFF_MILLIS 20000 // 20 seconds (ignored when AUTO_OFF_DISABLED)
#define BOOT_SCREEN_MILLIS 4000 // 4 seconds
// 'meshcore', 128x13px
@@ -28,55 +42,144 @@ void UITask::begin(NodePrefs* node_prefs, const char* build_date, const char* fi
_node_prefs = node_prefs;
_display->turnOn();
// strip off dash and commit hash by changing dash to null terminator
// e.g: v1.2.3-abcdef -> v1.2.3
char *version = strdup(firmware_version);
char *dash = strchr(version, '-');
if(dash){
*dash = 0;
}
if (dash) *dash = 0;
// v1.2.3 (1 Jan 2025)
sprintf(_version_info, "%s (%s)", version, build_date);
snprintf(_version_info, sizeof(_version_info), "%s (%s)", version, build_date);
free(version);
}
void UITask::renderCurrScreen() {
char tmp[80];
if (millis() < BOOT_SCREEN_MILLIS) { // boot screen
// meshcore logo
if (millis() < BOOT_SCREEN_MILLIS) {
// Boot screen — logo + version
_display->setColor(DisplayDriver::BLUE);
int logoWidth = 128;
_display->drawXbm((_display->width() - logoWidth) / 2, 3, meshcore_logo, logoWidth, 13);
// version info
_display->setColor(DisplayDriver::LIGHT);
_display->setTextSize(1);
uint16_t versionWidth = _display->getTextWidth(_version_info);
_display->setCursor((_display->width() - versionWidth) / 2, 22);
_display->print(_version_info);
// node type
#if defined(HAS_4G_MODEM)
const char* node_type = "< Remote Repeater >";
#elif defined(MECK_WIFI_REMOTE)
const char* node_type = "< WiFi Repeater >";
#else
const char* node_type = "< Repeater >";
#endif
uint16_t typeWidth = _display->getTextWidth(node_type);
_display->setCursor((_display->width() - typeWidth) / 2, 35);
_display->print(node_type);
} else { // home screen
// node name
} else {
// Home screen — node info + connection status
_display->setCursor(0, 0);
_display->setTextSize(1);
_display->setColor(DisplayDriver::GREEN);
_display->print(_node_prefs->node_name);
// freq / sf
_display->setCursor(0, 20);
_display->setColor(DisplayDriver::YELLOW);
sprintf(tmp, "FREQ: %06.3f SF%d", _node_prefs->freq, _node_prefs->sf);
_display->print(tmp);
// bw / cr
_display->setCursor(0, 30);
sprintf(tmp, "BW: %03.2f CR: %d", _node_prefs->bw, _node_prefs->cr);
_display->print(tmp);
// --- Cellular status (4G variant) ---
#ifdef HAS_4G_MODEM
int y = 44;
_display->setCursor(0, y);
_display->setColor(DisplayDriver::LIGHT);
sprintf(tmp, "4G: %s", cellularMQTT.stateString());
_display->print(tmp);
y += 10;
_display->setCursor(0, y);
sprintf(tmp, "CSQ: %d (%d bars)", cellularMQTT.getCSQ(), cellularMQTT.getSignalBars());
_display->print(tmp);
y += 10;
const char* oper = cellularMQTT.getOperator();
if (oper[0]) {
_display->setCursor(0, y);
sprintf(tmp, "Op: %.16s", oper);
_display->print(tmp);
y += 10;
}
_display->setCursor(0, y);
_display->setColor(cellularMQTT.isConnected() ? DisplayDriver::GREEN : DisplayDriver::YELLOW);
sprintf(tmp, "MQTT: %s", cellularMQTT.isConnected() ? "Connected" : "---");
_display->print(tmp);
y += 10;
const char* ip4g = cellularMQTT.getIPAddress();
if (ip4g[0]) {
_display->setColor(DisplayDriver::LIGHT);
_display->setCursor(0, y);
sprintf(tmp, "IP: %s", ip4g);
_display->print(tmp);
y += 10;
}
uint32_t upSec = millis() / 1000;
uint32_t upH = upSec / 3600;
uint32_t upM = (upSec % 3600) / 60;
_display->setColor(DisplayDriver::LIGHT);
_display->setCursor(0, y);
sprintf(tmp, "Up: %luh %lum Heap:%dk", upH, upM, ESP.getFreeHeap() / 1024);
_display->print(tmp);
#endif
// --- WiFi status (WiFi variant) ---
#ifdef MECK_WIFI_REMOTE
int y = 44;
_display->setCursor(0, y);
_display->setColor(DisplayDriver::LIGHT);
sprintf(tmp, "WiFi: %s", wifiMQTT.stateString());
_display->print(tmp);
y += 10;
_display->setCursor(0, y);
sprintf(tmp, "RSSI: %d (%d bars)", wifiMQTT.getRSSI(), wifiMQTT.getSignalBars());
_display->print(tmp);
y += 10;
_display->setCursor(0, y);
sprintf(tmp, "SSID: %.16s", wifiMQTT.getSSID());
_display->print(tmp);
y += 10;
_display->setCursor(0, y);
_display->setColor(wifiMQTT.isConnected() ? DisplayDriver::GREEN : DisplayDriver::YELLOW);
sprintf(tmp, "MQTT: %s", wifiMQTT.isConnected() ? "Connected" : "---");
_display->print(tmp);
y += 10;
const char* ipWifi = wifiMQTT.getIPAddress();
if (ipWifi[0]) {
_display->setColor(DisplayDriver::LIGHT);
_display->setCursor(0, y);
sprintf(tmp, "IP: %s", ipWifi);
_display->print(tmp);
y += 10;
}
uint32_t upSec = millis() / 1000;
uint32_t upH = upSec / 3600;
uint32_t upM = (upSec % 3600) / 60;
_display->setColor(DisplayDriver::LIGHT);
_display->setCursor(0, y);
sprintf(tmp, "Up: %luh %lum Heap:%dk", upH, upM, ESP.getFreeHeap() / 1024);
_display->print(tmp);
#endif
}
}
@@ -85,17 +188,15 @@ void UITask::loop() {
if (millis() >= _next_read) {
int btnState = digitalRead(PIN_USER_BTN);
if (btnState != _prevBtnState) {
if (btnState == LOW) { // pressed?
if (_display->isOn()) {
// TODO: any action ?
} else {
if (btnState == LOW) {
if (!_display->isOn()) {
_display->turnOn();
}
_auto_off = millis() + AUTO_OFF_MILLIS; // extend auto-off timer
_auto_off = millis() + AUTO_OFF_MILLIS;
}
_prevBtnState = btnState;
}
_next_read = millis() + 200; // 5 reads per second
_next_read = millis() + 200;
}
#endif
@@ -105,10 +206,10 @@ void UITask::loop() {
renderCurrScreen();
_display->endFrame();
_next_refresh = millis() + 1000; // refresh every second
_next_refresh = millis() + 10000;
}
if (millis() > _auto_off) {
if (!AUTO_OFF_DISABLED && millis() > _auto_off) {
_display->turnOff();
}
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ class UITask {
unsigned long _next_read, _next_refresh, _auto_off;
int _prevBtnState;
NodePrefs* _node_prefs;
char _version_info[32];
char _version_info[48];
void renderCurrScreen();
public:
File diff suppressed because it is too large Load Diff
+198 -8
View File
@@ -1,8 +1,20 @@
#include <Arduino.h> // needed for PlatformIO
#include <Mesh.h>
#include <time.h>
#include "MyMesh.h"
#ifdef HAS_4G_MODEM
#include <SD.h>
#include "CellularMQTT.h"
#endif
#ifdef MECK_WIFI_REMOTE
#if defined(HAS_SDCARD) || defined(SDCARD_CS)
#include <SD.h>
#endif
#include "WiFiMQTT.h"
#endif
#ifdef DISPLAY_CLASS
#include "UITask.h"
static UITask ui_task(display);
@@ -23,6 +35,10 @@ static char command[160];
unsigned long lastActive = 0; // mark last active time
unsigned long nextSleepinSecs = 120; // next sleep in seconds. The first sleep (if enabled) is after 2 minutes from boot
#if (defined(HAS_4G_MODEM) || defined(MECK_WIFI_REMOTE)) && (defined(HAS_SDCARD) || defined(SDCARD_CS))
static bool sdCardReady = false;
#endif
void setup() {
Serial.begin(115200);
delay(1000);
@@ -83,6 +99,72 @@ void setup() {
the_mesh.begin(fs);
// ---------------------------------------------------------------------------
// SD card init — needed for MQTT config on devices with SD slots.
// T-Deck Pro: SD shares display SPI bus (HSPI via displaySpi)
// T5S3: SD shares LoRa SPI bus (SCK=14, MOSI=13, MISO=21)
// Heltec V4 and others without SD: config lives in SPIFFS (already init'd)
// ---------------------------------------------------------------------------
#if (defined(HAS_4G_MODEM) || defined(MECK_WIFI_REMOTE)) && (defined(HAS_SDCARD) || defined(SDCARD_CS))
{
// Deselect all SPI devices before SD init to prevent bus contention
#ifdef SDCARD_CS
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
#endif
#ifdef PIN_DISPLAY_CS
pinMode(PIN_DISPLAY_CS, OUTPUT);
digitalWrite(PIN_DISPLAY_CS, HIGH);
#endif
#ifdef P_LORA_NSS
pinMode(P_LORA_NSS, OUTPUT);
digitalWrite(P_LORA_NSS, HIGH);
#endif
delay(100);
for (int i = 0; i < 3; i++) {
#if defined(LilyGo_T5S3_EPaper_Pro)
// T5S3: SD shares LoRa SPI bus — create local HSPI reference
static SPIClass sdSpi(HSPI);
sdSpi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI, SDCARD_CS);
if (SD.begin(SDCARD_CS, sdSpi, 4000000)) { sdCardReady = true; break; }
#elif defined(SDCARD_CS)
extern SPIClass displaySpi;
if (SD.begin(SDCARD_CS, displaySpi)) { sdCardReady = true; break; }
#else
if (SD.begin(SPI_CS)) { sdCardReady = true; break; }
#endif
delay(200);
}
Serial.printf("SD card: %s\n", sdCardReady ? "ready" : "FAILED");
}
#endif
// Start MQTT backhaul
#ifdef HAS_4G_MODEM
if (sdCardReady) {
cellularMQTT.begin();
Serial.println("Cellular MQTT starting...");
} else {
Serial.println("Cellular MQTT skipped — no SD card for config");
}
#endif
#ifdef MECK_WIFI_REMOTE
#if defined(HAS_SDCARD) || defined(SDCARD_CS)
if (sdCardReady) {
wifiMQTT.begin();
Serial.println("WiFi MQTT starting...");
} else {
Serial.println("WiFi MQTT skipped — no SD card for config");
}
#else
// No SD card slot — config lives in SPIFFS (already initialized above)
wifiMQTT.begin();
Serial.println("WiFi MQTT starting (SPIFFS config)...");
#endif
#endif
#ifdef DISPLAY_CLASS
ui_task.begin(the_mesh.getNodePrefs(), FIRMWARE_BUILD_DATE, FIRMWARE_VERSION);
#endif
@@ -118,6 +200,112 @@ void loop() {
command[0] = 0; // reset command buffer
}
// ---------------------------------------------------------------------------
// MQTT → CLI bridge: process incoming commands from MQTT (cellular)
// ---------------------------------------------------------------------------
#ifdef HAS_4G_MODEM
{
MQTTCommand mqttCmd;
while (cellularMQTT.recvCommand(mqttCmd)) {
Serial.printf("[MQTT] CLI: %s\n", mqttCmd.cmd);
char reply[512];
reply[0] = '\0';
the_mesh.handleCommand((uint32_t)time(nullptr), mqttCmd.cmd, reply);
if (reply[0] == '\0') strcpy(reply, "OK");
cellularMQTT.sendResponse(cellularMQTT.getRspTopic(), reply);
Serial.printf("[MQTT] Reply: %.80s\n", reply);
}
}
// Periodic telemetry snapshot for cellular MQTT
{
static unsigned long lastTelemUpdate = 0;
if (millis() - lastTelemUpdate > 10000) {
NodePrefs* p = the_mesh.getNodePrefs();
TelemetryData td;
memset(&td, 0, sizeof(td));
td.uptime_secs = millis() / 1000;
td.battery_mv = board.getBattMilliVolts();
#ifdef HAS_BQ27220
td.battery_pct = board.getBatteryPercent();
td.temperature = board.getBattTemperature();
#else
td.battery_pct = 0;
td.temperature = 0;
#endif
td.csq = cellularMQTT.getCSQ();
td.freq = p->freq;
td.bw = p->bw;
td.sf = p->sf;
td.cr = p->cr;
td.tx_power = p->tx_power_dbm;
strncpy(td.node_name, p->node_name, sizeof(td.node_name) - 1);
strncpy(td.apn, cellularMQTT.getAPN(), sizeof(td.apn) - 1);
strncpy(td.oper, cellularMQTT.getOperator(), sizeof(td.oper) - 1);
td.mqtt_connected = cellularMQTT.isConnected();
td.neighbor_count = 0; // TODO: expose from MyMesh
cellularMQTT.updateTelemetry(td);
lastTelemUpdate = millis();
}
}
#endif
// ---------------------------------------------------------------------------
// MQTT → CLI bridge: process incoming commands from MQTT (WiFi)
// ---------------------------------------------------------------------------
#ifdef MECK_WIFI_REMOTE
wifiMQTT.loop();
{
MQTTCommand mqttCmd;
while (wifiMQTT.recvCommand(mqttCmd)) {
Serial.printf("[MQTT] CLI: %s\n", mqttCmd.cmd);
char reply[512];
reply[0] = '\0';
the_mesh.handleCommand((uint32_t)time(nullptr), mqttCmd.cmd, reply);
if (reply[0] == '\0') strcpy(reply, "OK");
wifiMQTT.sendResponse(wifiMQTT.getRspTopic(), reply);
Serial.printf("[MQTT] Reply: %.80s\n", reply);
}
}
// Periodic telemetry snapshot for WiFi MQTT
{
static unsigned long lastTelemUpdate = 0;
if (millis() - lastTelemUpdate > 10000) {
NodePrefs* p = the_mesh.getNodePrefs();
TelemetryData td;
memset(&td, 0, sizeof(td));
td.uptime_secs = millis() / 1000;
td.battery_mv = board.getBattMilliVolts();
#ifdef HAS_BQ27220
td.battery_pct = board.getBatteryPercent();
td.temperature = board.getBattTemperature();
#else
td.battery_pct = 0;
td.temperature = 0;
#endif
td.rssi = wifiMQTT.getRSSI();
td.freq = p->freq;
td.bw = p->bw;
td.sf = p->sf;
td.cr = p->cr;
td.tx_power = p->tx_power_dbm;
strncpy(td.node_name, p->node_name, sizeof(td.node_name) - 1);
td.mqtt_connected = wifiMQTT.isConnected();
td.neighbor_count = 0;
wifiMQTT.updateTelemetry(td);
lastTelemUpdate = millis();
}
}
#endif
the_mesh.loop();
sensors.loop();
#ifdef DISPLAY_CLASS
@@ -125,14 +313,16 @@ void loop() {
#endif
rtc_clock.tick();
if (the_mesh.getNodePrefs()->powersaving_enabled && // To check if power saving is enabled
the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) { // To check if it is time to sleep
if (!the_mesh.hasPendingWork()) { // No pending work. Safe to sleep
board.sleep(1800); // To sleep. Wake up after 30 minutes or when receiving a LoRa packet
#if !defined(HAS_4G_MODEM) && !defined(MECK_WIFI_REMOTE)
if (the_mesh.getNodePrefs()->powersaving_enabled &&
the_mesh.millisHasNowPassed(lastActive + nextSleepinSecs * 1000)) {
if (!the_mesh.hasPendingWork()) {
board.sleep(1800);
lastActive = millis();
nextSleepinSecs = 5; // Default: To work for 5s and sleep again
nextSleepinSecs = 5;
} else {
nextSleepinSecs += 5; // When there is pending work, to work another 5s
nextSleepinSecs += 5;
}
}
}
#endif
}
+509
View File
@@ -0,0 +1,509 @@
#ifdef MECK_WIFI_REMOTE
#include "WiFiMQTT.h"
#include <esp_mac.h>
#include <Update.h>
#include <HTTPClient.h>
#include "target.h"
WiFiMQTT wifiMQTT;
#define WIFI_CONFIG_FILE "/remote/wifi.cfg"
#define MQTT_CONFIG_FILE "/remote/mqtt.cfg"
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
void WiFiMQTT::begin() {
Serial.println("[WiFi] begin()");
_state = WiFiMQTTState::OFF;
_cmdHead = _cmdTail = 0;
_rspHead = _rspTail = 0;
_activeNetwork = 0;
if (!loadConfig(_config)) {
Serial.println("[WiFi] ERROR: Missing config files — cannot start");
_state = WiFiMQTTState::ERROR;
return;
}
Serial.printf("[WiFi] Config: %d network(s), broker=%s:%d id=%s\n",
_config.networkCount, _config.broker, _config.port, _config.deviceId);
for (int i = 0; i < _config.networkCount; i++) {
Serial.printf("[WiFi] %d: %s\n", i + 1, _config.networks[i].ssid);
}
snprintf(_topicCmd, sizeof(_topicCmd), "meck/%s/cmd", _config.deviceId);
snprintf(_topicRsp, sizeof(_topicRsp), "meck/%s/rsp", _config.deviceId);
snprintf(_topicTelem, sizeof(_topicTelem), "meck/%s/telemetry", _config.deviceId);
snprintf(_topicOta, sizeof(_topicOta), "meck/%s/ota", _config.deviceId);
// Configure TLS — skip server cert verification (same as cellular)
_wifiClient.setInsecure();
_mqttClient.setClient(_wifiClient);
_mqttClient.setServer(_config.broker, _config.port);
_mqttClient.setCallback(mqttCallback);
_mqttClient.setBufferSize(MQTT_PAYLOAD_MAX + MQTT_TOPIC_MAX);
_state = WiFiMQTTState::WIFI_CONNECTING;
}
void WiFiMQTT::loop() {
if (_state == WiFiMQTTState::OFF || _state == WiFiMQTTState::ERROR) return;
// Check for pending OTA
if (_otaPending && _state == WiFiMQTTState::CONNECTED) {
performOTA();
return;
}
// WiFi connection management
if (WiFi.status() != WL_CONNECTED) {
if (_state == WiFiMQTTState::CONNECTED || _state == WiFiMQTTState::MQTT_CONNECTING) {
Serial.println("[WiFi] Connection lost");
_state = WiFiMQTTState::WIFI_CONNECTING;
}
if (millis() - _lastWifiAttempt > WIFI_RECONNECT_MS) {
connectWiFi();
_lastWifiAttempt = millis();
}
return;
}
// WiFi is up — check MQTT
if (!_mqttClient.connected()) {
if (_state == WiFiMQTTState::CONNECTED) {
Serial.println("[WiFi] MQTT disconnected");
}
_state = WiFiMQTTState::MQTT_CONNECTING;
if (millis() - _lastMqttAttempt > MQTT_RECONNECT_MS) {
connectMQTT();
_lastMqttAttempt = millis();
}
return;
}
// Connected — run MQTT loop
_mqttClient.loop();
// Publish queued responses
publishQueuedResponses();
// Periodic RSSI
if (millis() - _lastRSSI > 30000) {
_rssi = WiFi.RSSI();
_lastRSSI = millis();
}
// Periodic telemetry
if (millis() - _lastTelem > TELEMETRY_INTERVAL) {
publishTelemetry();
_lastTelem = millis();
}
}
bool WiFiMQTT::recvCommand(MQTTCommand& out) {
if (_cmdHead == _cmdTail) return false;
memcpy(&out, &_cmdBuf[_cmdTail], sizeof(MQTTCommand));
_cmdTail = (_cmdTail + 1) % CMD_QUEUE_SIZE;
return true;
}
bool WiFiMQTT::sendResponse(const char* topic, const char* payload) {
int next = (_rspHead + 1) % RSP_QUEUE_SIZE;
if (next == _rspTail) return false; // Full
memset(&_rspBuf[_rspHead], 0, sizeof(MQTTResponse));
strncpy(_rspBuf[_rspHead].topic, topic, MQTT_TOPIC_MAX - 1);
strncpy(_rspBuf[_rspHead].payload, payload, MQTT_PAYLOAD_MAX - 1);
_rspHead = next;
return true;
}
void WiFiMQTT::updateTelemetry(const TelemetryData& data) {
memcpy(&_telemetry, &data, sizeof(data));
}
void WiFiMQTT::requestOTA(const char* url) {
if (_state == WiFiMQTTState::OTA_IN_PROGRESS) return;
strncpy(_otaUrl, url, sizeof(_otaUrl) - 1);
_otaUrl[sizeof(_otaUrl) - 1] = '\0';
_otaPending = true;
Serial.printf("[OTA] Requested: %s\n", url);
}
int WiFiMQTT::getSignalBars() const {
if (_rssi == 0) return 0;
if (_rssi > -50) return 5;
if (_rssi > -60) return 4;
if (_rssi > -70) return 3;
if (_rssi > -80) return 2;
return 1;
}
const char* WiFiMQTT::stateString() const {
switch (_state) {
case WiFiMQTTState::OFF: return "OFF";
case WiFiMQTTState::WIFI_CONNECTING: return "WiFi...";
case WiFiMQTTState::WIFI_CONNECTED: return "WiFi OK";
case WiFiMQTTState::MQTT_CONNECTING: return "MQTT...";
case WiFiMQTTState::CONNECTED: return "CONNECTED";
case WiFiMQTTState::OTA_IN_PROGRESS: return "OTA";
case WiFiMQTTState::ERROR: return "ERROR";
default: return "???";
}
}
// ---------------------------------------------------------------------------
// Config files
//
// /remote/wifi.cfg — SSID/password pairs, two lines each:
// HomeNetwork
// HomePassword
// BackupNetwork
// BackupPassword
//
// /remote/mqtt.cfg — same format as cellular variant
// ---------------------------------------------------------------------------
bool WiFiMQTT::loadConfig(WiFiMQTTConfig& cfg) {
memset(&cfg, 0, sizeof(cfg));
// Determine filesystem: SD if available, otherwise SPIFFS
// Heltec V4 and other headless boards have no SD slot — config lives in SPIFFS.
// Upload config files via: pio run -t uploadfs (with data/ folder)
#if defined(HAS_SDCARD) || defined(SDCARD_CS)
fs::FS& configFS = SD;
Serial.println("[WiFi] Config source: SD card");
#else
fs::FS& configFS = SPIFFS;
Serial.println("[WiFi] Config source: SPIFFS");
#endif
// WiFi config: read SSID/password pairs
File wf = configFS.open(WIFI_CONFIG_FILE, FILE_READ);
if (!wf) {
Serial.printf("[WiFi] No %s\n", WIFI_CONFIG_FILE);
return false;
}
cfg.networkCount = 0;
while (wf.available() && cfg.networkCount < MAX_WIFI_NETWORKS) {
String ssid = wf.readStringUntil('\n'); ssid.trim();
if (ssid.length() == 0) break;
String pass = wf.readStringUntil('\n'); pass.trim();
strncpy(cfg.networks[cfg.networkCount].ssid, ssid.c_str(), sizeof(cfg.networks[0].ssid) - 1);
strncpy(cfg.networks[cfg.networkCount].password, pass.c_str(), sizeof(cfg.networks[0].password) - 1);
cfg.networkCount++;
}
wf.close();
if (cfg.networkCount == 0) {
Serial.println("[WiFi] No networks in wifi.cfg");
return false;
}
// MQTT config: /remote/mqtt.cfg (same format as cellular)
File mf = configFS.open(MQTT_CONFIG_FILE, FILE_READ);
if (!mf) {
Serial.printf("[WiFi] No %s\n", MQTT_CONFIG_FILE);
return false;
}
String line;
line = mf.readStringUntil('\n'); line.trim();
strncpy(cfg.broker, line.c_str(), sizeof(cfg.broker) - 1);
line = mf.readStringUntil('\n'); line.trim();
cfg.port = line.length() > 0 ? line.toInt() : 8883;
line = mf.readStringUntil('\n'); line.trim();
strncpy(cfg.username, line.c_str(), sizeof(cfg.username) - 1);
line = mf.readStringUntil('\n'); line.trim();
strncpy(cfg.password, line.c_str(), sizeof(cfg.password) - 1);
if (mf.available()) {
line = mf.readStringUntil('\n'); line.trim();
if (line.length() > 0) {
strncpy(cfg.deviceId, line.c_str(), sizeof(cfg.deviceId) - 1);
}
}
mf.close();
// Auto-generate device ID if not provided
if (cfg.deviceId[0] == '\0') {
uint8_t mac[6];
esp_efuse_mac_get_default(mac);
snprintf(cfg.deviceId, sizeof(cfg.deviceId), "meck-%02x%02x%02x%02x",
mac[2], mac[3], mac[4], mac[5]);
}
return cfg.broker[0] != '\0';
}
// ---------------------------------------------------------------------------
// WiFi connection — tries each configured network in order
// ---------------------------------------------------------------------------
bool WiFiMQTT::connectWiFi() {
WiFi.mode(WIFI_STA);
for (int n = 0; n < _config.networkCount; n++) {
Serial.printf("[WiFi] Trying %s (%d/%d)...\n",
_config.networks[n].ssid, n + 1, _config.networkCount);
WiFi.begin(_config.networks[n].ssid, _config.networks[n].password);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 10000) {
delay(100);
}
if (WiFi.status() == WL_CONNECTED) {
IPAddress ip = WiFi.localIP();
snprintf(_ipAddr, sizeof(_ipAddr), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
_rssi = WiFi.RSSI();
_activeNetwork = n;
Serial.printf("[WiFi] Connected to %s — IP: %s RSSI: %d\n",
_config.networks[n].ssid, _ipAddr, _rssi);
if (WiFi.status() == WL_CONNECTED) {
IPAddress ip = WiFi.localIP();
snprintf(_ipAddr, sizeof(_ipAddr), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
_rssi = WiFi.RSSI();
_activeNetwork = n;
Serial.printf("[WiFi] Connected to %s — IP: %s RSSI: %d\n",
_config.networks[n].ssid, _ipAddr, _rssi);
// Sync clock via NTP
configTime(0, 0, "pool.ntp.org", "time.google.com");
Serial.print("[WiFi] NTP sync...");
int tries = 0;
while (time(nullptr) < 1700000000 && tries < 20) {
delay(500);
tries++;
}
time_t now = time(nullptr);
if (now > 1700000000) {
extern AutoDiscoverRTCClock rtc_clock;
rtc_clock.setCurrentTime((uint32_t)now);
Serial.printf(" OK (%lu)\n", (unsigned long)now);
} else {
Serial.println(" timeout");
}
_state = WiFiMQTTState::WIFI_CONNECTED;
return true;
}
}
WiFi.disconnect();
delay(500);
}
Serial.println("[WiFi] All networks failed");
return false;
}
// ---------------------------------------------------------------------------
// MQTT connection
// ---------------------------------------------------------------------------
bool WiFiMQTT::connectMQTT() {
Serial.printf("[WiFi] MQTT connecting to %s:%d...\n", _config.broker, _config.port);
char clientId[48];
snprintf(clientId, sizeof(clientId), "%s-%lu", _config.deviceId, millis() & 0xFFFF);
if (_mqttClient.connect(clientId, _config.username, _config.password)) {
Serial.println("[WiFi] MQTT connected!");
_mqttClient.subscribe(_topicCmd, 1);
_mqttClient.subscribe(_topicOta, 1);
_state = WiFiMQTTState::CONNECTED;
// Publish boot event
_mqttClient.publish(_topicTelem, "{\"event\":\"boot\",\"state\":\"connected\"}", true);
return true;
}
Serial.printf("[WiFi] MQTT connect failed, rc=%d\n", _mqttClient.state());
return false;
}
// ---------------------------------------------------------------------------
// MQTT message callback
// ---------------------------------------------------------------------------
void WiFiMQTT::mqttCallback(char* topic, byte* payload, unsigned int length) {
wifiMQTT.onMessage(topic, payload, length);
}
void WiFiMQTT::onMessage(char* topic, byte* payload, unsigned int length) {
char buf[MQTT_PAYLOAD_MAX];
int len = (length < MQTT_PAYLOAD_MAX - 1) ? length : MQTT_PAYLOAD_MAX - 1;
memcpy(buf, payload, len);
buf[len] = '\0';
Serial.printf("[WiFi] RX [%s]: %.80s\n", topic, buf);
if (strstr(topic, "/cmd")) {
int next = (_cmdHead + 1) % CMD_QUEUE_SIZE;
if (next != _cmdTail) {
memset(&_cmdBuf[_cmdHead], 0, sizeof(MQTTCommand));
strncpy(_cmdBuf[_cmdHead].cmd, buf, MQTT_PAYLOAD_MAX - 1);
_cmdHead = next;
Serial.printf("[WiFi] Queued CLI: %s\n", buf);
} else {
Serial.println("[WiFi] Command queue full");
}
} else if (strstr(topic, "/ota")) {
requestOTA(buf);
}
}
// ---------------------------------------------------------------------------
// Publish helpers
// ---------------------------------------------------------------------------
void WiFiMQTT::publishQueuedResponses() {
while (_rspHead != _rspTail) {
_mqttClient.publish(_rspBuf[_rspTail].topic, _rspBuf[_rspTail].payload);
_rspTail = (_rspTail + 1) % RSP_QUEUE_SIZE;
}
}
void WiFiMQTT::publishTelemetry() {
_rssi = WiFi.RSSI();
char json[400];
snprintf(json, sizeof(json),
"{\"uptime\":%lu,\"batt_mv\":%d,\"batt_pct\":%d,\"temp\":%.1f,"
"\"rssi\":%d,\"bars\":%d,\"neighbors\":%d,"
"\"freq\":%.3f,\"bw\":%.1f,\"sf\":%d,\"cr\":%d,\"tx\":%d,"
"\"name\":\"%s\",\"ip\":\"%s\",\"ssid\":\"%s\","
"\"heap\":%d}",
_telemetry.uptime_secs, _telemetry.battery_mv, _telemetry.battery_pct,
_telemetry.temperature / 10.0f,
_rssi, getSignalBars(), _telemetry.neighbor_count,
_telemetry.freq, _telemetry.bw, _telemetry.sf, _telemetry.cr, _telemetry.tx_power,
_telemetry.node_name, _ipAddr, _config.networks[_activeNetwork].ssid,
ESP.getFreeHeap());
_mqttClient.publish(_topicTelem, json);
}
// ---------------------------------------------------------------------------
// OTA — HTTP download over WiFi + ESP32 flash
// ---------------------------------------------------------------------------
void WiFiMQTT::performOTA() {
_otaPending = false;
_state = WiFiMQTTState::OTA_IN_PROGRESS;
Serial.printf("[OTA] URL: %s\n", _otaUrl);
_mqttClient.publish(_topicRsp, "OTA: Starting download...");
_mqttClient.loop();
HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setTimeout(180000);
if (!http.begin(_wifiClient, _otaUrl)) {
Serial.println("[OTA] HTTP begin failed");
_mqttClient.publish(_topicRsp, "OTA: HTTP begin failed");
_state = WiFiMQTTState::CONNECTED;
return;
}
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
Serial.printf("[OTA] HTTP error: %d\n", httpCode);
char msg[60];
snprintf(msg, sizeof(msg), "OTA: HTTP error %d", httpCode);
_mqttClient.publish(_topicRsp, msg);
http.end();
_state = WiFiMQTTState::CONNECTED;
return;
}
int fileSize = http.getSize();
if (fileSize <= 0) {
Serial.println("[OTA] Unknown content length");
_mqttClient.publish(_topicRsp, "OTA: Unknown file size");
http.end();
_state = WiFiMQTTState::CONNECTED;
return;
}
Serial.printf("[OTA] File size: %d bytes\n", fileSize);
if (!Update.begin(fileSize)) {
Serial.printf("[OTA] Update.begin failed: %s\n", Update.errorString());
_mqttClient.publish(_topicRsp, "OTA: Flash init failed");
http.end();
_state = WiFiMQTTState::CONNECTED;
return;
}
WiFiClient* stream = http.getStreamPtr();
uint8_t buf[1024];
int offset = 0;
int lastPct = -1;
while (offset < fileSize) {
int avail = stream->available();
if (avail <= 0) {
if (!stream->connected()) break;
delay(10);
continue;
}
int toRead = (avail < (int)sizeof(buf)) ? avail : sizeof(buf);
int got = stream->readBytes(buf, toRead);
if (got <= 0) break;
size_t written = Update.write(buf, got);
if (written != (size_t)got) {
Serial.printf("[OTA] Write failed: %d of %d\n", written, got);
break;
}
offset += got;
int pct = (offset * 100) / fileSize;
if (pct / 10 != lastPct / 10) {
Serial.printf("[OTA] Progress: %d%% (%d/%d)\n", pct, offset, fileSize);
char msg[60];
snprintf(msg, sizeof(msg), "OTA: Flashing %d%%", pct);
_mqttClient.publish(_topicRsp, msg);
_mqttClient.loop();
lastPct = pct;
}
delay(1);
}
http.end();
if (offset < fileSize) {
Serial.printf("[OTA] Incomplete: %d of %d\n", offset, fileSize);
Update.abort();
_mqttClient.publish(_topicRsp, "OTA: Download incomplete");
_state = WiFiMQTTState::CONNECTED;
return;
}
if (!Update.end(true)) {
Serial.printf("[OTA] Update.end failed: %s\n", Update.errorString());
_mqttClient.publish(_topicRsp, "OTA: Verification failed");
_state = WiFiMQTTState::CONNECTED;
return;
}
Serial.println("[OTA] SUCCESS — rebooting in 3 seconds");
_mqttClient.publish(_topicRsp, "OTA: Success! Rebooting...");
_mqttClient.loop();
delay(3000);
ESP.restart();
}
#endif // MECK_WIFI_REMOTE
+191
View File
@@ -0,0 +1,191 @@
#pragma once
// =============================================================================
// WiFiMQTT — WiFi + MQTT for audio variant remote repeater
//
// Same interface as CellularMQTT but uses ESP32 native WiFi + PubSubClient.
// No modem, no AT commands, no FreeRTOS task — runs in the main loop.
//
// Supports multiple WiFi networks in wifi.cfg (SSID/password pairs).
// Tries each in order on connect/reconnect.
//
// Guard: MECK_WIFI_REMOTE (set in platformio env build_flags)
// =============================================================================
#ifdef MECK_WIFI_REMOTE
#ifndef WIFI_MQTT_H
#define WIFI_MQTT_H
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#if defined(HAS_SDCARD) || defined(SDCARD_CS)
#include <SD.h>
#endif
#include <SPIFFS.h>
// ---------------------------------------------------------------------------
// Configuration
// ---------------------------------------------------------------------------
#define MQTT_TOPIC_MAX 80
#define MQTT_PAYLOAD_MAX 512
#define MQTT_CLIENT_ID_MAX 32
#define CMD_QUEUE_SIZE 8
#define RSP_QUEUE_SIZE 8
#define MAX_WIFI_NETWORKS 4
#define TELEMETRY_INTERVAL 60000 // 60 seconds
#define WIFI_RECONNECT_MS 10000 // 10 seconds between WiFi reconnect attempts
#define MQTT_RECONNECT_MS 5000 // 5 seconds between MQTT reconnect attempts
// ---------------------------------------------------------------------------
// State machine
// ---------------------------------------------------------------------------
enum class WiFiMQTTState : uint8_t {
OFF,
WIFI_CONNECTING,
WIFI_CONNECTED,
MQTT_CONNECTING,
CONNECTED,
OTA_IN_PROGRESS,
ERROR
};
// ---------------------------------------------------------------------------
// Queue message types (same as CellularMQTT for compatibility)
// ---------------------------------------------------------------------------
struct MQTTCommand {
char cmd[MQTT_PAYLOAD_MAX];
};
struct MQTTResponse {
char topic[MQTT_TOPIC_MAX];
char payload[MQTT_PAYLOAD_MAX];
};
// ---------------------------------------------------------------------------
// Config (loaded from SD)
// ---------------------------------------------------------------------------
struct WiFiNetwork {
char ssid[40];
char password[64];
};
struct WiFiMQTTConfig {
WiFiNetwork networks[MAX_WIFI_NETWORKS];
int networkCount;
char broker[80];
uint16_t port; // 8883 for MQTT TLS
char username[40];
char password[40];
char deviceId[MQTT_CLIENT_ID_MAX];
};
// ---------------------------------------------------------------------------
// Telemetry snapshot
// ---------------------------------------------------------------------------
struct TelemetryData {
uint32_t uptime_secs;
uint16_t battery_mv;
uint8_t battery_pct;
int16_t temperature;
int rssi;
uint8_t neighbor_count;
float freq;
float bw;
uint8_t sf;
uint8_t cr;
uint8_t tx_power;
char node_name[32];
bool mqtt_connected;
};
// ---------------------------------------------------------------------------
// WiFiMQTT class
// ---------------------------------------------------------------------------
class WiFiMQTT {
public:
void begin();
void loop(); // Call from main loop — handles WiFi, MQTT, publish/subscribe
// --- Queue API (called from main loop) ---
bool recvCommand(MQTTCommand& out);
bool sendResponse(const char* topic, const char* payload);
// --- Telemetry ---
void updateTelemetry(const TelemetryData& data);
// --- OTA ---
void requestOTA(const char* url);
bool isOTAInProgress() const { return _state == WiFiMQTTState::OTA_IN_PROGRESS; }
// --- State queries ---
WiFiMQTTState getState() const { return _state; }
bool isConnected() const { return _state == WiFiMQTTState::CONNECTED; }
int getRSSI() const { return _rssi; }
int getSignalBars() const;
const char* getSSID() const { return _config.networks[_activeNetwork].ssid; }
const char* getIPAddress() const { return _ipAddr; }
const char* getBroker() const { return _config.broker; }
const char* getRspTopic() const { return _topicRsp; }
const char* stateString() const;
static bool loadConfig(WiFiMQTTConfig& cfg);
private:
WiFiMQTTState _state = WiFiMQTTState::OFF;
int _rssi = 0;
int _activeNetwork = 0;
char _ipAddr[20] = {0};
WiFiMQTTConfig _config = {};
TelemetryData _telemetry = {};
// Topic strings
char _topicCmd[MQTT_TOPIC_MAX] = {0};
char _topicRsp[MQTT_TOPIC_MAX] = {0};
char _topicTelem[MQTT_TOPIC_MAX] = {0};
char _topicOta[MQTT_TOPIC_MAX] = {0};
// Command/response ring buffers (no FreeRTOS queues needed — single-threaded)
MQTTCommand _cmdBuf[CMD_QUEUE_SIZE];
int _cmdHead = 0, _cmdTail = 0;
MQTTResponse _rspBuf[RSP_QUEUE_SIZE];
int _rspHead = 0, _rspTail = 0;
// MQTT client stack
WiFiClientSecure _wifiClient;
PubSubClient _mqttClient;
// Timers
unsigned long _lastWifiAttempt = 0;
unsigned long _lastMqttAttempt = 0;
unsigned long _lastTelem = 0;
unsigned long _lastRSSI = 0;
// OTA state
bool _otaPending = false;
char _otaUrl[256] = {0};
// --- Internal ---
bool connectWiFi();
bool connectMQTT();
void publishTelemetry();
void publishQueuedResponses();
void performOTA();
// PubSubClient callback (static → instance)
static void mqttCallback(char* topic, byte* payload, unsigned int length);
void onMessage(char* topic, byte* payload, unsigned int length);
};
extern WiFiMQTT wifiMQTT;
#endif // WIFI_MQTT_H
#endif // MECK_WIFI_REMOTE
+159
View File
@@ -0,0 +1,159 @@
"""
PlatformIO post-build script: merge bootloader + partitions + firmware + SPIFFS
into a single flashable binary.
Includes a pre-formatted empty SPIFFS image so first-boot doesn't need to
format the partition (which takes 1-2 minutes on 16MB flash).
Output: .pio/build/<env>/firmware_merged.bin
Flash: esptool.py --chip esp32s3 write_flash 0x0 firmware_merged.bin
Place this file in the project root alongside platformio.ini.
Add to each environment (or the base section):
extra_scripts = post:merge_firmware.py
"""
Import("env")
def find_spiffs_partition(partitions_bin):
"""Parse compiled partitions.bin to find SPIFFS partition offset and size.
ESP32 partition entry format (32 bytes each):
0xAA50 magic, type, subtype, offset(u32le), size(u32le), label(16), flags(u32le)
SPIFFS: type=0x01(data), subtype=0x82(spiffs)
"""
import struct
with open(partitions_bin, "rb") as f:
data = f.read()
for i in range(0, len(data) - 32, 32):
magic = struct.unpack_from("<H", data, i)[0]
if magic != 0xAA50:
continue
ptype = data[i + 2]
subtype = data[i + 3]
offset = struct.unpack_from("<I", data, i + 4)[0]
size = struct.unpack_from("<I", data, i + 8)[0]
label = data[i + 12:i + 28].split(b'\x00')[0].decode("ascii", errors="ignore")
if ptype == 0x01 and subtype == 0x82: # data/spiffs
return offset, size, label
return None, None, None
def build_spiffs_image(env, size):
"""Generate an empty formatted SPIFFS image using mkspiffs."""
import subprocess, os, tempfile, glob
build_dir = env.subst("$BUILD_DIR")
spiffs_bin = os.path.join(build_dir, "spiffs_empty.bin")
# If already generated for this build, reuse it
if os.path.isfile(spiffs_bin) and os.path.getsize(spiffs_bin) == size:
return spiffs_bin
# Find mkspiffs in PlatformIO packages
pio_home = os.path.expanduser("~/.platformio")
mkspiffs_paths = glob.glob(os.path.join(pio_home, "packages", "tool-mkspiffs*", "mkspiffs*"))
if not mkspiffs_paths:
# Also check platform-specific tool paths
mkspiffs_paths = glob.glob(os.path.join(pio_home, "packages", "tool-mklittlefs*", "mkspiffs*"))
mkspiffs = None
for p in mkspiffs_paths:
if os.path.isfile(p) and os.access(p, os.X_OK):
mkspiffs = p
break
if not mkspiffs:
print("[merge] WARNING: mkspiffs not found, skipping SPIFFS image")
return None
# Create empty data directory for mkspiffs
data_dir = os.path.join(build_dir, "_empty_spiffs_data")
os.makedirs(data_dir, exist_ok=True)
# SPIFFS block/page sizes — ESP32 Arduino defaults
block_size = 4096
page_size = 256
cmd = [
mkspiffs,
"-c", data_dir,
"-b", str(block_size),
"-p", str(page_size),
"-s", str(size),
spiffs_bin,
]
print(f"[merge] Generating empty SPIFFS image ({size // 1024} KB)...")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0 and os.path.isfile(spiffs_bin):
print(f"[merge] SPIFFS image OK: {spiffs_bin}")
return spiffs_bin
else:
print(f"[merge] mkspiffs failed: {result.stderr}")
return None
def merge_bin(source, target, env):
import subprocess, os
build_dir = env.subst("$BUILD_DIR")
env_name = env.subst("$PIOENV")
bootloader = os.path.join(build_dir, "bootloader.bin")
partitions = os.path.join(build_dir, "partitions.bin")
firmware = os.path.join(build_dir, "firmware.bin")
output = os.path.join(build_dir, "firmware-merged.bin")
# Verify all inputs exist
for f in [bootloader, partitions, firmware]:
if not os.path.isfile(f):
print(f"[merge] WARNING: {f} not found, skipping merge")
return
# Read flash settings from board config
flash_mode = env.BoardConfig().get("build.flash_mode", "qio")
flash_freq = env.BoardConfig().get("build.f_flash", "80000000L").rstrip("L")
flash_size = env.BoardConfig().get("upload.flash_size", "16MB")
mcu = env.BoardConfig().get("build.mcu", "esp32s3")
# Convert numeric frequency to esptool format
freq_map = {"80000000": "80m", "40000000": "40m", "26000000": "26m", "20000000": "20m"}
flash_freq_str = freq_map.get(flash_freq, "80m")
cmd = [
env.subst("$PYTHONEXE"), "-m", "esptool",
"--chip", mcu,
"merge_bin",
"-o", output,
"--flash_mode", flash_mode,
"--flash_freq", flash_freq_str,
"--flash_size", flash_size,
"0x0", bootloader,
"0x8000", partitions,
"0x10000", firmware,
]
# Try to include a pre-formatted SPIFFS image (eliminates 1-2 min first-boot format)
spiffs_offset, spiffs_size, spiffs_label = find_spiffs_partition(partitions)
if spiffs_offset and spiffs_size:
spiffs_bin = build_spiffs_image(env, spiffs_size)
if spiffs_bin:
cmd.extend([f"0x{spiffs_offset:x}", spiffs_bin])
print(f"[merge] Including SPIFFS image at 0x{spiffs_offset:x} ({spiffs_size // 1024} KB)")
else:
print("[merge] No SPIFFS partition found in partition table, skipping SPIFFS image")
print(f"\n[merge] Creating merged firmware for {env_name}...")
print(f"[merge] {' '.join(cmd[-8:])}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
size_kb = os.path.getsize(output) / 1024
print(f"[merge] OK: {output} ({size_kb:.0f} KB)")
else:
print(f"[merge] FAILED: {result.stderr}")
env.AddPostAction("$BUILD_DIR/firmware.bin", merge_bin)
+1 -1
View File
@@ -56,7 +56,7 @@ build_src_filter =
[esp32_base]
extends = arduino_base
platform = platformio/espressif32@6.11.0
monitor_filters = esp32_exception_decoder
monitor_filters = esp32_exception_decoder, clock_sync
extra_scripts = merge-bin.py
build_flags = ${arduino_base.build_flags}
-D ESP32_PLATFORM
BIN
View File
Binary file not shown.
+48 -11
View File
@@ -36,7 +36,7 @@ uint32_t Dispatcher::getCADFailRetryDelay() const {
return 200;
}
uint32_t Dispatcher::getCADFailMaxDuration() const {
return 4000; // 4 seconds
return 6000; // 6 seconds
}
void Dispatcher::loop() {
@@ -52,10 +52,28 @@ void Dispatcher::loop() {
prev_isrecv_mode = is_recv;
if (!is_recv) {
radio_nonrx_start = _ms->getMillis();
} else {
rx_stuck_count = 0; // radio recovered — reset counter
}
}
if (!is_recv && _ms->getMillis() - radio_nonrx_start > 8000) { // radio has not been in Rx mode for 8 seconds!
_err_flags |= ERR_EVENT_STARTRX_TIMEOUT;
rx_stuck_count++;
MESH_DEBUG_PRINTLN("%s Dispatcher::loop(): RX stuck (attempt %d), calling onRxStuck()", getLogDateTime(), rx_stuck_count);
onRxStuck();
uint8_t reboot_threshold = getRxFailRebootThreshold();
if (reboot_threshold > 0 && rx_stuck_count >= reboot_threshold) {
MESH_DEBUG_PRINTLN("%s Dispatcher::loop(): RX unrecoverable after %d attempts", getLogDateTime(), rx_stuck_count);
onRxUnrecoverable();
}
// Reset state to give recovery the full 8s window before re-triggering
radio_nonrx_start = _ms->getMillis();
prev_isrecv_mode = true;
cad_busy_start = 0;
next_agc_reset_time = futureMillis(getAGCResetInterval());
}
if (outbound) { // waiting for outbound send to be completed
@@ -68,7 +86,7 @@ void Dispatcher::loop() {
next_tx_time = futureMillis(t * getAirtimeBudgetFactor());
_radio->onSendFinished();
logTx(outbound, 2 + outbound->path_len + outbound->payload_len);
logTx(outbound, 2 + outbound->getPathByteLen() + outbound->payload_len);
if (outbound->isRouteFlood()) {
n_sent_flood++;
} else {
@@ -80,7 +98,7 @@ void Dispatcher::loop() {
MESH_DEBUG_PRINTLN("%s Dispatcher::loop(): WARNING: outbound packed send timed out!", getLogDateTime());
_radio->onSendFinished();
logTxFail(outbound, 2 + outbound->path_len + outbound->payload_len);
logTxFail(outbound, 2 + outbound->getPathByteLen() + outbound->payload_len);
releasePacket(outbound); // return to pool
outbound = NULL;
@@ -141,12 +159,13 @@ void Dispatcher::checkRecv() {
}
pkt->path_len = raw[i++];
if (pkt->path_len > MAX_PATH_SIZE || i + pkt->path_len > len) {
uint16_t path_byte_len = pkt->getPathByteLen();
if (path_byte_len > MAX_PATH_SIZE || i + path_byte_len > len) {
MESH_DEBUG_PRINTLN("%s Dispatcher::checkRecv(): partial or corrupt packet received, len=%d", getLogDateTime(), len);
_mgr->free(pkt); // put back into pool
pkt = NULL;
} else {
memcpy(pkt->path, &raw[i], pkt->path_len); i += pkt->path_len;
memcpy(pkt->path, &raw[i], path_byte_len); i += path_byte_len;
pkt->payload_len = len - i; // payload is remainder
if (pkt->payload_len > sizeof(pkt->payload)) {
@@ -258,7 +277,8 @@ void Dispatcher::checkSend() {
memcpy(&raw[len], &outbound->transport_codes[1], 2); len += 2;
}
raw[len++] = outbound->path_len;
memcpy(&raw[len], outbound->path, outbound->path_len); len += outbound->path_len;
uint16_t out_pbl = outbound->getPathByteLen();
memcpy(&raw[len], outbound->path, out_pbl); len += out_pbl;
if (len + outbound->payload_len > MAX_TRANS_UNIT) {
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): FATAL: Invalid packet queued... too long, len=%d", getLogDateTime(), len + outbound->payload_len);
@@ -271,14 +291,31 @@ void Dispatcher::checkSend() {
outbound_start = _ms->getMillis();
bool success = _radio->startSendRaw(raw, len);
if (!success) {
MESH_DEBUG_PRINTLN("%s Dispatcher::loop(): ERROR: send start failed!", getLogDateTime());
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): ERROR: send start failed!", getLogDateTime());
logTxFail(outbound, outbound->getRawLength());
releasePacket(outbound); // return to pool
// re-queue packet for retry instead of dropping it
int retry_delay = getCADFailRetryDelay();
unsigned long retry_time = futureMillis(retry_delay);
_mgr->queueOutbound(outbound, 0, retry_time);
outbound = NULL;
next_tx_time = retry_time;
// count consecutive failures and reset radio if stuck
uint8_t threshold = getTxFailResetThreshold();
if (threshold > 0) {
tx_fail_count++;
if (tx_fail_count >= threshold) {
MESH_DEBUG_PRINTLN("%s Dispatcher::checkSend(): TX stuck (%d failures), resetting radio", getLogDateTime(), tx_fail_count);
onTxStuck();
tx_fail_count = 0;
next_tx_time = futureMillis(2000);
}
}
return;
}
tx_fail_count = 0; // clear counter on successful TX start
outbound_expiry = futureMillis(max_airtime);
#if MESH_PACKET_LOGGING
@@ -312,8 +349,8 @@ void Dispatcher::releasePacket(Packet* packet) {
}
void Dispatcher::sendPacket(Packet* packet, uint8_t priority, uint32_t delay_millis) {
if (packet->path_len > MAX_PATH_SIZE || packet->payload_len > MAX_PACKET_PAYLOAD) {
MESH_DEBUG_PRINTLN("%s Dispatcher::sendPacket(): ERROR: invalid packet... path_len=%d, payload_len=%d", getLogDateTime(), (uint32_t) packet->path_len, (uint32_t) packet->payload_len);
if (packet->getPathByteLen() > MAX_PATH_SIZE || packet->payload_len > MAX_PACKET_PAYLOAD) {
MESH_DEBUG_PRINTLN("%s Dispatcher::sendPacket(): ERROR: invalid packet... path_len=%d (byte_len=%d), payload_len=%d", getLogDateTime(), (uint32_t) packet->path_len, (uint32_t) packet->getPathByteLen(), (uint32_t) packet->payload_len);
_mgr->free(packet);
} else {
_mgr->queueOutbound(packet, priority, futureMillis(delay_millis));
+10 -1
View File
@@ -122,6 +122,8 @@ class Dispatcher {
bool prev_isrecv_mode;
uint32_t n_sent_flood, n_sent_direct;
uint32_t n_recv_flood, n_recv_direct;
uint8_t tx_fail_count;
uint8_t rx_stuck_count;
void processRecvPacket(Packet* pkt);
@@ -142,6 +144,8 @@ protected:
_err_flags = 0;
radio_nonrx_start = 0;
prev_isrecv_mode = true;
tx_fail_count = 0;
rx_stuck_count = 0;
}
virtual DispatcherAction onRecvPacket(Packet* pkt) = 0;
@@ -159,6 +163,11 @@ protected:
virtual uint32_t getCADFailMaxDuration() const;
virtual int getInterferenceThreshold() const { return 0; } // disabled by default
virtual int getAGCResetInterval() const { return 0; } // disabled by default
virtual uint8_t getTxFailResetThreshold() const { return 3; } // reset radio after N consecutive TX failures; 0=disabled
virtual void onTxStuck() { _radio->resetAGC(); } // override to use doFullRadioReset() when available
virtual uint8_t getRxFailRebootThreshold() const { return 3; } // reboot after N failed RX recovery attempts; 0=disabled
virtual void onRxStuck() { _radio->resetAGC(); } // called each time RX stuck for 8s; override for deeper reset
virtual void onRxUnrecoverable() { } // called when reboot threshold exceeded; override to call _board->reboot()
public:
void begin();
@@ -188,4 +197,4 @@ private:
void checkSend();
};
}
}
+5 -2
View File
@@ -20,6 +20,10 @@ public:
memcpy(dest, pub_key, PATH_HASH_SIZE); // hash is just prefix of pub_key
return PATH_HASH_SIZE;
}
int copyHashTo(uint8_t* dest, uint8_t len) const {
memcpy(dest, pub_key, len);
return len;
}
bool isHashMatch(const uint8_t* hash) const {
return memcmp(hash, pub_key, PATH_HASH_SIZE) == 0;
}
@@ -90,5 +94,4 @@ public:
void readFrom(const uint8_t* src, size_t len);
};
}
}

Some files were not shown because too many files have changed in this diff Show More