Merge branch 'feature/add-th-support' into develop

This commit is contained in:
Agent Coldsnap 2026-01-22 00:08:14 +07:00
commit b7eae98bf8
49 changed files with 26385 additions and 72 deletions

View File

@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(pio run:*)"
]
}
}

70
get-platformio.py Normal file

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,16 @@
#include <builtinFonts/notosans_18_bolditalic.h> #include <builtinFonts/notosans_18_bolditalic.h>
#include <builtinFonts/notosans_18_italic.h> #include <builtinFonts/notosans_18_italic.h>
#include <builtinFonts/notosans_18_regular.h> #include <builtinFonts/notosans_18_regular.h>
#include <builtinFonts/notosansthai_8_regular.h>
#include <builtinFonts/notosansthai_10_regular.h>
#include <builtinFonts/notosansthai_12_regular.h>
#include <builtinFonts/notosansthai_12_bold.h>
#include <builtinFonts/notosansthai_14_regular.h>
#include <builtinFonts/notosansthai_14_bold.h>
#include <builtinFonts/notosansthai_16_regular.h>
#include <builtinFonts/notosansthai_16_bold.h>
#include <builtinFonts/notosansthai_18_regular.h>
#include <builtinFonts/notosansthai_18_bold.h>
#include <builtinFonts/opendyslexic_10_bold.h> #include <builtinFonts/opendyslexic_10_bold.h>
#include <builtinFonts/opendyslexic_10_bolditalic.h> #include <builtinFonts/opendyslexic_10_bolditalic.h>
#include <builtinFonts/opendyslexic_10_italic.h> #include <builtinFonts/opendyslexic_10_italic.h>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,953 @@
/**
* generated by fontconvert.py
* name: notosansthai_10_regular
* size: 10
* mode: 1-bit
*/
#pragma once
#include "EpdFontData.h"
static const uint8_t notosansthai_10_regularBitmaps[7705] = {
0xEE, 0xEE, 0x66, 0x66, 0x66, 0x60, 0x6E, 0xE4, 0xED, 0xDB, 0xB6, 0x6C, 0xD9, 0x80, 0x06, 0x60,
0x33, 0x03, 0x98, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x33, 0x03, 0x98, 0x18, 0xC7, 0xFF, 0xFF, 0xFE,
0x33, 0x03, 0x98, 0x18, 0xC0, 0xCE, 0x00, 0x0C, 0x03, 0x07, 0xFB, 0xFE, 0xEC, 0xB3, 0x0E, 0xC1,
0xF0, 0x3F, 0x03, 0xF0, 0xDC, 0x33, 0x8D, 0xFF, 0xEF, 0xF0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00,
0x78, 0x38, 0xFC, 0x30, 0xCC, 0x70, 0xCC, 0x60, 0xCE, 0xE0, 0xCE, 0xC0, 0xCD, 0xBC, 0xFF, 0xFE,
0x7F, 0x66, 0x37, 0x67, 0x06, 0x67, 0x0E, 0x67, 0x0C, 0x66, 0x1C, 0x7E, 0x18, 0x3E, 0x00, 0x08,
0x00, 0x00, 0x7E, 0x00, 0xFE, 0x03, 0x8C, 0x07, 0x18, 0x0E, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0x3E,
0x18, 0xFE, 0x33, 0x8E, 0xE6, 0x0F, 0xCC, 0x0F, 0x1C, 0x1E, 0x3F, 0xFE, 0x3F, 0xCE, 0x0C, 0x00,
0xFF, 0xED, 0x80, 0x1C, 0xE3, 0x8C, 0x71, 0xC6, 0x18, 0xE3, 0x8E, 0x18, 0x61, 0xC7, 0x0C, 0x38,
0x60, 0xC0, 0x61, 0xC3, 0x0E, 0x38, 0x61, 0xC7, 0x1C, 0x71, 0xC7, 0x18, 0x63, 0x8E, 0x71, 0x86,
0x00, 0x0E, 0x01, 0xC0, 0x18, 0x3B, 0xF7, 0xFE, 0x3F, 0x07, 0xC0, 0xDC, 0x39, 0x82, 0x20, 0x0C,
0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x37, 0x76, 0x66,
0x7F, 0xF7, 0xC0, 0x6E, 0xE4, 0x07, 0x06, 0x0E, 0x0E, 0x0C, 0x1C, 0x1C, 0x18, 0x38, 0x30, 0x70,
0x70, 0x60, 0xE0, 0xE0, 0x00, 0x0F, 0xC7, 0xFB, 0x86, 0xE1, 0xF0, 0x7C, 0x0F, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x07, 0xE1, 0xF8, 0x67, 0xF8, 0xFC, 0x0C, 0x00, 0x0E, 0x3D, 0xFB, 0xF4, 0xE1, 0xC3,
0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x80, 0x00, 0x1F, 0xCF, 0xFB, 0x0E, 0x01, 0xC0, 0x70,
0x18, 0x0E, 0x07, 0x03, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x0F, 0xFF, 0xFF, 0x00, 0x07, 0xF1, 0xFF,
0x30, 0x60, 0x0E, 0x01, 0xC0, 0x70, 0xFC, 0x1F, 0x80, 0xF8, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xDF,
0xF3, 0xFC, 0x0C, 0x00, 0x01, 0xC0, 0x3C, 0x07, 0xC0, 0x7C, 0x0F, 0xC1, 0xDC, 0x39, 0xC3, 0x1C,
0x71, 0xCE, 0x1C, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x7F, 0x9F, 0xE6, 0x01, 0x80,
0x60, 0x38, 0x0F, 0xF1, 0xFE, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xFF, 0xEF, 0xF0, 0x60, 0x00,
0x07, 0xE3, 0xF9, 0xC0, 0x60, 0x38, 0x0E, 0xE3, 0xFE, 0xFF, 0xF8, 0x7C, 0x0F, 0x03, 0xE0, 0xD8,
0x77, 0xF8, 0xFC, 0x0C, 0x00, 0x7F, 0xEF, 0xFC, 0x03, 0x80, 0x60, 0x1C, 0x03, 0x80, 0xE0, 0x1C,
0x07, 0x00, 0xE0, 0x18, 0x07, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x00, 0x0F, 0xC7, 0xFB, 0x87, 0xE1,
0xF8, 0x77, 0x38, 0xFC, 0x3F, 0x1D, 0xEE, 0x1F, 0x03, 0xC0, 0xF8, 0x7F, 0xFD, 0xFE, 0x0C, 0x00,
0x00, 0x0F, 0xC7, 0xFB, 0x86, 0xC1, 0xF0, 0x3C, 0x0F, 0x87, 0xF3, 0xDF, 0xF1, 0xDC, 0x07, 0x01,
0x80, 0xE7, 0xF1, 0xF8, 0x30, 0x00, 0x6E, 0xE6, 0x00, 0x00, 0x06, 0xEE, 0x40, 0x33, 0x9C, 0x60,
0x00, 0x00, 0x03, 0x9C, 0xE6, 0x33, 0x00, 0x00, 0x40, 0x70, 0x7C, 0x78, 0x78, 0x38, 0x0F, 0x80,
0xF8, 0x0F, 0xC0, 0x70, 0x04, 0x7F, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x80, 0x38,
0x0F, 0x80, 0xF8, 0x07, 0x80, 0x70, 0x7C, 0x7C, 0xFC, 0x38, 0x08, 0x00, 0x00, 0x7F, 0x3F, 0xC8,
0x70, 0x38, 0x1C, 0x1C, 0x1E, 0x1E, 0x0E, 0x06, 0x03, 0x00, 0x00, 0xC0, 0xE0, 0x70, 0x10, 0x00,
0x07, 0xF8, 0x0F, 0xFE, 0x0F, 0x03, 0x8E, 0x00, 0xE6, 0x3F, 0x37, 0x3F, 0x9F, 0x38, 0xC7, 0x9C,
0x63, 0xCC, 0x31, 0xE6, 0x19, 0xF3, 0x9C, 0xD8, 0xFF, 0xEE, 0x3D, 0xE3, 0x80, 0x00, 0xE0, 0x20,
0x3F, 0xF0, 0x0F, 0xF0, 0x00, 0x07, 0x00, 0x1C, 0x00, 0xF8, 0x03, 0xE0, 0x0D, 0xC0, 0x77, 0x01,
0xCC, 0x06, 0x38, 0x3F, 0xE0, 0xFF, 0xC7, 0xFF, 0x1C, 0x0C, 0x60, 0x3B, 0x80, 0xEC, 0x01, 0x80,
0xFF, 0x1F, 0xFB, 0x07, 0x60, 0x6C, 0x0D, 0x83, 0xBF, 0xE7, 0xFC, 0xC3, 0xD8, 0x1F, 0x03, 0xE0,
0x7C, 0x1D, 0xFF, 0xBF, 0xE0, 0x00, 0x00, 0xFF, 0x3F, 0xF7, 0x82, 0x70, 0x0E, 0x00, 0xE0, 0x0E,
0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x07, 0x80, 0x3F, 0xE1, 0xFE, 0x03, 0x80, 0xFF,
0x0F, 0xFC, 0xC1, 0xEC, 0x0E, 0xC0, 0x7C, 0x07, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x07, 0xC0, 0x7C,
0x0E, 0xC1, 0xEF, 0xFC, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0xFE, 0xC0,
0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x06, 0x03, 0x01, 0xFE,
0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00, 0x00, 0x00, 0x7F, 0x8F, 0xFC, 0xF0, 0x27, 0x00,
0x70, 0x03, 0x80, 0x1C, 0x00, 0xE1, 0xFF, 0x0F, 0xF8, 0x0F, 0xC0, 0x77, 0x03, 0xBC, 0x1C, 0xFF,
0xE3, 0xFF, 0x03, 0x80, 0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x07, 0xFF, 0xFF, 0xFF,
0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x70, 0xFE, 0xF8, 0xE1, 0xC3, 0x87,
0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x8F, 0xBF, 0x80, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x0C, 0x30, 0xC7, 0x1F, 0xEF, 0x80, 0xC0, 0xF8, 0x3B, 0x0E, 0x63, 0x8C, 0xE1, 0xB8,
0x3E, 0x07, 0xE0, 0xFE, 0x19, 0xC3, 0x1C, 0x61, 0xCC, 0x3D, 0x83, 0xB0, 0x38, 0xC0, 0x60, 0x30,
0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0xFE, 0xE0, 0x0F,
0xE0, 0x3F, 0xC0, 0x7F, 0x81, 0xFF, 0x83, 0xFB, 0x06, 0xF7, 0x1D, 0xEE, 0x33, 0xCC, 0x67, 0x9D,
0xCF, 0x1B, 0x1E, 0x3E, 0x3C, 0x78, 0x78, 0x70, 0xF0, 0xE1, 0x80, 0xE0, 0x3E, 0x03, 0xF0, 0x3F,
0x83, 0xF8, 0x3D, 0xC3, 0xCE, 0x3C, 0xE3, 0xC7, 0x3C, 0x3B, 0xC3, 0xBC, 0x1F, 0xC0, 0xFC, 0x0F,
0xC0, 0x70, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x03,
0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03, 0x00,
0xFF, 0x3F, 0xEC, 0x3F, 0x07, 0xC1, 0xF0, 0x7C, 0x3F, 0xFE, 0xFF, 0x3E, 0x0C, 0x03, 0x00, 0xC0,
0x30, 0x0C, 0x00, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8,
0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03,
0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0E, 0xFF, 0x1F, 0xF3, 0x0F, 0x60, 0xEC, 0x1D, 0x83, 0xB0, 0xE7,
0xFC, 0xFE, 0x18, 0xE3, 0x1C, 0x61, 0xCC, 0x1D, 0x83, 0xB0, 0x38, 0x00, 0x0F, 0xE7, 0xFB, 0x82,
0xE0, 0x38, 0x0F, 0x01, 0xF0, 0x3F, 0x03, 0xE0, 0x3C, 0x07, 0x01, 0xC0, 0x7F, 0xFB, 0xFC, 0x18,
0x00, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0,
0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03,
0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xD8, 0x0E, 0xC0, 0x67, 0x07, 0x1F, 0xF0, 0x7F,
0x00, 0xE0, 0xC0, 0x3F, 0x01, 0xB8, 0x1C, 0xE0, 0xE7, 0x06, 0x18, 0x70, 0xE3, 0x87, 0x18, 0x19,
0xC0, 0xEE, 0x07, 0x60, 0x1F, 0x00, 0xF0, 0x07, 0x80, 0x1C, 0x00, 0xE0, 0xE0, 0x6E, 0x0E, 0x0E,
0x60, 0xF0, 0xE6, 0x1F, 0x0E, 0x71, 0xB0, 0xC7, 0x1B, 0x9C, 0x33, 0xB9, 0xC3, 0x39, 0x9C, 0x3B,
0x19, 0x83, 0xB1, 0xF8, 0x1F, 0x0F, 0x81, 0xE0, 0xF0, 0x1E, 0x0F, 0x01, 0xE0, 0xF0, 0x0E, 0x07,
0x00, 0xE0, 0x73, 0x83, 0x0C, 0x38, 0x73, 0x81, 0xD8, 0x0F, 0xC0, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
0xFC, 0x06, 0x70, 0x73, 0x87, 0x0E, 0x30, 0x3B, 0x81, 0xC0, 0xE0, 0x7E, 0x06, 0x70, 0xE7, 0x0C,
0x39, 0xC3, 0x98, 0x1F, 0x80, 0xF0, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
0x00, 0x7F, 0xE7, 0xFE, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x38, 0x07, 0x00, 0xE0, 0x0E, 0x01, 0xC0,
0x38, 0x03, 0x80, 0x70, 0x07, 0xFE, 0xFF, 0xE0, 0xFF, 0xFE, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E,
0x38, 0xE3, 0x8E, 0x38, 0xFB, 0xF7, 0x80, 0xE0, 0xE0, 0x60, 0x70, 0x70, 0x30, 0x38, 0x18, 0x1C,
0x1C, 0x0C, 0x0E, 0x0E, 0x06, 0x07, 0xFF, 0xF1, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
0x71, 0xC7, 0x7F, 0xFF, 0x80, 0x06, 0x00, 0xE0, 0x0F, 0x01, 0xB0, 0x19, 0x83, 0x98, 0x30, 0xC7,
0x0E, 0x60, 0x66, 0x06, 0x7F, 0xCF, 0xFD, 0xFF, 0x00, 0x71, 0xC3, 0x86, 0x0F, 0x0F, 0xE3, 0xFC,
0x03, 0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0xE0, 0x1C, 0x03,
0x80, 0x70, 0x0E, 0x71, 0xFF, 0x3F, 0xF7, 0x87, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xE1,
0xFF, 0xF7, 0xFC, 0x06, 0x00, 0x0E, 0x1F, 0xDF, 0xDC, 0x0E, 0x06, 0x03, 0x01, 0x80, 0xE0, 0x70,
0x1F, 0xE7, 0xE0, 0xC0, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x61, 0xCC, 0xFF, 0x9F, 0xF7, 0x0E, 0xE0,
0xD8, 0x1B, 0x03, 0x60, 0x6E, 0x0D, 0xC3, 0x9F, 0xF1, 0xFE, 0x0C, 0x00, 0x1E, 0x0F, 0xC7, 0xFB,
0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00, 0x1F, 0x1F, 0x8E,
0x07, 0x03, 0xE7, 0xF3, 0xF8, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x1C,
0x47, 0xF9, 0xFF, 0x70, 0xEE, 0x0D, 0x81, 0xB0, 0x36, 0x06, 0xE0, 0xDC, 0x39, 0xFF, 0x1F, 0xE0,
0xCC, 0x01, 0x90, 0x73, 0xFE, 0x7F, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x71, 0xFF, 0xBF,
0xF7, 0x86, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0x5F, 0x85, 0xFF,
0xFF, 0xFF, 0xFF, 0x08, 0x71, 0xC0, 0x08, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
0x71, 0xDF, 0x78, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0xB8, 0xEE, 0x7B, 0xBC, 0xEE, 0x3F, 0x0F,
0xC3, 0xF8, 0xE7, 0x39, 0xCE, 0x3B, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x0E, 0x7F,
0xDF, 0xBF, 0xFF, 0xFE, 0x3C, 0x7E, 0x1C, 0x1F, 0x0E, 0x0F, 0x87, 0x07, 0xC3, 0x83, 0xE1, 0xC1,
0xF0, 0xE0, 0xF8, 0x70, 0x7C, 0x38, 0x30, 0x47, 0x1F, 0xFB, 0xFF, 0x78, 0x6E, 0x0F, 0xC1, 0xF8,
0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x70, 0x0E, 0x07, 0xF1, 0xFF, 0x70, 0xEE, 0x0F, 0x81,
0xF0, 0x3F, 0x07, 0xE0, 0xFC, 0x39, 0xFF, 0x1F, 0xC0, 0xC0, 0x47, 0x1F, 0xF3, 0xFF, 0x78, 0x7E,
0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFE, 0x1B, 0xFF, 0x7F, 0xCE, 0x61, 0xC0, 0x38, 0x07, 0x00,
0xE0, 0x00, 0x1C, 0x47, 0xF9, 0xFF, 0x70, 0xEE, 0x0D, 0x81, 0xB0, 0x36, 0x06, 0xE0, 0xDC, 0x39,
0xFF, 0x1F, 0xE0, 0xCC, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x46, 0xFF, 0xFE, 0xF0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x3C, 0x3F, 0xBF, 0xD8, 0x0E, 0x07, 0xC0, 0xF8, 0x1E, 0x03,
0x01, 0xBF, 0xDF, 0xC3, 0x80, 0x30, 0x30, 0x7E, 0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x3E, 0x3E, 0x0C, 0x40, 0x5C, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC1, 0xB8, 0x37, 0x06, 0xE0,
0xDC, 0x39, 0xFF, 0x3F, 0xE0, 0xC0, 0xC0, 0x5C, 0x1F, 0x83, 0x30, 0xE7, 0x1C, 0xE3, 0x0C, 0xE1,
0xD8, 0x1B, 0x03, 0xE0, 0x78, 0x07, 0x00, 0xC1, 0x83, 0x70, 0xE1, 0xB8, 0xF1, 0xCC, 0x78, 0xE6,
0x3E, 0x63, 0xBB, 0x31, 0xD9, 0xB8, 0x6C, 0xFC, 0x3E, 0x7C, 0x1F, 0x1E, 0x07, 0x0F, 0x03, 0x87,
0x80, 0x40, 0x4E, 0x39, 0xC7, 0x1D, 0xC1, 0xF0, 0x3E, 0x03, 0x80, 0xF8, 0x3B, 0x87, 0x71, 0xC7,
0x70, 0x70, 0xC0, 0x5C, 0x1F, 0x83, 0x30, 0xE7, 0x1C, 0xE3, 0x0E, 0xE1, 0xD8, 0x1B, 0x03, 0xE0,
0x38, 0x07, 0x00, 0xE0, 0x18, 0x07, 0x07, 0xC0, 0xF0, 0x00, 0x7F, 0xBF, 0xDF, 0xE0, 0xE0, 0x70,
0x70, 0x70, 0x38, 0x38, 0x38, 0x1F, 0xFF, 0xF0, 0x0F, 0x1F, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x38,
0xF8, 0xF0, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x0F, 0x02, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6,
0xDB, 0x6D, 0xB6, 0x00, 0xF0, 0xF8, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x0F, 0x1C, 0x18,
0x18, 0x18, 0x18, 0x38, 0x78, 0xF0, 0x40, 0x78, 0x7F, 0xF8, 0xFC, 0x00, 0x6E, 0xE6, 0x06, 0x66,
0x66, 0x6E, 0xEE, 0xEE, 0x00, 0x01, 0x80, 0xF0, 0xFE, 0x7F, 0x9C, 0x06, 0x01, 0x80, 0x60, 0x18,
0x06, 0x01, 0xC0, 0x3F, 0x8F, 0xE0, 0x60, 0x18, 0x04, 0x00, 0x00, 0x00, 0xFE, 0x1F, 0xE1, 0x80,
0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0xFF, 0x87, 0xF8, 0x38, 0x03, 0x80, 0x38, 0x03, 0x00, 0xFF,
0xEF, 0xFF, 0xE0, 0x76, 0x06, 0x70, 0xE3, 0x0C, 0x39, 0xC1, 0x98, 0x1F, 0x80, 0xF0, 0x3F, 0xC3,
0xFC, 0x06, 0x03, 0xFC, 0x3F, 0xC0, 0x60, 0x06, 0x00, 0x7F, 0x7F, 0xB8, 0x1C, 0x07, 0x83, 0xF3,
0xBD, 0x87, 0xE3, 0xBD, 0x8F, 0xC1, 0xE0, 0x38, 0x1F, 0xFD, 0xFC, 0x00, 0x00, 0x03, 0x3C, 0xC0,
0x00, 0x00, 0x0F, 0xE0, 0x3E, 0x78, 0x70, 0x1C, 0x67, 0xEE, 0xCF, 0xE6, 0xCC, 0x06, 0xCC, 0x03,
0xCC, 0x03, 0xCC, 0x03, 0xCC, 0x06, 0xCF, 0xE6, 0x67, 0xEE, 0x71, 0x9C, 0x3C, 0x78, 0x0F, 0xF0,
0x01, 0x80, 0x00, 0xF9, 0xB8, 0xF7, 0xFC, 0xFB, 0xBF, 0x00, 0x0C, 0xC7, 0x73, 0xB9, 0xDC, 0x66,
0x1D, 0xC3, 0xB8, 0x77, 0x0C, 0xC0, 0x00, 0x00, 0x0F, 0xE0, 0x3E, 0x78, 0x70, 0x1C, 0x6F, 0xCE,
0xCF, 0xE6, 0xCE, 0x66, 0xCE, 0xE3, 0xCF, 0xE3, 0xCF, 0xC3, 0xCE, 0xC6, 0xCE, 0xE6, 0x6E, 0x7E,
0x74, 0x3C, 0x3C, 0x78, 0x0F, 0xF0, 0x01, 0x80, 0x7F, 0xE7, 0xFF, 0x7F, 0xE0, 0x00, 0xFB, 0xFE,
0x3C, 0x7D, 0xDF, 0x1C, 0x38, 0xC7, 0x10, 0x3F, 0xEF, 0xFF, 0xF9, 0xFF, 0x3F, 0xE7, 0xFC, 0xFF,
0x9F, 0xF3, 0xFE, 0x6F, 0xCC, 0xF9, 0x81, 0x30, 0x26, 0x04, 0xC0, 0x98, 0x13, 0x02, 0x60, 0x4C,
0x09, 0x80, 0x6E, 0xE4, 0x63, 0x8F, 0xFF, 0x00, 0x00, 0x7C, 0x6E, 0xC6, 0xC7, 0xC6, 0x7E, 0x3C,
0x00, 0x66, 0x1D, 0xC3, 0xB8, 0xE6, 0x1D, 0xCE, 0x73, 0xB9, 0xDC, 0x66, 0x00, 0x0C, 0x07, 0x03,
0x81, 0x80, 0x00, 0x60, 0x30, 0x38, 0x3C, 0x3C, 0x18, 0x1C, 0x0E, 0x07, 0x09, 0xFE, 0x7E, 0x0E,
0x00, 0x38, 0x00, 0x70, 0x00, 0xC0, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x03, 0xE0, 0x0F, 0x80, 0x37,
0x01, 0xDC, 0x07, 0x30, 0x18, 0xE0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC, 0x70, 0x31, 0x80, 0xEE, 0x03,
0xB0, 0x06, 0x01, 0xC0, 0x0E, 0x00, 0x30, 0x01, 0x80, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x03, 0xE0,
0x0F, 0x80, 0x37, 0x01, 0xDC, 0x07, 0x30, 0x18, 0xE0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC, 0x70, 0x31,
0x80, 0xEE, 0x03, 0xB0, 0x06, 0x07, 0x00, 0x3E, 0x01, 0xDC, 0x06, 0x30, 0x00, 0x00, 0x1C, 0x00,
0x70, 0x03, 0xE0, 0x0F, 0x80, 0x37, 0x01, 0xDC, 0x07, 0x30, 0x18, 0xE0, 0xFF, 0x83, 0xFF, 0x1F,
0xFC, 0x70, 0x31, 0x80, 0xEE, 0x03, 0xB0, 0x06, 0x04, 0x60, 0x3F, 0x81, 0xFC, 0x06, 0x60, 0x00,
0x00, 0x1C, 0x00, 0x70, 0x03, 0xE0, 0x0F, 0x80, 0x37, 0x01, 0xDC, 0x07, 0x30, 0x18, 0xE0, 0xFF,
0x83, 0xFF, 0x1F, 0xFC, 0x70, 0x31, 0x80, 0xEE, 0x03, 0xB0, 0x06, 0x08, 0x80, 0x77, 0x00, 0xDC,
0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x03, 0xE0, 0x0F, 0x80, 0x37, 0x01, 0xDC, 0x07, 0x30,
0x18, 0xE0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC, 0x70, 0x31, 0x80, 0xEE, 0x03, 0xB0, 0x06, 0x00, 0x00,
0x1E, 0x00, 0xD8, 0x03, 0x60, 0x0F, 0x80, 0x1C, 0x00, 0xF8, 0x03, 0xE0, 0x0D, 0xC0, 0x77, 0x01,
0xCC, 0x06, 0x38, 0x3F, 0xE0, 0xFF, 0xC7, 0xFF, 0x1C, 0x0C, 0x60, 0x3B, 0x80, 0xEC, 0x01, 0x80,
0x01, 0xFF, 0xC0, 0x3F, 0xF8, 0x06, 0xE0, 0x01, 0xDC, 0x00, 0x33, 0x80, 0x0E, 0x70, 0x01, 0x8F,
0xF0, 0x71, 0xFE, 0x0F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x1C, 0x1C, 0x03, 0x83, 0x80, 0xE0,
0x7F, 0x9C, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x3F, 0xF7, 0x82, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x07, 0x80, 0x3F, 0xE1, 0xFE, 0x03, 0x80, 0x78, 0x01,
0x80, 0x78, 0x0F, 0x80, 0x70, 0x1C, 0x07, 0x01, 0x80, 0x07, 0xFF, 0xFF, 0x80, 0xC0, 0x60, 0x30,
0x1F, 0xEF, 0xF6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3F, 0xFF, 0xF0, 0x07, 0x07, 0x07, 0x03, 0x00,
0x07, 0xFF, 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x1F, 0xEF, 0xF6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3F,
0xFF, 0xF0, 0x1C, 0x1F, 0x1D, 0xCC, 0x60, 0x07, 0xFF, 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x1F, 0xEF,
0xF6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3F, 0xFF, 0xF0, 0x22, 0x3B, 0x9D, 0x80, 0x00, 0x07, 0xFF,
0xFF, 0x80, 0xC0, 0x60, 0x30, 0x1F, 0xEF, 0xF6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3F, 0xFF, 0xF0,
0x70, 0xE0, 0xE0, 0xC0, 0x1F, 0xDF, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x71,
0xF7, 0xF0, 0x0E, 0x38, 0xE1, 0x80, 0x1F, 0xDF, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C,
0x38, 0x71, 0xF7, 0xF0, 0x38, 0x7C, 0xEE, 0xC6, 0x00, 0xFE, 0x7C, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x7C, 0xFE, 0x45, 0xDF, 0xB8, 0x00, 0x1F, 0xDF, 0x1C, 0x38,
0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x71, 0xF7, 0xF0, 0x3F, 0xC0, 0xFF, 0xC3, 0x07, 0x8C,
0x0E, 0x30, 0x1C, 0xC0, 0x77, 0xF0, 0xFF, 0xC3, 0xFF, 0x0C, 0xC0, 0x73, 0x01, 0xCC, 0x0E, 0x30,
0x78, 0xFF, 0xC3, 0xFC, 0x00, 0x0C, 0x41, 0xFC, 0x3F, 0xC3, 0x18, 0x00, 0x0E, 0x03, 0xE0, 0x3F,
0x03, 0xF8, 0x3F, 0x83, 0xDC, 0x3C, 0xE3, 0xCE, 0x3C, 0x73, 0xC3, 0xBC, 0x3B, 0xC1, 0xFC, 0x0F,
0xC0, 0xFC, 0x07, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x60, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E,
0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70,
0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x38, 0x00, 0xC0, 0x00,
0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x03, 0xE0, 0x0F, 0x80,
0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03, 0x00, 0x07, 0x80, 0x1F,
0x00, 0xEE, 0x06, 0x18, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01,
0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8,
0x03, 0x00, 0x06, 0x20, 0x3F, 0x80, 0xFE, 0x02, 0x30, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E,
0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D,
0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00,
0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E,
0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03, 0x00, 0xC0, 0xB8, 0x77, 0x38,
0xFC, 0x1E, 0x07, 0x83, 0xF1, 0xCE, 0xE1, 0xC0, 0x00, 0x00, 0x18, 0x7F, 0xE3, 0xFF, 0x9E, 0x1E,
0x70, 0x7F, 0x83, 0xFE, 0x1D, 0xF8, 0xE3, 0xE3, 0x0F, 0x9C, 0x3E, 0xE1, 0xFB, 0x07, 0x7C, 0x1D,
0xE0, 0xE7, 0xFF, 0x1F, 0xF8, 0x63, 0x00, 0x0E, 0x00, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x00, 0x30,
0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xEC,
0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F, 0x80, 0x70, 0x00, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x0C,
0x00, 0x00, 0x30, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0,
0x1F, 0x80, 0xEC, 0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F, 0x80, 0x70, 0x00, 0x07, 0x00, 0x7C,
0x07, 0x70, 0x31, 0x80, 0x00, 0x30, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0,
0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xEC, 0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F, 0x80, 0x70, 0x00,
0x08, 0x80, 0xEE, 0x03, 0x70, 0x00, 0x00, 0x00, 0x30, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01,
0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xEC, 0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F,
0x80, 0x70, 0x00, 0x03, 0x80, 0x70, 0x06, 0x00, 0x40, 0x00, 0x0E, 0x07, 0xE0, 0x67, 0x0E, 0x70,
0xC3, 0x9C, 0x39, 0x81, 0xF8, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
0x60, 0xC0, 0x30, 0x0F, 0xC3, 0xFC, 0xFF, 0xB0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0xEF, 0xFB, 0xF8,
0xC0, 0x30, 0x0C, 0x00, 0x3F, 0x87, 0xFC, 0x61, 0xCE, 0x0C, 0xE1, 0xCE, 0x38, 0xE7, 0x0E, 0x60,
0xE7, 0x0E, 0x3C, 0xE1, 0xEE, 0x0E, 0xE0, 0x7E, 0x07, 0xEF, 0xEE, 0xFE, 0x03, 0x00, 0x1C, 0x03,
0x80, 0x60, 0x08, 0x0F, 0x0F, 0xE3, 0xFC, 0x03, 0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77,
0xFC, 0xFF, 0x0C, 0x00, 0x03, 0x81, 0xC0, 0x60, 0x10, 0x0F, 0x0F, 0xE3, 0xFC, 0x03, 0x00, 0xC7,
0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0x0E, 0x07, 0xC3, 0xB8, 0xC3, 0x0F,
0x0F, 0xE3, 0xFC, 0x03, 0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00,
0x08, 0x47, 0xF3, 0xFC, 0xC6, 0x0F, 0x0F, 0xE3, 0xFC, 0x03, 0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60,
0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0x00, 0x06, 0x61, 0x98, 0x00, 0x0F, 0x0F, 0xE3, 0xFC, 0x03,
0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0x00, 0x03, 0xC1, 0xB0,
0x64, 0x0F, 0x01, 0x80, 0xF0, 0xFE, 0x3F, 0xC0, 0x30, 0x0C, 0x7F, 0x3F, 0xDC, 0x36, 0x0D, 0x87,
0x7F, 0xCF, 0xF0, 0xC0, 0x0E, 0x1C, 0x1F, 0xFF, 0x8F, 0xFF, 0xE0, 0x3C, 0x70, 0x0C, 0x18, 0xFF,
0xFD, 0xFF, 0xFE, 0xE3, 0x80, 0x61, 0xC0, 0x30, 0xF0, 0x1F, 0xFF, 0xE7, 0xE7, 0xF0, 0x80, 0xC0,
0x0E, 0x1F, 0xDF, 0xDC, 0x0E, 0x06, 0x03, 0x01, 0x80, 0xE0, 0x70, 0x1F, 0xE7, 0xE0, 0xC0, 0xF0,
0x18, 0x3C, 0x3E, 0x00, 0x38, 0x07, 0x00, 0xC0, 0x18, 0x1E, 0x0F, 0xC7, 0xFB, 0x87, 0xE1, 0xFF,
0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00, 0x07, 0x01, 0x80, 0xE0, 0x20, 0x1E,
0x0F, 0xC7, 0xFB, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00,
0x1E, 0x0F, 0x83, 0x71, 0x86, 0x1E, 0x0F, 0xC7, 0xFB, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0,
0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00, 0x00, 0x0C, 0xC3, 0x30, 0x00, 0x1E, 0x0F, 0xC7, 0xFB, 0x87,
0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00, 0x71, 0xC3, 0x82, 0x10,
0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x3B, 0x99, 0x84, 0x73, 0x9C, 0xE7, 0x39, 0xCE,
0x73, 0x9C, 0x38, 0x7C, 0xEE, 0xC6, 0x10, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x38, 0x45, 0xDD, 0xB8, 0x01, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C,
0x19, 0x83, 0xF0, 0x3C, 0x1F, 0xC3, 0xB8, 0x03, 0x8F, 0xF3, 0xFF, 0xE1, 0xFC, 0x1F, 0x03, 0xE0,
0x7E, 0x0F, 0xC1, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x08, 0x87, 0xF8, 0xFE, 0x11, 0x84, 0x71, 0xFF,
0xBF, 0xF7, 0x86, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0x38, 0x03,
0x80, 0x38, 0x03, 0x00, 0xE0, 0x7F, 0x1F, 0xF7, 0x0E, 0xE0, 0xF8, 0x1F, 0x03, 0xF0, 0x7E, 0x0F,
0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x03, 0x80, 0xE0, 0x38, 0x06, 0x00, 0xE0, 0x7F, 0x1F, 0xF7,
0x0E, 0xE0, 0xF8, 0x1F, 0x03, 0xF0, 0x7E, 0x0F, 0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x0E, 0x03,
0xE0, 0xEE, 0x10, 0xC0, 0xE0, 0x7F, 0x1F, 0xF7, 0x0E, 0xE0, 0xF8, 0x1F, 0x03, 0xF0, 0x7E, 0x0F,
0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x18, 0x87, 0xF0, 0xFE, 0x11, 0x80, 0xE0, 0x7F, 0x1F, 0xF7,
0x0E, 0xE0, 0xF8, 0x1F, 0x03, 0xF0, 0x7E, 0x0F, 0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x11, 0x07,
0x70, 0xEC, 0x00, 0x00, 0xE0, 0x7F, 0x1F, 0xF7, 0x0E, 0xE0, 0xF8, 0x1F, 0x03, 0xF0, 0x7E, 0x0F,
0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x00, 0x03, 0x01, 0xC0, 0x30, 0x00, 0x3F, 0xFF, 0xFC, 0x00,
0x0C, 0x07, 0x00, 0xC0, 0x0E, 0xC7, 0xF9, 0xFF, 0x71, 0xEE, 0x7F, 0x8D, 0xF3, 0xBE, 0xE7, 0xF8,
0xFE, 0x39, 0xFF, 0x7F, 0xC4, 0xC0, 0x1C, 0x03, 0x80, 0x38, 0x03, 0x04, 0x05, 0xC1, 0xB8, 0x37,
0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC3, 0x9F, 0xF3, 0xFE, 0x0C, 0x00, 0x03, 0x80,
0xE0, 0x38, 0x06, 0x04, 0x05, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D,
0xC3, 0x9F, 0xF3, 0xFE, 0x0C, 0x00, 0x0E, 0x03, 0xE0, 0xEE, 0x18, 0xC4, 0x05, 0xC1, 0xB8, 0x37,
0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC3, 0x9F, 0xF3, 0xFE, 0x0C, 0x00, 0x11, 0x07,
0x70, 0xEE, 0x00, 0x04, 0x05, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D,
0xC3, 0x9F, 0xF3, 0xFE, 0x0C, 0x00, 0x03, 0x80, 0xE0, 0x38, 0x06, 0x0C, 0x05, 0xC1, 0xF8, 0x33,
0x0E, 0x71, 0xCE, 0x30, 0xEE, 0x1D, 0x81, 0xB0, 0x3E, 0x03, 0x80, 0x70, 0x0E, 0x01, 0x80, 0x70,
0x7C, 0x0F, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x71, 0xFF, 0x3F, 0xF7, 0x87, 0xE0, 0xFC,
0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xE1, 0xBF, 0xF7, 0xFC, 0xE6, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x00,
0x11, 0x07, 0x70, 0xEC, 0x00, 0x0C, 0x05, 0xC1, 0xF8, 0x33, 0x0E, 0x71, 0xCE, 0x30, 0xEE, 0x1D,
0x81, 0xB0, 0x3E, 0x03, 0x80, 0x70, 0x0E, 0x01, 0x80, 0x70, 0x7C, 0x0F, 0x00, 0x00, 0x00, 0x7F,
0x01, 0xFC, 0x00, 0x00, 0x07, 0x00, 0x1C, 0x00, 0xF8, 0x03, 0xE0, 0x0D, 0xC0, 0x77, 0x01, 0xCC,
0x06, 0x38, 0x3F, 0xE0, 0xFF, 0xC7, 0xFF, 0x1C, 0x0C, 0x60, 0x3B, 0x80, 0xEC, 0x01, 0x80, 0x00,
0x0F, 0xE1, 0xF8, 0x3C, 0x3F, 0x8F, 0xF0, 0x0C, 0x03, 0x1F, 0xCF, 0xF7, 0x0D, 0x83, 0x61, 0xDF,
0xF3, 0xFC, 0x30, 0x18, 0xC0, 0x77, 0x00, 0xF8, 0x01, 0xC0, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x03,
0xE0, 0x0F, 0x80, 0x37, 0x01, 0xDC, 0x07, 0x30, 0x18, 0xE0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC, 0x70,
0x31, 0x80, 0xEE, 0x03, 0xB0, 0x06, 0x30, 0x8E, 0xE1, 0xF8, 0x38, 0x0F, 0x0F, 0xE3, 0xFC, 0x03,
0x00, 0xC7, 0xF3, 0xFD, 0xC3, 0x60, 0xD8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0x07, 0x00, 0x1C, 0x00,
0xF8, 0x03, 0xE0, 0x0D, 0xC0, 0x77, 0x01, 0xCC, 0x06, 0x38, 0x3F, 0xE0, 0xFF, 0xC7, 0xFF, 0x1C,
0x0C, 0x60, 0x3B, 0x80, 0xEC, 0x01, 0x80, 0x0E, 0x00, 0x30, 0x01, 0xC0, 0x03, 0xC0, 0x0E, 0x0F,
0x07, 0xF0, 0xFF, 0x00, 0x60, 0x0C, 0x3F, 0x8F, 0xF3, 0x86, 0x60, 0xCC, 0x39, 0xFF, 0x1F, 0xE0,
0xCC, 0x03, 0x00, 0x60, 0x0F, 0x00, 0xE0, 0x01, 0xC0, 0x18, 0x03, 0x80, 0x20, 0x00, 0x00, 0xFF,
0x3F, 0xF7, 0x82, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x70,
0x07, 0x80, 0x3F, 0xE1, 0xFE, 0x03, 0x80, 0x07, 0x03, 0x03, 0x81, 0x00, 0xE1, 0xFD, 0xFD, 0xC0,
0xE0, 0x60, 0x30, 0x18, 0x0E, 0x07, 0x01, 0xFE, 0x7E, 0x0C, 0x00, 0x03, 0x00, 0x30, 0x03, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x3F, 0xF7, 0x82, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x0E, 0x00, 0x70, 0x07, 0x80, 0x3F, 0xE1, 0xFE, 0x03, 0x80, 0x0C, 0x06, 0x03, 0x00, 0x00,
0xE1, 0xFD, 0xFD, 0xC0, 0xE0, 0x60, 0x30, 0x18, 0x0E, 0x07, 0x01, 0xFE, 0x7E, 0x0C, 0x00, 0x1C,
0xE0, 0xFC, 0x07, 0x80, 0x30, 0x00, 0x00, 0xFF, 0x3F, 0xF7, 0x82, 0x70, 0x0E, 0x00, 0xE0, 0x0E,
0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x07, 0x80, 0x3F, 0xE1, 0xFE, 0x03, 0x80, 0x73,
0x9F, 0x87, 0x81, 0x80, 0xE1, 0xFD, 0xFD, 0xC0, 0xE0, 0x60, 0x30, 0x18, 0x0E, 0x07, 0x01, 0xFE,
0x7E, 0x0C, 0x00, 0x31, 0x81, 0xF0, 0x1F, 0x00, 0xE0, 0x00, 0x0F, 0xF0, 0xFF, 0xCC, 0x1E, 0xC0,
0xEC, 0x07, 0xC0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x7C, 0x07, 0xC0, 0xEC, 0x1E, 0xFF, 0xCF,
0xF0, 0x00, 0xDC, 0x03, 0x60, 0x0D, 0x80, 0x34, 0x1C, 0xC1, 0xFF, 0x07, 0xFC, 0x38, 0x70, 0xE0,
0xC3, 0x03, 0x0C, 0x0C, 0x30, 0x30, 0xE0, 0xC3, 0x87, 0x07, 0xFC, 0x0F, 0xF0, 0x0C, 0x00, 0x3F,
0xC0, 0xFF, 0xC3, 0x07, 0x8C, 0x0E, 0x30, 0x1C, 0xC0, 0x77, 0xF0, 0xFF, 0xC3, 0xFF, 0x0C, 0xC0,
0x73, 0x01, 0xCC, 0x0E, 0x30, 0x78, 0xFF, 0xC3, 0xFC, 0x00, 0x00, 0xC0, 0x0C, 0x1F, 0xF0, 0xFF,
0x1C, 0xC3, 0xFC, 0x7F, 0xCE, 0x1C, 0xE0, 0xCE, 0x0C, 0xC0, 0xCE, 0x0C, 0xE0, 0xCE, 0x1C, 0x7F,
0xC3, 0xFC, 0x0C, 0x00, 0x00, 0x3F, 0x9F, 0xC0, 0x0F, 0xFF, 0xFF, 0x01, 0x80, 0xC0, 0x60, 0x3F,
0xDF, 0xEC, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x7F, 0xFF, 0xE0, 0x00, 0x1F, 0xC3, 0xF0, 0x78, 0x3F,
0x1F, 0xEE, 0x1F, 0x87, 0xFF, 0xFF, 0xFC, 0x03, 0x80, 0xE0, 0x1F, 0xF3, 0xF8, 0x18, 0x08, 0x0E,
0x07, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x1F, 0xEF, 0xF6, 0x03, 0x01, 0x80,
0xC0, 0x60, 0x3F, 0xFF, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x1E, 0x0F, 0xC7, 0xFB, 0x87, 0xE1,
0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC, 0xFE, 0x06, 0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0C,
0x06, 0x03, 0xFD, 0xFE, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0xFE, 0x0E, 0x06, 0x07, 0x01,
0xE0, 0xE0, 0x1E, 0x0F, 0xC7, 0xFB, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38, 0x07, 0xFC,
0xFE, 0x07, 0x80, 0xC0, 0x70, 0x1E, 0x03, 0x80, 0x67, 0x3F, 0x0F, 0x03, 0x80, 0x07, 0xFF, 0xFF,
0x80, 0xC0, 0x60, 0x30, 0x1F, 0xEF, 0xF6, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3F, 0xFF, 0xF0, 0x73,
0x8F, 0xC1, 0xE0, 0x30, 0x1E, 0x0F, 0xC7, 0xFB, 0x87, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0x38,
0x07, 0xFC, 0xFE, 0x06, 0x00, 0x0C, 0x60, 0x77, 0x01, 0xF0, 0x07, 0x00, 0x00, 0x07, 0xF8, 0xFF,
0xCF, 0x02, 0x70, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x1F, 0xF0, 0xFF, 0x80, 0xFC, 0x07, 0x70,
0x3B, 0xC1, 0xCF, 0xFE, 0x3F, 0xF0, 0x38, 0x00, 0x21, 0x87, 0x70, 0xFC, 0x07, 0x01, 0xC4, 0x7F,
0x9F, 0xF7, 0x0E, 0xE0, 0xD8, 0x1B, 0x03, 0x60, 0x6E, 0x0D, 0xC3, 0x9F, 0xF1, 0xFE, 0x0C, 0xC0,
0x19, 0x07, 0x3F, 0xE7, 0xF0, 0x01, 0x00, 0x1C, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xF8, 0xFF,
0xCF, 0x02, 0x70, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x0E, 0x1F, 0xF0, 0xFF, 0x80, 0xFC, 0x07, 0x70,
0x3B, 0xC1, 0xCF, 0xFE, 0x3F, 0xF0, 0x38, 0x00, 0x0C, 0x01, 0xC0, 0x30, 0x00, 0x01, 0xC4, 0x7F,
0x9F, 0xF7, 0x0E, 0xE0, 0xD8, 0x1B, 0x03, 0x60, 0x6E, 0x0D, 0xC3, 0x9F, 0xF1, 0xFE, 0x0C, 0xC0,
0x19, 0x07, 0x3F, 0xE7, 0xF0, 0x00, 0x00, 0x7F, 0x8F, 0xFC, 0xF0, 0x27, 0x00, 0x70, 0x03, 0x80,
0x1C, 0x00, 0xE1, 0xFF, 0x0F, 0xF8, 0x0F, 0xC0, 0x77, 0x03, 0xBC, 0x1C, 0xFF, 0xE3, 0xFF, 0x03,
0x80, 0x0C, 0x00, 0xE0, 0x06, 0x00, 0x30, 0x00, 0x06, 0x01, 0xC0, 0x30, 0x06, 0x01, 0xC4, 0x7F,
0x9F, 0xF7, 0x0E, 0xE0, 0xD8, 0x1B, 0x03, 0x60, 0x6E, 0x0D, 0xC3, 0x9F, 0xF1, 0xFE, 0x0C, 0xC0,
0x19, 0x07, 0x3F, 0xE7, 0xF0, 0x30, 0x1C, 0x30, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x1C, 0x30,
0x1C, 0x3F, 0xFC, 0x3F, 0xFC, 0x30, 0x1C, 0x30, 0x1C, 0x30, 0x1C, 0x30, 0x1C, 0x30, 0x1C, 0x30,
0x1C, 0x30, 0x1C, 0x70, 0x07, 0x00, 0xFF, 0x0F, 0xF0, 0x70, 0x07, 0xFC, 0x7F, 0xE7, 0x8E, 0x70,
0x77, 0x07, 0x70, 0x77, 0x07, 0x70, 0x77, 0x07, 0x70, 0x77, 0x07, 0x01, 0xFF, 0xF8, 0x0F, 0xEF,
0x8E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0xFB, 0xF8, 0x01, 0xFF, 0xF8, 0x83,
0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x00, 0xFE, 0xF8, 0xE1, 0xC3, 0x87, 0x0E,
0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x8F, 0xBF, 0x8E, 0x18, 0x70, 0x78, 0xE0, 0x27, 0x70, 0x27, 0x77,
0x77, 0x77, 0x77, 0x77, 0x6E, 0xCF, 0x70, 0x10, 0x70, 0xE0, 0x00, 0x1F, 0xDF, 0x1C, 0x38, 0x70,
0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x71, 0xF7, 0xF0, 0x5F, 0xFF, 0xFF, 0xFF, 0xF0, 0xC0, 0xF8,
0x3B, 0x0E, 0x63, 0x8C, 0xE1, 0xB8, 0x3E, 0x07, 0xE0, 0xFE, 0x19, 0xC3, 0x1C, 0x61, 0xCC, 0x3D,
0x83, 0xB0, 0x38, 0x00, 0x0C, 0x01, 0x80, 0x70, 0x0C, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0,
0xB8, 0xEE, 0x7B, 0xBC, 0xEE, 0x3F, 0x0F, 0xC3, 0xF8, 0xE7, 0x39, 0xCE, 0x3B, 0x87, 0x00, 0x03,
0x01, 0xC0, 0x60, 0x18, 0x00, 0x38, 0x0C, 0x07, 0x01, 0x00, 0x00, 0x18, 0x06, 0x01, 0x80, 0x60,
0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x07, 0xFD, 0xFF, 0x3B, 0x99,
0x80, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x00, 0xC0, 0x60, 0x30, 0x18,
0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0xFE, 0x00, 0x1C, 0x0E,
0x06, 0x02, 0x00, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x06, 0x6E, 0xC0, 0xC3, 0xE1,
0xB0, 0xD8, 0x4C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFF, 0xFE, 0xED,
0xDB, 0xF7, 0xCE, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0x30, 0x06, 0x00,
0xC0, 0x18, 0x03, 0x00, 0x64, 0x0F, 0xC1, 0xF0, 0x78, 0x1E, 0x01, 0xC0, 0x18, 0x03, 0x00, 0x7F,
0xCF, 0xF8, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0F, 0x1F, 0x3C, 0xF1, 0xE1, 0xC3, 0x87, 0x0E, 0x1C,
0x03, 0x80, 0x30, 0x07, 0x00, 0x40, 0x00, 0x0E, 0x03, 0xE0, 0x3F, 0x03, 0xF8, 0x3F, 0x83, 0xDC,
0x3C, 0xE3, 0xCE, 0x3C, 0x73, 0xC3, 0xBC, 0x3B, 0xC1, 0xFC, 0x0F, 0xC0, 0xFC, 0x07, 0x03, 0x80,
0xE0, 0x38, 0x06, 0x04, 0x71, 0xFF, 0xBF, 0xF7, 0x86, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F,
0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0x3E, 0x03, 0xF0, 0x3F, 0x83, 0xF8, 0x3D, 0xC3, 0xCE, 0x3C, 0xE3,
0xC7, 0x3C, 0x3B, 0xC3, 0xBC, 0x1F, 0xC0, 0xFC, 0x0F, 0xC0, 0x70, 0x00, 0x07, 0x00, 0x60, 0x06,
0x00, 0xC0, 0x47, 0x1F, 0xFB, 0xFF, 0x78, 0x6E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F,
0x83, 0xF0, 0x70, 0x00, 0x0C, 0x03, 0x80, 0x60, 0x0C, 0x00, 0x39, 0xC1, 0xF8, 0x0F, 0x00, 0x60,
0x00, 0x0E, 0x03, 0xE0, 0x3F, 0x03, 0xF8, 0x3F, 0x83, 0xDC, 0x3C, 0xE3, 0xCE, 0x3C, 0x73, 0xC3,
0xBC, 0x3B, 0xC1, 0xFC, 0x0F, 0xC0, 0xFC, 0x07, 0x33, 0x83, 0xE0, 0x78, 0x07, 0x04, 0x71, 0xFF,
0xBF, 0xF7, 0x86, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0x3F,
0x03, 0xF0, 0x3F, 0x83, 0xFC, 0x3D, 0xC3, 0xCE, 0x3C, 0x73, 0xC7, 0x3C, 0x3B, 0xC1, 0xFC, 0x1F,
0xC0, 0xFC, 0x07, 0xC0, 0x70, 0x03, 0x00, 0x70, 0x3F, 0x03, 0xE0, 0x47, 0x1F, 0xFB, 0xFF, 0x78,
0x6E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x70, 0x0E, 0x01, 0xC0, 0x38,
0x3E, 0x07, 0xC0, 0x00, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0x00, 0x1F, 0xE0, 0xFF, 0xC7, 0x83, 0x9C,
0x07, 0xE0, 0x1F, 0x80, 0x7E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x7E, 0x01, 0xDC, 0x07, 0x78,
0x38, 0xFF, 0xC1, 0xFE, 0x00, 0xC0, 0x00, 0x07, 0xF0, 0xFE, 0x07, 0x03, 0xF8, 0xFF, 0xB8, 0x77,
0x07, 0xC0, 0xF8, 0x1F, 0x83, 0xF0, 0x7E, 0x1C, 0xFF, 0x8F, 0xE0, 0x60, 0x06, 0xE0, 0x3B, 0x01,
0xDC, 0x06, 0x40, 0x00, 0x00, 0x7F, 0x83, 0xFF, 0x1E, 0x0E, 0x70, 0x1F, 0x80, 0x7E, 0x01, 0xF8,
0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xF8, 0x07, 0x70, 0x1D, 0xE0, 0xE3, 0xFF, 0x07, 0xF8, 0x03,
0x00, 0x1F, 0x87, 0x70, 0xDC, 0x33, 0x00, 0xE0, 0x7F, 0x1F, 0xF7, 0x0E, 0xE0, 0xF8, 0x1F, 0x03,
0xF0, 0x7E, 0x0F, 0xC3, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE3, 0xFF, 0xF9,
0xE1, 0x80, 0x70, 0x60, 0x38, 0x18, 0x0E, 0x06, 0x03, 0x81, 0xFE, 0xE0, 0x7F, 0xB8, 0x1C, 0x0E,
0x06, 0x03, 0x81, 0x80, 0x70, 0x60, 0x1E, 0x18, 0x03, 0xFF, 0xF8, 0x7F, 0xFE, 0x03, 0x00, 0x00,
0x0E, 0x0E, 0x0F, 0xEF, 0xC7, 0xFF, 0xFB, 0x87, 0x87, 0xE0, 0xE1, 0xF0, 0x3F, 0xFC, 0x0F, 0xFF,
0x03, 0x80, 0xE0, 0xE0, 0x38, 0x78, 0x07, 0xFF, 0xFC, 0xFC, 0xFE, 0x0C, 0x06, 0x00, 0x07, 0x01,
0xC0, 0x70, 0x0C, 0x00, 0x01, 0xFE, 0x3F, 0xE6, 0x1E, 0xC1, 0xD8, 0x3B, 0x07, 0x61, 0xCF, 0xF9,
0xFC, 0x31, 0xC6, 0x38, 0xC3, 0x98, 0x3B, 0x07, 0x60, 0x70, 0x0E, 0x0E, 0x1C, 0x18, 0x46, 0xFF,
0xFE, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0x1F, 0xF3, 0x0F, 0x60, 0xEC,
0x1D, 0x83, 0xB0, 0xE7, 0xFC, 0xFE, 0x18, 0xE3, 0x1C, 0x61, 0xCC, 0x1D, 0x83, 0xB0, 0x38, 0x00,
0x0C, 0x01, 0x80, 0x70, 0x0C, 0x00, 0x46, 0xFF, 0xFE, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0x00, 0x60, 0x60, 0xC0, 0xC0, 0x63, 0x07, 0xC0, 0xF0, 0x0E, 0x00, 0x01, 0xFE, 0x3F,
0xE6, 0x1E, 0xC1, 0xD8, 0x3B, 0x07, 0x61, 0xCF, 0xF9, 0xFC, 0x31, 0xC6, 0x38, 0xC3, 0x98, 0x3B,
0x07, 0x60, 0x70, 0xE7, 0x7E, 0x3C, 0x18, 0x46, 0xFF, 0xFE, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0x07, 0x01, 0x80, 0xE0, 0x20, 0x00, 0x0F, 0xE7, 0xFB, 0x82, 0xE0, 0x38, 0x0F,
0x01, 0xF0, 0x3F, 0x03, 0xE0, 0x3C, 0x07, 0x01, 0xC0, 0x7F, 0xFB, 0xFC, 0x18, 0x00, 0x0E, 0x07,
0x07, 0x03, 0x03, 0xC3, 0xFB, 0xFD, 0x80, 0xE0, 0x7C, 0x0F, 0x81, 0xE0, 0x30, 0x1B, 0xFD, 0xFC,
0x38, 0x00, 0x00, 0x0F, 0xE7, 0xFB, 0x82, 0xE0, 0x38, 0x0F, 0x01, 0xF0, 0x3F, 0x03, 0xE0, 0x3C,
0x07, 0x01, 0xC0, 0x7F, 0xFB, 0xFC, 0x18, 0x07, 0x00, 0xE0, 0xF8, 0x3C, 0x00, 0x3C, 0x3F, 0xBF,
0xD8, 0x0E, 0x07, 0xC0, 0xF8, 0x1E, 0x03, 0x01, 0xBF, 0xDF, 0xC3, 0x80, 0xE0, 0x30, 0x78, 0x3C,
0x00, 0x73, 0x8F, 0xC1, 0xE0, 0x30, 0x00, 0x0F, 0xE7, 0xFB, 0x82, 0xE0, 0x38, 0x0F, 0x01, 0xF0,
0x3F, 0x03, 0xE0, 0x3C, 0x07, 0x01, 0xC0, 0x7F, 0xFB, 0xFC, 0x18, 0x00, 0xE7, 0x3F, 0x0F, 0x03,
0x03, 0xC3, 0xFB, 0xFD, 0x80, 0xE0, 0x7C, 0x0F, 0x81, 0xE0, 0x30, 0x1B, 0xFD, 0xFC, 0x38, 0x00,
0x39, 0xC1, 0xF8, 0x0F, 0x00, 0x60, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0xE0, 0x0E, 0x00, 0xE0, 0x0E,
0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x00, 0xC0,
0x73, 0x18, 0xC6, 0x7E, 0x3F, 0x8F, 0xE0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03,
0xE0, 0xF8, 0x0C, 0x00, 0x00, 0x00, 0xFE, 0x07, 0xF0, 0x00, 0x06, 0x03, 0xF0, 0x1F, 0x80, 0xFC,
0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1D, 0x80, 0xEC, 0x06, 0x70, 0x71,
0xFF, 0x07, 0xF0, 0x0E, 0x00, 0x00, 0x07, 0xF0, 0xFE, 0x20, 0x2E, 0x0D, 0xC1, 0xB8, 0x37, 0x06,
0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x1C, 0xFF, 0x9F, 0xF0, 0x60, 0x18, 0xC0, 0xEE, 0x03, 0xE0,
0x0E, 0x00, 0x00, 0x30, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03,
0xF0, 0x1F, 0x80, 0xEC, 0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F, 0x80, 0x70, 0x00, 0x31, 0x87,
0x70, 0x7C, 0x07, 0x04, 0x05, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D,
0xC3, 0x9F, 0xF3, 0xFE, 0x0C, 0x00, 0x00, 0x00, 0x3C, 0x03, 0x60, 0x1B, 0x00, 0xF8, 0x03, 0x80,
0x00, 0x0C, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07,
0xE0, 0x3B, 0x01, 0xD8, 0x0C, 0xE0, 0xE3, 0xFE, 0x0F, 0xE0, 0x1C, 0x00, 0x00, 0x03, 0xC0, 0x6C,
0x0D, 0x81, 0xF0, 0x1C, 0x10, 0x17, 0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC1, 0xB8,
0x37, 0x0E, 0x7F, 0xCF, 0xF8, 0x30, 0x00, 0x0E, 0xE0, 0xEE, 0x06, 0x60, 0x26, 0x00, 0x00, 0x30,
0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xEC,
0x07, 0x60, 0x33, 0x83, 0x8F, 0xF8, 0x3F, 0x80, 0x70, 0x00, 0x1D, 0x87, 0x70, 0xDC, 0x13, 0x04,
0x05, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC3, 0x9F, 0xF3, 0xFE,
0x0C, 0x00, 0x60, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0,
0x3F, 0x01, 0xD8, 0x0E, 0xC0, 0x67, 0x07, 0x1F, 0xF0, 0x7F, 0x80, 0xF8, 0x01, 0x80, 0x0C, 0x00,
0x78, 0x01, 0xC0, 0x40, 0x5C, 0x1B, 0x83, 0x70, 0x6E, 0x0D, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDC,
0x39, 0xFF, 0x3F, 0xE0, 0xDC, 0x03, 0x00, 0xE0, 0x0F, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x1F, 0x00,
0x03, 0xB8, 0x00, 0x31, 0x80, 0x00, 0x00, 0x0E, 0x0E, 0x06, 0xE0, 0xE0, 0xE6, 0x0F, 0x0E, 0x61,
0xF0, 0xE7, 0x1B, 0x0C, 0x71, 0xB9, 0xC3, 0x3B, 0x9C, 0x33, 0x99, 0xC3, 0xB1, 0x98, 0x3B, 0x1F,
0x81, 0xF0, 0xF8, 0x1E, 0x0F, 0x01, 0xE0, 0xF0, 0x1E, 0x0F, 0x00, 0xE0, 0x70, 0x03, 0xC0, 0x01,
0xF0, 0x01, 0xDC, 0x00, 0x86, 0x0C, 0x18, 0x37, 0x0E, 0x1B, 0x8F, 0x1C, 0xC7, 0x8E, 0x63, 0xE6,
0x3B, 0xB3, 0x1D, 0x9B, 0x86, 0xCF, 0xC3, 0xE7, 0xC1, 0xF1, 0xE0, 0x70, 0xF0, 0x38, 0x78, 0x0F,
0x01, 0xF0, 0x1B, 0x83, 0x0C, 0x00, 0x0E, 0x07, 0xE0, 0x67, 0x0E, 0x70, 0xC3, 0x9C, 0x39, 0x81,
0xF8, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x0E, 0x03, 0xE0,
0xEE, 0x10, 0xCC, 0x05, 0xC1, 0xF8, 0x33, 0x0E, 0x71, 0xCE, 0x30, 0xEE, 0x1D, 0x81, 0xB0, 0x3E,
0x03, 0x80, 0x70, 0x0E, 0x01, 0x80, 0x70, 0x7C, 0x0F, 0x00, 0x00, 0x01, 0x98, 0x19, 0x80, 0x00,
0x00, 0x0E, 0x07, 0xE0, 0x67, 0x0E, 0x70, 0xC3, 0x9C, 0x39, 0x81, 0xF8, 0x0F, 0x00, 0xF0, 0x06,
0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x03, 0x80, 0x38, 0x07, 0x00, 0x60, 0x00, 0x07,
0xFE, 0x7F, 0xE0, 0x0E, 0x01, 0xC0, 0x38, 0x03, 0x80, 0x70, 0x0E, 0x00, 0xE0, 0x1C, 0x03, 0x80,
0x38, 0x07, 0x00, 0x7F, 0xEF, 0xFE, 0x07, 0x07, 0x03, 0x01, 0x07, 0xFB, 0xFD, 0xFE, 0x0E, 0x07,
0x07, 0x07, 0x03, 0x83, 0x83, 0x81, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x07,
0xFE, 0x7F, 0xE0, 0x0E, 0x01, 0xC0, 0x38, 0x03, 0x80, 0x70, 0x0E, 0x00, 0xE0, 0x1C, 0x03, 0x80,
0x38, 0x07, 0x00, 0x7F, 0xEF, 0xFE, 0x0C, 0x06, 0x03, 0x00, 0x07, 0xFB, 0xFD, 0xFE, 0x0E, 0x07,
0x07, 0x07, 0x03, 0x83, 0x83, 0x81, 0xFF, 0xFF, 0x39, 0xC1, 0xF8, 0x0F, 0x00, 0x60, 0x00, 0x07,
0xFE, 0x7F, 0xE0, 0x0E, 0x01, 0xC0, 0x38, 0x03, 0x80, 0x70, 0x0E, 0x00, 0xE0, 0x1C, 0x03, 0x80,
0x38, 0x07, 0x00, 0x7F, 0xEF, 0xFE, 0x73, 0x9F, 0x87, 0x81, 0x87, 0xFB, 0xFD, 0xFE, 0x0E, 0x07,
0x07, 0x07, 0x03, 0x83, 0x83, 0x81, 0xFF, 0xFF, 0x73, 0x8E, 0x30, 0x3B, 0xB9, 0x80, 0x3C, 0x3E,
0x66, 0xC3, 0x23, 0xFF, 0xFE, 0xCC, 0x00, 0x7E, 0x7E, 0x42, 0x6E, 0x7E, 0x38, 0x66, 0x60, 0x03,
0x3C, 0xC0, 0x01, 0xEF, 0xF3, 0x78, 0xC0, 0x37, 0x76, 0xEE, 0xC8, 0xE7, 0x7E, 0x3C, 0x18, 0x37,
0x6E, 0xEC, 0x76, 0x6C, 0x30, 0xE1, 0x9E, 0x78, 0x26, 0xCC, 0xF7, 0xFF, 0xFC, 0x00, 0x3F, 0x1F,
0xEF, 0x3F, 0x87, 0xF0, 0xDE, 0x37, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xF1, 0xF9, 0xCE,
0xE6, 0x77, 0x3B, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xDF, 0xEF, 0xE0, 0xC0, 0x6C, 0xDF, 0x37, 0xCC,
0x73, 0x38, 0xCC, 0x37, 0x0D, 0xC3, 0x70, 0xDC, 0x73, 0xFC, 0xFE, 0x06, 0x00, 0x1F, 0x0F, 0xF1,
0xC7, 0x70, 0x6E, 0x0D, 0xD9, 0xBF, 0xB7, 0xE6, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x60, 0x3B, 0x8F,
0xFB, 0xBB, 0xF2, 0x7E, 0x0F, 0xD9, 0xFF, 0xBF, 0xE7, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, 0x70, 0x6C,
0x6F, 0x8D, 0xF1, 0x8E, 0x33, 0x86, 0xE0, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x1D, 0xFF, 0xB7, 0xE0,
0x30, 0xCE, 0x1D, 0xF3, 0x8F, 0x30, 0xE6, 0x0C, 0xE1, 0x9C, 0x31, 0x86, 0x39, 0xC7, 0x38, 0x7E,
0x0F, 0x80, 0x3E, 0x3F, 0xEE, 0x38, 0x07, 0x01, 0xDE, 0x37, 0x8C, 0x67, 0x19, 0xC6, 0x71, 0xF8,
0x7C, 0x3F, 0x1F, 0xE6, 0x3C, 0x07, 0x00, 0xF8, 0x3E, 0x0F, 0x83, 0xE1, 0xF8, 0x77, 0xFD, 0xFF,
0x08, 0x00, 0xF1, 0xF8, 0xCE, 0xE6, 0xE7, 0x7B, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xDF, 0xEF, 0xE0,
0xC0, 0x6C, 0xCF, 0x99, 0xF7, 0x0F, 0xC3, 0xBC, 0x61, 0x9C, 0x33, 0x86, 0x70, 0xCE, 0x38, 0xFF,
0x0F, 0xC0, 0x60, 0x3E, 0x03, 0x3F, 0xC1, 0xFC, 0xE0, 0xFC, 0x38, 0x7F, 0x9C, 0x39, 0xCE, 0x1D,
0xC7, 0x0F, 0xC3, 0x87, 0xE1, 0xC3, 0xF0, 0xF1, 0xBC, 0x7F, 0xCF, 0x3F, 0xE3, 0x00, 0x80, 0x3E,
0x03, 0x3F, 0xC1, 0xBC, 0xE0, 0xDC, 0x38, 0x6F, 0x9C, 0x31, 0xCE, 0x19, 0xC7, 0x0D, 0xC3, 0x86,
0xE1, 0xC3, 0x70, 0xE3, 0xBC, 0x3F, 0xCF, 0x1F, 0xE3, 0x00, 0x30, 0x06, 0x78, 0x03, 0xF8, 0x00,
0xF8, 0x1F, 0x87, 0xF9, 0xE7, 0xB8, 0x77, 0xC6, 0x38, 0xCE, 0x19, 0x83, 0x30, 0x66, 0x0F, 0xC1,
0xF8, 0x34, 0x06, 0x3E, 0xCF, 0xF9, 0xC7, 0x30, 0x60, 0x1F, 0x87, 0xF9, 0xE7, 0xB8, 0x77, 0xC6,
0x38, 0xCE, 0x19, 0x83, 0x30, 0x66, 0x0F, 0xC1, 0xF8, 0x34, 0x06, 0x7A, 0xDF, 0xFB, 0xBF, 0x20,
0x60, 0x00, 0x47, 0xDF, 0xFF, 0x71, 0xC0, 0x1C, 0x03, 0x9E, 0x73, 0xCE, 0x19, 0xC3, 0x38, 0x67,
0x0F, 0xC1, 0xF0, 0x00, 0x0E, 0xB3, 0xFE, 0x6F, 0xC8, 0x10, 0x6D, 0xC7, 0xFE, 0x7E, 0x71, 0xC7,
0x38, 0x73, 0x87, 0x30, 0x73, 0x07, 0x30, 0x73, 0x07, 0x30, 0x73, 0x07, 0x3B, 0x81, 0xBF, 0xE1,
0xFB, 0xB0, 0xFC, 0x98, 0x7E, 0x0C, 0x3F, 0x06, 0x1F, 0x83, 0x0F, 0xC1, 0x87, 0xE0, 0xE3, 0xF0,
0x71, 0xDF, 0x3F, 0xE7, 0xDF, 0xE0, 0xC0, 0xC0, 0x3E, 0x03, 0x3F, 0xC1, 0xBC, 0xE0, 0xDC, 0x38,
0x6F, 0x9C, 0x31, 0xCE, 0x19, 0xC7, 0x0D, 0xC3, 0x86, 0xE1, 0xC3, 0x70, 0xE3, 0xBC, 0x3F, 0xCF,
0x1F, 0xE3, 0x03, 0x00, 0x1F, 0x0F, 0xF9, 0xC7, 0x70, 0x6E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0,
0xFC, 0x1D, 0xF3, 0x9E, 0x70, 0x80, 0x3B, 0xCF, 0xFF, 0xBB, 0xF2, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F,
0x07, 0xE0, 0xFC, 0x1D, 0xF3, 0x9F, 0x70, 0xC0, 0x3F, 0x1F, 0xEF, 0x3F, 0x87, 0xF8, 0xCE, 0x37,
0x0F, 0x83, 0xE0, 0xF8, 0x3F, 0x0D, 0xE3, 0x30, 0x00, 0x4F, 0x3F, 0xFF, 0x9F, 0x83, 0xE0, 0xF8,
0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0x3F, 0x3F, 0xEE, 0x1B, 0x80, 0xFC, 0x1F, 0xC6,
0xFB, 0x87, 0xE1, 0xF8, 0x7F, 0xFB, 0xFC, 0x1C, 0x00, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8,
0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x77, 0xFC, 0xFF, 0x0C, 0x00, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0,
0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xD8, 0x77, 0xFC, 0xFE, 0x0C, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x03,
0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xD8, 0x77, 0xFC, 0xFE, 0x0C,
0x00, 0x78, 0x6F, 0x1F, 0x83, 0xF0, 0x7E, 0x6F, 0xDD, 0xFB, 0xFF, 0xFF, 0xF9, 0xFE, 0x3F, 0xC3,
0xF0, 0x70, 0x00, 0x60, 0x1C, 0x03, 0x80, 0x77, 0x8E, 0xF1, 0xF8, 0x3F, 0x07, 0xE6, 0xFD, 0xDF,
0xBF, 0xFF, 0xFF, 0x9F, 0xE3, 0xFC, 0x3F, 0x07, 0x63, 0x1D, 0x8E, 0x76, 0x39, 0xDD, 0xE6, 0x77,
0x99, 0xDF, 0x63, 0xEF, 0x8F, 0x3E, 0x3C, 0xF8, 0xF1, 0xC3, 0xC7, 0x0E, 0x1C, 0x00, 0x0C, 0x00,
0x70, 0x01, 0xC0, 0x07, 0x63, 0x1D, 0x8E, 0x66, 0x79, 0x9D, 0xE6, 0x77, 0x99, 0xDF, 0xE3, 0xEF,
0x8F, 0x3E, 0x3C, 0xF0, 0xF1, 0xC3, 0x87, 0x0E, 0x1C, 0x1F, 0x87, 0xF9, 0xE7, 0xB8, 0x77, 0xC6,
0x38, 0xCE, 0x19, 0x83, 0x30, 0x66, 0x0F, 0xC1, 0xF8, 0x34, 0x00, 0x60, 0xDC, 0x1B, 0x83, 0x70,
0x6E, 0x0D, 0xC1, 0xB8, 0x37, 0x06, 0xE0, 0xDE, 0x1B, 0xFF, 0x7F, 0xC0, 0x60, 0x3C, 0xDF, 0x7E,
0x1F, 0x87, 0xE1, 0xDF, 0x77, 0x9F, 0x87, 0xE1, 0xF8, 0x77, 0xFD, 0xFE, 0x0C, 0x00, 0x1F, 0x1F,
0xE7, 0x19, 0x80, 0x78, 0x1F, 0x81, 0xF8, 0x1E, 0x01, 0xC0, 0x77, 0xF9, 0xFE, 0x0C, 0x00, 0x3F,
0x1F, 0xEF, 0x3F, 0x87, 0xF8, 0xCE, 0x37, 0x0F, 0x83, 0xE0, 0xF8, 0x3F, 0x0D, 0xE3, 0x30, 0xC0,
0x30, 0x0C, 0x03, 0x00, 0xC0, 0x3E, 0x1F, 0xE6, 0x38, 0x07, 0x01, 0xCF, 0xF7, 0xFF, 0x87, 0xC1,
0xF0, 0x7F, 0xDD, 0xF7, 0x18, 0x00, 0x1F, 0x87, 0xF9, 0xE7, 0xB8, 0x77, 0xC6, 0x38, 0xCE, 0x19,
0x83, 0x30, 0x66, 0x0F, 0xC1, 0xF8, 0x34, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x7C, 0x7F,
0x91, 0xC0, 0x70, 0x38, 0x0C, 0x06, 0x03, 0x03, 0x81, 0xDF, 0xCF, 0xC1, 0x80, 0x00, 0x63, 0xFD,
0xFF, 0xB8, 0xEE, 0x0D, 0xC1, 0xBB, 0x37, 0xF6, 0xFC, 0xDC, 0x1B, 0x83, 0x70, 0x6E, 0x0C, 0xE0,
0xCE, 0x0E, 0xE0, 0xEE, 0x0E, 0xEC, 0xEE, 0xFE, 0xEF, 0xFE, 0x3F, 0xE0, 0xE6, 0x0C, 0x7F, 0xC3,
0xF8, 0x0E, 0x00, 0x00, 0x47, 0xF9, 0xFF, 0x31, 0xC0, 0x1C, 0x03, 0x8F, 0xF3, 0xFE, 0xE1, 0xD8,
0x3B, 0x07, 0x7E, 0xE7, 0xDC, 0x30, 0x00, 0x61, 0xF8, 0xEE, 0x73, 0xB8, 0xFF, 0xBF, 0xFF, 0x1F,
0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0x00, 0x1C, 0x00, 0x70, 0x1F, 0xD8, 0x7C, 0x60, 0x39, 0x8C,
0x66, 0x71, 0x9D, 0xEE, 0x77, 0xB9, 0xFE, 0xE3, 0xDF, 0x0F, 0x3C, 0x3C, 0xF0, 0xE3, 0xC3, 0x87,
0x00, 0x7E, 0x3F, 0xCE, 0x38, 0x07, 0x01, 0xFE, 0x7F, 0x9F, 0x07, 0xE1, 0xF8, 0x77, 0xF9, 0xFC,
0x0C, 0x00, 0x00, 0x4F, 0xDB, 0xFF, 0x71, 0xC0, 0x1C, 0x03, 0xBE, 0x77, 0xCE, 0xC1, 0xDC, 0x3B,
0x87, 0x3F, 0xC7, 0xF0, 0x18, 0x00, 0x39, 0xBC, 0xF8, 0x7C, 0x3E, 0x3F, 0xFD, 0xFE, 0x3B, 0x01,
0x80, 0xC0, 0x60, 0x30, 0x00, 0xC1, 0xFB, 0xF0, 0x00, 0x10, 0x70, 0x7E, 0xFC, 0x00, 0xC0, 0xFF,
0xFF, 0xFD, 0xFF, 0x38, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x70, 0x07, 0xC0, 0x36,
0x01, 0xF0, 0x03, 0x00, 0x01, 0xF8, 0x0F, 0xE0, 0x67, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30,
0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0xFF, 0xBF, 0xE0, 0x01, 0x80, 0x7F, 0xFF, 0xFE,
0x03, 0x81, 0xFF, 0xFF, 0xFE, 0x0D, 0x83, 0xFF, 0xFF, 0xFE, 0xEE, 0x77, 0x60, 0x66, 0x77, 0x77,
0x3E, 0x1C, 0x6F, 0x70, 0x0C, 0x01, 0x83, 0xFE, 0x7F, 0xEE, 0xDD, 0xDB, 0xBB, 0x77, 0xFC, 0xFF,
0x9D, 0xFB, 0xB3, 0x76, 0x7E, 0xDD, 0xFF, 0xBF, 0xE3, 0xF0, 0x0C, 0x01, 0x00, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xFF, 0x20, 0xC7, 0x31, 0xCC, 0x73, 0x1C, 0xC7, 0x31, 0xCC, 0x73, 0x1C, 0xC7, 0x31,
0xCF, 0x7B, 0xCF, 0x21, 0x80, 0x3E, 0xFF, 0xFE, 0x30, 0x30, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x3C, 0x3C, 0x08, 0x73, 0xFF, 0xC3, 0x1C, 0xE3, 0x9C, 0x71, 0xC7,
0x1C, 0x71, 0xC7, 0x1C, 0x7C, 0xF1, 0x80, 0x7E, 0x7E, 0x7E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x1E, 0x04, 0xFD, 0xFF, 0x38, 0x30, 0x60, 0xC1,
0x83, 0x06, 0x0C, 0x38, 0x70, 0x60, 0xC1, 0x83, 0x06, 0x3B, 0x9F, 0xFE, 0xDF, 0xB3, 0xE0, 0xF8,
0x37, 0x8C, 0xE3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x7F,
0x7F, 0xE9, 0xFF, 0x7F, 0x00, 0xDF, 0xFC, 0x61, 0xE0, 0xC7, 0xFF, 0xE0, 0x6C, 0x7F, 0x35, 0x9D,
0xF7, 0xF8, 0x30, 0xCF, 0xFE, 0x30, 0x7F, 0xFE, 0x30, 0x77, 0xF7, 0xF3, 0x00, 0x1C, 0xFF, 0x30,
0xC0, 0x3F, 0x0F, 0xF3, 0xC7, 0x7F, 0x6D, 0xED, 0xBF, 0xFF, 0xB7, 0x6E, 0x7F, 0xC7, 0xF0, 0x30,
0x00, 0x3F, 0x1F, 0xEF, 0x3B, 0x87, 0xE1, 0xF0, 0x7E, 0x1F, 0x87, 0x7F, 0x8F, 0xC0, 0xC0, 0x3E,
0x1F, 0xCE, 0x3B, 0x06, 0xC1, 0xFC, 0x7F, 0x18, 0xCE, 0x1F, 0x87, 0xC0, 0xC0, 0x40, 0x18, 0x03,
0x00, 0x67, 0xED, 0xFF, 0xB7, 0xF6, 0x3E, 0xF7, 0xCE, 0xFC, 0x1F, 0x83, 0xBF, 0xE3, 0xF8, 0x1C,
0x00, 0x7F, 0x9F, 0xEE, 0xDF, 0x87, 0xC1, 0xF0, 0x7E, 0x1F, 0x87, 0xF9, 0xDE, 0x71, 0x00, 0x01,
0x80, 0x60, 0x18, 0xFE, 0x7F, 0x3C, 0x0E, 0x03, 0x1E, 0xC7, 0xB9, 0x8E, 0x61, 0xFE, 0x7F, 0xC0,
0x18, 0x8F, 0x63, 0x78, 0xFE, 0x7F, 0x3C, 0x0E, 0x03, 0x0E, 0xC7, 0xB9, 0x8E, 0x61, 0xFE, 0x7F,
0xC0, 0x40, 0x38, 0x0E, 0x01, 0xFC, 0x7F, 0x9C, 0xE2, 0x1C, 0x07, 0x01, 0xC0, 0x72, 0x1D, 0xFE,
0x3F, 0x03, 0x00, 0x00, 0x10, 0x01, 0xC0, 0x0E, 0xFE, 0x7F, 0xFB, 0xF6, 0xDF, 0x06, 0xF8, 0x37,
0xC1, 0xBF, 0x0D, 0xF8, 0x6F, 0xF3, 0xE7, 0x9E, 0x08, 0x00, 0x00, 0x80, 0x60, 0x18, 0xFE, 0x7F,
0x3C, 0x0E, 0x03, 0x06, 0xC1, 0xF0, 0x3E, 0xCF, 0xFF, 0x7F, 0x80, 0xC0, 0x00, 0x80, 0x70, 0x1D,
0xFE, 0x7F, 0xBB, 0x0E, 0xE3, 0x18, 0xC7, 0x39, 0xCE, 0x33, 0xEE, 0x79, 0x84, 0x00, 0x39, 0x8D,
0xE6, 0x3E, 0x18, 0xF8, 0x63, 0xE3, 0x9F, 0xFF, 0xF7, 0xFF, 0xC7, 0x73, 0x01, 0x8C, 0x06, 0x30,
0x18, 0xC0, 0x63, 0x00, 0x00, 0x78, 0x00, 0xFC, 0x00, 0xCD, 0xBC, 0xCD, 0xFC, 0xCF, 0xFF, 0xE7,
0xFF, 0x7E, 0x50, 0x3C, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x49, 0xE3, 0x1E, 0x78, 0xC3, 0x0C,
0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x7F, 0xF7, 0xC0, 0x7F, 0xFF, 0xF7, 0xFC, 0x7F,
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x76, 0x6E, 0xEC, 0x76, 0xEE, 0xCC, 0x77, 0x66, 0xE4,
0x76, 0x66, 0x6E, 0xEE, 0xEE, 0xCC, 0x77, 0x66, 0xEE, 0xEE, 0xCC, 0xC8, 0x77, 0x77, 0x66, 0x6E,
0xEE, 0x44, 0x21, 0xEF, 0xFF, 0xF9, 0xE0, 0x63, 0x0F, 0x8E, 0x7E, 0x39, 0xD0, 0x42, 0x0C, 0x73,
0x9C, 0x61, 0xC3, 0x87, 0x0C, 0x61, 0xC3, 0x8E, 0x1C, 0xE3, 0x9C, 0x60, 0x00, 0x00, 0x7F, 0x1F,
0xF1, 0xC2, 0x38, 0x03, 0x80, 0xFF, 0x8F, 0xF8, 0x30, 0x0F, 0xF8, 0xFF, 0x83, 0x80, 0x38, 0x01,
0xC0, 0x1F, 0xF0, 0xFE, 0x01, 0x80, 0x7F, 0xF7, 0xC0,
};
static const EpdGlyph notosansthai_10_regularGlyphs[] = {
{ 0, 0, 0, 0, 0, 0, 0 }, //
{ 0, 0, 5, 0, 0, 0, 0 }, //
{ 0, 0, 5, 0, 0, 0, 0 }, //
{ 4, 16, 6, 1, 15, 8, 0 }, // !
{ 7, 6, 9, 1, 15, 6, 8 }, // "
{ 13, 15, 13, 0, 15, 25, 14 }, // #
{ 10, 18, 12, 1, 16, 23, 39 }, // $
{ 16, 17, 17, 1, 16, 34, 62 }, // %
{ 15, 17, 15, 1, 16, 32, 96 }, // &
{ 3, 6, 5, 1, 15, 3, 128 }, // '
{ 6, 19, 6, 0, 15, 15, 131 }, // (
{ 6, 19, 6, 0, 15, 15, 146 }, // )
{ 11, 10, 11, 0, 16, 14, 161 }, // *
{ 10, 11, 12, 1, 13, 14, 175 }, // +
{ 4, 6, 6, 0, 3, 3, 189 }, // ,
{ 6, 3, 7, 0, 7, 3, 192 }, // -
{ 4, 4, 6, 1, 3, 2, 195 }, // .
{ 8, 15, 8, 0, 15, 15, 197 }, // /
{ 10, 17, 12, 1, 16, 22, 212 }, // 0
{ 7, 15, 12, 1, 15, 14, 234 }, // 1
{ 10, 16, 12, 1, 16, 20, 248 }, // 2
{ 11, 17, 12, 0, 16, 24, 268 }, // 3
{ 12, 15, 12, 0, 15, 23, 292 }, // 4
{ 10, 16, 12, 1, 15, 20, 315 }, // 5
{ 10, 17, 12, 1, 16, 22, 335 }, // 6
{ 11, 15, 12, 0, 15, 21, 357 }, // 7
{ 10, 17, 12, 1, 16, 22, 378 }, // 8
{ 10, 17, 12, 1, 16, 22, 400 }, // 9
{ 4, 13, 6, 1, 12, 7, 422 }, // :
{ 5, 15, 6, 0, 12, 10, 429 }, // ;
{ 10, 11, 12, 1, 13, 14, 439 }, // <
{ 10, 7, 12, 1, 11, 9, 453 }, // =
{ 10, 11, 12, 1, 13, 14, 462 }, // >
{ 9, 17, 9, 0, 16, 20, 476 }, // ?
{ 17, 17, 19, 1, 15, 37, 496 }, // @
{ 14, 15, 13, 0, 15, 27, 533 }, // A
{ 11, 15, 14, 2, 15, 21, 560 }, // B
{ 12, 17, 13, 1, 16, 26, 581 }, // C
{ 12, 15, 15, 2, 15, 23, 607 }, // D
{ 9, 15, 12, 2, 15, 17, 630 }, // E
{ 9, 15, 11, 2, 15, 17, 647 }, // F
{ 13, 17, 15, 1, 16, 28, 664 }, // G
{ 12, 15, 15, 2, 15, 23, 692 }, // H
{ 7, 15, 7, 0, 15, 14, 715 }, // I
{ 6, 19, 6, -2, 15, 15, 729 }, // J
{ 11, 15, 13, 2, 15, 21, 744 }, // K
{ 9, 15, 11, 2, 15, 17, 765 }, // L
{ 15, 15, 19, 2, 15, 29, 782 }, // M
{ 12, 15, 16, 2, 15, 23, 811 }, // N
{ 14, 17, 16, 1, 16, 30, 834 }, // O
{ 10, 15, 13, 2, 15, 19, 864 }, // P
{ 14, 20, 16, 1, 16, 35, 883 }, // Q
{ 11, 15, 13, 2, 15, 21, 918 }, // R
{ 10, 17, 11, 1, 16, 22, 939 }, // S
{ 12, 15, 12, 0, 15, 23, 961 }, // T
{ 13, 16, 15, 1, 15, 26, 984 }, // U
{ 13, 15, 13, 0, 15, 25, 1010 }, // V
{ 20, 15, 19, 0, 15, 38, 1035 }, // W
{ 13, 15, 12, 0, 15, 25, 1073 }, // X
{ 12, 15, 12, 0, 15, 23, 1098 }, // Y
{ 12, 15, 12, 0, 15, 23, 1121 }, // Z
{ 6, 19, 7, 1, 15, 15, 1144 }, // [
{ 8, 15, 8, 0, 15, 15, 1159 }, // <backslash>
{ 6, 19, 7, 0, 15, 15, 1174 }, // ]
{ 12, 10, 12, 0, 15, 15, 1189 }, // ^
{ 11, 3, 9, -1, -1, 5, 1204 }, // _
{ 6, 4, 6, 0, 16, 3, 1209 }, // `
{ 10, 13, 12, 0, 12, 17, 1212 }, // a
{ 11, 17, 13, 1, 16, 24, 1229 }, // b
{ 9, 13, 10, 1, 12, 15, 1253 }, // c
{ 11, 17, 13, 1, 16, 24, 1268 }, // d
{ 10, 13, 12, 1, 12, 17, 1292 }, // e
{ 9, 16, 7, 0, 16, 18, 1309 }, // f
{ 11, 17, 13, 1, 12, 24, 1327 }, // g
{ 11, 16, 13, 1, 16, 22, 1351 }, // h
{ 3, 16, 5, 1, 16, 6, 1373 }, // i
{ 6, 21, 5, -2, 16, 16, 1379 }, // j
{ 10, 16, 11, 1, 16, 20, 1395 }, // k
{ 3, 16, 5, 1, 16, 6, 1415 }, // l
{ 17, 12, 19, 1, 12, 26, 1421 }, // m
{ 11, 12, 13, 1, 12, 17, 1447 }, // n
{ 11, 13, 13, 1, 12, 18, 1464 }, // o
{ 11, 17, 13, 1, 12, 24, 1482 }, // p
{ 11, 17, 13, 1, 12, 24, 1506 }, // q
{ 8, 12, 9, 1, 12, 12, 1530 }, // r
{ 9, 13, 10, 1, 12, 15, 1542 }, // s
{ 8, 15, 8, 0, 14, 15, 1557 }, // t
{ 11, 13, 13, 1, 12, 18, 1572 }, // u
{ 11, 12, 11, 0, 12, 17, 1590 }, // v
{ 17, 12, 16, 0, 12, 26, 1607 }, // w
{ 11, 12, 11, 0, 12, 17, 1633 }, // x
{ 11, 17, 11, 0, 12, 24, 1650 }, // y
{ 9, 12, 10, 0, 12, 14, 1674 }, // z
{ 8, 19, 8, 0, 15, 19, 1688 }, // {
{ 3, 22, 11, 4, 16, 9, 1707 }, // |
{ 8, 19, 8, 0, 15, 19, 1716 }, // }
{ 10, 4, 12, 1, 9, 5, 1735 }, // ~
{ 0, 0, 5, 0, 0, 0, 1740 }, //  
{ 4, 16, 6, 1, 12, 8, 1740 }, // ¡
{ 10, 17, 12, 1, 16, 22, 1748 }, // ¢
{ 12, 16, 12, 0, 16, 24, 1770 }, // £
{ 12, 15, 12, 0, 15, 23, 1794 }, // ¥
{ 9, 17, 11, 1, 16, 20, 1817 }, // §
{ 6, 3, 12, 3, 16, 3, 1837 }, // ¨
{ 16, 17, 17, 1, 16, 34, 1840 }, // ©
{ 7, 9, 7, 0, 16, 8, 1874 }, // ª
{ 10, 9, 11, 0, 10, 12, 1882 }, // «
{ 16, 17, 17, 1, 16, 34, 1894 }, // ®
{ 12, 3, 10, -1, 18, 5, 1928 }, // ¯
{ 7, 8, 9, 1, 16, 7, 1933 }, // °
{ 6, 4, 6, 0, 16, 3, 1940 }, // ´
{ 11, 19, 14, 1, 16, 27, 1943 }, // ¶
{ 4, 4, 6, 1, 9, 2, 1970 }, // ·
{ 5, 5, 5, 0, 0, 4, 1972 }, // ¸
{ 8, 9, 8, 0, 16, 9, 1976 }, // º
{ 10, 9, 11, 0, 10, 12, 1985 }, // »
{ 9, 16, 9, 0, 12, 18, 1997 }, // ¿
{ 14, 20, 13, 0, 20, 35, 2015 }, // À
{ 14, 20, 13, 0, 20, 35, 2050 }, // Á
{ 14, 20, 13, 0, 20, 35, 2085 }, // Â
{ 14, 20, 13, 0, 20, 35, 2120 }, // Ã
{ 14, 20, 13, 0, 20, 35, 2155 }, // Ä
{ 14, 19, 13, 0, 19, 34, 2190 }, // Å
{ 19, 15, 18, -1, 15, 36, 2224 }, // Æ
{ 12, 21, 13, 1, 16, 32, 2260 }, // Ç
{ 9, 20, 12, 2, 20, 23, 2292 }, // È
{ 9, 20, 12, 2, 20, 23, 2315 }, // É
{ 9, 20, 12, 2, 20, 23, 2338 }, // Ê
{ 9, 20, 12, 2, 20, 23, 2361 }, // Ë
{ 7, 20, 7, 0, 20, 18, 2384 }, // Ì
{ 7, 20, 7, 0, 20, 18, 2402 }, // Í
{ 8, 20, 7, 0, 20, 20, 2420 }, // Î
{ 7, 20, 7, 0, 20, 18, 2440 }, // Ï
{ 14, 15, 15, 0, 15, 27, 2458 }, // Ð
{ 12, 20, 16, 2, 20, 30, 2485 }, // Ñ
{ 14, 21, 16, 1, 20, 37, 2515 }, // Ò
{ 14, 21, 16, 1, 20, 37, 2552 }, // Ó
{ 14, 21, 16, 1, 20, 37, 2589 }, // Ô
{ 14, 21, 16, 1, 20, 37, 2626 }, // Õ
{ 14, 21, 16, 1, 20, 37, 2663 }, // Ö
{ 10, 10, 12, 1, 12, 13, 2700 }, // ×
{ 14, 17, 16, 1, 16, 30, 2713 }, // Ø
{ 13, 21, 15, 1, 20, 35, 2743 }, // Ù
{ 13, 21, 15, 1, 20, 35, 2778 }, // Ú
{ 13, 21, 15, 1, 20, 35, 2813 }, // Û
{ 13, 21, 15, 1, 20, 35, 2848 }, // Ü
{ 12, 20, 12, 0, 20, 30, 2883 }, // Ý
{ 10, 15, 13, 2, 15, 19, 2913 }, // Þ
{ 12, 17, 13, 1, 16, 26, 2932 }, // ß
{ 10, 17, 12, 0, 16, 22, 2958 }, // à
{ 10, 17, 12, 0, 16, 22, 2980 }, // á
{ 10, 17, 12, 0, 16, 22, 3002 }, // â
{ 10, 17, 12, 0, 16, 22, 3024 }, // ã
{ 10, 17, 12, 0, 16, 22, 3046 }, // ä
{ 10, 19, 12, 0, 18, 24, 3068 }, // å
{ 17, 13, 18, 0, 12, 28, 3092 }, // æ
{ 9, 17, 10, 1, 12, 20, 3120 }, // ç
{ 10, 17, 12, 1, 16, 22, 3140 }, // è
{ 10, 17, 12, 1, 16, 22, 3162 }, // é
{ 10, 17, 12, 1, 16, 22, 3184 }, // ê
{ 10, 17, 12, 1, 16, 22, 3206 }, // ë
{ 6, 16, 5, -1, 16, 12, 3228 }, // ì
{ 5, 16, 5, 1, 16, 10, 3240 }, // í
{ 8, 16, 5, -1, 16, 16, 3250 }, // î
{ 7, 16, 5, -1, 16, 14, 3266 }, // ï
{ 11, 17, 13, 1, 16, 24, 3280 }, // ð
{ 11, 16, 13, 1, 16, 22, 3304 }, // ñ
{ 11, 17, 13, 1, 16, 24, 3326 }, // ò
{ 11, 17, 13, 1, 16, 24, 3350 }, // ó
{ 11, 17, 13, 1, 16, 24, 3374 }, // ô
{ 11, 17, 13, 1, 16, 24, 3398 }, // õ
{ 11, 17, 13, 1, 16, 24, 3422 }, // ö
{ 10, 11, 12, 1, 13, 14, 3446 }, // ÷
{ 11, 13, 13, 1, 12, 18, 3460 }, // ø
{ 11, 17, 13, 1, 16, 24, 3478 }, // ù
{ 11, 17, 13, 1, 16, 24, 3502 }, // ú
{ 11, 17, 13, 1, 16, 24, 3526 }, // û
{ 11, 17, 13, 1, 16, 24, 3550 }, // ü
{ 11, 21, 11, 0, 16, 29, 3574 }, // ý
{ 11, 21, 13, 1, 16, 29, 3603 }, // þ
{ 11, 21, 11, 0, 16, 29, 3632 }, // ÿ
{ 14, 19, 13, 0, 19, 34, 3661 }, // Ā
{ 10, 16, 12, 0, 15, 20, 3695 }, // ā
{ 14, 20, 13, 0, 20, 35, 3715 }, // Ă
{ 10, 17, 12, 0, 16, 22, 3750 }, // ă
{ 14, 20, 13, 0, 15, 35, 3772 }, // Ą
{ 11, 17, 12, 0, 12, 24, 3807 }, // ą
{ 12, 21, 13, 1, 20, 32, 3831 }, // Ć
{ 9, 17, 10, 1, 16, 20, 3863 }, // ć
{ 12, 21, 13, 1, 20, 32, 3883 }, // Ċ
{ 9, 17, 10, 1, 16, 20, 3915 }, // ċ
{ 12, 21, 13, 1, 20, 32, 3935 }, // Č
{ 9, 17, 10, 1, 16, 20, 3967 }, // č
{ 12, 20, 15, 2, 20, 30, 3987 }, // Ď
{ 14, 17, 13, 1, 16, 30, 4017 }, // ď
{ 14, 15, 15, 0, 15, 27, 4047 }, // Đ
{ 12, 17, 13, 1, 16, 26, 4074 }, // đ
{ 9, 19, 12, 2, 19, 22, 4100 }, // Ē
{ 10, 16, 12, 1, 15, 20, 4122 }, // ē
{ 9, 20, 12, 2, 20, 23, 4142 }, // Ė
{ 10, 17, 12, 1, 16, 22, 4165 }, // ė
{ 9, 20, 12, 2, 15, 23, 4187 }, // Ę
{ 10, 17, 12, 1, 12, 22, 4210 }, // ę
{ 9, 20, 12, 2, 20, 23, 4232 }, // Ě
{ 10, 17, 12, 1, 16, 22, 4255 }, // ě
{ 13, 21, 15, 1, 20, 35, 4277 }, // Ğ
{ 11, 21, 13, 1, 16, 29, 4312 }, // ğ
{ 13, 21, 15, 1, 20, 35, 4341 }, // Ġ
{ 11, 21, 13, 1, 16, 29, 4376 }, // ġ
{ 13, 21, 15, 1, 16, 35, 4405 }, // Ģ
{ 11, 21, 13, 1, 16, 29, 4440 }, // ģ
{ 16, 15, 15, 0, 15, 30, 4469 }, // Ħ
{ 12, 16, 13, 0, 16, 24, 4499 }, // ħ
{ 7, 19, 7, 0, 19, 17, 4523 }, // Ī
{ 7, 15, 5, -1, 15, 14, 4540 }, // ī
{ 7, 20, 7, 0, 15, 18, 4554 }, // Į
{ 4, 21, 5, 0, 16, 11, 4572 }, // į
{ 7, 20, 7, 0, 20, 18, 4583 }, // İ
{ 3, 12, 5, 1, 12, 5, 4601 }, // ı
{ 11, 20, 13, 2, 15, 28, 4606 }, // Ķ
{ 10, 21, 11, 1, 16, 27, 4634 }, // ķ
{ 10, 20, 11, 1, 20, 25, 4661 }, // Ĺ
{ 5, 21, 5, 1, 21, 14, 4686 }, // ĺ
{ 9, 20, 11, 2, 15, 23, 4700 }, // Ļ
{ 4, 21, 5, 1, 16, 11, 4723 }, // ļ
{ 9, 15, 11, 2, 15, 17, 4734 }, // Ľ
{ 7, 16, 5, 1, 16, 14, 4751 }, // ľ
{ 11, 15, 11, 0, 15, 21, 4765 }, // Ł
{ 7, 16, 5, -1, 16, 14, 4786 }, // ł
{ 12, 20, 16, 2, 20, 30, 4800 }, // Ń
{ 11, 16, 13, 1, 16, 22, 4830 }, // ń
{ 12, 20, 16, 2, 15, 30, 4852 }, // Ņ
{ 11, 17, 13, 1, 12, 24, 4882 }, // ņ
{ 12, 20, 16, 2, 20, 30, 4906 }, // Ň
{ 11, 16, 13, 1, 16, 22, 4936 }, // ň
{ 12, 19, 16, 2, 15, 29, 4958 }, // Ŋ
{ 11, 17, 13, 1, 12, 24, 4987 }, // ŋ
{ 14, 20, 16, 1, 19, 35, 5011 }, // Ō
{ 11, 16, 13, 1, 15, 22, 5046 }, // ō
{ 14, 21, 16, 1, 20, 37, 5068 }, // Ő
{ 11, 17, 13, 1, 16, 24, 5105 }, // ő
{ 18, 17, 19, 1, 16, 39, 5129 }, // Œ
{ 18, 13, 20, 1, 12, 30, 5168 }, // œ
{ 11, 20, 13, 2, 20, 28, 5198 }, // Ŕ
{ 8, 16, 9, 1, 16, 16, 5226 }, // ŕ
{ 11, 20, 13, 2, 15, 28, 5242 }, // Ŗ
{ 8, 17, 9, 1, 12, 17, 5270 }, // ŗ
{ 11, 20, 13, 2, 20, 28, 5287 }, // Ř
{ 8, 16, 9, 1, 16, 16, 5315 }, // ř
{ 10, 21, 11, 1, 20, 27, 5331 }, // Ś
{ 9, 17, 10, 1, 16, 20, 5358 }, // ś
{ 10, 21, 11, 1, 16, 27, 5378 }, // Ş
{ 9, 17, 10, 1, 12, 20, 5405 }, // ş
{ 10, 21, 11, 1, 20, 27, 5425 }, // Š
{ 9, 17, 10, 1, 16, 20, 5452 }, // š
{ 12, 20, 12, 0, 20, 30, 5472 }, // Ť
{ 10, 17, 8, 0, 16, 22, 5502 }, // ť
{ 13, 20, 15, 1, 19, 33, 5524 }, // Ū
{ 11, 16, 13, 1, 15, 22, 5557 }, // ū
{ 13, 21, 15, 1, 20, 35, 5579 }, // Ŭ
{ 11, 17, 13, 1, 16, 24, 5614 }, // ŭ
{ 13, 23, 15, 1, 22, 38, 5638 }, // Ů
{ 11, 19, 13, 1, 18, 27, 5676 }, // ů
{ 13, 21, 15, 1, 20, 35, 5703 }, // Ű
{ 11, 17, 13, 1, 16, 24, 5738 }, // ű
{ 13, 20, 15, 1, 15, 33, 5762 }, // Ų
{ 11, 17, 13, 1, 12, 24, 5795 }, // ų
{ 20, 20, 19, 0, 20, 50, 5819 }, // Ŵ
{ 17, 16, 16, 0, 16, 34, 5869 }, // ŵ
{ 12, 20, 12, 0, 20, 30, 5903 }, // Ŷ
{ 11, 21, 11, 0, 16, 29, 5933 }, // ŷ
{ 12, 20, 12, 0, 20, 30, 5962 }, // Ÿ
{ 12, 20, 12, 0, 20, 30, 5992 }, // Ź
{ 9, 16, 10, 0, 16, 18, 6022 }, // ź
{ 12, 20, 12, 0, 20, 30, 6040 }, // Ż
{ 9, 16, 10, 0, 16, 18, 6070 }, // ż
{ 12, 20, 12, 0, 20, 30, 6088 }, // Ž
{ 9, 16, 10, 0, 16, 18, 6118 }, // ž
{ 5, 4, 0, -11, 16, 3, 6136 }, // ̀
{ 5, 4, 0, -7, 16, 3, 6139 }, // ́
{ 8, 4, 0, -4, 16, 4, 6142 }, // ̂
{ 8, 4, 0, -10, 16, 4, 6146 }, // ̃
{ 8, 3, 0, -4, 15, 3, 6150 }, // ̄
{ 8, 4, 0, -4, 16, 4, 6153 }, // ̆
{ 4, 3, 0, -2, 16, 2, 6157 }, // ̇
{ 6, 3, 0, -3, 16, 3, 6159 }, // ̈
{ 6, 6, 0, -3, 18, 5, 6162 }, // ̊
{ 8, 4, 0, -3, 16, 4, 6167 }, // ̋
{ 8, 4, 0, -4, 16, 4, 6171 }, // ̌
{ 4, 6, 0, -2, 15, 3, 6175 }, // ̒
{ 4, 4, 0, -2, -1, 2, 6178 }, // ̦
{ 6, 5, 0, -3, 0, 4, 6180 }, // ̧
{ 4, 6, 0, -2, 1, 3, 6184 }, // ̨
{ 7, 3, 0, -9, -1, 3, 6187 }, // ̱
{ 10, 12, 13, 1, 12, 15, 6190 }, // ก
{ 9, 13, 11, 1, 12, 15, 6205 }, // ข
{ 10, 13, 11, 0, 12, 17, 6220 }, // ฃ
{ 11, 12, 13, 1, 12, 17, 6237 }, // ค
{ 11, 12, 13, 1, 12, 17, 6254 }, // ฅ
{ 11, 13, 12, 0, 12, 18, 6271 }, // ฆ
{ 11, 12, 11, 0, 12, 17, 6289 }, // ง
{ 10, 12, 11, 0, 12, 15, 6306 }, // จ
{ 10, 13, 13, 1, 12, 17, 6321 }, // ฉ
{ 9, 13, 11, 1, 12, 15, 6338 }, // ช
{ 11, 13, 12, 0, 12, 18, 6353 }, // ซ
{ 17, 13, 19, 1, 12, 28, 6371 }, // ฌ
{ 17, 16, 19, 1, 12, 34, 6399 }, // ญ
{ 11, 17, 13, 0, 12, 24, 6433 }, // ฎ
{ 11, 17, 13, 0, 12, 24, 6457 }, // ฏ
{ 11, 18, 11, 0, 13, 25, 6481 }, // ฐ
{ 12, 12, 13, 0, 12, 18, 6506 }, // ฑ
{ 17, 13, 19, 1, 12, 28, 6524 }, // ฒ
{ 17, 13, 19, 1, 12, 28, 6552 }, // ณ
{ 11, 13, 13, 1, 12, 18, 6580 }, // ด
{ 11, 13, 13, 1, 12, 18, 6598 }, // ต
{ 10, 13, 13, 1, 12, 17, 6616 }, // ถ
{ 10, 12, 13, 1, 12, 15, 6633 }, // ท
{ 10, 13, 11, 1, 12, 17, 6648 }, // ธ
{ 10, 13, 13, 1, 12, 17, 6665 }, // น
{ 10, 13, 13, 1, 12, 17, 6682 }, // บ
{ 10, 17, 13, 1, 16, 22, 6699 }, // ป
{ 11, 12, 14, 1, 12, 17, 6721 }, // ผ
{ 11, 16, 14, 1, 16, 22, 6738 }, // ฝ
{ 14, 12, 14, 0, 12, 21, 6760 }, // พ
{ 14, 16, 14, 0, 16, 28, 6781 }, // ฟ
{ 11, 13, 13, 0, 12, 18, 6809 }, // ภ
{ 11, 13, 13, 1, 12, 18, 6827 }, // ม
{ 10, 13, 12, 1, 12, 17, 6845 }, // ย
{ 10, 13, 10, 0, 12, 17, 6862 }, // ร
{ 10, 17, 13, 1, 12, 22, 6879 }, // ฤ
{ 10, 13, 12, 1, 12, 17, 6901 }, // ล
{ 11, 17, 13, 0, 12, 24, 6918 }, // ฦ
{ 9, 13, 10, 0, 12, 15, 6942 }, // ว
{ 11, 13, 13, 1, 13, 18, 6957 }, // ศ
{ 12, 13, 13, 1, 12, 20, 6975 }, // ษ
{ 11, 14, 12, 1, 13, 20, 6995 }, // ส
{ 10, 12, 12, 1, 12, 15, 7015 }, // ห
{ 14, 15, 14, 0, 15, 27, 7030 }, // ฬ
{ 10, 13, 12, 1, 12, 17, 7057 }, // อ
{ 11, 14, 12, 1, 13, 20, 7074 }, // ฮ
{ 9, 12, 11, 0, 12, 14, 7094 }, // ฯ
{ 7, 10, 7, 0, 11, 9, 7108 }, // ะ
{ 8, 4, 0, -7, 17, 4, 7117 }, // ั
{ 7, 12, 8, 0, 12, 11, 7121 }, // า
{ 13, 17, 8, -6, 17, 28, 7132 }, // ำ
{ 10, 2, 0, -11, 15, 3, 7160 }, // ิ
{ 10, 4, 0, -11, 17, 5, 7163 }, // ี
{ 10, 4, 0, -11, 17, 5, 7168 }, // ึ
{ 10, 4, 0, -11, 17, 5, 7173 }, // ื
{ 4, 5, 0, -5, -1, 3, 7178 }, // ุ
{ 8, 5, 0, -9, -1, 5, 7181 }, // ู
{ 4, 4, 0, -5, -1, 2, 7186 }, // ฺ
{ 11, 18, 12, 1, 16, 25, 7188 }, // ฿
{ 4, 13, 6, 2, 12, 7, 7213 }, // เ
{ 10, 13, 12, 2, 12, 17, 7220 }, // แ
{ 8, 19, 6, 0, 18, 19, 7237 }, // โ
{ 6, 19, 6, 0, 18, 15, 7256 }, // ใ
{ 8, 19, 6, -1, 18, 19, 7271 }, // ไ
{ 7, 17, 8, 0, 12, 15, 7290 }, // ๅ
{ 10, 17, 12, 1, 12, 22, 7305 }, // ๆ
{ 8, 6, 0, -10, 18, 6, 7327 }, // ็
{ 3, 5, 0, -4, 18, 2, 7333 }, // ่
{ 7, 5, 0, -8, 18, 5, 7335 }, // ้
{ 9, 5, 0, -9, 18, 6, 7340 }, // ๊
{ 6, 5, 0, -7, 18, 4, 7346 }, // ๋
{ 6, 4, 0, -6, 16, 3, 7350 }, // ์
{ 5, 5, 0, -6, 17, 4, 7353 }, // ํ
{ 6, 5, 0, -6, 17, 4, 7357 }, // ๎
{ 11, 11, 12, 1, 10, 16, 7361 }, // ๏
{ 10, 11, 12, 1, 10, 14, 7377 }, //
{ 10, 11, 11, 1, 10, 14, 7391 }, // ๑
{ 11, 14, 13, 1, 13, 20, 7405 }, // ๒
{ 10, 11, 12, 1, 10, 14, 7425 }, // ๓
{ 10, 13, 11, 1, 13, 17, 7439 }, // ๔
{ 10, 13, 11, 1, 13, 17, 7456 }, // ๕
{ 10, 14, 11, 0, 13, 18, 7473 }, // ๖
{ 13, 14, 15, 1, 13, 23, 7491 }, // ๗
{ 10, 14, 12, 1, 13, 18, 7514 }, // ๘
{ 10, 14, 11, 1, 13, 18, 7532 }, // ๙
{ 14, 13, 16, 0, 12, 23, 7550 }, // ๚
{ 16, 8, 18, 1, 9, 16, 7573 }, // ๛
{ 0, 0, 0, 0, 0, 0, 7589 }, //
{ 2, 17, 0, -1, 14, 5, 7589 }, //
{ 6, 18, 0, -3, 15, 14, 7594 }, //
{ 6, 3, 7, 0, 7, 3, 7608 }, //
{ 10, 3, 10, 0, 7, 4, 7611 }, //
{ 20, 3, 21, 0, 7, 8, 7615 }, // —
{ 4, 6, 4, 0, 15, 3, 7623 }, //
{ 4, 6, 4, 0, 15, 3, 7626 }, //
{ 4, 6, 5, 0, 3, 3, 7629 }, //
{ 8, 6, 7, 0, 15, 6, 7632 }, // “
{ 8, 6, 7, 0, 15, 6, 7638 }, // ”
{ 8, 6, 9, 0, 3, 6, 7644 }, // „
{ 6, 6, 8, 1, 11, 5, 7650 }, // •
{ 14, 4, 16, 1, 3, 7, 7655 }, // …
{ 6, 9, 6, 0, 10, 7, 7662 }, //
{ 6, 9, 6, 0, 10, 7, 7669 }, //
{ 12, 17, 12, 0, 16, 26, 7676 }, // €
{ 6, 3, 7, 0, 7, 3, 7702 }, //
};
static const EpdUnicodeInterval notosansthai_10_regularIntervals[] = {
{ 0x0, 0x0, 0x0 },
{ 0xD, 0xD, 0x1 },
{ 0x20, 0x7E, 0x2 },
{ 0xA0, 0xA3, 0x61 },
{ 0xA5, 0xA5, 0x65 },
{ 0xA7, 0xAB, 0x66 },
{ 0xAE, 0xB0, 0x6B },
{ 0xB4, 0xB4, 0x6E },
{ 0xB6, 0xB8, 0x6F },
{ 0xBA, 0xBB, 0x72 },
{ 0xBF, 0xFF, 0x74 },
{ 0x100, 0x107, 0xB5 },
{ 0x10A, 0x113, 0xBD },
{ 0x116, 0x11B, 0xC7 },
{ 0x11E, 0x123, 0xCD },
{ 0x126, 0x127, 0xD3 },
{ 0x12A, 0x12B, 0xD5 },
{ 0x12E, 0x131, 0xD7 },
{ 0x136, 0x137, 0xDB },
{ 0x139, 0x13E, 0xDD },
{ 0x141, 0x148, 0xE3 },
{ 0x14A, 0x14D, 0xEB },
{ 0x150, 0x15B, 0xEF },
{ 0x15E, 0x161, 0xFB },
{ 0x164, 0x165, 0xFF },
{ 0x16A, 0x17E, 0x101 },
{ 0x300, 0x304, 0x116 },
{ 0x306, 0x308, 0x11B },
{ 0x30A, 0x30C, 0x11E },
{ 0x312, 0x312, 0x121 },
{ 0x326, 0x328, 0x122 },
{ 0x331, 0x331, 0x125 },
{ 0xE01, 0xE3A, 0x126 },
{ 0xE3F, 0xE5B, 0x160 },
{ 0x200B, 0x200D, 0x17D },
{ 0x2010, 0x2010, 0x180 },
{ 0x2013, 0x2014, 0x181 },
{ 0x2018, 0x201A, 0x183 },
{ 0x201C, 0x201E, 0x186 },
{ 0x2022, 0x2022, 0x189 },
{ 0x2026, 0x2026, 0x18A },
{ 0x2039, 0x203A, 0x18B },
{ 0x20AC, 0x20AC, 0x18D },
{ 0x2212, 0x2212, 0x18E },
};
static const EpdFontData notosansthai_10_regular = {
notosansthai_10_regularBitmaps,
notosansthai_10_regularGlyphs,
notosansthai_10_regularIntervals,
44,
31,
23,
-10,
false,
};

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,826 @@
/**
* generated by fontconvert.py
* name: notosansthai_8_bold
* size: 8
* mode: 1-bit
*/
#pragma once
#include "EpdFontData.h"
static const uint8_t notosansthai_8_boldBitmaps[5679] = {
0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x20, 0xFF, 0xFF, 0xF7, 0xCC, 0x1D, 0x83, 0xB0, 0x76, 0x3F,
0xF7, 0xFE, 0xFF, 0x8E, 0xC7, 0xFE, 0xFF, 0xC6, 0xE0, 0xD8, 0x3B, 0x00, 0x0C, 0x0F, 0x1F, 0xEF,
0xFF, 0xC3, 0xE1, 0xF8, 0x7F, 0x0F, 0xA7, 0xFF, 0xFF, 0xE3, 0xC0, 0x60, 0x00, 0x00, 0xF8, 0xE3,
0xF1, 0x87, 0x67, 0x0E, 0xEC, 0x1D, 0xBB, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x6E, 0x0F, 0xDC, 0x39,
0xB8, 0x63, 0xF1, 0xC7, 0xC0, 0x02, 0x00, 0x00, 0x01, 0xF8, 0x0F, 0xE0, 0xE7, 0x07, 0xF8, 0x1F,
0x80, 0xF9, 0xCF, 0xCE, 0x7F, 0xF7, 0xBF, 0x3C, 0xF8, 0xFF, 0xC3, 0xFF, 0x06, 0x00, 0xFF, 0xEC,
0x38, 0xE7, 0x1C, 0x73, 0x8E, 0x38, 0xE3, 0x87, 0x1C, 0x70, 0xE1, 0x80, 0xE3, 0x9C, 0x73, 0x9C,
0xE7, 0x39, 0xCE, 0x77, 0x3B, 0x80, 0x1C, 0x0E, 0x17, 0x7F, 0xFF, 0xF9, 0xF0, 0xFC, 0xEE, 0x00,
0x00, 0x0C, 0x0E, 0x07, 0x1F, 0xFF, 0xF8, 0xE0, 0x70, 0x38, 0x08, 0x00, 0x77, 0x6E, 0x40, 0xFF,
0xFE, 0x77, 0x72, 0x0E, 0x1C, 0x70, 0xE1, 0xC7, 0x0E, 0x38, 0x70, 0xE3, 0x87, 0x00, 0x00, 0x1F,
0x1F, 0xCE, 0xFF, 0x3F, 0x9F, 0x8F, 0xC7, 0xF3, 0xF9, 0xDD, 0xEF, 0xE3, 0xF0, 0x40, 0x0E, 0x7D,
0xFB, 0xF2, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0x00, 0x1F, 0xBF, 0xEE, 0xF0, 0x38, 0x1C,
0x1C, 0x1E, 0x1E, 0x1E, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0x9F, 0xEC, 0xF0, 0x38, 0x78, 0xF8,
0x7E, 0x07, 0x81, 0xF1, 0xFF, 0xFF, 0xF0, 0xC0, 0x07, 0x03, 0xC1, 0xF0, 0x7C, 0x3F, 0x1D, 0xC7,
0x73, 0xFE, 0xFF, 0xFF, 0xF0, 0x70, 0x1C, 0x7F, 0x3F, 0x9F, 0xCE, 0x07, 0xE3, 0xF9, 0xFE, 0x07,
0x03, 0xA3, 0xFF, 0xCF, 0xE1, 0x80, 0x00, 0x0F, 0xCF, 0xEF, 0x07, 0x07, 0xFB, 0xFF, 0xFF, 0xF3,
0xF9, 0xDC, 0xEF, 0xF3, 0xF0, 0x60, 0xFF, 0xFF, 0xDF, 0xE0, 0xF0, 0x70, 0x78, 0x38, 0x1C, 0x1C,
0x0E, 0x0F, 0x07, 0x00, 0x00, 0x1F, 0x9F, 0xEE, 0x77, 0x3B, 0xF8, 0xF8, 0xFE, 0x77, 0xF1, 0xFC,
0xEF, 0xF7, 0xF0, 0x40, 0x00, 0x1F, 0x1F, 0xDE, 0xFE, 0x3F, 0x1F, 0xDE, 0xFF, 0x3F, 0x81, 0xC1,
0xCF, 0xE7, 0xE1, 0x80, 0x27, 0x77, 0x00, 0x07, 0x77, 0x20, 0x27, 0x77, 0x00, 0x00, 0x77, 0xEE,
0x40, 0x00, 0x81, 0xC3, 0xE7, 0xEF, 0x87, 0xC1, 0xFC, 0x1F, 0x03, 0x80, 0x40, 0x7F, 0xFF, 0xFF,
0xEF, 0xFF, 0xFF, 0xFC, 0x00, 0x70, 0x3E, 0x07, 0xC0, 0xF8, 0x7C, 0xFD, 0xF8, 0xF0, 0x00, 0x00,
0x00, 0xFE, 0xFF, 0xC7, 0x07, 0x0E, 0x1E, 0x38, 0x38, 0x00, 0x38, 0x38, 0x38, 0x10, 0x0F, 0xE0,
0x3F, 0xF0, 0xF0, 0xF3, 0xBF, 0xE7, 0xFE, 0xCD, 0xDD, 0xBB, 0x3B, 0x76, 0x76, 0x6F, 0xFC, 0xDF,
0xF1, 0xCC, 0xC1, 0xFF, 0x81, 0xFF, 0x00, 0xF8, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81, 0xF8, 0x3B,
0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F, 0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0xFF, 0x3F, 0xEF, 0xFB, 0x8E,
0xFF, 0xBF, 0xCF, 0xFB, 0x8F, 0xE3, 0xF9, 0xFF, 0xFB, 0xFC, 0x00, 0x03, 0xF8, 0xFF, 0x3E, 0xE7,
0x80, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xE3, 0x1F, 0xE1, 0xFC, 0x04, 0x00, 0xFF, 0x1F,
0xF3, 0xFF, 0x70, 0xEE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xDC, 0xFB, 0xFE, 0x7F, 0x80, 0xFF,
0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0, 0xE0,
0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x03, 0xFC, 0xFF, 0xBE, 0x67, 0x80, 0xE0, 0x1C,
0xFB, 0x9F, 0x73, 0xEE, 0x1D, 0xF3, 0x9F, 0xF1, 0xFE, 0x06, 0x00, 0xE1, 0xFC, 0x3F, 0x87, 0xF0,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xF0, 0xFF, 0xF3, 0x8E, 0x38,
0xE3, 0x8E, 0x38, 0xEF, 0xFF, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1,
0xDF, 0xBE, 0x38, 0xE3, 0xDC, 0x73, 0x9E, 0x77, 0x8F, 0xE1, 0xF8, 0x3F, 0x87, 0xF8, 0xE7, 0x1C,
0xF3, 0x8F, 0x71, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF,
0xF0, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x3F, 0xFC, 0xFF, 0xF3, 0xFF, 0xDF, 0xFB, 0xFF, 0xEF, 0xBF,
0xBE, 0xFE, 0x7B, 0xF9, 0xCF, 0xF0, 0xEF, 0x8E, 0xF8, 0xEF, 0xCE, 0xFE, 0xEE, 0xEE, 0xEF, 0xEE,
0x7E, 0xE7, 0xEE, 0x3E, 0xE1, 0xEE, 0x1E, 0x00, 0x00, 0xFE, 0x0F, 0xF8, 0xF9, 0xE7, 0x87, 0x38,
0x3D, 0xC1, 0xEE, 0x0F, 0x70, 0x7B, 0x83, 0x9F, 0x3C, 0x7F, 0xC1, 0xFC, 0x01, 0x00, 0xFE, 0x7F,
0xBF, 0xFC, 0x7E, 0x3F, 0xFF, 0xFD, 0xFC, 0xE0, 0x70, 0x38, 0x1C, 0x00, 0x00, 0x00, 0xFE, 0x0F,
0xF8, 0xF9, 0xE7, 0x87, 0x38, 0x3D, 0xC1, 0xEE, 0x0F, 0x70, 0x7B, 0x83, 0x9F, 0x3C, 0x7F, 0xC1,
0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1E, 0xFE, 0x3F, 0xCF, 0xFB, 0x8E, 0xE3, 0xBF, 0xEF, 0xF3, 0xF8,
0xE7, 0x39, 0xEE, 0x3B, 0x8F, 0x00, 0x1F, 0xDF, 0xEE, 0x67, 0x03, 0xC1, 0xF8, 0x7E, 0x0F, 0x81,
0xF9, 0xFF, 0xE7, 0xF0, 0xC0, 0xFF, 0xFF, 0xFF, 0xF8, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C,
0x07, 0x01, 0xC0, 0x70, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1,
0xFE, 0x79, 0xFF, 0x1F, 0xC0, 0xC0, 0xE0, 0xFC, 0x3F, 0xC7, 0x38, 0xE7, 0x1C, 0xF7, 0x0E, 0xE1,
0xDC, 0x3F, 0x03, 0xE0, 0x7C, 0x0F, 0x00, 0xE3, 0xC7, 0x71, 0xE3, 0xB8, 0xF1, 0xDE, 0x7D, 0xE7,
0x7E, 0xE3, 0xBF, 0x71, 0xDF, 0xB8, 0x7C, 0xFC, 0x3E, 0x7C, 0x1F, 0x3E, 0x0F, 0x9F, 0x03, 0x87,
0x80, 0xF1, 0xE7, 0x1C, 0x7B, 0xC3, 0xF8, 0x1F, 0x01, 0xF0, 0x1F, 0x03, 0xF8, 0x3B, 0x87, 0xBC,
0x71, 0xEE, 0x0E, 0xE1, 0xFE, 0x39, 0xCF, 0x3D, 0xC3, 0xF0, 0x3E, 0x07, 0x80, 0x70, 0x0E, 0x01,
0xC0, 0x38, 0x07, 0x00, 0xFF, 0xBF, 0xE7, 0xF8, 0x1C, 0x0F, 0x07, 0x81, 0xC0, 0xF0, 0x78, 0x1C,
0x0F, 0xFF, 0xFF, 0xF7, 0xB9, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x7B, 0xC0, 0xE1, 0xC1, 0xC3,
0x87, 0x07, 0x0E, 0x1C, 0x1C, 0x38, 0x38, 0x70, 0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73,
0xFF, 0xE0, 0x1C, 0x07, 0x03, 0xE0, 0xF8, 0x37, 0x1C, 0xC6, 0x3B, 0x86, 0x7F, 0x7F, 0x71, 0xE1,
0xC0, 0x1C, 0x3F, 0x8F, 0xE0, 0x73, 0xFB, 0xFF, 0xCF, 0xE7, 0x7F, 0xBF, 0xC4, 0x00, 0xE0, 0x70,
0x38, 0x1D, 0x8F, 0xF7, 0xFF, 0xDF, 0xC7, 0xE3, 0xF1, 0xFD, 0xFF, 0xFF, 0xF0, 0x20, 0x0E, 0x1F,
0x9F, 0xCE, 0x0F, 0x07, 0x83, 0xC0, 0xE2, 0x7F, 0x1F, 0x83, 0x00, 0x03, 0xC0, 0xF0, 0x3C, 0x6F,
0x3F, 0xDF, 0xF7, 0x3F, 0xCF, 0xF1, 0xFC, 0xF7, 0x3D, 0xFF, 0x3F, 0xC2, 0x00, 0x0C, 0x0F, 0xC7,
0xF9, 0xCE, 0xFF, 0xBF, 0xFF, 0x01, 0xC2, 0x7F, 0x8F, 0xE0, 0x40, 0x1E, 0x3E, 0x7E, 0x78, 0xFE,
0xFE, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x18, 0x0F, 0xF7, 0xFD, 0xCF, 0xF3, 0xFC, 0x7F,
0x1D, 0xCF, 0x7F, 0xCF, 0xF0, 0xBD, 0x8E, 0x7F, 0x9F, 0xC0, 0xE0, 0x70, 0x38, 0x1D, 0xCF, 0xF7,
0xFF, 0xCF, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x38, 0xFF, 0x8F, 0xFF, 0xFF, 0xFE, 0x1C, 0x71,
0xC0, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xDF, 0x78, 0xE0, 0x38, 0x0E, 0x03, 0x80,
0xE7, 0xBB, 0xCF, 0xE3, 0xF0, 0xFC, 0x3F, 0x8E, 0xF3, 0x9E, 0xE3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0x0C, 0x31, 0xFF, 0xFB, 0xFF, 0xF7, 0xBC, 0xEE, 0x39, 0xFC, 0x73, 0xF8, 0xE7, 0xF1, 0xCF,
0xE3, 0x9F, 0xC7, 0x3C, 0x0E, 0x7F, 0xBF, 0xFE, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xC0,
0x0C, 0x0F, 0xC7, 0xF9, 0xCF, 0xF1, 0xFC, 0x7F, 0x1D, 0xCF, 0x7F, 0x8F, 0xC0, 0x40, 0x0C, 0x7F,
0xBF, 0xFE, 0xFE, 0x3F, 0x1F, 0x8F, 0xEF, 0xFF, 0xFF, 0xB9, 0x1C, 0x0E, 0x07, 0x00, 0x18, 0x0F,
0xF7, 0xFD, 0xCF, 0xF3, 0xFC, 0x7F, 0x3D, 0xCF, 0x7F, 0xCF, 0xF0, 0xBC, 0x0F, 0x03, 0xC0, 0xF0,
0x05, 0xFF, 0xF7, 0xCE, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x1C, 0x7F, 0x7E, 0xF0, 0x7C, 0x7E, 0x1F,
0x47, 0xFF, 0xFE, 0x18, 0x00, 0x61, 0xE7, 0xFF, 0xEE, 0x1C, 0x38, 0x70, 0xF1, 0xF9, 0xF0, 0x80,
0x00, 0x71, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xCF, 0xFF, 0xBF, 0xC4, 0x00, 0x00, 0x38, 0xFF,
0x39, 0xCE, 0x77, 0x1F, 0xC3, 0xF0, 0xF8, 0x1E, 0x07, 0x80, 0x00, 0x01, 0xCF, 0x3B, 0x9E, 0x73,
0xBE, 0xE7, 0xFF, 0x8F, 0xFF, 0x1F, 0xBE, 0x1E, 0x7C, 0x3C, 0xF0, 0x79, 0xE0, 0x00, 0x3C, 0xE7,
0x78, 0xFC, 0x3E, 0x07, 0x83, 0xF1, 0xFC, 0x77, 0xBC, 0xF0, 0x00, 0x38, 0xFF, 0x39, 0xCE, 0x77,
0x9F, 0xC3, 0xF0, 0xF8, 0x1E, 0x07, 0x81, 0xC0, 0xF0, 0xF8, 0x3C, 0x00, 0x00, 0xFF, 0xFF, 0x0E,
0x1C, 0x3C, 0x38, 0x70, 0xFF, 0xFF, 0x1C, 0xF3, 0x8E, 0x38, 0xEF, 0xBC, 0xF8, 0xE3, 0x8E, 0x3C,
0xF1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF1, 0xE1, 0xE1, 0xC3, 0x87, 0x0F, 0x8F,
0x3C, 0x70, 0xE1, 0xC7, 0x9E, 0x3C, 0x00, 0x30, 0x7F, 0xFF, 0xE0, 0xE0, 0x07, 0x77, 0x07, 0x77,
0x77, 0x77, 0x70, 0x00, 0x18, 0x3F, 0x7F, 0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0x7F, 0x3E, 0x18,
0x08, 0x00, 0x07, 0xE3, 0xF8, 0xE4, 0x38, 0x0E, 0x0F, 0xF3, 0xFC, 0x38, 0x0E, 0x07, 0xFB, 0xFF,
0xFF, 0xC0, 0xE3, 0xFC, 0xE7, 0x79, 0xDC, 0x3F, 0x0F, 0x87, 0xF1, 0xFC, 0x3F, 0x1F, 0xC3, 0xF0,
0x70, 0x3E, 0x7E, 0x62, 0x78, 0x7E, 0x7E, 0x67, 0x7F, 0x7E, 0x1E, 0x07, 0xFE, 0x7E, 0x10, 0xCF,
0xFE, 0xC0, 0x00, 0x00, 0x3F, 0x03, 0xCF, 0x1D, 0xEC, 0x6F, 0x99, 0xB0, 0x6D, 0xC1, 0xB7, 0x06,
0x6C, 0x19, 0xBE, 0x67, 0x7B, 0x0E, 0x3C, 0x1F, 0xE0, 0x0C, 0x00, 0x01, 0xE7, 0xDF, 0xFF, 0xF7,
0xC0, 0x10, 0x07, 0x73, 0xB9, 0xDE, 0xF7, 0x1F, 0xE3, 0xB8, 0x77, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x03, 0xCF, 0x1F, 0xEC, 0x6F, 0xD9, 0xB3, 0x6C, 0xFD, 0xB3, 0xE6, 0x6D, 0x99, 0xB7, 0x67, 0xCF,
0x0E, 0x3C, 0x1F, 0xE0, 0x0C, 0x00, 0x7F, 0x9F, 0xF7, 0xFC, 0x00, 0xF9, 0xFF, 0x7E, 0xEF, 0x8E,
0x00, 0x3D, 0xEE, 0x00, 0x3F, 0xDF, 0xF7, 0xED, 0xFB, 0x7E, 0xDF, 0xB7, 0xED, 0xFB, 0x3E, 0xC1,
0xB0, 0x6C, 0x1B, 0x06, 0xC1, 0xB0, 0x6C, 0x00, 0x77, 0x72, 0x73, 0xFF, 0xE0, 0x01, 0xEF, 0xFB,
0xEF, 0xF7, 0x80, 0x22, 0x1D, 0xC7, 0x78, 0xEE, 0x3F, 0xCE, 0xE7, 0x71, 0xDC, 0x00, 0x00, 0x00,
0x1C, 0x1C, 0x1C, 0x00, 0x1C, 0x1C, 0x7C, 0x70, 0xE0, 0xE3, 0xFF, 0x7F, 0x18, 0x1C, 0x01, 0xE0,
0x07, 0x00, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81, 0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F,
0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x03, 0x80, 0x78, 0x0E, 0x00, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81,
0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F, 0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x0F, 0x01, 0xF8,
0x3B, 0x80, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81, 0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F,
0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x1D, 0x81, 0xF8, 0x3F, 0x80, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81,
0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F, 0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x1B, 0x01, 0xF8,
0x1B, 0x80, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81, 0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F,
0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x0F, 0x01, 0xF0, 0x1F, 0x00, 0xF0, 0x1F, 0x01, 0xF8, 0x1F, 0x83,
0xB8, 0x3B, 0xC3, 0x9C, 0x7F, 0xC7, 0xFE, 0xFF, 0xEF, 0x0E, 0xE0, 0xF0, 0x07, 0xFE, 0x1F, 0xFC,
0x3F, 0xF8, 0xFF, 0x01, 0xDF, 0xE3, 0xBF, 0xCE, 0x7F, 0x9F, 0xF0, 0x7F, 0xE0, 0xFF, 0xC3, 0xC7,
0xFF, 0x0F, 0xF0, 0x00, 0x03, 0xF8, 0xFF, 0x3E, 0xE7, 0x80, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E,
0x01, 0xE3, 0x1F, 0xE1, 0xFC, 0x0E, 0x01, 0xC0, 0x78, 0x0F, 0x00, 0x70, 0x38, 0x1C, 0x00, 0xFF,
0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x0F, 0x1E, 0x1C, 0x00, 0xFF,
0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x3C, 0x7E, 0xE7, 0x00, 0xFF,
0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x66, 0x7E, 0x7E, 0x00, 0xFF,
0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xF1, 0xC3, 0x80, 0xFF, 0xF3,
0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xEF, 0xFF, 0x1E, 0x38, 0xE0, 0x0F, 0xDF, 0x8E, 0x1C, 0x38, 0x70,
0xE1, 0xC3, 0x87, 0x3F, 0x7E, 0x3C, 0x7E, 0x77, 0x00, 0x7E, 0x7E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x1C, 0x1C, 0x7E, 0x7E, 0x6D, 0xFB, 0xB0, 0x0F, 0xDF, 0x8E, 0x1C, 0x38, 0x70, 0xE1, 0xC3,
0x87, 0x3F, 0x7E, 0x7F, 0x87, 0xFC, 0x7F, 0xE7, 0x0E, 0x70, 0xFF, 0xCF, 0xFC, 0xF7, 0xCF, 0x70,
0xE7, 0x3E, 0x7F, 0xC7, 0xF8, 0x1D, 0x81, 0xF8, 0x3F, 0x80, 0x00, 0xF0, 0xEF, 0x8E, 0xF8, 0xEF,
0xCE, 0xFE, 0xEE, 0xEE, 0xEF, 0xEE, 0x7E, 0xE7, 0xEE, 0x3E, 0xE1, 0xEE, 0x1E, 0x1E, 0x00, 0x78,
0x00, 0xE0, 0x00, 0x01, 0xFC, 0x1F, 0xF1, 0xF3, 0xCF, 0x0E, 0x70, 0x7B, 0x83, 0xDC, 0x1E, 0xE0,
0xF7, 0x07, 0x3E, 0x78, 0xFF, 0x83, 0xF8, 0x02, 0x00, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x00, 0x01,
0xFC, 0x1F, 0xF1, 0xF3, 0xCF, 0x0E, 0x70, 0x7B, 0x83, 0xDC, 0x1E, 0xE0, 0xF7, 0x07, 0x3E, 0x78,
0xFF, 0x83, 0xF8, 0x02, 0x00, 0x07, 0x80, 0x7E, 0x07, 0x70, 0x00, 0x01, 0xFC, 0x1F, 0xF1, 0xF3,
0xCF, 0x0E, 0x70, 0x7B, 0x83, 0xDC, 0x1E, 0xE0, 0xF7, 0x07, 0x3E, 0x78, 0xFF, 0x83, 0xF8, 0x02,
0x00, 0x0E, 0xC0, 0xFE, 0x06, 0xE0, 0x00, 0x01, 0xFC, 0x1F, 0xF1, 0xF3, 0xCF, 0x0E, 0x70, 0x7B,
0x83, 0xDC, 0x1E, 0xE0, 0xF7, 0x07, 0x3E, 0x78, 0xFF, 0x83, 0xF8, 0x02, 0x00, 0x0D, 0x80, 0xEE,
0x03, 0x60, 0x00, 0x01, 0xFC, 0x1F, 0xF1, 0xF3, 0xCF, 0x0E, 0x70, 0x7B, 0x83, 0xDC, 0x1E, 0xE0,
0xF7, 0x07, 0x3E, 0x78, 0xFF, 0x83, 0xF8, 0x02, 0x00, 0x42, 0xE7, 0xFE, 0x7C, 0x3C, 0x7E, 0xEF,
0xC6, 0x00, 0x20, 0xFF, 0x8F, 0xF8, 0xFB, 0xE7, 0x9F, 0x39, 0xFD, 0xCD, 0xEE, 0xEF, 0x7E, 0x7B,
0xE3, 0x9F, 0x3C, 0x7F, 0xC3, 0xFC, 0x19, 0x00, 0x3C, 0x03, 0x80, 0x38, 0x00, 0x0E, 0x1F, 0xC3,
0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00,
0x07, 0x80, 0xE0, 0x38, 0x00, 0x0E, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0,
0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x1E, 0x07, 0xE0, 0xEE, 0x00, 0x0E, 0x1F, 0xC3,
0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00,
0x1B, 0x07, 0xE0, 0xEC, 0x00, 0x0E, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0,
0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x07, 0x80, 0xE0, 0x38, 0x00, 0x0E, 0x1F, 0xE3,
0x9C, 0xF3, 0xDC, 0x3F, 0x03, 0xE0, 0x78, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0xE0, 0x70,
0x3F, 0xDF, 0xFE, 0x7F, 0x1F, 0x8F, 0xFF, 0xFF, 0x7F, 0x38, 0x1C, 0x00, 0x3F, 0x0F, 0xF3, 0xFE,
0x71, 0xCE, 0x79, 0xDE, 0x3B, 0x87, 0x7C, 0xE7, 0xDC, 0x3F, 0x87, 0xF7, 0xEE, 0xFC, 0x04, 0x00,
0x38, 0x0E, 0x03, 0x83, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80,
0x07, 0x87, 0x83, 0x83, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80,
0x1E, 0x1F, 0x9C, 0xE3, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80,
0x19, 0x9F, 0x8F, 0xC3, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80,
0x33, 0x1F, 0x8E, 0xC3, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80,
0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xC3, 0xF8, 0xFE, 0x07, 0x3F, 0xBF, 0xFC, 0xFE, 0x77, 0xFB, 0xFC,
0x40, 0x1C, 0x70, 0xFF, 0xF8, 0xFF, 0xF0, 0x1C, 0x73, 0xFF, 0xEF, 0xFF, 0xFC, 0xE0, 0x7B, 0xE2,
0x7F, 0xFC, 0xFD, 0xF8, 0x40, 0xC0, 0x0E, 0x1F, 0x9F, 0xCE, 0x0F, 0x07, 0x83, 0xC0, 0xE2, 0x7F,
0x1F, 0x87, 0x03, 0xC1, 0xE0, 0xF0, 0x38, 0x07, 0x00, 0xE0, 0x30, 0x3F, 0x1F, 0xE7, 0x3B, 0xFE,
0xFF, 0xFC, 0x07, 0x09, 0xFE, 0x3F, 0x81, 0x00, 0x07, 0x83, 0xC0, 0xE0, 0x30, 0x3F, 0x1F, 0xE7,
0x3B, 0xFE, 0xFF, 0xFC, 0x07, 0x09, 0xFE, 0x3F, 0x81, 0x00, 0x1E, 0x0F, 0xC7, 0x38, 0x30, 0x3F,
0x1F, 0xE7, 0x3B, 0xFE, 0xFF, 0xFC, 0x07, 0x09, 0xFE, 0x3F, 0x81, 0x00, 0x37, 0x0F, 0xC3, 0x70,
0x30, 0x3F, 0x1F, 0xE7, 0x3B, 0xFE, 0xFF, 0xFC, 0x07, 0x09, 0xFE, 0x3F, 0x81, 0x00, 0xF1, 0xE3,
0x80, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0x39, 0xCE, 0x00, 0xE3, 0x8E, 0x38, 0xE3, 0x8E,
0x38, 0xE0, 0x7C, 0x7C, 0xEE, 0x00, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x6D,
0xDD, 0xB0, 0x03, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x80, 0x19, 0x07, 0xE1, 0xF0, 0x7E,
0x1B, 0x8F, 0xF7, 0xFD, 0xCF, 0xF1, 0xFC, 0x77, 0x3D, 0xFE, 0x3F, 0x03, 0x00, 0x3B, 0x3F, 0x9B,
0x81, 0xCF, 0xF7, 0xFF, 0xCF, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x38, 0x3C, 0x07, 0x00, 0xE0,
0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC, 0x77, 0x3D, 0xFE, 0x3F, 0x01, 0x00, 0x07, 0x81,
0xC0, 0xE0, 0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC, 0x77, 0x3D, 0xFE, 0x3F, 0x01, 0x00,
0x1E, 0x0F, 0xC7, 0x38, 0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC, 0x77, 0x3D, 0xFE, 0x3F,
0x01, 0x00, 0x19, 0x8F, 0xE3, 0xF0, 0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC, 0x77, 0x3D,
0xFE, 0x3F, 0x01, 0x00, 0x3B, 0x0F, 0xC3, 0xB0, 0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC,
0x77, 0x3D, 0xFE, 0x3F, 0x01, 0x00, 0x1C, 0x0E, 0x03, 0x1F, 0xFF, 0xF8, 0x40, 0x70, 0x38, 0x08,
0x00, 0x0D, 0x0F, 0xE7, 0xF9, 0xDF, 0xF7, 0xFF, 0xFF, 0xDD, 0xEF, 0x7F, 0x9F, 0xC2, 0x40, 0x78,
0x1E, 0x07, 0x00, 0x0E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0x07,
0x07, 0x07, 0x00, 0x0E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0x3E,
0x1F, 0x1D, 0xC0, 0x0E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0x36,
0x3B, 0x8D, 0x80, 0x0E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0x07,
0x03, 0xC1, 0xC0, 0x00, 0xE3, 0xFC, 0xE7, 0x39, 0xDE, 0x7F, 0x0F, 0xC3, 0xE0, 0x78, 0x1E, 0x07,
0x03, 0xC3, 0xE0, 0xF0, 0x00, 0xE0, 0x70, 0x38, 0x1D, 0x8F, 0xF7, 0xFF, 0xDF, 0xC7, 0xE3, 0xF1,
0xFD, 0xFF, 0xFF, 0xF7, 0x23, 0x81, 0xC0, 0xE0, 0x00, 0x36, 0x0F, 0xC3, 0x70, 0x00, 0xE3, 0xFC,
0xE7, 0x39, 0xDE, 0x7F, 0x0F, 0xC3, 0xE0, 0x78, 0x1E, 0x07, 0x03, 0xC3, 0xE0, 0xF0, 0x00, 0x1F,
0x81, 0xF8, 0x00, 0x00, 0xF0, 0x1F, 0x01, 0xF8, 0x1F, 0x83, 0xB8, 0x3B, 0xC3, 0x9C, 0x7F, 0xC7,
0xFE, 0xFF, 0xEF, 0x0E, 0xE0, 0xF0, 0x3F, 0x1F, 0x87, 0x0F, 0xE3, 0xF8, 0x1C, 0xFE, 0xFF, 0xF3,
0xF9, 0xDF, 0xEF, 0xF1, 0x00, 0x31, 0x81, 0xF8, 0x1F, 0x00, 0x00, 0x0F, 0x01, 0xF0, 0x1F, 0x81,
0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F, 0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x33, 0x9F, 0x87,
0x83, 0x87, 0xF1, 0xFC, 0x0E, 0x7F, 0x7F, 0xF9, 0xFC, 0xEF, 0xF7, 0xF8, 0x80, 0x0F, 0x01, 0xF0,
0x1F, 0x81, 0xF8, 0x3B, 0x83, 0xBC, 0x39, 0xC7, 0xFC, 0x7F, 0xEF, 0xFE, 0xF0, 0xEE, 0x0F, 0x00,
0xE0, 0x0C, 0x00, 0xE0, 0x0F, 0x1C, 0x3F, 0x8F, 0xE0, 0x73, 0xFB, 0xFF, 0xCF, 0xE7, 0x7F, 0xBF,
0xC4, 0xE0, 0xE0, 0x78, 0x1C, 0x03, 0xC0, 0x70, 0x1C, 0x00, 0x01, 0xFC, 0x7F, 0x9F, 0x73, 0xC0,
0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xF1, 0x8F, 0xF0, 0xFE, 0x02, 0x00, 0x07, 0x07, 0x87,
0x01, 0xC3, 0xF3, 0xF9, 0xC1, 0xE0, 0xF0, 0x78, 0x1C, 0x4F, 0xE3, 0xF0, 0x60, 0x07, 0x00, 0xE0,
0x1C, 0x00, 0x01, 0xFC, 0x7F, 0x9F, 0x73, 0xC0, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xF1,
0x8F, 0xF0, 0xFE, 0x02, 0x00, 0x1C, 0x0E, 0x07, 0x01, 0xC3, 0xF3, 0xF9, 0xC1, 0xE0, 0xF0, 0x78,
0x1C, 0x4F, 0xE3, 0xF0, 0x60, 0x19, 0xC3, 0xF0, 0x3C, 0x00, 0x01, 0xFC, 0x7F, 0x9F, 0x73, 0xC0,
0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0xF1, 0x8F, 0xF0, 0xFE, 0x02, 0x00, 0x73, 0x1F, 0x87,
0x81, 0xC3, 0xF3, 0xF9, 0xC1, 0xE0, 0xF0, 0x78, 0x1C, 0x4F, 0xE3, 0xF0, 0x60, 0x73, 0x87, 0xE0,
0x78, 0x00, 0x0F, 0xF1, 0xFF, 0x3F, 0xF7, 0x0E, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1D, 0xCF,
0xBF, 0xE7, 0xF8, 0x03, 0xF8, 0x1F, 0xC0, 0xFC, 0x37, 0x83, 0xFC, 0x3F, 0xE1, 0xCF, 0x1E, 0x78,
0xF1, 0xC7, 0x9E, 0x1C, 0xF0, 0xFF, 0x83, 0xFC, 0x04, 0x00, 0x7F, 0x87, 0xFC, 0x7F, 0xE7, 0x0E,
0x70, 0xFF, 0xCF, 0xFC, 0xF7, 0xCF, 0x70, 0xE7, 0x3E, 0x7F, 0xC7, 0xF8, 0x03, 0xC1, 0xFC, 0x3F,
0x87, 0xF3, 0xFC, 0xFF, 0x9F, 0xF7, 0x9E, 0xF1, 0xDE, 0x39, 0xCF, 0x3F, 0xE3, 0xFC, 0x10, 0x00,
0x7E, 0x7E, 0x00, 0xFF, 0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x3F,
0x0F, 0xC0, 0xC0, 0xFC, 0x7F, 0x9C, 0xEF, 0xFB, 0xFF, 0xF0, 0x1C, 0x27, 0xF8, 0xFE, 0x04, 0x00,
0x18, 0x3C, 0x18, 0x00, 0xFF, 0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF,
0x0C, 0x07, 0x80, 0xC0, 0x30, 0x3F, 0x1F, 0xE7, 0x3B, 0xFE, 0xFF, 0xFC, 0x07, 0x09, 0xFE, 0x3F,
0x81, 0x00, 0xFF, 0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x0E, 0x0C,
0x0F, 0x0F, 0x0C, 0x0F, 0xC7, 0xF9, 0xCE, 0xFF, 0xBF, 0xFF, 0x01, 0xC2, 0x7F, 0x8F, 0xE0, 0x70,
0x18, 0x07, 0x81, 0xE0, 0xE7, 0x7E, 0x3C, 0x00, 0xFF, 0xFF, 0xFE, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0,
0xE0, 0xE0, 0xFF, 0xFF, 0x73, 0x8F, 0xC1, 0xE0, 0x30, 0x3F, 0x1F, 0xE7, 0x3B, 0xFE, 0xFF, 0xFC,
0x07, 0x09, 0xFE, 0x3F, 0x81, 0x00, 0x18, 0xC3, 0xF8, 0x3E, 0x00, 0x01, 0xFE, 0x7F, 0xDF, 0x33,
0xC0, 0x70, 0x0E, 0x7D, 0xCF, 0xB9, 0xF7, 0x0E, 0xF9, 0xCF, 0xF8, 0xFF, 0x03, 0x00, 0x33, 0x8F,
0xC1, 0xF0, 0x60, 0x3F, 0xDF, 0xF7, 0x3F, 0xCF, 0xF1, 0xFC, 0x77, 0x3D, 0xFF, 0x3F, 0xC2, 0xF6,
0x39, 0xFE, 0x7F, 0x00, 0x07, 0x00, 0xE0, 0x1C, 0x00, 0x01, 0xFE, 0x7F, 0xDF, 0x33, 0xC0, 0x70,
0x0E, 0x7D, 0xCF, 0xB9, 0xF7, 0x0E, 0xF9, 0xCF, 0xF8, 0xFF, 0x03, 0x00, 0x0E, 0x03, 0x80, 0xE0,
0x60, 0x3F, 0xDF, 0xF7, 0x3F, 0xCF, 0xF1, 0xFC, 0x77, 0x3D, 0xFF, 0x3F, 0xC2, 0xF6, 0x39, 0xFE,
0x7F, 0x00, 0x00, 0x03, 0xFC, 0xFF, 0xBE, 0x67, 0x80, 0xE0, 0x1C, 0xFB, 0x9F, 0x73, 0xEE, 0x1D,
0xF3, 0x9F, 0xF1, 0xFE, 0x06, 0x01, 0xC0, 0x38, 0x06, 0x00, 0x06, 0x03, 0x80, 0xC0, 0x60, 0x3F,
0xDF, 0xF7, 0x3F, 0xCF, 0xF1, 0xFC, 0x77, 0x3D, 0xFF, 0x3F, 0xC2, 0xF6, 0x39, 0xFE, 0x7F, 0x00,
0x70, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x3F, 0xF9, 0xFF, 0xCE, 0x1E, 0x70, 0xF3, 0x87,
0x9C, 0x3C, 0xE1, 0xE0, 0x70, 0x3F, 0x8F, 0xE3, 0xF0, 0x7F, 0x9F, 0xF7, 0xFD, 0xC7, 0x71, 0xDC,
0x77, 0x1D, 0xC7, 0x71, 0xC0, 0xFF, 0xF0, 0x3F, 0xFC, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x3B, 0xFF,
0xC0, 0xFF, 0xFC, 0x01, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0xFF, 0xF3, 0x8E, 0x38,
0xE3, 0x8E, 0x38, 0xEF, 0xFF, 0x18, 0xE3, 0xC7, 0x73, 0x9C, 0x07, 0x39, 0xCE, 0x73, 0x9C, 0xE7,
0x39, 0x9E, 0x70, 0x38, 0xE3, 0x80, 0xFF, 0xF3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xEF, 0xFF, 0x1F,
0xFF, 0xFF, 0xFC, 0xE3, 0xDC, 0x73, 0x9E, 0x77, 0x8F, 0xE1, 0xF8, 0x3F, 0x87, 0xF8, 0xE7, 0x1C,
0xF3, 0x8F, 0x71, 0xE0, 0x00, 0x38, 0x07, 0x00, 0xC0, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE7, 0xBB,
0xCF, 0xE3, 0xF0, 0xFC, 0x3F, 0x8E, 0xF3, 0x9E, 0xE3, 0x80, 0x01, 0xC0, 0x60, 0x38, 0x00, 0x38,
0x78, 0xE0, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x39,
0xCE, 0x00, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0x00, 0x1C, 0x18, 0x38, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0x3F, 0xC0, 0xE3, 0xF3, 0xB9, 0xDC, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x3F, 0xDF,
0xE0, 0xFD, 0xFB, 0xE7, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x00, 0x70, 0x38, 0x1C,
0x0E, 0x07, 0xC3, 0xE3, 0xE1, 0xE0, 0x70, 0x38, 0x1F, 0xEF, 0xF0, 0x38, 0x70, 0xE1, 0xC3, 0x87,
0x8F, 0x3E, 0x78, 0xF0, 0xE1, 0xC3, 0x80, 0x03, 0x80, 0x78, 0x0E, 0x00, 0x00, 0xF0, 0xEF, 0x8E,
0xF8, 0xEF, 0xCE, 0xFE, 0xEE, 0xEE, 0xEF, 0xEE, 0x7E, 0xE7, 0xEE, 0x3E, 0xE1, 0xEE, 0x1E, 0x07,
0x07, 0x07, 0x01, 0xCF, 0xF7, 0xFF, 0xCF, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x38, 0xF0, 0xEF,
0x8E, 0xF8, 0xEF, 0xCE, 0xFE, 0xEE, 0xEE, 0xEF, 0xEE, 0x7E, 0xE7, 0xEE, 0x3E, 0xE1, 0xEE, 0x1E,
0x00, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x0E, 0x7F, 0xBF, 0xFE, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3,
0xF1, 0xC0, 0x03, 0x81, 0xC0, 0xC0, 0x39, 0x81, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0xEF, 0x8E, 0xF8,
0xEF, 0xCE, 0xFE, 0xEE, 0xEE, 0xEF, 0xEE, 0x7E, 0xE7, 0xEE, 0x3E, 0xE1, 0xEE, 0x1E, 0x77, 0x3F,
0x8F, 0x81, 0xCF, 0xF7, 0xFF, 0xCF, 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x38, 0xF0, 0xEF, 0x8E,
0xFC, 0xEF, 0xEE, 0xFE, 0xEE, 0xFE, 0xE7, 0xEE, 0x7E, 0xE3, 0xEE, 0x1E, 0xE1, 0xEE, 0x0E, 0x00,
0xE0, 0x7E, 0x07, 0xE0, 0x38, 0x0E, 0x7F, 0xBF, 0xFE, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1,
0xC0, 0xE0, 0x70, 0xF8, 0x78, 0x0F, 0xC0, 0x7E, 0x00, 0x00, 0x3F, 0x83, 0xFE, 0x3E, 0x79, 0xE1,
0xCE, 0x0F, 0x70, 0x7B, 0x83, 0xDC, 0x1E, 0xE0, 0xE7, 0xCF, 0x1F, 0xF0, 0x7F, 0x00, 0x40, 0x3F,
0x0F, 0xC0, 0xC0, 0xFC, 0x7F, 0x9C, 0xFF, 0x1F, 0xC7, 0xF1, 0xDC, 0xF7, 0xF8, 0xFC, 0x04, 0x00,
0x0F, 0xC0, 0xFE, 0x06, 0xE0, 0x00, 0x01, 0xFC, 0x1F, 0xF1, 0xF3, 0xCF, 0x0E, 0x70, 0x7B, 0x83,
0xDC, 0x1E, 0xE0, 0xF7, 0x07, 0x3E, 0x78, 0xFF, 0x83, 0xF8, 0x02, 0x00, 0x1F, 0x8F, 0xC7, 0x60,
0x30, 0x3F, 0x1F, 0xE7, 0x3F, 0xC7, 0xF1, 0xFC, 0x77, 0x3D, 0xFE, 0x3F, 0x01, 0x00, 0x00, 0x00,
0x1F, 0xFF, 0x3F, 0xFF, 0x7D, 0xFE, 0x70, 0xE0, 0x70, 0xFE, 0x70, 0xFE, 0x70, 0xFE, 0x70, 0xE0,
0x70, 0xE0, 0x78, 0xE0, 0x3F, 0xFF, 0x1F, 0xFF, 0x02, 0x00, 0x0C, 0x38, 0x3F, 0xFE, 0x7F, 0xFE,
0x73, 0xC7, 0xF1, 0xFF, 0xF1, 0xFF, 0xF1, 0xC0, 0x73, 0xC2, 0x7F, 0xFE, 0x3F, 0xFE, 0x04, 0x18,
0x07, 0x03, 0x81, 0xC0, 0x00, 0xFE, 0x3F, 0xCF, 0xFB, 0x8E, 0xE3, 0xBF, 0xEF, 0xF3, 0xF8, 0xE7,
0x39, 0xEE, 0x3B, 0x8F, 0x1E, 0x38, 0xE0, 0x2F, 0xFF, 0xBE, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x00,
0xFE, 0x3F, 0xCF, 0xFB, 0x8E, 0xE3, 0xBF, 0xEF, 0xF3, 0xF8, 0xE7, 0x39, 0xEE, 0x3B, 0x8F, 0x00,
0x03, 0x81, 0xC0, 0x70, 0x05, 0xFF, 0xF7, 0xCE, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x07, 0x0E, 0x18,
0x00, 0x77, 0x0F, 0xC3, 0xE0, 0x00, 0xFE, 0x3F, 0xCF, 0xFB, 0x8E, 0xE3, 0xBF, 0xEF, 0xF3, 0xF8,
0xE7, 0x39, 0xEE, 0x3B, 0x8F, 0x67, 0x7E, 0x3C, 0x02, 0x7F, 0x7E, 0x7C, 0x70, 0x70, 0x70, 0x70,
0x70, 0x70, 0x07, 0x07, 0x87, 0x00, 0x03, 0xFB, 0xFD, 0xCC, 0xE0, 0x78, 0x3F, 0x0F, 0xC1, 0xF0,
0x3F, 0x3F, 0xFC, 0xFE, 0x18, 0x00, 0x0F, 0x1E, 0x1C, 0x1C, 0x7F, 0x7E, 0xF0, 0x7C, 0x7E, 0x1F,
0x47, 0xFF, 0xFE, 0x18, 0x00, 0x1F, 0xDF, 0xEE, 0x67, 0x03, 0xC1, 0xF8, 0x7E, 0x0F, 0x81, 0xF9,
0xFF, 0xE7, 0xF0, 0xE0, 0x78, 0x7C, 0x3C, 0x00, 0x1C, 0x7F, 0x7E, 0xF0, 0x7C, 0x7E, 0x1F, 0x47,
0xFF, 0xFE, 0x3C, 0x1C, 0x3C, 0x3C, 0x73, 0x1F, 0x87, 0x80, 0x03, 0xFB, 0xFD, 0xCC, 0xE0, 0x78,
0x3F, 0x0F, 0xC1, 0xF0, 0x3F, 0x3F, 0xFC, 0xFE, 0x18, 0x00, 0xE7, 0x7E, 0x3C, 0x1C, 0x7F, 0x7E,
0xF0, 0x7C, 0x7E, 0x1F, 0x47, 0xFF, 0xFE, 0x18, 0x73, 0x8F, 0xC1, 0xE0, 0x00, 0xFF, 0xFF, 0xFF,
0xF8, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x01, 0xC0, 0x63, 0x39,
0xE0, 0xFE, 0x3F, 0x87, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x81, 0xF8, 0x3E, 0x02, 0x00, 0x3F, 0x07,
0xE0, 0x00, 0x70, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFF, 0x3C,
0xFF, 0x8F, 0xE0, 0x60, 0x7F, 0x3F, 0x80, 0x1C, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF3, 0xFF,
0xEF, 0xF1, 0x00, 0x31, 0x87, 0xE0, 0x7C, 0x00, 0x0E, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC,
0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x63, 0x3F, 0x8F, 0x80, 0x0E,
0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0x1E, 0x03, 0xE0, 0x7C, 0x0F,
0x00, 0x01, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xFC, 0xF3,
0xFE, 0x3F, 0x81, 0x80, 0x1C, 0x1F, 0x0F, 0x83, 0x80, 0x07, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF8,
0xFC, 0xFF, 0xFB, 0xFC, 0x40, 0x1F, 0x87, 0xE1, 0xD8, 0x00, 0x0E, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F,
0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xE7, 0x9F, 0xF1, 0xFC, 0x0C, 0x00, 0x3F, 0x3F, 0x9B,
0x00, 0x0E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF9, 0xFF, 0xF7, 0xF8, 0x80, 0xE1, 0xFC, 0x3F,
0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFE, 0x79, 0xFF, 0x1F, 0xC0, 0xF0, 0x0E,
0x01, 0xE0, 0x3C, 0x00, 0x71, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xCF, 0xFF, 0xBF, 0xC4, 0xC0,
0xC0, 0x78, 0x3C, 0x03, 0xC0, 0x03, 0xF0, 0x03, 0x9C, 0x00, 0x00, 0x0E, 0x3C, 0x77, 0x1E, 0x3B,
0x8F, 0x1D, 0xE7, 0xDE, 0x77, 0xEE, 0x3B, 0xF7, 0x1D, 0xFB, 0x87, 0xCF, 0xC3, 0xE7, 0xC1, 0xF3,
0xE0, 0xF9, 0xF0, 0x38, 0x78, 0x07, 0x80, 0x1F, 0x80, 0x73, 0x80, 0x00, 0x0E, 0x79, 0xDC, 0xF3,
0x9D, 0xF7, 0x3F, 0xFC, 0x7F, 0xF8, 0xFD, 0xF0, 0xF3, 0xE1, 0xE7, 0x83, 0xCF, 0x00, 0x1E, 0x07,
0xE1, 0xEE, 0x00, 0x0E, 0x1F, 0xE3, 0x9C, 0xF3, 0xDC, 0x3F, 0x03, 0xE0, 0x78, 0x07, 0x00, 0xE0,
0x1C, 0x03, 0x80, 0x70, 0x1E, 0x0F, 0xC7, 0x70, 0x00, 0xE3, 0xFC, 0xE7, 0x39, 0xDE, 0x7F, 0x0F,
0xC3, 0xE0, 0x78, 0x1E, 0x07, 0x03, 0xC3, 0xE0, 0xF0, 0x00, 0x3B, 0x07, 0xE0, 0xEC, 0x00, 0x0E,
0x1F, 0xE3, 0x9C, 0xF3, 0xDC, 0x3F, 0x03, 0xE0, 0x78, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70,
0x07, 0x83, 0xC0, 0xE0, 0x00, 0xFF, 0xBF, 0xE7, 0xF8, 0x1C, 0x0F, 0x07, 0x81, 0xC0, 0xF0, 0x78,
0x1C, 0x0F, 0xFF, 0xFF, 0x0F, 0x1E, 0x1C, 0x00, 0xFF, 0xFF, 0x0E, 0x1C, 0x3C, 0x38, 0x70, 0xFF,
0xFF, 0x0C, 0x07, 0x80, 0xC0, 0x00, 0xFF, 0xBF, 0xE7, 0xF8, 0x1C, 0x0F, 0x07, 0x81, 0xC0, 0xF0,
0x78, 0x1C, 0x0F, 0xFF, 0xFF, 0x18, 0x3C, 0x18, 0x00, 0xFF, 0xFF, 0x0E, 0x1C, 0x3C, 0x38, 0x70,
0xFF, 0xFF, 0x73, 0x8F, 0xC1, 0xE0, 0x00, 0xFF, 0xBF, 0xE7, 0xF8, 0x1C, 0x0F, 0x07, 0x81, 0xC0,
0xF0, 0x78, 0x1C, 0x0F, 0xFF, 0xFF, 0xE7, 0x7E, 0x3C, 0x00, 0xFF, 0xFF, 0x0E, 0x1C, 0x3C, 0x38,
0x70, 0xFF, 0xFF, 0xF3, 0x8E, 0x39, 0xEE, 0x00, 0x3C, 0x7E, 0xE7, 0x76, 0xFF, 0xF8, 0xFF, 0xF0,
0x67, 0x7E, 0x3C, 0x6F, 0x60, 0xCF, 0xFF, 0xC0, 0xF7, 0xBD, 0xE0, 0x7F, 0x7E, 0xEC, 0xE7, 0x7E,
0x3C, 0x77, 0xEE, 0x60, 0x7E, 0xE0, 0x67, 0xFF, 0x26, 0xEF, 0xF0, 0xFF, 0xF0, 0x1E, 0x0F, 0xE7,
0xF9, 0xCF, 0x7B, 0xDE, 0xF7, 0x3D, 0xCF, 0x73, 0xDC, 0xF0, 0x31, 0x7D, 0xDE, 0xE7, 0x77, 0xBB,
0x9D, 0xCE, 0xE7, 0x7F, 0x9F, 0x83, 0x00, 0x49, 0x7F, 0xDE, 0xE7, 0x77, 0xBB, 0x9D, 0xCE, 0xE7,
0x7F, 0x9F, 0x83, 0x00, 0x1C, 0x3F, 0xBF, 0xFC, 0xFE, 0x3F, 0xDF, 0xEF, 0xC7, 0xE3, 0xF1, 0xC0,
0x77, 0x7F, 0xFF, 0xFD, 0x7E, 0x3F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xC0, 0x49, 0xBF, 0x77, 0xDC,
0xE7, 0x79, 0xDC, 0x77, 0x1D, 0xEF, 0x7F, 0xDF, 0xE0, 0x20, 0xCC, 0x7F, 0xBB, 0xFE, 0x77, 0x3B,
0x9D, 0xEE, 0x7F, 0x3F, 0x1F, 0x00, 0x3C, 0x7F, 0xBF, 0xC0, 0xF7, 0x3B, 0xDD, 0xEE, 0x7F, 0x3F,
0x1F, 0x00, 0x3C, 0x7F, 0xBF, 0xD0, 0xEE, 0x7F, 0x3F, 0x9F, 0xCF, 0xFF, 0xBF, 0xC4, 0x00, 0x31,
0xBE, 0xE7, 0xF8, 0xFE, 0x7B, 0x9C, 0xE7, 0x39, 0xCE, 0x7F, 0x8F, 0xC0, 0xC0, 0x49, 0xBE, 0xE7,
0xF8, 0xFE, 0x7B, 0x9C, 0xE7, 0x39, 0xCE, 0x7F, 0x8F, 0xC0, 0xC0, 0x1E, 0x0C, 0xFE, 0x3D, 0xFE,
0x7B, 0x9C, 0xF7, 0xB9, 0xEF, 0x73, 0xDC, 0xE7, 0xB9, 0xEF, 0x7B, 0xFC, 0xF7, 0xF8, 0x40, 0x40,
0x1E, 0x0C, 0xFE, 0x3D, 0xFE, 0x7B, 0x9C, 0xF7, 0xB9, 0xEF, 0x73, 0xDC, 0xE7, 0xB9, 0xFF, 0x7B,
0xFE, 0xF3, 0xFC, 0x44, 0x70, 0x0F, 0xE0, 0x1F, 0x80, 0x1C, 0x00, 0x0E, 0x0F, 0xE7, 0xF9, 0xCF,
0x79, 0xDE, 0x77, 0x1D, 0xC7, 0xF1, 0xFC, 0x71, 0xDC, 0xFF, 0x7F, 0xDC, 0x70, 0x0E, 0x0F, 0xE7,
0xF9, 0xCF, 0x79, 0xDE, 0x77, 0x1D, 0xC7, 0xF1, 0xFC, 0x73, 0x1D, 0xFF, 0x7F, 0xDB, 0x70, 0x3D,
0xBF, 0xEF, 0xF0, 0x1E, 0x73, 0x9E, 0xE7, 0xB8, 0xFE, 0x3F, 0x0F, 0x82, 0x39, 0xFE, 0xFF, 0xBA,
0xE0, 0x4B, 0x3F, 0xF7, 0xFC, 0xF7, 0x79, 0xDC, 0x77, 0x1D, 0xC7, 0x71, 0xDC, 0x70, 0x1B, 0x04,
0xFF, 0x1D, 0xFF, 0x3B, 0xAE, 0x77, 0x1C, 0xFE, 0x39, 0xDC, 0x73, 0xB8, 0xFF, 0x7D, 0xFE, 0x7B,
0xF8, 0x20, 0x60, 0x1E, 0x0C, 0xFE, 0x3D, 0xFE, 0x7B, 0x9C, 0xF7, 0xB9, 0xEF, 0x73, 0xDC, 0xE7,
0xB9, 0xEF, 0x7B, 0xFE, 0xF3, 0xFC, 0x41, 0x00, 0x0E, 0x0F, 0xE7, 0xF9, 0xCF, 0xF1, 0xFC, 0x7F,
0x1D, 0xC7, 0x7D, 0xCF, 0x70, 0x80, 0x1B, 0x1F, 0xF7, 0xFD, 0xD7, 0x71, 0xFC, 0x77, 0x1D, 0xC7,
0x7D, 0xCF, 0x70, 0x80, 0x1E, 0x0F, 0xE7, 0xF9, 0xCF, 0x7B, 0xDE, 0xF7, 0x3D, 0xCF, 0x7B, 0xDE,
0xF1, 0x00, 0x4E, 0x7F, 0xBF, 0xFE, 0xFE, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xC0, 0x1E, 0x3F,
0x9F, 0xDF, 0x07, 0xF1, 0xFD, 0xDE, 0xE7, 0x7F, 0xBF, 0x87, 0x00, 0x43, 0x71, 0xF8, 0xFC, 0x7E,
0x3F, 0x1F, 0x9F, 0xEF, 0xFF, 0xBF, 0xC4, 0x00, 0x43, 0x71, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F,
0xCF, 0xFF, 0x3F, 0x86, 0x00, 0x03, 0x81, 0xC0, 0xE8, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1,
0xF9, 0xFF, 0xE7, 0xF0, 0xC0, 0x71, 0xBC, 0xEF, 0x3B, 0x8E, 0xFF, 0xBF, 0xEF, 0xFB, 0xDE, 0xF7,
0xB8, 0xE0, 0x01, 0x80, 0xE0, 0x39, 0xCE, 0xF3, 0xBC, 0xEE, 0x3B, 0xFE, 0xFF, 0xBF, 0xEF, 0x7B,
0xDE, 0xE3, 0x80, 0x60, 0x2E, 0x67, 0xFF, 0x77, 0xFF, 0x7F, 0xE7, 0xFE, 0x7F, 0xE7, 0xFE, 0x79,
0xE3, 0x9C, 0x00, 0x70, 0x07, 0x00, 0x76, 0x07, 0xE6, 0x7F, 0xFE, 0x7F, 0xE7, 0xFE, 0x7F, 0xE7,
0xFE, 0x7F, 0xE7, 0x9E, 0x39, 0xC0, 0x0E, 0x0F, 0xE7, 0xF9, 0xCF, 0x79, 0xDE, 0x77, 0x1D, 0xC7,
0xF1, 0xFC, 0x74, 0x00, 0x43, 0x71, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xEF, 0xFF, 0xFF, 0x81,
0x00, 0x19, 0x9F, 0xF7, 0xFD, 0xCF, 0x7F, 0xDF, 0xF7, 0x3D, 0xCF, 0x7F, 0x9F, 0xE0, 0xC0, 0x1E,
0x3F, 0x9F, 0xDE, 0x07, 0xC3, 0xF8, 0x7C, 0x8E, 0xFF, 0x7F, 0x86, 0x00, 0x1E, 0x0F, 0xE7, 0xF9,
0xCF, 0x7B, 0xDE, 0xF7, 0x3D, 0xCF, 0x7B, 0xDE, 0xF1, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x1E, 0x3F,
0x9F, 0xE8, 0x71, 0xFB, 0xFF, 0xFF, 0xE7, 0xFB, 0xBF, 0xC4, 0x00, 0x0E, 0x0F, 0xE7, 0xF9, 0xCF,
0x79, 0xDE, 0x77, 0x1D, 0xC7, 0xF1, 0xFC, 0x74, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x38, 0xFE, 0xFF,
0x0F, 0x07, 0x07, 0x07, 0x4F, 0x7E, 0xFE, 0x18, 0x1D, 0xDF, 0xEF, 0xFB, 0x8E, 0xE3, 0xBE, 0xEF,
0xBB, 0x8E, 0xE3, 0xB8, 0xE0, 0x41, 0x38, 0xEE, 0x3B, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0x8E, 0xFF,
0x9F, 0xC1, 0xC0, 0x1D, 0xDF, 0xF7, 0xF9, 0x0E, 0x1F, 0x9F, 0xEF, 0xFB, 0xCE, 0xFB, 0x9F, 0xE1,
0x00, 0x43, 0x73, 0xBB, 0xDF, 0xCF, 0xF7, 0xFF, 0xDF, 0xC7, 0xE3, 0xF1, 0xC0, 0x00, 0x70, 0x3F,
0x63, 0xEE, 0x3E, 0xF6, 0xF7, 0x6E, 0x7F, 0xE7, 0xFE, 0x7F, 0xE7, 0xFE, 0x79, 0xE7, 0x9C, 0x1C,
0x1F, 0xC7, 0xF9, 0x0E, 0x7B, 0xBE, 0xEF, 0xB9, 0xCE, 0x7F, 0x8F, 0xC0, 0xC0, 0x1D, 0xDF, 0xF7,
0xF9, 0x0E, 0x7B, 0xBE, 0xEF, 0xB9, 0xCE, 0x7F, 0x8F, 0xC0, 0xC0, 0x32, 0xFF, 0xF7, 0xE7, 0xFF,
0xFF, 0x3F, 0x07, 0x07, 0x07, 0x43, 0x8F, 0xDF, 0x01, 0x8F, 0x9F, 0x38, 0x01, 0xC3, 0xFB, 0xF0,
0x71, 0xFB, 0xF0, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x30, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x00,
0x1C, 0x01, 0xF8, 0x0F, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x38,
0x3E, 0xFF, 0xFF, 0x07, 0x3F, 0xFF, 0xFF, 0x07, 0x1F, 0xBF, 0xDF, 0xE0, 0x1B, 0x3F, 0xFF, 0xFF,
0xF7, 0x77, 0x7E, 0xFD, 0xF9, 0xE0, 0x1F, 0xF0, 0x10, 0xF8, 0xFE, 0xFF, 0xDF, 0xDF, 0xFE, 0xFF,
0xDF, 0xDF, 0xFF, 0xFE, 0xFC, 0x18, 0x67, 0x39, 0xCE, 0x73, 0x9C, 0xF7, 0xC8, 0x63, 0x39, 0xCE,
0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C, 0xF7, 0xBF, 0xF2, 0x10, 0xFF, 0xFD, 0xC3, 0xC7, 0x8F,
0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0xC7, 0x82, 0x00, 0x03, 0xEF, 0xC7, 0x3D, 0xE7, 0x1C, 0x71,
0xC7, 0x1C, 0x71, 0xE7, 0xC4, 0xFF, 0xF3, 0x9E, 0x79, 0xE7, 0x9E, 0x79, 0xE7, 0x9E, 0x7C, 0xF0,
0x80, 0x71, 0xFB, 0xF0, 0xE1, 0xC3, 0x87, 0x0E, 0x1E, 0x3C, 0x70, 0xE1, 0xC3, 0x80, 0x76, 0x7F,
0xBF, 0xFF, 0x7E, 0x3F, 0x9D, 0xCE, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x7D, 0xFF,
0x57, 0xF7, 0xC0, 0xDF, 0xFE, 0x01, 0xE1, 0xC3, 0xEF, 0xC0, 0x00, 0xFC, 0xFE, 0xFF, 0x7F, 0x33,
0xBF, 0xF7, 0x00, 0x07, 0xFF, 0xC0, 0x31, 0xE7, 0x9E, 0x3B, 0xFD, 0x80, 0x7E, 0x7F, 0xBF, 0xFF,
0xFF, 0xDE, 0xFF, 0xFE, 0xFE, 0x1C, 0x00, 0x3E, 0x3F, 0x9D, 0xFE, 0x7F, 0x3B, 0x9D, 0xFE, 0x7E,
0x0C, 0x00, 0x3E, 0x3F, 0xBD, 0xDE, 0xE7, 0xF3, 0xF8, 0xFC, 0x7C, 0x18, 0x00, 0x70, 0x1C, 0x07,
0xFD, 0xFF, 0x7F, 0xDF, 0xF7, 0xFD, 0xC7, 0x7F, 0xCF, 0xE0, 0xE0, 0x7F, 0x3F, 0xDF, 0xFE, 0x7F,
0x3B, 0x9D, 0xEE, 0xF7, 0x10, 0x00, 0x07, 0x03, 0x8F, 0xCF, 0xE7, 0x87, 0xBB, 0xFC, 0xFC, 0x7F,
0x1F, 0xC0, 0x3F, 0x9F, 0xCF, 0xEF, 0xE7, 0x87, 0xBB, 0xFC, 0xFC, 0x7F, 0x9F, 0xC0, 0xE0, 0xE0,
0xFE, 0x7F, 0x7F, 0x07, 0x07, 0x27, 0x7F, 0x7E, 0x18, 0x00, 0x70, 0x07, 0x7F, 0x77, 0xF7, 0x7F,
0x7F, 0x37, 0xF3, 0x77, 0x37, 0x7B, 0xE7, 0xBE, 0x10, 0x00, 0x03, 0x83, 0xCF, 0xCF, 0xE7, 0x07,
0x0B, 0x8F, 0xFF, 0x7F, 0xBF, 0xC0, 0x80, 0x03, 0x81, 0xCF, 0xEF, 0xF7, 0xE7, 0xF3, 0xD8, 0xEE,
0x7F, 0x3D, 0xC4, 0x00, 0x32, 0x37, 0xF9, 0xFD, 0xCF, 0xCE, 0x7F, 0xFF, 0xFF, 0xFC, 0xFF, 0xE0,
0xE7, 0x07, 0x38, 0x39, 0xC0, 0x10, 0x00, 0xF8, 0x01, 0xFF, 0xE7, 0x7F, 0xC7, 0x7F, 0xEF, 0xDF,
0xCF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x9F, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0xFF,
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x76, 0xEE, 0xC0, 0x7E, 0xEE, 0xC0,
0x77, 0xEE, 0x40, 0x76, 0x6E, 0xEE, 0xEE, 0xCC, 0x7E, 0xEE, 0xEE, 0xEC, 0xCC, 0x77, 0x77, 0xEE,
0xEE, 0x4C, 0x79, 0xFF, 0xFF, 0x78, 0xE0, 0x73, 0x19, 0xDE, 0xF7, 0x7B, 0xC8, 0x44, 0x10, 0x73,
0x9C, 0xF1, 0xE3, 0x87, 0x00, 0x21, 0xC7, 0x0E, 0x3C, 0xE7, 0x1C, 0x00, 0x0F, 0xCF, 0xE3, 0xD9,
0xE0, 0xFF, 0x3F, 0xCF, 0xE3, 0xF8, 0x78, 0x0F, 0x23, 0xF8, 0x7E, 0x02, 0x00, 0xFF, 0xFE,
};
static const EpdGlyph notosansthai_8_boldGlyphs[] = {
{ 0, 0, 0, 0, 0, 0, 0 }, //
{ 0, 0, 4, 0, 0, 0, 0 }, //
{ 0, 0, 4, 0, 0, 0, 0 }, //
{ 4, 13, 5, 0, 12, 7, 0 }, // !
{ 6, 5, 8, 1, 12, 4, 7 }, // "
{ 11, 12, 11, 0, 12, 17, 11 }, // #
{ 9, 14, 10, 0, 13, 16, 28 }, // $
{ 15, 14, 15, 0, 13, 27, 44 }, // %
{ 13, 14, 13, 0, 13, 23, 71 }, // &
{ 3, 5, 4, 1, 12, 2, 94 }, // '
{ 6, 15, 6, 0, 12, 12, 96 }, // (
{ 5, 15, 6, 0, 12, 10, 108 }, // )
{ 9, 9, 9, 0, 13, 11, 118 }, // *
{ 9, 9, 10, 0, 10, 11, 129 }, // +
{ 4, 5, 5, 0, 2, 3, 140 }, // ,
{ 5, 3, 5, 0, 6, 2, 143 }, // -
{ 4, 4, 5, 0, 3, 2, 145 }, // .
{ 7, 12, 7, 0, 12, 11, 147 }, // /
{ 9, 14, 10, 0, 13, 16, 158 }, // 0
{ 7, 12, 10, 0, 12, 11, 174 }, // 1
{ 9, 13, 10, 0, 13, 15, 185 }, // 2
{ 9, 14, 10, 0, 13, 16, 200 }, // 3
{ 10, 12, 10, 0, 12, 15, 216 }, // 4
{ 9, 13, 10, 0, 12, 15, 231 }, // 5
{ 9, 14, 10, 0, 13, 16, 246 }, // 6
{ 9, 12, 10, 0, 12, 14, 262 }, // 7
{ 9, 14, 10, 0, 13, 16, 276 }, // 8
{ 9, 14, 10, 0, 13, 16, 292 }, // 9
{ 4, 11, 5, 0, 10, 6, 308 }, // :
{ 4, 13, 5, 0, 10, 7, 314 }, // ;
{ 9, 10, 10, 0, 11, 12, 321 }, // <
{ 9, 6, 10, 0, 9, 7, 333 }, // =
{ 9, 10, 10, 0, 11, 12, 340 }, // >
{ 8, 14, 8, 0, 13, 14, 352 }, // ?
{ 15, 14, 15, 0, 12, 27, 366 }, // @
{ 12, 12, 12, 0, 12, 18, 393 }, // A
{ 10, 12, 11, 1, 12, 15, 411 }, // B
{ 11, 14, 11, 0, 13, 20, 426 }, // C
{ 11, 12, 12, 1, 12, 17, 446 }, // D
{ 8, 12, 9, 1, 12, 12, 463 }, // E
{ 8, 12, 9, 1, 12, 12, 475 }, // F
{ 11, 14, 12, 0, 13, 20, 487 }, // G
{ 11, 12, 13, 1, 12, 17, 507 }, // H
{ 6, 12, 6, 0, 12, 9, 524 }, // I
{ 7, 16, 6, -2, 12, 14, 533 }, // J
{ 11, 12, 11, 1, 12, 17, 547 }, // K
{ 8, 12, 9, 1, 12, 12, 564 }, // L
{ 14, 12, 16, 1, 12, 21, 576 }, // M
{ 12, 12, 14, 1, 12, 18, 597 }, // N
{ 13, 14, 13, 0, 13, 23, 615 }, // O
{ 9, 12, 10, 1, 12, 14, 638 }, // P
{ 13, 16, 13, 0, 13, 26, 652 }, // Q
{ 10, 12, 11, 1, 12, 15, 678 }, // R
{ 9, 14, 9, 0, 13, 16, 693 }, // S
{ 10, 12, 10, 0, 12, 15, 709 }, // T
{ 11, 13, 13, 1, 12, 18, 724 }, // U
{ 11, 12, 11, 0, 12, 17, 742 }, // V
{ 17, 12, 16, 0, 12, 26, 759 }, // W
{ 12, 12, 11, 0, 12, 18, 785 }, // X
{ 11, 12, 10, 0, 12, 17, 803 }, // Y
{ 10, 12, 10, 0, 12, 15, 820 }, // Z
{ 5, 15, 6, 1, 12, 10, 835 }, // [
{ 7, 12, 7, 0, 12, 11, 845 }, // <backslash>
{ 5, 15, 6, 0, 12, 10, 856 }, // ]
{ 10, 8, 10, 0, 12, 10, 866 }, // ^
{ 8, 2, 7, -1, -1, 2, 876 }, // _
{ 6, 3, 6, 0, 13, 3, 878 }, // `
{ 9, 11, 10, 0, 10, 13, 881 }, // a
{ 9, 14, 11, 1, 13, 16, 894 }, // b
{ 9, 11, 9, 0, 10, 13, 910 }, // c
{ 10, 14, 11, 0, 13, 18, 923 }, // d
{ 10, 11, 10, 0, 10, 14, 941 }, // e
{ 8, 13, 6, 0, 13, 13, 955 }, // f
{ 10, 14, 11, 0, 10, 18, 968 }, // g
{ 9, 13, 11, 1, 13, 15, 986 }, // h
{ 3, 13, 5, 1, 13, 5, 1001 }, // i
{ 6, 17, 5, -2, 13, 13, 1006 }, // j
{ 10, 13, 10, 1, 13, 17, 1019 }, // k
{ 3, 13, 5, 1, 13, 5, 1036 }, // l
{ 15, 10, 16, 1, 10, 19, 1041 }, // m
{ 9, 10, 11, 1, 10, 12, 1060 }, // n
{ 10, 11, 10, 0, 10, 14, 1072 }, // o
{ 9, 14, 11, 1, 10, 16, 1086 }, // p
{ 10, 14, 11, 0, 10, 18, 1102 }, // q
{ 7, 10, 8, 1, 10, 9, 1120 }, // r
{ 8, 11, 8, 0, 10, 11, 1129 }, // s
{ 7, 13, 7, 0, 12, 12, 1140 }, // t
{ 9, 11, 11, 1, 10, 13, 1152 }, // u
{ 10, 10, 9, 0, 10, 13, 1165 }, // v
{ 15, 10, 14, 0, 10, 19, 1178 }, // w
{ 10, 10, 10, 0, 10, 13, 1197 }, // x
{ 10, 14, 9, 0, 10, 18, 1210 }, // y
{ 8, 10, 8, 0, 10, 10, 1228 }, // z
{ 6, 15, 7, 0, 12, 12, 1238 }, // {
{ 3, 17, 9, 3, 13, 7, 1250 }, // |
{ 7, 15, 7, 0, 12, 14, 1257 }, // }
{ 9, 4, 10, 0, 8, 5, 1271 }, // ~
{ 0, 0, 4, 0, 0, 0, 1276 }, //  
{ 4, 13, 5, 0, 10, 7, 1276 }, // ¡
{ 8, 14, 10, 1, 13, 14, 1283 }, // ¢
{ 10, 13, 10, 0, 13, 17, 1297 }, // £
{ 10, 12, 10, 0, 12, 15, 1314 }, // ¥
{ 8, 14, 8, 0, 13, 14, 1329 }, // §
{ 6, 3, 10, 2, 13, 3, 1343 }, // ¨
{ 14, 14, 14, 0, 13, 25, 1346 }, // ©
{ 6, 7, 6, 0, 13, 6, 1371 }, // ª
{ 10, 9, 10, 0, 9, 12, 1377 }, // «
{ 14, 14, 14, 0, 13, 25, 1389 }, // ®
{ 10, 3, 8, -1, 15, 4, 1414 }, // ¯
{ 7, 7, 7, 0, 13, 7, 1418 }, // °
{ 6, 3, 6, 0, 13, 3, 1425 }, // ´
{ 10, 16, 11, 0, 13, 20, 1428 }, // ¶
{ 4, 4, 5, 0, 8, 2, 1448 }, // ·
{ 5, 4, 3, -1, 0, 3, 1450 }, // ¸
{ 6, 7, 6, 0, 13, 6, 1453 }, // º
{ 10, 9, 10, 0, 9, 12, 1459 }, // »
{ 8, 14, 8, 0, 10, 14, 1471 }, // ¿
{ 12, 16, 12, 0, 16, 24, 1485 }, // À
{ 12, 16, 12, 0, 16, 24, 1509 }, // Á
{ 12, 16, 12, 0, 16, 24, 1533 }, // Â
{ 12, 16, 12, 0, 16, 24, 1557 }, // Ã
{ 12, 16, 12, 0, 16, 24, 1581 }, // Ä
{ 12, 15, 12, 0, 15, 23, 1605 }, // Å
{ 15, 12, 16, 0, 12, 23, 1628 }, // Æ
{ 11, 17, 11, 0, 13, 24, 1651 }, // Ç
{ 8, 16, 9, 1, 16, 16, 1675 }, // È
{ 8, 16, 9, 1, 16, 16, 1691 }, // É
{ 8, 16, 9, 1, 16, 16, 1707 }, // Ê
{ 8, 16, 9, 1, 16, 16, 1723 }, // Ë
{ 6, 16, 6, 0, 16, 12, 1739 }, // Ì
{ 7, 16, 6, 0, 16, 14, 1751 }, // Í
{ 8, 16, 6, -1, 16, 16, 1765 }, // Î
{ 7, 16, 6, 0, 16, 14, 1781 }, // Ï
{ 12, 12, 12, 0, 12, 18, 1795 }, // Ð
{ 12, 16, 14, 1, 16, 24, 1813 }, // Ñ
{ 13, 17, 13, 0, 16, 28, 1837 }, // Ò
{ 13, 17, 13, 0, 16, 28, 1865 }, // Ó
{ 13, 17, 13, 0, 16, 28, 1893 }, // Ô
{ 13, 17, 13, 0, 16, 28, 1921 }, // Õ
{ 13, 17, 13, 0, 16, 28, 1949 }, // Ö
{ 8, 8, 10, 1, 10, 8, 1977 }, // ×
{ 13, 14, 13, 0, 13, 23, 1985 }, // Ø
{ 11, 17, 13, 1, 16, 24, 2008 }, // Ù
{ 11, 17, 13, 1, 16, 24, 2032 }, // Ú
{ 11, 17, 13, 1, 16, 24, 2056 }, // Û
{ 11, 17, 13, 1, 16, 24, 2080 }, // Ü
{ 11, 16, 10, 0, 16, 22, 2104 }, // Ý
{ 9, 12, 10, 1, 12, 14, 2126 }, // Þ
{ 11, 14, 12, 1, 13, 20, 2140 }, // ß
{ 9, 14, 10, 0, 13, 16, 2160 }, // à
{ 9, 14, 10, 0, 13, 16, 2176 }, // á
{ 9, 14, 10, 0, 13, 16, 2192 }, // â
{ 9, 14, 10, 0, 13, 16, 2208 }, // ã
{ 9, 14, 10, 0, 13, 16, 2224 }, // ä
{ 9, 15, 10, 0, 14, 17, 2240 }, // å
{ 15, 11, 15, 0, 10, 21, 2257 }, // æ
{ 9, 14, 9, 0, 10, 16, 2278 }, // ç
{ 10, 14, 10, 0, 13, 18, 2294 }, // è
{ 10, 14, 10, 0, 13, 18, 2312 }, // é
{ 10, 14, 10, 0, 13, 18, 2330 }, // ê
{ 10, 14, 10, 0, 13, 18, 2348 }, // ë
{ 6, 13, 5, -1, 13, 10, 2366 }, // ì
{ 6, 13, 5, 1, 13, 10, 2376 }, // í
{ 8, 13, 5, -1, 13, 13, 2386 }, // î
{ 7, 13, 5, -1, 13, 12, 2399 }, // ï
{ 10, 14, 10, 0, 13, 18, 2411 }, // ð
{ 9, 13, 11, 1, 13, 15, 2429 }, // ñ
{ 10, 14, 10, 0, 13, 18, 2444 }, // ò
{ 10, 14, 10, 0, 13, 18, 2462 }, // ó
{ 10, 14, 10, 0, 13, 18, 2480 }, // ô
{ 10, 14, 10, 0, 13, 18, 2498 }, // õ
{ 10, 14, 10, 0, 13, 18, 2516 }, // ö
{ 9, 9, 10, 0, 10, 11, 2534 }, // ÷
{ 10, 11, 10, 0, 10, 14, 2545 }, // ø
{ 9, 14, 11, 1, 13, 16, 2559 }, // ù
{ 9, 14, 11, 1, 13, 16, 2575 }, // ú
{ 9, 14, 11, 1, 13, 16, 2591 }, // û
{ 9, 14, 11, 1, 13, 16, 2607 }, // ü
{ 10, 17, 9, 0, 13, 22, 2623 }, // ý
{ 9, 17, 11, 1, 13, 20, 2645 }, // þ
{ 10, 17, 9, 0, 13, 22, 2665 }, // ÿ
{ 12, 15, 12, 0, 15, 23, 2687 }, // Ā
{ 9, 13, 10, 0, 12, 15, 2710 }, // ā
{ 12, 16, 12, 0, 16, 24, 2725 }, // Ă
{ 9, 14, 10, 0, 13, 16, 2749 }, // ă
{ 12, 16, 12, 0, 12, 24, 2765 }, // Ą
{ 9, 14, 10, 0, 10, 16, 2789 }, // ą
{ 11, 17, 11, 0, 16, 24, 2805 }, // Ć
{ 9, 14, 9, 0, 13, 16, 2829 }, // ć
{ 11, 17, 11, 0, 16, 24, 2845 }, // Ċ
{ 9, 14, 9, 0, 13, 16, 2869 }, // ċ
{ 11, 17, 11, 0, 16, 24, 2885 }, // Č
{ 9, 14, 9, 0, 13, 16, 2909 }, // č
{ 11, 16, 12, 1, 16, 22, 2925 }, // Ď
{ 13, 14, 11, 0, 13, 23, 2947 }, // ď
{ 12, 12, 12, 0, 12, 18, 2970 }, // Đ
{ 11, 14, 11, 0, 13, 20, 2988 }, // đ
{ 8, 15, 9, 1, 15, 15, 3008 }, // Ē
{ 10, 13, 10, 0, 12, 17, 3023 }, // ē
{ 8, 16, 9, 1, 16, 16, 3040 }, // Ė
{ 10, 14, 10, 0, 13, 18, 3056 }, // ė
{ 8, 16, 9, 1, 12, 16, 3074 }, // Ę
{ 10, 14, 10, 0, 10, 18, 3090 }, // ę
{ 8, 16, 9, 1, 16, 16, 3108 }, // Ě
{ 10, 14, 10, 0, 13, 18, 3124 }, // ě
{ 11, 17, 12, 0, 16, 24, 3142 }, // Ğ
{ 10, 17, 11, 0, 13, 22, 3166 }, // ğ
{ 11, 17, 12, 0, 16, 24, 3188 }, // Ġ
{ 10, 17, 11, 0, 13, 22, 3212 }, // ġ
{ 11, 17, 12, 0, 13, 24, 3234 }, // Ģ
{ 10, 17, 11, 0, 13, 22, 3258 }, // ģ
{ 13, 12, 13, 0, 12, 20, 3280 }, // Ħ
{ 10, 13, 11, 0, 13, 17, 3300 }, // ħ
{ 6, 15, 6, 0, 15, 12, 3317 }, // Ī
{ 7, 12, 5, -1, 12, 11, 3329 }, // ī
{ 6, 16, 6, 0, 12, 12, 3340 }, // Į
{ 5, 17, 5, 0, 13, 11, 3352 }, // į
{ 6, 16, 6, 0, 16, 12, 3363 }, // İ
{ 3, 10, 5, 1, 10, 4, 3375 }, // ı
{ 11, 16, 11, 1, 12, 22, 3379 }, // Ķ
{ 10, 17, 10, 1, 13, 22, 3401 }, // ķ
{ 8, 16, 9, 1, 16, 16, 3423 }, // Ĺ
{ 6, 17, 5, 1, 17, 13, 3439 }, // ĺ
{ 8, 16, 9, 1, 12, 16, 3452 }, // Ļ
{ 3, 17, 5, 1, 13, 7, 3468 }, // ļ
{ 9, 12, 9, 1, 12, 14, 3475 }, // Ľ
{ 7, 13, 5, 1, 13, 12, 3489 }, // ľ
{ 9, 12, 9, 0, 12, 14, 3501 }, // Ł
{ 7, 13, 5, -1, 13, 12, 3515 }, // ł
{ 12, 16, 14, 1, 16, 24, 3527 }, // Ń
{ 9, 13, 11, 1, 13, 15, 3551 }, // ń
{ 12, 16, 14, 1, 12, 24, 3566 }, // Ņ
{ 9, 14, 11, 1, 10, 16, 3590 }, // ņ
{ 12, 16, 14, 1, 16, 24, 3606 }, // Ň
{ 9, 13, 11, 1, 13, 15, 3630 }, // ň
{ 12, 16, 14, 1, 12, 24, 3645 }, // Ŋ
{ 9, 14, 11, 1, 10, 16, 3669 }, // ŋ
{ 13, 16, 13, 0, 15, 26, 3685 }, // Ō
{ 10, 13, 10, 0, 12, 17, 3711 }, // ō
{ 13, 17, 13, 0, 16, 28, 3728 }, // Ő
{ 10, 14, 10, 0, 13, 18, 3756 }, // ő
{ 16, 14, 16, 0, 13, 28, 3774 }, // Œ
{ 16, 11, 16, 0, 10, 22, 3802 }, // œ
{ 10, 16, 11, 1, 16, 20, 3824 }, // Ŕ
{ 7, 13, 8, 1, 13, 12, 3844 }, // ŕ
{ 10, 16, 11, 1, 12, 20, 3856 }, // Ŗ
{ 7, 14, 8, 1, 10, 13, 3876 }, // ŗ
{ 10, 16, 11, 1, 16, 20, 3889 }, // Ř
{ 8, 13, 8, 0, 13, 13, 3909 }, // ř
{ 9, 17, 9, 0, 16, 20, 3922 }, // Ś
{ 8, 14, 8, 0, 13, 14, 3942 }, // ś
{ 9, 17, 9, 0, 13, 20, 3956 }, // Ş
{ 8, 14, 8, 0, 10, 14, 3976 }, // ş
{ 9, 17, 9, 0, 16, 20, 3990 }, // Š
{ 8, 14, 8, 0, 13, 14, 4010 }, // š
{ 10, 16, 10, 0, 16, 20, 4024 }, // Ť
{ 10, 14, 7, 0, 13, 18, 4044 }, // ť
{ 11, 16, 13, 1, 15, 22, 4062 }, // Ū
{ 9, 13, 11, 1, 12, 15, 4084 }, // ū
{ 11, 17, 13, 1, 16, 24, 4099 }, // Ŭ
{ 9, 14, 11, 1, 13, 16, 4123 }, // ŭ
{ 11, 18, 13, 1, 17, 25, 4139 }, // Ů
{ 9, 15, 11, 1, 14, 17, 4164 }, // ů
{ 11, 17, 13, 1, 16, 24, 4181 }, // Ű
{ 9, 14, 11, 1, 13, 16, 4205 }, // ű
{ 11, 16, 13, 1, 12, 22, 4221 }, // Ų
{ 9, 14, 11, 1, 10, 16, 4243 }, // ų
{ 17, 16, 16, 0, 16, 34, 4259 }, // Ŵ
{ 15, 13, 14, 0, 13, 25, 4293 }, // ŵ
{ 11, 16, 10, 0, 16, 22, 4318 }, // Ŷ
{ 10, 17, 9, 0, 13, 22, 4340 }, // ŷ
{ 11, 16, 10, 0, 16, 22, 4362 }, // Ÿ
{ 10, 16, 10, 0, 16, 20, 4384 }, // Ź
{ 8, 13, 8, 0, 13, 13, 4404 }, // ź
{ 10, 16, 10, 0, 16, 20, 4417 }, // Ż
{ 8, 13, 8, 0, 13, 13, 4437 }, // ż
{ 10, 16, 10, 0, 16, 20, 4450 }, // Ž
{ 8, 13, 8, 0, 13, 13, 4470 }, // ž
{ 5, 3, 0, -9, 13, 2, 4483 }, // ̀
{ 6, 3, 0, -6, 13, 3, 4485 }, // ́
{ 8, 3, 0, -4, 13, 3, 4488 }, // ̂
{ 7, 3, 0, -9, 13, 3, 4491 }, // ̃
{ 6, 2, 0, -3, 12, 2, 4494 }, // ̄
{ 8, 3, 0, -4, 13, 3, 4496 }, // ̆
{ 4, 3, 0, -2, 13, 2, 4499 }, // ̇
{ 6, 3, 0, -3, 13, 3, 4501 }, // ̈
{ 5, 4, 0, -2, 14, 3, 4504 }, // ̊
{ 8, 3, 0, -3, 13, 3, 4507 }, // ̋
{ 8, 3, 0, -4, 13, 3, 4510 }, // ̌
{ 4, 5, 0, -2, 12, 3, 4513 }, // ̒
{ 4, 3, 0, -2, -1, 2, 4516 }, // ̦
{ 4, 4, 0, -2, 0, 2, 4518 }, // ̧
{ 4, 5, 0, -2, 1, 3, 4520 }, // ̨
{ 6, 2, 0, -8, -1, 2, 4523 }, // ̱
{ 10, 10, 10, 0, 10, 13, 4525 }, // ก
{ 9, 11, 10, 0, 10, 13, 4538 }, // ข
{ 9, 11, 10, 0, 10, 13, 4551 }, // ฃ
{ 9, 10, 11, 1, 10, 12, 4564 }, // ค
{ 9, 10, 11, 1, 10, 12, 4576 }, // ฅ
{ 10, 11, 11, 0, 10, 14, 4588 }, // ฆ
{ 9, 10, 10, 0, 10, 12, 4602 }, // ง
{ 9, 10, 9, 0, 10, 12, 4614 }, // จ
{ 9, 11, 10, 1, 10, 13, 4626 }, // ฉ
{ 10, 11, 10, 0, 10, 14, 4639 }, // ช
{ 10, 11, 10, 0, 10, 14, 4653 }, // ซ
{ 15, 11, 15, 0, 10, 21, 4667 }, // ฌ
{ 15, 14, 16, 0, 10, 27, 4688 }, // ญ
{ 10, 14, 11, 0, 10, 18, 4715 }, // ฎ
{ 10, 14, 11, 0, 10, 18, 4733 }, // ฏ
{ 10, 14, 10, 0, 10, 18, 4751 }, // ฐ
{ 10, 10, 11, 0, 10, 13, 4769 }, // ฑ
{ 15, 11, 16, 0, 10, 21, 4782 }, // ฒ
{ 15, 11, 16, 0, 10, 21, 4803 }, // ณ
{ 10, 11, 11, 0, 10, 14, 4824 }, // ด
{ 10, 11, 11, 0, 10, 14, 4838 }, // ต
{ 10, 11, 10, 0, 10, 14, 4852 }, // ถ
{ 9, 10, 11, 1, 10, 12, 4866 }, // ท
{ 9, 11, 9, 0, 10, 13, 4878 }, // ธ
{ 9, 11, 11, 1, 10, 13, 4891 }, // น
{ 9, 11, 11, 1, 10, 13, 4904 }, // บ
{ 9, 14, 11, 1, 13, 16, 4917 }, // ป
{ 10, 10, 11, 1, 10, 13, 4933 }, // ผ
{ 10, 13, 11, 1, 13, 17, 4946 }, // ฝ
{ 12, 10, 12, 0, 10, 15, 4963 }, // พ
{ 12, 13, 12, 0, 13, 20, 4978 }, // ฟ
{ 10, 11, 11, 0, 10, 14, 4998 }, // ภ
{ 9, 11, 11, 1, 10, 13, 5012 }, // ม
{ 10, 11, 10, 0, 10, 14, 5025 }, // ย
{ 9, 11, 9, 0, 10, 13, 5039 }, // ร
{ 10, 14, 10, 0, 10, 18, 5052 }, // ฤ
{ 9, 11, 10, 0, 10, 13, 5070 }, // ล
{ 10, 14, 11, 0, 10, 18, 5083 }, // ฦ
{ 8, 11, 9, 0, 10, 11, 5101 }, // ว
{ 10, 10, 11, 1, 10, 13, 5112 }, // ศ
{ 10, 11, 11, 1, 10, 14, 5125 }, // ษ
{ 10, 11, 10, 0, 10, 14, 5139 }, // ส
{ 9, 10, 10, 1, 10, 12, 5153 }, // ห
{ 12, 12, 12, 0, 12, 18, 5165 }, // ฬ
{ 10, 11, 10, 0, 10, 14, 5183 }, // อ
{ 10, 11, 10, 0, 10, 14, 5197 }, // ฮ
{ 8, 10, 9, 0, 10, 10, 5211 }, // ฯ
{ 6, 9, 6, 0, 9, 7, 5221 }, // ะ
{ 7, 4, 0, -6, 14, 4, 5228 }, // ั
{ 7, 10, 7, 0, 10, 9, 5232 }, // า
{ 13, 14, 7, -6, 14, 23, 5241 }, // ำ
{ 8, 3, 0, -9, 13, 3, 5264 }, // ิ
{ 8, 4, 0, -9, 14, 4, 5267 }, // ี
{ 9, 4, 0, -9, 14, 5, 5271 }, // ึ
{ 8, 4, 0, -9, 14, 4, 5276 }, // ื
{ 4, 4, 0, -5, -1, 2, 5280 }, // ุ
{ 7, 4, 0, -8, -1, 4, 5282 }, // ู
{ 3, 4, 0, -4, 0, 2, 5286 }, // ฺ
{ 8, 14, 10, 1, 13, 14, 5288 }, // ฿
{ 5, 11, 6, 1, 10, 7, 5302 }, // เ
{ 10, 11, 11, 1, 10, 14, 5309 }, // แ
{ 7, 15, 6, 0, 14, 14, 5323 }, // โ
{ 6, 16, 6, 0, 15, 12, 5337 }, // ใ
{ 6, 15, 6, 0, 14, 12, 5349 }, // ไ
{ 7, 14, 7, 0, 10, 13, 5361 }, // ๅ
{ 9, 14, 11, 1, 10, 16, 5374 }, // ๆ
{ 7, 5, 0, -8, 15, 5, 5390 }, // ็
{ 3, 5, 0, -4, 15, 2, 5395 }, // ่
{ 7, 5, 0, -7, 15, 5, 5397 }, // ้
{ 8, 5, 0, -8, 15, 5, 5402 }, // ๊
{ 5, 5, 0, -6, 15, 4, 5407 }, // ๋
{ 5, 4, 0, -5, 14, 3, 5411 }, // ์
{ 6, 4, 0, -6, 14, 3, 5414 }, // ํ
{ 5, 4, 0, -5, 14, 3, 5417 }, // ๎
{ 9, 9, 11, 1, 8, 11, 5420 }, // ๏
{ 9, 9, 9, 0, 8, 11, 5431 }, //
{ 9, 9, 9, 0, 8, 11, 5442 }, // ๑
{ 10, 11, 11, 0, 10, 14, 5453 }, // ๒
{ 9, 9, 9, 0, 8, 11, 5467 }, // ๓
{ 9, 10, 9, 0, 10, 12, 5478 }, // ๔
{ 9, 10, 9, 0, 10, 12, 5490 }, // ๕
{ 8, 11, 9, 0, 10, 11, 5502 }, // ๖
{ 12, 11, 13, 0, 10, 17, 5513 }, // ๗
{ 9, 11, 9, 0, 10, 13, 5530 }, // ๘
{ 9, 11, 9, 0, 10, 13, 5543 }, // ๙
{ 13, 10, 14, 0, 10, 17, 5556 }, // ๚
{ 15, 7, 15, 0, 8, 14, 5573 }, // ๛
{ 0, 0, 0, 0, 0, 0, 5587 }, //
{ 2, 14, 0, -1, 11, 4, 5587 }, //
{ 4, 15, 0, -2, 12, 8, 5591 }, //
{ 5, 3, 5, 0, 6, 2, 5599 }, //
{ 8, 3, 8, 0, 6, 3, 5601 }, //
{ 16, 3, 17, 0, 6, 6, 5604 }, // —
{ 4, 5, 4, 0, 12, 3, 5610 }, //
{ 4, 5, 4, 0, 12, 3, 5613 }, //
{ 4, 5, 5, 0, 2, 3, 5616 }, //
{ 8, 5, 7, 0, 12, 5, 5619 }, // “
{ 8, 5, 7, 0, 12, 5, 5624 }, // ”
{ 8, 5, 9, 0, 2, 5, 5629 }, // „
{ 6, 6, 6, 0, 9, 5, 5634 }, // •
{ 14, 4, 14, 0, 3, 7, 5639 }, // …
{ 6, 9, 6, 0, 9, 7, 5646 }, //
{ 6, 9, 6, 0, 9, 7, 5653 }, //
{ 10, 13, 10, 0, 12, 17, 5660 }, // €
{ 5, 3, 5, 0, 6, 2, 5677 }, //
};
static const EpdUnicodeInterval notosansthai_8_boldIntervals[] = {
{ 0x0, 0x0, 0x0 },
{ 0xD, 0xD, 0x1 },
{ 0x20, 0x7E, 0x2 },
{ 0xA0, 0xA3, 0x61 },
{ 0xA5, 0xA5, 0x65 },
{ 0xA7, 0xAB, 0x66 },
{ 0xAE, 0xB0, 0x6B },
{ 0xB4, 0xB4, 0x6E },
{ 0xB6, 0xB8, 0x6F },
{ 0xBA, 0xBB, 0x72 },
{ 0xBF, 0xFF, 0x74 },
{ 0x100, 0x107, 0xB5 },
{ 0x10A, 0x113, 0xBD },
{ 0x116, 0x11B, 0xC7 },
{ 0x11E, 0x123, 0xCD },
{ 0x126, 0x127, 0xD3 },
{ 0x12A, 0x12B, 0xD5 },
{ 0x12E, 0x131, 0xD7 },
{ 0x136, 0x137, 0xDB },
{ 0x139, 0x13E, 0xDD },
{ 0x141, 0x148, 0xE3 },
{ 0x14A, 0x14D, 0xEB },
{ 0x150, 0x15B, 0xEF },
{ 0x15E, 0x161, 0xFB },
{ 0x164, 0x165, 0xFF },
{ 0x16A, 0x17E, 0x101 },
{ 0x300, 0x304, 0x116 },
{ 0x306, 0x308, 0x11B },
{ 0x30A, 0x30C, 0x11E },
{ 0x312, 0x312, 0x121 },
{ 0x326, 0x328, 0x122 },
{ 0x331, 0x331, 0x125 },
{ 0xE01, 0xE3A, 0x126 },
{ 0xE3F, 0xE5B, 0x160 },
{ 0x200B, 0x200D, 0x17D },
{ 0x2010, 0x2010, 0x180 },
{ 0x2013, 0x2014, 0x181 },
{ 0x2018, 0x201A, 0x183 },
{ 0x201C, 0x201E, 0x186 },
{ 0x2022, 0x2022, 0x189 },
{ 0x2026, 0x2026, 0x18A },
{ 0x2039, 0x203A, 0x18B },
{ 0x20AC, 0x20AC, 0x18D },
{ 0x2212, 0x2212, 0x18E },
};
static const EpdFontData notosansthai_8_bold = {
notosansthai_8_boldBitmaps,
notosansthai_8_boldGlyphs,
notosansthai_8_boldIntervals,
44,
25,
18,
-8,
false,
};

View File

@ -0,0 +1,795 @@
/**
* generated by fontconvert.py
* name: notosansthai_8_regular
* size: 8
* mode: 1-bit
*/
#pragma once
#include "EpdFontData.h"
static const uint8_t notosansthai_8_regularBitmaps[5183] = {
0xDB, 0x6D, 0xB6, 0xC3, 0xF4, 0xDE, 0xF7, 0xBD, 0x80, 0x0D, 0x83, 0x30, 0x66, 0x3F, 0xF7, 0xFE,
0x36, 0x04, 0xC7, 0xFE, 0xFF, 0xC6, 0x40, 0xD8, 0x1B, 0x00, 0x18, 0x18, 0xFE, 0xFE, 0xD8, 0xF8,
0xFC, 0x3E, 0x1F, 0x1B, 0xFF, 0xFE, 0x38, 0x18, 0x00, 0x01, 0xE1, 0x86, 0xCC, 0x13, 0x30, 0xCD,
0x83, 0x36, 0x86, 0xFF, 0x9F, 0xF6, 0x36, 0xD8, 0x1B, 0x60, 0xCD, 0x87, 0x36, 0x18, 0x78, 0x00,
0x80, 0x00, 0x01, 0xF8, 0x0F, 0xC0, 0x66, 0x03, 0x30, 0x1F, 0x80, 0x70, 0x0F, 0xCE, 0x67, 0x63,
0x1F, 0x18, 0x70, 0xFF, 0xC3, 0xF7, 0x04, 0x00, 0xFF, 0xC0, 0x39, 0x9C, 0xC6, 0x73, 0x9C, 0xE7,
0x18, 0xC7, 0x18, 0x60, 0xE3, 0x1C, 0x63, 0x1C, 0xE7, 0x39, 0xCC, 0x67, 0x33, 0x00, 0x1C, 0x0E,
0x13, 0x5F, 0xF7, 0xF1, 0xF0, 0xD8, 0x6C, 0x0C, 0x06, 0x03, 0x0F, 0xFF, 0xF8, 0x60, 0x30, 0x18,
0x08, 0x00, 0x66, 0x6C, 0x40, 0x77, 0xDE, 0x1F, 0xA0, 0x0C, 0x18, 0x70, 0xC1, 0x86, 0x0C, 0x38,
0x60, 0xC3, 0x86, 0x00, 0x00, 0x1F, 0x1F, 0xCC, 0x76, 0x1B, 0x0F, 0x87, 0xC3, 0x61, 0xB0, 0xD8,
0xEE, 0xE3, 0xE0, 0x40, 0x1B, 0xFE, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x30, 0x00, 0x3F, 0x1F, 0xC0,
0x70, 0x38, 0x18, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0xFF, 0xF8, 0x00, 0x3F, 0x9F, 0xC0, 0x70,
0x38, 0x38, 0xF8, 0x7E, 0x03, 0x80, 0xC0, 0xFC, 0xEF, 0xF0, 0xC0, 0x07, 0x03, 0xC0, 0xF0, 0x6C,
0x3B, 0x0C, 0xC6, 0x33, 0x8C, 0xFF, 0xFF, 0xE0, 0x30, 0x0C, 0xFE, 0xFE, 0xC0, 0xC0, 0xF8, 0xFE,
0x0F, 0x03, 0x03, 0x07, 0xEE, 0xFC, 0x30, 0x00, 0x0F, 0x8F, 0xCE, 0x06, 0x03, 0x71, 0xFC, 0xE7,
0x61, 0xB0, 0xD8, 0x6E, 0xF3, 0xF0, 0x60, 0xFF, 0xBF, 0xC0, 0xE0, 0x60, 0x70, 0x30, 0x38, 0x18,
0x1C, 0x0C, 0x06, 0x07, 0x00, 0x00, 0x1F, 0x9F, 0xCC, 0x76, 0x3B, 0xB8, 0xF8, 0x7E, 0x63, 0xF0,
0xF8, 0x6E, 0x73, 0xF0, 0x40, 0x00, 0x1F, 0x1F, 0xCC, 0x7E, 0x1F, 0x0D, 0x8E, 0xFF, 0x3D, 0x81,
0xC0, 0xC1, 0xE7, 0xE1, 0x80, 0x1F, 0x80, 0x00, 0xFD, 0x00, 0x07, 0x60, 0x00, 0x00, 0x66, 0x6C,
0x00, 0x00, 0x00, 0xC1, 0xE3, 0xC7, 0x83, 0x80, 0xF8, 0x1F, 0x01, 0x80, 0x00, 0x7F, 0x3F, 0xC0,
0x00, 0x07, 0xFB, 0xFC, 0x00, 0x70, 0x1E, 0x03, 0xC0, 0x78, 0x3C, 0x7C, 0xF0, 0xE0, 0x00, 0x00,
0x01, 0xFB, 0xF8, 0x30, 0x61, 0xC7, 0x1C, 0x30, 0x60, 0x01, 0x83, 0x00, 0x00, 0x07, 0xE0, 0x3F,
0xF0, 0xE0, 0x63, 0x9F, 0x66, 0x7E, 0xCD, 0x8D, 0x9B, 0x1B, 0x36, 0x76, 0x6C, 0xEC, 0xCF, 0xF1,
0x88, 0x41, 0xC1, 0x01, 0xFE, 0x00, 0xF8, 0x00, 0x0E, 0x01, 0xC0, 0x78, 0x0D, 0x81, 0xB0, 0x67,
0x0C, 0x63, 0xFC, 0x7F, 0xCC, 0x1B, 0x03, 0x60, 0x30, 0xFF, 0x7F, 0xF8, 0xFC, 0x3E, 0x3F, 0xFB,
0xFF, 0xC3, 0xE1, 0xF0, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xE7, 0xFB, 0x80, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0x0E, 0x01, 0xFE, 0x3F, 0x81, 0x80, 0xFF, 0x1F, 0xF3, 0x87, 0x70, 0x6E, 0x0D,
0xC1, 0xF8, 0x3F, 0x06, 0xE0, 0xDC, 0x3B, 0xFE, 0x7F, 0x80, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE,
0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0x00, 0x07, 0xF7, 0xFD, 0x80, 0xE0, 0x30, 0x0C, 0x3F, 0x1F, 0xC0, 0xF0, 0x3E, 0x0D,
0xFF, 0x3F, 0xC1, 0x80, 0xC0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xFF, 0xFF, 0xFF, 0x83, 0xE0, 0xF8,
0x3E, 0x0F, 0x83, 0xFB, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8D, 0xF0, 0x18, 0x61, 0x86, 0x18, 0x61,
0x86, 0x18, 0x61, 0x86, 0x19, 0xEF, 0x90, 0xC1, 0xB8, 0xCE, 0x63, 0xB8, 0xFC, 0x3E, 0x0F, 0xC3,
0xB0, 0xE6, 0x39, 0xCE, 0x3B, 0x86, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xFE, 0xFF, 0xE0, 0x3F, 0x83, 0xFC, 0x1F, 0xE0, 0xFD, 0x8D, 0xEC, 0x6F, 0x77, 0x79, 0xB3, 0xCD,
0x9E, 0x38, 0xF1, 0xC7, 0x8E, 0x30, 0xE0, 0xDE, 0x1B, 0xC3, 0x7C, 0x6D, 0xCD, 0x99, 0xB3, 0xB6,
0x3E, 0xC3, 0xD8, 0x7B, 0x07, 0x60, 0x60, 0x00, 0x07, 0xF1, 0xFF, 0x70, 0x7C, 0x07, 0x80, 0xF0,
0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x83, 0xBF, 0xE3, 0xF8, 0x08, 0x00, 0xFE, 0x7F, 0xB8, 0xDC, 0x7E,
0x37, 0x3B, 0xF9, 0xF0, 0xE0, 0x70, 0x38, 0x1C, 0x00, 0x00, 0x07, 0xF1, 0xFF, 0x70, 0x7C, 0x07,
0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x83, 0xBF, 0xE3, 0xF8, 0x0F, 0x00, 0x70, 0x0E, 0xFE,
0x3F, 0xCE, 0x33, 0x8E, 0xE3, 0x3F, 0xCF, 0xE3, 0xB8, 0xE6, 0x39, 0xCE, 0x3B, 0x86, 0x00, 0x1F,
0x9F, 0xCC, 0x06, 0x03, 0x80, 0xF0, 0x3E, 0x03, 0x81, 0xC0, 0xFF, 0xE7, 0xE0, 0xC0, 0xFF, 0xBF,
0xE0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00, 0xC0, 0xF0,
0x3E, 0x1D, 0x86, 0x63, 0x8C, 0xC3, 0x30, 0xFC, 0x1E, 0x07, 0x81, 0xE0, 0x30, 0xC3, 0x87, 0xE3,
0x86, 0xE3, 0xC6, 0x63, 0xCE, 0x66, 0xCC, 0x76, 0xCC, 0x36, 0x6C, 0x3E, 0x7C, 0x3C, 0x78, 0x3C,
0x78, 0x1C, 0x38, 0x18, 0x38, 0xE1, 0xD8, 0x67, 0x30, 0xFC, 0x1E, 0x07, 0x01, 0xE0, 0x78, 0x37,
0x1C, 0xE6, 0x1B, 0x07, 0xC1, 0xF8, 0x66, 0x39, 0xCC, 0x36, 0x07, 0x81, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0xFF, 0xBF, 0xC0, 0xC0, 0xE0, 0xE0, 0x60, 0x70, 0x70, 0x30, 0x38, 0x3F, 0xFF,
0xF0, 0xF7, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7B, 0xC0, 0xC1, 0xC1, 0x83, 0x07, 0x06,
0x0C, 0x0C, 0x18, 0x30, 0x30, 0x60, 0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0xFF, 0xC0,
0x0C, 0x0E, 0x07, 0x86, 0xC3, 0x33, 0x19, 0x87, 0x83, 0x7F, 0xBF, 0xC0, 0xE3, 0x8C, 0x00, 0x3F,
0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xE7, 0xFB,
0x8D, 0x87, 0xC3, 0xE1, 0xF8, 0xDE, 0xEF, 0xE0, 0x40, 0x00, 0x3F, 0x7E, 0x60, 0x60, 0x60, 0x60,
0x60, 0x7F, 0x3F, 0x0C, 0x01, 0x80, 0xC0, 0x60, 0x33, 0xFB, 0xFD, 0x86, 0xC3, 0x61, 0xB0, 0xD8,
0x6E, 0xF3, 0xF8, 0x40, 0x00, 0x1F, 0x9F, 0xCC, 0x77, 0xFB, 0xFD, 0x80, 0xC0, 0x7B, 0x1F, 0x81,
0x00, 0x1E, 0x7C, 0xC3, 0x8F, 0xDF, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x00, 0x00, 0x1F, 0xDF,
0xEC, 0x36, 0x1B, 0x0D, 0x86, 0xC3, 0x73, 0x9F, 0xC2, 0x60, 0x37, 0xFB, 0xF8, 0xC0, 0xC0, 0xC0,
0xC0, 0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x5B, 0x0D, 0xB6, 0xDB, 0x6C, 0x11,
0x8C, 0x03, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xDE, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC7, 0xCE,
0xDC, 0xF8, 0xF8, 0xFC, 0xCC, 0xCE, 0xC7, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFB, 0xEF, 0xFF,
0xB8, 0xC7, 0xC3, 0x1F, 0x0C, 0x7C, 0x31, 0xF0, 0xC7, 0xC3, 0x1F, 0x0C, 0x70, 0x00, 0xFE, 0xFF,
0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x00, 0x0F, 0xC7, 0xF9, 0x86, 0x61, 0x98, 0x76, 0x19,
0x86, 0x73, 0x8F, 0xC0, 0xC0, 0x00, 0x7F, 0x3F, 0xDC, 0x6C, 0x3E, 0x1F, 0x0F, 0xC6, 0xF7, 0x7F,
0x32, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x1F, 0xDF, 0xEC, 0x36, 0x1B, 0x0D, 0x86, 0xC3, 0x73, 0x9F,
0xC2, 0x60, 0x30, 0x18, 0x0C, 0x03, 0xFF, 0xF8, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0x00, 0x7E, 0x7E,
0xE0, 0x78, 0x3E, 0x0E, 0x07, 0x66, 0x7E, 0x10, 0x21, 0x8F, 0xFE, 0x61, 0x86, 0x18, 0x61, 0xC3,
0xC2, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0xC3, 0xE1, 0x98, 0xCC, 0xE7,
0x61, 0xB0, 0xF0, 0x78, 0x1C, 0x00, 0xC7, 0x1E, 0x38, 0xF9, 0xCE, 0xDB, 0x66, 0xDB, 0x36, 0xD8,
0xE3, 0xC7, 0x1C, 0x38, 0xE0, 0xE3, 0x3B, 0x8D, 0x87, 0x81, 0xC1, 0xE0, 0xD8, 0xCE, 0xE3, 0x80,
0xC3, 0xF1, 0x98, 0xCC, 0xE7, 0x61, 0xB0, 0xF0, 0x38, 0x1C, 0x0C, 0x06, 0x1E, 0x0F, 0x00, 0x7E,
0x7E, 0x0E, 0x1C, 0x18, 0x30, 0x70, 0x7E, 0xFF, 0x1C, 0xF3, 0x0C, 0x30, 0xCF, 0x38, 0x70, 0xC3,
0x0C, 0x30, 0x70, 0xC0, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0x60, 0xE3, 0xC3, 0x0C, 0x30, 0xC3,
0xC7, 0x38, 0xC3, 0x0C, 0x33, 0xCE, 0x00, 0x7D, 0xFF, 0xC0, 0x80, 0x1F, 0x8D, 0xB6, 0xDB, 0x6C,
0x00, 0x00, 0x18, 0x3E, 0x7E, 0x60, 0xE0, 0xC0, 0xC0, 0xE0, 0x60, 0x7E, 0x3E, 0x18, 0x08, 0x00,
0x0F, 0xCF, 0xE6, 0x03, 0x01, 0x83, 0xF9, 0xFC, 0x30, 0x18, 0x0C, 0x1F, 0xFF, 0xF8, 0xC1, 0x98,
0x66, 0x30, 0xCC, 0x36, 0x07, 0x87, 0xF1, 0xFC, 0x3F, 0x1F, 0xC0, 0xC0, 0x30, 0x3E, 0x7E, 0x60,
0x78, 0x3E, 0x6F, 0x63, 0x73, 0x3E, 0x0E, 0x03, 0x67, 0x7E, 0x00, 0x03, 0x6C, 0x80, 0x00, 0x00,
0x7F, 0x03, 0x87, 0x1D, 0xEC, 0x6F, 0x99, 0x30, 0x2C, 0xC0, 0xB3, 0x02, 0x4C, 0x09, 0xBE, 0x66,
0x7B, 0x0E, 0x1C, 0x1F, 0xE0, 0x0C, 0x00, 0x01, 0xE0, 0x9F, 0xCF, 0xF7, 0x80, 0x1B, 0x37, 0x7E,
0xEC, 0x6E, 0x37, 0x1B, 0x00, 0x00, 0x00, 0x7F, 0x03, 0x87, 0x1F, 0xEC, 0x6F, 0xD9, 0x33, 0x2C,
0xFC, 0xB3, 0xE2, 0x4D, 0x89, 0xB3, 0x66, 0xCF, 0x0E, 0x1C, 0x1F, 0xE0, 0x0C, 0x00, 0x7F, 0xDF,
0xF0, 0x00, 0xF9, 0xB2, 0x36, 0xCF, 0x80, 0x00, 0x33, 0xB8, 0x3F, 0x9F, 0xF7, 0xED, 0xFB, 0x7E,
0xDF, 0xB7, 0xED, 0xFB, 0x3E, 0xC1, 0xB0, 0x6C, 0x1B, 0x06, 0xC1, 0xB0, 0x6C, 0x00, 0x1F, 0xA0,
0x67, 0x3E, 0x01, 0xEC, 0xF3, 0xCD, 0xF7, 0x80, 0x4C, 0x6E, 0x36, 0x3B, 0x37, 0x6E, 0x6C, 0x00,
0x00, 0x38, 0x70, 0x01, 0x83, 0x06, 0x38, 0x61, 0x83, 0x07, 0x77, 0xE3, 0x00, 0x18, 0x01, 0x80,
0x18, 0x00, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xD8, 0x1B, 0x06, 0x70, 0xC6, 0x3F, 0xC7, 0xFC, 0xC1,
0xB0, 0x36, 0x03, 0x07, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xD8, 0x1B, 0x06,
0x70, 0xC6, 0x3F, 0xC7, 0xFC, 0xC1, 0xB0, 0x36, 0x03, 0x0E, 0x03, 0xC0, 0xEC, 0x00, 0x00, 0xE0,
0x1C, 0x07, 0x80, 0xD8, 0x1B, 0x06, 0x70, 0xC6, 0x3F, 0xC7, 0xFC, 0xC1, 0xB0, 0x36, 0x03, 0x08,
0x03, 0xF0, 0xDC, 0x00, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xD8, 0x1B, 0x06, 0x70, 0xC6, 0x3F, 0xC7,
0xFC, 0xC1, 0xB0, 0x36, 0x03, 0x00, 0x03, 0x60, 0x6C, 0x00, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xD8,
0x1B, 0x06, 0x70, 0xC6, 0x3F, 0xC7, 0xFC, 0xC1, 0xB0, 0x36, 0x03, 0x0E, 0x03, 0xC0, 0x68, 0x07,
0x00, 0xE0, 0x3C, 0x06, 0xC0, 0xD8, 0x33, 0x86, 0x31, 0xFE, 0x3F, 0xE6, 0x0D, 0x81, 0xB0, 0x18,
0x03, 0xFE, 0x07, 0xFC, 0x1B, 0x00, 0x36, 0x00, 0xCC, 0x01, 0x9F, 0xC7, 0x3F, 0x8F, 0xE0, 0x3F,
0xC0, 0x61, 0x81, 0xC3, 0xFB, 0x07, 0xF0, 0x00, 0x0F, 0xE7, 0xFB, 0x80, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0x0E, 0x01, 0xFE, 0x3F, 0x83, 0x80, 0xE0, 0x18, 0x1E, 0x00, 0x30, 0x38, 0x18,
0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x0E, 0x0C, 0x18,
0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x18, 0x3C, 0x66,
0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x00, 0x76, 0x24,
0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0xE3, 0x8C, 0x0F,
0xB8, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xDF, 0x18, 0xE3, 0x00, 0xF9, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
0x30, 0xC3, 0x3E, 0x71, 0xED, 0xC0, 0xF9, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x3E, 0x03,
0x74, 0x80, 0xF9, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x3E, 0x7F, 0x87, 0xFC, 0x70, 0xE7,
0x06, 0x70, 0x6F, 0xC7, 0xFE, 0x77, 0x06, 0x70, 0x67, 0x0E, 0x7F, 0xC7, 0xF8, 0x08, 0x03, 0xF0,
0xDC, 0x00, 0x0E, 0x0D, 0xE1, 0xBC, 0x37, 0xC6, 0xDC, 0xD9, 0x9B, 0x3B, 0x63, 0xEC, 0x3D, 0x87,
0xB0, 0x76, 0x06, 0x1C, 0x01, 0x80, 0x18, 0x00, 0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0, 0x78,
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1, 0xFC, 0x04, 0x00, 0x03, 0x00, 0xE0, 0x38, 0x00,
0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1,
0xFC, 0x04, 0x00, 0x0E, 0x03, 0xE0, 0x6C, 0x00, 0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0, 0x78,
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1, 0xFC, 0x04, 0x00, 0x08, 0x83, 0xF0, 0x5C, 0x00,
0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1,
0xFC, 0x04, 0x00, 0x00, 0x03, 0x60, 0x6C, 0x00, 0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0, 0x78,
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1, 0xFC, 0x04, 0x00, 0xC2, 0xC7, 0x6E, 0x3C, 0x38,
0x7C, 0xE6, 0xC2, 0x00, 0x47, 0xF9, 0xFF, 0x70, 0xFC, 0x3F, 0x8E, 0xF1, 0x9E, 0x63, 0xDC, 0x7F,
0x0F, 0xC3, 0xBF, 0xEF, 0xF8, 0x88, 0x00, 0x18, 0x07, 0x00, 0xC0, 0x00, 0xC0, 0xF0, 0x3C, 0x0F,
0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00, 0x07, 0x01, 0x80,
0xC0, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8,
0xFC, 0x0C, 0x00, 0x0C, 0x07, 0x83, 0x30, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C,
0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00, 0x00, 0x0E, 0xC1, 0x20, 0x00, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00, 0x06,
0x03, 0x80, 0xC0, 0x00, 0xC1, 0xF8, 0x66, 0x39, 0xCC, 0x36, 0x07, 0x81, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0xC0, 0x70, 0x3F, 0x9F, 0xEE, 0x37, 0x1F, 0x8F, 0xCE, 0xFE, 0x7E, 0x38, 0x1C,
0x00, 0x7E, 0x7F, 0xB0, 0xD8, 0x6C, 0xE6, 0x63, 0x31, 0x9C, 0xC7, 0x61, 0xF0, 0x7B, 0x7D, 0xF0,
0x20, 0x38, 0x18, 0x0C, 0x00, 0x3F, 0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x06,
0x0E, 0x0C, 0x00, 0x3F, 0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x1C, 0x3E, 0x37,
0x00, 0x3F, 0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x11, 0x3F, 0x2F, 0x00, 0x3F,
0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x00, 0x36, 0x36, 0x00, 0x3F, 0x37, 0x03,
0x1F, 0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x1C, 0x1E, 0x16, 0x1C, 0x00, 0x3F, 0x37, 0x03, 0x1F,
0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x00, 0x01, 0xFB, 0xE7, 0x7F, 0x80, 0xC7, 0x1F, 0xFD, 0xFF,
0xF6, 0x30, 0x38, 0xE0, 0x67, 0xD9, 0xF3, 0xE1, 0x02, 0x00, 0x00, 0x3F, 0x7E, 0x60, 0x60, 0x60,
0x60, 0x60, 0x7F, 0x3F, 0x0C, 0x0C, 0x06, 0x1C, 0x38, 0x0E, 0x03, 0x00, 0x03, 0xF3, 0xF9, 0x8E,
0xFF, 0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0x06, 0x07, 0x03, 0x00, 0x03, 0xF3, 0xF9, 0x8E,
0xFF, 0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0x1C, 0x0F, 0x0D, 0xC0, 0x03, 0xF3, 0xF9, 0x8E,
0xFF, 0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0x00, 0x1B, 0x0C, 0x80, 0x03, 0xF3, 0xF9, 0x8E,
0xFF, 0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0x63, 0x8E, 0x03, 0x18, 0xC6, 0x31, 0x8C, 0x63,
0x00, 0x76, 0xC0, 0xCC, 0xCC, 0xCC, 0xCC, 0xC0, 0x31, 0xEC, 0xC0, 0x30, 0xC3, 0x0C, 0x30, 0xC3,
0x0C, 0x30, 0x03, 0xB4, 0x80, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0x19, 0x07, 0xC1, 0xE0,
0xEC, 0x03, 0x8F, 0xE7, 0xF9, 0x87, 0x61, 0xD8, 0x66, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x12, 0x3E,
0x6E, 0x00, 0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x18, 0x07, 0x00, 0xC0, 0x00,
0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x07, 0x01, 0x80,
0xC0, 0x00, 0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x0C,
0x07, 0x83, 0x30, 0x00, 0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66, 0x19, 0xCE, 0x3F, 0x03,
0x00, 0x09, 0x0F, 0xC3, 0x70, 0x00, 0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66, 0x19, 0xCE,
0x3F, 0x03, 0x00, 0x00, 0x0E, 0xC1, 0x20, 0x00, 0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66,
0x19, 0xCE, 0x3F, 0x03, 0x00, 0x0C, 0x0E, 0x02, 0x0F, 0xFF, 0xF8, 0x00, 0x30, 0x18, 0x00, 0x0F,
0xE7, 0xF9, 0x9E, 0x67, 0x9B, 0x77, 0xD9, 0xE6, 0x73, 0x9F, 0xC6, 0xC0, 0x30, 0x38, 0x1C, 0x00,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x0E, 0x0C, 0x18, 0x00, 0xC3, 0xC3,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x18, 0x3C, 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x00, 0x76, 0x24, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xEF, 0x7F, 0x10, 0x0E, 0x06, 0x06, 0x00, 0x0C, 0x3F, 0x19, 0x8C, 0xCE, 0x76, 0x1B, 0x0F,
0x03, 0x81, 0xC0, 0xC0, 0x61, 0xE0, 0xF0, 0x00, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xE7, 0xFB, 0x8D,
0x87, 0xC3, 0xE1, 0xF8, 0xDE, 0xEF, 0xE6, 0x43, 0x01, 0x80, 0xC0, 0x00, 0x00, 0x1B, 0x09, 0x80,
0x0C, 0x3F, 0x19, 0x8C, 0xCE, 0x76, 0x1B, 0x0F, 0x03, 0x81, 0xC0, 0xC0, 0x61, 0xE0, 0xF0, 0x00,
0x1F, 0x07, 0xE0, 0x00, 0x07, 0x00, 0xE0, 0x3C, 0x06, 0xC0, 0xD8, 0x33, 0x86, 0x31, 0xFE, 0x3F,
0xE6, 0x0D, 0x81, 0xB0, 0x18, 0x3E, 0x3F, 0x00, 0x3F, 0x37, 0x03, 0x1F, 0x7F, 0x63, 0xE3, 0x67,
0x7F, 0x10, 0x11, 0x03, 0xE0, 0x78, 0x00, 0x00, 0xE0, 0x1C, 0x07, 0x80, 0xD8, 0x1B, 0x06, 0x70,
0xC6, 0x3F, 0xC7, 0xFC, 0xC1, 0xB0, 0x36, 0x03, 0x22, 0x3E, 0x1E, 0x00, 0x3F, 0x37, 0x03, 0x1F,
0x7F, 0x63, 0xE3, 0x67, 0x7F, 0x10, 0x0E, 0x01, 0xC0, 0x78, 0x0D, 0x81, 0xB0, 0x67, 0x0C, 0x63,
0xFC, 0x7F, 0xCC, 0x1B, 0x03, 0x60, 0x30, 0x0C, 0x01, 0x80, 0x38, 0x07, 0x00, 0x1F, 0x8D, 0xC0,
0x61, 0xF3, 0xF9, 0x8D, 0xC6, 0x67, 0x3F, 0x84, 0xC0, 0xC0, 0x78, 0x1C, 0x07, 0x01, 0x80, 0xC0,
0x00, 0x3F, 0x9F, 0xEE, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x07, 0xF8, 0xFE,
0x06, 0x00, 0x06, 0x0E, 0x0C, 0x00, 0x3F, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x3F, 0x0C,
0x04, 0x03, 0x80, 0xC0, 0x00, 0x3F, 0x9F, 0xEE, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
0x38, 0x07, 0xF8, 0xFE, 0x06, 0x00, 0x08, 0x0C, 0x0C, 0x00, 0x3F, 0x7E, 0x60, 0x60, 0x60, 0x60,
0x60, 0x7F, 0x3F, 0x0C, 0x33, 0x07, 0xC0, 0xE0, 0x00, 0x3F, 0x9F, 0xEE, 0x03, 0x00, 0xC0, 0x30,
0x0C, 0x03, 0x00, 0xC0, 0x38, 0x07, 0xF8, 0xFE, 0x06, 0x00, 0x33, 0x3E, 0x1C, 0x00, 0x3F, 0x7E,
0x60, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x3F, 0x0C, 0x33, 0x03, 0xC0, 0x30, 0x00, 0x0F, 0xF1, 0xFF,
0x38, 0x77, 0x06, 0xE0, 0xDC, 0x1F, 0x83, 0xF0, 0x6E, 0x0D, 0xC3, 0xBF, 0xE7, 0xF8, 0x01, 0xB0,
0x1E, 0x01, 0xE0, 0x18, 0x3F, 0x87, 0xF8, 0x61, 0x86, 0x18, 0x61, 0x86, 0x18, 0x61, 0x87, 0x78,
0x3F, 0x80, 0x80, 0x7F, 0x87, 0xFC, 0x70, 0xE7, 0x06, 0x70, 0x6F, 0xC7, 0xFE, 0x77, 0x06, 0x70,
0x67, 0x0E, 0x7F, 0xC7, 0xF8, 0x01, 0x81, 0xF8, 0x7F, 0x00, 0xC3, 0xF8, 0xFF, 0x18, 0x63, 0x0C,
0x61, 0x8C, 0x31, 0x86, 0x39, 0xC3, 0xF8, 0x10, 0x00, 0x3E, 0x7E, 0x00, 0xFF, 0xFE, 0xE0, 0xE0,
0xE0, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x3E, 0x1F, 0x80, 0x07, 0xE7, 0xF3, 0x1D, 0xFE,
0xFF, 0x60, 0x30, 0x1E, 0xC7, 0xE0, 0x40, 0x08, 0x18, 0x18, 0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0,
0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x08, 0x06, 0x03, 0x00, 0x03, 0xF3, 0xF9, 0x8E, 0xFF,
0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xE0, 0xE0,
0xE0, 0xFE, 0xFF, 0x06, 0x0C, 0x0E, 0x06, 0x00, 0x1F, 0x9F, 0xCC, 0x77, 0xFB, 0xFD, 0x80, 0xC0,
0x7B, 0x1F, 0x81, 0xC0, 0xC0, 0x70, 0x38, 0x66, 0x3C, 0x1C, 0x00, 0xFF, 0xFE, 0xE0, 0xE0, 0xE0,
0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x33, 0x1F, 0x07, 0x00, 0x03, 0xF3, 0xF9, 0x8E, 0xFF,
0x7F, 0xB0, 0x18, 0x0F, 0x63, 0xF0, 0x20, 0x11, 0x07, 0xE0, 0xF0, 0x00, 0x1F, 0xDF, 0xF6, 0x03,
0x80, 0xC0, 0x30, 0xFC, 0x7F, 0x03, 0xC0, 0xF8, 0x37, 0xFC, 0xFF, 0x06, 0x00, 0x23, 0x1F, 0x87,
0x80, 0x03, 0xFB, 0xFD, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6E, 0x73, 0xF8, 0x4C, 0x06, 0xFF, 0x7F,
0x00, 0x04, 0x01, 0x80, 0x60, 0x00, 0x1F, 0xDF, 0xF6, 0x03, 0x80, 0xC0, 0x30, 0xFC, 0x7F, 0x03,
0xC0, 0xF8, 0x37, 0xFC, 0xFF, 0x06, 0x00, 0x08, 0x06, 0x03, 0x00, 0x03, 0xFB, 0xFD, 0x86, 0xC3,
0x61, 0xB0, 0xD8, 0x6E, 0x73, 0xF8, 0x4C, 0x06, 0xFF, 0x7F, 0x00, 0x00, 0x07, 0xF7, 0xFD, 0x80,
0xE0, 0x30, 0x0C, 0x3F, 0x1F, 0xC0, 0xF0, 0x3E, 0x0D, 0xFF, 0x3F, 0xC1, 0x80, 0x60, 0x18, 0x0C,
0x00, 0x04, 0x06, 0x03, 0x00, 0x03, 0xFB, 0xFD, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6E, 0x73, 0xF8,
0x4C, 0x06, 0xFF, 0x7F, 0x00, 0x60, 0x63, 0x83, 0x3F, 0xFF, 0xFF, 0xE7, 0x06, 0x3F, 0xF1, 0xFF,
0x8E, 0x0C, 0x70, 0x63, 0x83, 0x1C, 0x18, 0xE0, 0xC0, 0x60, 0x7E, 0x3F, 0x8C, 0x06, 0xF3, 0xFD,
0xC6, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x18, 0xFB, 0xF0, 0x3E, 0x70, 0xC3, 0x0C, 0x30, 0xC3,
0x0C, 0x30, 0xCF, 0x80, 0x7F, 0xF0, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0xFB, 0x8C, 0x63,
0x18, 0xC6, 0x31, 0x8D, 0xF3, 0x98, 0xE7, 0x26, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCE, 0x60,
0x21, 0x8C, 0x0F, 0xB8, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xDF, 0xFF, 0xFF, 0xC0, 0xC1, 0xB8, 0xCE,
0x63, 0xB8, 0xFC, 0x3E, 0x0F, 0xC3, 0xB0, 0xE6, 0x39, 0xCE, 0x3B, 0x86, 0x00, 0x03, 0x01, 0x80,
0x60, 0xC0, 0xC0, 0xC0, 0xC0, 0xC7, 0xCE, 0xDC, 0xF8, 0xF8, 0xFC, 0xCC, 0xCE, 0xC7, 0x00, 0x18,
0x30, 0x30, 0x70, 0x60, 0xC0, 0x00, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xFE, 0xFF, 0x76, 0xC0, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0x00, 0x18, 0x18, 0x10, 0xDB, 0x6D, 0xB6, 0xDB, 0x6C,
0x36, 0x80, 0xC3, 0xE6, 0xE6, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFF, 0xDE, 0xFD,
0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00, 0x60, 0x38, 0x1C, 0x0E, 0x07, 0xC3, 0xE1, 0xE1, 0xE0,
0x70, 0x38, 0x1F, 0xCF, 0xF0, 0x30, 0xC3, 0x0C, 0x30, 0xE3, 0xDC, 0x70, 0xC3, 0x0C, 0x30, 0x07,
0x00, 0xC0, 0x30, 0x00, 0x0E, 0x0D, 0xE1, 0xBC, 0x37, 0xC6, 0xDC, 0xD9, 0x9B, 0x3B, 0x63, 0xEC,
0x3D, 0x87, 0xB0, 0x76, 0x06, 0x0E, 0x0C, 0x18, 0x00, 0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xC3, 0xE0, 0xDE, 0x1B, 0xC3, 0x7C, 0x6D, 0xCD, 0x99, 0xB3, 0xB6, 0x3E, 0xC3, 0xD8, 0x7B,
0x07, 0x60, 0x60, 0x00, 0x1C, 0x03, 0x00, 0x60, 0x00, 0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xC3, 0x00, 0x18, 0x18, 0x10, 0x33, 0x03, 0xE0, 0x38, 0x00, 0x0E, 0x0D, 0xE1, 0xBC, 0x37,
0xC6, 0xDC, 0xD9, 0x9B, 0x3B, 0x63, 0xEC, 0x3D, 0x87, 0xB0, 0x76, 0x06, 0x66, 0x3C, 0x1C, 0x00,
0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE0, 0xDE, 0x1B, 0xC3, 0x7C, 0x6D, 0xCD,
0x99, 0xB3, 0xB6, 0x3E, 0xC3, 0xD8, 0x3B, 0x07, 0x60, 0x60, 0x0C, 0x07, 0x81, 0xF0, 0x10, 0x00,
0xFE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x03, 0x03, 0x0F, 0x0F, 0x1F, 0x03, 0xE0,
0x00, 0x1F, 0xC7, 0xFD, 0xC1, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x0E, 0xFF,
0x8F, 0xE0, 0x20, 0x1F, 0x0F, 0xC0, 0x00, 0xFC, 0x7F, 0x98, 0x66, 0x19, 0x87, 0x61, 0x98, 0x67,
0x38, 0xFC, 0x0C, 0x00, 0x1F, 0x83, 0x60, 0xD8, 0x00, 0x03, 0xF8, 0xFF, 0xB8, 0x3E, 0x03, 0xC0,
0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDF, 0xF1, 0xFC, 0x04, 0x00, 0x1B, 0x0F, 0xC3, 0x60,
0x00, 0x3F, 0x1F, 0xE6, 0x19, 0x86, 0x61, 0xD8, 0x66, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x00, 0x00,
0xFF, 0xF7, 0xFF, 0xF8, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x7E, 0xC1, 0x83, 0x06, 0x0E,
0x18, 0x1F, 0xFF, 0x3F, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x7E, 0xF9, 0xFF, 0xFB, 0x0E, 0x36, 0x1F,
0xEC, 0x3F, 0xD8, 0x60, 0x30, 0xE0, 0x73, 0xEE, 0x7E, 0xFC, 0x20, 0x40, 0x0E, 0x03, 0x01, 0x80,
0x00, 0xFE, 0x3F, 0xCE, 0x33, 0x8E, 0xE3, 0x3F, 0xCF, 0xE3, 0xB8, 0xE6, 0x39, 0xCE, 0x3B, 0x86,
0x1C, 0x63, 0x00, 0xFF, 0xFE, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0xFE, 0x3F, 0xCE, 0x33, 0x8E, 0xE3,
0x3F, 0xCF, 0xE3, 0xB8, 0xE6, 0x39, 0xCE, 0x3B, 0x86, 0x00, 0x03, 0x01, 0x80, 0x60, 0x03, 0xFF,
0xF8, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0x30, 0xC2, 0x00, 0x66, 0x0F, 0x01, 0xC0, 0x00, 0xFE, 0x3F,
0xCE, 0x33, 0x8E, 0xE3, 0x3F, 0xCF, 0xE3, 0xB8, 0xE6, 0x39, 0xCE, 0x3B, 0x86, 0xCD, 0xE3, 0x00,
0xFF, 0xFE, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x06, 0x07, 0x03, 0x00, 0x03, 0xF3, 0xF9, 0x80, 0xC0,
0x70, 0x1E, 0x07, 0xC0, 0x70, 0x38, 0x1F, 0xFC, 0xFC, 0x18, 0x00, 0x0E, 0x0C, 0x18, 0x00, 0x7E,
0x7E, 0xE0, 0x78, 0x3E, 0x0E, 0x07, 0x66, 0x7E, 0x10, 0x00, 0x1F, 0x9F, 0xCC, 0x06, 0x03, 0x80,
0xF0, 0x3E, 0x03, 0x81, 0xC0, 0xFF, 0xE7, 0xE0, 0xC0, 0x70, 0x18, 0x3C, 0x00, 0x00, 0x7E, 0x7E,
0xE0, 0x78, 0x3E, 0x0E, 0x07, 0x66, 0x7E, 0x18, 0x1C, 0x0C, 0x3C, 0x33, 0x1F, 0x07, 0x00, 0x03,
0xF3, 0xF9, 0x80, 0xC0, 0x70, 0x1E, 0x07, 0xC0, 0x70, 0x38, 0x1F, 0xFC, 0xFC, 0x18, 0x00, 0x66,
0x3C, 0x18, 0x00, 0x7E, 0x7E, 0xE0, 0x78, 0x3E, 0x0E, 0x07, 0x66, 0x7E, 0x10, 0x37, 0x0F, 0x81,
0xC0, 0x00, 0xFF, 0xBF, 0xE0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
0x30, 0x03, 0x03, 0x22, 0x60, 0xFC, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3C, 0x08, 0x1F,
0x0F, 0xC0, 0x03, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xE1, 0xDF,
0xE3, 0xF0, 0x30, 0x3E, 0x7E, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10,
0x31, 0x0F, 0xC1, 0xE0, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00, 0x62, 0x7E, 0x3C, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
0xC3, 0xEF, 0x7F, 0x10, 0x0E, 0x07, 0x81, 0xA0, 0x78, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x03, 0x00, 0x1C, 0x3C, 0x34, 0x3C, 0x00,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x1B, 0x0F, 0xC3, 0x60, 0x00, 0xC0,
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0C, 0x00,
0x36, 0x3E, 0x6C, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0xC0, 0xF0,
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x77, 0xF8, 0xFC, 0x0F, 0x01, 0x80,
0x78, 0x0E, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0xDE, 0x7F, 0x09, 0x81, 0x80, 0xE0,
0x70, 0x03, 0x80, 0x03, 0xC0, 0x06, 0xE0, 0x00, 0x00, 0xC3, 0x87, 0xE3, 0x86, 0xE3, 0xC6, 0x63,
0xCE, 0x66, 0xCC, 0x76, 0xCC, 0x36, 0x6C, 0x3E, 0x7C, 0x3C, 0x78, 0x3C, 0x78, 0x1C, 0x38, 0x18,
0x38, 0x07, 0x00, 0x7C, 0x03, 0x70, 0x00, 0x0C, 0x71, 0xE3, 0x8F, 0x9C, 0xED, 0xB6, 0x6D, 0xB3,
0x6D, 0x8E, 0x3C, 0x71, 0xC3, 0x8E, 0x00, 0x1C, 0x07, 0x83, 0x70, 0x00, 0xC1, 0xF8, 0x66, 0x39,
0xCC, 0x36, 0x07, 0x81, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x1C, 0x1E, 0x1D, 0x80, 0x0C,
0x3F, 0x19, 0x8C, 0xCE, 0x76, 0x1B, 0x0F, 0x03, 0x81, 0xC0, 0xC0, 0x61, 0xE0, 0xF0, 0x00, 0x00,
0x0D, 0x83, 0x20, 0x00, 0xC1, 0xF8, 0x66, 0x39, 0xCC, 0x36, 0x07, 0x81, 0xC0, 0x30, 0x0C, 0x03,
0x00, 0xC0, 0x30, 0x06, 0x07, 0x03, 0x00, 0x0F, 0xFB, 0xFC, 0x0C, 0x0E, 0x0E, 0x06, 0x07, 0x07,
0x03, 0x03, 0x83, 0xFF, 0xFF, 0x0E, 0x1C, 0x18, 0x00, 0x7E, 0x7E, 0x0E, 0x1C, 0x18, 0x30, 0x70,
0x7E, 0xFF, 0x08, 0x06, 0x03, 0x00, 0x0F, 0xFB, 0xFC, 0x0C, 0x0E, 0x0E, 0x06, 0x07, 0x07, 0x03,
0x03, 0x83, 0xFF, 0xFF, 0x10, 0x18, 0x18, 0x00, 0x7E, 0x7E, 0x0E, 0x1C, 0x18, 0x30, 0x70, 0x7E,
0xFF, 0x33, 0x1F, 0x07, 0x00, 0x0F, 0xFB, 0xFC, 0x0C, 0x0E, 0x0E, 0x06, 0x07, 0x07, 0x03, 0x03,
0x83, 0xFF, 0xFF, 0x66, 0x3C, 0x38, 0x00, 0x7E, 0x7E, 0x0E, 0x1C, 0x18, 0x30, 0x70, 0x7E, 0xFF,
0x63, 0x8C, 0x37, 0xE0, 0x31, 0xEC, 0xC0, 0x47, 0xFF, 0xC0, 0xFF, 0xF0, 0x8F, 0xF7, 0x80, 0xFC,
0x03, 0xF4, 0x80, 0x6F, 0xFF, 0x36, 0xFD, 0xB0, 0xCD, 0xE3, 0x00, 0x26, 0x6E, 0x40, 0x66, 0x40,
0x67, 0x3F, 0x26, 0xCF, 0x70, 0xFF, 0xC0, 0x38, 0x7E, 0xE7, 0xE3, 0x73, 0xE3, 0xC3, 0xC3, 0xC3,
0xC3, 0x20, 0x73, 0x33, 0x33, 0x73, 0x63, 0x63, 0x63, 0x77, 0x3E, 0x08, 0x40, 0xFB, 0x7B, 0x33,
0x73, 0x63, 0x63, 0x63, 0x77, 0x3E, 0x08, 0x1C, 0x7E, 0xE7, 0xC3, 0xC3, 0xFB, 0xFB, 0xC3, 0xC3,
0xC3, 0x26, 0xFF, 0xDB, 0xC3, 0xC3, 0xFB, 0xFB, 0xC3, 0xC3, 0xC3, 0x40, 0x7C, 0xDE, 0x66, 0x37,
0x1B, 0x0D, 0x86, 0xC3, 0x7B, 0xBF, 0x81, 0x00, 0x98, 0x6F, 0x31, 0xDC, 0x66, 0x33, 0x19, 0xCC,
0x66, 0x3E, 0x1F, 0x00, 0x38, 0xFE, 0xC7, 0x03, 0x73, 0x73, 0x33, 0x33, 0x3F, 0x3E, 0x38, 0xFE,
0xC7, 0x03, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x21, 0x73, 0x37, 0x37, 0x73, 0x63, 0x63,
0x63, 0x77, 0x3E, 0x08, 0x41, 0x7D, 0x9F, 0xC6, 0xE7, 0x33, 0x19, 0x8C, 0xC6, 0x77, 0x1F, 0x02,
0x00, 0x38, 0x03, 0xF0, 0xF9, 0x87, 0xCE, 0x37, 0x71, 0xF3, 0x8F, 0x1C, 0x78, 0xE3, 0xC7, 0xBF,
0xBF, 0x88, 0x10, 0x38, 0x03, 0xF0, 0xF9, 0x87, 0xCE, 0x37, 0x71, 0xF3, 0x8F, 0x1C, 0x78, 0xE7,
0xC3, 0xFF, 0x9F, 0xC8, 0x06, 0x07, 0xF0, 0x3F, 0x00, 0x1C, 0x1F, 0x9C, 0xEE, 0x33, 0x9B, 0x8D,
0x86, 0xC3, 0x61, 0xF0, 0xD0, 0x67, 0xF7, 0xF9, 0x0C, 0x1C, 0x1F, 0x9C, 0xEE, 0x33, 0x9B, 0x8D,
0x86, 0xC3, 0x61, 0xF0, 0xD0, 0x6F, 0xF7, 0xFB, 0x4C, 0x39, 0xFF, 0xB1, 0xC0, 0x67, 0x33, 0x98,
0xCC, 0x66, 0x3E, 0x1F, 0x00, 0x0F, 0xEF, 0xF2, 0x58, 0x43, 0x3F, 0xE7, 0xD8, 0xE6, 0x71, 0x9C,
0x67, 0x19, 0xC6, 0x71, 0x9C, 0x60, 0x26, 0x0B, 0xFC, 0x7D, 0xB1, 0xF0, 0xC7, 0xC3, 0x1F, 0x0C,
0x7C, 0x31, 0xF0, 0xC7, 0xE3, 0xF9, 0xEF, 0xE1, 0x02, 0x00, 0x38, 0x03, 0xF0, 0xF9, 0x87, 0xCE,
0x37, 0x71, 0xF3, 0x8F, 0x1C, 0x78, 0xE3, 0xC3, 0xFF, 0x9F, 0xC8, 0x20, 0x1C, 0x7E, 0xE7, 0xC3,
0xC3, 0xC3, 0xC3, 0xC3, 0xE3, 0x7B, 0x10, 0x36, 0x7F, 0xB6, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87,
0xE3, 0xBD, 0xC4, 0x00, 0x38, 0x7E, 0xE7, 0xE3, 0x73, 0xE3, 0xC3, 0xC3, 0xC3, 0xF3, 0x20, 0x1C,
0xFE, 0xE7, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x38, 0xFE, 0xC6, 0xE0, 0xFC, 0xFE, 0xC7,
0xC7, 0xEE, 0xFE, 0x10, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xEF, 0x7F, 0x10, 0x00,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x18, 0x03, 0x03, 0x03, 0x03, 0xC3, 0xC3,
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x18, 0x61, 0x78, 0xF0, 0x78, 0x3D, 0xDE, 0xEF, 0xDF,
0xEF, 0xE3, 0xE1, 0xC0, 0x01, 0x80, 0xC0, 0x6C, 0x3F, 0x1E, 0x0F, 0x07, 0xBB, 0xDD, 0xFB, 0xFD,
0xFC, 0x7C, 0x38, 0x40, 0x3C, 0xCD, 0xB9, 0xB7, 0xB6, 0xFE, 0xFF, 0x9E, 0xF1, 0xCE, 0x39, 0xC6,
0x38, 0x00, 0x60, 0x06, 0x00, 0x64, 0x46, 0xE6, 0x66, 0xE6, 0x6E, 0xE6, 0xFC, 0x7B, 0xC7, 0xBC,
0x79, 0xC3, 0x9C, 0x31, 0xC0, 0x1C, 0x1F, 0x9C, 0xEE, 0x33, 0x9B, 0x8D, 0x86, 0xC3, 0x61, 0xF0,
0xD0, 0x00, 0x41, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE3, 0xF7, 0xFE, 0x08, 0x32, 0xFB, 0xC3,
0xC3, 0xF3, 0xF3, 0xC3, 0xC3, 0xE7, 0x7E, 0x10, 0x1C, 0x7E, 0xE2, 0xE0, 0x78, 0x3E, 0x0F, 0x03,
0x67, 0xFE, 0x18, 0x38, 0x7E, 0xE7, 0xE3, 0x73, 0xE3, 0xC3, 0xC3, 0xC3, 0xF3, 0x23, 0x03, 0x03,
0x03, 0x1C, 0x3F, 0x98, 0xC0, 0x71, 0xFB, 0xFD, 0x8F, 0xC7, 0x63, 0xBF, 0xC4, 0x00, 0x1C, 0x1F,
0x9C, 0xEE, 0x33, 0x9B, 0x8D, 0x86, 0xC3, 0x61, 0xF0, 0xD0, 0x60, 0x30, 0x18, 0x0C, 0x70, 0xFC,
0x0E, 0x06, 0x06, 0x07, 0x06, 0x06, 0x5E, 0xFC, 0x10, 0x19, 0xBF, 0xF9, 0xD8, 0x6C, 0x37, 0xDB,
0xED, 0x86, 0xC3, 0x61, 0x80, 0x01, 0x30, 0xCC, 0x33, 0x0C, 0xDB, 0x37, 0xEC, 0xFB, 0x0C, 0xF7,
0x1F, 0x81, 0x80, 0x1D, 0xBF, 0xD8, 0xC0, 0x71, 0xFB, 0xFD, 0x8F, 0xC7, 0x63, 0xBF, 0xC4, 0x00,
0x42, 0xC6, 0xCC, 0xDC, 0xFE, 0xF7, 0xE3, 0xC3, 0xC3, 0xC3, 0x00, 0x60, 0x0E, 0x43, 0xCE, 0x0C,
0x64, 0xE6, 0xEC, 0x6E, 0xC7, 0xFC, 0x7B, 0xC7, 0xBC, 0x71, 0xC3, 0x18, 0x38, 0xFE, 0xCE, 0x07,
0xF3, 0xF3, 0xC3, 0xC7, 0xEE, 0x7E, 0x10, 0x3B, 0xFF, 0xCE, 0x07, 0xF3, 0xF3, 0xC3, 0xC7, 0xEE,
0x7E, 0x10, 0x32, 0xF6, 0xC6, 0xC6, 0xE6, 0x7E, 0x3E, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x70, 0x23,
0xEF, 0xC1, 0xFD, 0xF8, 0x73, 0xE9, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0x20, 0x1E, 0x03, 0x60,
0x38, 0x00, 0x38, 0x0F, 0x81, 0x38, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0,
0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x06, 0x0F, 0xFF, 0xFE, 0x08, 0x1B, 0xFF, 0xFF, 0xED, 0xB0,
0xED, 0xB7, 0xCE, 0xFD, 0x00, 0x18, 0xF8, 0xFE, 0xDF, 0xDB, 0xDF, 0xFE, 0xFF, 0xDB, 0xDB, 0xDF,
0xFF, 0xFC, 0x18, 0x4C, 0xCC, 0xCC, 0xCC, 0xEF, 0x20, 0x40, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33,
0x19, 0x8C, 0xE6, 0x7B, 0x88, 0x00, 0xFF, 0xF7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x70,
0xE1, 0x00, 0xF7, 0xC6, 0x77, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x3C, 0x40, 0x7D, 0xF1, 0x8E, 0x38,
0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0x70, 0x80, 0x73, 0xE9, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x70,
0xC3, 0x0C, 0x30, 0x26, 0xFF, 0xDB, 0xDB, 0xC3, 0xF3, 0x73, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x00, 0xFF, 0x17, 0xF7, 0xC0, 0x3F, 0xC0, 0x70, 0xE1, 0xF3, 0xE0, 0x7C, 0x7E, 0x7F, 0x7F,
0x01, 0xBE, 0xE2, 0x00, 0x7F, 0xF0, 0x27, 0xB6, 0xE0, 0x11, 0xF9, 0x80, 0x7C, 0xFF, 0xDB, 0xFF,
0xFF, 0xFF, 0xE7, 0x7E, 0x18, 0x3E, 0x3F, 0x98, 0xEC, 0x36, 0x1B, 0x1D, 0xDC, 0x7E, 0x08, 0x00,
0x3E, 0x3F, 0x98, 0xCC, 0x67, 0x33, 0x98, 0x1C, 0x3C, 0x08, 0x00, 0x60, 0x18, 0x06, 0xF9, 0xFF,
0x7B, 0xDF, 0x76, 0xDD, 0x87, 0x73, 0x8F, 0xC0, 0xC0, 0x3F, 0x3F, 0x9A, 0xEC, 0x76, 0x3B, 0x1D,
0x8E, 0xF7, 0x10, 0x00, 0x03, 0x01, 0x8F, 0xCF, 0xC6, 0x03, 0x39, 0x9C, 0xCC, 0x7F, 0x1F, 0xC0,
0x1F, 0x1B, 0x8F, 0xCF, 0xC6, 0x03, 0x39, 0x9C, 0xCC, 0x7F, 0x1F, 0xC0, 0xC0, 0xC0, 0xFE, 0x7E,
0x63, 0x03, 0x03, 0x03, 0x67, 0x7E, 0x08, 0x00, 0x60, 0x0C, 0xFD, 0xBF, 0xB6, 0xB6, 0xC6, 0xD8,
0xDB, 0x1B, 0x63, 0xEF, 0x78, 0x40, 0x00, 0x03, 0x01, 0x8F, 0xCF, 0xC6, 0x03, 0x09, 0x8E, 0xD3,
0x7F, 0x9F, 0x80, 0x80, 0x01, 0x81, 0xCF, 0xCF, 0xC6, 0xC3, 0x71, 0x98, 0xCC, 0x63, 0x3D, 0x84,
0x00, 0x32, 0x2F, 0x67, 0xC6, 0x7C, 0x67, 0xE7, 0xF7, 0xFF, 0x3F, 0x70, 0x67, 0x06, 0x70, 0x67,
0x00, 0x00, 0x78, 0x01, 0xFD, 0x0E, 0xFF, 0x1B, 0xFF, 0x7F, 0xEC, 0xF0, 0x00, 0xFF, 0xFF, 0xFF,
0xC0, 0x9F, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x77, 0xDE, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF,
0xFF, 0xFF, 0x7F, 0xFF, 0x6F, 0xEC, 0x7F, 0x68, 0x66, 0x6C, 0x00, 0x6D, 0xBF, 0xF6, 0xD8, 0x6F,
0xFD, 0xB6, 0x90, 0x6C, 0xD9, 0xB6, 0xC0, 0x80, 0x0F, 0xFF, 0xF0, 0x00, 0x1D, 0xCF, 0xB9, 0xA2,
0x20, 0x19, 0x9D, 0xC6, 0x18, 0x60, 0x43, 0x0C, 0x73, 0x31, 0x80, 0x00, 0x07, 0xE3, 0xF8, 0xC0,
0x30, 0x3F, 0xCF, 0xF1, 0xF8, 0xFE, 0x1C, 0x03, 0x00, 0xFE, 0x1F, 0x80, 0x80, 0x77, 0xDE,
};
static const EpdGlyph notosansthai_8_regularGlyphs[] = {
{ 0, 0, 0, 0, 0, 0, 0 }, //
{ 0, 0, 4, 0, 0, 0, 0 }, //
{ 0, 0, 4, 0, 0, 0, 0 }, //
{ 3, 13, 4, 1, 12, 5, 0 }, // !
{ 5, 5, 7, 1, 12, 4, 5 }, // "
{ 11, 12, 11, 0, 12, 17, 9 }, // #
{ 8, 14, 10, 1, 13, 14, 26 }, // $
{ 14, 14, 14, 0, 13, 25, 40 }, // %
{ 13, 14, 12, 0, 13, 23, 65 }, // &
{ 2, 5, 4, 1, 12, 2, 88 }, // '
{ 5, 15, 5, 0, 12, 10, 90 }, // (
{ 5, 15, 5, 0, 12, 10, 100 }, // )
{ 9, 8, 9, 0, 13, 9, 110 }, // *
{ 9, 9, 10, 0, 10, 11, 119 }, // +
{ 4, 5, 4, 0, 2, 3, 130 }, // ,
{ 5, 3, 5, 0, 6, 2, 133 }, // -
{ 3, 4, 4, 1, 3, 2, 135 }, // .
{ 7, 12, 6, 0, 12, 11, 137 }, // /
{ 9, 14, 10, 0, 13, 16, 148 }, // 0
{ 5, 12, 10, 1, 12, 8, 164 }, // 1
{ 9, 13, 10, 0, 13, 15, 172 }, // 2
{ 9, 14, 10, 0, 13, 16, 187 }, // 3
{ 10, 12, 10, 0, 12, 15, 203 }, // 4
{ 8, 13, 10, 1, 12, 13, 218 }, // 5
{ 9, 14, 10, 0, 13, 16, 231 }, // 6
{ 9, 12, 10, 0, 12, 14, 247 }, // 7
{ 9, 14, 10, 0, 13, 16, 261 }, // 8
{ 9, 14, 10, 0, 13, 16, 277 }, // 9
{ 3, 11, 4, 1, 10, 5, 293 }, // :
{ 4, 13, 4, 0, 10, 7, 298 }, // ;
{ 9, 10, 10, 0, 11, 12, 305 }, // <
{ 9, 6, 10, 0, 9, 7, 317 }, // =
{ 9, 10, 10, 0, 11, 12, 324 }, // >
{ 7, 14, 7, 0, 13, 13, 336 }, // ?
{ 15, 14, 15, 0, 12, 27, 349 }, // @
{ 11, 12, 11, 0, 12, 17, 376 }, // A
{ 9, 12, 11, 1, 12, 14, 393 }, // B
{ 10, 14, 11, 1, 13, 18, 407 }, // C
{ 11, 12, 12, 1, 12, 17, 425 }, // D
{ 8, 12, 9, 1, 12, 12, 442 }, // E
{ 8, 12, 9, 1, 12, 12, 454 }, // F
{ 10, 14, 12, 1, 13, 18, 466 }, // G
{ 10, 12, 12, 1, 12, 15, 484 }, // H
{ 5, 12, 6, 0, 12, 8, 499 }, // I
{ 6, 16, 5, -2, 12, 12, 507 }, // J
{ 10, 12, 10, 1, 12, 15, 519 }, // K
{ 8, 12, 9, 1, 12, 12, 534 }, // L
{ 13, 12, 15, 1, 12, 20, 546 }, // M
{ 11, 12, 13, 1, 12, 17, 566 }, // N
{ 11, 14, 13, 1, 13, 20, 583 }, // O
{ 9, 12, 10, 1, 12, 14, 603 }, // P
{ 11, 16, 13, 1, 13, 22, 617 }, // Q
{ 10, 12, 10, 1, 12, 15, 639 }, // R
{ 9, 14, 9, 0, 13, 16, 654 }, // S
{ 10, 12, 9, 0, 12, 15, 670 }, // T
{ 10, 13, 12, 1, 12, 17, 685 }, // U
{ 10, 12, 10, 0, 12, 15, 702 }, // V
{ 16, 12, 16, 0, 12, 24, 717 }, // W
{ 10, 12, 10, 0, 12, 15, 741 }, // X
{ 10, 12, 9, 0, 12, 15, 756 }, // Y
{ 9, 12, 10, 0, 12, 14, 771 }, // Z
{ 5, 15, 5, 1, 12, 10, 785 }, // [
{ 7, 12, 6, 0, 12, 11, 795 }, // <backslash>
{ 5, 15, 5, 0, 12, 10, 806 }, // ]
{ 9, 8, 10, 0, 12, 9, 816 }, // ^
{ 9, 2, 7, -1, -1, 3, 825 }, // _
{ 5, 3, 5, 0, 13, 2, 828 }, // `
{ 8, 11, 9, 0, 10, 11, 830 }, // a
{ 9, 14, 10, 1, 13, 16, 841 }, // b
{ 8, 11, 8, 0, 10, 11, 857 }, // c
{ 9, 14, 10, 0, 13, 16, 868 }, // d
{ 9, 11, 9, 0, 10, 13, 884 }, // e
{ 7, 13, 6, 0, 13, 12, 897 }, // f
{ 9, 14, 10, 0, 10, 16, 909 }, // g
{ 8, 13, 10, 1, 13, 13, 925 }, // h
{ 3, 13, 4, 1, 13, 5, 938 }, // i
{ 5, 17, 4, -1, 13, 11, 943 }, // j
{ 8, 13, 9, 1, 13, 13, 954 }, // k
{ 2, 13, 4, 1, 13, 4, 967 }, // l
{ 14, 10, 16, 1, 10, 18, 971 }, // m
{ 8, 10, 10, 1, 10, 10, 989 }, // n
{ 10, 11, 10, 0, 10, 14, 999 }, // o
{ 9, 14, 10, 1, 10, 16, 1013 }, // p
{ 9, 14, 10, 0, 10, 16, 1029 }, // q
{ 6, 10, 7, 1, 10, 8, 1045 }, // r
{ 8, 11, 8, 0, 10, 11, 1053 }, // s
{ 6, 12, 6, 0, 11, 9, 1064 }, // t
{ 8, 10, 10, 1, 9, 10, 1073 }, // u
{ 9, 9, 8, 0, 9, 11, 1083 }, // v
{ 13, 9, 13, 0, 9, 15, 1094 }, // w
{ 9, 9, 9, 0, 9, 11, 1109 }, // x
{ 9, 13, 9, 0, 9, 15, 1120 }, // y
{ 8, 9, 8, 0, 9, 9, 1135 }, // z
{ 6, 15, 6, 0, 12, 12, 1144 }, // {
{ 3, 18, 9, 3, 13, 7, 1156 }, // |
{ 6, 15, 6, 0, 12, 12, 1163 }, // }
{ 9, 3, 10, 0, 7, 4, 1175 }, // ~
{ 0, 0, 4, 0, 0, 0, 1179 }, //  
{ 3, 14, 4, 1, 10, 6, 1179 }, // ¡
{ 8, 14, 10, 1, 13, 14, 1185 }, // ¢
{ 9, 13, 10, 0, 13, 15, 1199 }, // £
{ 10, 12, 10, 0, 12, 15, 1214 }, // ¥
{ 8, 14, 9, 0, 13, 14, 1229 }, // §
{ 6, 3, 10, 2, 13, 3, 1243 }, // ¨
{ 14, 14, 14, 0, 13, 25, 1246 }, // ©
{ 6, 7, 6, 0, 13, 6, 1271 }, // ª
{ 8, 8, 8, 0, 8, 8, 1277 }, // «
{ 14, 14, 14, 0, 13, 25, 1285 }, // ®
{ 10, 2, 8, -1, 14, 3, 1310 }, // ¯
{ 7, 7, 7, 0, 13, 7, 1313 }, // °
{ 5, 3, 5, 0, 13, 2, 1320 }, // ´
{ 10, 16, 11, 0, 13, 20, 1322 }, // ¶
{ 3, 4, 4, 1, 8, 2, 1342 }, // ·
{ 4, 4, 4, 0, 0, 2, 1344 }, // ¸
{ 6, 7, 6, 0, 13, 6, 1346 }, // º
{ 8, 8, 8, 0, 8, 8, 1352 }, // »
{ 7, 14, 7, 0, 10, 13, 1360 }, // ¿
{ 11, 16, 11, 0, 16, 22, 1373 }, // À
{ 11, 16, 11, 0, 16, 22, 1395 }, // Á
{ 11, 16, 11, 0, 16, 22, 1417 }, // Â
{ 11, 16, 11, 0, 16, 22, 1439 }, // Ã
{ 11, 16, 11, 0, 16, 22, 1461 }, // Ä
{ 11, 15, 11, 0, 15, 21, 1483 }, // Å
{ 15, 12, 15, -1, 12, 23, 1504 }, // Æ
{ 10, 17, 11, 1, 13, 22, 1527 }, // Ç
{ 8, 16, 9, 1, 16, 16, 1549 }, // È
{ 8, 16, 9, 1, 16, 16, 1565 }, // É
{ 8, 16, 9, 1, 16, 16, 1581 }, // Ê
{ 8, 16, 9, 1, 16, 16, 1597 }, // Ë
{ 5, 16, 6, 0, 16, 10, 1613 }, // Ì
{ 6, 16, 6, 0, 16, 12, 1623 }, // Í
{ 6, 16, 6, 0, 16, 12, 1635 }, // Î
{ 6, 16, 6, 0, 16, 12, 1647 }, // Ï
{ 12, 12, 12, 0, 12, 18, 1659 }, // Ð
{ 11, 16, 13, 1, 16, 22, 1677 }, // Ñ
{ 11, 17, 13, 1, 16, 24, 1699 }, // Ò
{ 11, 17, 13, 1, 16, 24, 1723 }, // Ó
{ 11, 17, 13, 1, 16, 24, 1747 }, // Ô
{ 11, 17, 13, 1, 16, 24, 1771 }, // Õ
{ 11, 17, 13, 1, 16, 24, 1795 }, // Ö
{ 8, 8, 10, 1, 10, 8, 1819 }, // ×
{ 11, 14, 13, 1, 13, 20, 1827 }, // Ø
{ 10, 17, 12, 1, 16, 22, 1847 }, // Ù
{ 10, 17, 12, 1, 16, 22, 1869 }, // Ú
{ 10, 17, 12, 1, 16, 22, 1891 }, // Û
{ 10, 17, 12, 1, 16, 22, 1913 }, // Ü
{ 10, 16, 9, 0, 16, 20, 1935 }, // Ý
{ 9, 12, 10, 1, 12, 14, 1955 }, // Þ
{ 9, 14, 11, 1, 13, 16, 1969 }, // ß
{ 8, 14, 9, 0, 13, 14, 1985 }, // à
{ 8, 14, 9, 0, 13, 14, 1999 }, // á
{ 8, 14, 9, 0, 13, 14, 2013 }, // â
{ 8, 14, 9, 0, 13, 14, 2027 }, // ã
{ 8, 14, 9, 0, 13, 14, 2041 }, // ä
{ 8, 15, 9, 0, 14, 15, 2055 }, // å
{ 14, 11, 14, 0, 10, 20, 2070 }, // æ
{ 8, 14, 8, 0, 10, 14, 2090 }, // ç
{ 9, 14, 9, 0, 13, 16, 2104 }, // è
{ 9, 14, 9, 0, 13, 16, 2120 }, // é
{ 9, 14, 9, 0, 13, 16, 2136 }, // ê
{ 9, 14, 9, 0, 13, 16, 2152 }, // ë
{ 5, 13, 4, -1, 13, 9, 2168 }, // ì
{ 4, 13, 4, 1, 13, 7, 2177 }, // í
{ 6, 13, 4, -1, 13, 10, 2184 }, // î
{ 6, 13, 4, -1, 13, 10, 2194 }, // ï
{ 10, 14, 10, 0, 13, 18, 2204 }, // ð
{ 8, 13, 10, 1, 13, 13, 2222 }, // ñ
{ 10, 14, 10, 0, 13, 18, 2235 }, // ò
{ 10, 14, 10, 0, 13, 18, 2253 }, // ó
{ 10, 14, 10, 0, 13, 18, 2271 }, // ô
{ 10, 14, 10, 0, 13, 18, 2289 }, // õ
{ 10, 14, 10, 0, 13, 18, 2307 }, // ö
{ 9, 8, 10, 0, 10, 9, 2325 }, // ÷
{ 10, 11, 10, 0, 10, 14, 2334 }, // ø
{ 8, 14, 10, 1, 13, 14, 2348 }, // ù
{ 8, 14, 10, 1, 13, 14, 2362 }, // ú
{ 8, 14, 10, 1, 13, 14, 2376 }, // û
{ 8, 14, 10, 1, 13, 14, 2390 }, // ü
{ 9, 17, 9, 0, 13, 20, 2404 }, // ý
{ 9, 17, 10, 1, 13, 20, 2424 }, // þ
{ 9, 17, 9, 0, 13, 20, 2444 }, // ÿ
{ 11, 15, 11, 0, 15, 21, 2464 }, // Ā
{ 8, 13, 9, 0, 12, 13, 2485 }, // ā
{ 11, 16, 11, 0, 16, 22, 2498 }, // Ă
{ 8, 14, 9, 0, 13, 14, 2520 }, // ă
{ 11, 16, 11, 0, 12, 22, 2534 }, // Ą
{ 9, 14, 9, 0, 10, 16, 2556 }, // ą
{ 10, 17, 11, 1, 16, 22, 2572 }, // Ć
{ 8, 14, 8, 0, 13, 14, 2594 }, // ć
{ 10, 17, 11, 1, 16, 22, 2608 }, // Ċ
{ 8, 14, 8, 0, 13, 14, 2630 }, // ċ
{ 10, 17, 11, 1, 16, 22, 2644 }, // Č
{ 8, 14, 8, 0, 13, 14, 2666 }, // č
{ 11, 16, 12, 1, 16, 22, 2680 }, // Ď
{ 12, 14, 10, 0, 13, 21, 2702 }, // ď
{ 12, 12, 12, 0, 12, 18, 2723 }, // Đ
{ 11, 14, 10, 0, 13, 20, 2741 }, // đ
{ 8, 15, 9, 1, 15, 15, 2761 }, // Ē
{ 9, 13, 9, 0, 12, 15, 2776 }, // ē
{ 8, 16, 9, 1, 16, 16, 2791 }, // Ė
{ 9, 14, 9, 0, 13, 16, 2807 }, // ė
{ 8, 16, 9, 1, 12, 16, 2823 }, // Ę
{ 9, 14, 9, 0, 10, 16, 2839 }, // ę
{ 8, 16, 9, 1, 16, 16, 2855 }, // Ě
{ 9, 14, 9, 0, 13, 16, 2871 }, // ě
{ 10, 17, 12, 1, 16, 22, 2887 }, // Ğ
{ 9, 17, 10, 0, 13, 20, 2909 }, // ğ
{ 10, 17, 12, 1, 16, 22, 2929 }, // Ġ
{ 9, 17, 10, 0, 13, 20, 2951 }, // ġ
{ 10, 17, 12, 1, 13, 22, 2971 }, // Ģ
{ 9, 17, 10, 0, 13, 20, 2993 }, // ģ
{ 13, 12, 12, 0, 12, 20, 3013 }, // Ħ
{ 9, 13, 10, 0, 13, 15, 3033 }, // ħ
{ 6, 15, 6, 0, 15, 12, 3048 }, // Ī
{ 6, 12, 4, -1, 12, 9, 3060 }, // ī
{ 5, 16, 6, 0, 12, 10, 3069 }, // Į
{ 4, 17, 4, 0, 13, 9, 3079 }, // į
{ 5, 16, 6, 0, 16, 10, 3088 }, // İ
{ 2, 9, 4, 1, 9, 3, 3098 }, // ı
{ 10, 16, 10, 1, 12, 20, 3101 }, // Ķ
{ 8, 17, 9, 1, 13, 17, 3121 }, // ķ
{ 8, 16, 9, 1, 16, 16, 3138 }, // Ĺ
{ 4, 17, 4, 1, 17, 9, 3154 }, // ĺ
{ 8, 16, 9, 1, 12, 16, 3163 }, // Ļ
{ 3, 17, 4, 1, 13, 7, 3179 }, // ļ
{ 8, 12, 9, 1, 12, 12, 3186 }, // Ľ
{ 5, 13, 4, 1, 13, 9, 3198 }, // ľ
{ 9, 12, 9, 0, 12, 14, 3207 }, // Ł
{ 6, 13, 4, -1, 13, 10, 3221 }, // ł
{ 11, 16, 13, 1, 16, 22, 3231 }, // Ń
{ 8, 13, 10, 1, 13, 13, 3253 }, // ń
{ 11, 16, 13, 1, 12, 22, 3266 }, // Ņ
{ 8, 14, 10, 1, 10, 14, 3288 }, // ņ
{ 11, 16, 13, 1, 16, 22, 3302 }, // Ň
{ 8, 13, 10, 1, 13, 13, 3324 }, // ň
{ 11, 16, 13, 1, 12, 22, 3337 }, // Ŋ
{ 8, 14, 10, 1, 10, 14, 3359 }, // ŋ
{ 11, 16, 13, 1, 15, 22, 3373 }, // Ō
{ 10, 13, 10, 0, 12, 17, 3395 }, // ō
{ 11, 17, 13, 1, 16, 24, 3412 }, // Ő
{ 10, 14, 10, 0, 13, 18, 3436 }, // ő
{ 14, 14, 15, 1, 13, 25, 3454 }, // Œ
{ 15, 11, 16, 0, 10, 21, 3479 }, // œ
{ 10, 16, 10, 1, 16, 20, 3500 }, // Ŕ
{ 6, 13, 7, 1, 13, 10, 3520 }, // ŕ
{ 10, 16, 10, 1, 12, 20, 3530 }, // Ŗ
{ 6, 14, 7, 1, 10, 11, 3550 }, // ŗ
{ 10, 16, 10, 1, 16, 20, 3561 }, // Ř
{ 6, 13, 7, 1, 13, 10, 3581 }, // ř
{ 9, 17, 9, 0, 16, 20, 3591 }, // Ś
{ 8, 14, 8, 0, 13, 14, 3611 }, // ś
{ 9, 17, 9, 0, 13, 20, 3625 }, // Ş
{ 8, 14, 8, 0, 10, 14, 3645 }, // ş
{ 9, 17, 9, 0, 16, 20, 3659 }, // Š
{ 8, 14, 8, 0, 13, 14, 3679 }, // š
{ 10, 16, 9, 0, 16, 20, 3693 }, // Ť
{ 8, 14, 6, 0, 13, 14, 3713 }, // ť
{ 10, 16, 12, 1, 15, 20, 3727 }, // Ū
{ 8, 13, 10, 1, 12, 13, 3747 }, // ū
{ 10, 17, 12, 1, 16, 22, 3760 }, // Ŭ
{ 8, 14, 10, 1, 13, 14, 3782 }, // ŭ
{ 10, 18, 12, 1, 17, 23, 3796 }, // Ů
{ 8, 15, 10, 1, 14, 15, 3819 }, // ů
{ 10, 17, 12, 1, 16, 22, 3834 }, // Ű
{ 8, 14, 10, 1, 13, 14, 3856 }, // ű
{ 10, 16, 12, 1, 12, 20, 3870 }, // Ų
{ 9, 13, 10, 1, 9, 15, 3890 }, // ų
{ 16, 16, 16, 0, 16, 32, 3905 }, // Ŵ
{ 13, 13, 13, 0, 13, 22, 3937 }, // ŵ
{ 10, 16, 9, 0, 16, 20, 3959 }, // Ŷ
{ 9, 17, 9, 0, 13, 20, 3979 }, // ŷ
{ 10, 16, 9, 0, 16, 20, 3999 }, // Ÿ
{ 9, 16, 10, 0, 16, 18, 4019 }, // Ź
{ 8, 13, 8, 0, 13, 13, 4037 }, // ź
{ 9, 16, 10, 0, 16, 18, 4050 }, // Ż
{ 8, 13, 8, 0, 13, 13, 4068 }, // ż
{ 9, 16, 10, 0, 16, 18, 4081 }, // Ž
{ 8, 13, 8, 0, 13, 13, 4099 }, // ž
{ 5, 3, 0, -9, 13, 2, 4112 }, // ̀
{ 4, 3, 0, -6, 13, 2, 4114 }, // ́
{ 6, 3, 0, -3, 13, 3, 4116 }, // ̂
{ 6, 3, 0, -8, 13, 3, 4119 }, // ̃
{ 6, 2, 0, -3, 12, 2, 4122 }, // ̄
{ 6, 3, 0, -3, 13, 3, 4124 }, // ̆
{ 2, 3, 0, -1, 13, 1, 4127 }, // ̇
{ 6, 3, 0, -3, 13, 3, 4128 }, // ̈
{ 4, 4, 0, -2, 14, 2, 4131 }, // ̊
{ 7, 3, 0, -3, 13, 3, 4133 }, // ̋
{ 6, 3, 0, -3, 13, 3, 4136 }, // ̌
{ 4, 5, 0, -2, 12, 3, 4139 }, // ̒
{ 4, 3, 0, -2, -1, 2, 4142 }, // ̦
{ 4, 4, 0, -2, 0, 2, 4144 }, // ̧
{ 4, 5, 0, -2, 1, 3, 4146 }, // ̨
{ 5, 2, 0, -7, -1, 2, 4149 }, // ̱
{ 8, 10, 10, 1, 10, 10, 4151 }, // ก
{ 8, 11, 9, 0, 10, 11, 4161 }, // ข
{ 8, 11, 9, 0, 10, 11, 4172 }, // ฃ
{ 8, 10, 10, 1, 10, 10, 4183 }, // ค
{ 8, 10, 10, 1, 10, 10, 4193 }, // ฅ
{ 9, 11, 10, 0, 10, 13, 4203 }, // ฆ
{ 9, 10, 9, 0, 10, 12, 4216 }, // ง
{ 8, 10, 9, 0, 10, 10, 4228 }, // จ
{ 8, 11, 10, 1, 10, 11, 4238 }, // ฉ
{ 8, 11, 9, 0, 10, 11, 4249 }, // ช
{ 9, 11, 9, 0, 10, 13, 4260 }, // ซ
{ 13, 11, 15, 1, 10, 18, 4273 }, // ฌ
{ 13, 13, 15, 1, 10, 22, 4291 }, // ญ
{ 9, 14, 10, 0, 10, 16, 4313 }, // ฎ
{ 9, 14, 10, 0, 10, 16, 4329 }, // ฏ
{ 9, 14, 9, 0, 10, 16, 4345 }, // ฐ
{ 10, 10, 10, 0, 10, 13, 4361 }, // ฑ
{ 14, 11, 15, 1, 10, 20, 4374 }, // ฒ
{ 13, 11, 15, 1, 10, 18, 4394 }, // ณ
{ 8, 11, 10, 1, 10, 11, 4412 }, // ด
{ 9, 11, 11, 1, 10, 13, 4423 }, // ต
{ 8, 11, 10, 1, 10, 11, 4436 }, // ถ
{ 8, 10, 10, 1, 10, 10, 4447 }, // ท
{ 8, 11, 9, 1, 10, 11, 4457 }, // ธ
{ 8, 11, 10, 1, 10, 11, 4468 }, // น
{ 8, 11, 10, 1, 10, 11, 4479 }, // บ
{ 8, 14, 10, 1, 13, 14, 4490 }, // ป
{ 9, 10, 11, 1, 10, 12, 4504 }, // ผ
{ 9, 13, 11, 1, 13, 15, 4516 }, // ฝ
{ 11, 10, 12, 0, 10, 14, 4531 }, // พ
{ 12, 13, 11, 0, 13, 20, 4545 }, // ฟ
{ 9, 11, 10, 0, 10, 13, 4565 }, // ภ
{ 8, 11, 10, 1, 10, 11, 4578 }, // ม
{ 8, 11, 10, 1, 10, 11, 4589 }, // ย
{ 8, 11, 8, 0, 10, 11, 4600 }, // ร
{ 8, 14, 10, 1, 10, 14, 4611 }, // ฤ
{ 9, 11, 10, 0, 10, 13, 4625 }, // ล
{ 9, 14, 10, 0, 10, 16, 4638 }, // ฦ
{ 8, 11, 8, 0, 10, 11, 4654 }, // ว
{ 9, 10, 10, 1, 10, 12, 4665 }, // ศ
{ 10, 11, 11, 1, 10, 14, 4677 }, // ษ
{ 9, 11, 10, 0, 10, 13, 4691 }, // ส
{ 8, 10, 10, 1, 10, 10, 4704 }, // ห
{ 12, 12, 11, 0, 12, 18, 4714 }, // ฬ
{ 8, 11, 10, 1, 10, 11, 4732 }, // อ
{ 8, 11, 9, 1, 10, 11, 4743 }, // ฮ
{ 8, 10, 9, 0, 10, 10, 4754 }, // ฯ
{ 5, 8, 6, 0, 9, 5, 4764 }, // ะ
{ 7, 3, 0, -6, 13, 3, 4769 }, // ั
{ 6, 10, 7, 0, 10, 8, 4772 }, // า
{ 11, 14, 7, -5, 14, 20, 4780 }, // ำ
{ 8, 2, 0, -9, 12, 2, 4800 }, // ิ
{ 8, 4, 0, -9, 14, 4, 4802 }, // ี
{ 8, 4, 0, -9, 14, 4, 4806 }, // ึ
{ 8, 4, 0, -9, 14, 4, 4810 }, // ื
{ 3, 4, 0, -4, -1, 2, 4814 }, // ุ
{ 6, 4, 0, -7, -1, 3, 4816 }, // ู
{ 3, 3, 0, -4, -1, 2, 4819 }, // ฺ
{ 8, 14, 10, 1, 13, 14, 4821 }, // ฿
{ 4, 11, 5, 1, 10, 6, 4835 }, // เ
{ 9, 11, 9, 1, 10, 13, 4841 }, // แ
{ 6, 15, 5, 0, 14, 12, 4854 }, // โ
{ 5, 15, 5, 0, 14, 10, 4866 }, // ใ
{ 6, 15, 5, -1, 14, 12, 4876 }, // ไ
{ 6, 14, 7, 0, 10, 11, 4888 }, // ๅ
{ 8, 14, 10, 1, 10, 14, 4899 }, // ๆ
{ 7, 5, 0, -8, 15, 5, 4913 }, // ็
{ 2, 5, 0, -3, 15, 2, 4918 }, // ่
{ 7, 4, 0, -7, 14, 4, 4920 }, // ้
{ 8, 4, 0, -8, 14, 4, 4924 }, // ๊
{ 5, 5, 0, -6, 15, 4, 4928 }, // ๋
{ 5, 3, 0, -5, 13, 2, 4932 }, // ์
{ 5, 4, 0, -5, 14, 3, 4934 }, // ํ
{ 5, 4, 0, -5, 14, 3, 4937 }, // ๎
{ 8, 9, 10, 1, 8, 9, 4940 }, // ๏
{ 9, 9, 10, 0, 8, 11, 4949 }, //
{ 9, 9, 9, 0, 8, 11, 4960 }, // ๑
{ 10, 11, 10, 0, 10, 14, 4971 }, // ๒
{ 9, 9, 9, 0, 8, 11, 4985 }, // ๓
{ 9, 10, 9, 0, 10, 12, 4996 }, // ๔
{ 9, 10, 9, 0, 10, 12, 5008 }, // ๕
{ 8, 11, 9, 0, 10, 11, 5020 }, // ๖
{ 11, 11, 12, 0, 10, 16, 5031 }, // ๗
{ 9, 11, 9, 0, 10, 13, 5047 }, // ๘
{ 9, 11, 8, 0, 10, 13, 5060 }, // ๙
{ 12, 11, 13, 0, 10, 17, 5073 }, // ๚
{ 14, 6, 15, 0, 7, 11, 5090 }, // ๛
{ 0, 0, 0, 0, 0, 0, 5101 }, //
{ 2, 14, 0, -1, 11, 4, 5101 }, //
{ 4, 15, 0, -2, 12, 8, 5105 }, //
{ 5, 3, 5, 0, 6, 2, 5113 }, //
{ 8, 3, 8, 0, 6, 3, 5115 }, //
{ 16, 3, 17, 0, 6, 6, 5118 }, // —
{ 3, 5, 3, 0, 12, 2, 5124 }, //
{ 3, 5, 3, 0, 12, 2, 5126 }, //
{ 4, 5, 4, 0, 2, 3, 5128 }, //
{ 6, 5, 6, 0, 12, 4, 5131 }, // “
{ 6, 5, 6, 0, 12, 4, 5135 }, // ”
{ 7, 5, 7, 0, 2, 5, 5139 }, // „
{ 4, 5, 6, 1, 9, 3, 5144 }, // •
{ 11, 4, 13, 1, 3, 6, 5147 }, // …
{ 5, 8, 5, 0, 8, 5, 5153 }, //
{ 5, 8, 5, 0, 8, 5, 5158 }, //
{ 10, 14, 10, 0, 13, 18, 5163 }, // €
{ 5, 3, 5, 0, 6, 2, 5181 }, //
};
static const EpdUnicodeInterval notosansthai_8_regularIntervals[] = {
{ 0x0, 0x0, 0x0 },
{ 0xD, 0xD, 0x1 },
{ 0x20, 0x7E, 0x2 },
{ 0xA0, 0xA3, 0x61 },
{ 0xA5, 0xA5, 0x65 },
{ 0xA7, 0xAB, 0x66 },
{ 0xAE, 0xB0, 0x6B },
{ 0xB4, 0xB4, 0x6E },
{ 0xB6, 0xB8, 0x6F },
{ 0xBA, 0xBB, 0x72 },
{ 0xBF, 0xFF, 0x74 },
{ 0x100, 0x107, 0xB5 },
{ 0x10A, 0x113, 0xBD },
{ 0x116, 0x11B, 0xC7 },
{ 0x11E, 0x123, 0xCD },
{ 0x126, 0x127, 0xD3 },
{ 0x12A, 0x12B, 0xD5 },
{ 0x12E, 0x131, 0xD7 },
{ 0x136, 0x137, 0xDB },
{ 0x139, 0x13E, 0xDD },
{ 0x141, 0x148, 0xE3 },
{ 0x14A, 0x14D, 0xEB },
{ 0x150, 0x15B, 0xEF },
{ 0x15E, 0x161, 0xFB },
{ 0x164, 0x165, 0xFF },
{ 0x16A, 0x17E, 0x101 },
{ 0x300, 0x304, 0x116 },
{ 0x306, 0x308, 0x11B },
{ 0x30A, 0x30C, 0x11E },
{ 0x312, 0x312, 0x121 },
{ 0x326, 0x328, 0x122 },
{ 0x331, 0x331, 0x125 },
{ 0xE01, 0xE3A, 0x126 },
{ 0xE3F, 0xE5B, 0x160 },
{ 0x200B, 0x200D, 0x17D },
{ 0x2010, 0x2010, 0x180 },
{ 0x2013, 0x2014, 0x181 },
{ 0x2018, 0x201A, 0x183 },
{ 0x201C, 0x201E, 0x186 },
{ 0x2022, 0x2022, 0x189 },
{ 0x2026, 0x2026, 0x18A },
{ 0x2039, 0x203A, 0x18B },
{ 0x20AC, 0x20AC, 0x18D },
{ 0x2212, 0x2212, 0x18E },
};
static const EpdFontData notosansthai_8_regular = {
notosansthai_8_regularBitmaps,
notosansthai_8_regularGlyphs,
notosansthai_8_regularIntervals,
44,
25,
18,
-8,
false,
};

View File

@ -9,47 +9,60 @@ BOOKERLY_FONT_SIZES=(12 14 16 18)
NOTOSANS_FONT_SIZES=(12 14 16 18) NOTOSANS_FONT_SIZES=(12 14 16 18)
OPENDYSLEXIC_FONT_SIZES=(8 10 12 14) OPENDYSLEXIC_FONT_SIZES=(8 10 12 14)
for size in ${BOOKERLY_FONT_SIZES[@]}; do # for size in ${BOOKERLY_FONT_SIZES[@]}; do
for style in ${READER_FONT_STYLES[@]}; do # for style in ${READER_FONT_STYLES[@]}; do
font_name="bookerly_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')" # font_name="bookerly_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
font_path="../builtinFonts/source/Bookerly/Bookerly-${style}.ttf" # font_path="../builtinFonts/source/Bookerly/Bookerly-${style}.ttf"
output_path="../builtinFonts/${font_name}.h" # output_path="../builtinFonts/${font_name}.h"
python fontconvert.py $font_name $size $font_path --2bit > $output_path # python fontconvert.py $font_name $size $font_path --2bit > $output_path
echo "Generated $output_path" # echo "Generated $output_path"
done # done
done # done
for size in ${NOTOSANS_FONT_SIZES[@]}; do # for size in ${NOTOSANS_FONT_SIZES[@]}; do
for style in ${READER_FONT_STYLES[@]}; do # for style in ${READER_FONT_STYLES[@]}; do
font_name="notosans_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')" # font_name="notosans_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
font_path="../builtinFonts/source/NotoSans/NotoSans-${style}.ttf" # font_path="../builtinFonts/source/NotoSans/NotoSans-${style}.ttf"
output_path="../builtinFonts/${font_name}.h" # output_path="../builtinFonts/${font_name}.h"
python fontconvert.py $font_name $size $font_path --2bit > $output_path # python fontconvert.py $font_name $size $font_path --2bit > $output_path
echo "Generated $output_path" # echo "Generated $output_path"
done # done
done # done
for size in ${OPENDYSLEXIC_FONT_SIZES[@]}; do NOTOSANSTHAI_FONT_STYLES=("Regular")
for style in ${READER_FONT_STYLES[@]}; do NOTOSANSTHAI_FONT_SIZES=(8 10)
font_name="opendyslexic_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
font_path="../builtinFonts/source/OpenDyslexic/OpenDyslexic-${style}.otf"
output_path="../builtinFonts/${font_name}.h"
python fontconvert.py $font_name $size $font_path --2bit > $output_path
echo "Generated $output_path"
done
done
UI_FONT_SIZES=(10 12) for size in ${NOTOSANSTHAI_FONT_SIZES[@]}; do
UI_FONT_STYLES=("Regular" "Bold") for style in ${NOTOSANSTHAI_FONT_STYLES[@]}; do
font_name="notosansthai_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
for size in ${UI_FONT_SIZES[@]}; do font_path="../builtinFonts/source/NotoSansThai/NotoSansThai-${style}.ttf"
for style in ${UI_FONT_STYLES[@]}; do
font_name="ubuntu_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
font_path="../builtinFonts/source/Ubuntu/Ubuntu-${style}.ttf"
output_path="../builtinFonts/${font_name}.h" output_path="../builtinFonts/${font_name}.h"
python fontconvert.py $font_name $size $font_path > $output_path python fontconvert.py $font_name $size $font_path > $output_path
echo "Generated $output_path" echo "Generated $output_path"
done done
done done
python fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf > ../builtinFonts/notosans_8_regular.h # for size in ${OPENDYSLEXIC_FONT_SIZES[@]}; do
# for style in ${READER_FONT_STYLES[@]}; do
# font_name="opendyslexic_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
# font_path="../builtinFonts/source/OpenDyslexic/OpenDyslexic-${style}.otf"
# output_path="../builtinFonts/${font_name}.h"
# python fontconvert.py $font_name $size $font_path --2bit > $output_path
# echo "Generated $output_path"
# done
# done
# UI_FONT_SIZES=(10 12)
# UI_FONT_STYLES=("Regular" "Bold")
# for size in ${UI_FONT_SIZES[@]}; do
# for style in ${UI_FONT_STYLES[@]}; do
# font_name="ubuntu_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
# font_path="../builtinFonts/source/Ubuntu/Ubuntu-${style}.ttf"
# output_path="../builtinFonts/${font_name}.h"
# python fontconvert.py $font_name $size $font_path > $output_path
# echo "Generated $output_path"
# done
# done
# python fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf > ../builtinFonts/notosans_8_regular.h

View File

@ -1,3 +1,5 @@
#!python3 #!python3
import freetype import freetype
import zlib import zlib
@ -5,6 +7,8 @@ import sys
import re import re
import math import math
import argparse import argparse
import sys
sys.stdout.reconfigure(encoding="utf-8")
from collections import namedtuple from collections import namedtuple
# Originally from https://github.com/vroland/epdiy # Originally from https://github.com/vroland/epdiy
@ -99,6 +103,9 @@ intervals = [
# (0xFE30, 0xFE4F), # (0xFE30, 0xFE4F),
# # CJK Compatibility Ideographs # # CJK Compatibility Ideographs
# (0xF900, 0xFAFF), # (0xF900, 0xFAFF),
### Thai ###
# Thai script: consonants, vowels, tone marks, digits, and symbols
(0x0E00, 0x0E7F),
### Specials ### Specials
# Replacement Character # Replacement Character
(0xFFFD, 0xFFFD), (0xFFFD, 0xFFFD),

View File

@ -26,10 +26,37 @@ std::unique_ptr<PageLine> PageLine::deserialize(FsFile& file) {
} }
void Page::render(GfxRenderer& renderer, const int fontId, const int xOffset, const int yOffset) const { void Page::render(GfxRenderer& renderer, const int fontId, const int xOffset, const int yOffset) const {
size_t lineIdx = 0;
for (auto& element : elements) { for (auto& element : elements) {
element->render(renderer, fontId, xOffset, yOffset); element->render(renderer, fontId, xOffset, yOffset);
// After each line renders, validate ALL subsequent lines for corruption
// This helps identify which line's rendering corrupts future lines
size_t checkIdx = 0;
for (const auto& checkElement : elements) {
if (checkIdx > lineIdx) {
int corrupt = checkElement->validate("INTER_LINE_CHECK");
if (corrupt > 0) {
Serial.printf("[%lu] [PGE] !! CORRUPTION: Rendering line[%u] corrupted line[%u] (%d words)\n",
millis(), (uint32_t)lineIdx, (uint32_t)checkIdx, corrupt);
} }
} }
checkIdx++;
}
lineIdx++;
}
}
int Page::validate(const char* checkpoint) const {
int totalCorrupt = 0;
for (const auto& element : elements) {
totalCorrupt += element->validate(checkpoint);
}
if (totalCorrupt > 0) {
Serial.printf("[%lu] [PGE] Validation @ %s: %d corrupted words found\n", millis(), checkpoint, totalCorrupt);
}
return totalCorrupt;
}
bool Page::serialize(FsFile& file) const { bool Page::serialize(FsFile& file) const {
const uint16_t count = elements.size(); const uint16_t count = elements.size();

View File

@ -19,6 +19,7 @@ class PageElement {
virtual ~PageElement() = default; virtual ~PageElement() = default;
virtual void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) = 0; virtual void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) = 0;
virtual bool serialize(FsFile& file) = 0; virtual bool serialize(FsFile& file) = 0;
virtual int validate(const char* checkpoint) const { return 0; }
}; };
// a line from a block element // a line from a block element
@ -31,6 +32,7 @@ class PageLine final : public PageElement {
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override; void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override;
bool serialize(FsFile& file) override; bool serialize(FsFile& file) override;
static std::unique_ptr<PageLine> deserialize(FsFile& file); static std::unique_ptr<PageLine> deserialize(FsFile& file);
int validate(const char* checkpoint) const override { return block ? block->validateAllWords(checkpoint) : 0; }
}; };
class Page { class Page {
@ -40,4 +42,6 @@ class Page {
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const; void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const;
bool serialize(FsFile& file) const; bool serialize(FsFile& file) const;
static std::unique_ptr<Page> deserialize(FsFile& file); static std::unique_ptr<Page> deserialize(FsFile& file);
// Validate all elements for corruption, returns total corrupt word count
int validate(const char* checkpoint) const;
}; };

View File

@ -1,6 +1,7 @@
#include "ParsedText.h" #include "ParsedText.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <ThaiShaper.h>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -11,6 +12,29 @@
#include "hyphenation/Hyphenator.h" #include "hyphenation/Hyphenator.h"
// Debug: validate Thai UTF-8 strings for corruption
// Set to 1 to enable validation in addWord
#define PARSEDTEXT_THAI_VALIDATION 1
#if PARSEDTEXT_THAI_VALIDATION
#include <Arduino.h>
static bool checkThaiWordCorruption(const std::string& word, const char* context) {
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(word.data());
const uint8_t* end = ptr + word.size();
while (ptr + 3 <= end) {
if (*ptr == 0xE0 && (ptr[1] == 0x00 || ptr[2] == 0x00)) {
Serial.printf("[PTX] %s CORRUPT @ offset %u: %02X %02X %02X in word len=%u\n",
context, (uint32_t)(ptr - reinterpret_cast<const uint8_t*>(word.data())),
ptr[0], ptr[1], ptr[2], (uint32_t)word.size());
return true;
}
ptr++;
}
return false;
}
#endif
constexpr int MAX_COST = std::numeric_limits<int>::max(); constexpr int MAX_COST = std::numeric_limits<int>::max();
namespace { namespace {
@ -52,8 +76,48 @@ uint16_t measureWordWidth(const GfxRenderer& renderer, const int fontId, const s
void ParsedText::addWord(std::string word, const EpdFontFamily::Style fontStyle) { void ParsedText::addWord(std::string word, const EpdFontFamily::Style fontStyle) {
if (word.empty()) return; if (word.empty()) return;
#if PARSEDTEXT_THAI_VALIDATION
// Check input word BEFORE any processing
checkThaiWordCorruption(word, "ADDWORD_INPUT");
#endif
// Check if word contains Thai text that needs segmentation
if (ThaiShaper::containsThai(word.c_str())) {
#if PARSEDTEXT_THAI_VALIDATION
// Save a copy of the original input to detect if it gets corrupted during segmentation
std::string originalCopy = word;
#endif
// Segment Thai text into individual words for proper line breaking
auto segmentedWords = ThaiShaper::ThaiWordBreak::segmentWords(word.c_str());
#if PARSEDTEXT_THAI_VALIDATION
// Check if the ORIGINAL INPUT was corrupted during segmentation
if (word != originalCopy) {
Serial.printf("[PTX] !! ORIGINAL_CORRUPTED during segmentWords! len=%u\n", (uint32_t)word.size());
checkThaiWordCorruption(word, "ORIGINAL_AFTER_SEG");
}
#endif
bool isFirst = true;
for (auto& segment : segmentedWords) {
if (!segment.empty()) {
#if PARSEDTEXT_THAI_VALIDATION
// Check each segment AFTER Thai segmentation
checkThaiWordCorruption(segment, "AFTER_SEGMENT");
#endif
words.push_back(std::move(segment));
wordStyles.push_back(fontStyle);
wordNoSpaceBefore.push_back(!isFirst); // No space before Thai cluster continuations
isFirst = false;
}
}
return;
}
words.push_back(std::move(word)); words.push_back(std::move(word));
wordStyles.push_back(fontStyle); wordStyles.push_back(fontStyle);
wordNoSpaceBefore.push_back(false); // Normal words have space before
} }
// Consumes data to minimize memory usage // Consumes data to minimize memory usage
@ -120,6 +184,9 @@ std::vector<size_t> ParsedText::computeLineBreaks(const GfxRenderer& renderer, c
const size_t totalWordCount = words.size(); const size_t totalWordCount = words.size();
// Create vector copy of wordNoSpaceBefore for efficient random access
std::vector<bool> noSpaceBeforeVec(wordNoSpaceBefore.begin(), wordNoSpaceBefore.end());
// DP table to store the minimum badness (cost) of lines starting at index i // DP table to store the minimum badness (cost) of lines starting at index i
std::vector<int> dp(totalWordCount); std::vector<int> dp(totalWordCount);
// 'ans[i]' stores the index 'j' of the *last word* in the optimal line starting at 'i' // 'ans[i]' stores the index 'j' of the *last word* in the optimal line starting at 'i'
@ -130,12 +197,13 @@ std::vector<size_t> ParsedText::computeLineBreaks(const GfxRenderer& renderer, c
ans[totalWordCount - 1] = totalWordCount - 1; ans[totalWordCount - 1] = totalWordCount - 1;
for (int i = totalWordCount - 2; i >= 0; --i) { for (int i = totalWordCount - 2; i >= 0; --i) {
int currlen = -spaceWidth; int currlen = 0;
dp[i] = MAX_COST; dp[i] = MAX_COST;
for (size_t j = i; j < totalWordCount; ++j) { for (size_t j = i; j < totalWordCount; ++j) {
// Current line length: previous width + space + current word width // Current line length: previous width + space (if applicable) + current word width
currlen += wordWidths[j] + spaceWidth; const int thisSpacing = (j == static_cast<size_t>(i) || noSpaceBeforeVec[j]) ? 0 : spaceWidth;
currlen += wordWidths[j] + thisSpacing;
if (currlen > pageWidth) { if (currlen > pageWidth) {
break; break;
@ -212,6 +280,9 @@ std::vector<size_t> ParsedText::computeHyphenatedLineBreaks(const GfxRenderer& r
std::vector<size_t> lineBreakIndices; std::vector<size_t> lineBreakIndices;
size_t currentIndex = 0; size_t currentIndex = 0;
// Create vector copy of wordNoSpaceBefore for efficient random access
std::vector<bool> noSpaceBeforeVec(wordNoSpaceBefore.begin(), wordNoSpaceBefore.end());
while (currentIndex < wordWidths.size()) { while (currentIndex < wordWidths.size()) {
const size_t lineStart = currentIndex; const size_t lineStart = currentIndex;
int lineWidth = 0; int lineWidth = 0;
@ -219,7 +290,7 @@ std::vector<size_t> ParsedText::computeHyphenatedLineBreaks(const GfxRenderer& r
// Consume as many words as possible for current line, splitting when prefixes fit // Consume as many words as possible for current line, splitting when prefixes fit
while (currentIndex < wordWidths.size()) { while (currentIndex < wordWidths.size()) {
const bool isFirstWord = currentIndex == lineStart; const bool isFirstWord = currentIndex == lineStart;
const int spacing = isFirstWord ? 0 : spaceWidth; const int spacing = (isFirstWord || noSpaceBeforeVec[currentIndex]) ? 0 : spaceWidth;
const int candidateWidth = spacing + wordWidths[currentIndex]; const int candidateWidth = spacing + wordWidths[currentIndex];
// Word fits on current line // Word fits on current line
@ -236,6 +307,8 @@ std::vector<size_t> ParsedText::computeHyphenatedLineBreaks(const GfxRenderer& r
if (availableWidth > 0 && if (availableWidth > 0 &&
hyphenateWordAtIndex(currentIndex, availableWidth, renderer, fontId, wordWidths, allowFallbackBreaks)) { hyphenateWordAtIndex(currentIndex, availableWidth, renderer, fontId, wordWidths, allowFallbackBreaks)) {
// Prefix now fits; append it to this line and move to next line // Prefix now fits; append it to this line and move to next line
// Also update noSpaceBeforeVec to match the inserted word
noSpaceBeforeVec.insert(noSpaceBeforeVec.begin() + currentIndex + 1, false);
lineWidth += spacing + wordWidths[currentIndex]; lineWidth += spacing + wordWidths[currentIndex];
++currentIndex; ++currentIndex;
break; break;
@ -265,11 +338,13 @@ bool ParsedText::hyphenateWordAtIndex(const size_t wordIndex, const int availabl
return false; return false;
} }
// Get iterators to target word and style. // Get iterators to target word, style, and no-space flag.
auto wordIt = words.begin(); auto wordIt = words.begin();
auto styleIt = wordStyles.begin(); auto styleIt = wordStyles.begin();
auto noSpaceIt = wordNoSpaceBefore.begin();
std::advance(wordIt, wordIndex); std::advance(wordIt, wordIndex);
std::advance(styleIt, wordIndex); std::advance(styleIt, wordIndex);
std::advance(noSpaceIt, wordIndex);
const std::string& word = *wordIt; const std::string& word = *wordIt;
const auto style = *styleIt; const auto style = *styleIt;
@ -314,11 +389,13 @@ bool ParsedText::hyphenateWordAtIndex(const size_t wordIndex, const int availabl
wordIt->push_back('-'); wordIt->push_back('-');
} }
// Insert the remainder word (with matching style) directly after the prefix. // Insert the remainder word (with matching style and no-space flag) directly after the prefix.
auto insertWordIt = std::next(wordIt); auto insertWordIt = std::next(wordIt);
auto insertStyleIt = std::next(styleIt); auto insertStyleIt = std::next(styleIt);
auto insertNoSpaceIt = std::next(noSpaceIt);
words.insert(insertWordIt, remainder); words.insert(insertWordIt, remainder);
wordStyles.insert(insertStyleIt, style); wordStyles.insert(insertStyleIt, style);
wordNoSpaceBefore.insert(insertNoSpaceIt, false); // Remainder is a normal word (will be first on next line)
// Update cached widths to reflect the new prefix/remainder pairing. // Update cached widths to reflect the new prefix/remainder pairing.
wordWidths[wordIndex] = static_cast<uint16_t>(chosenWidth); wordWidths[wordIndex] = static_cast<uint16_t>(chosenWidth);
@ -340,43 +417,62 @@ void ParsedText::extractLine(const size_t breakIndex, const int pageWidth, const
lineWordWidthSum += wordWidths[i]; lineWordWidthSum += wordWidths[i];
} }
// Count actual word gaps (excluding no-space words) for justified spacing
auto noSpaceIt = wordNoSpaceBefore.begin();
std::advance(noSpaceIt, lastBreakAt);
size_t actualWordGaps = 0;
for (size_t i = lastBreakAt; i < lineBreak; i++) {
if (i > lastBreakAt && !*noSpaceIt) {
actualWordGaps++;
}
++noSpaceIt;
}
// Calculate spacing // Calculate spacing
const int spareSpace = pageWidth - lineWordWidthSum; const int spareSpace = pageWidth - lineWordWidthSum;
int spacing = spaceWidth; int spacing = spaceWidth;
const bool isLastLine = breakIndex == lineBreakIndices.size() - 1; const bool isLastLine = breakIndex == lineBreakIndices.size() - 1;
if (style == TextBlock::JUSTIFIED && !isLastLine && lineWordCount >= 2) { if (style == TextBlock::JUSTIFIED && !isLastLine && actualWordGaps >= 1) {
spacing = spareSpace / (lineWordCount - 1); spacing = spareSpace / actualWordGaps;
} }
// Calculate initial x position // Calculate initial x position (for right/center align, use actual word gaps)
uint16_t xpos = 0; uint16_t xpos = 0;
if (style == TextBlock::RIGHT_ALIGN) { if (style == TextBlock::RIGHT_ALIGN) {
xpos = spareSpace - (lineWordCount - 1) * spaceWidth; xpos = spareSpace - actualWordGaps * spaceWidth;
} else if (style == TextBlock::CENTER_ALIGN) { } else if (style == TextBlock::CENTER_ALIGN) {
xpos = (spareSpace - (lineWordCount - 1) * spaceWidth) / 2; xpos = (spareSpace - actualWordGaps * spaceWidth) / 2;
} }
// Pre-calculate X positions for words // Pre-calculate X positions for words, skipping spacing for no-space words
std::list<uint16_t> lineXPos; std::list<uint16_t> lineXPos;
noSpaceIt = wordNoSpaceBefore.begin();
std::advance(noSpaceIt, lastBreakAt);
for (size_t i = lastBreakAt; i < lineBreak; i++) { for (size_t i = lastBreakAt; i < lineBreak; i++) {
const uint16_t currentWordWidth = wordWidths[i]; const uint16_t currentWordWidth = wordWidths[i];
lineXPos.push_back(xpos); lineXPos.push_back(xpos);
xpos += currentWordWidth + spacing; const bool skipSpacing = (i == lastBreakAt) || *noSpaceIt;
xpos += currentWordWidth + (skipSpacing ? 0 : spacing);
++noSpaceIt;
} }
// Iterators always start at the beginning as we are moving content with splice below // Iterators always start at the beginning as we are moving content with splice below
auto wordEndIt = words.begin(); auto wordEndIt = words.begin();
auto wordStyleEndIt = wordStyles.begin(); auto wordStyleEndIt = wordStyles.begin();
auto noSpaceEndIt = wordNoSpaceBefore.begin();
std::advance(wordEndIt, lineWordCount); std::advance(wordEndIt, lineWordCount);
std::advance(wordStyleEndIt, lineWordCount); std::advance(wordStyleEndIt, lineWordCount);
std::advance(noSpaceEndIt, lineWordCount);
// *** CRITICAL STEP: CONSUME DATA USING SPLICE *** // *** CRITICAL STEP: CONSUME DATA USING SPLICE ***
std::list<std::string> lineWords; std::list<std::string> lineWords;
lineWords.splice(lineWords.begin(), words, words.begin(), wordEndIt); lineWords.splice(lineWords.begin(), words, words.begin(), wordEndIt);
std::list<EpdFontFamily::Style> lineWordStyles; std::list<EpdFontFamily::Style> lineWordStyles;
lineWordStyles.splice(lineWordStyles.begin(), wordStyles, wordStyles.begin(), wordStyleEndIt); lineWordStyles.splice(lineWordStyles.begin(), wordStyles, wordStyles.begin(), wordStyleEndIt);
std::list<bool> lineNoSpaceBefore;
lineNoSpaceBefore.splice(lineNoSpaceBefore.begin(), wordNoSpaceBefore, wordNoSpaceBefore.begin(), noSpaceEndIt);
for (auto& word : lineWords) { for (auto& word : lineWords) {
if (containsSoftHyphen(word)) { if (containsSoftHyphen(word)) {
@ -384,5 +480,12 @@ void ParsedText::extractLine(const size_t breakIndex, const int pageWidth, const
} }
} }
#if PARSEDTEXT_THAI_VALIDATION
// Check all words just before TextBlock creation
for (const auto& word : lineWords) {
checkThaiWordCorruption(word, "BEFORE_TEXTBLOCK");
}
#endif
processLine(std::make_shared<TextBlock>(std::move(lineWords), std::move(lineXPos), std::move(lineWordStyles), style)); processLine(std::make_shared<TextBlock>(std::move(lineWords), std::move(lineXPos), std::move(lineWordStyles), style));
} }

View File

@ -15,6 +15,7 @@ class GfxRenderer;
class ParsedText { class ParsedText {
std::list<std::string> words; std::list<std::string> words;
std::list<EpdFontFamily::Style> wordStyles; std::list<EpdFontFamily::Style> wordStyles;
std::list<bool> wordNoSpaceBefore; // true = no space before this word (Thai cluster continuations)
TextBlock::Style style; TextBlock::Style style;
bool extraParagraphSpacing; bool extraParagraphSpacing;
bool hyphenationEnabled; bool hyphenationEnabled;

View File

@ -240,5 +240,11 @@ std::unique_ptr<Page> Section::loadPageFromSectionFile() {
auto page = Page::deserialize(file); auto page = Page::deserialize(file);
file.close(); file.close();
// Validate immediately after deserialization, before file handle is released
if (page) {
page->validate("AFTER_DESERIALIZE");
}
return page; return page;
} }

View File

@ -2,6 +2,43 @@
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <Serialization.h> #include <Serialization.h>
#include <Utf8.h>
// Debug logging for Thai rendering investigation
// Set to 1 to enable verbose TextBlock render logging
#define TEXTBLOCK_DEBUG_LOGGING 0
// Validates a UTF-8 string for proper encoding
// Returns true if valid, false if corruption detected
static bool validateUtf8String(const std::string& str) {
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(str.data());
const uint8_t* end = ptr + str.size();
while (ptr < end) {
if (*ptr == 0) {
// Null byte in middle of string indicates corruption
return false;
}
int bytes = utf8CodepointLen(*ptr);
// Check we have enough bytes remaining
if (ptr + bytes > end) {
return false;
}
// Validate continuation bytes
for (int i = 1; i < bytes; i++) {
if ((ptr[i] & 0xC0) != 0x80) {
return false;
}
}
ptr += bytes;
}
return true;
}
void TextBlock::render(const GfxRenderer& renderer, const int fontId, const int x, const int y) const { void TextBlock::render(const GfxRenderer& renderer, const int fontId, const int x, const int y) const {
// Validate iterator bounds before rendering // Validate iterator bounds before rendering
@ -43,6 +80,25 @@ bool TextBlock::serialize(FsFile& file) const {
return true; return true;
} }
int TextBlock::validateAllWords(const char* checkpoint) const {
int corruptCount = 0;
size_t idx = 0;
for (const auto& word : words) {
if (!validateUtf8String(word)) {
corruptCount++;
Serial.printf("[%lu] [TXB] CORRUPT @ %s word[%u] len=%u bytes: ", millis(), checkpoint, (uint32_t)idx,
(uint32_t)word.size());
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(word.data());
for (size_t j = 0; j < word.size() && j < 16; j++) {
Serial.printf("%02X ", bytes[j]);
}
Serial.printf("\n");
}
idx++;
}
return corruptCount;
}
std::unique_ptr<TextBlock> TextBlock::deserialize(FsFile& file) { std::unique_ptr<TextBlock> TextBlock::deserialize(FsFile& file) {
uint16_t wc; uint16_t wc;
std::list<std::string> words; std::list<std::string> words;
@ -63,7 +119,23 @@ std::unique_ptr<TextBlock> TextBlock::deserialize(FsFile& file) {
words.resize(wc); words.resize(wc);
wordXpos.resize(wc); wordXpos.resize(wc);
wordStyles.resize(wc); wordStyles.resize(wc);
for (auto& w : words) serialization::readString(file, w); size_t wordIdx = 0;
for (auto& w : words) {
serialization::readString(file, w);
#if TEXTBLOCK_DEBUG_LOGGING
// Check for corruption immediately after deserialization
if (!validateUtf8String(w)) {
Serial.printf("[%lu] [TXB] !! CORRUPT ON DESERIALIZE word[%u] len=%u, bytes: ",
millis(), (uint32_t)wordIdx, (uint32_t)w.size());
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(w.data());
for (size_t j = 0; j < w.size() && j < 16; j++) {
Serial.printf("%02X ", bytes[j]);
}
Serial.printf("\n");
}
#endif
wordIdx++;
}
for (auto& x : wordXpos) serialization::readPod(file, x); for (auto& x : wordXpos) serialization::readPod(file, x);
for (auto& s : wordStyles) serialization::readPod(file, s); for (auto& s : wordStyles) serialization::readPod(file, s);

View File

@ -38,4 +38,6 @@ class TextBlock final : public Block {
BlockType getType() override { return TEXT_BLOCK; } BlockType getType() override { return TEXT_BLOCK; }
bool serialize(FsFile& file) const; bool serialize(FsFile& file) const;
static std::unique_ptr<TextBlock> deserialize(FsFile& file); static std::unique_ptr<TextBlock> deserialize(FsFile& file);
// Validate all words for UTF-8 corruption, returns number of corrupted words
int validateAllWords(const char* checkpoint) const;
}; };

View File

@ -30,6 +30,42 @@ constexpr int NUM_SKIP_TAGS = sizeof(SKIP_TAGS) / sizeof(SKIP_TAGS[0]);
bool isWhitespace(const char c) { return c == ' ' || c == '\r' || c == '\n' || c == '\t'; } bool isWhitespace(const char c) { return c == ' ' || c == '\r' || c == '\n' || c == '\t'; }
// Returns number of bytes forming incomplete UTF-8 at buffer end (0 if complete)
static int incompleteUtf8Tail(const char* buf, int len) {
if (len == 0) return 0;
for (int i = 1; i <= 3 && i <= len; i++) {
uint8_t c = buf[len - i];
if ((c & 0x80) == 0) return 0; // ASCII - complete
if ((c & 0xE0) == 0xC0) return (i < 2) ? i : 0; // 2-byte start
if ((c & 0xF0) == 0xE0) return (i < 3) ? i : 0; // 3-byte start (Thai)
if ((c & 0xF8) == 0xF0) return (i < 4) ? i : 0; // 4-byte start
if ((c & 0xC0) == 0x80) continue; // Continuation byte
}
return 0;
}
// Flush partWordBuffer, preserving incomplete UTF-8 for next callback
void ChapterHtmlSlimParser::flushPartWordBuffer(ChapterHtmlSlimParser* self, EpdFontFamily::Style fontStyle) {
if (self->partWordBufferIndex == 0) return;
int incomplete = incompleteUtf8Tail(self->partWordBuffer, self->partWordBufferIndex);
if (incomplete > 0 && incomplete < self->partWordBufferIndex) {
char saved[4];
memcpy(saved, self->partWordBuffer + self->partWordBufferIndex - incomplete, incomplete);
self->partWordBufferIndex -= incomplete;
self->partWordBuffer[self->partWordBufferIndex] = '\0';
if (self->partWordBufferIndex > 0) {
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
}
memcpy(self->partWordBuffer, saved, incomplete);
self->partWordBufferIndex = incomplete;
} else {
self->partWordBuffer[self->partWordBufferIndex] = '\0';
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
self->partWordBufferIndex = 0;
}
}
// given the start and end of a tag, check to see if it matches a known tag // given the start and end of a tag, check to see if it matches a known tag
bool matches(const char* tag_name, const char* possible_tags[], const int possible_tag_count) { bool matches(const char* tag_name, const char* possible_tags[], const int possible_tag_count) {
for (int i = 0; i < possible_tag_count; i++) { for (int i = 0; i < possible_tag_count; i++) {
@ -161,11 +197,7 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (isWhitespace(s[i])) { if (isWhitespace(s[i])) {
// Currently looking at whitespace, if there's anything in the partWordBuffer, flush it // Currently looking at whitespace, if there's anything in the partWordBuffer, flush it
if (self->partWordBufferIndex > 0) { flushPartWordBuffer(self, fontStyle);
self->partWordBuffer[self->partWordBufferIndex] = '\0';
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
self->partWordBufferIndex = 0;
}
// Skip the whitespace char // Skip the whitespace char
continue; continue;
} }
@ -186,9 +218,7 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
// If we're about to run out of space, then cut the word off and start a new one // If we're about to run out of space, then cut the word off and start a new one
if (self->partWordBufferIndex >= MAX_WORD_SIZE) { if (self->partWordBufferIndex >= MAX_WORD_SIZE) {
self->partWordBuffer[self->partWordBufferIndex] = '\0'; flushPartWordBuffer(self, fontStyle);
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
self->partWordBufferIndex = 0;
} }
self->partWordBuffer[self->partWordBufferIndex++] = s[i]; self->partWordBuffer[self->partWordBufferIndex++] = s[i];
@ -228,9 +258,7 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n
fontStyle = EpdFontFamily::ITALIC; fontStyle = EpdFontFamily::ITALIC;
} }
self->partWordBuffer[self->partWordBufferIndex] = '\0'; flushPartWordBuffer(self, fontStyle);
self->currentTextBlock->addWord(self->partWordBuffer, fontStyle);
self->partWordBufferIndex = 0;
} }
} }

View File

@ -40,6 +40,8 @@ class ChapterHtmlSlimParser {
void startNewTextBlock(TextBlock::Style style); void startNewTextBlock(TextBlock::Style style);
void makePages(); void makePages();
// Helper to flush partWordBuffer while preserving incomplete UTF-8 sequences
static void flushPartWordBuffer(ChapterHtmlSlimParser* self, EpdFontFamily::Style fontStyle);
// XML callbacks // XML callbacks
static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts); static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL characterData(void* userData, const XML_Char* s, int len); static void XMLCALL characterData(void* userData, const XML_Char* s, int len);

View File

@ -1,7 +1,12 @@
#include "GfxRenderer.h" #include "GfxRenderer.h"
#include <ThaiShaper.h>
#include <Utf8.h> #include <Utf8.h>
// Debug logging for Thai rendering investigation
// Set to 1 to enable verbose Thai rendering logging
#define THAI_RENDER_DEBUG_LOGGING 0
void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); } void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); }
void GfxRenderer::rotateCoordinates(const int x, const int y, int* rotatedX, int* rotatedY) const { void GfxRenderer::rotateCoordinates(const int x, const int y, int* rotatedX, int* rotatedY) const {
@ -72,11 +77,44 @@ int GfxRenderer::getTextWidth(const int fontId, const char* text, const EpdFontF
return 0; return 0;
} }
// Check if text contains Thai - use cluster-based width calculation
if (text != nullptr && ThaiShaper::containsThai(text)) {
return getThaiTextWidth(fontId, text, style);
}
int w = 0, h = 0; int w = 0, h = 0;
fontMap.at(fontId).getTextDimensions(text, &w, &h, style); fontMap.at(fontId).getTextDimensions(text, &w, &h, style);
return w; return w;
} }
int GfxRenderer::getThaiTextWidth(const int fontId, const char* text, const EpdFontFamily::Style style) const {
if (text == nullptr || *text == '\0') {
return 0;
}
const auto& font = fontMap.at(fontId);
int totalWidth = 0;
// Build clusters and sum their widths
auto clusters = ThaiShaper::ThaiClusterBuilder::buildClusters(text);
for (const auto& cluster : clusters) {
for (const auto& glyph : cluster.glyphs) {
if (!glyph.zeroAdvance) {
const EpdGlyph* glyphData = font.getGlyph(glyph.codepoint, style);
if (!glyphData) {
glyphData = font.getGlyph(REPLACEMENT_GLYPH, style);
}
if (glyphData) {
totalWidth += glyphData->advanceX;
}
}
}
}
return totalWidth;
}
void GfxRenderer::drawCenteredText(const int fontId, const int y, const char* text, const bool black, void GfxRenderer::drawCenteredText(const int fontId, const int y, const char* text, const bool black,
const EpdFontFamily::Style style) const { const EpdFontFamily::Style style) const {
const int x = (getScreenWidth() - getTextWidth(fontId, text, style)) / 2; const int x = (getScreenWidth() - getTextWidth(fontId, text, style)) / 2;
@ -85,9 +123,6 @@ void GfxRenderer::drawCenteredText(const int fontId, const int y, const char* te
void GfxRenderer::drawText(const int fontId, const int x, const int y, const char* text, const bool black, void GfxRenderer::drawText(const int fontId, const int x, const int y, const char* text, const bool black,
const EpdFontFamily::Style style) const { const EpdFontFamily::Style style) const {
const int yPos = y + getFontAscenderSize(fontId);
int xpos = x;
// cannot draw a NULL / empty string // cannot draw a NULL / empty string
if (text == nullptr || *text == '\0') { if (text == nullptr || *text == '\0') {
return; return;
@ -104,6 +139,16 @@ void GfxRenderer::drawText(const int fontId, const int x, const int y, const cha
return; return;
} }
// Check if text contains Thai script - use Thai rendering path if so
if (ThaiShaper::containsThai(text)) {
drawThaiText(fontId, x, y, text, black, style);
return;
}
// Standard rendering path for non-Thai text
const int yPos = y + getFontAscenderSize(fontId);
int xpos = x;
uint32_t cp; uint32_t cp;
while ((cp = utf8NextCodepoint(reinterpret_cast<const uint8_t**>(&text)))) { while ((cp = utf8NextCodepoint(reinterpret_cast<const uint8_t**>(&text)))) {
renderChar(font, cp, &xpos, &yPos, black, style); renderChar(font, cp, &xpos, &yPos, black, style);
@ -819,6 +864,140 @@ void GfxRenderer::renderChar(const EpdFontFamily& fontFamily, const uint32_t cp,
*x += glyph->advanceX; *x += glyph->advanceX;
} }
void GfxRenderer::drawThaiText(const int fontId, const int x, const int y, const char* text, const bool black,
const EpdFontFamily::Style style) const {
const int yPos = y + getFontAscenderSize(fontId);
int xpos = x;
const auto font = fontMap.at(fontId);
#if THAI_RENDER_DEBUG_LOGGING
Serial.printf("[GFX-THAI] drawThaiText at (%d,%d), text bytes: ", x, y);
const uint8_t* dbgPtr = reinterpret_cast<const uint8_t*>(text);
for (int i = 0; i < 32 && dbgPtr[i] != '\0'; i++) {
Serial.printf("%02X ", dbgPtr[i]);
}
Serial.printf("\n");
#endif
// Build Thai clusters from the text
auto clusters = ThaiShaper::ThaiClusterBuilder::buildClusters(text);
#if THAI_RENDER_DEBUG_LOGGING
Serial.printf("[GFX-THAI] Rendering %zu clusters\n", clusters.size());
#endif
// Render each cluster
for (const auto& cluster : clusters) {
renderThaiCluster(font, cluster, &xpos, yPos, black, style);
}
}
void GfxRenderer::renderThaiCluster(const EpdFontFamily& fontFamily, const ThaiShaper::ThaiCluster& cluster, int* x,
const int y, const bool pixelState, const EpdFontFamily::Style style) const {
const EpdFontData* fontData = fontFamily.getData(style);
if (!fontData) {
return;
}
// Calculate scale factor for y-offsets based on font size
// Thai offset values are designed for typical font metrics
const int fontHeight = fontData->advanceY;
const float yScale = fontHeight / 16.0f; // Normalize to ~16pt reference
// Track the maximum advance for this cluster (for non-combining glyphs)
int clusterAdvance = 0;
int baseX = *x; // Store base position for combining marks
#if THAI_RENDER_DEBUG_LOGGING
Serial.printf("[GFX-THAI] renderThaiCluster at x=%d, %zu glyphs: ", *x, cluster.glyphs.size());
for (const auto& g : cluster.glyphs) {
Serial.printf("U+%04X ", g.codepoint);
}
Serial.printf("\n");
#endif
for (const auto& glyph : cluster.glyphs) {
const EpdGlyph* glyphData = fontFamily.getGlyph(glyph.codepoint, style);
#if THAI_RENDER_DEBUG_LOGGING
Serial.printf("[GFX-THAI] Glyph U+%04X -> glyphData=%p\n", glyph.codepoint, (void*)glyphData);
#endif
if (!glyphData) {
glyphData = fontFamily.getGlyph(REPLACEMENT_GLYPH, style);
#if THAI_RENDER_DEBUG_LOGGING
Serial.printf("[GFX-THAI] !! No glyph for U+%04X, using replacement\n", glyph.codepoint);
#endif
}
if (!glyphData) {
continue;
}
const int is2Bit = fontData->is2Bit;
const uint32_t offset = glyphData->dataOffset;
const uint8_t width = glyphData->width;
const uint8_t height = glyphData->height;
const int left = glyphData->left;
// Calculate x position for this glyph
int glyphX;
if (glyph.zeroAdvance) {
// Combining mark: position relative to base consonant
// Center the mark over the base glyph
glyphX = baseX + glyph.xOffset;
} else {
// Normal glyph: position at current cursor
glyphX = *x + glyph.xOffset;
}
// Calculate y offset (scaled by font size)
const int yOffset = static_cast<int>(glyph.yOffset * yScale);
const int glyphY = y + yOffset;
const uint8_t* bitmap = &fontData->bitmap[offset];
if (bitmap != nullptr) {
for (int bitmapY = 0; bitmapY < height; bitmapY++) {
const int screenY = glyphY - glyphData->top + bitmapY;
for (int bitmapX = 0; bitmapX < width; bitmapX++) {
const int pixelPosition = bitmapY * width + bitmapX;
const int screenX = glyphX + left + bitmapX;
if (is2Bit) {
const uint8_t byte = bitmap[pixelPosition / 4];
const uint8_t bit_index = (3 - pixelPosition % 4) * 2;
const uint8_t bmpVal = 3 - (byte >> bit_index) & 0x3;
if (renderMode == BW && bmpVal < 3) {
drawPixel(screenX, screenY, pixelState);
} else if (renderMode == GRAYSCALE_MSB && (bmpVal == 1 || bmpVal == 2)) {
drawPixel(screenX, screenY, false);
} else if (renderMode == GRAYSCALE_LSB && bmpVal == 1) {
drawPixel(screenX, screenY, false);
}
} else {
const uint8_t byte = bitmap[pixelPosition / 8];
const uint8_t bit_index = 7 - (pixelPosition % 8);
if ((byte >> bit_index) & 1) {
drawPixel(screenX, screenY, pixelState);
}
}
}
}
}
// Track advance for non-combining glyphs
if (!glyph.zeroAdvance) {
// Update base position to right of center (for subsequent combining marks)
baseX = *x + glyphData->advanceX;
*x += glyphData->advanceX;
clusterAdvance += glyphData->advanceX;
}
}
}
void GfxRenderer::getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const { void GfxRenderer::getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const {
switch (orientation) { switch (orientation) {
case Portrait: case Portrait:

View File

@ -2,6 +2,7 @@
#include <EInkDisplay.h> #include <EInkDisplay.h>
#include <EpdFontFamily.h> #include <EpdFontFamily.h>
#include <ThaiShaper.h>
#include <map> #include <map>
@ -93,6 +94,13 @@ class GfxRenderer {
EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; EpdFontFamily::Style style = EpdFontFamily::REGULAR) const;
int getTextHeight(int fontId) const; int getTextHeight(int fontId) const;
// Thai text rendering helpers
void drawThaiText(int fontId, int x, int y, const char* text, bool black,
EpdFontFamily::Style style) const;
void renderThaiCluster(const EpdFontFamily& fontFamily, const ThaiShaper::ThaiCluster& cluster,
int* x, int y, bool pixelState, EpdFontFamily::Style style) const;
int getThaiTextWidth(int fontId, const char* text, EpdFontFamily::Style style) const;
public: public:
// Grayscale functions // Grayscale functions
void setRenderMode(const RenderMode mode) { this->renderMode = mode; } void setRenderMode(const RenderMode mode) { this->renderMode = mode; }

View File

@ -1,9 +1,43 @@
#pragma once #pragma once
#include <SdFat.h> #include <SdFat.h>
#include <cstring>
#include <iostream> #include <iostream>
// Debug logging for serialization corruption investigation
// Set to 1 to enable validation of Thai UTF-8 strings during serialize/deserialize
#define SERIALIZATION_THAI_VALIDATION 0
#if SERIALIZATION_THAI_VALIDATION
#include <Arduino.h>
#endif
namespace serialization { namespace serialization {
#if SERIALIZATION_THAI_VALIDATION
// Check if a byte sequence contains Thai UTF-8 with potential corruption
// Returns true if corruption is detected (null bytes within Thai sequences)
static bool checkThaiCorruption(const std::string& s, const char* context) {
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(s.data());
const uint8_t* end = ptr + s.size();
while (ptr < end) {
// Check for Thai UTF-8 start byte (0xE0 for Thai block U+0E00-U+0EFF)
if (*ptr == 0xE0 && (ptr + 3) <= end) {
// Thai characters are 0xE0 0xB8/0xB9 XX
if (ptr[1] == 0x00 || ptr[2] == 0x00) {
// Null byte in Thai sequence = corruption
Serial.printf("[SER] %s CORRUPT Thai @ offset %u: %02X %02X %02X\n",
context, (uint32_t)(ptr - reinterpret_cast<const uint8_t*>(s.data())),
ptr[0], ptr[1], ptr[2]);
return true;
}
}
ptr++;
}
return false;
}
#endif
template <typename T> template <typename T>
static void writePod(std::ostream& os, const T& value) { static void writePod(std::ostream& os, const T& value) {
os.write(reinterpret_cast<const char*>(&value), sizeof(T)); os.write(reinterpret_cast<const char*>(&value), sizeof(T));
@ -32,8 +66,43 @@ static void writeString(std::ostream& os, const std::string& s) {
static void writeString(FsFile& file, const std::string& s) { static void writeString(FsFile& file, const std::string& s) {
const uint32_t len = s.size(); const uint32_t len = s.size();
#if SERIALIZATION_THAI_VALIDATION
// Check for corruption BEFORE writing to file
checkThaiCorruption(s, "WRITE_BEFORE");
#endif
// Remember position for read-back verification
uint64_t writePos = file.curPosition();
writePod(file, len); writePod(file, len);
file.write(reinterpret_cast<const uint8_t*>(s.data()), len); file.write(reinterpret_cast<const uint8_t*>(s.data()), len);
#if SERIALIZATION_THAI_VALIDATION
// Read-back verification: immediately read what we just wrote to detect SD card issues
if (len > 0 && len <= 64) {
uint64_t afterWritePos = file.curPosition();
file.seek(writePos + sizeof(uint32_t)); // Skip the length prefix
uint8_t verifyBuf[64];
size_t bytesRead = file.read(verifyBuf, len);
// Check if read-back matches what we wrote
bool mismatch = false;
if (bytesRead == len) {
for (size_t i = 0; i < len; i++) {
if (verifyBuf[i] != static_cast<uint8_t>(s[i])) {
mismatch = true;
Serial.printf("[SER] READBACK MISMATCH @ %u: wrote %02X, read %02X\n",
(uint32_t)i, static_cast<uint8_t>(s[i]), verifyBuf[i]);
}
}
} else {
Serial.printf("[SER] READBACK: partial read %u/%u\n", (uint32_t)bytesRead, len);
}
// Restore file position
file.seek(afterWritePos);
}
#endif
} }
static void readString(std::istream& is, std::string& s) { static void readString(std::istream& is, std::string& s) {
@ -46,7 +115,66 @@ static void readString(std::istream& is, std::string& s) {
static void readString(FsFile& file, std::string& s) { static void readString(FsFile& file, std::string& s) {
uint32_t len; uint32_t len;
readPod(file, len); readPod(file, len);
// Sanity check: prevent unreasonably large allocations (max 64KB per string)
if (len > 65536) {
Serial.printf("[SER] readString: length %u exceeds maximum, truncating\n", len);
len = 0;
}
s.resize(len); s.resize(len);
file.read(&s[0], len); if (len > 0) {
#if SERIALIZATION_THAI_VALIDATION
// Use a temporary stack buffer to isolate file.read() from std::string memory
// This helps determine if corruption is in file.read() or in memory management
uint8_t tempBuf[64];
bool useTempBuf = (len <= sizeof(tempBuf));
if (useTempBuf) {
// Read into temporary buffer first
size_t bytesRead = file.read(tempBuf, len);
if (bytesRead != len) {
Serial.printf("[SER] readString: partial read %u/%u bytes\n", (uint32_t)bytesRead, len);
}
// Check temp buffer IMMEDIATELY after read
bool corruptInTemp = false;
for (size_t i = 0; i + 2 < len; i++) {
if (tempBuf[i] == 0xE0 && (tempBuf[i+1] == 0x00 || tempBuf[i+2] == 0x00)) {
Serial.printf("[SER] READ_TEMPBUF CORRUPT @ %u: %02X %02X %02X\n",
(uint32_t)i, tempBuf[i], tempBuf[i+1], tempBuf[i+2]);
corruptInTemp = true;
}
}
// Copy to string
memcpy(&s[0], tempBuf, len);
// Check string after copy
if (!corruptInTemp) {
checkThaiCorruption(s, "READ_AFTER_COPY");
}
} else {
// Large string - read directly
size_t bytesRead = file.read(&s[0], len);
if (bytesRead != len) {
Serial.printf("[SER] readString: partial read %u/%u bytes\n", (uint32_t)bytesRead, len);
if (bytesRead < len) {
memset(&s[bytesRead], 0, len - bytesRead);
}
}
checkThaiCorruption(s, "READ_AFTER");
}
#else
size_t bytesRead = file.read(&s[0], len);
if (bytesRead != len) {
Serial.printf("[SER] readString: partial read %u/%u bytes\n", (uint32_t)bytesRead, len);
// Zero-fill any unread portion to avoid garbage data
if (bytesRead < len) {
memset(&s[bytesRead], 0, len - bytesRead);
}
}
#endif
}
} }
} // namespace serialization } // namespace serialization

View File

@ -0,0 +1,97 @@
#include "ThaiCharacter.h"
#include <Utf8.h>
namespace ThaiShaper {
ThaiCharType getThaiCharType(uint32_t cp) {
// Not in Thai block
if (cp < 0x0E00 || cp > 0x0E7F) {
return ThaiCharType::NON_THAI;
}
// Thai consonants: ก-ฮ (U+0E01-U+0E2E)
// Note: U+0E2F (ฯ) is PAIYANNOI, a punctuation mark
if (cp >= 0x0E01 && cp <= 0x0E2E) {
return ThaiCharType::CONSONANT;
}
// Leading vowels: เ แ โ ไ ใ (U+0E40-U+0E44)
if (cp >= 0x0E40 && cp <= 0x0E44) {
return ThaiCharType::LEADING_VOWEL;
}
// Above vowels and marks
switch (cp) {
case 0x0E31: // MAI HAN-AKAT (ั)
case 0x0E34: // SARA I (ิ)
case 0x0E35: // SARA II (ี)
case 0x0E36: // SARA UE (ึ)
case 0x0E37: // SARA UEE (ื)
case 0x0E47: // MAITAIKHU (็)
return ThaiCharType::ABOVE_VOWEL;
}
// Below vowels
switch (cp) {
case 0x0E38: // SARA U (ุ)
case 0x0E39: // SARA UU (ู)
case 0x0E3A: // PHINTHU (ฺ)
return ThaiCharType::BELOW_VOWEL;
}
// Tone marks
switch (cp) {
case 0x0E48: // MAI EK (่)
case 0x0E49: // MAI THO (้)
case 0x0E4A: // MAI TRI (๊)
case 0x0E4B: // MAI CHATTAWA (๋)
return ThaiCharType::TONE_MARK;
}
// Follow vowels (vowels that display after consonant)
switch (cp) {
case 0x0E30: // SARA A (ะ)
case 0x0E32: // SARA AA (า)
case 0x0E33: // SARA AM (ำ)
case 0x0E45: // LAKKHANGYAO (ๅ)
return ThaiCharType::FOLLOW_VOWEL;
}
// Nikhahit
if (cp == 0x0E4D) {
return ThaiCharType::NIKHAHIT;
}
// Yamakkan / Thanthakhat
if (cp == 0x0E4C || cp == 0x0E4E) {
return ThaiCharType::YAMAKKAN;
}
// Thai digits: -๙ (U+0E50-U+0E59)
if (cp >= 0x0E50 && cp <= 0x0E59) {
return ThaiCharType::THAI_DIGIT;
}
// Everything else in Thai block is a symbol/punctuation
return ThaiCharType::THAI_SYMBOL;
}
bool containsThai(const char* text) {
if (text == nullptr || *text == '\0') {
return false;
}
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text);
uint32_t cp;
while ((cp = utf8NextCodepoint(&ptr))) {
if (isThaiCodepoint(cp)) {
return true;
}
}
return false;
}
} // namespace ThaiShaper

View File

@ -0,0 +1,95 @@
#pragma once
#include <cstdint>
/**
* Thai Character Classification
*
* Thai Unicode block (U+0E00-U+0E7F) contains:
* - Consonants (-): U+0E01-U+0E2E
* - Vowels that can appear in various positions
* - Tone marks that stack above consonants/vowels
* - Thai digits and punctuation
*
* Thai text rendering requires special handling because:
* 1. Leading vowels ( ) display BEFORE the consonant but
* appear AFTER in Unicode codepoint order
* 2. Above vowels ( etc.) must be positioned above consonants
* 3. Below vowels ( ) must be positioned below consonants
* 4. Tone marks must stack above vowels/consonants
*/
namespace ThaiShaper {
// Thai character types for positioning and cluster formation
enum class ThaiCharType : uint8_t {
NON_THAI, // Not a Thai character
CONSONANT, // Base consonant (ก-ฮ)
LEADING_VOWEL, // Vowels that display before consonant (เ แ โ ไ ใ)
ABOVE_VOWEL, // Vowels above consonant (ั ิ ี ึ ื ็)
BELOW_VOWEL, // Vowels below consonant (ุ ู ฺ)
FOLLOW_VOWEL, // Vowels that follow consonant (ะ า ำ)
TONE_MARK, // Tone marks (่ ้ ๊ ๋)
NIKHAHIT, // Nikhahit (ํ) - special combining mark
YAMAKKAN, // Yamakkan (์) - cancellation mark
THAI_DIGIT, // Thai digits (-๙)
THAI_SYMBOL, // Thai punctuation and symbols
};
// Check if a codepoint is in the Thai Unicode block
inline bool isThaiCodepoint(uint32_t cp) { return cp >= 0x0E00 && cp <= 0x0E7F; }
// Get the character type for a Thai codepoint
ThaiCharType getThaiCharType(uint32_t cp);
// Check if codepoint is a Thai consonant (can be a cluster base)
inline bool isThaiConsonant(uint32_t cp) { return cp >= 0x0E01 && cp <= 0x0E2E; }
// Check if codepoint is a leading vowel (needs reordering)
inline bool isThaiLeadingVowel(uint32_t cp) {
return cp == 0x0E40 || // SARA E (เ)
cp == 0x0E41 || // SARA AE (แ)
cp == 0x0E42 || // SARA O (โ)
cp == 0x0E43 || // SARA AI MAIMUAN (ใ)
cp == 0x0E44; // SARA AI MAIMALAI (ไ)
}
// Check if codepoint is an above vowel/mark (positioned above base)
inline bool isThaiAboveVowel(uint32_t cp) {
return cp == 0x0E31 || // MAI HAN-AKAT (ั)
cp == 0x0E34 || // SARA I (ิ)
cp == 0x0E35 || // SARA II (ี)
cp == 0x0E36 || // SARA UE (ึ)
cp == 0x0E37 || // SARA UEE (ื)
cp == 0x0E47; // MAITAIKHU (็)
}
// Check if codepoint is a below vowel (positioned below base)
inline bool isThaibelowVowel(uint32_t cp) {
return cp == 0x0E38 || // SARA U (ุ)
cp == 0x0E39 || // SARA UU (ู)
cp == 0x0E3A; // PHINTHU (ฺ)
}
// Check if codepoint is a tone mark (positioned above)
inline bool isThaiToneMark(uint32_t cp) {
return cp == 0x0E48 || // MAI EK (่)
cp == 0x0E49 || // MAI THO (้)
cp == 0x0E4A || // MAI TRI (๊)
cp == 0x0E4B; // MAI CHATTAWA (๋)
}
// Check if codepoint is a Thai digit
inline bool isThaiDigit(uint32_t cp) { return cp >= 0x0E50 && cp <= 0x0E59; }
// Check if a codepoint is a combining character (needs to attach to base)
inline bool isThaiCombining(uint32_t cp) {
return isThaiAboveVowel(cp) || isThaibelowVowel(cp) || isThaiToneMark(cp) || cp == 0x0E4C || // THANTHAKHAT (์)
cp == 0x0E4D || // NIKHAHIT (ํ)
cp == 0x0E4E; // YAMAKKAN
}
// Check if text contains any Thai codepoints (for fast path detection)
bool containsThai(const char* text);
} // namespace ThaiShaper

View File

@ -0,0 +1,65 @@
#pragma once
#include <cstdint>
#include <vector>
namespace ThaiShaper {
/**
* Represents a positioned glyph within a Thai cluster.
*
* Thai clusters consist of a base consonant with optional:
* - Leading vowel (displayed before base but stored after in Unicode)
* - Above vowel/marks (stacked above base)
* - Below vowel (positioned below base)
* - Tone mark (stacked above vowels)
* - Follow vowel (displayed after base)
*/
struct PositionedGlyph {
uint32_t codepoint; // Unicode codepoint to render
int8_t xOffset; // X offset from cluster origin (in font units fraction)
int8_t yOffset; // Y offset from baseline (negative = up, positive = down)
bool zeroAdvance; // If true, this glyph doesn't advance the cursor
};
/**
* A Thai grapheme cluster - the minimal unit for proper rendering.
*
* A cluster typically contains:
* - 0-1 leading vowel (displayed first)
* - 1 base consonant
* - 0-1 above vowel
* - 0-1 below vowel
* - 0-1 tone mark
* - 0-1 follow vowel
* - 0-1 thanthakhat/yamakkan
*/
struct ThaiCluster {
std::vector<PositionedGlyph> glyphs;
int totalAdvance; // Total width of cluster in font advanceX units
ThaiCluster() : totalAdvance(0) {}
};
/**
* Y-offset constants for Thai mark positioning.
* These are relative adjustments based on typical Thai font metrics.
* Values are in "font units" where the typical em-height is ~1.0
* Negative values move UP, positive move DOWN.
*/
namespace ThaiOffset {
// Above marks (relative to baseline, scaled by font size)
constexpr int8_t ABOVE_VOWEL = -2; // Base above-vowel position
constexpr int8_t TONE_MARK = -4; // Tone mark above vowel
constexpr int8_t TONE_MARK_ALONE =
-2; // Tone mark when no above vowel (sits lower at same position as above vowel would)
// Below marks
constexpr int8_t BELOW_VOWEL = 3; // Below-vowel position
// X-offset for ascender consonants (tall consonants like ป ฝ ฟ)
// When these have above marks, the marks may need to shift
constexpr int8_t ASCENDER_X_SHIFT = 0; // No shift needed in most fonts
} // namespace ThaiOffset
} // namespace ThaiShaper

View File

@ -0,0 +1,321 @@
#include "ThaiClusterBuilder.h"
#include <Utf8.h>
// Debug logging for Thai rendering investigation
// Set to 1 to enable verbose cluster building logging
#define THAI_CLUSTER_DEBUG_LOGGING 0
#if THAI_CLUSTER_DEBUG_LOGGING
#include <Arduino.h>
#endif
namespace ThaiShaper {
bool ThaiClusterBuilder::isAscenderConsonant(uint32_t cp) {
// Thai consonants with tall ascenders that may affect mark positioning
// These have parts that extend above the normal consonant height
switch (cp) {
case 0x0E1B: // PO PLA (ป)
case 0x0E1D: // FO FA (ฝ)
case 0x0E1F: // FO FAN (ฟ)
case 0x0E2C: // LO CHULA (ฬ)
return true;
default:
return false;
}
}
bool ThaiClusterBuilder::isDescenderConsonant(uint32_t cp) {
// Thai consonants with descenders that extend below the baseline
// These may affect below-vowel positioning
switch (cp) {
case 0x0E0E: // DO CHADA (ฎ)
case 0x0E0F: // TO PATAK (ฏ)
case 0x0E24: // RU (ฤ)
case 0x0E26: // LU (ฦ)
return true;
default:
return false;
}
}
std::vector<ThaiCluster> ThaiClusterBuilder::buildClusters(const char* text) {
std::vector<ThaiCluster> clusters;
if (text == nullptr || *text == '\0') {
return clusters;
}
#if THAI_CLUSTER_DEBUG_LOGGING
Serial.printf("[THAI] buildClusters input bytes: ");
const uint8_t* debugPtr = reinterpret_cast<const uint8_t*>(text);
for (int i = 0; i < 32 && debugPtr[i] != '\0'; i++) {
Serial.printf("%02X ", debugPtr[i]);
}
Serial.printf("\n");
#endif
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text);
while (*ptr != '\0') {
ThaiCluster cluster = buildNextCluster(&ptr);
if (!cluster.glyphs.empty()) {
clusters.push_back(std::move(cluster));
}
}
#if THAI_CLUSTER_DEBUG_LOGGING
Serial.printf("[THAI] Built %zu clusters\n", clusters.size());
#endif
return clusters;
}
ThaiCluster ThaiClusterBuilder::buildNextCluster(const uint8_t** text) {
ThaiCluster cluster;
if (*text == nullptr || **text == '\0') {
return cluster;
}
#if THAI_CLUSTER_DEBUG_LOGGING
// Log raw bytes at current position
Serial.printf("[THAI] buildNextCluster at ptr=%p, bytes: ", (void*)*text);
for (int i = 0; i < 6 && (*text)[i] != '\0'; i++) {
Serial.printf("%02X ", (*text)[i]);
}
Serial.printf("\n");
#endif
// Peek at first codepoint to determine cluster type
const uint8_t* peekPtr = *text;
uint32_t firstCp = utf8NextCodepoint(&peekPtr);
#if THAI_CLUSTER_DEBUG_LOGGING
Serial.printf("[THAI] First codepoint: U+%04X\n", firstCp);
#endif
// Non-Thai character: return as single-glyph cluster
if (!isThaiCodepoint(firstCp)) {
utf8NextCodepoint(text); // Consume the codepoint
PositionedGlyph glyph;
glyph.codepoint = firstCp;
glyph.xOffset = 0;
glyph.yOffset = 0;
glyph.zeroAdvance = false;
cluster.glyphs.push_back(glyph);
#if THAI_CLUSTER_DEBUG_LOGGING
Serial.printf("[THAI] Non-Thai cluster: U+%04X\n", firstCp);
#endif
return cluster;
}
// Collect all codepoints that form this Thai cluster
uint32_t leadingVowel = 0;
uint32_t baseConsonant = 0;
uint32_t aboveVowel = 0;
uint32_t belowVowel = 0;
uint32_t toneMark = 0;
uint32_t followVowel = 0;
uint32_t thanthakhat = 0; // ์ or ํ (nikhahit)
// Parse the cluster: consume codepoints until we hit a cluster boundary
while (**text != '\0') {
peekPtr = *text;
uint32_t cp = utf8NextCodepoint(&peekPtr);
if (!isThaiCodepoint(cp)) {
break; // Non-Thai ends the cluster
}
ThaiCharType type = getThaiCharType(cp);
switch (type) {
case ThaiCharType::LEADING_VOWEL:
if (leadingVowel != 0 || baseConsonant != 0) {
// Another leading vowel or we already have base = new cluster
goto done_parsing;
}
leadingVowel = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::CONSONANT:
if (baseConsonant != 0) {
// Second consonant = new cluster
goto done_parsing;
}
baseConsonant = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::ABOVE_VOWEL:
if (aboveVowel != 0) {
// Multiple above vowels - take first, new cluster for next
goto done_parsing;
}
aboveVowel = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::BELOW_VOWEL:
if (belowVowel != 0) {
goto done_parsing;
}
belowVowel = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::TONE_MARK:
if (toneMark != 0) {
goto done_parsing;
}
toneMark = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::FOLLOW_VOWEL:
if (followVowel != 0) {
goto done_parsing;
}
followVowel = cp;
utf8NextCodepoint(text);
// Follow vowel typically ends the syllable
goto done_parsing;
case ThaiCharType::NIKHAHIT:
case ThaiCharType::YAMAKKAN:
if (thanthakhat != 0) {
goto done_parsing;
}
thanthakhat = cp;
utf8NextCodepoint(text);
break;
case ThaiCharType::THAI_DIGIT:
case ThaiCharType::THAI_SYMBOL:
// Digits and symbols are standalone clusters
if (leadingVowel == 0 && baseConsonant == 0) {
// Start of cluster with digit/symbol
utf8NextCodepoint(text);
PositionedGlyph glyph;
glyph.codepoint = cp;
glyph.xOffset = 0;
glyph.yOffset = 0;
glyph.zeroAdvance = false;
cluster.glyphs.push_back(glyph);
return cluster;
}
// Otherwise end current cluster
goto done_parsing;
default:
// Unknown Thai character - treat as cluster boundary
goto done_parsing;
}
}
done_parsing:
// Now build positioned glyphs from collected codepoints
// 1. Leading vowel (if any) - rendered FIRST but stored after consonant in Unicode
if (leadingVowel != 0) {
PositionedGlyph glyph;
glyph.codepoint = leadingVowel;
glyph.xOffset = 0;
glyph.yOffset = 0;
glyph.zeroAdvance = false; // Leading vowel has its own advance
cluster.glyphs.push_back(glyph);
}
// 2. Base consonant
if (baseConsonant != 0) {
PositionedGlyph glyph;
glyph.codepoint = baseConsonant;
glyph.xOffset = 0;
glyph.yOffset = 0;
glyph.zeroAdvance = false;
cluster.glyphs.push_back(glyph);
// Check if this is an ascender consonant for mark positioning
bool hasAscender = isAscenderConsonant(baseConsonant);
// 3. Above vowel (positioned above base)
if (aboveVowel != 0) {
PositionedGlyph aboveGlyph;
aboveGlyph.codepoint = aboveVowel;
aboveGlyph.xOffset = hasAscender ? ThaiOffset::ASCENDER_X_SHIFT : 0;
aboveGlyph.yOffset = ThaiOffset::ABOVE_VOWEL;
aboveGlyph.zeroAdvance = true; // Above vowel doesn't advance cursor
cluster.glyphs.push_back(aboveGlyph);
}
// 4. Below vowel (positioned below base)
if (belowVowel != 0) {
PositionedGlyph belowGlyph;
belowGlyph.codepoint = belowVowel;
belowGlyph.xOffset = 0;
belowGlyph.yOffset = ThaiOffset::BELOW_VOWEL;
belowGlyph.zeroAdvance = true;
cluster.glyphs.push_back(belowGlyph);
}
// 5. Tone mark (positioned above everything else)
if (toneMark != 0) {
PositionedGlyph toneGlyph;
toneGlyph.codepoint = toneMark;
toneGlyph.xOffset = hasAscender ? ThaiOffset::ASCENDER_X_SHIFT : 0;
// Tone mark goes above above-vowel if present, otherwise just above base
toneGlyph.yOffset = aboveVowel != 0 ? ThaiOffset::TONE_MARK : ThaiOffset::TONE_MARK_ALONE;
toneGlyph.zeroAdvance = true;
cluster.glyphs.push_back(toneGlyph);
}
// 6. Thanthakhat/Nikhahit (positioned above)
if (thanthakhat != 0) {
PositionedGlyph thanGlyph;
thanGlyph.codepoint = thanthakhat;
thanGlyph.xOffset = 0;
// Position depends on what's already above
if (toneMark != 0) {
thanGlyph.yOffset = ThaiOffset::TONE_MARK - 2; // Above tone mark
} else if (aboveVowel != 0) {
thanGlyph.yOffset = ThaiOffset::TONE_MARK; // Above above-vowel
} else {
thanGlyph.yOffset = ThaiOffset::TONE_MARK_ALONE;
}
thanGlyph.zeroAdvance = true;
cluster.glyphs.push_back(thanGlyph);
}
}
// 7. Follow vowel (displayed after base)
if (followVowel != 0) {
PositionedGlyph glyph;
glyph.codepoint = followVowel;
glyph.xOffset = 0;
glyph.yOffset = 0;
glyph.zeroAdvance = false; // Follow vowel advances cursor
cluster.glyphs.push_back(glyph);
}
// Handle edge case: leading vowel with no consonant (shouldn't happen in valid Thai)
if (leadingVowel != 0 && baseConsonant == 0) {
// Just the leading vowel by itself
// Already added above
}
#if THAI_CLUSTER_DEBUG_LOGGING
Serial.printf("[THAI] Cluster built with %zu glyphs: ", cluster.glyphs.size());
for (const auto& g : cluster.glyphs) {
Serial.printf("U+%04X ", g.codepoint);
}
Serial.printf("(lead=%04X base=%04X above=%04X below=%04X tone=%04X follow=%04X)\n",
leadingVowel, baseConsonant, aboveVowel, belowVowel, toneMark, followVowel);
#endif
return cluster;
}
} // namespace ThaiShaper

View File

@ -0,0 +1,63 @@
#pragma once
#include <cstdint>
#include <vector>
#include "ThaiCharacter.h"
#include "ThaiCluster.h"
namespace ThaiShaper {
/**
* Thai Cluster Builder
*
* Takes a UTF-8 string containing Thai text and builds a sequence of
* grapheme clusters with proper glyph positioning for rendering.
*
* Thai text shaping involves:
* 1. Reordering: Leading vowels ( ) appear AFTER the consonant in
* Unicode but must be rendered BEFORE the consonant visually.
*
* 2. Stacking: Above vowels, tone marks, and other marks must be stacked
* vertically above the base consonant.
*
* 3. Below placement: Below vowels must be positioned under the consonant.
*
* Example: "เกี่ยว" (about/related) is stored as:
* (U+0E40) + (U+0E01) + (U+0E35) + (U+0E48) + (U+0E22) + (U+0E27)
*
* But renders as:
* [][ with and stacked above][][]
*
* Note: Consonant "ascenders" - Some Thai consonants have tall ascenders
* ( etc.) that may cause above marks to shift position. This
* implementation uses a simplified approach suitable for e-ink rendering.
*/
class ThaiClusterBuilder {
public:
/**
* Build clusters from a UTF-8 Thai text string.
*
* @param text UTF-8 encoded string (may contain mixed Thai and non-Thai)
* @return Vector of clusters, each representing one grapheme unit
*/
static std::vector<ThaiCluster> buildClusters(const char* text);
/**
* Build a single cluster from codepoints starting at the current position.
* Advances the text pointer past the consumed codepoints.
*
* @param text Pointer to pointer of UTF-8 text (advanced on return)
* @return Single cluster containing positioned glyphs
*/
static ThaiCluster buildNextCluster(const uint8_t** text);
private:
// Check if a consonant is a "tall" consonant that affects mark positioning
static bool isAscenderConsonant(uint32_t cp);
// Check if a consonant is a "descender" consonant that affects below-mark positioning
static bool isDescenderConsonant(uint32_t cp);
};
} // namespace ThaiShaper

View File

@ -0,0 +1,25 @@
#pragma once
/**
* Thai Text Shaping Library
*
* Provides proper rendering support for Thai script including:
* - Character classification and type detection
* - Grapheme cluster building with proper glyph ordering
* - Mark positioning (above vowels, below vowels, tone marks)
* - Word segmentation for line breaking
*
* Usage:
* 1. Check if text contains Thai: ThaiShaper::containsThai(text)
* 2. Build clusters: ThaiClusterBuilder::buildClusters(text)
* 3. Render each cluster's positioned glyphs
*
* For line breaking:
* 1. Find break points: ThaiWordBreak::findBreakPoints(text)
* 2. Or get next word boundary: ThaiWordBreak::nextWordBoundary(text, offset)
*/
#include "ThaiCharacter.h"
#include "ThaiCluster.h"
#include "ThaiClusterBuilder.h"
#include "ThaiWordBreak.h"

View File

@ -0,0 +1,149 @@
#include "ThaiWordBreak.h"
#include <Arduino.h>
#include <Utf8.h>
#include <cstring>
#include "ThaiCharacter.h"
namespace ThaiShaper {
size_t ThaiWordBreak::nextClusterBoundary(const char* text, size_t startOffset) {
if (text == nullptr) {
return 0;
}
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text + startOffset);
if (*ptr == '\0') {
return startOffset;
}
// Get first codepoint
const uint8_t* startPtr = ptr;
uint32_t cp = utf8NextCodepoint(&ptr);
// Non-Thai: just return next codepoint boundary
if (!isThaiCodepoint(cp)) {
return reinterpret_cast<const char*>(ptr) - text;
}
// For Thai leading vowels, include the following consonant and marks
ThaiCharType type = getThaiCharType(cp);
if (type == ThaiCharType::LEADING_VOWEL) {
// Consume the leading vowel, continue to get consonant + marks
if (*ptr != '\0') {
cp = utf8NextCodepoint(&ptr);
}
}
// Now consume any combining marks that follow
while (*ptr != '\0') {
const uint8_t* peekPtr = ptr;
cp = utf8NextCodepoint(&peekPtr);
if (!isThaiCodepoint(cp)) {
break;
}
type = getThaiCharType(cp);
// These types combine with the base - continue consuming
if (type == ThaiCharType::ABOVE_VOWEL || type == ThaiCharType::BELOW_VOWEL || type == ThaiCharType::TONE_MARK ||
type == ThaiCharType::NIKHAHIT || type == ThaiCharType::YAMAKKAN || type == ThaiCharType::FOLLOW_VOWEL) {
ptr = peekPtr;
} else {
// New cluster starts (consonant, leading vowel, digit, etc.)
break;
}
}
return reinterpret_cast<const char*>(ptr) - text;
}
// Maximum size for the static text buffer used in segmentWords
// Thai EPUBs typically have words up to a few hundred bytes
static constexpr size_t MAX_SEGMENT_TEXT_SIZE = 2048;
// Static buffer to hold text copy - avoids heap corruption issues
// Safe because ESP32 runs single-threaded for this code path
static char s_segmentTextBuffer[MAX_SEGMENT_TEXT_SIZE];
std::vector<std::string> ThaiWordBreak::segmentWords(const char* text) {
std::vector<std::string> segments;
if (text == nullptr || *text == '\0') {
return segments;
}
size_t textLen = strlen(text);
// CRITICAL FIX: Copy input to STATIC buffer to avoid heap corruption.
// On ESP32, heap allocations during string creation can corrupt the input
// pointer's memory. Using a static buffer ensures the source data is
// protected from heap fragmentation issues.
if (textLen >= MAX_SEGMENT_TEXT_SIZE) {
// Text too long for static buffer - truncate to prevent overflow
textLen = MAX_SEGMENT_TEXT_SIZE - 1;
}
memcpy(s_segmentTextBuffer, text, textLen);
s_segmentTextBuffer[textLen] = '\0';
// Structure to hold segment boundaries (POD - no heap allocation)
struct SegmentBounds {
uint16_t offset;
uint16_t length;
};
// Use a static array for bounds to avoid heap allocation during parsing
static SegmentBounds s_bounds[512];
size_t boundsCount = 0;
size_t offset = 0;
// Safety limit to prevent infinite loops
size_t maxIterations = textLen + 1;
size_t iterations = 0;
// Phase 1: Collect all segment boundaries WITHOUT any heap allocation
while (offset < textLen && iterations < maxIterations && boundsCount < 512) {
iterations++;
// Handle whitespace - preserve as separate segment
if (s_segmentTextBuffer[offset] == ' ' || s_segmentTextBuffer[offset] == '\n' || s_segmentTextBuffer[offset] == '\t') {
s_bounds[boundsCount++] = {static_cast<uint16_t>(offset), 1};
offset++;
continue;
}
// Get next cluster boundary
size_t nextBoundary = nextClusterBoundary(s_segmentTextBuffer, offset);
// Safety: ensure we always advance
if (nextBoundary <= offset) {
nextBoundary = offset + 1;
// Skip to valid UTF-8 boundary
while (nextBoundary < textLen && (s_segmentTextBuffer[nextBoundary] & 0xC0) == 0x80) {
nextBoundary++;
}
}
// Record segment bounds
if (nextBoundary > offset) {
s_bounds[boundsCount++] = {static_cast<uint16_t>(offset), static_cast<uint16_t>(nextBoundary - offset)};
}
offset = nextBoundary;
}
// Phase 2: Create strings from static buffer
segments.reserve(boundsCount);
for (size_t i = 0; i < boundsCount; i++) {
segments.emplace_back(s_segmentTextBuffer + s_bounds[i].offset, s_bounds[i].length);
}
return segments;
}
} // namespace ThaiShaper

View File

@ -0,0 +1,41 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace ThaiShaper {
/**
* Thai Word Break - Cluster-based segmentation
*
* Thai text has no spaces between words. This class provides simple
* cluster-based segmentation for line breaking. Each Thai syllable
* (consonant + vowels + tone marks) forms a breakable unit.
*
* This is a lightweight implementation suitable for embedded systems
* with limited memory. It breaks at grapheme cluster boundaries rather
* than true word boundaries, which provides reasonable line breaking
* without requiring a large dictionary.
*/
class ThaiWordBreak {
public:
/**
* Segment Thai text into breakable clusters.
*
* @param text UTF-8 encoded Thai text
* @return Vector of cluster strings
*/
static std::vector<std::string> segmentWords(const char* text);
/**
* Get the byte offset of the next cluster boundary.
*
* @param text UTF-8 encoded text
* @param startOffset Starting byte offset
* @return Byte offset of next boundary, or string length if at end
*/
static size_t nextClusterBoundary(const char* text, size_t startOffset);
};
} // namespace ThaiShaper

View File

@ -0,0 +1,5 @@
{
"name": "ThaiShaper",
"version": "1.0.0",
"description": "Thai text shaping for proper vowel and tone mark positioning"
}

View File

@ -1,5 +1,13 @@
#include "Utf8.h" #include "Utf8.h"
// Debug logging for Thai rendering investigation
// Set to 1 to enable verbose UTF-8 decode logging
#define UTF8_DEBUG_LOGGING 0
#if UTF8_DEBUG_LOGGING
#include <Arduino.h>
#endif
int utf8CodepointLen(const unsigned char c) { int utf8CodepointLen(const unsigned char c) {
if (c < 0x80) return 1; // 0xxxxxxx if (c < 0x80) return 1; // 0xxxxxxx
if ((c >> 5) == 0x6) return 2; // 110xxxxx if ((c >> 5) == 0x6) return 2; // 110xxxxx
@ -24,8 +32,30 @@ uint32_t utf8NextCodepoint(const unsigned char** string) {
uint32_t cp = chr[0] & ((1 << (7 - bytes)) - 1); // mask header bits uint32_t cp = chr[0] & ((1 << (7 - bytes)) - 1); // mask header bits
for (int i = 1; i < bytes; i++) { for (int i = 1; i < bytes; i++) {
// Validate continuation bytes: must be 10xxxxxx (0x80-0xBF)
if ((chr[i] & 0xC0) != 0x80) {
#if UTF8_DEBUG_LOGGING
Serial.printf("[UTF8] Invalid continuation byte at pos %d: 0x%02X (expected 0x80-0xBF), bytes=[", i, chr[i]);
for (int j = 0; j < bytes; j++) {
Serial.printf("0x%02X%s", chr[j], j < bytes - 1 ? " " : "");
}
Serial.printf("]\n");
#endif
return REPLACEMENT_GLYPH; // Return U+FFFD for invalid sequence
}
cp = (cp << 6) | (chr[i] & 0x3F); cp = (cp << 6) | (chr[i] & 0x3F);
} }
#if UTF8_DEBUG_LOGGING
// Log Thai codepoints specifically
if (cp >= 0x0E00 && cp <= 0x0E7F) {
Serial.printf("[UTF8] Thai codepoint U+%04X from bytes=[", cp);
for (int j = 0; j < bytes; j++) {
Serial.printf("0x%02X%s", chr[j], j < bytes - 1 ? " " : "");
}
Serial.printf("]\n");
}
#endif
return cp; return cp;
} }

View File

@ -4,4 +4,5 @@
#define REPLACEMENT_GLYPH 0xFFFD #define REPLACEMENT_GLYPH 0xFFFD
int utf8CodepointLen(const unsigned char c);
uint32_t utf8NextCodepoint(const unsigned char** string); uint32_t utf8NextCodepoint(const unsigned char** string);

View File

@ -150,6 +150,16 @@ float CrossPointSettings::getReaderLineCompression() const {
case WIDE: case WIDE:
return 1.0f; return 1.0f;
} }
case NOTOSANSTHAI:
switch (lineSpacing) {
case TIGHT:
return 0.90f;
case NORMAL:
default:
return 0.95f;
case WIDE:
return 1.0f;
}
case OPENDYSLEXIC: case OPENDYSLEXIC:
switch (lineSpacing) { switch (lineSpacing) {
case TIGHT: case TIGHT:
@ -222,6 +232,18 @@ int CrossPointSettings::getReaderFontId() const {
case EXTRA_LARGE: case EXTRA_LARGE:
return NOTOSANS_18_FONT_ID; return NOTOSANS_18_FONT_ID;
} }
case NOTOSANSTHAI:
switch (fontSize) {
case SMALL:
return NOTOSANSTHAI_12_FONT_ID;
case MEDIUM:
default:
return NOTOSANSTHAI_14_FONT_ID;
case LARGE:
return NOTOSANSTHAI_16_FONT_ID;
case EXTRA_LARGE:
return NOTOSANSTHAI_18_FONT_ID;
}
case OPENDYSLEXIC: case OPENDYSLEXIC:
switch (fontSize) { switch (fontSize) {
case SMALL: case SMALL:

View File

@ -40,7 +40,7 @@ class CrossPointSettings {
enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1 }; enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1 };
// Font family options // Font family options
enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, OPENDYSLEXIC = 2 }; enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, OPENDYSLEXIC = 2, NOTOSANSTHAI = 3 };
// Font size options // Font size options
enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3 }; enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3 };
enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 }; enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 };

View File

@ -13,8 +13,8 @@ void BootActivity::onEnter() {
renderer.clearScreen(); renderer.clearScreen();
renderer.drawImage(CrossLarge, (pageWidth + 128) / 2, (pageHeight - 128) / 2, 128, 128); renderer.drawImage(CrossLarge, (pageWidth + 128) / 2, (pageHeight - 128) / 2, 128, 128);
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 70, "CrossPoint", true, EpdFontFamily::BOLD); renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 70, "CrossPointTH", true, EpdFontFamily::BOLD);
renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "BOOTING"); renderer.drawCenteredText(SMALL_FONT_ID, pageHeight / 2 + 95, "ALUCARD BOOTING");
renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, CROSSPOINT_VERSION); renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, CROSSPOINT_VERSION);
renderer.displayBuffer(); renderer.displayBuffer();
} }

View File

@ -82,7 +82,7 @@ void EpubReaderActivity::onEnter() {
updateRequired = true; updateRequired = true;
xTaskCreate(&EpubReaderActivity::taskTrampoline, "EpubReaderActivityTask", xTaskCreate(&EpubReaderActivity::taskTrampoline, "EpubReaderActivityTask",
8192, // Stack size 16384, // Stack size (increased from 8192 for Thai rendering)
this, // Parameters this, // Parameters
1, // Priority 1, // Priority
&displayTaskHandle // Task handle &displayTaskHandle // Task handle
@ -232,6 +232,10 @@ void EpubReaderActivity::displayTaskLoop() {
updateRequired = false; updateRequired = false;
xSemaphoreTake(renderingMutex, portMAX_DELAY); xSemaphoreTake(renderingMutex, portMAX_DELAY);
renderScreen(); renderScreen();
// Log stack high water mark to detect stack overflow issues
UBaseType_t stackHighWaterMark = uxTaskGetStackHighWaterMark(NULL);
Serial.printf("[%lu] [ERS] Stack high water mark: %u words (%u bytes remaining)\n", millis(),
stackHighWaterMark, stackHighWaterMark * sizeof(StackType_t));
xSemaphoreGive(renderingMutex); xSemaphoreGive(renderingMutex);
} }
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
@ -387,7 +391,14 @@ void EpubReaderActivity::renderScreen() {
void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int orientedMarginTop, void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int orientedMarginTop,
const int orientedMarginRight, const int orientedMarginBottom, const int orientedMarginRight, const int orientedMarginBottom,
const int orientedMarginLeft) { const int orientedMarginLeft) {
// Validate before BW render
page->validate("BEFORE_BW_RENDER");
page->render(renderer, SETTINGS.getReaderFontId(), orientedMarginLeft, orientedMarginTop); page->render(renderer, SETTINGS.getReaderFontId(), orientedMarginLeft, orientedMarginTop);
// Validate after BW render
page->validate("AFTER_BW_RENDER");
renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
if (pagesUntilFullRefresh <= 1) { if (pagesUntilFullRefresh <= 1) {
renderer.displayBuffer(EInkDisplay::HALF_REFRESH); renderer.displayBuffer(EInkDisplay::HALF_REFRESH);
@ -403,11 +414,17 @@ void EpubReaderActivity::renderContents(std::unique_ptr<Page> page, const int or
// grayscale rendering // grayscale rendering
// TODO: Only do this if font supports it // TODO: Only do this if font supports it
if (SETTINGS.textAntiAliasing) { if (SETTINGS.textAntiAliasing) {
// Validate before grayscale LSB render
page->validate("BEFORE_GRAY_LSB");
renderer.clearScreen(0x00); renderer.clearScreen(0x00);
renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB); renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB);
page->render(renderer, SETTINGS.getReaderFontId(), orientedMarginLeft, orientedMarginTop); page->render(renderer, SETTINGS.getReaderFontId(), orientedMarginLeft, orientedMarginTop);
renderer.copyGrayscaleLsbBuffers(); renderer.copyGrayscaleLsbBuffers();
// Validate before grayscale MSB render
page->validate("BEFORE_GRAY_MSB");
// Render and copy to MSB buffer // Render and copy to MSB buffer
renderer.clearScreen(0x00); renderer.clearScreen(0x00);
renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB); renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB);

View File

@ -32,7 +32,7 @@ const SettingInfo settingsList[settingsCount] = {
{"Prev, Next", "Next, Prev"}), {"Prev, Next", "Next, Prev"}),
SettingInfo::Toggle("Long-press Chapter Skip", &CrossPointSettings::longPressChapterSkip), SettingInfo::Toggle("Long-press Chapter Skip", &CrossPointSettings::longPressChapterSkip),
SettingInfo::Enum("Reader Font Family", &CrossPointSettings::fontFamily, SettingInfo::Enum("Reader Font Family", &CrossPointSettings::fontFamily,
{"Bookerly", "Noto Sans", "Open Dyslexic"}), {"Bookerly", "Noto Sans", "Open Dyslexic", "Noto Sans Thai"}),
SettingInfo::Enum("Reader Font Size", &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}), SettingInfo::Enum("Reader Font Size", &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}),
SettingInfo::Enum("Reader Line Spacing", &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}), SettingInfo::Enum("Reader Line Spacing", &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}),
SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}),

View File

@ -9,6 +9,12 @@
#define NOTOSANS_14_FONT_ID (-890242897) #define NOTOSANS_14_FONT_ID (-890242897)
#define NOTOSANS_16_FONT_ID (241925189) #define NOTOSANS_16_FONT_ID (241925189)
#define NOTOSANS_18_FONT_ID (1503221336) #define NOTOSANS_18_FONT_ID (1503221336)
// #define NOTOSANSTHAI_8_FONT_ID (14032332)
// #define NOTOSANSTHAI_10_FONT_ID (13032332)
#define NOTOSANSTHAI_12_FONT_ID (12032332)
#define NOTOSANSTHAI_14_FONT_ID (-890242898)
#define NOTOSANSTHAI_16_FONT_ID (241925181)
#define NOTOSANSTHAI_18_FONT_ID (1503221332)
#define OPENDYSLEXIC_8_FONT_ID (875216341) #define OPENDYSLEXIC_8_FONT_ID (875216341)
#define OPENDYSLEXIC_10_FONT_ID (-1234231183) #define OPENDYSLEXIC_10_FONT_ID (-1234231183)
#define OPENDYSLEXIC_12_FONT_ID (1682200414) #define OPENDYSLEXIC_12_FONT_ID (1682200414)

View File

@ -95,6 +95,28 @@ EpdFont notosans18BoldItalicFont(&notosans_18_bolditalic);
EpdFontFamily notosans18FontFamily(&notosans18RegularFont, &notosans18BoldFont, &notosans18ItalicFont, EpdFontFamily notosans18FontFamily(&notosans18RegularFont, &notosans18BoldFont, &notosans18ItalicFont,
&notosans18BoldItalicFont); &notosans18BoldItalicFont);
EpdFont notosansthai8RegularFont(&notosansthai_8_regular);
EpdFontFamily notosansthai8FontFamily(&notosansthai8RegularFont);
EpdFont notosansthai10RegularFont(&notosansthai_10_regular);
EpdFontFamily notosansthai10FontFamily(&notosansthai10RegularFont);
EpdFont notosansthai12RegularFont(&notosansthai_12_regular);
EpdFont notosansthai12BoldFont(&notosansthai_12_bold);
EpdFontFamily notosansthai12FontFamily(&notosansthai12RegularFont, &notosansthai12BoldFont);
EpdFont notosansthai14RegularFont(&notosansthai_14_regular);
EpdFont notosansthai14BoldFont(&notosansthai_14_bold);
EpdFontFamily notosansthai14FontFamily(&notosansthai14RegularFont, &notosansthai14BoldFont);
EpdFont notosansthai16RegularFont(&notosansthai_16_regular);
EpdFont notosansthai16BoldFont(&notosansthai_16_bold);
EpdFontFamily notosansthai16FontFamily(&notosansthai16RegularFont, &notosansthai16BoldFont);
EpdFont notosansthai18RegularFont(&notosansthai_18_regular);
EpdFont notosansthai18BoldFont(&notosansthai_18_bold);
EpdFontFamily notosansthai18FontFamily(&notosansthai18RegularFont, &notosansthai18BoldFont);
EpdFont opendyslexic8RegularFont(&opendyslexic_8_regular); EpdFont opendyslexic8RegularFont(&opendyslexic_8_regular);
EpdFont opendyslexic8BoldFont(&opendyslexic_8_bold); EpdFont opendyslexic8BoldFont(&opendyslexic_8_bold);
EpdFont opendyslexic8ItalicFont(&opendyslexic_8_italic); EpdFont opendyslexic8ItalicFont(&opendyslexic_8_italic);
@ -252,14 +274,20 @@ void setupDisplayAndFonts() {
renderer.insertFont(NOTOSANS_14_FONT_ID, notosans14FontFamily); renderer.insertFont(NOTOSANS_14_FONT_ID, notosans14FontFamily);
renderer.insertFont(NOTOSANS_16_FONT_ID, notosans16FontFamily); renderer.insertFont(NOTOSANS_16_FONT_ID, notosans16FontFamily);
renderer.insertFont(NOTOSANS_18_FONT_ID, notosans18FontFamily); renderer.insertFont(NOTOSANS_18_FONT_ID, notosans18FontFamily);
renderer.insertFont(NOTOSANSTHAI_12_FONT_ID, notosansthai12FontFamily);
renderer.insertFont(NOTOSANSTHAI_14_FONT_ID, notosansthai14FontFamily);
renderer.insertFont(NOTOSANSTHAI_16_FONT_ID, notosansthai16FontFamily);
renderer.insertFont(NOTOSANSTHAI_18_FONT_ID, notosansthai18FontFamily);
renderer.insertFont(OPENDYSLEXIC_8_FONT_ID, opendyslexic8FontFamily); renderer.insertFont(OPENDYSLEXIC_8_FONT_ID, opendyslexic8FontFamily);
renderer.insertFont(OPENDYSLEXIC_10_FONT_ID, opendyslexic10FontFamily); renderer.insertFont(OPENDYSLEXIC_10_FONT_ID, opendyslexic10FontFamily);
renderer.insertFont(OPENDYSLEXIC_12_FONT_ID, opendyslexic12FontFamily); renderer.insertFont(OPENDYSLEXIC_12_FONT_ID, opendyslexic12FontFamily);
renderer.insertFont(OPENDYSLEXIC_14_FONT_ID, opendyslexic14FontFamily); renderer.insertFont(OPENDYSLEXIC_14_FONT_ID, opendyslexic14FontFamily);
#endif // OMIT_FONTS #endif // OMIT_FONTS
renderer.insertFont(UI_10_FONT_ID, ui10FontFamily); renderer.insertFont(UI_10_FONT_ID, notosansthai10FontFamily);
renderer.insertFont(UI_12_FONT_ID, ui12FontFamily); renderer.insertFont(UI_12_FONT_ID, notosansthai12FontFamily);
renderer.insertFont(SMALL_FONT_ID, smallFontFamily); renderer.insertFont(SMALL_FONT_ID, notosansthai8FontFamily);
Serial.printf("[%lu] [ ] Fonts setup\n", millis()); Serial.printf("[%lu] [ ] Fonts setup\n", millis());
} }